Float array over I2C

Hello,

I am trying to send data from an STM32 to an Arduino Nano, which then subsequently sends it to an SD card. I can't figure out how to get the STM32 to work with the SD card but thats a different matter.

I had this code idea reasonably well by sending the floats over as a series of chars, this obviously took more bytes than sending the bytes of each float so that is what I would like to achieve.

This first code is a snippet from the STM32. It activates when a switch on a RC Tx is selected. I'm trying to send 8 floats by I2C, then read them at the other end.

/////////// i2c data trasnfer begins here...../////////

  if (ch5 > 1300){

    float Table[8];

    Table[0] = compangleY;
    Table[1] = RollTarget;
    Table[2] = RollError;
    Table[3] = dE_Roll;
    Table[4] = P_term_Roll;
    Table[5] = D_term_Roll;
    Table[6] = PID_Roll;
    Table[7] = PID_Roll_Avg; 


    Wire.beginTransmission(4);              // transmit to device #4
    Wire.write((uint8_t*) Table, sizeof(Table));
    Wire.endTransmission();                // stop transmitting


  }

  /////////// i2c data trasnfer ends here...../////////

These next 3 blocks of code are from the Arduino Nano that is receiving the data. It dumps the strings to an SD card, but as you can see form the attachment, it is printing garbage. I'm not particularly well versed in pointers so I think that is where my issue is.

// This is the Slave code for 6.11a
// Nano connected to SD card logging data from i2c on STM32.


#include <Wire.h>
#include <SPI.h>
#include <SdFat.h>
#include <EEPROM.h>

SdFat sd;
SdFile myFile;

char filename[16];
String SD_String;
int index = -1, file_count;
uint32_t last_time = 0;
bool data_flag = false;
unsigned long logging_start, timer;

const int chipSelect = 14;  //A0 as CS pin

void setup() {
  Wire.setClock(400000);        // 400kHz I2c bus Clk
  Wire.begin(4); // join i2c bus (at address 4)
  Wire.onReceive(receiveEvent);

  //Serial.begin(57600);
  //while (!Serial) {}  // wait for serial

  if (!sd.begin(chipSelect, SPI_FULL_SPEED)){
    //Serial.println("SD.begin Failed");
  }
    
  sd_header();

   //Serial.println("Setup of Slave");
}

void loop() {

   if ((millis() - last_time) > 1000 && data_flag){
    myFile.close();                        // 14mS
    EEPROM.write(1, file_count + 1);       // Increment EEPROM value by 1
    data_flag = false;
   }

}
void sd_header(){

  file_count = EEPROM.read(1);                // Read from EEPROM location 1
  if (file_count > 99 || file_count == 0){    // If number is 0 or more than 100 make it 1
    file_count = 1;
  }
  sprintf(filename, "Drone_%02d.csv", file_count);
  if (!myFile.open(filename, O_RDWR | O_CREAT | O_AT_END)) {}
  String header = "Time (mS), compangleY, Roll_Target, Roll_Error, dE_Roll, P_Term_Roll, D_Term_Roll, PID_Roll, PID_Roll_Avg";
  myFile.println(header);
  myFile.close();
  
}
float Table[8];
uint8_t* vp = (uint8_t*) Table;


void receiveEvent(int howMany){

  if (index == -1){
    logging_start = millis();
    index = 0;
  }

  while (0 < Wire.available()){
    *vp++ = Wire.read();
  }

  timer = millis() - logging_start;
  
  SD_String = String(timer);

  for (int k = 0; k < 8; k++){
    SD_String += ", " + String(Table[k]);
  }


  if (!myFile.open(filename, O_RDWR | O_CREAT | O_AT_END)) {}
  myFile.println(SD_String); 
  myFile.flush(); 
  last_time = millis();

  if (!data_flag) data_flag = true;
}

Any help on the matter would be much appreciated or general guidance on sending a float via I2C.

Take a look at C library function - atof() - Tutorialspoint

That is what you need to be doing.

Thank you.

Here's a few thoughts that may help out:

  1. The STM32 is transferring over 8 floats in one go. You would need to know how many bytes of RAM are used to store a float on your STM32. It may be 4 bytes, in which case you are sending over 32 bytes to the Arduino. I think you may be ok here but you need to check what the Arduino internal I2C buffer size is - I think it's 32 bytes.

  2. You are sending over a number of bytes that represent a number of float data types that are stored internally in the STM32 in the format that it understands. These are then written to variables on your Arduino Nano and the Nano thinks that they are also floats. BUT is an STM32 float stored in memory the same way an Arduino Nano float is?

There is probably no need to send floats.

All the values you have are of limited accuracy and subject to unknown but surely significant errors, so multiply the floats by 100 and send the resulting integers.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.