Сумасшедшие результаты с I2C и I2C_Anything()

У меня есть следующий код в функции Arduino Mega для извлечения двух 4-байтовых целых чисел из 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);

И это дает следующий результат:

<<<<<<<   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

Это сводит меня с ума, потому что, хотя Fin1 & Значения Fin2, по-видимому, принимаются правильно, значение Fin2 всегда сообщается как 0, даже после того, как оно было явно задано равным Fin1 в качестве теста (строка 6 в коде).

Значения, полученные от Teensy (5375 и 10750 в выходном фрагменте), верны, но я не могу заставить Fin2 распечатать правильно (проблема «SteeringValue», вероятно, такая же, как и проблема «Fin2», но Я еще не добрался до него).

Я не могу понять, что я здесь делаю неправильно. Может ли кто-нибудь, проходящий мимо, взглянуть с расстояния 10 метров и сразу увидеть проблему?

ТИА

Фрэнк

31 марта 2020 г. Обновление:

Наконец-то я получил Wire.requestFrom() & I2C_Anything(), чтобы вести себя так, как я думал, но я все еще остаюсь загадкой - почему версия printf для PrintEx отказывается правильно печатать значения: Вот фрагмент кода:

//получить последнюю информацию из модуля IR Demod
long Fin1 = 0; //30.03.20 здесь должно быть 'long int' (4 байта), чтобы соответствовать Teensy int (4 байта)
long Fin2 = 23; //30.03.20 здесь должно быть 'long int' (4 байта), чтобы соответствовать Teensy int (4 байта)
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);

А вот и результат. Как видите, отдельные значения печатаются правильно, но при объединении в последний оператор mySerial.printf() все идет наперекосяк. Кто-нибудь знает?

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

Фрэнк

И последнее обновление: я сравнил вывод, полученный с помощью StreamEx mySerial = Serial; объект, а также полученный с помощью более традиционного оператора Serial.print(). Код

    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);

И результат:

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

Верхняя строка полностью верна, но по какой-то причине в версии mySerial.printf() она неверна. Идеи?

Фрэнк

, 👍0

Обсуждение

Что такое тип Fin1 и Fin2? Кроме того, в строках 10 и 12 вы фактически печатаете Fin1 дважды., @Fahad

Fin1 и Fin2 оба являются «длинными целыми» (4 байта на Arduino Mega). Они соответствуют 4-байтовому типу 'int' ведомого устройства Teensy 3.2. И да, я знаю, что печатаю вещи несколько раз, но я не думаю, что это меняет основное сумасшествие получения правильного результата в Fin2, а затем невозможность его распечатать., @user3765883

Какую библиотеку вы используете для printf()?, @Fahad

Библиотека Arduino PrintEx, @user3765883


1 ответ


Лучший ответ:

1

Дьявол кроется в деталях. Из репозитория PrintEx doc это форматирование для printf:

%[flags][width][.precision][length]спецификатор

Когда вы используете long, вам нужно указать [длину], а библиотека принимает только "l" (буква 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);

  // Это не удастся
  mySerial.printf("Fin1 = %d, Fin2 = %d, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);

  // Это будет работать как положено
  mySerial.printf("Fin1 = %ld, Fin2 = %ld, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);
}

void loop() {}

Строка 16 — это то, что у вас есть. Строка 19 — это формат, который вам следует использовать.

,

Да, это сработало, хотя я бы поклялся на Библии, что в какой-то момент пробовал модификатор %ld., @user3765883