Hi all,
I'm very new to Moteino and fairly new to arduino so bear with me, but I just can't seem to work out how to send a piece of unique data with my pair of Moteino LoRa modules.
I've got both modules powered up and programmed using the example programs, and they are happily sending "hello world!" and "And hello back to you" to each other and I can see this on the serial monitor.
My problem is I can't seem to work out how to swap the 'dumb' text for data that I can use in a program. My ultimate goal is to send gps coordinates, but for the moment I'm just trying to create a variable called 'data_to_send', and then send that variable across the link. But everything I try just give compile errors.
This is the code on the module with the gps:
// rf95_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messageing client
// with the RH_RF95 class. RH_RF95 class does not provide for addressing or
// reliability, so you should only use RH_RF95 if you do not need the higher
// level messaging abilities.
// It is designed to work with the other example rf95_server
// Tested with Anarduino MiniWirelessLoRa
#include <SPI.h>
#include <RH_RF95.h>
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#define FLASH_SS 23 // and FLASH SS on D23
#else
#define LED 9 // Moteinos have LEDs on D9
#define FLASH_SS 8 // and FLASH SS on D8
#endif
// Singleton instance of the radio driver
RH_RF95 rf95;
void setup()
{
Serial.begin(115200);
if (!rf95.init())
Serial.println("init failed");
else Serial.println("init OK - 915mhz");
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
rf95.setFrequency(915);
}
void loop()
{
Serial.println("Sending to rf95_server");
// Send a message to rf95_server
uint8_t data[] = "Hello World!";
rf95.send(data, sizeof(data));
rf95.waitPacketSent();
// Now wait for a reply
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (rf95.waitAvailableTimeout(3000))
{
// Should be a reply message for us now
if (rf95.recv(buf, &len))
{
Serial.print("got reply: ");
Serial.println((char*)buf);
Serial.print("RSSI: ");
Serial.println(rf95.lastRssi(), DEC);
}
else
{
Serial.println("recv failed");
}
}
else
{
Serial.println("No reply, is rf95_server running?");
}
Blink(LED,3);
delay(200);
}
void Blink(byte PIN, int DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
I've searched for hours and can't find anything that relates to my LoRa modules. I'm sure it's a simple fix, and if someone can reply with a well annotated reply, I'll be able to continue my learning how to code.
And I would give some examples of what I've tried, but as everything has failed, I doubt it will help haha.
Thanks
Dave
Dave,
The trick is in these 2 lines:
uint8_t data[] = "Hello World!";
rf95.send(data, sizeof(data));
Notice this is a c++ byte array that gets passed to the send() function, along with the length of that array - obtained by using sizeof(). This is short and sweet for hardcoded strings like "Hello World"
To define your own custom data, you will need to format your string into a byte array/buffer. I have a ton of such examples and how to deal with various types of data, if you just look in the RFM69 library examples (https://github.com/LowPowerLab/RFM69/tree/master/Examples).
The WeatherMote example (https://github.com/LowPowerLab/RFM69/blob/master/Examples/WeatherNode/WeatherNode.ino) probably suitable, look for these lines:
//variables used in formatting:
double P;
byte sendLen;
char Pstr[10];
char buffer[50]; //final byte array that gets passed to radio.send
.........
dtostrf(P, 3,2, Pstr); // format a double variable into a small string (byte array)
sprintf(buffer, "BAT:%sv F:%d H:%d P:%s", BATstr, weatherShield_SI7021.getFahrenheitHundredths(), weatherShield_SI7021.getHumidityPercent(), Pstr);
sendLen = strlen(buffer); //get the length of buffer
radio.send(buffer, sendLen); //finally pass the string (byte array) to the radio to send
sprintf (http://www.cplusplus.com/reference/cstdio/sprintf/) is where the magic happens. You can use this function to format your string using all kinds of variables. For simple types like integers you can use %d, for strings (byte arrays) you can use %s, the rest is just plain text.
Thanks Felix,
I've transposed your code into my LoRa sketch and it makes sense to me now, but I'm still getting a compile error of:
Arduino: 1.6.5 (Windows 7), Board: "Moteino"
v1_client_unadress.ino: In function 'void loop()':
v1_client_unadress:55: error: invalid conversion from 'char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]
In file included from v1_client_unadress.ino:11:0:
C:\Users\User\Documents\Arduino\libraries\RadioHead/RH_RF95.h:507:21: error: initializing argument 1 of 'virtual bool RH_RF95::send(const uint8_t*, uint8_t)' [-fpermissive]
virtual bool send(const uint8_t* data, uint8_t len);
^
invalid conversion from 'char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]
This is my code:
// rf95_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messageing client
// with the RH_RF95 class. RH_RF95 class does not provide for addressing or
// reliability, so you should only use RH_RF95 if you do not need the higher
// level messaging abilities.
// It is designed to work with the other example rf95_server
// Tested with Anarduino MiniWirelessLoRa
#include <SPI.h>
#include <RH_RF95.h>
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#define FLASH_SS 23 // and FLASH SS on D23
#else
#define LED 9 // Moteinos have LEDs on D9
#define FLASH_SS 8 // and FLASH SS on D8
#endif
// Singleton instance of the radio driver
RH_RF95 rf95;
//variables used in formatting:
byte sendLen;
char Pstr[10];
char buffer[50]; //final byte array that gets passed to radio.send
int data_to_send = 43;
void setup()
{
Serial.begin(115200);
if (!rf95.init())
Serial.println("init failed");
else Serial.println("init OK - 915mhz");
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
rf95.setFrequency(915);
}
void loop()
{
Serial.println("Sending to rf95_server");
// Send a message to rf95_server
// byte data[] = "hello";
// rf95.send(data, sizeof(data));
// dtostrf(P, 3,2, Pstr); // convert a double variable into a small string (byte array) (float variable to be read, length of string being created inc decimal point, number of digits after DP to print, array to store results)
sprintf(buffer, "%d", data_to_send);
sendLen = strlen(buffer); //get the length of buffer
rf95.send(buffer, sendLen); //finally pass the string (byte array) to the radio to send
rf95.waitPacketSent();
// Now wait for a reply
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (rf95.waitAvailableTimeout(3000))
{
// Should be a reply message for us now
if (rf95.recv(buf, &len))
{
Serial.print("got reply: ");
Serial.println((char*)buf);
Serial.print("RSSI: ");
Serial.println(rf95.lastRssi(), DEC);
}
else
{
Serial.println("recv failed");
}
}
else
{
Serial.println("No reply, is rf95_server running?");
}
Blink(LED,3);
delay(200);
}
void Blink(byte PIN, int DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
I changed radio.send to rf95.send (for the LoRa module), and created my own integer of 'data_to_send' for testing purposes. My ultimate goal is to send gps coordinates, but for the moment I'll settle with the number 43 haha.
My guess is that rf95.send doesn't like receiving either the buffer or sendlen, but as I've copied your code exactly complete with variable types, I don't understand why.
Piggy backing on this thread, I am having problems with the received data packet on the "server". If I send "123" the received message is "123*******" where the '*' are unrecognized characters in the serial monitor.
Client Code:
#include <SPI.h>
#include <RH_RF95.h>
#define FREQUENCY 434
#define FREQUENCY 915
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#define FLASH_SS 23 // and FLASH SS on D23
#else
#define LED 9 // Moteinos have LEDs on D9
#define FLASH_SS 8 // and FLASH SS on D8
#endif
// Singleton instance of the radio driver
RH_RF95 rf95;
byte sendLen;
char buffer[50]; //final byte array that gets passed to radio.send
void setup()
{
Serial.begin(115200);
if (!rf95.init())
Serial.println("init failed");
else { Serial.print("init OK - "); Serial.print(FREQUENCY); Serial.print("mhz"); }
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
rf95.setFrequency(FREQUENCY);
//rf95.setFrequency(915);
}
void loop()
{
Serial.println("Sending to rf95_server");
// Send a message to rf95_server
//uint8_t data[] = "Hello World!";
//rf95.send(data, sizeof(data));
int data_to_send = 123;
sprintf(buffer, "%d", data_to_send);
sendLen = strlen(buffer); //get the length of buffer
rf95.send((uint8_t *) buffer, sendLen); //finally pass the string (byte array) to the radio to send
rf95.waitPacketSent();
// Now wait for a reply
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (rf95.waitAvailableTimeout(3000))
{
// Should be a reply message for us now
if (rf95.recv(buf, &len))
{
Serial.print("got reply: ");
Serial.println((char*)buf);
Serial.print("RSSI: ");
Serial.println(rf95.lastRssi(), DEC);
}
else
{
Serial.println("recv failed");
}
}
else
{
Serial.println("No reply, is rf95_server running?");
}
Blink(LED,3);
delay(200);
}
void Blink(byte PIN, int DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
Server Code
#include <SPI.h>
#include <RH_RF95.h>
#define FREQUENCY 434
#define FREQUENCY 915
// Singleton instance of the radio driver
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#define FLASH_SS 23 // and FLASH SS on D23
#else
#define LED 9 // Moteinos have LEDs on D9
#define FLASH_SS 8 // and FLASH SS on D8
#endif
RH_RF95 rf95;
void setup()
{
pinMode(LED, OUTPUT);
Serial.begin(115200);
if (!rf95.init())
Serial.println("init failed");
else { Serial.print("init OK - "); Serial.print(FREQUENCY); Serial.print("mhz"); }
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
rf95.setFrequency(FREQUENCY);
}
void loop()
{
if (rf95.available())
{
// Should be a message for us now
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (rf95.recv(buf, &len))
{
digitalWrite(LED, HIGH);
// RH_RF95::printBuffer("request: ", buf, len);
Serial.print("got request: ");
Serial.println((char*)buf);
Serial.print("RSSI: ");
Serial.println(rf95.lastRssi(), DEC);
// Send a reply
uint8_t data[] = "And hello back to you";
rf95.send(data, sizeof(data));
rf95.waitPacketSent();
Serial.println("Sent a reply");
digitalWrite(LED, LOW);
}
else
{
Serial.println("recv failed");
}
}
}
How do I get the message to print correctly on the serial monitor without the extra characters?