Comunicación serial detiene mi código

Buenas tardes, espero me puedan ayudar un problema que tengo en un equipo, describo brevemente lo que tengo implementado:

Tengo un Arduino Mega que funciona como reloj utilizando paneles RGB, en el cual estoy utilizando los 4 puertos seriales para comunicar con distintos dispositivos. El serial para depuración, el Serial1 para conectar una impresora bluetooth, el Serial3 para recibir los datos desde otro dispositivo para poder igualar la hora de mi reloj.

Los inicializo así:

  Serial.begin(9600);
  Serial1.begin(115200); // IMPRESORA
 Serial3.begin(9600);  // IGUALADOR

El Arduino mega comanda unos módulos led RGB a manera de reloj con horas minutos y segundos. Esa parte la tengo trabajando correctamente, el problema se me presenta en el puerto Serial3, el cual utilizo para poder igualar la hora de mi reloj la cual la guardo en un módulo RTC.

  if (Serial3.available() > 0) {
    hora = Serial3.parseInt();
    minuto = Serial3.parseInt();
    segundo = Serial3.parseInt();
    Serial.print(hora);
    Serial.print(":");
    Serial.print(minuto);
    Serial.print(":");
    Serial.print(segundo);
    Serial.println();
  }

  if (hora != 0 && minuto != 0 && segundo != 0 ) {
    if (hora < 23 && minuto < 59 && segundo < 59 ) {
      rtc.adjust(DateTime(2019, 11, 11, hora, minuto, segundo));
    }
  }

Usando ese código logro igual el reloj, enviando los datos desde otro dispositivo mediante puerto serie usando un cable USB entre ellos, eso sí funciona, el módulo recibe los datos correctamente.

Mi problema se presenta al desconectar el cable USB dejo trabajando mi reloj y cada X minutos se congela lo mostrado en los paneles, porque detecta en el puerto Serial3 como si recibiera datos, pero en el monitor serie solo veo basura, aclaro que el cable está desconectado, no debería leer nada, pero esa basura hacer que el reloj se detenga por x seg y luego continúa trabajando con normalidad.

Intente colocando resistencias de 10k a modo de pulldown en los pines de comunicación serial, pero el problema persiste.

¿Se puede de alguna forma, hacer que la comunicación Serial no detenga la ejecución del código?

En realidad no me importa que llegue ruido por ese puerto, pero molesta que los segundos en el reloj se congelan por periodos de tiempo mientras este ruido se presenta.

Aclaro que probe cambiando fuentes de poder, cableado, incluso con otro arduino mega, pero el problema persiste.

mega

Pon el pin Rx en alto (la resistencia a 5V) sino al ponerlo a masa la UART interpreta que recibe todo el tiempo 0's (cuando no ruido que interpreta como 1's).

Cometí el mismo error comunicando algunos UNO por RS485 (ponía los pines Rx a masa cuando desconectaba los módulos) y me pasaba exactamente lo mismo (recibía datos inexistentes).

Por otro lado el pin Tx está en alto cuando no envía datos y se está generando una carga innecesaria con esa R a masa, es una salida por lo que no necesita la resistencia.

Desafortunadamente no publicaste tu código completo, pero da la impresión de que esta instrucción se ejecuta continuamente de forma incondicional:

Muchas gracias por la respuesta, voy a probarlo enseguida!

No coloqué todo el código, porque es largísima la parte del reloj >.<

Era para no saturar todo, pero tienes razón, esa línea está mal ubicada, voy a probar enseguida.

Muchas gracias por la respuesta.

Leíste las normas? Parece que no!!
Tu siempre coloca todo el código, no importa lo largo que sea (de todos modos no será algo que no se pueda visualizar), no creo que hayas inventado algo que desconozcamos. Además si supieras solucionarlo ya lo hubieras hecho y para nosotros ver todo el código nos permite tener otra idea de lo que pasa.

Mil disculpas, este es el codigo que estoy probando:

#include <Wire.h>
#include "RTClib.h"
#include <RGBmatrixPanel.h>

#define CLK  11   // USE THIS ON ARDUINO MEGA
#define OE   9
#define LAT 10
#define A   A0
#define B   A1
#define C   A2
#define D   A3
#define E   A5

RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false, 64);

#define MATRIX_HEIGHT 64
#define MATRIX_WIDTH 64


#define LED_BLACK           0

#define LED_RED_VERYLOW    (3 <<  11)
#define LED_RED_LOW        (7 <<  11)
#define LED_RED_MEDIUM     (15 << 11)
#define LED_RED_HIGH       (31 << 11)

#define LED_GREEN_VERYLOW  (1 <<  5)
#define LED_GREEN_LOW      (15 << 5)
#define LED_GREEN_MEDIUM   (31 << 5)
#define LED_GREEN_HIGH     (63 << 5)

#define LED_BLUE_VERYLOW     3
#define LED_BLUE_LOW         7
#define LED_BLUE_MEDIUM     15
#define LED_BLUE_HIGH       31

#define LED_ORANGE_VERYLOW (LED_RED_VERYLOW + LED_GREEN_VERYLOW)
#define LED_ORANGE_LOW     (LED_RED_LOW     + LED_GREEN_LOW)
#define LED_ORANGE_MEDIUM  (LED_RED_MEDIUM  + LED_GREEN_MEDIUM)
#define LED_ORANGE_HIGH    (LED_RED_HIGH    + LED_GREEN_HIGH)

#define LED_PURPLE_VERYLOW (LED_RED_VERYLOW + LED_BLUE_VERYLOW)
#define LED_PURPLE_LOW     (LED_RED_LOW     + LED_BLUE_LOW)
#define LED_PURPLE_MEDIUM  (LED_RED_MEDIUM  + LED_BLUE_MEDIUM)
#define LED_PURPLE_HIGH    (LED_RED_HIGH    + LED_BLUE_HIGH)

#define LED_CYAN_VERYLOW   (LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
#define LED_CYAN_LOW       (LED_GREEN_LOW     + LED_BLUE_LOW)
#define LED_CYAN_MEDIUM    (LED_GREEN_MEDIUM  + LED_BLUE_MEDIUM)
#define LED_CYAN_HIGH      (LED_GREEN_HIGH    + LED_BLUE_HIGH)

#define LED_WHITE_VERYLOW  (LED_RED_VERYLOW + LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
#define LED_WHITE_LOW      (LED_RED_LOW     + LED_GREEN_LOW     + LED_BLUE_LOW)
#define LED_WHITE_MEDIUM   (LED_RED_MEDIUM  + LED_GREEN_MEDIUM  + LED_BLUE_MEDIUM)
#define LED_WHITE_HIGH     (LED_RED_HIGH    + LED_GREEN_HIGH    + LED_BLUE_HIGH)

#define clear()          fillScreen(0)
#define show()           swapBuffers(true)
#define Color(x,y,z)     Color888(x,y,z)

RTC_DS3231 rtc;

#include <NewPing.h>

#define TRIGGER_PIN  A10  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     A11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 250 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.


// variables para almacenar la hora desde el gsm
char c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12;
int hora = 0;
int minuto = 0;
int segundo = 0;

int pulsador = A8;
int estado = 0;

int igualar = A9;
int estado_igualar = 0;

int indicador = 0;
byte second, minute, hour;
int fix = 0;

long horas = 0;
long minutos = 0;
long segundos = 0;
long decimales = 0;

long previousMillis = 0;        // will store last time LED was updated
long interval = 2000;           // interval at which to blink (milliseconds)

long d; //distancia en centimetros
int control = 0;
int encendido = 4;

////////////////////////////////////////////////////
unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000;  //the value is a number of milliseconds

void setup() {
  Serial.begin(9600);
  Serial1.begin(115200); // IMPRESORA
  Serial3.begin(9600);  // IGUALADOR
  // inicializar el Serial a los pines

  matrix.begin();
  // draw some text!
  matrix.setTextSize(1);     // size 1 == 8 pixels high
  matrix.setTextWrap(false); // Don't wrap at end of line - will do ourselves
  matrix.setCursor(0, 0);    // start at top left, with 8 pixel of spacing

  pinMode(TRIGGER_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  rtc.begin();
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2018, 4, 16, 10, 58, 20));
  }
  pinMode(pulsador, INPUT);
  pinMode(igualar, INPUT);
  pinMode(encendido, OUTPUT);

  startMillis = millis();  //initial start time

}

void loop() {
  rtc.begin();
  estado = digitalRead(pulsador);
  estado_igualar = digitalRead(igualar);

  DateTime now = rtc.now();
  hour = now.hour();
  minute = now.minute();
  second = now.second();

  Serial.print(hour);
  Serial.print(":");
  Serial.print(minute);
  Serial.print(":");
  Serial.println(second);

  Serial.print("estado_conteo: ");
  Serial.println(estado);

  Serial.print("estado_igualar: ");
  Serial.println(estado_igualar);

  if (estado == HIGH) {
    runClock();
  }
  if (estado == LOW) {
    conteo();
  }

  if (Serial3.available() > 0) {
    hora = Serial3.parseInt();
    minuto = Serial3.parseInt();
    segundo = Serial3.parseInt();
    Serial.print(hora);
    Serial.print(":");
    Serial.print(minuto);
    Serial.print(":");
    Serial.print(segundo);
    Serial.println();
    segundo = segundo + 2;

    if (hora != 0 && minuto != 0 && segundo != 0 ) {
      if (hora < 23 && minuto < 59 && segundo < 59 ) {
        rtc.adjust(DateTime(2018, 11, 11, hora, minuto, segundo));
        rtc.begin();
      }
    }
  }
}

void runClock()
{
  DateTime now = rtc.now();
  hour = now.hour();
  minute = now.minute();
  second = now.second();

  horas = now.hour();
  minutos = now.minute();
  segundos = now.second();

  currentMillis = millis();
  if (currentMillis - startMillis >= period)
  {
    matrix.clear();
    matrix.setTextSize(1.9);
    matrix.setRotation(0);
    matrix.setTextColor(LED_CYAN_HIGH);
    matrix.setCursor(0, 10);
    matrix.print(horas);
    matrix.print(":");
    matrix.print(minutos);
    matrix.setTextSize(2);
    matrix.setCursor(35, 9);
    if (segundos < 10) {
      matrix.print('0');
    }
    matrix.print(segundos);
    startMillis = currentMillis;
  }
}

void conteo()
{
  DateTime now = rtc.now();
  hour = now.hour();
  minute = now.minute();
  second = now.second();

  horas = now.hour();
  minutos = now.minute();
  segundos = now.second();

  // draw a pixel in solid white
  matrix.fillRect(28, 30, 4, 4, matrix.Color888(255, 255, 255));

  d = sonar.ping_cm();
  if (d == 0) {
    d = 500;
  }

  currentMillis = millis();  //get the current "time" (actually the number of milliseconds since the program started)
  if (currentMillis - startMillis >= period)  //test whether the period has elapsed
  {
    if (segundos <= 59) //Stop
    {
      matrix.clear();
      matrix.setTextSize(1.9);     //
      matrix.setRotation(0);
      matrix.setTextColor(LED_CYAN_HIGH);
      matrix.setCursor(0, 10);
      matrix.print(horas);
      matrix.print(":");
      matrix.print(minutos);
      matrix.setTextSize(2);
      matrix.setCursor(35, 9);
      if (segundos < 10) {
        matrix.print('0');
      }
      matrix.print(segundos);
      startMillis = currentMillis;

      if (d < 200) {
        if (control == 0) {
          horas = now.hour();
          minutos = now.minute();
          segundos = now.second();

          Serial1.print("Su tiempo es: ");
          Serial1.write(10);
          if (horas < 10) {
            Serial1.print('0');
          }
          Serial1.print(horas); // Horas
          Serial1.print(':');
          if (minutos < 10) {
            Serial1.print('0');
          }
          Serial1.print(minutos); // Minutos
          Serial1.print(':');
          if (segundos < 10) {
            Serial1.print('0');
          }
          Serial1.print(segundos); // Segundos
          Serial1.write(10);
          Serial1.write(10);
          control = 1;
        }
      }
    }
  }
}

La idea es que el panel tiene dos modos de trabajo:

  • En runClock(); funciona como un reloj comun y silvestre.
  • En conteo(); mediante un sensor de ultrasonido detecta si algo cruzó el sensor y envía ese tiempo a la impresora bluetooth.

Aclaro que todo esto funciona correctamente, el problema lo tengo cuando habilito la conexión serial para igualar la hora del reloj que se me presenta el problema que el ruido en el puerto serial congela el display y los segundos se quedan colgados por x tiempo y luego vuelve a trabajar normalmente.

¿Hicistes las modificaciones que te indiqué?

Te repito que si Rx está en bajo la UART interpreta que se están recibiendo datos.

No funcionó, cuando pongo el pin en alto, deja de recibir los datos por el puerto serial.

Con la R de 10K?!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.