Последовательные данные, показывающие неверные значения
Я отправляю данные по последовательному порту 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
Почему данные неверны?
Может быть, монитор последовательного порта показывает неправильно, но значения на самом деле правильные?
@tyczj, 👍-1
Обсуждение1 ответ
Похоже, вы анализируете входящие данные для строки из 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
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Использовать все контакты как цифровые входы/выходы
- Float печатается только 2 десятичных знака после запятой
- Arduino как USB HID
- Serial1' was not declared in this scope
- Очень простая операция Arduino Uno Serial.readString()
- AT-команда не отвечает на последовательный монитор
это, вероятно, не поможет, но четыре раза parseInt() сгодятся. синтаксический анализ заканчивается на нецифровом символе и пропускает начальные нецифровые символы, @Juraj
вы отправляете данные одной строкой?, @Juraj
@Juraj да одна строчка, @tyczj
@Juraj parseInt действительно помогает, мне просто нужно добавить дополнительную логику, чтобы он не пытался читать после последнего числа, @tyczj
вы не знаете количество наборов rgb на линии?, @Juraj
Да, я делаю это в этом примере, что я делаю, так это проверяю позицию как последнюю вещь в то время как, и если позиция является последним ожидаемым значением rgb, я просто «читаю», пока «доступно» не станет равным нулю, @tyczj
Я не думаю, что ваша проблема связана с вашим кодом. Я запустил его (на скоростях 9600, 115200 и 230400 бод) и получил правильные результаты. Я использовал встроенный терминал Arduino в линейном режиме — скопируйте/вставьте пример отправленных данных в строку ввода терминала и нажмите «Отправить»., @JRobert