Возникла проблема с правильной передачей значений массива.
Я впервые задаю здесь вопрос, заранее извините, если это неправильный способ задать этот вопрос.
Я нахожусь на промежуточном этапе написания программы, и на этом этапе мне хотелось бы, чтобы байтовая информация, которую я ввожу в последовательный монитор, заняла места элементов моего массива. Я могу это сделать, но когда я пытаюсь использовать 5-значный ввод, я получаю взамен только 4-значный ввод.
Похоже, что мой цикл Serial.available() == 4 препятствует работе моего цикла Serial.available() == 5. Могу ли я внести простую модификацию, позволяющую получать 5-значный результат из 5-значного ввода и 4-значный результат из 4-значного ввода? Я пробовал много вещей, и Chat GPT, кажется, думает, что текущий код должен работать, но это не так. Вот код:
int fiveArray[5];
int fourArray[4];
const char* colors[] = {"black ", "brown ", "red ", "blue ", "yellow ", "orange ", "white ", "gold ", "green ", "purple "};
void setup() {
Serial.begin(9600);
Serial.print("Input a number value: ");
Serial.println();
}
void loop() {
if (Serial.available() ==5 ) {
char tempArrayFive[6];
Serial.readBytes(tempArrayFive, 6);
tempArrayFive[5] = '\0';
for (int i = 0; i < 5; i++) {
fiveArray[i] = tempArrayFive[i] - '0';
}
Serial.print("Color Value: ");
for (int i = 0; i < 5; i++) {
Serial.print(colors[fiveArray[i]]);
}
Serial.println();
}
if (Serial.available() == 4 ) {
char tempArrayfour[5];
Serial.readBytes(tempArrayfour, 5);
tempArrayfour[4] = '\0';
for (int i = 0; i < 4; i++) {
fourArray[i] = tempArrayfour[i] - '0';
}
Serial.print("Color Value: ");
for (int i = 0; i < 4; i++) {
Serial.print(colors[fourArray[i]]);
}
Serial.println();
}
}
@PairsRoyale, 👍-1
Обсуждение2 ответа
Да, если вы отправите 5 байт в Arduino, они будут приходить по одному. Когда поступает 4-й байт, оператор if (Serial.available() == 4 )
становится истинным и запускает этот код. Этот код считывает данные из буфера, а это означает, что часть, проверяющая 5 байтов, никогда не сможет работать. Прежде чем станет 5, всегда будет 4.
Лучше было бы отправлять байты с маркерами начала и конца. Программа на Arduino будет читать байты и собирать их в массив, пока не увидит маркер конца. Затем вы можете подсчитать, сколько байт вы получили, если хотите предпринять разные действия в зависимости от этого числа.
Вот хорошая тема по обработке последовательных данных: https://forum.arduino.cc/ t/serial-input-basics-updated/382007
У меня есть сообщение здесь, в котором обсуждается обработка входящих последовательных данных. Также здесь, на Stack Exchange.
Для обработки последовательного ввода, как вы пытаетесь это сделать, я предлагаю использовать «маркер конца строки»; например символ новой строки (который Терминальный монитор в IDE сделает за вас автоматически).
Тогда это просто случай просмотра того, что у вас было, до новой строки. Пример кода:
/*
Пример обработки входящих последовательных данных без блокировки.
Author: Nick Gammon
Date: 13 November 2011.
Modified: 31 August 2013.
Released for public use.
*/
// сколько последовательных данных мы ожидаем перед переводом строки
const unsigned int MAX_INPUT = 50;
void setup ()
{
Serial.begin (115200);
} // конец настройки
// здесь для обработки входящих последовательных данных после получения терминатора
void process_data (const char * data)
{
// пока просто отображаем это
// (но вы можете сравнить его с каким-то значением, преобразовать в целое число и т. д.)
Serial.println (data);
} // конец Process_data
void processIncomingByte (const byte inByte)
{
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;
switch (inByte)
{
case '\n': // конец текста
input_line [input_pos] = 0; // завершающий нулевой байт
// терминатор достигнут! обработать input_line здесь...
process_data (input_line);
// сбрасываем буфер для следующего раза
input_pos = 0;
break;
case '\r': // отбрасываем возврат каретки
break;
default:
// продолжаем добавлять, если не заполнено... разрешаем завершающий нулевой байт
if (input_pos < (MAX_INPUT - 1))
input_line [input_pos++] = inByte;
break;
} // конец переключателя
} // конец процессаIncomingByte
void loop()
{
// если серийные данные доступны, обработаем их
while (Serial.available () > 0)
processIncomingByte (Serial.read ());
// выполняем здесь другие действия, например, проверяем цифровой ввод (нажатие кнопок) ...
} // конец цикла
В вашем случае вы должны поместить код в функцию process_data
, чтобы преобразовать входной текст в число, а затем что-то сделать с этим числом.
Я удивлен, что ChatGPT не указал на мой код <grin> но, возможно, вы задали слишком конкретный вопрос.
Я бы просто отметил, что без символа завершения строки (например, новой строки) ваш код будет постоянно не соответствовать входящим данным, если он начинается не в том месте. Например:
123456789
В зависимости от скорости доставки, увидим ли мы 123
, за которым следует 456
? Или 12
, а затем 34
? Или 1234
, а затем 5678
? Разделитель в конце строки очень важен, чтобы избежать такой двусмысленности.
Или, если код начнет выполняться после того, как вы отправили 1
, но до 2
, он будет думать, что вы отправили 234
, а не 123
, и тогда все остальные числа будут отставать на одну позицию.
- C++ против языка Arduino?
- avrdude ser_open() can't set com-state
- Как читать и записывать EEPROM в ESP8266
- Float печатается только 2 десятичных знака после запятой
- устаревшее преобразование из строковой константы в 'char*'
- Запрограммировать ATMega328P и использовать его без платы Arduino.
- Разница между print() и println()
- Как исправить: Invalid conversion from 'const char*' to 'char*' [-fpermissive]
«Похоже» — отличное наблюдение, отправка одного байта (10 бит со стартовым и стоповым битами) со скоростью 9600 бод в секунду занимает около 1 мс. С другой стороны, Arduino на частоте 16 МГц за это время может обрабатывать 16 000 циклов команд — я предполагаю, что это более 200 циклов() между 4-м и 5-м символом..., @KIIV
Можете ли вы приложить образец того, что вы отправляете из последовательного монитора, и какое окончание строки вы там установили? Ваш текущий код не имеет для меня особого смысла. Как писал KIIV, у вас есть состояние гонки между двумя операторами if, но вы также читаете 6 (и 5) байтов, но перезаписываете последний нулём для завершения строки. Вы говорите о байтовых данных, но из вашего кода кажется, что вы используете текст в кодировке ASCII (важная разница при обработке данных), @chrisl
ОТ по поводу ChatGPT: Никогда не доверяйте чат-боту, он понятия не имеет о программировании, просто хорошо умеет складывать слова. Не смешивайте идеальную грамматику и формулировку со знаниями!, @the busybee
«_Я впервые задаю здесь вопрос_»: Поскольку вы предположительно умный человек, вы хотите совершить [экскурсию] и прочитать «[спросить]», а также другие страницы [помощи]., @the busybee