Teensy with 4 or 5 wireless temperature sensors

Status
Not open for further replies.

bossredman

Well-known member
Hi wondering if anyone can point me in right directions pls.

I was thinking a trying to record temperature data in 4 or 5 rooms in my house at the same time over a period of a few weeks or so.

Is it possible for a Teensy to accept temperature readings from say 4 or 5 wireless temperature sensors?

If so:

what Teensy would do this? (ie currently have 3.2 & 3.6)
what extra HW is required. (make/model suggestions would be most welcome).
Is there a limit of the number of sensors that could be used.

As this is just for a few weeks or so would prefer not to spend £'s & £'s.

Thanks
 
Hi,

One of the easiest ways to achieve this is to use NRF24L01 RF transceivers. There's loads of code out there that show how to send/receive data with these. For each room you need a temperaturesensor(eg DS18B20)+MCU+NRF24L01 and a set of batteries. In my house I am using NRF24L01 with MSP430 chips, a single DS18B20 and 2 AA batteries. Sending data every 2 minutes or so these units run for months on rechargables (ENELOOP). Your basestation (any Teensy or other MCU) also needs an NRF24L01 to listen to the signals, but its all rather simple and easy to build.

cheers
Cor
 
Tanks Cor for the swift response & useful info.

How many do you have running at once?

Do you have any more info pls on your particular setup pls.

Excuse my ignorance but how does the Sensor RF tansceiver & teh MCU (MSP430) got together.
As when I googled MSP430 they just see, to be chips.
 
Hi,

I have >10 running at the moment. I combined the MSP430 and the NRF24L01 on a small perfboard and the DS18B20 is on the same perfboard. I got MSP430G2553 chips from a time that TI was more or less giving them away in promoting their MSP430 launchpads. These chips are easy to use for this purpose and can be mounted on a dual-DIP slot. If you want to keep it cheap you probably can use an atmel chip (simplest arduino) as they are often a lot cheaper. You can also use arduino (or clone) boards like the nano (see https://www.seeedstudio.com/blog/2019/11/21/nrf24l01-getting-started-arduino-guide/). In my setup the temperature-sensors read temperature en battery-value every 2 minutes, send the data via NRF24L01 and go to sleep. I have not tried to make the sensors listen to an acknowledgement or so, its a simple "shoot and forget" operation for the sensors. My base-station collects incoming data from the NRF24L01 and sends this via serial to a linux-machine (Orange PI) which takes care of storage(influxdb) and dashboards (grafana).

Takes time to get sometime usefull but its not difficult to build a transmitter/receiver and send data around. But you need a bit of hardware and software skills (I am not trained).

Cor
P.S. this comes even closer to a full design https://www.elec-cafe.com/nrf24l01-wireless-temperature-monitoring-ds18b20-arduino-uno/
 
So managed to get teh Teensy 3.6 reading Temp vlaues from sensor.

I also manged do the same with a Nano.

SO moved onto installing the NRF24L01+'s on both T3.6 (Rx) & Nano (Tx).

All i ever get is "nan" on the Recieving T3.6.

Spent all afternoon trying various thing & nothing.

Is teh "Nan" value an indication of anything specific?
 
Hi,

NaN stands for " Not a number " and could be that there is something in the format of the data you are receiving ("." or "," as decimal separator for instance). Try printing the data not as a number but as a string ?

And ... share your code for both TX and RX so we can have a look at it.
 
So managed to get teh Teensy 3.6 reading Temp vlaues from sensor.

I also manged do the same with a Nano.

SO moved onto installing the NRF24L01+'s on both T3.6 (Rx) & Nano (Tx).

All i ever get is "nan" on the Recieving T3.6.

Spent all afternoon trying various thing & nothing.

Is teh "Nan" value an indication of anything specific?
 
Thanks - so does the NAN imply its definately recieving "somethng".

I have no idea how to check if actually recieving soemthing.
 
No problem, this if often the only way to inspect code and see where things might go wrong.

Cor
 
Transmit:

Code:
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <elapsedMillis.h>
#include <nRF24L01.h>
#include <RF24.h>

#define ONE_WIRE_BUS 2

int debounce_time = 100;
int ButtCntr = 0;

unsigned long currentMillis;
unsigned long previousMillis = 0;
unsigned long SampleRate = 1000;
unsigned long Blink_Time = 10000;
int led = 13;
boolean LED_Status = true;
unsigned long BLINKpreviousMillis = 0;
unsigned long ReadingCount =0;
unsigned long LED_Flash_Gap = 150;

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

RF24 radio(9, 10);
const uint64_t pipe = 0xE6E6E6E6E6E6;
float temperature;
String StrgMsg;

Void Setup()
{
  pinMode(led, OUTPUT);

  //Open serial communications and wait for port to open:
      Serial.begin(9600);

      radio.begin();
      radio.openWritingPipe(pipe);
      delay(100);

  //Start Sensor
      sensors.begin(); 

  //Take a reading from Sensor
      Read_Temperature();

}

void loop()
{
  currentMillis = millis();

  if (currentMillis - previousMillis >= SampleRate)
  {
      Read_Temperature();
      previousMillis = currentMillis;
  }

  BlinkLED();

  radio.write(&temperature, sizeof(float));

}

void Read_Temperature()
{
      sensors.requestTemperatures();
      //float temperature = sensors.getTempCByIndex(0);
      temperature = sensors.getTempCByIndex(0);

      ReadingCount = ReadingCount + 1;

      ButtCntr = ButtCntr + 1;
      Serial.print(ButtCntr); Serial.print(" - ");
      Serial.print("_");  Serial.print("Temp:_"); Serial.println(temperature);

      //StrgMsg = String(temperature);
      //radio.write(StrgMsg);
      radio.write(&temperature, sizeof(float));

      Serial.println(sizeof(float));


}

Reciever Code:

Code:
#include <SD.h>
#include <SPI.h>
#include <Bounce.h>               //SWitch/Button debouncing
#include <TimeLib.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>        //LCD displays
#include <elapsedMillis.h>
#include <nRF24L01.h>
#include <RF24.h>

#define TIME_HEADER  "T"   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 
#define BUTTON1 30    // Preset + 
#define ONE_WIRE_BUS 36

File myFile;

const int chipSelect = BUILTIN_SDCARD;
int debounce_time = 100;
int ButtCntr = 0;
Bounce bouncer1 = Bounce(BUTTON1, debounce_time);
String tHH, tMM, tSS, tDD, tMMM, tYYYY;
String MyDate1, MyDate2, MyTime, MyTimeStamp, MyLogFile;

unsigned long currentMillis;
unsigned long previousMillis = 0;
unsigned long SampleRate = 2000;  //60000 = 1 min
unsigned long Blink_Time = 10000;
int led = 13;
boolean LED_Status = true;
unsigned long BLINKpreviousMillis = 0;
unsigned long ReadingCount =0;
unsigned long LED_Flash_Gap = 150;
boolean RTC_Set = false;

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

//LCD setup 
    #define RS 21
    #define D4 19
    #define D5 18
    #define D6 17
    #define D7 16
    LiquidCrystal lcd =  LiquidCrystal(RS, 20, D4, D5, D6, D7);

RF24 radio(9, 10);
//const uint64_t pipe = 0xE8E8F0F0E1LL;
const uint64_t pipe = 0xE6E6E6E6E6E6;
float SENT_temperature = 0;
int SentMsg = 0;


time_t getTeensy3Time()
{
  return Teensy3Clock.get();
}

/*  code to process time sync messages from the serial port   */
  #define TIME_HEADER  "T"   // Header tag for serial time sync message

  unsigned long processSyncMessage() {
  unsigned long pctime = 0L;
  const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 

  if(Serial.find(TIME_HEADER)) {
     pctime = Serial.parseInt();
     return pctime;
     if( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013)
       pctime = 0L; // return 0 to indicate that the time is not valid
     }
  }
  return pctime;
}

void printDigits(int digits)
{
  // utility function for digital clock display: prints preceding colon and leading 0
      Serial.print(":");
      if(digits < 10)
        Serial.print('0');
      Serial.print(digits);
}

void setup() 
{
  pinMode(BUTTON1,INPUT_PULLUP);
  pinMode(led, OUTPUT);

  //Set the Time library to use Teensy 3.0's RTC to keep time
      setSyncProvider(getTeensy3Time);
  
  //Open serial communications and wait for port to open:
      Serial.begin(9600);
      //Serial.begin(115200);
      
      //while (!Serial)                                         //*********  commented out as this hangs up code if not connected to a PC
      {
        ; // wait for serial port to connect.
      }
      delay(100);

    //Start LCD & display config msg
      lcd.begin(20, 4);
      lcd.setCursor(0, 0);   lcd.print("                    ");
      lcd.setCursor(0, 0);   lcd.print("Config/Setup.");
      delay(1000);

    //Check if RTC was able to be setup
      if (timeStatus()!= timeSet) 
      {
        Serial.println("Unable to sync with the RTC");
        RTC_Set = false;
        MyDate2 = "RTC-NA";
      } 
      else 
      {
        Serial.print("Teensy's RTC has been set with the system time: ");
        RTC_Set = true;
        digitalClockDisplay();
        MyDate2 = String(tYYYY) +  String(tMMM)  + String(tDD);
      }

    //Initialse onboard SD card
      Serial.println("Initializing SD card ...");
      if (!SD.begin(chipSelect)) 
      {
        Serial.println("initialization failed!");
        return;
      }
      Serial.println("initialization COMPLETE.");

  
  //Update Serial Prompt & Log file with initialisation data.
      Serial.println(MyTimeStamp);
      
      MyLogFile = MyDate2 + ".txt";
      Serial.print("SD card Log File Name will be: ");      Serial.println(MyLogFile);
      Serial.println("***********************************************");
      Serial.println("");

  //Create Log file name depending if RTC setup was successfull.
  //Open Log file,  add a bootup header entry, close file
      if (RTC_Set == true)
      {
          myFile = SD.open(MyLogFile.c_str(), FILE_WRITE);
      }
      else
      {
          //myFile = SD.open("RTCNA.TXT", FILE_WRITE);
          myFile = SD.open(MyLogFile.c_str(), FILE_WRITE);
      }
      
          if (myFile) 
          {
            myFile.println("");
            myFile.println("***********************************************");
            myFile.print("SD card initialised & RTC set - ");
            myFile.println(MyTimeStamp);
            myFile.println("***********************************************");
          }
          else
          {
            //
          }

      myFile.close();

  //Start Sensor
      sensors.begin(); 

      radio.begin();
      radio.openReadingPipe(1, pipe);
      radio.startListening();

       //Take a reading from Sensor
      Read_Temperature();

}

void loop()
{
  bouncer1.update();
  currentMillis = millis();

  if (Serial.available()) 
  {
    time_t t = processSyncMessage();
    if (t != 0) 
    {
      Teensy3Clock.set(t); // set the RTC
      setTime(t);
    }
  }
  
  if ( bouncer1.fallingEdge())                          //Button Pressed
  {
      Read_Temperature();
  }

  if (currentMillis - previousMillis >= SampleRate)
  {
      Read_Temperature();
      previousMillis = currentMillis;
  }

  if (radio.available()) 
  {
      if (!radio.read(&SENT_temperature, sizeof(float)) ) 
      {
        Serial.println("ACK not received by client.");
      }

      radio.read(&SENT_temperature, sizeof(float)); // Read information from the NRF24L01
      Serial.print("****** SENT Temperature : ");
      Serial.println(SENT_temperature);
      Serial.println(sizeof(float));
      
      delay(1000);
  }
  else
  {
    Serial.println("###### RADIO NOT AVAILABLE ######");
  }

  BlinkLED();
  


}

void Read_Temperature()
{
      sensors.requestTemperatures();
      float temperature = sensors.getTempCByIndex(0);
      SENT_temperature = temperature;
      
      ReadingCount = ReadingCount + 1;

      digitalClockDisplay();  
      ButtCntr = ButtCntr + 1;
      Serial.print(ButtCntr); Serial.print(" - ");
      Serial.print(MyTimeStamp); Serial.print("_");  Serial.print("Temp:_"); Serial.println(temperature);
      //MyDate1 = String(tYYYY) + "-" + String(tMMM) + "-" + String(tDD);
      
      if (RTC_Set == true)
      {
          MyDate2 = String(tYYYY) +  String(tMMM)  + String(tDD);
          MyLogFile = MyDate2 + ".txt";
          myFile = SD.open(MyLogFile.c_str(), FILE_WRITE);
      }
      else
      {
          MyDate2 = "TRCNA";
          MyLogFile = MyDate2 + ".txt";
          myFile = SD.open("TRCNA.TXT", FILE_WRITE);
      }

      //myFile = SD.open(MyLogFile.c_str(), FILE_WRITE);
      
        if (myFile) 
        {
            myFile.print(ReadingCount); myFile.print("_"); myFile.print(MyTimeStamp); myFile.print("_"); myFile.print("Sensor-A-Temp:_"); myFile.println(temperature);
        }    
        else 
        {
          // if the file didn't open, print an error:
          Serial.print("error opening:- ");
          Serial.println(MyLogFile);
        }
      
      myFile.close();

      lcd.setCursor(0, 0);   lcd.print("                    ");
      lcd.setCursor(0, 0);   lcd.print(MyDate1);

      lcd.setCursor(0, 1);   lcd.print("                    ");
      lcd.setCursor(0, 1);   lcd.print("Sensor A");
      lcd.setCursor(10, 1);  lcd.print(temperature);

      lcd.setCursor(0, 2);   lcd.print("                    ");
      lcd.setCursor(0, 2);   lcd.print(MyTime);

      lcd.setCursor(0, 3);   lcd.print("                    ");
      lcd.setCursor(0, 3);   lcd.print(ReadingCount);

}
 
I can only view 1 serial at a time - but when connected to the Rx - the recvieved value just reads
'****** SENT Temperature : nan
4'
'


Code:
radio.read(&SENT_temperature, sizeof(float)); // Read information from the NRF24L01
Serial.print("****** SENT Temperature : ");
Serial.println(SENT_temperature);
Serial.println(sizeof(float));

edit - missed a line out
 
WOuld be got to be sure about what the TX has send also, if TX sends something wrong RX cant correct that.

What happens if you dont try to send the data as a float but as a string (I saw you had commented that out in the TX part) and just try to read that ?
 
I couldnt get that to work - but i'll keep trying.

TBH dont really understand teh format of teh read & write commands with teh "&" prefix & size of float
 
The & and size are logical, you send the data of a variable and the receiver needs to know how many bytes should be send (depending on the type of variable)


from https://forum.arduino.cc/index.php?topic=421081
rslt = radio.write( &dataToSend, sizeof(dataToSend) );
// Always use sizeof() as it gives the size as the number of bytes.
// For example if dataToSend was an int sizeof() would correctly return 2


So your code
radio.write(&temperature, sizeof(float));

would be more logical as:
radio.write(&temperature, sizeof(temperature));

And its good practice to start your code very simple, so just code for TX and code for RX on the Teensy side. Nothing else that can complicate matters, if you are sure the right data leaves from the TX side (serial output) you can start checking if anything arrives on the RX side. If nothing arrives ... check your wiring. If something arrives try to see how the raw data looks before decoding it into a float/int or whatever.
 
Thanks.

I take your points.
I'd started the sensor stuff first becasue I was waiting for the Nano's & NRF24L01+'s to arrive :).

SO to my earlier point ref 'nan'.

Could I be getting that even if teh Tx isn't actually sending anything?
 
Should be easy to find out. Just make your TX send every 10 seconds or so and check if you get incoming data every 10 seconds also. If you get a regular signal coming in that is most likely due to TX and RX sending/listening on the same channels with the same settings.
 
Oh I now only get the point of your message ... you are not even sending/receiving real data yet ... You cant test anything without the proper hardware !
 
no no - sorry.

I was responding to you comment about simple code.

WHilst waiting for teh new HW I started on tehRTC & Log captuiing to SD card.
Thast why my code is full of other stuff :)

I have everything here now.
 
OK. Than proceed as suggested, first make sure the data leaving the TX is what you want. Serial will tell you that, and make sure it sends out data at a regular interval (not to short). If that works OK, switch to RX and see when it picks up a signal. Is that signal showing the same regular interval ? If so, good chance you have set up the TX/RX properly. Then start checking the incoming data, the webpage I have send before shows you very detailed how that should work. And I also still advice to first make a simple piece of code for the RX TX and get that working, then you can extend your current code with RTC etc with the RX/TX code.
 
BTW - change my Tx Code to just this :

Code:
void loop()
{
  currentMillis = millis();

  BlinkLED();

  String myStr= "Text";
  bool rslt;
  
    rslt = radio.write(&myStr, sizeof(myStr));
    
    Serial.println("Data Sent ");
    Serial.println(myStr);
    
    if (rslt) 
    {
        Serial.println("  Acknowledge received");
    }
    else 
    {
        Serial.println("  Tx failed");
    }



}

But all I get is "Tx failed" in Serial print
 
Status
Not open for further replies.
Back
Top