UART отваливается через продолжительное время постоянной работы, как лечить?

egor1855
Offline
Зарегистрирован: 24.10.2016

Имеем 2 дуины :

1 Arduino pro mini - передатчик (используя SoftwareSerial) постоянно передает значения без остановки.

2 Arduino UNO - приёмник, используя встроенный UART принимает байты от передатчика.

Всё хорошо работает. Но, спустя какое-то время, приёмник перестаёт что-либо принимать (постоянно горит светодиод L) и лечится только reset'om приёмника. При этом передатчик работает исправно сутками на софтварном сериал порту.

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

loop
...
Serial.begin(9600);
...
//эта сторока необходима, т.к. программные задержки не точны, а таким образом они более-менее синхронизируются и, пару верных значений успеваем принять до рассинхрона, потом сбрасываем соединение и устанавливаем заново.
while( (!Serial.available() ) && (j>0) ) {delay(100);if (j!=0) j--;}

while( (Serial.available() )   { 
обработка полученных значений
}


//если пр разборе получили "ересь", то разрываем соединение
Serial.flush();
Serial.end();

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

Вопрос: как лечить ? И можно ли программно "заресетить" UART ?

Sts
Offline
Зарегистрирован: 22.06.2015
У меня такое было, когда была утечка памяти. Запись за пределами массива[].
Компилятор тут бессилен. 


Может так :

Buffer[128];

loop {
....
int com = 0;
memset(Buffer,(char)0,128);
if (Serial.avaible() > 0 ) com = Serial.readBytes(Buffer,128);

readBytes - стоит на конце данных, пока не Timeout(). Т.е. Есть задержка по приему и вычистит весь RX.

А еще - flush(). Ждете, пока все исходящие отправятся ...?

А еще end() - а потом снова Serial.begin() ... как то :(( ... или есть еще Serial1/2 в теле.

egor1855
Offline
Зарегистрирован: 24.10.2016

Sts пишет:

Может так :
Buffer[128];
readBytes - стоит на конце данных, пока не Timeout(). Т.е. Есть задержка по приему и вычистит весь буфер.

Спасибо, попробую. Только UNO 63 байта только в буфере держит.

Sts пишет:

А еще - flush(). Ждете, пока все исходящие отправятся ...?

Да, это конечно уберу, языки перепутал, считал что оно буфер приёма очищает ) Но на ошибку никак не влияет .

Sts пишет:

А еще end() - а потом снова Serial.begin() ... как то :(( ... или есть еще Serial1/2 в теле.

Да, конечно Serial.begin() ... end() в цикле.

Serial1/2 нигде нет.

Сейчас так получаю из буфера :

char ch_temp='\0';

//...

while( (Serial.available() )   {      
        ch_temp=Serial.read();
        buf[i++]=ch_temp;
}
//...

переменная i ограничена числом 30. Но в буфере ещё остается 64-30=34 символа. Которые получаю в след цикле. Есть какая-нибудь команда по очистке буфера, или только выбирать моим или вашим способом ?

Sts
Offline
Зарегистрирован: 22.06.2015
#ifndef SoftwareSerial_h
#define SoftwareSerial_h

#include <inttypes.h>
#include <Stream.h>

/******************************************************************************
* Definitions
******************************************************************************/

#ifndef _SS_MAX_RX_BUFF
#define _SS_MAX_RX_BUFF 128 // RX buffer size
#endif

Это если нужен больше буфер и SoftSerial. так к слову

GSM+Serial - возвращает больше 64 байта. Это точно. (SMS) (?не уверен)

 

Serial.end() - отменяет прерывание для заполнения буффера этого Serial

На мой взгляд потом идет кусок мертвой зоны, до "UNO" не достучаться.

 

Дело в принципе хозяйское... Я всегда , если не Mega , делаю так :

#include </////>

Serial m_Serial();  

void setup()
{
 m_Serial.begin(9600);
}

void loop()
{
......

Пример с сайта :

Пример для Ардуино Мега:


// Arduino Mega пример использования всех 4 последовательных портов
// (Serial, Serial1, Serial2, Serial3),
// с разными скоростями:
 
void setup(){
  Serial.begin(9600);
  Serial1.begin(38400);
  Serial2.begin(19200);
  Serial3.begin(4800);
 
  Serial.println("Hello Computer");
  Serial1.println("Hello Serial 1");
  Serial2.println("Hello Serial 2");
  Serial3.println("Hello Serial 3");
}
 
void loop() {}

< вступать в спор не буду>

egor1855
Offline
Зарегистрирован: 24.10.2016

Sts, спасибо.

Поставил вывод объема памяти в loop  и заметил при обрыве(для теста искусственно выдираю провода)/ошибках уменьшалось по 2 байта. Нашел место где не убивалась временная переменная, исправил. Вот пол дня отработала - всё ОК.

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