Я делаю проект Arduino для вращения вентилятора, основанного на скорости автомобиля в iRacing. Это мой самый первый проект arduino, поэтому, пожалуйста, несите меня. Я действительно смущен каким-то странным поведением с последовательной связью ПК/Arduino, и я надеюсь, что кто-то поможет объяснить, что происходит ...Данные Arduino Serial.parseInt() повреждены слишком большим количеством Serial.print()?
В принципе, на ПК есть программа на C++, которая получает данные от iRacing SDK для скорости транспортного средства и отправляет это по последовательной линии на Arduino. Arduino выполняет некоторую простую обработку и управляет контроллером двигателя для запуска вентилятора.
Явление, которое я пытаюсь понять, состоит в том, что, если у меня есть Arduino, слишком много написано в сериале с инструкциями Serial.print(), он начинает разлагать значения, которые он считывает с помощью Serial.parseInt().
Я получил его на работу просто не писать «слишком много» на последовательной линии, но на некоторое время он ведет себя непредсказуемо - скорость вращения вентилятора вверх и вниз, даже если значение iRacing было устойчивым , Я добавил дополнительный материал Serial.print в моем эскизе arduino и serial.readSerial, чтобы попытаться увидеть на стороне ПК, что происходит со значениями, и оказалось, что это делало это хуже.
После того, как я немного потянул мои волосы, я начал с нуля на эскизе arduino, и он работал со всей его логикой, но с командами Serial.print, прокомментированными! Поэтому я систематически добавлял их обратно и обнаружил, что существует некоторый порог, когда, если я печатаю слишком много для последовательной линии, он начинает работать неправильно.
Вот результат, как видно на ПК, когда он работает. ПК отправляет 59 в качестве int в Arduiono. Arduino получает это, когда Serial.parseInt() выполняет ограничение() до 55, а затем сопоставляет его с диапазоном 40-255. Минимальные операторы Serial.print() отправляют эти данные обратно на компьютер, где он считывается и печатается. Все хорошо.
59 55 255
59 55 255
59 55 255
59 55 255
59 55 255
59 55 255
59 55 255
59 55 255
Если добавить больше Serial.print() заявления, чтобы описать данные, значение, которое я читаю с компьютера с Serial.parseInt() начинает получать возмущенные. Этот результат показывает, что я вижу, когда это происходит. Данные выглядят перепутанными, и, действительно, скорость вентилятора снижается. Это тот же случай, как указано выше, и оно должно быть устойчивым в 59:
Car Vel: 59 55 255
Car Vel: 59 55 255
Car Vel: 9 9 71
Car Vel: 47 47 223
Car Vel: 59 55 255
Car Vel: 59 55 255
Car Vel: 9 9 71
Car Vel: 47 47 223
Car Vel: 59 55 255
Car Vel: 71 55 255
Car Vel: 47 47 223
Car Vel: 59 55 255
Car Vel: 59 55 255
Вот Arduino эскиз упрощен весь путь вниз, так что все это не читается в междунар с ПК, ограничить его, сопоставьте его на диапазон и распечатать значения. Как будет показано ниже, он будет работать с ошибками и выдавать выходные данные (как во втором списке выше). Если я прокомментирую распечатку «Car Vel:», она будет работать, и данные будут устойчивыми (например, первый список выше).
#define MIN 40
#define MAX 255
#define TOPSPEED 55
void setup() {
Serial.begin(9600);
}
void loop() {
uint8_t v;
uint8_t s;
if (Serial.available() > 0) {
v = Serial.parseInt();
Serial.print("Car Vel: "); //UNCOMMENT ANY OF THESE TO SEE THE FAIL
Serial.print(v);
Serial.print("\t");
v = constrain(v,0,TOPSPEED);
// Serial.print("Clamped Vel: "); //UNCOMMENT ANY OF THESE TO SEE THE FAIL
Serial.print(v);
Serial.print("\t");
s = map(v,1,TOPSPEED,MIN,MAX);
// Serial.print("Fan Speed: "); //UNCOMMENT ANY OF THESE TO SEE THE FAIL
Serial.println(s);
}
}
На стороне ПК, я использую irsdk_ir2ad C++ код из iRacing SDK с только запустить() рутина модифицированного таким образом:
void run()
{
// wait up to 16 ms for start of session or new data
if(irsdkClient::instance().waitForData(16))
{
// and grab the data
int v = g_carVelX.getInt();
serial.writeSerialPrintf("%d\n", v);
}
// check for data coming back from Arduino
if (serial.serialHasData())
{
static char buffer[256];
serial.readSerial(buffer, 256);
printf("%s", buffer);
}
monitorConnectionStatus();
}
Я уверен, что раскомментировав Сериал .print делает эту проблему присутствующей, но у меня нет реального хорошего объяснения, почему. Может ли кто-нибудь помочь? Это какая-то длина отправки, которая была превышена (кажется, действительно малое количество текста)? Или слишком много данных записывается с ПК, в то время как Arduino пишет свои собственные данные? Или какой-то момент hickup, где его просто дополнительное время и не имеет ничего общего с объемом данных, которые записываются?
Правильный инструмент для решения таких проблем - использовать ваш отладчик, но не спрашивать при переполнении стека до того, как вы это сделали, и рассказать нам обо всех ваших наблюдениях, которые вы делали при проверке кода, проходящего по строкам. –
От отладки, которую я сделал, похоже, проблема связана с Arduino (у которой нет отладчика). Запуск эскиза с включенной линией, он неисправен: 'Serial.print (« Car Vel: »); // УНИЧТОЖЕНИЕ ЛЮБОГО ИЗ ЭТИГО, ЧТОБЫ ВИДЕТЬ НЕИСПРАВНОСТЬ. Комментируя эту линию, она работает. Я не понимаю, почему дополнительный вызов Serial.print() искажает данные, прочитанные на Serial.parseInt() –