RF 433 Transmitter and Receiver with sensors and OLED displays
In this video I show you how to send data between 2 Arduino Nanos and use some OLED displays to show if something happened. I wanted to use a microphone as a triggering device, but my microphone circuit was not working as I wanted to. The main concept of this circuit is to see something remotely, but you can easily transform this idea into a for example remote controller.
Wiring diagram
Arduino source code
Transmitter
#include <RH_ASK.h> //RadioHead Amplitude Shift Keying Library #include <SPI.h> //SPI Library #include <Wire.h> //Wire Library (I2C) //ASCII-based OLED library //Its huge advantage that it is _not_ graphical, so it is using much less memory #include "SSD1306Ascii.h" #include "SSD1306AsciiAvrI2c.h" // 0X3C+SA0 - 0x3C or 0x3D #define I2C_ADDRESS 0x3C //Address #define RST_PIN -1 //For OLED with no reset pin SSD1306AsciiAvrI2c display; //Instantiating a display RH_ASK rf_driver; //Instatiating a rf_driver for the transmitter int soundLevel = 0; //variable for the microphone's output int triggerLevel = 0; int AVGsoundLevel = 0; int messageNumber = 0; //1 = triggered, 0 = reset (receiver will wait for a new trigger). bool triggered = false; //we change this based on the status //PINS int microphonePin = A6; int redLED = 5; // On, when triggered (Triggered) int greenLED = 6; //on when not triggered (Waiting) int calibratePin = 2; //to save the triggel level void setup() { //Initializing the display #if RST_PIN >= 0 display.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN); #else // RST_PIN >= 0 display.begin(&Adafruit128x64, I2C_ADDRESS); #endif // RST_PIN >= 0 display.setFont(System5x7); //font type display.set1X(); //font size (small) display.clear(); //----------------------------------------------------- // Initialize ASK Object rf_driver.init(); //----------------------------------------------------- //Pins. By default, green will be on. pinMode(calibratePin, INPUT_PULLUP); //use the internal pullup pinMode(redLED, OUTPUT); pinMode(greenLED, OUTPUT); digitalWrite(redLED, LOW); digitalWrite(greenLED, HIGH); attachInterrupt(digitalPinToInterrupt(calibratePin), triggerSoundLevel, RISING); //L -> H, button for calibration } void loop() { PrintScreen(); //Print the info on the screen MeasureSound(); //Measure the sound } void PrintScreen() { display.clear(); //clear display display.setCursor(0, 0); //start in the 0 position //---------------------------- display.print("Level: "); display.println(AVGsoundLevel); display.println(); //---------------------------- display.print("Trigger level: "); display.println(triggerLevel); //---------------------------- display.println(); display.print("Status: "); if(triggered == false) { //This gets printed if we do not cross the trigger value display.println("Waiting"); messageNumber = 0; //sends a 0 to the receiver SendMessage(messageNumber); digitalWrite(redLED, LOW); //only green is on while waiting digitalWrite(greenLED, HIGH); } else { //triggered == true //This gets printed if we cross the trigger value display.println("Triggered"); messageNumber = 1; //sends a 0 to the receiver SendMessage(messageNumber); digitalWrite(redLED, HIGH); //red is on when triggered and green is off digitalWrite(greenLED, LOW); } } void MeasureSound() { soundLevel = 0; //Reset it, before filling it up AVGsoundLevel = 0; //Reset it, before filling it up //Let's measure it for some time and create an average for(int i = 0; i < 10; i++) { soundLevel += analogRead(microphonePin); delay(200); } AVGsoundLevel = soundLevel / 10; //calculate average if(AVGsoundLevel < (triggerLevel-100)) //if there is less value, we flip the value of the variable { triggered = true; //set the bool to true } else { triggered = false; //set the bool to false } } void triggerSoundLevel() { soundLevel = 0; //Reset it, before filling it up triggerLevel = 0; //Reset for(int i = 0; i < 10; i++) { soundLevel += analogRead(microphonePin); delay(200); } triggerLevel = soundLevel / 10; //calculate average soundLevel = 0; //Reset it, again, otherwise, it goes to weird levels in the measure() } void SendMessage(int messageNumber) { rf_driver.send((uint8_t *)&messageNumber, sizeof(messageNumber)); //send the message through the RF module rf_driver.waitPacketSent(); }
Receiver
#include <RH_ASK.h>//RadioHead Amplitude Shift Keying Library #include <SPI.h> // SPI Library #include <Wire.h> //Wire Library (I2C) RH_ASK rf_driver; //Instatiating a rf_driver for the receiver //ASCII-based OLED library //Its huge advantage that it is _not_ graphical, so it is using much less memory #include "SSD1306Ascii.h" #include "SSD1306AsciiAvrI2c.h" #define I2C_ADDRESS 0x3C //Address #define RST_PIN -1 //For OLED with no reset pin SSD1306AsciiAvrI2c display; // Set buffer to size of expected message uint8_t buf[24]; uint8_t buflen = sizeof(buf); String receivedString; //String for long messages //REC pin = D11 int redLED = 5; //on, when it is too loud int greenLED = 6; //on when it is OK void setup() { // Initialize ASK Object rf_driver.init(); #if RST_PIN >= 0 display.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN); #else // RST_PIN >= 0 display.begin(&Adafruit128x64, I2C_ADDRESS); #endif // RST_PIN >= 0 // Call oled.setI2cClock(frequency) to change from the default frequency. display.setFont(System5x7); display.set1X(); display.clear(); //Managing the LEDs pinMode(redLED, OUTPUT); pinMode(greenLED, OUTPUT); digitalWrite(redLED, LOW); digitalWrite(greenLED, HIGH); //---------------------------- //Serial.begin(9600); //Serial.println("Receiver started"); } void loop() { // Check if received packet is correct size if (rf_driver.recv(buf, &buflen)) { for (int i = 0; i < buflen-1; i++) { receivedString += String(buf[i]); //building up a string from the received data } PrintScreen(); //print to OLED receivedString=""; //reset to zero, so we don't mix the messages } } void PrintScreen() { display.clear(); display.setCursor(0, 0); display.println("Status: "); display.println(); if(receivedString == "0") { display.println("Waiting..."); digitalWrite(redLED, LOW); digitalWrite(greenLED, HIGH); //Only green is on, while we are waiting } if(receivedString == "1") { display.println("Check device!"); digitalWrite(redLED, HIGH); //Red goes on, when the trigger level is crossed on the transmitter side digitalWrite(greenLED, LOW); } }