Последовательные данные, показывающие неверные значения

Я отправляю данные по последовательному порту USB на мой Uno в указанном формате и распечатываю значения после их чтения

void loop() {
    if(Serial.available()){
        while(Serial.available()){
            int pos = Serial.readStringUntil(':').toInt();
            Serial.println(pos);
            int r = Serial.readStringUntil(',').toInt();
            Serial.println(r);
            int g = Serial.readStringUntil(',').toInt();
            Serial.println(g);
            int b = Serial.readStringUntil(';').toInt();
            Serial.println(b);
        }
    }
}

Так отправляются данные

0:255,255,255;1:255,255,255;2:255,255,255;3:255,255,255;4:255,255,255;5:255,255,255;6:255,255,255;7:255,255,255;8:255,255,255;9:255,255,255;10:255,255,255;

формат: {позиция}:{красное значение},{зеленое значение},{синее значение};

Когда я отправляю эту строку на устройство через последовательный монитор, он печатает неправильные значения

0
255
255
255
1
55 // должно быть 255
255
255
2
55 // должно быть 255
255
255
3
55 // должно быть 255
255
255
4
55 // должно быть 255
255
255
5
255
255
255
6
255
255
255
7
255
255
255
8
255
255
255
9
255
255
255
10
255
255
255

Почему данные неверны?

Может быть, монитор последовательного порта показывает неправильно, но значения на самом деле правильные?

, 👍-1

Обсуждение

это, вероятно, не поможет, но четыре раза parseInt() сгодятся. синтаксический анализ заканчивается на нецифровом символе и пропускает начальные нецифровые символы, @Juraj

вы отправляете данные одной строкой?, @Juraj

@Juraj да одна строчка, @tyczj

@Juraj parseInt действительно помогает, мне просто нужно добавить дополнительную логику, чтобы он не пытался читать после последнего числа, @tyczj

вы не знаете количество наборов rgb на линии?, @Juraj

Да, я делаю это в этом примере, что я делаю, так это проверяю позицию как последнюю вещь в то время как, и если позиция является последним ожидаемым значением rgb, я просто «читаю», пока «доступно» не станет равным нулю, @tyczj

Я не думаю, что ваша проблема связана с вашим кодом. Я запустил его (на скоростях 9600, 115200 и 230400 бод) и получил правильные результаты. Я использовал встроенный терминал Arduino в линейном режиме — скопируйте/вставьте пример отправленных данных в строку ввода терминала и нажмите «Отправить»., @JRobert


1 ответ


0

Похоже, вы анализируете входящие данные для строки из 4 чисел, pos+r+g+b. Чтобы избежать потери данных, а также повысить скорость (если вам это нужно), лучше отправлять данные в виде байтов:

: 0x01 0xFF 0xFF 0xFF : 0x02 0xFF 0xFF 0xFF : 0x03 0xFF 0xFF 0xFF ... etc

Это можно сделать с помощью последовательного монитора Arduino через преобразователь шестнадцатеричного кода в ASCII. Например, https://www.branah.com/ascii-converter

Введите шестнадцатеричный код (отсутствует 0x, где 0x3a=':'): 3a01FFFFFF3a02FFFFFF3a03FFFFFF3a04FFFFFFFF

Получить ASCII: :ÿÿÿ:ÿÿÿ:ÿÿÿ:ÿÿÿ

Скопируйте это в последовательный монитор Arduino

Кроме того, старайтесь делать все серийные отпечатки за один раз, не чередуйте чтение и запись, если в этом нет крайней необходимости. Иногда таким же образом отбрасываются и байты.

byte pos, r, g, b;

void setup(){
// serial begin
}

void loop() {
    if(Serial.available()){
        while(Serial.available()){
            Serial.readStringUntil(':');
            pos = Serial.read();
            r   = Serial.read();
            g   = Serial.read();
            b   = Serial.read();
            Serial.write(pos);
            Serial.write(r);
            Serial.write(g);
            Serial.write(b);
         }
    }
}

Если вам нужен более элегантный способ последовательной записи, вы найдете множество ответов уже на странице обмена стеками (слишком много, чтобы предложить только один).

,

Технически мне не нужны разделители, я просто использовал их как способ узнать, что я читал, разделив значения, @tyczj

@MichaelT, как вы отправляете байты из Serial Monitor для чтения с помощью read ()? Я не думаю, что Serial Monitor преобразует шестнадцатеричные значения в байты., @Juraj

Последовательный монитор Arduino позволяет вводить символы. Вы можете использовать другие программы либо для преобразования байтов в char (и копирования/вставки в IDE), либо для всего последовательного чтения и записи (например, Qt, matlab, mathematica)., @MichaelT

но вопрос подразумевает Serial Monitor как вход и выход. ваш ответ хорош и верен, только добавьте немного вступления об отправке и получении с помощью компьютерной программы, @Juraj

Я привел пример того, как отправить шестнадцатеричный код с помощью последовательного монитора Arduino. Если это работает для вас, пожалуйста, примите / проголосуйте., @MichaelT