Buenos dias compañeros
He realiazado este codigo para tomar el valor de un sensor y enviarlo por medio de una trama de dato utilizando XBee hacia una comutaodra.
El codigo que le presento a continuacion hace lo siguiente:
-
Primero Espera a recibir un simple mensaje, despues de recibirlo comienza a la programacion. Esto lo hice para sincronizar varios dispositivos, quiero colocarlos y que me envien informacion sin parar, una vez que le llegue el mensaje de inicio.
-
Luego llama al RTC para la hora y la fecha.
-
Siguiente Conforma el encabezado de la trama.
-
Luego toma del ADC el valor y lo convierte al valor real.
-
Luego empaqueta el hora y fecha y voltaje en la trama de datos .
-
Calcula el cheksum.
-
Envia la trama.
-
Guarda el voltage con la hora y la fecha.
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <SafeString.h>
#include <SoftwareSerial.h>
//DATALOGGER
const int chipSelect = 4;
//ADC
const int ADCpin = A0;
float voltPanel;
cSF(sfVolts,6);
//XBEE
SoftwareSerial XBeeSerial(2, 3); //(Rx, TX)
uint8_t Rx_nextByte;
#define START_DELIMITER 0x7E
//TRAMAS
byte packet1[] = {0x7E, 0x00, 0x27}; //Byte delimitador y Longitud de trama // variar por el voltaje
byte packet2[] = {0x10, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0xD7, 0xAE, 0xAD, 0xFF, 0xFE, 0x00, 0x00,}; //Id de trama, tipo de trama, direccion de 64bits, opciones y numero de brincos.
// xx.xx,00:11:46,05/01/2021 == 25 chars
byte fullPacket[3 + 14 + 25 + 1];// (Delimitador + longitud )+ (tipo + direccion)+ voltage + fecha + checksum = 37
// [3 + 14 + 4 + 19 + 1]
char buffer [27]; // 19 la fecha +1 '\0', 25 bytes de tamaño // cambiar porque hay voltaje
#define DEBUG SafeString::Output
//SETUP
void setup() {
Serial.begin(9600);
delay(100);
XBeeSerial.begin(9600);
delay(100);
// if (!SD.begin(4)) {
// Serial.println("initialization failed!");
//while (1);
//}
//Serial.println("initialization done.");
delay(2000);
Serial.println();
Serial.println("CODIGO PRINCIPAL");
Serial.println("-------------------");
SafeString::setOutput(Serial);
}
//LOOP
void loop() {
Serial.println("Espera a recibir señal");
while (XBeeSerial.available()) {
Rx_nextByte = XBeeSerial.read();
if (Rx_nextByte == START_DELIMITER){
//Inicia a mandar datos Si el primer Byte que recive de la PC es un 0x7E.
Serial.println("Señal recibida");
//RTC
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));
Serial.println(buffer); // Compruebo la fecha y hora actual.
//Inicializo un sumador de caracteres
size_t idx = 0;
memmove(fullPacket + idx, packet1, sizeof(packet1));
idx += sizeof(packet1);
memmove(fullPacket + idx, packet2, sizeof(packet2));
idx += sizeof(packet2);
if ((idx + 6 + 19 + 1) > sizeof(fullPacket)) {
Serial.println(F("1 Paquete completo esta mal."));
}
//float voltPanel= ((float(analogRead(ADCpin))*5.0/1023)*6+10, 2);//Obtengo del ADC el voltaje
//Realizo una operacion y = mx + b para obtener el valor real del Panel Fotovoltaico.
sfVolts.clear(); // remove last text //Voltage xx.xx == 5 y coma 1 == 6
sfVolts.print((float(analogRead(ADCpin))*5.0/1023)*6+10, 2,2,5); // "xx.xx" o " x.xx" o "-x.xx" o "xxx.x"
sfVolts.print(',');
memmove(fullPacket + idx, sfVolts.c_str(), 6); // Siempre van a ser 6 caracteres de largo
idx += 6;
if ((idx + 19 + 1) > sizeof(fullPacket)) {
Serial.println(F("2 Paquete completo esta mal."));
}
memmove(fullPacket + idx, buffer, 19);
idx += 19;
//Dejo un ultimo byte para tener el Checksum.
if ((idx + 1) != sizeof(fullPacket)) {
Serial.println(F("3 Paquete completo esta mal."));
}
//Se le da el formato al paquete completo
for (size_t i = 0; i < idx; i++) {
if (fullPacket[i] < 16) {
Serial.print('0');
}
Serial.print(fullPacket[i], HEX);
Serial.print(' ');
}
Serial.println();//Se comprueba que el formato de la Trama API.
XBeeSerial.write (fullPacket , idx);//Se envia la trama del sensor a la PC.
//DATALOGGER
String dataString = "";
dataString += String(voltPanel);
dataString += String(buffer);
File dataFile = SD.open("TensionDePanel.txt", FILE_WRITE);
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
delay(5000);
}
}
}
}
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
Serial.write('0');
}
Serial.print(number);
}
Pero tengo varios problemas.
-
Se usa mucha memoria. Quisiera que me ayuden con eso.
-
Cuando tomo el voltaje del ADC, a la hora de calcular el voltage real. No esta funcionado, me da un valor menor. Lo proble haciendo un codigo aparta y si funciona.
-
Cuando corro el programa y lo corro, se queda esperando a recibir la señal. Todo bien hasta ahi. Pero cuando le envio la señal, me logra enviar la primer trama. Luego de eso el codigo vuelve a caer en el loop. Lo cual esta mal.