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

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

if (Serial.read() == /* first byte(character)*/ r)
{
  float i = SerialRead(); /* but the bytes from 2nd space to the end of the variable*/
}

Упрощённо: если я ввожу в последовательный монитор команду «r1.5», то цикл if распознаёт первый символ «r» как допустимое условие, тем самым устанавливая напряжение на красном выводе на 50%, игнорируя первый символ. Я также хочу отображать установленное значение, но это должно быть просто.

вся программа код - (Он подает напряжение, эквивалентное значению, которое потенциометр пропускает на соответствующий вывод RGB_LED):

#define LED_R 3
#define LED_B 5
#define LED_G 6

//Serial.write legenda: A0 A1 A2 RED BLUE GREEN A0_F A1_F A2_F

void setup()
{
  pinMode(LED_R, OUTPUT);
  pinMode(LED_B, OUTPUT);
  pinMode(LED_G, OUTPUT);

  Serial.begin(9600);
}

void loop()
{
  int RED = analogRead(A0)/ 4;
  int BLUE = analogRead(A1)/4;
  int GREEN = analogRead(A2)/4;

  Serial.print(analogRead(A0));//печать необработанных (входных) значений с R_потенциометра
  Serial.print(" ");
  Serial.print(analogRead(A1));//печать необработанных (входных) значений с B_потенциометра
  Serial.print(" ");
  Serial.print(analogRead(A2));//печать необработанных (входных) значений с G_потенциометра
  Serial.print(" ");

  Serial.print(RED); //печать значений (выходных) с R_потенциометра
  Serial.print(" ");
  Serial.print(BLUE); //печать значений (выходных) с B_потенциометра
  Serial.print(" ");
  Serial.print(GREEN);//печать значений (выходных) с G_потенциометра
  Serial.print(" ");

  float A0_F = (((float)RED)/(1023))*(5); //преобразовать значение аналогового выхода A0 в (обрабатываемое светодиодом) напряжение A0_F (конечное)
  float A1_F = (((float)BLUE)/(1023))*(5); //преобразовать значение аналогового выхода A1 в (обрабатываемое светодиодом) напряжение A1_F (конечное)
  float A2_F = (((float)GREEN)/(1023))*(5);// преобразует значение аналогового выхода A1 в (обрабатываемое светодиодом) напряжение A2_F (конечное)

  Serial.print(A0_F);//вывод окончательных значений на LED_R
  Serial.print(" ");
  Serial.print(A1_F);//вывод окончательных значений на LED_B
  Serial.print(" ");
  Serial.println(A2_F);//вывод окончательных значений на LED_G

  analogWrite(LED_R, A0_F);//присваивание значения LED_R
  analogWrite(LED_B, A1_F);//присваивание значения LED_B
  analogWrite(LED_G, A2_F);//присваивание значения LED_G
}
//сделаем усилитель снова

Пожалуйста, не делайте этого за меня, мне просто нужно подтверждение моей точки зрения или, что еще лучше: совет и руководство. А пока я продолжу искать ответ. Спасибо!

схема

Публикую впервые. Если что-то не так, пожалуйста, сообщите мне.

e1: Функция Serial.read() ещё не реализована, я застрял на предложении в вопросе. Если получу ответ, потом запрограммирую весь фрагмент.

, 👍0

Обсуждение

Ну, для начала вам нужно использовать функцию Serial.read(). В вашем коде эта функция нигде не запущена, поэтому сложно помочь вам, не зная, где именно вы застряли., @InBedded16

Я не вижу Serial.read() в вашем коде, поэтому я не понимаю вашей проблемы. Serial.read() возвращает -1, если читать пока нечего. Возвращает код символа (например, 49 == '1' ), если данные есть., @DataFiddler

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

Предполагая, что вы будете вводить эти инструкции вручную, помните, что мы, люди, гораздо медленнее Arduino, и пока вы не закончите вводить команду, микросхема будет считать её неполной. Пока команда не будет завершена, её анализ завершится неудачей. Вы можете проверить первый введённый символ и настроить светодиод, как вы описали, но он будет гореть на 50%, а затем, когда вы закончите вводить это значение, он достигнет своей максимальной яркости. Возможно, это то, что вам нужно, а может и нет..., @JRobert

Чтобы правильно прочитать числовое значение, вам потребуется собрать несколько символов из последовательного буфера, пока вы не обнаружите конец строки (например, '\n') или пробел., @liaifat85


3 ответа


Лучший ответ:

0

Вот небольшой псевдокод для того, что вы хотите сделать:

byte message = Serial.read()
if message == 'r', set red LED as one to change, else if 'g' for green, else if 'b' for blue
message = Serial.read()
double Value = message
message = Serial.read(), if message != '.', Value*= 10, value += message //если вы хотите разрешить значения больше 10
if message == '.', message = Serial.read, Value+= double(message/10) //повторите, если нужно больше знаков после запятой
A0_F/A1_F/A2_F *= Value
analogWrite(LED_R/LED_G/LED_B, A0_F/A1_F/A2_F)

Возможно, вы захотите добавить другие функции, например, проверку максимальных/минимальных значений и проверку недопустимых входных данных.

,

Использование Serial.parseFloat() может оказаться проще, чем ручной анализ числа., @Edgar Bonet


0

Похоже, вы смешиваете светодиод и потенциометры на одной плате Arduino, в таком случае последовательный порт вообще ни к чему. Так что, если вы хотите сделать то, что я ожидаю (локальное и удалённое управление), вам нужен цикл, в котором вы

  • Проверьте наличие Serial и прочтите его, если он доступен. Рекомендую прочитать строку (можно использовать пробел в качестве разделителя, но в конечном итоге это не будет очевидно для отладки), содержащую, например, R999, B77 или G09. В плавающих числах нет необходимости.
  • Проверьте наличие ощутимых изменений (например, более 50) на ваших потенциометрах/аналоговых входах. При изменении уровня измените Serial.print('R');Serial.println(RED), если хотите сообщить об этом другой стороне.

По вашей просьбе я намеренно не включаю полную программу, сделать это вам предстоит ;-)

,

0

Этот ответ не дает полного решения, но подталкивает вас в направлении, которое может сработать.

Ваш фрагмент кода почти то, что вам нужно. Просто замените SerialRead() на Serial.parseFloat(). Подробности в документации. Пожалуйста, прочтите её, всегда нужно знать, что вы используете.

if (Serial.read() == /* первый байт(символ)*/ r)
{
    float i = Serial.parseFloat(); /* но байты от 2-го пробела до конца переменной*/
}

Если вы введёте строку через Serial Monitor, она будет отправлена как целая строка. Пока вы не нажмёте Enter, ничего не будет отправлено.

Serial реализует поток. Это означает, что символы, считанные из потока, не будут доступны для последующих операций чтения. Поэтому вызов Serial.read() считывает ровно один символ, а следующий Serial.parseFloat() начинается со второго символа. По умолчанию он пропускает все символы, не являющиеся числами, но вы можете использовать аргумент lookahead, чтобы изменить это поведение.

Обратите внимание, что остальная часть строки после плавающего элемента не будет прочитана. Необходимо позаботиться об этом, например, прочитать все символы, включая конец строки.

Ещё одно замечание: поскольку вы хотите различать светодиоды по первому символу, кэшируйте первый символ в переменной, чтобы иметь возможность использовать несколько операторов if. Или рассмотрите возможность использования switch.

,