Нагрузка
- Войдите на сайт для отправки комментариев
Добрый вечер. Помогите пожалуйста победить вывод данных по UART.
Уровень програмирования у меня базовый, поэтому прошу помощи на простом языке или толковую ссылку по теме.
Есть нагрузка:
XY-FZ25, которая позволят разряжать аккумуляторы и нагружать БП.
Также у нее есть UART (9600), по которому можно отправлять различные команды, при этом на некоторые из них, нагрузка, может прислать ответ:
При таком коде проблем нет:
#include <SoftwareSerial.h> //библиотека для подключения RX TX на порты с PWM, так как родные использую по USB. SoftwareSerial softSerial(5, 6); //обьявляю где мои rx\tx, виртуальный порт обзываю softSerial. void setup() { Serial.begin (9600); softSerial.begin (9600); softSerial.print("read"); //отправляю команду на нагрузку } void loop() { if (softSerial.available()){ //если приходит ответ по виртуальному uart char data = softSerial.read(); //ответ переводим в char, иначе пишет ерунду Serial.print(data); //выводим данные с виртуального на реальный uart. } }
Ответ нагрузки: OVP:25.2, OCP:4.05, OPP:25.50, LVP:01.5,OAH:0.000,OHP:00:00
Но запуск команды инициализирован до цикла, это просто как проверка что нагрузка умеет отвечать на команду.
Если отправлять команду в теле loop, то в ответ получаем кучу квадратов, знаков и т.д:
#include <SoftwareSerial.h> //библиотека для подключения RX TX на порты с PWM, так как родные использую по USB. SoftwareSerial softSerial(5, 6); //обьявляю где мои rx\tx, виртуальный порт обзываю softSerial. void setup() { Serial.begin (9600); softSerial.begin (9600); } void loop() { if (Serial.available()){ //запуск кода при условии что на встроенный порт что то придет softSerial.print("read"); //отправляю команду на нагрузку if (softSerial.available()){ //если приходит ответ по виртуальному uart char data = softSerial.read(); //ответ переводим в char, иначе пишет ерунду Serial.print(data); //выводим данные с виртуального на реальный uart. } } }
Ответ нагрузки: 5⸮⸮A⸮I j*g⸮05⸮AA&⸮$*'L5,⸮!⸮r⸮⸮.... и т.д. с паузами, при этом шлет и шлет. Так понимаю что это данные от нагрузки, что ей что то не нравится.
Частично вышел из ситуации, но не совсем понял что изменилось, разве что read теперь в отдельной функции:
#include <SoftwareSerial.h> //библиотека для подключения RX TX на порты с PWM, так как родные использую по USB. SoftwareSerial softSerial(5, 6); //обьявляю где мои rx\tx, виртуальный порт обзываю softSerial. void setup() { Serial.begin (9600); softSerial.begin (9600); } void loop() { if (Serial.available() && Serial.read() > 0){ //запуск кода при условии что на встроенный порт что то придет softSerial.print("read"); //отправляю команду на нагрузку } if (softSerial.available()){ //если приходит ответ по виртуальному uart char data = softSerial.read(); //ответ переводим в char, иначе пишет ерунду Serial.print(data); //выводим данные с виртуального на реальный uart. } }
Теперь при каждом вводе в serial, я получаю нужные мне данные. Но не могу встроить это в Switch-case:
#include <SoftwareSerial.h> //библиотека для подключения RX TX на порты с PWM, так как родные использую по USB. SoftwareSerial softSerial(5, 6); //обьявляю где мои rx\tx, виртуальный порт обзываю softSerial. byte val; void setup() { Serial.begin (9600); softSerial.begin (9600); } void loop() { if (Serial.available()){ val = Serial.parseInt(); switch (val) { case 1: Serial.println ("Vveli 1"); softSerial.write ("on"); break; case 2: Serial.println ("Vveli 2"); softSerial.write ("off"); break; case 3: softSerial.print ("read"); if (softSerial.available()){ //если приходит ответ по виртуальному uart char data = softSerial.read(); //ответ переводим в char, иначе пишет ерунду Serial.print(data); //выводим данные с виртуального на реальный uart. } break; default: Serial.println ("NE VERNO"); }}}
При каждом нажатии "3", выводится по одному символу от нагрузки. Почему не приходит вся строка?
Подскажите пожалуйста решение. Спасибо.
Потому что softSerial.read() читaет только один байт, а не все.
sadman41, спасибо за ответ. Почему оно тогда работает в варианте без Switch-case?
Чем можно заменить .read? Тут не нашел альтернатив.
А почему Вы решили, что нужно на что-то менять? Нужно просто грамотно использовать.
Сначала подробно напишите по русски, что и как, по-вашему, должно работать. А то создается впечатление, что Вы пытаетесь составить код не осмысленно, а методом тыка.
Задача иметь возможность отправлять на "нагрузку" различные команды. "on, off" - работают без проблем, так как ответ от устройства тут не нужен, но с получением данных траблы.
Для управления планирую кнопки, а может если ума хватит, прикручу энкодер. В связке с "нагрузкой" работает nano и TFT SPI экранчик, на котором буду отображать данные с ответа на команду "read", "start".
Сейчас сложность получить ответ от "нагрузки" при использовании Switch-case. Три дня читаю, вникаю... пока не осенило. Покажите где подсмотреть решение. Спасибо.
Писать за вас код я не буду, но вот вам наводящий вопрос: сколько раз выполняется loop() ?
sadman41, огромное спасибо. В case оставил только отправку команды на нагрузку, а в самом начале loop вывод того что есть на порте от нагрузки. Спасибо за помощь.
Вот ещё один хинт вместо read(): https://doc.arduino.ua/ru/prog/Serial/ReadBytesUntil
Думаю, что он сработает, SoftwareSerial же тоже наследник Stream. Только нужно взять буфер (char[NN]) с запасом и понять, какой терминатор у строки, которой отвечает девайс. Скорее всего это будет '\n'.
Спасибо, буду изучать.