0

I have the following code in a Arduino Mega function to retrieve two 4-byte integers from a Teensy 3.2.

Wire.requestFrom(SLAVE_ADDR, sizeof(float)+ 2*sizeof(long));
mySerial.printf("\n<<<<<<<   In IsIRBeamAvail()  >>>>>>>>>>>>>>>>>>>>\n\n");
mySerial.printf("Wire.Available() reports %d\n", Wire.available());
I2C_readAnything(Fin1);
mySerial.printf("Read Fin1 %d, Wire.Available() reports %d\n",Fin1, Wire.available());
Fin2 = Fin1; 
mySerial.printf("Fin1 = %d, Fin2 = %d\n", Fin1, Fin2);
I2C_readAnything(Fin2);
mySerial.printf("Read Fin2 = %d, Wire.Available() reports %d\n", Fin2, Wire.available());
mySerial.printf("Fin1 = %d, Fin2 = %d and SteeringValue = %2.2f\n", Fin1, Fin1, SteeringValue);
mySerial.printf("Read %f, Wire.Available() reports %d\n", SteeringValue, Wire.available());
mySerial.printf("Fin1 = %d, Fin2 = %d and SteeringValue = %2.2f\n", Fin1, Fin1, SteeringValue);

And this produces the following output:

<<<<<<<   In IsIRBeamAvail()  >>>>>>>>>>>>>>>>>>>>

Wire.Available() reports 12
I2C_readAnything: Sizeof(value) = 4
Read Fin1 5375, Wire.Available() reports 0
Fin1 = 5375, Fin2 = 0
I2C_readAnything: Sizeof(value) = 4
Read Fin2 = 10750, Wire.Available() reports 0
Fin1 = 5375, Fin2 = 0 and SteeringValue = 0.00
Read 0, Wire.Available() reports 4
Fin1 = 5375, Fin2 = 0 and SteeringValue = 0.00

This is driving me nuts, because while the Fin1 & Fin2 values are apparently received correctly, the Fin2 value is always reported as 0, even after it was explicitly set to be equal to Fin1 as a test (line 6 in the code).

The values obtained from the Teensy (5375 and 10750 in the output snippet) are correct, but I can't get Fin2 to print out correctly (the 'SteeringValue' issue is probably the same as the 'Fin2' problem, but I haven't gotten there yet).

I cannot for the life of me figure out what I'm doing wrong here. Could someone walking by take a glance from 30 feet away and immediately see the problem?

TIA,

Frank

3/31/20 Update:

I finally got Wire.requestFrom() & I2C_Anything() to behave the way I thought it should, but I'm still left with a mystery - why the PrintEx version of printf refuses to print the values properly: Here's the code snippet:

//get latest info from IR Demod Module
long Fin1 = 0; //03/30/20 needs to be 'long int' (4 bytes) here to match Teensy int (4 bytes)
long Fin2 = 23; //03/30/20 needs to be 'long int' (4 bytes) here to match Teensy int (4 bytes)
float SteeringValue;

mySerial.printf("\n<<<<<<<   In IsIRBeamAvail()  >>>>>>>>>>>>>>>>>>>>\n\n");

Wire.requestFrom(SLAVE_ADDR, sizeof(Fin1) + sizeof(Fin2)+ sizeof(SteeringValue));
mySerial.printf("Wire.Available() reports %d\n", Wire.available());

I2C_readAnything(Fin1);
mySerial.printf("Fin1 = %d\n", Fin1);

I2C_readAnything(Fin2);
mySerial.printf("Fin2 = %d\n", Fin2);

I2C_readAnything(SteeringValue);
mySerial.printf("SteeringValue = %2.3f\n", SteeringValue);

mySerial.printf("Fin1 = %d, Fin2 = %d, SteeringVal = %6.3f\n", Fin1, Fin2, SteeringValue);

And here's the output produced. As you can see, the individual values print out correctly, but when combined into the last mySerial.printf() statement, things go awry. Anyone have a clue?

Wire.Available() reports 12
I2C_readAnything: Sizeof(value) = 4
Fin1 = 1986
I2C_readAnything: Sizeof(value) = 4
Fin2 = 3972
I2C_readAnything: Sizeof(value) = 4
SteeringValue = 6239.219
Fin1 = 1986, Fin2 = 0, SteeringVal =  0.000

Frank

And one last update: I compared the output obtained by using the StreamEx mySerial = Serial; object, and the one obtained by using the more traditional Serial.print() statement. The code

    Serial.print("Fin1 = "); Serial.print(Fin1); Serial.print(", ");
Serial.print("Fin2 = "); Serial.print(Fin2); Serial.print(", "); 
Serial.print("SteeringValue = "); Serial.println(SteeringValue);
mySerial.printf("Fin1 = %d, Fin2 = %d, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);

And the output:

Fin1 = 9185, Fin2 = 18370, SteeringValue = 28851.73
Fin1 = 9185, Fin2 = 0, SteeringValue = 0.00

The top line is entirely correct, but for some reason, the mySerial.printf() version gets it wrong. Ideas?

Frank

4
  • What is the type of Fin1 and Fin2? Also, on lines 10 and 12, you are actually printing Fin1, twice.
    – Fahad
    Commented Mar 31, 2020 at 8:09
  • Fin1 & Fin2 are both 'long int' (4 bytes on Arduino Mega). These match the 4-byte 'int' type from the Teensy 3.2 slave. And yes I know I'm printing things multiple times, but I don't think that changes the basic craziness of getting a correct result into Fin2 and then not being able to print it.
    – starship15
    Commented Mar 31, 2020 at 13:07
  • What library you are using for printf()?
    – Fahad
    Commented Mar 31, 2020 at 21:08
  • Arduino PrintEx library
    – starship15
    Commented Apr 1, 2020 at 15:03

1 Answer 1

1

The devil is in the details. From the PrintEx repo doc, this is the formatting for printf:

%[flags][width][.precision][length]specifier

When you use long, you will have to provide the [length], and the lib only accepts "l" (Letter L).

#include <PrintEx.h>

long int Fin1 = 5;
long int Fin2 = 2;
float SteeringValue = 3.5;

void setup() 
{
  Serial.begin(9600);
  PrintEx mySerial = Serial; 

  Serial.print("Fin1 = "); Serial.print(Fin1); Serial.print(", "); 
  Serial.print("Fin2 = "); Serial.print(Fin2); Serial.print(", "); 
  Serial.print("SteeringValue = "); Serial.println(SteeringValue);

  // This will fail
  mySerial.printf("Fin1 = %d, Fin2 = %d, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);

  // This will work as expected
  mySerial.printf("Fin1 = %ld, Fin2 = %ld, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);
}

void loop() {}

Line 16 is what you have. Line 19 is the format you should use.

1
  • Yep -that did the trick, although I would have sworn on a bible that I had tried the %ld modifier at some point.
    – starship15
    Commented Apr 2, 2020 at 16:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.