top of page

Search Results

163 results found with an empty search

  • IoT Based LDR Light control using MQTT

    In this project, I will show you how to build a simple Light Activated Switch Circuit using LDR. Using this circuit, an electrical device or an appliance like a street light or a fan for example, can be controlled based on the intensity of the light near the circuit. In this to build an IoT system using an ESP8266, myDevices Cayenne, and MQTT. In more detail, this IoT tutorial discovers how to use an ESP8266 to send data to Cayenne using the MQTT protocol. Moreover, this ESP8266 MQTT project investigates how to use MQTT to control remote peripheral devices using a web interface. This is a complete step-by-step tutorial on building an IoT system using Cayenne and ESP. On the other hand, Cayenne is an IoT cloud platform that provides several cloud services, such as: Data visualization IoT cloud Alerts Scheduling Events We will focus our attention on data visualization and on the IoT cloud services. Cayenne Cayenne IoT Platform accelerates the development of IoT-based solutions, including quick design, prototyping and other commercialized projects. It is a drag-and-drop IoT project builder that can help developers build complete, ready-to-use IoT solutions with little to no coding. Cayenne IoT Platform contains a vast catalog of certified IoT-ready devices and connectivity options. This allows users to easily add any device to the library utilizing MQTT API. All devices in Cayenne are interoperable and benefit from features such as rules engine, asset tracking, remote monitoring and control, and tools to visualize real-time and historical data. MQTT is a lightweight messaging protocol for sensors and mobile devices. NodeMCU NodeMCU ESP8266-12E MCU is a development board with one analogue and many general-purpose input output (GPIO) pins. It has 4MB flash memory, and can operate at a default clock frequency of 80MHz. In this project, Analog pin A0 of NodeMCU is used to read Voltage in Between LDR and Series Resister. LDR Light dependent resistors, LDRs, or a photoresistor is a passive component that decreases resistance with respect to receiving luminosity on the component's sensitive surface. The resistance of a photoresistor decreases with increase in incident light intensity; in other words, it exhibits photoconductivity. Principle behind the Circuit The main principle of this circuit is based on the working of the LDR Sensor i.e. the Light Dependent Resistor and to switch ON or OFF the light based on the intensity of illumination. Theory of the light dependent resistor, it will have a high resistance in darkness and low resistance in the presence of light. A typical light dependent resistor, LDR / photoresistor specification may be: Example Photo Resistors Spec parameters Example below. Max power dissipation - 200mWMax voltage @ 0 lux - 200V Peak wavelength - 600nmMin. resistance @ 10lux - 1.8kΩMax. resistance @ 10lux - 4.5kΩTyp. resistance @ 100lux - 0.7kΩ Dark resistance after 1 sec - 0.03MΩ Dark resistance after 5 sec - 0.25MΩ Installing the ESP8266_Arduino_Library Download the Cayenne-MQTT-ESP-master library from this link. Click on Add ZIP Library and add Cayenne-MQTT-ESP-master zip file, or directly copy the folder (Cayenne-MQTT-ESP-master) and paste it in Libraries folder of Arduino IDE. After installing the library, go to your Arduino IDE. Make sure you have the Nodemcu 1.0 ESP-12E board selected, and then, Copy and Paste code in Arduino IDE. Circuit Diagram Subscribe and Download code. Arduino code #include #include char ssid[] = "SSID"; //YOUR SSID char password[]="PASSWORD"; // YOUR PASSWORD char username[] = "2031dd30-5414-11eb-b767-3f1a8f1211ba"; ////YOURs char mqtt_password[] = "f2ce829d98df3a768328ac6936eae9fd47d28289"; ////YOURs char client_id[] = "3d65e860-5414-11eb-a2e4-b32ea624e442"; // //YOURs int ldr = A0; int ldr_data; void setup() { Serial.begin(9600); Cayenne.begin(username,mqtt_password,client_id,ssid,password); pinMode(A0,INPUT); } void loop() { Cayenne.loop(); ldr_data = analogRead(ldr); Serial.println(ldr_data); Cayenne.virtualWrite(2, ldr_data); } Hardware interfacing with Cayenne IoT platform refer detail: https://www.dofbot.com/post/cayenne-iot-based-weather-monitor Click on Add new and then Device/Widget in Settings, Add New Device here and select Generic ESP8266 for in this project. Configure device Generic ESP8266, MQTT username, password and client ID from Create App Paste these respective details under username, password and client ID in Arduino source code , along with your Wi-Fi name and password. After successfully compiling and uploading the code to NodeMCU, You will see ESP8266 connected to Wi-Fi. After the connection is established, the previous page is automatically updated on Cayenne. A new dashboard opens in the browser. Cayenne generates an ID and a device icon for your device. Click on Custom Widgets and then value, and populate all fields . The channel number should be 1. (Make sure the channel number is same as in code.) Now, click on Add Widget. Graphical representation by click Graph Icon.

  • NodeMCU Web Server Controlled Servo Motor

    Here to show you how to build a web server with the ESP8266 12E that controls the shaft’s position of a servo motor using a Web page slider. Connecting the Servo Motor to the ESP8266 Servo motors have three wires: power, ground, and signal. Servo Wire Color Power-Red GND-Black, or brown Signal-Yellow, orange, or white When using a small servo like the SG90 as shown in the figure below, you can power it directly from the ESP8266. If you’re using a small servo like the SG90, you need to connect: GND -> ESP8266 GND pin; Power -> ESP8266 Vin pin; Signal -> GPIO 5 (or any PWM pin). Installing the ESP8266_Arduino_Servo_Library The ESP32 Arduino Servo Library makes it easier to control a servo motor with your ESP8266, using the Arduino IDE. Follow the next steps to install the library in your Arduino IDE: Download the ESP32_Arduino_Servo_Library. You should have a .zip folder in your Downloads folder, Unzip the .zip folder and you should get ESP32-Arduino-Servo-Library. After installing the library, go to your Arduino IDE. Make sure you have the Nodemcu 1.0 ESP-12E board selected, and then, Copy and Paste code in Arduino IDE. Subscribe and Download code. #include #include #include //Include the Servo Library #include #include "PageIndex.h"; //--> Include the contents of the User Interface Web page, stored in the same folder as the .ino file #define ServoPort D1 //--> Defining Servo Port //Make a wifi name and password as access point const char* ssid = "TP-Link_3200"; // your SSID const char* password = "9500112137"; //WIFI Password // Servo myservo; //--> create servo object to control a servo ESP8266WebServer server(80); //--> Server on port 80 //This routine is executed when you open NodeMCU ESP8266 IP Address in browser void handleRoot() { String s = MAIN_page; //Read HTML contents server.send(200, "text/html", s); //Send web page } //Procedure for handling servo control void handleServo(){ String POS = server.arg("servoPOS"); int pos = POS.toInt(); myservo.write(pos); //--> Move the servo motor according to the POS value delay(15); Serial.print("Servo Angle:"); Serial.println(pos); server.send(200, "text/plane",""); } void setup() { Serial.begin(115200); delay(500); myservo.attach(ServoPort); //--> attaches the servo on D1 to the servo object WiFi.begin(ssid, password); Serial.print("Connect your wifi laptop/mobile phone to this NodeMCU Access Point : "); Serial.println(ssid); Serial.println("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("."); } // Print ESP8266 Local IP Address Serial.println(WiFi.localIP()); //Initialize Webserver server.on("/",handleRoot); //--> Routine to handle at root location. This is to display web page. server.on("/setPOS",handleServo); //--> Sets servo position from Web request server.begin(); Serial.println("HTTP server started"); } void loop() { server.handleClient(); } Creating the HTML Page we need to include the HTML file PageIndex.h in the sketch and rotate the servo accordingly. const char MAIN_page[] PROGMEM = R"=====( NodeMCU ESP8266 Web Server Controlled Servo Motor Servo angle: )====="; Upload the Code Now, upload the code to your ESP8266. Make sure you have the right board and COM port selected. After uploading, open the Serial Monitor at a baud rate of 115200. Press the ESP8266 reset button. The ESP8266 IP address should be printed in the serial monitor. Finally Result.

  • ESP8266 Weather station InDoor & OutDoor

    In this project you’ll create a standalone web server with an ESP8266 that displays the temperature and humidity with a DHT11 or DHT22 sensor for Indoor weather and Weather widgets used for Outdoor weather data using the Arduino IDE . The web server you’ll build can be accessed with any device that has a browser on your local network. For Indoor Weather station already posted, Refer https://www.dofbot.com/post/esp8266-server-dht-weather-station To Interfacing the Widgets in the Local web page already posted in Covid-19 tracker, Refer https://www.dofbot.com/post/esp8266-covid-19-live-tracker Circuit Diagram: Uploading code Having the ESP8266 add-on for the Arduino IDE installed (how to Install the ESP8266 Board in Arduino IDE), go to Tools and select “NodeMCU (ESP-12E Module)”. Subscribe and Download code. Copy the following code to your Arduino IDE and upload it to your ESP8266 board. #include #include #include #include #include #include #include // Replace with your network credentials const char* ssid = "SSID"; // your SSID const char* password = "PASSWORD"; // your wifi password #define DHTPIN 5 // Digital pin D1 connected to the DHT sensor // Uncomment the type of sensor in use: #define DHTTYPE DHT11 // DHT 11 //#define DHTTYPE DHT22 // DHT 22 (AM2302) //#define DHTTYPE DHT21 // DHT 21 (AM2301) DHT dht(DHTPIN, DHTTYPE); // current temperature & humidity, updated in loop() float t = 0.0; float h = 0.0; // Create AsyncWebServer object on port 80 AsyncWebServer server(80); // Generally, you should use "unsigned long" for variables that hold time // The value will quickly become too large for an int to store unsigned long previousMillis = 0; // will store last time DHT was updated // Updates DHT readings every 10 seconds const long interval = 10000; const char index_html[] PROGMEM = R"rawliteral( ESP8266 Indoor Weather DHT Server Temperature %TEMPERATURE% °C Humidity %HUMIDITY% % Outdoor Weather Server Please Subscribe to Dofbot YouTube Channel )rawliteral"; // Replaces placeholder with DHT values String processor(const String& var){ //Serial.println(var); if(var == "TEMPERATURE"){ return String(t); } else if(var == "HUMIDITY"){ return String(h); } return String(); } void setup(){ // Serial port for debugging purposes Serial.begin(115200); dht.begin(); // Connect to Wi-Fi WiFi.begin(ssid, password); Serial.println("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("."); } // Print ESP8266 Local IP Address Serial.println(WiFi.localIP()); // Route for root / web page server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", index_html, processor); }); server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", String(t).c_str()); }); server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", String(h).c_str()); }); // Start server server.begin(); } void loop(){ unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { // save the last time you updated the DHT values previousMillis = currentMillis; // Read temperature as Celsius (the default) float newT = dht.readTemperature(); // Read temperature as Fahrenheit (isFahrenheit = true) //float newT = dht.readTemperature(true); // if temperature read failed, don't change t value if (isnan(newT)) { Serial.println("Failed to read from DHT sensor!"); } else { t = newT; Serial.println(t); } // Read Humidity float newH = dht.readHumidity(); // if humidity read failed, don't change h value if (isnan(newH)) { Serial.println("Failed to read from DHT sensor!"); } else { h = newH; Serial.println(h); } } } final Result Demo video:

  • ESP8266 Covid-19 Live Tracker

    Here to make an automatic Coronavirus COVID 19 Live Data Tracker using ESP8266 Web Server with widget. Data reporting in the webpage from WHO Coronavirus Disease (COVID-19) statics in world wide and countrywise data by editing setting in the Local webpage (widget). ESP8266 based boards are by far the most popular platform, among makers and hobbyist, for building WiFi based projects due to their low cost and general ease of use. For today’s tutorial, we will continue our exploration of the most popular of the ESP8266 based boards; the NodeMCU development board and we will explore how to build a web server using it. Through the web server, we will be able to control anything connected to the GPIO pins of the board. But here no component and GPIO pins used in this project except ESP8266 12E v3 development board. In this tutorial we are making ESP8266 web server with HTML web page. ESP8266 connects to WiFi Network and we get web page in our phone and PC which is connected to same WiFi network. A Web server is a program that uses HTTP (Hypertext Transfer Protocol) to serve the files that form Web pages to users, in response to their requests, which are forwarded by their computers’ HTTP clients. To implement web server on ESP, there are two ways to make your first web server first connect to your WiFi router or make ESP as access point. Subscribe and Download code. Web Server Step by Step We need these libraries to make web server. #include #include #include In order to setup the webserver, we will need ESPAsyncWebServer, which we will use in our code.This library allows setting an asynchronous HTTP (and Websocket) server, once we set the server callback functions, we don’t need to periodically call any client handling function on the main loop, like we had to do on the ESP8266 HTTP webserver original implementation. Define your SSID and Password of your WiFi router, where the ESP connects //SSID and Password of your WiFi router const char* ssid = "your_ssid"; const char* password = "password"; To finalize, we will declare a variable of class AsyncWebServer, which we will use to set up our asynchronous ESP8266 HTTP server. As input of the constructor, we will pass the port where the server will be listening. We will use port 80, which is the default HTTP port. AsyncWebServer server(80); As we know that all web servers have a web page to be served. First make a web page using HTML code. ESP8266 Web Server for A Live COVID-19 Tracker Inserting Widget HTML code: In addition to adding a covid statics widgets from elfsight in the web page. create account and get HTML code for the Widgets, With this done, we move to the void setup() function. We start by initializing the serial monitor. Serial.begin(115200); Next, we connect to the access point using the credentials as arguments to the WiFi.begin() function and we use the WiFi.status() function to check if connection was successful. WiFi.begin(ssid, password); Serial.print("Connecting to "); Serial.println(ssid); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); If the connection is successful, a text is printed on the serial monitor to indicate that, and the IP address of the web server is also displayed. This IP address becomes the web address for server and it is what will be entered on any web browser on the same network to access the server. Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP());// this will display the Ip address of the Pi which should be entered into your browser With that done, we start the server using the server.begin() function and proceed to the void loop( ) function. server.begin(); void loop(){ } Subscribe and Download code. Complete Arduino code here below: #include #include #include // Replace with your network credentials const char* ssid = "SSID"; // your SSID const char* password = "password"; // your wifi password // Create AsyncWebServer object on port 80 AsyncWebServer server(80); const char index_html[] PROGMEM = R"rawliteral( ESP8266 Web Server for A Live COVID-19 Tracker Subscribe to Dofbot YouTube Channel )rawliteral"; void setup(){ // Serial port for debugging purposes Serial.begin(115200); // Connect to Wi-Fi WiFi.begin(ssid, password); Serial.println("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("."); } // Print ESP8266 Local IP Address Serial.println(WiFi.localIP()); // Route for root / web page server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", index_html); }); // Start server server.begin(); } void loop(){ // nothing here }

  • ESP8266 Server DHT Weather Station

    In this project you’ll create a standalone web server with an ESP8266 that displays the temperature and humidity with a DHT11 or DHT22 sensor using the Arduino IDE. The web server you’ll build can be accessed with any device that has a browser on your local network. Component Required: ESP8266 12E- v3- 1 no DHT11- 1no DHT 11/22/AM2302 Connecting DHT11/DHT22/AM2302 sensor to ESP8266 NodeMCU is fairly simple. Connect VCC pin on the sensor to the 3.3V pin on the NodeMCU and ground to ground. Also connect Data pin on the sensor to D1 pin of the ESP8266 NodeMCU. Installing DHT Sensor Library Communicating with DHT11, DHT22/AM2302 sensors is a bunch of work, as they have their own single wire protocol for data transfer. And this protocol requires precise timing. To read from the DHT sensor, we’ll use the DHT library from Adafruit. To use this library you also need to install the Adafruit Unified Sensor library. Follow the next steps to install those libraries. 1. Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open. 2. Search for “DHT” on the Search box and install the DHT library from Adafruit version 1.3.4. 3. After installing the DHT library from Adafruit version 1.0.2, type “Adafruit Unified Sensor” in the search box. Scroll all the way down to find the library and install it. After installing the libraries, restart your Arduino IDE. ESP8266 Asynchronous Web Server To build the web server we’ll use the ESPAsyncWebServer library that provides an easy way to build an asynchronous web server. Building an asynchronous web server has several advantages. We recommend taking a quick look at the library documentation on its GitHub page. Installing the ESPAsyncWebServer library The ESPAsyncWebServer library is not available to install in the Arduino IDE Library Manager. So, you need to install it manually. Click here to download the https://github.com/me-no-dev/ESPAsyncWebServer/archive/master.zip library. You should have a .zip folder in your Downloads folder Unzip the .zip folder and you should get ESPAsyncWebServer-master folder Rename your folder from ESPAsyncWebServer-master to ESPAsyncWebServer Move the ESPAsyncWebServer folder to your Arduino IDE installation libraries folder Installing the ESPAsync TCP Library The ESPAsyncWebServer library requires the ESPAsyncTCP library to work. Follow the next steps to install that library: Click here to download the https://github.com/me-no-dev/ESPAsyncTCP/archive/master.zip library. You should have a .zip folder in your Downloads folder Unzip the .zip folder and you should get ESPAsyncTCP-master folder Rename your folder from ESPAsyncTCP-master to ESPAsyncTCP Move the ESPAsyncTCP folder to your Arduino IDE installation libraries folder After installing the libraries, restart your Arduino IDE. Code Install the ESP8266 Board in Arduino IDE Open your Arduino IDE and copy the following code. How the Code Works In the following paragraphs we’ll explain how the code works. Keep reading if you want to learn more or jump to the Demonstration section to see the final result. Importing libraries First, import the required libraries. Subscribe and Download code. #include #include #include #include #include #include #include Setting your network credentials Insert your network credentials in the following variables, so that the ESP8266 can connect to your local network. const char* ssid = "REPLACE_WITH_YOUR_SSID"; const char* password = "REPLACE_WITH_YOUR_PASSWORD"; Variables definition Define the GPIO that the DHT data pin is connected to. In this case, it’s connected to GPIO5 (D1). #define DHTPIN 5 // Digital pin connected to the DHT sensor Then, select the DHT sensor type you’re using. In our example, we’re using the DHT22. If you’re using another type, you just need to uncomment your sensor and comment all the others. #define DHTTYPE DHT22 // DHT 22 (AM2302) Instantiate a DHTobject with the type and pin defined earlier. DHT dht(DHTPIN, DHTTYPE); Create an AsyncWebServerobject on port 80. AsyncWebServer server(80); Create float variables to hold the current temperature and humidity values. The temperature and humidity are updated in the loop(). float t = 0.0; float h = 0.0; Create timer variables needed to update the temperature readings every 10 seconds. unsigned long previousMillis = 0; // will store last time DHT was updated // Updates DHT readings every 10 seconds const long interval = 10000; Building the Web Page Proceeding to the web server page. As you can see in the above figure, the web page shows one heading and two paragraphs. There is a paragraph to display the temperature and another to display the humidity. There are also two icons to style the page. Let’s see how this web page is created. All the HTML text with styles included is stored in the index_html variable, refer in final code. The tags display the fontawesome icons. How to display icons To chose the icons, go to the Font Awesome Icons website. Search the icon you’re looking for. For example, “thermometer”. Click the desired icon. Then, you just need to copy the HTML text provided. To chose the color, you just need to pass the style parameter with the color in hexadecimal, as follows: Proceeding with the HTML text… The next line writes the word “Temperature” into the web page. Temperature The TEMPERATURE text between % signs is a placeholder for the temperature value. %TEMPERATURE% This means that this %TEMPERATURE% text is like a variable that will be replaced by the actual temperature value from the DHT sensor. The placeholders on the HTML text should go between % signs. Finally, we add the degree symbol. °C The tags make the text superscript. We use the same approach for the humidity paragraph, but it uses a different icon and the %HUMIDITY% placeholder. Humidity %HUMIDITY% % Automatic Updates Finally, there’s some JavaScript code in our web page that updates the temperature and humidity automatically, every 10 seconds. Scripts in HTML text should go between the tags. To update the temperature on the background, we have a setInterval() function that runs every 10 seconds. Basically, it makes a request in the /temperature URL to get the latest temperature reading. xhttp.open("GET", "/temperature", true); xhttp.send(); }, 10000 ) ; When it receives that value, it updates the HTML element whose id is temperature. if (this.readyState == 4 && this.status == 200) { document.getElementById("temperature").innerHTML = this.responseText; } In summary, this previous section is responsible for updating the temperature asynchronously. The same process is repeated for the humidity readings. Processor Now, we need to create the processor() function, that will replace the placeholders in our HTML text with the actual temperature and humidity values. String processor(const String& var){ //Serial.println(var); if(var == "TEMPERATURE"){ return String(t); } else if(var == "HUMIDITY"){ return String(h); } return String(); } When the web page is requested, we check if the HTML has any placeholders. If it finds the %TEMPERATURE% placeholder, we return the temperature that is stored on the t variable. if(var == "TEMPERATURE"){ return String(t); } If the placeholder is %HUMIDITY%, we return the humidity value. else if(var == "HUMIDITY"){ return String(h); } setup() In the setup(), initialize the Serial Monitor for debugging purposes. Serial.begin(115200); Initialize the DHT sensor. dht.begin(); Connect to your local network and print the ESP8266 IP address. WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } Finally, add the next lines of code to handle the web server. server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", index_html, processor); }); server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", String(t).c_str()); }); server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", String(h).c_str()); }); When we make a request on the root URL, we send the HTML text that is stored on the index_html variable. We also need to pass the processorfunction, that will replace all the placeholders with the right values. server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", index_html, processor); }); We need to add two additional handlers to update the temperature and humidity readings. When we receive a request on the /temperature URL, we simply need to send the updated temperature value. It is plain text, and it should be sent as a char, so, we use the c_str() method. server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", String(t).c_str()); }); The same process is repeated for the humidity. server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", String(h).c_str()); }); Lastly, we can start the server. server.begin(); In the loop() is where we get new temperature readings from the sensor every 10 seconds. Basically, we check if it is time to get new sensor readings: if (currentMillis - previousMillis >= interval) { If it is, we store a new temperature reading on the newT variable float newT = dht.readTemperature(); If the newT variable is a valid temperature readings, we update the t variable. else { t = newT; Serial.println(t); } The same process is repeated for the humidity. // Read Humidity float newH = dht.readHumidity(); // if humidity read failed, don't change h value if (isnan(newH)) { Serial.println("Failed to read from DHT sensor!"); } else { h = newH; Serial.println(h); } That’s pretty much how the code works. Finally Download CODE: https://drive.google.com/file/d/1C4Qu_AJqVkhTDFliZJOYqxuSErOp4h6P/view?usp=sharing Subscribe and Download code.

  • Voice Controlled Home automation using Bluetooth

    Here is a simple tutorial for interfacing an Android smartphone with Arduino via Bluetooth! The main parts to this project. An Android smartphone and application, a Bluetooth transceiver, and an Arduino. We just need an Arduino UNO to serially communicate with HC-05 Bluetooth module and a smartphone to send voice command to Bluetooth module HC-05. Circuit Diagram: Connection made as per circuit diagram. The Following parts are required for this project: 1) Arduino Uno R3 2) HC-05 or HC-06 3) 4 channel Relay module 4) Android smartphone 5) 9V power supply Make the circuit as is given by the circuit diagram. Make the robot assembly with your selected parts and connect the motors to the circuit. 1) The VCC of HC-05 to 5V of Arduino 2) The GND of HC-05 to GND of Arduino 3) The TX of HC-05 to RX of Arduino (Digital power pin 0) 4) The RX of HC-05 to TX of Arduino (Digital power pin 1) Then Power on the Arduino. The HC-05 should power up if all connections are perfect. The LED on the HC-05 Module will continuously blink which means the device is now discoverable. When you are connecting to the Bluetooth module for the first time, it will ask you the password. Enter 0000 OR 1234. When the device gets successfully paired with the android smart phone. The Arduino Bluetooth module at the other end receives the data and sends it to the Arduino through the TX pin of the Bluetooth module (connected to RX pin of Arduino) The idea is to use the App to turn ON and OFF the LEDS and also controlling their intensity. Connections: Device 1: “device1on / device1off” ==> LED Red ==> Pin 3 UNO Device 2: “device2on / device2off” ==> LED Yellow ==> Pin 5 of the UNO Device 3: “device3on / device3off” ==> LED Green ==> Pin 6 UNO Device 4: “device4on / device4off” ==> LED Blue ==> Pin 9 of the UNO Loop: { while (BT.available()) //Check if there is an available byte to read { delay(10); //Delay added to make thing stable char c = BT.read(); //Conduct a serial read device += c; //build the string. } if (device.length() > 0) { Serial.println(device); // Button control: if (device == "One") {digitalWrite(Device1, HIGH);} else if (device == "Two") {digitalWrite(Device1, LOW);} else if (device == "Three") {digitalWrite(Device2, HIGH);} else if (device == "Four") {digitalWrite(Device2, LOW);} else if (device == "Five") {digitalWrite(Device3, HIGH);} else if (device == "Six") {digitalWrite(Device3, LOW);} else if (device == "Seven") {digitalWrite(Device4, HIGH);} else if (device == "Eight") {digitalWrite(Device4, LOW);} That is, to trigger the “ON” related to “Device 1” button, the text message “device1on” will be sent to the Arduino. Upon receiving this message, the red LED should light and so on. Note that the 4 pins are the pins capable of generating PWM. This is important for the use of “sliders” at the App, to send numeric data to control the intensity of the LEDs through PWM: Device A0: “r / 0-255” ==> LED Red ==> Pin 3 UNO Device A1 “y / 0-255” ==> LED Yellow ==> Pin 5 of the UNO Device A2: “g / 0-255” ==> LED Green ==> Pin 6 UNO Device A3: “b / 0-255” ==> LED Blue ==> Pin 9 do UNO In the case of sliders, before the PWM data value (0 to 255), a character is sent to the Arduino to inform it that a ”slider” command is coming. In the video bellow, a demonstration of the portion above program (Buttons & Slider): The slider code: // Slider control: char colour = device[0]; int value = device[2]; Serial.print(" "); Serial.println(value); if ( colour == 'r') //RED LED { analogWrite(Device1, value); // use value to set PWM for LED brightness } if ( colour == 'y') //yellow LED { analogWrite(Device2, value); // use value to set PWM for LED brightness } if ( colour == 'g') //green LED { analogWrite(Device3, value); // use value to set PWM for LED brightness } if ( colour == 'b') //BLUE LED { analogWrite(Device4, value); } device=""; //Reset the variable } The following voice command to control the LED on/off through voice to text command from android device through bluetooth HC-05. The bluetooth sent text data to the arduino and control LED on/off respectively. // Voice control: else if (device == "TV on" || device == "turn on TV") {digitalWrite(Device1, HIGH);} else if (device == "TV off" || device == "turn off TV") {digitalWrite(Device1, LOW);} else if (device == "light on" || device == "turn on light") {digitalWrite(Device2, HIGH);} else if (device == "light off" || device == "turn off light") {digitalWrite(Device2, LOW);} else if (device == "fan on" || device == "turn on fan") {digitalWrite(Device3, HIGH);} else if (device == "fan off" || device == "turn off fan") {digitalWrite(Device3, LOW);} else if (device == "5" || device == "turn on AC") {digitalWrite(Device4, HIGH);} else if (device == "7" || device == "turn off AC") {digitalWrite(Device4, LOW);} ANDROID APPLICATION The Android app developers generally use JAVA language, but this Android app can also build without knowing the Java language. This app was developed in the online Development Environment which is developed by MIT called “App Inventor”. This app inventor is specially designed for Block programmers those who don’t know the JAVA language. The app shown below has buttons and all the buttons give different bytes in the output that has to be sent to the Arduino using Bluetooth for processing. Demo: Download code: App: https://drive.google.com/file/d/1qd3ByJEpwfPVbR2NaYhI_YoHhzzRsvYU/view?usp=sharing Arduini code: https://drive.google.com/file/d/1PjiEUYMd3z4bI1PzbwpNdYWZA4FgXppx/view?usp=sharing Subscribe and Download code.

  • Gesture Controlled Bot Using arduino & Bluetooth (Two way control)

    To make a car that can be controlled using the accelerometer in a android phone. We can use the data from the accelerometer and transmit it to arduino using bluetooth module HC-05. It will help you in building a gesture based android controlled robot without any experience in android app development by providing you the free android app. The communication between the robot and the android application is carried over by the Bluetooth link between the phone’s Bluetooth and the Bluetooth device in the Robot. The ASCII commands are sent from the phone to the Robot which in turn checked by the Arduino for the control of the wheels according to the commands to move the robot in the desired direction. The Following parts are required for this project: 1) Arduino Uno R3 2) HC-05 or HC-06 3) Chassis With Motors 4) Breadboard 5) L293D Motor Driver Board 6) 9V Batteries with battery Caps (2 battery and 2 caps) 7) Jumper Cables 8) Android Phone for controlling the bot Make the circuit as is given by the circuit diagram. Make the robot assembly with your selected parts and connect the motors to the circuit. 1) The VCC of HC-05 to 5V of Arduino 2) The GND of HC-05 to GND of Arduino 3) The TX of HC-05 to RX of Arduino (Digital power pin 0) 4) The RX of HC-05 to TX of Arduino (Digital power pin 1) Then Power on the Arduino. The HC-05 should power up if all connections are perfect. The LED on the HC-05 Module will continuously blink which means the device is now discoverable. Go to the settings of the Android phone search for bluetooth. Make sure your device is discoverable. The default name of the module is HC-05 and the default password is 1234. Pair the device with your phone. If paired Successfully you will see a change in the blinking of the LED on HC-05 Module. The LED will blink less frequently if the device is paired Successfully. We are using L293D Motor driver Board because arduino only gives a output of 5V from the digital pins. 5V are not enough to run 2 DC motors. L293D Motor driver board gives us the option to supply power to the motors externally using a battery. If you look at the L293D carefully you will find 4 Pins for output and 4 Pins for input. Connect the Output Pins to the motors and input pins will later be connected to the arduino. There Will Also Be A Set Of Pins + and - Which Need To Be Powered By External 9V Battery. Arduino Can be easily be programmed by using its IDE. refer arduino iDE installion project in previous post in our website. const int motor1Pin1 = 3; const int motor1Pin2 = 4; const int motor2Pin1 = 10; const int motor2Pin2 = 11; byte serialA; void setup() { // initialize the serial communication: Serial.begin(9600); //baud rate - make sure it matches that of the module you got: // initialize the ledPin as an output: pinMode(motor1Pin1, OUTPUT); pinMode(motor1Pin2, OUTPUT); pinMode(motor2Pin1, OUTPUT); pinMode(motor2Pin2, OUTPUT); } void loop() { if (Serial.available() > 0) {serialA = Serial.read();Serial.println(serialA);} switch (serialA) { case 0: digitalWrite(motor1Pin1, LOW); digitalWrite(motor1Pin2, LOW); digitalWrite(motor2Pin1, LOW); digitalWrite(motor2Pin2, LOW); break; case 1: digitalWrite(motor1Pin1, HIGH); digitalWrite(motor1Pin2, LOW); digitalWrite(motor2Pin1, HIGH); digitalWrite(motor2Pin2, LOW); break; case 2: digitalWrite(motor1Pin1, LOW); digitalWrite(motor1Pin2, HIGH); digitalWrite(motor2Pin1, LOW); digitalWrite(motor2Pin2, HIGH); break; case 3: digitalWrite(motor1Pin1, LOW); digitalWrite(motor1Pin2, LOW); digitalWrite(motor2Pin1, HIGH); digitalWrite(motor2Pin2, LOW); break; case 4: digitalWrite(motor1Pin1, HIGH); digitalWrite(motor1Pin2, LOW); digitalWrite(motor2Pin1, LOW); digitalWrite(motor2Pin2, LOW); break; } } ANDROID APPLICATION The Android app developers generally use JAVA language, but this Android app can also build without knowing the Java language. This app was developed in the online Development Environment which is developed by MIT called “App Inventor”. This app inventor is specially designed for Block programmers those who don’t know the JAVA language. The app shown below has buttons and all the buttons give different bytes in the output that has to be sent to the Arduino using Bluetooth for processing. For eg. if we press forward button, the Bluetooth Module will give 1 byte at its output, which is received by the Arduino to process the byte and take necessary action. The app consists of the option to use the accelerometer of the Android phone or to use the buttons to control the Robot. You can find tutorials related to the App inventor in its website. Step1: Step2: Step3: Step4: Step5: Step6: Step7: Step8: Demo: download app: https://drive.google.com/file/d/17VMHbsEUSGCthyf3IziY06zqpQQ3m8S7/view?usp=sharing Subscribe and Download code.

  • Dot Matrix LED Clock, Event, Temperature & Humidity Display

    It’s a simple Clock, Event message, temperature and humidity display, and so far it’s working pretty well. It’s built around an Arduino Mega2560, rtc DS1307 and uses a DHT11 sensor. Components: 1. arduino mega2560 2. RTC DS1307 3. DHT11 4. Push button Switch - 3nos .5. Dot matrix module - 8 nos 6. LDR 7. 10k resistor Circuit diagram: arduino Code: /* Clock project using two MX7219 matrix displays and the AdaFruit FX Soundboard Provides date, time, temp, humidity and event notifications in rotating order Also can chime in multiple ways, including Westminster chimes Chimes are provided by Adafruit FX Soundboard in GPIO mode */ // Code to set up the clock // Pushbutton 1 is the toggler , cycle between year, month, day, hours, minutes, seconds // Pushbutton 2 is the increment up one // Pushbutton 3 is the decrement down one // Chime setup for toggle switch // Center = No chimes // Up = Westminster hours + quarterly // Down = Simple Bell (hours and 1/2 hour) // Comment out next line to leave out the little show #define showoffcode // include "show off" graphics at startup // include the libraries for LCD Display, DHT-11 Temperature/humidity sensor and DS3231 RTC and // include libraries for bigger seven segment display with backpack #include "DHT.h" #include #include "RTClib.h" #include // uncomment next two lines to use UART for SoundBoard rather than GPIO //#include //#include // Set up output functions #define DHTPIN A1 //Temp Humidity sensor on pin 9 #define DHTTYPE DHT11 // DHT 11 because the sensor is that type // Initialize DHT sensor for normal 16mhz Arduino DHT dht(DHTPIN, DHTTYPE); // Initialize for Adafruit DS3231 RTC real time clock RTC_DS3231 rtc; // uncomment next set of lines to use UART for SoundBoard /* // Choose any two pins that can be used with SoftwareSerial to RX & TX for UART SoundBoard //#define SFX_TX 5 //#define SFX_RX 6 // Connect to the RST pin on the Sound Board #define SFX_RST 4 // You can also monitor the ACT pin for when audio is playing! // we'll be using software serial //SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); // pass the software serial to Adafruit_soundboard, the second // argument is the debug port (not used really) and the third // arg is the reset pin //Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, SFX_RST); // can also try hardware serial with // Adafruit_Soundboard sfx = Adafruit_Soundboard(&Serial1, NULL, SFX_RST); */ // Define the number of devices we have in the chain and the hardware interface // NOTE: These pin numbers will probably not work with your hardware and may // need to be adapted #define HARDWARE_TYPE MD_MAX72XX::FC16_HW // NOTE: This parameter differs by vendor #define MAX_DEVICES 8 // 2 x 4 matrices per unit //Pins for Arduino Uno //#define CLK_PIN 13 // or SCK (this is for the UNO, different for the Mega //#define DATA_PIN 11 // or MOSI //#define CS_PIN 10 // or SS //Pins for Arduino Mega #define CLK_PIN 52 // or SCK 13 #define DATA_PIN 51 // or MOSI 11 #define CS_PIN 53 // or SS 10 // SPI hardware interface MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES); // We always wait a bit between updates of the display #define DELAYTIME 100 // in milliseconds // Text parameters #define CHAR_SPACING 1 // pixels between characters //const int CHAR_PIXELS = 6; // Pixels taken by each character (including trailing space) //const int MAX_CHARS = (MAX_DEVICES*COL_SIZE)/ CHAR_PIXELS; // Maximum characters at once (happens to be 10 btw) //const int LEFT_OVER = (MAX_DEVICES*COL_SIZE)- (CHAR_PIXELS*MAX_CHARS); //Since its not 'even' additional pad from front on printText const int BufferStringLength = 31; char BufferString [BufferStringLength]; //used to construct printouts #define DecToAscii 48 // convert number to ascii (add as a constant) #define DegreeSign 0x0090 // for display of 'degrees' after temperature int TDigits[4] = {0, 0, 0, 0}; // used to convert four digits to four chacacters #define TDOnes 3 // positions in arrays and templates #define TDTens 2 #define TDHundreds 1 #define TDThousands 0 #define sunday 0 // used for events, floating events and holidays #define monday 1 // just for readability #define thursday 4 #define january 1 #define february 2 #define march 3 #define april 4 #define may 5 #define june 6 #define july 7 #define august 8 #define september 9 #define october 10 #define november 11 #define december 12 //Template Strings and pointers const int LOTS = 13; // Length of TimeString (without terminator) char TimeString[LOTS + 1 ] = {' ', ' ', '1', '2', ':', '3', '1', ':', '4', '5', ' ', 'P', 'M', '\0'}; char DateString[ ] = {'1', '2', '/', '3', '1', '/', '2', '0', '1', '9', '\0'}; char TempString[ ] = {'T', 'e', 'm', 'p', ' ', '7', '2', '.', '0', DegreeSign, 'F', '\0'}; char HumidString[ ] = {'H', 'u', 'm', ' ', '2', '5', '.', '0', '%', '\0'}; const int THptr = 2; // Pointers within the strings const int TMptr = 5; // for loading values const int TSptr = 8; const int TAMPMptr = 11; const int DMptr = 0; const int DDptr = 3; const int DYptr = 6; const int TEMPptr = 5; const int HUMIDptr = 4; // Differentiated Displays const int DisplayTime = 0; const int DisplayDate = 2; const int DisplayDOW = 1; const int DisplayTemp = 3; const int DisplayHumid = 4; const int DisplayEvent = 5; const int DisplayEventRepeat = 2; //times to repeat the scrolling 'event' display const int DisplaySize = 6; // Nunber of different displays int DisplayIndex = DisplayTime; // display we are on at the time const int DisplayDelayArray[DisplaySize] = {100, 50, 30, 30, 30, 20}; // multiplier for each event const int DisplayDelay = 100; // milliseconds to leave each display * its multiplier unsigned long DisplayTimer; // used to time each matrix display char daysOfTheWeek[7][12 ] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; // Event arrays // Load with month of 'event', day of event and description to be displayed const int eventnumber = 21; // number of events and remember: No strings longer than 30 characters! int eventmonth [eventnumber] = {june, april, november, february, july, december, november, june, december, june, march, december, january, september, october, march, february, february, july,december, february}; int eventday [eventnumber] = {11, 1, 23, 12, 4, 3, 12, 29, 25, 18, 17, 31, 1, 3, 31, 17, 14, 2, 14, 30,12}; char* eventdescription [eventnumber] = { Enter here special days ""New Year's Eve", "New Year's Day", " }; bool event; // logic flag "on" = event found int eventindex; // and the event we found const int maxevents = 3; // maximum of three events (real and floating combined) char* eventstrings[maxevents] ; // used to store displayed events String floatstring = " "; // used for floating events (e.g., Thanksgiving) #define pb1pin 2 // Pin assignments for reset, increment and decrement #define pb2pin 3 #define pb3pin 4 #define showoffbuttonpin 7 // invoke showing off the matrix display #define DoWestminster 5 #define DoHoursOnly 6 #define silent 0 // no chiming at all #define hoursonly 1 // no prelude, just chime number of hours and half hour single chime #define westminster 2 // hours + Westminster prelude per quarter int ChimeValue = silent; // default to silent const int LEDpin = A0; // Pin assignment for analog reading LDR for LED brightness const int minbright = 0; // MAX_BRIGHT for this module is 15 const int midbright = 2; // but these values "seem" to work const int maxbright = 4; int setupindex = 0; // first thing to set if required bool insetupmode = false; // and assume RTC is set, OK, etc., and no 'set' required bool setinsetup = false; // flag set to true at interrupt level to go back into setup mode // date time array for setting, reading, displaying #define setsize 6 // size of the setting array #define setyear 0 // index name for each element #define setmonth 1 #define setday 2 #define sethour 3 #define setminute 4 #define setsecond 5 int setarray [setsize] = {2019, 1, 1, 1, 1, 0}; // set year, month, day, hour, minutes, seconds int lowlimit [setsize] = {2019, 1, 1, 0, 1, 0}; // lower limit for each int highlimit [setsize] = {2080, 12, 31, 23, 59, 59}; //high limit for each const int setdesclength = 4; // maximum length of 'set' descriptor char setdesc [setsize] [setdesclength] = {"Yr ", "Mon", "Day", "Hr ", "Min", "Sec"}; #define cqtr0 1 // Chime the hour #define cqtr1 2 // Chime the quarter hour #define cqtr2 3 // Chime the half hour #define cqtr3 4 // Chime the 3/4 hour // Definitions for the Sound Board #define SoundTruncatedSingle 0 // Truncated Single Westminster #define SoundQ1 1 // First Quarter #define SoundQ2 2 // Second Quarter #define SoundQ3 3 // Third #define SoundQ4 4 // Fourth (before hour chime) #define SoundTrailingSingle 5 // Finish Westminster string of chimes with longer sound tail #define SoundTruncatedBell 6 // Simple Bell #define SoundTrailingBell 7 // Final Bell (like single, has longer 'tail') #define SoundStartup 8 // startup sound #define SoundShowOff 9 // Play during show off of matrix #define FirstSoundPin 30 // first pin to use for soundboard (0-10 available on soundboard); #define SizeSoundPin 10 // number of pins used (must be consecutive) #define fxset 150 // Time soundboard must be held LOW to register (documentation says 125 ms) #define SoundBusyPin 8 // Soundboard pin that goes LOW when board is active const int SizeQueue = 15; // Assume Q4+12 bells is the maximum that'll be in the queue at any point int SoundQueue[SizeQueue]; // Circular Queue for waiting sounds int SoundQueuePtr = -1; //pointer for Queue fill Position int SoundPlayPtr = -1; //pointer for Queue play Position int SoundQueueCtr = 0; // number of items in the queue int setstrike = -1; // Chime/strike flag byte alreadychimed = false ; // Used to keep from chiming multiple times during the "hot" second const int BounceDelay = 250; // Not really 'bounce', its a change of state detection int i; // generic index variable int dayoftheweek; // stored day of the week (0-6, 0 = Sunday) int phours; // for print conversion of military time float temperaturef; // farenheit temperature back int temperature; // integer version of temperature for matrix float temperaturec; // centrigade temperature back (not used) float humidityf; // and humidity int humidity ; // and same as temp float tempadjust = 0; // temperature adjustment for sensor (I found it didn't read right against 'comps') byte degreesymbol = 223; // LCD output of 'degree' symbol #define DDT #ifdef DDT // debugging tools void DDTl(String st, int vt) { // Print descriptor and value and new line DDTs(st, vt); Serial.println(" "); } void DDTs(String st, int vt) { // Print descriptor and value Serial.print(" "); Serial.print(st); Serial.print(" "); Serial.print(vt); } #endif //DDT// void setup() // put your setup code here, to run once: { Wire.begin(); // initialize I2C interface dht.begin(); // initialize the temp/humidity sensor mx.begin(); // and MX7219 display Serial.begin (9600); //Terminal monitor printing for debugging // softwareserial at 9600 baud (uncomment this line and next for UART control of sound board // ss.begin(9600); pinMode(pb1pin, INPUT_PULLUP); // The three pushbuttons - reset pinMode(pb2pin, INPUT_PULLUP); // increment pinMode(pb3pin, INPUT_PULLUP); // decrement pinMode (DoWestminster, INPUT_PULLUP); // When pulled 'low' we want Westminster chimes pinMode (DoHoursOnly , INPUT_PULLUP); // When pulled 'low' we want hours and 1/2 bell (neither is 'silent') #ifdef showoffcode pinMode(showoffbuttonpin, INPUT_PULLUP) ; // if show off matrix is there, initialize pin #endif //showoffcode// for (i = FirstSoundPin; i < FirstSoundPin + SizeSoundPin; i++) { // pins for sound board pinMode(i, OUTPUT); // each an output digitalWrite(i, HIGH); // and initialize high (off) } // set up interupt for PB1 // if PB1 is pushed, it'll pick up on next release from Matrix display attachInterrupt(digitalPinToInterrupt(pb1pin), SetToSetup, FALLING); // and re-enter setup mode (after the end of current display) #ifdef showoffcode // ShowOff(); // Show off a little (uncomment to give initial showoff at beginning) #endif //showoffcode// QueueSound(SoundStartup); // play boot up sound PlaySound(); if (! rtc.begin()) { // check that clock is there scrollText("Couldn't find RTC"); // clock missing is a fatal error while (1); } if (rtc.lostPower()) { // if power lost force a setup, else load 'current' values and scrollText("RTC lost power!"); delay(1000); scrollText("Replace battery?"); delay(1000); scrollText("Setup Mode: "); setupindex = setyear - 1; // setup differently (becuase it will increment) insetupmode = true; for (i = 0; i < setsize; i++) { setarray[i] = lowlimit[i]; } } else // else reload from RTC { DateTime (setarray[setyear], setarray[setmonth], setarray[setday], setarray[sethour], setarray[setminute], setarray[setsecond]) = rtc.now(); insetupmode = false; // not in setup mode, and setinsetup = false; //no interrupt } // Two alternative modes of setting date and time (for debugging, just un-comment): // This line sets the RTC to the date & time this sketch was compiled // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // This line sets the RTC with an explicit date & time, for example to set // January 21, 2014 at 3am you would call: // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); LEDBrightness(); // Do an initial check for room brightness } // end of setup void loop() { // Main code divided into setup mode and non-setup mode while (insetupmode) { // code for setting time, date set, etc. // Read the increment button if (digitalRead(pb2pin) == LOW) { setarray[setupindex]++; // read increment of current item delay(BounceDelay); if (setarray[setupindex] > highlimit[setupindex]) { setarray[setupindex] = lowlimit[setupindex]; } ShowValue(setupindex, setdesc[setupindex]); // and display description and value } // Read the decrement Button if (digitalRead(pb3pin) == LOW) { setarray[setupindex]--; // read decrement of value delay(BounceDelay); if (setarray[setupindex] < lowlimit[setupindex]) { setarray[setupindex] = highlimit[setupindex]; } ShowValue(setupindex, setdesc[setupindex]); // and display description and value } // Read for another increment of index if (digitalRead(pb1pin) == LOW) { // Rolling through Chime, Year, Month, Day, Hour, Minutes, Seconds setupindex++ ; // increment index delay(BounceDelay); if (setupindex < setsize) { ShowValue(setupindex, setdesc[setupindex]); // show description and value if in bounds } if (setupindex >= setsize) { // and finally exiting setup mode after setting chime, date and time rtc.adjust(DateTime(setarray[setyear], setarray[setmonth], setarray[setday], setarray[sethour], setarray[setminute], setarray[setsecond])); insetupmode = false; DisplayIndex = DisplayTime; } //exit setup mode when done } } // End of "While" for setup // Begin regular loop for date, time, temp humidity and event display while (!insetupmode) { GetTempandHumid(); // read temperature and humidity from sensor ChimeValue = ReadChimeSetting(); // read SPDT Center off switch for silent, westminster or hours only (and 1/2) GetTheDate(); // load date array from RTC for a chime/bell check CheckForChime(); // Check for a chime event between displays CheckForEvent(setarray[setmonth], setarray[setday], dayoftheweek); // check for static and floating events MatrixDisplay(); // Do whatever display is required on the MX7219 LEDBrightness(); // Good place to check for change in room brightness // end of display update logic // Read a potential request for an entry into setup from PB 1 if ((digitalRead(pb1pin) == LOW) || setinsetup) { // to see if we go back to setup mode insetupmode = true; // via a pushbutton or the interrupt setinsetup = false; // clear the interrupt flag setupindex = 0; // re-initialize to 'Year' in setup DisplayIndex = DisplayTime; // and go back to time display when exit setup scrollText("Setup Mode: "); delay(2000); ShowValue(setupindex, setdesc[setupindex]); // show the first setup item (Year) delay(BounceDelay); } #ifdef showoffcode if (digitalRead(showoffbuttonpin) == LOW) {ShowOff();} // check for want to show off matrix #endif //showoffcode// } // end of not in setup } // end of sketch void MatrixDisplay() { // Main display routine for display sequences Scrollup(); // Clear last display if (DisplayIndex >= DisplaySize) { DisplayIndex = DisplayTime; // reset if at the end } DisplayTimer = DisplayDelayArray[DisplayIndex] * DisplayDelay; // set individual display time switch (DisplayIndex) { // and do next display case DisplayTime: // Dislay the time do // time is different in that there's a constant { // update of time during display and also play chime, bell etc. GetTheDate(); // Get Current Time CheckForChime(); // Check for a chime event LoadNumber(phours); // Load the 4 digit character array from number TimeString[THptr] = TDigits[TDTens]; // left digit of the two digit hour TimeString[THptr + 1] = TDigits[TDOnes]; // rightmost digit if (TimeString[THptr] == '0') { TimeString[THptr] = ' '; // eliminate leading zero } LoadNumber(setarray[setminute]); // do same for minutes TimeString[TMptr] = TDigits[TDTens]; // except no need to do space for zero TimeString[TMptr + 1] = TDigits[TDOnes]; LoadNumber(setarray[setsecond]); // seconds then TimeString[TSptr] = TDigits[TDTens]; TimeString[TSptr + 1] = TDigits[TDOnes]; if (setarray[sethour] < 12) // and AM vs PM { TimeString[TAMPMptr] = 'A'; } else { TimeString[TAMPMptr] = 'P'; } printText(TimeString, LOTS, false); // Keep position (no centering) because time keeps updating during display and chimes PlaySound(); // Play any chimes or bells if (SoundQueueCtr == 0) { DisplayTimer = DisplayTimer - DisplayDelay; // if no sound, use display delay logic delay(DisplayDelay); } } while ((DisplayTimer > 0) || (SoundQueueCtr > 0)); // leave this display when no sound or no delay left DisplayIndex++ ; // then move on to next display item break; case DisplayDate: // Month, Day and Year Display LoadNumber(setarray[setmonth]); DateString[DMptr] = TDigits[TDTens]; if (DateString[DMptr] == '0') { DateString[DMptr] = ' '; } DateString[DMptr + 1] = TDigits[TDOnes]; LoadNumber(setarray[setday]); DateString[DDptr] = TDigits[TDTens]; DateString[DDptr + 1] = TDigits[TDOnes]; LoadNumber(setarray[setyear]); for (int i = 0; i < 4; i++) { DateString[DYptr + i] = TDigits[i]; } printCenter(DateString); CommonDelay(DisplayTimer); DisplayIndex++ ; break; case DisplayDOW: // Just display the day of week string printCenter(daysOfTheWeek[dayoftheweek]); CommonDelay(DisplayTimer); DisplayIndex++ ; break; case DisplayTemp: // Temperature display LoadNumber(temperature); TempString[TEMPptr] = TDigits[TDHundreds]; TempString[TEMPptr + 1] = TDigits[TDTens]; TempString[TEMPptr + 3] = TDigits[TDOnes]; printCenter(TempString); CommonDelay(DisplayTimer); DisplayIndex++ ; break; case DisplayHumid: // Humidity display LoadNumber(humidity); HumidString[HUMIDptr] = TDigits[TDHundreds]; HumidString[HUMIDptr + 1] = TDigits[TDTens]; HumidString[HUMIDptr + 3] = TDigits[TDOnes]; printCenter(HumidString); CommonDelay(DisplayTimer); DisplayIndex++ ; break; case DisplayEvent: // Event Display if (event) { // "Real" events repeat 3 times if (eventindex > 0 ) { // for case where there is more than one event while (eventindex >= 0) {scrollText(eventstrings[eventindex]); // scroll each of them once if (eventindex > 0) { delay(DisplayDelay * 6); printCenter("and"); delay(DisplayDelay * 6);} eventindex--; // and decrement delay(DisplayDelay * 2); } } else { // case of only one event -- repeat it for readability for (int i = 1; i <= DisplayEventRepeat; i++) { // scroll either static or floating event scrollText(eventstrings[eventindex]); // the index is 0 (greater than zero if multiple events) } delay(DisplayDelay * 2); } } // end of "if event" logic if (!event){ // Scroll Default message only once if (setarray[sethour] >= 6 && setarray[sethour] <= 11) { scrollText("Good Morning ");} else if (setarray[sethour] >= 12 && setarray[sethour] <= 16) { scrollText(" Afternoon");} else if (setarray[sethour] >= 17 && setarray[sethour] <= 21) { scrollText(" Evening");} else{scrollText("Good Night"); } } CommonDelay(DisplayTimer); DisplayIndex++ ; break; default: scrollText("Should never get here"); while (1); } // End of Switch } // End of MatrixDisplay void GetTheDate() { // Read RTC into array DateTime now = rtc.now(); setarray[setyear] = now.year(); setarray[setmonth] = now.month(); setarray[setday] = now.day(); setarray[sethour] = now.hour(); setarray[setminute] = now.minute(); setarray[setsecond] = now.second(); dayoftheweek = now.dayOfTheWeek(); if (setarray[sethour] <= 12) // convert military time to am pm { phours = setarray[sethour]; } else {phours = setarray[sethour] - 12;} if (phours <= 0) { phours = 12; } // don't print 0 for midnite, print "12" } // End of Get The Date void GetTempandHumid(){ // Temperature and humidity update // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) humidityf = dht.readHumidity(); // Read temperature as Fahrenheit temperaturef = (dht.readTemperature()) + tempadjust; // read and correct for inaccuracy in sensor // Check if any reads failed and exit early (to try again). if (isnan(humidityf) || isnan(temperaturec) || isnan(temperaturef)) { temperaturef = 0; // use 0 as a no-read humidityf = 0; // error indication } temperature = temperaturef * 10.0; // get read for matrix printout humidity = humidityf * 10.0; } // end of Temperature and Humidity update void SetToSetup() { // interrupt level back to setup if ((!insetupmode) && (!setinsetup)) { // skip if we are already in Setup mode or have seen the interrupt setinsetup = true; // Go back into setup at next loop DisplayTimer = 0; } // and zero the timer to speed that up if you can } // SetToSetup void CommonDelay(long int MyDelay) { // Common delay routine DisplayTimer = MyDelay; do { DisplayTimer = DisplayTimer - DisplayDelay; delay(DisplayDelay); GetTheDate(); // load date array from RTC for a chime/bell check CheckForChime(); // if a chime happens, setup to end delay } while ((DisplayTimer > 0) && (!setinsetup) && (SoundQueueCtr <= 0)); // repeat while still time and no interrupt and no sound waiting if (SoundQueueCtr > 0){DisplayIndex = DisplayTime-1;} // if leaving due to chime, go directly to time } // End of CommonDelay int ReadChimeSetting() { int returnvalue = silent; // Assume 'silent' (Center position) if (digitalRead(DoWestminster) == LOW) { returnvalue = westminster; } else if (digitalRead(DoHoursOnly) == LOW) { returnvalue = hoursonly; } return returnvalue; } // Routine to deal with combinations of chime type, time of day and the current hour // called parameters are chime type (e.g., Westminster), Strike type (hour, qtr, half, 3/4) and the hour in military time // Note for delays and print cycles: You need to call this at least once during the 'golden' minute (0,15,30,45) void CheckForChime() { // Logic for chiming setstrike = -1; // initialize 'strike' flag to "no strike" if (ChimeValue != silent) // if silenced due to setting silent, skip the whole thing { if (setarray[setminute] == 0) { // Look for 'on the hour' setstrike = cqtr0; } else if (setarray[setminute] == 15 ) { // Look for on the quarter hour setstrike = cqtr1; } else if (setarray[setminute] == 30 ) { // Look for on the 1/2 hour setstrike = cqtr2; } else if (setarray[setminute] == 45 ) { // Look for on the three-quarter hour setstrike = cqtr3; } else { alreadychimed = false; // none of the above, reset ability to chime } if (setstrike > 0 && !alreadychimed ) { chime(ChimeValue, setstrike, setarray[sethour]); // call chiming with 'type of chime'; 0,15,30,45 ; and # hours DisplayIndex = DisplayTime; // force display of time while chiming alreadychimed = true; // we will be here multiple times but only chime once } } // end of logic for chiming } // end of CheckForChime void chime (int chimetype, int strikeflag, int chour) { int chour1; // am pm variable\ if (chour <= 12) { chour1 = chour; // convert military time to am pm } else { chour1 = chour - 12; } if (chour1 <= 0) { chour1 = 12; // don't chime 0 for midnite, chime 12 } if (chimetype == hoursonly && strikeflag == cqtr2) { QueueSound(SoundTrailingBell); // 1/2 hour only, do single 'ding' } else if ( chimetype == hoursonly && strikeflag == cqtr0) { for (int i = 1; i < chour1; i++) { QueueSound(SoundTruncatedBell); // Ding once less than hours } QueueSound(SoundTrailingBell); } // and follow by trailing bell as last 'ding' (if used) else if (((chimetype == westminster) ) && strikeflag == cqtr1) { QueueSound(SoundQ1); // First Quarter } else if (((chimetype == westminster) ) && strikeflag == cqtr2) { QueueSound(SoundQ2); // Second Quarter } else if (((chimetype == westminster)) && strikeflag == cqtr3) { QueueSound(SoundQ3); // Third Quarter } else if (((chimetype == westminster)) && strikeflag == cqtr0) { QueueSound(SoundQ4); for (int i = 1; i < chour1; i++) { QueueSound(SoundTruncatedSingle); // Chime once less than hours } QueueSound(SoundTrailingSingle); } // Chime Westminster final hours } // end of Chime // Routine to check for 'real' (static) events and floating events (e.g., Memorial Day, Thanksgiving, Mother's Day and Fathers Day) /* Memorial Day is Last Monday in May Thanksgiving is 4th Thursday in November Mother's Day is 2nd Sunday in May Father's Day is 3rd Sunday in June MLK Day is 3rd Monday in February Memorial Day is last Monday in May Labor Day is first Monday in September Daylight Savings Times starts 2nd Sunday in March Daylight Savings Times ends first Sunday in November Indigenous People's Day is second Monday in October (also its Columbus Day) */ void CheckForEvent(int m, int d, int dow) { // called with Month, Day within month and day of the week (0 = Sunday) event = false; // assume neither static or floating eventindex = -1; // initial index to eventstrings // Static event check for (int i = 0; i < eventnumber; i++) { // then check the static events if ((setarray[setmonth] == eventmonth[i]) && (setarray[setday] == eventday[i])) { event = true; // set if match on month and day eventindex++; // found one! eventstrings[eventindex] = eventdescription[i]; // store pointer to static event description } } // Floating event check floatstring = "none"; // initialize string if ((dow == thursday) && (m == november) && (d >= 22) && (d <= 28)) { // Thanksgiving floatstring = "Thanksgiving"; } else if ((dow == sunday) && (m == may) && (d >= 8) && (d <= 14)) { // Mother's Day floatstring = "Mother's Day"; } else if ((dow == sunday) && (m == june) && (d >= 15) && (d <= 21)) { //Father's Day floatstring = "Father's Day"; } else if ((dow == monday) && (m == september) && (d <= 7) ) { //Labor Day floatstring = "Labor Day"; } if (floatstring != "none" ) { // did we load anything? event = true; // if so, then we have one eventindex++; // so load it into event display queue eventstrings[eventindex] = floatstring.c_str(); // store pointer to static event description } } // end of floatingevent void LEDBrightness() { int LEDvalue; LEDvalue = analogRead(LEDpin); // Read LDR value (may need to play with values) DDTs("LED value",LEDvalue); LEDvalue = map(LEDvalue, 0, 1023, 0, MAX_INTENSITY); //map to valid value for brightness (max intensity is 15 btw) if (LEDvalue <= 11) { mx.control(MD_MAX72XX::INTENSITY, minbright);} else if (LEDvalue > 13 ) { mx.control(MD_MAX72XX::INTENSITY, maxbright); } else {mx.control(MD_MAX72XX::INTENSITY, midbright); } DDTl("Mapped LED value", LEDvalue); } //end of LEDbrightness void Scrollup() { // used to 'wipe' previous display for (uint8_t i = 0; i < 8; i++) { mx.transform(MD_MAX72XX::TSU); delay(2 * DELAYTIME); delay(DELAYTIME); } } // End of Scrollup void scrollText(char *p) // copied from library { uint8_t charWidth; uint8_t cBuf[8]; // this should be ok for all built-in fonts mx.clear(); while (*p != '\0') { charWidth = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf); for (uint8_t i = 0; i <= charWidth; i++) // allow space between characters {mx.transform(MD_MAX72XX::TSL); if (i < charWidth) mx.setColumn(0, cBuf[i]); delay(DELAYTIME);} } } // End of Scroll Text void printText(char *pMsg, int LOS, bool CenterJustify) // copied and modified from library // Print the text string to the LED matrix modules specified. // Message area is padded with blank columns after printing. // And center justified if third argument is "true" { uint8_t modStart = 0; uint8_t modEnd = MAX_DEVICES - 1; uint8_t state = 0; uint8_t curLen; uint16_t showLen; uint8_t cBuf[8]; int16_t col = ((modEnd + 1) * COL_SIZE) - 1; int pixelcount = 0; int ccounter = LOS; mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::OFF); do // finite state machine to print the characters in the space available { switch (state) { case 0: // Load the next character from the font table // if we reached end of message, reset the message pointer if (*pMsg == '\0') { showLen = col - (modEnd * COL_SIZE); // padding characters state = 2; break; } // retrieve the next character form the font file showLen = mx.getChar(*pMsg++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf); if (ccounter > 0) { pixelcount = (pixelcount + showLen) + CHAR_SPACING; ccounter--; } curLen = 0; state++; // !! deliberately fall through to next state to start displaying case 1: // display the next part of the character mx.setColumn(col--, cBuf[curLen++]); // done with font character, now display the space between chars if (curLen == showLen) { showLen = CHAR_SPACING; state = 2; } break; case 2: // initialize state for displaying empty columns curLen = 0; state++; // fall through case 3: // display inter-character spacing or end of message padding (blank columns) mx.setColumn(col--, 0); curLen++; if (curLen == showLen) state = 0; break; default: col = -1; // this definitely ends the do loop } } while (col >= (modStart * COL_SIZE)); if (CenterJustify) { for (int i = 1; i <= (((MAX_DEVICES * COL_SIZE) - pixelcount) / 2); i++) { mx.transform( MD_MAX72XX::TSR); } } mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::ON); } void printCenter(String StringtoPrint) // Loads the print buffer and centers it { int LOS = StringtoPrint.length(); // Get the string's length for (int i = 0; i < BufferStringLength; i++) { BufferString[i] = ' '; // clear buffer } for (int i = 0; i < LOS; i++) { BufferString[i] = StringtoPrint[i]; // transfer printText(BufferString, LOS, true); // Print, providing length of string and "Yes, center" } } // End of Center and Load void ShowValue(int myindex, String setdescription) // Display while in setup mode { // shows what item is setting and its value for (int i = 0; i < BufferStringLength; i++) {BufferString[i] = ' ';} // clear buffer setdescription.toCharArray(BufferString, setdesclength); // move description to output buffer LoadNumber(setarray[setupindex]); BufferString[setdesclength-1] = ' '; for (int i = 0; i = 0; i--) { TDigits[i] = (tempnum % 10) + DecToAscii;; tempnum = tempnum / 10; } } // end of LoadNumber void QueueSound(int SoundFile) { // place a sound to be played into sequence if ((SoundQueuePtr == SizeQueue) || (SoundQueueCtr <= 0)) { SoundQueuePtr = -1; // Dont overflow the queue } SoundQueuePtr++; // Increment pointer SoundQueue[SoundQueuePtr] = SoundFile; // and store the sound chosen SoundQueueCtr++; // and increment # sounds in queue } // end of Queue Sound File void PlaySound() { // Plays appropriate Sound file if (SoundQueueCtr > 0) { // if nothing in the queue, just return if (digitalRead(SoundBusyPin) == LOW) { //or if sound card busy, just return return; } //until idle if (SoundPlayPtr == SizeQueue) { SoundPlayPtr = -1; // Dont go past the queue } SoundPlayPtr++; // Increment pointer digitalWrite(FirstSoundPin + SoundQueue[SoundPlayPtr], LOW); //Play the sound delay(fxset); // hold to start the sound digitalWrite(FirstSoundPin + SoundQueue[SoundPlayPtr], HIGH); //Turn off the sound delay(fxset); // Ensure its set SoundQueueCtr--; // and decrement sounds yet to be played if (SoundQueueCtr <= 0) { SoundPlayPtr = -1; }; // reset play pointer when queue is empty } } // end of PlaySound /* void PlaySoundUART() // uncomment for FX sound board UART use // sfx.playTrack(name); } { Serial.print("\nPlaying track \""); Serial.print(name); Serial.print("\""); if (! sfx.playTrack(name) ) { Serial.println("Failed to play track?"); } } */ #ifdef showoffcode void ShowOff() { // Played at startup -- just the MX Panel Test Graphics QueueSound(SoundShowOff); // play Game of Thones theme as sound PlaySound(); scrollText("Showing Off"); rows(); columns(); cross(); checkboard(); bullseye(); bounce(); stripe(); stripe(); transformation1(); transformation2(); bullseye(); spiral(); delay(2000); DisplayIndex = DisplayTime; // force display of time after showing off display } // end of Show Off void rows() // these routines are all // Demonstrates the use of setRow() // from the MX library {mx.clear(); for (uint8_t row = 0; row < ROW_SIZE; row++) { mx.setRow(row, 0xff); delay(2 * DELAYTIME); mx.setRow(row, 0x00); } } void checkboard() // nested rectangles spanning the entire display { uint8_t chkCols[][2] = { { 0x55, 0xaa }, { 0x33, 0xcc }, { 0x0f, 0xf0 }, { 0xff, 0x00 } }; mx.clear(); for (uint8_t pattern = 0; pattern < sizeof(chkCols) / sizeof(chkCols[0]); pattern++) { uint8_t col = 0; uint8_t idx = 0; uint8_t rep = 1 << pattern; while (col < mx.getColumnCount()) { for (uint8_t r = 0; r < rep; r++) mx.setColumn(col++, chkCols[pattern][idx]); // use odd/even column masks idx++; if (idx > 1) idx = 0; } delay(10 * DELAYTIME); } } // end of Checkboard void columns() // Demonstrates the use of setColumn() { mx.clear(); for (uint8_t col = 0; col < mx.getColumnCount(); col++) { mx.setColumn(col, 0xff); delay(DELAYTIME / MAX_DEVICES); mx.setColumn(col, 0x00); } } void cross() // Combination of setRow() and setColumn() with user controlled // display updates to ensure concurrent changes. { mx.clear(); mx.control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF); // diagonally down the display R to L for (uint8_t i = 0; i < ROW_SIZE; i++) { for (uint8_t j = 0; j < MAX_DEVICES; j++) { mx.setColumn(j, i, 0xff); mx.setRow(j, i, 0xff); } mx.update(); delay(DELAYTIME); for (uint8_t j = 0; j < MAX_DEVICES; j++) { mx.setColumn(j, i, 0x00); mx.setRow(j, i, 0x00); } } // moving up the display on the R for (int8_t i = ROW_SIZE - 1; i >= 0; i--) { for (uint8_t j = 0; j < MAX_DEVICES; j++) { mx.setColumn(j, i, 0xff); mx.setRow(j, ROW_SIZE - 1, 0xff); } mx.update(); delay(DELAYTIME); for (uint8_t j = 0; j < MAX_DEVICES; j++) { mx.setColumn(j, i, 0x00); mx.setRow(j, ROW_SIZE - 1, 0x00); } } // diagonally up the display L to R for (uint8_t i = 0; i < ROW_SIZE; i++) { for (uint8_t j = 0; j < MAX_DEVICES; j++) { mx.setColumn(j, i, 0xff); mx.setRow(j, ROW_SIZE - 1 - i, 0xff); } mx.update(); delay(DELAYTIME); for (uint8_t j = 0; j < MAX_DEVICES; j++) { mx.setColumn(j, i, 0x00); mx.setRow(j, ROW_SIZE - 1 - i, 0x00); } } mx.control(MD_MAX72XX::UPDATE, MD_MAX72XX::ON); } void bullseye() // Demonstrate the use of buffer based repeated patterns // across all devices. { mx.clear(); mx.control(MD_MAX72XX::UPDATE, MD_MAX72XX::OFF); for (uint8_t n = 0; n < 3; n++) { byte b = 0xff; int i = 0; while (b != 0x00) { for (uint8_t j = 0; j < MAX_DEVICES + 1; j++) { mx.setRow(j, i, b); mx.setColumn(j, i, b); mx.setRow(j, ROW_SIZE - 1 - i, b); mx.setColumn(j, COL_SIZE - 1 - i, b); } mx.update(); delay(3 * DELAYTIME); for (uint8_t j = 0; j < MAX_DEVICES + 1; j++) { mx.setRow(j, i, 0); mx.setColumn(j, i, 0); mx.setRow(j, ROW_SIZE - 1 - i, 0); mx.setColumn(j, COL_SIZE - 1 - i, 0); } bitClear(b, i); bitClear(b, 7 - i); i++; } while (b != 0xff) { for (uint8_t j = 0; j < MAX_DEVICES + 1; j++) { mx.setRow(j, i, b); mx.setColumn(j, i, b); mx.setRow(j, ROW_SIZE - 1 - i, b); mx.setColumn(j, COL_SIZE - 1 - i, b); } mx.update(); delay(3 * DELAYTIME); for (uint8_t j = 0; j < MAX_DEVICES + 1; j++) { mx.setRow(j, i, 0); mx.setColumn(j, i, 0); mx.setRow(j, ROW_SIZE - 1 - i, 0); mx.setColumn(j, COL_SIZE - 1 - i, 0); } i--; bitSet(b, i); bitSet(b, 7 - i); } } mx.control(MD_MAX72XX::UPDATE, MD_MAX72XX::ON); } void spiral() // setPoint() used to draw a spiral across the whole display { int rmin = 0, rmax = ROW_SIZE - 1; int cmin = 0, cmax = (COL_SIZE * MAX_DEVICES) - 1; mx.clear(); while ((rmax > rmin) && (cmax > cmin)) { // do row for (int i = cmin; i <= cmax; i++) { mx.setPoint(rmin, i, true); delay(DELAYTIME / MAX_DEVICES); } rmin++; // do column for (uint8_t i = rmin; i <= rmax; i++) { mx.setPoint(i, cmax, true); delay(DELAYTIME / MAX_DEVICES); } cmax--; // do row for (int i = cmax; i >= cmin; i--) { mx.setPoint(rmax, i, true); delay(DELAYTIME / MAX_DEVICES); } rmax--; // do column for (uint8_t i = rmax; i >= rmin; i--) { mx.setPoint(i, cmin, true); delay(DELAYTIME / MAX_DEVICES); } cmin++; } } void bounce() // Animation of a bouncing ball { const int minC = 0; const int maxC = mx.getColumnCount() - 1; const int minR = 0; const int maxR = ROW_SIZE - 1; int nCounter = 0; int r = 0, c = 2; int8_t dR = 1, dC = 1; // delta row and column mx.clear(); while (nCounter++ < 200) { mx.setPoint(r, c, false); r += dR; c += dC; mx.setPoint(r, c, true); delay(DELAYTIME / 2); if ((r == minR) || (r == maxR)) dR = -dR; if ((c == minC) || (c == maxC)) dC = -dC; } } void stripe() // Demonstrates animation of a diagonal stripe moving across the display // with points plotted outside the display region ignored. { const uint16_t maxCol = MAX_DEVICES*ROW_SIZE; const uint8_t stripeWidth = 10; mx.clear(); for (uint16_t col=0; col

  • IoT Water Level Controller using Ultrasonic

    Here to build a water level monitoring and controller based on Internet of things. we used an ultrasonic distance sensor to measure water level, here we are also going to use the same non-contact method because of its convenience and accuracy in reading of water level. Measuring water level is same as measuring distance of solid surfaces, the ultrasonic transducer outputs a train of ultrasonic bursts at 40 KHz which will hit the water surface and reflect back to the sensor. The time taken between sent and received ultrasonic waves are calculated by a microcontroller such as ESP8266 12E. The measured distance is converted in to percentage. Circuit Diagram Components Required To make this project you need the following components: ESP8266 Development Board HC-SR04 Ultrasonic sensor 5V 1 Channel Relay Module Breadboard Jumper wires Ultrasonic: The HC-SR04 ultrasonic module is a module that can provide non-contact measurement within the range of 2cm to 400cm with ranging accuracy that can reach 3mm. It works on the principle of echolocation. The ultrasonic sensor as a trigger and an echo pin. The arduino provides a high signal of 10microseconds to this pin. After the HC-SR04 is triggered, it sends out eight 40Khz sound waves to the surface of the water. On getting to the surface of the water, the wave is echoed back to the sensor and the ESP8266 reads the echo pin to determine time spent between triggering and receiving of the echo. Since we know that the speed of sound is around 340m/s then we can calculate the distance using; Distance = (time/2)*speed of sound Ultrasonic HC-SR04 wiring to ESP8266 Ultrasonic HC-SR04 ESP8266 Vcc Pin Vin Pin Trig Pin D1 (GPIO 5) Echo Pin D2 (GPIO 4) GND Pin GND NodeMCU: NodeMCU ESP8266-12E MCU is a development board with one analogue and many general-purpose input output (GPIO) pins. It has 4MB flash memory, and can operate at a default clock frequency of 80MHz. In this project, digital pin D4 of NodeMCU is used to control of Water Pump ON/OFF. And digital pin D1 &D2 of NodeMCU is used to read data of distance sensor HC-SR04. Flat Slider Here's a nice example of a modern, flat style slider using pips. There are no labels so this kind of slider would be purely visual without much help to the user for knowing their real chosen value. In this example we make use of the .ui-slider-pip-inrange class to create the nice "filled in" effect on the pips. The default way to use the plugin is to call the pips method on an initialized slider. This will add the markers along the slider, and place the min/max values to the beginning/end of the slider: In this Project jQuery UI Slider Pips added in the Web page to adjust the Value between two points 0 to 100. 1st Point for water Level Lower Threshold value adjustment slider to Control Motor ON. 2nd Point for water Level Higher Threshold value adjustment slider to Control Motor OFF. Cylinder Fill The cylinder is the main component in a cylinder chart. You can understand the value being illustrated by looking at the percentage of cylinder filled. The cylinder gauge is a real-time chart, which can update its data after specified intervals, without requiring any page refreshes. In this section, you will be shown how you can create a simple cylinder gauge. Create a Cylinder Gauge Use the following attributes to create a simple cylinder gauge: Specify the type using the type attribute. To render Cylinder gauge, set cylinder. Set the container object using renderAt attribute. Specify the dimension of the chart using width and height attributes. Set the type of data (JSON/XML) you want to pass to the chart object using dataFormat attribute. Use the lowerLimit attribute to specify the lower limit, or the minimum value, of the gauge scale. Use the upperLimit attribute to specify the upper limit, or the maximum value, of the gauge scale. Use the lowerLimitDisplay attribute to specify the label to be displayed with the lower limit value on the gauge scale. Use the upperLimitDisplay attribute to specify the label to be displayed with the upper limit value on the gauge scale. Use the numberSuffix attribute to specify the character(s) to be appended to the end of a number. https://www.fusioncharts.com/dev/chart-guide/gauges-and-widgets/cylinder-gauge Subscribe and Download code. Code: #include #include #include const char* ssid = "TP-Link_3200"; // your SSID const char* password = "9500112137"; //your wifi password const char index_html[] PROGMEM={"\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\t\n" "\n" "\n" "\n" "\n" "\n" "\n" " \n" " \n" " \n" " \n" " \n" "\n" " FusionCharts XT will load here!\n" "\tWater Pump OFF\n" " \n" "\n" "\n" "\n" "\t\n" "" }; #define MAX_HEIGHT 27 // tank height 27 cm manually enter here for automatic empty tank //scan refer post https://www.dofbot.com/post/water-level-monitoring #define MOTOR_CONTROL_PIN D4 UltraSonicDistanceSensor distanceSensor(D1,D2); //D1 trig, D2=echo int waterLevelLowerThreshold=15; int waterLevelUpperThreshold=90; float volume = 0; float liters = 0; WiFiClient client; String inputString = ""; // a string to hold incoming data String dataToSend=""; int waterLevelDownCount=0,waterLevelUpCount=0; ESP8266WebServer server(80); void handleRoot() { server.send_P(200, "text/html;charset=UTF-8", index_html); } void handleLevelRequest(){ server.send(200,"text",String(liters)); } void handleNotFound(){ String message = "File Not Found\n\n"; server.send(404, "text/plain", message); } void handleStatus() { if(digitalRead(MOTOR_CONTROL_PIN)==0)//MOTOR ON server.send(200, "text/plain","on"); else server.send(200, "text/plain","off"); } void handleRangeSetting(){ waterLevelLowerThreshold=(server.arg(0)).toInt(); waterLevelUpperThreshold=(server.arg(1)).toInt(); Serial.print(waterLevelLowerThreshold); Serial.print(":"); Serial.println(waterLevelUpperThreshold); server.send(200, "text/plain", ""); } void measure_Volume() { float heightInch=1*distanceSensor.measureDistanceCm(); Serial.println(heightInch); volume=(MAX_HEIGHT-heightInch)/28;//MAX_HEIGHT-distance will give actual height, 1 cm for // offset adjustment liters=volume*100 ; // for percentage Serial.println(liters); if(liters<=waterLevelLowerThreshold) waterLevelDownCount++; else waterLevelDownCount=0; if(liters>=waterLevelUpperThreshold) waterLevelUpCount++; else waterLevelUpCount=0; if(waterLevelDownCount==3) {//TURN ON RELAY Serial.println("motor turned on"); digitalWrite(MOTOR_CONTROL_PIN,LOW);//Relay is active LOW } if(waterLevelUpCount==3) {//TURN OFF RELAY Serial.println("motor turned off"); digitalWrite(MOTOR_CONTROL_PIN,HIGH);//Relay is active LOW } } void runPeriodicFunc() { static const unsigned long REFRESH_INTERVAL1 = 1000; // 2.1sec static unsigned long lastRefreshTime1 = 0; if(millis() - lastRefreshTime1 >= REFRESH_INTERVAL1) { measure_Volume(); lastRefreshTime1 = millis(); } } void setup(void){ Serial.begin(115200); delay(100); pinMode(MOTOR_CONTROL_PIN, OUTPUT); WiFi.begin(ssid, password); Serial.println(""); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.print("IP address:"); Serial.println(WiFi.localIP()); server.on("/", handleRoot); server.on("/level",handleLevelRequest); server.on("/configRange",handleRangeSetting); server.on("/motor_status",handleStatus); server.onNotFound(handleNotFound); server.begin(); Serial.println("HTTP server started"); } void loop(void){ runPeriodicFunc(); server.handleClient(); } Then, upload the code to your NodeMCU board. Make sure you have selected the right board and COM port. Also, make sure you’ve inserted your WiFi Credentials in the code. After a successful upload, open the Serial Monitor at a baud rate of 115200. Press the “EN/RST” button on the ESP8266 board. Now it should print its IP address. Open Browser and type ip address in the address bar and see the below result. Subscribe and Download code.

  • Water Level Depth Detection and LED control with Bluetooth HC-05

    In this article, we’re going to do an Arduino based water level depth sensor and (PWM) LED brightness control and interface with HC-05 Bluetooth module for Graphical representation using android mobile application and LCD display for Sensor dipped in water level data print. Circuit Diagram Components Required Arduino Uno - 1 no LCD16x2 I²C - 1no Bluetooth module HC-05 - 1no water level sensor K-0135- 1no LED - 1no Water Level Sensor Water sensor brick is designed for water detection, which can be widely used in sensing the rainfall, water level, even the liquate leakage. The brick is mainly comprised of three parts: An Electronic brick connector, a 1 MΩ resistor, and several lines of bare conducting wires. This sensor works by having a series of exposed traces connected to ground and interlaced between the grounded traces are the sense traces. The sensor traces have a weak pull-up resistor of 1 MΩ. The resistor will pull the sensor trace value high until a drop of water shorts the sensor trace to the grounded trace. Believe it or not this circuit will work with the digital I/O pins of your Arduino or you can use it with the analog pins to detect the amount of water induced contact between the grounded and sensor traces. This item can judge the water level through with a series of exposed parallel wires stitch to measure the water droplet/water size. This High Sensitivity Water Sensor can easily change the water size to analog signal, and output analog value can directly be used in the program function, then to achieve the function of water level alarm. This item have low power consumption, and high sensitivity, which are the biggest characteristics of this module. The High Sensitivity Water Sensor can be compatible with Arduino UNO, Arduino mega2560,Arduino ADK etc. However, one commonly known issue with these sensors is their short lifespan when exposed to a moist environment. Having power applied to the probe constantly speeds the rate of corrosion significantly. To overcome this, we recommend that you do not power the sensor constantly, but power it only when you take the readings The working of the water level sensor is pretty straightforward. The series of exposed parallel conductors, together acts as a variable resistor (just like a potentiometer) whose resistance varies according to the water level. The change in resistance corresponds to the distance from the top of the sensor to the surface of the water. The resistance is inversely proportional to the height of the water: The more water the sensor is immersed in, results in better conductivity and will result in a lower resistance. The less water the sensor is immersed in, results in poor conductivity and will result in a higher resistance. The sensor produces an output voltage according to the resistance, which by measuring we can determine the water level. Features : Working voltage: DC5V Working Current: <20ma Interface: Analog Width of detection: 40mm×16mm Working Temperature: 10°C~30°C Humidity: 10% -90% non-condensing Arduino compatible interface Low power consumption High sensitivity Output voltage signal: 0~4.2V Pin definition : "S" stand for signal input "+" stand for power supply "-" stand for GND Applications : Rainfall detecting Liquid leakage Tank overflow detector Bluetooth HC-05: HC-05 is a Bluetooth module which is designed for wireless comunication. This module can be used in a master or slave configuration. Bluetooth serial modules allow all serial enabled devices to communicate with each other using Bluetooth. It has 6 pins, 1.Key/EN: It is used to bring Bluetooth module in AT commands mode. If Key/EN pin is set to high, then this module will work in command mode. Otherwise by default it is in data mode. The default baud rate of HC-05 in command mode is 38400bps and 9600 in data mode. HC-05 module has two modes, Data mode: Exchange of data between devices. Command mode: It uses AT commands which are used to change setting of HC-05. To send these commands to module serial (USART) port is used. 2. VCC: Connect 5 V or 3.3 V to this Pin. 3. GND: Ground Pin of module. 4. TXD: Transmit Serial data (wirelessly received data by Bluetooth module transmitted out serially on TXD pin) 5. RXD: Receive data serially (received data will be transmitted wirelessly by Bluetooth module). 6. State: It tells whether module is connected or not. HC-05 module Information HC-05 has red LED which indicates connection status, whether the Bluetooth is connected or not. Before connecting to HC-05 module this red LED blinks continuously in a periodic manner. When it gets connected to any other Bluetooth device, its blinking slows down to two seconds. This module works on 3.3 V. We can connect 5V supply voltage as well since the module has on board 5 to 3.3 V regulator. As HC-05 Bluetooth module has 3.3 V level for RX/TX and microcontroller can detect 3.3 V level, so, no need to shift transmit level of HC-05 module. But we need to shift the transmit voltage level from microcontroller to RX of HC-05 module. HC-05 Default Settings Default Bluetooth Name: “HC-05” Default Password: 1234 or 0000 Default Communication: Slave Default Mode: Data Mode Data Mode Baud Rate: 9600, 8, N, 1 Command Mode Baud Rate: 38400, 8, N, 1 Default firmware: LINVOR Installing the Arduino Library LiquidCrystal_I2C.h : you need to Download and install the LiquidCrystal_I2C library. Follow the next steps to install those libraries. In your Arduino IDE, to install the libraries go to Sketch > Include Library > Add .ZIP library… and select the library you’ve just downloaded. After installing the required libraries, copy the following code to your Arduino IDE. Mobile output Subscribe and Download code. Download Android application. Final result: Arduino Code: #include LiquidCrystal_I2C lcd(0x27,16,2); // These constants won't change. They're used to give names to the pins used: const int analogInPin = A0; // Analog input pin that the potentiometer is attached to const int analogOutPin = 9; // Analog output pin that the LED is attached to int sensorValue = 0; // value read from the pot int outputValue = 0; // value output to the PWM (analog out) int Level = 0; void setup() { // initialize serial communications at 9600 bps: Serial.begin(9600); pinMode(analogOutPin, OUTPUT); lcd.init(); // initialize the lcd // Print a message to the LCD. lcd.backlight(); lcd.begin(16, 2); // set up the LCD's number of columns and rows: } void loop() { // read the analog in value: sensorValue = analogRead(analogInPin); // map it to the range of the analog out: outputValue = map(sensorValue, 0, 750, 0, 255); Level = map(outputValue, 0, 255, 0, 100); // calibrated value // change the analog out value: analogWrite(analogOutPin, outputValue); // print the results to the Serial Monitor: // Serial.print("sensor = "); // Serial.print(sensorValue); // Serial.print("\t output = "); // Serial.println(outputValue); Serial.println(Level); lcd.setCursor(0,0); lcd.print("LEVEL DETECTION "); lcd.setCursor(0,1); lcd.print("Dipped: "); lcd.print(Level); lcd.print(" %"); lcd.print(" "); // lcd.setCursor(0,1); // lcd.print("PWM: "); // lcd.print(outputValue); // lcd.print(" "); // wait 2 milliseconds before the next loop for the analog-to-digital // converter to settle after the last reading: delay(500); } MIT Block for mobile application.

  • LUX Meter Using BH1750 and OLED Display

    In this project, we will make a Arduino based LUX Meter Using BH1750 and OLED Gauge Display. Sometime we need to measure the exposure of light but a lux meter costs is high. Here to learn low cost and accurate ambient lighting sensor BH1750 interface with arduino with OLED Gauge display and enjoyed it. In this Project Push Button added for HOLD the Lux meter display value if pressed and Reading value displayed again push button pressed. Circuit Diagram Components Required Arduino Uno - 1 no OLED 0.96 SSD1306 - 4 PIN - 1no BH1750 GY-302- 1no Push button switch- 1 no BH1750 Refer previous project for more detail : https://www.dofbot.com/post/iot-cloud-bh1750-lux-monitor A digital Lux Meter is a device to measure the intensity of a source of light. A lux meter will be used in photography to estimate how bright the flash is and also the encircling ambient lighting. BH1750 is a digital ambient light sensor that is used commonly used in mobile phones to manipulate the screen brightness based on the environment lighting. This sensor can accurately measure the LUX value of light up to 65535lx. A digital Lux Meter is a device to measure the intensity of a source of light. A lux meter will be used in photography to estimate how bright the flash is and also the encircling ambient lighting. working principle of lux meter Most of the lux meter consists of a body, photocell or light sensor, and display. The light that falls on to the photocell or sensor contains energy that is transformed into electric current. Indeed, the measure of current depends on the light that strokes the photocell or light sensor. Lux meters read the electrical current calculate the appropriate value, and show this value on its display. BH1750 Features Power Supply: 2.4V-3.6V (typically 3.0V) Less current consumption: 0.12mA Measuring Rang: 1-65535lx Communication: I2C bus Accuracy: +/-20% Built in A/D converter for converting analog illuminance in the digital data. Very small effect of IR radiation Highly responsive near to human eye. This is a BH1750 light intensity sensor breakout board with a 16 bit AD converter built-in which can immediately output a digital signal, there is no need for complex calculations. This is more accurate and simpler to use the version of the simple LDR which only outputs a voltage that needs to be calculated to obtain meaningful data. First, connect the VCC and GND of the BH1750 Light Sensor to 3V3 and GND of Arduino Then connect the SCL and SDA pins of the sensor to corresponding pins of Arduino A5 &A4 Pin using jumper wires. Then, connect the SCL, SDA, GND, and VCC pin of the OLED display to the corresponding BH1750 sensor pins. Let's talk about lux and Illuminance: The lux (symbol: lx) is the SI derived unit of illuminance, measuring luminous flux per unit area. It is equal to one lumen per square meter. In photometry, this is used as a measure of the intensity, as perceived by the human eye, of light that hits or passes through a surface. It is analogous to the radiometric unit watt per square meter, but with the power at each wavelength weighted according to the luminosity function, a standardized model of human visual brightness perception. In English, "lux" is used as both the singular and plural form. Illuminance: Illuminance is a measure of how much luminous flux is spread over a given area. One can think of luminous flux (measured in lumens) as a measure of the total "amount" of visible light present, and the illuminance as a measure of the intensity of illumination on a surface. A given amount of light will illuminate a surface more dimly if it is spread over a larger area, so illuminance is inversely proportional to the area when the luminous flux is held constant. One lux is equal to one lumen per square meter: 1 lx = 1 lm/m2 = 1 cd·sr/m2. A flux of 1000 lumens, concentrated into an area of 1 square meter, lights up that square meter with an illuminance of 1000 lux. However, the same 1000 lumens, spread out over 10 square meters produces a dimmer illuminance of only 100 lux. OLED SSD1306-I2C 128X64 Display Module 0.96 inch This is a 0.96 inch Blue OLED display module. The display module can be interfaced with any microcontroller using SPI/IIC protocols. It is having a resolution of 128x64. The package includes display board,display, 4 pin male header presoldered to board. OLED (Organic Light-Emitting Diode) is a self light-emitting technology composed of a thin, multi-layered organic film placed between an anode and cathode. In contrast to LCD technology, OLED does not require a backlight. OLED possesses high application potential for virtually all types of displays and is regarded as the ultimate technology for the next generation of flat-panel displays. Download Data sheet Installing the Arduino Library Installing SSD1306 OLED Library – Arduino Download u8glib Library , we need to use this library for OLED Download BH1750_Library , we need to use this library for Lux Sensor Follow the next steps to install those libraries. In your Arduino IDE, to install the libraries go to Sketch > Include Library > Add .ZIP library… and select the library you’ve just downloaded. After installing the required libraries, copy the following code to your Arduino IDE. Subscribe and Download code. Arduino Code: //----------------------------------------Include Library #include #include "U8glib.h" #include //---------------------------------------- //----------------------------------------Initialize u8g U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI //---------------------------------------- ///----------------------------------------BH1750 I2C address // ADDR line LOW/open: I2C address 0x23 (0x46 including R/W bit) [default] // ADDR line HIGH: I2C address 0x5C (0xB8 including R/W bit) BH1750 sensor(LOW); //---------------------------------------- //----------------------------------------Variable and button pin declarations #define Button_Pin 4 bool Button; //---------------------------------------- //----------------------------------------Variable for LUX Value uint16_t read_lux; uint16_t result_lux; byte lux_HR; //---------------------------------------- int x_LUX_val; //--> X position to display LUX value //----------------------------------------Variables for Gauge Chart int xmax=128; int ymax=62; int xcenter=xmax/2; int ycenter=ymax/2+10; int arc=ymax/2; int angle=0; int p, w, m; u8g_uint_t xx=0; //----------------------------------------Variables for Gauge Chart //----------------------------------------Variable for Mode // Mode = 1 for realtime reading of sensor values (LUX). // Mode = 2 to capture sensor value (LUX). int Mode = 1; //---------------------------------------- bool Blink_Cap; //--> Variables to make the sensor value flashes on the capture mode. unsigned long previousMillis = 0; //--> will store last time was updated const long interval = 250; //--> interval (milliseconds) //========================================================================VOID ShowLux_With_GaugeChart(uint8_t angle) void ShowLux_With_GaugeChart(uint8_t angle) { //----------------------------------------draw border of the gauge u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_RIGHT); u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_RIGHT); u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_LEFT); u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_LEFT); //---------------------------------------- //----------------------------------------draw the needle float x1=sin(2*angle*2*3.14/360); float y1=cos(2*angle*2*3.14/360); u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1); u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_LEFT); u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_RIGHT); u8g.setFont(u8g_font_chikita); //---------------------------------------- //----------------------------------------show MIN and MAX labels u8g.drawStr(0, 5, "MIN"); u8g.drawStr(0, 13, "1"); u8g.drawStr(110, 5, "MAX"); u8g.drawStr(98, 13, "65535"); u8g.drawStr(9, 42, "MIN"); u8g.drawStr(105, 42, "MAX"); //---------------------------------------- //----------------------------------------show gauge label u8g.setPrintPos(56,24); u8g.print("LUX"); u8g.setPrintPos(50,32); u8g.print("METER"); //---------------------------------------- u8g.setFont(u8g_font_unifont); //----------------------------------------Conditions for displaying LUX value center align on OLED if (result_lux < 10) { x_LUX_val = 36; } else if (result_lux < 100 && result_lux > 9) { x_LUX_val = 32; } else if (result_lux < 1000 && result_lux > 99) { x_LUX_val = 28; } else if (result_lux < 10000 && result_lux > 999) { x_LUX_val = 24; } else if (result_lux > 9999) { x_LUX_val = 20; } //---------------------------------------- //----------------------------------------Mode = 1 for realtime reading of sensor values (LUX). if (Mode == 1) { u8g.setPrintPos(x_LUX_val, 60); u8g.print(result_lux); u8g.print("."); u8g.print(lux_HR); u8g.print(" lx"); } //---------------------------------------- //----------------------------------------Mode = 2 to capture sensor value (LUX). if (Mode == 2) { if (Blink_Cap == false) { u8g.setPrintPos(x_LUX_val, 60); u8g.print(result_lux); u8g.print("."); u8g.print(lux_HR); u8g.print(" lx"); } else { u8g.setPrintPos(0, 60); u8g.print(" "); } //---------------------------------------- } } //======================================================================== //========================================================================VOID SETUP void setup(void) { u8g.setFont(u8g_font_chikita); pinMode(Button_Pin, INPUT_PULLUP); Wire.begin(); //--> Initialize I2C bus sensor.begin(ModeContinuous, ResolutionHigh); //--> Initialize sensor in continues mode, high 0.5 lx resolution sensor.startConversion(); //--> Start conversion } //======================================================================== //========================================================================VOID LOOP void loop(void) { //----------------------------------------Read button Button = digitalRead(Button_Pin); if (Button == LOW) { Mode++; if (Mode > 2) Mode = 1; //----------------------------------------Looping to check the button condition until the button is finished pressing to perform the next instruction. while(Button == LOW) { Button = digitalRead(Button_Pin); delay(100); } //---------------------------------------- } //---------------------------------------- //.................................................................................Millis for loop delay unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; //--> save the last time currentMillis //----------------------------------------Mode = 1 for realtime reading of sensor values (LUX). if (Mode == 1) { //----------------------------------------Wait for completion (blocking busy-wait delay) if (sensor.isConversionCompleted()) { read_lux = sensor.read(); //--> Read light result_lux = read_lux / 2; lux_HR = read_lux % 10; } //---------------------------------------- } //---------------------------------------- if (Mode == 2) Blink_Cap = !Blink_Cap; //--> Toggle Blink_Cap //----------------------------------------Converts sensor / LUX value to angle value m = map(result_lux,0,65535,0,90); //---------------------------------------- //----------------------------------------show needle and dial xx = m; if (xx<45){ xx=xx+135; } else { xx=xx-45; } //---------------------------------------- //----------------------------------------picture loop (Loop for display on OLED) u8g.firstPage(); do { ShowLux_With_GaugeChart(xx); } while( u8g.nextPage() ); //---------------------------------------- } //................................................................................. }

  • Radar Monitor using Ultrasonic sensor

    In this tutorial we are learn to finding Object distance and angle (radar monitor) using Ultrasonic sensor and Servo Motor. Radars have long been used for detecting objects far away and mapping them on a display. With a number of military and arial applications radars are widely used these days. This advanced Arduino sonar system can be used to monitor local patch area and can also scan suspicious object. We propose to demonstrate this concept using arduino based radar project. This Arduino sonar project system continuously scans the area at 180 degree angle using Servo motor and the radar provides the angle as well as distance of the object from the source and value sent to OLED display. It makes use of an ultrasonic wave to simulate sonar or radar sweep 180 degree. It is mounted on a Servo motor to create sweep angles and rotate the ultrasonic sensor. Circuit Diagram Components Required Arduino Uno - 1 no Ultrasonic Sensor HC-SR04 - 1no Ultrasonic Sensor Mounting Bracket - 1 Servo Motor MG90S - 1no OLED 0.96 SSD1306 - 4 PIN - 1no HC-SR04 HC-SR04 Ultrasonic (US) sensor is a 4 pin module, whose pin names are Vcc, Trigger, Echo and Ground respectively. This sensor is a very popular sensor used in many applications where measuring distance or sensing objects are required. The module has two eyes like projects in the front which forms the Ultrasonic transmitter and Receiver. The sensor works with the simple high school formula that Distance = Speed × Time Refer more Data sheet Download OLED SSD1306-I2C 128X64 Display Module 0.96 inch This is a 0.96 inch Blue-Yellow OLED display module. The display module can be interfaced with any microcontroller using SPI/IIC protocols. It is having a resolution of 128x64. The package includes display board,display, 4 pin male header presoldered to board. OLED (Organic Light-Emitting Diode) is a self light-emitting technology composed of a thin, multi-layered organic film placed between an anode and cathode. In contrast to LCD technology, OLED does not require a backlight. OLED possesses high application potential for virtually all types of displays and is regarded as the ultimate technology for the next generation of flat-panel displays. ssd1306 Specifications : Viewing angle : greater than 160 degrees Supported platforms : for arduino, 51 series, MSP430 series, STIM32 / 2, SCR chips Low power consumption : 0.04W during normal operation Support wide voltage : 3.3V-5V DC Driver IC : SSD1306 Communication : IIC, only two I / O ports No font : The software takes word modulo Backlight : OLED self light, no backlight Interface: VCC: 3.3-5V GND: Ground SCL: Serial Clock SDA: Serial Installing the Arduino Library Installing SSD1306 OLED Library – Arduino Download Adafruit_SSD1306_Library , we need to use this library for OLED Download Adafruit_GFX_Library , we need to use this library for OLED Follow the next steps to install those libraries. 1. Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open. 2. Type “SSD1306” in the search box and install the Adafruit SSD1306 library version 1.2.9 library from Adafruit. 3. After installing the SSD1306 library from Adafruit GFX version 1.4.13 in the search box and install the library. 4. After installing the libraries, restart your Arduino IDE. After installing the required libraries, copy the following code to your Arduino IDE. Subscribe and Download code. Arduino Code: #include #include #include #include #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)//unstroke for yellow+blue OLED // double stroke for Blue OLED Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); #include Servo servo; const int trig = 2, echo = 3 ; int pos = 0, distcm = 0; void setup() { Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); pinMode(trig, OUTPUT); pinMode(echo, INPUT); servo.attach(9); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(7,0); display.clearDisplay(); display.println("DOFBOT PROJECTS"); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(0,10); display.println("WELCOME"); display.display(); delay(3000); } void loop() { for (pos = 0; pos <= 180; pos += 1) { servo.write(pos); delay(50); Serial.println(radar()); display.clearDisplay(); // text display tests display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("RADAR SCANNING.."); display.setTextColor(BLACK, WHITE); // 'inverted' text //display.println(3.141592); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,16); display.print("DISTANCE SERVO"); display.setCursor(0,30); display.print(" IN CM DEGREE"); display.display(); display.setTextColor(WHITE); display.setCursor(0,45); display.setTextSize(2); display.print(radar()); display.setCursor(90,45); display.setTextSize(2); display.print(pos); // display.println(0xDEADBEEF, HEX); display.display(); } for (pos = 180; pos >= 0; pos -= 1) { servo.write(pos); delay(50); Serial.println(radar()); display.clearDisplay(); // text display tests display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("RADAR SCANNING...."); display.setTextColor(BLACK, WHITE); // 'inverted' text //display.println(3.141592); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,16); display.print("DISTANCE SERVO"); display.setCursor(0,30); display.print(" IN CM DEGREE"); display.display(); display.setTextColor(WHITE); display.setCursor(0,45); display.setTextSize(2); display.setTextSize(2); display.print(radar()); display.setCursor(90,45); display.setTextSize(2); display.print(pos); // display.println(0xDEADBEEF, HEX); display.display(); } delay(50); } long radar(void) { digitalWrite(trig, HIGH); delayMicroseconds(15); digitalWrite(trig, LOW); long dur = pulseIn(echo, HIGH); distcm = dur / 58; return distcm; delay(300); } After a successful upload, open the Serial Monitor at a baud rate of 9600. Press the “EN/RST” button on the Arduino Uno board and Open Serial monitor and see the result in Serial monitor.

bottom of page