Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 4 1 2 3 ... LastLast
Results 1 to 25 of 86

Thread: Teensy with 4 or 5 wireless temperature sensors

  1. #1
    Senior Member
    Join Date
    Jun 2015
    Posts
    289

    Teensy with 4 or 5 wireless temperature sensors

    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

  2. #2
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    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

  3. #3
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    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.

  4. #4
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    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/201...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-w...0-arduino-uno/

  5. #5
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    Brilliant thansk again.

    Gives me a great start point.

  6. #6
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    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?

  7. #7
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    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.

  8. #8
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    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?

  9. #9
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    Thanks - so does the NAN imply its definately recieving "somethng".

    I have no idea how to check if actually recieving soemthing.

  10. #10
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    Share your code

  11. #11
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    I will do

    Its just Im not at my PC at moment

  12. #12
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    No problem, this if often the only way to inspect code and see where things might go wrong.

    Cor

  13. #13
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    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);
    
    }

  14. #14
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    And what does the serial on the TX and RX show ?

  15. #15
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    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

  16. #16
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    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 ?

  17. #17
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    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

  18. #18
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    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.

  19. #19
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    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?

  20. #20
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    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.

  21. #21
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    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 !

  22. #22
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    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.

  23. #23
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    346
    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.

  24. #24
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    OK will crack on with this later.
    Family stuff to deal with Im afraid.

    Thanks for help so far

  25. #25
    Senior Member
    Join Date
    Jun 2015
    Posts
    289
    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •