United Kingdom
Asked
Resolved Resolved by DJ Sures!

Reading UART Integer/Float Sent From Arduino

Hi,

I've been using the following tutorial and code to get data from an Arduino for a battery of sensors...

Using Arduino as Encoder

One of my sensors is a Barometer and is sending the pressure....but the value falls outside of the 255 that this tutorial seems to accept. The number for the pressure on my arduino is a float of currently 998.10 - but I don't mind losing the decimal and just having an integer.

Could one of you kind folks give me some advice on what script / command I can use to read this number?

Thanks

Steve Haze


Related Hardware EZ-B v4
Related Control Script

ARC Pro

Upgrade to ARC Pro

Subscribe to ARC Pro, and your robot will become a canvas for your imagination, limited only by your creativity.

United Kingdom
#9  

Hmmm.....that didn't still didn't seem to work...

SO.... I did some googling and learning and this is what worked for me for sending the Float...SORT OF..... I'm cheating a bit....but for the 1 decimal place that I need for this sensor reading, I'm happy.

(PS: I know the Ezb could poll this particular sensor itself...but my arduino is handling all my sensors and then sending to Ezb.) :)

On the Arduino...

  // if there is data to read, read it
if (Serial1.available() > 0) {

    // read the incoming data from the ezb
    int incomingByte = Serial1.read();

   // Listen for an "x" sent from Ezb to request this data - I'm using other commands for other requests.
    if (incomingByte == 78) {      

        // Get the Pressure from the BME Barometric Sensor
        float pressure = bme.readPressure();   
        pressure = bme.seaLevelForAltitude(ALTITUDE,pressure);
        pressure = pressure/100.0F;
         
       // Multiply by 10 to get rid of the decimal
         int pressure10 = pressure * 10;   
                
        byte * b = (byte *) &pressure10;
        Serial1.write(b[0]);
        Serial1.write(b[1]);
     
    }
]


Then in ARC....JavaScript (modified from what DJ Sures posted)....

// initialize the hardware uart #0 at 9600 on ezb #0
UART.initHardwareUart(0, 115200, 0);

var x = 78;

// Tell the Arduino to send us the Barometric Pressure reading
UART.hardwareUartWrite(0, x, 0);

// Wait 100ms to allow for receipt...
sleep(100);

// Get the number of bytes available to read
var bytesAvail = UART.hardwareUartAvailable(0, 0);
print(bytesAvail);


if (bytesAvail == 2) {
   
   // Get the data as an array from the UART buffer
   var dataArray = UART.hardwareUartRead(0, 2, 0);
   
   var value = dataArray[0] + (dataArray[1] << 8);

   // Divide by 10 to regain the decimal place.
   value = value / 10; 
   
   print("Your value is " + value);
}
 else {

   print("Not enough bytes available to assemble an int16");
   
}

Thank you so much DJ for your ALWAYS quick replies and sharing of knowledge.:D

PRO
Synthiam
#10   — Edited

Oh - you were still trying to send a float? The float wouldn't work in my example, as it was only an in16. Your example would work, but you do lose one digit of resolution. It, the maximum range of a signed Int16 is -32,768 to 32,767. So with your solution, the maximum rage would be -2,768 to 2,767

If that range is acceptable for your application, it's golden:). Otherwise, use a signed Int 32 (4 bytes)

United Kingdom
#11  

I tried that...but I couldn't find or figure out the decoding of the 4 byte array... I had the arduino variable that's being sent as a Long and the following...

        // Get the Pressure from the BME Barometric Sensor
        float pressure = bme.readPressure();   
        pressure = bme.seaLevelForAltitude(ALTITUDE,pressure);
        pressure = pressure/100.0F;

        // Multiply by 100 to get rid of the decimal
         long pressure100 = pressure * 100;   
                
        byte * b = (byte *) &pressure10;
      Serial1.write(b[0]);
       Serial1.write(b[1]);
       Serial1.write(b[2]);
        Serial1.write(b[3]);

I'm only just learning about shifting... So I'm guessing after receiving 4 bytes and not 2....the Javascript line here would need to be different.....but I'm not sure how. Can you advise?:)

 var value = dataArray[0] + (dataArray[1] << 8);
PRO
Synthiam
#12   — Edited

4 byte (int32) would look like this...

On the Arduino...


  // if there is data to read, read it
if (Serial1.available() > 0) {

 // read the incoming data from the ezb
 int incomingByte = Serial1.read();

// Listen for an "x" sent from Ezb to request this data - I'm using other commands for other requests.
 if (incomingByte == 78) {

  // Get the Pressure from the BME Barometric Sensor
float pressure = bme.readPressure();
  pressure = bme.seaLevelForAltitude(ALTITUDE,pressure);
  pressure = pressure/100.0F;

 // Multiply by 10 to get rid of the decimal and convert to int32
int32 pressure10 = pressure * 10;
 
  byte * b = (byte *) &pressure10;
  Serial1.write(b[0]);
  Serial1.write(b[1]);
  Serial1.write(b[2]);
  Serial1.write(b[3]);
}

Then in ARC....JavaScript (modified from what DJ Sures posted)....


// initialize the hardware uart #0 at 9600 on ezb #0
UART.initHardwareUart(0, 115200, 0);

var x = 78;

// Tell the Arduino to send us the Barometric Pressure reading
UART.hardwareUartWrite(0, x, 0);

// Wait 100ms to allow for receipt...
sleep(100);

// Get the number of bytes available to read
var bytesAvail = UART.hardwareUartAvailable(0, 0);
print(bytesAvail);


if (bytesAvail == 4) {

// Get the data as an array from the UART buffer
var dataArray = UART.hardwareUartRead(0, 4, 0);

var value = dataArray[0] + (dataArray[1] << 8) + (dataArray[2] << 16) + (dataArray[3] << 24)

// Divide by 10 to regain the decimal place.
value = value / 10; 

print("Your value is " + value);
}
 else {

print("Not enough bytes available to assemble an int32");

}

United Kingdom
#13  

Excellent....

I'm getting 'int32' was not declared in this scope but if I use LONG then it works.:D

Namaste!

PRO
Synthiam
#14  

Oh ya! Arduino is int_32 I think or long. Thanks for correcting my codez!