2016-08-12 3 views
-1

Я делаю проект 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, где его просто дополнительное время и не имеет ничего общего с объемом данных, которые записываются?

+0

Правильный инструмент для решения таких проблем - использовать ваш отладчик, но не спрашивать при переполнении стека до того, как вы это сделали, и рассказать нам обо всех ваших наблюдениях, которые вы делали при проверке кода, проходящего по строкам. –

+0

От отладки, которую я сделал, похоже, проблема связана с Arduino (у которой нет отладчика). Запуск эскиза с включенной линией, он неисправен: 'Serial.print (« Car Vel: »); // УНИЧТОЖЕНИЕ ЛЮБОГО ИЗ ЭТИГО, ЧТОБЫ ВИДЕТЬ НЕИСПРАВНОСТЬ. Комментируя эту линию, она работает. Я не понимаю, почему дополнительный вызов Serial.print() искажает данные, прочитанные на Serial.parseInt() –

ответ

1

Ответ оказывается ограниченным символом 9600 бод.

В данном конкретном случае ПК получает данные с частотой 60 Гц. При скорости 9600 бод последовательная линия может обрабатывать только 16 символов за цикл.

Попытка вывода вся строка превышает 16 байт предел: «Автомобиль Вель: 59 55 255»

Эксперименты показали, что если опустить комбинированный посылать/принимать данные к < = 16 байт, она последовательно ошибка бесплатная.

Смежные вопросы