I'm adapting a sketch I found to send sensor data over a wifi chip (Nrf2401), and although I get the message through, the value I send contains decimals (e.g. 24.59), but the received message will only be 24.
I'm sure there's something wrong on the transmitter part of the code, but I can't see what.
Here's my code:
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(4);
DallasTemperature sensors(&oneWire);
// ce,csn pins
RF24 radio(8,7);
// init data buffer to hold a sensor type byte and one uint16_t sensor data
unsigned char data[3] = {
0};
unsigned long count=0;
void setup(void)
{
sensors.begin();
Serial.begin(57600);
Serial.println("**************V1 Send Sensor Data***********");
radio.begin();
radio.setPALevel(RF24_PA_LOW);
radio.setChannel(0x4c);
// open pipe for writing
radio.openWritingPipe(0xF0F0F0F0E1LL);
radio.enableDynamicPayloads();
radio.setAutoAck(true);
radio.powerUp();
Serial.println("...Sending");
}
void loop(void)
{
sensors.requestTemperatures();
float currentTemp;
currentTemp = sensors.getTempCByIndex(0);
//assign 'T' to represent a Temperature reading
data[0] = 'T';
data[1] = currentTemp;
count++;
sprintf(data, "T %5.2f\n", currentTemp); // build command in data[]
radio.txMode(strlen(data)); // set # bytes to xmit
radio.write(data); // send bytes
// print and increment the counter
Serial.print("Temperature sent: ");
Serial.println(currentTemp);
// pause a second
delay(500);
}
In this example, when I print currentTemp, it will display the decimals, but if I print data[1], it won't.
What am I missing?
EDIT:
I've modified the code to include the answer from JRobert (updated code above), but it comes back the following error:
nrf24SendSensorDataV1_ino.cpp: In function 'void loop()':
nrf24SendSensorDataV1_ino:56: error: invalid conversion from 'unsigned char*' to 'char*'
nrf24SendSensorDataV1_ino:56: error: initializing argument 1 of 'int sprintf(char*, const char*, ...)'
nrf24SendSensorDataV1_ino:57: error: 'class RF24' has no member named 'txMode'
nrf24SendSensorDataV1_ino:57: error: invalid conversion from 'unsigned char*' to 'const char*'
nrf24SendSensorDataV1_ino:57: error: initializing argument 1 of 'size_t strlen(const char*)'
nrf24SendSensorDataV1_ino:58: error: no matching function for call to 'RF24::write(unsigned char [3])'
C:\Users\Zuh\Downloads\arduino-1.0.1\libraries\RF24L01/RF24.h:281: note: candidates are: bool RF24::write(const void*, uint8_t)
Any thoughts?
EDIT 2
I've made a dirty fix that will solve the issue.
In the transmitter code I've added:
uint16_t sensorValue = currentTemp*100;
//do the bit shift to put uint16 into uint8 array
data[1] = sensorValue >> 8;
data[2] = sensorValue;
// print and increment the counter
radio.write(data, sizeof(uint16_t)+1);
This will send the (temperature value)*100
On the receiver end, I just convert the uint16_t to a float element and divide it by 100.
uint16_t sensorValue = data[2] | data[1] << 8;
float temp = (float) sensorValue/100;
Serial.print("T: ");
Serial.println(temp);
Dirty, but effective!
Many thanks guys for the help, it really pointed me and my lousy programming skills to the right direction.
3 Answers 3
From the Arduino playground documentation for the Nrf2401 library, the .write method accepts either: a byte to transmit, a pointer to your unsigned char
buffer; or a void argument meaning use the library's internal buffer. You must have called the .txmode() method first.
Since you're trying to use your own buffer, you'll need to make it long enough to contain the message you want to transmit (plus one byte for the terminating NUL). You'll need a character representation of the value you want to send, not the binary number itself. At a quick read of the library doc I didn't see the message format the library wants, but assuming it's something like:
T<space>12.34<newline>
, you'll need something like this (untested, it may need tweaking)
sprintf(data, "T %5.2f\n", currentTemp); // build command in data[]
radio.txMode(strlen(data)); // set # bytes to xmit
radio.write(data); // send bytes
-
Ill test it tonite! Looks really good, thanks JRobert!!Eric Mitjans– Eric Mitjans2014年05月24日 16:19:58 +00:00Commented May 24, 2014 at 16:19
-
I've tested it and I get the following error:
nrf24SendSensorDataV1_ino:54: error: stray '\' in program nrf24SendSensorDataV1_ino.cpp: In function 'void loop()': nrf24SendSensorDataV1_ino:54: error: 'f5' was not declared in this scope nrf24SendSensorDataV1_ino:55: error: 'class RF24' has no member named 'txMode' nrf24SendSensorDataV1_ino:55: error: invalid conversion from 'unsigned char*' to 'const char*'
Eric Mitjans– Eric Mitjans2014年05月25日 00:40:45 +00:00Commented May 25, 2014 at 0:40 -
nrf24SendSensorDataV1_ino:55: error: initializing argument 1 of 'size_t strlen(const char*)' nrf24SendSensorDataV1_ino:56: error: no matching function for call to 'RF24::write(unsigned char [3])' C:\Users\Zuh\Downloads\arduino-1.0.1\libraries\RF24L01/RF24.h:281: note: candidates are: bool RF24::write(const void*, uint8_t)
Eric Mitjans– Eric Mitjans2014年05月25日 00:41:11 +00:00Commented May 25, 2014 at 0:41 -
I fixed a couple typos in the sprintf() format string that should clean up some of the errors; you'll have to make sure your data types match what the library's requirements, especially with regard to
const
qualifiers. Sorry, I don't have the part to be able to debug this.JRobert– JRobert2014年05月25日 12:14:18 +00:00Commented May 25, 2014 at 12:14 -
Updated question with your code. I'm using the RF24 library, maybe this interferes with it? Because the error mentions that 'class RF24' has no member named 'txMode'Eric Mitjans– Eric Mitjans2014年05月25日 12:31:26 +00:00Commented May 25, 2014 at 12:31
data[] is an array of three chars. You assign the letter "T" to data[0] (the first char of the array), then data[1] = currentTemp attempts to assign a float to the second char in the data array - floats won't fit in chars.
-
Hi Peter. I see! Is there any other way to send currentTemp using radio.write then? Thanks!!Eric Mitjans– Eric Mitjans2014年05月23日 16:28:30 +00:00Commented May 23, 2014 at 16:28
-
I'm not familiar with the radio.* functions you are using. In C, I'd use printf("%5.2f\n", currentTemp); The %5.2f" tells the print function that the variable is a float, and it should be formatted with two digits after the decimal.Peter Bennett– Peter Bennett2014年05月23日 18:21:34 +00:00Commented May 23, 2014 at 18:21
Since I can't comment yet I will place this as answer.
But have you tried to use radio.print(data[1], DEC);
?
DEC stands for Decimal for if you want to force something to print it in Decimals. When you want something to be printed in Hexadecimals you can use HEX for example. Hope this will help you.
-
This post is simply not true. Decimal and decimals are two entirely different things. He's missing the
.
decimal when sending the data.DEC
just specifies that the info given is presented in the decimal (base ten) system. This isn't related.Anonymous Penguin– Anonymous Penguin2014年05月23日 22:24:07 +00:00Commented May 23, 2014 at 22:24 -
The info given huh? Now I don't get it that I can simply make a calculator using arduino and print everything in DEC and HEX without writing a new calculation. All I do is printing it as DEC and or HEX. I would love to hear a more specific explanation about it cuz this is what I learned on my college.Handoko– Handoko2014年05月23日 22:38:17 +00:00Commented May 23, 2014 at 22:38
currentTemp
float value in thedata
unsigned char vector. How do you expect the 'data' vector to hold a float number?