Пропадают символы при отправке по COM

Kakmyc
Offline
Зарегистрирован: 15.01.2018

При отправке через монитор набора символов, переодически (больше да, чем нет) пропадают символы.

Т.е. в отправку ушло 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();
   
}

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

То же справедливо , для работы через bluetooth

Выглядит примерно так

sadman41
Offline
Зарегистрирован: 19.10.2016
Kakmyc
Offline
Зарегистрирован: 15.01.2018

sadman41 пишет:

Проверьте на Example code: https://www.arduino.cc/reference/en/language/functions/communication/ser...

Спасибо, ошибку понял.

Странно , что иногда все же полностью выводились посланные данные

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Kakmyc пишет:

При отправке через монитор набора символов, переодически (больше да, чем нет) пропадают символы.

Т.е. в отправку ушло 5, приехало 3, произвольных.

не отправляй почтой Роисси. 

sadman41
Offline
Зарегистрирован: 19.10.2016

Kakmyc пишет:

Странно , что иногда все же полностью выводились посланные данные

Иногда в Serial до момента считывания успевали залетать все данные.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Сделал так, вроде работает

#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();
   
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Тоже не лучший вариант, но если вас устраивает...

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Не помогло.

Такая же хрень .

В итоге,  поставил таймер и функцию дисплея дисплея запускаю раз в секунду.

Так не глотает символы

sadman41
Offline
Зарегистрирован: 19.10.2016

Потому что не по-человечески делаете.  Отсылаемая cтрока имеет определенную длину или терминатор типа '\n'?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Нет. 

Просто когда появилось, что то в буфере, ждём какое то время и считываем все что есть в строковую переменную.

Потом передаём это в другую переменную, а первую обновляем.

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

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

Примерно так, если в буфере 60байт, удаляем все ждем новых данных.

Kakmyc
Offline
Зарегистрирован: 15.01.2018
//вот рабочий вариант

#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();
   
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Чтобы не менять длину ввода передавайте терминирующий символ. В примере Ethernet -> Webclient этот подход отлично проиллюстрирован.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Хочу в терминале  , через блюпуп, меню организовать.

С возможностью добавления новых функций и подменю.

sadman41
Offline
Зарегистрирован: 19.10.2016

И как это меняет правильный подход к организации взаимодействия сторон, который продемонстрирован в вышеупомянутом примере?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Да никак, просто пока излишне это.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Кстати в WebClient нету такого.

Есть в WebServer

nik182
Offline
Зарегистрирован: 04.05.2015

Умные дяди наступив на грабли обмена придумали протокол. Это позволило асинхронно передавать символы и не терять их. По сути вы наступаете на эти грабли опять и набив себе шишек опять придёте к протоколу, даже если "просто пока излишне это". Потом будет не излишно, даже если придумаете свой. Возьмите любой стандартный протокол обмена и ничего не будет теряться.   

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Чего вы все умные то такие ?

Я только изучаю.

Сейчас вот въехал в первый вариант передачи. На очереди следующий.

Постепенно надо изучать, от простого к сложному.

 

Лучше бы сказали, что во время while передача бесполезна, и сам цикл должен начинаться после того, как придут все данные.

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Kakmyc пишет:

Лучше бы сказали, что во время while передача бесполезна, и сам цикл должен начинаться после того, как придут все данные.

Не бесполезна. И не обязательно, когда придут все данные. Главное - понять, когда закончить прием и приступить к анализу.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Только вот проблема была не в этом, а в том что используемая библиотека работает, через прерывания.
Что в итоге и рвало цепочку.

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, как скажете. Только газовыми котлами не управляйте через блюпуп и свой скетч.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Упаси боже.