idahowalker thanks.
I'll check that.
I don't think the code of post 1 etc is using the Sigfox.h library where read() is called in a loop to read the next byte
int SIGFOXClass::read() {
but some higher level library (which probably uses Sigfox.h) which returns the 8 bytes of data as a String, e.g. RX=7B FF 2C FF 2C FF FF 7D.
What library is being used in the code of post 1?
upload the complete code?
https://github.com/Thinxtra/Xkit-Sample
I've been using this example
OK a pointer to a character array; the number of bytes in that array is specified by RecvMsg -> len. What do you get when you print RecvMsg -> len?
#include <WISOL.h> //
#include <Tsensors.h> //
#include <Wire.h> //
#include <math.h> //
#include <SimpleTimer.h> //
#include <avr/wdt.h> //
#include <stdio.h>
//
Isigfox *Isigfox = new WISOL(); //
Tsensors *tSensors = new Tsensors(); //
I get a sequence of 3 and 2
This is like pulling teeth
Have you posted your full sketch as requested in the first reply to your original post ?
If so, then I missed it
No, I haven't posted yet. I'm putting it in now. Just a minute
/*
XKIT_WISOL_SIGFOX_V17 13FEB2023 - IJC PVM VERSION
Version 1.7
DOWNLINK: 7B | FF | 2C | FF | 2C | FF FF | 7D
{ | HZ | , | AL | , | TIME TX | }
UPLINK: 4E FF FF | 2C | 44 | FF | 2C | 42 | FF | 2C | 41 | FF
N ID | , | D | DIS | , | B | BAT | , | A | ALA
*********************************************************************************************************************************
*/
#include <WISOL.h> // OK *
#include <Tsensors.h> //
#include <Wire.h> //
#include <math.h> //
#include <SimpleTimer.h> //
#include <avr/wdt.h> //
#include <stdio.h>
//
Isigfox *Isigfox = new WISOL(); //
Tsensors *tSensors = new Tsensors(); //
SimpleTimer timer;
int watchdogCounter;
uint8_t buttonCounter;
uint8_t PublicModeSF;
uint8_t stateLED;
uint8_t ledCounter;
const uint8_t buttonPin = A1;
const int redLED = 6;
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// VAR & CONSTANTS FOR DOWNLINK // Payload > {FF,FF,FF FF}
const byte numChars = 8; //
char receivedChars[numChars]; // HazardZone: 1-255cm AlarmAck: 0-1 TimeToTX: 1-65535min
char tempChars[numChars]; // temporary array for use when parsing
boolean newData = false; //
char idFromServer[numChars] = {0}; // variables that arrives from SERVER [to hold the parsed data]
int hazardZoneLimit = 0; // Hazard Zone Parameter - default 20cm (200mm) - Hazard zone var
int alarmAck = 0; // Alarm acknoledge 0 - do nothing; 1 - unlatch flag of alarm - Alarm acknowledgment var
int timeFromServer = 1; // time from Kore to the next uplink in minutes - Range 1 to 65535min - Transmission time var
String buffTrans; // = {"7B FF 2C FF 2C FF FF 7D"}; // Buffer of transition
String hazardZone, alAck, tTTx;
String bufTest;
//
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//
uint8_t n = 78;
uint8_t d = 68;
uint8_t b = 66;
uint8_t a = 65;
uint8_t comma = 44;
uint16_t varID = 0;
uint8_t varDistance = 0;
uint8_t varBatt = 0;
uint8_t varAlarm = 0;
//
typedef union{
uint16_t number;
uint8_t bytes[2];
} UINT16id_t;
//---------------------------------------------------------------------------------------------------------------------------
void setup() { // SETUP ***********
Wire.begin();
Wire.setClock(100000);
Serial.begin(9600);
// Init watchdog timer
watchdogSetup(); //
watchdogCounter = 0;
// WISOL test
Serial.println(""); // Make a clean restart
delay(1000);
PublicModeSF = 0;
Isigfox->initSigfox();
Isigfox->testComms();
GetDeviceID(); //
// Init sensors on Thinxtra Module
tSensors->initSensors();
tSensors->setReed(reedIR);
buttonCounter = 0;
tSensors->setButton(buttonIR);
// Init LED
stateLED = 0;
ledCounter = 0;
unsigned long sendInterval = 600000; // Init timer to send a Sigfox message every 10 minutes
timer.setInterval(sendInterval, timeIR);
Serial.println(""); // Make a clean start
delay(1000);
} //.................. end Setup ...........................
//---------------------------------------------------------------------------------------------------------------------------
void loop() { // MAIN LOOP ****
//
varID = 65535;
varDistance = 255;
varBatt = 255;
varAlarm = 255;
//
timer.run();
wdt_reset();
watchdogCounter = 0;
} //.................. end loop ...........................
//------------------------- PAYLOAD ------------------------------------------------------------
//
void Send_Sensors(uint8_t n, uint8_t d, uint8_t b, uint8_t a, uint8_t comma, uint16_t varID, uint8_t varDistance, uint8_t varBatt, uint8_t varAlarm){
UINT16id_t iD;
iD.number = varID;
Serial.print("ID [n]: "); Serial.println(varID);
Serial.print("Distance [cm]: "); Serial.println(varDistance);
Serial.print("Battery Level [V]: "); Serial.println(varBatt);
Serial.print("Alarm Code: "); Serial.println(varAlarm);
//
const uint8_t payloadSize = 12; //in bytes
uint8_t buf_str[payloadSize];
buf_str[0] = n;
buf_str[1] = iD.bytes[1];
buf_str[2] = iD.bytes[0];
buf_str[3] = comma;
buf_str[4] = d;
buf_str[5] = varDistance;
buf_str[6] = comma;
buf_str[7] = b;
buf_str[8] = varBatt;
buf_str[9] = comma;
buf_str[10] = a;
buf_str[11] = varAlarm;
//
Send_Pload(buf_str, payloadSize); //
}
//---------------------------------------------------------------------------------------------------------------------------
void reedIR(){
Serial.println("Reed");
// timer.setTimeout(50, Send_Sensors); // send a Sigfox message after get out IRS I don't need
}
//---------------------------------------------------------------------------------------------------------------------------
void buttonIR(){
if (buttonCounter==0) {
timer.setTimeout(500, checkLongPress); // check long click after 0.5s
}
}
//---------------------------------------------------------------------------------------------------------------------------
void checkLongPress() {
buttonCounter++;
if ((buttonCounter < 4)) {
if (digitalRead(buttonPin) == 1) {
Serial.println("Short Press");
Send_Sensors (n, d, b, a, comma, varID, varDistance, varBatt, varAlarm); //
buttonCounter = 0;
} else {
timer.setTimeout(500, checkLongPress); // check long click after 0.5s
}
} else {
Serial.println("Long Press");
Serial.print ("Hazard Zone:" );
Serial.println (hazardZoneLimit);
Serial.print ("Alarm Ack:" );
Serial.println (alarmAck);
Serial.print ("Time to TX:" );
Serial.println (timeFromServer);
//
BlinkLED();
pinMode(redLED, OUTPUT);
buttonCounter = 0;
}
}
//-----------------------------------------------------------------------------------------------------------------------------
void BlinkLED() {
ledCounter++;
if (ledCounter<=6) {
if (stateLED == 0){
digitalWrite(redLED, HIGH);
stateLED = 1;
timer.setTimeout(200, BlinkLED);
} else {
digitalWrite(redLED, LOW);
stateLED = 0;
timer.setTimeout(200, BlinkLED);
}
} else {
pinMode(redLED, INPUT);
ledCounter = 0;
}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void timeIR(){ // Send payload using preset time
Serial.println("Sending for the Time");
Send_Sensors (n, d, b, a, comma, varID, varDistance, varBatt, varAlarm); // Send_Sensors(varID,varDistance,varBatt,varAlarm);
}
//
//*************************************************************************************************************************************************************************************
void getDLMsg(){ // Sigfox Downlink Payload *
recvMsg *RecvMsg;
int result;
RecvMsg = (recvMsg *)malloc(sizeof(recvMsg));
result = Isigfox->getdownlinkMsg(RecvMsg);
for (int i=0; i<RecvMsg->len; i++){
// Downlink string example RX=7B FF 2C FF 2C FF FF 7D
buffTrans = (RecvMsg->inData[i]); // { FF , FF , FF FF }
Serial.print (buffTrans); // {HazardZone, Alarm ack, Time to TX}
}
parseData();
Serial.println ("");
free(RecvMsg);
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void parseData() { // split the data into its parts
//
BlinkLED();
pinMode(redLED, OUTPUT);
//
// String rx = (buffTrans);
// int d[8]={0};
// sscanf(rx.c_str(),"RX=%2x%2x%2x%2x%2x%2x%2x%2x",&d[0],&d[1],&d[2],&d[3],&d[4],&d[5],&d[6],&d[7]);
// for(int i=0;i<8;i++) {
// Serial.print(d[i],HEX);
// Serial.print(rx);
// }
//
// hazardZone = buffTrans.substring (6,8);
// alAck = buffTrans.substring (12,14);
// tTTx = buffTrans.substring (18,23);
// Serial.print ("Hazard Zone: "); // Only for test. The data will be used in another part of the code
// Serial.println (hazardZone);
// Serial.print ("Alarm Ack: ");
// Serial.println (alAck);
// Serial.print ("Time to TX: ");
// Serial.println (tTTx);
}
// hazardZoneLimit = atoi(hazardZone.c_str());
// Serial.print ("Hazard Zone: ");
// Serial.println (hazardZoneLimit);
// Serial.println (" ");
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void Send_Pload(uint8_t *sendData, const uint8_t len){ //
recvMsg *RecvMsg;
RecvMsg = (recvMsg *)malloc(sizeof(recvMsg));
Isigfox->sendPayload(sendData, len, 0, RecvMsg); //
for (int i = 0; i < RecvMsg->len; i++) {
Serial.print(RecvMsg->inData[i]);
}
Serial.println("Enviou a mensagem para Backend");
free(RecvMsg);
//
Isigfox->sendPayload(sendData, len, 1); // If want to get non-blocking downlink message, use the following block instead ++++++
timer.setTimeout(46000, getDLMsg); //
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void GetDeviceID(){ //
recvMsg *RecvMsg;
const char msg[] = "AT$I=10";
RecvMsg = (recvMsg *)malloc(sizeof(recvMsg));
Isigfox->sendMessage(msg, 7, RecvMsg);
Serial.print("Device ID: ");
for (int i=0; i<RecvMsg->len; i++){
Serial.print(RecvMsg->inData[i]);
}
Serial.println("");
free(RecvMsg);
}
//===========================================================================================================================================================================================
void watchdogSetup(void) { // Enable watchdog timer
cli(); // disable all interrupts
wdt_reset(); // reset the WDT timer
// Enter Watchdog Configuration mode:
// IF | IE | P3 | CE | E | P2 | P1 | P0
WDTCSR |= B00011000;
WDTCSR = B01110001;
sei();
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void watchdog_disable() { // Disable watchdog timer
cli(); // disable all interrupts
WDTCSR |= B00011000;
WDTCSR = B00110001;
sei();
}
ISR(WDT_vect) // Watchdog timer interrupt.
{
// ################### Include your code here - be careful not to use functions they may cause the interrupt to hang and prevent a reset. ###############################
Serial.print("WD reset: ");
Serial.println(watchdogCounter);
watchdogCounter++;
if (watchdogCounter == 20) { // reset CPU after about 180 s
// Reset the CPU next time
// Enable WD reset
cli(); // disable all interrupts
WDTCSR |= B00011000;
WDTCSR = B01111001;
sei();
wdt_reset();
} else if (watchdogCounter < 8) {
wdt_reset();
}
}
It's 32, not alternating 3 and 2; and probably printed 32 times.
AT$SF ... ,1
is 32 characters.
But nowhere in your earlier posts was a mention of AT$SF And it does not seem to match the earlier text
RX=7B FF 2C FF 2C FF FF 7D
The AT code to send the message to the backend server is AT$SF. In the case here, I send it twice to guarantee, but the second time I send it with the ending ,1 to ask the server to send me the previously established downlink string.
therefore the content of the payload that I send does not correspond to the values 7B FF 2C FF 2C FF FF 7D which is the value that I receive from the backen
Guys, I need to leave my lab now for a meeting and I'll be back later. I greatly appreciate your help.
Thank you very much!
And that is what you're interested in
What I actually wanted you to do was
Serial.print(F("RecvMsg->len = "));
Serial.println(RecvMsg->len);
for (int i=0; i<RecvMsg->len; i++){
// Downlink string example RX=7B FF 2C FF 2C FF FF 7D
buffTrans = (RecvMsg->inData[i]); // { FF , FF , FF FF }
Serial.print (buffTrans); // {HazardZone, Alarm ack, Time to TX}
}
I forgot to mention that you don't seem to get a String (capital S) nor that yopu receive a c-string (nul-terminated character array) but just an array of characters.
So (spaces added for clarity)
'R' 'X' '=' '7' 'B' 'F' 'F' '2' 'C' 'F' 'F' '2' 'C' 'F' 'F' 'F' ' F' '7' 'D'
You can create a String object and add the received characters one-by-one to it in the for-loop.
String theData;
Serial.print(F("RecvMsg->len = "));
Serial.println(RecvMsg->len);
for (int i=0; i<RecvMsg->len; i++){
// Downlink string example RX=7B FF 2C FF 2C FF FF 7D
buffTrans = (RecvMsg->inData[i]); // { FF , FF , FF FF }
Serial.print (buffTrans); // {HazardZone, Alarm ack, Time to TX}
theData += (RecvMsg->inData[i]);
}
You can in that case use the substring method.
Or use a character array that is one byte bigger than RecvMsg->len
, fill it with '\0' and next add RecvMsg->inData[i]
. In that case you can use strstr() to find the FF
. It might be the better choice as you will not have the pitfalls of the String class.
I don't use Strings. I use char arrays with zero terminated text right in data. I address it with a pointer and process char by char.
if ( chr >= '0' && chr <= '9' )
{
val = chr - '0'; // ASCII 0 is 48 is '0'. Text is numbers that print as symbols.
}
else if ( chr >= 'A' && chr <= ''F' )
{
val = 10 + chr - 'A';
}
else
{
//not a number, maybe interpret RX= type identifiers here
}
``'
PS if you're going to do trig, use pre-calculated tables where possible for speed, Arduino floats are generally slow, trig values get generated..v.v.slow.
Hi guys.
as would say Mr. Schwarzenegger "I'm back"
I saw that you posted some interesting stuff here.
Thank you very much.
Well, I think I'm going to capture a part of my dreams tonight.
I'll be testing these concepts and getting back to you.
Thanks.
Hi guys,
the problem was solved. See below:
//*************************************************************************************************************************************************************************************
void getDLMsg(){ // Sigfox Downlink Payload *
recvMsg *RecvMsg;
int result;
RecvMsg = (recvMsg *)malloc(sizeof(recvMsg));
result = Isigfox->getdownlinkMsg(RecvMsg);
// Serial.print(F("RecvMsg->len = "));
// Serial.println(RecvMsg->len);
for (int i=0; i<RecvMsg->len; i++){
buffTrans = (RecvMsg->inData[i]);
Serial.print (buffTrans);
theData += (RecvMsg->inData[i]);
}
parseData();
Serial.println ("");
free(RecvMsg);
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void parseData() { // split the data into its parts
BlinkLED();
pinMode(redLED, OUTPUT);
//
(theData.substring (10,12)).toCharArray(hazardZone,3);
(theData.substring (16,18)).toCharArray(alAck,3);
ttx2 = theData.substring (22,27);
ttx2.replace(" ","");
ttx2.toCharArray(tTTx,5);
Serial.print ("Hazard Zone: ");
long transHZ = strtol(hazardZone,NULL,16);
Serial.println (transHZ);
Serial.print ("Alarm Ack: ");
long transAA = strtol(alAck,NULL,16);
Serial.println (transAA);
Serial.print ("Time to TX: ");
long transTX = strtol(tTTx, NULL,16);
Serial.println (transTX);
//
} // --> end function
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.