Project tutorial
Dual Location Temperature Monitoring System

Dual Location Temperature Monitoring System © GPL3+

Transmit temperature readings via two nRF24L01 transceiver modules using an Arduino Nano and a TTGO T-Display and upload to Thingspeak.

  • 280 views
  • 0 comments
  • 1 respect

Components and supplies

Apps and online services

About this project

After obtaining a few nRF24L01 transceiver modules, I wanted to try making a simple project with it, where you can send information from one device to a 'main device' (of sorts). I wanted this 'main device' to have a screen so that it can show the important information and also upload the data online so it can be kept track of.

Each time data is uploaded to the Thingspeak channel, a notification will show up below the square showing the device from which the data is being uploaded.

How it works

In this project, an Arduino Nano is used to transmit temperature readings (taken from a DS18B20 temperature sensor) to a TTGO T-Display. The TTGO T-Display has its own DS18B20, and both these temperature readings will be displayed on the device's screen, and also uploaded to a ThingSpeak channel.

How to make it

Listed below are some of the main components needed for this project.

nRF24L01

The nRF24L01 transceiver module from Nordic Semiconductors operates in the 2.4 GHz ISM frequency band (also used for WiFi) and uses GFSK modulation. It can operate at three different data rates: 250 kbps, 1 mbps, and 2 mbps. The low power consumption of the device and its low price point makes it a very attractive option for projects of this caliber. Many online sources mention that there will be noise introduced into the device. It will therefore be a good idea to place a 10µf capacitor from the Vcc to the Gnd to reduce noise, but this is not compulsory.

DS18B20

This digital thermometer provides 9-bit to 12-bit temperature measurements and is particularly useful thanks to its 1-Wire protocol. Each device has a unique 64-bit serial code, allowing multiple devices to be read using one pin. There is a waterproof device and a non-waterproof one. Regardless of the form-factor you choose, you will require a 4.7k pull up resistor from the Vcc to the Data connection.

Arduino Nano

This device has been around for a while and has all the features of an Arduino Uno in a smaller form factor.

LILYGO TTGO T-Display

This device is equipped with an ESP32 microcontroller and therefore has all the features that come with it (WiFi, Bluetooth, etc.). To top it off, it has its own color LCD display.

ThingSpeak

ThingSpeak makes IoT very easy for hobbyists. It will store and retrieve data from things using the HTTP and MQTT protocol over the Internet or via a Local Area Network. It is quite easy to make a Channel for the data logging, and each channel will have 8 fields to upload data to. It is possible to use a paid subscription, but for this project, the free features will be enough.

Assembly

Physical

There will be two boards: one for transmitting from an nRF24L01 and one for receiving from an nRF24L01. The Arduino Nano will be used for the transmission end, and the LILYGO TTGO T-Display will be used to receive data and then upload it online. All setups will be assembled on a breadboard as this is a prototype.

The transmitter's assembly is shown in the figure below.

The connections are as follows.

D2 (Arduino Nano) ----------------------------> Data (DS18B20)

D7 (Arduino Nano) ----------------------------> CE (nRF24L01)

D8 (Arduino Nano) ----------------------------> CSN (nRF24L01)

D11 (Arduino Nano) ----------------------------> MOSI (nRF24L01)

D12 (Arduino Nano) ---------------------------> MISO (nRF24L01)

D13 (Arduino Nano) ---------------------------> SCK (nRF24L01)

The receiver's connections are listed below.

The connections are as follows.

GPIO2 (LILYGO TTGO T-Display) ------------------------------> Data (DS18B20)

GPIO32 (LILYGO TTGO T-Display) ----------------------------> CE (nRF24L01)

GPIO33 (LILYGO TTGO T-Display) ----------------------------> CSN (nRF24L01)

GPIO27 (LILYGO TTGO T-Display) ----------------------------> MOSI (nRF24L01)

GPIO25 (LILYGO TTGO T-Display) ---------------------------> MISO (nRF24L01)

GPIO26 (LILYGO TTGO T-Display) ---------------------------> SCK (nRF24L01)

Setting up the Thingspeak Channel

This system will require a Thingspeak channel for use (https://thingspeak.com/). This can be made quite easily after making an account. In the Thinkspeak homepage, go to 'Channels', click on 'My Channels', and click on the green icon that says 'New Channel'. Fill in a suitable name and click the first two tick boxes as we require two fields for this project.

Take note of the 'Write API' key which can be found on the 'API keys' section and the 'Channel ID' from the channel itself. These values need to be input into the code for the LILYGO TTGO T-Display.

Codes

Each device can be programmed using the Arduino IDE. Both files are listed below. The.h files required for both the devices are nRF24L01.h and RF24.h. Note that the RF24.h file used in this project is a fork published by nhatuan84, which can be found here. For more information, visit the following link. This fork makes it easy to alter all the pins used by the microcontroller for the nRF24L01.

For the transmitting Arduino Nano, the file is titled 'transmitter.ino' and for the receiving LILYGO TTGO T-Display, the file is titled 'receiver.ino'. Look through online resources to find out the necessary libraries to set up the LILYGO TTGO T-Display. After installing the necessary libraries, in the 'TFT_eSPI' folder in the Arduino Libraries, open 'User_Setup_Select.h' and uncomment the following line of code

#include <User_Setups/Setup25_TTGO_T_Display.h>    // Setup file for ESP32 and TTGO T-Display ST7789V SPI bus TFT

in order to make the library function with this device.

Both devices will have a pipe value as shown below.

const uint64_t pipee = 0xE8E8AAFFE122;

This value needs to be identical for the transmitter and the receiver in order to establish communication.

Code

ReceiverArduino
The code used for the TINYGO TTGO T-Display (Receiver)
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI();  // Invoke library, pins defined in User_Setup.h
#include "nRF24L01.h"
#include "RF24.h"
char msg[6];
//You need the altered nRF24L01 library by nhatuan84 (https://github.com/nhatuan84/RF24)
//RF24(uint16_t _cepin, uint16_t _cspin, uint16_t sck, uint16_t miso, uint16_t mosi)
RF24 radio(32, 33, 26, 25, 27);

const uint64_t pipee = 0xE8E8AAFFE122; //Pipe value, must be similar to the value on the transmitting end

#include <OneWire.h> 
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2 
OneWire oneWire(ONE_WIRE_BUS); 
DallasTemperature sensors(&oneWire);

#include <WiFi.h>
#include "ThingSpeak.h"

//WiFi details
const char* ssid = "[your network SSID (name)]";   // your network SSID (name) 
const char* password = "[your network password]";   // your network password
WiFiClient  client;
unsigned long myChannelNumber = [your channel number]; //your channel number
const char * myWriteAPIKey = "[your write API key]"; //your write API key

//Independant time values
const long printAllTimeI = 5000; //Screen will update every 5 seconds
const long uploadDataII = 1800000; //Data will upload every 30 minutes 

//Previous time values
unsigned long prevTimeI = 0;
unsigned long prevTimeII = 0;

#define TFT_GREY 0x5AEB // We'll need this color for the screen's background

void setup(void){
  Serial.println("Dallas Temperature IC Control Library Demo"); 
  sensors.begin(); 
  
  tft.init();
  tft.setRotation(1);
 
  Serial.begin(115200);
  radio.begin();
  radio.setChannel(2);
  radio.setPayloadSize(7);
  radio.setDataRate(RF24_250KBPS);
  radio.openReadingPipe(1,pipee);
  radio.startListening();

  tft.fillScreen(TFT_BLACK);

  WiFi.mode(WIFI_STA);     
  ThingSpeak.begin(client);  // Initialize ThingSpeak

  mainScreen();
}

void loop(void){
  tft.setTextColor(TFT_WHITE);
  tft.setTextFont(2);

  Serial.print("Requesting temperatures..."); 
  sensors.requestTemperatures();
  Serial.println("DONE\n\n"); 
  
  if (radio.available()){  
    radio.read(msg, 6);      
    Serial.print("External temperature: ");
    Serial.print(msg);
    Serial.println(" C\n");
  }
  else{
    Serial.println("No radio available");
  }

  unsigned long currentTime = millis();
  
  if(currentTime - prevTimeI >= printAllTimeI){
    //tft.fillScreen(TFT_BLACK);
    Serial.print("Internal temperature: "); 
    Serial.print(sensors.getTempCByIndex(0)); 
    Serial.println(" C"); 

    tft.setTextColor(TFT_WHITE, TFT_GREY);
    tft.setCursor(35, 70, 2); //TTGO Internal temperature
    tft.print(sensors.getTempCByIndex(0));
    tft.print(" C");
    tft.setCursor(150, 70, 2); //Nano External temperature
    tft.print(msg);
    tft.print(" C");
    
    prevTimeI = currentTime;
  }

  if(currentTime - prevTimeII >= uploadDataII){
    //Connect or reconnect to WiFi
    if(WiFi.status() != WL_CONNECTED){
      Serial.print("Attempting to connect");
      while(WiFi.status() != WL_CONNECTED){
        WiFi.begin(ssid, password); 
        delay(5000);     
      } 
      Serial.println("\nConnected.");
    }

    //Uploading internal temperature
    int x = ThingSpeak.writeField(myChannelNumber, 1, (sensors.getTempCByIndex(0)), myWriteAPIKey); //TTGO

    if(x == 200){
      Serial.println("Channel 1 Field 1 update successful");
      uploadNotificationTTGO();
    }
    else{
      Serial.println("Problem updating Channel 1 Field 1. HTTP error code " + String(x));
    }

    //Uploading external temperature
    int y = ThingSpeak.writeField(myChannelNumber, 2, msg, myWriteAPIKey); //Nano

    if(y == 200){
      Serial.println("Channel 1 Field 2 update successful");
      uploadNotificationNano();
    }
    else{
      Serial.println("Problem updating Channel 1 Field 2. HTTP error code " + String(x));
    }
   
    prevTimeII = currentTime;
  }
}

void mainScreen(){
  tft.fillScreen(TFT_GREY);
  //range along TTGO sign
  //x 1 - 239
  //y 1 - 134
  //tft.drawRoundRect(x, y, w, h, 5, color);
  tft.setRotation(1);
  tft.setCursor(50, 5, 2);
  tft.setTextColor(TFT_WHITE, TFT_GREY);
  tft.print("2-sensor temp monitor");
  tft.setCursor(45, 40, 2); //left side
  tft.print("TTGO");
  tft.drawRoundRect(5, 30, 110, 100, 5, TFT_BLACK);
  tft.drawRoundRect(6, 31, 108, 98, 5, TFT_BLACK);
  tft.drawRoundRect(7, 32, 106, 96, 5, TFT_BLACK);
  tft.drawRoundRect(8, 33, 104, 94, 5, TFT_BLACK);
  tft.drawRoundRect(9, 34, 102, 92, 5, TFT_BLACK);

  tft.setCursor(165, 40, 2); //right side
  tft.print("Nano");
  tft.drawRoundRect(124, 30, 110, 100, 5, TFT_BLACK);
  tft.drawRoundRect(125, 31, 108, 98, 5, TFT_BLACK);
  tft.drawRoundRect(126, 32, 106, 96, 5, TFT_BLACK);
  tft.drawRoundRect(127, 33, 104, 94, 5, TFT_BLACK);
  tft.drawRoundRect(128, 34, 102, 92, 5, TFT_BLACK);
}

void uploadNotificationTTGO(){
  tft.setTextColor(TFT_GREEN, TFT_GREY);
  tft.setCursor(35, 100, 2);
  tft.print("Uploaded");  
  delay(60000);
  tft.setTextColor(TFT_GREEN, TFT_GREY);
  tft.setCursor(35, 100, 2);
  tft.print("         ");
}

void uploadNotificationNano(){
  tft.setTextColor(TFT_GREEN, TFT_GREY);
  tft.setCursor(155, 100, 2);
  tft.print("Uploaded");
  delay(60000);
  tft.setTextColor(TFT_GREEN, TFT_GREY);
  tft.setCursor(155, 100, 2);
  tft.print("         ");
}
TransmitterArduino
The code for the Arduino Nano (Transmitting Device)
#include  <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
char msg[6] = "hello";
RF24 radio(7,8);

const uint64_t pipee = 0xE8E8AAFFE122;

#include <OneWire.h> 
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2 
OneWire oneWire(ONE_WIRE_BUS); 
DallasTemperature sensors(&oneWire);

void setup(void) {
  Serial.begin(115200);

  Serial.println("Initializing DS18B20 sensor"); 
  sensors.begin(); 
  
  radio.begin();
  radio.setChannel(2);
  radio.setPayloadSize(7);
  radio.setDataRate(RF24_250KBPS);
  radio.openWritingPipe(pipee);
}

void loop(void) {
  Serial.print("Requesting temperatures..."); 
  sensors.requestTemperatures(); // Send the command to get temperature readings 
  Serial.println("DONE"); 
  Serial.print("Temperature is: ");
  Serial.print(sensors.getTempCByIndex(0)); // Not using a hexadecimal address, since there is only one sensor  
  Serial.println(" C ");

  dtostrf((sensors.getTempCByIndex(0)), 6, 2, msg);
  
  Serial.print("Sending to receiver...");
  radio.write(msg, 6);
  Serial.println("sent!\n");
  delay(3000);
}

Schematics

Schematic for transmitter and receiver
Fritzing based schematic for transmitter and receiver.
schematic_for_transmitter_and_receiver_n2Dk7aF0Qz.fzz

Comments

Similar projects you might like

SMART Temperature Monitoring for Schools

Project tutorial by Aden and reginald loo

  • 13,048 views
  • 7 comments
  • 19 respects

Arduino Control AC Water Heater temperature

Project tutorial by Mohannad Rawashdeh

  • 25,198 views
  • 1 comment
  • 12 respects

Arduino Dual BME280 IoT Recording HygroThermoGraph

Project tutorial by jim Myracle

  • 8,428 views
  • 2 comments
  • 18 respects

Cardiac Monitoring System - EKG

Project showcase by Zorzonel Vlad

  • 22,978 views
  • 14 comments
  • 53 respects

Windows 10 IoT Plant Monitoring System

Project tutorial by Team BME-AUT

  • 22,929 views
  • 7 comments
  • 77 respects

Baby-Pram Monitoring System

Project tutorial by IP

  • 12,965 views
  • 4 comments
  • 15 respects
Add projectSign up / Login