Пропадают символы при отправке по COM
- Войдите на сайт для отправки комментариев
Пт, 22/06/2018 - 10:42
При отправке через монитор набора символов, переодически (больше да, чем нет) пропадают символы.
Т.е. в отправку ушло 5, приехало 3, произвольных.
Куда копать не знаю.
#include <OLED_I2C.h>
OLED myOLED(SDA, SCL);
extern uint8_t SmallFont[];
extern uint8_t BigNumbers[];
#include <DS1307RTC.h>
#define TimeZone 60*60*4
#include <TimeLib.h>
int YEAR;
unsigned long UT;
String myChar="";
String myPrint="";
void setup(){
Serial.begin(9600);
myOLED.begin();
// myOLED.setFont(BigNumbers);
myOLED.setFont(SmallFont);
}
void loop(){
OLEDprint();
while (Serial.available()) {
char recived=Serial.read();
myChar+=recived;
}
}
//========================
void OLEDprint(){
tmElements_t tm;
UT=RTC.get()+TimeZone;
breakTime(UT,tm);
YEAR=tm.Year-30;
myOLED.clrScr();
myOLED.printNumI(tm.Day,9,10,2,'0');
myOLED.print(".",21,10);
myOLED.printNumI(tm.Month,25,10,2,'0');
myOLED.print(".",37,10);
myOLED.printNumI(YEAR,41,10);
myOLED.print(" ",58,10);
myOLED.printNumI(tm.Hour,65,10,2,'0');
myOLED.print(":",77,10);
myOLED.printNumI(tm.Minute,82,10,2,'0');
myOLED.print(":",94,10);
myOLED.printNumI(tm.Second,98,10,2,'0');
myOLED.print(String(myPrint),CENTER,30);
if (myChar!=""){
myPrint=myChar;
Serial.println(myChar);
myChar="";}
myOLED.update();
}
То же справедливо , для работы через bluetooth
Выглядит примерно так
Проверьте на Example code: https://www.arduino.cc/reference/en/language/functions/communication/ser...
Проверьте на Example code: https://www.arduino.cc/reference/en/language/functions/communication/ser...
Спасибо, ошибку понял.
Странно , что иногда все же полностью выводились посланные данные
При отправке через монитор набора символов, переодически (больше да, чем нет) пропадают символы.
Т.е. в отправку ушло 5, приехало 3, произвольных.
не отправляй почтой Роисси.
Странно , что иногда все же полностью выводились посланные данные
Иногда в Serial до момента считывания успевали залетать все данные.
Сделал так, вроде работает
#include <OLED_I2C.h> OLED myOLED(SDA, SCL); extern uint8_t SmallFont[]; extern uint8_t BigNumbers[]; #include <DS1307RTC.h> #define TimeZone 60*60*4 #include <TimeLib.h> int YEAR; unsigned long UT; String myChar=""; String myPrint=""; unsigned long readTime; void setup(){ Serial.begin(9600); myOLED.begin(); // myOLED.setFont(BigNumbers); myOLED.setFont(SmallFont); } void loop(){ OLEDprint(); if(Serial.available()){ delay(100); while (Serial.available()>0) { myChar+=(char)Serial.read(); delay(20); } } } //======================== void OLEDprint(){ tmElements_t tm; UT=RTC.get()+TimeZone; breakTime(UT,tm); YEAR=tm.Year-30; myOLED.clrScr(); myOLED.printNumI(tm.Day,9,10,2,'0'); myOLED.print(".",21,10); myOLED.printNumI(tm.Month,25,10,2,'0'); myOLED.print(".",37,10); myOLED.printNumI(YEAR,41,10); myOLED.print(" ",58,10); myOLED.printNumI(tm.Hour,65,10,2,'0'); myOLED.print(":",77,10); myOLED.printNumI(tm.Minute,82,10,2,'0'); myOLED.print(":",94,10); myOLED.printNumI(tm.Second,98,10,2,'0'); myOLED.print(String(myPrint),CENTER,30); if (myChar!=""){ myPrint=myChar; Serial.println(myChar); myChar="";} myOLED.update(); }Тоже не лучший вариант, но если вас устраивает...
Не помогло.
Такая же хрень .
В итоге, поставил таймер и функцию дисплея дисплея запускаю раз в секунду.
Так не глотает символы
Потому что не по-человечески делаете. Отсылаемая cтрока имеет определенную длину или терминатор типа '\n'?
Нет.
Просто когда появилось, что то в буфере, ждём какое то время и считываем все что есть в строковую переменную.
Потом передаём это в другую переменную, а первую обновляем.
Просто хочу универсальную функцию написать, чтоб каждый раз не менять длинну ввода.
Вот думаю, ограничение буфера надо прописывать, или без него можно обойтись.
Примерно так, если в буфере 60байт, удаляем все ждем новых данных.
//вот рабочий вариант #include <OLED_I2C.h> OLED myOLED(SDA, SCL); extern uint8_t SmallFont[]; extern uint8_t BigNumbers[]; #include <DS1307RTC.h> #define TimeZone 60*60*4 #include <TimeLib.h> int YEAR; unsigned long UT; String myChar=""; String myPrint=""; unsigned long readTime=0; void setup(){ Serial.begin(9600); myOLED.begin(); // myOLED.setFont(BigNumbers); myOLED.setFont(SmallFont); } void loop(){ while (Serial.available()>0) { myChar+=(char)Serial.read(); delay(20); } if(millis()-readTime>=1000){OLEDprint(),readTime=millis();} } //======================== void OLEDprint(){ if (myChar!=""){ myPrint=myChar; Serial.println(myChar); myChar="";} tmElements_t tm; UT=RTC.get()+TimeZone; breakTime(UT,tm); YEAR=tm.Year-30; myOLED.clrScr(); myOLED.printNumI(tm.Day,9,10,2,'0'); myOLED.print(".",21,10); myOLED.printNumI(tm.Month,25,10,2,'0'); myOLED.print(".",37,10); myOLED.printNumI(YEAR,41,10); myOLED.print(" ",58,10); myOLED.printNumI(tm.Hour,65,10,2,'0'); myOLED.print(":",77,10); myOLED.printNumI(tm.Minute,82,10,2,'0'); myOLED.print(":",94,10); myOLED.printNumI(tm.Second,98,10,2,'0'); myOLED.print(String(myPrint),CENTER,30); myOLED.update(); }Чтобы не менять длину ввода передавайте терминирующий символ. В примере Ethernet -> Webclient этот подход отлично проиллюстрирован.
Хочу в терминале , через блюпуп, меню организовать.
С возможностью добавления новых функций и подменю.
И как это меняет правильный подход к организации взаимодействия сторон, который продемонстрирован в вышеупомянутом примере?
Да никак, просто пока излишне это.
Кстати в WebClient нету такого.
Есть в WebServer
Умные дяди наступив на грабли обмена придумали протокол. Это позволило асинхронно передавать символы и не терять их. По сути вы наступаете на эти грабли опять и набив себе шишек опять придёте к протоколу, даже если "просто пока излишне это". Потом будет не излишно, даже если придумаете свой. Возьмите любой стандартный протокол обмена и ничего не будет теряться.
Чего вы все умные то такие ?
Я только изучаю.
Сейчас вот въехал в первый вариант передачи. На очереди следующий.
Постепенно надо изучать, от простого к сложному.
Лучше бы сказали, что во время while передача бесполезна, и сам цикл должен начинаться после того, как придут все данные.
Лучше бы сказали, что во время while передача бесполезна, и сам цикл должен начинаться после того, как придут все данные.
Не бесполезна. И не обязательно, когда придут все данные. Главное - понять, когда закончить прием и приступить к анализу.
Только вот проблема была не в этом, а в том что используемая библиотека работает, через прерывания.
Что в итоге и рвало цепочку.
Ну, как скажете. Только газовыми котлами не управляйте через блюпуп и свой скетч.
Упаси боже.