Issue sending user input floats to Serial for Simulink

Hey everyone,

Currently im trying to do is send user inputs from Arduino to Simulink. What my physical project is looking like right now is theres two Megas, ones running arduino code to send a number (Mega Send) and another run to recieve it (Mega Recieve). On Simulink, essentaillty Mega Receive is using the Serial Recieve block connected to a display.

Currently the issue im facing is when i've hardcoded the value like the code below, it works fine and its returning the correct data.

Working Hardcoded Code:

void setup() {
  Serial1.begin(9600); // Initialize Serial1 for communication
}

void loop() {
  float predefinedNumber = 43.546; // Predefined number to send
  
  // Send the predefined number to Simulink via Serial1
  writeToSimulink(predefinedNumber);

 delay(100); // Delay for 1 second before sending the number again
}

// Function to send the float number in byte format to Simulink
void writeToSimulink(float number) {
  byte *b = (byte *)&number;
  Serial1.write(b, 4);  // Send the float as 4 bytes
  Serial1.write(13);    // Carriage return
  Serial1.write(10);    // Line feed
}

But when I use anything to read the user input, like this, it doesnt work! Im really scratching my head, because i dont understand why it send, despite the converted data type being the same.

Not working user input code:

void setup() {
  Serial.begin(9600);   // Initialize Serial0 (USB) for communication
  Serial1.begin(9600);  // Initialize Serial1 for communication
}

void loop() {
  // Check if data is available to read from Serial (USB)
  if (Serial.available() > 0) {
    String inputString = Serial.readStringUntil('\n');  // Read input as string until newline character
    
    // Convert the string to float
    float userNumber = inputString.toFloat();
    
    // Send the converted float number to Simulink via Serial1
    writeToSimulink(userNumber);

    // Optional: Print the number back to the Serial Monitor to verify
    Serial.print("Sent number: ");
    Serial.println(userNumber);
  }

  delay(100); // Small delay to allow Serial communication to settle
}

// Function to send the float number in byte format to Simulink
void writeToSimulink(float number) {
  byte *b = (byte *)&number;
  Serial1.write(b, 4);  // Send the float as 4 bytes
  Serial1.write(13);    // Carriage return
  Serial1.write(10);    // Line feed
}

Really at my wits ends at this, consdiering I need to get it to a stage where it can take two inputs in one line like [123.45 345.67]. Any help would be greatly appreciated :slight_smile:

This is the problem:

if (Serial.available() > 0) {
    String inputString = Serial.readStringUntil('\n');  // Read input as string until newline character
    
    // Convert the string to float
    float userNumber = inputString.toFloat();

The above code should be doing the inverse of this:

void writeToSimulink(float number) {
  byte *b = (byte *)&number;
  Serial1.write(b, 4);  // Send the float as 4 bytes
  Serial1.write(13);    // Carriage return
  Serial1.write(10);    // Line feed
}
void setup() {
  Serial.begin(9600);   // why so slow ?
  Serial1.begin(9600);  // Initialize Serial1 for communication
}

void loop() {
  if (Serial.available() > 0) {  // Check if data is available to read from Serial (USB)
    float input = Serial.parseFloat();  // Read input as float
    while (Serial.available() > 0)Serial.read(); // dumb what is left
    writeToSimulink(input );

    // Optional: Print the number back to the Serial Monitor to verify
    Serial.print("Sent number: ");
    Serial.println(input, 4);
    delay(100); // Small delay to allow Serial communication to settle
  }
}

// Function to send the float number in byte format to Simulink
void writeToSimulink(float number) {
  byte *b = (byte *)&number;
  Serial1.write(b, 4);  // Send the float as 4 bytes
  Serial1.write(13);    // Carriage return
  Serial1.write(10);    // Line feed
}

I wouldn’t define your float variable within loop - every time it loops it has to redefine that variable and it can’t be used outside of loop.
Define it before setup , you don’t need to then pass it into your procedure making things simplier .

You might want to look at multiplying up your number so it can be an integer rather than a float . With bit of thinking you can often avoid floats

Say send 20345 instead of 20.345 and convert it back at the receiver .( in my example , you can divide that by 1000, to get 20. Add and decimal point and print the remainder to show 20.345)

Also look at what that number is ? If you are for example reading an analog input , just send it and do the maths at the receiver .

Sorry im just a bit confused? as in read the number from serial and convert it to its byte equivalent?

Hey, im having a bit of a hard time trying to understand the logic of this? Itakes from serial, and what ever it doesnt take in as a float it clears?

The same problem still seems to be the case, where its not reading the inputs on SIMULINK, but with the hardcoded constant its fine. Would love to see and hear some of your other suggestions.

Hey unfortunately with your iteration it doesnt work. Even when set as a global variable the float value doesnt actually get read by simulink.

float userNumber;  // Define the float variable globally

void setup() {
  Serial.begin(9600);   // Initialize Serial0 (USB) for communication
  Serial1.begin(9600);  // Initialize Serial1 for communication
}

void loop() {
  // Check if data is available to read from Serial (USB)
  if (Serial.available() > 0) {
    String inputString = Serial.readStringUntil('\n');  // Read input as string until newline character
    
    // Convert the string to float
    userNumber = inputString.toFloat();
    
    // Send the converted float number to Simulink via Serial1
    writeToSimulink();

    // Optional: Print the number back to the Serial Monitor to verify
    Serial.print("Sent number: ");
    Serial.println(userNumber);
  }

  delay(100); // Small delay to allow Serial communication to settle
}

// Function to send the float number in byte format to Simulink
void writeToSimulink() {
  byte *b = (byte *)&userNumber;
  Serial1.write(b, 4);  // Send the float as 4 bytes
  Serial1.write(13);    // Carriage return
  Serial1.write(10);    // Line feed
}

The only reason why im sending it as floats is becuase of the double type im reading it as on my simulink set up. I find that other data types are very problematic and doesnt convert well.

Same reason as why I cannot really do maths at the reciever as simulink, whilst possible, isnt very flexible within that department.

This might also give an indication, here im printing the bytes sent back and it honestly looks fine.

void setup() {
  Serial.begin(9600); // Initialize Serial for USB communication with the Serial Monitor
  Serial1.begin(9600); // Initialize Serial1 for communication
  Serial.println("Enter float numbers:");
}

void loop() {
  if (Serial.available() > 0) {
    String inputString = Serial.readStringUntil('\n'); // Read the input until a newline character

    // Debug: Print the received input string to Serial Monitor for verification
    Serial.print("Received: ");
    Serial.println(inputString);

    float number = inputString.toFloat(); // Convert the input string to a float

    // Debug: Print the float number to Serial Monitor to verify correct conversion
    Serial.print("Converted float: ");
    Serial.println(number, 4); // Print with 4 decimal places for precision

    // Send the converted float number to Simulink via Serial1
    writeToSimulink(number);
  }
}

// Function to send the float number in byte format to Simulink
void writeToSimulink(float number) {
  byte *b = (byte *)&number;

  // Debug: Print the byte array to verify its content before sending
  Serial.print("Sending bytes: ");
  for (int i = 0; i < 4; i++) {
    Serial.print(b[i], HEX);
    Serial.print(" ");
  }
  Serial.println();

  Serial1.write(b, 4); // Send the float as 4 bytes
  Serial1.write(13);   // Carriage return
  Serial1.write(10);   // Line feed
}

So im pretty lost now.

what number do you see received in Simulink ?

Sorry I don't have time ATM to spot the difference between:

  1. what works in post #1 with predefinedNumber and
  2. why the code in post #8 doesn't work

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