Xbee S2C Arduino --- TX--->PC

Hola amigos, pues he tenido un par de problemas a la hora de realizar una conexion entre Xbees y lo he publicado en este foro, bueno en el foro de ingles, seccion guia de proyectos, y pues bueno, he topado con personas increibles que me han ayudado.

Asi que, este codigo logra enviar por medio de TransmitRequest , los xbee en API modo 1, la hora y la fecha obtenidos directamente de un RTC DS1307. Hasta aqui todo bien.

Quiero hacerle unas actualizaciones, quiero que cuando yo corra el programa, este se espera hasta recibir una señal del xbee ubicado en la computadora, un TX sencillo, no tiene que llevar data, lo unico que quiero esque el Xbee del arduino y el arduino comiencen a enviar la hora y la fecha una vez que hayan recibid esta señal. Por decirlo de una manera sencilla, hasta que la PC indique que trabajen, ellos comienzan a trabajar.

El problema: bueno he querido utilizar un poco la libreria de andrewrapp pero como que no me ha solucionado del todo, y queria saber si alguien de aqui puede ayudarme.

#include <SafeString.h>
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <SoftwareSerial.h>

SoftwareSerial xbee(2, 3); //(Rx, TX)

byte packet1[] = {0x7E, 0x00, 0x21}; //Byte delimitador y Longitud de trama
byte packet2[] = {0x10, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x41, 0x4E, 0xF1, 0x24, 0xFF, 0xFE, 0x00, 0x00,}; //Id de trama, tipo de trama, direccion de 64bits, opciones y numero de brincos.

// 00:11:46 05/01/2021 == 19 chars
byte fullPacket[3 + 14 + 19 + 1];// (Delimitador + longitud )+ (tipo + direccion) + fecha + checksum = 37
// 
char buffer [25]; // 19 la fecha  +1  '\0', 25 bytes de tamaño

#define DEBUG SafeString::Output

void setup() {
  Serial.begin(9600);
  xbee.begin(9600);
  delay(2000);
  Serial.println();
  Serial.println("DS1307RTC convertir valores a HEX");
  Serial.println("-------------------");

  SafeString::setOutput(Serial);
  }

void loop() {
  tmElements_t tm;
  if (RTC.read(tm)) {
    sprintf(buffer, "%02d:%02d:%02d %02d/%02d/%04d", tm.Hour , tm.Minute, tm.Second, tm.Day, tm.Month, tmYearToCalendar(tm.Year));
    //sprintf(buffer, "%02d:%02d:%02d %02d/%02d/%04d", 5 , 6, 7, 8, 9, 2021);
    Serial.println(buffer); // con este print compruebo que la fecha y hora
    // build fullpacket
    size_t idx = 0;
    memmove(fullPacket + idx, packet1, sizeof(packet1));
    idx += sizeof(packet1);
    memmove(fullPacket + idx, packet2, sizeof(packet2));
    idx += sizeof(packet2);
    if ((idx + 19 + 1) > sizeof(fullPacket)) {
      // Si el tamaño es incorrecto
      Serial.println(F("fullPacket size wrong"));
    }
    memmove(fullPacket + idx, buffer, 19);
    idx += 19;
    // dejar un byte para el cheksum
    if ((idx + 1) != sizeof(fullPacket)) {
      // fullPacket size wrong
      Serial.println(F("fullPacket size wrong"));
    }

    int chksum = 0;
    for (size_t i = 3; i < idx; i++) { // comienza despues del tamaño dela trama
      chksum += fullPacket[i]; // comienza a sumar 
    }
    chksum = (0xff & chksum);
    chksum = (0xff) & (0xff - chksum);
    fullPacket[idx] = chksum;
    idx++; // El tamao total de la trama
    if (idx != sizeof(fullPacket)) {
      Serial.println(F("fullPacket size error"));
    }

    // Imprime el paquete
    size_t printSize = idx * 3; // ..<space>
    cSF(sfPacket, printSize);
    for (size_t i = 0; i < idx; i++) {
      //sfPacket += "0x";
      if (fullPacket[i] < 16) {
        sfPacket += '0'; 
      }
      sfPacket.print(fullPacket[i], HEX); 
      sfPacket.print(' ');
    }
    Serial.println(sfPacket);

    xbee.write (fullPacket , idx);   
    delay(10000);
  }
}
void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

Y cuál es el problema?
Ahora se envía la hora cuando se lee el RTC no bajo la orden de la Computadora.

Si claro, la parte del RTC y el envió de ahora y la fecha, funcionan perfectamente.

Simplemente quería agregar un loop antes de que comience a leer la fecha y hora,
y que este loop nada mas este preguntando/verificando si ha recibido una señal de inicio desde la computadora.

Y si no la ha recibido, que no mande nada.

Si lo quieres únicamente cuando enciendas el arduino puedes agregar un lazo en el setup() que verifique el estado del buffer serie, algo así

while(Serial.available() < 1);  // solo espera algún dato entrante, nada más
while(Serial.available() > 0) {  // quita del buffer los datos ya que son innecesarios
  char dummy = Serial.read();
}

Ten en cuanta que si no llega nada por el serial se queda ahí “clavado” esperando.

Saludos

Hola Gatul, gracias.

Ok bueno, talves me falto agregar algo mas.

Lo que estoy haciendo es mandar mensajes desde el arduino hasta la PC, por medio de Xbee. Yo puedo ver estos mensajes por medio del Software XCTU, este software es para Xbee y bueno ahi vizualizo las tramas que recibo desde el arduino. Pero asi mismo, puedo enviarle tramas al arduino desde el Xbee.

Mi idea es enviarle ese mensaje por el medio del xbee, como un mensaje en blanco, nada mas que el Xbee que esta en el arduino, detecte que ya la PC esta conectada y que ya puede enviarle mensajes.

Si, entendí la idea, por eso te consulté si el único momento en que se espera esa “señal” es en el arranque, de ser así, el final de setup() es el lugar indicado para ubicar esta secuencia…
Luego el puerto te queda libre para usarlo cuando lo desees, por eso es necesario dejar vacío el buffer de entrada.

En cuanto al puerto, para el Xbee usarás SoftwareSerial en lugar de Serial y listo.

Sin embargo, si tu idea es dejar el arduino encendido siempre y solo desconectarlo de la PC, habría que buscar otra forma de hacerlo porque tendría que ir en el loop()

Saludos

1 Like

Si claro, esa es la idea Gatul. Por el momento estoy realizando la programación en el Arduino para observar el funcionamiento de la programación, luego de esto, procedo a cargar el Sketch en el Microcontrolador ATMega 328 con el bootloader de arduino UNO.
Y de esta forma crear un sensor que espera la señal de inicio desde la compu, para que inicie sus mediciones.