Save HEX data in an array to send by Xbee

Hello Arduiforeros, good afternoon, my intention with this code is to obtain the Time and Date data from the RTC DS1307 and send it from an Xbee on the Arduino, to an Xbee on the PC and read it through the XCTU. This is a test because later on I would like to send a voltage value along with the time and date. I have a problem when viewing the characters in HEX mode because when I import the array the characters are not displayed.

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

SoftwareSerial xbee(2, 3);
char buffer [20];
char packet2 [40];
char varHex ;

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // Espero al serial
  delay(200);
  Serial.println("DS1307RTC convertir valores a HEX");
  Serial.println("-------------------");
}
void loop() {
  tmElements_t tm;
  if (RTC.read(tm)) {
    //Sprintf Crea una cadena tipo string 
    sprintf(buffer, "%02d:%02d:%02d %02d/%02d/%04d", tm.Hour, tm.Minute, tm.Second, tm.Day, tm.Month, tmYearToCalendar(tm.Year)); 
    Serial.println(buffer); // con este print compruebo que la fecha y hora
    
   //Pasar de ASCII a HEX 
   // Formato ASCII :00:11:46 1/5/2021  
   // Formato HEX : 30 30 3A 31 31 3A 34 36 20 7C 20 31 2F 35 2F 32 30 32 31 0D  
    for (int i=0; i<20; i++){
      varHex = (buffer[i], HEX);
      packet2[i] = varHex;
      Serial.println(buffer[i], HEX); // con este print compruebo que he convertido los caracteres a Hex
    }                                // Quisiera tener estos Hex como como el formato HEX para enviarlos por el serial del Xbe
  Serial.println(packet2); //Pero cuando los imprimo aqui argumentando que inicialice un array, me imprime otra cosa.
  //xbee.write (packet , sizeof(packet));  // Manda el mensaje al nodo PC 
  } 
  delay(10000);
}
  
void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

I have this result.

Just to clarify, you don't need to convert to HEX chars to send, just send the buffer.
If you really want to convert to HEX, try using my SafeString library available from the library manager

#include "SafeString.h"
. . . 
createSafeStringFromCharArray(sfPacket,packet2); // picks up packet2 size automatically
 for (int i=0; i<strlen(buffer); i++) {  // only process the chars we have
      if (buffer[i] < 16) {
         sfPacket += '0'; // add leading 0
       }
       sfPacket.print(buffer[i], HEX); // you can print to SafeStrings
       Serial.println(buffer[i], HEX); // con este print compruebo que he convertido los caracteres a Hex
}   
Serial.println(packet2); // now updated with hex values

Here is a complete sketch

#include "SafeString.h"

char buffer [25]; // 20 and a bit
char packet2 [40];  // using SafeString will ensure this does not overflow.


void setup() {
  Serial.begin(9600);
  for (int i = 10; i > 0; i--) {
    Serial.print(' '); Serial.print(i);
    delay(500);
  }
  Serial.println();
  Serial.println("DS1307RTC convertir valores a HEX");
  Serial.println("-------------------");
}

void loop() {
  // this is fragile!! make sure buffer is large enough or you code will crash.
  sprintf(buffer, "%02d:%02d:%02d %02d/%02d/%04d", 6, 23, 45, 5, 3, 2021);
  Serial.println(buffer); // con este print compruebo que la fecha y hora

  cSFA(sfPacket,packet2); // or long hand, createSafeStringFromCharArray(sfPacket, packet2); // picks up packet2 size automatically
  for (size_t i = 0; i < strlen(buffer); i++) { // only process the chars we have
    if (buffer[i] < 16) {
      sfPacket += '0'; // add leading 0
    }
    sfPacket.print(buffer[i], HEX); // you can print to SafeStrings
    Serial.println(buffer[i], HEX); // con este print compruebo que he convertido los caracteres a Hex
  }
  Serial.println(packet2); // now updated with hex values
  //xbee.write (buffer , sizeof(buffer));  // Manda el mensaje al nodo PC or sizeof(buffer)+1 if you want to send the terminating '\0'
  //}
  delay(10000);
}

Thanks Drmpf its works.

Hi DRmpf, first thanks for your help.

Well I have another 2 problems here.
1- with packet 3 I try to make this packet3 like this {0x10, 0x01, 0x00, 0x13,....} beacuse I want to see in my serial monitor. But when I use,

 sprintf(buffer, "%02d:%02d:%02d %02d/%02d/%04d", packet3);

doesnt work well.

2- I want to do a checksum of bytes from packet2 and packet3 (Data).
I have examples but I don't know how to implement them.

unsigned char
checksum (
    byte *pkt,
    int   size )
{
    unsigned char sum = 0;
    for (int i = 3; i < size-1; i++)
        sum += pkt [i];
    return 0xff - sum;
}

This my code

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

byte packet1[] = {0x7E, 0x00, 0x28}; //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.
byte packet4; //El checksum

char buffer [25]; // 25 and a bit
char packet3 [40];  // la trama de datos por mandar


void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
  Serial.println();
  Serial.println("DS1307RTC convertir valores a HEX");
  Serial.println("-------------------");
}
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));
    Serial.println(buffer); // con este print compruebo que la fecha y hora

    cSFA(sfPacket,packet3); 
    for (size_t i = 0; i < strlen(buffer); i++) { 
      if (buffer[i] < 16) {
      sfPacket += '0'; // add leading 0
    }
    sfPacket.print(buffer[i], HEX); // you can print to SafeStrings
    Serial.println(buffer[i], HEX); // con este print compruebo que he convertido los caracteres a Hex

    }     
  Serial.println(packet3); // I try to make this packet3 like this {0x10, 0x01, 0x00, 0x13,....} 
                          
  
  //xbee.write (packet1 , sizeof(packet1));    O los concateno y los mando juntos.
  //xbee.write (packet2 , sizeof(packet2));
  //xbee.write (packet3 , sizeof(packet3));
  //xbee.write (packet4 , sizeof(packet4));
  delay(10000);
  }}  //xbee.write (buffer , sizeof(buffer));  // Manda el mensaje al nodo PC or sizeof(buffer)+1 if you want to send the terminating '\0'```
    cSFA(sfPacket,packet3); 
    for (size_t i = 0; i < strlen(buffer); i++) { 
      if (buffer[i] < 16) {
      sfPacket += '0'; // add leading 0
    }
    sfPacket.print(buffer[i], HEX); // you can print to SafeStrings
    Serial.println(buffer[i], HEX); // con este print compruebo que he convertido los caracteres a Hex

    }    

Is not what you want to send hex via xbee. After this code packet3 is in ASCII not Hex. You want to send the original packet3
Or are you really wanting to send ASCII "0x10" instead of hex (decimal 8)

For checksum you need to know the length of the packet.
You can have a fixed length packet with space for 1 byte the check sum
OR you can have a '\0' terminated string with the checksum in a know location after the end of the string
OR you can have the first byte hold the length of the data (like Pascal strings) and the checksum following the end of the chars.

Edit -- where does the 0x00 come from in ?

0x10, 0x01, 0x00, 0x13

Going back one step.
I have not used XCTU, but it looks like it sends some header info and then just send plain text.
Correct me if I have that wrong.
If so then you don't want to convert packet 3 to a text string of "0x32 ... "
rather you just want to send the chars returned by sprintf
i.e. something like
Does this code give you the output you are looking for on the other end?
If not what comes out on XCTU?
Edit -- Not clear to me how the 'length' of the message is communicated to XTCU.
Can someone enlighten me?

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

byte packet1[] = {0x7E, 0x00, 0x28}; //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.
byte packet4; //El checksum

char buffer [25]; // 25 and a bit
char packet3 [40];  // la trama de datos por mandar


void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
  Serial.println();
  Serial.println("DS1307RTC convertir valores a HEX");
  Serial.println("-------------------");
}
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));
    Serial.println(buffer); // con este print compruebo que la fecha y hora

    // skip this stuff as it mucks up packet3
    //    cSFA(sfPacket,packet3);
    //    for (size_t i = 0; i < strlen(buffer); i++) {
    //      if (buffer[i] < 16) {
    //      sfPacket += '0'; // add leading 0
    //    }
    //    sfPacket.print(buffer[i], HEX); // you can print to SafeStrings
    //    Serial.println(buffer[i], HEX); // con este print compruebo que he convertido los caracteres a Hex
    //    }
    //  Serial.println(packet3); // I try to make this packet3 like this {0x10, 0x01, 0x00, 0x13,....}


    xbee.write (packet1 , sizeof(packet1));    O los concateno y los mando juntos.
    xbee.write (packet2 , sizeof(packet2));
    xbee.write (buffer , strlen(buffer));
    delay(10000);
  }
}

These two methods calculate and check check sums

#define DEBUG SafeString::Output

// calcuates the checksum to add to the end of textToSendPtr as 2 hex chars
void SerialComs::calcCheckSum(SafeString& msg, SafeString& chkHexStr) {
  chkHexStr.clear();
  if ((msg.isEmpty()) || (!(!notUsingCheckSum))) {
    return;
  }
  uint8_t chksum = 0;
  for (size_t i = 0; i < msg.length(); i++) {
    chksum ^= msg[i];
  }
  if (chksum < 16) {
    chkHexStr += '0';
  }
  chkHexStr.print(chksum, HEX); // add as hex
}

// removes checksum 2 hex chars at end of textToSendPtr
// calcuates checksum char for this message and compares them
bool SerialComs::checkCheckSum(SafeString& msg) {
  if (!(!notUsingCheckSum)) {
    return true; // don't check checksum
  }
  size_t len = msg.length();
  if (len < 3) {
    //DEBUG.print(F(" CheckSum failed for msg '")); DEBUG.print(*textReceivedPtr); DEBUG.println("'");
    DEBUG.print(F(" CheckSum failed -- "));
    DEBUG.print(F(" Need at least 3 chars in msg"));
    DEBUG.println();
    return false; // 2 Hex for checksum + at least one char for msg
    // empty lines don't have checksums
  }
  cSF(msgChksum, 2);
  msg.substring(msgChksum, len - 2, len);
  msg.removeLast(2);
  cSF(chksum, 2);
  calcCheckSum(msg, chksum); // calculate this msg checksum as two hex char
  if (chksum == msgChksum) {
    return true;
  } // else
//  DEBUG.print(F(" CheckSum failed for msg '")); DEBUG.print(*textReceivedPtr); DEBUG.println("'");
  DEBUG.print(F(" CheckSum failed -- "));
  DEBUG.print(F(" CheckSum Hex received '")); DEBUG.print(msgChksum); DEBUG.print("'");
  DEBUG.print(F(" calculated '")); DEBUG.print(chksum); DEBUG.print("'");
  DEBUG.println();
  return false; // check sum failed
}

Here is a complete sketch that adds the check sum to the end of the text part of the msg
Note it does not do a check sum on the header

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

byte packet1[] = {0x7E, 0x00, 0x28}; //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.

char buffer [25]; // 20 for date and + 2 for check sum +1 for terminating '\0' so 25 should be OK

#define DEBUG SafeString::Output

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
  Serial.println();
  Serial.println("DS1307RTC convertir valores a HEX");
  Serial.println("-------------------");
  // comment this line out to remove error msgs and debug output
  SafeString::setOutput(Serial); // for error msgs and debug
}

// calcuates the checksum to add to the end of textToSendPtr as 2 hex chars
void SerialComs::calcCheckSum(SafeString& msg, SafeString& chkHexStr) {
  chkHexStr.clear();
  if ((msg.isEmpty()) || (!(!notUsingCheckSum))) {
    return;
  }
  uint8_t chksum = 0;
  for (size_t i = 0; i < msg.length(); i++) {
    chksum ^= msg[i];
  }
  if (chksum < 16) {
    chkHexStr += '0';
  }
  chkHexStr.print(chksum, HEX); // add as hex
}

// removes checksum 2 hex chars at end of textToSendPtr
// calcuates checksum char for this message and compares them
bool SerialComs::checkCheckSum(SafeString& msg) {
  if (!(!notUsingCheckSum)) {
    return true; // don't check checksum
  }
  size_t len = msg.length();
  if (len < 3) {
    //DEBUG.print(F(" CheckSum failed for msg '")); DEBUG.print(*textReceivedPtr); DEBUG.println("'");
    DEBUG.print(F(" CheckSum failed -- "));
    DEBUG.print(F(" Need at least 3 chars in msg"));
    DEBUG.println();
    return false; // 2 Hex for checksum + at least one char for msg
    // empty lines don't have checksums
  }
  cSF(msgChksum, 2);
  msg.substring(msgChksum, len - 2, len);
  msg.removeLast(2);
  cSF(chksum, 2);
  calcCheckSum(msg, chksum); // calculate this msg checksum as two hex char
  if (chksum == msgChksum) {
    return true;
  } // else
  DEBUG.print(F(" CheckSum failed -- "));
  DEBUG.print(F(" CheckSum Hex received '")); DEBUG.print(msgChksum); DEBUG.print("'");
  DEBUG.print(F(" calculated '")); DEBUG.print(chksum); DEBUG.print("'");
  DEBUG.println();
  return false; // check sum failed
}

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));
    Serial.println(buffer); // con este print compruebo que la fecha y hora

    { // put this in { } to recover SafeString objects when finished with them
      // add checksum
      cSF(ckSum, 2); // a SafeString for the checksum
      cSFA(sfBuffer, buffer); // wrap buffer in a SafeString automatically picks up the buffer max size [25]
      calcCheckSum(sfBuffer, ckSum); // calculated checksum returned in SafeString ckSum
      // add check sum to buffer
      sfBuffer += ckSum;  // buffer now has check sum as ASCII HEX digits format on the end
      Serial.println(buffer);
    }

    xbee.write (packet1 , sizeof(packet1));    O los concateno y los mando juntos.
    xbee.write (packet2 , sizeof(packet2));
    xbee.write (buffer , strlen(buffer));
    delay(10000);
  }
}

Well the XCTU is the software that is used to configure the Xbees. Xbees have two ways of communicating on a network, this is the transparent mode and the API mode. I want to use API because this method uses a data frame to send the data.

The data frame is made up of several parts, first the delimiting byte 0x7E, second 2 bytes that represent the length of the data, third the data and the type of frame, the Frame ID and the 64-bit address of the xbee recipient, and fourth the checksum, the checksum is the The checksum is the sum of ALL bytes in the frame except the delimiting byte 0x7e and the two bytes of length.
The sum that is obtained, the least significant byte is extracted, the two numbers on the right for example, if the sum of 0x456, 56 is extracted. These are subtracted from 0xFF, that is, Checksum = FF-56.

The XCTU has the tool to be able to generate those data frames, and if I connect two Xbees to my computer I can send that data frame from Xbee A to Xbee B.

I used the XCTU frame generator to find out how my data frame is made up, in this case the "Transmit Request" frame.

My idea with the code is to generate that frame with the Arduino and send from the Arduino through an Xbee the time and date of the RTC, to the other Xbee connected to the computer and to be able to observe the time in the XCTU.

My logic for the program is the following, I know that the delimiter is always 0x7E, that the length of the data 00:11:46 05/01/2021 will not vary, so it is not necessary to take the length, I I already have the Frame ID 0x01, I already know the frame type "Transmit Request" 0x10 and the address of the recipient.

With the data, 00:11:46 05/01/2021 first I want to get it from the RTC, this data will be passed to HEX so that I can get the checksum.
And finally Add this data to the frame and at the end of the frame the checsum, to form the complete frame.

In the other hand we have the Xbee connect via USB to my computer and I use XCTU and see the Receive Packet, the receive packet it is the transmit request tha we send with the arduino. So when I open the frame I see the RF data and se the Hour.

Now you are thinking, how can you see a Receive packet if you have not been able to carry out the program (The program in which you are helping me), well what I used to check that if you can send a data frame from the arduino to the Xbee, this is :

#include <SoftwareSerial.h>

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

byte packet[] = {0x7E, 0x00, 0x28, 0x10, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x41, 0x4E, 0xF1, 0x24, 0xFF, 0xFE, 0x00, 0x00, 0x58, 0x58, 0x2E, 0x58, 0x58, 0x20, 0x30, 0x30, 0x3A, 0x31, 0x31, 0x3A, 0x34, 0x36, 0x20, 0x30, 0x31, 0x2F, 0x30, 0x35, 0x2F, 0x32, 0x30, 0x32, 0x31, 0x0D, 0x34};

//Copiamos la Trama de datos generada desde el software XCTU.
//7E 00 28 10 01 00 13 A2 00 41 4E F1 24 FF FE 00 00 58 58 2E 58 58 20 30 30 3A 31 31 3A 34 36 20 30 31 2F 30 35 2F 32 30 32 31 0D 34

//Datos a enviar
//XX.XX 00:11:46 01/05/2021

void setup (){
  Serial.begin(9600);
  xbee.begin(9600);
  delay (1000);
  Serial.println("La primer prueba de envio de informacion del sensor hacia la computadora :");
  }
  
void loop () {
  xbee.write (packet , sizeof(packet));

  delay(3000);
  
  }  

I proceed to explain this code, well what happens here is that I take the plot generated by the XCTU and put it in the PACKET and gave it the format, because that is how I saw it on YouTube. And well, I ran the program and voila.
With this program confirm that the frame has to be sent complete.
If the checksum is wrong, the frame is not delivered.

@drmpf I have this message when I run the program.
image

And It seems to me that when it comes to removing the Checksum, it does not take packet2 into consideration.

You correct me if it is not true.

Yes ignore that. SerialComs is not in the Arduino Library manager version at the moment and in any case the checksum calc is different to the one you describe.
I am working on a sketch at the moment, but the check sum is not correct :frowning:

here the test code I have at the moment
checking the result against this website
Switching to API mode

but the checksum is not correct :frowning:

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

//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];// (start + length) + (type+address) + date + checksum = 37
// length of data, including mode and address but witout checksum
// without checksum length is 33 = 0x21


//char buffer [25]; // 19 for date  +1 for terminating '\0' so 25 should be OK

byte packet1[] = {0x7E, 0x00, 0x1B};
byte packet2[] = {0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,}; //Id de trama, tipo de trama, direccion de 64bits, opciones y numero de brincos.
byte fullPacket[35]; // > 30
char buffer[] = "Hello, world!";

#define DEBUG SafeString::Output

void setup() {
  Serial.begin(9600);
  for (int i = 10; i > 0; i--) {
    Serial.print(' '); Serial.print(i);
    delay(500);
  }
  Serial.println();
  Serial.println("DS1307RTC convertir valores a HEX");
  Serial.println("-------------------");
  // comment this line out to remove error msgs and debug output
  SafeString::setOutput(Serial); // for error msgs and debug
}


void loop() {

  //tmElements_t tm;
  //if (RTC.read(tm)) {
  if (1) {
    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);
    memmove(fullPacket + idx, buffer, strlen(buffer));
    idx += strlen(buffer);

    // should have just one byte left for check sum
    if ((idx + 1) >= sizeof(fullPacket)) {
      // fullPacket size wrong
      Serial.println(F("fullPacket size wrong"));
    }

    uint8_t chksum = 0;
    for (size_t i = 3; i < idx; i++) { // skip frame start and length, stop before last byte (the checksum
      chksum += fullPacket[i]; // will wrap around
      Serial.println(chksum);
    }
    chksum = 0xff - chksum;
    fullPacket[idx] = chksum;
    idx++;


    // print out packet
    size_t printSize = sizeof(fullPacket) * 5; // 0x..<space>
    cSF(sfPacket, printSize);
    for (size_t i = 0; i < idx; i++) {
      sfPacket += "0x";
      if (fullPacket[i] < 16) {
        sfPacket += '0'; // add leading 0
      }
      sfPacket.print(fullPacket[i], HEX); // you can print to SafeStrings
      sfPacket.print(' ');
    }
    Serial.println(sfPacket);

    //    xbee.write (fullpacket , sizeof(fullpacket));    O los concateno y los mando juntos.
    delay(10000);
  }
}
1 Like

this code works, compared to
Calculating the Checksum of an API Packet

#include <SafeString.h>
uint8_t testPacket[] = {0x7E, 0x00, 0x0A, 0x01, 0x01, 0x50, 0x01, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x00};

#define DEBUG SafeString::Output

void setup() {
  Serial.begin(9600);
  for (int i = 10; i > 0; i--) {
    Serial.print(' '); Serial.print(i);
    delay(500);
  }
  Serial.println();
  Serial.println("test check sum");
  Serial.println("-------------------");
  // comment this line out to remove error msgs and debug output
  SafeString::setOutput(Serial); // for error msgs and debug
}

void loop() {
  int chksum = 0;
  size_t idx = sizeof(testPacket) - 1; // last byte is for check sum
  for (size_t i = 3; i < idx; i++) { // skip frame start and length, stop before last byte (the checksum
    chksum += testPacket[i]; // will wrap around
  }
  chksum = (0xff & chksum);
  chksum = (0xff) & (0xff - chksum);
  testPacket[idx] = chksum;
  idx++;


  // print out packet
  size_t printSize = sizeof(testPacket) * 5; // 0x..<space>
  cSF(sfPacket, printSize);
  for (size_t i = 0; i < idx; i++) {
    sfPacket += "0x";
    if (testPacket[i] < 16) {
      sfPacket += '0'; // add leading 0
    }
    sfPacket.print(testPacket[i], HEX); // you can print to SafeStrings
    sfPacket.print(' ');
  }
  Serial.println(sfPacket);
  while (1);
}
1 Like

Let me check with those links you send to me.

Try this sketch

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

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];// (start + length) + (type+address) + date + checksum = 37
// length of data, including mode and address but witout checksum
// without checksum length is 33 = 0x21

char buffer [25]; // 19 for date  +1 for terminating '\0' so 25 should be OK

#define DEBUG SafeString::Output

void setup() {
  Serial.begin(9600);
  for (int i = 10; i > 0; i--) {
    Serial.print(' '); Serial.print(i);
    delay(500);
  }
  Serial.println();
  Serial.println("DS1307RTC convertir valores a HEX");
  Serial.println("-------------------");
  // comment this line out to remove error msgs and debug output
  SafeString::setOutput(Serial); // for error msgs and debug
}


void loop() {

  //tmElements_t tm;
  //if (RTC.read(tm)) {
  if (1) {
    // 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)) {
      // fullPacket size wrong
      Serial.println(F("fullPacket size wrong"));
    }
    memmove(fullPacket + idx, buffer, 19);
    idx += 19;
    // should have just one byte left for check sum
    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++) { // skip frame start and length, stop before last byte (the checksum
      chksum += fullPacket[i]; // will wrap around
    }
    chksum = (0xff & chksum);
    chksum = (0xff) & (0xff - chksum);
    fullPacket[idx] = chksum;
    idx++; // the total length of the full packet
    if (idx != sizeof(fullPacket)) {
      Serial.println(F("fullPacket size error"));
    }

    // print out packet
    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'; // add leading 0
      }
      sfPacket.print(fullPacket[i], HEX); // you can print to SafeStrings
      sfPacket.print(' ');
    }
    Serial.println(sfPacket);

    //    xbee.write (fullpacket , idx);    O los concateno y los mando juntos.
    delay(10000);
  }
}


I going to try send.


I don't know why this happens. I initialized xbee in the header and set the xbee baud to 9600.

No.
You want to send the bytes in fullpacket NOT the string chars in sfPacket

xbee.write (fullpacket , idx); O los concateno y los mando juntos.

sfPacket is for debug printing ONLY, not for sending

Its working Great, thanks A LOT