Hey everyone,
I'm using an Adafruit feather M0 with inbuilt rfm95 LoRa.
I'm taking data on my Tx from a BME280, converting the float values into integers and then putting those integer values into a char buffer through 'sprintf'.
on my Rx I'm receiving the values into a char buffer and then trying to convert them back into integers through 'sscanf' which will then be converted back to a float to be used.
This method worked on my old adafruit 32u4 radio but the m0 kicks out an error of:
"Compliation error: invalid conversion from 'uint8_t*' {aka 'unsigned char*'} to 'const char*' [-fpermissive]"
If the AVR boards have issues with sscanf, what is the best way to go about converting the received data into integers? I've seen 'atoi' and 'toint' but not sure if they have the capacity to do this.
Complete code:
// Libraries
#include <SPI.h>
#include <RH_RF95.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
// Rx Frequency
#define RF95_FREQ 433.0
// Assign Pins
#define RFM95_CS 8
#define RFM95_INT 3
#define RFM95_RST 4
unsigned const int vBattPin = A7,
bdLed = 13;
// Assign radio code, pins and values
RH_RF95 radio(RFM95_CS, RFM95_INT);
int16_t packetnum = 0; // Packetnumber counter
// Assign screen values
Adafruit_SH1107 disp = Adafruit_SH1107(64, 128, &Wire);
// Battery Declarations
float vBatt = 0;
// Timer Variables
unsigned long vBattStartTim = 0, // Voltage measurment timer
vBattCurrTim = 0;
unsigned const int vBattDelay = 5000;
unsigned long dispStartTim = 0, // Display Timer
dispCurrTim = 0;
unsigned const int dispDelay = 1000;
unsigned long ackStartTim = 0, // Acknowledgment Timer
ackCurrTim = 0;
unsigned const int ackDelay = 3000;
// Interger/Float Conversion Variables
unsigned int valInt = 0, // Interger to be converted
valDec = 0;
float valFlo = 0, // Final generated real number
valFrac = 0; // Decimal for float
// Rx Data Integer Variables
int vBattIntR = 0,
vBattDecR = 0,
//wSpeedIntR = 0,
//wSpeedDecR = 0;
tempIntR = 0,
tempDecR = 0,
humidIntR = 0,
humidDecR = 0,
pressIntR = 0,
pressDecR = 0,
altiIntR = 0,
altiDecR = 0;
// Rx data Float Variables
float //wSpeedR = 0,
vBattR = 0,
tempR = 0,
humidR = 0,
pressR = 0,
altiR = 0;
// Acknowledgement Variables
bool connected = false;
// Interger -> Float conversion
void genFlo()
{
valFrac = valDec * 0.01; // eg Int = 12, Dec = 75. 75 * 0.01 = 0.75
valFlo = valInt + valFrac; // 12 + 0.75 = 12.75
}
// LED reply blink
void blink(byte pin, byte delay_ms, byte loops)
{
while(loops--)
{
digitalWrite(pin, HIGH);
delay(delay_ms);
digitalWrite(pin, LOW);
delay(delay_ms);
}
}
void setup() {
// Init Serial
Serial.begin(115200);
delay(2000);
// Start Timers
vBattStartTim = millis();
dispStartTim = millis();
ackStartTim = millis();
// Declare pin modes
pinMode(RFM95_RST, OUTPUT);
// Pull radio reset pin low
digitalWrite(RFM95_RST, HIGH);
// Init Display
disp.begin(0x3C, true);
disp.display();
delay(1000);
disp.clearDisplay();
disp.display();
disp.setRotation(1);
// Manual reset of radio
digitalWrite(RFM95_RST, LOW);
delay(10);
digitalWrite(RFM95_RST, HIGH);
delay(10);
// Update
Serial.println("Serial init, pin init, display init, RFM reset");
// Hold program if radio fails
if (!radio.init())
{
Serial.println("RFM95 init failed!");
while(1);
}
Serial.println("RFM95 init ok!");
// Set Frequency
if (!radio.setFrequency(RF95_FREQ))
{
Serial.println("Frequency set failed!");
while(1);
}
Serial.print("Frequency set - "); Serial.println(RF95_FREQ);
// Set Power
radio.setTxPower(23, false); // Range from 14 - 20 power
// set Encryption
/*uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
radio.setEncryptionKey(key);*/
Serial.println("Init complete");
}
void loop() {
// Start Timers
vBattCurrTim = millis();
dispCurrTim = millis();
ackCurrTim = millis();
// Read and calculate Rx battery voltage every 5 second(s)
if (vBattCurrTim - vBattStartTim >= vBattDelay)
{
vBatt = analogRead(vBattPin);
vBatt *= 2;
vBatt *= 3.3;
vBatt /= 1024;
vBattStartTim = vBattCurrTim;
Serial.print("Rx voltage: "); Serial.print(vBatt); Serial.println("v\n");
}
// If disconnected for three seconds connected = false
/*if (ackCurrTim - ackStartTim >= ackDelay)
{
connected = false;
ackStartTim = ackCurrTim;
}*/
// listen for message, receive message.
if (radio.available()) // Listen
{
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN]; // Generate buffer for incoming data
uint8_t len = sizeof(buf); // Length of message
if (radio.recv(buf, &len)) // If message received
{
if (!len) return;
buf[len] = 0;
Serial.print("Received: ["); Serial.print(len); Serial.print("]: "); Serial.println((char*)buf);
Serial.print("RSSI: "); Serial.println(radio.lastRssi(), DEC);
connected = true;
// Put data from buffer and convert from char to integers through 'sscanf'
sscanf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", &vBattIntR, &vBattDecR, &tempIntR, &tempDecR, &humidIntR, &humidDecR, &pressIntR, &pressDecR, &altiIntR, &altiDecR);
// Send a reply
uint8_t data[] = "Data Received";
radio.send(data, sizeof(data));
radio.waitPacketSent();
Serial.println("Reply Sent");
blink(bdLed, 40, 3);
}
}
// Process recieved data every 1 second(s)
if (dispCurrTim - dispStartTim >= dispDelay)
{
// Convert Intergers to Floats
valInt = vBattIntR; valDec = vBattDecR; // Tx Battery Conversion
genFlo();
vBattR = valFlo;
/*valInt = wSpeedIntR; valDec = wSpeedDecR; // Windspeed Conversion
genFlo();
wSpeedR = valFlo;*/
valInt = tempIntR; valDec = tempDecR; // Temp Conversion
genFlo();
tempR = valFlo;
valInt = humidIntR; valDec = humidDecR;
genFlo();
humidR = valFlo;
valInt = pressIntR; valDec = pressDecR;
genFlo();
pressR = valFlo;
valInt = altiIntR; valDec = altiDecR;
genFlo();
altiR = valFlo;
// Print to serial
if (connected == true)
{
Serial.println("CONNECTED");
}
else
{
Serial.println("DISSCONNECTED");
}
Serial.print("Tx Voltage: "); Serial.print(vBattR); Serial.println("v");
Serial.print("Temp: "); Serial.print(tempR); Serial.println("C");
Serial.print("Humid: "); Serial.print(humidR); Serial.println("%");
Serial.print("Press: "); Serial.print(pressR); Serial.println("HPa");
Serial.print("Alti: "); Serial.print(altiR); Serial.println("m");
// Print to display
disp.clearDisplay(); disp.setTextSize(2); disp.setTextColor(SH110X_WHITE);
disp.setCursor(0,0); disp.print(tempR); disp.print("C");
disp.setTextSize(1); disp.setCursor(0,20);
if (connected == true)
{
disp.print("CONNECTED");
}
else
{
disp.print("DISSCONNECTED");
}
connected = false;
disp.setCursor(0,35); disp.print("RSSI: "); disp.print(radio.lastRssi(), DEC);
disp.setCursor(0,50); disp.print("Rx:"); disp.print(vBatt); disp.print("v ");
disp.print("Tx:"); disp.print(vBattR); disp.print("v");
float rssiLvl = (((radio.lastRssi()*-1)-27)/1.49);
int rssiLvlInt = rssiLvl;
disp.drawRect(115, 0, 10, 64, SH110X_WHITE);
disp.fillRect(116, rssiLvlInt, 8, 63-(rssiLvlInt), SH110X_WHITE);
disp.display();
dispStartTim = dispCurrTim;
}
}
Any advice would be awesome, many thanks.