Teensy with 4 or 5 wireless temperature sensors

Status
Not open for further replies.
FNIGNERS crossed ;)

I had more than fingers crossed mate & but it appears between all teh things we had crossed - it's done teh trick- looks like you've suceeded.

They're now working.!!!!!!

Thanks so much for your guidance, wisdom & patience.
Much appreciated.

No doubt I'll be back - so don't run away to far :)
 
Nice to hear that. Good on you to keep trying also, frustration can be a unpleasant experience but when you overcome the issues ... you should have forgotten all about it ;)
 
Nice to hear that. Good on you to keep trying also, frustration can be a unpleasant experience but when you overcome the issues ... you should have forgotten all about it ;)

..and good on you to keep persevering on your end too.

Im off to try & send soem reall data now.
Later!
 
Hi,

Any ideas how I would take the temperature value from senor (which is a float) but then send it as a string prefixed with some text.

ie Sensor reading = 23.25

So sent vlaue would be Sensor-A_23.25

I can send & receive a Float nps now.
But as i will hopefully be wanting the base unit to recieve temperature values from various other Tx modules - I was wanting teh received value to also identify the sending unit
 
I suggest looking up how to create a payload structure. The advantage of that is that you can send/receive this as a single variable with the data inside the payload.

This (see below) is for instance what I use as a payload, I suggest keeping the payload as simple as possible. I have a multitude of sensorpacks hanging around with different configurations (some only send temperature/battery, others send temperature/pressure or humidity). In your case I suggest adding an ID that corresponds to your individual sensor and then the temperature as a float. This has the advantage of keeping things nice and tidy and allows easy expansion.




Code:
typedef struct PayloadFrame {
        char msg; // messageformat 0x01 #0
	char msgdata0; // var1 that belongs to the message // sensortype #1
	char msgdata1; // var2 that belongs to the message //secondary data #2
	char Stext[4]; //#5678
	unsigned int data0; //#910
	char RSSI; //#11
	unsigned int msgNodeId; //#1213
	unsigned int data1; // maindata //#1415
	unsigned char DataUnit; //#16

} PayloadFrame; //#17bytes

static PayloadFrame In_Payload;  // receiving payload
static PayloadFrame Out_Payload; // sending payload


#define maxPayload sizeof(PayloadFrame)

And dont forget that the maximum payload for the NRF24L01+ is 32 bytes !!!
 
Best to send the float to the receiver, and let the receiver decide what string to put on the beginning of it.

The reason is that in software design, it's best to have each module responsible only for its own concerns. The sender should only care about sending the temperature. It should not know what the receiver does with it, or even that the receiver does anything with it.

Concrete example: Suppose you have 4 of these sensors, and you want to print something like "Node x: 12.4 degrees C". If all four nodes have that string format hard-coded, and you want to change even one character of it... you guessed it... you will be doing that four times. On the other hand, if the receiver is the only place that knows how to format the text, you only have to change it one time.

Always assume that the software has to change in the future, and that you want to make it as easy as possible to do so, and you will save yourself loads of trouble!
 
Best to send the float to the receiver, and let the receiver decide what string to put on the beginning of it.

The reason is that in software design, it's best to have each module responsible only for its own concerns. The sender should only care about sending the temperature. It should not know what the receiver does with it, or even that the receiver does anything with it.

Concrete example: Suppose you have 4 of these sensors, and you want to print something like "Node x: 12.4 degrees C". If all four nodes have that string format hard-coded, and you want to change even one character of it... you guessed it... you will be doing that four times. On the other hand, if the receiver is the only place that knows how to format the text, you only have to change it one time.

Always assume that the software has to change in the future, and that you want to make it as easy as possible to do so, and you will save yourself loads of trouble!

Thanks for your thoughts.
I understand what you are saying.
But I am storing all the reading Im getting on an SD card on the Base/Rx unit.
So its critical I know which reading came from which Sensor/Room.

As Im sure CorBee can confirm - my knowledge on this RF stuff is quite limited - this is my first dabble into it.
Im sure there will be more advanced techniques to sending & recieving the data which I may pick up on as time goes on.

I've thought of an intermediate step for now - which I think might work.
If I have 4 sensors say.
Then for sensor 1 - I'll add 1000 to the reading being sent
Sesnor 2 - add 2000
Sensor 3 - add 3000
Sensor 4 - add 4000.

Assuming an actual reading will always be in the range of +/- 50 deg C (not likely I know).
I can decode each Rx'd reading by its magnitude.

ie Sensor 1 will always be within 950 & 1050 & I can just subract 1000 to get actual reading
Sensor 2 will always be within 1950 & 2050 & I can just subract 2000 to get actual reading
Sensor 3 will always be within 2950 & 2050 & I can just subract 3000 to get actual reading
Sensor 4 will always be within 3950 & 4050 & I can just subract 4000 to get actual reading
 
Hi

By simply creating a payload
typedef struct PayloadFrame {
unsigned int NodeId;
float temperature;

} PayloadFrame;

static PayloadFrame Out_Payload;

Out_Payload.NodeId=1;
Out_Payload.temperature=20.1;

You can send all data you need and the formatting is -as pilot also stated - something better don in the receiver mode. Keep the data as simple as possible and you will see that it will be a lot easier to keep the project up to date. Dont start codeing an ID into data, its unclear and unnessesary.

At the receiver-end you will immediately see which Node has send data and can respond to that overthere.
 
Sorry - but the payload thing is a little unlcear to me at the moment.
Apprecite teh advice & I will look at it a little further down the line.

Also ref the code you ref'd in #57.
Am i missing something - but is there anything in the Rx code that guarentees that when
Code:
radio.read(&temp1, sizeof(temp1));
is called that it will always read what was sent from Tx1.
And similarly when
Code:
radio.read(&temp2, sizeof(temp2));
is called it will always read Tx2?
 
Hi,

You dont use temp1 or temp2 ... !

For the TX units:

start by declaring this structure
Code:
typedef struct {
unsigned int NodeId;
float temperature;

} PayloadFrame;
static PayloadFrame Out_Payload; //the variable used in sending data

As each unit (Node) needs to get a unique ID, I would use a const you need to declare:
Code:
unsigned int ID=1; // sets the unique ID

Then in your sending code:

Code:
Out_Payload.NodeId=ID;
Out_Payload.temperature=temperature; // store the float from the DS18B20 in the payload
radio.write( &Out_Payload, sizeof(Out_Payload) );

On your RX side:

you need the same structure declared (I made a common library for my setup) so
Code:
typedef struct {
unsigned int NodeId;
float temperature;

} PayloadFrame;
static PayloadFrame In_Payload; //the variable used in sending data

And then when data comes in you only need:
Code:
radio.read( &In_Payload, sizeof(In_Payload) );

In_Payload.NodeId will tell you which unit has send the data, and In_Payload.temperature will tell its temperature. Simple, easily to extend and also clear code.
 
:) yes they were 2 seperate statements - sorry.

1st one relating to teh payload.

2nd just a general question about that link you sent.
 
Additionally: You could consider using the unique ID of your DS18B20 sensors as the ID for each node. Ive done that too, this can make your TX code even simpler as you dont need a static declared ID for each unit you need to change before uploading. The ID of each DS18B20 can easily be read and has 8 bytes, in my sets I often see that many of the bytes in the 8byte ID are identical. But you could also simply use some of the bytes to create a unique ID.
 
Can I be really cheeky & ask for a response to teh 2nd part of #64 pls? (ref the code in ##57).

The pay load is not returning whats being send - so I'll put that on back burner for now.
 
Hi,

I suggest investing time in understanding what goes wrong with the payload. Thats the most logical coding, the earlier code was just an example.

Cor
 
If you share what you are receiving that might be helpfull in finding what goes wrong. The code used for sending/receiving should then also be shared.
 
Hi,

Sorry Didn't make a note of the ID that was being Recieved - but it was at least an 8 didgit number.
And it changed sometimes too.
Even though it was coded thus:
Code:
unsigned int ID = 2; // sets the unique ID
.

The Temp recieved was always reading 0.00.

Unfortunately I've removed that code from my project for now - as I need to try & capture a night's worth of data from the 3 units/sensors I've managed to get working (of a fashion).
I'll re-install again tomorrow & report back.

For now I used my un-favoured method I described earlier (cringe).
I'm getting 3 readings:
1 from from teh base unit (which doesnt need to be Tx & Rx'd)
1 from a remote unit - reading & Tx'ing the directl Sensor value
1 from a remote unit - reading value + 2000 then Tx'ing that. (Decoding at Rx'ing end).
 
Hi,

You cant have 8 digits in an unsigned int normally ... so something must have gone wrong in the code either when sending or reading.

Cor
PS just checked. The unsigned int should be 2 bytes and the float is 4 bytes on an arduino, so in total 6 bytes. But ... if you are receiving with a NON-arduino but a teensy you will need to make the type-definition of the structure more strictly.
 
Last edited:
I would suggest using uint16_t for 16 bit unsigned int, int16_t for signed 16 bit int, etc etc. And you'll have
to check endianness too - you might need to write marshalling/unmarshalling code if the endianness differs.
 
Status
Not open for further replies.
Back
Top