circuitdigestDetail1

Must Watch!



MustWatch



DIY Automatic Portable Humidifier using Arduino

to read the atmospheric humidity values. If it finds that relative humidity is lower than the required limit, it turns on the humidifier, and vice versa.

Components Required for Building a Portable Humidifier

Ultrasonic humidifier Arduino Nano 5V Relay 7805 25V,1000uf Electrolytic capacitor 12V,2 AMP AC-DC Adapter DHT11 Sensor USB Female socket Perf Board Connecting wires

Working of the Portable Humidifier

Portable humidifier can produce a warm/cool mist by using a metal diaphragm vibrating at high frequency. The sound vibrations propel moisture into the air. The mist produced in the humidifier is almost immediately absorbed into the air. The humidifier needs to be floated on water bed to produce the mist. The working of the humidifier that we are going to build can be understood by below block diagram: As shown in the above block diagram, the ultrasonic humidifier is placed on the water surface in the container.The humidifier floatson the water. Since we need to sense the humidity, the DHT11 humidity sensor is connected with Arduino Nano and an OLED display is connected to display the real-time values. Moreover, depending on the humidity value, we need to trigger the relay, which in turn switches the humidifier to ON/OFF. So, the humidifier value is compared with a reference value, and depending on the humidity values, the humidifier is turned ON/OFF. Main features of this dehumidifier are given below: Type: Floating/Ultrasonic Power: USB, 5V DC Working Current: 500Ma Noise level: ≐󱵤b

Portable Humidifier Circuit Diagram

using Arduino is given here: Let us learn the circuit diagram in detail. As shown, first of all a 12V DC power supply is converted into 5V DC power supply using 7805 Regulator and Capacitive filter. Then this power is supplied to Arduino Nano, OLED, DHT11 and Relay circuits. The data pin of DHT11 is connected to the Digital input pin of Arduino as shown and configured in the code. The OLED display is connected to Arduino via the I2C Pins which are A4, A5 pin of Arduino. Similarly, the digital output pins of Arduino are connected to the Relay and BJT for DC Fan driving. To make the project setup mobile and more compatible, I soldered all the components on the perfboard as shown in the below image:

Programming Arduino Nano for Humidifier

After completion of successful hardware connection as per the circuit diagram, now it’s time to flash the code to Arduino. The complete code is given at the end of the document. Here we are explaining the entire code line by line. #include <SoftwareSerial.h> #include <Wire.h> #include <Adafruit_SH1106.h> #include "DHT.h" Then, the OLED I2C address is defined, which is can be either OX3C or OX3D, which is OX3C in my case. Often, the address of 1.3-inch OLED is OX3C. Also, the Reset pin of the display has to be defined. In my case, it is defined as -1, as the display is sharing Arduino’s Reset pin. #define OLED_ADDRESS 0x3C #define OLED_RESET -1 Adafruit_SH1106 display(OLED_RESET); Now, an object is declared in DHT Class type which can be used throughout the code. DHT dht; int humidity=0; function is used to initialize the display. void setup() { Serial.begin(9600); dht.setup(2); pinMode(6,OUTPUT); pinMode(11,OUTPUT); display.begin(SH1106_SWITCHCAPVCC, OLED_ADDRESS); display.clearDisplay(); } To read the humidity value from sensor, getHumidity() function is used and stored in a variable. Then it is displayed on the OLED using respective functions for selecting Text size and Cursor positions as shown below. delay(dht.getMinimumSamplingPeriod()); humidity = dht.getHumidity(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(27, 2); display.print("CIRCUIT DIGEST"); display.setTextSize(1); display.setCursor(35, 20); display.print("HUMIDITY(%)"); display.display(); display.setTextSize(2); display.setCursor(55, 40); display.print(humidity); display.display(); delay(50); display.clearDisplay(); Finally, to trigger the Humidifier, the humidity value is compared with a reference humidity level, below which the relay is triggered which turn ON the humidifier and Fan. if(humidity<88 ) { digitalWrite(6,HIGH); digitalWrite(11,HIGH); } else { digitalWrite(6,LOW); digitalWrite(11,LOW); } }

Testing the Portable Humidifier

Once the code and Hardware are ready, we can test how this humidifier performs when placed in a close room. For that, follow the steps given below: Fill the container with fresh water up to 3/4th of the container and then float the humidifier on it as shown below: Power ON the Adapter to switch ON the circuit and now we should see the humidity levels on OLED. Then if the humidity level is less than Reference, then the Humidifier should start producing mists and the Fan should be turned ON. is also explained in the video given at the end of the document. If you have any questions, you can leave them in the comment section below. Code #include <SoftwareSerial.h> #include <Wire.h> #include <Adafruit_SH1106.h> #define OLED_ADDRESS 0x3C #define OLED_RESET -1 Adafruit_SH1106 display(OLED_RESET); #include "DHT.h" DHT dht; int humidity=0; void setup() { Serial.begin(9600); dht.setup(2); pinMode(6,OUTPUT); pinMode(11,OUTPUT); display.begin(SH1106_SWITCHCAPVCC, OLED_ADDRESS); display.clearDisplay(); } void loop() { delay(dht.getMinimumSamplingPeriod()); humidity = dht.getHumidity(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(27, 2); display.print("CIRCUIT DIGEST"); display.setTextSize(1); display.setCursor(35, 20); display.print("HUMIDITY(%)"); display.display(); display.setTextSize(2); display.setCursor(55, 40); display.print(humidity); display.display(); delay(50); display.clearDisplay(); if(humidity<85) { digitalWrite(6,HIGH); digitalWrite(11,HIGH); } else { digitalWrite(6,LOW); digitalWrite(11,LOW); } } Video microcontroller-projects/automatic-irrigation-system-using-arduino-uno

Automatic Irrigation System using an Arduino Uno

garden or for your Indoor plants thus taking care of your leafy pets when you are away.

Working of the Automatic Irrigation System

The logic of this system is very simple. In this system, the moisture sensor senses the moisture level of the soil and when the sensor senses a low moisture level it automatically switches the water pump with the help of a microcontroller and irrigates the plant. After supplying sufficient water, the soil gets retains the moisture hence automatically stopping the pump. according to the water content in the soil. This resistance is inversely proportional to the soil moisture which means that higher water in the soil means better conductivity and hence a lower resistance. While the lower water in the soil means poor conductivity and will result in higher resistance. The sensor produces an analog voltage output according to the resistance. which converts the analog signal to a Digital Output which is fed to the microcontroller. We need a small pump to irrigate the plant, but in the case of a garden, we need to drive a larger pump that can provide a higher volume of water depending on the size of your garden which can’t be directly powered by an Arduino. So in case you need to operate a larger pump, a driver is necessary to provide enough current for the pump, to show that I am using a 5v relay. You can also use an AC-powered pump and use a suitable relay. The working will remain the same as shown in this project, you just have to replace the DC power input connected to the relay with an AC power input and have to power your Arduino with a separate DC power source.

Components Required for the Automatic Irrigation System

The project requires very few components and the connection is also very simple. The components are listed below: Arduino * 1 moisture sensor * 1 5v relay module * 1 6v Mini water pump with small pipe * 1 Connecting wires 5v battery * 1

Circuit Diagram of the Arduino Automatic irrigation system

The complete circuit diagram for theArduino Automatic irrigation system is shown below: is the brain of this whole project. It controls the motor pump according to the moisture in the soil which is given by the moisture sensor. To power the circuit, I am using an external Battery. You can use any 9v or 12-volt battery. The battery is connected to the Vin and ground pins of Arduino and we can also connect the motor to this battery via a relay. Moisture sensor output is connected to the analog pin of Arduino. Do remember to use the Arduino’s 5volt pin to power the sensor and relay module.

Assembling the Automatic Irrigation System

Let's start with connecting the relay to the Arduino board. Connect the VCC of the relay module to the 5v pin of the Arduino and connect the ground of the relay to the ground of Arduino. Now connect the relay signal pin to any digital pin of Arduino except pin 13. Here I have connected it to pin 3 as shown in the image below. The next step is to connect the soil moisture sensor with the Arduino. Connect the VCC and gnd of the sensor to the 5volt and ground pin of the Arduino. The analogue output of the sensor connects to any analogue pin of the Arduino, here I’ve connected it to pin A0 (according to our program). Finally, connect the pump to the relay module. A relay module has 3 connection points which are common, normally closed, and normally open. We have to connect the pump positive to common and connect the normally open pin to the positive of the battery. You have to select the battery as per your pump. The next step is to connect the ground of the pump to the ground of the Arduino and finally, connect the small hose to the water pump. Now connect the battery to the circuit and if the pump starts working then your circuit is okay. Now let's upload code to Arduino.

Explanation of the code for The Automatic Irrigation System

For this project, we are not using any library we are just using the basic functions for programming. The code is very simple and easy to use. The explanation of the code is as follows. We start by defining all the required integers here I used two integers for storing the soil moisture and the converted moisture percentage. int soilMoistureValue = 0; int percentage=0; Now, we define the pin mode, here I have used pin 3 as an output and in the next line, I have initialised Serial Monitor for debugging. void setup() { pinMode(3,OUTPUT); Serial.begin(9600); } section by reading the soil moisture. I used the analogRead function of Arduino to read the soil moisture and I stored that in soilMoistureValue. This value varies from 0 to 1023 void loop() { soilMoistureValue = analogRead(A0); In the below line, I have converted the sensor values from 0-100 percent for that we use the map function on Arduino. That means that if the soil is dry then the output moisture percentage is 0% and if the soil is extremely wet then the moisture percentage is 100%. percentage = map(soilMoistureValue, 490, 1023, 0, 100); Serial.println(percentage);

Calibrating our Moisture Sensor

we need to assign the dry value and wet value. To do that we need to monitor that values. You can read that values using the following code: void setup() { Serial.begin(9600); } void loop() { int sensorValue = analogRead(A0); Serial.println(sensorValue); delay(1); Upload the above code to your Arduino and open the serial monitor. Then place your soil moisture sensor in dry soil or just hold the sensor in the air and read the value. now put that value in place of 490(second term of map function). The next step is to place the sensor in wet soil or submerge it in water and read the value and assign that value in place of 1023 (third term of map function). These values will calibrate your sensors correctly to get better results. ) and the Arduino will print pump on message in the serial monitor. If (percentage < 10) { Serial.println(" pump on"); digitalWrite(3,LOW); } When the moisture percentage goes above 80 percent ( indicating soil is filled with water) the Arduino will turn off the pump and print the ‘pump offᾠon the serial monitor. if(percentage >80) { Serial.println("pump off"); digitalWrite(3,HIGH); } }

Testing the Automatic Irrigation System

After uploading the code to the Arduino, I placed the whole circuit except the pump and sensor probe in a plastic box as shown in the figure below. Now place the moisture sensor into the soil. Place the sensor as close to the roots of the plants as possible for higher accuracy. The final step is to place your motor in a container filled with water and your automatic irrigation is ready to take care of your lovely plants when you are not around. You might have to change the moisture percentage to start and stop the pump as different plants have different water requirements. Hope you enjoyed the project and are ready to build your own automatic irrigation system using Arduino. If you have any questions, you can leave them in the comment section below. Code int soilMoistureValue = 0; int percentage=0; void setup() { pinMode(3,OUTPUT); Serial.begin(9600); } void loop() { soilMoistureValue = analogRead(A0); Serial.println(percentage); percentage = map(soilMoistureValue, 490, 1023, 100, 0); if(percentage < 10) { Serial.println(" pump on"); digitalWrite(3,LOW); } if(percentage >80) { Serial.println("pump off"); digitalWrite(3,HIGH); } } Video microcontroller-projects/diy-music-audio-visualizer-using-dot-matrix-display-and-arduino-nano

DIY Music/Audio Visualizer using 32x8 Dot Matrix Display and Arduino

using Arduino and other microcontrollers.

Components Required for Building a Music/Audio Visualizer

To follow along with this tutorial, you'll need the following components: Arduino Nano MAX7219 32x8 Dot Matrix Display Module Microphone/Microphone Module Jumper Wires 3-D Printer (Optional)

What is MAX7219 32x8 Dot Matrix Display Module?

MAX7219 4-in-1 Display Dot Matrix Module is an integrated serial input/output common-cathode display designed to be mounted in a horizontal chain or to be expanded in a vertical plane to build a versatile displaypanel. This display module uses a convenient 3-wire serial interface to connect to all common controller boards like Arduino or Raspberry. This display module contains four 8×8 dot matrix displays and four MAX7219 LED display driver ICs one for each display. An 8x8 LED matrix module contains 64 LED (Light Emitting Diodes) which are arranged in the form of a matrix; hence the name is LED matrix. If the module were to be drawn in the form of a circuit diagram, we will have a picture as shown below: As shown in the above image, the 8×8 dot matrix display has 16 pins, 8 for each row and 8 for each column. Here, all the rows and columns are wired together to reduce the number of pins required. This technique of controlling a large number of LEDs with fewer pins is called Multiplexing. MAX7219 LED display driver ICs are used to control the display modules. This IC can precisely control and generate the pattern or text that you want. Apart from this, the other advantage of using this IC is that all the 64 LED can be controlled by just 3 pins. Input Voltage: 5V Max. Operating Current (mA): 320 Requires only 3 communication wires of MCU Cascading multiple Matrix LED Module is very easy The size of the display is very compact The PCB features M3 holes for mounting

Audio Spectrum Visualizer Circuit Diagram

is shown in below image. The Dot matrix display and Microphone both are powered with 5V and GND pins of Arduino Nano. But if you are planning to use the Dot matrix with its maximum brightness then it's better to use an external 5V source as the display draws a lot of current when set to maximum brightness. The data pin of the microphone is connected to the A7 pin of Arduino Nano. Now, we are left with SPI pins of the display. These pins are connected to hardware SPI pins of Arduino Nano as the hardware SPI pins are much faster than software SPI pins of any microcontroller. The connections which are done between Arduino Nano, LED matrix module, and Microphone are shown in below table.
5VVCC
GNDGND
D11DIN
D10CS
D13CLK
5VVCC
GNDGND
A7OUT

Building the Circuit on Perf Board

The idea is to fit this circuit inside a 3-D printed casing so that it can be mounted on a wall or placed beside the music system. For that, I soldered this complete circuit on a perf board. The perf board with all the soldered components is shown below:

Programming Arduino Nano Audio Visualization

and install the arduinoFFT library by Enrique Condes. library is used to control the display and draw the audio spectrum on display. While the SPI library is used to establish SPI communication between Arduino and Dot-matrix display. #include <arduinoFFT.h> #include <MD_MAX72xx.h> #include <SPI.h> MD_MAX72XX disp = MD_MAX72XX(MD_MAX72XX::FC16_HW, 10, 4); arduinoFFT FFT = arduinoFFT(); Then in the next lines, define two new arrays to store the 64-bit spectral components for the real and imaginary part of the spectrum. double realComponent[64]; double imagComponent[64]; function. void setup() { disp.begin(); Serial.begin(9600); } Now, within the loop function, we will take 64 samples of microphone readings using the for loop through the A7 pin of Arduino nano and store in into the ‘realComponentᾠarray that we defined earlier. for (int i=0; i<64; i++) { realComponent[i] = analogRead(A7)/sensitivity; imagComponent[i] = 0; } function to compute the magnitude of 64 spectral components. FFT.Windowing(realComponent, 64, FFT_WIN_TYP_HAMMING, FFT_FORWARD); FFT.Compute(realComponent, imagComponent, 64, FFT_FORWARD); FFT.ComplexToMagnitude(realComponent, imagComponent, 64); Now, in the next lines, we used a for loop to control all the 32 columns of the LED matrix. Inside this, for loop, we first converted these readings to a known range and then using the map function, we mapped these readings to a range from 0 to 8. Zero means all the LED of that particular column will be low and vice versa. for(int i=0; i<32; i++) { realComponent[i] = constrain(realComponent[i],0,80); realComponent[i] = map(realComponent[i],0,80,0,8); index = realComponent[i]; value = spectralHeight[index]; c = 31 - i; disp.setColumn(c, value); }

3-D Printing the Casing for Audio Spectrum Visualizer

and you can print your casing using it.

Testing the Music Visualizer

Once the hardware and code were ready, we mounted the circuit inside the 3-D printed casing as shown below. We used a 5V adapter to power the device. Initially, there will be nothing on display but when we play some music or speak in front of the mic then the LEDs of the dot matrix display changes according to the signal intensity. to start a discussion on it. Code #include <arduinoFFT.h> #include <MD_MAX72xx.h> #include <SPI.h> MD_MAX72XX disp = MD_MAX72XX(MD_MAX72XX::FC16_HW, 10, 4); arduinoFFT FFT = arduinoFFT(); double realComponent[64]; double imagComponent[64]; int spectralHeight[] = {0b00000000,0b10000000,0b11000000, 0b11100000,0b11110000,0b11111000, 0b11111100,0b11111110,0b11111111}; int index, c, value; void setup() { disp.begin(); Serial.begin(9600); } void loop() { int sensitivity = map(analogRead(A6),0,1023,50,100); Serial.println (analogRead(A6)); for(int i=0; i<64; i++) { realComponent[i] = analogRead(A7)/sensitivity; imagComponent[i] = 0; } FFT.Windowing(realComponent, 64, FFT_WIN_TYP_HAMMING, FFT_FORWARD); FFT.Compute(realComponent, imagComponent, 64, FFT_FORWARD); FFT.ComplexToMagnitude(realComponent, imagComponent, 64); for(int i=0; i<32; i++) { realComponent[i] = constrain(realComponent[i],0,80); realComponent[i] = map(realComponent[i],0,80,0,8); index = realComponent[i]; value = spectralHeight[index]; c = 31 - i; disp.setColumn(c, value); } } Video microcontroller-projects/building-your-own-sun-tracking-solar-panel-using-arduino

Building your own Sun Tracking Solar Panel using an Arduino

Renewable energy is a type of energy that is harnessed from the nature without causing ill effects to the environment. One of the most prominent kind of renewable energy is solar energy. Solar radiation from the sun is collected by the solar panels and converted into electrical energy. The output electrical energy depends on the amount of sunlight falling on the solar panel. You can check those out if you are looking for more projects on solar power.

How does a Solar Tracker Works?

You must be wondering how does it work? As discussed earlier, the solar panel should face the sun to harness maximum power. So, our system has two steps, first is to detect the position of sun and second is to move along with it. : and compare the intensity of light falling on both LDRs. The LDRs are placed on the edges of the solar panel as shown in the figure below. Based on the intensity of light on the LDR, we give the signal to the servo motor to cause the movement. When the intensity of the light falling on the right LDR is more, the panel turns towards the right and if the intensity is higher on the left then the panel slowly turns towards the left side. Consider a scenario of a beautiful winter morning, the sun rises from east side and therefore it has more light intensity than the west side, so the panel moves towards to east side. Throughout the day it will track the sun and by the evening, sun has moved towards the west, hence it will have more intensity than the east direction so the panel will face the west direction.

Components Required for Making the Solar Tracker

1 x Arduino Uno 1 x Servo motor 1 x Solar panel 2 x LDR 2 x 10k Resistor Jumper wires 1 x MDF board Servo motor is used to rotate the solar panel. We are using servo motor because we can control the position of our solar panels precisely and it can cover the whole path of sun. We are using a servo motor that can be operated with 5volt. A light-dependent resistor is made from semiconductor material having light-sensitive properties and hence are very sensitive to light. The resistance of LDR changes according to the light that falls on it and it is inversely proportional to the intensity of light. That is resistance of the LDR will increase at high-intensity light and vice versa.

Schematics and Connection of the Solar Tracker

The connection of the circuit is very straightforward. Here, I used an ArduinoUno as controller and connected the 2 LDRs to analogue pin A0 and A1 respectively. Pin 9 of Arduino is connected to the servo motor. Since, we have used a 5V servomotor, we don’t require any external power supply because all the components can easily be powered the Arduino itself. All the connections are shown in the figure below.

Assembling the Solar Tracker

The first step before assembling our solar tracker is to construct the base. For building the base, I am going to use a MDF board. First step is to cut and make rectangular pieces of 12*8cm and 12*2cm from the MDF board as shown in the figure. Then stick 12*2cm piece vertically to the 12*8cm piece as shown in the image. Next step is to attach the solar panel with the servo motor, for that we require theL-shaped contraption. For this,I am using a plastic piece, you can also make this by bending a plastic sheet or aluminum sheet and finally glue the solar panel to your contraption. Note: If you are going to make a tracker for a large solar panel then you should use different materials for bases such as aluminium or wood. Second terminal of the LDRs are directly connected to the 5v output. The output of each LDR, I connected it to A1 and A2 pins of Arduino. Next step is to connect the servo motor, a servo motor has three wires, i.e. ground, V_in and a signal wire. I connected the V_in pin to the 5volt of Arduino, ground to the common ground and the signal wire to pin-9 of Arduino. That's all about the circuit. Now, all we have to do is assemble everything. First, I glued the Arduino on the base sheet. Then I attached the servo motor to the vertical section using glue gun. Finally, I fixed the solar panel with the servo motor’s hand and secured it with a screw.

Let’s see how does the code works?

to control the motion of the servo. The step-by-step explanation of the program is given below. #include <Servo.h> Servo servo ; First, I included the servo library and created a servo object and named it as ‘servoᾮ int eastLDR = 0; int westLDR = 1; int east = 0; int west = 0; int error = 0; Here, I have assigned the analogue pins A0 and A1pins for LDR and declared the variables for sensor values. int calibration = 0; This variable is for calibrating the system, if you are using exactly same LDRs on both sides then you can leave it as zero. But if you are using different LDRs then you should use this to calibrate. To calibrate, follow the instruction in next paragraph. Serial print the sensor values and check the reading of each sensor in the noon or placea light source just above the solar panel. If the reading shows the same values,then you can leave this as it is and if it shows any difference, then you have to copy those values here. int servoposition = 90; This variable is to store the servo position. void setup() { servo.attach(9); } In the section, I have defined the servo pin as pin 9 east = calibration + analogRead(eastLDR); west = analogRead(westLDR); In the loop section, first step is to read the LDR values using the analogue read function of Arduino and store it in east and west variables. if(east<350 && west<350) { while(servoposition<=150) { servoposition++; servo.write(servoposition); delay(100); } This if condition is for turning the solar panel back to the east side, i.e. if both the LDRs read low value then the panel moves towards the east side. error = east - west; Here, we calculate the difference between east and west readings. If the error value is positive that means east has more intensity and if the error is negative then west has higher intensity of light. So, according to this error value, we can rotate the servo to the low-intensity side. if(error>30) { if(servoposition<=150) { servoposition++; servo.write(servoposition); } } If the error is positive and greater than 30, it means that the east side has more intensity. So, initially the system will check the starting position of servo and if it is less than 150 degrees then it rotates to the east direction. You can adjust these angles according to your system. else if(error<-30) { if(servoposition>20) { servoposition--; servo.write(servoposition); } If the error is negative and less than -30 that means the west side is more intense, hence servo rotates to the west side. So, that's all about coding. Now you can open this code on your ArduinoIDEand upload the sketch to your Arduino. I hope that you enjoyed this project. Ithas a lot of application in real life and it is implemented in a lot of solar farms and individual solar harnessing setups. You can enhance the scope of this project by replacing the 5V servo motor with a high torque servo motor and connectit using a relay and powerthe servo from an external source. As mentioned above, if you are having bigger solar panels, then you will have to use stronger material such as aluminum for base. Code #include <Servo.h> Servo servo ; int eastLDR = 0; int westLDR = 1; int east = 0; int west = 0; int error = 0; int calibration = 600; int servoposition = 90; void setup() { servo.attach(9); } void loop() { east = calibration + analogRead(eastLDR); west = analogRead(westLDR); if (east < 350 && west < 350) { while (servoposition <= 150) { servoposition++; servo.write(servoposition); delay(100); } } error = east - west; if (error > 15) { if (servoposition <= 150) { servoposition++; servo.write(servoposition); } } else if (error < -15) { if (servoposition > 20) { servoposition--; servo.write(servoposition); } } delay(100); } Video microcontroller-projects/how-to-use-edge-impulse-signal-based-model-training-to-train-a-fever-detection-model

How to use Edge Impulse Signal based Model Training to train a Fever Detection Model

AI has been a buzzword this entire decade. People have been applying the concepts of AI in all possible fields ᾠAgriculture, Medical Imaging, Autonomous Driving, Biometrics, encryption, Data Analysis, FinTech, and what not. However, because it is a rapidly emerging field there is a lot of changing and upcoming technologies. Frameworks get old within months and libraries start causing more errors than they should due to outdated software dependencies. Due to all this, it might be a very inconvenient, steep learning curve for a maker to develop his own AI model without spending months just to realize the model he has created is no longer optimized and the things he figured out are outdated. to identify if a person has a fever or not.

What is Edge Impulse?

libraries in all popular formats so that you can run inference on the go.

Why Use Edge Impulse Models for Signals?

as it can be easily integrated with the library exported by edge impulse. For this project, we will integrate the MLX90614 sensor to measure the temperature of a person’s finger and predict if he/she has a fever or not. While at first thought it might be a simple case of thresholding, I assure you it is not. Why? Simply because of the following reasons: Ambient Temperature and distance between the finger and the mlx sensor significantly change the measured value of the object temperature. The same person might have slightly different core body temperatures on different days Different people of different ethnic backgrounds also have different emissivities and slightly different core temperatures The temperature of a finger is a few degrees lower than the core body temperature So, while theoretically, the temperature at which fever is considered to have set is around 100 degF according to modern standards, just thresholding the measured object temperature value will give a lot of false readings affecting your model’s accuracy.

Circuit Diagram for Interfacing MLX90614 with Arduino Nano 33 IoT

The schematic is very simple. We will be using the mlx90614 and a 1.3ᾠOLED I2C display. The connections are very simple as both the modules (MLX90614 & OLED display) works on I2C.
5VVCC
GNDGND
A4SDA
A5SCL

Training a Fever Detection Model with Edge Impulse Studio

Training a Machine Learning model with Edge Impulse is very simple and can be completed in 7-8 steps. All the steps for Training a model with Edge Impulse are explained below: The first step is to register on the edge Impulse website. After registration, you will see the Dashboard screen which will show you the basic workflow of model development at edge impulse. You will be asked to create and name a new project. As mentioned under project info, select the Labelling method to be “one label per data itemᾠand the Latency calculations to Cortex-M4F 80 MHz. For vision-based models, you can select the bounding boxes option. There are a lot of other processors and boards fully supported by the edge impulse platform, like the Spresense kit, ST discovery IoT kit, etc. In the danger zone, there is an option called rebalance dataset, which will divide your training and test data in an 80:20 percentage ratio. Now the second step is collecting the data for model training. If you click on the “LET’S COLLECT SOME DATAᾠbutton, you will see a variety of options. , first, upload the data collection script provided to your Arduino 33 IOT board setup. With the device still plugged into your Laptop/Desktop, open a cmd or terminal with admin or sudo rights and type the following command: $ edge-impulse-data-forwarder The data forwarder should then respond accordingly: Edge Impulse data forwarder v1.5.0 ? What is your user name or e-mail address (edgeimpulse.com)? <enter registered email-id> ? What is your password? <enter password> Endpoints: Websocket: wss://remote-mgmt.edgeimpulse.com API: https://studio.edgeimpulse.com Ingestion: https://ingestion.edgeimpulse.com [SER] Connecting to /dev/tty.usbmodem401203 [SER] Serial is connected [WS ] Connecting to wss://remote-mgmt.edgeimpulse.com [WS ] Connected to wss://remote-mgmt.edgeimpulse.com ? To which project do you want to add this device? <project_name> ? 3 sensor axes detected. What do you want to call them? Separate the names with ',': <axis1,axis2,axis3,…> ? What name do you want to give this device? <device_name> [WS ] Authenticated Enter the valid registration credentials, name of the project you just created, and name the 2 axes that are detected as O_Temp and A_Temp respectively. The data frequency should be detected automatically. This is how it will look- If you move back to the edge impulse UI, you should see the name of the just added device as shown below- The green dot indicates that the device is active and plugged. Now, select the Data acquisition tab on the left and you will be able to see the following page: Enter the desired sample length and then click on the Start Sampling button. The counter should start in place of the sampling button just pressed and after the entered time has elapsed, the data collected will be displayed as shown. You can rename the sample and change its label by clicking on the 3 dots at the right of each collected sample. To visualize the sample collected, just click on it. Few things to note: Collect at least9 minutes of data, equally divided into three classes ᾠNo finger, healthy, and fever. Collect 1 sample of 100 seconds each for all three labels on each day for multiple days, so that your model works for a variety of ambient temperatures. For the first class, just remove your finger over the sensor and let it be as is. In the second case, keep your finger 1 cm away from the sensor and for the fever label, touch your finger to the sensor. Use The oled display should show you the temperature that is being measured by the sensor. Fingers are 5-6 degF lower than core body temperature, and we are assuming the fever threshold to be 100 degF. You can also collect test data by selecting the “Test dataᾠtab beside the “Training dataᾠtab currently selected. You can also use the rebalance data button and divide the dataset automatically in an 80:20 ratio. For test data, 100-second sample length should be convenient and for test data, 10-second sample length should be convenient. Edge Impulse allows you to split and crop your samples as well so remove any spikes or erroneous data before proceeding further. Impulses are used to train the model from the collected signal values. Select the Impulse design tab on the left and you will see a new page. Set it up to look as follows- Look at the various options and blocks available. You can choose the blocks as per your data and even select the axes you want to train the data on. Edge impulse explains each block and its general use case. We will be using raw data as it allows us to directly feed the values from our sensor to the model’s API and also saves processing time. Keep the frequency to two hertz. This will mean that we will feed sensor data to the model every 500ms. Note that this does not mean we will be reading data from the sensor at the same rate. We might read the data faster just to average it out before feeding it to the model. Hence, our sample length will be 1/frequency or 500ms. With a window size of 500ms, we will run inference on 500ms length of data together, which in our case is the length of a single sample. The more the window size, the more the samples that will be classified together, the more will be the feature list. To avoid complications, we will classify each sample separately. Keep both ᾠO_Temp and A_Temp checked in the raw data block as we want our model to work at various ambient temperatures. Now we move on to create features from our raw data. Under impulse design, once you have saved the impulse you just created, the circle beside “Create impulseᾠshould turn green indicating your impulse has been created. You should also see additional tabs like “Raw dataᾠdepending on the blocks you have added. When you click on the raw data tab, the following page should open ᾍ You can use the drop-down on the top right to select which collected training sample you want to see. Below the visualization, you can see two types of features ᾠraw and DSP. DSP features are not of importance in this project hence we will shed light on them later. The raw features if you look closely are nothing but O_Temp,A_Temp or 1 sample which we are collecting. This seems to be correct as we had used a frequency of 2 and a window size of 500 ms. On the Topmost tab select “Generate featuresᾠwhich will lead to this page- You will not be seeing any graph because we have not yet generated any features. Click on the “Generate featuresᾠbutton and you will see that edge impulse has started learning features from the collected data. It basically runs a K-means algorithm, clustering data having the same label together. You should be able to see a 3D graph on the right, with all the different labels in different colors. Once this is done, we can now proceed to training the model. Select the NN Classifier tab on the left. You will be able to see the window shown below, keep the default settings as it is or modify them a bit as I have done. Click on start training and within a few minutes, you should have 50 epochs done, showing you the accuracy of the model. Since this is a relatively simple problem, we should see a very high accuracy of >98%. After this, we can check how well the model is performing using the live classification tab. You can take a new sample by attaching the registered data collection device using the data forwarder or you can classify an existing test sample. You will be able to see how well each window of the new/test sample has been classified visually and in a report-like format under the “Detailed resultᾠsection. Now we will see how the model performs on the test data we have collected overall. Select the “Model testingᾠtab and press the “Classify allᾠbutton. You should see the test accuracies in the form of a confusion matrix. Versioning will help you create multiple versions of the same model and project. Finally, we move on to the Deployment tab. Select the Arduino library option under create a library and then go down. You will see the available optimization options for the NN classifier. Press on the Analyze optimizations button to see which optimization is better. In our case, float32 performs better hence we will build the library using that. Click on the build button and a zip file should automatically start downloading. Congratulations! You have successfully built your first edge impulse model!

Deploying the Trained Model on Arduino Nano 33 IoT

So, the following array- static const float features[] = { // copy raw features here (for example from the 'Live classification' page) // see https://docs.edgeimpulse.com/docs/running-your-impulse-arduino }; Inside the static_buffer example has been replaced with Object = mlx.readObjectTempF(); Ambient = mlx.readAmbientTempF(); ei_printf("Edge Impulse standalone inferencing (Arduino)\n"); features[0] = Object; features[1] = Ambient; In our modified version This allows us to run our classification live on the Arduino Nano 33 IOT. The rest of the code requires a very deep understanding of Tf-lite and edge impulse APIs which is beyond the scope of this already extensive project. Once you are done with the changes, select the Arduino 33 IoT in Board type and upload the code. After uploading the code open the serial monitor and the output looks as follows- Code /* Edge Impulse Arduino examples * Copyright (c) 2021 EdgeImpulse Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* Includes ---------------------------------------------------------------- */ #include <cstdarg> #define EIDSP_USE_CMSIS_DSP 1 #define EIDSP_LOAD_CMSIS_DSP_SOURCES 1 #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline #define __SSAT(ARG1, ARG2) \ __extension__ \ ({ \ int32_t __RES, __ARG1 = (ARG1); \ __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ __RES; \ }) #include <Wire.h> #include <Adafruit_MLX90614.h> #include <Adafruit_GFX.h> #include <U8x8lib.h> #include <hackster_neo_inferencing.h> #define DELAY_MS 1000 #define DISPLAY_INTERVAL 1 * 1000/DELAY_MS //update rate for the i2c display = REPORTING_PERIOD_MS*DISPLAY_INTERVAL #define COMPENSATION 5 //compensation in object temperature. Different body parts have different temperatures. Fingers are around 5 degF lower than core body temperature Adafruit_MLX90614 mlx = Adafruit_MLX90614(); U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); size_t ix = 0, i = 0; float features[2], Object, Ambient;; int count = 0, flag = 0; /** * @brief Copy raw feature data in out_ptr * Function called by inference library * * @param[in] offset The offset * @param[in] length The length * @param out_ptr The out pointer * * @return 0 */ int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) { memcpy(out_ptr, features + offset, length * sizeof(float)); return 0; } /** * @brief Arduino setup function */ void setup() { u8x8.begin(); u8x8.setPowerSave(0); u8x8.setFont(u8x8_font_chroma48medium8_r); // put your setup code here, to run once: Serial.begin(115200); /* while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } */ mlx.begin(); Serial.println("Edge Impulse Inferencing Demo"); } /** * @brief Arduino main function */ void loop() { count++; flag = 0; Object = mlx.readObjectTempF(); Ambient = mlx.readAmbientTempF(); ei_printf("Edge Impulse standalone inferencing (Arduino)\n"); features[0] = Object; features[1] = Ambient; if (sizeof(features) / sizeof(float) != EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) { ei_printf("The size of your 'features' array is not correct. Expected %lu items, but had %lu\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, sizeof(features) / sizeof(float)); delay(1000); return; } ei_impulse_result_t result = { 0 }; // the features are stored into flash, and we don't want to load everything into RAM signal_t features_signal; features_signal.total_length = sizeof(features) / sizeof(features[0]); features_signal.get_data = &raw_feature_get_data; // invoke the impulse EI_IMPULSE_ERROR res = run_classifier(&features_signal, &result, false /* debug */); ei_printf("run_classifier returned: %d\n", res); if (res != 0) return; // print the predictions ei_printf("Predictions "); ei_printf("(DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n", result.timing.dsp, result.timing.classification, result.timing.anomaly); //ei_printf(": \n"); ei_printf("["); for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { //ei_printf("%.5f", result.classification[ix].value); ei_printf("%d", static_cast<int>(result.classification[ix].value * 100)); #if EI_CLASSIFIER_HAS_ANOMALY == 1 ei_printf(", "); #else if (ix != EI_CLASSIFIER_LABEL_COUNT - 1) { ei_printf(", "); } #endif } #if EI_CLASSIFIER_HAS_ANOMALY == 1 //ei_printf("%.3f", result.anomaly); ei_printf("%d", static_cast<int>(result.anomaly)); #endif ei_printf("]\n"); // human-readable predictions for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { //ei_printf(" %s: %.5f\n", result.classification[ix].label, result.classification[ix].value); ei_printf(" %s: %d\n", result.classification[ix].label, static_cast<int>(result.classification[ix].value * 100)); } #if EI_CLASSIFIER_HAS_ANOMALY == 1 ei_printf(" anomaly score: %.3f\n", result.anomaly); #endif if ((count%DISPLAY_INTERVAL == 0) && (flag != 1)) { flag = 1; //This flag makes sure the display is updated only once every DISPLAY_INTERVAL seconds Wire.end(); u8x8.clearDisplay(); u8x8.setCursor(0,0); u8x8.print(result.classification[0].label); u8x8.setCursor(0,1); u8x8.print(result.classification[0].value * 100); u8x8.print(" %"); u8x8.setCursor(0,2); u8x8.print(result.classification[1].label); u8x8.setCursor(0,3); u8x8.print(result.classification[1].value * 100); u8x8.print(" %"); u8x8.setCursor(0,4); u8x8.print(result.classification[2].label); u8x8.setCursor(0,5); u8x8.print(result.classification[2].value * 100); u8x8.print(" %"); u8x8.setCursor(0,6); u8x8.print("Object: "); u8x8.print(Object); u8x8.print("F"); u8x8.setCursor(0,7); u8x8.print("Ambient: "); u8x8.print(Ambient); u8x8.print("F"); Wire.begin(); } delay(DELAY_MS); } /** * @brief Printf function uses vsnprintf and output using Arduino Serial * * @param[in] format Variable argument list */ void ei_printf(const char *format, ...) { static char print_buf[1024] = { 0 }; va_list args; va_start(args, format); int r = vsnprintf(print_buf, sizeof(print_buf), format, args); va_end(args); if (r > 0) { Serial.write(print_buf); } } /*************************************************** This is a library example for the MLX90614 Temp Sensor Designed specifically to work with the MLX90614 sensors in the adafruit shop ----> https://www.adafruit.com/products/1747 3V version ----> https://www.adafruit.com/products/1748 5V version These sensors use I2C to communicate, 2 pins are required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution ****************************************************/ #include <Wire.h> #include <Adafruit_MLX90614.h> #include <Adafruit_GFX.h> #include <U8x8lib.h> #define DELAY_MS 50 #define DISPLAY_INTERVAL 1 * 1000/DELAY_MS //update rate for the i2c display = REPORTING_PERIOD_MS*DISPLAY_INTERVAL #define COMPENSATION 5 //compensation in object temperature. Different body parts have different temperatures. Fingers are around 5 degF lower than core body temperature Adafruit_MLX90614 mlx = Adafruit_MLX90614(); U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); int count = 0, flag = 0; float Object, Ambient; void setup() { u8x8.begin(); u8x8.setPowerSave(0); u8x8.setFont(u8x8_font_chroma48medium8_r); Serial.begin(9600); Serial.println("Adafruit MLX90614 test"); mlx.begin(); } void loop() { Object = mlx.readObjectTempF(); Ambient = mlx.readAmbientTempF(); Serial.print(Object); Serial.print(","); Serial.println(Ambient); count++; flag = 0; if ((count%(int(DISPLAY_INTERVAL)) == 0) && (flag != 1)) { flag = 1; //This flag makes sure the display is updated only once every DISPLAY_INTERVAL seconds Wire.end(); send_display(); Wire.begin(); } delay(DELAY_MS); } void send_display() { u8x8.clearDisplay(); u8x8.setCursor(0,1); u8x8.print("Object:"); u8x8.print(Object); u8x8.print(" degF"); u8x8.setCursor(0,2); u8x8.print("Ambient:"); u8x8.print(Ambient); u8x8.print(" %"); //delay(200); } Video microcontroller-projects/interfacing-154-inch-epaper-display-with-arduino-uno

Interfacing 1.54-inch E-Paper Display with Arduino UNO

and we will interface this small E-paper display with Arduino UNO. We can interface it with other boards also for example ᾠRaspberry Pi, STM32, and jetson. Here, we will print characters and images in the E-paper display and at the end of this tutorial, we will also see the power consumption and discuss the advantages and disadvantages of E-Paper display.

Introduction to 1.54-Inch E-Paper Display

Waveshare's 1.54-inch e-Ink Paper Display Module with SPI Interface has a resolution of 200x200 pixels and has an embedded controller module. It communicates through the SPI interface and allows for a partial refresh. These displays offer a huge advantage of ultra-low power consumption because they don't have backlight panels and don't require a continuous power supply to display the (static data with periodic intervals) data on the screen. It also offers a broad viewing angle and a good viewing effect in the sun, making it an excellent choice for shelf labels, industrial instruments, and other similar applications. In this tutorial, we are going to use a 1.54-inch E-Paper display whichcosts around 15$.

Features of E-Paper Display

No backlight keeps displaying last content for a long time even when power down Ultra-low power consumption, basically power is only required for refreshing SPI interface, for connecting with controller boards like Raspberry Pi/Arduino/Nucleo, etc. Onboard voltage translator, compatible with 3.3V/5V MCUs Comes with development resources and manual (examples for Raspberry Pi/Jetson Nano/Arduino/STM32)

Specifications of E-Paper Display

Operating voltage: 3.3V/5V Interface: 3-wire SPI, 4-wire SPI Outline dimension: 48mm × 33mm Display size: 27.6mm × 27.6mm Dot pitch: 0.138 × 0.138 Resolution: 200 × 200 Display color: black, white Grey level: 2 Partial refresh time: 0.3s Full refresh time: 2s Refresh power: 26.4mW (typ.) Standby power: <0.017mW Viewing angle: >170°

Working Principle of e-Paper Display

(MED) technology whichis one of the famous image display technology. In this technology, the first step is to make microscopic spheres in which charged color pigments are suspended in clear oil and move in response to the electronic charge. In the E-paper display, there is no background light because the E-paper screen displays patterns by reflecting ambient light. The E-paper screen offers a wide viewing angle of 180 degrees and is very visible in ambient light so because of the wide range of viewing angles, E-paper displays are widely used in Digital tablets for E-reading. We should not use this display in direct sunlight because it doesn’t have any backlight.

Communication Protocol of E-Paper Display

E-Paper display communicates through SPI protocol but theSPI protocol used here is slightly different from standard SPI protocol. Here SPI only has display requirements so the data line from the slave to the master is buried, unlike the standard SPI protocol. In the below table, we can see the Pin description of the E-Paper display.
PinDescription
VCC3.3V/5V
GNDGround
DINSPI MOSI pin
CLKSPI SCK pin
CSSPI chip selection, low active
CSData/Command selection (high for data, low for command)
RSTExternal reset, low active
BUSYBusy status output, high active
Now, we will see the working of SPI protocol in E-Paper display: (a) When CS is low, the chip is enabled, and when CS is high, the chip is disabled. (b) DC is the data/command control pin; if DC is 0, write command; if DC is 1, and write data. (c) The SPI communication clock is known as SCLK. (d) In SPI communication, the data line from the master to the slave is known as SDIN. The data transfer timing of SPI communication is combined by CPHA and CPOL. 1- At idle state, CPOL determines the level of the serial synchronous clock. When CPOL equals 0, the level is considered low. CPOL, on the other hand, has little influence on transmission. 2- When CPHL = 0, data is collected at the first clock edge of the serial synchronous clock; when CPHL = 1, data is collected at the second clock edge of the serial synchronous clock. (e) There are four SPI communication options to choose from. The SPI0 method is widely used, with CPHL = 0 and CPOL = 0. Data transmission begins at the first falling edge of SCLK, as shown in the diagram below, and 8 bits of data are communicated in one clock cycle. SPI0 is utilized here, and data is transmitted in bits, MSB first.

Interfacing of E-paper Display with Arduino UNO

Now, we are going to interface a 1.5-inch E-Paper display with Arduino UNO. The E-Paper display offers a resolution of 200x200pixels which is great anduses the SPI interface. E-Paper display supports a 3.3V display so Vcc must be connected to the 3.3V output of the Arduino Uno. The other pins of the display are 5V tolerant. The second pin is GND and it connects to theGND pin of Arduino UNO. The third pin is named DIN and it connects to Digital Pin 11. The fourth pin is CLK and it connects to Digital Pin 13. The fifth pin (CS) connects to digital pin 10, the 6th pin (DC) connects to digital pin 9, the 7th pin (RST) connects to digital pin 8 (BUSY) and the last pin connects to digital pin 7.
E-Paper PinsArduino UNO Pins
3.3V3.3V
GNDGND
DIND11
CLKD13
CSD10
DCD9
RSTD8
BUSYD7
Here, in below figure we have shown hardware connection of Arduino UNO and 1.54-inch E-Paper display. In the below image you can see actual hardware image of interfacing circuit of E-Paper display and Arduino UNO. library for printing images on E-Paper display. #include <SPI.h> #include "epd1in54_V2.h" #include "imagedata.h" #include "epdpaint.h" #include <stdio.h> Here are using Serial.println function to print the statement “welcome toᾠin the first line. We have only two colors for the E-Paper display, first one is the black and the second one is white. So we have used Paint.DrawString to give color and size to text. Same thing we have done for the next line “Circuit Digestᾮ Serial.println("WELCOME TO"); paint.Clear(COLORED); paint.DrawStringAt(30, 4, "WELCOME TO", &Font16, UNCOLORED); epd.SetFrameMemory(paint.GetImage(), 0, 10, paint.GetWidth(), paint.GetHeight()); paint.Clear(UNCOLORED); paint.DrawStringAt(30, 4, "CIRCUIT DIGEST", &Font16, COLORED); epd.SetFrameMemory(paint.GetImage(), 0, 30, paint.GetWidth(), paint.GetHeight()); paint.SetWidth(64); paint.SetHeight(64); epd.DisplayFrame(); delay(2000); tutorial. Here, we have given the hex code for the CircuitDigest logo. We have to write this code in imagedata.cpp library. const unsigned char IMAGE_DATA[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ………………………………….. ………………………………….. }; In the below images, you can see the circuit digest logo on the E-Paper display. Here, we have used very few lines and one image to print it on E-Paper display but it consumed a lot of memory of Arduino ᾠUNO so we need to use another board with more memory like the ESP8266, the ESP32, STM32, and Raspberry Pi. E-Paper display can update part of the display, without updating the whole display. Refreshing the entire display takes around 2 seconds and a lot of currents, this is really beneficial. The updating of a portion of the display, on the other hand, is quick and does not require a lot of current.

Power Consumption in E-Paper Display

Now, we are going to measure power consumption in the E-Paper display using a USB current meter. When the E-Paper display is updating then it needs lots of current (around 7-9mA) and when the display is not updating then it draws only 0.02 mA current. So power consumption is very less in the E-Paper display. We can use an E-Paper display in battery-powered projects. Even project cab run on battery for months. Here in the below image, you can see two different power consumption during updating and after updating, here we are getting higher values because we are measuring the current value including Arduino-UNO.

Advantages of E-Paper Display

E-Paper or Electronic paper display does not emit light but reflects. These displays are not like traditional LCD or OLED displays. It is like the ink on the paper. This characteristic makes e-paper displays very comfortable to read, and they have excellent readability under direct sunlight. Another great thing about e-paper displays is that they can hold static text and images for months without electricity. The display can show text and images even when it is off! That makes e-paper displays ideal for low-powered projects.

Disadvantages of E-Paper Display

The price of an E-paper display is very high as compared to other displays. Another significant disadvantage is that E-Paper displays take a lot of time to update, as much as 2-3 seconds. So, they are only helpful for static text and images and not for animations. So these displays are used for only reading purposes. We cannot use an E-Paper display for animations and videos. to start a discussion on this. Code #include <SPI.h> #include "epd1in54_V2.h" #include "imagedata.h" #include "epdpaint.h" #include <stdio.h> Epd epd; unsigned char image[1024]; Paint paint(image, 0, 0); unsigned long time_start_ms; unsigned long time_now_s; #define COLORED 0 #define UNCOLORED 1 void setup() { // put your setup code here, to run once: Serial.begin(115200); Serial.println("e-Paper init and clear"); epd.LDirInit(); epd.Clear(); paint.SetWidth(200); paint.SetHeight(24); Serial.println("WELCOME TO"); paint.Clear(COLORED); paint.DrawStringAt(30, 4, "WELCOME TO", &Font16, UNCOLORED); epd.SetFrameMemory(paint.GetImage(), 0, 10, paint.GetWidth(), paint.GetHeight()); paint.Clear(UNCOLORED); paint.DrawStringAt(30, 4, "CIRCUIT DIGEST", &Font16, COLORED); epd.SetFrameMemory(paint.GetImage(), 0, 30, paint.GetWidth(), paint.GetHeight()); paint.SetWidth(64); paint.SetHeight(64); epd.DisplayFrame(); delay(2000); Serial.println("e-Paper show pic"); // epd.Display(IMAGE_DATA); //Part display epd.HDirInit(); epd.DisplayPartBaseImage(IMAGE_DATA); paint.SetWidth(50); paint.SetHeight(60); } void loop() { } imagedata.cpp library #include "imagedata.h" #include <avr/pgmspace.h> const unsigned char IMAGE_DATA[] PROGMEM = { /* 0X00,0X01,0XC8,0X00,0XC8,0X00, */ // 'unnamed, 200x200px 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x3f, 0xf3, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x3f, 0xe0, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x7f, 0xc0, 0x00, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0xff, 0x8e, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0xff, 0x9e, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc1, 0xff, 0x9e, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x81, 0xff, 0x8e, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x03, 0xff, 0xc0, 0x7f, 0xc0, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x03, 0xff, 0xe0, 0xff, 0xf0, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xc1, 0xff, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0x80, 0xff, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x18, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x3c, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x3c, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x1c, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x08, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x03, 0xff, 0x81, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x7f, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x7f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xe0, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc1, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x81, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x83, 0xff, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x03, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfe, 0x31, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfe, 0x78, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfe, 0x78, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfe, 0x78, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xfe, 0x30, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x80, 0x04, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0xe3, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0xf3, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf8, 0xf3, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0xe3, 0xff, 0xfc, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x07, 0xff, 0xf0, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfe, 0x0f, 0xfc, 0x00, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xbf, 0xf8, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf8, 0xe0, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf9, 0xf1, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf9, 0xe3, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0xe7, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xfc, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xfe, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x28, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xc1, 0x83, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x86, 0x10, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x0c, 0x1e, 0x00, 0x00, 0x01, 0xc1, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x38, 0xfc, 0x7f, 0x98, 0x18, 0xe7, 0xf9, 0x80, 0x21, 0x07, 0xf8, 0x3f, 0x03, 0xf3, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0xfc, 0xf1, 0x18, 0x18, 0xe7, 0xf9, 0x80, 0x31, 0x0c, 0x08, 0x60, 0x84, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0xc0, 0xc0, 0x18, 0x18, 0xe1, 0x81, 0x80, 0x31, 0x08, 0x08, 0x40, 0xc4, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0xc0, 0xc0, 0x18, 0x18, 0xe1, 0x81, 0x80, 0x31, 0x08, 0x0c, 0xc0, 0x46, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x38, 0xc1, 0xc0, 0x18, 0x18, 0xe1, 0x81, 0x80, 0x21, 0x18, 0x0c, 0xff, 0xc3, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x38, 0xc1, 0xc0, 0x18, 0x18, 0xe1, 0x81, 0x80, 0x21, 0x18, 0x0c, 0xc0, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x38, 0xc0, 0xc0, 0x1c, 0x18, 0xe1, 0x81, 0x80, 0x61, 0x08, 0x0c, 0xc0, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x86, 0x38, 0xc0, 0xe0, 0x1c, 0x18, 0xe1, 0x81, 0x80, 0xc1, 0x0c, 0x0c, 0x40, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x38, 0xc0, 0x7f, 0x8f, 0xf8, 0xe1, 0xc1, 0x87, 0x81, 0x06, 0x18, 0x30, 0x84, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x30, 0xc0, 0x3f, 0x07, 0xf8, 0x61, 0x81, 0xfe, 0x01, 0x03, 0xf8, 0x1f, 0x87, 0xe0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; Video microcontroller-projects/design-and-build-an-arduino-touch-capacitive-piano-with-recording-and-replay

Design and Build an Arduino Based Touch Capacitive Piano with Recording and Replay

, we will also explore how we designed and fabricated this board but before that, let's explorecapacitive touch sensors and how it works.

How a Capacitive Touch Sensor Works?

C = A/d Where "A" is representing the area of the conducting plates, "d" is representing the distance between the two conductive plates and the "" is representing the permittivity of the AIR. As a result, increasing the area and decreasing the distance between the two parallel conductive plates increases the capacitance value. In our case, touching the conductive plate reduces the distance while increasing the capacitance value. Can we detect this changing capacitance by connecting a conductive material to a resistor and a microcontroller's GPIO pin? The answer is, we can't. Yes, connecting a voltage source to it will cause a small change in the analog voltage, but this is not a very robust solution.

How to Detect the Capacitance Change in a Capacitive Touch Sensor?

So, how could we tell if the capacitance value had changed? There is, however, a better way to go about it. Let's take a look at the block diagram below. Consider this to be a basic circuit consisting of a Microcontroller (in this case, an Arduino Nano), a 1 Mega Ohm resistor, and a Conductive Plate. The Arduino Nano's two digital lines are connected to a resistor loop with a 1 megaohm resistor. This resistor is also connected to the conductive plate at one point. Although this plate is acting as a single point of the capacitor, it can still introduce capacitance that changes when we touch it. This, however, cannot be detected simply by detecting a change in voltage. The change in capacitance on this line is not as easy as sensing the toggle of the on or off the value on the GPIO pin. The change in capacitance on this line is not as simple as sensing the toggle of the GPIO pin's value on or off.

How the Capacitive Sensor Library Works?

As a result, we can determine what the normal state is and then check for changes each time they send pin toggles. platform. On the EasyEDA platform, we've created a large number of PCB projects. Those projects can be used to obtain a concept of how to design a PCB on EasyEDA.

Components Required to build a PCB Piano using Arduino Nano

The following components are required to build a PCB Piano using Arduino Nano. Arduino Nano Resistors (1Mega Ohm) X 8 Piezoelectric Buzzer 18650 Battery cell 18650 Battery cell holder 18650 battery Charging Module DC to DC Voltage Booster.

Circuit Diagram for the PCB Piano Using Arduino Nano

of the Arduino Nano. .

The Overview of the PCB

from our GitHub Repo. Or, you can visit the project on EasyEDA platform for more details. The yellow color is for the Top-Silk Layer. Whereas the Green color is representing the bottom silk Layer. The Red Color is for the Top- Layer and the Blue color is representing the Bottom-Layer. Now, let’s see every layer of the PCB one by one. The top-layer is shown in the image below. As you can see the Top-Layer is Red in color. I have designed each conductive plate in such a way that it looks like a piano. Every key of the piano is connected to each of the 1 megaohm resistors respectively. I used the Rectangular shape that can be found in the PCB Tool section on the EasyEDA that is circled in red color in the image below. Make sure that the width of the keys is large enough so that you can touch each of the keys with your finger. In my case, I managed to draw every key having 10mm or greater than 10mm width.

The Bottom-Layer of the PCB:

This step will convert the bottom layer as a common grounded layer. We have some other copper connections at this layer. which are available on the EasyEDA. At the bottom silk layer of the PCB we have the footprint of the Arduino Nano, eight 1Mega ohm resistors, eight capacitors, one 18650 batter holder or single cell and the charging module.

Ordering PCB from PCBWay

Now after finalizing the design, you can proceed with ordering the PCB: , sign up if this is your first time. Then, in the PCB Prototype tab, enter the dimensions of your PCB, the number of layers, and the number of PCB you require. Proceed by clicking on the ‘Quote Nowᾠbutton. You will be taken to a page where to set a few additional parameters like the Board type, Layers, Material for PCB, Thickness, and More, most of them are selected by default, if you are opting for any specific parameters, you can select it inhere. The final step is to upload the Gerber file and proceed with the payment. To make sure the process is smooth, PCBWAY verifies if your Gerber file is valid before proceeding with the payment. This way, you can sure that your PCB is fabrication friendly and will reach you as committed. After a few days, we received our PCB in a neat package and the PCB quality was good as always.

Program the Piano PCB Using Arduino Nano

option as shown in the image below. Then restart the Arduino IDE. file. #include <CapacitiveSensor.h> #include "piano_tones.h" #define common_pin 2 // The common ‘send’ pin for all keys #define buzzer A4 // The output pin for the piezo buzzer #define recordbtn 12 // The recording button #define CPin(pin) CapacitiveSensor(common_pin, pin) for multiple times. int notes[]={NOTE_C7,NOTE_D7,NOTE_E7,NOTE_F7,NOTE_G7,NOTE_A7,NOTE_B7,NOTE_C8}; // Sound on startup int soundOnStartUp[] = { NOTE_E7, NOTE_E7, 0, NOTE_E7, 0, NOTE_C7, NOTE_E7, 0, NOTE_G7, 0, 0, 0, NOTE_G6, 0, 0, 0 }; CapacitiveSensor keys[] = {CPin(3), CPin(4), CPin(5), CPin(6), CPin(7), CPin(8), CPin(9), CPin(10)}; function that we have defined before. void recordButtons(){ // Set the sensitivity of the sensors. long touch1 = keys[0].capacitiveSensor(sensitivity); long touch2 = keys[1].capacitiveSensor(sensitivity); long touch3 = keys[2].capacitiveSensor(sensitivity); long touch4 = keys[3].capacitiveSensor(sensitivity); long touch5 = keys[4].capacitiveSensor(sensitivity); long touch6 = keys[5].capacitiveSensor(sensitivity); long touch7 = keys[6].capacitiveSensor(sensitivity); long touch8 = keys[7].capacitiveSensor(sensitivity); pev_button = button; // When we touched the sensor, the the button will record the corresponding numbers. if (touch1 > sensitivity) button = 1; if (touch2 > sensitivity) button = 2; if (touch3 > sensitivity) button = 3; if (touch4 > sensitivity) button = 4; if (touch5 > sensitivity) button = 5; if (touch6 > sensitivity) button = 6; if (touch7 > sensitivity) button = 7; if (touch8 > sensitivity) button = 8; // When we didn't touch it, no tone is produced. if (touch1<=sensitivity & touch2<=sensitivity & touch3<=sensitivity & touch4<=sensitivity & touch5<=sensitivity & touch6<=sensitivity & touch7<=sensitivity & touch8<=sensitivity) button = 0; /****Rcord the pressed buttons in a array***/ if (button != pev_button && pev_button != 0) { recorded_button[button_index] = pev_button; button_index++; recorded_button[button_index] = 0; button_index++; } /**End of Recording program**/ } inside the if loop, and then we increase this index value to avoid overwriting the same location. void playTone(){ /****Rcord the time delay between each button press in a array***/ if (button != pev_button) { note_time = (millis() - start_time) / 10; if(note_time!=0){ recorded_time[time_index] = note_time; time_index++; start_time = millis(); } Serial.println(time_index); } /**End of Recording program**/ if (button == 0) { noTone(buzzer); } if (button == 1) { tone(buzzer, notes[0]); } if (button == 2) { tone(buzzer, notes[1]); } if (button == 3) { tone(buzzer, notes[2]); } if (button == 4) { tone(buzzer, notes[3]); } if (button == 5) { tone(buzzer, notes[4]); } if (button == 6) { tone(buzzer, notes[5]); } if (button == 7) { tone(buzzer, notes[6]); } if (button == 8) { tone(buzzer, notes[7]); } } conditions, we'll play the appropriate tone for the key hit inside the playTone() function. The entire code for the function is displayed above. We will also use an array named recorded time[] to preserve the time length for which the button was pressed. The procedure is similar to recording button sequences in that we use the millis() function to calculate how long each button was pressed and then divide the value by 10 to reduce the size of the variable. We play no tone for the same period for button 0, which signifies the user is not pressing anything. void setup(){ Serial.begin(9600); // Turn off autocalibrate on all channels: for(int i=0; i<8; ++i) { keys[i].set_CS_AutocaL_Millis(0xFFFFFFFF); } // Set the buzzer as an output: pinMode(buzzer, OUTPUT); pinMode(recordbtn, INPUT); noTone(buzzer); delay(10); int sizeed = sizeof(soundOnStartUp) / sizeof(int); for (int thisNote = sizeed; thisNote > 0 ; thisNote--) { tone(buzzer, soundOnStartUp[thisNote]); delay(100); } noTone(buzzer); delay(10); } void loop() { Serial.println(digitalRead(recordbtn)); while (digitalRead(recordbtn) == 1) //If the toggle switch is set in recording mode { recordButtons(); playTone(); } while (digitalRead(recordbtn) == 0) //If the toggle switch is set in Playing mode { for (int i = 0; i < sizeof(recorded_button) / 2; i++) { delay((recorded_time[i]) * 10); //Wait for before paying next tune if (recorded_button[i] == 0) noTone(buzzer); //user didnt touch any button else tone(buzzer, notes[(recorded_button[i] - 1)]); //play the sound corresponding to the button touched by the user } } } Then, to play the recorded tone, the user must push the Slide Switch to the other way after recording. When this is done, the Programme exits the previous while loop and enters the second while loop, where we play the notes in the order that the keys were hit for a previously recorded length. The code to accomplish this is provided above. You can watch the video attached below for more explanation. Code #include <CapacitiveSensor.h> #include "piano_tones.h" #define common_pin 2 // The common ‘sendᾠpin for all resistors #define buzzer A4 // The output pin for the piezo buzzer #define recordbtn 12 // The recording button // This macro creates a capacitance sensor object for each resistor pins #define CPin(pin) CapacitiveSensor(common_pin, pin) char button = 0; int analogVal; char REC = 0; int recorded_button[200]; int pev_button; int sensitivity = 2000; int recorded_time[200]; char time_index; char button_index = 0; unsigned long start_time; int note_time; // Each key corresponds to a note, which are defined here. Uncomment the scale that you want to use: //int notes[]={NOTE_C4,NOTE_D4,NOTE_E4,NOTE_F4,NOTE_G4,NOTE_A4,NOTE_B4,NOTE_C5}; // C-Major scale //int notes[]={NOTE_A4,NOTE_B4,NOTE_C5,NOTE_D5,NOTE_E5,NOTE_F5,NOTE_G5,NOTE_A5}; // A-Minor scale //int notes[]={NOTE_C4,NOTE_D4,NOTE_E4,NOTE_F4,NOTE_G4,NOTE_A4,NOTE_C5,NOTE_D5}; // C Blues scale //int notes[] = {1300, 1500, 1700, 1900, 2000, 2300, 2600, 2700}; int notes[]={NOTE_C7,NOTE_D7,NOTE_E7,NOTE_F7,NOTE_G7,NOTE_A7,NOTE_B7,NOTE_C8}; //int notes[] = {1915, 1700, 1519, 1432, 1275, 1136, 1014, 956}; // Sound on startup int soundOnStartUp[] = { NOTE_E7, NOTE_E7, 0, NOTE_E7, 0, NOTE_C7, NOTE_E7, 0, NOTE_G7, 0, 0, 0, NOTE_G6, 0, 0, 0 }; // Defines the pins that the registers are connected to: CapacitiveSensor keys[] = {CPin(3), CPin(4), CPin(5), CPin(6), CPin(7), CPin(8), CPin(9), CPin(10)}; void setup(){ Serial.begin(9600); // Turn off autocalibrate on all channels: for(int i=0; i<8; ++i) { keys[i].set_CS_AutocaL_Millis(0xFFFFFFFF); } // Set the buzzer as an output: pinMode(buzzer, OUTPUT); pinMode(recordbtn, INPUT); noTone(buzzer); delay(10); int sizeed = sizeof(soundOnStartUp) / sizeof(int); for (int thisNote = sizeed; thisNote > 0 ; thisNote--) { tone(buzzer, soundOnStartUp[thisNote]); delay(100); } noTone(buzzer); delay(10); } void loop() { Serial.println(digitalRead(recordbtn)); while (digitalRead(recordbtn) == 1) //If the toggle switch is set in recording mode { recordButtons(); playTone(); } while (digitalRead(recordbtn) == 0) //If the toggle switch is set in Playing mode { for (int i = 0; i < sizeof(recorded_button) / 2; i++) { delay((recorded_time[i]) * 10); //Wait for before paying next tune if (recorded_button[i] == 0) noTone(buzzer); //user didnt touch any button else tone(buzzer, notes[(recorded_button[i] - 1)]); //play the sound corresponding to the button touched by the user } } } void recordButtons(){ // Set the sensitivity of the sensors. long touch1 = keys[0].capacitiveSensor(sensitivity); long touch2 = keys[1].capacitiveSensor(sensitivity); long touch3 = keys[2].capacitiveSensor(sensitivity); long touch4 = keys[3].capacitiveSensor(sensitivity); long touch5 = keys[4].capacitiveSensor(sensitivity); long touch6 = keys[5].capacitiveSensor(sensitivity); long touch7 = keys[6].capacitiveSensor(sensitivity); long touch8 = keys[7].capacitiveSensor(sensitivity); pev_button = button; // When we touched the sensor, the the button will record the corresponding numbers. if (touch1 > sensitivity) button = 1; if (touch2 > sensitivity) button = 2; if (touch3 > sensitivity) button = 3; if (touch4 > sensitivity) button = 4; if (touch5 > sensitivity) button = 5; if (touch6 > sensitivity) button = 6; if (touch7 > sensitivity) button = 7; if (touch8 > sensitivity) button = 8; // When we didn't touch it, no tone is produced. if (touch1<=sensitivity & touch2<=sensitivity & touch3<=sensitivity & touch4<=sensitivity & touch5<=sensitivity & touch6<=sensitivity & touch7<=sensitivity & touch8<=sensitivity) button = 0; /****Rcord the pressed buttons in a array***/ if (button != pev_button && pev_button != 0) { recorded_button[button_index] = pev_button; button_index++; recorded_button[button_index] = 0; button_index++; } /**End of Recording program**/ } void playTone(){ /****Rcord the time delay between each button press in a array***/ if (button != pev_button) { note_time = (millis() - start_time) / 10; if(note_time!=0){ recorded_time[time_index] = note_time; time_index++; start_time = millis(); } Serial.println(time_index); } /**End of Recording program**/ if (button == 0) { noTone(buzzer); } if (button == 1) { tone(buzzer, notes[0]); } if (button == 2) { tone(buzzer, notes[1]); } if (button == 3) { tone(buzzer, notes[2]); } if (button == 4) { tone(buzzer, notes[3]); } if (button == 5) { tone(buzzer, notes[4]); } if (button == 6) { tone(buzzer, notes[5]); } if (button == 7) { tone(buzzer, notes[6]); } if (button == 8) { tone(buzzer, notes[7]); } } Video microcontroller-projects/iot-based-forest-fire-detection-using-arduino-and-gsm-module

IoT Based Forest Fire Detection System using Arduino and GSM Module

which would detect the fire and send an emergency alert to Authority through IoT. Here a GSM/GPRS module is used to communicate with IoT sever as usually in forest areas network bandwidth is very low or not available. Hence a 2G network is preferable to communicate with the server.

Components Used

Arduino Nano SIM800L GPS/GPRS Module 3.7V Li-ion Battery Flame sensor Dot matrix Perf board

SIM800L Module Working

The first is for a ring antenna which can be soldered directly on the board and the other is meant for an external antenna. Input voltage: 3.4V - 4.2V Interface: UART and AT commands Supported frequencies: Quad Band (850 / 950 / 1800 /1900 MHz) SIM card socket: micro SIM slot Antenna connector: IPX Working temperature range: -40 do + 85 ° C

Block Diagram for IoT Based Forest Fire Detection System

, Arduino Nano & SIM800L GSM/GPRS module as its primary components. The fire can be detected by the flame sensor which gives a digital output that corresponds to the Fire status and is received by the Arduino Nano. Arduino compares the signal and triggers the SIM800L in case of fire incidents. Through AT commands, SIM800L communicates with thingspeak server. which we have built earlier if you are interested. SIM800L is connected to Arduino Nano via Logic shifting resistors as SIM800L works on 3.3v Logic. Separate power is given to SIM800L module because it works in 3.4-4.2V DC and5V DC external supply is given to Arduino Nano. Alternatively, a 3.7-5 V Boost converter can be used here to avoid two power supplies.

Setup ThingspeakAccount

After successful completion of hardware as per the above circuit diagram, the IoT platform needs to be set up, where the real-time data will be received. Here Thingspeak is used to store the parameters and show them in GUI. For creating an account in Thingspeak follow the steps below: and create a new free Mathworks account if you don’t have a Mathworks account before. ᾮ Select the created channel and record the following credentials. Channel ID, which is at the top of the channel view. Write API key, which can be found on the API Keys tab of your channel view. ᾠand add four appropriate widgets like gauges, numeric displays, and indicators. In my case, I have taken Indicator for Fire Alert. Select appropriate field names for each widget.

Arduino Program for IoT Based Forest Fire Detection

ᾠin my case. #include <SoftwareSerial.h> #include <String.h> The next step is to define the RX, TX Pin of Arduino where SIM800L is connected. SoftwareSerial gprsSerial(10, 11); In the setup (), all the primary initializations are made such as Serial initializations, SIM800L module initializations, and GPIO pin declarations. void setup() { pinMode(12, OUTPUT); pinMode(9, INPUT); gprsSerial.begin(9600); // the GPRS baud rate Serial.begin(9600); // the GPRS baud rate Module_Init(); } where the access point of operator is defined. Make sure that, correct Access point name is replaced with “wwwᾮ void Module_Init() { gprsSerial.println("AT"); delay(1000); gprsSerial.println("AT+CPIN?"); delay(1000); gprsSerial.println("AT+CREG?"); delay(1000); gprsSerial.println("AT+CGATT?"); delay(1000); gprsSerial.println("AT+CIPSHUT"); delay(1000); gprsSerial.println("AT+CIPSTATUS"); delay(2000); gprsSerial.println("AT+CIPMUX=0"); delay(2000); ShowSerialData(); gprsSerial.println("AT+CSTT=\"www\""); delay(1000); ShowSerialData(); gprsSerial.println("AT+CIICR"); delay(3000); ShowSerialData(); gprsSerial.println("AT+CIFSR"); delay(2000); ShowSerialData(); gprsSerial.println("AT+CIPSPRT=0"); delay(3000); ShowSerialData(); } Inside loop(), digital values from pin 12 are read and stored in a variable. int fire = digitalRead(12); ᾠwith your actual key in the string which was recorded earlier. gprsSerial.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");//start up the connection delay(6000); ShowSerialData(); gprsSerial.println("AT+CIPSEND");//begin send data to remote server delay(4000); ShowSerialData(); String str = "GET https://api.thingspeak.com/update?api_key=ER43PWXXXXXQF0I&field1=" + String(1); Serial.println(str); gprsSerial.println(str);//begin send data to remote server After completion of data transmission, AT+CIPSHUT is used to close the connection. gprsSerial.println("AT+CIPSHUT");//close the connection delay(100);

Forest Fire Detection System ᾠTesting

To test the prototype, first, the Microsim needs to be inserted in the SIM800L slot as shown in the figure. Then power ON the module and then we can see the LED blinking in the Module. If the LED blinking is delayed as compared to the initial start, it means it got the network, and is ready to connect to the server. Now we can see the status in Thingspeak server. Code #include <SoftwareSerial.h> SoftwareSerial gprsSerial(10, 11); #include <String.h> int flag = 0; void setup() { pinMode(9, OUTPUT); pinMode(12, INPUT); gprsSerial.begin(9600); // the GPRS baud rate Serial.begin(9600); // the GPRS baud rate Module_Init(); } void loop() { if (gprsSerial.available()) Serial.write(gprsSerial.read()); int fire = digitalRead(12); if (fire == 0) { digitalWrite(9, HIGH); gprsSerial.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");//start up the connection delay(6000); ShowSerialData(); gprsSerial.println("AT+CIPSEND");//begin send data to remote server delay(4000); ShowSerialData(); String str = "GET https://api.thingspeak.com/update?api_key=ER43PXXXXXHQF0I&field1=" + String(1); Serial.println(str); gprsSerial.println(str);//begin send data to remote server delay(4000); ShowSerialData(); digitalWrite(9, LOW); gprsSerial.println((char)26);//sending delay(5000);//waitting for reply, important! the time is base on the condition of internet gprsSerial.println(); ShowSerialData(); gprsSerial.println("AT+CIPSHUT");//close the connection delay(100); ShowSerialData(); flag = 0; } else { digitalWrite(9, LOW); if (flag == 0) { flag = 1; gprsSerial.println("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"");//start up the connection delay(6000); ShowSerialData(); gprsSerial.println("AT+CIPSEND");//begin send data to remote server delay(4000); ShowSerialData(); String str = "GET https://api.thingspeak.com/update?api_key=ER43PWT91CGHQF0I&field1=" + String(0); Serial.println(str); gprsSerial.println(str);//begin send data to remote server delay(4000); ShowSerialData(); digitalWrite(9, LOW); gprsSerial.println((char)26);//sending delay(5000);//waitting for reply, important! the time is base on the condition of internet gprsSerial.println(); ShowSerialData(); gprsSerial.println("AT+CIPSHUT");//close the connection delay(100); ShowSerialData(); } } } void ShowSerialData() { while (gprsSerial.available() != 0) Serial.write(gprsSerial.read()); delay(5000); } void Module_Init() { gprsSerial.println("AT"); delay(1000); gprsSerial.println("AT+CPIN?"); delay(1000); gprsSerial.println("AT+CREG?"); delay(1000); gprsSerial.println("AT+CGATT?"); delay(1000); gprsSerial.println("AT+CIPSHUT"); delay(1000); gprsSerial.println("AT+CIPSTATUS"); delay(2000); gprsSerial.println("AT+CIPMUX=0"); delay(2000); ShowSerialData(); gprsSerial.println("AT+CSTT=\"www\""); delay(1000); ShowSerialData(); gprsSerial.println("AT+CIICR"); delay(3000); ShowSerialData(); gprsSerial.println("AT+CIFSR"); delay(2000); ShowSerialData(); gprsSerial.println("AT+CIPSPRT=0"); delay(3000); ShowSerialData(); } Video microcontroller-projects/arduino-uno-line-follower-robot

Building an easy Line Follower Robot using Arduino Uno

) is a simple autonomously guided robot that follows a line drawn on the ground to either detect a dark line on a white surface or a white line on a dark. TheLFR is quite an interesting project to work on!In this tutorial, we will learn how tobuild a black line follower robot using Arduino Uno and some easily accessible components. Sounds intersting? Let's get started.

Working of a Line Follower Robot

As stated earlier, line follower robot (LFR) follows a line, and in order to follow a line, robot must detect the line first. Now the question is how to implement the line sensing mechanism in a LFR. We all know that the reflection of light on the white surface is maximum and minimum on the black surface because the black surface absorbs maximum amount of light. So, we are going to use this property of light to detect the line. To detect light, either LDR (light-dependent resistor) or an IR sensor can be used. For this project, we are going with the IR sensor because of its higher accuracy. To detect the line, we place two IR sensors one on the left and other on the right side of the robot as marked in the diagram below. We then place the robot on the line such that the line lies in the middle of both sensors. Infrared sensors consist of two elements, a transmitter and a receiver. The transmitter is basically an IR LED, which produces the signal and the IR receiver is a photodiode, which senses the signal produced by the transmitter. The IR sensors emits the infrared light on an object, the light hitting the black part gets absorbed thus giving a low output but the light hitting the white part reflects back to the transmitter which is then detected by the infrared receiver, thereby giving an analog output. Using the stated principle, we control the movement of the robot by driving the wheels attached to the motors, the motors are controlled by a microcontroller.

How does a Line Follower Robot Navigates?

A typical line follower robot has two sets of motors, let's call them left motor and right motor. Both motors rotate on the basis of the signal received from the left and the right sensors respectively. The robot needs to perform 4 sets of motion which includes moving forward, turning left, turning right and coming to a halt. The description about the cases are given below. In this case, when both the sensors are on a white surface and the line is between the two sensors, the robot should move forward, i.e., both the motors should rotate such that the robot moves in forward direction (actually both the motors should rotate in the opposite direction due to the placement of motors in our setup. But for the sake of simplicity, we will call the motors rotating forward.) In this case, the left sensor is on top of the dark line, whereas the right sensor is on the white part, hence the left sensor detects the black line and gives a signal, to the microcontroller. Since, signal comes from the left sensor, the robot should turn to the left direction. Therefore, the left motor rotates backwards and the right motor rotates in forward direction. Thus, the robot turns towards left side. This case is similar to the left case, but in this situation only the right sensor detects the line which means that the robot should turn in the right direction. To turn the robot towards the right direction, the left motor rotates forward and the right motor rotates backwards and as a result, the robot turns towards the right direction. In this case, both the sensors are on top of the line and they candetect the black line simultaneously, the microcontroller is fed to consider this situation as a process for halt. Hence, both the motors are stopped, which causes the robot to stop moving.

Components Required for Making ArduinoUno Line Follower Robot

Arduino Uno - 1Nos L293D motor driver- 1Nos IR sensor module -2 Nos 7.4 or 9V battery -1 Nos BO motor - 2 Nos Motor wheel - 2 Nos Castor wheel - 1 Nos Hobby robot chassis - 1 Nos Wires Screw

Circuit Diagram and Assembling the Line Follower Robot

The circuit consists of mainly four parts: Two IR sensors, one motor drive, two motors, one Arduino, a battery and few connecting wires. The sensor senses the IR light reflected from the surface and feeds the output to the onboard op-amp comparator. When the sensor is situated over the white background, the light emitted by the sensor is reflected by the white ground and is received by the receiver. But when the sensor is above the black background, the light from the source doesn’t reflect to it. The sensor senses the intensity of reflected light to give an output. The sensor’s output is fed to the microcontroller, which gives commands to the motor driver to drive the motor accordingly. In our project, the Arduino Uno is programmed to make the robot move forward, turn right or turn left and stop according to the input coming from the sensor. The output of the Arduino is fed to the motor driver. motor driver and is sufficient for our 2 motors. The L293D has 16 pins, the pinout of L293D is shown in the below diagram. Pin number 1 and 9 are the enable pins, we connect these two pins to a 5v input to enable the motor. Pin number 1A, 2A, 3A, and 4A are the control pins. For eg. The motor will turn to the right if the pin 1A goes low and 2A goes high, and the motor will turn to the left if 1A goes low and 2A high. So, we connect these pins to the output pins of the decoder. Pins 1Y, 2Y, 3Y, and 4Y are the motor connection pins. Note: Vcc2 is the motor driving voltage pin, and only used if you are using a high voltage motor. Pin connection of Arduino Uno with the Motor driver are as follows: Here, we are using a 7.4 li-ion battery to power the whole circuit. You can use any battery type from 6-12 volt. To move the robot, we need to use motors with low RPM but torque high enough to carry the weight of the robot. So, I chose two 60 RPM 6V Battery Operated, geared motors for this robot.

Assembling the Line Follower Robot

Once we have understood the connection of all the components, we can start assembling our LFR. I have explained the step-by-step assembly procedure of the Robot in the video provided at the bottom of the page. To make this robot, first we need a robot body; here I am using a homemade chassis. You can either use a readymade chassis or build one yourself. Now, place the BO motors to the chassis with the help of some hot glue as shown in the image below. Next step is to place the motor driver on chassis and connect the motor wires to the output of the motor driver. Next, bend the IR LED and sensor as shown in the image. Then place the sensors on the downside of the robot, adjust the sensors according to the track width and robot width. Remember that one sensor is for left side detection and another is for the right side detection. Now place the Arduino uno using glue and connect the sensor output pins to digital pin 2 and 4 of the Arduino. Connect the VCC pins to 5volt and the ground pins to ground. Now, connect the enable pins of the motor driver to pin 5 and 8 of Arduino and connect the motor driver input pins to pin number 6, 7, 9 and 10 of Arduino respectively. Finally, connect the battery with the circuit and place the battery on chassis. Here, I have connected everything with jumper wires. To make a permanent setup, you can directly solder everything together. Now turn the board upside down and with the help of hot glue gun, attach the castor wheels as shown in the image below. Finally, add the wheels. For extra safety, I have added a plastic sheet as a bumper too.

Arduino Line Follower Robot Code

The programming part of line follower robot is very simple and we require only basic Arduino functions. The complete program for this project can be found at the bottom of this page. The explanation of this program is as follows: First step is to defined every Arduino pin that we are using. I started with motoring the driver pins and sensor pins. Here, I have commented on each line of code for your easy understanding. #define enA 5 //Enable1 L293 Pin enA #define in1 6 //Motor1 L293 Pin in1 #define in2 7 //Motor1 L293 Pin in1 #define in3 9 //Motor2 L293Pin in1 #define in4 10 //Motor2 L293 Pin in1 #define enB 8 //Enable2 L298 Pin enB #define R_S 4 // Right sensor #define L_S 2 // Left sensor In the loop section, declare the pin modes of each pin. Here, we need to read the output of IR sensors, hence I have defined those pins as an input. The motor needs to be driven by the Arduino, thus defining the motor driver pins as output. Finally, I pulled enable pin to high. pinMode(R_S, INPUT); pinMode(L_S, INPUT); pinMode(enA, OUTPUT); pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); pinMode(in3, OUTPUT); pinMode(in4, OUTPUT); pinMode(enB, OUTPUT); digitalWrite(enA, HIGH); digitalWrite(enB, HIGH); In the loop section, we first read the values of IR sensors and then using ‘if conditionᾠcontrol the movement of motor as per our requirements. The four movement conditions are explained below. if((digitalRead(R_S) == 0)&&(digitalRead(L_S) == 0)){forward();} In this case, if Right Sensor and Left Sensor are on top of white colour then the robot should move in the forward direction, so we call the forward function. (Note : here 0 means output of IR sensor is high as the sensor is on white surface) if((digitalRead(R_S) == 1)&&(digitalRead(L_S) == 0)){turnRight();} if Right Sensor is detecting Black and Left Sensor is not detecting any black line, then it will call the Right function, initiating the protocol for making right turn by calling turnRight function. if((digitalRead(R_S) == 0)&&(digitalRead(L_S) == 1)){turnLeft();} if Right Sensor is over white and the Left Sensor is detecting Black then it will call turnLeft function. It will initiate the steps for turning the robot in left direction. if((digitalRead(R_S) == 1)&&(digitalRead(L_S) == 1)){Stop();} If the Right Sensor and Left Sensor are on the Black color then it will call the Stop function. In this case, the robot will come to a complete halt. We have defined the 4 functions of the robot as Forward, turnLeft, turnRight and Stop. The code to perform these functions are given below: void forward(){ digitalWrite(in1, HIGH); digitalWrite(in2, LOW); digitalWrite(in3, LOW); digitalWrite(in4, HIGH); } This means we are pulling to high the input 1 and 4 of the motor driver, as a result, both motors will move forward same as this I made other functions void turnRight(){ digitalWrite(in1, LOW); //Right Motor forword Pin digitalWrite(in2, HIGH); //Right Motor backword Pin digitalWrite(in3, LOW); //Left Motor backword Pin digitalWrite(in4, HIGH); //Left Motor forword Pin } void turnLeft(){ digitalWrite(in1, HIGH); //Right Motor forword Pin digitalWrite(in2, LOW); //Right Motor backword Pin digitalWrite(in3, HIGH); //Left Motor backword Pin digitalWrite(in4, LOW); //Left Motor forword Pin } void Stop(){ digitalWrite(in1, LOW); //Right Motor forword Pin digitalWrite(in2, LOW); //Right Motor backword Pin digitalWrite(in3, LOW); //Left Motor backword Pin digitalWrite(in4, LOW); //Left Motor forward Pin So, that’s all about coding. Now we need to upload the code to the Arduino and to do so, connect your Arduino with the computer using USB cable and upload this code using the Arduino IDE. We have assembled the robot and uploaded the code, so now its time to see it in action and if it is unable to follow the line then we’ll have to calibrate the robot. For that first place robot on a black surface ( both sensors should be on top of the black surface) then adjust the variable resistor of IR Module until the output led of IR module become off. Next, place the robot on a white surface and check whether the led is turning on, if not, then just adjust the variable resistor. Repeat the process once again to be sure that the output LED is operating as per the requirement. Now, since we have calibrated the robot, all we need to do is place the robot on top of the black line and see it in action. The complete makingof the line follower robotcan be found in the video linked at the bottom of this page. If you have any questions leave them in the comment section. Code // Arduino Line Follower Robot Code #define enA 5//Enable1 L293 Pin enA #define in1 6 //Motor1 L293 Pin in1 #define in2 7 //Motor1 L293 Pin in1 #define in3 9 //Motor2 L293 Pin in1 #define in4 10 //Motor2 L293 Pin in1 #define enB 8 //Enable2 L293 Pin enB #define R_S 4//ir sensor Right #define L_S 2 //ir sensor Left void setup(){ pinMode(R_S, INPUT); pinMode(L_S, INPUT); pinMode(enA, OUTPUT); pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); pinMode(in3, OUTPUT); pinMode(in4, OUTPUT); pinMode(enB, OUTPUT); digitalWrite(enA, HIGH); digitalWrite(enB, HIGH); delay(1000); } void loop(){ if((digitalRead(R_S) == 0)&&(digitalRead(L_S) == 0)){forward();} //if Right Sensor and Left Sensor are at White color then it will call forword function if((digitalRead(R_S) == 1)&&(digitalRead(L_S) == 0)){turnRight();} //if Right Sensor is Black and Left Sensor is White then it will call turn Right function if((digitalRead(R_S) == 0)&&(digitalRead(L_S) == 1)){turnLeft();} //if Right Sensor is White and Left Sensor is Black then it will call turn Left function if((digitalRead(R_S) == 1)&&(digitalRead(L_S) == 1)){Stop();} //if Right Sensor and Left Sensor are at Black color then it will call Stop function } void forward(){ //forword digitalWrite(in1, HIGH); //Right Motor forword Pin digitalWrite(in2, LOW); //Right Motor backword Pin digitalWrite(in3, LOW); //Left Motor backword Pin digitalWrite(in4, HIGH); //Left Motor forword Pin } void turnRight(){ //turnRight digitalWrite(in1, LOW); //Right Motor forword Pin digitalWrite(in2, HIGH); //Right Motor backword Pin digitalWrite(in3, LOW); //Left Motor backword Pin digitalWrite(in4, HIGH); //Left Motor forword Pin } void turnLeft(){ //turnLeft digitalWrite(in1, HIGH); //Right Motor forword Pin digitalWrite(in2, LOW); //Right Motor backword Pin digitalWrite(in3, HIGH); //Left Motor backword Pin digitalWrite(in4, LOW); //Left Motor forword Pin } void Stop(){ //stop digitalWrite(in1, LOW); //Right Motor forword Pin digitalWrite(in2, LOW); //Right Motor backword Pin digitalWrite(in3, LOW); //Left Motor backword Pin digitalWrite(in4, LOW); //Left Motor forword Pin } Video microcontroller-projects/what-is-tasmota-and-how-to-use-it-with-esp-01-to-control-smart-home-devices

What is Tasmota and How to use it with ESP-01 to Control Smart Home Devices

is, how does it work and what it can do for you? Other than this, we are also going to flash Tasmota firmware on ESP-01 and then control an LED and read DHT11 sensor data using it. So, without any further ado let’s get started.

Tasmota: Working and Functions

, HTTP, Serial, or WEB UI. Tasmota was initially started as a custom firmware for sonoff devices but then the developers decided to transform it into a powerful tool for controlling everything within the ESP chip. Tasmota comes with built-in drivers to control many popular sensors and chips such as Tuya/Smart Life products or Wemos D1 Mini. In case,your device is not on the list of built-in devices then Tasmota also offers a way to configure devices. It is also possible to create your own configuration, and build your own device by making your own template. Apart from all these, Tasmota is lightweight and easy to install and there are several methods to do so. For example, you can use the Tasmotizer to flash the firmware of your choice over serial or USB. You can also use ESPTool. ESPTool is a Python script for flashing the firmware over serial and USB from platforms such as Mac, Linux, and Raspberry Pi. You can also flash most of the devices over the air (OTA). Now that you have an understanding of what Tasmota is, let’s tackle the question of what it can do for you. Tasmota can unlock your smart devices, allowing them to communicate with systems and environments with which they were not designed. This allows you to connect all of your smart devices present in your house to the same platform, making your home automation system and life easier. Tasmota can allow you integration with any platform that supports MQTT like Domoticz, Home Assistant, NodeRed, OpenHAB, etc.

Components Required for Flashing Tasmota

ESP-01 Arduino Uno LED DHT11

Flashing Tasmota on ESP-01

Apart from ESP-01, we need three other things to run Tasmota on ESP-01 viz.Tasmota firmware file, programmer board, and Image flashing software. There are two methods for flashing Tasmota on the ESP-01. Over the air (OTA) is one method, while using FTDI and Arduino Uno as a programmer is the another method. Here, we will use an Arduino Uno as a programmer board to flash Tasmota firmware on ESP-01. Tasmota has a big list of firmware files with different built-in drivers for various sensors and other devices. If you're a beginner and not sure which file to use, just start with “tasmota.binᾮ It includes all the features required for the majority of compatible hardware. As mentioned earlier, we will use Arduino Uno as a programmer to flash the firmware on ESP-01. The circuit for connecting ESP-01 with Arduino Uno is given below:
VCC3.3V
GNDGND
CH-PD3.3V
RXRX
TXTX
GPIO-0GND
GPIO-2Not Connected
RSTInitially not connected. Before hitting upload, connect RST to ground and remove after half a second
and then click on Upload in your Arduino IDE. from the given link, after that, double click the downloaded file and it'll start without asking for any installation. Finally, choose the port to which the Arduino Uno is connected. Then select the Tasmota firmware file that you downloaded earlier. Tasmotizer also provides you the option of saving the old firmware that is present on your ESP-01. If you want to save your ESP-01 firmware then tick the "Save original firmware" option. Once you have selected the port and file, click on ‘Tesmotize!ᾠand wait until it is done. Once you are done with flashing the Firmware, disconnect the ESP-01 completely, then reconnect the VCC, GND, and CH_EN pins. When the Tasmota firmware starts up for the first time, it provides a wireless access point for easy Wi-Fi configuration. Connect to the Tasmota network that starts with “tasmota_XXXXXX-####ᾠusing your Smartphone or laptop, and you will be redirected to the Tasmota configuration page automatically where you can set up the Wi-Fi credentials. Once done click ‘Saveᾬ ESP will restart and connect to the Wi-Fi network that you provided. device and use that to access the Tasmota UI.

Setting up and Controlling Smart Devices using Tasmota

Tasmota allows you to configure and control any device that uses the ESP Wi-Fi chip. Here, we are using the ESP-01 chip and to control LED and read the DHT11 sensor. With it, we first have to configure Tasmota. For that, first click on the ‘Configurationᾠbutton and then in the next step click on ‘Configure Module.ᾍ Now, on the ‘Configure Moduleᾠpage by default, the module type will be ‘Generic (0)ᾮ Change it to ‘Generic (18)ᾠi.e.ESP8266 board and save the changes. Again, go to the configure module page and select ‘PWMᾠto control LED on GPIO2 and DHT11 on GPIO0. After that, click on ‘Saveᾠto save the changes. The ESP-01 will restart. Then go to Main Menu and you will have a toggle button with a slider to control the brightness and DHT11 readings on your Tasmota Web UI. Now, to test whether this works or not, connect an LED to GPIO2 and DHT11 sensor to GPIO 0 of ESP-01 as shown in the below image: And with this done, DHT11 sensor readings will be displayed on Tasmota Web UI and you can use the toggle switch to turn on/off the LED and slider to change the brightness of the LED. to start a discussion on this. Video microcontroller-projects/portable-ultrasonic-ruler-circuit-pcb-using-attiny85

How to Make a Portable Ultrasonic Digital Ruler using ATtiny85

to fabricatetheboards for this project. In the following sections of the article, we have covered in detail the complete procedure to design, order, and assemble the PCB boards for this ultrasonic rulerso that you can also easily build one on your own. which we built previously.

Components Required for Ultrasonic Ruler

ATtiny85 IC HC-SR04 Ultrasonic Sensor I2C OLED Display Module AMS1117 5V Voltage Regulator 3× 10K Resistor 1× 10 μf Capacitor 9V Battery

Ultrasonic Digital RulerCircuit Diagram

is given below: The above image shows the circuit diagram for interfacing Ultrasonic Sensor and OLED Display with Attiny85 IC. The interface between OLED Display and ATtiny85 must be implemented using I2C Protocol. Hence, the SCL Pin (PB2) of the ATtiny85 is connected to the SCL Pin of the OLED Display. Similarly, the SDA Pin (PB0) of the ATtiny85 is connected to the SDA Pin of OLED Display. Echo and Trig pins of Ultrasonic sensor are connected to PB3 and PB4 pins of ATtiny85 respectively. Finally, to power all the components, we have used the 9V battery. This 9V is then converted to 5V using an AMS117-5V voltage regulator. to program the ATtiny85 IC.

Fabricating PCB for Ultrasonic Ruler

You can design the PCB using any PCB software of your choice. Below are the 3D model views of the top layer and bottom layer of the Ultrasonic Ruler PCB: The PCB layout for the above circuit is also available for download as Gerber from the link given below:

Ordering PCB from PCBWay

Now after finalizing the design, you can proceed with ordering the PCB: , sign up if this is your first time. Then, in the PCB Prototype tab, enter the dimensions of your PCB, the number of layers, and the number of PCB you require. Proceed by clicking on the ‘Quote Nowᾠbutton. You will be taken to a page to set a few additional parameters like the Board type, Layers, Material for PCB, Thickness, and More, most of them are selected by default, if you are opting for any specific parameters, you can select it inhere. The final step is to upload the Gerber file and proceed with the payment. To make sure the process is smooth, PCBWAY verifies if your Gerber file is valid before proceeding with the payment. This way, you can be sure that your PCB is fabrication friendly and will reach you as committed.

Assembling the Attiny85 Ultrasonic Ruler PCB

After a few days, we received our PCB in a neat package and the PCB quality was good as always. The top layer and the bottom layer of the board are shown below: After making sure the tracks and footprints were correct. I proceeded with assembling the PCB. The completely soldered board looks like the below:

ATtiny85 Ultrasonic Ruler Code Explanation

The complete Arduino step counter code is given at the end of the document. Here we are explaining some important parts of the code. library by Adafruit. library can be downloaded from the given link. After installing the libraries to Arduino IDE, start the code by including the needed libraries files. #include "TinyWireM.h" #include "TinyOzOLED.h" In the next lines, define the ultrasonic sensor pins. We have defined the trig and echo pins of ultrasonic sensor as shown below. const int trigPin = 4; //P4 int echoPin = 3; //P3 function. This is where we define the ATtiny85 pins as input/output and start the communication between ATtiny85 and OLED. void setup() { TinyWireM.begin(); OzOled.init(); OzOled.clearDisplay(); OzOled.setNormalDisplay(); OzOled.sendCommand(0xA1); OzOled.sendCommand(0xC8); pinMode(trigPin, OUTPUT); } function has 2 parameters, the first one is the name of the echo pin and the second one is the state of echo pin. Then after getting the distance, we displayed it on OLED display. digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); pinMode(echoPin, INPUT); duration = pulseIn(echoPin, HIGH); cm = microsecondsToCentimeters(duration); OzOled.printString("Distance:", 3, 4); OzOled.printNumber(cm, 0, 12, 4);

Testing our Ultrasonic Ruler

After assembling the PCB and programming ATtiny85 for distance measurement, we can now test the Ultrasonic ruler. For that, power the board using 9V and wait until the measured distance is displayed on OLED display. You can use a scale or measurement tape to check if the measured distance is correct or not. to start a discussion on this. Code #include "TinyWireM.h" #include "TinyOzOLED.h" const int trigPin = 4; //P4 int echoPin = 3; //P3 int duration, cm; void setup() { TinyWireM.begin(); OzOled.init(); OzOled.clearDisplay(); OzOled.setNormalDisplay(); OzOled.sendCommand(0xA1); // set Orientation OzOled.sendCommand(0xC8); pinMode(trigPin, OUTPUT); } void loop() { //OzOled.clearDisplay(); digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); //setting up the input pin, and receiving the duration in uS pinMode(echoPin, INPUT); duration = pulseIn(echoPin, HIGH); // convert the pulse travel time into a distance cm = microsecondsToCentimeters(duration); displayOLED(); delay(1000); OzOled.clearDisplay(); } void displayOLED() { OzOled.printString("Distance:", 3, 3); OzOled.printNumber(cm, 0, 12, 3); OzOled.printString("(In CM)", 5, 5); } long microsecondsToCentimeters(long microseconds) { // The speed of sound is 340 m/s (29 us/cm) return microseconds / 29 / 2; } Files Ultrasonic-Ruler-PCB-Gerber-File.zip Video microcontroller-projects/build-your-own-arduino-based-smart-vacuum-cleaning-robot-for-automatic-floor-cleaning

Build your own Arduino based Smart Vacuum Cleaner Robot for Automatic Floor Cleaning

we are going to build here will be compact and more practical. On top of that, this robot will have ultrasonic sensors and an IR proximity sensor. The ultrasonic sensor will allow the robot to avoid obstacles so that it can move freely until the room is properly cleaned, and the proximity sensor will help it to avoid falling from stairs. All these features sound interesting, right? So, let's get started. Do check those out if that sounds interesting to you.

Materials Required to Build Arduino Based Floor Cleaning Robot

, you should be able to find all of those in your local hobby store. Here is the complete list of required material along with the image of all the components. Arduino Pro Mini - 1 HC-SR04 Ultrasonic Module - 3 L293D Motor Driver - 1 5Volt N20 Motors and Mounting Brackets - 2 N20 Motor Wheels - 2 Switch - 1 LM7805 Voltage Regulator - 1 7.4V Lithium-Ion Battery - 1 IR Module - 1 Perfboard - 1 Castor Wheel - 1 MDF Generic Portable Vacuum Cleaner

Portable Vacuum Cleaner

This comes with a very simple mechanism. It has three parts in the bottom (asmall chamber for storing the dust, the middle portion includes the motor, fan, and the battery socket on the top (thereis a cover or cap for the battery). It has a DC motor and a fan. This motor is directly connected to 3V (2*1.5volt AA batteries) via a simple switch. As we are powering our robot with a 7.4V battery,we will cut the connection from the internal battery and power it from the 5V power supply. So, we have removed all the unnecessary parts and only the motor with two-wire stays. You can see that in the image below.

HC-SR04 Ultrasonic Sensor Module

project, we have discussed the working principle of this sensor very thoroughly. You can check that out if you want to know more about the HC-SR04 ultrasonic distance sensor module.

Floor Sensor (IR Sensor) for Staircase Detection

and explained the workingprinciple in details, you can check that out if you want to know more about this sensor.

Circuit Diagram of Arduino Based Floor Cleaner Robot

and its operations. The Arduino, Ultrasonic modules, motor driver, and motors work on 5 Volt,the higher voltage will kill it and we are using the 7.4-volt battery, to convert that into 5 Volt,the LM7805 voltage regulator is used. Connect the vacuum cleaner directly to the main circuit.

Building the Circuit for Arduino Based Floor Cleaning Robot

After completing the perfboard soldering, we connect wires to ultrasonic modules and connect them to the corresponding pins, as shown in the schematic.

Building a Housing for Arduino Based Floor Cleaning Robot

online and got some images of round-shaped robots. So, I decided to build a round-shaped robot. To build the chase and body of the robot, I have plenty of options like foam sheet, MDF, cardboard, etc. But I choose MDFbecause it is hard and hassome water-resistant properties. If you are doing this, you can decide which material you will choose for your bot. for fitting the vacuum cleaner. Then I cut out the circles. Also, I have cut and removed appropriate pieces for the wheel path (refer to the images for better understanding). Finally, I made three small holes for the castor wheel. The next step is fitting the motors on the base using its brackets, also place and fix the castor wheel to its position. After that, placethe ultrasonic sensors to left, right, and middle of the robot. Also, connect the IR module to the downside of the robot. Don't forget to add the switch on outside. That's all about building the robot, if you are getting confused at this point, you can refer to the following images. For the top part, I have also drawn a circle of 11 CM in radius on the foam sheet and cut it. For the spacing between the top and the bottom part, I had cut three 4 CM long pieces of a plastic tube. After that, I glued the plastic spacers on the bottom part and then I glued the top part. You can cover the sideparts of the bot with plastic or similar materials if you want.

Arduino Based Floor Cleaning Robot - Code

code,the only change is in the floor detection. In the following lines, I am explaining how the code works. In this case, we are not using any extra libraries.Below we have described the code in a step-by-step manner. We are not using any extra librariesto decode the distance data from the HC-SR04 sensor, because it's very simple. In the following lines, we described how. First,we need to define the Trigger Pin and Echo Pin for all three ultrasonic distance sensorswhich are connected to the Arduino board. In this project, we have three Echo pins and three Trigger pins. Note that 1 is the left sensor, 2 is the front sensor, and 3 is the right sensor. const int trigPin1 = 3; const int echoPin1 = 5; const int trigPin2 = 6; const int echoPin2 =9; const int trigPin3 = 10; const int echoPin3 = 11; int irpin =2; Then we defined variables for the distance whichall are (int) type variables and for the duration, we chose to use (long). Again, we have three of each. Also, I have defined an integer for storing the status of the movement, we will talk about it later in this section. long duration1; long duration2; long duration3; int distanceleft; int distancefront; int distanceright; int a=0; as input. pinMode(trigPin1, OUTPUT); pinMode(trigPin2, OUTPUT); pinMode(trigPin3, OUTPUT); pinMode(echoPin1, INPUT); pinMode(echoPin2, INPUT); pinMode(echoPin3, INPUT); pinMode(irpin, INPUT); for the input of the motor driver. pinMode(4, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(12, OUTPUT); when the sound wave will end which will stop the counting. This function gives the length of the pulse in microseconds. For calculating the distance, we will multiply the duration by 0.034 (speed of sound in air is 340m/s) and divide it by 2 (this is due to the back and forth traveling of the sound wave). Finally, we store the distance of each sensor in corresponding integers. digitalWrite(trigPin1, LOW); delayMicroseconds(2); digitalWrite(trigPin1, HIGH); delayMicroseconds(10); digitalWrite(trigPin1, LOW); duration1 = pulseIn(echoPin1, HIGH); distanceleft = duration1 * 0.034 / 2; We are going to control the robot according to this status. if(s==HIGH) { digitalWrite(4, LOW); digitalWrite(7, HIGH); digitalWrite(8, LOW); digitalWrite(12, HIGH); delay(1000); a=1; } after understanding floor is not present. We also check this condition for other movements. After detecting the absence of the floor, the robot will not move forward. Instead, it will move left, this way, we can avoid the problem. if ((a==0)&&(s==LOW)&&(distanceleft <= 15 && distancefront > 15 && distanceright <= 15) || (a==0)&&(s==LOW)&&(distanceleft > 15 && distancefront > 15 && distanceright > 15)) In the above condition. First, the robot will check the floor status and integer value. The bot will only move forward if all conditions are satisfied. Now, we can write the commands for the motor driver. This will drive the right-motor backward and the left-motor forward, thereby turningthe robot to the Right. digitalWrite(4, HIGH); digitalWrite(7, LOW); digitalWrite(8, HIGH); digitalWrite(12, LOW); If the bot detects the floor is absent, the value changes to 1, and the bot will move to the left. After turning left, the value of 'a' changes to 0 from 1. if ((a==1) &&(s==LOW) ||(s==LOW) && (distanceleft <= 15 && distancefront <= 15 && distanceright > 15) || (s== LOW) && (distanceleft <= 15 && distancefront <= 15 && distanceright > 15) || (s==LOW) && (distanceleft <= 15 && distancefront > 15 && distanceright > 15) || (distanceleft <= 15 && distancefront > 15 && distanceright > 15)) { digitalWrite(4, HIGH); digitalWrite(7, LOW); digitalWrite(8, LOW); digitalWrite(12, HIGH); delay(100); a=0; } if ((s==LOW)&&(distanceleft > 15 && distancefront <= 15 && distanceright <= 15) ||(s==LOW)&& (distanceleft > 15 && distancefront > 15 && distanceright <= 15) ||(s==LOW)&& (distanceleft > 15 && distancefront <= 15 && distanceright > 15) ) { digitalWrite(4, LOW); digitalWrite(7, HIGH); digitalWrite(8, HIGH); digitalWrite(12, LOW); } linked at the bottom of this page. If you have any questions, comment down below. Code // defining the pins const int trigPin1 = 3; const int echoPin1 = 5; const int trigPin2 = 6; const int echoPin2 = 9; const int trigPin3 = 10; const int echoPin3 = 11; int irpin =2; // defining variables long duration1; long duration2; long duration3; int distanceleft; int distancefront; int distanceright; int a=0; void setup() { pinMode(trigPin1, OUTPUT); pinMode(trigPin2, OUTPUT); pinMode(trigPin3, OUTPUT);// Sets the trigPin as an Output pinMode(echoPin1, INPUT); // Sets the echoPin as an Input pinMode(echoPin2, INPUT); pinMode(echoPin3, INPUT); pinMode(irpin, INPUT); pinMode(4, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(12, OUTPUT); } void loop() { digitalWrite(trigPin1, LOW); delayMicroseconds(2); digitalWrite(trigPin1, HIGH); delayMicroseconds(10); digitalWrite(trigPin1, LOW); duration1 = pulseIn(echoPin1, HIGH); distanceleft = duration1 * 0.034 / 2; Serial.print("Distance1: "); Serial.println(distanceleft); digitalWrite(trigPin2, LOW); delayMicroseconds(2); digitalWrite(trigPin2, HIGH); delayMicroseconds(10); digitalWrite(trigPin2, LOW); duration2 = pulseIn(echoPin2, HIGH); distancefront = duration2 * 0.034 / 2; Serial.print("Distance2: "); Serial.println(distancefront); digitalWrite(trigPin3, LOW); delayMicroseconds(2); digitalWrite(trigPin3, HIGH); delayMicroseconds(10); digitalWrite(trigPin3, LOW); duration3 = pulseIn(echoPin3, HIGH); distanceright = duration3 * 0.034 / 2; Serial.print("Distance3: "); Serial.println(distanceright); int s = digitalRead(irpin); if(s==HIGH) { digitalWrite(4, LOW); digitalWrite(7, HIGH); digitalWrite(8, LOW); digitalWrite(12, HIGH); delay(1000); a=1; } if ((a==0)&&(s==LOW)&&(distanceleft <= 15 && distancefront > 15 && distanceright <= 15) || (a==0)&&(s==LOW)&&(distanceleft > 15 && distancefront > 15 && distanceright > 15)) { digitalWrite(4, HIGH); digitalWrite(7, LOW); digitalWrite(8, HIGH); digitalWrite(12,LOW); } if ((a==1)&&(s==LOW)||(s==LOW)&&(distanceleft <= 15 && distancefront <= 15 && distanceright > 15)||(s==LOW)&&(distanceleft <= 15 && distancefront <= 15 && distanceright > 15)||(s==LOW)&& (distanceleft <= 15 && distancefront > 15 && distanceright > 15)||(distanceleft <= 15 && distancefront > 15 && distanceright > 15)) { digitalWrite(4, HIGH); digitalWrite(7, LOW); digitalWrite(8, LOW); digitalWrite(12, HIGH); delay(100); a=0; } if ((s==LOW)&&(distanceleft > 15 && distancefront <= 15 && distanceright <= 15) ||(s==LOW)&& (distanceleft > 15 && distancefront > 15 && distanceright <= 15) ||(s==LOW)&& (distanceleft > 15 && distancefront <= 15 && distanceright > 15) ) { digitalWrite(4, LOW); digitalWrite(7, HIGH); digitalWrite(8, HIGH); digitalWrite(12, LOW); } } Video microcontroller-projects/fingerprint-based-car-ignition-system-using-arduino-and-rfid

Fingerprint based Car Ignition System using Arduino and RFID

will only allow an authorized person in the vehicle.

Materials Used

Arduino Nano R305 Fingerprint sensor EM18 RFID reader 16*2 Alphanumeric LCD DC motors L293D Motor driver IC Veroboard or Breadboard (Whichever is available) Connecting wires 12V DC Battery

EM18 RFID Reader Module

, etc. is a module that can read the ID information stored in the RFID tags. The RFID tags stores a 12 digit unique number which can be decoded by an EM18 reader module, when the tag comes in range with the Reader. This module operates at a frequency of 125 kHz, which is having an inbuilt antenna, and it is operated using a 5 volt DC power supply. It gives a serial data output, and it has a range of 8-12 cm. The serial communication parameters are 8 data bits, 1 stop bit, and 9600 baud rate. Operating voltage: +4.5V to +5.5V DC Current consumption: 50mA Operating frequency: 125KHZ Operating temperature: 0-80 degree C Communication Baud Rate: 9600 Reading distance: 8-12 cm Antenna: Inbuilt VCC: 4.5- 5V DC voltage input GND: Ground pin Buzzer: Buzzer or LED pin TX: Serial data Transmitter pin of EM18 for RS232 (Output) SEL: This must be HIGH for using RS232 (LOW if using WEIGAND) Data 0: WEIGAND data 0 Data 1: WEIGAND data 1

Find out RFID Tag Unique 12 digit Code using Arduino

, first, we need to find out the 12 digit RFID tag unique code. As we discussed before, RFID tags contain a 12 digit unique code and it can be decoded by using an RFID reader. When we swipe the RFID tag near the Reader, the Reader will give the unique codes via the output serial port. First, connect the Arduino to the RFID reader as per circuit diagram and then upload below given code to Arduino. int count = 0; char card_no[12]; void setup() { Serial.begin(9600); } void loop() { if(Serial.available()) { count = 0; while(Serial.available() && count < 12) { card_no[count] = Serial.read(); count++; delay(5); } Serial.print(card_no); } } After successfully uploading the code, open the serial monitor, and set the baud rate to 9600. Then swipe the card near the Reader. Then the 12 digit code will start to display on the serial monitor. Do this process for all the used RFID tags and note it down for future references.

Circuit Diagram

is given below: In my case, I have soldered the complete circuit on perf board like shown below:

Finger Print Sensor Module

is a module that captures finger’s print image and then converts it into the equivalent template and saves them into its memory on selected ID (location) by Arduino. Here all the process is commanded by Arduino like taking an image of a fingerprint, convert it into templates, and storing location, etc. here. ᾠfor using the R305 fingerprint sensor. So first of all download the library using the link given below: Adafruit fingerprint sensor library and then select the zip file location to install the library. After successful library installation, follow the steps given below to enroll a new fingerprint in the sensor memory. Upload the code to the Arduino, and open the Serial monitor at a baud rate of 9600. button. Then the light on the fingerprint sensor will blink which indicates that you should place your finger on the sensor and after that follow the steps showing on serial monitor till it acknowledges you for successful enrolment.

Programming for RFID Keyless Ignition

is given at the end of the tutorial. Here we are explaining a few important parts of the code. ᾠfor using R305 fingerprint sensor. Then configure the serial port in which the fingerprint sensor will be connected. In my case, I have declared 12 as RX Pin and 11 as a TX pin. #include <Adafruit_Fingerprint.h> #include <LiquidCrystal.h> SoftwareSerial mySerial(12,11); Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); class. char input[12]; int count = 0; int a = 0; const int rs = 6, en = 7, d4 = 2, d5 = 3, d6 = 4, d7 = 5; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); code is written to get the unique 12 digit codes of the RFID tags and they are stored in an array. Here the elements of the array will be matched with the stored unique codes in the memory, to get the authenticated person details. count = 0; while (Serial.available() && count < 12) { input[count] = Serial.read(); count++; delay(5); } Then, the received array is compared with the stored tag codes. If the code is matched, then the license is considered as valid, which allows the user to put valid fingerprint. Otherwise, it will show an invalid license. if ((strncmp(input, "3F009590566C", 12) == 0) && (a == 0)) { lcd.setCursor(0, 0); lcd.print("License Valid "); lcd.setCursor(0, 1); lcd.print("Welcome "); delay(1000); a = 1; fingerprint(); } is written which will return a valid fingerprint ID for an already enrolled fingerprint. int getFingerprintID() { uint8_t p = finger.getImage(); if (p != FINGERPRINT_OK) return -1; p = finger.image2Tz(); if (p != FINGERPRINT_OK) return -1; p = finger.fingerFastSearch(); if (p != FINGERPRINT_OK) return -1; return finger.fingerID; } to get the information regarding authenticated person data and if data is matched, then the vehicle is ignited, otherwise, it will prompt for the wrong Fingerprint. int fingerprintID = getFingerprintID(); delay(50); if (fingerprintID == 1) { lcd.setCursor(0, 0); lcd.print("Access Granted "); lcd.setCursor(0, 1); lcd.print("Vehicle Started "); digitalWrite(9,HIGH); digitalWrite(10,LOW); while(1); } works which adds two layers of security to your car. are given below. Code #include <Adafruit_Fingerprint.h> #include <LiquidCrystal.h> char input[12]; int count = 0; int a = 0; const int rs = 6, en = 7, d4 = 2, d5 = 3, d6 = 4, d7 = 5; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); SoftwareSerial mySerial(12,11); Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); void setup() { pinMode(9,OUTPUT); pinMode(10,OUTPUT); digitalWrite(9,LOW); digitalWrite(10,LOW); Serial.begin(9600); lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print(" WELCOME TO "); lcd.setCursor(0, 1); lcd.print(" CIRCUIT DIGEST "); delay(2000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Please swipe "); lcd.setCursor(0, 1); lcd.print("Your License "); } void loop() { if (Serial.available()) { count = 0; while (Serial.available() && count < 12) { input[count] = Serial.read(); count++; delay(5); } if (count == 12) { if ((strncmp(input, "3F009590566C", 12) == 0) && (a == 0)) { lcd.setCursor(0, 0); lcd.print("License Valid "); lcd.setCursor(0, 1); lcd.print("Welcome "); delay(1000); a = 1; fingerprint(); } else if ((strncmp(input, "0B0028883E95", 12) == 0) && (a == 0)) { lcd.setCursor(0, 0); lcd.print("License Valid "); lcd.setCursor(0, 1); lcd.print("Welcome "); delay(1000); a = 1; fingerprint(); } else { if (a != 1) { lcd.setCursor(0, 0); lcd.print("License Invalid "); lcd.setCursor(0, 1); lcd.print("Try Again!!! "); delay(2000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Please swipe "); lcd.setCursor(0, 1); lcd.print("Your License "); } } } } } int getFingerprintID() { uint8_t p = finger.getImage(); if (p != FINGERPRINT_OK) return -1; p = finger.image2Tz(); if (p != FINGERPRINT_OK) return -1; p = finger.fingerFastSearch(); if (p != FINGERPRINT_OK) return -1; return finger.fingerID; } void fingerprint() { finger.begin(57600); while(a==1) { int fingerprintID = getFingerprintID(); delay(50); if (fingerprintID == 1) { lcd.setCursor(0, 0); lcd.print("Access Granted "); lcd.setCursor(0, 1); lcd.print("Vehicle Started "); digitalWrite(9,HIGH); digitalWrite(10,LOW); while(1); } else if (fingerprintID == 2) { lcd.setCursor(0, 0); lcd.print("Access Granted "); lcd.setCursor(0, 1); lcd.print("Vehicle Started "); digitalWrite(9,HIGH); digitalWrite(10,LOW); while(1); } else { lcd.setCursor(0, 0); lcd.print("Pls Place a "); lcd.setCursor(0, 1); lcd.print("Valid Finger "); } } } Video microcontroller-projects/diy-arduino-neo-pixel-digital-watch

Yet Another Arduino Digital Clock, but It’s Unique and You Will Need It

with Arduino pro mini and RTC module. About the clock I made, it's a very simple clock that shows time and room temperature and the main feature of this clock is that the color of the digits changes every minute.

Components to build your own Rainbow Clock

Arduino Pro Mini DS3231 RTC Module WS2812 Neo pixel LEDs- 42nos 2× Push Button Switches AMS1117 Voltage Regulator Perf Board Connecting Wires 330-ohm Resistor MDF sheet

Arduino 10 Segment Rainbow ClockWorking

The working of this clock is very simple and similar to other digital clocks. This clock gets the current time and date using the DS3231 RTC module and then this time is displayed on Neo-Pixel LEDs using Arduino Pro Mini. The DS3231 is a low-cost, accurate Real Time Clock that can maintains hours, minutes, and seconds, as well as, day, month, and year information. The module uses the I2C communication protocol which makes the connection to the Arduino board very easy. However, when it comes to communication between Arduino and RTC module the code isn’t that small and easy. But there are already several libraries for the DS3231 RTC which can be found on the internet. with the help of such libraries, we can read the current time, and with the help of Arduino, we can display that time in any type of display. DS3231 RTC module also comes with a temperature sensor so, we can also get the temperature readings.

Ten Segment Rainbow ClockCircuit Diagram

The complete schematic for building Arduino LED Clock is shown in the image given below: As you can see, this circuit diagram has two parts, first one is the main circuit that consists of an Arduino Pro Mini, DS3231 RTC module, push buttons, and AMS1117 voltage regulator and the second is the LED digit circuit where all the Neo-Pixel LEDs are arranged to display the time. DS3231 works on the I2C communication protocol so the SCL and SDA pins of the RTC module are connected to I2C pins (A4 and A5) of Arduino. The push buttons are connected to digital pin 2 and 4 of Arduino. This complete setup is powered by two 18650 cells connected in series. The output voltage from these cells will be around 7.4 so an AMS1117 5V voltage regulator is used to supply regulated 5V to Arduino pro mini and other components.

3-D Printing the Parts to Display Time

As discussed earlier, instead of using a 7-segment display we are going to use Neo-Pixel LEDs for displaying time. Here, we are going to 3-D print some parts so that we can arrange the Neo-Pixel LEDs in digits form and display time. After hours of thinking and calculations, I designed a ten-segment digit. The design is very simple, each segment has a slot for Neo pixel LED. Later in these slots, we will place Neo pixel LEDs. I also designed two segments for the second indication. I have designed all the parts in Tinker CAD software. Once it was done, my design looked something like this: and you can print your casing using it.

Assembling the Neo-Pixel LEDs on 3-D Printed Parts

After 3D printing of the parts, first, we need to insert the Neo-pixel LEDs on their respective sockets. A Neo-pixel LED has 4 pins that are VCC, GND, data IN, and data Out. To control a Neo-pixel LED, we should feed the signal to the din pin. We can connect multiple LEDs by connecting the Data OUT pin to the Data IN pin of the next LED and so on. Here, take a WS2812 Neo-pixel and insert it into the socket. Do the same for the 10 segments,remember to place the LEDs in the same orientation. After placing the LEDs let's start soldering. First, solder all the grounds of 10 LEDs together. For this, I am using single-stranded copper wire. Check the pins of each LED before soldering. Also, don't apply more heat on the LED. After connecting all grounds, now let's connect all VCC pins together. Next, connect the first data out to the data in the pin of the next LED. Repeat this for all the ten LEDs. After finishing all the soldering, we will get a common ground, common 5v, data in connection for the first LED, and data out the wire from the last LED. We have to repeat this process for the remaining 3 digits. Also, insert two LEDs in the second segment and solder. After connecting all the digits and the second segment, let's connect digits together. Connect first digit (from left-hand side) data out to the din in of the second digit then data out of second to the din of third and so on finally connect the last digit out to the data in of the second segment. connect all the 5 v together and also the grounds. That's it, now we have a common ground, a common 5v, and a din.

Building the Circuit on PerfBoard

After testing the circuit on the breadboard, I decided to solder it permanently on a perf board. I tried to build the circuit as small as possible to reduce the size. First, I took a small piece of perf board, and then I placed the female header pin for the RTC module and Arduino pro mini. Next, I placed the push buttons on an even small perf board and soldered its pins to the perf board. Then with the help of flexible wire, I attached the push buttons to the main PCB.

Building the Enclosure for Ten Segment Rainbow Clock

This is not the hardest part. Either you can 3D print the enclosure or make it yourself. So, first I measured the length and width of the digits. After getting the measurement, I took a 5mm MDF board and drawn sides of rectangles having a length of 18cm and a width of 6.5mm. I plan to build a rectangular structure and place the digits in it. After drawing the lines, I cut the rectangles using the cutter and joined them together, and made a rectangular structure without a front. If you are confused with the making, you can refer to the images. After building the frame, I inserted the digits into the frame and secured it with glue. On the backside of the frame, I fixed the main circuit and battery. Also, I placed the pushbuttons and the on/off switch on the outer backside. After connecting the digits with the main circuit, I closed the backside. Finally, we need to attach a plastic sheet to the front side of the clock for better light diffusion. You can use any type of diffused plastic sheet.

Programming Arduino Pro Mini for Rainbow Clock

As I mentioned earlier, the code for this project is not very simple. Honestly, I referred to lots of other clock projects to make this code. Whatever, the complete code is given at the end of the document. Here, I am explaining the complete code line by line. First, I included the required libraries. In this project, we are using the ds3231 RTC library to control the DS3232RTC module. DS3232RTC is an Arduino library that supports the Maxim Integrated DS3232 and DS3231 Real-Time Clocks. The DS3232RTC library also implements functions to support the additional features of the DS3232 and DS3231.Time and Timelib libraries provide timekeeping functionality for Arduino. Wire library allows communication with I2C(DS3231) devices. And finally, I am using FastLED to control the neopixel LEDs #include <DS3232RTC.h> #include <TimeLib.h> #include <Time.h> #include <Wire.h> #include <FastLED.h> Next, I defined the total number of LEDs, colour order of LED type, Arduino pin for data input, and push-button pins. #define NUM_LEDS 42 #define COLOR_ORDER RGB #define LED_PIN 6 #define MIN_PIN 4 #define HUR_PIN 2 Also, I made a byte array for the numbers and symbols. We have a total of 10 LEDs in each digit and a total of 12 characters (0-9 numbers + Degree symbol and C letter) each array represents each character. For example {1,1,0,1,1,1,1,0,1,1} represents zero that is in our digit segment 3 and segment 8 in off-stage all other LEDs in on stage that will display zero and so on‐󋈍 byte digits[12] [10] = { {1,1,0,1,1,1,1,0,1,1}, {1,1,1,1,1,0,0,0,0,0}, {1,0,1,1,1,1,0,1,1,1}, {1,1,1,1,1,1,0,1,0,1}, {1,1,1,1,0,1,1,1,0,0}, {1,1,1,0,1,1,1,1,0,1}, {1,1,1,0,0,1,1,1,1,1}, {1,1,1,1,1,1,1,0,0,0}, {1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,0,0}, {1,1,1,1,1,1,1,1,0,0}, {0,0,1,1,1,1,1,1,0,0}}; Next, I defined the color table you can customize this according to your ideas. long ColorTable[21] = { CRGB::Amethyst, //white CRGB::Aqua, //pink CRGB::Blue, //Blue CRGB::Chartreuse,// Gold CRGB::DarkGreen, //Red CRGB::DarkMagenta,//Aqua CRGB::DarkOrange, // yellow green CRGB::DeepPink, //Aqua CRGB::Fuchsia, //Sea blue CRGB::Gold, //Gold CRGB::GreenYellow,//off white CRGB::LightCoral,//white CRGB::Tomato,//white CRGB::Salmon,//Pure white CRGB::Red,// Drak Green CRGB::Orchid,//blue white CRGB::Sienna,//yellow white CRGB::Purple,// aqua CRGB::DarkOrange,//yellow green CRGB::FloralWhite,//white CRGB::Yellow //yellow }; In the setup section first, I started the serial monitor and I2C communication using serial.begin and wire.begin respectively. Here, we use the serial monitor for testing the code and circuit. Also, I defined the mode of all pins here we are using button pins are as input and data pin as output and in the case of input, I used the input pull-up function to pull high pin status. void setup(){ Serial.begin(9600); Wire.begin(); FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS); pinMode(DST_PIN, INPUT_PULLUP); pinMode(MIN_PIN, INPUT_PULLUP); pinMode(HUR_PIN, INPUT_PULLUP); } Then I read the time using the RTC.read function and stored it into a DateTime object. Also, I converted the 24-hour format into a 12-hour format. GetTime(){ tmElements_t Now; RTC.read(Now); int hour=Now.Hour; int minute=Now.Minute; int second =Now.Second; if (second % 2==0) {Dot = false;} else {Dot = true;}; if (hour >= 12) { hour -= 12; } Next, I defined two arrays that are timetoarray and temptoarray for displaying the current time and temperature in the display. I started from the last LED of digits and displayed 4 digits. I defined the first LED of each digit using the cursor function. Inthe same way, I displayed the temperature also. for(int i=1;i<=4;i++){ int digit = Now % 10; if (i==1){ cursor = 30; for(int k=0; k<=9;k++){ if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;} cursor ++ }; In the void time function, we can set the time. Here, I used the digital read function of Arduino to read the state of the pushbutton. void TimeAdjust(){ int buttonH = digitalRead(HUR_PIN); int buttonM = digitalRead(MIN_PIN); if (buttonH == LOW || buttonM == LOW){ delay(500); tmElements_t Now; RTC.read(Now); int hour=Now.Hour; int minutes=Now.Minute; int second =Now.Second; if (buttonH == LOW){ if (Now.Hour== 23){Now.Hour=0;} else {Now.Hour += 1;}; }else { if (Now.Minute== 59){Now.Minute=0;} else {Now.Minute += 1;}; }; RTC.write(Now); } Finally, in the main loop section, first I checked if the time is modified or not. Then, I updated the LED array according to the time. The same I did to the temperature array. Finally, I displayed the values in digits using fastLED.show function. Void loop() { BrightnessCheck(); DSTcheck(); TimeAdjust(); TimeToArray(); TempToArray(); FastLED.show(); if (TempShow == true) delay (8000); } }

Testing our Ten Segment Rainbow Clock

Ok, so now we have assembled the Neo-Pixel LEDs and circuit. It’s time to test the clock. For that, connect the Arduino to laptop and upload the code. I hope you liked this clock project.The completemaking video is given below. If you have any questions, please, leave them in the comment section below. Code #include <DS3232RTC.h> #include <TimeLib.h> #include <Time.h> #include <Wire.h> #include <FastLED.h> #define NUM_LEDS 42 #define COLOR_ORDER RGB // Define color order for your strip #define LED_PIN 6 // Data pin for led comunication #define DST_PIN 5 // Define DST adjust button pin #define MIN_PIN 4 // Define Minutes adjust button pin #define HUR_PIN 2 // Define Hours adjust button pin #define BRI_PIN 3 // Define Light sensor pin CRGB leds[NUM_LEDS]; byte digits[12][10] = { {1,1,0,1,1,1,1,0,1,1}, {1,1,1,1,1,0,0,0,0,0}, {1,0,1,1,1,1,0,1,1,1}, {1,1,1,1,1,1,0,1,0,1}, {1,1,1,1,0,1,1,1,0,0}, {1,1,1,0,1,1,1,1,0,1}, {1,1,1,0,0,1,1,1,1,1}, {1,1,1,1,1,1,1,0,0,0}, {1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,0,0}, {1,1,1,1,1,1,1,1,0,0}, {0,0,1,1,1,1,1,1,0,0}}; bool Dot = true; //Dot state bool DST = true; //DST state// false to true bool TempShow = false; int last_digit = 0; // int ledColor = 0x0000FF; // Color used (in hex) long ledColor = CRGB::DarkOrchid; // Color used (in hex) //long ledColor = CRGB::MediumVioletRed; //Random colors i picked up long ColorTable[21] = { CRGB::Amethyst, //white CRGB::Aqua, //pink CRGB::Blue, //Blue CRGB::Chartreuse,// Gold CRGB::DarkGreen, //Red CRGB::DarkMagenta,//Aqua CRGB::DarkOrange, // yellow green CRGB::DeepPink, //Aqua CRGB::Fuchsia, //Sea blue CRGB::Gold, //Gold CRGB::GreenYellow,//off white CRGB::LightCoral,//white CRGB::Tomato,//white CRGB::Salmon,//Pure white CRGB::Red,// Drak Green CRGB::Orchid,//blue white CRGB::Sienna,//yellow white CRGB::Purple,// aqua CRGB::DarkOrange,//yellow green CRGB::FloralWhite,//white CRGB::Yellow //yellow }; void setup(){ Serial.begin(9600); Wire.begin(); FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS); LEDS.setBrightness(75); // Set initial brightness pinMode(DST_PIN, INPUT_PULLUP); // Define DST adjust button pin pinMode(MIN_PIN, INPUT_PULLUP); // Define Minutes adjust button pin pinMode(HUR_PIN, INPUT_PULLUP); // Define Hours adjust button pin pinMode(BRI_PIN, INPUT_PULLUP); // Define bright adjust TempShow = false; // do not show temperature } // Get time in a single number, if hours will be a single digit then time will be displayed 155 instead of 0155 int GetTime(){ tmElements_t Now; RTC.read(Now); //time_t Now = RTC.Now();// Getting the current Time and storing it into a DateTime object int hour=Now.Hour; int minute=Now.Minute; int second =Now.Second; if (second % 2==0) {Dot = false;} else {Dot = true;}; if (hour >= 12) { hour -= 12; } // Handle hour 0 (midnight) being shown as 12. // else if (hour == 0) { // hour += 12; // } return (hour*100+minute); }; // Check Light sensor and set brightness accordingly void BrightnessCheck(){ const byte sensorPin = 3; // light sensor pin const byte brightnessLow = 75; // Low brightness value const byte brightnessHigh = 20; // High brightness value int sensorValue = digitalRead(sensorPin); // Read sensor if (sensorValue == 0) {LEDS.setBrightness(brightnessHigh);} else {LEDS.setBrightness(brightnessLow);} }; // Convert time to array needed for display void TimeToArray(){ int Now = GetTime(); // Get time int cursor = 42; // last led number // Serial.print("Time is: ");Serial.println(Now); if (DST){ // if DST is true then add one hour Now+=100; // Serial.print("DST is ON, time set to : ");Serial.println(Now); }; if (Dot){leds[40]=ledColor; leds[41]=ledColor;} else {leds[40]=0x000000; leds[41]=0x000000; }; for(int i=1;i<=4;i++){ int digit = Now % 10; // get last digit in time if (i==1){ // Serial.print("Digit 4 is : ");Serial.print(digit);Serial.print(" "); cursor = 30; for(int k=0; k<=9;k++){ // Serial.print(digits[digit][k]); if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;}; cursor ++; }; // Serial.println(); if (digit != last_digit) { cylon(); ledColor = ColorTable[random(21)]; } last_digit = digit; } else if (i==2){ // Serial.print("Digit 3 is : ");Serial.print(digit);Serial.print(" "); cursor =20; for(int k=0; k<=9;k++){ // Serial.print(digits[digit][k]); if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;}; cursor ++; }; // Serial.println(); } else if (i==3){ // Serial.print("Digit 2 is : ");Serial.print(digit);Serial.print(" "); cursor =10; for(int k=0; k<=9;k++){ // Serial.print(digits[digit][k]); if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;}; cursor ++; }; // Serial.println(); } else if (i==4){ // Serial.print("Digit 1 is : ");Serial.print(digit);Serial.print(" "); cursor =0; if(digit !=0){ for(int k=0; k<=9;k++){ // Serial.print(digits[digit][k]); if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;}; cursor ++; }; } if(digit ==0){ for(int k=0; k<=9;k++){ // Serial.print(digits[digit][k]); if (digits[12][k]== 1){leds[cursor]=ledColor;} else if (digits[12][k]==0){leds[cursor]=0x000000;}; cursor ++; }; // Serial.println(); } } Now /= 10; }; }; // Convert temp to array needet for display void TempToArray(){ tmElements_t tm; RTC.read(tm); if (tm.Second != 27) { TempShow = false; return; } TempShow = false;//true to false int t = RTC.temperature(); int celsius = (t / 4.0) * 100; Serial.print("Temp is: ");Serial.println(celsius); int cursor = 42; // last led number leds[40]=0x000000; leds[41]=0x000000; for(int i=1;i<=4;i++){ int digit = celsius % 10; // get last digit in time if (i==1){ Serial.print("Digit 4 is : ");Serial.print(digit);Serial.print(" "); cursor = 30; for(int k=0; k<=9;k++){ Serial.print(digits[11][k]); if (digits[11][k]== 1){leds[cursor]=ledColor;} else if (digits[11][k]==0){leds[cursor]=0x000000;}; cursor ++; }; Serial.println(); } else if (i==2){ Serial.print("Digit 3 is : ");Serial.print(digit);Serial.print(" "); cursor =20; for(int k=0; k<=9;k++){ Serial.print(digits[10][k]); if (digits[10][k]== 1){leds[cursor]=ledColor;} else if (digits[10][k]==0){leds[cursor]=0x000000;}; cursor ++; }; Serial.println(); } else if (i==3){ Serial.print("Digit 2 is : ");Serial.print(digit);Serial.print(" "); cursor =10; for(int k=0; k<=9;k++){ Serial.print(digits[digit][k]); if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;}; cursor ++; }; Serial.println(); } else if (i==4){ Serial.print("Digit 1 is : ");Serial.print(digit);Serial.print(" "); cursor =0; for(int k=0; k<=9;k++){ Serial.print(digits[digit][k]); if (digits[digit][k]== 1){leds[cursor]=ledColor;} else if (digits[digit][k]==0){leds[cursor]=0x000000;}; cursor ++; }; Serial.println(); } celsius /= 10; }; }; void DSTcheck(){ int buttonDST = digitalRead(DST_PIN); // Serial.print("DST is: ");Serial.println(DST); if (buttonDST == LOW){ if (DST){ DST=false; // Serial.print("Switching DST to: ");Serial.println(DST); } else if (!DST){ DST=true; // Serial.print("Switching DST to: ");Serial.println(DST); }; delay(500); }; } void TimeAdjust(){ int buttonH = digitalRead(HUR_PIN); int buttonM = digitalRead(MIN_PIN); if (buttonH == LOW || buttonM == LOW){ delay(500); tmElements_t Now; RTC.read(Now); int hour=Now.Hour; int minutes=Now.Minute; int second =Now.Second; if (buttonH == LOW){ if (Now.Hour== 23){Now.Hour=0;} else {Now.Hour += 1;}; }else { if (Now.Minute== 59){Now.Minute=0;} else {Now.Minute += 1;}; // if (Now.Hour > 12){Now.Hour = Now.Hour -12;} // 24 to 12 hr // else {Now.Hour = Now.Hour ;}; }; RTC.write(Now); } } /* coool effect function*/ void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } } void cylon () { static uint8_t hue = 0; Serial.print("x"); // First slide the led in one direction for(int i = 0; i < NUM_LEDS; i++) { // Set the i'th led to red leds[i] = CHSV(hue++, 255, 255); // Show the leds FastLED.show(); // now that we've shown the leds, reset the i'th led to black // leds[i] = CRGB::Black; fadeall(); // Wait a little bit before we loop around and do it again delay(10); } Serial.print("x"); // Now go in the other direction. for(int i = (NUM_LEDS)-1; i >= 0; i--) { // Set the i'th led to red leds[i] = CHSV(hue++, 255, 255); // Show the leds FastLED.show(); // now that we've shown the leds, reset the i'th led to black // leds[i] = CRGB::Black; fadeall(); // Wait a little bit before we loop around and do it again delay(10); } } void loop() // Main loop { BrightnessCheck(); // Check brightness DSTcheck(); // Check DST TimeAdjust(); // Check to se if time is geting modified TimeToArray(); // Get leds array with required configuration TempToArray(); // Show Temperature FastLED.show(); // Display leds array if (TempShow == true) delay (8000); } Video microcontroller-projects/simple-arduino-rc-boat-that-can-be-controlled-wirelessly-using-rf-module

Build a Simple Arduino RC Boat that can be Controlled Wirelessly using 433 MHz RF Modules

in this tutorial. previously. You can also check out these projects if you are interested.

Components Required for Arduino RC Boat

433MHz transmitter and receiver Arduino (any Arduino, to reduce the size I am using promini) HT12E and HT12D Push buttons- 4Nos Resistors- 1mega ohm, 47k ohm L293d Motor Driver 9V Battery (I am using a 7.4-volt battery)- 2Nos 7805 regulator- 2Nos DC motors- 2Nos Motor leaf or propellors(I am using homemade propellors)- 2Nos .1uf capacitor- 2Nos Common PCB

433MHz RF Transmitter and Receiver Modules

type RF modules, Amplitude-shift keying (ASK) is a form of amplitude modulation that represents digital data as variations in the amplitude of a carrier wave. In an ASK system, the binary symbol 1 is represented by transmitting a fixed-amplitude carrier wave and fixed frequency for a bit duration of T seconds. If the signal value is 1, then the carrier signal will be transmitted; otherwise, a signal value of 0 will be transmitted. That means they usually draw no power when transmitting Logic “zeroᾮ This low power consumption makes them very useful in battery-operated projects.

433MHZ RF Transmitter

This type of module is super tiny and comes with 3 pins VCC, ground, and data. Some other modules come with an extra antenna pin. The working voltage of the transmitter module is 3V-12V and this module doesn't have any adjustable components. One of the major advantages of this module is the low current consumption, it requires almost zero current to send bit zero.

Block Diagram of Arduino RC Boat Transmitter

In the above block diagram, there are four pushbuttons (Control Buttons), these pushbuttons are for controlling the direction of the boat. We have four of them for forward, backward, left, and right. From the pushbuttons, we get logic for controlling the boat but can’t directly connect to the encoder that's why we used the Arduino. You might think why I used Arduino here, it is simply because we need to pull down two parallel data inputs of the encoder at the same time for a backward and forward movement that can’t be achieved with just pushbuttons. Then the encoder encodes the coming parallel data to serial outputs. Then we can transmit that serial data with the help of an RF transmitter.

Circuit Diagram of the Arduino RC Remote (Transmitter)

encoder connected to another four digital pins of Arduino (D2-D5). So with the help of Arduino, we can decide the input of the encoder. for 5V operation. Then the resistor value will be 1.1MΩ for 5V. Then I connected the output of the HT12E to the transmitter module. We already mentioned, the Arduino and rf transmitter module, both of these devices work on 5V high voltage will kill it, so to avoid this, I added the 7805, voltage regulator. Now we can connect (Vcc) 6-12volt any type batteries to input.

Building the RC BOAT Transmitter Circuit

I soldered every component on a common PCB. Remember we are working on an RF project so there are a lot of chances for different types of interferences so connect all components very closely as much possible. It's better to use female pin headers for Arduino and the transmitter module.Also, try to solder everything on the copper pads instead of using extra wires. Finally, connect a small wire to the transmitter module that will help to increase the total range. Before connecting the Arduino and transmitter module, double-check the voltage of the lm7805 output. The above image shows the top view of the completed RC Boat transmitter circuit and the Bottom view of the completed RC Boat Transmitter circuit is shown below.

Building the Arduino RC Boat Transmitter Enclosure

A decent body is necessary for the remote. This step is all about your ideas, you can create a remote body with your ideas. I am explaining how I made this. For making a remote body, I choose 4mm MDF sheets, you can also choose plywood, foam sheet, or cardboard, then I cut two pieces from that with a length of 10cm and breadth of 5cm. Then I marked the positions for the buttons. I placed the direction buttons on the left side and forward, backward buttons on right. On the other side of the sheet, I connected the push buttons to the main transmitting circuit. Remember a normal pushbutton has 4 pins that are two pins for each side. Connect one pin to Arduino and the other pin to the ground. If you are confused with that, please check it with a multimeter or check the datasheet. After connecting all these things, I placed the control circuit in between the two MDF boards and tighten with some long bolt (please refer to the below images if you want). Once again creating a good body is all about your ideas.

433Mhz Receiver Module

This receiver also very tiny and comes with 4 pins VCC, ground, and the two middle pins are data out. The working voltage of this module is 5v. Like the transmitter module, this is also a low power module. Some modules come with an extra antenna pin but in my case, that is not present.

Block Diagram of the Arduino RC Boat Receiver

The above block diagram describes the working of the RF receiver circuit. First, we can receive the transmitted signals using the RF receiver module. The output of this receiver is serial data. But we can't control anything with this serial data that's why we connected the output to the decoder. The decoder decodes the serial data to our original parallel data. In this section, we don't require any microcontrollers, we can directly connect the outputs to the motor driver.

Circuit Diagram of Arduino RC Boat Receiver

The input pin of the HT12D will be connected to a receiver that has a serial output. Among the 12-bits, 8 bits (A0-A7) are address bits and the HT12D will decode the input if only it matches its current address. D8-D11 are the output bits. To match this circuit to the transmitter circuit, I connected all the address pins to the ground. Data out of the module is the serial type and the decoder decodes this serial data to original parallel data and we get out through D8-D11. To match the oscillation frequency should connect the 33-56k resistor to oscillator pins. Led on the 17th pin indicates the valid transmission, it only lit after when the receiver connected to a transmitter. The voltage input of the receiver is also 6-12 volts. To control motors, I used theL293D IC, I choose this IC because to decrease the size and weight and this IC is best for controlling two motors in two directions. L293D has 16 pins, the below diagram shows the pinouts. 1, 9 pins are the enable pin, we connect that to 5 v to enable motors 1A, 2A, 3A, and 4A are the control pins. The motor will turn to the right if the pin 1A goes low and 2A goes high, and the motor will turn to the left if 1A goes low and 2A high.So we connected these pins to the output ps of the decoder. 1Y, 2Y, 3Y, and 4Y are the motor connection pins. Vcc2 is the motor driving voltage pin, if you are using a high voltage motor, then you connect this pin to the corresponding voltage source.

Building the Receiver Circuit of Arduino RC Boat

Before building the receiver circuit, you should remember some important things. The important one is the size and weight because after building the circuit, we need to fix it on the boat. So if the weight increases, that will affect the buoyancy and movement. So same asin the transmitter circuit, solder every component in a small common PCB and try to use minimum wires. I connected pin 8 of the motor driver to 5v because I am using 5V motors.

Buildingthe RC-BOAT

I tried different materials to build the boat body. And I got a better result with thermocol sheet. So I decided to build the body with thermocol. First, I took a 3cm thick thermocol piece and place the receiver circuit on top, then I marked the shape of the boat in thermocol and cut. So this is my way to build the boat, you can build according to your ideas.

Motors and Propellers for Arduino Air Boat

should connect 0.1uf capacitor parallel to motor inputs. In the case of propellers,I made propellers using plastic sheets. You can buy propellers from the store or you can build your own both will work just fine. To build the propellers, first, I took a small plastic sheet and cut two small pieces from it andI bend the pieces with the help of candle heat. Finally, I put a small hole in its center for the motor and fixed to the motor that's it.

Working of Arduino RC Boat

This boat has two motors lets call it left and right. If the motor moves to clockwise also (the position of the propellor also depends) propellor sucks air from the front and exhaust to the backside. That generates forward drag. : If both the left and right motors rotate to clockwise that will forward movement : If both the left and right motors to rotate counterclockwise(that is propeller sucks air from the backside and exhaust to the front side )that will make backward movement If only the right motor rotates that is boat get only drag from the right side that will the boat to move to the left side : If only the left motor rotates that is boat gets only drag from the left side that will make the boat move to the right side. We connected the motors driver's input to four output bits of the decoder(D8-D11). we can control these 4 outputs by connecting the AD8-AD11 to the ground that is the buttons in the remote. For example, if we connect AD8 to the ground that will activate the D8. So such a way we can control the two motors in two directions using these 4 outputs. But we can't control two motors by just one button (we need that for forward and backward movement) that's why we used the Arduino. With help of Arduino, we can select the input data pins as our wish.

Arduino Programming of the RC Boat

The programming of this boat is very simple because we want only some logic switching. And we can achieve everything with basic Arduino functions. The complete program for this project can be found at the bottom of this page. The explanation of your program is as follows We start the program by defining the integers for four input buttons and decoder inputs pins. int f_button = 9; int b_button = 8; int l_button = 7; int r_button = 6; int m1=2; int m2=3; int m3=4; int m4=5; In the setup section, I defined the pin modes. That is, the buttons are connected to digital pins so these pins should define as input and we need to get output for the input of the decoder so we should define those pins as output. pinMode(f_button,INPUT_PULLUP); pinMode(b_button,INPUT_PULLUP); pinMode(l_button,INPUT_PULLUP); pinMode(r_button,INPUT_PULLUP); pinMode(m1,OUTPUT); pinMode(m2,OUTPUT); pinMode(m3,OUTPUT); pinMode(m4,OUTPUT); function of Arduino. If the pin status goes low that means the corresponding pin is pressed then we will execute the conditions as like follows- if ( digitalRead(f_button)==LOW) That means the forward button is pressed { digitalWrite(m1, LOW); digitalWrite(m3, LOW); digitalWrite(m2, HIGH); digitalWrite(m4, HIGH); } This will pulldown m1 and m2 of the encoder this will activate both motors on the receiver side. Similarly, for backward movement { digitalWrite(m1, HIGH); digitalWrite(m3, HIGH); digitalWrite(m2, LOW); digitalWrite(m4, LOW); } For left movement { digitalWrite(m1, LOW); digitalWrite(m3, HIGH); digitalWrite(m2, HIGH); digitalWrite(m4, HIGH); } For right movement { digitalWrite(m1, HIGH); digitalWrite(m3, LOW); digitalWrite(m2, HIGH); digitalWrite(m4, HIGH); } After compiling the code, upload it to your Arduino board. : Place the boat on the water surface and check whether it is moving correctly if not try to change the polarity of motors and propellers. Also, try to balance weight. The complete working of the project can be found in the video linked at the bottom of this page. If you have any questions leave them in the comment section. Code int f_button = 9; int b_button = 8; int l_button = 7; int r_button = 6; int m1 = 2; int m2 = 3; int m3 = 4; int m4 = 5; void setup () { pinMode(f_button, INPUT_PULLUP); pinMode(b_button, INPUT_PULLUP); pinMode(l_button, INPUT_PULLUP); pinMode(r_button, INPUT_PULLUP); pinMode(m1, OUTPUT); pinMode(m2, OUTPUT); pinMode(m3, OUTPUT); pinMode(m4, OUTPUT); } void loop() { if ( digitalRead(f_button) == LOW) { digitalWrite(m1, LOW); digitalWrite(m3, LOW); digitalWrite(m2, HIGH ); digitalWrite(m4, HIGH); } if ( digitalRead(b_button) == LOW) { digitalWrite(m2, LOW); digitalWrite(m4, LOW); digitalWrite(m1, HIGH); digitalWrite(m3, HIGH); } if ( digitalRead(l_button) == LOW) { digitalWrite(m1, LOW); digitalWrite(m2, HIGH); digitalWrite(m3, HIGH); digitalWrite(m4, HIGH); } if ( digitalRead(r_button) == LOW) { digitalWrite(m1, HIGH); digitalWrite(m2, LOW); digitalWrite(m3, HIGH); digitalWrite(m4, HIGH); } } Video microcontroller-projects/arduino-walkie-talkie-using-nrf24l01

Long Range Arduino Based Walkie Talkie using nRF24L01

project using the links.

Walkie Talkie using nRF24L01 RF Module

and the data rate can be 250kbps, 1Mbps, 2 Mbps. It has 125 possible channels in between 1Mhz spacing so the module can use 125 different channels which makes it possible to have a network of 125 independently working modems in one place. Most importantly, NRF24L01 signals don’t overlap or cross interface with other walkie-talkie systems like police walkie-talkie and railway walkie-talkie and it does not disturb other walkie-talkies. A single nrf24l01 module can communicate up with the other 6 nrf24l01 modules at a time when they are in the receiving state. Also, it is a low power consumption module which is an added advantage. There are two types of NRF24L01 modules that are widely available and commonly used, one is NRF24L01+ and another is NRF24L01+PA+LNA (shown below) with built-in antenna. The NRF24L01+ has an onboard antenna and only a 100 meters range. It is good only for indoor use and is not suitable for outdoor long-distance communications. Moreover, if there is a wall present in between transmitter and receiver, the signal transmission is very poor. The NRF24L01 +PA+LNA with an external antenna has a PA that boosts the power of the signal before the transmission. LNA stands for Low Noise Amplifier. It is clear, filters out the noise and boosts the extremely weak and uncertain low level of the signal received from the antenna. It helps in making useful levels of signal and it has 2dB external antenna through which it can transmit 1000 meters of on-air range coverage, so it is perfect for our outdoor walkie-talkie communication projects.

Component Required for Arduino based Walkie Talkie

NRF24L01 +PA+LNA with external 2DB antenna (2 pcs) Arduino UNO or any version of Arduino Audio amplifier (2pcs) Microphone circuit: You can make it yourself (discussed later) or purchase a sound sensor module. DC to DC step-up booster module (2pcs) 3.3V AMS1117 voltage regulator module Power indicator LED (2pcs) 470 ohms resistance (2pcs) A 4-inch loudspeaker (2pcs) push button (for PTT button) 104 PF for making of PTT button (2pcs) 100 NF capacitor for NRF24L01 (2pcs) 1k resistance for PTT button (2pcs) 2 sets of li-ion battery Li-ion battery charging and battery protection module (2pcs) Some jumper wire, male header pin, dotted vero board

Arduino Walkie Talkie Circuit Diagram

is shown in the image below. The circuit diagram shows all the connections including the PTT button, microphone circuit, and stereo audio output. The NRF24L01 module voltage input range is 1.9v to a maximum of 3.6 volts and for voltage and current stability you have to use a 100nf capacitor into the +VCC and - GND, yet other pins of nrf24l01 module can tolerate 5-volt signal levels. I started with making homemade custom PCB and Arduino Atmega328p board. I had put the IC Atmega328p on the programmer and flashed it and then uploaded the code. Then, I added 16 MHz crystal on Atmega328p IC on (PB6, PB7) pin 9 and 10. The pictures of my custom made PCB and the assembled board with programmed IC is shown below. I connected NRF24L01 modules as shown in the circuit diagram in the following order. CE to digital pin number 7, CSN to pin number 8, SCK to digital pin 13, MOSI to digital pin 11, MISO to digital pin 12 and IRQ to digital pin 2. which is a 3.3-volt voltage regulator, the module also reduces your project size and makes it compact. project. circuit for more information. For better understanding, I have made another representation of the whole connection with component values as you can see below because by default the Arduino audio output is very low (usually you can only hear sound using just headphone, not a loudspeaker, so we need an amplification stage). The module can drive two laptop speakers easily and is available at a very low cost. Also, it comes with a very powerful audio amplifier in an SMD package which requires very little space.The PAM8403 audio amplifier module is shown below. and only used right channel output. If you want, you can use two speakers with this module. or erratic signals when the switch is pressed. Pin 4 is now directly connected with Arduino Digital pin D3 as an interrupted pin is assigned to the coding. The NRF24L01 + PA+LNA when transmitting an audio signal or DATA packets consumes more power hence, it consumes more current. When you press the PTT button suddenly, the power consumption increases. For handling this suddenly increased load, you must use a 100nF capacitor on +vcc and Ground for the transmission stability of the NRF24L01+PA+LNA Module. on its pin D3. In the program, we will declare the digital pin 3 of Arduino constantly checking its input voltage. If the input voltage is low, it keeps the walkie-talkie in receiving mode and if the digital pin number 3 is high, it switches the walkie-talkie into transmitting mode for sending voice signal picked up by the microphone process through microcontroller and transmit through NRF24L01+PA+LNA with an external antenna. To power, all the components like Arduino IC Atmega328p, NRF24L01+PA+LNA, audio amplifier, PTT button, and Microphone circuit, I used 2 sets of Li-ion battery for this project as shown below. to reach 5V with more than 1 Amp of stable power output. After you have built the circuit, you can assemble it in a small enclosure. I used a plastic box and placed my circuits as shown in the image below

Walkie Talkie Arduino Code

The complete program for your Arduino walkie talkie can be found at the bottom of this page. In this section, let's discuss how the program works. Before getting there, you need to include some Libraries which are listed below. nRF24 Library nRF24 Audio Library Maniaxbug RF24 Library Begin the programming by including the Radio and Audio Library headers as shown below #include <RF24.h> #include <SPI.h> #include <RF24Audio.h> #include "printf.h" // General includes for radio and audio lib Initialize the RF Radio on pins 7 and 8 and set up the audio radio number to 0. Also, initialize the ppt button on pin 3. RF24 radio(7,8); // Set radio up using pins 7 (CE) 8 (CS) RF24Audio rfAudio(radio,0); // Set up the audio using the radio, and set to radio number 0 int talkButton = 3; Inside the setup function, begin serial monitor at 115200 baudrate for debugging. Then initialize the ppt button connect to pin 3 as an interrupt pin. void setup() { Serial.begin(115200); printf_begin(); radio.begin(); radio.printDetails(); rfAudio.begin(); pinMode(talkButton, INPUT);//sets interrupt to check for button talk abutton press attachInterrupt(digitalPinToInterrupt(talkButton), talk, CHANGE); //sets the default state for each module to receive rfAudio.receive(); } Next, we have a function called talk() which is called in response to interrupt. The program checks the state of the button if the button is pressed and held it enters transmit mode to send the audio. If the button is released it enters receive mode. void talk() { if (digitalRead(talkButton)) rfAudio.transmit(); else rfAudio.receive(); } void loop() { } The complete working of this project can be found in the video linked below. The Walkie Talkie produces some noise during operation, this is the noise from the carrier frequency of the nRF24L01 Module. It can be reduced by using a good sound sensor or microphone module. If you have any questions about this project you can leave them in the comment section below. You can also use our forums for getting quick answers to your other technical queries. Code #include <RF24.h> #include <SPI.h> #include <RF24Audio.h> #include "printf.h" // General includes for radio and audio lib RF24 radio(7,8); // Set radio up using pins 7 (CE) 8 (CS) RF24Audio rfAudio(radio,0); // Set up the audio using the radio, and set to radio number 0 int talkButton = 3; void setup() { Serial.begin(115200); printf_begin(); radio.begin(); radio.printDetails(); rfAudio.begin(); pinMode(talkButton, INPUT); //sets interrupt to check for button talk abutton press attachInterrupt(digitalPinToInterrupt(talkButton), talk, CHANGE); //sets the default state for each module to receiver rfAudio.receive(); } //void talk() //Called in response to interrupt. Checks the state of the button. //If the button is pressed (and held) enters transmit mode to send //audio. If button is release, enters receive mode to listen. void talk() { if (digitalRead(talkButton)) rfAudio.transmit(); else rfAudio.receive(); } void loop() { } Video microcontroller-projects/diy-hand-gesture-controlled-robotic-arm-using-arduino-nano

Hand Gesture Controlled Robotic Arm using Arduino Nano

using Arduino Nano, MPU6050 Gyroscope and flex sensor. that we built earlier using Arduino. Before going into detail, first, let’s learn about the MPU6050 sensor and flex sensor.

MPU6050 Gyroscopic & Accelerometer Sensor

and also built a few projects using it like- Self Balancing robot, Arduino Digital Protractor, and Arduino Inclinometer. Communication:I2Cprotocol with configurableI2CAddress Input Power Supply:3-5V Built-in 16-bit ADC provides high accuracy Built-inDMPprovides high computational power Can be used to interface with otherI2Cdevices like a magnetometer In-built temperature sensor
PinUsage
VccProvides power for the module, can be +3V to +5V. Typically +5V is used
GroundConnected to Ground of system
Serial Clock (SCL)Used for providing clock pulse for I2C Communication
Serial Data (SDA)Used for transferring Data through I2C communication
Auxiliary Serial Data (XDA)Can be used to interface other I2C modules with MPU6050
Auxiliary Serial Clock (XCL)Can be used to interface other I2C modules with MPU6050
AD0If more than one MPU6050 is used a single MCU, then this pin can be used to vary the address
Interrupt (INT)Interrupt pin to indicate that data is available for MCU to read

Flex Sensor

In this Gesture controlled Robotic Arm, a flex sensor is used to control the gripper of the robotic arm. When the flex sensor on the hand glove is bent, the servo motor attached to the gripper rotates and the gripper opens. like a game controller, Tone generator, etc.

Getting ready the 3D printed Robotic ARM:

The complete procedure for making the 3D printed robotic arm and the assembling detail with video is present in theThingiverselink, which is shared above. Above is the image of my 3D printed Robotic Arm after assembling with 4 Servo Motors.

Components Required:

Arduino Nano Flex Sensor 10kResistor MPU6050 Hand Gloves Connecting Wires Breadboard

Circuit Diagram:

VCC+5V
GNDGND
SDAA4
SCLA5
D2Servo 1 Orange (PWMPin)-
D3Servo 2 Orange (PWMPin)-
D4Servo 3 Orange (PWMPin)-
D5Servo 4 Orange (PWMPin)-
GNDServo 1,2,3,4 Brown (GNDPin)GND
-Servo 1,2,3,4 Red (+5V Pin)+5V
contains two pins. It doesn’t contain polarized terminals. So the pin one P1 is connected to the ArduinoNano’sAnalog Pin A0 with a pull-up resistor of10kand the pin two P2 is grounded to Arduino.

Mounting MPU6050 & Flex Sensor to Gloves

looks like the below image:

Programming Arduino Nano for Robotic Arm

is given at the end of this tutorial. Here a few important lines of code are explained. for controlling servo motor. #include<Wire.h> #include<Servo.h> 2. Next, the objects for the class servo is declared. As we use four servo motors, four objects such as servo_1, servo_2, servo_3, servo_4 are created. Servo servo_1; Servo servo_2; Servo servo_3; Servo servo_4; 3. Next, theI2Caddress of MPU6050 & the variables to be used is declared. const int MPU_addr=0x68; //MPU6050 I2C Address int16_t axis_X,axis_Y,axis_Z; int minVal=265; int maxVal=402; double x; double y; double z; Serial.begin(9600); AndI2Ccommunication between the Arduino Nano & MPU6050 is established: Wire.begin(); //Initilize I2C Communication Wire.beginTransmission(MPU_addr); //Start communication with MPU6050 Wire.write(0x6B); //Writes to Register 6B Wire.write(0); //Writes 0 into 6B Register to Reset Wire.endTransmission(true); //Ends I2C transmission Also, fourPWMpins are defined for servo motor connections. servo_1.attach(2); // Forward/Reverse_Motor servo_2.attach(3); // Up/Down_Motor servo_3.attach(4); // Gripper_Motor servo_4.attach(5); // Left/Right_Motor function, again establishI2Cconnection between the MPU6050 and Arduino Nano and then start to read the X, Y, Z-Axis data from the register of MPU6050 and store them in corresponding variables. Wire.beginTransmission(MPU_addr); Wire.write(0x3B); //Start with regsiter 0x3B Wire.endTransmission(false); Wire.requestFrom(MPU_addr,14,true); //Read 14 Registers axis_X=Wire.read()<<8|Wire.read(); axis_Y=Wire.read()<<8|Wire.read(); axis_Z=Wire.read()<<8|Wire.read(); After that, map the min and max value of the axis data from the MPU6050 sensor in the range of -90 to 90. int xAng = map(axis_X,minVal,maxVal,-90,90); int yAng = map(axis_Y,minVal,maxVal,-90,90); int zAng = map(axis_Z,minVal,maxVal,-90,90); Then use the following formula to calculate the x, y, z values in terms of 0 to 360. x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI); y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI); z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI); Then read the flex sensor Analog output data at the ArduinoNano’sA0 pin and according to the digital value of the flex sensor set the servo angle of the gripper. So if the flex sensor data is greater than 750 the servo motor angle of the gripper is 0 degree and if less than 750 it is 180 degrees. int gripper; int flex_sensorip = analogRead(A0); if(flex_sensorip > 750) { gripper = 0; } else { gripper = 180; } servo_3.write(gripper); is mapped in terms of 0 to 90 degrees for the servo motor’s Forward/Reverse motion the Robotic arm. if(x >=0 && x <= 60) { int mov1 = map(x,0,60,0,90); Serial.print("Movement in F/R = "); Serial.print(mov1); Serial.println((char)176); servo_1.write(mov1); } is mapped in terms of 0 to 90 degrees for the servo motor’s UP/DOWN motion Robotic arm. else if(x >=300 && x <= 360) { int mov2 = map(x,360,250,0,90); Serial.print("Movement in Up/Down = "); Serial.print(mov2); Serial.println((char)176); servo_2.write(mov2); } is mapped in terms of 90 to 180 degrees for the servo motor’s Left Movement of the Robotic arm. if(y >=0 && y <= 60) { int mov3 = map(y,0,60,90,180); Serial.print("Movement in Left = "); Serial.print(mov3); Serial.println((char)176); servo_4.write(mov3); } is mapped in terms of 0 to 90 degrees for the servo motor’s Right Movement of the Robotic arm. else if(y >=300 && y <= 360) { int mov3 = map(y,360,300,90,0); Serial.print("Movement in Right = "); Serial.print(mov3); Serial.println((char)176); servo_4.write(mov3); }

Working of Gesture controlled Robotic Arm using Arduino

Finally, upload the code to Arduino Nano and wear the hand glove mounted with the MPU6050 & Flex Sensor. 1. Now move the hand down to move the robotic arm forward and move up to move the robotic arm up. 2. Then tilt the hand left or right to turn the robotic arm left or right. 3. Bend the flex cable attached with the hand glove’s finger to open the gripper and then release it to close it. Code //Code for Gesture Controlled Robotic ARM (Arduino Nano & MPU6050) //Circuit Digest #include<Wire.h> //I2C Wire Library #include<Servo.h> //Servo Motor Library Servo servo_1; Servo servo_2; Servo servo_3; Servo servo_4; const int MPU_addr=0x68; //MPU6050 I2C Address int16_t axis_X,axis_Y,axis_Z; int minVal=265; int maxVal=402; double x; double y; double z; void setup() { Serial.begin(9600); Wire.begin(); //Initilize I2C Communication Wire.beginTransmission(MPU_addr); //Start communication with MPU6050 Wire.write(0x6B); //Writes to Register 6B Wire.write(0); //Writes 0 into 6B Register to Reset Wire.endTransmission(true); //Ends I2C transmission servo_1.attach(2); // Forward/Reverse_Motor servo_2.attach(3); // Up/Down_Motor servo_3.attach(4); // Gripper_Motor servo_4.attach(5); // Left/Right_Motor } void loop() { Wire.beginTransmission(MPU_addr); Wire.write(0x3B); //Start with regsiter 0x3B Wire.endTransmission(false); Wire.requestFrom(MPU_addr,14,true); //Read 14 Registers axis_X=Wire.read()<<8|Wire.read(); //Reads the MPU6050 X,Y,Z AXIS Value axis_Y=Wire.read()<<8|Wire.read(); axis_Z=Wire.read()<<8|Wire.read(); int xAng = map(axis_X,minVal,maxVal,-90,90); // Maps axis values in terms of -90 to +90 int yAng = map(axis_Y,minVal,maxVal,-90,90); int zAng = map(axis_Z,minVal,maxVal,-90,90); x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI); //Formula to convert into degree y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI); z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI); int gripper; int flex_sensorip = analogRead(A0); //Reads flex sensor output if(flex_sensorip > 750) { gripper = 0; } else { gripper = 180; } servo_3.write(gripper); //Writes gripper value to 3rd servo motor if(x >=0 && x <= 60) { int mov1 = map(x,0,60,0,90); Serial.print("Movement in F/R = "); Serial.print(mov1); Serial.println((char)176); servo_1.write(mov1); } else if(x >=300 && x <= 360) { int mov2 = map(x,360,250,0,180); Serial.print("Movement in Up/Down = "); Serial.print(mov2); Serial.println((char)176); servo_2.write(mov2); } if(y >=0 && y <= 60) { int mov3 = map(y,0,60,90,180); Serial.print("Movement in Left = "); Serial.print(mov3); Serial.println((char)176); servo_4.write(mov3); } else if(y >=300 && y <= 360) { int mov3 = map(y,360,300,90,0); Serial.print("Movement in Right = "); Serial.print(mov3); Serial.println((char)176); servo_4.write(mov3); } } Video microcontroller-projects/build-your-own-compact-pulse-oximeter-sensor-circuit

Compact Arduino Based Pulse Oximeter Sensor Circuit

that we build earlier.

MAX30100 Sensor

Thus, this module has two integrated functions, Pulse rate monitoring and provides oxygen saturation level of the blood in a non-invasive form. the LED pulses. The LED current is configurable from 0 to 50mA. The image given below showsthe MAX30100 sensor. The above sensor module works with the 1.8V to the 5.5V range. The pull-up resistors for the I2C pins are included in Below is the image of theOLEDDisplay. the module.

OLED Display

Components Required to Build Arduino Based Pulse Oximeter Circuit

Arduino Nano 2 pcs ᾠ4.7k resistor for I2C pull-up MAX30100 Sensor OLED Display SSD1306 based 128x32 Resolution 5V adequate power supply unit with the rated current of at least 300mA

Schematic of the OximeterCircuit

with the SDA and SCL pins. Both pins are using a pull-up resistor of 4.7k value.

Code explanation

for the display driver, and Fonts/FreeSerif9pt7b.h for the front. Those libraries are included at the beginning of the code. #include <Wire.h> #include "MAX30100_PulseOximeter.h" #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Fonts/FreeSerif9pt7b.h> This has to be the exact value of the OLED Display resolution. #define ENABLE_MAX30100 1 #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 //64 // OLED display height, in pixels A callback function is defined when the pulse is detected by the sensor which is available as the function given. void onBeatDetected() { Serial.println("Beat!"); heart_beat(&xPos); } Activating the display driver on the I2C line Clearing the display, setting the text size, text color, and setting up the cursor position Printing the Pulse Oximeter Setting up the Heartbeat animation location Initializing the MAX30100 Setting up the cursor position for the heartbeat and spo2 information. // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever } display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(20, 18); display.print("Pulse OxiMeter"); int temp1 = 0; int temp2 = 40; int temp3 = 80; heart_beat(&temp1); heart_beat(&temp2); heart_beat(&temp3); xPos = 0; #if ENABLE_MAX30100 // Initialize the PulseOximeter instance // Failures are generally due to an improper I2C wiring, missing power supply // or wrong target chip if (!pox.begin()) { Serial.println("FAILED"); for (;;); } else { Serial.println("SUCCESS"); } pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA); // Register a callback for the beat detection pox.setOnBeatDetectedCallback(onBeatDetected); By calling this function on the loop section, we can get the updated value from the sensor. pox.getHeartRate(); and pox.getSpO2();

Arduino Based Pulse Oximeter Circuit Testing

The circuit is made in a small compact Vero board. The data is perfectly displayed on the display. Without any data, the screen looks like this. As we can see in the below image, the SPO2 level is showing 97% and the heartbeat is showing 82 bits per minute when measured and the animation is also changed. Code /* File Name: pulse-oxymeter.ino Created on: 28-Jan-2021 Author: Noyel Seth (noyelseth@gmail.com) */ #include <Wire.h> #include "MAX30100_PulseOximeter.h" #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Fonts/FreeSerif9pt7b.h> #define ENABLE_MAX30100 1 #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 //64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) // The pins for I2C are defined by the Wire-library. // On an arduino UNO: A4(SDA), A5(SCL) // On an arduino MEGA 2560: 20(SDA), 21(SCL) // On an arduino LEONARDO: 2(SDA), 3(SCL), ... #define OLED_RESET -1 // 4 // Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3c ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #if ENABLE_MAX30100 #define REPORTING_PERIOD_MS 5000 // PulseOximeter is the higher level interface to the sensor // it offers: // * beat detection reporting // * heart rate calculation // * SpO2 (oxidation level) calculation PulseOximeter pox; #endif uint32_t tsLastReport = 0; int xPos = 0; // Callback (registered below) fired when a pulse is detected void onBeatDetected() { Serial.println("Beat!"); heart_beat(&xPos); } void setup() { Serial.begin(115200); Serial.println("SSD1306 128x64 OLED TEST"); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever } // Show initial display buffer contents on the screen -- // the library initializes this with an Adafruit splash screen. //display.display(); display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(20, 18); // Display static text display.print("Pulse OxiMeter"); int temp1 = 0; int temp2 = 40; int temp3 = 80; heart_beat(&temp1); heart_beat(&temp2); heart_beat(&temp3); xPos = 0; display.display(); delay(2000); // Pause for 2 seconds display.cp437(true); display.clearDisplay(); Serial.print("Initializing pulse oximeter.."); #if ENABLE_MAX30100 // Initialize the PulseOximeter instance // Failures are generally due to an improper I2C wiring, missing power supply // or wrong target chip if (!pox.begin()) { Serial.println("FAILED"); for (;;); } else { Serial.println("SUCCESS"); } // The default current for the IR LED is 50mA and it could be changed // by uncommenting the following line. Check MAX30100_Registers.h for all the // available options. pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA); // Register a callback for the beat detection pox.setOnBeatDetectedCallback(onBeatDetected); display_data(0, 0); #endif } void loop() { #if ENABLE_MAX30100 // Make sure to call update as fast as possible pox.update(); int bpm = 0; int spo2 = 0; // Asynchronously dump heart rate and oxidation levels to the serial // For both, a value of 0 means "invalid" if (millis() - tsLastReport > REPORTING_PERIOD_MS) { //Serial.print("Heart rate:"); bpm = pox.getHeartRate(); spo2 = pox.getSpO2(); Serial.println(bpm); //Serial.print("bpm / SpO2:"); Serial.println(spo2); //Serial.println("%"); tsLastReport = millis(); display_data(bpm, spo2); } #endif drawLine(&xPos); } void display_data(int bpm, int spo2) { display.fillRect(0, 18, 127, 15, SSD1306_BLACK); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 18); // Display static text display.print("PRbpm "); display.print(bpm); display.display(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(64, 18); // Display static text display.print("%Sp02 "); display.println(spo2); display.display(); } void drawLine(int *x_pos) { // Draw a single pixel in white display.drawPixel(*x_pos, 8, SSD1306_WHITE); display.drawPixel((*x_pos)++, 8, SSD1306_WHITE); display.drawPixel((*x_pos)++, 8, SSD1306_WHITE); display.drawPixel((*x_pos)++, 8, SSD1306_WHITE); display.drawPixel((*x_pos), 8, BLACK); // ----- //Serial.println(*x_pos); display.fillRect(*x_pos, 0, 31, 16, SSD1306_BLACK); display.display(); delay(1); if (*x_pos >= SCREEN_WIDTH) { *x_pos = 0; } } void heart_beat(int *x_pos) { /************************************************/ //display.clearDisplay(); display.fillRect(*x_pos, 0, 30, 15, SSD1306_BLACK); // Draw a single pixel in white display.drawPixel(*x_pos + 0, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 1, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 2, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 3, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 4, 8, BLACK); // ----- //display.display(); //delay(1); display.drawPixel(*x_pos + 5, 7, SSD1306_WHITE); display.drawPixel(*x_pos + 6, 6, SSD1306_WHITE); display.drawPixel(*x_pos + 7, 7, SSD1306_WHITE); // .~. //display.display(); //delay(1); display.drawPixel(*x_pos + 8, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 9, 8, SSD1306_WHITE); // -- //display.display(); //delay(1); /******************************************/ display.drawPixel(*x_pos + 10, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 10, 9, SSD1306_WHITE); display.drawPixel(*x_pos + 11, 10, SSD1306_WHITE); display.drawPixel(*x_pos + 11, 11, SSD1306_WHITE); //display.display(); //delay(1); /******************************************/ display.drawPixel(*x_pos + 12, 10, SSD1306_WHITE); display.drawPixel(*x_pos + 12, 9, SSD1306_WHITE); display.drawPixel(*x_pos + 12, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 12, 7, SSD1306_WHITE); //display.display(); //delay(1); display.drawPixel(*x_pos + 13, 6, SSD1306_WHITE); display.drawPixel(*x_pos + 13, 5, SSD1306_WHITE); display.drawPixel(*x_pos + 13, 4, SSD1306_WHITE); display.drawPixel(*x_pos + 13, 3, SSD1306_WHITE); //display.display(); //delay(1); display.drawPixel(*x_pos + 14, 2, SSD1306_WHITE); display.drawPixel(*x_pos + 14, 1, SSD1306_WHITE); display.drawPixel(*x_pos + 14, 0, SSD1306_WHITE); display.drawPixel(*x_pos + 14, 0, SSD1306_WHITE); //display.display(); //delay(1); /******************************************/ display.drawPixel(*x_pos + 15, 0, SSD1306_WHITE); display.drawPixel(*x_pos + 15, 1, SSD1306_WHITE); display.drawPixel(*x_pos + 15, 2, SSD1306_WHITE); display.drawPixel(*x_pos + 15, 3, SSD1306_WHITE); //display.display(); //delay(1); display.drawPixel(*x_pos + 15, 4, SSD1306_WHITE); display.drawPixel(*x_pos + 15, 5, SSD1306_WHITE); display.drawPixel(*x_pos + 16, 6, SSD1306_WHITE); display.drawPixel(*x_pos + 16, 7, SSD1306_WHITE); //display.display(); //delay(1); display.drawPixel(*x_pos + 16, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 16, 9, SSD1306_WHITE); display.drawPixel(*x_pos + 16, 10, SSD1306_WHITE); display.drawPixel(*x_pos + 16, 11, SSD1306_WHITE); //display.display(); //delay(1); display.drawPixel(*x_pos + 17, 12, SSD1306_WHITE); display.drawPixel(*x_pos + 17, 13, SSD1306_WHITE); display.drawPixel(*x_pos + 17, 14, SSD1306_WHITE); display.drawPixel(*x_pos + 17, 15, SSD1306_WHITE); //display.display(); //delay(1); display.drawPixel(*x_pos + 18, 15, SSD1306_WHITE); display.drawPixel(*x_pos + 18, 14, SSD1306_WHITE); display.drawPixel(*x_pos + 18, 13, SSD1306_WHITE); display.drawPixel(*x_pos + 18, 12, SSD1306_WHITE); //display.display(); //delay(1); display.drawPixel(*x_pos + 19, 11, SSD1306_WHITE); display.drawPixel(*x_pos + 19, 10, SSD1306_WHITE); display.drawPixel(*x_pos + 19, 9, SSD1306_WHITE); display.drawPixel(*x_pos + 19, 8, SSD1306_WHITE); //display.display(); //delay(1); /****************************************************/ display.drawPixel(*x_pos + 20, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 21, 8, SSD1306_WHITE); //display.display(); //delay(1); /****************************************************/ display.drawPixel(*x_pos + 22, 7, SSD1306_WHITE); display.drawPixel(*x_pos + 23, 6, SSD1306_WHITE); display.drawPixel(*x_pos + 24, 6, SSD1306_WHITE); display.drawPixel(*x_pos + 25, 7, SSD1306_WHITE) //display.display(); //delay(1); /************************************************/ display.drawPixel(*x_pos + 26, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 27, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 28, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 29, 8, SSD1306_WHITE); display.drawPixel(*x_pos + 30, 8, SSD1306_WHITE); // ----- *x_pos = *x_pos + 30; display.display(); delay(1); } Video microcontroller-projects/diy-handheld-game-console-using-arduino-pro-micro-and-arduboy

DIY Handheld Game Console using Arduino Pro Micro and Arduboy

is an 8-bit, credit-card-sized programmable gaming system inspired by Nintendo Gameboy. Arduboy is a game development system based on the popular open-source Arduino platform. It is really easy to learn, share, and play, allowing us to learn to code and create our games. The original Arduboy game package is based on an ATmega32U4 microcontroller and 128x64 Pixels serial OLED display. So, to build this project you should have an ATmega32u4-based Arduino microcontroller and a 6-pin SPI Based OLED display. to fabricate the PCB boards for this project. NextPCB is an experienced PCB manufacturer specialized in the PCB manufacturing and assembly industry for more than 15 years. They provide high-quality industry-standard PCB with a very quick turnaround time, as low as 24 hours. They can also provide other turnkey solutions like component sourcing, PCB prototyping, quality testing, etc. We will explain more on how to use NextPCB later in this article, but for now, let’s discuss the design and working of our Handheld Game Console.

Components Required for Handheld Game Console

1x Arduino Pro Micro (5V) 1x OLED Display (SPI) 6x Tactile Push Button 1x Buzzer 1x 7805 Voltage Regulator 1x 4mm SPDT Slide Switch 2x 18650 Cell 1x 18650 Double Cell Battery Holder

Circuit Diagram for Arduino Handheld Game Console

is shown below. As this is a clone board, we used the same components as the original board. The schematic was drawn using EasyEDA. The circuit consists of an Arduino Pro Micro, SPI OLED Display Module, voltage regulator, and some push buttons. This complete setup is powered by two 18650 cells connected in series. Output voltage from these cells will be around 7.4 so a 7805-voltage regulator is used to supply regulated 5V to Arduino pro micro and other modules. The complete connections are as follows:
VccVcc
GNDGND
D15SCL
D16SDA
D4DC
D2RES
A0UP
A3Down
A1Right
A2Left
D7A
D8B
D5Positive
D6GND

Designing a PCB Arduboy

If you want to skip the design processes, you can also download the Gerber file of this Handheld Game Console project using the link below: is easy; simply follow the steps given below. sign up if this is your first time. Then, in the next window click on ‘Quote nowᾮ Now in the next window, upload the Gerber file, and fill out the other important details like dimensions of your PCB, the number of layers, and the number of PCBs you require. In the next step, you have to select the build time, shipping country, and shipping method. The final cost of the PCB depends on the shipping country and shipping method. The final step is Checkout. To make sure the process is smooth; NextPCB first verifies all the details and Gerber file before proceeding with the payment. This way, you can be sure that your PCB is fabrication-friendly and will reach you as committed.

Assembling our Handheld Game Console Board

After a few days, we received our PCB from NextPCB in a neat package and as you can see below, the PCB quality was good as always. The top layer and bottom layer were seamlessly done with proper visa and track spacing. The top layer and the bottom layer of the board are shown below. After making sure that the tracks and footprints were correct, I proceeded with assembling the PCB. The completely soldered board looked like as shown in the image below:

Programming Arduino Pro Micro for Playing Arduboy-Homemade Games

on Arduino IDE. This package includes all Arduboy libraries with support for alternate displays and wiring. Click on the Arduboy Homemade package and click the Install button. menu and make the selection as follows: Arduboy Cathy3K Arduboy optimized core After that, select the port to which Arduino micro is connected and hit upload.

Testing our Arduino based Gameboy

After uploading the code plug in the Arduino and 18650 cells and you should see the OLED display start up a demo of the game. Push button A is used to start and stop the game while Push button B is used for Attack. I hope you enjoyed building this project. A complete working video is given below. If you have any questions, please leave them in the comment section. Code #include "Globals.h" #include "Draw.h" #include "Sprites.h" #include "Items.h" itemsManager iM; #include "Animations.h" animationManager aM; #include "Player.h" playerTank pT; #include "Projectiles.h" projectileManager pM; #include "Enemys.h" enemyManager eM; #include "Map.h" mapManager mM; #include "Spawn.h" spawnManager sM; #include "Buttons.h" #include "Checks.h" void setup() { #ifdef USE_SERIAL Serial.begin(57600); Serial.println(F("MicroTank!")); #endif #ifdef ESP8266 ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, false, false); // this function must be called or the esp will crash with the first call arduboy.setExternalButtonsHandler(getButtons); #endif arduboy.begin(); arduboy.setFrameRate(GAME_FRAMES); // some start tone sound.tone(200, 200, 300, 200); arduboy.fillScreen(WHITE); sM.init(); pT.init(); //eM.add(100, 30, ENEMY_MINE, 0); //eM.add(100, 30, ENEMY_ROCKET, 0); //arduboy.display(); //delay(60000); } void playMode() { checkItemsCatch(); checkItemsSpawn(); checkEnemyChrush(); checkProjectiles(); mM.update(); sM.update(); pM.update(); iM.update(); eM.update(); aM.update(); pT.update(); checkSlowmo(); checkSpecialAttack(); } void menuMode() { mM.drawMap(); pT.drawTankShop(); } void playGame() { #ifdef DEBUG_FRAME_TIME uint32_t start = millis(); #endif prepareThings(); updateGameButtons(); if (isPlayMode) { playMode(); } else { menuMode(); } // needs to be after the drawMap pT.drawCornerInfo(); #ifdef DEBUG_FRAME_TIME // pirnt time for a frame to screen arduboy.fillRect(0, 0, 26, 7, BLACK); //drawNumbers(0, 0, millis() - start); //drawNumbers(0, 0, eM.count()); //drawNumbers(0, 0, sM.difficulty); #endif } void loop() { if (!(arduboy.nextFrame())) return; arduboy.pollButtons(); arduboy.fillScreen(WHITE); if (isStartAnimation) { playAnimation(); } else { playGame(); } arduboy.display(); gameFrames++; } Video microcontroller-projects/arduino-usb-key-lets-you-login-to-windows-twitter-gmail-with-just-a-push-button

Arduino USB key lets you Login into Windows, Twitter, and Gmail with just a Push of a Button

Are you fed up with manually logging in to your windows or social media accounts? Wouldn’t it be nice to have a pocket-sized device which when connected to a computer would automatically login into all your accounts? if you are looking for something similar.

Components Required for Automatic Login System

ATtiny85 IC USB A-type Plug Male 3 Resistors (2×47 & 1×1 K) 1×IN5819 Diode 8-Pin IC Base 4× Push Buttons 4× 10K Resistors (Pull-Up Resistors) Perf Board Connecting Wires

Automatic Login System Circuit Diagram

using Push Button is given below: The above circuit can be divided into two parts. The first one is USB, and the second one is Push Buttons. Data pins of USB are connected to PB3 and PB4 of ATtiny85 through 47-ohm resistors. R1 is a pull-up resistor that is connected between Vcc and PB3 pins of IC. Three push buttons are connected to PB0, PB1, PB2 pins of ATtiny85. All three push buttons are pulled high using 10K pull-up resistors. After soldering all the components on the perf board, it will look something like below:

Installing Digispark Drivers

Once the drivers are successfully installed, Plug in your ATtiny85 board to the laptop. Now go to Device Manager on your Windows and your device will be listed under “libusb-win32 devicesᾠas “Digispark Boot-loaderᾮ If you can’t find ‘libusb-win32 devicesᾠon device manager, then go to View and click on ‘Show hidden Devices.ᾍ

Setting up Arduino IDE for Attiny85

To program the ATtiny85 Board with Arduino IDE, first, we need to add the Digispark board Support to Arduino IDE. For that go to File > Preferences and add the below link in the Additional Boards Manager URLs and click ‘OK.ᾍ and search for ‘Digistump AVRᾠand install the latest version.

Programming ATtiny85 for Automatic Login System

The complete code is given at the end of the document; here we are explaining some important commands of the code. So, start the code by including the ‘DigiKeyboard.hᾠlibrary. The DigiKeyboard library enables the ATtiny85 to send keystrokes to an attached computer through their micro’s native USB port. #include "DigiKeyboard.h" Then define the ATtiny85 IC pins where push buttons are connected. Here we named these buttons Facebook, Windows, and Gmail as these push buttons will be used to login to Facebook, Windows, and Gmail. const int facebook = 2; const int twitter = 1; const int gmail = 0; for debugging. void setup() { pinMode (facebook, INPUT); pinMode (twitter, INPUT); pinMode (gmail, INPUT); } function to check if a push button is in a low state. void loop() { fac_state = digitalRead(facebook); twit_state = digitalRead(twitter); gmail_state = digitalRead(gmail); buttons(); } function. This is the function where we issue commands to log in to different platforms. Here we have three different conditions for three push buttons. So if the push button connected to PB2 of ATtiny85 is Low then it sends all the keystrokes that are used to login to Facebook. if (fac_state == LOW){ DigiKeyboard.delay(2000); DigiKeyboard.sendKeyStroke(0); DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT); DigiKeyboard.delay(600); DigiKeyboard.print("https://www.facebook.com/login/device-based/regular/login/?login_attempt=1"); DigiKeyboard.sendKeyStroke(KEY_ENTER); DigiKeyboard.delay(5000); DigiKeyboard.print("Your Password"); DigiKeyboard.sendKeyStroke(KEY_ENTER); DigiKeyboard.delay(5000); } A similar process is followed for Gmail and Windows.

Testing our Automatic Log in Device

Once you have done with Hardware and code, now what is left to do is upload the code on ATtiny85. So, plug in the board and upload the code. Now you can log in to your favourite website by just pressing a button. Uploading code on ATtiny85 isn’t similar to Arduino or ESP. To upload the code first hit the upload button and wait until Arduino IDE displays a message saying “Plugin device nowᾠand then plug in the ATtiny85. This is how you can use ATtiny85 as a Hardware security key. A working video and complete code is given below. Code #include "DigiKeyboard.h" const int windows = 2; //const int facebook = 2; const int twitter = 1; const int gmail = 0; int win_state, fac_state, twit_state, gmail_state; void setup() { // don't need to set anything up to use DigiKeyboard pinMode (windows, INPUT); //pinMode (facebook, INPUT); pinMode (twitter, INPUT); pinMode (gmail, INPUT); } void loop() { win_state = digitalRead(windows); //fac_state = digitalRead(facebook); twit_state = digitalRead(twitter); gmail_state = digitalRead(gmail); DigiKeyboard.print(twit_state); buttons(); } void buttons() { //Facebook /*if (fac_state == LOW){ DigiKeyboard.delay(2000); DigiKeyboard.sendKeyStroke(0); DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT); DigiKeyboard.delay(600); DigiKeyboard.print("https://www.facebook.com/login/device-based/regular/login/?login_attempt=1"); DigiKeyboard.sendKeyStroke(KEY_ENTER); DigiKeyboard.delay(5000); DigiKeyboard.print("Facebook Password"); DigiKeyboard.sendKeyStroke(KEY_ENTER); DigiKeyboard.delay(5000); }*/ //Twitter if (twit_state == LOW){ DigiKeyboard.delay(2000); DigiKeyboard.sendKeyStroke(0); DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT); DigiKeyboard.delay(600); DigiKeyboard.print("https://twitter.com/login"); DigiKeyboard.sendKeyStroke(KEY_ENTER); DigiKeyboard.delay(5000); DigiKeyboard.print("Twitter Email"); DigiKeyboard.delay(1000); DigiKeyboard.write('\t'); DigiKeyboard.print("Twitter Password"); DigiKeyboard.sendKeyStroke(KEY_ENTER); DigiKeyboard.delay(5000); } //Gmail if (gmail_state == LOW){ DigiKeyboard.delay(2000); DigiKeyboard.sendKeyStroke(0); DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT); DigiKeyboard.delay(600); DigiKeyboard.print("https://accounts.google.com/AccountChooser/identifier?service=mail&conti..."); DigiKeyboard.sendKeyStroke(KEY_ENTER); DigiKeyboard.delay(5000); DigiKeyboard.print("Email ID"); DigiKeyboard.sendKeyStroke(KEY_ENTER); DigiKeyboard.delay(4000); DigiKeyboard.print("Email ID Password"); DigiKeyboard.sendKeyStroke(KEY_ENTER); DigiKeyboard.delay(5000); } //Windows if (win_state == LOW){ //DigiKeyboard.print("Windows"); DigiKeyboard.update(); //Get the Keboard input ready DigiKeyboard.sendKeyStroke(0); // Send a null keystroke DigiKeyboard.delay(3000); DigiKeyboard.sendKeyStroke(KEY_ENTER); DigiKeyboard.delay(2000); DigiKeyboard.print("1231"); DigiKeyboard.delay(2000); } } Video microcontroller-projects/portable-weighing-machine-using-arduino-and-hx711-weight-sensor-load-cell

Portable Arduino Weighing Machine with Set Weight Option for Retail Packing

, which can measure weights up to 10kg. is perfect for local stores, where they pack items in bulk quantity. Like commercial products, our weight scale will have a zero button that zeroes out the scale. Also, It has an option to set weight for measurement, when the measuring weight reaches the set weight, a buzzer beeps fast and stops when the set weight equals the measuring weight. This way, the user can pack it just by hearing the sound and would not have to look at the display. As this is a very simple project, we will be building this very easily using components like Arduino and strain gauge load cell. So, without further delay, let's get right into it. using the popular HX711 load cell amplifier module. So, do check that out if that is your requirement.

Arduino Weighing Machine Working

As you can see, one side is marked with ten kilograms. Also, you can notice some sort of white protective glue over the load cell and four different colors of wires are coming out, will uncover the secret underneath the white protective glue and the function of these four-color wires later in the article. because of the giant hole in the middle. When a load is placed on the load side of the load cell, the top part will suffer tension, and the bottom part will suffer compression. Thatis why the aluminum bar bents downward on the left side. If we measure this deformation, we can measure the force that was applied to the aluminum block and that's exactly what we will do. A strain gauge is a component that is used to measure strain. If we take a closer look at this component, we can see two connection pads, and then we have a conductive wire pattern with repetitive deflections. This conductive wire has a defined resistance. When we bend it, the resistance value will change? So, one side of the strain gauge is mounted and fixed in a place, if we place a weight on the other side of the aluminum bar, this will force the strain gauge to bend, which will cause a change in resistance. How this happens actually? The conductive pattern of the strain gauge is made out of copper, this wire will have a certain area and length, so these two units will give the resistance of the wire. The resistance of a wire opposes the flow of current. Now it's obvious that if the area of this wire gets smaller, fewer electrons could pass meaning a lower current. Now if we increase the area, it will increase the resistance of a conductor. If some force is applied to this wire, this will stretch the area and it will get smaller at the same time, resistance increases. But this resistance variation is very low. If we stretch the strain gauge, the resistance will increase and if we compress it, the resistance will get lower. To measure the force, we need to measure the resistance. Measuring the resistance directly is not always practical, because the change is very small. So instead of measuring resistance, we can measure voltages easily. So, in this case, we need to convert the gauge output from resistance values to voltage values. , you can check that out if you want to know more about the topic). When the strain gauge changes its resistance, it will unbalance the bridge, and the voltage will also change. So, this is how the Wheatstone bridge converts resistance variations to voltage values. HX711 is a 24-bit Differential ADC, in this way, we could measure very small voltage changes. it will give values from 0 to 2 exponential 24.

Components Required for Arduino Based Weighing Machine

To make this project as simple as possible, we have used very generic components that you can find in any local hobby store. The image below will give you an idea about the components. Furthermore, we have the Bill of Materials (BOM) listed below. Load cell (We are using a 10 kg load cell) HX 711 amplifier module Arduino Nano I2C LCD 16X2 ᾠI2C Compatible 1k resistor -2 Nos LEDs -2Nos Buzzer Common PCB 7.4V battery (if you want it portable) LM7805 voltage regulator

Arduino Based Weighing Machine - Circuit Diagram

If you don't want it as portable, you can directly power the Arduino using a USB cable.

Making the Circuit on a Dotted Perfboard

We have soldered all the components on a common dotted perfboard. We used female headers to solder the Arduino and ADC with the circuit board, also we have used wires to connect all the pushbuttons and LEDs. After all the soldering process is finished, we have made sure that proper 5V is coming out of the LM7805. Finally, we have put a switch to power on/off the circuit. Once we were all finished, it looked like the image below.

Building an Enclosure for Arduino Based Weighing Machine

As you can see, the load cell has some screw threads, so we could mount it on a base plate. We will be using a PVC board for the base of our scale, for that, we first cut 20*20 cm square and four 20*5 rectangles from the PVC board. Then using hard glue, we glued every piece and made a small enclosure. Remember, we didn't fix one side, because we need to place the pushbuttons, LEDs, and the LCD on it. Then we used a plastic board for the top of the scale. Before making this setup permanent, we need to make sure that we have sufficient space from the ground to the load cell, so it will be able to bend, so we placed screw and nuts in between the load cell and the base, also we added some plastic spacers in between the load cell and top part. we used a round plastic sheet as the top smart of balance. You can design with your ideas but remember to place the load cell-like as in the image.

Arduino Weighing Machine - Code

, after downloading the library, Install it into Arduino ide. Before uploading the code, place the balance on a stable plane surface. Then upload the code to Arduino and open the serial monitor. Then change the baud rate to 572600. Now monitor ask to take the weight, for thatwe need to press t and enter. Now, we need to place the known weight on the balance, in my case,that is 194gm. After placing the known weight, type weight on the serial monitor, and hit enter. Now, the serial monitor asks you whether you want to save the value in EEPROM or not, so type Y for choosing yes. Now we can see the weight on the serial monitor. The main code of this project, which we developedfrom the example sketch of the HX711 library. You can download the code of this project from below. In the coding section, first, we added all three libraries. The HX711 library is for taking the load cell values. EEPROM is the inbuilt library of Arduino ide, which is used to store values in EEPROM and the LiquidCrystal library is for the l2C LCD Module. #include <HX711_ADC.h> #include <EEPROM.h> #include <LiquidCrystal_I2C.h> function is for setting the Dout and clock pin. const int HX711_dout = 4; const int HX711_sck = 5; int tpin = 3; HX711_ADC LoadCell(HX711_dout, HX711_sck); const int calVal_eepromAdress = 0; long t; const int Up_buttonPin = 9; const int Down_buttonPin = 8; float buttonPushCounter = 0; float up_buttonState = 0; float up_lastButtonState = 0; float down_buttonState = 0; float down_lastButtonState = 0; In the setup section, first, we started the serial monitor, this is just for debugging only. Then we defined the pin modes, all push buttons are defined as input. With help of the Arduino PULL UP function, we set the pins to a logical high at normally. So, we don't want to use any external resistors for that. pinMode(tpin, INPUT_PULLUP); pinMode(6, OUTPUT); pinMode(12, OUTPUT); pinMode( Up_buttonPin , INPUT_PULLUP); pinMode( Down_buttonPin , INPUT_PULLUP); as welcome text, and after two seconds, it will clear and display the measuring weights. lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print("ARDUINO BALANCE"); lcd.setCursor(0, 1); lcd.print("let's measure"); delay(2000); lcd.clear(); address, we just retake that value. LoadCell.begin(); EEPROM.get(calVal_eepromAdress, calibrationValue); That explained in the last section. if (LoadCell.update()) newDataReady = true; if (newDataReady) { if (millis() > t + serialPrintInterval) { float i = LoadCell.getData(); lcd.setCursor(0, 0); lcd.print("set wei:"); lcd.setCursor(9, 0); lcd.print(buttonPushCounter); lcd.setCursor(14, 0); lcd.print("GM"); lcd.setCursor(0, 1); lcd.print("weight :"); lcd.setCursor(9, 1); lcd.print(i); lcd.setCursor(14, 1); lcd.print("GM"); of this weight scale is to bring the readings to zero. For example, if we have a bowl in which the things are loaded, then the net weight will be the weight of the bowl + the weight of the things. If we press the tare button with the bowl on the load cell before loading things, the weight of the basket will be negated and we can measure the weight of the things alone. if (digitalRead(tpin) == LOW) { LoadCell.tareNoDelay(); conditions, we have a total of three conditions. First, we calculate the difference between set weight and measuring weight, then stored that value in the variable k. float k = buttonPushCounter-i ; If the difference between set weight and measuring weight is greater than or equal to 50gms, the buzzer beeps with a 200-millisecond delay (slowly). if ( k >= 50 ) { digitalWrite (6, HIGH); delay(200); digitalWrite (6, LOW); delay(200); } If the difference between set weight and measuring weight is lower than 50 and greater than 1 gram, the buzzer beeps with a 50-millisecond delay (faster). if ( k < 50 && k > 1 ) { digitalWrite (6, HIGH); delay(50); digitalWrite (6, LOW); delay(50); } When the measuring weight equals or greater than the set value, this will turn on the green led and off the buzzer and red led. if(i>=buttonPushCounter) { digitalWrite (6, LOW); digitalWrite (12, HIGH); } We have two more void functions () for setting the set weight (for counting the button press). function of Arduinoif the pin is low that means the button is pressed and that will increment the value by 10gms. up_buttonState = digitalRead(Up_buttonPin); if (up_buttonState != up_lastButtonState) { if (up_buttonState == LOW) { bPress = true; buttonPushCounter = buttonPushCounter + 10; } Similarly, checkdown is for decreasing the set value by 10gms for each press. down_buttonState = digitalRead(Down_buttonPin); if (down_buttonState != down_lastButtonState) { if (down_buttonState == LOW) { bPress = true; buttonPushCounter = buttonPushCounter - 10; } This marks the end of the programming part. This Arduino based electronic scale is perfect for measuring the weights up to 10kg (we can increase this limit by using a higher rated loadcell). This is 99% accurate to original measurements. If you have any questions regarding this Arduino based LCD weight balance machine circuit, please post it in the comment section, thank you! Code #include <HX711_ADC.h> #include <EEPROM.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 2, 16); HX711_ADC LoadCell(HX711_dout, HX711_sck); const int HX711_dout = 4; //mcu > HX711 dout pin const int HX711_sck = 5; //mcu > HX711 sck pin int tpin = 3; const int calVal_eepromAdress = 0; long t; const int Up_buttonPin = 9; // the pin that the pushbutton is attached to const int Down_buttonPin = 8; float buttonPushCounter = 0; // counter for the number of button presses float up_buttonState = 0; // current state of the up button float up_lastButtonState = 0; // previous state of the up button float down_buttonState = 0; // current state of the up button float down_lastButtonState = 0; // previous state of the up button bool bPress = false; void setup() { Serial.begin(57600); delay(10); Serial.println(); Serial.println("Starting..."); pinMode(tpin, INPUT_PULLUP); pinMode(6, OUTPUT); pinMode(12, OUTPUT); pinMode( Up_buttonPin , INPUT_PULLUP); pinMode( Down_buttonPin , INPUT_PULLUP); lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print("ARDUINO BALANCE"); lcd.setCursor(0, 1); lcd.print("let's measure"); delay(2000); lcd.clear(); LoadCell.begin(); float calibrationValue; // calibration value (see example file "Calibration.ino") calibrationValue = 696.0; // uncomment this if you want to set the calibration value in the sketch #if defined(ESP8266)|| defined(ESP32) //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom #endif EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time boolean _tare = true; //set this to false if you don't want tare to be performed in the next step LoadCell.start(stabilizingtime, _tare); if (LoadCell.getTareTimeoutFlag()) { Serial.println("Timeout, check MCU>HX711 wiring and pin designations"); while (1); } else { LoadCell.setCalFactor(calibrationValue); // set calibration value (float) Serial.println("Startup is complete"); } } void loop() { static boolean newDataReady = 0; const int serialPrintInterval = 0; //increase value to slow down serial print activity // check for new data/start next conversion: if (LoadCell.update()) newDataReady = true; // get smoothed value from the dataset: if (newDataReady) { if (millis() > t + serialPrintInterval) { float i = LoadCell.getData(); Serial.print("Load_cell output val: "); Serial.println(i); newDataReady = 0; t = millis(); lcd.setCursor(0, 0); lcd.print("set wei:"); lcd.setCursor(9, 0); lcd.print(buttonPushCounter); lcd.setCursor(14, 0); lcd.print("GM"); lcd.setCursor(0, 1); lcd.print("weight :"); lcd.setCursor(9, 1); lcd.print(i); lcd.setCursor(14, 1); lcd.print("GM"); } } checkUp(); checkDown(); if (digitalRead(tpin) == LOW) { LoadCell.tareNoDelay(); } // check if last tare operation is complete: if (LoadCell.getTareStatus() == true) { lcd.clear(); lcd.print("Tare complete"); delay(1000); lcd.clear(); } float i = LoadCell.getData(); float k = buttonPushCounter - i; if ( k < 50 && k > 1 ) { digitalWrite (6, HIGH); delay(50); digitalWrite (6, LOW); delay(50); } if ( k >= 50 ) { digitalWrite (6, HIGH); delay(200); digitalWrite (6, LOW); delay(200); } if (i >= buttonPushCounter) { digitalWrite (6, LOW); digitalWrite (12, HIGH); } else { digitalWrite(12, LOW); } } void checkUp() { up_buttonState = digitalRead(Up_buttonPin); // compare the buttonState to its previous state if (up_buttonState != up_lastButtonState) { // if the state has changed, increment the counter if (up_buttonState == LOW) { bPress = true; // if the current state is HIGH then the button went from off to on: buttonPushCounter = buttonPushCounter + 10; } } // save the current state as the last state, for next time through the loop up_lastButtonState = up_buttonState; } void checkDown() { down_buttonState = digitalRead(Down_buttonPin); // compare the buttonState to its previous state if (down_buttonState != down_lastButtonState) { // if the state has changed, increment the counter if (down_buttonState == LOW) { bPress = true; buttonPushCounter = buttonPushCounter - 10; } } // save the current state as the last state, for next time through the loop down_lastButtonState = down_buttonState; } Video microcontroller-projects/how-to-measure-walter-level-using-jsn-sr-40t-waterproof-ultrasonic-sensor-with-arduino

How to Measure Water Level using JSN SR-40T Waterproof Ultrasonic Sensor

with Arduino and other microcontrollers for distance measurement and other applications. This sensor is easy to use and pretty inexpensive. But it has some downsides. One of them is that these sensors can’t be used in applications that involve water and harsh environments. works, what are its features and specifications and how to interface it with the Arduino Nano.

Components Required

Arduino Nano JSN SR-04T Waterproof Ultrasonic Sensor 16*2 LCD Display Breadboard Jumper Wires

JSN SR-04T Waterproof Ultrasonic Sensor

JSN-SR0T4 is a waterproof ultrasonic distance measurement sensor module that can provide 25cm-450cm non-contact distance measurements, with a ranging accuracy of up to 2mm. This sensor module comes in two separate parts, one being the transducer, which is the sensing element and the other being the control board. It is very similar to the ultrasonic sensors which are found in car bumpers. sensor module has an industrial-grade integrated ultrasonic sensing probe design, waterproof type, stable performance, and high precision. It can be used in horizontal ranging, obstacle avoidance, automated control, monitoring of objects and their movement, traffic control, security, and artificial intelligence, and other applications.
15VPositive supply pin of the sensor
2Trigto initialize measurement by sending ultrasonic waves.
3EchoOutput pin sensor. This pin goes high for a period that will be equal to the time taken for the ultrasonic wave to return to the sensor.
4GndThis pin is connected to the Ground of the system.
The JSN SR-04T sensor module is similar to HC-SR04, but it brings some improvements compared to HC-SR04: Unlike HC-SR04, JSN SR-04T doesn’t have the transducer soldered onto the PCB. Instead, it’s connected with a pretty long external cable (2.5 Meters) so, you can put the sensing element far away from all the control circuitry. The sensor itself is encased in a waterproof enclosure, which might be useful if you want to locate it outside in harsher environments. With all these advantages, ithas some disadvantages too. The minimum distance this sensor can measure is 20cm compared to the 2cm of the HC-SR04. The reason behind this is that JSN SR-04T has only one transducer. It uses the same transducer to both transmit and receive the signal so it needs time to switch from one mode toanother. This is why the JSN SR-04T sensor can't measure below 20cm but HC-SR04 can because it has a separate transmitter and receiver. Working voltage: DC 5V Static working current: 5mA Working current: 30mA Acoustic emission frequency:40KHz Operating Range: 25cm to 4.5m Cable Length: 2.5 meter

Interfacing JSN SR-04T with Arduino

is given below: That’s pretty much the wiring. Both modules are powered with GND and 5V, Trigger and Echo pins of ultrasonic sensor are connected to D2 and D3 of Arduino. Complete LCD connections are given in the table below.
VSSGND
VDD5V
VOPotentiometer
RSD12
RWGND
ED11
D4D4
D5D5
D6D6
D7D7
A5V
KGND
My hardware looked like this:

Programming Arduino for Waterproof Ultrasonic Sensor

Complete code for Interfacing Waterproof Ultrasonic Sensor JSN SR-04T to Arduino can be found at the end of the page. Here, I am explaining some important parts of the program. library. It is used for controlling the LCD module using an Arduino board with the help of built-in methods defined inside the library. This library can be used for both the 4-bit mode and 8-bit mode wiring of LCD. #include<LiquidCrystal.h> Then in the next line, define the pins of Arduino that are interfaced to LCD LiquidCrystal lcd(12, 11, 5, 6, 7, 8); Then define the trigger pin and echo for the ultrasonic sensor. We have connected the trigger pin to the D2 pin of Arduino and the echo pin to the D3 pin of the Arduino. #define ECHOPIN 3 #define TRIGPIN 2 function, define the trigger pin as an output and the echo pin as an Input and also start the serial communication at 9600 for showing the results on the serial monitor and initialize the interface to the LCD screen and specifies the dimensions. void setup() { Serial.begin(9600); lcd.begin(16, 2); pinMode(ECHOPIN,INPUT_PULLUP); pinMode(TRIGPIN, OUTPUT); digitalWrite(ECHOPIN, HIGH); } function to read the travel time and store that value into the variable “durationᾮ In the end, we will print the value of the distance on the Serial Monitor. void loop() { digitalWrite(TRIGPIN, LOW); delayMicroseconds(2); digitalWrite(TRIGPIN, HIGH); delayMicroseconds(15); digitalWrite(TRIGPIN, LOW); int distance = pulseIn(ECHOPIN, HIGH, 26000); distance=distance/58; Serial.print(distance);

Testing the Waterproof Ultrasonic Sensor JSN SR-04T

Once your code and hardware are ready, connect Arduino to the laptop and upload the code. After that, open the serial monitor at a baud rate of 9600, and put something in front of the sensor. Calculated distance will be displayed on LCD display. Complete working video and code are given below. If you have any queries regarding this project, drop them in the comment section below. Code #include<LiquidCrystal.h> LiquidCrystal lcd(12, 11, 4, 5, 6, 7); // sets the interfacing pins #define ECHOPIN 3 #define TRIGPIN 2 void setup() { Serial.begin(9600); lcd.begin(16, 2); // initializes the 16x2 LCD pinMode(ECHOPIN,INPUT_PULLUP); pinMode(TRIGPIN, OUTPUT); digitalWrite(ECHOPIN, HIGH); } void loop() { lcd.clear(); digitalWrite(TRIGPIN, LOW); delayMicroseconds(2); digitalWrite(TRIGPIN, HIGH); delayMicroseconds(15); digitalWrite(TRIGPIN, LOW); int distance1 = pulseIn(ECHOPIN, HIGH, 26000); int distance=distance1/58; Serial.print(distance); Serial.println(" cm"); lcd.setCursor(0,0); //sets the cursor at row 0 column 0 lcd.print("Water Level"); // prints 16x2 LCD MODULE lcd.setCursor(0,1); lcd.print(distance); delay(500); } Video microcontroller-projects/getting-started-with-arduino-cloud-iot-connect-esp8266-to-arduino-cloud-iot

Getting Started with Arduino Cloud IoT: Connect ESP8266 to Arduino Cloud IoT

enables users to collect, graph, and analyze their sensor data, trigger events, and fully control their devices. This way, users can automate their homes or businesses with ease, all in a single place. sensor data from the board to the cloud, and set up a switch that can control the LED connected to NodeMCU.

Arduino Cloud IoT ᾠKey Features and Limitations

Arduino Cloud IoT platform enables users to write code, compile and upload directly from their browser, connect their IoT devices, and build real-time dashboards. It automatically generates a sketch when setting up a new thing according to the variables defined. All the features of Arduino Cloud IoT are listed below: The Arduino Cloud IoT automatically generates a sketch according to the variables that the user defines while setting up a Thing, thus it removes barriers for users who are not familiar with coding and empowering makers of all ages and experiences. Using theArduino cloud IoT platform, you can write code, compile and upload directly from your browser, connect your IoT devices, and build real-time dashboards. So, you don’t need to move to Arduino IDE for programming the hardware. This enables users to access, check data, and control remote sensor monitoring from anywhere using accessible widgets. Arduino Cloud IoT can be integrated with Amazon Alexa, Google Sheets, IFTTT, and ZAPIER, which enables users to program and manage devices using voice, spreadsheets, databases, and automate alerts using webhooks. The platform also enables developers to create custom apps using the Arduino IoT API, with custom endpoint webhooks to be added for further flexibility. With all these features, Arduino Cloud IoT has some limitations too. One of them is that it only works with certain Arduino and ESP boards. All the supported boards are listed below:

Arduino Boards

Arduino NANO 33 IoT Arduino MKR Wi-Fi 1010 Arduino MKR WAN 1310 Arduino MKR WAN 1300 Arduino MKR NB 1500 Arduino MKR GSM 1400 Arduino MKR1000 Arduino Portenta H7 (M7 core) Arduino Nano RP2040 Connect

ESP and Other Boards

ESP8266 ESP32 Pelion Generic LoRa And using the Arduino Cloud IoT free plan, users can add only two devices and it provides a limited compilation time of 200 s/day. So, if you want to connect more than two devices you have to buy a premium plan. Currently,Arduino cloud IoT offers four different plans with different features and prices. All the plans are summarized in the below image:

Components Required for Connecting ESP8266 to Arduino Cloud IoT

NodeMCU ESP8266 DHT11 Sensor LED (5mm)

Circuit Diagram for Connecting ESP8266 to Arduino Cloud IoT

Circuit Diagram for sending DHT11 sensor data to the Arduino IoT cloud is given below. Connections are pretty simple. DHT11 sensor is powered through 5V and GND pin of NodeMCU. The data pin of DHT11 is connected to D0 of NodeMCU and the positive lead of LED is connected to the D7 pin of NodeMCU.

Setting Up the Arduino Cloud IoT

and create one. Once the account setup is complete, we will add a new device, i.e.NodeMCU to Arduino Cloud IoT. In the cloud, go to the "Devices" tab. Then, click on the "Add device" button. Then, click on "Set up a 3rd party device". In the next step, we need to select the development board that we are using. First, select ESP8266 in device type, and then choose the NodeMCU1.0 from the drop-down menu. Next, rename the device as per your project and click next. A window will pop up with the Device ID and Secret Key for that device. You can either note it down or click on the “download the PDFᾠto save the details on your local system. Please note that the secret key cannot be recovered. Then click on CONTINUE to add the device. After adding the device, the next step is to create a Thing. So go to the "Things" tab and click on ‘Create Thingᾮ Now, on the Things tab, we have three options to configure i.e., Variables, Device, and Network. First, we will link our device with our Thing. This can be done by clicking on the Link icon button in the "Device" section. This will open a window, where your recently created Device should be available to select. Once the device is linked, we need to add some variables that will be used in the code. Click on the "Add variable" button. This will open a window where you need to fill in variable information. Here, we will create three variables out of which, one will be used for LED, and two will be used for storing temperature and humidity values. first. The data type is int, permission is read-only and the update policy is on change. Once done, click on the "Add variable" button. Similarly, add ‘temperatureᾠand ‘humidityᾠvariables. The data type for these variables is float, the permission is read & write, and the update policy is on change. Now, in the next step, we need to enter the Wi-Fi credentials and the secret key is generated during the device configuration. For that click on the ‘Configureᾠbutton in the "Network Section". Enter the credentials and then click on ‘Save.ᾍ Step3: Now that we have added the device and the variables, we can move on to the next step, which is creating a dashboard. For that, go to the ‘Dashboardᾠtab and click on the ‘Build Dashboardᾠbutton. To add the widgets on the dashboard, click on the pencil icon at the top left corner, click on the ‘Addᾠbutton and then go to "Things" and select the Thing. Then select all the variables and click on "Add widgets". The final desktop screen will look like this:

Programming NodeMCU for Sending Data to Cloud

We are now done with setting up the Arduino Cloud IoT, the next step is to program the NodeMCU to read the data from DHT11 and send it to Arduino Cloud. To do so, we need to go to the "Sketch" tab. When you add any variable in Things, the Sketch on the cloud is automatically updated according to the variables. So, most of the code is already written and we only need to add some lines for the DHT11 sensor. The complete code is given below. When the code is ready, select the Board and Port and hit the upload button in the top left corner. With this done now, you can control LED and monitor the DHT11 sensor data using the Arduino Cloud IoT platform. Code #include "thingProperties.h" #include "DHT.h" #define DHTTYPE DHT11 // DHT 11 #define dht_dpin 1 DHT dht(dht_dpin, DHTTYPE); int LED = D0; void setup() { // Initialize serial and wait for port to open: Serial.begin(9600); pinMode(LED, OUTPUT); // This delay gives the chance to wait for a Serial Monitor without blocking if none is found delay(1500); // Defined in thingProperties.h initProperties(); // Connect to Arduino IoT Cloud ArduinoCloud.begin(ArduinoIoTPreferredConnection); /* The following function allows you to obtain more information related to the state of network and IoT Cloud connection and errors the higher number the more granular information you’ll get. The default is 0 (only errors). Maximum is 4 */ setDebugMessageLevel(2); ArduinoCloud.printDebugInfo(); } void loop() { ArduinoCloud.update(); // Your code here temperature = dht.readTemperature(); humidity = dht.readHumidity(); } void onLedSwitchChange() { // Do something if(led_switch){ digitalWrite(LED, LOW); } else{ digitalWrite(LED, HIGH); } } void onTemperatureChange() { } void onHumidityChange() { } Video microcontroller-projects/dog-barking-security-alarm-using-arduino-pir-sensor-and-dog-barking-sound-module

Dog Barking Security Alarm using Arduino, PIR Sensor and Dog Barking Sound Module

The need for home security alarm systems nowadays is a serious demand. As the number of crimes is increasing every day, there has to be something that will keep us safe. A motion sensor dog barking alarm can be a great choice for that purpose. The sound will alert you when someone approaches the house. They can also deter burglars from deciding to enter a home. , using different microcontrollers and sensors; you can also check them for more inspiration.

Components Required for Dog Barking Security Alarm

Arduino Nano PIR Motion Sensor Dog Barking Sound Module LM386 Amplifier Module 8ohm (0.25W to 2W) Speaker Capacitor (220uF, 2×10uF, 2×0.1uF) Resistor (2×10k) 100k Potentiometer

Dog Barking Sound Module

A useful, as well as a single module to produce dog barking sound, can be easily interfaced with speakers and a simple power supply without the need for additional amplifiers and passive components. The module comes with a non-removable chip and easy-to-connect PCB leads for trouble-free soldering. It can be powered using 3-4.5V DC. The output specification requires an 8 Ohms speaker with 0.25W to 2W sound output. Inbuilt button or trigger offers one-time play (three-time dog bark) if shorted. Good Quality Output 3.0-4.5V Operation voltage No additional amplifier requires Small size PCB to be fitted in very small space during DIY 0.25W-2W speaker support with 8 Ohms impedance Solder-able pads available in the module

Dog Barking Security Alarm Circuit Diagram

is given below. The Amplifier IC is used to amplify the Output from Dog Barking Sound Module. The Alarm circuit consists of an Arduino Nano, PIR Motion sensor, LM386 Amplifier IC, Speaker, NPN Transistor, and a couple of resistors and capacitors. BC547 Transistor is used to activate the Alarm whenever PIR Sensor detects motion. The VCC and GND pins of the PIR Sensor are connected to 5V and GND of Arduino, while the OUT pin is connected to digital pin 12 of Arduino. of the Amplifier IC are the gain control pins, internally the gain is set to 20 but it can be increased up to 200 by using a capacitor between PIN 1 and 8. We have used 10uF capacitor C1 to get the highest gain i.e. 200. are the input PINs. Pin 2 is the negative input terminal, connected to the ground. Pin 3 is the positive input terminal, in which the sound signal is fed to be amplified. In our circuit, it is connected to the one terminal of the Dog Barking Module with a 100k potentiometer RV1. are the power supply Pins of IC, Pin 6 for is +Vcc and Pin 4 is Ground. The circuit can be powered with a voltage between 5-12v. is the output PINfrom which we get the amplified sound signal. The output signal has both AC and DC components. DC component is undesirable and can’t be fed to Speaker. So to remove this DC component, a capacitor of 220uF has been used. is the bypass terminal. It can be left open or can be grounded using a capacitor for stability.

Building the Circuit on Perf Board

The complete circuit shown above is soldered onto a perf board. Make sure to use wires to leave enough distance to mount the Arduino and Sensors. I have soldered the Dog Barking sound module on the backside of the perf board. My perf board soldered to Arduino and the sensor module is shown below.

Programming Arduino for Burglar Alarm

The code for Dog Barking Alarm using Arduino andPIR Sensor is very simple. Complete code can be found at the end of the document. The explanation of the code is as follows: Start the code by defining all the necessary pins that are required to read the sensor data and control the transistor. int Sensor = 12; int transistor = 2; function, initialize the serial monitor at 9600 for debugging purposes. Also, set the sensor pin as input and the transistor pin as output. void setup() { Serial.begin(9600); pinMode (Sensor, INPUT); pinMode (transistor, OUTPUT); Serial.println("Waiting for motion");} and if the pin is valued greater than 0, then turn on the Alarm else turn off the Alarm. void loop() { int val = digitalRead(Sensor); if(val ==HIGH) { digitalWrite(transistor, HIGH); Serial.println("Motion Detected"); } if(val == LOW) { digitalWrite(transistor, LOW); Serial.println("NO Motion"); } delay(1000); }

Working of Dog Barking Security using Arduino

Make the connections as per the circuit diagram and upload the code to Arduino Nano. When powered, the PIR sensor detects the IR rays emitted from the human body. When any human is detected, the PIR sensor outputs a logic HIGH value i.e. voltage of 3.5V to 5V to Arduino’s digital pin 12. As soon as the Arduino detects logic HIGH on Pin 12, it switches the transistor, and the alarm is activated. In this circuit, it produces Dog Bark sound three times. The complete working of the project can be found in the video given below; if you have any questions, feel free to write them in the comment section below. Code int Sensor = 12; int transistor = 2; void setup() { Serial.begin(9600); pinMode (Sensor, INPUT); pinMode (transistor, OUTPUT); Serial.println("Waiting for motion");} void loop() { int val = digitalRead(Sensor); if(val ==HIGH) { digitalWrite(transistor, HIGH); Serial.println("Motion Detected"); } if(val == LOW) { digitalWrite(transistor, LOW); Serial.println("NO Motion"); } delay(1000); } Video microcontroller-projects/understanding-ecg-sensor-and-program-ad8232-ecg-sensor-with-arduino-to-diagnose-various-medical-conditions

Understating ECG Sensors and How to Program one to Diagnose Various Medical Conditions

which you may also like to check. So let's start with having a brief overviewof ECG sensors.

How does anECGSensor Work?

ECGor ElectroCardioGraphyis a method to measure some important parameters of a human heart. It outputs analog values that produce a particular signalthat looks as shown below. As visible, the signal has a few peaks and important features that are of biological importance. These are marked below. Each interval has an optimal value range, and deviation from that might be linked to a particular disease. Here are the main parts of anECGsignal. P wave - It is the trailing wave on the left of theQRScomplex. QRScomplex - It is an impulse generated by ventricular contraction. T wave - It is a leading wave right to theQRScomplex. U wave - It is not always observed due to its low peak value. There are many other features aswell,but these are the main ones. Based on the shapes of the above features, their interval as well as the interval between them, we can diagnose a lot of cardiac diseases and irregularities. For example: Irregular heartbeat or absence of P-wave: Atrial Fibrillation Resting Heart Rate of more than 100:Tachyarrhythmia Tachyarrhythmiaand delta wave: Wolf-Parkinson-White orWPWsyndrome Sawtooth P wave: Atrial flutter Depression of ST-segment: it might indicate Ischemia Elevation of ST-segment: it might indicate myocardial Infarction Hence,ECGsare extremely important for a cardiologist or any doctor for that matter. Today, we will try to develop a simple system that will be able to measureECGsignal values and even measure the heartbeat of a person using them. First, we will focus on the hardware part as tohow exactly is theECGsignal retrieved from the human body?

AD8232ECGSensor Electrodes Placement (3 Lead Sensor)

For a 3-lead system,there are two placements that are used-
The left position is generally used for females and is the reason why the three electrodes are called RA, LA, and RL. However, this method of placing electrodes produces more noise and hence, it is preferred that the electrodes are placed as shown in the right position, especially for hospital patients.

Interfacing AD8232ECGsensor withArduino

The AD8232 from Analog Devices is a 3 leadECGsensor, which has been converted into various breakouts and modules bySparkfunand other 3rd party electronics manufacturers. All breakouts generally contain the following pins: The shutdown pin is used to send the AD8232 sensor into standby mode, during which it only consumes a current of 200nA. Generally, that mode is not used because theECGsensor data are to be taken continuously, but we can code in such a manner that the module enters standby mode when electrodes are removed or on a button press. A few possible schematics are shown below. available online look as simple as this: void setup() { Serial.begin(9600); pinMode(8, INPUT); // Setup for leads off detection LO + pinMode(9, INPUT); // Setup for leads off detection LO - } void loop() { if((digitalRead(8) == 1) || (digitalRead(9) == 1)){ //check if leads are removed Serial.println("leads off!"); } else{ Serial.println(analogRead(A0)); } delay(1); } However, this code can only show you anECGoutput similar to this- As discussed earlier, HR = No. of R peaks in 1 minute. However, this would mean that it would take 1 entire minute for a single HR value to appear. Hence, many people tend to measure the time interval between two consecutive R peaks and estimate HR using the following formula- This might be very fast, but medically this is incorrect. Why? Because this equation assumes that each R-R interval throughout the entire 1 minute is the same. However, this is not the case. For an average healthy human, the time taken by 1 entire heartbeat is around 800-850 ms (65-75 beats per minute). This might change depending on whether the person is resting or working. Whatever the case might be, the heartbeat intervals do not vary much for the person. But for a person suffering from Atrial fibrillation or Arrhythmia varies significantly throughout theECG, despite the average heartbeat appearing to be normal. The parameter to identify this is called Heart Rate Variability. Heart rate variability orHRVis calculated as follows- HRV = HR/60 - RR interval So, for calculatingHRV,we need HR first. But 1 minute is too long. Hence, we use a window of 10 seconds to calculate bothparameters. HR = (RR peaks in 10 seconds)*6 HRV = HRV = HR/60 - RR interval We can easily identify the R peak bythresholding. Then we can use interrupts or simple micros() to measure the interval between the two beats.

Working Demonstration of AD8232ECGSensor withArduino

Place the electrodes as shown in the picture below. Since the image is a selfie, the placement of theECGleads ismirror images of the actual placement. Connect theECGsensor module to theArduinoboard and upload the code which is given at the bottom of this page. If everything works the way it is supposed,you can find the output on a serial plotter like something shown below. The green signal indicates a slightly modifiedECGwhile the blue signal indicates the approx. heartbeat. TheHRVvalues can be seen on the monitor when the plotter is not in use.Hrvis not visible much on the plotter because it will generally be around -1 to 1millisecs for a normal human, while theECGvalue and hr will be around 70. Hence,hrvis seen as a red line on the serial plotter. On the serial monitor, the values are displayed as follows: hr, hrv, ECG_value The default threshold is 100, but please set it as per your own sensor. The code is pretty simple and intuitive and just implements simple timers to measure theECGvalues and RR intervals to calculate the hr and HRV variables according to the formula explained earlier. to post your technical quires. Code /* * VARIABLES * count: variable to hold count of rr peaks detected in 10 seconds * flag: variable that prevents multiple rr peak detections in a single heatbeat * hr: HeartRate (initialised to 72) * hrv: Heart Rate variability (takes 10-15 seconds to stabilise) * instance1: instance when heart beat first time * interval: interval between second beat and first beat * timer: variable to hold the time after which hr is calculated * value: raw sensor value of output pin */ long instance1=0, timer; double hrv =0, hr = 72, interval = 0; int value = 0, count = 0; bool flag = 0; #define shutdown_pin 10 #define threshold 100 // to identify R peak #define timer_value 10000 // 10 seconds timer to calculate hr void setup() { Serial.begin(9600); pinMode(8, INPUT); // Setup for leads off detection LO + pinMode(9, INPUT); // Setup for leads off detection LO - } void loop() { if((digitalRead(8) == 1)||(digitalRead(9) == 1)){ Serial.println("leads off!"); digitalWrite(shutdown_pin, LOW); //standby mode instance1 = micros(); timer = millis(); } else { digitalWrite(shutdown_pin, HIGH); //normal mode value = analogRead(A0); value = map(value, 250, 400, 0, 100); //to flatten the ecg values a bit if((value > threshold) && (!flag)) { count++; Serial.println("in"); flag = 1; interval = micros() - instance1; //RR interval instance1 = micros(); } else if((value < threshold)) { flag = 0; } if ((millis() - timer) > 10000) { hr = count*6; timer = millis(); count = 0; } hrv = hr/60 - interval/1000000; Serial.print(hr); Serial.print(","); Serial.print(hrv); Serial.print(","); Serial.println(value); delay(1); } } Video microcontroller-projects/how-to-connect-your-arduino-uno-nano-with-internet-using-w5100-ethernet-module

How to connect your Arduino UNO/Nano to internet using the W5100 Ethernet Module

and the second option is to connect an Ethernet module with Arduino. The Ethernet module is used to establish communication between the computer and Arduino in a LAN or Wired Network. This article is written assuming that the reader has an understanding of basic computer networking which includes having knowledge of connecting computers to hub/router with RJ45 cables, IP and MAC addresses, etc.

W5100 Ethernet Module

We are using the W5100 Ethernet module. It is a single-chip, full-featured, internet-enabled module to establish an internet connection. In simple terms, this module enables the Arduino board to connect to the internet. By using this module, we can complete the internet linking without the support of an Operating System. It also supports Hardwired TCP/IP Protocols like TCP, PPPoE, Ethernet, UDP, ICMP, IPv4, etc. It supports full-duplex and half-duplex modes of operation. It supports ADSL connections and up to four simultaneous socket connections. As an advantage, it comes at half the price of a shield.

Circuit Diagram to Connect Arduino W5100 Ethernet Module

The Circuit consists of Arduino Nano and Ethernet Module W5100 (This project would be possible with Ethernet Arduino Shield and Arduino UNO as well). The connection between Arduino and Ethernet modules are made as shown in the circuit diagram. Connect pin 5V and GND pins of Arduino Nano to +5 and G pin of Ethernet Module respectively (These connections supply power to the Ethernet Module). Connect pin 9, 10, 11,12, and 13 of Arduino to R, SS, MO, MI, CK of the Ethernet module respectively (These make the communication between Arduino and Ethernet over SPI).

Arduino Code to get data from W5100 Ethernet Module

SPI header file is included to use the protocols to communicate to the Ethernet module. #include <SPI.h> The Ethernet header file has the library to run webclient/webserver over Ethernet. #include <Ethernet.h> Physical Mac address is set to the Ethernet module. byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; depends on the host (default gateway) of the network you are connected to, check that by doing ipconfig on the command prompt. byte ip[] = { 192, 168, 0, 12 }; byte gateway[] = { 192, 168, 0, 12 }; byte subnet[] = { 255, 255, 255, 0 }; Just for reference, this default gateway ofa different network is shown below. This creates a local server at port 80 which can be later accessed by the clients. EthernetServer server(80); This reads the response from the client when the user accesses the webserver. String readString; int ledPin = 2; void setup(){ pinMode(ledPin, OUTPUT); Ethernet.begin(mac, ip, gateway, subnet); server.begin(); } In the loop function, we create a client connection and check if someone is trying to access the assigned IP address over a browser. void loop(){ EthernetClient client = server.available(); if (client) { while (client.connected()) { if (client.available()) { If connected, continue checking if the client is sending some message back to the server char c = client.read(); variable. if (readString.length() < 100) { readString += c; } if (c == 0x0D) { Once we receive an OK response, we start displaying the webpage, and below is the HTML code. client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(); client.println("<HTML>"); client.println("<HEAD>"); client.println("<TITLE> ARDUINO ETHERNET</TITLE>"); client.println("</HEAD>"); client.println("<BODY>"); client.println("<hr>"); client.println("<H1 style=\"color:green;text-align:center\">ARDUINO ETHERNET LED CONTROL</H1>"); client.println("<hr>"); client.println("<br>"); which further turns on the LED. client.println("<H2 style=\"text-align:center\"><a href=\"/?LEDON\"\">Turn On LED</a><br></H2>"); Similar to the above code, this redirectsthe user to the “TURN OFF LEDᾠURL. client.println("<H2 style=\"text-align:center\"><a href=\"/?LEDOFF\"\">Turn Off LED</a><br></H2>"); Remaining part of the HTML Code- client.println("<br>"); client.println("</BODY>"); client.println("</HTML>"); delay(10); client.stop(); Control Arduino pin to turn on and turn off the LED depending on the URL the users are redirected to. if(readString.indexOf("?LEDON") > -1) { digitalWrite(ledPin, HIGH); } else{ if(readString.indexOf("?LEDOFF") > -1) { digitalWrite(ledPin, LOW); } } clearing string for next read readString=""; } } } } }

Connecting Arduino to PC or Router Ethernet Port

To connect the two (PC and Arduino) together, we need a suitable cable (CAT-6 crossover cable) if the PC's Ethernet port doesn't have auto-direction sensing. In case your PC supports auto-direct sensing, just connect a regular cable that comes with the router. In this special cable TX+/TX- and RX+/RX- are swapped over. In any case, if you don’t have an Ethernet port in your PC or you don’t want to buy a special cable you can follow our method to connect the Ethernet module to a router LAN network port.

Blinking LED over Internet using Ethernet module on Arduino

is clicked, the LED is turned OFF in the circuit. This command is executed using the wired connection of the Ethernet module. The web server page is as shown in the figure below. Code #include <SPI.h> //protocol to communicate to the ethernet module #include <Ethernet.h> //library to run webclient / web server over ethernet byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address set to the ethernet module /*the number 0 in the IP address depends on the host of the network you are connected to, check that by doing ipconfig on command prompt*/ byte ip[] = { 192, 168, 0, 12 }; // IP address in LAN ᾠneed to change according to your Network address byte gateway[] = { 192, 168, 0, 12 }; // internet access via router byte subnet[] = { 255, 255, 255, 0 }; //subnet mask EthernetServer server(80); //port where the server can be accessed String readString; // to read the response form the user / client int ledPin = 2; // Led is connected to pin 2 void setup(){ pinMode(ledPin, OUTPUT); //pin selected to control //start Ethernet Ethernet.begin(mac, ip, gateway, subnet); //initialize ethernet server.begin(); //start the server } void loop(){ // Create a client connection EthernetClient client = server.available(); //check if someone is tried access the assigned IP address over a browser if (client) { //if connected, continue checking if client is sending some message back to the server while (client.connected()) { if (client.available()) { char c = client.read(); //read char by char HTTP request if (readString.length() < 100) { //store characters to string readString += c; } //if HTTP request has endedᾠ0x0D is Carriage Return \n ASCII if (c == 0x0D) { //display the webpage client.println("HTTP/1.1 200 OK"); //send new page client.println("Content-Type: text/html"); client.println(); client.println("<HTML>"); client.println("<HEAD>"); client.println("<TITLE> ARDUINO ETHERNET</TITLE>"); client.println("</HEAD>"); client.println("<BODY>"); client.println("<hr>"); client.println("<H1 style=\"color:green;text-align:center\">ARDUINO ETHERNET LED CONTROL</H1>"); client.println("<hr>"); client.println("<br>"); //creating a link to redirect the user to turn on the light client.println("<H2 style=\"text-align:center\"><a href=\"/?LEDON\"\">Turn On LED</a><br></H2>"); //creating a link to redirect the user to turn off the light client.println("<H2 style=\"text-align:center\"><a href=\"/?LEDOFF\"\">Turn Off LED</a><br></H2>"); client.println("<br>"); client.println("</BODY>"); client.println("</HTML>"); delay(10); //stopping client client.stop(); // control arduino pin with URL if(readString.indexOf("?LEDON") > -1) //checks for LEDON { digitalWrite(ledPin, HIGH); // set pin high } else{ if(readString.indexOf("?LEDOFF") > -1) //checks for LEDOFF { digitalWrite(ledPin, LOW); // set pin low } } //clearing string for next read readString=""; } } } } } Video microcontroller-projects/automatic-bottle-filling-system-using-arduino

Automatic Bottle Filling System using Arduino

You can program the Arduino to automatically detect the bottle using IR or ultrasonic sensor and allow the bottler to fill by stopping the conveyer belt for some time. Then again move the belt and stop when the next bottle is detected. , conveyor belt, solenoid valve, IR sensor, and Stepper motor. Belt conveyor is driven by a stepper motor at a constant preset speed. The stepper motor will keep driving the belt until an IR sensor detects the presence of a bottle on the belt. We used the IR sensor as an external trigger. So whenever the IR sensor goes high it sends a trigger to Arduino to stop the motor and turn on the solenoid valve. A preset required delay is already entered in the code for bottle filling. The Arduino will keep the solenoid valve on and stepper motor off until that specified time. After that time, the solenoid valve turns off the filling, and the conveyor starts moving so that the next bottle can be filled. , so to learn more about basic interfacing of Arduino with these components, you can visit the links.

Components Required

Arduino Uno Stepper Motor (Nema17) Relay Solenoid Valve IR Sensor A4988 Motor Driver Battery

Circuit Diagram

is given below. tutorial for more information on Nema17 and A4988 driver module. pin of Arduino. Solenoid Valve is powered by a 24V power source, and Stepper motor is powered by a12V power source.

Arduino Program for Automatic Bottle Filling

is given at the end. Here I am explaining some important lines. After that, define the no of steps per revolution for the stepper motor. For NEMA 17 steps per revolution is 200. #include <Stepper.h> #define STEPS 200 Stepper stepper(STEPS, 2, 4); #define motorInterfaceType 1 Set the stepper motor speed. stepper.setSpeed(500); Define the Relay, step and direction pins as output pinMode(relay,OUTPUT); pinMode(4,OUTPUT); pinMode(2,OUTPUT); The syntax for external interrupt in Arduino is given below: attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); Where: It is used to define the pin at which external interrupt is connected. In Arduino Uno Pin 2 & 3 are external interrupt pins. : It is a function that is called when an external interrupt is called. : Type of transition to trigger on, e.g., falling, rising, etc. by following the link. function is called whenever IR sensor changes its state from is LOW to HIGH (RISING). attachInterrupt(digitalPinToInterrupt(3),IR_detected,HIGH); is an ISR function that executes when the IR sensor goes high. So whenever the IR sensor goes high, this function runs the stepper motor for a few steps, and then stops the stepper motor and turns on the solenoid valve. void IR_detected() { stepper.step(150); digitalWrite(relay,HIGH); stepper.step(0); are given below. Code #include <Stepper.h> #define STEPS 200 #define motorInterfaceType 1 Stepper stepper(STEPS, 2, 4); int relay=7; int step_num =700; void setup() { Serial.begin(9600); pinMode(relay,OUTPUT); stepper.setSpeed(500); pinMode(4,OUTPUT); pinMode(2,OUTPUT); attachInterrupt(digitalPinToInterrupt(3),IR_detected,RISING); } boolean solenoid_on = false; void loop() { if (solenoid_on) { delay(6000); //wait for 6 sec solenoid_on = false; } digitalWrite(relay,LOW); // now relay is off condition (and motor is on condition) stepper.step(step_num); } void IR_detected() //ISR function excutes when IR sensor goes high. { Serial.println ("Interrupt Detected"); stepper.step(150); //To run the stepper motor few steps before it stops digitalWrite(relay,HIGH); //to turn on solenoid stepper.step(0); //to stop the stepper motor solenoid_on = true; } Video microcontroller-projects/voice-alert-based-smart-blind-stick-using-arduino-and-ultrasonic-sensor

Voice Alert based Smart Blind Stick Using Arduino Nano and Ultrasonic Sensors

Uno andUltrasonic sensors. The primary goal of this project is to assist blind people to walk with ease and to alert them whenever their walking path is obstructed by other objects or people. As a warning signal, a Voice module is connected in the circuit, that gives a voice warning according to the direction of the object, for example, if the object is in Left then it will say ‘Careful Object in Leftᾮ This Smart stick will have three Ultrasonic sensors connected in left, right, and centerto sense distance from any obstacle, a JQ6500 Voice Sound Module to give warning signal, and a 9V battery to power the setup.

Components Required for Smart Blind Stick

Arduino Nano 3× Ultrasonic Sensor JQ6500 Voice Sound Module 8 Speaker 1 K Resistor

JQ6500 Voice Sound Module

JQ6500 Voice Sound Module is perfect for broadcasting a message on the speaker like a fire alarm, train, and bus alert systems, business hall prompts, equipment failure alarms, etc. It can decode the MP3, hardcoded MP3, or WMV format files into the audible voice format. It comes with 24 bits Digital-to-Analog Converter with a dynamic range of 90dB and supports 8 / 11.025 / 12/16 / 22.05 / 24/32 / 44.1 / 48 kHz sampling rate. The MP3 files can be controlled with buttons, or via a serial communications protocol. The MP3 files to the on-board memory of JQ6500 can be uploaded using a Windows computer (Mac or Linux users you will need to use the JQ6500-28p and an SD Card). Steps for the same are given below: Connect the board to your computer over the Mini USB connector. A new “CD-ROMᾠdrive will appear on your computer, double click on that and open the application named ᾼstrong>MusicDownload.exeᾮ Some JQ6500-16P devices do not have the MusicDownload.exe installed on them, if you can’t find the MusicDownload.exe program; you can download this zip file that contains it. The application is in the Chinese language, so to upload the files, open the .exe file and then click the second tab from the left. Then click on the file selector tab that is in the right corner. A file selector will open, select all the mp3 files you wish to upload click the Open button on the file selector Click back to the first tab and then click the button to upload the files

Smart Blind Stick Circuit Diagram

is shown below. It is pretty simple as we only need to connect three ultrasonic sensors and one JQ6500 voice module. The complete board is powered by a 9V battery. The brain of the circuit is Arduino Nano. Three Ultrasonic sensors are used for obstacle detection in the left, right, and front of the stick. Two of the four pins of these three sensors, namely VCC & GND, are connected to Arduino’s 5V and GND. The remaining two pins–TRIG & ECHO are connected to Arduino as follows.
TrigD6
EchoD7
TrigD2
EchoD3
TrigD4
EchoD5
The JQ5600 MP3 module is a 3.3V logic module, so you can’t connect it directly to the Arduino’s IO pins, but it is fine to be powered from the Arduino’s 5V power line. RX and TX pins of the MP3 module are connected to digital pins 9 and 8 of the Arduino Nano. A 1kΩ resistor is put in between the Arduino digital pin 9 to MP3 module RX to drop the voltage down from the Arduino’s 5V.

Arduino Program for Smart Blind Stick

Once we are ready with our hardware, we can connect the Arduino to our computer and start programming. The complete code for this project is given at the bottom of this page; you can upload it directly to your Arduino board. However, if you are curious to know how the code works, read further. can be installed from the given link. As usual, start the code by including all the required libraries and defining all the pins used in this project. #include <Arduino.h> #include <SoftwareSerial.h> #include <JQ6500_Serial.h> JQ6500_Serial mp3(8,9); int left_trigPin = 6; int left_echoPin = 7; int right_trigPin = 2; int right_echoPin = 3; int center_trigPin = 4; int center_echoPin = 5; function,initialize Input Output pins. In our program, the Trigger pins of all three sensors are the Output device and the Echo pins are the Input device. We also initialize the serial monitor and JQ6500 voice module. pinMode(left_trigPin,OUTPUT); pinMode(left_echoPin,INPUT); pinMode(right_trigPin,OUTPUT); pinMode(right_echoPin,INPUT); pinMode(center_trigPin,OUTPUT); pinMode(center_echoPin,INPUT); Serial.begin(115200); mp3.begin(9600); mp3.reset(); we are reading all three sensors' data, i.e. left, right, and center. We begin with reading the sensor data of the Ultrasonic sensor for distance, and then calculate the distance using the time taken between triggering and Received ECHO. The formula for calculating distance is given below: digitalWrite (left_trigPin, HIGH); delayMicroseconds (10); digitalWrite (left_trigPin, LOW); duration = pulseIn (left_echoPin, HIGH); distance = (duration/2) / 29.1; There will be no warning if the measured distance is more than 50cm. But, if it is less than 50cm the Voice module will be triggered to play the voice warning. if (distance < 50) { Serial.print("Left Distance"); Serial.print(distance); mp3.playFileByIndexNumber(2); } The same logic is used for all three sensors. The program can be easily adapted for your application by changing the value which we use to compare. You use the serial monitor to debug if a false alarm is trigger.

Testing the Smart Arduino Blind Stick

closer to the object and you will notice the voice warning according to the direction of the object. For example, if the object is in Left, then it will say ‘Careful Object in Leftᾮ The complete working of this Smart Arduino blind stick is shown in the video given at the end of this page. Code #include <Arduino.h> #include <SoftwareSerial.h> #include <JQ6500_Serial.h> JQ6500_Serial mp3(8,9); int left_trigPin = 7; int left_echoPin = 6; int right_trigPin = 2; int right_echoPin = 3; int center_trigPin = 4; int center_echoPin = 5; void setup() { pinMode(left_trigPin,OUTPUT); pinMode(left_echoPin,INPUT); pinMode(right_trigPin,OUTPUT); pinMode(right_echoPin,INPUT); pinMode(center_trigPin,OUTPUT); pinMode(center_echoPin,INPUT); Serial.begin(115200); mp3.begin(9600); mp3.reset(); mp3.setVolume(50); mp3.setLoopMode(MP3_LOOP_NONE); } void loop(){ left(); right(); center(); } void left(){ delay(500);// reading will be taken after ....miliseconds Serial.println("\n"); int duration, distance; digitalWrite (left_trigPin, HIGH); delayMicroseconds (10); digitalWrite (left_trigPin, LOW); duration = pulseIn (left_echoPin, HIGH); distance = (duration/2) / 29.1; //distance= duration*0.034/2; if (distance < 30) { // Change the number for long or short distances. Serial.print("Left Distance"); Serial.print(distance); mp3.playFileByIndexNumber(2); } } void right(){ delay(500);// reading will be taken after ....miliseconds Serial.println("\n"); int duration, distance; digitalWrite (right_trigPin, HIGH); delayMicroseconds (10); digitalWrite (right_trigPin, LOW); duration = pulseIn (right_echoPin, HIGH); distance = (duration/2) / 29.1; if (distance <30) { // Change the number for long or short distances. Serial.print("Right Distance"); Serial.print(distance); mp3.playFileByIndexNumber(3); } } void center(){ delay(500);// reading will be taken after ....miliseconds Serial.println("\n"); int duration, distance; digitalWrite (center_trigPin, HIGH); delayMicroseconds (10); digitalWrite (center_trigPin, LOW); duration = pulseIn (center_echoPin, HIGH); distance = (duration/2) / 29.1; if (distance <30) { // Change the number for long or short distances. Serial.print("Center Distance"); Serial.print(distance); mp3.playFileByIndexNumber(1); } } Video microcontroller-projects/interfacing-e18d80nk-ir-proximity-sensor-with-arduino

Interfacing E18-D80NK IR Obstacle Avoidance Proximity Sensor with Arduino

can’t be put in sunlight as the sun also releases IR waves. There is only one common solution for this problem: Modulate your IR signal so that your sensor can detect an IR variation rather than a fixed IR level. The E18-D80NK is an advanced low-cost IR Proximity Sensor with an obstacle detection range of 3 cm to 80 cm. The use of modulated IR signal protects the sensor from the interferences caused by the normal light of a light bulb or the sunlight.

Components Required for interfacing E18-D80NK

Arduino Nano E18-D80NK IR Sensor Jumper Wired Breadboard

E18-D80NK IR Obstacle Avoidance Proximity Sensor

E18-D80NK Infrared Obstacle Avoidance Sensor is a low-cost IR Proximity Sensor with an adjustable range of 3 cm to 80 cm. The E18-D80 sensor comes with IR Transmitter and IR receiver in one module. The IR transmitter transmits modulated IR signal, which is then reflected by the object in its path and then detected by the receiver. This sensor has less interference by sunlight because of the modulated IR light. E18-D80 IR Sensor is widely used in robots to avoid obstacles, industrial assembly lines, Reverse Car Parking, and many other automation applications. The detection range can be adjusted according to the application using the multi-turn screw that is located at the back of the sensor. The switching signal output changes according to the obstacle detection. It remains high when no obstacles and changes to low when there are obstacles. A red LED is placed behind the probe that turns high whenever an obstacle is detected. The E18 sensor operates on 5V and consumes around 5mA to 30mA current without any load. Input voltage: 5V DC Current consumption: > 25mA (min) ~ 100mA (max) Dimension: 1.7cm (diameter) x 4.5cm (length) Cable length: 45cm Detection of objects: Transparent or Opaque Diffuse reflective type Sensing range: 3cm to 80cm (depends on obstacle surface) NPN output (normally high) Environment temperature: -25 °C ~ 55 °C

Circuit Diagram for Interfacing E18-D80NK Sensor with Arduino

is given below: The connection for Interfacing of E18-D80NK IR Sensor with Arduino is very easy, connect the Brown wire of sensor with Arduino 5V pin, connect the Blue wire of sensor with Arduino’s Ground and connect Black pin of a sensor with a digital pin 7 of Arduino Nano.

Programming Arduino for E18-D80NK IR Sensor

is given at the end of the document. The explanation of the code is as follows: Start the code by defining all the necessary pins that are required to read the sensor data and control the LED. const int e18_sensor = 7; const int led = 6; function initialize the serial monitor at 9600 for debugging purposes. Also, set the sensor pin as input and the LED pin as output. void setup() { Serial.begin(9600); pinMode (e18_sensor, INPUT); pinMode (led, INPUT); } and if pin state is LOW turn on the LED else turn off the LED. void loop() { int state = digitalRead(e18_sensor); Serial.println(state); if(state==LOW){ Serial.println("Object Detected"); digitalWrite(led, HIGH); } else { Serial.println("All Clear"); digitalWrite(led, LOW); }

Testing the E18-D80NK IR Sensor

Once your code and hardware are ready, connect Arduino to the laptop and upload the code. After that open the serial monitor at a baud rate of 9600, and make some motion in front of the sensor. Observe LED and Serial monitor. are given below. Hope you enjoyed the tutorial and learned something useful. If you have any questions, leave them in the comment section or use our forums for other technical queries. Code const int e18_sensor = 7; const int led = 2; void setup() { Serial.begin(9600); pinMode (e18_sensor, INPUT); pinMode (led, INPUT); } void loop() { int state = digitalRead(e18_sensor); Serial.println(state); if(state==LOW){ Serial.println("Object Detected"); digitalWrite(led, HIGH); } else { Serial.println("All Clear"); digitalWrite(led, LOW); } delay(1000); } Video microcontroller-projects/small-size-radio-frequency-module-for-long-range-communication-xy-wa-interface-with-arduino

Small Size Radio Frequency Module for long-range Data Communication - XY-WA Interface with Arduino

using different RF modules.

Hardware Section

We'll begin by discussing the module’s pin description, working, and its connections to a microcontroller. The module's working is also briefly described in this section.

Components used for XY-WA Radio Frequency Module

XY - WA 2.4Ghz Transceiver module Arduino Uno Jumper wires

Pin Configuration of XY-WA Radio Frequency Module

The image below describes the pin configuration of the XY-WA module used in our project. It is a Type A module and has 8 pins. It can be used to mount over custom circuit boards to reduce the size and make a compact device.

Wiring of the Radio Frequency Module with Arduino or MCU

and a few digital pins. The module can be hooked up to any microcontroller i.e. Arduino Uno, Mega, etc. The image below also represents a pictorial demonstration of the wiring of the XY-WA module to an Arduino Uno. simplified pin connections to the Arduino Uno microcontrollers are described below: The reset pin (PIN 1) of the XY-WA module is connected to the 6th pin on the Arduino Uno microcontroller. CS pin(PIN 3) of the module is connected to the 5th pin of the Arduino Uno. Packet/Pkt (PIN 6) of the module is connected to the 4th pin of the Arduino Uno. Once these connections are made, we can connect the terminals for the SPI interface. MISO pin(PIN ) is connected to the 12th pin on the Arduino, MOSI pin(PIN ) is connected to the 11th pin on the Arduino, clock/CLK pin (PIN) is connected to the 13th pin on the Arduino. Whereas, the ground(PIN 7) and power 3.3V (PIN 8) are connected to the 7th and 8th pin of the Arduino Unorespectively. To understand more about the pin configuration of the XY-WA module, you can follow the pin description table below.

IMPORTANT TABULATIONS

The table below shows some of the characteristics and the values of the following characteristics. Followalong, these may help to understand the module better.
Operating Voltage2.2-3.6V
Operating Temperature-40-85 degree C
Emission Current15-24 mA
Reception Current18 mA
Sleep Current6 uA
The table below showcases the following pin number of the module XY-WA along with the description. This may help while making the connections with the Microcontroller.
2.4Ghz ISM band range is used in order to communicate between two peripherals. To communicate between two nodes using radio frequencies, it is important for both nodes to be on the same frequency band. Here, using XY-WA, the frequency range could be between 2.4Ghz to 2.525Ghz. Here, I have soldered some jumper wires to the Zero board and connected male jumpers to itto make it convenient to connect it to the microcontroller. Every channel on which two modules communicate occupies a bandwidth thatis less than 1Mhz. Considering the frequency range of 2.4Ghz to 2.525Ghz, we get 125 possible channels. You can use this formula to determine the frequency of the selected channel: Frequency = 2400 + Channel selected As there are 125 possible channels, you can use a value between 0 to 125 and put it in the channel selected value, and determine the frequency of the channel which will be used. Increasing the transmitter module power. Most modules can be configured to send a custom output power, and a higher transmission power can be used to increase the range. Reducing the transmission data rate. A lower data rate over a channel can cover longer ranges. Changing the frequency channels could also serve as a great option since lower frequency bands are acquired by the Wi-Fi or other signals, shifting to a higher frequency band could remove any kind of interference therebyincreasing the range. A bad power supply can not only hinder the range but also induce noises and lead to improper functioning of the module. A very low supply voltage can also become a problem at the transmitting and receiving ends. It is best to choose an adapter for these purposesas it will supply a stable output voltage supply. A low-quality antenna. These antennas would not hinder the true range potential of the module. The XY-WA comes with a built-in silicon antenna which allows a transmission power of 100mW. When it comes to radio frequencies, RF signals are very susceptible to noise from different sources, one of which is its power input. DC batteries do get away with those, but if it is an AC-DC converter, using it probably will generate noise and affect the RF signals in terms of additive noise and low range. Serial Peripheral Interface is primarily used for short-distance communication. It is a synchronous* serial data protocol that is used by multiple microcontrollers, microprocessors to communicate with various peripherals at higher speeds and over short distances. It is a full-duplex and a 4-wire communication. SPI communication contains a single master and can communicate with multiple slave nodes using SS pins(SS0, SS1, SS2,.....). The figure below explains how one master controls multiple slaves. Whichever slave has to be selected, a logic 0 is sent via the SS pin and that slave communicates with the master. SPI has 4 modes of transmission, mode 0, mode1, mode 2, mode 3 are responsible for pushing the data in or out into the rising edge and falling edge of the clock signal which is called the Clock phase. These modes also tell when the clock is idle when high or low(called clock polarity). The table below shows how the modes combine polarity and phases together.
SPI_MODE 000FallingRising
SPI_MODE 101RisingFalling
SPI_MODE 210RisingFalling
SPI_MODE 311FallingRising
The major four common pins/ports in all SPI devices are defined below: MISO (Master In Slave Out): It is the Slave line to send the data to the master. MOSI (Master Out Slave In): It is the Master line to send the data to the multiple peripherals. SS (Slave Select): It is the pin that helps the master to decide which slave to choose and exchange data. SCK (Serial Clock): Since SPI is a synchronous communication mode, the serial clock pulses which are generated by the master helps to synchronize the communication channel.

Software Section

In order to begin with the project, we would require some libraries. LT8920.h: (#include "LT8920.hᾩ LT8920.h library is used for LT8910/ LT8920 low-cost 2.4Ghz transceiver modules. SPI.h: (#include <SPI.h>) SPI.h library is used to communicate between Arduino and the Module. The following code can be used for both the modules since they are transceivers, hence anyone can either act as a transmitter and another as a receiver and vice versa. The first step is to include the libraries, you can download the libraries from the above-mentioned links. SPI.h is used for the communication between the microcontroller and LT8920.h is used for the module. Also define the RST, CS, PKT pins are defined. #include <SPI.h> #include "LT8920.h" const uint8_t PIN_NRF_RST = 6; // Arduino Uno Pin = 6 const uint8_t PIN_NRF_CS = 5; //Arduino Uno Pin = 5 const uint8_t PIN_NRF_PKT = 4; //Arduino Uno Pin = 4 // Similarly connect MISO = 12 // MOSI = 11 // SCK = 13 char sbuf[32]; LT8920 lt(PIN_NRF_CS, PIN_NRF_PKT, PIN_NRF_RST); uint8_t a = 0; //+1 with every packet recieved uint8_t b = 105; //Change from 0 to 255 in receiver and put other numbers uint8_t c = 218; //Check signal uint8_t d = 53; //reception / transmission uint8_t e = 95; void setup() { Serial.begin(9600); SPI.begin(); SPI.beginTransaction(SPISettings(12000000, MSBFIRST, SPI_MODE1)); SPI.setClockDivider(SPI_CLOCK_DIV16); lt.begin(); lt.writeRegister(35, 0x0F00); //Setting the number of repeated dispatches to 255 lt.setCurrentControl(255,255); //Setting the power and gain lt.setDataRate(LT8920::LT8920_1MBPS); lt.setChannel(80); // Setting the Channel lt.setSyncWord(0x123A123B123C123D); //The receiver and transmitter must be on the same channel } void loop() { uint8_t data[] = { a,b,c,d,e }; lt.sendPacket(data,5); //Sending the second digit in the number of words in the packet Serial.print("Packet send:"); // Printing “Packet sendᾍ Serial.println(a); a=a+1; if (a>=256) { a=0; } lt.startListening(); //We switch to the reception part delay(1000); if (lt.available()) { uint8_t buf[32]; int packetSize = lt.read(buf, 32); if (packetSize > 0) { Serial.println(F("Packet read OK")); // If packet received print “Packet read OKᾍ for(int i = 0; i < packetSize; i++) { Serial.print(i); Serial.print("="); Serial.println(buf[i]); } } } else { Serial.println(F("Packet read --")); } } and his code for this module. You can check out his YouTube channel for more details. Google drive link for Olegmih’s code.

Testing of the XY-WA Radio Frequency Module

Below, I have hooked both the Radio Frequency modules to the Arduino and then connected them to the laptop. The code was then uploaded to both the modules and the serial monitor was observed. As per the print commands described in the code, we observe that the packets are now being sent and received by the RF modules. and we will get back to you as soon as possible. Thanks! For further clarification, you can also follow the video below: Code #include <SPI.h> #include "LT8920.h" const uint8_t PIN_NRF_RST = 6; // Arduino Uno Pin = 6 const uint8_t PIN_NRF_CS = 5; //Arduino Uno Pin = 5 const uint8_t PIN_NRF_PKT = 4; //Arduino Uno Pin = 4 // Similarly connect MISO = 12 // MOSI = 11 // SCK = 13 char sbuf[32]; LT8920 lt(PIN_NRF_CS, PIN_NRF_PKT, PIN_NRF_RST); uint8_t a = 0; //+1 with every packet recieved uint8_t b = 105; //Change from 0 to 255 in receiver and put other numbers uint8_t c = 218; //Check signal uint8_t d = 53; //reception / transmission uint8_t e = 95; void setup() { Serial.begin(9600); SPI.begin(); SPI.beginTransaction(SPISettings(12000000, MSBFIRST, SPI_MODE1)); SPI.setClockDivider(SPI_CLOCK_DIV16); lt.begin(); lt.writeRegister(35, 0x0F00); //Setting the number of repeated dispatches to 255 lt.setCurrentControl(255,255); //Setting the power and gain lt.setDataRate(LT8920::LT8920_1MBPS); lt.setChannel(80); // Setting the Channel lt.setSyncWord(0x123A123B123C123D); //The receiver and transmitter must be on the same channel } void loop() { uint8_t data[] = { a,b,c,d,e }; lt.sendPacket(data,5); //Sending the second digit in the number of words in the packet Serial.print("Packet send:"); // Printing “Packet sendᾍ Serial.println(a); a=a+1; if (a>=256) { a=0; } lt.startListening(); //We switch to the reception part delay(1000); if (lt.available()) { uint8_t buf[32]; int packetSize = lt.read(buf, 32); if (packetSize > 0) { Serial.println(F("Packet read OK")); // If packet received print “Packet read OKᾍ for(int i = 0; i < packetSize; i++) { Serial.print(i); Serial.print("="); Serial.println(buf[i]); } } } else { Serial.println(F("Packet read --")); } } Video microcontroller-projects/wireless-controlled-shutter-button-for-dslr-using-arduino-and-nrf24l01

Wireless Controlled Shutter Button for DSLR using Arduino and nRF24L01

In Wildlife Photography, there are situations where getting close to the subject may become life-threatening or dangerous, but at the same time, the photo needs to be captured. In sucha case,a wired switch that could control the camera from a long distance will be beneficial in such cases. What if it goes wireless? It will definitely be of great benefit for the photographer.

Components Required to Build Wireless Trigger for DSLR

Since this project deals with wireless control, a wireless receiver or transmitter is required. That is none other than NRF24L01 pairs. By using this with a microcontroller, data transfer can be done wirelessly. We used Arduino UNO and Arduino NANO for this one. Arduino UNO Board USB Cable with 5V Adapter or Power Bank - 2 Pcs Arduino NANO NRF24L01 - 2pcs 2.5mm JACK - Monotype. 5V converter (Requires if it is using 7.4V Lithium Battery)

DSLR Remote Trigger - Schematic Diagram

is shown below. On the other hand, the Receiver will receive the data and transfer this to the 2.5mm Jack. Both the transmitter and receiver circuit setup are shown below.

Explanation of the Circuit and Working

DSLR supports shutter remote input where existing wired remotes can be connected to trigger the shutter. This can be seen in the image given below. The connection of this pin can be seen in the image given below. available inside of the 2.5mm Jack. Now, when this tip gets 0V or Low, the shutter button gets released. This is done using the Arduino NANO. Whenever the Arduino Nano receives the data via NRF24L01 that the switch in the transmitter is pressed, it immediately makes the TIP of the connector to Low. Whenever the switch is pressed, the input pin where the switch is connected gets low. The Arduino further transmits this data via nRF24L01 to the transmitter. Also, the button on the transmitter side uses a debounce for false triggering issues. Another important module is the NRF24L201. This is used as a pair. Below is the pin diagram of NRF24L01. where we have mentioned all the necessary things to abort this module, you can check that out if you want to know more about these modules.

Arduino Code for Remote DSLR Trigger

There are two different codes used for this project, one for the Transmitter and the other one for the Receiver. The Libraries are included first. //Include Libraries #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include "printf.h" #include <ArduinoJson.h> The address is set, This must be the same for both transmitter and receiver. //address through which two modules communicate. const byte address[6] = {0xe1, 0xe1, 0xe1, 0xe1, 0xe1}; A boolean is created where the trigger state will be changed from true to false or vice versa. volatile bool isTrigger = false; The next step is to start the NRF24L01 before running the actual application. Here, the range, data type, and state are also set. The nRF24L01 is set as a transmitter, and it is also set for the long-range distance with maximum RF Power. Also, putthe address that was previously set. void setup() { Serial.begin(9600); printf_begin(); Serial.println(F("\n\rRF24/examples/scanner/")); // Setup and configure rf radio radio.begin(); radio.setAutoAck(false); //set the address radio.openWritingPipe(address); radio.setPALevel(RF24_PA_MIN); //set as: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate(RF24_2MBPS); //set as: F24_250KBPS, F24_1MBPS, F24_2MBPS ==>250KBPS = longest range radio.setChannel(115); //sets channel from 2.4 to 2.524 GHz in 1 MHz increments 2.483.5 GHz is normal legal limit radio.setCRCLength(RF24_CRC_8); // radio.printDetails(); //Set module as transmitter radio.stopListening(); After setting the Transmitter nRF24L01, it is time to set the button input that will be pressed by the user during the trigger. The pin is set as input mode. pinMode(SHUTT_REMOTE_TRIGGER_PIN, INPUT); // sets the digital pin "SHUTT_TRIGGER_PIN" as output // attachInterrupt(digitalPinToInterrupt(SHUTT_REMOTE_TRIGGER_PIN), shutter_remote_trigger, LOW); // attachInterrupt(digitalPinToInterrupt(SHUTT_REMOTE_TRIGGER_PIN), shutter_remote_trigger, HIGH ); } void shutter_remote_trigger() { isTrigger = true; } // Variables will change: int ledState = HIGH; // the current state of the output pin int buttonState; // the current reading from the input pin int lastButtonState = LOW; // the previous reading from the input pin // the following variables are unsigned longs because the time, measured in // milliseconds will quickly become a bigger number than can be stored in an int. unsigned long lastDebounceTime = 0; // the last time the output pin was toggled unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers In the loop, the button state is constantly monitored and whenever it is pressed, a JSON is sent to the receiver. void loop() { // read the state of the switch into a local variable: int reading = digitalRead(SHUTT_REMOTE_TRIGGER_PIN); // check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited long enough // since the last press to ignore any noise: // If the switch changed, due to noise or pressing: if (reading != lastButtonState) { // reset the debouncing timer lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer than the debounce // delay, so take it as the actual current state: // if the button state has changed: if (reading != buttonState) { buttonState = reading; // only toggle the LED if the new button state is LOW if (buttonState == LOW) { isTrigger = true; } } } // save the reading. Next time through the loop, it'll be the lastButtonState: lastButtonState = reading; if (true == isTrigger) { // Allocate the JSON document // // Inside the brackets, 200 is the RAM allocated to this document. // Don't forget to change this value to match your requirement. // Use arduinojson.org/v6/assistant to compute the capacity. StaticJsonDocument<50> doc; doc[SHUTT_TRIGGER_JSON_KEY] = SHUTT_TRIGGER_ACTIVE; //Send message to receiver char send_dt[32] = {0}; String output; //serializeJson(doc, Serial); serializeJson(doc, send_dt); Serial.println(send_dt); radio.write(&send_dt, sizeof(send_dt)); isTrigger = false; } delay(10); } This code is similar to the transmitter, but after receiving the bit, it provides data for the trigger. The Libraries are included first. //Include Libraries #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include "printf.h" #include <ArduinoJson.h> The address is set, as discussed before, this address must be the same for both transmitter and receiver. It is given previously in the transmitter address section as well. //address through which two modules communicate. const byte address[6] = {0xe1, 0xe1, 0xe1, 0xe1, 0xe1}; The next step is to start the nRF24L01 before running the actual application. Here, the range,data type, and the state are also set the same as the transmitter section, but here it is set as a receiver instead ofa transmitter. It is also set for the long-range distance with maximum RF Power. It also putsthe address that was previously set. void setup() { Serial.begin(9600); printf_begin(); //Serial.println(F("\n\rRF24/examples/scanner/")); // Setup and configure rf radio radio.begin(); radio.setAutoAck(false); radio.openReadingPipe(0, address); radio.setPALevel(RF24_PA_MIN); //set as: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate(RF24_2MBPS); //set as: F24_250KBPS, F24_1MBPS, F24_2MBPS ==>250KBPS = longest range radio.setChannel(115); //sets channel from 2.4 to 2.524 GHz in 1 MHz increments 2.483.5 GHz is normal legal limit radio.setCRCLength(RF24_CRC_8); // Get into standby mode radio.startListening(); After setting the Receiver nRF24L01, it is time to put the logic to set the shutter pin low if the JSON is received that has the information of the button being pressed. void loop() { digitalWrite(SHUTT_TRIGGER_PIN, HIGH); //Read the data if available in buffer if (radio.available()) { // Allocate the JSON document // // Inside the brackets, 200 is the capacity of the memory pool in bytes. // Don't forget to change this value to match your JSON document. // Use arduinojson.org/v6/assistant to compute the capacity. StaticJsonDocument<50> doc; char recv_dt[32] = {0}; radio.read(&recv_dt, sizeof(recv_dt)); Serial.println(recv_dt); // Deserialize the JSON document DeserializationError error = deserializeJson(doc, recv_dt); // Test if parsing succeeds. if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); //return; } else { // Fetch values. // // Most of the time, you can rely on the implicit casts. // In other case, you can do doc["time"].as<long>(); char s_trig_stat = doc[SHUTT_TRIGGER_JSON_KEY]; if (SHUTT_TRIGGER_ACTIVE == s_trig_stat) { Serial.println("Set Shutter pin Low"); digitalWrite(SHUTT_TRIGGER_PIN, LOW); // sets the digital pin "SHUTT_TRIGGER_PIN" on digitalWrite(LED_BUILTIN, HIGH); delay(250); // waits for a 250 millisecond } } digitalWrite(LED_BUILTIN, LOW); } }

Testing

To test the circuit, the transmitter and receiver circuit is constructed properly. A 2.5mm mono jack is used with the DSLR and tested for the circuitry operations. Below are the images of the setup. To check the full testing and working, please watch the video givenbelow. And if you have any questions regarding this project, feel free to comment down below. Code #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include "printf.h" #include <ArduinoJson.h> //create an RF24 object RF24 radio(9, 8); // CE, CSN //address through which two modules communicate. const byte address[6] = {0xe1, 0xe1, 0xe1, 0xe1, 0xe1}; //DSLR Shutter Trigger Operation's variable #define SHUTT_TRIGGER_JSON_KEY "s_trig" #define SHUTT_TRIGGER_ACTIVE 100 #define SHUTT_TRIGGER_INACTIVE 0 #define SHUTT_REMOTE_TRIGGER_PIN 4 volatile bool isTrigger = false; void setup() { Serial.begin(9600); printf_begin(); Serial.println(F("\n\rRF24/examples/scanner/")); // Setup and configure rf radio radio.begin(); radio.setAutoAck(false); //set the address radio.openWritingPipe(address); radio.setPALevel(RF24_PA_MIN); //set as: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate(RF24_2MBPS); //set as: F24_250KBPS, F24_1MBPS, F24_2MBPS ==>250KBPS = longest range radio.setChannel(115); //sets channel from 2.4 to 2.524 GHz in 1 MHz increments 2.483.5 GHz is normal legal limit radio.setCRCLength(RF24_CRC_8); // radio.printDetails(); //Set module as transmitter radio.stopListening(); pinMode(SHUTT_REMOTE_TRIGGER_PIN, INPUT); // sets the digital pin "SHUTT_TRIGGER_PIN" as output // attachInterrupt(digitalPinToInterrupt(SHUTT_REMOTE_TRIGGER_PIN), shutter_remote_trigger, LOW); // attachInterrupt(digitalPinToInterrupt(SHUTT_REMOTE_TRIGGER_PIN), shutter_remote_trigger, HIGH ); } void shutter_remote_trigger() { isTrigger = true; } // Variables will change: int ledState = HIGH; // the current state of the output pin int buttonState; // the current reading from the input pin int lastButtonState = LOW; // the previous reading from the input pin // milliseconds will quickly become a bigger number than can be stored in an int. unsigned long lastDebounceTime = 0; // the last time the output pin was toggled unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers void loop() { // read the state of the switch into a local variable: int reading = digitalRead(SHUTT_REMOTE_TRIGGER_PIN); // check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited long enough // since the last press to ignore any noise: // If the switch changed, due to noise or pressing: if (reading != lastButtonState) { // reset the debouncing timer lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer than the debounce // delay, so take it as the actual current state: if (reading != buttonState) { buttonState = reading; // only toggle the LED if the new button state is LOW if (buttonState == LOW) { isTrigger = true; } } } // save the reading. Next time through the loop, it'll be the lastButtonState: lastButtonState = reading; if (true == isTrigger) { // Allocate the JSON document // // Inside the brackets, 200 is the RAM allocated to this document. // Don't forget to change this value to match your requirement. // Use arduinojson.org/v6/assistant to compute the capacity. StaticJsonDocument<50> doc; doc[SHUTT_TRIGGER_JSON_KEY] = SHUTT_TRIGGER_ACTIVE; //Send message to receiver char send_dt[32] = {0}; String output; //serializeJson(doc, Serial); serializeJson(doc, send_dt); Serial.println(send_dt); radio.write(&send_dt, sizeof(send_dt)); isTrigger = false; } delay(10); } Receiver Code - //Include Libraries #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include "printf.h" #include <ArduinoJson.h> //create an RF24 object RF24 radio(9, 8); // CE, CSN //address through which two modules communicate. const byte address[6] = {0xe1, 0xe1, 0xe1, 0xe1, 0xe1}; //DSLR Shutter Trigger Operation's variable #define SHUTT_TRIGGER_JSON_KEY "s_trig" #define SHUTT_TRIGGER_ACTIVE 100 #define SHUTT_TRIGGER_INACTIVE 0 #define SHUTT_TRIGGER_PIN 4 void setup() { Serial.begin(9600); printf_begin(); //Serial.println(F("\n\rRF24/examples/scanner/")); // Setup and configure rf radio radio.begin(); radio.setAutoAck(false); radio.openReadingPipe(0, address); radio.setPALevel(RF24_PA_MIN); //set as: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate(RF24_2MBPS); //set as: F24_250KBPS, F24_1MBPS, F24_2MBPS ==>250KBPS = longest range radio.setChannel(115); //sets channel from 2.4 to 2.524 GHz in 1 MHz increments 2.483.5 GHz is normal legal limit radio.setCRCLength(RF24_CRC_8); // Get into standby mode radio.startListening(); pinMode(LED_BUILTIN, OUTPUT); pinMode(SHUTT_TRIGGER_PIN, OUTPUT); // sets the digital pin "SHUTT_TRIGGER_PIN" as output digitalWrite(SHUTT_TRIGGER_PIN, HIGH); // sets the digital pin "SHUTT_TRIGGER_PIN" off } void loop() { digitalWrite(SHUTT_TRIGGER_PIN, HIGH); //Read the data if available in buffer if (radio.available()) { // Allocate the JSON document // // Inside the brackets, 200 is the capacity of the memory pool in bytes. // Don't forget to change this value to match your JSON document. // Use arduinojson.org/v6/assistant to compute the capacity. StaticJsonDocument<50> doc; char recv_dt[32] = {0}; radio.read(&recv_dt, sizeof(recv_dt)); Serial.println(recv_dt); // Deserialize the JSON document DeserializationError error = deserializeJson(doc, recv_dt); // Test if parsing succeeds. if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); //return; } else { // Fetch values. // // Most of the time, you can rely on the implicit casts. // In other case, you can do doc["time"].as<long>(); char s_trig_stat = doc[SHUTT_TRIGGER_JSON_KEY]; if (SHUTT_TRIGGER_ACTIVE == s_trig_stat) { Serial.println("Set Shutter pin Low"); digitalWrite(SHUTT_TRIGGER_PIN, LOW); // sets the digital pin "SHUTT_TRIGGER_PIN" on digitalWrite(LED_BUILTIN, HIGH); delay(250); // waits for a 250 millisecond } } digitalWrite(LED_BUILTIN, LOW); } } Video microcontroller-projects/iot-based-live-scoreboard-using-arduino-and-p10-display

IoT Based IPL Scoreboard using Arduino to Display Live Score using Cric API

using NodeMCU and P10 display Module, which will be big enough to display the live score and it will be very easy and simple to make. Solet’s dive into the complete process of building the project. , you can check that out if you want to learn more about the display itself. We have also built many IoT related projects:

Components Required to Build IoT Score Board

The project is relatively simple and there are not many components required. Just gather the items listed below. Arduino Nano ESP8266 NodeMCU Perf board Male and Female headers 9V DC, 2 Amp Power supply 5AMP, 3 AMP SMPS Connecting wires

Node MCU and Arduino Based IoT Score-Board Working

to the Arduino Uno. Then Arduino sends the required information which needs to be displayed to the p10 display.

Basic Working Principle of P10 LED Matrix Module

is a very popular matrix display builtto advertise outdoor or indoor conditions. Each p10 display module has a total of 512 high brightness LEDs mounted on a plastic housing designed for best display results. Any number of such panels can be combined in any row and column structures to design a LED notice/advertisement board. The 32*16 module size means that there are 32 LEDs in each row and 16 LEDs in each column. So there are 512LEDs present in each module unit. It also needs a separate 5V power supply to power the logic section. It has an IP65 waterproof rating so it can be easily used outdoors in humid and rainy weather. Enable: This pin is used to control the brightness of the LED panel by giving PWM pulse to it. A, B: These are called multiplex select pins. They take digital input to select any multiplex rows. Shift clock (CLK), Store clock (SCLK), and Data: These are the normal shift register control pins. Here, a shift register 74HC595 is used. Arduino UNO and P10 display modules are interconnected as per the pin mapping shown below:
ENABLE9
A6
B7
CLK13
SCLK8
DATA11
GNDGND
Important Note: Connect the power terminal of the P10 module to 5V DC SMPS separately. It is recommended to connect a 5V, 3 Amp DC power supply to a single unit of P10 LED module. If you are planning to connect more modules, then increase your SMPS rating accordingly.

NodeMCU and IoT Based Live Score Board - Schematic Diagram

is shown above. As shown in the circuit diagram, first a 9V DC power supply is connected to Arduino Nano, and the regulated 5V DC supply from Arduino is supplied to the NodeMCU. For communication between Arduino and NodeMCU, TX and RX pins are used, which are connected as shown in the diagram. Finally, the P10 display is connected to Arduino as per the circuit diagram shown above. In this project, all the connections have been made as per the above diagram and soldered in a perfboard. After completion of the circuit diagram, the Circuit board looks like as shown in the image below: After successful connection, I have connected the board to the p10 display and enclosed the circuit in an enclosure as shown below:

Software Setup For IoT Based Score Board

and sign upto create a new account. We can also log in using our Google account. Login to your CricAPI account, which is free up to 100 hits/day. The dashboard looks like below: ᾠoption. A window will appear as shown below, which consists of a URL and sample output. Copy the URL for our future reference. I am in India and I love cricket so I am configuring it to display the cricket score. Ifyou want it to configure it for any other purpose, you can do it very easily by altering the code a little bit.

NodeMCU and IoT based Live Cricket Board Code

In this section, we will be discussing the code that is required to get the data from the HTTP website and display it to the P10 display as we are using a NodeMCU and an Arduino so these will be divided into two sections. First Arduino code configures the NodeMCU and the second one configures the Arduino Nano. If you are uploading the code to nodeMCU for the first time, then you have to include the board first, using the following steps. To upload code to NodeMCU, follow the steps below: ᾠfield and click ‘Okᾮ in the search box, select the latest version of the board, and click on install. Now you can program NodeMCU with Arduino IDE. is used for using JSON library which is used to receive information from CricAPI. #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <ArduinoJson.h> Now, the network credentials are defined, i.e. SSID and password. It is required to connect NodeMCU to the internet. const char* ssid = "admin"; const char* password = "123456789"; is called passing SSID and password as its arguments. Also, initialize the Serial communication with Baud rate=115200. Serial.begin(115200);W iFi.begin(ssid, password); () function to get the information. http.begin("http://cricapi.com/api/cricketScore?apikey=rd0uOcJvvxUCbNlzlsGWyJt3gP53&unique_id=1254075"); Now, verify the received JSON file by reading it and print JSON data on the serial monitor. Then if the data received is correct, print it on Serial to send it to Arduino. int httpCode = http.GET(); if (httpCode > 0) { String payload = http.getString(); const size_t bufferSize = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(8) + 370; DynamicJsonBuffer jsonBuffer(bufferSize); JsonObject& root = jsonBuffer.parseObject(http.getString()); const char* name1 = root["description"]; Serial.println(name1); delay(10000); } After the code is complete, compile the code and upload it to the NodeMCU. After successful uploading, now it’s time to write code for Arduino. Similar to NodeMCU, we need to program the Arduino before we can move forward and complete the code. ᾠare used in this code, both of the libraries can be downloaded by following the link given below. After you have downloaded and included both the libraries, start the code by including all the required libraries. #include <SPI.h> #include <DMD.h> #include <TimerOne.h> #include "SystemFont5x7.h" #include "Arial_black_16.h" In the next step, the number of rows and columns is defined for the LED matrix. Here in this project, only one module is used, so both ROW value and COLUMN value can be defined as 1. #define ROW 1 #define COLUMN 1 #define FONT Arial_Black_16 DMD led_module(ROW, COLUMN); is defined, which continuously checks for any incoming data from Arduino Nano through the SPI Terminals. If yes, then it will trigger an interrupt for doing certain events as defined by the user in the program. void scan_module() { led_module.scanDisplayBySPI(); } which means all the pixels are defined as OFF. where 115200 is the baud rate for the Serial communication. void setup() { Serial.begin(115200); Timer1.initialize(2000); Timer1.attachInterrupt(scan_module); led_module.clearScreen( true ); } Here, the serial data availability is checked, if there is valid data coming from nodeMCU or not. The received data is stored in a variable and then printed on the p10 display. void loop() { if (Serial.available()) { data=Serial.readString(); } Serial.println(data); (String("Score:")+String(data)).toCharArray(cstr1, 100); led_module.selectFont(FONT); function is used to display the desired information on the p10 board. led_module.drawMarquee(cstr1,100, (32 * ROW), 0); long start = millis(); long timming = start; boolean flag = false; Finally, as we need a scrolling message display, we have written a code to shift our whole message from Right to Left directions using a certain period. while (!flag) { if ((timming + 30) < millis()) { flag = led_module.stepMarquee(-1, 0); timming = millis(); } } } After completion of the Code, compile the code and upload it to Arduino. Then switch ON the Power supply and make sure that the Network Router/Hotspot device is turned ON. After some time, the NodeMCU will be connected to Network and the live scores will be shown on the display. This marks the end of our project. If you have any questions regarding the article, you can leave a commentbelow. Code #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <ArduinoJson.h> const char* ssid = "admin"; const char* password = "123456789"; int count = 0; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); } } void loop() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin("http://cricapi.com/api/cricketScore?apikey=rd0uOcJvvxUCbNlzlsGWyJt3gP53&..."); int httpCode = http.GET(); if (httpCode > 0) { String payload = http.getString(); const size_t bufferSize = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(8) + 370; DynamicJsonBuffer jsonBuffer(bufferSize); JsonObject& root = jsonBuffer.parseObject(http.getString()); const char* name1 = root["description"]; Serial.println(name1); delay(10000); } http.end(); } } #include <SPI.h> #include <DMD.h> #include <TimerOne.h> #include "SystemFont5x7.h" #include "Arial_black_16.h" #define ROW 1 #define COLUMN 1 #define FONT Arial_Black_16 char input; int a = 0, b = 0; int flag = 0; char cstr1[100]; DMD led_module(ROW, COLUMN); String data=""; void scan_module() { led_module.scanDisplayBySPI(); } void setup() { Serial.begin(115200); Timer1.initialize(2000); Timer1.attachInterrupt(scan_module); led_module.clearScreen( true ); } void loop() { if (Serial.available()) { data=Serial.readString(); } Serial.println(data); (String("Score:")+String(data)).toCharArray(cstr1, 100); led_module.selectFont(FONT); led_module.drawMarquee(cstr1,100, (32 * ROW), 0); long start = millis(); long timming = start; boolean flag = false; while (!flag) { if ((timming + 30) < millis()) { flag = led_module.stepMarquee(-1, 0); timming = millis(); } } } Video microcontroller-projects/interfacing-nrf24l01-rf-module-with-pic-microcontroller

Interfacing nRF24L01 RF Module with PIC Microcontroller

By doing so we can get a clearer idea about how the communication process works, solet's get right into it. In our previous articles, we have made many interesting projects that include IoT and NRF modules, a list of some of those is given below; you can check that out if you are interested in the topic. Fast Arduino RC Card using Coreless DC Motors and nRF24L01 RF module Wireless Communication Between Raspberry Pi and Arduino Long Range Arduino Based Walkie Talkie

What is the nRF24L01 2.4GHz RF Transceiver Module?

for that reason, we can either send or receive data at a time. The nRF24L01 comes with a 2.4GHz RF band and which is legal to use for Industrial, Scientific, and Medical purposes. For better understanding, the pinout of this module is shown below. As this module communicates via SPI, it is very easy to pair with any microcontroller over the SPI bus. Also, this module has a very high transfer speed of 250Kbps to 2Mbps for long-range communication 100m to 1000m. As we have mentioned earlier, this module has two variants,the cheaper one does not offer the PA+LNA but the more expensive one offers a built-in PA+LNA that can boost the output signal of this module to 3dBm. This module operates under a supply voltage of 1.9V to 3.6V and consumes only 13.5mA of current and in deep sleep mode,it consumes 26uA. One very interesting fact of this module is that the SPI pins of this module are 5V tolerant so we can directly communicate this module with Arduino without a Logic level converter.

Components Required to Build the nRF24L01 Based Test Circuit

The component required to build this project is very generic and most of these can be found in your local hobby store. A list of required components is given below. PIC Microcontroller (PIC18F46K22) - 1 Arduino Uno/Nano any - 1 nRF24L01- 1 20MHz crystal oscillator for PIC - 1 33pf Capacitor - 2 4.7k, 100E Resistor - 1 10uF and 0.1uF for nRF24L01 Decoupling Capacitor - 2 PicKit3 Programmer - 1 Led - 1 Push Button - 1 Bread Board Jumper wires 12V adapter and Breadboard power supply to Power up the PIC and nRF24L01 card module MPLAB-X IDE and xc8 compiler. Arduino IDE

Schematic Used to Connect the nRF24L01 With PIC18F46K22 Microcontroller

is shown below. in the power supply line. The capacitor can be 10uF and 0.1uF. The 3.3V pin on Arduino boards may not always provide adequate power to the nRF24L01 module. So, it is also a good idea to strengthen the module with an external power source. For our demonstration, we have directly soldered the capacitor onto the pin of the nRF module.

Program to Establish Communication Between nRF24L01 Module with PIC and Arduino Microcontroller

to configure the program for (PIC18F46K22). The complete program can be found at the bottom of this page. Note: For convenience, we have ported the NRF library from Arduino, and you can get that by clickon the download link below. Download Complete code with Ported Arduino Library for PIC18F622K Microcontroller Those libraries mentioned above are included at the beginning of the code. #include "mcc_generated_files/mcc.h" #include "nrf24_lib.h" #include <string.h> value to 1 for Tx operation and 0 for Rx operation. #define NRF24L01_TX_EX 0 #define NRF24L01_RX_EX !NRF24L01_TX_EX about 1sec time interval. This is our heartbeat indicator LED that will blink in conjunction with a timer. This is an indicator that our system is working properly. void blink_led() { LED_Toggle(); } function to initialize the system peripheral like (INTERRUPT, Pin, Timer0, UART, SPI1) and enable the Global and Peripheral Interrupt. void main(void) { // Initialize the device SYSTEM_Initialize(); // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global and Peripheral Interrupts // Use the following macros to: // Enable the Global Interrupts INTERRUPT_GlobalInterruptEnable(); // Disable the Global Interrupts //INTERRUPT_GlobalInterruptDisable(); // Enable the Peripheral Interrupts INTERRUPT_PeripheralInterruptEnable(); // Disable the Peripheral Interrupts //INTERRUPT_PeripheralInterruptDisable(); function set the callback function, and then start the Timer0. TMR0_SetInterruptHandler(blink_led); TMR0_StartTimer(); function along with the nRF24L01 Operation mode(Tx or Rx) and the RF channel frequency (0-127). After successfully initializingthe nRF24, print the current configure nRF24’s Register Maps setting. #if NRF24L01_TX_EX ret = nrf24_rf_init(TX_MODE, 115); // Tx mode with 2400+115 Ghz RF frq #elif NRF24L01_RX_EX ret = nrf24_rf_init(RX_MODE, 115); // Rx mode with 2400+115 Ghz RF frq #endif if (ret == NRF24_INIT_OK) { printf("###############################################################\r\n"); printf("NRF24L01 Initialize successful\r\n"); nrf24_printf_rf_config(); printf("###############################################################\r\n"); After initializing the nRF24, we execute the Tx and Rx operation process in a while loop. & increment the integer variable value. #if NRF24L01_TX_EX static char val = 0; sprintf(bufferTX, "Sending: %d", val); nrf24_send_rf_data(bufferTX); val++; __delay_ms(100); to get the received data into the buffer and print the buffer. #elif NRF24L01_RX_EX while (nrf24_is_rf_data_available()) { } nrf24_read_rf_data(bufferRX); printf("RX data %s\r\n", bufferRX); __delay_ms(10); #endif On the Arduino side of things, we start our code by including all the required libraries. The library includes RF24 to access nRF24L01 commands, SPI library, and printf library. And we also include some machines that we are going to use to set the module as transmitter and receiver. //Include Libraries #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include "printf.h" #define NRF24L01_TX_EX 1 #define NRF24L01_RX_EX !NRF24L01_TX_EX Next, we create an instance for the RF24 and we pass on the CE and CSN PIN we also hold the address through which we are going to communicate with the module. //create an RF24 object RF24 radio(9, 8); // CE, CSN //address through which two modules communicate. const byte address[6] = {0xe1, 0xe1, 0xe1, 0xe1, 0xe1}; Next, we have our setup function. In the setup function, we initial the serial monitor for debugging and we also set up the NRF24 Radio. Serial.begin(115200); printf_begin(); Serial.println(F("\n\rRF24/examples/scanner/")); // Setup and configure rf radio radio.begin(); radio.setAutoAck(false); Now, remember the two macros that we have defined up to.with the help of these macros, you can set up the module as a transmitter or receiver very easily. #if NRF24L01_TX_EX //set the address radio.openWritingPipe(address); radio.setPALevel(RF24_PA_MIN); //set as: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate(RF24_2MBPS); //set as: F24_250KBPS, F24_1MBPS, F24_2MBPS ==>250KBPS = longest range radio.setChannel(115); //sets channel from 2.4 to 2.524 GHz in 1 MHz increments 2.483.5 GHz is normal legal limit radio.setCRCLength(RF24_CRC_8); radio.printDetails(); //Set module as transmitter radio.stopListening(); #elif NRF24L01_RX_EX radio.openReadingPipe(0, address); radio.setPALevel(RF24_PA_MIN); //set as: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate(RF24_2MBPS); //set as: F24_250KBPS, F24_1MBPS, F24_2MBPS ==>250KBPS = longest range radio.setChannel(115); //sets channel from 2.4 to 2.524 GHz in 1 MHz increments 2.483.5 GHz is normal legal limit radio.setCRCLength(RF24_CRC_8); // Get into standby mode radio.startListening(); radio.stopListening(); radio.printDetails(); // Get into standby mode radio.startListening(); #endif function, we send one character at a time and we also print the value on the serial monitor window for debugging. And finally, we end our code with a delay of 250ms, at last, this will give us the module additional stability. void loop() { #if NRF24L01_TX_EX //Send message to receiver char text[32] = {0}; sprintf(text, "Hello PIC18 %d", val++); radio.write(&text, sizeof(text)); Serial.println(text); #elif NRF24L01_RX_EX //Read the data if available in buffer if (radio.available()) { char text[32] = {0}; radio.read(&text, sizeof(text)); Serial.println(text); } #endif delay(250); }ᾍ

Testing and Debugging the Communication Process

Once the circuit and code were complete, we tested the circuit with the help of the debug log that we have put in our code. As you can see, we have used an Arduino IDE serial monitor to UART converter to log debug data for Arduino UNO, and for the PIC microcontroller, we use aPuTTY serial monitor. message on the Arduino IDE serial monitor. Then we look into the PuTTY serial monitor to verify that the received data message is the same or not at the PIC microcontroller side. The below image show exactly that. message into the PuTTY serial monitor, then we look into the Arduino IDE serial monitor to verify that the received data message is the same or not at the Arduino side. Video microcontroller-projects/interfacing-rdm6300-rfid-reader-module-interfacing-with-arduino-nano

Interfacing RDM6300 RFID Reader Module with Arduino

Nano. The RDM6300 RFID Reader is one type of RFID module with a 125 kHz frequency. This RFID module can read data from 125 kHz compatible read-only tags and read/write 125 kHz cards.

Components Required for Interfacing RDM6300 with Arduino

Arduino Nano RDM6300 RFID Reader Module 125 kHz Tags Jumper Wires Breadboard

RDM6300 RFID Reader Module

The RDM6300 125 kHz EM4100 RFID Card ID Reader Module is designed to read and write data from 125 kHz compatible tags. It can be used in surveillance systems for workplaces and residences, personal authentication, access management, anti-forgery, digital toys, and output control systems, among other items. RDM6300 Series non-contact RFID board uses an advanced RF receiver circuit and built-in MCU architecture, combined with a high-efficiency decoding algorithm, to read the EM4100 and all the compatible cards. It uses serial TTL at a 9600 baud rate to transmit the RFID tag data. Any microcontroller with UART serial peripheral can be used to work with this RFID reader.
5VPower Supply Pin
GNDGround
RXData Receive pin
TXData Transmit pin
ANT1Antenna connection pin
ANT2Antenna connection pin
Operating Frequency: 125KHZ Baud Rate: 9600 Interface: TTL level RS232 format Working voltage: DC 5V Working current: <50mA Receive distance: 20~50mm Dimension (mm): 38.5 x 20 Weight: 7g The RDM6300 RFID module is similar to the EM-18 RFID reader module. Both the modules have the same operating frequency i.e. 125 KHz and support Serial RS232/TTL output while the operating frequency for RC522 is 13.56 kHz.

Circuit Diagram for Interfacing RDM6300 with Arduino

The schematic for Interfacing RDM6300 RFID Reader Module with Arduino is given below: Wire up the Arduino to the RDM6300 RFID Reader Module as shown in the diagram. The 5V and GND pin of the RDM6300 module is connected to the 5V and GND pin of Arduino Nano while the TX pin of the module is connected to D6 of Nano. The RX pin is not required as we do not send data to the RFID module in this tutorial. Lastly, connect the antenna to ANT1 and ANT2 pin in any polarity.

Programming Arduino for RDM6300 RFID Reader

to read the data. The complete code is given at the end of the document. An explanation of the code is as follows: Start the code by including the RDM6300 RFID Reader library. #include <rdm6300.h> Then define all the necessary pins that are required to read the sensor data and control the LED. #define RDM6300_RX_PIN 6 function, initialize the serial monitor at 9600 for debugging purposes. Also, initialize the RFID Reader Module. void setup() { Serial.begin(9600); rdm6300.begin(RDM6300_RX_PIN); Serial.println("\nPlace RFID tag near the rdm6300..."); } function, check if the tag is near, if yes, then read the tag number and print it on Serial Monitor. void loop() { if (rdm6300.update()) Serial.println(rdm6300.get_tag_id(), HEX); delay(10); }

Testing the RDM6300 RFID Reader

Once your code and hardware are ready, connect Arduino to the laptop and upload the code. After that, open the serial monitor at a baud rate of 9600, and scan the RFID tag on the Module’s Antenna. Tag number will be printed on the serial monitor. This is how you can interface RDM6300 RFID Reader with Arduino. The complete working of the project can be found in the video given below; if you have any questions, feel free to write them in the comment section below. Code #include <rdm6300.h> #define RDM6300_RX_PIN 2 #define READ_LED_PIN 13 Rdm6300 rdm6300; void setup() { Serial.begin(9600); pinMode(READ_LED_PIN, OUTPUT); digitalWrite(READ_LED_PIN, LOW); rdm6300.begin(RDM6300_RX_PIN); Serial.println("\nPlace RFID tag near the rdm6300..."); } void loop() { /* if non-zero tag_id, update() returns true- a new tag is near! */ if (rdm6300.update()) Serial.println(rdm6300.get_tag_id(), HEX); digitalWrite(READ_LED_PIN, rdm6300.is_tag_near()); delay(10); } Video microcontroller-projects/interfacing-rcwl-0516-doppler-radar-sensor-with-arduino

Interfacing RCWL-0516 Doppler Radar Sensor with Arduino

, it senses the change in ambient infrared energy caused when a warm body enters the monitored area. Nano. The RCWL-0516 is a motion detection sensor. It can detect motion through doppler microwave technology through walls or other materials. It will get triggered not only by people but also by other moving objects. Later on, in this tutorial, we will compare the RCWL-0516 motion sensor with the PIR sensor.

Components Required

Arduino Nano RCWL-0516 Doppler Radar Sensor LED 220 Resistor

RCWL-0516 Doppler RADAR Motion Sensor

The RCWL-0516 Doppler RADAR Motion Sensor module has been designed as an alternative to the common PIR motion sensors that are widely used by hobbyists and in burglar alarms and security lights. The PIR sensor detects motion by sniffing the black body radiation from a moving person. On the other hand, the RCWL-0516 sensor uses the Microwave Doppler radar technology to detect moving objects. The Doppler radar works by transmitting a microwave signal to a target and then analyzing the change in the frequency of the returned signal. The variation in the received signal frequency can also help measure the target’s velocity with respect to the radar. This sensor module uses an RCWL-9196 chip that supports repeat trigger and a 360-degree detection area with no blind spot. It can detect motion through walls and other materials and have a sensitivity range of 7 meters.
3V33.3V regulated output. Max 100mA
GNDGround
OUTTrigger: high (3.3V) if motion detected. 0V normally
VIN4 - 28V Supply Voltage
CDSSensor disable input (low = disable)
The Motion detection range and Repeat trigger time of the module can be adjusted by adding passive components in their respective solder pads located on the back of the board. There is also an option to add LDR, and a sensor disabledinput pin is available to turn off the detecting function at night if necessary.
C-TMRegulate the repeat trigger time. The default time is 2s. An SMD capacitor will extend the repeat trigger time.
R-GNDetection distance adjustment. Default detection range is 7m, adding a 1M resistor reduces it to 5m
R-CDSThe VCC is in parallel connection with CDS through R-CDS. Connect the LDR at the R-CDS to turn off the detecting function at night
Supply Voltage: 4ᾲ8 VDC Operating frequency: ~3.2 GHz Transmit power: 20 mW (typical)/30 mW (max) Sensing Distance: 5ᾷ m Output Level: 3.4V High <0.7 Low Output Drive: 100mA Output Timing: 2sec Retrigger with motion

Circuit Diagram for interfacing RCWL-0516 with Arduino

is given below: and GND pin of RCWL-0516 is connected to the 5V and GND pin of Arduino Nano while the OUT pin of the sensor is connected to D12 of Nano. The LED is connected to the D3 pin of Nano.

Programming Arduino for Motion Detection using RCWL-0516 Sensor

The code for mode detection using Arduino Nano and RCWL-0516 Sensor is as simple as it gets. The complete code is given at the end of the article. The explanation of the code is as follows: Start the code by defining all the necessary pins that are required to read the sensor data and control the LED. int Sensor = 12; int LED = 3; function initialize the serial monitor at 9600 for debugging purposes. Also, set the sensor pin as input and the LED pin as output. void setup() { Serial.begin(9600); pinMode (Sensor, INPUT); pinMode (LED, OUTPUT); Serial.println("Waiting for motion"); } and the pin is valued greater than 0, then turn on the LED else turn off the LED. void loop() { int val = digitalRead(Sensor); //Read Pin as input if((val > 0) && (flg==0)) { digitalWrite(LED, HIGH); Serial.println("Motion Detected"); flg = 1; } if(val == 0) { digitalWrite(LED, LOW); Serial.println("NO Motion"); flg = 0; }

Testing the Motion Detection Sensor

Once your code and hardware are ready, connect Arduino to the laptop and upload the code. After that, open the serial monitor at a baud rate of 9600, and make some motion in front of the sensor. Observe LED and Serial monitor.

PIR vs. RCWL-0516 Doppler Radar Sensor

PIR detectors can detect the movement by sniffing the black body radiation from a moving person, and are ideally suited where a defined detection pattern is required, for example, a walkway. In order to have an effective coverage area, the PIR sensor must be mounted in the correct location at the right angle and can be easily misled by an attacker. On the other hand, Microwave sensors are ideal for large spaces. Microwave sensors have a much better sensibility compared to PIR sensors. They can sometimes false trigger due to things such as trees blowing in the wind. Although, itcan also detect motion through plastic, glass, and thin walls. Most PIR sensors are affected by the climate, mostly high temperatures. The sensibility of PIR sensors is also compromised if the ambient temperature is more than 35 degrees Celsius. Microwave sensors provide more stable performance and will function at temperatures as low as -20°C and as high as 45°C. Compared to PIR sensors, microwave sensors provide a longer life cycle and can still work correctly after 100,000 hours. All in all, both sensors are very good and at a reasonable distance. If you want an all-weather motion sensor that covers a broader area with good accuracy, then a Microwave Radar sensor is a good option. Video microcontroller-projects/arduino-based-encoder-motor-using-pid-controller

Design an Arduino Based Encoder Motor using PID Controller

is the most common application that you can find on the internet. Without a PID controller, doing the job manually can be a tedious process. And in this era of advanced digital electronics and microcontrollers, it became easier to design and implement a PID controller in any system. and we will understand the problems that are associated with it. Finally, we will solve those problems by implementing a PID based control algorithm with our favourite microcontroller,Arduino. , you can check that out if you are interested in topics like that.

What is a PID Controller and How does it Work?

, and you want to stop it in a certain position, this can be very difficult without PID because if you just cut the power, the car will absolutely miss its target because of its momentum. The image below will give you a better idea of the process. , and in this post, you will find a block diagram along with an equation. But what this equation even means and how do we implement it in our microcontroller?Good question, now follow along and you will understand how, , and then differentiated. After that, the three values are summed together to produce the output. Now in the controller, the Kp, Kd and Ki, parameters are called the gain. And they are adjusted or tuned to fulfill a certain set of requirements and by changing these values, you can adjust how sensitive your system becomes to each of these different parameters, either the P, I, or D parameters. Let me explain it by individually examining each parameter. the output is the error that is defined by the gain Kp. Asyou can see, when the error is large, the output will produce a large output, and when the error is zero, the output error is zero and when the error is negative, the output is negative as the error value changes over time, the integral will start to sum up the error starts, and it will multiply it with constant Ki. In this type of controller, it’s easy to see that the integral result is the area underneath the curve where the area shown in blue is the positive area and the area shown in yellow is the negative area. In a complicated system, the integral controller is used to remove constant errors in a control system. No matter how small is the constant error, eventually, the summation of the errors will be enough to adjust the controller output. In the above picture, the error is represented with the green line. , it’s the rate of change of the error that contributes to the output signal. When the change in error is moving relatively slowly, as an example we can use the starting position of the sine wave. The derivative output will be small as you can see in the above picture (represented by the green line). And faster the error changes,the largerthe output becomes. Now at this point, you can sum up the three outputs and you have the PID controller. But often you do not need all three controllers working together,instead, we could remove anyone by setting the setpoint to zero. For example, we can have a PI controller by setting the D value to zero, else we can have a PD controller by setting the I parameter to zero. Now that we have a clear idea, we can move onto the actual hardware example.

What is an Encoder Motor and how does it Work?

in detail, you can check that out if you want to know more about the topic. attached to the PCB. These hall sensors pick up the direction in which the motor is rotating, and with the help of a microcontroller, we can read it very easily.

Components Required to Build a PID Enabled Encoder Motor Controller

At this point, we have a good idea about the working of a PID controller and we also know our end objective. Based on that we have decided to use an Arduino and some other complementary components to build a circuit. Alist of those complementary components is shown below. Arduino Nano - 1 N20 Encode Motor - 1 BD139 - 2 BD140 - 2 BC548 - 2 100R Resistor - 2 4.7K Resistor - 2 Breadboard Jumper Wires Power Supply

Schematic Diagram for Testing PID Enabled Encoder Motor Controller

is shown below. The working principle of this circuit is very simple, and it's described below. are connected to the Pin 9 and pin 10 of the Arduino pin 9 and 10 are both PWM capable pins; the selected pins must have PWM functionality otherwise the code will not work. The PID controller controls the motor by controlling the PWM. Next, we have our H-bridge motor driver, the motor driver is so made that we can control the motor by only using two pins of the Arduino and it even prevents the motor from false triggering.

Arduino Code for PID Enabled Encoder Motor Controller

from the link given below or else you can use the board manager method to install the library. Download PID Controller Library for Arduino so we need to include that first. After that, we define all the necessary pins that are required to read the encoder and drive the motor. Once that is done, we define all the values for the Kp, Ki, and Kd. #include <PIDController.h> /* ENCODER_A and ENCODER_B pins are used to read the encoder * Data from the microcontroller, the data from the encoder * comes very fast so these two pins have to be interrupt enabled * pins */ #define ENCODER_A 2 #define ENCODER_B 3 /* the MOTOR_CW and MOTOR_CCW pins are used to drive the H-bridge * the H-bridge then drives the motors, These two pins must have to * be PWM enabled, otherwise the code will not work. */ #define MOTOR_CW 9 #define MOTOR_CCW 10 to set the constants, but there exist other methods that do the job very well. /*In this section we have defined the gain values for the * proportional, integral, and derivative controller I have set * the gain values with the help of trial and error methods. */ #define __Kp 260 // Proportional constant #define __Ki 2.7 // Integral Constant #define __Kd 2000 // Derivative Constant function. volatile long int encoder_count = 0; // stores the current encoder count unsigned int integerValue = 0; // stores the incoming serial value. Max value is 65535 char incomingByte; // parses and stores each character one by one int motor_pwm_value = 255; // after PID computation data is stored in this variable. PIDController pid_controller; method, and we also tuned the controller with the Kp, Ki and Kd values. And finally, we have set the limit for our PID controller output. void setup() { Serial.begin(115200); // Serial for Debugging pinMode(ENCODER_A, INPUT); // ENCODER_A as Input pinMode(ENCODER_B, INPUT); // ENCODER_B as Input pinMode(MOTOR_CW, OUTPUT); // MOTOR_CW as Output pinMode(MOTOR_CCW, OUTPUT); // MOTOR_CW as Output /* attach an interrupt to pin ENCODER_A of the Arduino, and when the pulse is in the RISING edge called the function encoder(). */ attachInterrupt(digitalPinToInterrupt(ENCODER_A), encoder, RISING); pidcontroller.begin(); // initialize the PID instance pidcontroller.tune(__Kp , __Ki , __Kd); // Tune the PID, arguments: kP, kI, kD pidcontroller.limit(-255, 255); // Limit the PID output between -255 to 255, this is important to get rid of integral windup! } and pass on the integer value that we just received from serial. Next, we print the received value for debugging. function. This marks the end of our loop section. void loop() { while (Serial.available() > 0) { integerValue = Serial.parseInt(); // stores the integerValue incomingByte = Serial.read(); // stores the /n character pidcontroller.setpoint(integerValue); // The "goal" the PID controller tries to "reach", Serial.println(integerValue); // print the incoming value for debugging if (incomingByte == '\n') // if we receive a newline character we will continue in the loop continue; } motor_pwm_value = pidcontroller.compute(encoder_count); //Let the PID compute the value, returns the calculated optimal output Serial.print(motor_pwm_value); // print the calculated value for debugging Serial.print(" "); if (motor_pwm_value > 0) // if the motor_pwm_value is greater than zero we rotate the motor in clockwise direction MotorCounterClockwise(motor_pwm_value); else // else, we move it in a counter-clockwise direction MotorClockwise(abs(motor_pwm_value)); Serial.println(encoder_count);// print the final encoder count. } Once true, we counter variable gets incremented. Otherwise, it gets decremented. void encoder() { if (digitalRead(ENCODER_B) == HIGH) // if ENCODER_B is high increase the count Encoder_count++; // increment the count else // else decrease the count Encoder_count--; // decrement the count } Next, we have the function which rotates the motor clockwise. When this function is called, it checks if the value is greater than 100 or not. If so, we rotate the motor in a clockwise direction otherwise we stop the motor. void motor_cw(int power) { if (power > 100) { analogWrite(MOTOR_CW, power); digitalWrite(MOTOR_CCW, LOW); } // both of the pins are set to low else { digitalWrite(MOTOR_CW, LOW); digitalWrite(MOTOR_CCW, LOW); } } The same is true for the function which rotates the motor counter-clockwise. When this function is called, we check the value and rotate the motor counter-clockwise. void motor_ccw(int power) { if (power > 100) { analogWrite(MOTOR_CCW, power); digitalWrite(MOTOR_CW, LOW); } else { digitalWrite(MOTOR_CW, LOW); digitalWrite(MOTOR_CCW, LOW); } } This marks the end of our coding section.

Testing the PID Enabled Motor Controller

The following setup is used to test the circuit. As you can see, I have used an electrical box with some double-sided tape to hold the motor in place,and I have used a small buck converter module to power the motor as the motor runs on a 3.3V. you can also see, we have connected a USB cable with the Arduino that is used to set the setpoint of the PID controller. We also get the debugging information from the Arduino with the USB. In this case, it gives the current encoder count. The image below will give you a better idea of the process. You can also check out the video at the bottom of the page for better understanding. Code #include <PIDController.h> /* ENCODER_A and ENCODER_B pins are used to read the encoder data from the microcontroller, the data from the encoder comes very fast so these two pins have to be interrupt enabled pins */ #define ENCODER_A 2 #define ENCODER_B 3 /* the MOTOR_CW and MOTOR_CCW pins are used to drive the H-bridge the H-bridge then drives the motors, This two pins must have to be PWM enabled, otherwise the code will not work. */ #define MOTOR_CW 9 #define MOTOR_CCW 10 /*In this section we have defined the gain values for the proportional,integral, and derivative controller i have set the gain values with the help of trial and error methods. */ #define __Kp 260 // Proportional constant #define __Ki 2.7 // Integral Constant #define __Kd 2000 // Derivative Constant volatile long int encoder_count = 0; // stores the current encoder count unsigned int integerValue = 0; // stores the incoming serial value. Max value is 65535 char incomingByte; // parses and stores each individual character one by one int motor_pwm_value = 255; // after PID computation data is stored in this variable. PIDController pidcontroller; void setup() { Serial.begin(115200); // Serial for Debugging pinMode(ENCODER_A, INPUT); // ENCODER_A as Input pinMode(ENCODER_B, INPUT); // ENCODER_B as Input pinMode(MOTOR_CW, OUTPUT); // MOTOR_CW as Output pinMode(MOTOR_CCW, OUTPUT); // MOTOR_CW as Output /* attach an interrupt to pin ENCODER_A of the Arduino, and when the pulse is in the RISING edge called the function encoder(). */ attachInterrupt(digitalPinToInterrupt(ENCODER_A), encoder, RISING); pidcontroller.begin(); // initialize the PID instance pidcontroller.tune(260, 2.7, 2000); // Tune the PID, arguments: kP, kI, kD pidcontroller.limit(-255, 255); // Limit the PID output between -255 to 255, this is important to get rid of integral windup! } void loop() { while (Serial.available() > 0) { integerValue = Serial.parseInt(); // stores the integerValue incomingByte = Serial.read(); // stores the /n character if (incomingByte == '\n') // if we receive a newline character we will continue in the loop continue; } pidcontroller.setpoint(integerValue); // The "goal" the PID controller tries to "reach", Serial.println(integerValue); // print the incoming value for debugging motor_pwm_value = pidcontroller.compute(encoder_count); //Let the PID compute the value, returns the calculated optimal output Serial.print(motor_pwm_value); // print the calculated value for debugging Serial.print(" "); if (motor_pwm_value > 0) // if the motor_pwm_value is greater than zero we rotate the motor in clockwise direction motor_ccw(motor_pwm_value); else // else we move it in a counter clockwise direction motor_cw(abs(motor_pwm_value)); Serial.println(encoder_count);// print the final encoder count. } void encoder() { if (digitalRead(ENCODER_B) == HIGH) // if ENCODER_B is high increase the count encoder_count++; // increment the count else // else decrease the count encoder_count--; // decrement the count } void motor_cw(int power) { if (power > 100) { analogWrite(MOTOR_CW, power); //rotate the motor if the value is grater than 100 digitalWrite(MOTOR_CCW, LOW); // make the other pin LOW } else { // both of the pins are set to low digitalWrite(MOTOR_CW, LOW); digitalWrite(MOTOR_CCW, LOW); } } void motor_ccw(int power) { if (power > 100) { analogWrite(MOTOR_CCW, power); digitalWrite(MOTOR_CW, LOW); } else { digitalWrite(MOTOR_CW, LOW); digitalWrite(MOTOR_CCW, LOW); } } Video microcontroller-projects/simple-arduino-voice-recorder-for-spy-bug-voice-recording

Simple Arduino Voice Recorder for Spy Bug Voice Recording

.Our spy bug uses a small microphone to record the voice and it stores the recorded voice onto an SD card. It will able to record audio clips that are 2 minutes long, each 2 minutes long clip would be numbered serially. Once powered up, the recording process will continue until the battery is dead or there is no more space to store the recorded audio. We also attached an LED with the Arduino that indicates the recording process has started. All this sounds interesting, right? So, let's get started. The project discussed here is only intended for educational use. Respect other people’s privacy, any misuse of this device might be a punishable offense according to your state law. You have been warned.

List of Components - Arduino Based Spy Bug

consists of very basic components that you will be able to find in your local hobby store, when you have accrued all the components, it can be easily built at home without any complexity. Arduino NANO MAX9814 Amplifier board SD card module SD card 5V power supply unit (Can be a power bank or so)

Arduino Based Spy Bug ᾠSchematic Diagram

is shown below. The brain of the project is the Arduino Nano that you can see in the schematic. (AGC) and low noise microphone bias. This device features a low-noise front-end amplifier, a variable gain amplifier (VGA), an output amplifier, a microphone bias voltage generator, and an AGC control circuit; all inside a single chip. and stores it inside a MicroSD card module that is also connected with the Arduino. There are many pins available in the MAX9814 module, but, majorly the VCC, GND, and out pins are used. There is also a gain pin that can be connected to the GND or VDD for a controlled gain of 50dB and 40dB. But we did not use gain control. By default, the module provides an uncompressed gain set to 60dB. For the micro SD card, SPI (Serial Parallel Interface) is used. These SPI pins are connected with the following pins.
Arduino PinsSD Card Pins
5VVCC
GNDGND
D10CS
D11MOSI
D12MISO
D13SCK
For the MAX9814, Analogpins are used that arelisted in the table given below.
Arduino PinsMAX9814 Pins
3.3VVDD
GNDGND
A0OUT
The audio stores in 2 minutes format and then starts to store in a new file. Thus each .wav file is of 2 minutes in length.

Arduino Based Spy Bug - code explanation

#include <TMRpcm.h> #include <SD.h> #include <SPI.h> TMRpcm audio; // make instance variable int file_number = 0; char filePrefixname[50] = "spy"; char exten[10] = ".wav"; const int recordLed = 2; const int mic_pin = A0; const int sample_rate = 16000; In the above lines “recording is goingon"notification LED is selected which is the available LED in the Arduino. The mic pin is available in the A0 pin with a sample rate of 16000 bits. #define SD_CSPin 10 // defines the CS pin of the SD card. // delay function for serial log. void wait_min(int mins) { int count = 0; int secs = mins * 60; while (1) { Serial.print('.'); delay(1000); count++; if (count == secs) { count = 0; break; } } Serial.println(); return ; } The above code is used for printing the serial codes. void setup() { // put your setup code here, to run once: //initializes the serial connection between the Arduino and any connected serial device(e.g. computer, phone, raspberry pi...) Serial.begin(9600); //Sets up the pins pinMode(mic_pin, INPUT); pinMode(recordLed, OUTPUT); Serial.println("loading... SD card"); if (!SD.begin(SD_CSPin)) { Serial.println("An Error has occurred while mounting SD"); } while (!SD.begin(SD_CSPin)) { Serial.print("."); delay(500); } audio.CSPin = SD_CSPin; } In the above codes, pin directions are set and the SD card is mounted. This section also gives you an error on the serial monitor if anything is wrong. void loop() { Serial.println("####################################################################################"); char fileSlNum[20] = ""; itoa(file_number, fileSlNum, 10); char file_name[50] = ""; strcat(file_name, filePrefixname); strcat(file_name, fileSlNum); strcat(file_name, exten); Serial.print("New File Name: "); Serial.println(file_name); digitalWrite(recordLed, HIGH); audio.startRecording(file_name, sample_rate, mic_pin); Serial.println("startRecording "); // record audio for 2mins. means, in this loop process record 2mins of audio. // if you need more time duration recording audio then // pass higher value into the wait_min(int mins) function. wait_min(2); // This is the length of the audio file which is set to 2 minutes digitalWrite(recordLed, LOW); audio.stopRecording(file_name); Serial.println("stopRecording"); file_number++; Serial.println("####################################################################################"); } The above code is the infinite loop where the voice recorder records the voices. Then stores them in the SD card where the file number is increased every timewriting in the file is completed.

Testing of the Arduino Based Spy Bug

All components are connected and flashedthe code inside the Arduino. It is working as expected. The Audio is recorded and tested using a mobile phone. Kindly check the video given for a fullworking video. for quickresponse. Code /* File Name: spy-recorder.ino Created on: 7-Jan-2021 Author: Noyel Seth (noyelseth@gmail.com) */ /* Hardware Pinout Connection Arduino Nano SD Pin 5v ------------ VCC GND ----------- GND D10 ----------- CS D11 ----------- MOSI D12 ----------- MISO D13 ----------- SCK ________________________________________ Arduino Nano MAX9814 3.3v ----------- VDD GND ------------ GND A0 ------------- Out ________________________________________ Arduino Nano D2 pin user for Led to notify that record is in process. */ /* use Link: https://www.arduino.cc/reference/en/libraries/tmrpcm/ TMRpcm library for recording audio using MAX9814 Recording a WAV file to an SD card is an advanced feature of the TMRpcm library so you must edit the library configuration file in order to use it. It simply searches the file "pcmConfig.h" using File Explorer and disables a few lines of code (then saves it). 1. On Uno or non-mega boards uncomment the line #define buffSize 128 2. Also uncomment #define ENABLE_RECORDING and #define BLOCK_COUNT 10000UL */ #include <TMRpcm.h> #include <SD.h> #include <SPI.h> TMRpcm audio; int file_number = 0; char filePrefixname[50] = "spy"; char exten[10] = ".wav"; const int recordLed = 2; const int mic_pin = A0; const int sample_rate = 16000; #define SD_CSPin 10 // delay function for with serial log. void wait_min(int mins) { int count = 0; int secs = mins * 60; while (1) { Serial.print('.'); delay(1000); count++; if (count == secs) { count = 0; break; } } Serial.println(); return ; } void setup() { // put your setup code here, to run once: //initialises the serial connection between the arduino and any connected serial device(e.g. computer, phone, raspberry pi...) Serial.begin(9600); //Sets up the pins pinMode(mic_pin, INPUT); pinMode(recordLed, OUTPUT); Serial.println("loading... SD card"); if (!SD.begin(SD_CSPin)) { Serial.println("An Error has occurred while mounting SD"); } while (!SD.begin(SD_CSPin)) { Serial.print("."); delay(500); } audio.CSPin = SD_CSPin; } void loop() { Serial.println("####################################################################################"); char fileSlNum[20] = ""; itoa(file_number, fileSlNum, 10); char file_name[50] = ""; strcat(file_name, filePrefixname); strcat(file_name, fileSlNum); strcat(file_name, exten); Serial.print("New File Name: "); Serial.println(file_name); digitalWrite(recordLed, HIGH); audio.startRecording(file_name, sample_rate, mic_pin); Serial.println("startRecording "); // record audio for 2mins. means , in this loop process record 2mins of audio. // if you need more time duration recording audio then // pass higher value into the wait_min(int mins) function. wait_min(2); digitalWrite(recordLed, LOW); audio.stopRecording(file_name); Serial.println("stopRecording"); file_number++; Serial.println("####################################################################################"); } Video microcontroller-projects/arduino-low-resistance-meter

Build Your Very Own Low Resistance Meter with Arduino

, which we have covered in one of our previous articles. A milliohm meter is a device that can be used to determine the values of small resistors, the resistance of PCB traces, and if you are aware of the know-how, it can be used to find out a short circuit in the PCB. which is not only reliable but also gives an accurate measurement. Wwill also display the information on an OLED display and at the end, we will do a performance test of our circuit. This circuit is not only accurate but also has a decent range, in our testing. We were able to measure 0.05R to 22R pretty accurately. So without further ado,let’s get started.

What is a Milliohm meter and how does it work?

nd if you are asking why it’s important to measure low resistance, let me tell you it can be used in many different types of applications other than measuring resistance. An example could be like; suppose you have a circuit board that shows a short circuit in the power section, most of the time, the problem can be a bad capacitor. If you have a low resistance meter at your disposal, you can check different parts of your circuit board in order to pinpoint a particular region where the resistance is lowest, then you can start debugging from there. This was a simple exampleif you want you could do more than just this. Resistance can be defined as a component that opposes the flow of electrons; the unit of resistance is ohms. A milliohm meter is a very simple instrument used to measure unknown / low-value resistances. There are many ohmmeters available in the market and they can measure a wide range of resistances, but those meters have one thing in common, they are pretty expensive, to begin with.

Components Required to Build the Arduino Based Low Resistance Meter

You need a handful of components to build this project, as they are very generic you can find all of them in your local hobby store. Alist of components with values is given below. Arduino Nano - 1 LM317T - 1 128 X 64 OLED - 1 10 R Resistor - 1 Test Resistors

Schematic Diagram of the Arduino Based Low Resistance Meter

is shown below. The connection diagram and the working principle of this circuit are very simple, as you can see in the above schematic, we have an Arduino Nano which is responsible for data collection, calculation, and processing. We have an OLED display that shows the calculated resistance value. And finally, we are using an LM317T which is the constant current source. With the constant current source and a little bit of ohm's law, we can calculate the resistance value quite easily. In the schematic, you can see a formula that isused to calculate the current limit for the LM317 Regulator IC. As you can also see in the schematic, we have used a 10R resistor with the circuit to calculate a constant current of 0.125A or 125mA. Now, as we have the current value, we just need to divide that with voltage to get the Resistance V=IR so R =V/I, and we will get the resistance.

Code: Arduino Based Low Resistance Meter

The complete code used in this project can be found at the bottom of this page. After adding the required header files and source files, you should be able to directly compile the Arduino code. You can download the libraries from the link given below or else you can use the board manager method to install the library. Download SSD1306 OLED Library by Adafruit The code is very simple, and it goes as follows. We start by including all the required libraries. As we are using an OLED display, we have to include the SSD1306 library and the Wire library, the SSD1306 library uses the wire library. #include <Adafruit_SSD1306.h> #include <Wire.h> // Wire Library for OLED Next, we will define the screen width and screen height for the display. Also, we will define the resistance value, and the reference value for the LM317 regulator IC. This is required because we will calculate the constant current with these values. Once we do that, we will define all the necessary variables required for averaging the ADC values. Also, we will declare the pin no and other variables. const int numReadings = 50; // used for averaging / we will take 50 samples and average it to get ADC value int readings[numReadings]; // Store the readings from the analog input int readIndex = 0; // the index of the current reading int total = 0; // the running total int ADCaverage = 0; // the average float R; // Stores the Resistance Value int inputPin = A0; // A0 is selected as input Next, we create an instance for the SSD1306 display and pass in the wire object. Adafruit_SSD1306 display(SCREEN_WIDATA_PINH, SCREEN_HEIGHT, &Wire, -1); Next, in the setup () section,we will initialize the display and check if the display is available or not. We do that with the help of an if statement. If the display is available, we move forward to our code, else we print an error statement. if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for (;;); } This is important because there can be garbage values inside the array that can introduce errors with our calculations. display.setTextColor(WHITE); // set LCD Colour display.setRotation(2); // it has modes 1,2,3,4 // for (int thisReading = 0; thisReading < numReadings; thisReading++) { readings[thisReading] = 0; } delay(500); } section. In this section, we do all the necessary calculation that is required to average the ADC value for smoothing the output ADC reading. The code you see below is used to average the ADC value. total = total - readings[readIndex]; // subtract the last reading: readings[readIndex] = analogRead(inputPin); // read from the sensor: total = total + readings[readIndex]; // add the reading to the total: readIndex = readIndex + 1; // advance to the next position in the array: if (readIndex >= numReadings) { // if we're at the end of the array... // ...wrap around to the beginning: readIndex = 0; } Once the ADC value is averaged, we print the average value just for debugging. Next, we convert the ADC value to voltage value, as this is required for calculation. Thereafter, we print the voltage value for debugging. Once we have the voltage, we know our current value is fixed. Now, with the help of OHMs law, we calculate the Resistance value and print it in the serial monitor window. Also, we print the values on the OLED display. ADCaverage = total / numReadings; // calculate the average: Serial.print("AVG: "); Serial.print(ADCaverage); float voltage = ADCaverage * (5.0 / 1024.0); // Convert ADCaverage to Voltage Serial.print(" \t \t"); // give me a little TAb would ya Serial.print(voltage, 3); // Print Voltage to Serial Monitor Serial.print(" \t \t");// give me another little TAb would ya R = voltage / (LM317_REF / LM317_Resistance) ; Serial.print("Resistance: "); Serial.println(R); display.clearDisplay(); display.setTextSize(2); display.setCursor(10, 10); display.print(R,3); display.print(" R"); display.display(); delay(50); This marks the end of our coding process and now we can move onto testing our meter.

Testing of the Arduino Based Low Resistance Meter

To test this circuit, the following setup is used. The setup is made on a breadboard for testing purposes only, and it's highly recommended to make this circuit on a proper PCB board. As you can see in the picture, we have made the circuit on a breadboard as it was a test circuit, and it turned out to be a bad idea because the contact resistance and impedance were taking a heavy toll on the circuit. This is why at the last moment, we decided to solder some wires directly on the circuit board, we also soldered the 10R resistance and the wire of the alligator clip directly onto the LM317 IC itself. Once we were done with that, we measured some resistances with this meter and observed the results, and the results were pretty good. As you can see in the above image, the value is very spot on. To verify the results, we decided to test the circuit again with the help of our MECHO 450B+ Multimeter and the results were pretty bad. The Multimeter gave us pretty odd values and probably it was an error. To verify, we again tested different resistor values and the result was pretty much the same. At this point, we were sure that the Meco Multimeter was unable to measure such low resistance values. You can check out the video in the description for more details. Further Enhancements This circuit is not perfect and it has a lot of room for improvement. First, the circuit needs to be in a perfboard or a piece of PCB board, otherwise, we will have all sorts of problems. We have used the LM317 IC to make the constant current source that can be upgraded to a specific constant current source that is designed for this purpose. We used resistance with 5% tolerances but using resistance with a tolerance of 1% or less will improve the results very much. With that being said, it's time to end this project. I hope you enjoyed the article and learned something new. If you have any questions regarding the article, you can comment down below else you can post it to our forum for quick response. Code #include <Adafruit_SSD1306.h> #include <Wire.h> // Wire Library for OLED #define SCREEN_WIDATA_PINH 128 // OLED display Width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define LM317_REF 1.25 #define LM317_Resistance 10.1 const int numReadings = 50; // used for averaging / we will take 50 samples and average it to get ADC value int readings[numReadings]; // the readings from the analog input int readIndex = 0; // the index of the current reading int total = 0; // the running total int ADCaverage = 0; // the average float R; int inputPin = A0; Adafruit_SSD1306 display(SCREEN_WIDATA_PINH, SCREEN_HEIGHT, &Wire, -1); void setup() { // put your setup code here, to run once: Serial.begin(9600); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for (;;); } display.setTextColor(WHITE); // set LCD Colour display.setRotation(2); // it has modes 1,2,3,4 // for (int thisReading = 0; thisReading < numReadings; thisReading++) { readings[thisReading] = 0; } delay(500); } void loop() { total = total - readings[readIndex]; // subtract the last reading: readings[readIndex] = analogRead(inputPin); // read from the sensor: total = total + readings[readIndex]; // add the reading to the total: readIndex = readIndex + 1; // advance to the next position in the array: if (readIndex >= numReadings) { // if we're at the end of the array... // ...wrap around to the beginning: readIndex = 0; } ADCaverage = total / numReadings; // calculate the average: Serial.print("AVG: "); Serial.print(ADCaverage); float voltage = ADCaverage * (5.0 / 1024.0); // Convert ADCaverage t0 Voltage Serial.print(" \t \t"); // give me a little TAb would ya Serial.print(voltage, 3); // Print Voltage to Serial Monitor Serial.print(" \t \t");// give me another little TAb would ya R = voltage / (LM317_REF / LM317_Resistance) ; Serial.print("Resistance: "); Serial.println(R); display.clearDisplay(); display.setTextSize(2); display.setCursor(10, 10); display.print(R,3); display.print(" R"); display.display(); delay(50); } Video microcontroller-projects/build-your-own-function-generator-with-arduino-and-ad9833-module

Build your own Function Generator with Arduino and AD9833 DDS Function Generator Module

sometimes becomes mandatory. But owning one is a problem because such basic equipment can cost a fortune. Building your own test equipment is not only cheaper but also a great way to improve your knowledge. which can produce sine, square, and triangle waves with a maximum frequency of 12 MHz at the output. And finally, we are going to testthe output frequency with the help of our oscilloscope. Project.

What is a DDS Function Generator?

forwhich you want to test your output frequency response, you can easily do that with the help of a function generator. All you need to do is set your desired output frequency and waveform, then you can crank it down or up in order to test the response. This was just one example,you can do more things with it as the list goes on. (DAC) to build a signal from the ground up. This method is specifically used to generate a sine wave. But the IC we are using can produce Square or Triangular wave signals. The Operations that happened inside a DDS chip are digital so it can switch the frequency very fast or it can switch from one signal to another very rapidly. This device has a fine frequency resolution with a broad frequency spectrum.

Understand the Working of the AD9833 Function Generator IC

wave with a maximum frequency of 12 MHz. It’s a very unique IC that is capable of altering the output frequency and phase with just a software program. It has a 3 wire SPI interface which is why communicating with this ICbecomes very simple and easy. The functional block diagram of this IC is shown below. , you can also check it out for further information.

Components Required to Build the AD9833 based Function Generator

The components required to build the AD9833 based function generator is listed below, we designed this circuit with very generic components, which makes the replication process very easy. Arduino Nano - 1 AD9833 DDS Function Generator - 1 128 X 64 OLED Display - 1 Generic Rotary Encoder - 1 DC Barrel Jack - 1 LM7809 Voltage Regulator - 1 470uF Capacitor - 1 220uF Capacitor - 1 104pF Capacitor - 1 10K Resistor - 6 Tactile Switches - 4 Screw Terminal 5.04mm - 1 Female Header - 1 12V Power Source - 1

AD9833 Based Function Generator - Schematic Diagram

is shown below. The AD9833 module is the function generator module and it’s connected with the Arduino according to the schematic. To power the circuit, we are using an LM7809 voltage regulator IC, with a decent decoupling capacitor, this is necessary because the supply noise can interfere with the output signal resulting in unwanted output. As always, the Arduino is working as the brainfor this project. To display the set frequency and other valuable information, we have connected a 128 X 64 OLED display module. To change the frequency range, we are using three switches. The first one sets the frequency to Hz, the second one sets the output frequency to KHz, and the third one sets the frequency to MHz, we also have another button that can be used to enable or disable the output. Finally, we have the rotary encoder, and we have to attach some pull-up resistor with it otherwise those switches will not work because we are checking the button press event on the pooling method. The rotary encoder is used to change the frequency and the tactile switch inside the rotary encoder is used to select the set waveform.

AD9833 Based Function Generator - Arduino Code

and other libraries from the link given below or else you can use the board manager method to install the library. Download AD9833 Library by Bill Williams Download SSD1306 OLED Library by Adafruit Download Adafruit GFX library is first followed by the library for OLED and the math library is required for some of our calculations. #include <AD9833.h> // LIbrary for AD9833 Module #include <Wire.h> // Wire Library for OLED #include <Adafruit_GFX.h> // Support Library for OLED #include <Adafruit_SSD1306.h> // OLED library #include <math.h> // Math Library Next, we define all the necessary input and output pins for the buttons, switch, rotary encoder, and OLEDs. #define SCREEN_WIDATA_PINH 128 // OLED display Width in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define SET_FREQUENCY_HZ A2 // Pushbutton To Set Frequency in Hz #define SET_FREQUENCY_KHZ A3 // Pushbutton To Set Frequency in Khz #define SET_FREQUENCY_MHZ A6 // Pushbutton To Set Frequency in Mhz #define ENABLE_DISABLE_OUTPUT_PIN A7 // Pushbutton To Enable/Disable the Output #define FNC_PIN 4 // Fsync Required by the AD9833 Module #define CLK_PIN 8 // Clock Pin of the Encoder #define DATA_PIN 7 // Data Pin of the Encoder #define BTN_PIN 9 // Internal Push Button on the Encoder variable that holds the encoder-button count which is used to set the output waveform. int counter = 1; // This Counter value will increase or decrease if when the rotary encoder is turned int clockPin; // Placeholder for pin status used by the rotary encoder int clockPinState; // Placeholder for pin status used by the rotary encoder unsigned long time = 0; // Used for debouncing unsigned long moduleFrequency; // used to set output frequency long debounce = 220; // Debounce delay bool btn_state; // used to enable disable output of the AD98333 Module bool set_frequency_hz = 1; // Defult frequency of the AD9833 Module bool set_frequency_khz; bool set_frequency_mhz; String waveSelect = "SIN"; // Startup waveform of the module int encoder_btn_count = 0; // used to check encoder button press Next, we have our two objects one is for the OLED display and another one is for the AD9833 module. Adafruit_SSD1306 display(SCREEN_WIDATA_PINH, SCREEN_HEIGHT, &Wire, -1); AD9833 gen(FNC_PIN); variable, this is a necessary step for the rotary encoder. method willbe discussed later in the article. void setup() { Serial.begin(9600); // Enable Serial @9600 baud gen.Begin(); // This MUST be the first command after declaring the AD9833 object pinMode(CLK_PIN, INPUT); // Setting Pins as input pinMode(DATA_PIN, INPUT); pinMode(BTN_PIN, INPUT_PULLUP); clockPinState = digitalRead(CLK_PIN); pinMode(SET_FREQUENCY_HZ, INPUT);// Setting Pins as input pinMode(SET_FREQUENCY_KHZ, INPUT); pinMode(SET_FREQUENCY_MHZ, INPUT); pinMode(ENABLE_DISABLE_OUTPUT_PIN, INPUT); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for (;;); } display.clearDisplay(); // Clear the Screen display.setTextSize(2); // Set text Size display.setTextColor(WHITE); // set LCD Colour display.setCursor(30, 0); // Set Cursor Position display.println("AD9833"); // Print the this Text display.setCursor(17, 20); // Set Cursor Position display.println("Function"); // Print the this Text display.setCursor(13, 40); // Set Cursor Position display.println("Generator"); // Print the this Text display.display(); // Update the Display delay(2000); // Delay of 2 SEC update_display(); // Call update_display Function } function, all the major functionalities are written in the loop section. value for future use. void loop() { clockPin = digitalRead(CLK_PIN); if (clockPin != clockPinState && clockPin == 1) { if (digitalRead(DATA_PIN) != clockPin) { counter --; } else { counter ++;// Encoder is rotating CW so increment } if (counter < 1 ) counter = 1; Serial.println(counter); update_display(); } And finally, we update the time variable with the current timer counter value. //If we detect a LOW signal, the button is pressed if ( digitalRead(BTN_PIN) == LOW && millis() - time > debounce) { encoder_btn_count++; // Increment the values if (encoder_btn_count > 2) // if value is greater than 2 reset it to 0 { encoder_btn_count = 0; } if (encoder_btn_count == 0) { // if the value is 0 sine wave is selected waveSelect = "SIN"; // update the string variable with sin value update_display(); // update the display } if (encoder_btn_count == 1) { // if the value is 1 square wave is selected waveSelect = "SQR"; // update the string variable with SQR value update_display(); // update the display } if (encoder_btn_count == 2) { // if the value is 1 Triangular wave is selected waveSelect = "TRI"; // update the string variable with TRI value update_display();// update the display } time = millis(); // update the time variable } If this statement is true, we assign the boolean variables with values that are used to set the Hz, Khz, and Mhz values of the function generator. Next, we update the display and update the time variable. We do that for all the four buttons connected with the Arduino. if (analogRead(SET_FREQUENCY_HZ) < 30 && millis() - time > debounce) { set_frequency_hz = 1; //update boolean values set_frequency_khz = 0; set_frequency_mhz = 0; update_display();// update the display time = millis();// update the time variable } if (analogRead(SET_FREQUENCY_KHZ) < 30 && millis() - time > debounce){ set_frequency_hz = 0; //update boolean values set_frequency_khz = 1; set_frequency_mhz = 0; moduleFrequency = counter * 1000; update_display();// update the display time = millis();// update the time variable } if (analogRead(SET_FREQUENCY_MHZ) < 30 && millis() - time > debounce ) { // check analog pin with debounce delay set_frequency_hz = 0; //update boolean values set_frequency_khz = 0; set_frequency_mhz = 1; moduleFrequency = counter * 1000000; update_display();// update the display time = millis();// update the time variable } if (analogRead(ENABLE_DISABLE_OUTPUT_PIN) < 30 && millis() - time > debounce ) {// check analog pin with debounce delay btn_state = ! btn_state; // Invert the button state gen.EnableOutput(btn_state); // Enable / Disable output of the function generator depending on button state update_display();// update the display time = millis();// update the time variable } } function. In this function, we did a lot more than just updating this display because a certain portion of the display cannot be updated in an OLED.To update it, you have to repaint it with new values. This makes the coding process a lot more difficult. This is where we print the information for what wave it is. display.clearDisplay(); // FIrst clear the display display.setTextSize(1); //set text Size display.setCursor(10, 0); // Set cursor position display.println("Function Generator"); //print the text display.setTextSize(2);//set text Size display.setCursor(0, 20);//Set cursor position variable and identify which wave is selected. Now, we have the values to set the wave type and frequency. if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0 ) { // check if button for setting the frequency in Hz is pressed moduleFrequency = counter; //update the moduleFrequency variable with current counter value } if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0 ) { // check if button for setting the frequency in KHz is pressed moduleFrequency = counter * 1000;//update the moduleFrequency variable with current counter value but we multiply 1000 to set it on KHZ } if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) { // check if button for setting the frequency in MHz is pressed moduleFrequency = counter * 1000000; if (moduleFrequency > 12000000) { moduleFrequency = 12000000; // do not let the frequency to be grater that 12Mhz counter = 12; } } if (waveSelect == "SIN") { // Sine wave is selected display.println("SIN"); gen.ApplySignal(SINE_WAVE, REG0, moduleFrequency); Serial.println(moduleFrequency); } if (waveSelect == "SQR") {// Sqr wave is selected display.println("SQR"); gen.ApplySignal(SQUARE_WAVE, REG0, moduleFrequency); Serial.println(moduleFrequency); } if (waveSelect == "TRI" ) {// Tri wave is selected display.println("TRI"); gen.ApplySignal(TRIANGLE_WAVE, REG0, moduleFrequency); // update the AD9833 module. Serial.println(moduleFrequency); } We set the cursor again and update the counter values. Again we check the boolean to update the frequency range on the display, we have to dothis because the working principle of the OLED is very weird. display.setCursor(45, 20); display.println(counter); // print the counter information on the display. if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0 ) { display.setCursor(90, 20); display.println("Hz"); // print Hz on the display display.display(); // when all set update the display } if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0 ) { display.setCursor(90, 20); display.println("Khz"); display.display(); // when all set update the display } if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) { display.setCursor(90, 20); display.println("Mhz"); display.display(); // when all set update the display } Next, we check the button press variable to print output on / output off to the OLED. Again this needs to be donebecause of the OLED module. if (btn_state) { display.setTextSize(1); display.setCursor(65, 45); display.print("Output ON"); // print output on to the display display.display(); display.setTextSize(2); } else { display.setTextSize(1); display.setCursor(65, 45); display.print("Output OFF"); // print output off to the display display.display(); display.setTextSize(2); } This marks the end of our coding process. If you are confused at this point, you can check the comments in the code for further understanding.

Testing the AD9833 Based Function Generator

To test the circuit, the above setup is used. As you can see, we have connected a 12V DC power adapter to the DC barrel jack and we have connected the Hantek Oscilloscope to the output of the circuit. We have also connected the oscilloscope to the laptop to visualize and measure the output frequency. Once this was done, we set the output frequency to 5Khz with the help of the rotary encoder and we test the output sine wave and sure enough, it is a 5Khz sine wave at the output. Next, we have changed the output waveform to a triangular wave but the frequency stayed the same, the output waveform is shown below. Then we changed the output to a square wave and observed the output, and it was a perfect square wave. We also altered the frequency ranges and tested the output, and it was working well.

Further Enhancements

This circuit is only a proof of concept and needs further enhancements. First, we need a good quality PCB and some good quality BNC connector for the output otherwise we cannot obtain a higher frequency. The amplitude of the module is very low, so to enhance that, we need some op-amp circuits to amplify the output voltage. A potentiometer can be connected in order to vary the output amplitude. A switch for offsetting the signal can be connected; this is also a must-have feature. And further, the code needs a lot of improvement as it'sa little buggy. Finally, OLED displays need to be changed otherwise it's impossible to write easily understandable code. Code #include <AD9833.h> // LIbrary for AD9833 Module #include <Wire.h> // Wire Library for OLED #include <Adafruit_GFX.h> // Support Library for OLED #include <Adafruit_SSD1306.h> // OLED library #include <math.h> // Math Library #define SCREEN_WIDATA_PINH 128 // OLED display Width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define SET_FREQUENCY_HZ A2 // Pushbutton To Set Frequency In Hz #define SET_FREQUENCY_KHZ A3 // Pushbutton To Set Frequency In Khz #define SET_FREQUENCY_MHZ A6 // Pushbutton To Set Frequency In Mhz #define ENABLE_DISABLE_OUTPUT_PIN A7 // Pushbutton To Enable / Disable the Output #define FNC_PIN 4 // Fsync Required by the AD9833 Module #define CLK_PIN 8 // Clock Pin of the Encoder #define DATA_PIN 7 // Data Pin of the Encoder #define BTN_PIN 9 // Internal Push Button on the Encoder int counter = 1; // This Counter value will increas or decreas if when the rotarty encoder is turned int clockPin; // Placeholder por pin status used by the rotary encoder int clockPinState; // Placeholder por pin status used by the rotary encoder unsigned long time = 0; // Used for debouncing unsigned long moduleFrequency; // used to set output frequency In the long debounce = 220; // Debounce delay bool btn_state; // used to enable disable output of the AD98333 Module bool set_frequency_hz = 1; // Defult frequency of the AD9833 Module bool set_frequency_khz; bool set_frequency_mhz; String waveSelect = "SIN"; // Startup waveform of the module int encoder_btn_count = 0; // used to check encoder button press Adafruit_SSD1306 display(SCREEN_WIDATA_PINH, SCREEN_HEIGHT, &Wire, -1); AD9833 gen(FNC_PIN); void setup() { Serial.begin(9600); gen.Begin(); // This MUST be the first command after declaring the AD9833 object pinMode(CLK_PIN, INPUT); pinMode(DATA_PIN, INPUT); pinMode(BTN_PIN, INPUT_PULLUP); clockPinState = digitalRead(CLK_PIN); pinMode(SET_FREQUENCY_HZ, INPUT); pinMode(SET_FREQUENCY_KHZ, INPUT); pinMode(SET_FREQUENCY_MHZ, INPUT); pinMode(ENABLE_DISABLE_OUTPUT_PIN, INPUT); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for (;;); } display.clearDisplay(); // Clear the Screen display.setTextSize(2); // Set text Size display.setTextColor(WHITE); // set LCD Colour display.setCursor(30, 0); // Set Cursor Position display.println("AD9833"); // Print the this Text display.setCursor(17, 20); // Set Cursor Position display.println("Function"); // Print the this Text display.setCursor(13, 40); // Set Cursor Position display.println("Generator"); // Print the this Text display.display(); // Update the Display delay(2000); // Delay of 2 SEC update_display(); // Call update_display Function } void loop() { clockPin = digitalRead(CLK_PIN); if (clockPin != clockPinState && clockPin == 1) { if (digitalRead(DATA_PIN) != clockPin) { counter --; } else { counter ++;// Encoder is rotating CW so increment } if (counter < 1 ) counter = 1; Serial.println(counter); update_display(); } clockPinState = clockPin; // Remember last CLK_PIN state //If we detect LOW signal, button is pressed if ( digitalRead(BTN_PIN) == LOW && millis() - time > debounce) { encoder_btn_count++; // Increment the values if (encoder_btn_count > 2) // if value is grater that 2 reset it to 0 { encoder_btn_count = 0; } if (encoder_btn_count == 0) { // if the value is 0 sine wave is selected waveSelect = "SIN"; // update the string variable with sin value update_display(); // update the display } if (encoder_btn_count == 1) { // if the value is 1 square wave is selected waveSelect = "SQR"; // update the string variable with SQR value update_display(); // update the display } if (encoder_btn_count == 2) { // if the value is 1 Triangular wave is selected waveSelect = "TRI"; // update the string variable with TRI value update_display();// update the display } time = millis(); // update the time variable } // Check buttton press action with analogread method // Put in a slight delay to help debounce the reading if (analogRead(SET_FREQUENCY_HZ) < 30 && millis() - time > debounce) { // check analogpin with debounce delay //update boolean values set_frequency_hz = 1; set_frequency_khz = 0; set_frequency_mhz = 0; update_display();// update the display time = millis();// update the time variable } if (analogRead(SET_FREQUENCY_KHZ) < 30 && millis() - time > debounce) { // check analogpin with debounce delay //update boolean values set_frequency_hz = 0; set_frequency_khz = 1; set_frequency_mhz = 0; moduleFrequency = counter * 1000; update_display();// update the display time = millis();// update the time variable } if (analogRead(SET_FREQUENCY_MHZ) < 30 && millis() - time > debounce ) { // check analogpin with debounce delay //update boolean values set_frequency_hz = 0; set_frequency_khz = 0; set_frequency_mhz = 1; moduleFrequency = counter * 1000000; update_display();// update the display time = millis();// update the time variable } if (analogRead(ENABLE_DISABLE_OUTPUT_PIN) < 30 && millis() - time > debounce ) {// check analogpin with debounce delay btn_state = ! btn_state; // Invert the button state gen.EnableOutput(btn_state); // Enable / Disable output of the function generator depending on button state update_display();// update the display time = millis();// update the time variable } } void update_display() { display.clearDisplay(); // FIrst clear the display display.setTextSize(1); //set text Size display.setCursor(10, 0); // Set cursor position display.println("Function Generator"); //print the text display.setTextSize(2);//set text Size display.setCursor(0, 20);//Set cursor position if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0 ) { // check if button for setting the frequency in Hz is pressed moduleFrequency = counter; //updayte teh moduleFrequency variable with current counter value } if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0 ) { // check if button for setting the frequency in KHz is pressed moduleFrequency = counter * 1000;//updayte teh moduleFrequency variable with current counter value but we multiply 1000 to set it on KHZ } if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) { // check if button for setting the frequency in MHz is pressed moduleFrequency = counter * 1000000; if (moduleFrequency > 12000000) { moduleFrequency = 12000000; // do not let the frequency to be grater that 12Mhz counter = 12; } } if (waveSelect == "SIN") { // Sine wave is selected display.println("SIN"); gen.ApplySignal(SINE_WAVE, REG0, moduleFrequency); Serial.println(moduleFrequency); } if (waveSelect == "SQR") {// Sqr wave is selected display.println("SQR"); gen.ApplySignal(SQUARE_WAVE, REG0, moduleFrequency); Serial.println(moduleFrequency); } if (waveSelect == "TRI" ) {// Tri wave is selected display.println("TRI"); gen.ApplySignal(TRIANGLE_WAVE, REG0, moduleFrequency); // update the AD9833 module. Serial.println(moduleFrequency); } display.setCursor(45, 20); display.println(counter); // print the counter information on teh display. if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0 ) { display.setCursor(90, 20); display.println("Hz"); // print Hz on the display display.display(); // when all set update the display } if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0 ) { display.setCursor(90, 20); display.println("Khz"); display.display(); // when all set update the display } if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) { display.setCursor(90, 20); display.println("Mhz"); display.display(); // when all set update the display } if (btn_state) { display.setTextSize(1); display.setCursor(65, 45); display.print("Output ON"); // print output on to the display display.display(); display.setTextSize(2); } else { display.setTextSize(1); display.setCursor(65, 45); display.print("Output OFF"); // print output off to the display display.display(); display.setTextSize(2); } } Video microcontroller-projects/arduino-based-roller-blinds-project-to-automate-and-control-window-curtains-using-nodemcu-and-stepper-motor

Arduino based Roller Blinds to Automate and Control your Window Curtains with Google Assistant

can also take commands from Google assistant so that you can open or close your window blinds remotely through voice commands. Intriguing? Then, let's get it built.

Components Requiredto Build Arduino Automated Blinds

The project is relatively simple and there are not many components required. Just gather the items listed below. NodeMCU Stepper Motor ᾠ28BYJ-48 Stepper Motor Driver Module LM117-3.3V Capacitors (10uf,1uf) 12V DC Adapter Perf Board Soldering kit 3D Printer

Controlling Roller Blinds using Arduino

Now there are many types of Blinds in the market, but the most commonly used one has a rope with beadings (as shown below) that can be pulled to open or close the blinds. When we pull this circular rope in a clockwise direction, the window blinds will open and when we pull this rope in an anti-clockwise direction, the window blinds will close. So, if we were to automate this process, all we have to do isuse a motor to pull this rope in a clockwise or anti-clockwise direction and we will be done with it. In fact, this is what we are going to do in this project; we will be using the 28BYJ-48 stepper motor along with a NodeMCU to pull the beaded rope.

Design and Build the Window Blind Gear

The Electronics part of this project was fairly simple and straight forward, the challenging part was in building the Blind Gear that could pull the beaded rope. So let’s start this article with the blind gear design, I am not going to get into details on how to design the gear, but this basic idea should help you out. An image of the rope with the beads on it is shown below. Again, there are many types of ropes butthe most commonly used ropes are the center-to-center distance of each beading is 6mm and the diameter of each beading is 4mm. Using this information, we can start the design of our gear. If the rope on your blinds has the same dimensions as discussed, you can simply skip this step and download the STL file provided in this article and print the gear.If your rope has a different beading arrangement, then this is how you should re-design the blind gear. I decided to have 24 beads on my gear to get an optimum gear wheel size, you can select any number close to this for your gear wheel to be largeor small. So now, we know that the distance between each beading is 6mm and we need 24 beads on our gear. Multiplying both will give the circumference of the gear wheel. With this data, you can calculate the radius of the gear wheel. As you can see in the above image, the diameter of my gear wheel was calculated to be around 46 mm. Butremember, this is not the actual diameter of the gearbecause we have not accounted for the diameter of the beading which is 4mm. So, the actual diameter of the gearwheel will be 42 mm, I printed and tested many gear wheels beforeI found the one that works the best. If you are not into designs, just download and print the STL files from the next paragraph and continue with your project.

3D Printing the Motor Holder and Blind Gear

Along with the gear, we will also need a small casing that can be drilled onto the wall and hold the stepper motor in position, both the casing and the gear used in this project are shown below. You can find complete design files and STL files on the Arduino Blind Control Thingiverse page given below. You can just download and print your blind gear and motor case.

Circuit Diagram for Arduino Blinds Control

Once you are ready with the gear and assembly, it is easy to proceed with the electronics and software part. The complete circuit diagram for the IoT Blind control project is shown below. We have used a 12V adapter to power the entire setup; the LM1117-3.3V regulator converts the 12V to 3.3V which can be used to power the NodeMCUboard. The stepper motor driver module is directly powered from the 12V adapter. I did try running the stepper motor on 5V, but then it did not provide enough torque to pull the blinds, so make sure you are also using 12V. article to understand how it works and how it can be used with a microcontroller.

BlynkApplication for Arduino Blind Control

Before we get into the Arduino program for Controlling Blinds, letsopen the blynk application and create some buttons using which we can open or close our blinds. We will also need this later to control from Google home. I have just added two buttons to open and close the blinds and one-timer to open the blinds at 10:00 amevery day. You can add multiple timers to open or close the blinds at different intervals of the day. Basically, when we have to close the blinds, we have to trigger virtual pin V1 and when we have to open the blinds, we have to trigger virtual pin V2. The program to control the stepper motor based on the button pressed here will be written on the Arduino IDE, the same is discussed below.

Programming NodeMCU to ControlBlinds using Blynk

The complete ESP8266 code for this Blind Control Project can be found at the bottom of this page. Our program has to wait for a command from the blynk application and based on that command, we have to rotate the stepper motor either in a clockwise direction or in an anti-clockwise direction. The important segments of the code are discussed below. According to our circuit diagram, we have used digital pins 1, 2, 3, and 4 on nodemcu to control our stepper motor. So, we have to create an instance called stepper using these pins as shown below. Notice that we have defined the pins in order 1, 3, 2, and 4. It was done deliberately and is not a mistake;we have to swap pins 2 and 3 for the motor to work properly. // create an instance of the stepper class using the steps and pins Stepper stepper (STEPS, D1, D3, D2, D4); project to understand the basics of theblynk application and how to use it. // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "l_b47mF1hioCc_7FzdKMJJeFnJjTxxxx"; // Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "CircuitDigest"; char pass[] = "dummy123"; Moving on with our code, after the setup function, we have defined two methods for blynk.As mentioned previously, we have to define what virtual pins V1 and V2 should do. The code for the same is given below. BLYNK_WRITE (V1) //CLOSE the BLINDS { Serial.println("Closing Blinds"); if (opened == true) { for (int c_val = 0; c_val <= 130; c_val++) //rotate in Counter-Clockwise for closing { stepper.step(c_val); yield(); } closed = true; opened = false; disable_motor(); // always desable stepper motors after use to reduce power consumption and heating } } BLYNK_WRITE(V2) // OPEN the BLINDS { Serial.println("Opening Blinds"); if (closed == true) { for (int cc_val = 0; cc_val >= -130; cc_val--) //rotate in Clockwise for opening { stepper.step(cc_val); yield(); } opened = true; closed = false; } disable_motor(); // always desable stepper motors after use to reduce power consumption and heating } to rotate stepper motor in a clockwise and counter-clockwise direction is shown below. for (int c_val = 0; c_val <= 130; c_val++) //rotate in Counter-Clockwise for closing { stepper.step(c_val); yield(); } for (int cc_val = 0; cc_val >= -130; cc_val--) //rotate in Clockwise for opening { stepper.step(cc_val); yield(); } You can also notice two Boolean variables “openedᾠand “closedᾠin our program. These two variables are used to prevent the motor from opening or closing the blinds twice. Meaning, the blinds will open only when it is previously closed and it will close only when it is previously opened. again I found 500 to be an optimal value, anything more than that actually makes the stepper motor slower. Do you know any other way to increase the speed of these motors? If yes, leave them in the comment section below. Stepper motors should always be disabled when not in use to prevent overheating. Disabling a stepper motor is very simple; just change the pin status of all the four GPIO pins that are controlling the stepper motor to low. This is very important, else your motor might get very hot at +12V and damage itself permanently. The program to disable the stepper motor is given below. void disable_motor() //turn off the motor when done to avoid heating { digitalWrite(D1,LOW); digitalWrite(D2,LOW); digitalWrite(D3,LOW); digitalWrite(D4,LOW); }

Controlling Window Blinds using Google Assistant

project, so do check that if interested. Basically, we have to trigger the below link when we say a pre-defined phrase to Google Assistant. //http://188.166.206.43/l_b47mF1hioCc_7FzdKMJJeFnJjTxxxx/update/V1?value=1 / , just replace the adafruit services with webhooks. I am also sharing a screenshot of my snippet for reference.

Arduino based Automatic Window Blind Control ᾠDemonstration

After the circuit and 3D printed enclosures are ready, just assemble the device on the wall by drilling two holes on the wall. My mounting setup is shown in the pictures below. After that, make sure your blinds are in an open condition and then power on the circuit. Now, you can try to close the blinds from the blynk application or through Google Assistant and it should work. You can also set timers on the blynk application to automatically open and close the blind at a particular time of the day. for other technical discussions. Code // Arduino Program to control blinds usig stepper motor #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> #include <Stepper.h> // Include the header file #define BLYNK_PRINT Serial // change this to the number of steps on your motor #define STEPS 64 // create an instance of the stepper class using the steps and pins Stepper stepper(STEPS, D1, D3, D2, D4); // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "l_b47mF1hioCc_7FzdKMJJeFnJjTxxxx"; // Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "CircuitDigest"; char pass[] = "dummy123"; //Run the program only after opening the blinds boolean closed = false; boolean opened = true; void disable_motor() //turn off the motor when done to avoid heating { digitalWrite(D1,LOW); digitalWrite(D2,LOW); digitalWrite(D3,LOW); digitalWrite(D4,LOW); } void setup() { pinMode(D0, OUTPUT); //on-board LED as output digitalWrite(D0,HIGH); //turn this light on Serial.begin(9600); stepper.setSpeed(500); Blynk.begin(auth, ssid, pass); //http://188.166.206.43/l_b47mF1hioCc_7FzdKMJJeFnJjxxxx_/update/V1?value=1 / digitalWrite(D0,LOW); //turn it off after connecting to blynk } BLYNK_WRITE(V1) //CLOSE the BLINDS { Serial.println("Closing Blinds"); if (opened == true) { for (int c_val = 0; c_val <= 130; c_val++) //rotate in Counter-Clockwise for closing { stepper.step(c_val); yield(); } closed = true; opened = false; disable_motor(); // always desable stepper motors after use to reduce power consumption and heating } } BLYNK_WRITE(V2) // OPEN the BLINDS { Serial.println("Opening Blinds"); if (closed == true) { for (int cc_val = 0; cc_val >= -130; cc_val--) //rotate in Clockwise for opening { stepper.step(cc_val); yield(); } opened = true; closed = false; } disable_motor(); // always desable stepper motors after use to reduce power consumption and heating } void loop() { Blynk.run(); } Video microcontroller-projects/understanding-fuse-bits-in-atmega328p-to-enhance-arduino-programming-skills

Understanding Fuse Bits in ATmega328P to Enhance Arduino Programming Efficiency

These bits are like tiny switches inside the AVR andby turning them on/off, we can turn on/off some special features of the AVR. Turning it on and off meanssetting and resetting. Here, you will learn how to set these fuses for setting some of these features on and off which comes in really handy in real-life applications. So,let’s get right into it. You can check them out if you want to learn more about those projects.

What are Fuses in AVR - A Detail Explanation

Rev: 7810D–AVRᾰ1/15, you can find out all the little details about the fuse bits. Butthe below image will give you a better idea about the fuse bits section of the datasheet. Now as you have learned a little about the fuse bits, let’s go through the datasheet and find out all the necessary details about this IC. The image below shows exactly that. As you can see in the Note if we look at Table 28-5, we can find more details about it. Brownout detection is a feature that resets the microcontroller when the supply voltage falls below a certain voltage level. In the ATmega328P IC, we can completely disable the brownout detection or we can set it to the levels that are shown in the above table. of the datasheet shows the Higher Fuse bits of the ATmega328P IC. The watchdog timer is a special timer in the ATmega328P IC which has its separate clock and runs independently. If the watchdog timer is enabled, then you need to clear it with a certain period, otherwise, the watchdog timer will reset the microcontroller. This is a useful feature that comes within many microcontrollers if the processor gets stuck; the watchdog will reset it to prevent any damage to the end application. ; this is a preparatory protocol that is internally built into their hardware, that is used to program and debug the processors. With this feature enabled, you can flash and debug the processor with a single wire attached. But to use it, you will need special hardware that is preparatory to Atmel. The remaining two bits are those bits that you need to avoid unless you exactly know what you are doing. These are the RSTDISBL bit-7 and the SPIEN bit-5. The RSTDISBL (External Reset Disable) as the name implies disables the external hardware reset pin, and the SPIEN bit is used to disable the SPI programming interface. Disabling any of these two bits can completely brick your AVR; so, leaving them alone is a good idea. As you can see in the image below, table 27-7: of the datasheet shows the Lower Fuse bits of the ATmega328P IC. This fuse byte is responsible for setting up the clock source and some other parameters of the clock inside the AVR. In this section, we will learn about all that. The 7th bit or the CKDIV8 flag can be set to divide the clock source by 8, this comes invery handy which youmight already know if you have tried programming the AVRyourself. The next bit is the CKOUT bit and it’s the 6th bit in the Low Fuse Byte. Programming it would output the internal clock signal on the PORTB0 of the microcontroller. The bits-5 and bit-4 SUT1 and SUT0 control the start-up time of the microcontroller. This prevents any start-up actions which may or may not take place before the supply voltage can reach an acceptable minimum threshold voltage level. And the final four CKSEL0 - 4 bits are used to select the clock source of the microcontroller. The table shown below gives you a better understanding of these four bits which are responsible for setting up the clock source, you can find this table on the Clock Source Section of the datasheet. Now, before we get any further, there is one more thing that I should go throughis the table for oscillator start-up delay. By start-up delay, we are referring to bits 4 and 5 of the lower fuse byte. The delays need to be set depending upon the condition that the circuit will operate in and the type of oscillator you are using. The default values are set to slow rising power with 6 clock cycles when a power-up or power-down sequence is performed. Next, there is another delay of 14 clock cycles with 65 Ms of delay after start-up. Phew! That was a lot of information to digest. But before proceeding any further, let’s end this section with a quick note. If you have looked at the datasheet carefully, you must havenoticed, programming a fuse bit means setting it low, i.e.0 (zero), which is the opposite of what we generally do to make a port high or low. You have to keep that in mind while configuring your fuses.

Fuse Bits in Arduino

Itis a tool that can be used to read, write, and modify memory in AVR microcontrollers. It works with SPI and it has a long list of support for different types of programmers. you can download the tool from the link given below.Also, we will be using our favorite microcontroller Arduino. Download Avrdude Version 6.3 Windows-ming32 to our PC and we will make sure that we have the proper driver for our USBasp programmer. Once we do that, we are good to go and we will read the default fuse value first. To do that, you need to run the following command. avrdude.exe -c usbasp -p m328p -U lfuse:r:low_fuse_val.txt:h -U hfuse:r:high_fuse_val.txt:h -U efuse:r:ext_fuse_val.txt:h If everything is right, this command will read the fuse bytes and put them into three separate text files. The image below will give you a better idea of the process. This was the default fuse value we got for an Arduino nano. Now, let’s convert these bits to binary and compare them to their default value from the datasheet. The table below shows exactly that.
CKDIV870 (programmed)1 (unprogrammed)
CKOUT61 (unprogrammed)1 (unprogrammed)
SUT151 (unprogrammed)1 (unprogrammed)
SUT040 (programmed)1 (unprogrammed)
CKSEL330 (programmed)1 (unprogrammed)
CKSEL220 (programmed)1 (unprogrammed)
CKSEL111 (unprogrammed)1 (unprogrammed)
CKSEL000 (programmed)1 (unprogrammed)
RSTDISBL71 (unprogrammed)1 (unprogrammed)
DWEN61 (unprogrammed)1 (unprogrammed)
SPIEN50 (programmed)0 (programmed)
WDTON41 (unprogrammed)1 (unprogrammed)
EESAVE31 (unprogrammed)1 (unprogrammed)
BOOTSZ120 (programmed)0 (programmed)
BOOTSZ010 (programmed)1 (unprogrammed)
BOOTRST01 (unprogrammed)0 (programmed))
711
611
511
411
311
BODLEVEL221 (unprogrammed)1 (unprogrammed)
BODLEVEL111 (unprogrammed)0 (programmed)
BODLEVEL001 (unprogrammed)1 (unprogrammed)
Now, this marks the end of this section. As of now, we have learned a lot about the AVR microcontroller and its fuse bits. So, let’s wrap up this article by putting our theory to the test by altering and experimenting with some of the fuse bits in the Arduino Nano.

Components Required to Test Fuses in AVR

We have talked a lot about the fuses in the above part. But to proceed any further in the article, we need some hardware components and some software tools. In this section, we will talk about those. A list of required components with images is shown below. Breadboard - 1 Arduino Nano - 1 USBasp AVR Programmer - 1 USB Cable - 1 AVR 10-Pin to 6- Pin Converter - 1 Avrdude (Software tool for Programming AVR) LED - 1 330R Resistor - 1 Jumper Cables

Schematic for Testing the Fuse Bits in AVR

The Hardware testing setup is shown below in this setup. We have connected the Arduino Nano to the PC with a USB cable, and we have also connected the USBasp programmer to the PC. The objective of this article is to program the fuse bits in AVR. For that reason, we have connected the USBasp programmer with the Arduino. The image below will give you a better idea of the setup.

Testing the Fuses in AVR

The testing setup is shown below. As you can see, we have connected the Arduino and the USBasp programmer both to the USB of my laptop. Now let’s open the Arduino IDE and upload a basic blink sketch. The content of the basic blink sketch is self-explanatory, so I did not put any details about it. Now let's configure it with Avrdude, flash it, and see what happens. The code we will be using is- avrdude -c usbasp -p m328P -U lfuse:w:0x62:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m Once I do this, you will see the LED will blink extremely slowly because we have calculated and programmed the value for a 16Mhz clock and now after burning the fuses, it’s only a 1Mhz internal RC oscillator. This is why the LED is blinking so slowly. Now let's try to upload a sketch once again. Wewill see that the Arduino gives out an error and the code is not uploaded. Because by altering the fuses, we have also messed up the bootloader settings too. You can see that in the below image. , and once we do that, we can again go to tools and we can click on the burn bootloader option. This will again burn the stock bootloader on your Arduino and everything will go back to as it was before. After the bootloader was flashed back to the Arduino, itwent back to its original state and the last image shows you a blinking LED after the bootloader was burned again. And this marks the end of this article. I hope you enjoyed the article and learned something new. If you haveany questions regarding the article, do not hesitate to put a comment below. Video microcontroller-projects/programming-attiny85-microcontroller-ic-using-arduino

Programming ATtiny85 Microcontroller IC with Arduino Uno

Components Required for Programming ATtiny85

Arduino UNO ATtiny85 IC LED 220-ohm resistor Breadboard Jumper Wires

ATtiny85 Microcontroller Chip - Introduction

is given below: for each pin.
1PB5(PCINT5/ADC0/dW): Pin Change Interrupt 0, Source5 : Reset Pin ADC Input Channel 0 debug WIRE I/O
2PB3(PCINT3/XTAL1/CLKI/ADC3)Pin Change Interrupt 0, Source3 Crystal Oscillator Pin1 External Clock Input ADC Input Channel 3
3PB4 (PCINT4/XTAL2/CLKO/OC1B/ADC2)Pin Change Interrupt 0, Source 4 Crystal Oscillator Pin 2 System Clock Output Timer/Counter1 Compare Match B Output ADC Input Channel 2
4GNDGround Pin
5PB0(MOSI/DI/SDA/AIN0/OC0A/AREF/ PCINT0)SPI Master Data Output / Slave Data Input USI Data Input (Three Wire Mode) USI Data Input (Two Wire Mode) Analog Comparator, Positive Input Timer/Counter0 Compare Match A output External Analog Reference Pin Change Interrupt 0, Source 0
6PB1(MISO/D0/AIN1/OC0B/OC1A/ PCINT1)SPI Master Data Input / Slave Data Output USI Data Output (Three Wire Mode) Analog Comparator, Negative Input Timer/Counter0 Compare Match B Output Timer/Counter1 Compare Match A Output Pin Change Interrupt 0, Source 1
7PB2(SCK/USCK/SCL/ADC1/T0/INT0/ PCINT2)Serial Clock Input USI Clock (Three Wire Mode) USI Clock (Two Wire Mode) ADC Input Channel 1 Timer/Counter0 Clock Source External Interrupt 0 Input Pin Change Interrupt 0, Source 2
8VCCSupply Voltage Pin
and upload the Arduino ISP code. Uno is given below: The positive pin of LED is connected to Pin 0 of the ATtiny85 IC through a 220 resistor while the GND pin is connected to the GND of IC. The complete connections are given in the table below:
Vcc5V
GNDGND
Pin 213
Pin 112
Pin 011
Reset10
and add the below link in the Additional Boards Manager URLs and click ‘OK.ᾍ and search for ‘attinyᾠand install the latest version. and open the Blink example. to 0. Now, go ahead and upload the code. If the LED connected to Pin 0 of Attiny85 IC blinks, then the code is uploaded successfully. to get better insights. Video microcontroller-proejcts/build-a-portable-step-counter-using-attiny85-and-mpu6050

Build a Portable Step Counter using ATtiny85 and MPU6050

In this tutorial, we are going to build an easy and cheap Pedometer using ATtiny85 IC, MPU6050 Accelerometer & Gyroscope, and OLED Display Module. This simple Arduino based step counter is powered by a 3V coin cell, making it easy to carry when you go out for a walk or jog. It also requires very few components to build and the code is also relatively simple. The program in this project uses theMPU6050to measure the magnitude of the acceleration along the 3 axis (X, Y, and Z). Then it calculates the difference of the acceleration magnitude between the previous and current values. If the difference is greater than a certain threshold (For walking greater than 6 and for running greater than 10), then it increases the step count accordingly. The total steps taken are then displayed onOLEDDisplay. , check them out if you are interested.

Components Required

you will need the followingcomponents. Attiny85IC MPU6050 OLEDDisplay Module 2× Push Buttons 5×10K Resistors (SMD)

MPU6050Sensor Module ᾠA Brief Introduction

TheMPU6050module is small in size and has low power consumption, high repetition, high shock tolerance, and low user price points. TheMPU6050comes with anI2Cbus and AuxiliaryI2Cbus interface and can easily interfere with other sensors such as magnetometers andmicrocontrollers.

Attiny85Step Counter Circuit Diagram

The schematic for theMPU6050Step Counteris given below: The above image shows the circuit diagram for interfacingMPU6050andOLEDDisplay withAttiny85IC. The interface betweenMPU6050,OLEDDisplay, andArduinomust be implemented usingI2CProtocol. Hence, theSCLPin(PB2) of theATtiny85is connected to theSCLPinof theMPU6050andOLEDDisplay respectively. Similarly, theSDAPin(PB0) of theATtiny85is connected to theSDAPinof theMPU6050andOLEDDisplay. Two pushbuttons are also connected to thePB3&PB4pin ofATtiny85IC. These buttons can be used to scroll the text or change the text on display. to program theATtiny85IC through USB andDigisparkBoot-loader.

Fabricating PCB forAttiny85Step Counter

The schematic is done, and we can proceed with laying out the PCB. You can design the PCB using any PCB software of your choice. We have usedEasyEDAto fabricate PCB for this project. Below are the 3D model views of the top layer and bottom layer of the Step Counter PCB: The PCB layout for the above circuit is also available for download as Gerber from the link given below: Gerber file forATtiny85Step Counter

Ordering PCB fromPCBWay

Now after finalizing the design, you can proceed with ordering the PCB: , sign up if this is your first time. Then, in the PCB Prototype tab, enter the dimensions of your PCB, the number of layers, and the number of PCByou require. Proceed by clicking on the ‘Quote Nowᾠbutton. You will be taken to a page where to set a few additional parameters like the Board type, Layers, Material for PCB, Thickness, and More, most of them are selected by default, if you are opting for any specific parameters, you can select it inhere. The final step is to upload the Gerber file and proceed with the payment. To make sure the process is smooth,PCBWAYverifies if your Gerber file is valid before proceeding with the payment. This way, you can sure that your PCB is fabrication friendly and will reach you as committed.

Assembling theATtiny85Step Counter PCB

After a few days, we received our PCB in a neat package and the PCB quality was good as always. The top layer and the bottom layer of the board are shown below: After making sure the tracks and footprints were correct. I proceeded with assembling the PCB. The completely soldered board looks like the below:

ATtiny85Step Counter Code Explanation

is given at the end of the document. Here we are explaining some important parts of the code. librarycan be downloaded from the given links. After installing the libraries toArduinoIDE, start the code by including the needed libraries files. #include "TinyWireM.h" #include "TinyOzOLED.h" After including the libraries, define the variables to store the Accelerometer readings. intaccelX, accelY, accelZ; loop, initialize the wire library and reset the sensor through the power management register also initialize theI2Ccommunication forOLEDDisplay. Then in the next lines set the display orientation and enter the register address for accelerometer and gyroscope values. TinyWireM.begin(); OzOled.init(); OzOled.clearDisplay(); OzOled.setNormalDisplay(); OzOled.sendCommand(0xA1); OzOled.sendCommand(0xC8); TinyWireM.beginTransmission(mpu); TinyWireM.write(0x6B); TinyWireM.write(0b00000000); TinyWireM.write(0x1B); function, we request to read all 6 registers for the X, Y, and Z axes. Then we read the data from each register, and because the outputs are two’s complement, combine them appropriately to get the complete accelerometer values. voidgetAccel() { TinyWireM.beginTransmission(mpu); TinyWireM.write(0x3B); TinyWireM.endTransmission(); TinyWireM.requestFrom(mpu, 6); accelX = TinyWireM.read() << 8|TinyWireM.read(); accelY = TinyWireM.read() << 8|TinyWireM.read(); accelZ = TinyWireM.read() << 8|TinyWireM.read(); } Now inside the loop function, first read the X, Y, and Z-axis values and after getting the 3-axis values, calculate the total acceleration vector by taking the square root of X, Y, and Z-axis values. Then calculate the difference between the current vector and the previous vector and if the difference is greater than 6, then increase the step count. getAccel(); vector = sqrt( (accelX * accelX) + (accelY * accelY) + (accelZ * accelZ) ); totalvector = vector - vectorprevious; if (totalvector> 6){ Steps++; } OzOled.printString("Steps", 0, 4); OzOled.printNumber(Steps, 0, 8, 4); vectorprevious = vector; delay(600);

Let’s take ourArduinoStep Counter for a Walk

Once you finished assembling the PCB, connect theATtiny85to the programmer board, and upload the code. Now take the step counter setup in your hands and start walking step by step, it should display the number of steps onOLED. Sometimes it increases the number of steps when the setup vibrates very rapidly or very slowly. andMPU6050. The complete working of the project can also be found in the video linked below. Hope you enjoyed the project and found it interesting to build your own. If you have any questions, please leave them in the comment section below. Code #include "TinyWireM.h" #include "TinyOzOLED.h" int accelX, accelY, accelZ; char mpu = 0x68; float vectorprevious; float vector; float totalvector; int Steps = 0; void setup() { TinyWireM.begin(); OzOled.init(); OzOled.clearDisplay(); OzOled.setNormalDisplay(); OzOled.sendCommand(0xA1); // set Orientation OzOled.sendCommand(0xC8); TinyWireM.beginTransmission(mpu); TinyWireM.write(0x6B); // Power setting address TinyWireM.write(0b00000000); // Disable sleep mode (just in case) TinyWireM.endTransmission(); TinyWireM.beginTransmission(mpu); TinyWireM.write(0x1B); // Config register for Gyro TinyWireM.write(0x00000000); // 250° per second range (default) TinyWireM.endTransmission(); TinyWireM.beginTransmission(mpu); //I2C address of the MPU TinyWireM.write(0x1C); // Accelerometer config register TinyWireM.write(0b00000000); // 2g range +/- (default) TinyWireM.endTransmission(); } void loop() { getAccel(); vector = sqrt( (accelX * accelX) + (accelY * accelY) + (accelZ * accelZ) ); //OzOled.printString("Vec:", 0, 2); //OzOled.printNumber(vector, 0, 5, 2); totalvector = vector - vectorprevious; //OzOled.printString("Pre:", 0, 4); //OzOled.printNumber(vectorprevious, 0, 5, 4); //OzOled.printString("Diff:", 0, 6); //OzOled.printNumber(totalvector, 0, 5, 6); if (totalvector > 6){ Steps++; } //String Step_count = String(Steps); //char data[2]; //Step_count.toCharArray(data, 2); //OzOled.printBigNumber(data, 6, 2, 3); OzOled.printString("Steps", 0, 4); OzOled.printNumber(Steps, 0, 8, 4); vectorprevious = vector; delay(600); //OzOled.clearDisplay(); } void getAccel() { TinyWireM.beginTransmission(mpu); //I2C address of the MPU TinyWireM.write(0x3B); // Acceleration data register TinyWireM.endTransmission(); TinyWireM.requestFrom(mpu, 6); // Get 6 bytes, 2 for each DoF accelX = TinyWireM.read() << 8|TinyWireM.read(); accelY = TinyWireM.read() << 8|TinyWireM.read(); accelZ = TinyWireM.read() << 8|TinyWireM.read(); // OzOled.printNumber(accelX, 0, 0, 0); // OzOled.printNumber(accelY, 0, 0, 2); //OzOled.printNumber(accelZ, 0, 0, 4); } Video microcontroller-projects/attiny85-ic-programming-through-usb-using-digispark-bootloader

Programming ATtiny85 IC directly through USB using Digispark Bootloader

Its small size and low power consumption make it a great match for portable projects with small footprints and low power requirements. But getting your code onto the chip can be a little bit of a challenge as it doesn’t have any USB interface like microcontroller boards. , so that we can directly plugin and program it like other microcontroller boards.

Components Required to Program ATtiny85 through USB

Arduino UNO (Only for the first time while uploading bootloader) ATtiny85 IC USB A-type Plug Male 3 Resistors (2×47 & 1×1k) 3 Diodes (2×Zener Diode & 1×IN5819 Diode ) 8-Pin IC Base Breadboard Jumper Wires

ATtiny85 Microcontroller IC ᾠIntroduction

is given below: for each pin is given in below table:
1PB5(PCINT5/ADC0/dW): Pin Change Interrupt 0, Source5 : Reset Pin ADC Input Channel 0 debug WIRE I/O
2PB3(PCINT3/XTAL1/CLKI/ADC3)Pin Change Interrupt 0, Source3 Crystal Oscillator Pin1 External Clock Input ADC Input Channel 3
3PB4 (PCINT4/XTAL2/CLKO/OC1B/ADC2)Pin Change Interrupt 0, Source 4 Crystal Oscillator Pin 2 System Clock Output Timer/Counter1 Compare Match B Output ADC Input Channel 2
4GNDGround Pin
5PB0(MOSI/DI/SDA/AIN0/OC0A/AREF/ PCINT0)SPI Master Data Output / Slave Data Input USI Data Input (Three Wire Mode) USI Data Input (Two Wire Mode) Analog Comparator, Positive Input Timer/Counter0 Compare Match A output External Analog Reference Pin Change Interrupt 0, Source 0
6PB1(MISO/D0/AIN1/OC0B/OC1A/ PCINT1)SPI Master Data Input / Slave Data Output USI Data Output (Three Wire Mode) Analog Comparator, Negative Input Timer/Counter0 Compare Match B Output Timer/Counter1 Compare Match A Output Pin Change Interrupt 0, Source 1
7PB2(SCK/USCK/SCL/ADC1/T0/INT0/ PCINT2)Serial Clock Input USI Clock (Three Wire Mode) USI Clock (Two Wire Mode) ADC Input Channel 1 Timer/Counter0 Clock Source External Interrupt 0 Input Pin Change Interrupt 0, Source 2
8VCCSupply Voltage Pin

Flashing Boot-loader on ATtiny85 Using Arduino Uno

on ATtiny85. A step by step guide to flash bootloader onto ATtiny85 using Arduino Uno and Arduino IDE is given below: and upload the Arduino ISP code. The complete schematic for Flashing Boot-loader on ATtiny85 is given below: A 10 μf capacitor is connected between the Reset and GND pin of Arduino. The complete connections are given in the below table:
Vcc5V
GNDGND
Pin 213
Pin 112
Pin 011
Reset10
Now plug-in the Arduino Uno to the laptop and open Arduino IDE. Find what COM port the Uno is connected to. In my case, it's COM5. " and change the COM port number "PCOM5" with whatever COM port number your Uno is connected to. Save the changes before exiting. ). " and select "Run as Admin". It takes approx 5 to 6 seconds to flash the boot-loader. If all went well, you should receive this message "AVRdude done. Thank you. Press any key to continue...". through USB is given below:

Circuit Diagram for ATtiny Programmer

we are only connecting Male USB Plug with ATtiny85. The R3 is a pull-up resistor that is connected between Vcc and PB3 pins of IC while the Zener Diodes (D1-D2) are added for total USB interface protection. After soldering all the components on the perf board, it will look something like below:

Installing Digispark Drivers

ᾠapplication to install the drivers. and click on ‘Show hidden Devices.ᾍ

Setting up Arduino IDE to Program ATttiny85

and add the below link in the Additional Boards Manager URLs and click ‘OK.ᾍ and search for ‘Digistump AVRᾠand install the latest version. and open the Blink example. Change the pin number on there from LED_BUILTIN to 0. ᾠboard. Then click on the upload button in Arduino IDE. Connect the ATtiny85 board to the computer, only when the Arduino IDE displays a message saying “Plugin device nowᾮ Once the code is uploaded, the LED connected to ATtiny85 should start blinking. Video microcontroller-projects/bluetooth-controlled-arduino-scoreboard-using-p10-led-matrix-display

Build an Arduino Scoreboard using Outdoor P10 LED Matrix Display and Update Scores Remotely using Smartphone

The brain of this project is an Arduino Nano, and for the display part, we will be using a P10 LED matrix to show the score remotely in real-time.

The P10 LED Display Matrix

by combining any number of such panels in any row and column structure. to build a simple LEDBoard. uses a 10-pin mail headerfor input and output connection, in this section, we have described all the necessary pins of this module. Also, you can seethere is an external 5V connector in the middle of the module which is used to connect the external power to the board. Enable: This pin is used to control the brightness of the LED panel, by giving a PWM pulse to it. A, B: These are called multiplex select pins. They take digital input to select any multiplex rows. Shift clock (CLK), Store clock (SCLK), and Data: These are the normal shift register control pins. Here a shift register 74HC595 is used. to Arduino is a very simple process, in our circuit, we configured pin 9 of the Arduino as Enable pin, Pin 6 as Pin A, Pin 7 as pin B, Pin 13 is the CLK, Pin 8 is the SCLK, Pin 11 is the DATA, and finally Pin GND is the GND pin for the module and Arduino, a complete table below explain the pin configuration clearly.
ENABLE9
A6
B7
CLK13
SCLK8
DATA11
GNDGND
Connect the power terminal of the P10 moduleto an external 5V power source, because 512 LEDs will consume a lot of power. It is recommended to connect a 5V, 3 Amp DC power supply to a single unit of P10 LED module. If you are planning to connect more numbers module, then increase your SMPS capacity accordingly.

Components Required for Arduino Scoreboard

As this is a very simple project, the components requirements are very generic, a list of required components are shown below, you should be able to find all of the listed material in your local hobby store. Arduino Nano P10 LED matrix display Breadboard 5V, 3 AMP SMPS HC-05 Bluetooth Module Connecting Wires

Circuit Diagram for Arduino Scoreboard

is shown below as this project is very simple, I have used the popular software fritzing to develop the schematic. The working of the circuit is very simple, we have an Android application and a Bluetooth module, to successfully communicate with the Bluetooth module, you have to pair the HC-05 module with the android application. Once we are connected, we can send the string that we want to display, once the string is sent, Arduino will process the string and convert it to a signal that the internal 74HC595 shift resistor can understand, after the data is sent to the shift resistor, its ready to display.

Arduino Scoreboard Code Explanation

at the bottom of this Tutorial. , which will be used for interrupt programming in our code. ᾠfor this project. #include <SPI.h> #include <DMD.h> #include <TimerOne.h> #include "SystemFont5x7.h" #include "Arial_black_16.h" In the next step, the number of rows and columns are defined for our LED matrix board. We have usedonly one module in this project, so both ROW value and COLUMN value can be defined as 1. #define ROW 1 #define COLUMN 1 #define FONT Arial_Black_16 DMD led_module (ROW, COLUMN); After that, all the variables used in the code are defined. A character variable is used to receive serial data from Android App, two integer values are used to store scores, and an array is defined which stores the final data to be displayed on the Matrix. char input; int a = 0, b = 0; int flag = 0; char cstr1[50]; for doing certain events as defined by the user in the program. void scan_module() { led_module.scanDisplayBySPI(); } which means all the pixels are defined as OFF. where 9600 is the baud rate for Bluetooth communication. void setup() { Serial.begin(9600); Timer1.initialize(2000); Timer1.attachInterrupt(scan_module); led_module.clearScreen( true ); } Here, the serial data availability is checked, if there is valid data is coming from Arduino or not. The received data from the App is stored in a variable. if(Serial.available() > 0) { flag = 0; input = Serial.read(); Then, the received value was compared with the predefined variable. Here, in the Android application, two buttons are taken to select the scores for both teams. When button 1 is pressed, Character ‘aᾠis transmitted to Arduino and when button2 is pressed, Character ‘bᾠis transmitted to Arduino. Hence, in this section, this data is matched, and if matched, then the respective score values are incremented as shown in the code. if (input == 'a' && flag == 0) { flag = 1; a++; } else if (input == 'b' && flag == 0) { flag = 1; b++; } else; Then, the received data is converted into a character Array, as the P10 matrix function is only capable of displaying character data type. This is why all variables are converted and concatenated into a character array. (String("HOME:")+String(a) + String(" - ") + String("AWAY:")+String(b)).toCharArray(cstr1, 50); function is used to display the desired information on the P10 board. led_module.selectFont(FONT); led_module.drawMarquee(cstr1,50, (32 * ROW), 0); Finally, as we need a scrolling message display, I have written a code to shift our whole message from Right to Left directions using a certain period. long start = millis(); long timming = start; boolean flag = false; while (!flag) { if ((timming + 30) < millis()) { flag = led_module.stepMarquee(-1, 0); timming = millis(); } } This marks the end of our coding process. And now it’s ready for uploading. from the given link. Once installed, open the app and the home screen should look like the below image. before, pair the module using your phone’s Bluetooth setting and then do this step. The screen will look like shown: Then, from the list, click on “HC-05ᾠas this is the name of our Bluetooth module used here. After clicking on it, it will show connected on the screen. Then we can proceed with the scoreboard. Click on any button between “Homeᾠ& “Awayᾠas shown in the App. If the Home button is selected, the score of Home will be incremented in the P10 display. Similarly, if the Away button is selected, the score of Away will be incremented. The below image shows how the final screen looks. Code #include <SPI.h> #include <DMD.h> #include <TimerOne.h> #include "SystemFont5x7.h" #include "Arial_black_16.h" #define ROW 1 #define COLUMN 1 #define FONT Arial_Black_16 char input; int a = 0, b = 0; int flag = 0; char cstr1[50]; DMD led_module(ROW, COLUMN); void scan_module() { led_module.scanDisplayBySPI(); } void setup() { Serial.begin(9600); Timer1.initialize(2000); Timer1.attachInterrupt(scan_module); led_module.clearScreen( true ); } void loop() { if(Serial.available() > 0) { flag = 0; input = Serial.read(); if (input == 'a' && flag == 0) { flag = 1; a++; } else if (input == 'b' && flag == 0) { flag = 1; b++; } else; } (String("HOME:")+String(a) + String(" - ") + String("AWAY:")+String(b)).toCharArray(cstr1, 50); led_module.selectFont(FONT); led_module.drawMarquee(cstr1,50, (32 * ROW), 0); long start = millis(); long timming = start; boolean flag = false; while (!flag) { if ((timming + 30) < millis()) { flag = led_module.stepMarquee(-1, 0); timming = millis(); } } } Video microcontroller-projects/interfacing-mq135-gas-sensor-with-arduino-to-measure-co2-levels-in-ppm

Measuring CO2 Concentration in Air using Arduino and MQ-135 Sensor

has also started to gain importance. gas using Arduino.

Components Required

Arduino Nano MQ-135 Sensor Jumper Wires 0.96ᾠSPI OLED Display Module Breadboard 22K Resistor

0.96ᾠOLED Display Module

OLED (Organic Light-Emitting Diodes) is a self light-emitting technology, constructed by placing a series of organic thin films between two conductors. A bright light is produced when an electric current is applied to these films. OLEDs are using the same technology as televisions, but have fewer pixels than in most of our TVs. by reading the linked article. The pins and its functions are explained in the table below:
GndGroundGround pin of the module
VddVcc, 5VPower pin (3-5V tolerable)
SCKD0,SCL,CLKActs as the clock pin. Used for both I2C and SPI
SDAD1,MOSIData pin of the module. Used for both IIC and SPI
RESRST, RESETResets the module (useful during SPI)
DCA0Data Command pin. Used for SPI protocol
CSChip SelectUseful when more than one module is used under SPI protocol
OLED Driver IC: SSD1306 Resolution: 128 x 64 Visual Angle: >160° Input Voltage: 3.3V ~ 6V Pixel Colour: Blue Working temperature: -30°C ~ 70°C

Preparing the MQ-135 Sensor

MQ-135 Gas Sensor is an air quality sensor for detecting a wide range of gases, including NH3, NOx, alcohol, benzene, smoke, and CO2. MQ-135 sensor can either purchased as a module or just as a sensor alone. In this project, we are using an MQ-135 sensor module to measure CO2 concentration in PPM. The circuit diagram for the MQ-135 board is given below: in the board, you can see a 1KΩ (102) load resistor. So to measure the appropriate CO2 concentration values, you have to replace the 1KΩ resistor with a 22K resistor.

Circuit Diagram to Interface MQ135 with Arduino

is given below: The circuit is very simple as we are only connecting the MQ-135 Sensor and OLED Display module with Arduino Nano. MQ-135 Gas Sensor and OLED Display module both are powered with +5V and GND. The Analog Out pin of the MQ-135 sensor is connected to the A0 pin of Arduino Nano. Since the OLED Display module uses SPI communication, we have established an SPI communication between the OLED module and Arduino Nano. The connections are shown in the below table:
1GNDGround
2VCC5V
3D010
4D19
5RES13
6DC11
7CS12
After connecting the hardware according to the circuit diagram, the Arduino MQ135 sensor setupshould look something like below:

Calculating the Ro Value of MQ135 Sensor

values: #include "MQ135.h" void setup (){ Serial.begin (9600); } void loop() { MQ135 gasSensor = MQ135(A0); // Attach sensor to pin A0 float rzero = gasSensor.getRZero(); Serial.println (rzero); delay(1000); } file and change the RLOAD & RZERO values. ///The load resistance on the board #define RLOAD 22.0 ///Calibration resistence at atmospheric CO2 level #define RZERO 5804.99 ///Atmospheric CO2 level for calibration purposes #define ATMOCO2 397.13

Code to Measure CO2 Using Arduino MQ135 Sensor

. After installing the libraries to Arduino IDE, start the code by including the needed libraries files. #include "MQ135.h" #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> variables according to your display. #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 Then define the SPI communication pins where OLED Display is connected. #define OLED_MOSI 9 #define OLED_CLK 10 #define OLED_DC 11 #define OLED_CS 12 #define OLED_RESET 13 Then, create an Adafruit display instance with the width and height defined earlier with the SPI communication protocol. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); After that, define the Arduino pin where the MQ-135 sensor is connected. int sensorIn = A0; function. Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC); display.clearDisplay(); function. val = analogRead(A0); Serial.print ("raw = "); and reading from the analog pin. float ppm = gasSensor.getPPM(); Serial.print ("ppm: "); Serial.println (ppm); display.setTextSize(1); display.setTextColor(WHITE); function. display.setCursor(18,43); display.println("CO2"); display.setCursor(63,43); display.println("(PPM)"); display.setTextSize(2); display.setCursor(28,5); display.println(ppm); method to display the text on OLED Display. display.display(); display.clearDisplay();

Testing the Interfacing of MQ-135 Sensor with Arduino

Once the hardware and code are ready, it is time to test the sensor. For that, connect the Arduino to the laptop, select the Board and Port, and hit the upload button. Then open your serial monitor and wait for some time (preheat process), then you'll see the final data. The Values will be displayed on OLED display as shown below: and working video are given below. If you have any doubts, leave them in the comment section. Code /* * Interfacing MQ135 Gas Senor with Arduino * Author: Ashish * Website: www.circuitdigest.com * Date: 11-11-2020 */ // The load resistance on the board #define RLOAD 22.0 #include "MQ135.h" #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for SSD1306 display connected using software SPI (default case): #define OLED_MOSI 9 #define OLED_CLK 10 #define OLED_DC 11 #define OLED_CS 12 #define OLED_RESET 13 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); MQ135 gasSensor = MQ135(A0); int val; int sensorPin = A0; int sensorValue = 0; void setup() { Serial.begin(9600); pinMode(sensorPin, INPUT); display.begin(SSD1306_SWITCHCAPVCC); display.clearDisplay(); display.display(); } void loop() { val = analogRead(A0); Serial.print ("raw = "); Serial.println (val); // float zero = gasSensor.getRZero(); // Serial.print ("rzero: "); //Serial.println (zero); float ppm = gasSensor.getPPM(); Serial.print ("ppm: "); Serial.println (ppm); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(18,43); display.println("CO2"); display.setCursor(63,43); display.println("(PPM)"); display.setTextSize(2); display.setCursor(28,5); display.println(ppm); display.display(); display.clearDisplay(); delay(2000); } Video microcontroller-projects/controlling-ws2812b-rgb-led-shield-with-arduino-and-blynk

Controlling a WS2812B RGB LED Matrix with Android App using Arduino and Blynk

, so do check that out if that’s interesting to you. That is why in this project we are going to use a Neopixel Based RGB LED matrix shield, Arduino, and Blynk application to produce many fascinating animation effects and colors which we will be able to control with the Blynk app. So let’s get started!!!

Adafruit 5X8 NeoPixel Shield for Arduino

Multiple NeoPixel Shields can also be connected to form a larger Shield if that's a requirement. To control the RGB LEDs, a single Arduino pin is required, so in this tutorial, we have decided to use pin 6 of the Arduino to do so. In our case, the LEDs are powered from the Arduino’s inbuilt 5V pin, which is sufficient for powering about “a third of the LEDsᾠat full brightness. If you need to power more LEDs, then you can cut the inbuilt trace and use an external 5v supply to power the shield using the External 5V terminal.

Understanding the Communication Process Between Blynk App and Arduino

where I find the operating voltage range of the shield is 4V to 6V and the current consumption is found out 50mA per LED at 5V with red, green, and blue at full brightness. It is having Reverse-voltage protection on the external power pins and a Reset button on the Shield to reset the Arduino. It has also an External Power input pin for LEDs if a sufficient amount of power is not available through internal circuitry. on our smartphone where the parameters such as color, brightness can be controlled. After setting up the parameters, if any changes happen to the app, it's to the Blynk cloud where our PC is also connected and ready to receive the updated data. The Arduino Uno is connected to our PC via USB cable with a communication port opened, with this communication port (COM Port), data can be exchanged between the Blynk cloud and Arduino UNO. PC is requesting data from Blynk cloud at constant time intervals and when an updated data is received, it transfers it to Arduino and makes user-defined decisions like controlling the RGB led brightness and Colors. The RGB LED shield is placed on the Arduino LED and connected via a single data pin for communication, by default it is connected via the D6 pin of Arduino. The serial data sent from Arduino UNO are sent to the Neopixel shied which is then reflected on the LED matrix.

Components Required

Arduino UNO 8*5 RGB LED Matrix shield USB A/B cable for Arduino UNO Laptop/PC

Adafruit RGB LED Shield and Arduino - Hardware Connection

have three pins, one is for data and another two is used for power, but this specific Arduino shield makes the hardware connection very simple, all we have to do is place the Neopixel LED matrix on the top of Arduino UNO. In our case, the LED is powered from the default Arduino 5V Rail. After placing the Neopixel Shield, the setup looks like below:

Configuring up the Blynk Application

and Appliances using our smartphones. First of all, a Graphical User Interface (GUI) needs to be created to control the RGB LED matrix. The application will send all the selected parameters from the GUI to the Blynk Cloud. In the receiver section, we have Arduino connected to the PC via a serial communication cable. Hence, PC requests data from the Blynk cloud,and thesedata are sent to Arduino for necessary processing. So, let’s get started with the Blynk application setup. from the Google Play store (IOS users can download from App Store). After installation, Sign-up using your email id and Password. in our registered mail. Save the Authenticate ID for future reference. Open the project in Blynk, click on the ᾫᾠsign where we will get the widgets which we can use in our project. In our case, we need an RGB Color Picker which is listed as “zeRGBaᾠas shown below. After dragging the widgets to our project, now we have to set its parameters which are used to send the color RGB values to Arduino UNO. ᾠand set the pin to “V2ᾠwhich is shown in the image below.

Arduino Code Controlling Adafruit WS2812B RGB LED Shield

After completion of the hardware connection, the code needs to be uploaded to Arduino. The step by step explanation of the code is shown below. Then search for Blynk in the search box and then download and install the Blynk package for Arduino UNO. from the given link. Once you got that, you can include it with the Include ZIP Library option. #define BLYNK_PRINT DebugSerial #include <Adafruit_NeoPixel.h> #include <SoftwareSerial.h> Then we define the number of LEDs, which is required for our LED matrix, also we define the pin-number which is used to control the LED parameters. #define PIN 6 #define NUM_PIXELS 40 array, which we have saved earlier. char auth[] = "HoLYSq-SGJAafQUQXXXXXXXX"; Here software serial pins are used as debug console. So, the Arduino pins are defined as debug serial below. #include <SoftwareSerial.h> SoftwareSerial DebugSerial(2, 3); the LED Matrix is initialized. void setup() { DebugSerial.begin(9600); pixels.begin(); Serial.begin(9600); Blynk.begin(Serial, auth); } which checks for incoming commands from blynk GUI and executes the operations accordingly. void loop() { Blynk.run(); } function is an inbuilt function that gets called whenever the associated virtual pin’s state/value changes. we can run code inside this function just like any other Arduino function. function as shown in the code below. function is used to display the set colour in the Matrix. BLYNK_WRITE(V2) { int r = param[0].asInt(); int g = param[1].asInt(); int b = param[2].asInt(); pixels.clear(); pixels.setBrightness(20); for (int i=0; i<=NUM_PIXELS;i++) { pixels.setPixelColor(i, pixels.Color(r, g, b)); } pixels.show(); }

Uploading the Code to Arduino Board

First, we need to select the PORT of the Arduino inside the Arduino IDE, then we need to upload the code into Arduino UNO. After a successful upload, note down the Port-Number which will be used for our serial communication setup. After this, find the script folder of the Blynk library on your PC. It gets installed when you install the library, mine was in, “C:\Users\PC_Name\Documents\Arduino\libraries\Blynk\scriptsᾼ/em> which is a batch file used for serial communication which we need to edit with notepad. Open the file with notepad and change the Port number to your Arduino Port number which you have noted in the last step. After editing, save the file and run the batch file by double-clicking on it. Then, you must be seeing a window like shown below: Now, it’s time for testing the circuit and its functionality. Open the Blynk application and open the GUI and click on the Play button. After that, you can select any of your desired colors to be reflected on the LED Matrix. As shown below, in my case I have selected the Red and Blue color, it is being displayed on the Matrix. Similarly, you can also try to make different animations using these LED matrices by customizing the coding a bit. Code #define BLYNK_PRINT DebugSerial #include <Adafruit_NeoPixel.h> #include <SoftwareSerial.h> SoftwareSerial DebugSerial(2, 3); #include <BlynkSimpleStream.h> char auth[] = "-54csCxRMCSyHxxxxxxxxx"; #define PIN 6 #define NUM_PIXELS 40 Adafruit_NeoPixel pixels(NUM_PIXELS, PIN, NEO_GRB + NEO_KHZ800); void setup() { DebugSerial.begin(9600); pixels.begin(); Serial.begin(9600); Blynk.begin(Serial, auth); } void loop() { Blynk.run(); } BLYNK_WRITE(V2) { int r = param[0].asInt(); int g = param[1].asInt(); int b = param[2].asInt(); pixels.clear(); pixels.setBrightness(20); for (int i=0; i<=NUM_PIXELS;i++) { pixels.setPixelColor(i, pixels.Color(r, g, b)); } pixels.show(); } Video microcontroller-projects/interfacing-gravity-inrared-co2-sensor-to-measure-carbon-dioxide-in-ppm

Interfacing Gravity Infrared CO2 Sensor with Arduino to Measure Carbon Dioxide in PPM

and can install it in our area. to build an air quality monitor.

Components Required

Arduino Nano Gravity Infrared CO2 Sensor V1.1 Jumper Wires 0.96ᾠSPI OLED Display Module Breadboard

Gravity Infrared CO2 Sensor

This sensor is based on non-dispersive infrared (NDIR) technology and has good selectivity and oxygen-free dependency. It integrates temperature compensation and supports DAC output. The effective measuring range of this sensor is from 0 to 5000ppm with an accuracy of ± 50ppm + 3%. This Infrared CO2 Sensor can be used in HVAC, indoor air quality monitoring, industrial process, and security protection monitoring, agriculture, and animal husbandry production process monitoring. The below figure and table shows the pin assignments for the Infrared CO2 Sensor:
1SignalAnalog Output (0.4~2V)
2VCCVCC (4.5~5.5V)
3GNDGND
Gas Detection: Carbon Dioxide (CO2) Operating Voltage: 4.5 ~ 5.5V DC Preheating Time: 3min Response Time: 120s Operating Temperature: 0 ~ 50 ₍ Operating Humidity: 0 ~ 95% RH (no condensation) Waterproof and anti-corrosion High cycle life Anti-water vapor interference

0.96ᾠOLED Display Module

OLED (Organic Light-Emitting Diodes) is a self light-emitting technology, constructed by placing a series of organic thin films between two conductors. A bright light is produced when an electric current is applied to these films. OLEDs are using the same technology as televisions, but have fewer pixels than in most of our TVs. For this project, we are using aMonochrome 7-pin SSD1306 0.96ᾠOLED display. It can work on three different communications Protocols: SPI 3 Wire mode, SPI four-wire mode, and I2C mode. The pins and its functions are explained in the table below: in the previous article.
GndGroundGround pin of the module
VddVcc, 5VPower pin (3-5V tolerable)
SCKD0,SCL,CLKActs as the clock pin. Used for both I2C and SPI
SDAD1,MOSIData pin of the module. Used for both IIC and SPI
RESRST, RESETResets the module (useful during SPI)
DCA0Data Command pin. Used for SPI protocol
CSChip SelectUseful when more than one module is used under SPI protocol
OLED Driver IC: SSD1306 Resolution: 128 x 64 Visual Angle: >160° Input Voltage: 3.3V ~ 6V Pixel Colour: Blue Working temperature: -30°C ~ 70°C by following the link.

Circuit Diagram

is given below: , we have established an SPI communication between the OLED module and Arduino Nano. The connections are shown in the below table:
1GNDGround
2VCC5V
3D010
4D19
5RES13
6DC11
7CS12
After connecting the hardware according to the circuit diagram, it should look something like below:

Arduino Code to Measure CO2 Concentration

project is given at the end of the document. Here we are explaining some important parts of the code. The Infrared CO2 sensor doesn’t require any library as we are reading the voltage values directly from the analog pin of Arduino. After installing the libraries to Arduino IDE, start the code by including the needed libraryfiles. Dust sensor doesn’t require any library as reading is taken directly from the analog pin of Arduino. #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> variables according to your display. #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 Then define the SPI communication pins where OLED Display is connected. #define OLED_MOSI 9 #define OLED_CLK 10 #define OLED_DC 11 #define OLED_CS 12 #define OLED_RESET 13 Then, create an Adafruit display instance with the width and height defined earlier with the SPI communication protocol. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); After that, define the Arduino pin where the CO2 sensor is connected. int sensorIn = A0; function. Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC); analogReference(DEFAULT); function. After that, convert these analog signal values to voltage values. void loop(){ int sensorValue = analogRead(sensorIn); float voltage = sensorValue*(5000/1024.0); After that, compare the voltage values. If the voltage is 0 V, it means that some problem has occurred with the sensor. If voltage is greater than 0 V but lesser than 400 V, then it means that the sensor is still in the pre-heating process. if(voltage == 0) { Serial.println("Fault"); } else if(voltage < 400) { Serial.println("preheating"); } If the voltage is equal or greater than 400 V, then convert it toCO2 concentration values. else { int voltage_diference=voltage-400; float concentration=voltage_diference*50.0/16.0; display.setTextSize(1); display.setTextColor(WHITE); function. display.println("CO2"); display.setCursor(63,43); display.println("(PPM)"); display.setTextSize(2); display.setCursor(28,5); display.println(concentration); method to display the text on OLED Display. display.display(); display.clearDisplay();

Testing the Interfacing of Gravity Infrared CO2 Sensor with Arduino

Once the hardware and code are ready, it is time to test the sensor. For that, connect the Arduino to the laptop, select the Board and Port, and hit the upload button. Then open your serial monitor and wait for some time (preheat process), then you'll see the final data. The Values will be displayed on OLED display as shown below: Before using the sensor, let the sensor heat-up for approx 24 hours to get correct PPM values. When I powered the sensor for the first time, the output CO2 concentration was 1500 PPM to 1700PPM and after a 24 hour heat-up process, the output CO2 concentration decreased to 450 PPM to 500 PPM that are the correct PPM values. So it is necessary to calibrate the sensor before using it to measure the CO2 concentration. for technical help. Code int sensorIn = A4; #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for SSD1306 display connected using software SPI (default case): #define OLED_MOSI 9 #define OLED_CLK 10 #define OLED_DC 11 #define OLED_CS 12 #define OLED_RESET 13 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); void setup(){ Serial.begin(9600); // Set the default voltage of the reference voltage analogReference(DEFAULT); display.begin(SSD1306_SWITCHCAPVCC); display.clearDisplay(); display.display(); } void loop(){ //Read voltage int sensorValue = analogRead(sensorIn); // The analog signal is converted to a voltage float voltage = sensorValue*(5000/1024.0); if(voltage == 0) { Serial.println("Fault"); } else if(voltage < 400) { Serial.println("preheating"); } else { int voltage_diference=voltage-400; float concentration=voltage_diference*50.0/16.0; // Print Voltage Serial.print("voltage: "); Serial.print(voltage); Serial.println("mv"); //Print CO2 concentration Serial.print("CO2 Concentration: "); Serial.print(concentration); Serial.println("ppm"); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(18,43); display.println("CO2"); display.setCursor(63,43); display.println("(PPM)"); display.setTextSize(2); display.setCursor(28,5); display.println(concentration); display.display(); display.clearDisplay(); } delay(2000); } Video microcontroller-projects/arduino-based-automatic-surface-disinfecting-robot-using-ultraviolet-lights

Automatic Surface Disinfecting Robot using Ultraviolet Lights

that will be able to kill the coronavirus in the hospital and apartment building, and for that, we are going to be using an Arduino, some UV LEDs, and ultrasonic sensors. , so do check those out if that sounds interesting to you. This is just a model project to understand the basics of a sanitization robot. We do not claim that the LEDs used in this project or the robot by itself can kill the CVOID-19 virus. This project is only for educational purposes.

How canUV Light Sterilize Viruses and Pathogens?

, you can check out the linked article which explains in detail.

Working of the Ultraviolet Light Enabled Surface-Disinfecting Robot

, first is the range, it has a longer range compared to the range of an IR based proximity sensor. Second, like the IR sensor, sunlight doesn’t interfere with the sensing capabilities of the sensor. The image below shows all the sensors used in this project. we can calculate the distance of the obstacle. , there we have discussed the working principle of this sensor in detail. In this robot, we have three ultrasonic sensors for detecting obstacles in the left, right, and front. When an obstacle comes in front of any sensor (at a certain distance) the robot will turn in to the opposite side and avoid that obstacle for example if an obstacle comes in front of the left sensor robot moves to the right. (Two on each side and two on the downside) so this gives a 360°+ downside sterilization. This robot is 100% safe to operate and it will detect items in the environment for its operation and the safety of operators (obstacle avoidance). The robot is fully autonomous when UV irradiation is being performed this robot has a full 360-degree movement.

Components Needed to Build the Ultraviolet Light Enabled Surface-Disinfecting Robot

As we have used very generic components to build the control and hardware section of the robot, you should be able to find all of those in your local hobby store. which is why acomplete list of required material with an image is shown below. Arduino Pro Mini (1) HC-SR04 Ultrasonic module (3) L293D Motor driver (1) 5Volt N20 motors and mounting brackets (2) N20 motor wheels (2) UV LEDs (8) 7805 Voltage Regulator (1) 7.4V Li-Ion Battery (1) 330R Resistor (10) Dotted Board (1) Foam Board or MDF (As per Requirement) castor wheel (1)

Circuit Diagram - Ultraviolet Light Enabled Surface-Disinfecting Robot

in parallel each of which contains a current limiting resistor and we tied them all up to VCC and ground. In our case, we choose this resistor according to the LED type we are using, the LEDs are generic type so I am using a 330ohm resistor. The Arduino, Ultrasonic modules, motor driver, and motors work on 5 Volt higher voltage will kill it and we are using a 7.4-volt battery to convert that into5 Volt,7805 voltage regulator is used.

Building the Circuit For the Robot using Arduino Pro Mini and A Piece of Dotted Board

We are building a moving robot so we need to make everything as tiny as possible. To solder every component together, first,I took a very small dot PCB and place every component according to the circuit diagram, and solder everything. This part is very simple but do it with care. Also, try to use a female header pin for connecting Arduino pro mini and motors. After completing the soldering process, the board and the sensors look like the image shown below.

Building the Enclosure for Arduino Based Sterilizing Robot

and hide all other circuitry for better finishing, that is why we need an enclosure. For our build, we decided to build it ourselves, while building, we have plenty of options, like foam sheet, MDF, cardboard, etc. Here we choose to go for afoam sheet because it's very easy to modify and the finishing looks great. If you have anything else in your mind, you can go for that. To build the enclose, first we took the form sheet and drawn all the necessary blocks, after which we cut them together for later use. The first four blocks we cut was 11 CM’s each, once that was done, we cut out the bottom of the bot using four, 3CM square blocks and we drilled all the necessary holes, the first big hole will be used for the castor wheel and the other two will hold the UV LEDs. You can check out the image for a better understanding. on chase using its brackets. On the other square, we fixed four rectangles like a box and insert ultrasonic sensors and LEDs. After checking everything once again, we finally place the battery and close it with motor chases. But before closing, we put a switch outside. That's all about building the robot if you are confused with anything, you can refer to the images. As you can see, the image below shows the final build and it looks and works great, you can find a video that shows the working of this robot.

Code Explanation - Ultraviolet Light Enabled Surface-Disinfecting Robot

Below we have described the code in a step-by-step manner. We are not using any extra libraries, to decode the distance data from the HC-SR04 sensor, because it's very simple. In the following, we described howfirstwe need to define the Trigger Pin and Echo Pin which are connected to the Arduino board. In this project, we have three Echo Pins and three trigger pins. Note that 1 means left sensor, 2 is the front sensor, and 3 is the right sensor. const int trigPin1 = 3; const int echoPin1 = 5; const int trigPin2 = 6; const int echoPin2 =9; const int trigPin3 = 10; const int echoPin3 = 11; Then we defined variables for the distance whichall are (int) type variables and for the duration, we chose to use (long). Again we have three of each. long duration1; long duration2; long duration3; int distanceleft; int distancefront; int distanceright; Also, we enable the serial monitor for troubleshooting pinMode(trigPin1, OUTPUT); pinMode(trigPin2, OUTPUT); pinMode(trigPin3, OUTPUT); pinMode(echoPin1, INPUT); pinMode(echoPin2, INPUT); pinMode(echoPin3, INPUT); Serial.begin(9600); for the input of the motor driver. pinMode(4, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(12, OUTPUT); when the sound wave will end which will stop the counting. And this function gives the length of the pulse in microseconds. For calculating the distance, we will multiply the duration by 0.034 (speed of sound in air is 340m/s ) and divide it by 2 (this is due to the back and forth traveling of the sound wave). Finally, we store the distance of each sensor in corresponding integers. digitalWrite(trigPin1, LOW); delayMicroseconds(2); digitalWrite(trigPin1, HIGH); delayMicroseconds(10); digitalWrite(trigPin1, LOW); duration1 = pulseIn(echoPin1, HIGH); distanceleft = duration1 * 0.034 / 2; Serial.print("Distance1: "); Serial.println(distanceleft); statement, thus we control the movement of the robot. This is very simple, first, we gave an obstacle distance value in this case that is 15cm (change this value as your wish). Then we gave conditions according to that value. For example, when an obstacle comes in front of the left sensor (that is the distance of the left sensor should below or equals to 15 cm ) and the other two distances are high (that means no obstacle is in front of that's sensors), then with the help of digital write function, we can drive the motors to right. if ((distanceleft <= 15 && distancefront <= 15 && distanceright > 15) || (distanceleft <= 15 && distancefront > 15 && distanceright > 15)) if an obstacle presents only in front of the left sensor. Below we have separately explained the code used to move the motor Left, Right, and Forward. digitalWrite(4, HIGH); digitalWrite(7, LOW); digitalWrite(8, HIGH); digitalWrite(12, LOW); Similarly, Igave conditions for the right movement and straight movement. if ((distanceleft > 15 && distancefront <= 15 && distanceright <= 15) || (distanceleft > 15 && distancefront > 15 && distanceright <= 15) || (distanceleft > 15 && distancefront <= 15 && distanceright > 15) ) digitalWrite(4, LOW); digitalWrite(7, HIGH); digitalWrite(8, HIGH); digitalWrite(12, LOW); if ((distanceleft <= 15 && distancefront > 15 && distanceright <= 15) || (distanceleft > 15 && distancefront > 15 && distanceright > 15)) { digitalWrite(4, HIGH); digitalWrite(7, LOW); digitalWrite(8, HIGH); digitalWrite(12, LOW); } linked at the bottom of this page. If you have any questions, comment on it. Code // defining the pins const int trigPin1 = 3; const int echoPin1 = 5; const int trigPin2 = 6; const int echoPin2 = 9; const int trigPin3 = 10; const int echoPin3 = 11; // defining variables long duration1; long duration2; long duration3; int distanceleft; int distancefront; int distanceright; void setup() { pinMode(trigPin1, OUTPUT); pinMode(trigPin2, OUTPUT); pinMode(trigPin3, OUTPUT);// Sets the trigPin as an Output pinMode(echoPin1, INPUT); // Sets the echoPin as an Input pinMode(echoPin2, INPUT); pinMode(echoPin3, INPUT); Serial.begin(9600); // Starts the serial communication pinMode(4, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(12, OUTPUT); } void loop() { digitalWrite(trigPin1, LOW); delayMicroseconds(2); digitalWrite(trigPin1, HIGH); delayMicroseconds(10); digitalWrite(trigPin1, LOW); duration1 = pulseIn(echoPin1, HIGH); distanceleft = duration1 * 0.034 / 2; Serial.print("Distance1: "); Serial.println(distanceleft); digitalWrite(trigPin2, LOW); delayMicroseconds(2); digitalWrite(trigPin2, HIGH); delayMicroseconds(10); digitalWrite(trigPin2, LOW); duration2 = pulseIn(echoPin2, HIGH); distancefront = duration2 * 0.034 / 2; Serial.print("Distance2: "); Serial.println(distancefront); digitalWrite(trigPin3, LOW); delayMicroseconds(2); digitalWrite(trigPin3, HIGH); delayMicroseconds(10); digitalWrite(trigPin3, LOW); duration3 = pulseIn(echoPin3, HIGH); distanceright = duration3 * 0.034 / 2; Serial.print("Distance3: "); Serial.println(distanceright); if ((distanceleft <= 15 && distancefront > 15 && distanceright <= 15) || (distanceleft > 15 && distancefront > 15 && distanceright > 15)) { digitalWrite(4, HIGH); digitalWrite(7, LOW); digitalWrite(8, HIGH); digitalWrite(12, LOW); } if ((distanceleft <= 15 && distancefront <= 15 && distanceright > 15) || (distanceleft <= 15 && distancefront > 15 && distanceright > 15)) { digitalWrite(4, HIGH); digitalWrite(7, LOW); digitalWrite(8, LOW); digitalWrite(12, HIGH); } if ((distanceleft > 15 && distancefront <= 15 && distanceright <= 15) || (distanceleft > 15 && distancefront > 15 && distanceright <= 15) || (distanceleft > 15 && distancefront <= 15 && distanceright > 15) ) { digitalWrite(4, LOW); digitalWrite(7, HIGH); digitalWrite(8, HIGH); digitalWrite(12, LOW); } } Video microcontroller-projects/air-quality-analyzer-using-arduino-and-nova-air-quality-sensor-sds011

Air Quality Analyzer using Arduino and Nova PM Sensor SDS011 to Measure PM2.5 and PM10

Components Required

Arduino Nano Nova PM Sensor SDS011 0.96ᾠSPI OLED Display Module Jumper Wires

Nova PM Sensor SDS011

The SDS011 Sensor is a very recent Air Quality Sensor developed by Nova Fitness. It works on the principle of laser scattering and can get the particle concentration between 0.3 to 10μm in the air. This sensor consists of a small fan, air inlet valve, Laser diode, and photodiode. The air enters through the air inlet where a light source (Laser) illuminates the particles and the scattered light is transformed into a signal by a photodetector. These signals are then amplified and processed to get the particle concentration of PM2.5 and PM10. Output: PM2.5, PM10 Measuring Range: 0.0-999.9μg/m3 Input Voltage: 4.7V to 5.3V Maximum Current: 100mA Sleep Current:2mA Response Time: 1 second Serial Data Output Frequency: 1 time/second Particle Diameter Resolution: ≐󞮮3μm Relative Error:10% Temperature Range: -20~50°C

0.96ᾠOLED Display Module

OLED (Organic Light-Emitting Diodes) is a self light-emitting technology, constructed by placing a series of organic thin films between two conductors. A bright light is produced when an electric current is applied to these films. OLEDs are using the same technology as televisions, but have fewer pixels than in most of our TVs. For this project, we are using aMonochrome 7-pin SSD1306 0.96ᾠOLED display. It can work on three different communications Protocols: SPI 3 Wire mode, SPI four-wire mode, and I2C mode. The pins and its functions are explained in the table below:
GndGroundGround pin of the module
VddVcc, 5VPower pin (3-5V tolerable)
SCKD0,SCL,CLKActs as the clock pin. Used for both I2C and SPI
SDAD1,MOSIData pin of the module. Used for both IIC and SPI
RESRST, RESETResets the module (useful during SPI)
DCA0Data Command pin. Used for SPI protocol
CSChip SelectUseful when more than one module is used under SPI protocol
OLED Driver IC: SSD1306 Resolution: 128 x 64 Visual Angle: >160° Input Voltage: 3.3V ~ 6V Pixel Colour: Blue Working temperature: -30°C ~ 70°C by following the link.

Circuit Diagram for Air Quality Analyzer

is very simple and given below. , we have established an SPI communication between the OLED module and Arduino Nano. The connections are shown in the below table:
GNDGround
VCC5V
D010
D19
RES13
DC11
CS12

Building the Circuit on Perf Board

I have also soldered all the components on the perf board to make it look neat. Butyou can also make them on a breadboard. The boards that I made are below. While soldering, makesure you don’t sort the wires. The perf board that I soldered is shown below:

Code Explanation for Air Quality Monitor

The complete code for this project is given at the end of the document. Here we are explaining some important parts of the code. After installing the libraries to Arduino IDE, start the code by including the needed libraryfiles. #include <SDS011.h> #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> In the next lines, define two variables to store the PM10 and PM2.5 values. float p10,p25; variables according to your display. #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 Then define the SPI communication pins where OLED Display is connected. #define OLED_MOSI 9 #define OLED_CLK 10 #define OLED_DC 11 #define OLED_CS 12 #define OLED_RESET 13 Then, create an Adafruit display instance with the width and height defined earlier with the SPI communication protocol. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); function. my_sds.begin(3,4); Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC); read the PM10 and PM2.5 values from the SDS011 sensor and print the readings on a serial monitor. void loop() { error = my_sds.read(&p25,&p10); if (! error) { Serial.println("P2.5: "+String(p25)); Serial.println("P10: "+String(p10)); display.setTextSize(2); display.setTextColor(WHITE); method. Here we will display the PM2.5 and PM10 values on OLED display so the first line starts at (0,15)while the second line starts at (0, 40) coordinates. display.setCursor(0,15); display.println("PM2.5"); display.setCursor(67,15); display.println(p25); display.setCursor(0,40); display.println("PM10"); display.setCursor(67,40); display.println(p10); method to display the text on OLED Display. display.display(); display.clearDisplay();

Arduino Air Quality Monitor Testing

Once the hardware and code are ready, it is time to test the device. For that, connect the Arduino to the laptop, select the Board and Port, and hit the upload button.As you can see in the below image, it will display PM2.5 and PM10 values on OLED Display. for other technical queries. Code #include <SDS011.h> #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> float p10,p25; int error; SDS011 my_sds; #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for SSD1306 display connected using software SPI (default case): #define OLED_MOSI 9 #define OLED_CLK 10 #define OLED_DC 11 #define OLED_CS 12 #define OLED_RESET 13 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); void setup() { my_sds.begin(3,4); Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC); display.clearDisplay(); display.display(); } void loop() { error = my_sds.read(&p25,&p10); if (! error) { Serial.println("P2.5: "+String(p25)); Serial.println("P10: "+String(p10)); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(0,15); display.println("PM2.5"); display.setCursor(67,15); display.println(p25); display.setCursor(0,40); display.println("PM10"); display.setCursor(67,40); display.println(p10); display.display(); display.clearDisplay(); } delay(100); } Video microcontroller-projects/arduino-touch-sensitive-color-changing-plants-using-rgb-leds

Touch Sensitive Color Changing Plants using Arduino and RGB LEDs

using Arduino, which works on a similar principle, you can also check them out. Now when we say touch-based plants, a common question that might pop-up is, how can an electronic circuit detect the human touch through a plant. Nowadays, touch sensing devices are all around us. we can see touch displays in our smartphones and also in different types of appliances. The touch sensor is simply as a switch, when someone touches the touch sensor, the sensor closes an electronic circuit and allows the flow of current.

Typeof Touch Sensors

The name of the type itself indicates the mode of operation and the working principle. As the name indicates Resistive Touch Sensor works based on the resistance of the conductor. When a touch happens with the human body, the resistivity of the conductor changes and there is also a voltage change, this voltage change is detected by the circuit and things happen. sensor works based on the change in capacitance, that is when we touch the sensor the capacitance of the circuit changes and this will be detected as a touch. Now let's discuss our circuit in detail.

How to Detect a Touch on the Plant?

That is we will connect awire to our plant to make it act like an electrode, then when we touch the plant, due to the presence of our body, the capacitance changes and this will be detected by our circuit. And talking about the circuit, we need a microcontroller to detect the change in capacitance and also control the whole system. In our case, the microcontroller is Arduino.

Materials Needed to Build our Colour Changing Plant Vase

Arduino Common cathode RGB LED 1mega ohm resistor (brown, black, green) Connecting wire A plant with its base Common PCB

Circuit Diagram for Touch-Based Colour Changing Arduino Plant

The complete circuit diagram used in this project is shown below. The circuit was created using Easy EDA and as you can see, it is a very simple circuit. First, connect the one mega ohm resistor in between Arduino pin 2 and pin 4. Then connect a long wire (copper) to pin 4. This wire acts as an electrode or touch lead, then connect RGBled common ground to ground and red to D5 of Arduino and green to D6, blue to D7, finally attach the wire to the plant body and that's it. My hardware set-up after the connections has been made looks like this as shown below. I have connected the RGB LEDs in a common perf board (like shown below) and finally placed the base (glass) above on the PCB. That's it.

Arduino Program to Detect Touch on Plant and Change LED Colour

You can download the Arduino capacitive sensor library from the below link. After downloading and adding the library to your Arduino IDE, include that library to your code. This library helps to read the capacitance of Arduino pins. #include <CapacitiveSensor.h> We have already connected the resistor between pin 2 and 4, so we need to measure the capacitance in pin 4, for that, defined the pins. CapacitiveSensor cs_2_4 = CapacitiveSensor(2,4); capacitive sensor toggles a microcontroller pin, that is it sends the pin to a new state and then waits for the receive pin to change to the same state as the send pin. In the setup section, I defined different pinsfor led and sensor lead. pinMode(4, INPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); In the loop section With the help of digital read, we can read the state of pin 4 and we store the value in variable ‘rᾮ r = digitalRead(4); if (r == HIGH && p == LOW && millis() - time > debounce) { cnt++; if (state == HIGH) state = LOW; if(cnt == 1){ digitalWrite(5, HIGH); digitalWrite(6, LOW); digitalWrite(7, LOW); } if(cnt == 2){ digitalWrite(5, LOW); digitalWrite(6, HIGH); digitalWrite(7, LOW); } if(cnt == 3){ digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, HIGH); } if(cnt > 3){ cnt = 1; } p = r; Each time a touch is detected, it will increase the counts and I have given different conditions to light up in different colors based on the incremented number. Once the code is ready, simply upload it to your Arduino board and place the LEDs under your vase. Here I am using a glass vase and my setup looks like this when everything is ready. As you can see, the vase is already lit up in red color, and when I touch the plant, the color will change. Just make sure to use water-rich plants like lucky bamboo, money plant, etc. The complete working of this project can also be found in the video below. for starting other technical discussions. Code #include <CapacitiveSensor.h> CapacitiveSensor cs_2_4 = CapacitiveSensor(2,4); // 1M resistor between pins 2 & 4, pin 4 is sensor pin, add a wire and int cnt=0; int in = 2; int out = 4; int state = HIGH; int r; int p = LOW; long time = 0; long debounce = 200; void setup() { pinMode(4, INPUT); /* LED Outputs */ pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); } void loop() { r = digitalRead(4); if (r == HIGH && p == LOW && millis() - time > debounce) { cnt++; if (state == HIGH) state = LOW; else time = millis(); } if(cnt == 1){ digitalWrite(5, HIGH); digitalWrite(6, LOW); digitalWrite(7, LOW); } if(cnt == 2){ digitalWrite(5, LOW); digitalWrite(6, HIGH); digitalWrite(7, LOW); } if(cnt == 3){ digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, HIGH); } if(cnt > 3){ cnt = 1; } p = r; } Video microcontroller-projects/li-fi-communication-between-two-arduino

Li-Fi based Text Communication between Two Arduino

is an advanced technology that allows transferring data using optical communication such as visible light.Li-Fi data can travel through the light and then interpreted on the receiver side using any light-sensitive device like LDR or photodiode. Li-Fi communication can be 100 times faster than Wi-Fi.

Components Required

Arduino UNO LDR Sensor 4*4 Keypad 16*2 Alphanumeric LCD I2C Interface module for LCD Breadboard Connecting Jumpers 5 mm LED

Brief Introduction to Li-Fi

is an advanced communication technology which can be 100 times faster than Wi-Fi communication. Using this technology, the data can be transferred using visible light sources. Imagine, if you can access to high-speed internet by just using your light source. Isn’t it seem very interesting? Li-Fi uses visible light as a communication medium for the transmission of data. A LED can act as a light source and the photodiode acts as a transceiver that receives light signals and transmits them back. By Controlling the light pulse at the transmitter side, we can send unique data patterns. This phenomenon occurs at extremely high speed and can't be seen through the human eye. Then at the receiver side, the photodiode or Light-dependent resistor (LDR) converts the data into useful information.

Li-Fi Transmitter Section using Arduino

As shown in the figure above, in the transmitter part of Li-Fi communication, the keypad is used as input here. That means we’ll be selecting the text to be transmitted using the keypad. Then the information is processed by the control unit which is nothing but Arduino in our case. Arduino converts the information into binary pulses which can be fed to an LED source for transmission. Then these data are fed to LED light which sends the visible light pulses to the receiver side.

Li-Fi Receiver Section using Arduino

Arduino Coding For Li-Fi

As shown above, we have two sections for Li-Fi Transmitter and Receiver. The complete codes for each section are given at the bottom of the tutorial and a stepwise explanation of codes are given below: #include <Keypad.h> After the successful installation of library files, define the no. of rows and column values which is 4 for both as we have used a 4*4 keypad here. const byte ROW = 4; const byte COL = 4; char keyscode[ROW][COL] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; Then, the Arduino pins are defined that are used to interface with the 4*4 keypad. In our case, we have used A5, A4, A3, and A2 for R1, R2, R3, R4 respectively, and A1, A0, 12, 11 for C1, C2, C3, and C4 respectively. byte rowPin[ROW] = {A5, A4, A3, A2}; byte colPin[COL] = {A1, A0, 12, 11}; Keypad customKeypad = Keypad( makeKeymap(keyscode), rowPin, colPin, ROW, COL); the output pin is defined, where the LED source is connected. Also, it is kept OFF while switching ON the device. void setup() { pinMode(8,OUTPUT); digitalWrite(8,LOW); } loop, to generate unique pulses in each key presses. It can be seen in the code that the timer intervals are kept unique for all the key values. char customKey = customKeypad.getKey(); if (customKey) { if (customKey == '1') { digitalWrite(8,HIGH); delay(10); digitalWrite(8,LOW); } with LCD to reduce no. of connections with Arduino as this module requires only 2 data pins SCL/SDA and 2 power pins. for LCD, etc. These libraries would be pre-installed with Arduino, so there is no need to download them. #include <Wire.h> #include <LiquidCrystal_I2C.h> class. Here we have to pass the address, row, and column number which are 0x3f, 16, and 2 respectively in our case. LiquidCrystal_I2C lcd(0x3f, 16, 2); declare the pulse input pin for receiving the signal. Then print a welcome message on the LCD which will be displayed during the initialization of the project. void setup() { pinMode(8, INPUT); Serial.begin(9600); lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print(" WELCOME TO "); lcd.setCursor(0, 1); lcd.print(" CIRCUIT DIGEST "); delay(2000); lcd.clear(); } function, and the type of pulse is defined which is LOW in our case. The value is printed on the serial monitor for debugging purposes. It is suggested to check the duration, as it might be different for different setups. unsigned long duration = pulseIn(8, HIGH); Serial.println(duration); loop for getting the exact data that has been transmitted. One sample loop for Key 1 is given below: if (duration > 10000 && duration < 17000) { lcd.setCursor(0, 0); lcd.print("Received: 1 "); } After uploading the complete code in both the Arduinos, press any button on the keypad at the receiver side and the same digit will be displayed on 16x2 LCD at the receiver side. Code //Transmitter Side: #include <Keypad.h> const byte ROW = 4; const byte COL = 4; char keyscode[ROW][COL] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; byte rowPin[ROW] = {A5, A4, A3, A2}; byte colPin[COL] = {A1, A0, 12, 11}; Keypad customKeypad = Keypad( makeKeymap(keyscode), rowPin, colPin, ROW, COL); char keycount = 0; char code[5]; void setup() { Serial.begin(9600); pinMode(8,OUTPUT); digitalWrite(8,LOW); } void loop() { char customKey = customKeypad.getKey(); if (customKey) { Serial.println(customKey); if (customKey == '1') { digitalWrite(8,HIGH); delay(10); digitalWrite(8,LOW); } else if (customKey == '2') { digitalWrite(8,HIGH); delay(20); digitalWrite(8,LOW); } else if (customKey == '3') { digitalWrite(8,HIGH); delay(30); digitalWrite(8,LOW); } else if (customKey == '4') { digitalWrite(8,HIGH); delay(40); digitalWrite(8,LOW); } else if (customKey == '5') { digitalWrite(8,HIGH); delay(50); digitalWrite(8,LOW); } else if (customKey == '6') { digitalWrite(8,HIGH); delay(60); digitalWrite(8,LOW); } else if (customKey == '7') { digitalWrite(8,HIGH); delay(70); digitalWrite(8,LOW); } else if (customKey == '8') { digitalWrite(8,HIGH); delay(80); digitalWrite(8,LOW); } else if (customKey == '9') { digitalWrite(8,HIGH); delay(90); digitalWrite(8,LOW); } else if (customKey == '*') { digitalWrite(8,HIGH); delay(100); digitalWrite(8,LOW); } else if (customKey == '0') { digitalWrite(8,HIGH); delay(110); digitalWrite(8,LOW); } else if (customKey == '#') { digitalWrite(8,HIGH); delay(120); digitalWrite(8,LOW); } else if (customKey == 'A') { digitalWrite(8,HIGH); delay(130); digitalWrite(8,LOW); } else if (customKey == 'B') { digitalWrite(8,HIGH); delay(140); digitalWrite(8,LOW); } else if (customKey == 'C') { digitalWrite(8,HIGH); delay(150); digitalWrite(8,LOW); } else if (customKey == 'D') { digitalWrite(8,HIGH); delay(160); digitalWrite(8,LOW); } else; } } //Receiver Side: #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); #include <SoftwareSerial.h> #include <Keypad.h> void setup() { pinMode(8, INPUT); Serial.begin(9600); lcd.init(); lcd.backlight(); //lcd.backlight(); lcd.setCursor(0, 0); lcd.print(" WELCOME TO "); lcd.setCursor(0, 1); lcd.print(" CIRCUIT DIGEST "); delay(2000); lcd.clear(); } void loop() { unsigned long duration = pulseIn(8, HIGH); Serial.println(duration); if (duration > 10000 && duration < 17000) { lcd.setCursor(0, 0); lcd.print("Received: 1 "); } else if (duration > 20000 && duration < 27000) { lcd.setCursor(0, 0); lcd.print("Received: 2 "); } else if (duration > 30000 && duration < 37000) { lcd.setCursor(0, 0); lcd.print("Received: 3 "); } else if (duration > 40000 && duration < 47000) { lcd.setCursor(0, 0); lcd.print("Received: 4 "); } else if (duration > 50000 && duration < 57000) { lcd.setCursor(0, 0); lcd.print("Received: 5 "); } else if (duration > 60000 && duration < 67000) { lcd.setCursor(0, 0); lcd.print("Received: 6 "); } else if (duration > 70000 && duration < 77000) { lcd.setCursor(0, 0); lcd.print("Received: 7 "); } else if (duration > 80000 && duration < 87000) { lcd.setCursor(0, 0); lcd.print("Received: 8 "); } else if (duration > 90000 && duration < 97000) { lcd.setCursor(0, 0); lcd.print("Received: 9 "); } else if (duration > 100000 && duration < 107000) { lcd.setCursor(0, 0); lcd.print("Received: * "); } else if (duration > 110000 && duration < 117000) { lcd.setCursor(0, 0); lcd.print("Received: 0 "); } else if (duration > 120000 && duration < 127000) { lcd.setCursor(0, 0); lcd.print("Received: # "); } else if (duration > 130000 && duration < 137000) { lcd.setCursor(0, 0); lcd.print("Received: A "); } else if (duration > 140000 && duration < 147000) { lcd.setCursor(0, 0); lcd.print("Received: B "); } else if (duration > 150000 && duration < 157000) { lcd.setCursor(0, 0); lcd.print("Received: C "); } else if (duration > 160000 && duration < 167000) { lcd.setCursor(0, 0); lcd.print("Received: D "); } } Video microcontroller-projects/cell-phone-controlled-fingerprint-solenoid-door-lock-using-arduino

Cell Phone Controlled Fingerprint Solenoid Door Lock using Arduino and HC-05

so that we don’t have to touch the fingerprint sensor at all and just use your own phones to control the lock. So, let’s get started.

Components Required

1×Arduino Nano 1×HC-05 Bluetooth Module 1×Solenoid Lock 1×Piezoelectric Buzzer 1×Red LED 5mm 1×Green LED 5mm 1×IRF540N N-Channel MOSFET 1×BC547 NPN Transistor Resistors: 1×550, 1×2k0, 1×220 1×7805 Voltage Regulator 1×DC Jack connector pair Perfboard

Solenoid Lock

In a conventional door lock, there is a key to pull or push the latch, and we have to operate it manually, but in a solenoid lock, the latch can be operated automatically by applying a voltage across the solenoid coil which will control the latch present in the lock. has a low-voltage solenoid coil that pulls the latch back into the door when a suitable voltage is applied to it and will remain open until the voltage is removed. So, you can control the operation by controlling the voltage given to it by using a pushbutton, relay, microcontrollers, etc. Solenoid door locks are mainly used in remote areas to automate operations without involving any human effort.

HC-05 Bluetooth Module

which is used to configure your Bluetooth module. It communicates using USART communication at a 9600 baud rate so that you can connect it to any microcontroller which supports USART communication and can be easily connected to the Serial ports available on the board. Mind that you need to power the device with a 5V power supply and connect the TX pin to RX pin of your microcontroller and RX pin to the TX pin of the microcontroller. You can use it in automation applications and wireless applications in data logging and robotics.

Circuit Diagram for Bluetooth Controlled Solenoid Lock

The complete circuit diagram that shows how to interface and control a solenoid lock with an Arduino through a MOSFET is shown below. As shown in the circuit diagram, the connections are rather, simple you need toconnect the HC-05 Bluetooth module to the nano by powering the device with a 5V power supply and connect the TX pin to RX pin of your microcontroller and RX pin to the TX pin of the microcontroller. You need to add a red LED to display the power status of the Arduino nano and a green LED to show if the door is unlocked. You also need to connect a buzzer. The connection diagram is also shown below for easy understanding. To control the solenoid lock, you need to use a control circuit that comprises an NPN Transistor and N channel MOSFET. We will control the NPN transistor by connecting the D9 pin of the Nano to the base pin of the transistor via a 550 Ohm resistor to control the current flowing into the Transistor. When the D9 pin is pulled high, the transistor is turned on and the gate pin of the MOSFET is pulled to the ground, turning the MOSFET OFF thatturn off the solenoid lock and when the D9 pin is LOW, the NPN transistor is off which means that the GATE of the MOSFET is pulled to 12V via a 2kOhm pull up resistor to turn on the MOSFET and power the solenoid lock. In this way, you can control the Solenoid lock using your 5V Arduino Nano. You can not directly control the IRF540N MOSFET with 5V pins from the Nano as it is not a logic-level MOSFET so it won't fully turn on or off with 5V from the nano, hence we will use the BC547 NPN transistor to control the MOSFET. I have soldered the complete circuit on a perf board to make it compact. The idea is to design a 3D printed casing for our lock so that it can be easily installed and used.

Arduino Program to Control Solenoid Lock based on Fingerprint Data

We will write the code on the official Arduino IDE, if you do not have the IDE, you must download it from the official Arduino website. We start the code by declaring the variables we will use in the code to control the peripherals like buzzer and led, also to control the solenoid lock by controlling the transistor. int value1; #define led 12 #define bjt 9 #define buzzer 7 Now coming to the setup part of the Arduino, we will first initialize the serial communication of the Arduino at a 9600 baud rate. As we are using the hardware pins of the Arduino for serial communication, so we don’t have to use software serial in the project. Now we must declare the pins we are using as outputs or inputs and give them initial conditions. Serial.begin(9600); pinMode(bjt, OUTPUT); pinMode(led,OUTPUT); pinMode(buzzer, OUTPUT); digitalWrite(bjt, HIGH); digitalWrite(led, LOW); Now in the loop function of the code, we will read the data coming serially from the HC-05 Bluetooth module and check if they are corresponding to the lock or unlock command. In our program logic if the fingerprint is correctly recognized, then the Bluetooth module will send value ᾱᾠand if the fingerprint is not recognized, then the Bluetooth module will send value ᾰᾮ If the value read by Nano is ᾱᾬ then the door will be unlocked and the buzzer will sound for a second and the door will remain unlocked for 7 seconds. After that, the door will be locked again. If the value read is ᾰᾬ which means the fingerprint is not recognized, hence the buzzer will sound an alarm three times for a second each to alert the security. Serial.println("Reading"); while(Serial.available()==0); value1 = Serial.read(); Serial.println(value1); if (value1==1) { Serial.println("Unlocking"); digitalWrite(bjt, LOW); digitalWrite(buzzer, HIGH); digitalWrite(led, HIGH); delay(1000); digitalWrite(buzzer, LOW); delay(6000); digitalWrite(bjt, HIGH); digitalWrite(led, LOW); } if (value1==0) { digitalWrite(bjt, HIGH); digitalWrite(buzzer, HIGH); Serial.println("Locking"); delay(1000); digitalWrite(buzzer, LOW); delay(1000); digitalWrite(buzzer, HIGH); delay(1000); digitalWrite(buzzer, LOW); delay(1000); digitalWrite(buzzer, HIGH); delay(1000); digitalWrite(buzzer, LOW); }

Android App for Reading Fingerprint Data and Sending to Arduino via Bluetooth

Creating an app using Kodular is very simple; you can make an app by combining the blocks according to the flow chart of your project. option. button to create a Project. ᾮ Screen properties can be changed by changing the properties for each block. ᾠscreen to build the app using the blocks. and drag & drop the first code block as shown in the image: block and then drag & drop the first code block on the Viewer screen. code block. as shown in the below image. code block as shown in the below image. block and select the first code block. With this, the first code block is finished. We need to create three more code blocks to call the fingerprint sensor of the Android phone and authenticate the fingerprint. The complete code block is shown in the below picture. Use this picture to join the rest of the code blocks. file of this app can be downloaded from thebelow link. Download Android application to Control solenoid lock through Arduino

3D Printed Casing for Biometric-based Lock

As mentioned earlier, we have created a 3D model to assemble the perf board and solenoid lock into a neat little casing. The model placed on slicing software is shown below. If you are using the same size perf board and solenoid lock, then you can also print the same casing using the STL files given below. You can also check out other 3D printing projects that we have build earlier.

Testing our Arduino based Fingerprint controlled lock

on your phone to control the lock. You also need to upload the complete code on your Arduino Nano but make sure you remove the TX and RX pins from the nano before you upload the code. After the upload is complete, install the lock and then turn on the Bluetooth on your mobile phone and pair with the Bluetooth device you are using and open the app. Now tap on the Bluetooth icon on the app and connect to the Bluetooth device and the Bluetooth icon on the app will turn to the lock icon. Now you have to tap on the fingerprint icon to check the fingerprint using your phone’s fingerprint scanner and the value will be sent to the Arduino Nano. This project is just a basic demonstration of the things you could do with the Bluetooth module connected to your phone. You can build a whole working robot, attendance register, app-controlled home automation devices, etc. and the list goes on up toyour imagination. You can also interface displays to show the name of the person entering the premises or add a camera to click a picture of the person for security purposes. Try this on your own, make some changes, and if you ever get stuck somewhere, just let us know in the comments section and we will help you out. Thanks again and have a great day. Code int value1; #define led 12 #define bjt 9 #define buzzer 7 void setup() { Serial.begin(9600); pinMode(bjt, OUTPUT); pinMode(led,OUTPUT); pinMode(buzzer, OUTPUT); digitalWrite(bjt, HIGH); digitalWrite(led, LOW); } void loop() { Serial.println("Reading"); while(Serial.available()==0); value1 = Serial.read(); Serial.println(value1); if (value1==1) { Serial.println("Unlocking"); digitalWrite(bjt, LOW); digitalWrite(buzzer, HIGH); digitalWrite(led, HIGH); delay(1000); digitalWrite(buzzer, LOW); delay(6000); digitalWrite(bjt, HIGH); digitalWrite(led, LOW); } if (value1==0) { digitalWrite(bjt, HIGH); digitalWrite(buzzer, HIGH); Serial.println("Locking"); delay(1000); digitalWrite(buzzer, LOW); delay(1000); digitalWrite(buzzer, HIGH); delay(1000); digitalWrite(buzzer, LOW); delay(1000); digitalWrite(buzzer, HIGH); delay(1000); digitalWrite(buzzer, LOW); } } Video microcontroller-projects/interfacing-sharp-gp2y1014au0f-sensor-with-arduino-to-build-air-quality-analyzer

Interfacing Sharp GP2Y1014AU0F Sensor with Arduino to build Air Quality Analyser

Air pollution is a major issue in many cities and the air quality index is getting worse every day. According to the World Health Organization report, more people are killed prematurely by the effects of hazardous particles presented in the air than from car accidents. According to the Environmental Protection Agency (EPA), indoor air can be 2 to 5 times more toxic than outdoor air. So here we build a project to monitor air quality by measuring dust particles density in the air. Apart from the Dust sensor and Arduino Nano, an OLED display is also used to display the measured values. Sharp’s GP2Y1014AU0F Dust Sensor is very effective in detecting very fine particles like cigarette smoke. It is designed for use in Air purifiers and Air conditioners.

Components Required

Arduino Nano Sharp GP2Y1014AU0F Sensor 0.96ᾠSPI OLED Display Module Jumper Wires 220 μf Capacitor 150 Resistor

Sharp GP2Y1014AU0F Sensor

Inside the sensor module, an infrared emitting diode and a photosensor are diagonally arranged near the air inlet hole as shown in the below image: pin of the sensor changes according to the intensity of scattered light. The below figure and table shows the pin assignments for GP2Y1014AU0F:
1V-LEDLED Vcc Pin. Connect to 5V through 150 Resistor
2LED-GNDLED Ground Pin. Connect to GND
3LEDUsed to Toggle LED On/Off. Connect to any digital pin of Arduino
4S-GNDSensor Ground Pin. Connect to GND of Arduino
5Sensor Analog Output Pin. Connect to any Analog Pin
6Positive Supply Pin. Connect to 5V of Arduino
Low Current Consumption: 20mA max Typical Operating Voltage: 4.5V to 5.5V Minimum Detectable Dust Size: 0.5μm Dust Density Sensing Range: Up to 580 ug/m3 Sensing Time: Less than 1 Second Dimensions: 1.81 x 1.18 x 0.69'' (46.0 x 30.0 x 17.6mm)

OLED Display Module

OLED (Organic Light-Emitting Diodes) is a self light-emitting technology, constructed by placing a series of organic thin films between two conductors. A bright light is produced when an electric current is applied to these films. OLEDs are using the same technology as televisions, but have fewer pixels than in most of our TVs. For this project, we are using aMonochrome 7-pin SSD1306 0.96ᾠOLED display. It can work on three different communications Protocols: SPI 3 Wire mode, SPI four-wire mode, and I2C mode. The pins and its functions are explained in the table below: in the previous article.
GndGroundGround pin of the module
VddVcc, 5VPower pin (3-5V tolerable)
SCKD0,SCL,CLKActs as the clock pin. Used for both I2C and SPI
SDAD1,MOSIData pin of the module. Used for both IIC and SPI
RESRST, RESETResets the module (useful during SPI)
DCA0Data Command pin. Used for SPI protocol
CSChip SelectUseful when more than one module is used under SPI protocol
OLED Driver IC: SSD1306 Resolution: 128 x 64 Visual Angle: >160° Input Voltage: 3.3V ~ 6V Pixel Colour: Blue Working temperature: -30°C ~ 70°C by following the link.

Circuit Diagram

is given below: , we have established an SPI communication between the OLED module and Arduino Nano. The connections are shown in the below table:
1GNDGround
2VCC5V
3D010
4D19
5RES13
6DC11
7CS12
1Vcc5V
2A5
3S-GNDGND
4LED7
5LED-GNDGND
6V-LED5V Through 150 Resistor

Building the Circuit on Perf Board

After soldering all the components on the perf board, it will look something like below. Butit can be also built on a breadboard. I have soldered the GP2Y1014 sensor on the same board that I used to interface the SDS011 sensor. While soldering, make sure your solder wires should be at enough distance from each other.

Code Explanation for Air Quality Analyzer

The complete code for this project is given at the end of the document. Here we are explaining some important parts of the code. . After installing the libraries to Arduino IDE, start the code by including the needed libraries files. Dust sensor doesn’t require any library as we are reading the voltage values directly from the analog pin of Arduino. #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> variables according to your display. #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 Then define the SPI communication pins where OLED Display is connected. #define OLED_MOSI 9 #define OLED_CLK 10 #define OLED_DC 11 #define OLED_CS 12 #define OLED_RESET 13 Then, create an Adafruit display instance with the width and height defined earlier with the SPI communication protocol. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); After that, define the Dust sensors sense and led pins. Sense pin is the output pin of the Dust sensor that is used to read the voltage values while the led pin is used to turn on/off the IR Led. int sensePin = A5; int ledPin = 7; function. Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC); digitalWrite(ledPin,LOW); delayMicroseconds(280); outVo = analogRead(sensePin); delayMicroseconds(40); digitalWrite(ledPin,HIGH); delayMicroseconds(9680); Then in the next lines, calculate the Dust density using the output voltage and signal value. sigVolt = outVo*(5/1024); dustLevel = 0.17 * sigVolt - 0.1; display.setTextSize(1); display.setTextColor(WHITE); function. display.println("Dust"); display.println("Density"); display.setTextSize(3); display.println(dustLevel); method to display the text on OLED Display. display.display(); display.clearDisplay();

Testing the Interfacing of Sharp GP2Y1014AU0F Sensor with Arduino

Once the hardware and code are ready, it is time to test the sensor. For that, connect the Arduino to the laptop, select the Board and Port, and hit the upload button.As you can see in the below image, it will display Dust Density on OLED Display. for other technical queries. Code #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for SSD1306 display connected using software SPI (default case): #define OLED_MOSI 9 #define OLED_CLK 10 #define OLED_DC 11 #define OLED_CS 12 #define OLED_RESET 13 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); int measurePin = A5; int ledPower = 7; float voMeasured = 0; float calcVoltage = 0; float dustDensity = 0; void setup(){ Serial.begin(9600); pinMode(ledPower,OUTPUT); display.begin(SSD1306_SWITCHCAPVCC); display.clearDisplay(); display.display(); } void loop(){ digitalWrite(ledPower,LOW); delayMicroseconds(280); voMeasured = analogRead(measurePin); delayMicroseconds(40); digitalWrite(ledPower,HIGH); delayMicroseconds(9680); calcVoltage = voMeasured*(5.0/1024); dustDensity = 0.17*calcVoltage-0.1; if ( dustDensity < 0) { dustDensity = 0.00; } Serial.println("Raw Signal Value (0-1023):"); Serial.println(voMeasured); Serial.println("Voltage:"); Serial.println(calcVoltage); Serial.println("Dust Density:"); Serial.println(dustDensity); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(85,22); display.println("Dust"); display.setCursor(85,38); display.println("Density"); display.setTextSize(3); display.setCursor(0,13); display.println(dustDensity); display.setCursor(6,43); display.setTextSize(2); display.println("ug/m3"); display.display(); display.clearDisplay(); delay(1000); } Video microcontroller-projects/gesture-based-contactless-elevator-using-arduino-and-apds9960-sensor

Gesture Controlled Contactless Elevator using APDS9960 Sensor

In this time of the Corona pandemic, elevators have become a high-risk place where everybody touches the same buttons. At many places, people have discovered tricks to prevent contact with elevator buttons like using a pumping paper, toothpicks, or sanitary tissues for pressing the lift buttons. is using Arduino Nano, an APDS9960 Gesture Sensor, and an OLED display module. With this gesture based control panel, you can easily control your Lift by making a hand gesture. The APDS9960 Sensor is used to read the gestures. UP and DOWN gestures are used to set the floor number, the left gesture is to close the lift door and move the lift according to the floor number and the Right gesture is used to open the door.

Components Required

Arduino Nano OLED Display Module APDS9960 RGB & Gesture Sensor Breadboard Jumper Wires

APDS9960 RGB & Gesture Sensor

The APDS9960 RGB & Gesture Detection Module is a small breakout board that comes with a built-in APDS-9960 sensor, UV and IR blocking filters, four separate diodes sensitive to different directions, and an I2C compatible interface. This sensor can be used for ambient light and color measuring, proximity detection, and touchless gesture sensing. It has a gesture detection range of 10 to 20 cm and can be used to control a microcontroller, robot, and in many other projects. Operational Voltage: 2.4V to 3.6V Operating Range: 4-8in (10-20cm). I2C Interface (I2C Address: 0x39). Ambient Light and RGB Colour Sensing, Proximity Sensing, and Gesture Detection in an Optical Module I2C-bus Fast Mode Compatible Interface with Data Rates up to 400 kHz.

Circuit Diagram

is given below. We are interfacing the Arduino Nano with APDS9960 Sensor and OLED Display. VCC and GND pins of both APDS9960 Sensor and OLED Display are connected to 3.3V and GND of Arduino. While SCL and SDA pins of APDS9960 Sensor and OLED Display are connected to A5 and A4 pins of Arduino Respectively.
VCC3.3v
GNDGND
SCLA5
SDAA4
will look: , follow the link.

Code Explanation

is the modified version of the original Adafruit library. #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SH1106.h> #include <Arduino_APDS9960.h> In the next lines, define the variables to store the current floor and floor number where the user wants to go. int floornum=0; int currentfloor=0; tutorial. const unsigned char up [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,…………………………………………………………………………………‐󬬍 }; const unsigned char down [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,…………………………………………………………………………………‐󬬍 }; const unsigned char dooropen [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xe0, ,…………………………………………………………………………………‐󬬍 }; method as follows: Serial.begin(9600); if (!APDS.begin()) { Serial.println("Error initializing APDS9960 sensor!"); } Serial.println("Detecting gestures ..."); display.begin(SH1106_SWITCHCAPVCC, 0x3C); methods. display.setTextSize(2); display.setTextColor(WHITE); display.clearDisplay(); display.display(); constantly check if any gesture was made. If yes, then read the gesture values and checks which gesture it is (UP, DOWN, RIGHT, LEFT) and prints the corresponding reading on the serial monitor. UP and DOWN gestures are used to set the floor number where the user wants to go to. The left gesture is to close the lift door and move the lift according to the floor number while the Right gesture is used to open the door. if (APDS.gestureAvailable()) { int gesture = APDS.readGesture(); switch (gesture) { case GESTURE_UP: Serial.println("Detected UP gesture"); display.clearDisplay(); floornum ++; home1(); break; case GESTURE_DOWN: Serial.println("Detected DOWN gesture"); display.clearDisplay(); floornum --; home1(); break; case GESTURE_LEFT: Serial.println("Detected LEFT gesture"); display.clearDisplay(); start(); break; case GESTURE_RIGHT: Serial.println("Detected RIGHT gesture"); display.clearDisplay(); home1(); break; default: break; } function is given below: drawBitmap(int16_t x, int16_t y, bitmap, int16_t w, int16_t h, colour); are X and Y coordinates of OLED display is the name of the bitmap are the height and weight of the image. void home1() { display.setCursor(101,23); display.println(floornum); display.drawBitmap(23, 0, uparrow, 40, 18, WHITE); display.drawBitmap(26, 46, downarrow, 40, 18, WHITE); display.drawBitmap(0, 15, dooropen, 29, 30, WHITE); display.drawBitmap(60, 15, closedoor, 29, 30, WHITE); display.display(); } function is used to move the lift upwards or downwards. For that, the current floor no is compared with the floor number where the user wants to go. If the floor number is greater than the current floor no. then the lift will move upwards and if the floor number is lesser than the current floor no. then the lift will move downwards. The lift will stop when both the current floor no. and floor no. are the same. void start() { while(floornum > currentfloor){ Serial.println("going UP "); currentfloor++; display.drawBitmap(0, 0, up, 100, 64, WHITE); display.setCursor(101,23); display.println(currentfloor); display.display(); display.clearDisplay(); delay(2000); } while(floornum < currentfloor){ Serial.println("going Down "); currentfloor--; display.drawBitmap(0, 0, down, 100, 64, WHITE); display.setCursor(101,23); display.println(currentfloor); display.display(); display.clearDisplay(); delay(2000); } if(floornum== currentfloor){ Serial.println("Reached"); display.clearDisplay(); home1(); Serial.print(currentfloor); } }

Testing the Gesture Controlled Touchless Lift

Once the hardware and code are ready, connect the Arduino Nano to the laptop and upload the complete code given below. As you can see by default OLED will display the Elevator UI. Now wave off your hand up or down, like shown in the video below, to set the floor where you want to go. Then make the left gesture for acknowledging the lift to go to that floor. If you want to stop the lift, then make the right gesture with your hand. The complete working video and code for this project are given below. Hope you enjoyed building this project. If you have any questions regarding this project, please leave them in the comment section. Code #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SH1106.h> #include <Arduino_APDS9960.h> #define OLED_RESET -1 Adafruit_SH1106 display(OLED_RESET); int floornum=0; int currentfloor=0; //Paste your bitmap here const unsigned char up [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc7, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x81, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x38, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x7c, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x01, 0xff, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x03, 0xff, 0x80, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xe0, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x03, 0xff, 0xc7, 0xff, 0x80, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x07, 0xff, 0x81, 0xff, 0xc0, 0x00, 0x1f, 0xfe, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x1f, 0xfe, 0x00, 0xff, 0xf0, 0x00, 0x07, 0xff, 0x00, 0x07, 0xff, 0x80, 0x00, 0x3f, 0xfc, 0x00, 0x3f, 0xf8, 0x00, 0x03, 0xff, 0xc0, 0x0f, 0xfe, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0xff, 0xe0, 0x3f, 0xfc, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x07, 0xff, 0x00, 0x00, 0x7f, 0xf0, 0x1f, 0xf0, 0x00, 0x07, 0xff, 0x80, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x1f, 0xf0, 0x0f, 0xe0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x0f, 0xe0, 0x03, 0xc0, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x03, 0x80, 0x01, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const unsigned char down [] PROGMEM = { // 'down, 105x64px 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x40, 0x00, 0xe0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x01, 0xe0, 0x03, 0xf8, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x03, 0xf0, 0x0f, 0xfc, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x07, 0xf0, 0x0f, 0xff, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x1f, 0xf0, 0x03, 0xff, 0x80, 0x00, 0x3f, 0xfc, 0x00, 0x07, 0xff, 0x80, 0x00, 0x3f, 0xf0, 0x01, 0xff, 0xe0, 0x00, 0x0f, 0xfe, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x7f, 0xf0, 0x00, 0x07, 0xff, 0x80, 0x3f, 0xfc, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x3f, 0xfc, 0x00, 0x01, 0xff, 0xc0, 0xff, 0xf0, 0x00, 0x07, 0xff, 0x80, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0xff, 0xf1, 0xff, 0xe0, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x1f, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x0e, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const unsigned char uparrow [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const unsigned char downarrow [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const unsigned char dooropen [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xf0, 0x38, 0x00, 0x00, 0xf0, 0x38, 0x00, 0x00, 0xf0, 0x38, 0x00, 0x00, 0xf0, 0x38, 0x04, 0x80, 0xf0, 0x38, 0x1c, 0xc0, 0xf0, 0x38, 0x3c, 0xf0, 0xf0, 0x38, 0x7c, 0xf8, 0xf0, 0x39, 0xfc, 0xfc, 0xf0, 0x3b, 0xfc, 0xfe, 0xf0, 0x3b, 0xfc, 0xfe, 0xf0, 0x38, 0xfc, 0xfc, 0xf0, 0x38, 0x7c, 0xf8, 0xf0, 0x38, 0x3c, 0xf0, 0xf0, 0x38, 0x1c, 0xc0, 0xf0, 0x38, 0x04, 0x80, 0xf0, 0x38, 0x00, 0x00, 0xf0, 0x38, 0x00, 0x00, 0xf0, 0x38, 0x00, 0x00, 0xf0, 0x3c, 0x00, 0x00, 0xf0, 0x3f, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const unsigned char closedoor [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xc0, 0x08, 0x00, 0x00, 0x40, 0x0a, 0x00, 0x03, 0x40, 0x0b, 0x80, 0x07, 0x40, 0x0b, 0xc0, 0x0f, 0x40, 0x0b, 0xe0, 0x1f, 0x40, 0x0b, 0xf0, 0x3f, 0x40, 0x0b, 0xf8, 0x7f, 0x40, 0x0b, 0xfc, 0xff, 0x40, 0x0b, 0xff, 0xff, 0x40, 0x0b, 0xff, 0xff, 0x40, 0x0b, 0xfe, 0xff, 0x40, 0x0b, 0xf8, 0x7f, 0x40, 0x0b, 0xf0, 0x3f, 0x40, 0x0b, 0xe0, 0x1f, 0x40, 0x0b, 0xc0, 0x0f, 0x40, 0x0b, 0x80, 0x07, 0x40, 0x0b, 0x00, 0x03, 0x40, 0x08, 0x00, 0x01, 0x40, 0x0f, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; void setup(){ Serial.begin(9600); if (!APDS.begin()) { Serial.println("Error initializing APDS9960 sensor!"); } Serial.println("Detecting gestures ..."); display.begin(SH1106_SWITCHCAPVCC, 0x3C); display.setTextSize(2); display.setTextColor(WHITE); display.clearDisplay(); display.display(); home1(); } void loop() { display.clearDisplay(); if (APDS.gestureAvailable()) { int gesture = APDS.readGesture(); switch (gesture) { case GESTURE_UP: Serial.println("Detected UP gesture"); display.clearDisplay(); floornum ++; home1(); break; case GESTURE_DOWN: Serial.println("Detected DOWN gesture"); display.clearDisplay(); floornum --; home1(); break; case GESTURE_LEFT: Serial.println("Detected LEFT gesture"); display.clearDisplay(); start(); break; case GESTURE_RIGHT: Serial.println("Detected RIGHT gesture"); display.clearDisplay(); home1(); break; default: break; } } } void home1() { display.setCursor(101,23); display.println(floornum); display.drawBitmap(23, 0, uparrow, 40, 18, WHITE); display.drawBitmap(26, 46, downarrow, 40, 18, WHITE); display.drawBitmap(0, 15, dooropen, 29, 30, WHITE); display.drawBitmap(60, 15, closedoor, 29, 30, WHITE); display.display(); } void start() { while(floornum > currentfloor){ Serial.println("going UP "); currentfloor++; display.drawBitmap(0, 0, up, 100, 64, WHITE); display.setCursor(101,23); display.println(currentfloor); display.display(); display.clearDisplay(); delay(2000); } while(floornum < currentfloor){ Serial.println("going Down "); currentfloor--; display.drawBitmap(0, 0, down, 100, 64, WHITE); display.setCursor(101,23); display.println(currentfloor); display.display(); display.clearDisplay(); delay(2000); } if(floornum== currentfloor){ Serial.println("Reached"); display.clearDisplay(); home1(); Serial.print(currentfloor); } } Video microcontroller-projects/measuring-turbidity-of-water-to-determine-water-quality-using-arduino-turbidity-sensor

Measuring Turbidity of Water to Determine Water Quality using Arduino and Turbidity Sensor

device using ESP8266, you can also check that out if interested. That being said, let's get started

What is Turbidity in Liquid?

of a liquid. This happens due to the presence of large numbers of invisible particles (with the naked eye) similar to white smoke in the air. When light passes through liquids, light waves get scattered Due to the presence of these tiny particles. The turbidity of a liquid is directly proportional to the free suspended particles that is if the number of particles increases turbidity will also increase.

How to Measure Turbidity using Arduino?

depending on the method used for measurement. The two units are roughly equal. The transmitter consists of a light source typically an led and a driver circuit. In the receiver end, there is a light detector like a photodiode or an LDR. We place the solution in between the transmitter and receiver. to turbidity. So we can measure the turbidity by measuring the light intensity if the light intensity is high, the solution is less turbid and if the light intensity is very low that means the solution is more turbid.

Components Needed for Making Turbidity Meter

Turbidity module Arduino 16*2 I2C LCD Common cathode RGB LED Breadboard Jumper wires

Overview of Turbidity Sensor

The turbidity sensor used in this project is shown below. As you can see, this turbidity sensor module comes with 3 parts. A waterproof lead, a driver circuit, and a connecting wire. The testing probe consists of both the transmitter and receiver. The above image shows, this type of module uses an IR diode as a light source and an IR receiver as a detector. But the working principle is the same as before. The driver part (shown below) consists of an op-amp and some components which amplify the detected light signal. The actual sensor can be connected to this module by using a JST XH connector. It has three pins,VCC, ground, and output. Vcc connects to the 5vand ground to ground. The output of this module is an analog value that is it changes according to the light intensity.

Key Features of Turbidity Module

Operating Voltage: 5VDC. Current: 30mA (MAX). Operating temperature: -30 ° C to 80 ° C. Compatible with Arduino, Raspberry Pi, AVR, PIC, etc.

Interfacing Turbidity Sensor with Arduino ᾠCircuit Diagram

The complete schematic to connect the Turbidity sensor to Arduino is shown below, the circuit was designed using EasyEDA. This is a very simple circuit diagram. The output of the turbidity sensor isanalog so that connected to Arduino's A0 pin, I2CLCD connected to I2Cpins of Arduino that is SCL to A5 and SDA to A4. Then the RGB LEDconnected to digital pin D2, D3, and D4. After the connections are done, my hardware setup looks like this below. Connect the VCC of the sensor to Arduino 5v, then connect ground to ground. The output pin of the sensor to analog 0 of Arduino. Next, connect VCC and ground of LCD module to 5v and ground of Arduino. Then SDA to A4 and SCL to A5,these two pins are the I2C pins of Arduino. finally connects the ground of RGB LED to the ground of Arduino and connect green to D3, blue to D4, and red to D5.

Programming Arduino to Measure Turbidity in Water

The plan is to display the turbidity values from 0 to 100. That is the meter should display 0 for pure liquid and 100 for highly turbid ones. This Arduino code is also very simple and the complete code can be found at the bottom of this page. First, I included the I2C liquid crystal library because we are using an I2C LCD to minimize the connections. #include <LiquidCrystal_I2C.h> Then I set integer for sensor input. int sensorPin = A0; In the setup section, I defined the pins. pinMode(3,OUTPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); function, we can read the output values in the loop section. int sensorValue =analogRead(sensorPin); function. To get these values, first, read the sensor freely that is without any solution. Igot a value around 640 and after that, place a black substance betweenthe transmitter and receiver, we get a value that is the minimum value, usually, that valueis zero. So we got 640 as maximum and zero as a minimum. Now we need to convert these values to0-100 function of Arduino. int turbidity = map(sensorValue, 0,640, 100, 0); Then Idisplayed that values in the LCDdisplay. lcd.setCursor(0, 0); lcd.print("turbidity:"); lcd.print(" "); lcd.setCursor(10, 0); lcd.print(turbidity); conditions, I gave different conditions. if (turbidity < 20) { digitalWrite(2, HIGH); digitalWrite(3, LOW); digitalWrite(4, LOW); lcd.setCursor(0, 1); lcd.print(" its CLEAR "); } This will active green led and display "its clear"on LCD if the turbidity value is below 20. if ((turbidity > 20) && (turbidity < 50)) { digitalWrite(2, LOW); digitalWrite(3, HIGH); digitalWrite(4, LOW); lcd.setCursor(0, 1); lcd.print(" its CLOUDY "); } This will active blue led and display "its cloudy"on LCD if the turbidity value is in between 20 and 50. if ((turbidity > 50) { digitalWrite(2, LOW); digitalWrite(3, HIGH); digitalWrite(4, LOW); lcd.setCursor(0, 1); lcd.print(" its DIRTY "); } This will active red led and display "it's dirty"on LCD if the turbidity value is greater than 50 as shown below. Just follow the circuit diagram and upload the code, if everything goes correct, you should be able to measure the turbidity of water and the LCD should display the quality of the water as shown above. for posting your technical questions or start a relevant discussion. Code #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 2, 16); int sensorPin = A0; void setup() { Serial.begin(9600); lcd.begin(); pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); } void loop() { int sensorValue = analogRead(sensorPin); Serial.println(sensorValue); int turbidity = map(sensorValue, 0, 750, 100, 0); delay(100); lcd.setCursor(0, 0); lcd.print("turbidity:"); lcd.print(" "); lcd.setCursor(10, 0); lcd.print(turbidity); delay(100); if (turbidity < 20) { digitalWrite(2, HIGH); digitalWrite(3, LOW); digitalWrite(4, LOW); lcd.setCursor(0, 1); lcd.print(" its CLEAR "); } if ((turbidity > 20) && (turbidity < 50)) { digitalWrite(2, LOW); digitalWrite(3, HIGH); digitalWrite(4, LOW); lcd.setCursor(0, 1); lcd.print(" its CLOUDY "); } if (turbidity > 50) { digitalWrite(2, LOW); digitalWrite(3, LOW); digitalWrite(4, HIGH); lcd.setCursor(0, 1); lcd.print(" its DIRTY "); } } Video microcontroller-projects/diy-raspberry-pi-lora-hat-for-lora-communication-between-raspberry-pi-and-arduino

DIY Raspberry Pi LoRa HAT - LoRa Communication between Raspberry Pi and Arduino

on PCB. This LoRa Hat consists of an SX1278 433MHz LoRa Module, OLED Display Module, and 3.7 to 5V booster circuit. This Raspberry Pi LoRa HAT will come in handy when you have to create a LoRa mesh network or to deploy LoRa sensing nodes. Here we are using the LoRa hat to communicate with Arduino.

Components Required

Raspberry Pi SX1278 433MHz LoRa Module OLED Display Module FP6291 Boost Converter IC 3× Resistor (12k, 88k, 48k) 6× Capacitor (2×0.1μf, 1×10μf, 2×20μf) 1× Inductor (4.7μH) 1× Diode (1N5388BRLG) 18650 Lithium Cell 18650 Cell Holder 6-Pin Push Button Switch

Raspberry Pi LoRa HAT Circuit Diagram

to boost the battery voltage from 3.7v to 5V. The HAT will directly sit on top of Raspberry Pi providing its LoRa capabilities. FP6291 IC is a 1 MHz DC-DC Step-Up Booster IC, mainly used in the application, for example, getting stable 5V from a 3V battery. You only need a few extra components to design a booster circuit with this IC. Here in this circuit, the Boost Converter circuit gets the input supply through battery terminals (+ and -). This input voltage is then processed by FP6291 IC to give a stable 5V DC supply to the 5V pin of Raspberry Pi. The output voltage from this IC can be configured using the potential divider circuit. The formula to calculate the output voltage is: VOUT = 0.6(1+ R1/ R2) is explained in detail.

Fabricating PCB for Raspberry Pi LoRa HAT

The schematic is done, and we can proceed with laying out the PCB. You can design the PCB using any PCB software of your choice. We have used EasyEDA to fabricate PCB for this project. Below are the 3D model views of the top layer and bottom layer of the LoRa HAT: The PCB layout for the above circuit is also available for download as Gerber from the link given below: Gerber file for Raspberry Pi LoRa Hat

Ordering PCB from PCBWay

Now after finalizing the design, you can proceed with ordering the PCB: , sign up if this is your first time. Then, in the PCB Prototype tab, enter the dimensions of your PCB, the number of layers, and the number of PCB you require. Proceed by clicking on the ‘Quote Nowᾠbutton. You will be taken to a page where to set a few additional parameters like the Board type, Layers, Material for PCB, Thickness, and More, most of them are selected by default, if you are opting for any specific parameters, you can select it inhere. The final step is to upload the Gerber file and proceed with the payment. To make sure the process is smooth, PCBWAY verifies if your Gerber file is valid before proceeding with the payment. This way, you can sure that your PCB is fabrication friendly and will reach you as committed.

Assembling the Raspberry Pi LoRa HAT

After a few days, we received our PCB in a neat package and the PCB quality was good as always. The top layer and the bottom layer of the board are shown below. After making sure the tracks and footprints were correct. I proceeded with assembling the PCB. The completely soldered board looks like the below: It will look like this after putting OLED on it:

Raspberry Pi Setup for LoRa Hat

Now to test the LoRa HAT for Raspberry Pi, first, we have to program the Raspberry Pi so that it can receive data from LoRa Transmitter and display the vales on OLED Display. So first update the Raspberry Pi OS using the below commands: sudo apt-get update sudo apt-get upgrade Spidev is a python package for Linux which can be used to perform SPI communication on Raspberry Pi. pip3 install spidev installs the Radio models associated with LoRa. pip3 install pyLoRa Use the below commands to install the luma.oled Dependencies: sudo apt-get update sudo apt-get install python3 python3-pip python3-pil libjpeg-dev zlib1g-dev libfreetype6-dev liblcms2-dev libopenjp2-7 libtiff5 -y sudo -H pip3 install luma.oled sudo apt-get install python3-imaging Now in the last step, check if the SPI and I2C interface is enabled or not. For that, enter the below command in the pi terminal and press enter: sudo raspi-config and enable SPI and I2C Interface if not enabled already.

Programming Raspberry Pi for LoRa Module

The complete Raspberry Pi program can be found at the bottom of this page. Here I will try to explain the important lines in the Raspberry Pi program. So start the code by including all the required packages. from time import sleep from SX127x.LoRa import * from SX127x.board_config import BOARD from luma.core.interface.serial import i2c, spi, pcf8574 from luma.core.render import canvas from luma.oled.device import ssd1306, ssd1309, ssd1325, ssd1331, sh1106 from PIL import ImageFont, ImageDraw class is used to initialize the LoRa module in 433MHz with 125kHz bandwidth. It initializes it in sleep mode to save power consumption. def __init__(self, verbose=False): super(LoRaRcvCont, self).__init__(verbose) self.set_mode(MODE.SLEEP) self.set_dio_mapping([0] * 6) loop to read values like RSSI and modem status. def start(self): self.reset_ptr_rx() self.set_mode(MODE.RXCONT) while True: sleep(.5) rssi_value = self.get_rssi_value() status = self.get_modem_status() sys.stdout.flush() from the Rx buffer. Then the received values are decoded with utf-8 to print user-readable data on the shell. def on_rx_done(self): print ("\nReceived: ") self.clear_irq_flags(RxDone=1) payload = self.read_payload(nocheck=True #print (bytes(payload).decode("utf-8",'ignore')) data = bytes(payload).decode("utf-8",'ignore') data1 = data[2:9] print(data1) with canvas(device) as draw: font = ImageFont.load_default() font = ImageFont.truetype('arial.ttf',18) draw.text((10, 17), "Received:", font=font, fill="white") draw.text((25, 40),data1,font=font,fill="white") for circuit diagram and other information.

Testing the Raspberry Pi LoRa HAT

Now, that both Arduino and Raspberry Pi codes are ready, simply have to upload the Arduino code to the UNO board and launch the Python sketch in Raspberry Pi. If the code uploads successfully, you should see the Arduino packets received in pi through the OLED Display as shown in the below image: for other technical questions. Code from time import sleep from SX127x.LoRa import * from SX127x.board_config import BOARD from luma.core.interface.serial import i2c, spi, pcf8574 from luma.core.render import canvas from luma.oled.device import ssd1306, ssd1309, ssd1325, ssd1331, sh1106 from PIL import ImageFont, ImageDraw serial = i2c(port=1, address=0x3C) device = sh1106(serial) BOARD.setup() class LoRaRcvCont(LoRa): def __init__(self, verbose=False): super(LoRaRcvCont, self).__init__(verbose) self.set_mode(MODE.SLEEP) self.set_dio_mapping([0] * 6) def start(self): self.reset_ptr_rx() self.set_mode(MODE.RXCONT) while True: sleep(.5) rssi_value = self.get_rssi_value() status = self.get_modem_status() sys.stdout.flush() def on_rx_done(self): print ("\nReceived: ") self.clear_irq_flags(RxDone=1) payload = self.read_payload(nocheck=True) print (payload) data = bytes(payload).decode("utf-8",'ignore') data1 = data[2:9] print(data1) with canvas(device) as draw: device.clear() font = ImageFont.load_default() font = ImageFont.truetype('arial.ttf',18) draw.text((10, 17), "Received:", font=font, fill="white") draw.text((30, 40),data1,font=font,fill="white") device.clear() self.set_mode(MODE.SLEEP) self.reset_ptr_rx() self.set_mode(MODE.RXCONT) lora = LoRaRcvCont(verbose=False) lora.set_mode(MODE.STDBY) # Medium Range Defaults after init are 434.0MHz, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on 13 dBm lora.set_pa_config(pa_select=1) try: lora.start() except KeyboardInterrupt: sys.stdout.flush() print ("") sys.stderr.write("KeyboardInterrupt\n") finally: sys.stdout.flush() print ("") lora.set_mode(MODE.SLEEP) BOARD.teardown() Video microcontroller-projects/spi-communication-with-nuvoton-n76e003-microcontroller-to-communicate-with-arduino

SPI Communication with Nuvoton N76E003 MCU to Communicate with Arduino

it's a synchronous data transfer protocol where the master device could communicate with multiple slave devices as well as get data from them. It is synchronous because the master generates a clock in a separate I/O line that guarantees that both devices, master and the slave are running at the same clock speed. SPI protocol uses two data lines, one selection line, and one clock line. The connections are SS (Slave Select), MISO (Master In Slave Out), MOSI (Master Out Slave In), and SCK (Serial Clock). Despite an SCK line, the master generates a clock, and the SS is used for selecting any individual slave in a bus line where multiple slave devices are connected with the master. MISO is used to receive the data from the slave, and MOSI is used to send data from the master to the slave device. guide

Hardware Setup and Requirements to Enable SPI Function on N76E003

that is connected with the N76E003 SPI line. We will send data to the Arduino, validate it, and print it using Arduinos UART. Next, we send a data from Arduino to the N76E003, validate it, and print it using N76E003 UART, that is why a USB to UART converter for the N76E003 and an Arduino becomes necessary for our example application, we will use CP2102 UART to USB converter, and an Arduino Nano to fulfill our requirements. to program the board. Additionally, berg wires are used for all the hardware connections. where we have setup an Arduino as a master device, feel free to check those out if that peaks your interest.

Circuit to Interface N76E003 with Arduino via SPI

As we can see in the schematic, the Arduino Nano is connected with the SPI of N76E003.On the extreme left, the programming interface connection is shown.

SPIPins on Nuvoton N76E003 Microcontroller

The pin diagram of N76E003 can be seen in the below image- pins respectively. If we enable SPI, it'll lose PWM and other functionality. But, that is not a problem as another functionality is not required for this project. This chip considers all the SPI pins as GPIO, which is why those needs to be configured. The configuration method is described below.

SPI Information N76E003

among many other generic communication protocols, which is why different types of microcontrollers come with an in-built SPI peripheral. Before proceeding with SPI communication, it is important to know a few things about SPI communication on N7E003. All individual slaves must require one slave select pin. A single SS pin cannot be connected to multiple slaves. The below image is showing the possible multiple slave connections- By default, the MSB first is selected. However, LSB's first data can also be selected in N76E003. We will take care of this selection in the coding process. The simple SPI connection with Single-Master and Single-Salve is shown in the below image- SPI control register SPCR is used to control the SPI operations. The first two bits are the SPI clock rate selection bit. The clock rates are illustrated below where the system frequency is 16 Mhz. CPHA bit is the clock phase select bit. If the CPHA flag is set, the data is sampled on the second edge of the SPI clock. If it is cleared, then the data is sampled on the first edge. The next bit is CPOLI which is the idle state level of the SPI clock. If set to 0, the clock will be low in idle state, if it is set to 1, it will be high in idle state. The MSTR is the Master mode enable bit, which is used to configure the N76E003 as a master mode, clearing this bit will make it a slave mode. LSBFE is used to data transfer direction. Clearing this bit will make the data transfer as MSB first, whereas setting it 1 will activate the LSB first direction. SPIEN is used to enable the SPI. Setting 1 will enable the SPI peripheral. The final SSOE is the SPI slave select output enable bit, and it is used for configuring the SS pin as general-purpose or in automatic mode. Other than the above, there is another register called the Serial Peripheral Status register. The above register is used to get the various SPI status.

Master N76E003 SPI Programming Explanation

, check out the linked tutorial. void main(void) { Set_All_GPIO_Quasi_Mode; InitialUART0_Timer1(115200); /* 115200 Baud Rate*/ SPI_Initial(); printf ("\nSPI Start Transmit...\n"); while(1) // SPI transmission finish { Start_Sending_SPI(); } } function. void SPI_Initial(void) { P15_Quasi_Mode; // P15 (SS) Quasi mode P10_Quasi_Mode; // P10(SPCLK) Quasi mode P00_Quasi_Mode; // P00 (MOSI) Quasi mode P01_Quasi_Mode; // P22 (MISO) Quasi mode set_DISMODF; // SS General purpose I/O ( No Mode Fault ) clr_SSOE; clr_LSBFE; // MSB first clr_CPOL; // The SPI clock is low in idle mode set_CPHA; // The data is sample on the second edge of SPI clock. set_MSTR; // SPI in Master mode SPICLK_DIV2; // Select SPI clock Enable_SPI_Interrupt; // Enable SPI interrupt set_SPIEN; // Enable SPI function } header file. function, the SS pin is pulled low first, the data is submitted to the Arduino via SPI. The SPDR register will hold the value to be sent to the SPI slave as well as will receive the value from the Slave. void Start_Sending_SPI() { SS = 0; SPDR = 0x90; // Send 0x90 to Slave PCON |= SET_BIT0; // Enter idle mode if(SPDR != 0x4E) // Receive slave 1st DATA SPI_Error(); printf ("\nSlave Return %x\n",SPDR & 0xFF); SS = 1; } However, there is a validation condition, where the SPRD value is checked with (0x4E) that is received from the Arduino. If the data is not 0x4E, it will stop the SPI communication by going into the while loop. void SPI_Error(void) { printf ("\nSlave stoped the Data sending.\n"); while(1) // SPI error and P0.7 flash/ { } } As the SPI used in timer interrupt, one ISR function is used here- void SPI_ISR(void) interrupt 9 // Vecotr @ 0x4B { clr_SPIF; Timer3_Delay10us(1); } It will clear the SPIF with a 1-microsecond time gap.

Programming Arduino as a slave for SPI

Arduino Nano also has the same SPI pins shown in the image below- However, we will not go into the details about Arduino SPI, as there are a ton of details available showing how to use SPI on an Arduino. First, we include all the necessary header and variables, #include<SPI.h> volatile boolean received; volatile byte Slavereceived,Slavesend; Next, in the setup section, we initialize UART, we set our predefined MISO pin as an output, we enable SPI in slave mode, we set our predefined received variable as false, and finally, we enable our interrupt, which marks the end of the setup loop. void setup () { Serial.begin(115200); pinMode(MISO,OUTPUT); //Sets MISO as OUTPUT (Have to Send data to Master IN SPCR |= _BV(SPE); //Turn on SPI in Slave Mode received = false; SPI.attachInterrupt(); //Interuupt ON is set for SPI commnucation } variable to true. In the loop section, we are sending a predefined value to the SPDR register, once every second which transmits the data to the master module.

Testing SPICommunication on Nuvoton using Arduino

The complete code is given at the end of this page. The code when uploaded returned 0 warning and 0 Errors and flashed using the default flashing method by the Keil. The application starts working. Build target 'SPI_INT_M' linking... Program Size: data=58.2 xdata=0 code=2402 creating hex file from ".\Output\Master_P"... ".\Output\Master_P" - 0 Error(s), 0 Warning(s). Build Time Elapsed: 00:00:01 Batch-Build summary: 1 succeeded, 0 failed, 0 skipped - Time Elapsed: 00:00:01 I have used jumper wires to connect my nuvoton board with Arduino, my testing set-up connection is shown below. The Output of the UART can be seen in the below images. When we open the serial monitor of Arduino, we can see the values from the nuvoton board being received through SPI communication. Similarly, on the nuvoton side, we have used tera term to monitor the data is being received from the slave (here Arduino). Basically, we are sending 90 from nuvoton to Arduino and sending 4e00 from Arduino to nuvoton. From the snapshots on the serial monitor, it is clear that both SPI master and slave is working as expected. to post other technical questions. Code #Master N76E003 SPI /*---------------------------------------------------------------------------------------------------------*/ /* */ /* Copyright(c) 2017 Nuvoton Technology Corp. All rights reserved. */ /* */ /*---------------------------------------------------------------------------------------------------------*/ //*********************************************************************************************************** // Website: http://www.nuvoton.com // E-Mail : MicroC-8bit@nuvoton.com // Date : Jan/21/2017 //*********************************************************************************************************** //*********************************************************************************************************** // File Function: N76E003 SPI in Master mode demo code //*********************************************************************************************************** #include "N76E003.h" #include "SFR_Macro.h" #include "Function_define.h" #include "Common.h" #include "Delay.h" //*********************************************************************************************************** // Application: SPI Function // Master send 0x90 and recevie 0x4E // Master send 0x01 and recevie 0x55 // Master send 0x02 and recevie 0x56 // Master send 0x03 and recevie 0x4F // Master send 0x04 and recevie 0x54 // // Master receive 0x4E and 0x4F form slave after transmitting // // Output : P1.4 & P2.1 flash when SPI pass // UART show result on hyper-terminal // P0.7 flash when SPI error //*********************************************************************************************************** #if 0 ///***************************************************************************************** //* For ADC INIT setting //*****************************************************************************************/ //#define SPICLK_DIV2 clr_SPR0;clr_SPR1 //#define SPICLK_DIV4 set_SPR0;clr_SPR1 //#define SPICLK_DIV8 clr_SPR0;set_SPR1 //#define SPICLK_DIV16 set_SPR0;set_SPR1 //#define Enable_SPI_Interrupt set_ESPI;set_EA //#define SS P15 #endif //----------------------------------------------------------------------------------------------------------- void SPI_Error(void) { printf ("\nSlave stoped the Data sending.\n"); while(1) // SPI error and P0.7 flash/ { } } //----------------------------------------------------------------------------------------------------------- void SPI_Initial(void) { P15_Quasi_Mode; // P15 (SS) Quasi mode P10_Quasi_Mode; // P10(SPCLK) Quasi mode P00_Quasi_Mode; // P00 (MOSI) Quasi mode P01_Quasi_Mode; // P22 (MISO) Quasi mode set_DISMODF; // SS General purpose I/O ( No Mode Fault ) clr_SSOE; clr_LSBFE; // MSB first clr_CPOL; // The SPI clock is low in idle mode set_CPHA; // The data is sample on the second edge of SPI clock set_MSTR; // SPI in Master mode SPICLK_DIV2; // Select SPI clock Enable_SPI_Interrupt; // Enable SPI interrupt set_SPIEN; // Enable SPI function } //----------------------------------------------------------------------------------------------------------- void Start_Sending_SPI() { SS = 0; SPDR = 0x90; // Send 0x90 to Slave PCON |= SET_BIT0; // Enter idle mode if(SPDR != 0x4E) // Receive slave 1st DATA SPI_Error(); printf ("\nSlave Return %x\n",SPDR & 0xFF); SS = 1; } //----------------------------------------------------------------------------------------------------------- void main(void) { Set_All_GPIO_Quasi_Mode; InitialUART0_Timer1(115200); /* 115200 Baud Rate*/ SPI_Initial(); printf ("\nSPI Start Transmit...\n"); while(1) // SPI transmission finish { Start_Sending_SPI(); } } //----------------------------------------------------------------------------------------------------------- void SPI_ISR(void) interrupt 9 // Vecotr @ 0x4B { clr_SPIF; Timer3_Delay10us(1); } //----------------------------------------------------------------------------------------------------------- #Slave Arduino SPI #include<SPI.h> volatile boolean received; volatile byte Slavereceived,Slavesend; void setup () { Serial.begin(115200); pinMode(MISO,OUTPUT); //Sets MISO as OUTPUT (Have to Send data to Master IN SPCR |= _BV(SPE); //Turn on SPI in Slave Mode received = false; SPI.attachInterrupt(); //Interuupt ON is set for SPI commnucation } ISR (SPI_STC_vect) //Inerrrput routine function { Slavereceived = SPDR; // Value received from master if store in variable slavereceived Serial.println("Data Recieved\n"); Serial.println("Recieved Data: "); Serial.println(Slavereceived,HEX); received = true; //Sets received as True } void loop(){ SPDR = 0x4E; //Sends the value to master via SPDR delay(1000); } Video microcontroller-projects/18650-lithium-battery-capacity-tester-using-arduino

18650 Lithium Battery Capacity Tester using Arduino

, you can check them out if interested.

Why Do WeNeed a Battery Capacity Tester?

if the cell is not one of these cheap knockoffs? One of the methods is to measure the open-circuit voltage at no load and loading but this is not at all reliable. for a Li-Ion 18650 Cell which will discharge a fully charged 18650 cell through a resistor while measuring the current flowing through the resistor to calculate its capacity. If you do not get the claimed battery capacity while the cell voltage is within the specified limits, then that cell is faulty and you should not use that as the State of Charge of the cell will deplete at a very fast rate under load, creating a local current loop if used in a battery pack resulting in heating and possibly fire. So let’s jump right into it.

Components Required

Arduino Nano 16×2 Character LCD LM741 OPAMP IC 2.2, 5Watt Resistor 7805 Positive Voltage Regulator IC 12V Power Supply 10k Trimmer Potentiometer 0.47uF Capacitor 33k Resistor DC Power Barrel Jack Connector PCB Screw Terminals IRF540N N-Channel Mosfet IC Perfboard Soldering Kit Heat Sinks

Arduino Battery Capacity Tester Circuit Diagram

is shown below. The explanation of the circuit is as follows- This circuit is further divided into two parts, first is a low 5V supply for Arduino Nano and 16×2 Alphanumeric LCD screen and their connections to display the results of the current and voltage measurements in real-time. The circuit is powered by the 12V power supply using SMPS or you can use a 12V battery as well as the maximin current will be around 60-70mA for powering the Arduino and LCD screen. to control the contrast of the LCD display. which controls the current flowing through the MOSFET by switching ON and OFF the MOSFET according to the voltage level set by us. so in this mode. the output of the op-amp will be high whenever the voltage of the non-inverting pin of the op-amp is higher than the inverting pin. Similarly, if the voltage at the inverting pin of the op-amp is higher than the non-inverting pin, the output of the op-amp will be pulled down. In the given circuit, the non-inverting pin voltage level is controlled by the D9 PWM pin of the Arduino NANO, which switches at 500Hz frequency which is then passed through low pass RC circuit filter with Resistance value 33k and Capacitor having a capacitance of 0.47uF, to provide an almost constant DC signal at the non-inverting pin. The inverting pin is connected to the load resistor, which reads the voltage across the resistor and common GND. The output pin of the OPAMP is connected to the gate terminal of the MOSFET to switch it ON or OFF. The OPAMP will try to make the voltages on both its terminals equal by switching the MOSFET connected so the current flowing through the resistor will be proportional to the PWM value you have set at the D9 pin of the NANO. In this project, the maximum current, I have limited my circuit to is 1.3A which is reasonable as the cell I have is 10A as its maximum current rating The Maximum voltage a typical fully charged Li-Ion cell is 4.1V to 4.3V which is less than the 5V voltage limit of the Analog input pins of the Arduino Nano which has more than 10k internal resistance in them so that we can directly connect the Cell to any of the analog input pins without worrying about the current flowing through them. So, in this project, we need to measure the voltage of the cell so that we can determine whether the cell is in the correct voltage operating range and if it is fully discharged or not. We need to measure the current flowing through the resistor as well for that we can’t use the current shunt as the complexity of the circuit will increase and increasing resistance in the load path will decrease the cell discharge rate. Using smaller shunt resistors will require an additional amplifier circuit to make the voltage reading coming from it, readable to the Arduino. the voltage obtained by the load resistor value to get the current flowing through it. The negative terminal of the resistor is connected directly to the GND, so we can safely assume that the voltage we are reading on the resistor is the voltage drop in the resistor.

Arduino Program to Measure Battery Capacity

and while you are there also select the port your Arduino is connected to on your PC. We are using Arduino to drive the 16×2 Alphanumeric LCD connected to it and to measure the voltage of the cell and current flowing through the load resistor as explained in the previous section we start our code by declaring the header files to drive 16×2 Alphanumeric LCD screen. You can skip this section to get the fully cooked and served code at the end of the page but bear with us while we divide the code into small sections and try to explain. Now that the header file is defined, we move on the declaring the variables, we will use in the code to calculate the voltage and current. Also, we have to define the pins we are using to drive the LCD and the pins we will be using to give PWM output and read the analog voltages coming from the cell and resistor as well in this section. #include <LiquidCrystal.h> //Default Arduino LCD Librarey is included const int rs = 3, en = 4, d4 = 5, d5 = 6, d6 = 7, d7 = 8; //Mention the pin number for LCD connection LiquidCrystal lcd(rs, en, d4, d5, d6, d7); const float BAT_LOW = 3.0; //to define the low voltage limit of the Li Ion cell const float BAT_HIGH = 4.5; //to define the high voltage limit of the cell const int MOSFET_Pin=9; const int PWM_VALUE=150; unsigned long previousMillis = 0; // Previous time in ms unsigned long millisPassed = 0; // Current time in ms float Capacity=0; //Variable to define the battery Capacity float Resistor=2.2; // Load Resistor Value is 2.2ohms float mA; Now coming to the setup part, If you want to keep your Arduino connected to your PC the whole time and monitor the progress using Serial Monitor and initialize the LCD screen here. It will also display a welcome message “Battery Capacity Tester Circuitᾠon the screen for 3 seconds. void setup() { Serial.begin(9600); lcd.begin(16, 2); lcd.setCursor(0, 0); // Set the cursor on the first column and first row. lcd.print("Battery Capacity"); lcd.setCursor(0,1); lcd.print("Tester Circuit"); delay(3000); lcd.clear(); } Make sure you correctly measure the voltage between the 5V and GND pins of the Arduino Nano using a calibrated Voltmeter or Multimeter as most of the times the regulated voltage is not exactly 5.0V and even a small difference in this reference voltage would result in errors creeping in the voltage readings so measure the correct voltage and replace the 5.0 in the multiplier given above. Now to explain the logic of the code, we continuously measure the voltage of the cell and if the cell voltage is over the upper limit specified by us in the code, then the error message is shown on LCD to let you know if the cell is overcharged or there is something wrong with the connection and the power to the MOSFET gate pin is stopped so that no current can flow through the load resistor. It is crucial that you fully charge your cell first before connecting it to the capacity tester board so that you can calculate its total charge capacity. analogWrite(MOSFET_Pin, PWM_VALUE); // read the input on analog pin 0: int sensorValue_voltage_Cell = analogRead(A0); // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V): float voltage = sensorValue_voltage_Cell * (5.08 / 1023.0); Serial.print("VOLTAGE: "); Serial.println(voltage); // Here the voltage is being printed on Serial Monitor lcd.setCursor(0, 0); // Set the cursor on the first column and first row. lcd.print("Voltage: "); // Print the voltage reading on the screen lcd.print(voltage); delay(100); int sensorValue_Shunt_Resistor= analogRead(A1); float voltage1= sensorValue_Shunt_Resistor *(5.08 / 1023.0); float current= voltage1/Resistor; Serial.print("Current: "); Serial.println(current); lcd.setCursor(0, 1); //Set the cursor on the first column and the second row (counting starts at 0!). lcd.print("Current: "); lcd.print(current); Now, if the cell voltage is within the upper and lower voltage limits specified by us then the Nano will read the Current value by the method specified above and multiply it with the time passed during the measurements and store it in the capacity variable we defined earlier in mAh units. During this whole time, the real-time current and voltages values are being displayed on the LCD screen attached, and if you want, you can also see them on the serial monitor. The process of discharging the cell will continue until the cell’s voltage reach below the lower limit specified by us in the program and then the total capacity of the cell is displayed on the LCD screen and current flow through the resistor is stopped by pulling the MOSFET gate pin low. else if(voltage > BAT_LOW && voltage < BAT_HIGH ) { // Check if the battery voltage is within the safe limit millisPassed = millis() - previousMillis; mA = current * 1000.0 ; Capacity = Capacity + (mA * (millisPassed / 3600000.0)); // 1 Hour = 3600000ms to convert it into mAh units previousMillis = millis(); delay(1000); lcd.clear(); }

Accuracy Improvements

It is, by all means, a good enough way to read voltage and current, but it is not perfect. The relationship between the actual voltage and measured ADC voltage is not linear and this will amount to some error in the measurements of the voltages and currents. If you want to increase the accuracy of the result, then you must plot the ADC values you get from applying various known voltage sources on a graph and then determine the multiplier equation from it by using any method you like. This way, accuracy will be improved, and you will get very close to actual results. Also, the MOSFET we used is not a logic-level MOSFET, so it needs more than 7V to fully turn on the current channel and if we apply 5V directly to it, the current readings would be inaccurate. But you can use a logic level IRL520N N-Channel MOSFET to eliminate the use of a 12V supply and directly work with 5V logic levels you have with your Arduino.

Building and Testing the Circuit

Now as we designed and tested different sections of our circuit on a breadboard and after making sure that all of them are working as intended we use a Perfboard to solder all the components together as it is a much more professional and reliable method to test the circuit. If you want, you can design your own PCB on AutoCAD Eagle, EasyEDA, or Proteus ARES or any other software you like. The Arduino Nano, 16×2 Alphanumeric LCD, and LM741 OPAMP are mounted on Female Bergstik so that they can be reused later. I have provided a 12V supply through a DC Barrel Jack connector for Constant Load Current Circuit and then with the help of LM7805, the 5V for the Nano and LCD screen is provided. Now power the circuit and adjust the trimmer pot to set the contrast level of the LCD screen, you should see the Welcome Message on the LCD screen by now, and then if the voltage level of the cell is in the working range, then the current-voltage and current from the battery will be displayed there. Go and have fun with it and if you want, we can guide you in the comments section below on how to proceed further from here. Till then Adios!!! Code #include <LiquidCrystal.h> //Default Arduino LCD Librarey is included const int rs = 3, en = 4, d4 = 5, d5 = 6, d6 = 7, d7 = 8; //Mention the pin number for LCD connection LiquidCrystal lcd(rs, en, d4, d5, d6, d7); const float BAT_LOW = 3.0; //to define the low voltage limit of the Li Ion cell const float BAT_HIGH = 4.5; //to define the high voltage limit of the cell const int MOSFET_Pin=9; const int PWM_VALUE=50 ; unsigned long previousMillis = 0; // Previous time in ms unsigned long millisPassed = 0; // Current time in ms float Capacity=0; //Variable to define the battery Capacity float Resistor=2.2; // Load Resistor Value is 2.5ohms float mA; void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); lcd.begin(16, 2); //Initialise 16*2 LCD lcd.setCursor(0, 0); // Set the cursor on the first column and first row. lcd.print("Battery Capacity"); lcd.setCursor(0,1); lcd.print("Tester Circuit"); delay(3000); lcd.clear(); } void loop() { analogWrite(MOSFET_Pin, PWM_VALUE); // read the input on analog pin 0: int sensorValue_voltage_Cell = analogRead(A0); // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V): float voltage = sensorValue_voltage_Cell * (5.12 / 1023.0)*1.2; Serial.print("VOLTAGE: "); Serial.println(voltage); // Here the voltage is being printed on Serial Monitor lcd.setCursor(0, 0); // Set the cursor on the first column and first row. lcd.print("Voltage: "); // Print the voltage reading on the screen lcd.print(voltage); delay(100); int sensorValue_Shunt_Resistor= analogRead(A1); float voltage1= sensorValue_Shunt_Resistor *(5.00 / 1023.0); float current= voltage1/Resistor; Serial.print("Current: "); Serial.println(current); lcd.setCursor(0, 1); //Set the cursor on the first column and the second row (counting starts at 0!). lcd.print("Current: "); lcd.print(current); if ( voltage > BAT_HIGH) { digitalWrite(MOSFET_Pin, LOW); // Turned Off the MOSFET , No discharge Serial.println( "Warning High-V! "); lcd.clear(); lcd.setCursor(0,0); lcd.print("HIGH VOLTAGE!!"); delay(2000); lcd.clear(); } else if(voltage < BAT_LOW) { digitalWrite(MOSFET_Pin, LOW); // Turned Off the MOSFET , No discharge Serial.println( "Warning Low-V! "); lcd.clear(); lcd.setCursor(0,0); lcd.print("Low Voltage!!!"); delay(2000); lcd.clear(); lcd.setCursor(0,0); lcd.print("CAPACITY:"); lcd.setCursor(0,1); lcd.print(Capacity); delay(10000); } else if(voltage > BAT_LOW && voltage < BAT_HIGH ) { // Check if the battery voltage is within the safe limit millisPassed = millis() - previousMillis; mA = current * 1000.0 ; Capacity = Capacity + (mA * (millisPassed / 3600000.0)); // 1 Hour = 3600000ms to convert it into mAh units previousMillis = millis(); //Serial.print("DATA,TIME,"); Serial.print(voltage); Serial.print(","); Serial.println(Capacity); //uncomment this line to diplay on serial monitor delay(1000); lcd.clear(); } } Video microcontroller-projects/long-distance-wired-serial-communication-using-arduino-rs485-and-cat-cables

Long Distance Wired Serial Communication with Arduino using RS485 and CAT Cables

, then you should take the noise and signal power into consideration because if you want your system to work reliably, then you cannot afford to lose the data while transferring. , you can also check them out if interested.

Difference between UART and RS485 Communication

because it only requires 2 wires TX(Transmitter) and RX (Receiver). It is not a standard Communication protocol, but it is a physical circuit with which you can transmit and receive serial data with other peripherals. It can only transmit/receive data serially, so it first converts the parallel data into serial data and then transmits the data. and the maximum data frame is limited to 9 bits. For the transfer of data, the baud rates of both Master and Slave must be between 10% of each other. Shown below is the example of how a character is a transmitter over a UART data line. Signal High and Lows are measured against the GND level so shifting the GND level will have a disastrous effect on the data transfer. of measurement rather than voltage measurement wrt GND pin. The RS485 signals are floating and each signal is transmitted over a Sig+ line and a Sig- line. which has 4 twisted pairs of 24AWG wires and can support up to 600MHz. It is terminated at both ends by an RJ45 connector. Typical line voltage levels from the line drivers are a minimum of ±1.5 V to a maximum of about ±6 V. Receiver input sensitivity is ±200 mV. Noise in the range of ±200 mV is essentially blocked due to common-mode noise cancellation. An example of how a byte(0x3E) is transferred over the two lines of RS485 Communication.

Components Required

2×MAX485 Converter Module 2×Arduino Nano 2×16*2 Alphanumeric LCD 2×10k Wiper Potentiometers Cat-6E Ethernet Cable Breadboards Jumper Wires

Circuit Diagram for Long Distance Wired Communication

Do note that both transmitter and receiver circuits look identical the only thing that differs is the code written into it. Also for the demonstration, we are using one board as a transmitter and one board as a receiver, but we can easily program the boards to work as both transmitter and receiver with the same set-up The connection diagram for the above circuit is also given below. connected to each end of an Ethernet Cat-6E cable via an RJ45 connector. The cable which I have used in the tutorial is 25m in length. We will send some data from the transmitter side over the cable from the Nano which is converted to RS485 signals via MAX RS485 Module working in Master Mode. At the receiving end, the MAX485 converter module is working as a Slave, and listening to the transmission from the Master it again converts the RS485 Data it received to the standard 5V TTL UART signals to be read by the receiving Nano and displayed on 16*2 Alphanumeric LCD connected to it.

MAX485 UART-RS485 Converter Module

It works at a single +5V power supply and the rated current is 300 μA. It works on half-duplex communication to implement the function of converting the TTL level into RS-485 level which means it can either transmit or receive at any time, not both, it can achieve a maximum transmission rate of 2.5Mbps. MAX485 transceiver draws a supply current of between 120μA and 500μA under the unloaded or fully loaded conditions when the driver is disabled. The driver is limited for short-circuit current and the driver outputs can be placed at a high impedance state through the thermal shutdown circuit. The receiver input has a fail-safe feature that guarantees logic high output if the input is open circuit. In addition, it has strong anti-interference performance. It also has onboard LEDs to display the current state of the chip i.e. whether the chip is powered or its transmitting or receiving data making it easier to debug and use. The circuit diagram given above explains how the onboard MAX485 IC is connected to various components and provide 0.1-inch standard spacing headers to be used with breadboard if you like.

Ethernet CAT-6E Cable

and also each pair of wires is twisted together to prevent any current loop formation and thus much better protection against the noise. They are often terminated with 8 pin RJ45 connectors at either end. There are many categories of Ethernet cables we can use like CAT-4, CAT-5, CAT-5E, CAT-6, CAT-6A, etc. In our tutorial, we are going to use CAT-6E cable which has 4 twisted pairs of 24AWG wires and can support up to 600MHz.

Arduino Code Explanation

In this project, we are using two Arduino Nano, one as a transmitter and One as a receiver each driving a 16*2 Alphanumeric LCD to display the results. So, in the Arduino code, we will focus on sending the data and display that sent or received data on the LCD screen. We start with including the standard library for driving the LCD and declare the D8 pin of the Arduino Nano as an output pin which we will later use to declare the MAX485 Module as a transmitter or Receiver. int enablePin = 8; int potval =0 ; #include <LiquidCrystal.h> //Include LCD library for using LCD display functions LiquidCrystal lcd(2,3,4,5,6,7); // Define LCD display pins RS,E,D4,D5,D6,D7 Now coming to the setup part. We will pull the enable pin high to put the MAX485 module in transmitter mode. As it is a half-duplex IC hence it cannot both transmit and receive at the same time. We will also initialize the LCD here and print a welcome message. Serial.begin(9600); // initialize serial at baudrate 9600: pinMode(enablePin, OUTPUT); lcd.begin(16,2); lcd.print("CIRCUIT DIGEST"); lcd.setCursor(0,1); lcd.print("Transmitter Nano"); delay(3000); lcd.clear(); Now in the loop, we write a continuously increasing integer value on the Serial lines which is then transmitted to the other nano. This value is also printed on the LCD for display and debugging. Serial.print("Sent Value= "); Serial.println(potval); //Serial Write POTval to RS-485 Bus lcd.setCursor(0,0); lcd.print("Sent Value"); lcd.setCursor(0,1); lcd.print(potval); delay(1000); lcd.clear(); potval+=1; Here again, we start with including the standard library for driving the LCD and declare the D8 pin of the Arduino Nano as an output pin which we will later use to declare the MAX485 Module as a transmitter or Receiver. int enablePin = 8; #include <LiquidCrystal.h> //Include LCD library for using LCD display functions LiquidCrystal lcd(2,3,4,5,6,7); // Define LCD display pins RS,E,D4,D5,D6,D7 Now coming to the setup part. We will pull the enable pin high to put the MAX485 module in receiver mode. As it is a half-duplex IC hence it can not both transmit and receive at the same time. We will also initialize the LCD here and print a welcome message. Serial.begin(9600); // initialize serial at baudrate 9600: pinMode(enablePin, OUTPUT); lcd.begin(16,2); lcd.print("CIRCUIT DIGEST"); lcd.setCursor(0,1); lcd.print("Receiver Nano"); delay(3000); digitalWrite(enablePin, LOW); // (Pin 8 always LOW to receive value from Master) Now in the loop, we check if there is anything available on the serial port and then read the data and since the incoming data is an integer, we parse it and display on the connected LCD. int pwmval = Serial.parseInt(); //Receive INTEGER value from Master throught RS-485 Serial.print("I got value"); Serial.println(pwmval); lcd.setCursor(0,0); lcd.print("Received Value"); lcd.setCursor(0,1); lcd.print(pwmval); delay(1000); lcd.clear();

Conclusion

The test setup we used for this project can be found below. and I will try my best answering them. Till then,adios! Code int enablePin = 8; int potval =0 ; #include <LiquidCrystal.h> //Include LCD library for using LCD display functions LiquidCrystal lcd(2,3,4,5,6,7); // Define LCD display pins RS,E,D4,D5,D6,D7 void setup() { Serial.begin(9600); // initialize serial at baudrate 9600: pinMode(enablePin, OUTPUT); lcd.begin(16,2); lcd.print("CIRCUIT DIGEST"); lcd.setCursor(0,1); lcd.print("Transmitter Nano"); delay(3000); lcd.clear(); digitalWrite(enablePin, HIGH); // (always high as Master Writes data to Slave) } void loop() { Serial.print("Sent Value= "); Serial.println(potval); //Serial Write POTval to RS-485 Bus lcd.setCursor(0,0); lcd.print("Sent Value"); lcd.setCursor(0,1); lcd.print(potval); delay(1000); lcd.clear(); potval+=1; } int enablePin = 8; #include <LiquidCrystal.h> //Include LCD library for using LCD display functions LiquidCrystal lcd(2,3,4,5,6,7); // Define LCD display pins RS,E,D4,D5,D6,D7 void setup() { Serial.begin(9600); // initialize serial at baudrate 9600: pinMode(enablePin, OUTPUT); lcd.begin(16,2); lcd.print("CIRCUIT DIGEST"); lcd.setCursor(0,1); lcd.print("Receiver Nano"); delay(3000); digitalWrite(enablePin, LOW); // (Pin 8 always LOW to receive value from Master) } void loop() { while (Serial.available()) //While have data at Serial port this loop executes { int pwmval = Serial.parseInt(); //Receive INTEGER value from Master throught RS-485 Serial.print("I got value"); Serial.println(pwmval); lcd.setCursor(0,0); lcd.print("Received Value"); lcd.setCursor(0,1); lcd.print(pwmval); delay(1000); lcd.clear(); } } Video microcontroller-projects/non-contact-wall-mount-digital-infrared-thermometer-with-sd-card-logging

Non-Contact Wall Mount Digital Infrared Thermometer with SD Card Logging

that can record the temperature of a person with a photograph and save it in an Excel file that can be shared on WhatsApp or Gmail.It has a lot of useful features but again this device also needs human intervention to measure the temperature of each individual. , that can be simply fixed on a wall and left turned on. Every induvial entering the premises can scan their temperature by stepping forward to this IR temperature sensor and it will measure the temperature of the individual and display it on the LCD. Apart from that, it also logs the time and temperature of the employee/visitor in excel format on an SD card. It is also very easy to add an RFID reader or a barcode scanner to this project to detect the employee's name and log the temperature and time against his name. This way, the device can also act as an attendance system since the time is also logged. Interesting right!! So let's get started‐󬋊

Materials Required for Wall Mount IR Thermometer

Arduino nano MLX90615 TCRT5000 DS3231 RTC module 16*2 LCD SD Card Module Buzzer Red LED Green LED Perf Board 1K, 4.7K, 10K Resistors 10K Potentiometer DC Barrel Jack 12V 1A DC Power Adapter LED Mount brackets Metal enclosure and screws

Wall Mounted Digital IR Thermometer Circuit Diagram

given below. It might look like a complex circuit but most of them are simple interfacing circuits. project. The sensor works on the principle that all hot objects (including humans) emit IR rays and the intensity of the IR rays will be proportional to the temperature of the object. So, the sensor measures the temperature of the object by measuring the IR rays emitted from the object. The MLX90615 is a digital IR temperature sensor, meaning it has its own internal circuit to measure IR light from an object and directly convert it to a temperature value. This output temperature can be read using I2C communication, the pinout of MLX90615 is shown below. we have connected the IR receiver LED to the analog port of Arduino and IR emitter to a digital pin. This way we can measure the IR signal received by the IR receiver when the IR emitter is turned on and again we can measure it when the IR emitter is turned off. Taking a difference between these two values will help us find the noise in the environment and thus avoid false triggering. has its own inbuilt battery so the device will remember the time even when powered is turned off. However, we have to set the correct time before we use it for the first time. We will not be discussing on how to do that in this article. DS3231 also communicated with I2C pins and hence is connected to the same pins of the MLX90615. However, both the modules have a different I2C address and hence we need not worry about the signals interfering. The SD card module is used to connect an SD card with our Arduino microcontroller. It is used to save the value of the temperature and time of the scan in a text file. The module works with SPI communication protocol and hence we have connected it to the SPI pins of Arduino as shown above. that we have used in many other projects. Finally, we have the LEDs and Buzzer for output indication. The buzzer will beep once along with the green LED if the temperature is normal and the buzzer will beep multiple times along with the Red LED to indicate a high temperature. As you can see there is nothing very complex with the circuit diagram, we have just directly connected the module with Arduino. And apart from that, we have few resistors for the LED and buzzer to act as current limiting resistors and the other 4.7k ohm resistors on the I2C bus is used to pull-up resistors. We also have a potentiometer connected to the LCD to adjust the contrast level of the LCD.

Building the Circuit on Perf Board

As you can see from the main image, the idea was to use this circuit inside a sheet metal enclosure. So the complete circuit shown above is soldered onto a perf board. Make sure to use wires to leave enough distance to mount the LCD, LED, Sensor, and Buzzers. I have used two perf boards, one for placing Arduino nano, DS3231, and all passive components and other for the two sensors (MLX90615 and TCRT500), based on your mounting enclosure, you can solder it in a different way. My perf board soldered to LCD and sensor module is shown below.

Installing the Required Libraries for MLX90615, DS3231, and SD Card

Now that the hardware is ready, its time to start programming our IR digital thermometer. The complete code for this project is given at the end of this page, but before we start, it is important to add the required libraries to your Arduino IDE. Make sure you add the right libraries from the below link else the code will throw errors when compiled. Download DS3231 Library Download MLX90615 Library

Programming Arduino for Wall Mounted Thermometer

After adding the required libraries, you can directly upload the code given at the bottom of this page to check if the circuit is working. If you want to know how the code works, then keep reading... Like always, we begin the program by adding the required header files and defining the pin names. #define Buzz 5 #define Green 3 #define Red 4 #include <Wire.h> #include "DS3231.h" #include "MLX90615.h" #include <LiquidCrystal.h> #include <SPI.h> //Library for SPI communication (Pre-Loaded into Arduino) #include <SD.h> //Library for SD card (Pre-Loaded into Arduino) , this value is used to determine how close the person should get before triggering our device. I have used a value of 200 but you can decrease this value if you want to increase the range. float error_correction = 4; //add this to actual value int Range_sensitivity = 200; //Decrease this value to increase range Then we will also open this file and write the heading for log. Here we are logging Date, Time, and Temperature so we name the heading accordingly. This function will be called only once when during the setup function execution. void Initialize_SDcard() { // see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); // don't do anything more: return; } // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. File dataFile = SD.open("Temp_Log.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.println("Date,Time,Temperature"); //Write the first row of the excel file dataFile.close(); } } that we build earlier. void Write_SDcard() { // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. File dataFile = SD.open("Temp_Log.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.print(rtc.getDateStr()); //Store date on SD card dataFile.print(","); //Move to next column using a "," dataFile.print(rtc.getTimeStr()); //Store date on SD card dataFile.print(","); //Move to next column using a "," dataFile.print(temperature); //Store date on SD card dataFile.println(); //End of Row move to next row dataFile.close(); //Close the file } else Serial.println("OOPS!! SD card writing failed"); } function where we initialize the device. We just display some intro message on the LCD and also initialize the SD card ready for use. There is nothing very serious to explain here. void setup() { Serial.begin(9600); rtc.begin(); lcd.begin(16, 2); lcd.print("Temp. Scanner"); lcd.setCursor(0,1); lcd.print("CircuitDigest"); pinMode(2,OUTPUT); pinMode(Buzz,OUTPUT); pinMode(Red,OUTPUT); pinMode(Green,OUTPUT); mlx.begin(); digitalWrite(Buzz,LOW); digitalWrite(Red,LOW); digitalWrite(Green,LOW); Initialize_SDcard(); } function, our code also gets the current time and date and updates it on the LCD. Then we turn on digital pin 2 which is connected to the IR emitter LED and perform analog read on in A7 to which the IR receiver LED is connected. Then we again repeat this with the IR led turned off. This helps us to measure the Noise and Noise+Signal value from the IR sensor. Then we only have to subtract Noise value from the Noise+Signal value to get the value of Signal. lcd.setCursor(0,1); lcd.print("Date: "); lcd.print(rtc.getDateStr()); digitalWrite(2,HIGH); // Turn on IR LED delayMicroseconds(500); // Forward rise time of IR LED Noise_P_Signal=analogRead(A7); // Read value from A0 => noise+signal digitalWrite(2,LOW); // Turn off IR LED delayMicroseconds(500); // Fall time of IR LED Noise=analogRead(A7); // Read value from A0 => noise only Signal = Noise - Noise_P_Signal; The signal value will tell us how close the person is to the TCRT5000 IR sensor without the influence of the sunlight around the person. Then by comparing this signal value and noise value, we will trigger our thermometer to read the temperature value and also store it in the SD card. If the temperature is normal the Green Led will turn on and if the temperature is high the Red LED will turn on. if (Signal>Range_sensitivity && Noise >500) //dec. signal to increase rage { digitalWrite(Buzz,HIGH); if (trigger == true) Serial.println("start") digitalWrite(2,LOW); //Turn off IR sensor to avoid interferance. for (int i=1; i<=3; i++) { temperature = (mlx.get_object_temp()) + error_correction; Serial.println(temperature,1); delay(150); } digitalWrite(Buzz,LOW); lcd.clear(); lcd.setCursor(0,0); lcd.print("Temp: "); lcd.print(temperature,1); lcd.setCursor(0,1); lcd.print("Saved to SD card"); Write_SDcard();

Wall Mount Thermometer Enclosure ᾠAssembling

After testing the hardware and code, we can assemble our project in a permanent enclosure to install it in a facility. We have designed and fabricated a sheet metal enclosure for this purpose. The design was made considering the size of the LCD display, LEDs, and other components used in the project. Then the design was taken to a laser cutting shop to cut and bend the sheet metal according to design. Finally, it was given for a powder coating to improve the aesthetic look and cover the metal parts. After receiving the casing, we simply have to mount the LCD, DC connector, and LES in the respective slots. Make sure the electronics part is well insulated from the metal enclosure. The above image shows the bottom and top part of the enclosure with the electronics assembled. And after the assembly was completed, the enclosure looked something like this below.

Wall Mounted Digital IR Thermometer Testing

After the assembling is done, it is time to test the device. We used an external 12V 1A adapter to power the device and mounted the device on the wall. As you can see by default device will display time and date. If a person steps in front of the device sensor or shows his hand, it will read the temperature of the person and display it on the screen as shown in the below picture taken during testing. It will also store the same value with time and date on the SD card. with all the temperature values taken with the device. My recorded file that was created during testing is shown below. As you can see, the values are not easy to read on a notepad like this. So it is always better to open the file using Microsoft Excel. Just open it as a CSV file and use a comma as a separator. The excel file will open our data something like this. to get them answered or to start a discussion. Code /*Wall Mounted Temperature Scanner with SD Logging * Website: circuitdigest.com * Code by: B.Aswinth Raj */ float error_correction = 4; //add this to actual value int Range_sensitivity = 200; //Decrease this value to increase range #define Buzz 5 #define Green 3 #define Red 4 #include <Wire.h> #include "DS3231.h" #include "MLX90615.h" #include <LiquidCrystal.h> #include <SPI.h> //Library for SPI communication (Pre-Loaded into Arduino) #include <SD.h> //Library for SD card (Pre-Loaded into Arduino) DS3231 rtc(SDA, SCL); //RTC is connected via I2C LiquidCrystal lcd(9, 8, 14, 15, 16, 17); // initialize the library with the numbers of the interface pins MLX90615 mlx = MLX90615(); const int chipSelect = 10; //SD card CS pin connected to pin 4 of Arduino int Noise; int Signal; int Noise_P_Signal; boolean trigger = true; float temperature; float pvs_temperature; void Initialize_SDcard() { // see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); // don't do anything more: return; } // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. File dataFile = SD.open("Temp_Log.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.println("Date,Time,Temperature"); //Write the first row of the excel file dataFile.close(); } } void Write_SDcard() { // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. File dataFile = SD.open("Temp_Log.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.print(rtc.getDateStr()); //Store date on SD card dataFile.print(","); //Move to next column using a "," dataFile.print(rtc.getTimeStr()); //Store date on SD card dataFile.print(","); //Move to next column using a "," dataFile.print(temperature); //Store date on SD card dataFile.println(); //End of Row move to next row dataFile.close(); //Close the file } else Serial.println("OOPS!! SD card writing failed"); } void setup() { Serial.begin(9600); rtc.begin(); lcd.begin(16, 2); lcd.print("Temp. Scanner"); lcd.setCursor(0,1); lcd.print("CircuitDigest"); pinMode(2,OUTPUT); pinMode(Buzz,OUTPUT); pinMode(Red,OUTPUT); pinMode(Green,OUTPUT); mlx.begin(); digitalWrite(Buzz,LOW); digitalWrite(Red,LOW); digitalWrite(Green,LOW); Initialize_SDcard(); } void loop() { lcd.setCursor(0,0); lcd.print("Time: "); lcd.print(rtc.getTimeStr()); lcd.setCursor(0,1); lcd.print("Date: "); lcd.print(rtc.getDateStr()); digitalWrite(2,HIGH); // Turn on IR LED delayMicroseconds(500); // Forward rise time of IR LED Noise_P_Signal=analogRead(A7); // Read value from A0 => noise+signal digitalWrite(2,LOW); // Turn off IR LED delayMicroseconds(500); // Fall time of IR LED Noise=analogRead(A7); // Read value from A0 => noise only Signal = Noise - Noise_P_Signal; if (Signal>Range_sensitivity && Noise >500) //dec. signal to increase rage { digitalWrite(Buzz,HIGH); if (trigger == true) Serial.println("start"); digitalWrite(2,LOW); //Turn off IR sensor to avoid interferance. for (int i=1; i<=3; i++) { temperature = (mlx.get_object_temp()) + error_correction; Serial.println(temperature,1); delay(150); } digitalWrite(Buzz,LOW); lcd.clear(); lcd.setCursor(0,0); lcd.print("Temp: "); lcd.print(temperature,1); lcd.setCursor(0,1); lcd.print("Saved to SD card"); Write_SDcard(); if (temperature>38) { digitalWrite(Red,HIGH); digitalWrite(Buzz,HIGH); delay (5000); } else { digitalWrite(Green,HIGH); delay (1000); } trigger = false; } else { delay(100); trigger = true; digitalWrite(13,LOW); Serial.println("position_error"); } digitalWrite(Red,LOW); digitalWrite(Buzz,LOW); digitalWrite(Green,LOW); } Video microcontroller-projects/arduino-gps-speedometer-using-oled

DIY GPS Speedometer using Arduino and OLED

is widely used in smartphones and vehicles for navigation and traffic alerts. using a NEO6M GPS module with an OLED display.

Materials Used

Arduino Nano NEO6M GPS Module 1.3 inch I2C OLED display Breadboard Connecting Jumpers

NEO6M GPS Module

Here we are using the NEO6M GPS module. The NEO-6M GPS module is a popular GPS receiver with a built-in ceramic antenna, which provides a strong satellite search capability. This receiver has the ability to sense locations and track up to 22 satellites and identifies locations anywhere in the world. With the on-board signal indicator, we can monitor the network status of the module. It has a data backup battery so that the module can save the data when the main power is shut down accidentally. The core heart inside the GPS receiver module is the NEO-6M GPS chip from u-blox. It can track up to 22 satellites on 50 channels and have a very impressive sensitivity level which is -161 dBm. This 50-channel u-blox 6 positioning engine boasts a Time-To-First-Fix (TTFF) of under 1 second. This module supports the baud rate from 4800-230400 bps and has the default baud of 9600. Operating voltage: (2.7-3.6)V DC Operating Current: 67 mA Baud rate: 4800-230400 bps (9600 Default) Communication Protocol: NEMA Interface: UART External antenna and built-in EEPROM. VCC:Input voltage pin of Module GND:Ground pin RX, TX:UART communication pins with Microcontroller

1.3 inch I2C OLED Display

This Display can only work with the I2C mode. Driver IC: SH1106 Input Voltage: 3.3V-5V DC Resolution: 128x64 Interface: I2C Current consumption: 8 mA Pixel color: Blue Viewing angle: >160 degree Input power supply 3.3-5V DC Ground reference pin Clock pin of the I2C interface Serial Data pin of the I2C interface Library was very easy to use and had a handful of graphical options, hence we will use the same in this tutorial. OLED looks very cool and can be easily interfaced with other microcontrollers to build some interesting projects: Interfacing SSD1306 OLED Display with Raspberry Pi Interfacing SSD1306 OLED Display with Arduino Internet Clock using ESP32 and OLED Display Automatic AC Temperature Controller using Arduino, DHT11 and IR Blaster

Circuit Diagram

is given below. The complete setup will look like below:

Programming Arduino for Arduino OLED Speedometer

The complete code of the project is given at the bottom of the tutorial. Here we are explaining the complete code line by line. is used for OLED. #include <TinyGPS++.h> #include <SoftwareSerial.h> #include <Wire.h> #include <Adafruit_SH1106.h> Then, the OLED I2C address is defined, which can be either OX3C or OX3D, here it is OX3C in my case. Also, the Reset pin of the display has to be defined. In my case, it is defined as -1, as the display is sharing Arduino’s Reset pin. #define OLED_ADDRESS 0x3C #define OLED_RESET -1 Adafruit_SH1106 display(OLED_RESET); class are defined as shown below. Software serial class needs the Arduino pin no. for serial communication, which is defined as 2 and 3 here. int RX = 2, TX = 3; TinyGPSPlus gps; SoftwareSerial gpssoft(RX, TX); function is used to initialize the display. void setup() { Serial.begin(9600); gpssoft.begin(9600); display.begin(SH1106_SWITCHCAPVCC, OLED_ADDRESS); display.clearDisplay(); } is called to show the speed value on OLED. while (gpssoft.available() > 0) if (gps.encode(gpssoft.read())) displayspeed(); if (gps.speed.isValid()) { display.setTextSize(2); display.setCursor(40, 40); display.print(gps.speed.kmph()); display.display(); } Finally, upload the code in Arduino Uno and put the system in moving vehicle, and you can see the speed on the OLED display as shown in the below image. Complete code with a demo video is given below. Code #include <TinyGPS++.h> #include <SoftwareSerial.h> #include <Wire.h> #include <Adafruit_SH1106.h> #define OLED_ADDRESS 0x3C #define OLED_RESET -1 Adafruit_SH1106 display(OLED_RESET); int RX = 2, TX = 3; TinyGPSPlus gps; SoftwareSerial gpssoft(RX, TX); void setup() { Serial.begin(9600); gpssoft.begin(9600); display.begin(SH1106_SWITCHCAPVCC, OLED_ADDRESS); display.clearDisplay(); display.display(); } void loop() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(27, 2); display.print("CIRCUIT DIGEST"); display.setTextSize(1); display.setCursor(35, 20); display.print("SPEED(KMPH)"); display.display(); while (gpssoft.available() > 0) if (gps.encode(gpssoft.read())) displayspeed(); if (millis() > 5000 && gps.charsProcessed() < 10) { display.setTextSize(1); display.setCursor(35, 40); display.print("Error!!!"); display.display(); while (true); } } void displayspeed() { if (gps.speed.isValid()) { display.setTextSize(2); display.setCursor(40, 40); display.print(gps.speed.kmph()); display.display(); } else { display.setTextSize(1); display.setCursor(35, 40); display.print("No Data!!!"); display.display(); } delay(100); } Video microcontroller-projects/pure-sine-wave-generator-using-arduino

Pure Sine Wave Inverter Using Arduino

here. and explain the working principle of the circuit. If you are making this circuit, please note that this circuit features no feedback, no overcurrent protection, no short circuit protection, and no temperature protection. Hence this circuit is built and demonstrated for educational purposes only, and it’s absolutely not recommended to build and use this type of circuit for commercial appliances. However you can add them to your circuit if required, the commonly used protection circuits like , etc. have already been discussed. If you are making this type of circuit, please be extra careful about high voltage and voltage spikes generated by the switching signal to the input.

What is SPWM (Sinusoidal Pulse Width Modulation)?

, you can read it here. So, by varying the duty cycle, we alter the average voltage of the pulse. The image below shows that- , the below image shows that. So, by providing proper values of the duty cycle at the input, we will have a very sinusoidal wave at the output.

How the SPWMInverter Works

here. in the direction in which the current is flowing, and the core of the transformer will pass the magnetic flux in the secondary winding, and we will get the positive half cycle of the sinusoidal signal at the output. here. That is how the basic inverter works. used in this project is given below.

Components Required to Build SPWM Inverter

1Atmega328PIC1
2IRFZ44NMosfet2
3BD139Transistor2
4BD140Transistor2
522pFCapacitor2
610K,1%Resistor1
716MHzCrystal1
80.1uFCapacitor3
94.7RResistor2
101N4148Diode2
11LM7805Voltage Regulator1
12200uF,16VCapacitor1
1347uF, 16VCapacitor1
142.2uF,400VCapacitor1

SPWM Inverter Circuit Construction

, At the output of the transformer, a huge amount of current will flow through the connection, so the connection jumpers need to be as thick as possible.

Arduino Program for SPWMInverter

now the question remains how we can make such a varying wave at the output pins of the Arduino. if we consider a single half-cycle of a sine wave, that fits exactly 100 times within a one-half cycle of the wave. In simple terms, we will be able to sample our sine wave 200 times. to feed it to the counter and we will get our sine wave. The code is very simple, We begin our program by adding the required header files #include <avr/io.h> #include <avr/interrupt.h> Next, we have our two lookup tables from which we are going to get the timer counter values. int lookUp1[] = {50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,981 ,1020 ,1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264 ,1294 ,1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,1536 ,1550 ,1561 ,1572 ,1580 ,1587 ,1593 ,1597 ,1599 ,1600 ,1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,1264 ,1233 ,1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,446 ,398 ,349 ,300 ,250 ,201 ,151 ,100 ,50 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0}; int lookUp2[] = {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,981 ,1020 ,1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264 ,1294 ,1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,1536 ,1550 ,1561 ,1572 ,1580 ,1587 ,1593 ,1597 ,1599 ,1600 ,1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,1264 ,1233 ,1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,446 ,398 ,349 ,300 ,250 ,201 ,151 ,100 ,50 ,0}; of the atmega328 IC. TCCR1A = 0b10100010; /*10 clear on match, set at BOTTOM for compA. 10 clear on match, set at BOTTOM for compB. 00 10 WGM1 1:0 for waveform 15. */ TCCR1B = 0b00011001; /*000 11 WGM1 3:2 for waveform 15. 001 no prescale on the counter. */ TIMSK1 = 0b00000001; /*0000000 1 TOV1 Flag interrupt enable. */ register with a predefined value of 16000 as this will help us to generate exactly 200 samples. ICR1 = 1600; // Period for 16MHz crystal, for a switching frequency of 100KHz for 200 subdivisions per 50Hz sine wave cycle. Next, we enable global interrupts by calling in the function, sei(); Finally, we set Arduino pin 9 and 10 as output DDRB = 0b00000110; // Set PB1 and PB2 as outputs. That marks the end of the setup function. The loop section of the code stays empty as it is a timer counter interrupt-driven program. void loop(){; /*Do nothing . . forever!*/} Next, we have defined the timer1 overflow vector, this interrupt function gets a call once the timer1 gets overflowed and generates an interrupt. ISR(TIMER1_OVF_vect){ Next, we declare some local variables as static variables and we have started feeding the values to the capture and compare resistor. static int num; static char trig; // change duty-cycle every period. OCR1A = lookUp1[num]; OCR1B = lookUp2[num]; Finally, we pre-increment the counter to feed the next values to the capture and compare resistors, which marks the end of this code. if(++num >= 200){ // Pre-increment num then check it's below 200. num = 0; // Reset num. trig = trig^0b00000001; digitalWrite(13,trig); }

Testing the TL494 PWM Inverter Circuit

In order to test the circuit, the following setup is used. 12V lead-acid battery. A transformer which has a 6-0-6 tap and a 12-0-12 tap 100W incandescent light bulb as a load Meco 108B+TRMS Multimeter Meco 450B+TRMS Multimeter which looks like the below image, If we zoom in a little bit we can see the ever-changing duty cycle of the PWM wave. Next, the below image shows the output signal from the transformer. As you can see from the above image, this circuit draws around 13W while running ideal The output voltage of the inverter circuit is shown above, this is the voltage coming out at the output without any load attached. The above image shows the input power which ic consume when a 40W load is attached. The above image shows the output power which is consumed by this circuit, (the load is a 40W incandescent light bulb) With that, we conclude the testing part of the circuit. You can check out the video below for a demonstration. I hope you liked this article and learned a bit about SPWM and its implementation techniques. Keep reading, keep learning, keep building and I will see you in the next project. Code /* * sPWMv2.c * * Created: 31/12/2014 3:44:43 PM * Author: Kurt Hutten SPWM on the atMega328 for the arduino Uno, might be compatible with other atmel chips / arduino boards. Compare outputs A and B output to PORTB pins 1 and 2 which are pins 9 and 10 respectively on the Uno. Also useful to know the led on the Uno is pin 5 on PORTB. */ #include <avr/io.h> #include <avr/interrupt.h> // Look up tables with 200 entries each, normalised to have max value of 1600 which is the period of the PWM loaded into register ICR1. int lookUp1[] = {50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,981 ,1020 ,1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264 ,1294 ,1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,1536 ,1550 ,1561 ,1572 ,1580 ,1587 ,1593 ,1597 ,1599 ,1600 ,1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,1264 ,1233 ,1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,446 ,398 ,349 ,300 ,250 ,201 ,151 ,100 ,50 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0}; int lookUp2[] = {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,981 ,1020 ,1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264 ,1294 ,1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,1536 ,1550 ,1561 ,1572 ,1580 ,1587 ,1593 ,1597 ,1599 ,1600 ,1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,1264 ,1233 ,1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,446 ,398 ,349 ,300 ,250 ,201 ,151 ,100 ,50 ,0}; void setup(){ // Register initialization, see datasheet for more detail. TCCR1A = 0b10100010; /*10 clear on match, set at BOTTOM for compA. 10 clear on match, set at BOTTOM for compB. 00 10 WGM1 1:0 for waveform 15. */ TCCR1B = 0b00011001; /*000 11 WGM1 3:2 for waveform 15. 001 no prescale on the counter. */ TIMSK1 = 0b00000001; /*0000000 1 TOV1 Flag interrupt enable. */ ICR1 = 1600; // Period for 16MHz crystal, for a switching frequency of 100KHz for 200 subdivisions per 50Hz sine wave cycle. sei(); // Enable global interrupts. DDRB = 0b00000110; // Set PB1 and PB2 as outputs. pinMode(13,OUTPUT); } void loop(){; /*Do nothing . . forever!*/} ISR(TIMER1_OVF_vect){ static int num; static char trig; // change duty-cycle every period. OCR1A = lookUp1[num]; OCR1B = lookUp2[num]; if(++num >= 200){ // Pre-increment num then check it's below 200. num = 0; // Reset num. trig = trig^0b00000001; digitalWrite(13,trig); } } Video microcontroller-projects/how-to-program-arduino-wirelessly-over-bluetooth

How to Program Arduino Wirelessly over Bluetooth

Components Required

Arduino UNO HC05 Bluetooth Module Jumpers Wires 1K, 2.2K Resistors Capacitor (0.1uF) Power Adapter Breadboard

HC05 Bluetooth Module

HCᾰ5 module is a Bluetooth Serial Port Protocol module, specially designed for wireless communication between microcontrollers. HC-05 Bluetooth module provides switching mode between master and slave mode configuration and communicates through Serial Communication at 9600 baud rate, which makes it easy to interface with controller. HC05 module works on 3.3 V but we can connect it to 5V supply voltage because the module comes with onboard 5v to 3.3 V regulator. here.

Program Arduino over Bluetooth

, first, we have to program the Arduino to respond to AT commands. For that, connect the Arduino to Laptop’s serial port and upload the below code: #include <SoftwareSerial.h> SoftwareSerial HC05(2,3); void setup() { Serial.begin(9600); Serial.println("Enter AT commands:"); HC05.begin(38400); } void loop() { if (HC05.available()) Serial.write(HC05.read()); if (Serial.available()) HC05.write(Serial.read()); } library. #include <SoftwareSerial.h> SoftwareSerial HC05(2,3); , define the baud rates for both Hardware and Software serial ports. The Baud rates for Hardware and Software serial ports are 9600 and 38400 respectively. void setup() { Serial.begin(9600); Serial.println("Enter AT commands:"); HC05.begin(38400); } First condition checks if any command is given to HC05, if yes, then write it to Arduino Serial Monitor. The second condition checks if any command is given to Arduino Serial Monitor, if yes, then send it to HC05. void loop() { if (HC05.available()) Serial.write(HC05.read()); if (Serial.available()) HC05.write(Serial.read()); } for the same is given below: and then connect the Arduino to a computer. Hold the key button until the Bluetooth module LED starts blinking at an interval of 2 seconds. The Bluetooth module LED blinks slower in command mode than the normal mode. " each time command runs successfully. AT+ORGL AT+ROLE=0 AT+POLAR=1,0 AT+UART=115200, 0, 0 AT+INIT After successfully testing the AT commands, just remove all the connections and connect it as per the schematics below. in your Laptop, turn on the Bluetooth, and then connect the Bluetooth module to your Laptop. , and check the COM Ports option. It will display two COM ports, one for incoming and the other for outgoing. We need to select the second COM port number as we are uploading the program. Now open up the Arduino IDE and select the blink program, select the right com port, and hit the upload button. If everything went well, the Arduino onboard LED will start blinking at an interval of 1 sec. is given below. Code #include <SoftwareSerial.h> SoftwareSerial HC05(2,3); void setup() { Serial.begin(9600); Serial.println("Enter AT commands:"); HC05.begin(38400); } void loop() { if (HC05.available()) Serial.write(HC05.read()); if (Serial.available()) HC05.write(Serial.read()); } Video microcontroller-projects/interfacing-sx1278-lora-module-with-esp32

Interfacing SX1278 LoRa Module with ESP32

is also connected at ESP32 to display the temperature and humidity on the sender's side.

Components Required

ESP32 Arduino Uno Arduino Lora Shield LoRa -02 SX1278 Module (2) 16*2 LCD Module OLED Display Module Breadboard Jumper Wires can be built by following the link, where you can find Gerber files for PCB and all the required steps to build it.

Circuit Diagram

Circuit diagram for the LoRa transmitter/Server and Receiver/Client section is given below. In this project, we are going to send weather data from the ESP32 module to Arduino Uno using the LoRa SX1278 module. The temperature and humidity data will be read from the internet using an API with the ESP32 module and then sent to Arduino using the LoRa module.

Transmitting Side- Interfacing LoRa with ESP32

On the transmitting side, we are using ESP32 with the LoRa module and OLED Display. Circuit diagram for the same is shown below. Complete connections are given in the below table.
LoRa SX1278 ModuleESP32
3.3V3.3V
GNDGND
NSSD5
DIO0D2
SCKD18
MISOD19
MOSID23
RSTD14
OLED PinESP32 Pin
Vcc3.3v
GNDGND
SCLD22
SDAD21
; follow the link to learn more.

Receiver Side- Interfacing LoRa with Arduino UNO

You can follow this article for the Gerber file and other information on the LoRa shield. This shield consists of the SX1278 433MHz module with a 3.3V regulator designed using LM317 Variable regulator. The Shield will directly sit on top of Arduino providing it LoRa capabilities. The complete circuit diagram for the LoRa Arduino Shield is given below:

API Link for Getting the Weather Data

, which has a very simple to use API that allows us to retrieve weather information. So sign up in the website to get the API link. After sign up, Go to the ‘My Accountᾠand get the API. An API key is used to make requests to get the data. Now onAPI explorer page, enter the API and the City name. button to make a request. It will give you the API key. Now paste your API URL into a new browser tab and the output of that query will look like this (JSON data): and paste the JSON data in the Input section. and copy the code section that is useful for you.

ESP32 LoRa Transmitter Code

Complete code for the LoRa transmitter and receiver side is given at the end of the document. Here we are explaining some important snippets of code. Library is used for communication between I2C devices. You can download the required libraries from here: Wire.h SH1106.h LoRa library by Sandeep Mistry. #include <HTTPClient.h> #include <WiFi.h> #include <ArduinoJson.h> #include <SPI.h> #include <LoRa.h> #include <Wire.h> #include<SH1106.h> Then create an instance for the OLED display that includes the Address and pins where the display is connected. SH1106 display(0x3c, 21, 22); After that, enter the Wi-Fi name and password. ESP32 needs the internet connection as it is getting the weather data from a website. const char* ssid = "Wi-fi Name"; const char* pass = "Password"; In the next lines, define the pins where the LoRa Module is connected. #define ss 5 #define rst 14 #define dio0 2 Now enter the API link that is generated earlier. Using this link, we will get the temperature and humidity data for Jaipur City. Const char* url = "http://api.weatherapi.com/v1/current.json?key=ade61a8aef37445d8c0100632202407&q=Jaipur"; function. Serial.begin(115200); Serial.println(ssid); WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); } LoRa.setPins(ss, rst, dio0); while (!LoRa.begin(433E6)) { } LoRa.setSyncWord(0xF3); } function, we will check if the JSON file is received by ESP32 and printing JSON data on the serial monitor using the following lines. int httpCode = https.GET(); if (httpCode > 0) { String payload = https.getString(); char charBuf[500]; payload.toCharArray(charBuf, 500); Serial.println(payload); This phrasing program will give us temperature and humidity data for Jaipur. const size_t capacity = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(8) + JSON_OBJECT_SIZE(23) + 490; DynamicJsonDocument doc(capacity); const char* json = "{\"location\":{\"name\":\"Jaipur\",\"region\":\"Rajasthan\",\"country\":\"India\",\"lat\":26.92,\"lon\":75.82,\"tz_id\":\"Asia/Kolkata\",\"localtime_epoch\":1595741089,\"localtime\":\"2020-07-26 10:54\"},\"current\":{\"last_updated_epoch\":1595740520,\"last_updated\":\"2020-07-26 10:45\",\"temp_c\":31,\"temp_f\":87.8,\"is_day\":1,\"condition\":{\"text\":\"Mist\",\"icon\":\"//cdn.weatherapi.com/weather/64x64/day/143.png\",\"code\":1030},\"wind_mph\":0,\"wind_kph\":0,\"wind_degree\":0,\"wind_dir\":\"N\",\"pressure_mb\":1008,\"pressure_in\":30.2,\"precip_mm\":0,\"precip_in\":0,\"humidity\":66,\"cloud\":50,\"feelslike_c\":32.2,\"feelslike_f\":89.9,\"vis_km\":5,\"vis_miles\":3,\"uv\":8,\"gust_mph\":7.2,\"gust_kph\":11.5}}"; deserializeJson(doc, json); long current_last_updated_epoch = current["last_updated_epoch"]; const char* current_last_updated = current["last_updated"]; // int current_temp_c = current["temp_c"]; // 31 int current_humidity = current["humidity"]; // 66 Now in the last step, send the temperature and humidity values to LoRa receiver. LoRa.beginPacket(); LoRa.print("Temperature: "); LoRa.print(current_temp_c); LoRa.print("c"); LoRa.print("Humidity: "); LoRa.print(current_humidity); LoRa.endPacket();

Arduino LoRa Receiver Code

Similarly, add the library for the LoRa module and LCD and define which pins the LCD is connected to. #include <SPI.h> #include <LoRa.h> #include <LiquidCrystal.h> constintrs = 8, en = 7, d4 = 6, d5 = 5, d6 = 4, d7 = 3; LiquidCrystallcd(rs, en, d4, d5, d6, d7); function, we receive the data packets from the transmitter module. After receiving the packets, Arduino starts reading them as characters and print them on the LCD. When it receives the keyword “c,ᾠit prints the remaining information on the second line. void loop() { intpacketSize = LoRa.parsePacket(); if (packetSize) { Serial.print("Received packet '"); while (LoRa.available()) { char incoming = (char)LoRa.read(); if (incoming == 'c') { lcd.setCursor(0, 1); } else { lcd.print(incoming); }

Working of ESP32 LoRa Setup

Once the hardware and program are ready, upload the below given codes in ESP32 and Arduino modules. Transmitter module will send the temperature and humidity values to Receiver Module. And receiver LoRa module will display them on LCD connected to Arduino as shown below. project is given below. Code Arduino Code: #include <SPI.h> //SPI Library #include <LoRa.h> //LoRa Library #include <LiquidCrystal.h> //Library for LCD const int rs = 8, en = 7, d4 = 6, d5 = 5, d6 = 4, d7 = 3; //Mention the pin number for LCD connection LiquidCrystal lcd(rs, en, d4, d5, d6, d7);//Initialize LCD method void setup() { Serial.begin(9600); //Serial for Debugging lcd.begin(16, 2); //Initialise 16*2 LCD lcd.print("Arduino LoRa"); //Intro Message line 1 Serial.print("Arduino LoRa"); //Intro Message line 1 lcd.setCursor(0, 1); lcd.print("Receiver"); //Intro Message line 2 delay(2000); if (!LoRa.begin(433E6)) { //Operate on 433MHz Serial.println("Starting LoRa failed!"); lcd.print("LoRa Failed"); while (1); } } void loop() { int packetSize = LoRa.parsePacket(); // lcd.print("LoRa"); if (packetSize) { // If packet received Serial.print("Received packet '"); lcd.clear(); while (LoRa.available()) { char incoming = (char)LoRa.read(); if (incoming == 'c') { lcd.setCursor(0, 1); } else { lcd.print(incoming); Serial.print(incoming); } } } } ESP32 Code: #include <HTTPClient.h> #include <WiFi.h> #include <ArduinoJson.h> #include <SPI.h> #include <LoRa.h> #include <Wire.h> #include<SH1106.h> SH1106 display(0x3c, 21, 22); const char* ssid = "Galaxy-M20"; const char* pass = "ac312124"; int count; //define the pins used by the transceiver module #define ss 5 #define rst 14 #define dio0 2 const char* url = "http://api.weatherapi.com/v1/current.json?key=ade61a8aef37445d8c0100632202407&q=Jaipur"; void setup() { Serial.begin(115200); delay(2000); Serial.println("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); // print ... till not connected } Serial.println("WiFi connected"); Serial.println("LoRa Sender"); LoRa.setPins(ss, rst, dio0); while (!LoRa.begin(433E6)) { Serial.println("."); delay(500); } // Change sync word (0xF3) to match the receiver // The sync word assures you don't get LoRa messages from other LoRa transceivers // ranges from 0-0xFF LoRa.setSyncWord(0xF3); Serial.println("LoRa Initializing OK!"); display.init(); display.flipScreenVertically(); display.setFont(ArialMT_Plain_10); } void loop() { HTTPClient https; String data; https.begin(url); int httpCode = https.GET(); if (httpCode > 0) { //Check for the returning code String payload = https.getString(); char charBuf[500]; payload.toCharArray(charBuf, 500); //Serial.println(payload); const size_t capacity = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(8) + JSON_OBJECT_SIZE(23) + 490; DynamicJsonDocument doc(capacity); const char* json = "{\"location\":{\"name\":\"Jaipur\",\"region\":\"Rajasthan\",\"country\":\"India\",\"lat\":26.92,\"lon\":75.82,\"tz_id\":\"Asia/Kolkata\",\"localtime_epoch\":1595741089,\"localtime\":\"2020-07-26 10:54\"},\"current\":{\"last_updated_epoch\":1595740520,\"last_updated\":\"2020-07-26 10:45\",\"temp_c\":31,\"temp_f\":87.8,\"is_day\":1,\"condition\":{\"text\":\"Mist\",\"icon\":\"//cdn.weatherapi.com/weather/64x64/day/143.png\",\"code\":1030},\"wind_mph\":0,\"wind_kph\":0,\"wind_degree\":0,\"wind_dir\":\"N\",\"pressure_mb\":1008,\"pressure_in\":30.2,\"precip_mm\":0,\"precip_in\":0,\"humidity\":66,\"cloud\":50,\"feelslike_c\":32.2,\"feelslike_f\":89.9,\"vis_km\":5,\"vis_miles\":3,\"uv\":8,\"gust_mph\":7.2,\"gust_kph\":11.5}}"; deserializeJson(doc, json); JsonObject location = doc["location"]; const char* location_name = location["name"]; // "Jaipur" const char* location_region = location["region"]; // "Rajasthan" const char* location_country = location["country"]; // "India" JsonObject current = doc["current"]; long current_last_updated_epoch = current["last_updated_epoch"]; const char* current_last_updated = current["last_updated"]; // int current_temp_c = current["temp_c"]; // 31 int current_humidity = current["humidity"]; // 66 Serial.print("Temperature: "); Serial.println(current_temp_c); Serial.println("Humidity: "); Serial.println(current_humidity); Serial.print("Sending packet: "); // Serial.println(counter); //Send LoRa packet to receiver LoRa.beginPacket(); LoRa.print("Temperature: "); LoRa.print(current_temp_c); String Temp = String(current_temp_c); LoRa.print("c"); LoRa.print("Humidity: "); LoRa.print(current_humidity); String Humidity = String(current_humidity); LoRa.endPacket(); display.clear(); display.setTextAlignment(TEXT_ALIGN_LEFT); display.setFont(ArialMT_Plain_16); display.drawString(0, 23, "Temperature:"); display.drawString(94, 23, Temp); display.drawString(0, 38, "Humidity:"); display.drawString(70, 38, Humidity); display.display(); delay(5000); } else { Serial.println("Error on HTTP request"); } https.end(); count++; } Video microcontroller-projects/contactless-smart-thermometer-using-mlx90615-ir-temperature-sensor-arduino-and-android

Contactless Smart IR Thermometer using Arduino and Android ᾠSave and Share Results with Pictures

, you can also check that out if interested. So, the objective of this tutorial is to design a Low cost, Easy to build Contactless Thermometer that can measure body temperature, log them into an excel along with the picture of the individuals so that the record can be easily shared with concerned authorities. Intriguing right!! let’s get started‐󬋊

Low Cost and Easy to Build ᾠAndroid App for Rescue

On a quick look, we can distinct some of the important parts on a thermometer, namely the IR temperature sensor, microcontroller, Display, Display driver, and the Battery. Now our objective here is to reduce the cost and the most expensive material (at the time of documentation) is the IR temperature sensor itself. Sadly, though as a maker, there are not many options here that you can reach out quickly other than MLX90614 and MLX90615. On the other hand, if you are okay with using an Analog sensor, you will have many cheaper alternatives but it won’t be easy to build and calibrate your device, the choice is yours here. For this tutorial, we will be using the MLX90615 sensor from Melexis. With the sensor selected, we are only left with Microcontroller, Display, and Battery. So we decided to cut down the cost of all these three parts by leveraging an Android Mobile Phone. Today almost everyone has a good android phone with a decent camera. We can create a simple Android application that can communicate with our thermometer and perform other activities like data logging and image capture. This way we can not only make it work faster but can also increase its potential application by instantaneously sharing log results with pictures on WhatsApp, Gmail, or any other preferred platform. This is why we created our Android application called “Easy Scanᾠwhich is open-sourced and the APK is also free to download, more on this later. So the only material required for this project is- MLX90615 IR Temperature Sensor TCRT5000 IR Sensor Arduino Nano

Why TCRT5000 and Arduino Nano?

For many people, this question would have popped up. The reason for using a TCRT5000 IR sensor is to detect the position of the thermometer and take temperature reading automatically. This way you would never have to do anything with the application once it is launched making it easy to use. Also, the reading will be taken only when the sensor is in the right distance from the person so we not worry about false readings. or any other controller that supports I2C, ADC, and UART will work fine for this project.

Interfacing MLX90615 and TCRT5000 with Arduino

is given below. So I have connected the IR diode to a digital pin and the Photodiode to an Analog pin of the Arduino. This way we can measure the value from photodiode during the normal stage and then measure again after turning on the IR LED, the difference between these two values should help us deal with noise. More on this will be discussed in the programming section. You can build a PCB for this if required but for quick prototyping, I have directly soldered the components on a perf board. My set-up looks like this when completed, we will be building a 3D printed case for this, so try following the same component spacing when you are building your protoboard.

Contactless Smart Thermometer ᾠArduino Program

The Arduino program for this project is very simple, thanks to the Arduino community. You can download the header file for MLX90615 provided by Sergey Kiselev from the below link. Download MLX90615 header file The complete Arduino program for this project can be found at the bottom of this page, the explanation of this code is as follows. and other is the range sensitivity value. Even though the MLX90615 is factory calibrated, I found that the values were sensible only if I add an error correction value to it. In my case, I had to add 3.2 to the value I obtained from the sensor to get reliable values. I tested my values against a handheld thermometer and found that after adding this error correction value and found it to be reliable. The next variable is the Range sensitivity if we decrease this value, we can increase the range of our thermometer. Although the values are reliable, I am not sure if this is the best way to do it, any comment on this is welcomed. float calibration = 3.2; //add this to actual value int Range_sensitivity = 200; //Decrease this value to increase range #include <Wire.h> #include "MLX90615.h" MLX90615 mlx = MLX90615(); The next set of code that needs error correction is the way TCRT5000 is used in this project. It is possible to use it as a simple position sensor, but then the biggest drawback with the IR position sensor is that it will get triggered if IR rays from the sun directly fall on it. To avoid this problem, we measure two values from our TCRT5000 sensor as explained in the circuit, the emitter LED of the IR sensor is connected to a digital pin and the receiver LED is connected to the Analog pin. Now in our program, we will read two values from our IR sensor, one is Noise and the other is Noise plus Signal. The Noise value will be measured while keeping the emitter IR LED turned off, so that the receiver IR LED will only tell about the sunlight intensity present in the environment. Then we will measure the Noise Plus signal after turning on the IR LED. Then in the program, we only have to subtract Noise from Noise Plus Signal and we will get our Signal value. The code to do that is shown below. digitalWrite(2,HIGH); // Turn on IR LED delayMicroseconds(500); // Forward rise time of IR LED Noise_P_Signal=analogRead(A7); // Read value from A0 => noise+signal digitalWrite(2,LOW); // Turn off IR LED delayMicroseconds(500); // Fall time of IR LED Noise=analogRead(A7); // Read value from A0 => noise only Signal = Noise - Noise_P_Signal; as output. If the noise value is very high (in this case greater than 500), it means the sensor is facing direct sunlight and we will not read the temperature in this case because I found the sensor values very unreliable when it is facing direct sunlight. Again, this should help avoid false readings. if (Signal>Range_sensitivity && Noise >500) //dec. signal to increase rage { if (trigger == true) Serial.println("start"); digitalWrite(13,HIGH); temperature = (mlx.get_object_temp()) + error_correction; Serial.println(temperature,1); delay(100); trigger = false; } else { delay(100); trigger = true; digitalWrite(13,LOW); Serial.println("position_error"); }

Easy Scan Android Application

The most feature rich part of this project is the Easy Scan Android Application. You can download this application APK file from the below link. and add new features or tweak according to your requirements. As mentioned earlier, the Android application allows us to store all the temperature values with a photograph and also share it as an excel file through Whatsapp E-mail, etc. Few screenshots of the applications are shown below.

3D Printed Enclosure for Contactless IR Thermometer

The idea of the project is to make the thermometer compact enough to mount it along with our phone. We designed a CAD model to fit all the electronics into a neat little box used paper clip to secure the device with the phone. The CAD model is shown below. The design is very simple, it just houses all the electronics and provides an opening to mount the IR sensor and temperature sensor and also a slot to connect the programming cable to Arduino nano USB port. The sensor mounting is tilted buy 30 degree so that it gets mostly perpendicular when a user is holding it against another person’s forehead. We have used a simple sliding top piece to act as a cover. You can also download the complete cad file and STL from the below link to print the same enclosure if required. Note that the design was made to suit my perf board, you might have to tweak it a bit to match your board. Maybe in the future, we will have a PCB board and design a better casing. But for now, you can use the CAD model as a reference and make your own. Feel free to share your designs.

Testing Contactless Smart IR Thermometer with Easy Scan Android Application

Once the hardware is ready, upload the Arduino code given below. Then open the serial monitor and you see position error being displayed. If you bring your hand close to the sensor, you will see the value of temperature. You can use any existing IR thermometer to check if the values are correct if not you have to change your error correction value. My Serial monitor screenshot is given below. This will help us make sure the hardware and program are working as expected. After that use an OTG connector and connect your device to mobile phone. Both mobiles, with Type-C and micro USB port, were tested and found to be working. Make sure you turn on OTG in your mobile phone under setting options. Not all phones ask for this, but it never hurts to check. After making the connection, install the Easy Scan application using the APK shared earlier and launch the Application. Place the device against an object and if everything is working as expected, you should see the temperature value on the application. The application allows you to set threshold temperature, if the temperature is more than this threshold value, it will prompt you to take a picture. All the scanned records and be viewed on the application with time and date and can also be shared in Excel format for maintaining records. You can watch the video below for the complete working demonstration. if you have any technical queries to be answered. Code float error_correction = 3.5; //add this to actual value int Range_sensitivity = 200; //Decrease this value to increase range #include <Wire.h> #include "MLX90615.h" MLX90615 mlx = MLX90615(); void setup() { Serial.begin(9600); delay(100); while (! Serial); pinMode(2,OUTPUT); mlx.begin(); } int Noise; int Signal; int Noise_P_Signal; boolean trigger = true; float temperature; float pvs_temperature; void loop() { digitalWrite(2,HIGH); // Turn on IR LED delayMicroseconds(500); // Forward rise time of IR LED Noise_P_Signal=analogRead(A7); // Read value from A0 => noise+signal digitalWrite(2,LOW); // Turn off IR LED delayMicroseconds(500); // Fall time of IR LED Noise=analogRead(A7); // Read value from A0 => noise only Signal = Noise - Noise_P_Signal; //Serial.print("Noise + Signal = "); Serial.println(Noise_P_Signal); //Serial.print("Noise ="); Serial.println(Noise); //Serial.print ("--> Signal ="); Serial.println (Signal); //temperature = (mlx.get_object_temp()) + error_correction; //Serial.println(temperature,1); //delay(100); if (Signal>Range_sensitivity && Noise >500) //dec. signal to increase rage { if (trigger == true) Serial.println("start"); digitalWrite(2,LOW); //Turn off IR sensor to avoid interferance. for (int i=1; i<=3; i++) { temperature = (mlx.get_object_temp()) + error_correction; Serial.println(temperature,1); delay(150); } trigger = false; } else { delay(100); trigger = true; digitalWrite(13,LOW); Serial.println("position_error"); } } Video microcontroller-projects/arduino-max30205-human-body-temperature-measurement

Arduino Based Digital Thermometer using MAX30205 Human Body Temperature Sensor

which we designed earlier. project which combined with MAX30205 can be used to monitoring the temperature of individuals.

Required Components

Arduino NANO 7-Seg displays common cathode - 3pcs 74HC595 - 3 pcs 680R resistor - 24pcs MAX30205 module board 5V power supply Breadboard Lots of hook up wires Arduino IDE A micro-USB cable

MAX30205 with Arduino ᾠCircuit Diagram

is a great way to display your value big and bright with very low cost. But you can also display these values on an OLED or LCD if you wish so. , etc. to name a few. However, few module boards do not require additional pullup as the pull-up resistors are already given inside the module. Therefore, one needs to confirm whether the module board has internal pull-up resistors or it requires an external pull up additionally. The board that is used in this project already has the inbuilt pull-up resistors inside the module board.

Interfacing Arduino with MAX30205 Body Temperature Sensor

(37°C to 39°C). The sensor works with the I2C protocol. The module board can work with 5 or 3.3V. However, the board is configured to be used with 5V operating voltage. It also includes a logic level shifter, since the sensor itself supports a maximum of 3.3V as power or data communication-related purposes. On the output, three 74HC595, 8-bit shift registers are used to interface three 7-Segment displays with the Arduino NANO. The pin diagram can be shown in the below image- The pin description of the 74HC595 can be seen in the below table- The QA to QH are the data output pins that are connected with the 7-Seg displays. Since three 74HC595 are cascaded together, the Data input pin (PIN14) of the first shift register will be connected with the Arduino NANO and the Serial data output pin will provide the data to the next shift register. This serial data connection will be continued up to the third 74HC595.

Programming MAX30205 with Arduino

The complete program for this tutorial can be found at the bottom of this page. The explanation of this code is as follows. First, we include the standard Arduino I2C library header file. #include <Wire.h> The above line will include the Arduino contributed library from protocentral. This library has important functions to communicate with the MAX30205 sensor. The library is taken from the below GitHub link- After importing the library, we define MAX30205 object data as shown below- #include "Protocentral_MAX30205.h" MAX30205 tempSensor; Next two lines are important to set the parameters. The below line will provide temperature in Fahrenheit if set true. For showing the result in Celsius, the line needs to be set false. const bool fahrenheittemp = true; // I'm showing the temperature in Fahrenheit, If you want to show the temperature in Celsius the make this variable false. Below line needs to be configured if common cathode type 7-segment displays are being used in the hardware. Make it false if common anode is used. const bool commonCathode = true; // I'm using common Cathode 7segment if you use common Anode then change the value into false. const byte digit_pattern[17] = { // 74HC595 Outpin Connection with 7segment display. // Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 // a b c d e f g DP 0b11111100, // 0 0b01100000, // 1 0b11011010, // 2 0b11110010, // 3 0b01100110, // 4 0b10110110, // 5 0b10111110, // 6 0b11100000, // 7 0b11111110, // 8 0b11110110, // 9 0b11101110, // A 0b00111110, // b 0b00011010, // C 0b01111010, // d 0b10011110, // E 0b10001110, // F 0b00000001 // . }; The above array is used to store the digit pattern for the 7-Segment displays. In the setup function, after setting the pin modes of 74HC595 pins, the I2C protocol and temperature sensor reading is initialized. void setup() { // put your setup code here, to run once: // set the serial port at 9600 Serial.begin(9600); delay(1000); // set the 74HC595 Control pin as output pinMode(latchPin, OUTPUT); //ST_CP of 74HC595 pinMode(clkPin, OUTPUT); //SH_CP of 74HC595 pinMode(dtPin, OUTPUT); //DS of 74HC595 // initialize I2C Libs Wire.begin(); // start MAX30205 temperature read in continuos mode, active mode tempSensor.begin(); } After that, if Fahrenheit temperature mode is selected, the data is converted from Celsius to Fahrenheit. Then, three digits from the converted sensed temperature data are further separated into three individual digits. To do this, below lines of codes are used- // saperate 3 digits from the current temperature (like if temp = 31.23c, ) int dispDigit1=(int)temp/10; // digit1 3 int dispDigit2=(int)temp%10; // digit2 1 int dispDigit3=(temp*10)-((int)temp*10); //digit3 2 In the same way, remaining second and first digits are also sent to the respective 74HC595, thus remaining two 7-segment displays. After sending all the data, the latch pin is released and pulled high to confirm the end of data transmission.The respective codes can be seen below - // display digits into 3, 7segment display. digitalWrite(latchPin, LOW); if(commonCathode == true){ shiftOut(dtPin, clkPin, LSBFIRST, digit_pattern[dispDigit3]); shiftOut(dtPin, clkPin, LSBFIRST, digit_pattern[dispDigit2]|digit_pattern[16]); // 1. (Digit+DP) shiftOut(dtPin, clkPin, LSBFIRST, digit_pattern[dispDigit1]); }else{ shiftOut(dtPin, clkPin, LSBFIRST, ~(digit_pattern[dispDigit3])); shiftOut(dtPin, clkPin, LSBFIRST, ~(digit_pattern[dispDigit2]|digit_pattern[16])); // 1. (Digit+DP) shiftOut(dtPin, clkPin, LSBFIRST, ~(digit_pattern[dispDigit1])); } digitalWrite(latchPin, HIGH);

Arduino Body Temperature Meter ᾠTesting

The circuit is constructed in two sets of breadboards as you can see below. When we place the finger on the sensor, the temperature is sensed and the output is shown into a 7 segment display, here the value is 92.1*F. Code /* * This program Print temperature on 3, 7segment display * Hardware Connections (Breakoutboard to Arduino Nano): * Vin - 5V (3.3V is allowed) * GND - GND * MAX30205 SDA - A4 * MAX30205 SCL - A5 * 74HC595 ST_CP - D5 * 74HC595 SH_CP - D6 * 74HC595 DS - D7 * */ #include <Wire.h> #include "Protocentral_MAX30205.h" // Arduino Contributed Libs (https://github.com/protocentral/ProtoCentral_MAX30205) // define MAX30205 objectData MAX30205 tempSensor; // Show the temperature in Fahrenheit const bool fahrenheittemp = true; // I'm showing the temperature in Fahrenheit, If you want to show the temperature in Celsius then make this variable false. // set the 7segment type (common Cathode or Anode) const bool commonCathode = true; // I'm using common Cathode 7segment if you use common Anode then change the value into false. // alpha-digit pattern for a 7-segment display const byte digit_pattern[17] = { // 74HC595 Output Connection with 7segment display. // Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 // a b c d e f g DP 0b11111100, // 0 0b01100000, // 1 0b11011010, // 2 0b11110010, // 3 0b01100110, // 4 0b10110110, // 5 0b10111110, // 6 0b11100000, // 7 0b11111110, // 8 0b11110110, // 9 0b11101110, // A 0b00111110, // b 0b00011010, // C 0b01111010, // d 0b10011110, // E 0b10001110, // F 0b00000001 // . }; //Pin connected to ST_CP of 74HC595 int latchPin = 5; //Pin connected to SH_CP of 74HC595 int clkPin = 6; //Pin connected to DS of 74HC595 int dtPin = 7; void setup() { // put your setup code here, to run once: // set the serial port at 9600 Serial.begin(9600); delay(1000); // set the 74HC595 Control pin as output pinMode(latchPin, OUTPUT); //ST_CP of 74HC595 pinMode(clkPin, OUTPUT); //SH_CP of 74HC595 pinMode(dtPin, OUTPUT); //DS of 74HC595 // initialize I2C Libs Wire.begin(); // start MAX30205 temperature read in continuous mode, active mode tempSensor.begin(); } void loop() { float temp = tempSensor.getTemperature(); // read temperature for every 5ms if( fahrenheittemp == true){ temp = (temp * 1.8) + 32 ; // convert the temperature from Celcius to Farenhite using formula of [ T(°C) × 1.8 + 32 ] Serial.print(temp ,2); Serial.println("°f" ); }else{ Serial.print(temp ,2); Serial.println("°c" ); } // saperate 3 digits from the current temperature (like if temp = 31.23c, ) int dispDigit1=(int)temp/10; // digit1 3 int dispDigit2=(int)temp%10; // digit2 1 int dispDigit3=(temp*10)-((int)temp*10); //digit3 2 /* Serial.print(temp); Serial.print(" "); Serial.print(dispDigit1); Serial.print(" "); Serial.print(dispDigit2); Serial.print(" "); Serial.println(dispDigit3); */ // display digits into 3, 7segment display. digitalWrite(latchPin, LOW); if(commonCathode == true){ shiftOut(dtPin, clkPin, LSBFIRST, digit_pattern[dispDigit3]); shiftOut(dtPin, clkPin, LSBFIRST, digit_pattern[dispDigit2]|digit_pattern[16]); // 1. (Digit+DP) shiftOut(dtPin, clkPin, LSBFIRST, digit_pattern[dispDigit1]); }else{ shiftOut(dtPin, clkPin, LSBFIRST, ~(digit_pattern[dispDigit3])); shiftOut(dtPin, clkPin, LSBFIRST, ~(digit_pattern[dispDigit2]|digit_pattern[16])); // 1. (Digit+DP) shiftOut(dtPin, clkPin, LSBFIRST, ~(digit_pattern[dispDigit1])); } digitalWrite(latchPin, HIGH); delay(500); } Video microcontroller-projects/ir-remote-decoder-using-arduino

IR Remote Decoder using Arduino

IR (Infrared) communication is simple, low-cost, and widely used wireless communication technology. IR light is somewhat similar to the visible light, except that the wavelength is slightly longer. This property of IR makes it undetectable to the human eye and perfect for wireless communication. The hex code for every button will be logged to Microsoft Excel Sheet. This simple IR Remote Control Decoder can be used in projects like IR Remote control Robot, Home automation, and other IR controlled projects. to build many useful applications like: IR Remote Controlled TRIAC Dimmer Circuit IR Remote Controlled Home Automation using Arduino IR Remote Controlled Home Automation using PIC Microcontroller Cell Phone Controlled AC using Arduino and Bluetooth

Components Required

Arduino Uno / Arduino Nano IR Receiver (TSOP1838) Jumper Wires Breadboard

How does IR Communication Works?

, follow the link. When a remote button is pressed, the IR LED (Transmitter) emits infrared light. This light is received by the Receiver that is typically a photodiode or phototransistor. But the IR light is also emitted by the sun, light bulbs, and anything else that produces heat. This can interfere the transmitter signal, so to prevent, the transmitter signal is modulated using a carrier frequency between 36 kHz to 46 kHz. Upon receiving the signal, the IR receiver demodulates the signal and converts it to binary before sending it to the microcontroller. for receiving them.

Circuit Diagram

is given below: The connections are very simple as the IR Receiver sensor only has three pins, Vs, GND, and Data. Connect Vs and GND pin of IR Receiver to 3.3V GND pin of Arduino and Data pin to Digital pin 2 of Arduino.

Programming for Arduino IR Remote Decoder

is given at the end of the page. Select the library file and click on ‘Openᾮ Start your code by including the IR Remote library file. #include <IRremote.h> After that define the Arduino pin where you connected the Data pin of IR Receiver. In my case, it is connected to the D2 pin of Arduino. int IRPIN = 2; After that create an instance for IR Receiver pin. IRrecv irrecv(IRPIN); class, it will be used by the IR receiver to send the decoded information. decode_results result; void setup() { Serial.begin(9600); Serial.println("Enabling IRin"); irrecv.enableIRIn(); Serial.println("Enabled IRin"); Initialize_streamer(); } function. void loop() { if (irrecv.decode(&result)) { Serial.print("Value: "); Serial.println(result.value, HEX); Write_streamer(); irrecv.resume(); } delay(500); } function, we are sending the data serially in a specific pattern just like displaying the value on serial monitor. The key lines are explained below: void Write_streamer() { Serial.print("DATA"); //always write "DATA" to Indicate the following as Data Serial.print(","); //Move to next column using a "," Serial.print(result.value, HEX); //Store date on Excel Serial.print(","); //Move to next column using a "," Serial.println(); //End of Row move to next row } Once the hardware and the program are ready, it is time to upload the program into your Arduino Nano Board. After uploading the code, point the remote towards the IR receiver and press the remote buttons. The hex code for every button will be printed on the serial monitor.

Saving the IR Remote Decoder Data into Excel Sheet

on your desktop. file from the desktop folder. If macros are disabled on your Excel, then you will see a security block as shown in the below image: to Enable the Macros. After this, you will get the following screen: Now select the baud rate as Ᾱ600ᾠand the port to which your Arduino is connected and then click on Connect to start the data streaming. Your values should start to get logged like shown in the picture below. can be built easily to convert the IR remote signals into equivalent HEX code. Complete Arduino code with a demo video is given below. Code #include <IRremote.h> int IRPIN = 2; IRrecv irrecv(IRPIN); decode_results result; int button = 0; void setup() { Serial.begin(9600); Serial.println("Enabling IRin"); irrecv.enableIRIn(); Serial.println("Enabled IRin"); Initialize_streamer(); } void loop() { if (irrecv.decode(&result)) { button = button+1; Serial.print("Value: "); Serial.println(result.value, HEX); Write_streamer(); irrecv.resume(); } delay(500); } void Initialize_streamer() { Serial.println("CLEARDATA"); //clears up any data left from previous projects Serial.println("LABEL,Hex Code, Button"); //always write LABEL, to indicate it as first line } void Write_streamer() { Serial.print("DATA"); //always write "DATA" to Indicate the following as Data Serial.print(","); //Move to next column using a "," Serial.print(result.value, HEX); //Store date on Excel Serial.print(","); //Move to next column using a "," Serial.print(button); //Store date on Excel Serial.print(","); //Move to next column using a "," Serial.println(); //End of Row move to next row } Video microcontroller-projects/arduino-speech-recognition

Speech Recognition using Arduino

Speech recognition technology is very useful in automation which not only gives you hands free control over devices but also adds security to the system. Apart from making voice controlled gadgets, speech recognition also provides significant help to people suffering from various disabilities.

Components Required

Arduino 33 BLE Sense LED Jumper Wires Edge Impulse Studio Arduino IDE

Circuit Diagram

is given below. Fritzing part for Arduino 33 BLE was not available, so I used Arduino Nano as both have the same pinout. The Positive lead of LED is connected to digital pin 5 of Arduino 33 BLE sense and Negative lead is connected to the GND pin of Arduino.

Creating the Dataset for Arduino Speech Recognition

Here Edge Impulse Studio is used to train our Speech Recognition model. Training a model on Edge Impulse Studio is similar to training machine learning models on other machine learning frameworks. For training, a machine learning model's first step is to collect a dataset that has the samples of data that we would like to be able to recognize. As our goal is to control an LED with our voice command, we will need to collect voice samples for all the commands and noise so that it can distinguish between voice commands and other Noises. account, verify your account and then start a new project. You can load the samples by using your mobile, your Arduino board or you can import a dataset into your edge impulse account. The easiest way to load the samples into your account is by using your mobile phone. For that connect the mobile with Edge Impulse. , and a QR code will appear. Scan the QR code with your Mobile Phone or enter the URL given on QR code. This will connect your phone with Edge Impulse studio. , your device will capture a 2 Sec sample. Record a total of 10 to 12 voice samples in different conditions. class. These samples are for Training the module, in the next steps, we will collect the Test Data. Test data should be at least 30% of training data, so collect the 4 samples of ‘noiseᾠand 4 to 5 samples for ‘light onᾠand ‘light offᾮ

Training the Model

ᾠpage. Change the default settings of a 1000 ms Window size to 1200ms and 500 ms Window increase to 50ms. This means our data will be processed 1.2 s at a time, starting each 58ms. In the next step go to the MFCC page and then click on ‘Generate Featuresᾮ It will generate MFCC blocks for all of our windows of audio. button. It will start training your model. import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, InputLayer, Dropout, Flatten, Reshape, BatchNormalization, Conv2D, MaxPooling2D, AveragePooling2D from tensorflow.keras.optimizers import Adam from tensorflow.keras.constraints import MaxNorm # model architecture model = Sequential() model.add(InputLayer(input_shape=(X_train.shape[1], ), name='x_input')) model.add(Reshape((int(X_train.shape[1] / 13), 13, 1), input_shape=(X_train.shape[1], ))) model.add(Conv2D(10, kernel_size=5, activation='relu', padding='same', kernel_constraint=MaxNorm(3))) model.add(AveragePooling2D(pool_size=2, padding='same')) model.add(Conv2D(5, kernel_size=5, activation='relu', padding='same', kernel_constraint=MaxNorm(3))) model.add(AveragePooling2D(pool_size=2, padding='same')) model.add(Flatten()) model.add(Dense(classes, activation='softmax', name='y_pred', kernel_constraint=MaxNorm(3))) # this controls the learning rate opt = Adam(lr=0.005, beta_1=0.9, beta_2=0.999) # train the neural network model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy']) model.fit(X_train, Y_train, batch_size=32, epochs=9, validation_data=(X_test, Y_test), verbose=2) and loss was 0.45 that is not ideal performance but we can proceed with it. You can increase your model's performance by creating a vast dataset. page. The Live classification feature allows you to test the model both with the existing testing data that came with the dataset or by streaming audio data from your mobile phone. on your phone. ᾠto start the process. This will build an Arduino library for your project.

Arduino Code for Arduino Voice Recognition

Here some changes have been made to control LED with the voice commands. where it is printing the probability of commands. In the original code, it is printing all the labels and their values together. for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { ei_printf(" %s: %.5f\n", result.classification[ix].label, result.classification[ix].value); } command is more than 0.50 than it will turn off the LED. for (size_t ix = 2; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { noise = result.classification[ix].value; Serial.println("Noise: "); Serial.println(noise); } for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix--) { lightoff = result.classification[ix].value; Serial.println("Light Off: "); Serial.print(lightoff); } lighton = 1- (noise +lightoff); Serial.println("Light ON: "); Serial.print(lighton); if (lighton > 0.50){ digitalWrite(led, HIGH); } if (lightoff > 0.50){ digitalWrite(led, LOW); } After making the changes, upload the code into your Arduino. Open the serial monitor at 115200 baud. and give commands to operate the devices. A complete working video with a library and code is given below. Code #define EIDSP_QUANTIZE_FILTERBANK 0 /* Includes ---------------------------------------------------------------- */ #include <PDM.h> #include <arduino_ac3121_inference.h> /** Audio buffers, pointers and selectors */ typedef struct { int16_t *buffer; uint8_t buf_ready; uint32_t buf_count; uint32_t n_samples; } inference_t; static inference_t inference; static bool record_ready = false; static signed short sampleBuffer[2048]; static bool debug_nn = false; // Set this to true to see e.g. features generated from the raw signal float lighton, lightoff, noise; #define led 5 void setup() { // put your setup code here, to run once: Serial.begin(115200); Serial.println("Edge Impulse Inferencing Demo"); pinMode( led, OUTPUT ); // summary of inferencing settings (from model_metadata.h) ei_printf("Inferencing settings:\n"); ei_printf("\tInterval: %.2f ms.\n", (float)EI_CLASSIFIER_INTERVAL_MS); ei_printf("\tFrame size: %d\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE); ei_printf("\tSample length: %d ms.\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT / 16); ei_printf("\tNo. of classes: %d\n", sizeof(ei_classifier_inferencing_categories) / sizeof(ei_classifier_inferencing_categories[0])); if (microphone_inference_start(EI_CLASSIFIER_RAW_SAMPLE_COUNT) == false) { ei_printf("ERR: Failed to setup audio sampling\r\n"); return; } } /** * @brief Arduino main function. Runs the inferencing loop. */ void loop() { ei_printf("Starting inferencing in 2 seconds...\n"); delay(2000); ei_printf("Recording...\n"); bool m = microphone_inference_record(); if (!m) { ei_printf("ERR: Failed to record audio...\n"); return; } ei_printf("Recording done\n"); signal_t signal; signal.total_length = EI_CLASSIFIER_RAW_SAMPLE_COUNT; signal.get_data = &microphone_audio_signal_get_data; ei_impulse_result_t result = { 0 }; EI_IMPULSE_ERROR r = run_classifier(&signal, &result, debug_nn); if (r != EI_IMPULSE_OK) { ei_printf("ERR: Failed to run classifier (%d)\n", r); return; } // print the predictions ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n", result.timing.dsp, result.timing.classification, result.timing.anomaly); // for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { // ei_printf(" %s: %.5f\n", result.classification[ix].label, result.classification[ix].value); // } for (size_t ix = 2; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { noise = result.classification[ix].value; Serial.println("Noise: "); Serial.println(noise); } for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix--) { lightoff = result.classification[ix].value; Serial.println("Light Off: "); Serial.print(lightoff); } lighton = 1- (noise +lightoff); Serial.println("Light ON: "); Serial.print(lighton); if (lighton > 0.60){ digitalWrite(led, HIGH); } if (lightoff > 0.29){ digitalWrite(led, LOW); } #if EI_CLASSIFIER_HAS_ANOMALY == 1 ei_printf(" anomaly score: %.3f\n", result.anomaly); #endif } /** * @brief Printf function uses vsnprintf and output using Arduino Serial * * @param[in] format Variable argument list */ void ei_printf(const char *format, ...) { static char print_buf[1024] = { 0 }; va_list args; va_start(args, format); int r = vsnprintf(print_buf, sizeof(print_buf), format, args); va_end(args); if (r > 0) { Serial.write(print_buf); } } /** * @brief PDM buffer full callback * Get data and call audio thread callback */ static void pdm_data_ready_inference_callback(void) { int bytesAvailable = PDM.available(); // read into the sample buffer int bytesRead = PDM.read((char *)&sampleBuffer[0], bytesAvailable); if (record_ready == true || inference.buf_ready == 1) { for(int i = 0; i < bytesRead>>1; i++) { inference.buffer[inference.buf_count++] = sampleBuffer[i]; if(inference.buf_count >= inference.n_samples) { inference.buf_count = 0; inference.buf_ready = 1; } } } } /** * @brief Init inferencing struct and setup/start PDM * * @param[in] n_samples The n samples * * @return { description_of_the_return_value } */ static bool microphone_inference_start(uint32_t n_samples) { inference.buffer = (int16_t *)malloc(n_samples * sizeof(int16_t)); if(inference.buffer == NULL) { return false; } inference.buf_count = 0; inference.n_samples = n_samples; inference.buf_ready = 0; // configure the data receive callback PDM.onReceive(&pdm_data_ready_inference_callback); // optionally set the gain, defaults to 20 PDM.setGain(80); //ei_printf("Sector size: %d nblocks: %d\r\n", ei_nano_fs_get_block_size(), n_sample_blocks); PDM.setBufferSize(4096); // initialize PDM with: // - one channel (mono mode) // - a 16 kHz sample rate if (!PDM.begin(1, EI_CLASSIFIER_FREQUENCY)) { ei_printf("Failed to start PDM!"); } record_ready = true; return true; } /** * @brief Wait on new data * * @return True when finished */ static bool microphone_inference_record(void) { inference.buf_ready = 0; inference.buf_count = 0; while(inference.buf_ready == 0) { delay(10); } return true; } /** * Get raw audio signal data */ static int microphone_audio_signal_get_data(size_t offset, size_t length, float *out_ptr) { arm_q15_to_float(&inference.buffer[offset], out_ptr, length); return 0; } /** * @brief Stop PDM and release buffers */ static void microphone_inference_end(void) { PDM.end(); free(inference.buffer); } #if !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_MICROPHONE #error "Invalid model for current sensor." #endif Video microcontroller-projects/cough-detection-using-arduino-33-ble-sense-and-edge-impulse

Cough Detection System using Arduino 33 BLE Sense and Edge Impulse

techniques for that. It can differentiate between normal background noise and coughing in real-time audio. We used Edge Impulse Studio to train a dataset of coughing and background noise samples and build a highly optimized TInyML model, that can detect a Cough sound in real-time.

Components Required

Arduino 33 BLE Sense LED Jumper Wires Edge Impulse Studio Arduino IDE

Circuit Diagram

Sense is given below. Fritzing part for Arduino 33 BLE was not available, so I used Arduino Nano as both have the same pin-out. The Positive lead of LED is connected to digital pin 4 of Arduino 33 BLE sense and Negative lead is connected to the GND pin of Arduino.

Creating the Dataset for Cough Detection Machine

As mentioned earlier, we are using Edge Impulse Studio to train our cough detection model. For that, we have to collect a dataset that has the samples of data that we would like to be able to recognize on our Arduino. Since the goal is to detect the cough, you'll need to collect some samples of that and some other samples for noise, so it can distinguish between Cough and other Noises. account, verify your account and then start a new project. You can load the samples by using your mobile, your Arduino board or you can import a dataset into your edge impulse account. The easiest way to load the samples into your account is by using your mobile phone. For that, you have to connect your mobile with Edge Impulse. , and a QR code will appear. Scan the QR code with your Mobile Phone using Google Lens or other QR code scanner app. This will connect your phone with Edge Impulse studio. , to start sampling a 40 Sec sample. Instead of forcing yourself to cough, you can use online cough samples of different lengths. Record a total of 10 to 12 cough samples of different lengths. After uploading the cough samples, now set the label to ‘noiseᾠand collect another 10 to 12 noise samples. These samples are for Training the module, in the next steps, we will collect the Test Data. Test data should be at least 30% of training data, so collect the 3 samples of ‘noiseᾠand 4 to 5 samples of ‘coughᾮ Instead of collecting your data, you can import our dataset into your Edge Impulse account using the Edge Impulse CLI Uploader. on your laptop. After that open the command prompt and enter the below command: npm install -g edge-impulse-cli Now download the dataset (Dataset Link) and extract the file in your project folder. Open the command prompt and navigate to dataset location and run the below commands: edge-impulse-uploader --clean edge-impulse-uploader --category training training/*.json edge-impulse-uploader --category training training/*.cbor edge-impulse-uploader --category testing testing/*.json edge-impulse-uploader --category testing testing/*.cbor

Training the Model and Tweaking the Code

ᾠpage. It will generate MFCC blocks for all of our windows of audio. button. It will start training your model. import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, InputLayer, Dropout, Flatten, Reshape, BatchNormalization, Conv2D, MaxPooling2D, AveragePooling2D from tensorflow.keras.optimizers import Adam from tensorflow.keras.constraints import MaxNorm # model architecture model = Sequential() model.add(InputLayer(input_shape=(X_train.shape[1], ), name='x_input')) model.add(Reshape((int(X_train.shape[1] / 13), 13, 1), input_shape=(X_train.shape[1], ))) model.add(Conv2D(10, kernel_size=5, activation='relu', padding='same', kernel_constraint=MaxNorm(3))) model.add(AveragePooling2D(pool_size=2, padding='same')) model.add(Conv2D(5, kernel_size=5, activation='relu', padding='same', kernel_constraint=MaxNorm(3))) model.add(AveragePooling2D(pool_size=2, padding='same')) model.add(Flatten()) model.add(Dense(classes, activation='softmax', name='y_pred', kernel_constraint=MaxNorm(3))) # this controls the learning rate opt = Adam(lr=0.005, beta_1=0.9, beta_2=0.999) # train the neural network model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy']) model.fit(X_train, Y_train, batch_size=32, epochs=9, validation_data=(X_test, Y_test), verbose=2) After training the model, it will show the training performance. For me, the accuracy was 96.5% and loss was 0.10 that is good to proceed. page. to start the process. This will build an Arduino library for your project. We will make some changes in the code so that we can make an alert sound when the Arduino detects cough. For that, a buzzer is interfaced with Arduino and whenever it detects cough, LED will blink three times. functions where it is printing the noise and cough values. In the original code, it is printing both the labels and their values together. for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { ei_printf(" %s: %.5f\n", result.classification[ix].label, result.classification[ix].value); } code with this: for (size_t ix = 1; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { Serial.print( result.classification[ix].value); float Data = result.classification[ix].value; if (Data < 0.50){ Serial.print("Cough Detected"); alarm(); } } After making the changes, upload the code into your Arduino. Open the serial monitor at 115200 baud. can be built, it's not a very effective method to find any COVID19 suspect but it can work nicely in some crowded area. A complete working video with library and code is given below: Code #define EIDSP_QUANTIZE_FILTERBANK 0 #include <PDM.h> #include <ashish3121-project-1_inference.h> #define led 5 /** Audio buffers, pointers and selectors */ typedef struct { int16_t *buffer; uint8_t buf_ready; uint32_t buf_count; uint32_t n_samples; } inference_t; static inference_t inference; static bool record_ready = false; static signed short sampleBuffer[2048]; static bool debug_nn = false; // Set this to true to see e.g. features generated from the raw signal void setup() { // put your setup code here, to run once: Serial.begin(115200); pinMode(led, OUTPUT); Serial.println("Edge Impulse Inferencing Demo"); // summary of inferencing settings (from model_metadata.h) ei_printf("Inferencing settings:\n"); ei_printf("\tInterval: %.2f ms.\n", (float)EI_CLASSIFIER_INTERVAL_MS); ei_printf("\tFrame size: %d\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE); ei_printf("\tSample length: %d ms.\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT / 16); ei_printf("\tNo. of classes: %d\n", sizeof(ei_classifier_inferencing_categories) / sizeof(ei_classifier_inferencing_categories[0])); if (microphone_inference_start(EI_CLASSIFIER_RAW_SAMPLE_COUNT) == false) { ei_printf("ERR: Failed to setup audio sampling\r\n"); return; } } void loop() { ei_printf("Starting inferencing in 2 seconds...\n"); delay(2000); ei_printf("Recording...\n"); bool m = microphone_inference_record(); if (!m) { ei_printf("ERR: Failed to record audio...\n"); return; } ei_printf("Recording done\n"); signal_t signal; signal.total_length = EI_CLASSIFIER_RAW_SAMPLE_COUNT; signal.get_data = &microphone_audio_signal_get_data; ei_impulse_result_t result = { 0 }; EI_IMPULSE_ERROR r = run_classifier(&signal, &result, debug_nn); if (r != EI_IMPULSE_OK) { ei_printf("ERR: Failed to run classifier (%d)\n", r); return; } // print the predictions ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n", result.timing.dsp, result.timing.classification, result.timing.anomaly); for (size_t ix = 1; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { Serial.print( result.classification[ix].value); float Data = result.classification[ix].value; if (Data < 0.50){ Serial.print("Cough Detected"); alarm(); } } //for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) { // ei_printf(" %s: %.5f\n", result.classification[ix].label, result.classification[ix].value); // } #if EI_CLASSIFIER_HAS_ANOMALY == 1 ei_printf(" anomaly score: %.3f\n", result.anomaly); #endif } void ei_printf(const char *format, ...) { static char print_buf[1024] = { 0 }; va_list args; va_start(args, format); int r = vsnprintf(print_buf, sizeof(print_buf), format, args); va_end(args); if (r > 0) { Serial.write(print_buf); } } static void pdm_data_ready_inference_callback(void) { int bytesAvailable = PDM.available(); // read into the sample buffer int bytesRead = PDM.read((char *)&sampleBuffer[0], bytesAvailable); if (record_ready == true || inference.buf_ready == 1) { for(int i = 0; i < bytesRead>>1; i++) { inference.buffer[inference.buf_count++] = sampleBuffer[i]; if(inference.buf_count >= inference.n_samples) { inference.buf_count = 0; inference.buf_ready = 1; } } } } static bool microphone_inference_start(uint32_t n_samples) { inference.buffer = (int16_t *)malloc(n_samples * sizeof(int16_t)); if(inference.buffer == NULL) { return false; } inference.buf_count = 0; inference.n_samples = n_samples; inference.buf_ready = 0; // configure the data receive callback PDM.onReceive(&pdm_data_ready_inference_callback); // optionally set the gain, defaults to 20 PDM.setGain(80); //ei_printf("Sector size: %d nblocks: %d\r\n", ei_nano_fs_get_block_size(), n_sample_blocks); PDM.setBufferSize(4096); // initialize PDM with: // - one channel (mono mode) // - a 16 kHz sample rate if (!PDM.begin(1, EI_CLASSIFIER_FREQUENCY)) { ei_printf("Failed to start PDM!"); } record_ready = true; return true; } static bool microphone_inference_record(void) { inference.buf_ready = 0; inference.buf_count = 0; while(inference.buf_ready == 0) { delay(10); } return true; } static int microphone_audio_signal_get_data(size_t offset, size_t length, float *out_ptr) { arm_q15_to_float(&inference.buffer[offset], out_ptr, length); return 0; } static void microphone_inference_end(void) { PDM.end(); free(inference.buffer); } #if !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_MICROPHONE #error "Invalid model for current sensor." #endif void alarm(){ for (size_t t = 0; t < 4; t++) { digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); delay(1000); // digitalWrite(led, HIGH); // delay(1000); // digitalWrite(led, LOW); } } Video microcontroller-projects/arduino-ultrasonic-acoustic-levitation-using-hc-sr04-ultrasonic-sensors

Simple Ultrasonic Acoustic Levitation using Arduino and HCSR04 Ultrasonic Sensor

, which works very similar to this, and these grippers can be useful in moving objects without touching them.

Component Required

Arduino Uno / Arduino Nano ATMEGA328P Ultrasonic Module HC-SR04 IC or L239d H-Bridge Module L239D Vero Board Dotted Vero Diode 4007 Capacitor (PF) 104 Additional Requirement for 8v To 12v Power Supply Voltage Regulator LM 7809 Led Driver Power Supply 12V 2Amp Some hookup wire, male header, female to female jumper wire

Ultrasonic Levitation Circuit Diagram

, in which the HCSR04 is primarily used to measure distance.In this project, we have soldered out the transducer out from the module. We placed two transducers face to face in the opposite direction in such a manner that some space is left between them. Acoustic sound waves travel between two transducers and allow the object to float. ) applied to output component driving voltage and this VCC pin can accept up to 36v. This IC has 2 Enable pins, 4 input-output pins, 4 ground pins.The concept of using this IC comes from the concept of using a microcontroller and this chip where we can change the direction and speed of 2 motors individually by just providing a logical or digital signal from the microcontroller. pin of L139D with common grounds. According to the Arduino, Cc, and Arduino forum, Arduino UNO board support 7 to 12 volts of input, but it's safer to put 9V Max.

Programming Arduino for Ultrasonic Levitation

The coding is very simple, just of few lines. Using this little code with the help of a timer and interrupt functions, we are making high or low (0 / 1) and generating an oscillating signal of 40Khz to Arduino A0 and A1 output pins. First, start with a phase shift array. byte TP = 0b10101010; And every second port receives this opposite signal. After that under the void setup, we define all the analog ports as an output using this line of code. DDRC = 0b11111111; Then we initialize the timer 1 and disable all the interrupt to set as zero. By this code, noInterrupts(); TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; Then, timer one is configured to trigger a compare interrupt clock at 80KHZ. Arduino runs at 16000000 MHZ ÷200 = 80,000 kHz square waves are generated using this function. OCR1A = 200;TCCR1B |= (1 << WGM12); TCCR1B |= (1 << CS10); After that, this line activates, compare timer interrupt. TIMSK1 |= (1 << OCIE1A); And finally, activate interrupt using this piece of code. interrupts(); Each interrupt reverses the state of the analog ports, this turns 80 kHz square wave signal into a full-wave cycling signal at 40Khz. And then we send the value to Arduino output A0 and A1 port. ISR(TIMER1_COMPA_vect) { PORTC = TP; TP = ~TP; // Invert TP for the next run } And there is nothing to put or needed to run under the loops.

Building the Ultrasonic Levitation Setup

Please note that for this project, correctly mounting ultrasonic transducers is important. They should face each other in the opposite direction which is very important and they should be in the same line so that ultrasonic sound waves can travel and intersect each other in opposite directions. For this, you can take two small pieces of wood or MD board, nut bolt, and glue. You may make two holes to fit the transducer perfectly by the drill machine. On the stand, you can hang the ultrasonic transducer arrangement. In this case, I used two pieces of cardboard and then fixed ultrasonic Transducer with the help of glue from the glue gun. Later, for making the stand, I used a simple wiring casing box and fixed everything with glue. Here are some pictures of ultrasonic levitation that show the working of the project. The ultrasonic levitation or acoustic levitation also works if one side is mounted with the ultrasonic transducer but a reflector will be needed in that case which will act as an obstacle so that it can be used in hoverboard in future and anti-gravity transportation. You can also check out the complete working video below. for other technical questions. Code byte TP = 0b10101010; //every 2nd port receives the opposite signal void setup() { DDRC = 0b11111111; //Define all analog ports as outputs // Initialize timer 1 noInterrupts(); // Disable interrupts TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; OCR1A = 200; // Set Compare Match Register (16MHz / 200 = 80kHz square -> 40kHz full wave) TCCR1B |= (1 << WGM12); // CTC mode TCCR1B |= (1 << CS10); TIMSK1 |= (1 << OCIE1A); // Switch on Compare Timer Interrupt interrupts(); // Activate interrupts } ISR(TIMER1_COMPA_vect) { PORTC = TP; // Send the value TP to the outputs TP = ~TP; // Invert TP for the next run } void loop(){ // there is nothing left to do here:-( } Video microcontroller-projects/arduino-based-women-safety-device-for-emergency-alert-and-tracking

Women Safety Device with GPS Tracking and Alerts Using Arduino

for wireless communication between the Band and Receiving device with GPS/GSM.

Materials Used

Arduino Nano SIM900 Modem NEO6M GPS module 433 MHZ RF Transmitter and Receiver Button Battery Breadboard Jumpers

GPS Module

Here we are using the NEO6M GPS module. The NEO-6M GPS module is a popular GPS receiver with a built-in ceramic antenna, which provides a strong satellite search capability. This receiver has the ability to sense locations and track up to 22 satellites and identifies locations anywhere in the world. With the on-board signal indicator, we can monitor the network status of the module. It has a data backup battery so that the module can save the data when the main power is shut down accidentally. The core heart inside the GPS receiver module is the NEO-6M GPS chip from u-blox. It can track up to 22 satellites on 50 channels and have a very impressive sensitivity level which is -161 dBm. This 50-channel u-blox 6 positioning engine boasts a Time-To-First-Fix (TTFF) of under 1 second. This module supports the baud rate from 4800-230400 bps and has the default baud of 9600. Operating voltage: (2.7-3.6)V DC Operating Current: 67 mA Baud rate: 4800-230400 bps (9600 Default) Communication Protocol: NEMA Interface: UART External antenna and built-in EEPROM. VCC: Input voltage pin of Module GND: Ground pin RX, TX: UART communication pins with Microcontroller

GSM Module SIM900

This is a GSM/GPRS-compatibleQuad-band cell phone, which works on a frequency of 850/900/1800/1900MHz and which can be used for various applications such as access the Internet, make a voice call, send and receive SMS, etc. The frequency bands of the GSM modem can be set by AT Commands. The baud rate is configurable from 1200-115200 through AT command. The GSM/GPRSModem is having an internal TCP/IP stack which enables us to connect with the internet viaGPRS. This is anSMTtype module and designed with a very powerful single-chip processor integrating AMR926EJ-S core, which is very popular in various industrial products. Supply voltage: 3.4V ᾠ4.5V Power saving mode: Sleep Mode power consumption=.5mA Frequency bands: SIM900A Dual-band: EGSM900, DCS1800. Operating Temperature: -30oC to +80oC Supports MIC and Audio Input Speaker Input UART interface support Firmware upgrade by debug port Communication: AT Commands

Connection Diagram

can be subdivided into two sections such as Transmitter and Receiver section. The circuit diagrams for each section is described as follows: In the RF Transmitter part, there will be an SOS button along with a 433 MHz RF transmitter, which will transmit the data to the receiver part wirelessly. The purpose of making two individual parts here is, to minimize the size of the transmitting module so that it can be worn as a wrist band. The circuit diagram for the transmitter part is shown below: In the RF Receiver section, the data transmitted from the wrist band (Transmitter part) is received by the device having a 433 MHz RF receiver. The RF receiver sends this information to Arduino through the digital pin. Arduino Nano then receives the signal and processes it using the program which is flashed into it. When the victim presses the SOS button in the transmitter part, a HIGH signal is generated and passes to the Arduino side, and then Arduino sends a signal to SIM900 modem, to send an SMS to Registered user along with the GPS coordinate which has already been stored in the Microcontroller by the help of NEO6M GPS module. The circuit diagram of the Receiver side is shown as below:

Programming of Arduino

After successful completion of the Hardware connections, now it’s time for programming the Arduino Nano. The stepwise explanation of the code is given below. for defining the Software serial pins. #include <TinyGPS++.h> #include <SoftwareSerial.h> Now, declare the connection pins of the GPS module and its default baud rate, which is 9600 in our case. Also, define the software serial pins using which GPS will communicate with Arduino. static const int RXPin = 2, TXPin = 3; static const uint32_t gps_baudrate = 9600; class with the pins as arguments declared earlier. TinyGPSPlus gps; SoftwareSerial soft(RXPin, TXPin); declare all the input pins and output pins. Then, initialize the hardware serial and Software serial functionality, providing the default baud rate which is 9600 in our case. void setup() { pinMode(12,INPUT); // Input from RF module pinMode(4, OUTPUT); // Output for Buzzer Serial.begin(19200); soft.begin(gps_baudrate); } for sending the SMS regarding Location data. void loop() { int key = digitalRead(12); if(key==1) { digitalWrite(4,HIGH); // Switch ON the Buzzer sendsms(); digitalWrite(4,LOW); // Switch OFF the Buzzer } else; For receiving the GPS coordinates, the code is written which continuously checks for a serial terminal for incoming data from the GPS module. When valid data is found having GPS coordinates, this is stored in two separate variables as Latitude and Longitude. while (soft.available() > 0) { gps.encode(soft.read()); if (gps.location.isUpdated()) { Lat = gps.location.lat(); Lon = gps.location.lng(); } else; } } command. Then the recipient’s number is defined using the format shown. You can replace this with your mobile number. Then the message with location variables appended within is sent via the serial terminal. void sendsms() { Serial.print("AT+CMGF=1\r"); delay(100); Serial.println("AT+CMGS =\"+9194XXXXXXX\”ᾩ; delay(100); Serial.println(“I want Help !!!Location:ᾠ+ String(“Lat: ᾩ +String(Lat) + ᾠᾫString(“Lon: ᾩ + String(Lon)); delay(100); Serial.println((char)26); delay(100); Serial.println(); delay(5000); }

Women Safety Device with GPS Tracking & Alerts Using Arduino

When the SOS button is pressed, the Buzzer starts beeping and an SMS will come to the authorized number containing the latitude and longitude of the location of the victim. The screenshot of the output is shown below: Complete Arduino code and demo video are given below. Code #include <LiquidCrystal.h> #include <TinyGPS++.h> #include <SoftwareSerial.h> static const int RXPin = 2, TXPin = 3; static const uint32_t gps_baudrate = 9600; TinyGPSPlus gps; SoftwareSerial soft(RXPin, TXPin); String textMessage; float Lat, Lon; void setup() { soft.begin(gps_baudrate); Serial.begin(19200); pinMode(12,INPUT); pinMode(4, OUTPUT); } void loop() { int key = digitalRead(12); while (soft.available() > 0) { gps.encode(soft.read()); if (gps.location.isUpdated()) { Lat = gps.location.lat(); Lon = gps.location.lng(); } else; } if(key==1) { digitalWrite(4,HIGH); sendsms(); digitalWrite(4,LOW); } } void sendsms() { Serial.print("AT+CMGF=1\r"); delay(100); Serial.println("AT+CMGS =\"+9194XXXXXX\""); delay(100); Serial.println("I want Help !!!Location:" + String("Lat: ") +String(Lat) + " "+String("Lon: ") + String(Lon)); delay(100); Serial.println((char)26); delay(100); Serial.println(); delay(5000); } Video microcontroller-projects/rfid-based-contactless-body-screening-using-mlx90614-infrared-termperature-sensor-and-arduino

RFID based Contactless Body Temperature Screening using Arduino and MLX90614 IR Temperature Sensor

are being used as a screening tool to scan the people at Airports, Railway Stations, and other crowded establishments. These scans are being used to identify potential patients of Covid-19. The government made it compulsory to scan everyone before entering the office, school, or any other crowded place. , which also records the body temperature of every person.

Components Required

Arduino Nano EM-18 RFID Module MLX90614 Contactless Temperature Sensor Ultrasonic Sensor Breadboard Jumper Wires

EM18 RFID Reader Module

One of the widely used RFID readers for reading 125 kHz tags is the EM-18 RFID Reader. This low-cost RFID Reader module features low power consumption, low form factor, and easy to use. EM-18 Reader Module can provide output through two communication interfaces i.e. RS232 and WEIGAND26. EM18 RFID Reader features a transceiver that transmits a radio signal. When the RFID tag comes in the transmitter signal range, this signal hits the transponder that is inside the card. The tag draws power from the reader module-generated electromagnet field. The transponder then transforms the radio signal into the usable form of power. Upon getting power, the transponder transfers all the information, such as a specific ID, in the form of an RF signal to the RFID Module. Then this data sent to the microcontroller using UART communication.

MLX90614 Infrared Thermometer

extensively for many applications where atmospheric humidity or temperature has to be measured. , follow the link.

Circuit Diagram

Circuit Diagram for RFID based non-contact temperature sensor using Arduino is given below: As shown in the circuit diagram, the connections are very simple since we have used them as modules, we can directly build them on a breadboard. The LED connected to the BUZ pin of the EM18 Reader module turns high when someone scans the tag. The RFID module sends data to the controller in serial; hence the transmitter pin of the RFID module is connected to the Receiver pin of Arduino. The connections are further classified in the table below:
5VVcc
GNDGND
5VSEL
RxTx
5VVcc
GNDGND
A5SCL
A4SDA
5VVcc
GNDGND
D5Trig
D6Echo

Code Explanation

libraries. After downloading the libraries, add them to your Arduino IDE. is given at the end of the page. Here the same program will be explained in small snippets. library is used to read the MLX90614 sensor data. #include <Wire.h> #include <Adafruit_MLX90614.h> We then define the pins of the ultrasonic sensor to which we have made the connection const int trigPin = 5; const int echoPin = 6; After that, define the variables to store the RFID module, ultrasonic sensor, and MLX90614 sensor data. long duration; int distance; String RfidReading; float TempReading; function, we initialize serial monitor for debugging and the MLX90614 temperature sensor. Also, set the Trig and Echo pins as output and input pins. void setup() { Serial.begin(9600); // Initialise Serial Communication with the Serial Monitor pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); mlx.begin(); Initialize_streamer(); } function to scan the tag. void loop() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = duration * 0.0340 / 2; if (distance <= 25){ reader(); } function is used to read the RFID tag card. Once the card is brought near the reader module, the reader module reads the serial data and store it in the input variable. void reader() { if(Serial.available()) { count = 0; while(Serial.available() && count < 12) { input[count] = Serial.read(); count++; delay(5); In the next lines, compare the scanned card data with the predefined tag ID. If the tag ID matches the scanned card, then read the temperature of the person and send the temperature and name of the person to the excel sheet. if(input[count]==tag[count]) flag = 1; else flag= 0; count++; RfidReading = "Ashish"; } } if(flag == 1) { temp_read(); Write_streamer(); } variable. void temp_read() { TempReading = mlx.readObjectTempC();} Once the hardware and the software are ready, it is time to upload the program into your Arduino Nano Board. As soon your program gets uploaded, the ultrasonic sensor starts calculating the distance. When the calculated distance is less than 40 cm, it reads the temperature and the card.

Storing Sensor Data into Excel Sheet from Arduino Controller

on your desktop. Now open the ‘PLX-DAQ spreadsheetᾠfile from the desktop folder. If macros are disabled on your Excel than you will see a security block as shown in below image: to Enable the Macros. After this you will get the following screen: Now select the baud rate as Ᾱ600ᾠand the port to which your Arduino is connected and then click on Connect to start the data streaming. Your values should start to get logged like shown in the picture below. A working video and complete code are given at the end of the page. Code #include <Wire.h> #include <Adafruit_MLX90614.h> Adafruit_MLX90614 mlx = Adafruit_MLX90614(); char tag[] ="180088FECCA2"; // Replace with your own Tag ID char input[12]; // A variable to store the Tag ID being presented int count = 0; // A counter variable to navigate through the input[] character array boolean flag = 0; // A variable to store the Tag match status const int trigPin = 5; const int echoPin = 6; long duration; int distance; String RfidReading; float TempReading; void setup() { Serial.begin(9600); // Initialise Serial Communication with the Serial Monitor pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); mlx.begin(); Initialize_streamer(); } void loop() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = duration * 0.0340 / 2; // Serial.println("Distance"); //Serial.println(distance); if (distance <= 40){ reader(); } delay(1000); } void reader() { if(Serial.available())// Check if there is incoming data in the RFID Reader Serial Buffer. { count = 0; // Reset the counter to zero while(Serial.available() && count < 12) { input[count] = Serial.read(); // Read 1 Byte of data and store it in the input[] variable count++; // increment counter delay(5); } if(count == 12) // { count =0; // reset counter varibale to 0 flag = 1; while(count<12 && flag !=0) { if(input[count]==tag[count]) flag = 1; // everytime the values match, we set the flag variable to 1 else flag= 0; count++; // increment i RfidReading = "Ashish"; } } if(flag == 1) // If flag variable is 1, then it means the tags match { //Serial.println("Access Allowed!"); temp_read(); Write_streamer(); } else { // Serial.println("Access Denied"); // Incorrect Tag Message } for(count=0; count<12; count++) { input[count]= 'F'; } count = 0; // Reset counter variable } } void temp_read() { TempReading = mlx.readObjectTempC(); // Serial.println(sensorReading1); // Serial.print(","); //Serial.print("Ambient "); //Serial.print(mlx.readAmbientTempC()); //Serial.print(" C"); // Serial.print("Target "); // Serial.print(mlx.readObjectTempC()); // Serial.print(" C"); // delay(1000); } void Initialize_streamer() { Serial.println("CLEARDATA"); //clears up any data left from previous projects Serial.println("LABEL,Date,Time,Temperature,Name"); //always write LABEL, to indicate it as first line } void Write_streamer() { // Serial.print("DATA"); //always write "DATA" to Indicate the following as Data // Serial.print(","); //Move to next column using a "," // Serial.print("DATE"); //Store date on Excel // Serial.print(","); //Move to next column using a "," // Serial.print("TIME"); //Store date on Excel // Serial.print(","); //Move to next column using a "," Serial.print(RfidReading); //Store date on Excel Serial.print(","); //Move to next column using a "," Serial.print(TempReading); //Store date on Excel Serial.print(","); //Move to next column using a "," Serial.println(); //End of Row move to next row } Video microcontroller-projects/digital-audio-volume-control-circuit-using-pt2258-ic-and-arduino

Digital Audio Volume Control Circuit using PT2258 IC and Arduino

, etc.

IC PT2258

this IC uses CMOS technology specially designed for multi-channel audio-video applications. This IC provides an I2C Control Interface with an attenuation range of 0 to -79dB at 1dB/step and comes in a 20-pin DIP or SOP package. Some of the basics feature includes, 6-Input and output channels (For 5.1 Home Audio Systems) Selectable I2C address (For Daisy-chain Application) High channel Separation (For Low Noise Application) S/N ratio of > 100dB Operating voltage is 5 to 9V

How PT2258 IC Works

This IC transmits and receives data from the microcontroller via SCL and SDA lines. The SDA and SCL make up the bus interface. These lines must be pulled high by two 4.7K resistors in order to ensure stable operation. Before we go to the actual hardware operation, here is the detailed functional description of the IC. if you don't want to know all this, you can skip this part because all the functional part is managed by the Arduino library. The data on the SDA line is considered stable when the SCL signal is HIGH. The HIGH and LOW states of the SDA line changes only when the SCL is LOW. A Start Condition is activated when the SCL is set to HIGH and SDA shifts from HIGH to LOW State. The Stop Condition is activated when SCL is set to HIGH and SDA shifts from LOW to HIGH State This information is very useful for debugging the signals. Every byte transmitted to the SDA Line consists of 8 bits, which form a byte. Each byte must be followed by an Acknowledge Bit. Acknowledgment ensures stable and proper operation. During the Acknowledge Clock Pulse, the microcontroller pulls the SDA pin HIGH at this exact moment the peripheral device (audio processor) pulls-down (LOW) the SDA line. The peripheral device (PT2258) is now addressed & it has to generate an acknowledge after receiving a byte, otherwise, the SDA line will remain at High level during the ninth (9th) Clock Pulse. If this happens, the master transmitter will generate STOP Information in order to abort the transfer. That clears the no need to be in place for a valid data transfer. The I2C address of this IC depends on the state of CODE1 (Pin No.17) and CODE2 (Pin No.4).
000X80
010X84
100X88
110X8C
Logic High = 1 Logic Low = 0 The interface protocol consists of the following: A Start bit A Chip Address Byte ACK=Acknowledge bit A Data byte A Stop bit After the IC is powered on, it needs to wait at least 200ms before transmitting the first data bit, otherwise, the data-transfer may fail. After the delay, the first thing to do is to clear the register by sending ᾰXC0ᾠvi the I2C line, this ensures proper operation. The above step clears the entire register, now we need to set a value to the register, otherwise, the register stores garbage value and we get a freckled output. To ensure proper volume adjustments, it is necessary to send a multiple of 10dB followed by a 1dB code to the attenuator in sequence, otherwise, the IC can behave abnormally. The diagram below clarifies it more. Both the above methods will work properly. To ensure proper operation, make sure that the I2C data transfer speed never exceeds 100KHz. That's how you can transmit a byte to the IC and attenuate the input signal. The above section is to learn how the IC functions, but as I have said earlier, we are going to use an Arduino library to communicate with the IC which manages all the hard code, and we just need to make some function calls. , please refer to it for further information.

The Schematic

and modified according to need. For the demonstration, the circuit is constructed on a solderless breadboard with the help of the schematic shown above.

Components Required

PT2258 IC ᾠ1 Arduino Nano Controller ᾠ1 Generic Breadboard ᾠ1 Screw Terminal 5mm x 3 ᾠ1 Push Button ᾠ1 4.7K Resistor, 5% - 2 150K Resistor, 5% - 4 10k Resistor, 5% - 2 10uF Capacitor ᾠ6 0.1uF Capacitor ᾠ1 Jumper Wires - 10

Arduino Code

This is a very well written library that's why I have decided to use it, but since it is very old, it’s a little buggy and we need to fix it before we can use it. First, download & extract the library from the GitHub repository. You will get the above two files after extraction. #include <arduino.h> #include <wire.h> #include <PT2258.h> file with your favorite Text Editor, I am using Notepad++. You can see that the “wᾠof the wire library is in small letters, which is incompatible with the latest Arduino versions, & you need to replace it with a caps “Wᾬthat's it. of this section. Here important parts of the program are explained. library is used to interface with the push-buttons. Instead of using below code images, Copy all the code instances from code file and make them Formatted like we used to do in other projects #include <PT2258.h> #include <ezButton.h> #include <Wire.h> Next, make the objects for the two buttons and the PT2258 library itself. PT2258 pt2258; ezButton button_1(2); ezButton button_2(4); Next, define the volume level. This is the default volume level that this IC will start off with. Int volume = 40; Next, initiate the UART, and set the clock frequency for the I2C bus. Serial.begin(9600); Wire.setClock(100000); It’s very important to set the I2C clock, otherwise, the IC will not work because the maximum clock frequency supported by this IC is 100KHz. statement in order to ensure the IC is communicating properly with the I2C bus. If (!pt2258.init()) Serial.printIn(“PT2258 Successfully Initiatedᾩ; Else Serial.printIn(“Failed to Initiate PT2258ᾩ; Next, we set the debounce delay for the pushbuttons. Button_1.setDebounceTime(50); Button_2.setDebounceTime(50); Finally, initiate the PT2258 IC by setting it up with the default channel volume and Pin number. /* Iniciating PT with default volume and Pin*/ Pt2258.setChannelVolume(volume,4); Pt2258.setChannelVolume(volume,5); section. section, we need to call the loop function from the button class; it's a library norm. Button_1.loop(); //Library norms Button_2.loop(); //Library norms section is to decrease the volume. /* if button 1 is pressed if condition is true */ If (button_1.ispressed()) { Volume++; // Incrementing the volume counter. // This if statement ensures the volume does not goes above 79 If (volume >= 79) { Volume = 79; } Serial.print(“volume: ᾩ; // printing the volume level Serial.printIn(volume); /* set the volume for channel 4 Which is in PIN 9 of the PT2558 IC */ Pt2558.setChannelVolume(volume,4); /*set the volume for channel 5 Which is the PIN 10 of the PT2558 IC */ Pt2558.setChannelVolume(volume,5); } section is to increase the volume. // The same happens for the button 2 If (button_2.isPressed()) { Volume--; // this if statement ensures the volume level does not go below zero. If (volume <= 0) Volume = 0; Serial.print(“volume: “); Serial.printIn(volume); Pt2258.setChannelVolume(volume,4); Pt2558.setChannelVolume(volume,5); }

Testing the Digital Audio Volume Control Circuit

To test the circuit, the following apparatus was used A transformer which has a 13-0-13 Tap 2 4Ω 20W speaker as a load. Audio source (Phone) IC, I am going to use that for this demonstration also. I have disordered the mechanical potentiometer and shorted two leads with two small jumper cables. Now, with the help of two push-buttons, the volume of the amplifier can be controlled.

Further Enhancement

for detailed discussion. Code #include <PT2258.h> #include <ezButton.h> #include <Wire.h> PT2258 pt2258; // PT2258 Object ezButton button_1(2); //Button_1 Object ezButton button_2(4); //Button_2 Object int volume = 40; // Default volume / Starting Volume void setup() { Serial.begin(9600); //UART begin Wire.setClock(100000); // setting the I2C clock to 100KHz /* checking if the MCU can talk with the PT or not*/ if (!pt2258.init()) Serial.println("PT2258 Successfully Initiated"); else Serial.println("Failed to Initiate PT2258"); /* Setting up button debounce delay*/ button_1.setDebounceTime(50); button_2.setDebounceTime(50); /* Initiating PT with default volume and Pin*/ pt2258.setChannelVolume(volume, 4); pt2258.setChannelVolume(volume, 5); } void loop() { button_1.loop(); //Library norms button_2.loop(); //Library norms /* If button 1 is pressed if condition is true*/ if (button_1.isPressed()) { volume++; // Incrementing the volume counter. // this if statement ensures the volume does not goes above 79 if (volume >= 79) { volume = 79; } Serial.print("volume: "); // Printing the volume level Serial.println(volume); /*Set the volume for channel 4 Which is in PIN 9 of the PT2258 IC */ pt2258.setChannelVolume(volume, 4); /*Set the volume for channel 5 Which is the Pin 10 of the PT2258 IC */ pt2258.setChannelVolume(volume, 5); } //The same happens for the button 2 if (button_2.isPressed()) { volume--; // this if statement ensures the volume level doesn't go below zero. if (volume <= 0) volume = 0; Serial.print("volume: "); Serial.println(volume); pt2258.setChannelVolume(volume, 4); pt2258.setChannelVolume(volume, 5); } } Video microcontroller-projects/arduino-ph-meter

pH Meter using Arduino Uno and LCD Display

is used in a wide variety of applications like agriculture, wastewater treatment, industries, environmental monitoring, etc. to determine the accuracy of the sensor. So let’s get started!

Required Components

Arduino Uno 16*2 Alphanumeric LCD I2C Module for LCD Gravity Analog pH sensor Connecting wires Breadboard

What is pH Value?

The range of pH can have values from 0 to 14. A pH value of 7 is neutral, as pure water has a pH value of exactly 7. Values lower than 7 are acidic and values greater than 7 are basic or alkaline.

How Does Gravity Analog pH Sensor Work?

Analog pH sensor is designed to measure the pH value of a solution and show the acidity or alkalinity of the substance. It is commonly used in various applications such as agriculture, wastewater treatment, industries, environmental monitoring, etc. The module has an on-board voltage regulator chip which supports the wide voltage supply of 3.3-5.5V DC, which is compatible with 5V and 3.3V of any control board like Arduino. The output signal is being filtered by hardware low jitter. Supply Voltage: 3.3~5.5V BNC Probe Connector High Accuracy: ±0.1@25°C Detection Range: 0~14 Operating Temperature Range: 5~60°C Zero (Neutral) Point: 7±0.5 Easy calibration Internal Resistance: <250MΩ 5V DC input Ground pin pH analog output 3.3V DC output Temperature output The difference between these potentials determines the pH value based on the Nernst equation. The Nernst equation gives a relation between the cell potential of an electrochemical cell, temperature, reaction quotient and the standard cell potential. In non-standard conditions, the Nernst equation is used to calculate cell potentials in an electrochemical cell. The Nernst equation can also be used to calculate the total electromotive force (EMF) for a full electrochemical cell. This equation is used to calculate the PH value of a solution as well. The glass electrode response is governed by the Nernst Equation can be given as: E = E0 - 2.3 (RT/nF) ln Q Where Q= Reaction coefficient E = mV output from the electrode E0 = Zero offset for the electrode R = Ideal gas constant= 8.314 J/mol-K T = Temperature in oK F = Faraday constant = 95,484.56 C/mol N = Ionic Charge

Arduino pH Meter Circuit Diagram

is given below: The connection between Arduino and PH signal conversion board is shown in the table below.
5VV+
GNDG
A0Po

Programming Arduino for pH Meter

is given at the bottom part of this tutorial. The stepwise explanation of the project is given below. ᾠfor using I2C functionality on Arduino. #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); Next, the calibration value is defined, which can be modified as required to get an accurate pH value of solutions. (This is explained later in the article) float calibration_value = 21.34; LCD commands are written for displaying a welcome message on LCD. lcd.init(); lcd.begin(16, 2); lcd.backlight(); lcd.setCursor(0, 0); lcd.print(" Welcome to "); lcd.setCursor(0, 1); lcd.print(" Circuit Digest "); delay(2000); lcd.clear(); read 10 sample analog values and store them in an array. This is required to smooth the output value. for(int i=0;i<10;i++) { buffer_arr[i]=analogRead(A0); delay(30); } Then, sort the Analog values received in ascending order. This is required because we need to calculate the running average of samples in the later stage. for(int i=0;i<9;i++) { for(int j=i+1;j<10;j++) { if(buffer_arr[i]>buffer_arr[j]) { temp=buffer_arr[i]; buffer_arr[i]=buffer_arr[j]; buffer_arr[j]=temp; } } } Finally, calculate the average of a 6 centre sample Analog values. Then this average value is converted into actual pH value and printed on an LCD display. for(int i=2;i<8;i++) avgval+=buffer_arr[i]; float volt=(float)avgval*5.0/1024/6; float ph_act = -5.70 * volt + calibration_value; lcd.setCursor(0, 0); lcd.print("pH Val:"); lcd.setCursor(8, 0); lcd.print(ph_act); delay(1000); }

Calibration of pH Electrode

Calibration of the PH electrode is very important in this project. For this, we need to have a solution whose value is known to us. This can be taken as the reference solution for the calibration of the sensor. Similarly, adjust this variable to calibrate the sensor. Then check for all other solutions to get the exact output.

Testing Arduino pH Tester

We have tried this Arduino pH meter by dipping it into pure water and Lemon water, you can see the result below. and can use it to check the pH level of various liquids. aregiven below. Code #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); float calibration_value = 21.34; int phval = 0; unsigned long int avgval; int buffer_arr[10],temp; void setup() { Serial.begin(9600); lcd.init(); lcd.begin(16, 2); lcd.backlight(); lcd.setCursor(0, 0); lcd.print(" Welcome to "); lcd.setCursor(0, 1); lcd.print(" Circuit Digest "); delay(2000); lcd.clear(); } void loop() { for(int i=0;i<10;i++) { buffer_arr[i]=analogRead(A0); delay(30); } for(int i=0;i<9;i++) { for(int j=i+1;j<10;j++) { if(buffer_arr[i]>buffer_arr[j]) { temp=buffer_arr[i]; buffer_arr[i]=buffer_arr[j]; buffer_arr[j]=temp; } } } avgval=0; for(int i=2;i<8;i++) avgval+=buffer_arr[i]; float volt=(float)avgval*5.0/1024/6; float ph_act = -5.70 * volt + calibration_value; lcd.setCursor(0, 0); lcd.print("pH Val:"); lcd.setCursor(8, 0); lcd.print(ph_act); delay(1000); } Video microcontroller-projects/arduino-to-arduino-bluetooth-communication-using-master-slave-configuration

Arduino to Arduino Bluetooth Communication using Master Slave Configuration

, etc. However, have you ever neededto connect two HC-05s together? It’s not as straightforward connecting an HC05 to a smartphone, there are some additional steps involved. This tutorial will guide you through this process. Let’s jump right in!

Materials Required

2x Arduino (Any model will do; I’m using an Arduino Uno R3 and an Arduino Nano) 2x HC05 Bluetooth Modules Breadboard Jumper Wires 2x 1kΩ resistor 2x 2.2kΩ resistor

Circuit Diagram

This is the basic circuit diagram. Wire up 2 of these circuits, one for master and one for the slave. For the connections, all we are doing here is connecting the HC05 to the Arduino. The Receiver (Rx) pin of the HC05 operates at the 0V to 3.3V range and the Arduino operates at the 0V to 5V range. So, we will use resistors (R1 and R2) to create a voltage divider to reduce the 5V output of the Arduino to 3.3V, so as to not damage the HC05 module. are shown below.

Initial Configuration of the HC05 modules

and send commands to it through the Arduino IDE’s serial monitor. To do this, we need to write an Arduino code to send commands through the serial monitor to the HC05. can be found at the bottom of this page, the explanation of the code is as follows Add the SoftwareSerial library to this code. #include <SoftwareSerial.h> Define the transmit (Tx) and Receive (Rx) pin numbers. I’m using pin 2 for Tx and pin 3 for Rx. #define tx 2 #define rx 3 SoftwareSerial configBt(rx, tx); // RX, TX In order to configure the Bluetooth module, the Arduino needs to send commands to it at a baud rate of 38400 baud. Similarly, we set the baud rate of the Bluetooth connection as well to 38400 baud. Set the Transmit (Tx) to the output pin and Receive (Rx) to the input pin void setup() { Serial.begin(38400); configBt.begin(38400); pinMode(tx, OUTPUT); pinMode(rx, INPUT); } Inside the forever loop, we have the main chunk of the code. The idea here is to send whatever is typed in the textbox in the serial monitor to the HC05 through the Arduino’s Tx pin. Then display whatever is output by the HC05 in the serial monitor. void loop() { if(configBt.available()) // if the HC05 is sending something‐󞋊{ Serial.print(configBt.readString()); // print in serial monitor } if(Serial.available()) // if serial monitor is outputting something‐󞋊{ configBt.write(Serial.read()); // write to Arduino’s Tx pin } } (slow blinking!). Normally before the HC05 is connected to any Bluetooth device, it’s red light blinks at a very high frequency (fast blinking!). Now, type in AT in the serial monitor, if all goes well, you’ll get an “OKᾠfrom the HC05 displayed in the serial monitor window. Congratulations! You are have successfully logged into the HC05 module’s AT command mode.
(enter this in the serial monitor and press enter)(reply from HC05, displayed in the serial monitor)(What does this command do?)
ATOKTest
AT+CMODE?OKthe CMODE or Connection Mode ----------------------------- CMODE: 0 is the slave 1 is master
AT+CMODE=1OKHC05
AT+ADDR?+ADDR:FCA8:9A:58D5 OK *This is the address of my master HC05. Your address will be different!as we will need it later on!
(enter this in the serial monitor and press enter)(reply from HC05, displayed in the serial monitor)(What does this command do?)
ATOKTest
AT+CMODE?OKthe CMODE or Connection Mode ----------------------------- CMODE: 0 is a slave 1 is master
AT+CMODE=0OKHC05
AT+BIND= FCA8,9A,58D5 *Replace the Ὰᾠin the master HC05 address with ᾬᾍ *Here I’m using the address of the master HC05 I noted down from the previous table. You should use the address of your master HC05!OKSetting the address of the master HC05 that this slave HC05 will automatically connect to on boot up
AT+BIND?+BIND: FCA8:9A:58D5 OK *This is the address of my master HC05. Your address will be different!Check the binding address of your slave. If it matches the address of your master HC05, you are good to go!

Arduino to Arduino Bluetooth Communication Testing

Firstly, power both the master and slave HC05 modules. After the power on and a few seconds have passed look at the red light on the HC05 modules.
Blinking at a very high frequency (fast blinking!)Not good! It means your HC05 modules are not connecting with each other! Time to troubleshoot!
Blinking at a low frequency (slow blinking!)Nice! You have done it! But we still got to do one more check just to be super sure that this setup works! Move on!
we haven’t tested if data can be sent back and forth between the master and slave. After all, that’s the main purpose here. again the complete code for both transmitter and receiver can be found at the bottom of this page. Following the previous code, we add the SoftwareSerial library to this code and define the transmit (Tx) and Receive (Rx) pin numbers. Then we name the Bluetooth connection and pass the Tx and Rx pin numbers to the library. #include <SoftwareSerial.h> #define tx 2 #define rx 3 SoftwareSerial bt(rx,tx); //RX, TX the HC05 with AT commands and 9600 baud is the default baud rate of the HC05 module. Lastly, just like before we configure the Tx pin as output and Rx pin as an input. void setup() { Serial.begin(9600); bt.begin(9600); pinMode(tx, OUTPUT); pinMode(rx, INPUT); } Inside the forever loop, all we are doing is transmitting a random value of ᾱ23ᾠthrough the HC05. void loop() { bt.write(123); } Exactly the same as the previous codes, we configure the SoftwareSerial library. #include <SoftwareSerial.h> #define tx 2 #define rx 3 SoftwareSerial bt(rx, tx); //RX, TX The code in the setup function is exactly the same as the code to test transmit (Tx). void setup() { Serial.begin(9600); bt.begin(9600); pinMode(tx, OUTPUT); pinMode(rx, INPUT); } In the forever loop, we just need to receive what we are sending from the transmitting Arduino. If the receive buffer has received some data from the HC05, then display whatever is received in the serial monitor. void loop() { if(bt.available()>0) { Serial.println(bt.read()); } } After you have uploaded the respective codes to each Arduino, open the Serial monitor to the receiving Arduino. Make sure you choose the baud rate as 9600 and the line ending as Newline in the serial monitor. If everything is working fine, you should be seeing 123. If you have connected both the transmitting and receiving Arduinos to the same laptop, make sure you choose the right COM port under TOOLS > PORT. You should be connected to the receiving Arduino’s COM port. If all goes well, swap the HC05 modules to make sure communication can happen in both directions and WE ARE DONE! Code HC05 Configuration: #include <SoftwareSerial.h> #define tx 2 #define rx 3 SoftwareSerial configBt(rx, tx); // RX, TX void setup() { Serial.begin(38400); configBt.begin(38400); pinMode(tx, OUTPUT); pinMode(rx, INPUT); } void loop() { if(configBt.available()) //if the bluetooth module is sending something... { Serial.print(configBt.readString()); //print whatever the bluetooth module is sending } if(Serial.available()) //if we have typed anything into the serial monitor input text box... { configBt.write(Serial.read()); //write whatever we typed into the serial monitor input text box to the bluetooth module } } Receiver: #include <SoftwareSerial.h> #define tx 2 #define rx 3 SoftwareSerial bt(rx, tx); //RX, TX void setup() { Serial.begin(9600); bt.begin(9600); pinMode(tx, OUTPUT); pinMode(rx, INPUT); } void loop() { if(bt.available()>0) { Serial.println(bt.read()); } } Sender: #include <SoftwareSerial.h> #define tx 2 #define rx 3 SoftwareSerial bt(rx,tx); //RX, TX void setup() { Serial.begin(9600); bt.begin(9600); pinMode(tx, OUTPUT); pinMode(rx, INPUT); } void loop() { bt.write(123); } Video microcontroller-projects/arduino-freertos-tutorial-using-semaphore-and-mutex-in-freertos-with-arduino

Arduino FreeRTOS Tutorial 3- Using Semaphore and Mutex in FreeRTOS with Arduino

Now, in this third FreeRTOS tutorial, we will learn more about FreeRTOS and its advance APIs, which can make you understand the multi-tasking platform more deeply.

What is Semaphore?

In previous tutorials, we have discussed about task priorities and also get to know that a higher priority task pre-empts a lower priority task so while execution of high priority task there may be a possibility that data corruption can happen in lower priority task because it is not executed yet and data is coming continuously to this task from a sensor which causes data loss and malfunctioning of the whole application. and here Semaphore plays an important role. Semaphore is a signaling mechanism in which a task in a waiting state is signaled by another task for execution. In other words, when a task1 finished its work, then it will show a flag or increment a flag by 1 and then this flag is received by another task (task2) showing that it can perform its work now. When task2 finished its work then the flag will be decreased by 1. So, basically, it is a “Giveᾠand “Takeᾠmechanism and semaphore is an integer variable that is used to synchronize access to resources. Semaphore is of two types. Binary Semaphore Counting Semaphore It has two integer values 0 and 1. It is somewhat similar to the Queue of length 1. For example, we have two tasks, task1 and task2. Task1 sends data to task2 so task2 continuously checks the queue item if there is 1, then it can read the data else it has to wait until it becomes 1. After taking the data, task2 decrement the queue and make it 0 That means task1 again can send the data to task2. From the above example, it can be said that binary semaphore is used for synchronization between tasks or between tasks and interrupt. It has values greater than 0 and can be thought of queue of length more than 1. This semaphore is used for counting events. In this usage scenario, an event handler will ‘giveᾠa semaphore each time an event occurs (incrementing the semaphore count value), and a handler task will ‘takeᾠa semaphore each time it processes an event (decrementing the semaphore count value). The count value is, therefore, the difference between the number of events that have occurred and the number that has been processed. Now, let's see how to use Semaphore in our FreeRTOS code.

How to use Semaphore in FreeRTOS?

FreeRTOS supports different APIs for creating a semaphore, taking a semaphore and giving a semaphore. Now, there can be two types of APIs for the same kernel object. If we have to give semaphore from an ISR, then normal semaphore API cannot be used. You should use interrupt protected APIs. because it is easy to understand and implement. As interrupt functionality is used here, you need to use interrupt protected APIs in ISR function. When we are saying synchronizing a task with an interrupt, it means putting the task into Running state right after the ISR. is created to store the semaphore. SemaphoreHandle_t sema_v; sema_v = xSemaphoreCreateBinary(); For giving a semaphore, there are two versions- one for interrupt and another one for the normal task. xSemaphoreGive(): This API takes only one argument which is the variable name of semaphore like sema_v as given above while creating a semaphore. It can be called from any normal task that you want to synchronize. xSemaphoreGiveFromISR(): This is the interrupt protected API version of xSemaphoreGive(). When we need to synchronize an ISR and normal task, then xSemaphoreGiveFromISR() should be used from the ISR function. This API takes two parameters. xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait ); Name of the semaphore to be taken in our case sema_v. to make the task_1 to wait indefinitely in Blocked state until the sema_v is available. Now, let's use these APIs and write a code to perform some tasks. Here one push-button and two LEDs are interfaced. The push-button will act as an interrupt button which is attached to pin 2 of Arduino Uno. When this button is pressed an interrupt will be generated and an LED which is connected to pin 8 will be turned ON and when you press it again it will be OFF. function will be called from TaskLED function. To make the system look multitasking, connect other LEDs with pin 7 which will be in always blinking state.

Semaphore Code Explanation

Let’s start writing code for by opening the Arduino IDE header file. Now, if any kernel object is used like queue semaphore then a header file must also be included for it. #include <Arduino_FreeRTOS.h> #include <semphr.h> to store the values of semaphore. SemaphoreHandle_t interruptSemaphore; 3. In void setup(), create two tasks(TaskLED and TaskBlink)using the xTaskCreate() API and then create a semaphore using xSemaphoreCreateBinary().Create a task with equal priorities and later on try to play with this number. Also, Configure pin 2 as an input and enable the internal pull-up resistor and attach the interrupt pin. Finally, start the scheduler as shown below. void setup() { pinMode(2, INPUT_PULLUP); xTaskCreate(TaskLed, "Led", 128, NULL, 0, NULL ); xTaskCreate(TaskBlink, "LedBlink", 128, NULL, 0, NULL ); interruptSemaphore = xSemaphoreCreateBinary(); if (interruptSemaphore != NULL) { attachInterrupt(digitalPinToInterrupt(2), debounceInterrupt, LOW); } } function as shown below. long debouncing_time = 150; volatile unsigned long last_micros; void debounceInterrupt() { if((long)(micros() - last_micros) >= debouncing_time * 1000) { interruptHandler(); last_micros = micros(); } } API. void interruptHandler() { xSemaphoreGiveFromISR(interruptSemaphore, NULL); } This function will give a semaphore to TaskLed to turn ON the LED. API and check if the semaphore is successfully taken or not. If it is equal to pdPASS (i.e 1) then make the LED toggle as shown below. void TaskLed(void *pvParameters) { (void) pvParameters; pinMode(8, OUTPUT); while(1) { if (xSemaphoreTake(interruptSemaphore, portMAX_DELAY) == pdPASS) { digitalWrite(8, !digitalRead(8)); } } } 6. Also, create a function to blink other LED connected to pin 7. void TaskLed1(void *pvParameters) { (void) pvParameters; pinMode(7, OUTPUT); while(1) { digitalWrite(7, HIGH); vTaskDelay(200 / portTICK_PERIOD_MS); digitalWrite(7, LOW); vTaskDelay(200 / portTICK_PERIOD_MS); } } 7. The void loop function will remain empty. Don’t forget it. void loop() {} That’s it, complete code can be found at the end of this tutorial. Now, upload this code and connect the LEDs and push-button with the Arduino UNO according to the circuit diagram.

Circuit Diagram

After uploading the code, you will see an LED is blinking after 200ms and when the button is pressed, immediately the second LED will glow as shown in the video given at the end. where it needs to pass the data from one task to another without any loss. Now, let’s see what is Mutex and how to use it FreeRTOS.

What is Mutex?

As explained above semaphore is a signaling mechanism, similarly, Mutex is a locking mechanism unlike the semaphore that has separate functions for increment and decrement but in Mutex, the function takes and gives in itself. It is a technique to avoid the corruption of shared resources. To protect the shared resource, one assigns a token card (mutex) to the resource. Whoever has this card can access the other resource. Others should wait until the card returned. In this way, only one resource can access the task and others wait for their chance. with the help of an example. Here we have three tasks, One for printing data on LCD, second for sending LDR data to LCD task and last task for sending Temperature data on LCD. So here two tasks are sharing the same resource i.e. LCD. If the LDR task and temperature task send data simultaneously then one of the data may be corrupted or lost. So to protect the data loss, we need to lock the LCD resource for task1 until it finished the display task. Then the LCD task will unlock and then task2 can perform its work. You can observe the working of Mutex and semaphores in the below diagram.

How to use Mutex in FreeRTOS?

Mutexs are also used in the same way as semaphores. First, create it, then give and take using respective APIs. As its name suggests that Mutex is a type of Binary semaphore. They are used in different contexts and purposes. A binary semaphore is for synchronizing tasks while Mutex is used for protecting a shared resource. return NULL. SemaphoreHandle_t mutex_v; mutex_v = xSemaphoreCreateMutex(); API. It is the same as a binary semaphore. It also takes two parameters. is available. API is used to give the Mutex back. The xSemaphoreGive() function takes only one argument which is the Mutex to be given in our case mutex_v.

Mutex Code Explanation

Here the goal for this part is to use a Serial monitor as a shared resource and two different tasks to access the serial monitor to print some message. 1. The header files will remain the same as a semaphore. #include <Arduino_FreeRTOS.h> #include <semphr.h> to store the values of Mutex. SemaphoreHandle_t mutex_v; Create a task with equal priorities and later on try to play with this number. void setup() { Serial.begin(9600); mutex_v = xSemaphoreCreateMutex(); if (mutex_v == NULL) { Serial.println("Mutex can not be created"); } xTaskCreate(Task1, "Task 1", 128, NULL, 1, NULL); xTaskCreate(Task2, "Task 2", 128, NULL, 1, NULL); } Then give some delay. void Task1(void *pvParameters) { while(1) { xSemaphoreTake(mutex_v, portMAX_DELAY); Serial.println("Hi from Task1"); xSemaphoreGive(mutex_v); vTaskDelay(pdMS_TO_TICKS(1000)); } } will remain empty. Now, upload this code on Arduino UNO and open the serial monitor. You will see messages are printing from task1 and task2. of FreeRTOS. Complete codes and video for Semaphore and Mutes are given below. Code CODE for Semaphore: #include <Arduino_FreeRTOS.h> #include <semphr.h> long debouncing_time = 150; volatile unsigned long last_micros; SemaphoreHandle_t interruptSemaphore; void setup() { pinMode(2, INPUT_PULLUP); xTaskCreate(TaskLed, "Led", 128, NULL, 0, NULL ); xTaskCreate(TaskBlink, "LedBlink", 128, NULL, 0, NULL ); interruptSemaphore = xSemaphoreCreateBinary(); if (interruptSemaphore != NULL) { attachInterrupt(digitalPinToInterrupt(2), debounceInterrupt, LOW); } } void loop() {} void interruptHandler() { xSemaphoreGiveFromISR(interruptSemaphore, NULL); } void TaskLed(void *pvParameters) { (void) pvParameters; pinMode(8, OUTPUT); for (;;) { if (xSemaphoreTake(interruptSemaphore, portMAX_DELAY) == pdPASS) { digitalWrite(8, !digitalRead(8)); } } } void TaskBlink(void *pvParameters) { (void) pvParameters; pinMode(7, OUTPUT); for (;;) { digitalWrite(7, HIGH); vTaskDelay(200 / portTICK_PERIOD_MS); digitalWrite(7, LOW); vTaskDelay(200 / portTICK_PERIOD_MS); } } void debounceInterrupt() { if((long)(micros() - last_micros) >= debouncing_time * 1000) { interruptHandler(); last_micros = micros(); } } CODE for Mutex: #include <Arduino_FreeRTOS.h> #include <semphr.h> SemaphoreHandle_t mutex_v; void setup() { Serial.begin(9600); mutex_v = xSemaphoreCreateMutex(); if (mutex_v == NULL) { Serial.println("Mutex can not be created"); } xTaskCreate(Task1, "Task1", 128, NULL, 1, NULL); xTaskCreate(Task2, "Task2", 128, NULL, 1, NULL); } void Task1(void *pvParameters) { while(1) { xSemaphoreTake(mutex_v, portMAX_DELAY); Serial.println("Hi from Task1"); xSemaphoreGive(mutex_v); vTaskDelay(pdMS_TO_TICKS(1000)); } } void Task2(void *pvParameters) { while(1) { xSemaphoreTake(mutex_v, portMAX_DELAY); Serial.println("Hi from Task2"); xSemaphoreGive(mutex_v); vTaskDelay(pdMS_TO_TICKS(500)); } } void loop() { } Video microcontroller-projects/arduino-freertos-tutorial-using-queues-in-arduino-freertos

Arduino FreeRTOS Tutorial 2- Using Queues in Arduino FreeRTOS

API function to delete itself, or any other task. as shown below. and make sure its value is ᾱᾠ(1 means enable and 0 means disable). It is 1 by default but checks for it. We will be using this config file frequently in our next tutorials for setting the parameters. Now, let’s see how to delete a task.

Deleting a Task in FreeRTOS Arduino

To delete a task, we have to use the vTaskDelete() API function. It takes only one argument. vTaskDelete( TaskHandle_t pxTaskToDelete ); , this argument is set as NULL but you can pass the address of the contents of the task by using any name. Let say if you want to set task handle for Task2 which is declared as TaskHandle_t any_name; Example: TaskHandle_t xTask2Handle; argument as xTaskCreate(TaskBlink2 , "task2" , 128 , NULL, 1 , &xTask2Handle ); The content of this task can be now accessed using the handle given by you. Also, a task can delete itself by passing NULL in place of a valid task handle. inside the task2 function. function. Then the above function will look like this void TaskBlink2(void *pvParameters) { Serial.println(“Task2 is running and about to delete”); vTaskDelete(NULL); pinMode(7, OUTPUT); while(1) { digitalWrite(7, HIGH); vTaskDelay( 300 / portTICK_PERIOD_MS ); digitalWrite(7, LOW); vTaskDelay( 300 / portTICK_PERIOD_MS ); } } Now, upload the code and observe the LEDs and Serial monitor. You will see that the second LED is not blinking now and task2 is deleted after encountering the delete API. So this API can be used to stop the execution of the particular task. Now, let’s start with the Queue.

What is the Queue in FreeRTOS?

Queue is the data structure that can hold the finite number of fixed size elements and it is operated in the FIFO scheme (First-in First-out). Queues provide a task-to-task, task-to-interrupt, and interrupt-to-task communication mechanism. The maximum number of elements queue can hold is called its “lengthᾮ Both the length and the size of each element are set when the queue is created. You can easily understand the given example. After understanding the Queues, let’s try to understand the process of creating a queue and try to implement it in our FreeRTOS code.

Creating a Queue in FreeRTOS

First, describe the problem statement that is to be implemented with the help of the FreeRTOS queue and Arduino Uno. So there are two tasks now Task1 is getting analog values of LDR. Task2 is printing the analog value on LCD. So, here queue plays its role because to send the data generated by task1 to task2. In task1, we will send analog value to the queue and in task2, we will receive it from the queue. There are three functions to work with queues Creating a Queue Sending data to Queue Receiving data from Queue 1. Creating a Queue function API. It takes two arguments. xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize ); The maximum number of items that the queue being created can hold at any one time. The size in bytes of each data item that can be stored in the queue. If this function returns NULL then the queue is not created due to insufficient memory and if it returns a non-NULL value, the queue is created successfully. Store this return value to a variable to use it as a handle to access the queue as shown below. QueueHandle_t queue1; queue1 = xQueueCreate(4,sizeof(int)); handle variable. To send the values to the queue, FreeRTOS has 2 variants of API for this purpose. xQueueSendToBack(): Used to send data to the back (tail) of a queue. xQueueSendToFront(): Used to send data to the front (head) of a queue. All these APIs takes 3 arguments. xQueueSendToBack( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait ); The handle of the queue to which the data is being sent (written). This variable is the same as used to store the return value of xQueueCreate API. A pointer to the data to be copied into the queue. The maximum amount of time the task should remain in the Blocked state to wait for space to become available in the queue. to convert a time specified in milliseconds into a time specified in ticks. is used. The item that is received is removed from the queue. This API also takes three arguments. xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ); First and third arguments are the same as sending API. Only the second argument is different. A pointer to the memory into which the received data will be copied. Hope you understood the three APIs. Now, we will implement these APIs in the Arduino IDE and try to solve the problem statement that we have described above.

Circuit Diagram

This is how it looks on the breadboard:

Implementing FreeRTOS Queue in Arduino IDE

Let’s start writing code for our application. header file. Now, if any kernel object like queue is used then include the header file of it. As we are using 16*2 LCD so include the library for it also. #include <Arduino_FreeRTOS.h> #include <queue.h> #include <LiquidCrystal.h> 2. Initialize a queue handle to store the contents of the queue. Also, initialize LCD pin numbers. QueueHandle_t queue_1; LiquidCrystal lcd(7, 8, 9, 10, 11, 12); initialize LCD and serial monitor with 9600 baud rate. Create a queue and two tasks using the respective APIs. Here we will create a queue of size 4 with integer type. Create a task with equal priorities and later on try to play with this number. Finally, start the scheduler as shown below. void setup() { Serial.begin(9600); lcd.begin(16, 2); queue_1 = xQueueCreate(4, sizeof(int)); if (queue_1 == NULL) { Serial.println("Queue can not be created"); } xTaskCreate(TaskDisplay, "Display_task", 128, NULL, 1, NULL); xTaskCreate(TaskLDR, "LDR_task", 128, NULL, 1, NULL); vTaskStartScheduler(); } API as shown below. void TaskLDR(void * pvParameters) { int current_intensity; while(1) { Serial.println("Task1"); current_intensity = analogRead(A0); Serial.println(current_intensity); xQueueSend(queue_1, &current_intensity, portMAX_DELAY); vTaskDelay( 1000 / portTICK_PERIOD_MS ); } } if a queue is empty. function. void TaskDisplay(void * pvParameters) { int intensity = 0; while(1) { Serial.println("Task2"); if (xQueueReceive(queue_1, &intensity, portMAX_DELAY) == pdPASS) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Intensity:"); lcd.setCursor(11, 0); lcd.print(intensity); } } } can be found at the end. Now, connect the LCD and LDR with Arduino UNO according to the circuit diagram upload the code. Open the serial monitor and observe the tasks. You will see tasks are switching and LDR values are changing according to the light intensity. Most of the libraries made for different sensors are not supported by the FreeRTOS kernel due to delay function implementation inside the libraries. Delay makes the CPU stop completely, therefore, the FreeRTOS kernel also stops working and code will not execute further and it starts misbehaving. So, we have to make the libraries delay-free to work with the FreeRTOS. Code #include <Arduino_FreeRTOS.h> #include <queue.h> #include <LiquidCrystal.h> QueueHandle_t queue_1; LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // RST E D4 D5 D6 D7 void setup() { Serial.begin(9600); lcd.begin(16, 2); queue_1 = xQueueCreate(5, sizeof(int)); if (queue_1 == NULL) { Serial.println("Queue can not be created"); } xTaskCreate(TaskDisplay, "Display_task", 128, NULL, 1, NULL); xTaskCreate(TaskLDR, "LDR_task", 128, NULL, 1, NULL); vTaskStartScheduler(); } void loop() { } void TaskDisplay(void * pvParameters) { int intensity = 0; while(1) { Serial.println("TaskDisplay"); if (xQueueReceive(queue_1, &intensity, portMAX_DELAY) == pdPASS) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Intensity:"); lcd.setCursor(11, 0); lcd.print(intensity); } } } void TaskLDR(void * pvParameters) { int current_intensity; while(1) { Serial.println("TaskLDR"); current_intensity = analogRead(A0); Serial.println(current_intensity); xQueueSend(queue_1, &current_intensity, portMAX_DELAY); vTaskDelay( 1000 / portTICK_PERIOD_MS ); } } Video microcontroller-projects/arduino-alcohol-detector-circuit-board

Arduino Alcohol Detector Circuit Board

will detect the alcohol level in breath and by using some calculations in code we can calculate the alcohol level in breath or blood and can trigger some alarm.

Components Required:

Arduino UNO Alcohol detector Arduino shield from JLCPCB Alcohol Sensor (MQ3) Resistor 10K Resistor 1K 16x2 LCD Power Supply 10k POT LED LM358 Burgstips Push button

Circuit Diagram and Explanation:

is used for displaying the PPM Value of alcohol. And an LM358 IC for converting alcohol level sensor output to digital (this function is optional). A buzzer is also place for indicating high alcohol level. is connected at Pin D9. And LCD connections are same as Arduino LCD examples that are available in Arduino IDE (12, 11, 5, 4, 3, 2). A push button also used here for start taking reading from Alcohol Sensor connected at digital pin D6 of Arduino. Remaining connections are shown in the circuit diagram. Note: In the circuit, we need to short all the three pin of J2 header to calculate PPM. we have used EasyEDA, in which first we have designed a Schematic and then converted that into the PCB layout by Auto Routing feature of EasyEDA.Complete Process is explained below.

Calculations for Alcohol Level:

According to MQ3 datasheet, alcohol in clean air is 0.04 mg/L. So we power the circuit and find the output voltage of MQ3 sensor in room air (I assume my room has clean air) so I got 0.60 voltage. It means when the sensor is giving 0.60v in the clean air then alcohol will be 0.04 mg/L. Now we can find a multiplier by dividing alcohol by output voltage in clean air and we get Multiplier = 0.40/0.60 Multiplier = 0.67 Now we have a formula for calculating alcohol (may be far away from the accurate or actual calculation. These are not standard calculations) Alcohol = 0.67 * v . Where v is the output voltage of alcohol sensor. Now we know the least driving limit while drinking alcohol is around 0.5mg/L. But in our calculation, we are getting around 0.40 mg/L in clean air so that we have set a threshold of alcohol while driving 0.80mg/L (just for Demonstration).

MQ3 Sensor:

is made by using SnO2 material which has less conductivity in clean air. Whenever it comes nearby alcohol gas its starts conducting highly according to the gas concentration. So user can sense the difference of output voltage using any microcontroller and can detect the presence of Alcohol. This is low cost and a suitable sensor for many applications for alcohol detection. This sensor has a long life and good sensitivity. Some of the applications that can be made by using this sensor are Alcohol gas alarm, portable alcohol detector, gas alarms, Breathalyzer etc.

Circuit and PCB Design using EasyEDA:

where they have a large stock of electronic components and users can order their required components along with the PCB order. While designing your circuits and PCBs, you can also make your circuit and PCB designs public so that other users can copy or edit them and can take benefit from there, we have also made our whole Circuit and PCB layouts public for thisArduino Alcohol Detector,check the below link: You canview any Layer(Top, Bottom, Topsilk, bottomsilk etc) of the PCB by selecting the layer form the ‘LayersᾠWindow. button in EasyEDA:

Calculating and Ordering Samples online:

page. button, then you can select the number of PCBs you want to order, how manycopper layers you need, the PCB thickness, copper weight, and even the PCB color, like the snapshot shown below: Afteryou have selected all of theoptions, click “Save to Cartᾠand then you will be taken to the page where you can upload your Gerber File which we have downloaded from EasyEDA. Upload your Gerber file and click “Save to Cartᾮ And finally click on Checkout Securely to complete your order, then you will get your PCBs a few days later. They are fabricating the PCB atvery low rate which is $2. Theirbuild time is also very less which is 48 hours with DHL delivery of 3-5 days, basically you will get your PCBs within a week of ordering. as shown in below pictures. And after getting these pieces I have soldered all the required components over the PCB, Align the Pins of this Shield with the Arduino and firmly press it over the Arduino. Now just upload the code to the Arduino and power on the circuit and you are done! Your Alcohol Detector is ready to test. Code #include <LiquidCrystal.h> LiquidCrystal lcd(12,11,5,4,3,2); #define sensor A0 #define led 13 #define buz 9 void setup() { Serial.begin(9600); lcd.begin(16,2); lcd.print("Alcohol Detector"); lcd.setCursor(0,1); lcd.print(" Circuit Digest "); delay(2000); pinMode(sensor, INPUT); pinMode(buz, OUTPUT); pinMode(led, OUTPUT); lcd.clear(); } void loop() { float adcValue=0; for(int i=0;i<10;i++) { adcValue+= analogRead(sensor); delay(10); } float v= (adcValue/10) * (5.0/1024.0); float mgL= 0.67 * v; Serial.print("BAC:"); Serial.print(mgL); Serial.print(" mg/L"); lcd.setCursor(0,0); lcd.print("BAC: "); lcd.print(mgL,4); lcd.print(" mg/L "); lcd.setCursor(0,1); if(mgL > 0.8) { lcd.print("Drunk "); Serial.println(" Drunk"); digitalWrite(buz, HIGH); digitalWrite(led, HIGH); } else { lcd.print("Normal "); Serial.println(" Normal"); digitalWrite(buz, LOW); digitalWrite(led, LOW); } delay(100); } Video microcontroller-projects/arduino-freertos-tutorial1-creating-freertos-task-to-blink-led-in-arduino-uno

Arduino FreeRTOS Tutorial 1 - Creating a FreeRTOS task to Blink LED in Arduino Uno

means the response time to any event is always constant so that it can be guaranteed that any particular event will occur at a fixed time. RTOS is designed to run applications with very precise timing and a high degree of reliability. RTOS also helps in multi-tasking with a single core. where you can know more about RTOS, the difference between general-purpose OS and RTOS, different types of RTOS, etc. can be found here. : How RTOS works Some frequently used terms in RTOS Installing FreeRTOS in Arduino IDE How to create FreeRTOS Tasks with example

How RTOS works?

This work is done by Scheduler present in the kernel. In a single-core processor, the scheduler helps tasks to execute in a particular time slice but it seems like different tasks are executing simultaneously. Every task runs according to the priority given to it. Now, let’s see what happens in the RTOS kernel if we want to create a task for LED blinking with a one-second interval and put this task on the highest priority. The idle task is created when no task is available for execution. This task always runs on the lowest priority i.e. 0 priority. If we analyze the timing graph given above, it can be seen that execution starts with an LED task and it runs for a specified time then for remaining time, the idle task runs until a tick interrupt occurs. Then kernel decides which task has to be executed according to the priority of the task and total elapsed time of the LED task. When 1 second is completed, the kernel chooses the led task again to execute because it has a higher priority than the idle task, we can also say that the LED task preempts the idle task. If there are more than two tasks with the same priority then they will run in round-robin fashion for a specified time. Every newly created task goes in Ready state (part of not running state). If the created task (Task1) has the highest priority than other tasks, then it will move to running state. If this running task preempts by the other task, then it will go back to the ready state again. Else if task1 is blocked by using blocking API, then CPU will not engage with this task until the timeout defined by the user. If Task1 is suspended in running state using Suspend APIs, then Task1 will go to Suspended state and it is not available to the scheduler again. If you resume Task1 in the suspended state then it will go back to the ready state as you can see in the block diagram. In this tutorial, we will implement two tasks in Arduino Uno using FreeRTOS API.

Frequently used terms in RTOS

It is a piece of code that is schedulable on the CPU to execute. It is responsible for selecting a task from the ready state list to the running state. Schedulersare often implemented so they keep all computer resources busy (as in load balancing). It is the act of temporarily interrupting an already executing task with the intention of removing it from the running state without its co-operation. interrupt. If there is any task in the list whose priority is higher than running task then context switch occurs. Basically, in this process contents of different tasks get saved in their respective stack memory. Preemptive Scheduling: In this type of scheduling, tasks run with equal time slice without considering the priorities. Priority-based Preemptive: High priority task will run first. Co-operative Scheduling: Context switching will happen only with the co-operation of running tasks. Task will run continuously until task yield is called. For signaling the task to perform some work, the synchronization process is used. To perform this process Kernel objects are used. Some Kernel objects are Events, Semaphores, Queues,Mutex, Mailboxes, etc. We will see how to use these objects in upcoming tutorials.

Installing Arduino FreeRTOS Library

Search for FreeRTOS and install the library as shown below. file. as shown below. Here we will write the code from scratch to understand the working, later you can check the example codes and use them.

Circuit Diagram

Below is the circuit diagram for creating Blinking LED task using FreeRTOS on Arduino:

Arduino FreeRTOS Example- Creating FreeRTOS tasks in Arduino IDE

Let’s see a basic structure to write a FreeRTOS project. 1. First, include Arduino FreeRTOS header file as #include <Arduino_FreeRTOS.h> 2. Give the function prototype of all functions that you are writing for execution which is written as void Task1( void *pvParameters ); void Task2( void *pvParameters ); .. ‐󬺯strong> function, create tasks and start the task scheduler. function with certain parameters/arguments. xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask ); There are 6 arguments that should be passed while creating any task. Let’s see what these arguments are pvTaskCode: It is simply a pointer to the function that implements the task (in effect, just the name of the function). pcName: A descriptive name for the task. This is not used by FreeRTOS. It is included purely for debugging purposes. usStackDepth: Each task has its own unique stack that is allocated by the kernel to the task when the task is created. The value specifies the number of words the stack can hold, not the number of bytes. For example, if the stack is 32-bits wide and usStackDepth is passed in as 100, then 400 bytes of stack space will be allocated (100 * 4 bytes) in RAM. Use this wisely because Arduino Uno has only 2Kbytes of RAM. pvParameters: Task input parameter (can be NULL). uxPriority: Priority of the task ( 0 is the lowest priority). pxCreatedTask: It can be used to pass out a handle to the task being created. This handle can then be used to reference the task in API calls that, for example, change the task priority or delete the task (can be NULL). xTaskCreate(task1,"task1",128,NULL,1,NULL); xTaskCreate(task2,"task2",128,NULL,2,NULL); Here, Task2 has higher priority and hence executes first. API. function will remain empty as we don’t want to run any task manually and infinitely. Because task execution is now handled by Scheduler. API. void task1(void *pvParameters) { while(1) { .. ..//your logic } } function as it stops the CPU and hence RTOS also stops working. So FreeRTOS has a kernel API to block the task for a specific time. vTaskDelay( const TickType_t xTicksToDelay ); can be used to calculate real-time from the tick rate. This means if you want a delay of 200ms, just write this line vTaskDelay( 200 / portTICK_PERIOD_MS ); to implement three tasks. APIs to be used: xTaskCreate(); vTaskStartScheduler(); vTaskDelay(); Task to be created for this tutorial: LED blink at Digital pin 8 with 200ms frequency LED blink at Digital pin 7 with 300ms frequency Print numbers in serial monitor with 500ms frequency.

FreeRTOS Task Implementation in Arduino IDE

1. From the above basic structure explanation, include the Arduino FreeRTOS header file. Then make function prototypes. As we have three tasks, so make three functions and it’s prototypes. #include <Arduino_FreeRTOS.h> void TaskBlink1( void *pvParameters ); void TaskBlink2( void *pvParameters ); void Taskprint( void *pvParameters ); API. Initially, make the priorities of all tasks as ᾱᾠand start the scheduler. void setup() { Serial.begin(9600); xTaskCreate(TaskBlink1,"Task1",128,NULL,1,NULL); xTaskCreate(TaskBlink2,"Task2 ",128,NULL,1,NULL); xTaskCreate(Taskprint,"Task3",128,NULL,1,NULL); vTaskStartScheduler(); } void TaskBlink1(void *pvParameters) { pinMode(8, OUTPUT); while(1) { digitalWrite(8, HIGH); vTaskDelay( 200 / portTICK_PERIOD_MS ); digitalWrite(8, LOW); vTaskDelay( 200 / portTICK_PERIOD_MS ); } } will be written as void Taskprint(void *pvParameters) { int counter = 0; while(1) { counter++; Serial.println(counter); vTaskDelay( 500 / portTICK_PERIOD_MS ); } } project for Arduino Uno. You can find full code along with a video at the end of this tutorial. Finally, connect two LEDs at the digital pin 7 and 8 and upload the code on your Arduino board and open the Serial monitor. You will see a counter is running once in 500ms with task name as shown below. function. Change the number and observe the behavior on serial monitor and LEDs. Now, you can understand the first two example codes in which analog read and digital read tasks are created. In this way, you can make more advance projects using just Arduino Uno and FreeRTOS APIs. Code #include <Arduino_FreeRTOS.h> void TaskBlink1( void *pvParameters ); void TaskBlink2( void *pvParameters ); void Taskprint( void *pvParameters ); void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); xTaskCreate( TaskBlink1 , "task1" , 128 , NULL , 1 , NULL ); xTaskCreate( TaskBlink2 , "task2" , 128 , NULL , 1 , NULL ); xTaskCreate( Taskprint , "task3" , 128 , NULL , 1 , NULL ); vTaskStartScheduler(); } void loop() { } void TaskBlink1(void *pvParameters) { pinMode(8, OUTPUT); while(1) { Serial.println("Task1"); digitalWrite(8, HIGH); vTaskDelay( 200 / portTICK_PERIOD_MS ); digitalWrite(8, LOW); vTaskDelay( 200 / portTICK_PERIOD_MS ); } } void TaskBlink2(void *pvParameters) { pinMode(7, OUTPUT); while(1) { Serial.println("Task2"); digitalWrite(7, HIGH); vTaskDelay( 300 / portTICK_PERIOD_MS ); digitalWrite(7, LOW); vTaskDelay( 300 / portTICK_PERIOD_MS ); } } void Taskprint(void *pvParameters) { int counter = 0; while(1) { counter++; Serial.println(counter); vTaskDelay(500 / portTICK_PERIOD_MS); } } Video microcontroller-projects/automatic-hand-sanitizer-dispenser-with-covid19-live-updates

Automatic Hand Sanitizer Dispenser with COVID19 Live Updates

, etc. is used to check the presence of hands below the outlet of the sanitizer machine. It will continuously calculate the distance between the sanitizer outlet and itself and tells the ESP to turn on the pump whenever the distance is less than 15cm to push the sanitizer out.

Components Required

ESP32 Dev Module Ultrasonic Sensor 16*2 LCD Display Relay Module Mini DC Submersible Pump Hand Sanitizer

API link for getting the Corona Live Data

.You can easily compile the correct query URL to get the total Confirmed and recovered cases for India and can also change the country/Region if you want to use this for a different country. Now click on “Try Nowᾠor paste the query URL into a new browser, the output of that query will look like this: {"objectIdFieldName":"OBJECTID","uniqueIdField":{"name":"OBJECTID","isSystemMaintained":true},"globalIdFieldName":"","geometryType":"esriGeometryPoint","spatialReference":{"wkid":4326,"latestWkid":4326},"fields":[{"name":"Country_Region","type":"esriFieldTypeString","alias":"Country/Region","sqlType":"sqlTypeOther","length":8000,"domain":null,"defaultValue":null},{"name":"Province_State","type":"esriFieldTypeString","alias":"Province/State","sqlType":"sqlTypeOther","length":8000,"domain":null,"defaultValue":null},{"name":"Confirmed","type":"esriFieldTypeInteger","alias":"Confirmed","sqlType":"sqlTypeOther","domain":null,"defaultValue":null},{"name":"Recovered","type":"esriFieldTypeInteger","alias":"Recovered","sqlType":"sqlTypeOther","domain":null,"defaultValue":null},{"name":"Deaths","type":"esriFieldTypeInteger","alias":"Deaths","sqlType":"sqlTypeOther","domain":null,"defaultValue":null},{"name":"Active","type":"esriFieldTypeInteger","alias":"Active","sqlType":"sqlTypeOther","domain":null,"defaultValue":null}],"features":[{"attributes":{"Country_Region":"India","Province_State":null,"Confirmed":194,"Recovered":20,"Deaths":4,"Active":170}}]} and paste the JSON data in the Input section. Now scroll down to the parsing program and copy the code section that is useful for you. I copied the below variables as I only needed the confirmed and recovered cases in India.

Circuit Diagram

is given below The water pump is connected to the ESP32 through a relay module. Vcc and GND pins of the relay are connected to Vin and GND pins of ESP32 while the input pin of the relay is connected to the D19 pin of ESP32. Trig and Echo pins of the Ultrasonic sensor are connected to D5 and D18 Pins of Arduino. Complete connections are given in the below table.
LCDESP32
VSSGND
VDD5V
VOPotentiometer
RSD22
RWGND
ED4
D4D15
D5D13
D6D26
D7D21
A5V
KGND
Ultrasonic SensorESP32
VccVin
GNDGND
TrigD5
ECHOD18
will look like this

Programming ESP32 for Covid19 Tracker

can be found at the end of the page. Here important parts of the program are explained. library is used to phrase the data arrays. Here ArduinoJson library is used to filter the Confirmed cases and Recovered from the data array that we are getting from the server. LiquidCrystal library is used for the LCD display Module. #include <HTTPClient.h> #include <WiFi.h> #include <ArduinoJson.h> #include <LiquidCrystal.h> To get the data from the server, NodeMCU ESP32 has to connect with the internet. For that, enter your Wi-Fi SSID and Password in the below lines. const char* ssid = "Galaxy-M20"; const char* pass = "ac312124"; After that define the pins where you have connected the LCD module, Ultrasonic sensor, and Relay module. const int rs = 22, en = 4, d4 = 15, d5 = 13, d6 = 26, d7 = 21; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); const int trigPin = 5; const int echoPin = 18; const int pump = 19; Now we enter the API link that is generated earlier. Using this link, we will get the total confirmed cases and Recovered cases in India. You can change the country name in the URL according to you. constchar*url="https://services1.arcgis.com/0MSEUqKaxRlEPj5g/arcgis/rest/services/ncov_cases/FeatureServer/1/query?f=json&where=(Country_Region=%27India%27)&returnGeometry=false&outFields=Country_Region,Confirmed,Recovered"; , define the Trig and Echo pin of Ultrasonic sensor as input pins and Relay pin as an output. pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(pump, OUTPUT); After that, check if the ESP is connected with the Wi-Fi, if not it will wait for ESP to connect by printing “‐󬯢€ on the serial monitor. WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); // print ... till not connected } Serial.println("WiFi connected"); function we will continuously calculate the distance using an ultrasonic sensor and if the distance is less than or equal to 15 cm, then it will turn on the pump for 2 seconds to push the sanitizer outside through the pipe. Obliviously when someone puts his hands below the outlet pipe, the distance will decrease and it will trigger the pump to turn on. void ultra(){ digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = duration * 0.0340 / 2; Serial.println("Distance"); Serial.println(distance); if (distance <= 15){ Serial.print("Opening Pump"); digitalWrite(pump, HIGH); delay(2000); digitalWrite(pump, LOW); ESP.restart(); } } function, check if JSON file received by the ESP32 by reading it and printing JSON data on the serial monitor using the following lines int httpCode = https.GET(); if (httpCode > 0) { //Check for the returning code String payload = https.getString(); This phrasing program will give us the total confirmed and recovered cases in India. JsonArray fields = doc["fields"]; JsonObject features_0_attributes = doc["features"][0]["attributes"]; long features_0_attributes_Last_Update = features_0_attributes["Last_Update"]; int features_0_attributes_Confirmed = features_0_attributes["Confirmed"]; //int features_0_attributes_Deaths = features_0_attributes["Deaths"]; int features_0_attributes_Recovered = features_0_attributes["Recovered"];

Testing the Automatic Hand Sanitizer with Covid19 Tracker

is ready to test. Just connect the hardware as per circuit diagram and upload the program into ESP32, in the starting you should see the “Covid19 Trackerᾠ& “Hand Sanitizerᾠmessage on the LCD and then after few seconds it will display confirmed cases & recovered cases in the LCD screen as shown below. given at the end of the page. Code #include <HTTPClient.h> #include <WiFi.h> #include <ArduinoJson.h> #include <LiquidCrystal.h> const char* ssid = "Galaxy-M20"; const char* pass = "ac312124"; int count; const int rs = 22, en = 4, d4 = 15, d5 = 13, d6 = 26, d7 = 21; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); const int trigPin = 5; const int echoPin = 18; const int pump = 19; long duration; int distance; const char* url = "https://services1.arcgis.com/0MSEUqKaxRlEPj5g/arcgis/rest/services/ncov_...(Country_Region=%27India%27)&returnGeometry=false&outFields=Country_Region,Confirmed,Recovered"; void setup() { Serial.begin(115200); delay(2000); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(pump, OUTPUT); digitalWrite(pump, LOW); lcd.begin(16, 2); lcd.clear(); lcd.setCursor(0,0); lcd.print("Covid19 Tracker"); lcd.setCursor(0,1); lcd.print("Hand Sanitizer"); Serial.println("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); // print ... till not connected } Serial.println("WiFi connected"); } void ultra(){ digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = duration * 0.0340 / 2; Serial.println("Distance"); Serial.println(distance); if (distance <= 15){ Serial.print("Opening Pump"); digitalWrite(pump, HIGH); delay(2000); digitalWrite(pump, LOW); ESP.restart(); } } void loop() { ultra(); HTTPClient https; String data; https.begin(url); int httpCode = https.GET(); if (httpCode > 0) { //Check for the returning code String payload = https.getString(); char charBuf[500]; payload.toCharArray(charBuf, 500); //Serial.println(payload); const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + 3 * JSON_OBJECT_SIZE(6) + 2 * JSON_OBJECT_SIZE(7) + 690; DynamicJsonDocument doc(capacity); deserializeJson(doc, payload); JsonArray fields = doc["fields"]; JsonObject features_0_attributes = doc["features"][0]["attributes"]; long features_0_attributes_Last_Update = features_0_attributes["Last_Update"]; int features_0_attributes_Confirmed = features_0_attributes["Confirmed"]; //int features_0_attributes_Deaths = features_0_attributes["Deaths"]; int features_0_attributes_Recovered = features_0_attributes["Recovered"]; if (count < 3){ //Serial.println(features_0_attributes_Confirmed); lcd.setCursor(0, 0); lcd.print("IN Confirmed:"); lcd.print(features_0_attributes_Confirmed); //Serial.println(features_0_attributes_Recovered); lcd.setCursor(0, 1); lcd.print("IN Recovered:"); lcd.print(features_0_attributes_Recovered); } if (count > 3){ lcd.clear(); lcd.setCursor(0, 0); lcd.print("Wash Hands"); lcd.setCursor(0, 1); lcd.print("Avoid Contacts"); } if (count > 6){ count = 0; } } else { Serial.println("Error on HTTP request"); } https.end(); count++; } Video microcontroller-projects/digital-keypad-security-door-lock-using-arduino

Digital Keypad Security Door Lock using Arduino

which can be mounted to any of your existing doors to secure them with a digital password. Previously, we have also built other interesting door locks which are listed below. Arduino RFID Door Lock Arduino Solenoid Door Lock Raspberry Pi Digital Code Lock 555 Timer electronic Door lock Before building our password door locking project, first, we need to collect the required components and then go ahead and follow the step by step building process.

List of components

Arduino Uno/Pro/Mini or Custom board using Atmega328p Microcontroller 16 x 2 LCD (Liquid Crystal Display) 4 x 3 or 4 x 4 matrix keypad for Arduino Servomotor 3D printed door locker/customized door locker Additional components for power supply of 1 Amp 5 Volt mobile charger 4’ᾠ/ 6’’plastics boxes, jumper wires, nuts bolts, plastic casing, etc.

Circuit Diagram for Arduino Keypad Door Lock

The Complete circuit diagram for our Arduino based Digital Keypad Door Lock project is shown below. tutorial to learn more about it. tutorial to learn more about the servo motor and how it works. Connect the servo motor with Arduino Digital pin D9 and with a 5volt power supply. This servo motor has a total of 3 input lines (GND, +5V & SIGNAL LINE). In this project, I have used a 4 x 4 matrix keypad (but the 4 x 4 keypad part is not available in fritzing for making this graphical representation), but don’t worry as 4 x 3 Matrix keypad also works fine with my coding. We need a keypad for password input and manually lock our customized door locker. It consists of 16 keys (soft switch) 4 keys in Rows (R1, R2, R3, R4) and 4 keys in Columns (C1, C2, C3, C4) when a key pressed, it establishes a connection in between the corresponding rows and columns. The below table shows how to connect your Arduino with Keypad.
KeypadArduino
Pin 1 (row 1)Digital Pin1
Pin 2 (row 2)Digital Pin 2
Pin 3 (row 3)Digital pin 3
Pin 4 (row 4)Digital pin 4
Pin 5 (columns 5)Digital pin 5
Pin 6 (columns 6)Digital pin 6
Pin 7 (columns 7)Digital pin 7

Arduino Code for Digital Keypad Door Lock

The complete Arduino Door Lock Code can be found at the bottom of this page. You can directly upload the code, but it is recommended to read the below paragraphs to understand how the code works. Also, it is important to make sure you have added the following keypad library to your Arduino IDE to compile the code successfully. To do that just open the link below and download the ZIP file. Then on your Arduino IDE navigate to Sketch -> Include Library -> Add.ZIP Library and browse for the file that you just downloaded. Arduino Keypad Library After inserting all the header and library files, assign all the pin for LCD and define the password length and set the initial position of the servo to 0. After that, take a “charᾠdatatype for declaring the number that can hold it including the null character. //#include <Keypad.h> #include <LiquidCrystal.h> #include <Servo.h> Servo myservo; LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); #define Password_Lenght 7 // Give enough room for six chars + NULL char int pos = 0; // variable to store the servo position char Data[Password_Lenght]; // 6 is the number of chars it can hold + the null char = 7 char Master[Password_Lenght] = "123456"; With this piece of code (char Master[Password_Lenght] = "123456";) -- under the Char Master, I declare the password of the door lock, then assign the number of rows and columns in the keyboard and also declare keyMaps and connect with rows and columns. Under the void setup, initialize the servo signal pin D9, servo status closed and print the name of the project/device/company with 3 seconds of delay on LCD time of starting the device. void setup() { myservo.attach(9); ServoClose(); lcd.begin(16, 2); lcd.print(" Arduino Door"); lcd.setCursor(0, 1); lcd.print("--Look project--"); delay(3000); lcd.clear(); } Under the loop function, the simple if-else condition is there. According to status (it’s locked automatically), print “Door is closeᾠwith 3 seconds of delay and servo rotate to close position, door data count as 1 otherwise door locker remains open and data count 0, servo open rotate to the position goes 0 degrees to 180 degrees and to close it goes from 180 to 0. The servo open and servo close functions are shown below. void ServoOpen() { for (pos = 180; pos >= 0; pos -= 5) { // goes from 0 degrees to 180 degrees // in steps of 1 degree myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } } void ServoClose() { for (pos = 0; pos <= 180; pos += 5) { // goes from 180 degrees to 0 degrees myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } } Write the position of the servo with 15 seconds of delay to reach the servo position. Under the void open function, print on LCD “Enter Passwordᾠthen the condition specifies that the entered password should be same with custom key, within this body data counted and stores char into the data array, incremented and input password printed on LCD if the data length (number of key) and input password matches with Data Master (where the pre-defined keys are present). Then as an action LCD clear, servo drive, print on LCD “Door is openᾠand the data counter is reset to 0. If the input key does not match with Data Master, as an action on LCD clear print on LCD “Wrong Password ᾠto notify with 1 second of delay and remains in its lock position with data counter sets to 1 and continue this process in a loop. if (data_count == Password_Lenght - 1) // if the array index is equal to the number of expected chars, compare data to master { if (!strcmp(Data, Master)) // equal to (strcmp(Data, Master) == 0) { lcd.clear(); ServoOpen(); lcd.print(" Door is Open"); door = 0; } else { lcd.clear(); lcd.print(" Wrong Password"); delay(1000); door = 1; } clearData(); }

Arduino Keypad DoorLock Assembling and Testing

Now, fit everything on a 4 inch/ 6-inch plastic box and power it with a mobile charger, line up everything nicely using casing. Ideally, I could have used 3D printing to assemble my lock, but after designing my files, I found that 3D printing is very costly, so I just fixed the servo first, then connected the normal slide locker with my servo using metal plate and covered it up with glass fiber, although it is working fine, it is less secure. If you want more security, then you have to print a 3D door lock model that works internally with this servo. You can download the required STL files form the link below and 3D print them if you have access to a 3D printer. The design files are also shown in the picture below. At the beginning of the project, the moment we power it up for the first time, we need to give the project name ( you can display the company name also) so it looks smart and exclusive like a commercial device (as you can see in the picture below). , quickly lock the door and directly check the display for the status of the door lock as shown in the picture given below. If the door remains in unlock condition, it displays - Door is open as long as you manually lock the door according to the coding. I have given the code and you can customize the settings by changing the code display parameter as required. You can also check the complete working with the video linked at the bottom of this page. Code #include <Keypad.h> #include <LiquidCrystal.h> #include <Servo.h> Servo myservo; LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); #define Password_Lenght 7 // Give enough room for six chars + NULL char int pos = 0; // variable to store the servo position char Data[Password_Lenght]; // 6 is the number of chars it can hold + the null char = 7 char Master[Password_Lenght] = "123456"; byte data_count = 0, master_count = 0; bool Pass_is_good; char customKey; const byte ROWS = 4; const byte COLS = 3; char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'*', '0', '#'} }; bool door = true; byte rowPins[ROWS] = {1, 2, 3, 4}; //connect to the row pinouts of the keypad byte colPins[COLS] = {5, 6, 7}; //connect to the column pinouts of the keypad Keypad customKeypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad void setup() { myservo.attach(9); ServoClose(); lcd.begin(16, 2); lcd.print(" Arduino Door"); lcd.setCursor(0, 1); lcd.print("--Look project--"); delay(3000); lcd.clear(); } void loop() { if (door == 0) { customKey = customKeypad.getKey(); if (customKey == '#') { lcd.clear(); ServoClose(); lcd.print(" Door is close"); delay(3000); door = 1; } } else Open(); } void clearData() { while (data_count != 0) { // This can be used for any array size, Data[data_count--] = 0; //clear array for new data } return; } void ServoOpen() { for (pos = 180; pos >= 0; pos -= 5) { // goes from 0 degrees to 180 degrees // in steps of 1 degree myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } } void ServoClose() { for (pos = 0; pos <= 180; pos += 5) { // goes from 180 degrees to 0 degrees myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } } void Open() { lcd.setCursor(0, 0); lcd.print(" Enter Password"); customKey = customKeypad.getKey(); if (customKey) // makes sure a key is actually pressed, equal to (customKey != NO_KEY) { Data[data_count] = customKey; // store char into data array lcd.setCursor(data_count, 1); // move cursor to show each new char lcd.print(Data[data_count]); // print char at said cursor data_count++; // increment data array by 1 to store new char, also keep track of the number of chars entered } if (data_count == Password_Lenght - 1) // if the array index is equal to the number of expected chars, compare data to master { if (!strcmp(Data, Master)) // equal to (strcmp(Data, Master) == 0) { lcd.clear(); ServoOpen(); lcd.print(" Door is Open"); door = 0; } lcd.clear(); lcd.print(" Wrong Password"); delay(1000); door = 1; } clearData(); } else {} Video microcontroller-projects/arduino-coin-sorter-and-counter

Coin Sorting Machine using Arduino

Required Components

Arduino UNO IR sensor Breadboard 16*2 Alphanumeric LCD I2C Module for 16x2 (1602) Alphanumeric LCD Connecting Wires

Making Structure for Arduino Coin Sorter

Take a cardboard sheet and mark for different coin sizes as shown in the below figure. Then carefully cut the marked portions. Cutting of these portions must be done accurately; otherwise, the project may not work perfectly. Place the above arrangement in a slope structure as per the image shown below. After making the arrangement, check it by inserting different coins on the slope to ensure that the arrangement is perfectly working. If the coin is not inserting properly, then slightly increase the size of the hole according to coin and recheck until successful operation. here.

Circuit Diagram

Below is the Circuit diagram for Arduino counting machine: Here, IR sensors are placed at different output paths of the coin sorting machine to sense the coins. When a coin is inserted into this Arduino coin counter, it enters the dedicated path as per the mechanical design and the respective IR sensor senses the coin and gives HIGH output value to the Arduino which can be read by the analog pins of Arduino. The IR sensor which is giving HIGH value, decides the coin value like Rupees 2/5/10. without using the I2C module, but this requires more number of connections. So to make it simpler, an I2C module is used along with LCD, which only uses 2 pins, i.e. SCL, SDA for connecting LCD with Arduino. For powering the Arduino, a 12VDC, 1 AMP AC-DC adapter is used, which can be directly connected to the power jack of Arduino. will look like below:

Programming the Arduino

After successful hardware connections, now it’s time to program the Arduino. The complete code for Arduino is given at the bottom part of this tutorial. The stepwise explanation of the code is given below: ᾠfor using I2C functionality on Arduino. #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2); LCD commands are written for displaying a welcome message on LCD. lcd.init(); lcd.backlight(); lcd.setCursor(0,0); lcd.print(" ARDUINO BASED "); lcd.setCursor(0,1); lcd.print(" COIN SORTING "); delay(2000); lcd.clear(); function is used to read the Infrared sensor values, from different Analog channels of Arduino and store them in different variables. int s1=analogRead(A0); int s2=analogRead(A1); int s3=analogRead(A2); Then, the code below is written to sense the Coins and increment the coin counter values. Here a flag value f1 is used to avoid multiple counts of the coins. if(s1>=200 && f1==0) { f1=1; } else if(s1<200 && f1==1) { f1=0; c1++; } Finally, the count values are displayed on LCD, using the commands below. lcd.setCursor(0,0); lcd.print("RS10 RS2 RS5"); lcd.setCursor(1,1); lcd.print(c1); lcd.setCursor(7,1); lcd.print(c2); lcd.setCursor(14,1); lcd.print(c3);

Operation of Arduino Coin Counter

After the complete setup and uploading the code, switch ON the 12V DC power supply. First, a welcome message will be displayed on the LCD and after a few seconds, a screen with the number of all the available coins will be displayed on LCD. In the beginning, it will show zero as we haven’t inserted any coins yet. ᾠis written. Now you will see the value of the coin count must be updated on LCD. Then Insert multiple coins of different values and check the count of the respective coins on LCD. is given below. Code #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2); int f1=0,f2=0,f3=0; int c1=0,c2=0,c3=0; void setup() { lcd.init(); lcd.backlight(); lcd.setCursor(0,0); lcd.print(" ARDUINO BASED "); lcd.setCursor(0,1); lcd.print(" COIN SORTING "); delay(2000); lcd.clear(); } void loop() { int s1=analogRead(A0); int s2=analogRead(A1); int s3=analogRead(A2); lcd.setCursor(0,0); lcd.print("RS10 RS2 RS5"); if(s1>=200 && f1==0) { f1=1; } else if(s1<200 && f1==1) { f1=0; c1++; } if(s2>=200 && f2==0) { f2=1; } else if(s2<200 && f2==1) { f2=0; c2++; } if(s3>=200 && f3==0) { f3=1; } else if(s3<200 && f3==1) { f3=0; c3++; } lcd.setCursor(1,1); lcd.print(c1); lcd.setCursor(7,1); lcd.print(c2); lcd.setCursor(14,1); lcd.print(c3); } Video microcontroller-projects/adustable-electronic-dc-load-using-arduino

Build your own Adjustable Electronic DC Load using Arduino

, a china based professional PCB manufacturing and assembling service provider. Obviously, A digitally controlled current source requires a digital circuit and to serve the purpose, an Arduino NANO is used. The Arduino NANO will provide required controls for the DC load. , however, the circuit is changed for less complexity with basic features for everyone to build it. Our Electronic load is designed to have the following input and output sections. Two input switches for increasing and decreasing the load. An LCD that will display the set load, actual load, and the load voltage. The maximum load current is limited to 5A. The maximum input voltage is 24V for the load.

Materials Required

are listed below. Arduino nano 16x2 character LCD Two barrel socket Mosfet irf540n Mcp4921 Lm358 5watt shunt resistor .1 ohms 1k 10k - 6pcs Heatsink .1uF 50v 2k - 2pcs

Arduino DC Electronic Load Circuit Diagram

In the below schematic, the operational amplifier has two sections. One is to control the MOSFET and the other one is to amplify the sensed current. You can also check the video at the bottom of this page which explains the complete working of the circuit. The first section is having R12, R13, and MOSFET. R12 is used to reduce the loading effect on the feedback section and R13 is used as the Mosfet gate resistor. , these two resistors support a maximum of 24V. More than 24V will produce a voltage that will be not suitable for the Arduino pins. So be careful not to connect power supply that has more than 24V output voltage. R), but for the safe side, it is wiser to limit the load current maximum of 5A. Therefore, at present maximum 24V, 5A load can be set by this dummy load. will amplify it to x6, therefore 3V will be the output from the second part of the amplifier. This output will be sensed by the Arduino nano analog input pin and the current will be calculated. which will control the MOSFET as per the input voltage and get the desired feedback voltage due to the load current flowing through the shunt resistor. . Finally, by increasing the load, the Arduino nano will provide the load data to the DAC in digital format, the DAC will provide analog data to the operational amplifier, and the operational amplifier will control the MOSFET as per the input voltage of the operational amplifier. Finally, depending on the load current flow through the shunt resistor, a voltage drop will appear which will further be amplified by the second channel of LM358 and get by the Arduino nano. This will be displayed on the character display. The same thing will happen when the user presses the decrease button.

PCB Design and Gerber File

The final designed PCB in the CAD software is shown in the below image, in both the layers to the top and bottom. You can also download the Gerber file of this PCB from the link below and use it for fabrication. Download Adjustable Electronic DC Load Gerber File

Ordering your PCB from AllPCB

and signup. Then on the home page, enter the dimensions of your PCB and the required quantity as shown below. Then click on Quote now. Now you can change the other parameters of your PCB like the number of layers, mask color, thickness, etc. On the right-hand side, you can choose your country and the preferred shipping option. This will show you the lead time and total amount to be paid. I have chosen DHL and my total amount is $26, but if you are a first time customer the prices will go down in the checkout. Then click on Add to Cart and then click on check out now. Now, you can click on upload your Gerber file by clicking on “Upload Gerberᾠand then click on buy. On the next page, you can enter your shipping address and check the final price you have to pay for your PCB. You can then review your order and then click on submit to make the payment. Once your order is confirmed you can sit back and relay for your PCB to arrive at your doorstep. I received my order after a few days and then packaging was neat as shown below. The quality of the PCB was good as always as you can see for yourself in the pictures below. The top side and the bottom side of the board are shown below. Once you get your board, you can proceed with assembling all the components. My finished board looks something like this shown below. Next, you can upload the code and power up the module to check how it is working. The complete code for this project is given at the bottom of this page. The explanation of the code is as follows.

Arduino Code for Adjustable DC Load

The code is pretty simple. At first, we included SPI and LCD header files as well as set the maximum logic voltage, chip selection pins, etc. #include <SPI.h> #include <LiquidCrystal.h> #define SS_PIN 10 #define MAX_VOLT 5.0 // maximum logic voltage #define load_resistor 0.1 // shunt resistor value in Ohms #define opamp_gain 6 // gain of the op-amp #define average 10 // average time This section consists of required program flow-related declarations of integers and variables. Also, we set the associate peripherals pins with Arduino Nano. const int slaveSelectPin = 10; // Chip select pin int number = 0; int increase = A2; // Increase pin int decrease = A3; //decrease pin int current_sense = A0; //current sense pin int voltage_sense = A1; // voltage sense pin int state1 = 0; int state2 = 0; int Set = 0; float volt = 0; float load_current = 0.0; float load_voltage = 0.0; float current = 0.0; float voltage = 0.0; LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // LCD pins This is used for the Setup of LCD and SPI. Also, the pin directions are set over here. void setup() { pinMode(slaveSelectPin, OUTPUT); pinMode(increase, INPUT); pinMode(decrease, INPUT); pinMode(current_sense, INPUT); pinMode(voltage_sense, INPUT); // initialize SPI: SPI.begin(); //set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.print("Digital Load"); lcd.setCursor(0, 1); lcd.print("Circuit Digest"); delay (2000); } It is used for Converting the DAC value. void convert_DAC(unsigned int value) { /*Step Size = 2^n, Therefore 12bit 2^12 = 4096 For 5V reference, the step will be 5/4095 = 0.0012210012210012V or 1mV (approx)*/ unsigned int container ; unsigned int MSB; unsigned int LSB; /*Step: 1, stored the 12 bit data into the container Suppose the data is 4095, in binary 1111 1111 1111*/ container = value; /*Step: 2 Creating Dummy 8 bit. So, by dividing 256, upper 4 bits are captured in LSB LSB = 0000 1111*/ LSB = container/256; /*Step: 3 Sending the configuration with punching the 4 bit data. LSB = 0011 0000 OR 0000 1111. Result is 0011 1111 */ LSB = (0x30) | LSB; /*Step:4 Container still has the 21bit value. Extracting the lower 8 bits. 1111 1111 AND 1111 1111 1111. Result is 1111 1111 which is MSB*/ MSB = 0xFF & container; /*Step:4 Sending the 16bits data by dividing into two bytes. */ digitalWrite(slaveSelectPin, LOW); delay(100); SPI.transfer(LSB); SPI.transfer(MSB); delay(100); // take the SS pin high to de-select the chip: digitalWrite(slaveSelectPin, HIGH); } This section is used for current sensing related operations. float read_current (void){ load_current = 0; for (int a = 0; a < average; a++){ load_current = load_current + analogRead(current_sense); } load_current = load_current / average; load_current = (load_current* MAX_VOLT) / 1024; load_current = (load_current / opamp_gain) / load_resistor; return load_current; } This is used for reading the load voltage. float read_voltage (void){ load_voltage = 0; for (int a = 0; a < average; a++){ load_voltage = load_voltage + analogRead(voltage_sense); } load_voltage = load_voltage / average; load_voltage = ((load_voltage * MAX_VOLT)/1024.0)*6; return load_voltage; } This is the actual loop. Here, switch steps are measured and the data is sent to the DAC. After transmitting the data, the actual current flow and the load voltage is being measured. Both values are also finally printed on the LCD. void loop () { state1 = analogRead(increase); if (state1 > 500){ delay(50); state1 = analogRead(increase); if (state1 > 500){ volt = volt+0.02; } } state2 = analogRead(decrease); if (state2 > 500){ delay(50); state2 = analogRead(decrease); if (state2 > 500){ if (volt == 0){ volt = 0; } else{ volt = volt-0.02; } } } number = volt / 0.0012210012210012; convert_DAC (number); voltage = read_voltage(); current = read_current(); lcd.setCursor(0, 0); lcd.print("Set Value"); lcd.print("="); Set = (volt/2)*10000; lcd.print(Set); lcd.print("mA "); lcd.setCursor(0, 1); lcd.print("I"); lcd.print("="); lcd.print(current); lcd.print("A "); lcd.print(" V"); lcd.print("="); lcd.print(voltage); lcd.print("V"); // lcd.print(load_voltage); //lcd.print("mA "); // delay(1000); //lcd.clear(); }

Testing our Adjustable DC Load

The digital load circuit is soldered and powered up using a 12V power source. I used my 7.4V Lithium battery on the power source side and connected a clamp meter to check how it is working. As you can see when the set current is 300mA the circuit draws 300mA from the battery which is also measured by clamp meter as 310mA. Code #include <SPI.h> #include <LiquidCrystal.h> #define SS_PIN 10 #define MAX_VOLT 5.0 #define load_resistor 0.1 #define opamp_gain 6 #define average 10 const int slaveSelectPin = 10; int number = 0; int increase = A2; int decrease = A3; int current_sense = A0; int voltage_sense = A1; int state1 = 0; int state2 = 0; int Set = 0; float volt = 0; float load_current = 0.0; float load_voltage = 0.0; float current = 0.0; float voltage = 0.0; LiquidCrystal lcd(7, 6, 5, 4, 3, 2); void setup() { // set the slaveSelectPin as an output: pinMode(slaveSelectPin, OUTPUT); pinMode(increase, INPUT); // declare LED as output pinMode(decrease, INPUT); // declare pushbutton as input pinMode(current_sense, INPUT); // pinMode(voltage_sense, INPUT); // // initialize SPI: SPI.begin(); //set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.print("Digital Load"); lcd.setCursor(0, 1); lcd.print("Circuit Digest"); delay (2000); } void convert_DAC(unsigned int value) { /*Step Size = 2^n, Therefore 12bit 2^12 = 4096 For 5V reference, the step will be 5/4095 = 0.0012210012210012V or 1mV (approx)*/ unsigned int container ; unsigned int MSB; unsigned int LSB; /*Step: 1, stored the 12 bit data into the container Suppose the data is 4095, in binary 1111 1111 1111*/ container = value; /*Step: 2 Creating Dummy 8 bit. So, by dividing 256, upper 4 bits are captured in LSB LSB = 0000 1111*/ LSB = container/256; /*Step: 3 Sending the configuration with punching the 4 bit data. LSB = 0011 0000 OR 0000 1111. Result is 0011 1111 */ LSB = (0x30) | LSB; /*Step:4 Container still has the 21bit value. Extracting the lower 8 bits. 1111 1111 AND 1111 1111 1111. Result is 1111 1111 which is MSB*/ MSB = 0xFF & container; /*Step:4 Sending the 16bits data by dividing into two bytes. */ digitalWrite(slaveSelectPin, LOW); delay(100); SPI.transfer(LSB); SPI.transfer(MSB); delay(100); // take the SS pin high to de-select the chip: digitalWrite(slaveSelectPin, HIGH); } float read_current (void){ load_current = 0; for (int a = 0; a < average; a++){ load_current = load_current + analogRead(current_sense); } load_current = load_current / average; load_current = (load_current* MAX_VOLT) / 1024; load_current = (load_current / opamp_gain) / load_resistor; return load_current; } float read_voltage (void){ load_voltage = 0; for (int a = 0; a < average; a++){ load_voltage = load_voltage + analogRead(voltage_sense); } load_voltage = load_voltage / average; load_voltage = ((load_voltage * MAX_VOLT)/1024.0)*6; return load_voltage; } void loop () { state1 = analogRead(increase); if (state1 > 500){ delay(50); state1 = analogRead(increase); if (state1 > 500){ volt = volt+0.02; } } state2 = analogRead(decrease); if (state2 > 500){ delay(50); state2 = analogRead(decrease); if (state2 > 500){ if (volt == 0){ volt = 0; } else{ volt = volt-0.02; } } } number = volt / 0.0012210012210012; convert_DAC (number); voltage = read_voltage(); current = read_current(); lcd.setCursor(0, 0); lcd.print("Set Value"); lcd.print("="); Set = (volt/2)*10000; lcd.print(Set); lcd.print("mA "); lcd.setCursor(0, 1); lcd.print("I"); lcd.print("="); lcd.print(current); lcd.print("A "); lcd.print(" V"); lcd.print("="); lcd.print(voltage); lcd.print("V"); // lcd.print(load_voltage); //lcd.print("mA "); // delay(1000); //lcd.clear(); } Video microcontroller-projects/arduino-smart-restaurant-menu-ordering-menu-ordering-system

Smart Restaurant Menu Ordering System using Arduino

Now day’s automation systems are everywhere whether its home, office or any big industry, all are equipped with automation systems. Restaurants/Hotels are also adopting recent automation trends and are installing robots to deliver food and tablets for taking orders.Using these digital menu cards like tablets, customers can easily select the items. This information will be sent to the kitchen of the Restaurant and also displayed on the display. , TFT display, and 433MHz RF transmitter/receiver module. Here the transmitter section will consist of Arduino Uno, TFT display, and an RF transmitter, using which customers can select the food items and place the order. While the receiver section consists of an Arduino Uno, LCD module, RF receiver, and a Buzzer, which will be installed in the restaurant kitchen to track the order items.

Components Required

Arduino Uno (2) 433MHz RF Transmitter & Receiver 2.4" TFT LCD Touch shield 16*2 LCD Module I2C Module

Interfacing TFT LCD Touch shield with Arduino

2.4" TFT LCD Touch shield is a multicolored Arduino UNO/ Mega compatible TFT display that comes with touch-screen and SD card socket as well. This TFT display module has a bright backlight and a colorful 240X320 pixels display. It also consists of individual RGB pixel control that gives it a much better resolution than the black and white displays. is very simple and explained in the previous tutorial. You only need to mount the TFT display over the Arduino Uno board, as shown in the below image. TFT LCD is very useful in building portable applications like: Arduino Touch Screen Calculator Smart Phone Controlled Digital Code Lock using Arduino Arduino SMART Alarm Clock NeoPixel LED Strip with Arduino and TFT LCD here.

Circuit Diagram

, etc. The circuit diagram for the transmitter and receiver section is given below. and GND pins are connected to 5V and GND pin of Arduino. and GND pin is connected to the 5V and GND pin of Arduino. The positive pin of Buzzer is connected to the digital pin 2 of Arduino, and the negative pin is connected to the GND pin of Arduino. SCL and SDA pins of the I2C module is connected to analog pins A5 & A4 Arduino while VCC and GND pins are connected to 5V and GND pins of Arduino.

Code Explanation

are given at the end of the document. All the libraries used in this project can be downloaded from the given links. RadioHead Library SPFD5408 library is used for TFT display. is a Core graphics library for TFT display. #include <RH_ASK.h> #include <SPI.h> #include <SPFD5408_Adafruit_GFX.h> #include <SPFD5408_Adafruit_TFTLCD.h> #include <SPFD5408_TouchScreen.h> RH_ASK driver; After that define the minimum and maximum calibrated X & Y-axis values for your TFT display. #define TS_MINX 125 #define TS_MINY 85 #define TS_MAXX 965 #define TS_MAXY 905 function is given below: tft.drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color) Where: x0= X co-ordinate of the starting point of rectangular y0= Y coordinate of the starting point of rectangular w = Width of the rectangular h = Height of the Rectangular radius= Radius of the round corner color = Colour of the Rect. function is given below: tft.fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color) tft.fillScreen(WHITE); tft.drawRoundRect(0, 0, 319, 240, 8, WHITE); //Page border tft.fillRoundRect(30, 40, 100, 40, 8, GOLD); tft.drawRoundRect(30, 40, 100, 40, 8, WHITE); //Dish1 tft.fillRoundRect(30, 90, 100, 40, 8, GOLD); tft.drawRoundRect(30, 90, 100, 40, 8, WHITE); //Dish2 tft.fillRoundRect(30, 140, 100, 40, 8, GOLD); //Dish3 tft.drawRoundRect(30, 140, 100, 40, 8, WHITE); is used to set the cursor from where you want to start the text. tft.setCursor(60, 0); tft.setTextSize(3); tft.setTextColor(LIME); tft.print(" Menu"); tft.setTextSize(2); tft.setTextColor(WHITE); tft.setCursor(37, 47); tft.print(" Dish1"); function, send the data to the receiver side every 1 second. void transmit() { driver.send((uint8_t *)msg, strlen(msg)); driver.waitPacketSent(); delay(1000); } function, read the Raw ADC value using the ts.getPoint function. TSPoint p = ts.getPoint(); function to convert the Raw ADC values to Pixel Co-ordinates. p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320); p.y = map(p.y, TS_MAXY, TS_MINY, 0, 240); button and if someone touches the screen between this area then send the message to the receiver side. if (p.x > 180 && p.x < 280 && p.y > 190 && p.y < 230 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { Serial.println("Dish1"); msg = "Dish1"; transmit(); tft.fillRoundRect(30, 40, 100, 40, 8, WHITE); delay(70); tft.fillRoundRect(30, 40, 100, 40, 8, GOLD); tft.drawRoundRect(30, 40, 100, 40, 8, WHITE); tft.setCursor(37, 47); tft.println(" Dish1"); delay(70); } Follow the same procedure for all other buttons. library for establishing an SPI communication between Arduino and RF receiver. #include <RH_ASK.h> #include <SPI.h> // Not actualy used but needed to compile #include <LiquidCrystal_I2C.h> function, continuously check for transmitted messages. And if the receiver module receives a message, then display the message on the LCD module and make a beep sound. if (driver.recv(buf, &buflen)) // Non-blocking { int i; digitalWrite(buzzer, HIGH); delay(1000); digitalWrite(buzzer, LOW);. lcd.print("T1:"); lcd.print((char*)buf);

Testing the Smart Restaurant Project using Arduino

After connecting all the hardware and uploading the code for both the transmitter and receiver section, now it’s time to test the project. To test the project, press a button on the TFT display, it should display the dish name with table number that is T1 on the LCD module connected to the receiver side. If the receiver side LCD doesn’t display anything, then check whether your TFT screen is working or not. This is how you can build a Smart Restaurant Menu Ordering System project using Arduino and TFT display. You can also change the orientation of the screen to add more buttons. is given below. Code #include <RH_ASK.h> #include <SPI.h> // Not actually used but needed to compile #include <SPFD5408_Adafruit_GFX.h> // Core graphics library #include <SPFD5408_Adafruit_TFTLCD.h> // Hardware-specific library #include <SPFD5408_TouchScreen.h> const char *msg ; RH_ASK driver; #define YP A1 // must be an analog pin, use "An" notation! #define XM A2 // must be an analog pin, use "An" notation! #define YM 7 // can be a digital pin #define XP 6 // can be a digital pin #define TS_MINX 125 #define TS_MINY 85 #define TS_MAXX 965 #define TS_MAXY 905 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); #define LCD_CS A3 #define LCD_CD A2 #define LCD_WR A1 #define LCD_RD A0 // optional #define LCD_RESET A4 #define REDBAR_MINX 80 #define GREENBAR_MINX 130 #define BLUEBAR_MINX 180 #define BAR_MINY 30 #define BAR_HEIGHT 250 #define BAR_WIDTH 30 Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); #define BLACK 0x0000 int BLUE = tft.color565(50, 50, 255); #define DARKBLUE 0x0010 #define VIOLET 0x8888 #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #define GREY tft.color565(64, 64, 64); #define GOLD 0xFEA0 #define BROWN 0xA145 #define SILVER 0xC618 #define LIME 0x07E0 void drawHome() { tft.fillScreen(WHITE); tft.drawRoundRect(0, 0, 319, 240, 8, WHITE); //Page border tft.fillRoundRect(30, 40, 100, 40, 8, GOLD); tft.drawRoundRect(30, 40, 100, 40, 8, WHITE); //Dish1 tft.fillRoundRect(30, 90, 100, 40, 8, GOLD); tft.drawRoundRect(30, 90, 100, 40, 8, WHITE); //Dish2 tft.fillRoundRect(30, 140, 100, 40, 8, GOLD); //Dish3 tft.drawRoundRect(30, 140, 100, 40, 8, WHITE); tft.fillRoundRect(10, 190, 190, 40, 8, CYAN); tft.drawRoundRect(10, 190, 190, 40, 8, WHITE); //Call Waiter tft.fillRoundRect(180, 40, 100, 40, 8, GOLD); tft.drawRoundRect(180, 40, 100, 40, 8, WHITE); //Dish4 tft.fillRoundRect(180, 90, 100, 40, 8, GOLD); tft.drawRoundRect(180, 90, 100, 40, 8, WHITE); //Dish5 tft.fillRoundRect(180, 140, 100, 40, 8, GOLD); tft.drawRoundRect(180, 140, 100, 40, 8, WHITE); //Dish6 tft.fillRoundRect(210, 190, 100, 40, 8, GREEN); tft.drawRoundRect(210, 190, 100, 40, 8, WHITE); //Bill tft.setCursor(60, 0); tft.setTextSize(3); tft.setTextColor(LIME); tft.print(" Menu"); tft.setTextSize(2); tft.setTextColor(WHITE); tft.setCursor(37, 47); tft.print(" Dish1"); tft.setCursor(37, 97); tft.print(" Dish2"); tft.setCursor(37, 147); tft.print(" Dish3"); tft.setCursor(23, 197); tft.print(" Call Waiter"); tft.setCursor(187, 47); tft.print(" Dish4"); tft.setCursor(187, 97); tft.print(" Dish5"); tft.setCursor(187, 147); tft.print(" Dish6"); tft.setCursor(227, 197); tft.print(" Bill"); // delay(500); } int oldcolor, currentcolor, currentpcolour; void setup(void) { tft.reset(); tft.begin(tft.readID()); Serial.begin(9600); Serial.println(); Serial.print("reading id..."); delay(500); Serial.println(tft.readID(), HEX); tft.fillScreen(BLACK); tft.setRotation(1); tft.setTextSize(3); tft.setTextColor(WHITE); tft.setCursor(50, 140); tft.print("Loading..."); tft.setTextColor(tft.color565(255, 255, 0)); tft.setCursor(30, 70); tft.print("By:"); tft.setCursor(10, 100); tft.print("CircuitDigest.Com"); for (int i; i < 250; i++) { tft.fillRect(BAR_MINY - 10, BLUEBAR_MINX, i, 10, RED); delay(0.000000000000000000000000000000000000000000000000001); } tft.fillScreen(BLACK); if (!driver.init()) Serial.println("init failed"); drawHome(); pinMode(13, OUTPUT); } #define MINPRESSURE 10 #define MAXPRESSURE 1000 void transmit() { driver.send((uint8_t *)msg, strlen(msg)); driver.waitPacketSent(); delay(1000); } void loop() { digitalWrite(13, HIGH); TSPoint p = ts.getPoint(); digitalWrite(13, LOW); // if sharing pins, you'll need to fix the directions of the touchscreen pins //pinMode(XP, OUTPUT); pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); //pinMode(YM, OUTPUT); if (p.z > ts.pressureThreshhold) { p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320); p.y = map(p.y, TS_MAXY, TS_MINY, 0, 240); if (p.x > 180 && p.x < 280 && p.y > 190 && p.y < 230 && p.z > MINPRESSURE && p.z < MAXPRESSURE) { Serial.println("Dish1"); msg = "Dish1 Ordered"; transmit(); tft.fillRoundRect(30, 40, 100, 40, 8, WHITE); delay(70); tft.fillRoundRect(30, 40, 100, 40, 8, GOLD); tft.drawRoundRect(30, 40, 100, 40, 8, WHITE); tft.setCursor(37, 47); tft.println(" Dish1"); delay(70); } if (p.x > 180 && p.x < 280 && p.y > 140 && p.y < 180) { Serial.println("Dish2"); msg = "Dish2 Ordered"; transmit(); tft.fillRoundRect(30, 90, 100, 40, 8, WHITE); delay(70); tft.fillRoundRect(30, 90, 100, 40, 8, GOLD); tft.drawRoundRect(30, 90, 100, 40, 8, WHITE); tft.setCursor(37, 97); tft.println(" Dish2"); delay(70); } if (p.x > 180 && p.x < 280 && p.y > 90 && p.y < 130) { Serial.println("Dish3"); msg = "Dish3 Ordered"; transmit(); tft.fillRoundRect(30, 140, 100, 40, 8, WHITE); //rgb led delay(70); tft.fillRoundRect(30, 140, 100, 40, 8, GOLD); //rgb led tft.drawRoundRect(30, 140, 100, 40, 8, WHITE); //rgb led tft.setCursor(37, 147); tft.print(" Dish3"); delay(70); } if (p.x > 210 && p.x < 310 && p.y > 40 && p.y < 80) { Serial.println("Call Waiter"); msg = "CallingWaiter"; transmit(); tft.fillRoundRect(10, 190, 190, 40, 8, WHITE); delay(70); tft.fillRoundRect(10, 190, 190, 40, 8, CYAN); tft.drawRoundRect(10, 190, 190, 40, 8, WHITE); tft.setCursor(23, 197); tft.print(" Call Waiter"); delay(70); } if (p.x > 30 && p.x < 130 && p.y > 190 && p.y < 230) { Serial.println("Dish4"); msg = "Dish4 Ordered"; transmit(); tft.fillRoundRect(30, 40, 100, 40, 8, WHITE); delay(70); tft.fillRoundRect(30, 40, 100, 40, 8, GOLD); tft.drawRoundRect(30, 40, 100, 40, 8, WHITE); tft.setCursor(187, 47); tft.print(" Dish4"); delay(70); } if (p.x > 30 && p.x < 130 && p.y > 140 && p.y < 180 ) { Serial.println("Dish5"); msg = "Dish5 Ordered"; transmit(); tft.fillRoundRect(180, 90, 100, 40, 8, WHITE); delay(70); tft.fillRoundRect(180, 90, 100, 40, 8, GOLD); tft.drawRoundRect(180, 90, 100, 40, 8, WHITE); tft.setCursor(187, 97); tft.print(" Dish5"); delay(70); } if (p.x > 30 && p.x < 130 && p.y > 90 && p.y < 130) { Serial.println("Dish6"); msg = "Dish6 Ordered"; transmit(); tft.fillRoundRect(180, 140, 100, 40, 8, WHITE); delay(70); tft.fillRoundRect(180, 140, 100, 40, 8, GOLD); tft.drawRoundRect(180, 140, 100, 40, 8, WHITE); tft.setCursor(187, 147); tft.print(" Dish6"); delay(70); } if (p.x > 10 && p.x < 210 && p.y > 40 && p.y < 80) { Serial.println("Bill"); msg = "Customer Bill"; transmit(); tft.fillRoundRect(210, 190, 100, 40, 8, WHITE); delay(70); tft.fillRoundRect(210, 190, 100, 40, 8, GREEN); tft.drawRoundRect(210, 190, 100, 40, 8, WHITE); tft.setCursor(227, 197); tft.print(" Bill"); delay(70); } } } #include <RH_ASK.h> #include <SPI.h> // Not actualy used but needed to compile #include <LiquidCrystal_I2C.h> //String msg; LiquidCrystal_I2C lcd(0x27, 16, 2); RH_ASK driver; #define buzzer 2 void setup() { Serial.begin(9600); // Debugging only pinMode(buzzer, OUTPUT); lcd.begin(); lcd.clear(); if (!driver.init()) Serial.println("init failed"); } void loop() { uint8_t buf[17]; uint8_t buflen = sizeof(buf); if (driver.recv(buf, &buflen)) // Non-blocking { int i; digitalWrite(buzzer, HIGH); delay(1000); digitalWrite(buzzer, LOW); // Message with a good checksum received, dump it. Serial.print("Message: "); Serial.println((char*)buf); lcd.clear(); lcd.setCursor(0,0); lcd.print("T1:"); lcd.print((char*)buf); } } Video microcontroller-proejcts/arduino-buzz-wire-game

Make a Buzz Wire Game with an Arduino

is also interfaced to display the game status. Both the ends of the maze wire will be connected to the digital pin 2 & 3 of Arduino, and the handle wire is connected to the Ground pin of Arduino. The digital pins are defined as INPUT_PULLUP pins. So when the handle wire touches the maze wire, it changes the digital pins state to low, and the buzzer makes a sound. A diode is connected at the end of the maze wire, so when you go past to that diode and touch the maze wire with round handle wire, only one pin (Pin 3) will go low. In that condition, a congratulation text (Well done) will be displayed on LCD.

Components Required

Arduino Uno Aluminium Wire 16x2 LCD I2C Module Breadboard Buzzer Diode

Circuit Diagram

and GND pin of the I2C module are connected to 5V and GND pin of Arduino. The positive rail of Buzzer is connected to digital pin 4 of Arduino and the negative rail is connected to GND. Cut an aluminum wire and bends it in Zig-Zag shape. Solder a diode at the one end of the wire. Then cut another wire to make a handle and bend one end into a loop. without using an I2C module. Connect the D2 & D3 pins of Arduino to both the ends of Zig-Zag wire and connect the handle wire to the GND pin of Arduino.

Code Explanation

is given at the end of the document. Start your code by including the library file for the LCD module. LiquidCrystal_I2C.h library is used for I2C communication between Arduino and LCD modules. #include <LiquidCrystal_I2C.h> After that, define the Arduino pins for the buzzer, the start point of the wire, and the endpoint of wire. const int startPin = 2; const int endPin = 3; const int buzzer = 4; These variables will be used to save the readings of wire. int start, end_; Defining an INPUT_PULLUP is functionally the same as connecting a ~20k ohm resistor between the pin and +5V. pinMode(buzzer, OUTPUT); pinMode(startPin, INPUT_PULLUP); pinMode(startPin, INPUT_PULLUP); read the status of the wire pins. start = digitalRead(startPin); end_ = digitalRead(endPin); Now compare the readings of wire pins. If both the pins are low it means, you have touched the wire so buzzer will make a sound, and if the start pin of wire is high and endpin is low that means you reached the endpoint. if (start == LOW && end_== LOW ){ digitalWrite(buzzer, HIGH); delay(1000); digitalWrite(buzzer, LOW); lcd.setCursor(0,0); lcd.print("Try Again"); Serial.print("Try Again"); } else if (start == HIGH && end_== LOW){ lcd.setCursor(0,0); lcd.print("Well Done"); Serial.print("Well Done"); }

Testing the Buzz Wire Game

ᾮ A working video and complete code are given below. Code #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); const int startPin = 2; const int endPin = 3; const int buzzer = 4; int start, end_; void setup(void) { Serial.begin(9600); lcd.begin(); lcd.clear(); pinMode(buzzer, OUTPUT); pinMode(startPin, INPUT_PULLUP); pinMode(startPin, INPUT_PULLUP); } void loop(void) { start = digitalRead(startPin); end_ = digitalRead(endPin); Serial.print(start); Serial.print("\n"); Serial.print(end_); if (start == LOW && end_== LOW ){ digitalWrite(buzzer, HIGH); delay(1000); digitalWrite(buzzer, LOW); lcd.setCursor(0,0); lcd.print("Try Again"); Serial.print("Try Again"); } else if (start == HIGH && end_== LOW){ lcd.setCursor(0,0); lcd.print("Well Done"); Serial.print("Well Done"); } delay(500); } Video microcontroller-projects/ac-fan-speed-control-using-arduino-and-triac

AC Fan Speed Control using Arduino and TRIAC

The circuit diagram discussed in this project is only for educational purposes. Be advised that working with 220V AC mains voltage requires extreme precaution and safety procedures should be followed. Do not touch any of the components or wires when the circuit is in operation.

Components Required

Arduino UNO 4N25 (Zero crossing detector) 10k Potentiometer MOC3021 0pto-coupler (0-9)V, 500 mA Stepdown Transformer BT136 TRIAC 230 VAC Axial AC fan Connecting wires Resistors

Working of AC fan control using Arduino

The working can be divided into four different parts. They are as follows 1. Zero-Crossing Detector 2. Phase Angle Controlling circuit 3. Potentiometer to control the Fan speed amount 4. PWM signal Generation circuit

1. Zero-Crossing Detector

point, then the LED turns ON and the transistor will also turn ON with the ground pin connected to the output pin, which makes this pin 0V. Using this pulse, the zero-crossing point can be detected using Arduino.

2. Phase Angle controlling Circuit

will decide the amount of voltage output to the AC motor, which in turn controls the speed of it. Here a BT136 TRIAC is used, which controls the AC voltage as it is a power electronic switch for controlling an AC voltage signal. , follow our previous articles. As shown in the figure above, the TRIAC is triggered at a firing angle of 90 degrees by applying a small gate pulse signal to it. The time “t1ᾠis the delay time which is given as per the dimming requirement. For example, in this case, the firing angle is 90 percent, hence the power output will also be halved and hence the lamp will also glow with half intensity. We know that the frequency of the AC signal is 50 Hz here. So the time period will be 1/f, which is 20ms. For a half cycle, this will be 10ms or 10,000 microseconds. Hence for controlling the power of an AC lamp, the range of “t1ᾠcan be varied from 0-10000 microseconds. is also known as Optoisolator. It is used to maintain isolation between two electrical circuits like DC and AC signals. Basically, it consists of an LED that emits infrared light and the photosensor which detects it. Here a MOC3021 optocoupler is used to control the AC Fan from the microcontroller signals which is a DC signal.

3. Potentiometer to control the Fan Speed

Here a potentiometer is used to vary the speed of AC Fan. We know that a potentiometer is a 3 terminal device that acts as a voltage divider and provides a variable voltage output. This variable analog output voltage is given at the Arduino analog input terminal to set the speed value of the AC fan.

4. PWM Signal Generation Unit

Circuit Diagram

is given below: : I have shown the complete circuit on a breadboard only for the purpose of understanding. You should not use 220V AC supply directly on your breadboard, I have used a dotted board to make the connections as you can see in the image below

Programming the Arduino for AC fan speed control

is given at the bottom of this project. The stepwise explanation of the code is given below. is declared to store the value of speed step. int TRIAC = 6; int speed_val =0; when it detects any interrupts at its pin. void setup() { pinMode(LAMP, OUTPUT); attachInterrupt(digitalPinToInterrupt(3), zero_crossing, CHANGE); } , read the analog value from potentiometer which is connected at A0 and map it to a value range of (10-49). To find out this range we have to do a small calculation. Earlier it is told that each half cycle is equivalent to 10,000 microseconds. So here the dimming will be controlled in 50 steps which is an arbitrary value and can be changed. Here the minimum steps are taken as 10, not Zero because 0-9 steps give approximately the same power output and maximum steps are taken as 49 as it is not recommended practically to take the upper limit (which is 50 in this case). Then each step time can be calculated as 10000/50= 200 microseconds. This will be used in the next part of the code. void loop() { int pot=analogRead(A0); int data1 = map(pot, 0, 1023,10,49); speed_val=data1; } Here the dimming time can be calculated by multiplying the individual step time with no. of steps. Then after this delay time, the TRIAC can be triggered using a small high pulse of 10 microseconds which is sufficient to turn on a TRIAC. void zero_crossing() { int chop_time = (200*speed_val); delayMicroseconds(chop_time); digitalWrite(TRIAC, HIGH); delayMicroseconds(10); digitalWrite(TRIAC, LOW); } is given below. Code int TRIAC = 6; int speed_val=0; void setup() { pinMode(TRIAC, OUTPUT); attachInterrupt(digitalPinToInterrupt(3), zero_crossing, CHANGE); } void zero_crossing() { int chop_time = (200*speed_val); delayMicroseconds(chop_time); digitalWrite(TRIAC, HIGH); delayMicroseconds(10); digitalWrite(TRIAC, LOW); } void loop() { int pot=analogRead(A0); int data1 = map(pot, 0, 1023,10,40); speed_val=data1; } Video microcontroller-projects/arduino-rc-car-using-bldc-motors-and-nrf24l01-rf-module

Fastest Arduino RC Car using Coreless DC Motors and nRF24L01 RF module

projects.

Coreless DC Motor for RC Cars

Just look for 8520 Magnetic Micro Coreless Motor and you will find these. as the brain of our RC car. With these problems sorted out, let’s look at the materials required to build this project.

Materials Required

3.3V Arduino Pro Mini Arduino Nano NRF24L01 ᾠ2pcs Joystick Module SI2302 MOSFET 1N5819 Diode Coreless BLDC Motors AMS1117-3.3V Lithium Polymer battery Resistors, Capacitors, Connecting wires

RF Joystick for RC car using Arduino

you can follow the below Circuit Diagram. The RF Joystick circuit can be powered using the USB port of the nano board. The nRF24L01 module operates only on 3.3V, hence we have used the 3.3V pin on Arduino. I have constructed the circuit on a breadboard and it looks like below, you can also create a PCB for this if required. is pretty simple, we have to read the X value and Y value from our Joystick and send it to the RC car through the nRF24L01. The complete program for this circuit can be found at the bottom of this page. We will not get into the explanation of that since we have already discussed it in the interfacing project link shared above.

Arduino RC Car Circuit Diagram

so that it can work on its own without being controlled externally. However, for the sake of this project we will not be concentrating on it, stay tuned for another project tutorial in which we will try building the “Fastest Line Follower Robotᾮ I have combined both the circuits on a single PCB for the ease of building, you can ignore the IR sensor and Op-amp section for this project. is used to regulate 3.3V for our nRF24L01 and our pro-mini-board. We can also power the Arduino board directly on the raw pin but the on-board 3.3V voltage regulator on pro mini will not be able to supply enough current to our RF modules, hence we have used an external voltage regulator. To drive our two BLDC motor, we have used two SI2302 MOSFETs. It is important to make sure that these MOSFETS can be driven by 3.3V. If you can’t find the exact same part number, you can look for equivalent MOSFETs with the below transfer characteristics The motors can consume peak current as high as 7A (continuous was tested to be 3A with load), hence the MOSFET drain current should be 7A or more and it should turn on completely at 3.3V. As you can see here the MOSFET that we selected can provide 10A even at 2.25V so it’s an ideal choice.

Fabricating PCB for Arduino RC Car

The fun part with the building this project was the PCB Development. The PCB’s here not only forms the circuit but also acts as a Chassis for our Car, so we planned a car looking shape for it with options to easily mount our motors. You can also try designing your own PCB using the circuit above or you can use my PCB design which looks like this below once completed. for this PCB from the link. Once you are ready with the Gerber file, its time to get it fabricated. To get your PCBs easily done by PCBGOGO follow the steps below , sign up if this is your first time. Then, in the PCB Prototype tab enter the dimensions of your PCB, the number of layers and the number of PCB you require. My PCB is 80cm×80cm so the tab looks like this below. button. You will be taken to a page where to set a few additional parameters if required like the material used track spacing etc. But mostly the default values will work fine. The only thing that we have to consider here is the price and time. As you can see the Build Time is only 2-3 days and it just costs only $5 for our PSB. You can then select a preferred shipping method based on your requirements. and proceed with the payment. To make sure the process is smooth PCBGOGOverifies if your Gerber file is valid before proceeding with the payment. This way you can sure that your PCB is fabrication friendly and will reach you as committed.

Assembling the PCB

After the board was ordered, it reached me after some days though courier in a neatly labeled well-packed box and like always the quality of the PCB was awesome. I am sharing a few pictures of the boards below for you to judge. I turned on my soldering rod and started assembling the Board. Since the Footprints, pads, vias, and silkscreen are perfect of the right shape and size, I had no problem assembling the board. The board was ready in just 10 minutes from the time of unpacking the box. are shown below.

3D Printing Wheels and Motor Mount

I have used Cura to slice my models and printed them using Tevo Terantuala with no supports and 0% infill for reducing weight. You can alter the setting as suited for our printer. Since the motors rotate very fast, I found it tough to design a wheel that will fit snug and tight to the motor shaft. Hence I decided to use the drone blades inside the wheel as you can see below I found this to be more reliable and sturdy, however, do experiment with different wheel designs and let me know in the comment section what worked for you.

Programming the Arduino

The complete program (both Arduino nano and pro mini) for this project can be found at the bottom of this page. The explanation of your RC program is as follows We start the program by including the required header file. Note that, the nRF24l01 module requires a library to be added to your Arduino IDE, you can download RF24 Library from Github using this link. Apart from that, we have already defined the minimum speed and maximum speed for our robot. The minimum and maximum range are 0 to 1024 respectively. #define min_speed 200 #define max_speed 800 #include <SPI.h> #include "RF24.h" RF24 myRadio (7, 8); Then inside the setup function, we initialize our nRF24L01 module. We have used the 115 bands since it is not congested and has set the module to operate with low power, you can also play around with these settings. void setup() { Serial.begin (9600); myRadio.begin(); myRadio.setChannel(115); //115 band above WIFI signals myRadio.setPALevel(RF24_PA_MIN); //MIN power low rage myRadio.setDataRate( RF24_250KBPS ) ; //Minimum speed } Next in the main loop function, we will only execute the ReadData function with which we will be constantly reading the value sent from our Transmitter joystick module. Note that the pipe address mentioned in the program should be the same as the one mentioned in the transmitter program. We have also printed the value that we receive for debugging purposes. Once the value is successfully read we will execute the Control Car function to control our RC car based on the value received from the Rf module. void ReadData() { myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //Which pipe to read, 40 bit Address myRadio.startListening(); //Stop Transminting and start Reveicing if ( myRadio.available()) { while (myRadio.available()) { myRadio.read( &data, sizeof(data) ); } Serial.print("\nReceived:"); Serial.println(data.msg); received = data.msg; Control_Car(); } } Inside the Control Car function, we will control motors connected to the PWM pins using the analog write function. In our transmitter program we have converted the Analog values from A0 and A1 pin of Nano to 1 to 10, 11 to 20, 21 to 30 and 31 to 40 for controlling the car in forward, reverse, left and right respectively. The below program is used to control the robot in a forward direction if (received>=1 && received <=10) // Move Forward { int PWM_Value = map (received, 1, 10, min_speed, max_speed); analogWrite(R_MR,PWM_Value); analogWrite(L_MR,PWM_Value); } Similarly, we can also write three more functions for reverse, left, and right control as shown below. if (received>=11 && received <=20) // Break { int PWM_Value = map (received, 11, 20, min_speed, max_speed); analogWrite(R_MR,0); analogWrite(L_MR,0); } if (received>=21 && received <=30) // Turn left { int PWM_Value = map (received, 21, 30, min_speed, max_speed); analogWrite(R_MR,PWM_Value); analogWrite(L_MR,0); } if (received>=31 && received <=40) // Turn Right { int PWM_Value = map (received, 31, 40, min_speed, max_speed); analogWrite(R_MR,0); analogWrite(L_MR,PWM_Value); }

Working of Arduino RC Car

After you are done with the code, upload it to your pro-mini-board. Remove the battery and your board through the FTDI module for testing. Launch your code, open serial battery and you should receive the value from your transmitter Joystick module. Connect your battery and your motors should also start to rotate. to get quick answers for your other technical questions. Code RF Remote Joystick /*Code to transmit RF values to Arduino * * Pin Conections * CE - 7 MISO - 12 MOSI - 11 SCK - 13 CS - 8 A0 - JoyX A1 - JoyY */ #include <SPI.h> #include "RF24.h" RF24 myRadio (7, 8); struct package { int msg = 0; }; byte addresses[][6] = {"0"}; typedef struct package Package; Package data; void setup() { Serial.begin(9600); myRadio.begin(); myRadio.setChannel(115); //115 band above WIFI signals myRadio.setPALevel(RF24_PA_MAX); //MAX power long rage myRadio.setDataRate( RF24_250KBPS ) ; //Minimum speed delay(500); Serial.print("Remote Initialized"); } int forward; int reverse; int left; int right; void loop() { int xValue = analogRead(A0); //Read JoyX value int yValue = analogRead(A1); //Read JoyY Value //Serial.print(xValue); Serial.print(" , "); Serial.println(yValue); if (xValue>560 && xValue<1000) // Filter JoyX for up { forward = map (xValue, 560, 1000, 1, 10); //Convert Joyx-up to 0-10 //Serial.print("F="); Serial.println(forward); data.msg = forward; WriteData(); delay(50); } if (xValue<500 && xValue > 10) // Filter JoyX for break { reverse = map (xValue, 10, 500, 20, 11); //Convert JoyX-down to 11-20 //Serial.print("B="); Serial.println(reverse); data.msg = reverse; WriteData(); delay(50); } else if (yValue>600 && yValue<1000) // Filter JoyY for right { right = map (yValue, 600, 1000, 21, 30); //Convert JoyY-right to 21-30 //Serial.print("R="); Serial.println(right); data.msg = right; WriteData(); delay(50); } else if (yValue<450 && yValue > 10) // Filter JoyY for left { left = map (yValue, 10, 450, 40, 31); //Convert JoyY-left to 31-40 //Serial.print("L="); Serial.println(left); data.msg = left; WriteData(); delay(50); } /* else { Serial.println("Rest"); data.msg = 0; WriteData(); delay(50); } */ } void WriteData() { myRadio.stopListening(); //Stop Receiving and start transminitng myRadio.openWritingPipe( 0xF0F0F0F0AA); //Sends data on this 40-bit address myRadio.write(&data, sizeof(data)); //Serial.print("\nSent:"); //Serial.println(data.msg); delay(50); } void ReadData() { myRadio.openReadingPipe(1, 0xF0F0F0F066); // Which pipe to read, 40 bit Address myRadio.startListening(); //Stop Transminting and start Reveicing if ( myRadio.available()) { while (myRadio.available()) { myRadio.read( &data, sizeof(data) ); } Serial.print("\nReceived:"); Serial.println(data.msg); } } BLDC Motor /*CE - 7 MISO - 12 MOSI - 11 SCK - 13 CS - 8 Recently tested with nano */ /*PIN DEFANITIONS*/ #define R_IR 3 #define L_IR 4 #define L_MR 5 #define R_MR 6 #define min_speed 200 #define max_speed 800 #include <SPI.h> #include "RF24.h" RF24 myRadio (7, 8); struct package { int msg; }; typedef struct package Package; Package data; byte addresses[][6] = {"0"}; void setup() { pinMode(R_IR, INPUT); pinMode(L_IR, INPUT); pinMode(L_MR, OUTPUT); pinMode(R_MR, OUTPUT); Serial.begin (9600); myRadio.begin(); myRadio.setChannel(115); //115 band above WIFI signals myRadio.setPALevel(RF24_PA_MIN); //MIN power low rage myRadio.setDataRate( RF24_250KBPS ) ; //Minimum speed } int received; void loop() { ReadData(); } void Control_Car() { if (received>=1 && received <=10) // Move Forward { int PWM_Value = map (received, 1, 10, min_speed, max_speed); analogWrite(R_MR,PWM_Value); analogWrite(L_MR,PWM_Value); } if (received>=11 && received <=20) // Break { int PWM_Value = map (received, 11, 20, min_speed, max_speed); analogWrite(R_MR,0); analogWrite(L_MR,0); } if (received>=21 && received <=30) // Turn Right { int PWM_Value = map (received, 21, 30, min_speed, max_speed); analogWrite(R_MR,PWM_Value); analogWrite(L_MR,0); } if (received>=31 && received <=40) // Turn Right { int PWM_Value = map (received, 31, 40, min_speed, max_speed); analogWrite(R_MR,0); analogWrite(L_MR,PWM_Value); } } void ReadData() { myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //Which pipe to read, 40 bit Address myRadio.startListening(); //Stop Transminting and start Reveicing if ( myRadio.available()) { while (myRadio.available()) { myRadio.read( &data, sizeof(data) ); } Serial.print("\nReceived:"); Serial.println(data.msg); received = data.msg; Control_Car(); } else //If not data from RF { //analogWrite(R_MR,0); //analogWrite(L_MR,0); } } void WriteData() { myRadio.stopListening(); //Stop Receiving and start transminitng myRadio.openWritingPipe(0xF0F0F0F066);//Sends data on this 40-bit address myRadio.write(&data, sizeof(data)); Serial.print("\nSent:"); Serial.println(data.msg); delay(300); } Video microcontroller-projects/arduino-based-water-flow-sensor

Measuring water Flow Rate and Volume using Arduino and Flow Sensor

where we need to monitor and control the flow of liquids. , which uses a hall effect to sense the flow rate of the liquid.

Components Required

Water Flow Sensor Arduino UNO LCD (16x2) Connector with internal threading Connecting wires Pipe

YFS201 Water Flow Sensor

The sensor has 3 wires RED, YELLOW, and BLACK as shown in the figure below. The red wire is used for supply voltage which ranges from 5V to 18V and the black wire is connected to GND. The yellow wire is used for output(pulses), which can be read by an MCU. The water flow sensor consists of a pinwheel sensor that measures the quantity of liquid that has passed through it. is simple to understand. The water flow sensor works on the principle of hall effect. Hall effect is the production of the potential difference across an electric conductor when a magnetic field is applied in the direction perpendicular to that of the flow of current. The water flow sensor is integrated with a magnetic hall effect sensor, which generates an electric pulse with every revolution. Its design is in such a way that the hall effect sensor is sealed off from the water, and allows the sensor to stay safe and dry. The picture of the YFS201 sensor module alone is shown below. To connect with the pipe and water flow sensor, I used two connectors with a female thread as shown below. the maximum current it draws at 5V is 15mA, and the working flow rate is 1 to 30 liters/minute.When the liquid flows through the sensor, it makes contact with the fins of the turbine wheel, which is placed in the path of the flowing liquid. The shaft of the turbine wheel is connected to a hall effect sensor. Due to this, whenever water flows through the valve it generates pulses. Now, all we have to do is to measure the time for the pluses or to count the number of pulses in 1 second and then calculate the flow rates in liter per hour (L/Hr) and then use simple conversion formula to find the volume of the water which had passed through it. To measure the pulses, we are going to use Arduino UNO. The pic below shows you the pinout of the water flow sensor.

Circuit Diagram

Article. The connection of the water flow sensor and LCD(16x2) with the Arduino is given below in table format. Note that the pot is connected in between 5V and GND and pot’s pin 2 is connected with the V0 pin of the LCD.
1Red Wire5V
2BlackGND
3YellowA0
1VssGND(ground rail of breadboard)
2VDD5V (Positive rail of the breadboard)
3 For connection with V0 check the above note
4RS12
5RWGND
6E11
7D79
8D6 to D33 to 5
I used a breadboard, and once the connection was done as per the circuit diagram shown above, my testing set-up looked something like this.

Arduino Water Flow Sensor Code

is given at the bottom of the page. The explanation of the code is as follows. We are using the header file of the LCD, which eases our interfacing the LCD with Arduino, and the pins 12,11,5,4,3,9 are allotted for data transfer between LCD and Arduino. The sensor's output pin is connected to pin 2 of Arduino UNO. volatile int flow_frequency; // Measures flow sensor pulses // Calculated litres/hour float vol = 0.0,l_minute; unsigned char flowsensor = 2; // Sensor Input unsigned long currentTime; unsigned long cloopTime; #include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 9); void flow () // Interrupt function { flow_frequency++; } In the void setup, we tell the MCU that the pin 2 of the Arduino UNO is used as INPUT by giving command pinMode(pin, OUTPUT). By using attachInterrupt command, whenever there is a rise in the signal at pin 2, the flow function is called. This increases the count in the variable flow_frequency by 1. The current time and cloopTime are used for the code to run in every 1 second. void setup() { pinMode(flowsensor, INPUT); digitalWrite(flowsensor, HIGH); Serial.begin(9600); lcd.begin(16, 2); attachInterrupt(digitalPinToInterrupt(flowsensor), flow, RISING); // Setup Interrupt lcd.clear(); lcd.setCursor(0,0); lcd.print("Water Flow Meter"); lcd.setCursor(0,1); lcd.print("Circuit Digest"); currentTime = millis(); cloopTime = currentTime; } The if function ensures that for every one second the code inside it runs. In this way, we can count the number of frequencies produces by the water flow sensor per second. The flow rate pulse characteristics from the datasheet are given that frequency is 7.5 multiplied by flow rate. So the flow rate is frequency / 7.5. After finding flow rate which is in liters/minute, divide it by 60 to convert it into liter/sec. This value is added to the vol variable for every one second. void loop () { currentTime = millis(); // Every second, calculate and print litres/hour if(currentTime >= (cloopTime + 1000)) { cloopTime = currentTime; // Updates cloopTime if(flow_frequency != 0){ // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min. l_minute = (flow_frequency / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour lcd.clear(); lcd.setCursor(0,0); lcd.print("Rate: "); lcd.print(l_minute); lcd.print(" L/M"); l_minute = l_minute/60; lcd.setCursor(0,1); vol = vol +l_minute; lcd.print("Vol:"); lcd.print(vol); lcd.print(" L"); flow_frequency = 0; // Reset Counter Serial.print(l_minute, DEC); // Print litres/hour Serial.println(" L/Sec"); } The else function works when there is no output from the water flow sensor within the given time span. else { lcd.clear(); lcd.setCursor(0,0); lcd.print("Rate: "); lcd.print( flow_frequency ); lcd.print(" L/M"); lcd.setCursor(0,1); lcd.print("Vol:"); lcd.print(vol); lcd.print(" L"); }

Arduino Water Flow Sensor Working

In our project, we connected the water flow sensor to a pipe. If the output valve of the pipe is closed, the output of the water flow sensor is zero (No pulses). There will be no interrupt signal seen at the pin 2 of the Arduino, and the count of the flow_frequency will be zero. In this condition, the code which is written inside the else loop will work. If the output valve of the pipe is opened. The water flows through the sensor, which in turn rotates the wheel inside the sensor. In this condition, we can observe pulses, which are generated from the sensor. These pulses will act as an interrupt signal to the Arduino UNO. For every interrupt signal(rising edge), the count of the flow_frequency variable will be increased by one. The current time and cloopTIme variable ensure that for every one second the value of the flow_frequency is taken for calculation of flow rate and volume. After the calculation is finished, the flow_frequency variable is set to zero and the whole procedure is started from the beginning. for other technical questions. Code /* YFᾠS201 Water Flow Sensor Water Flow Sensor output processed to read in litres/hour Adaptation Courtesy: hobbytronics.co.uk */ volatile int flow_frequency; // Measures flow sensor pulses // Calculated litres/hour float vol = 0.0,l_minute; unsigned char flowsensor = 2; // Sensor Input unsigned long currentTime; unsigned long cloopTime; #include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 9); void flow () // Interrupt function { flow_frequency++; } void setup() { pinMode(flowsensor, INPUT); digitalWrite(flowsensor, HIGH); // Optional Internal Pull-Up Serial.begin(9600); lcd.begin(16, 2); attachInterrupt(digitalPinToInterrupt(flowsensor), flow, RISING); // Setup Interrupt lcd.clear(); lcd.setCursor(0,0); lcd.print("Water Flow Meter"); lcd.setCursor(0,1); lcd.print("Circuit Digest"); currentTime = millis(); cloopTime = currentTime; } void loop () { currentTime = millis(); // Every second, calculate and print litres/hour if(currentTime >= (cloopTime + 1000)) { cloopTime = currentTime; // Updates cloopTime if(flow_frequency != 0){ // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min. l_minute = (flow_frequency / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour lcd.clear(); lcd.setCursor(0,0); lcd.print("Rate: "); lcd.print(l_minute); lcd.print(" L/M"); l_minute = l_minute/60; lcd.setCursor(0,1); vol = vol +l_minute; lcd.print("Vol:"); lcd.print(vol); lcd.print(" L"); flow_frequency = 0; // Reset Counter Serial.print(l_minute, DEC); // Print litres/hour Serial.println(" L/Sec"); } else { Serial.println(" flow rate = 0 "); lcd.clear(); lcd.setCursor(0,0); lcd.print("Rate: "); lcd.print( flow_frequency ); lcd.print(" L/M"); lcd.setCursor(0,1); lcd.print("Vol:"); lcd.print(vol); lcd.print(" L"); } } } Video microcontroller-projects/arduino-solenoid-door-lock-using-rfid

Arduino Solenoid Door Lock using RFID

, follow the link.

Components Required

Arduino Uno RFID-RC522 Module 12v Solenoid Lock Relay Module Hall Effect Sensor 10k Resistor Buzzer

Solenoid Lock

A solenoid lock works on the electronic-mechanical locking mechanism. This type of lock has a slug with a slanted cut and a good mounting bracket. When the power is applied, DC creates a magnetic field that moves the slug inside and keeps the door in the unlocked position. The slug will retain its position until the power is removed. When the power is disconnected the slug moves outside and locks the door. It doesn’t use any power in a locked state. To drive the solenoid lock you would need a power source that can give 12V @ 500mA.

Circuit Diagram

is given below. The solenoid lock is connected to Arduino through the relay module.
RFID PinArduino Uno Pin
SDADigital 10
SCKDigital 13
MOSIDigital 11
MISODigital 12
IRQUnconnected
GNDGND
RSTDigital 9
3.3V3.3V
Hall Effect Sensor PinArduino Uno Pin
5V5V
GNDGND
OUT3
After soldering all the components on the perf board according to the circuit diagram, it looks like the below image:

Code Explanation

is given at the end of the document. Here we are explaining this code step by step for better understanding. Start the code by including all the required libraries. Here it only requires two libraries, one for SPI communication between Arduino and RFID, and second for the RFID module. Both the libraries can be downloaded from the links given below: SPI.h MFRC522.h Now define the pins for Buzzer, Solenoid Lock and RFID Module int Buzzer = 4; const int LockPin = 2; #define SS_PIN 10 #define RST_PIN 9 Then define the Lock pin and Buzzer pin as an output, and Hall Effect sensor pin as input and initiate the SPI communication. pinMode(LockPin, OUTPUT); pinMode(Buzzer, OUTPUT); pinMode(hall_sensor, INPUT); SPI.begin(); // Initiate SPI bus mfrc522.PCD_Init(); // Initiate MFRC522 , read the hall sensor values, and when it becomes low, close the door. state = digitalRead(hall_sensor); Serial.print(state); delay(3000); if(state==LOW){ digitalWrite(LockPin, LOW); Serial.print("Door Closed"); digitalWrite(Buzzer, HIGH); delay(2000); digitalWrite(Buzzer, LOW);} given at the end. if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } // Select one of the cards if ( ! mfrc522.PICC_ReadCardSerial()) { return; } //Show UID on serial monitor String content= ""; byte letter; for (byte i = 0; i < mfrc522.uid.size; i++) { content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ")); content.concat(String(mfrc522.uid.uidByte[i], HEX)); } Serial.println(); Serial.print("Message : "); content.toUpperCase(); if (content.substring(1) == "60 4E 07 1E" ) //change here the UID of the card/cards that you want to give access { digitalWrite(LockPin, HIGH); Serial.print("Door Unlocked"); digitalWrite(Buzzer, HIGH); delay(2000); digitalWrite(Buzzer, LOW); } else { Serial.println("You are not Authorised"); digitalWrite(Buzzer, HIGH); delay(2000); digitalWrite(Buzzer, LOW); } }

Testing the RFID Solenoid Lock

Once you are ready with the code and hardware, you can start testing the Solenoid Door Lock project. Here we have soldered all the components on the perf board so that it can be mounted on the door easily. So to test it, mount the perf board on the door frame and magnet on the door so that it can detect the door movement. The below picture shows how the magnet and Hall sensors are fixed on the door. Now scan your authorized RFID card to open the door lock. The solenoid door lock will remain open until the Hall Effect sensor output is high. Now when the door again reaches near to the Hall sensor while closing, Hall Effect sensor status will change to Low due to the magnetic field (generated by the magnet attached at the door), and the lock will be closed again. Instead of using the Hall Effect sensor, you can introduce a delay to keep the door open for a defined time. Code #include <SPI.h> #include <MFRC522.h> int hall_sensor = 3; int state,lockread; int Buzzer = 4; const int LockPin = 2; #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance. void setup() { Serial.begin(9600); // Initiate a serial communication pinMode(LockPin, OUTPUT); pinMode(Buzzer, OUTPUT); pinMode(hall_sensor, INPUT); SPI.begin(); // Initiate SPI bus mfrc522.PCD_Init(); // Initiate MFRC522 //Serial.println("Approximate your card to the reader..."); // Serial.println(); digitalWrite(LockPin, LOW); } void readsensor() { lockread = digitalRead(LockPin); state = digitalRead(hall_sensor); //Serial.print(lockread); //Serial.print(state); // delay(2000); } void loop() { readsensor(); sensor(); // Look for new cards if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } // Select one of the cards if ( ! mfrc522.PICC_ReadCardSerial()) { return; } //Show UID on serial monitor String content= ""; byte letter; for (byte i = 0; i < mfrc522.uid.size; i++) { content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ")); content.concat(String(mfrc522.uid.uidByte[i], HEX)); } //Serial.println(); //Serial.print("Message : "); content.toUpperCase(); if (content.substring(1) == "60 4E 07 1E" ) //change here the UID of the card/cards that you want to give access { digitalWrite(LockPin, HIGH); Serial.print("Door Unlocked"); digitalWrite(Buzzer, HIGH); delay(2000); digitalWrite(Buzzer, LOW); sensor(); } else { Serial.println("You are not Authorised"); digitalWrite(Buzzer, HIGH); delay(2000); digitalWrite(Buzzer, LOW); } } void sensor() { readsensor(); if (lockread == HIGH){ readsensor(); if(state==LOW){ digitalWrite(LockPin, LOW); Serial.print("Door Closed"); digitalWrite(Buzzer, HIGH); delay(2000); digitalWrite(Buzzer, LOW); } } } Video microcontroller-projects/interface-adxl345-accelerometer-with-arduino-uno

Interfacing ADXL345 Accelerometer with Arduino UNO

(IMU) to find the orientation, position, and velocity. which is used to measure the acceleration or change in velocity in x, y, and z-axis. These small sensors are used in cars and bikes to detect accidents to deploy the airbags and are also used in mobile phones for a variety of applications like compass and location tracking. We used the accelerometer to build various useful applications which you can check at below links: Vehicle Accident Alert System Hand Gesture Controlled Robot using Arduino Earthquake Detector Alarm Ping Pong Game

Types of Accelerometer Sensors

sensors available in the market. They can be classified on the basis of precision, power consumption, and interfacing. All these sensors are portable and can be fitted in any kind of device like wearables. These sensors measure acceleration in 3-axis (x,y,z). Some widely used Sensors are: ADXL335 ADXL345 ADXL356 These accelerometer sensors are very popular and apart from these three, there are many other accelerometer sensors like ADXL354, ADXL355, ADXL372, etc. Let’s see the difference between these sensors.
ADXL356ADXL345ADXL335
Range±10g to ±40g±16g±3g, small range with precise readings
InterfaceAnalogSPI, I2CAnalog
Power ConsumptionLow Typical: 150μLow Typical: 140μStandard Typical: 350μ
PricingHighLowLowest
Among the above three, ADXL345 is easy to interface because of its digital nature. But its programming is difficult as it works on the SPI/I2C protocol. ADXL345 can measure static and dynamic accelerations and suitable for mobile applications. Also, these sensors are laboratory calibrated and don’t require any further calibrations. sensor to interface it with Arduino Uno.

Components Required

Arduino UNO ADXL345 Accelerometer Male-female wires Breadboard

Circuit Diagram

is given below: Connect A4 pin (SDA) of Arduino -> SDA pin of adxl345 Connect A5 pin (SCL) of Arduino -> SCL pin of adxl345 Connect GND of Arduino -> GND pin of adxl345 Connect 5V of Arduino -> Vcc of adxl345

ADXL345Arduino Code Explanation

Adafruit ADXL345 Adafruit Unified sensor Search for Adafruit ADXL345 and install it. Similarly, search for Adafruit Unified sensor and install. 1. First, include all the required libraries header files to support the functionality of the sensor. Here we are also using wire library for I2C communication. #include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_ADXL345_U.h> to use the various functions of the ADXL345 Arduino library. Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(); function if it returns false then print a message that no valid sensor found. void setup() { Serial.begin(9600); if(!accel.begin()) { Serial.println("No valid sensor found"); while(1); } } function. void loop() { sensors_event_t event; accel.getEvent(&event); Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print(""); Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print(""); Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print(""); Serial.println("m/s^2 "); delay(500); } is given at the end of this article.

Testing ADXL345 accelerometer Arduino Interfacing

Finally, connect the ADXL345 sensor with Arduino UNO properly and upload the code in the Arduino Uno board. Then open Serial monitor and you will see acceleration readings in x, y, z-axis as shown below. Try to move the sensor slowly in all the directions and observe the readings. So this is how an Accelerometer can be used with Arduino UNO to detect the variations in x, y, and z-axis. with a video that is given below. Code #include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_ADXL345_U.h> Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(); void setup(void) { Serial.begin(9600); if(!accel.begin()) { Serial.println("No valid sensor found"); while(1); } } void loop(void) { sensors_event_t event; accel.getEvent(&event); Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print(" "); Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print(" "); Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print(" "); Serial.println("m/s^2 "); delay(500); } Video microcontroller-projects/esp32-dual-core-programming-using-arduino-ide

ESP32 Dual Core Programming with Arduino IDE

has two 32-bit Tensilica Xtensa LX6 microprocessors which makes it a powerful dual-core (core0 and core1) microcontroller. It is available in two variants single-core and dual-core. But the dual-core variant is more popular because there is no significant price difference. to perform two operations simultaneously. Here the first task will be to blink the onboard LED and the second task will be to fetch the temperature data from the DHT11 sensor. Let’s first see the advantages of a multi-core processor over a single core.

Advantages of Multi-core processor

Multi-core processors are useful when there are more than 2 processes to work simultaneously. As work is distributed among different cores, its speed increases and multiple processes can be finished at the same time. Power consumption can be reduced because when any core is in idle mode than it can be used to shut down the peripherals that are not in use at that time. Dual-core processors have to switch between different threads less often than single-core processors because they can handle two at once instead of one at a time.

ESP32 and FreeRTOS

ESP32 board already has FreeRTOS firmware installed on it. FreeRTOS is an open-source Real-time Operating system which is very useful in multitasking. RTOS helps in managing the resources and maximizing the system performance. FreeRTOS has many API functions for different purposes and using these APIs, we can create tasks and make them run on different cores. We will try to use some APIs in our code to build a multitasking application that will run on both the cores.

Finding the ESP32 core ID

To know the Core ID on which the code is running, there is an API function xPortGetCoreID() function to know the core ID on which these functions are running. You can test this API by uploading the below sketch: void setup() { Serial.begin(115200); Serial.print("setup() function running on core: "); Serial.println(xPortGetCoreID()); } void loop() { Serial.print("loop() function running on core: "); Serial.println(xPortGetCoreID()); } After uploading the above sketch, open the Serial monitor and you will find that both the functions are running on core1 as shown below.

ESP32Dual Core Programming

Arduino IDE supports FreeRTOS for ESP32 and FreeRTOS APIs allow us to create tasks that can run independently on both the cores. The task is the piece of code that performs some operation on the board like blinking led, sending temperature, etc. The below function is used to create tasks that can run on both the cores. In this function, we have to give some arguments like a priority, core id, etc. Now, follow the below steps to create task and task function. function. Here we will create two tasks, one for blinking LED after every 0.5 seconds and another task is to get temperature reading after every 2 seconds. : Function name to implement the task (task1) Any name given to the task (“task1ᾬ etc) Stack size allotted to the task in words(1 word=2bytes) Task input parameter (can be NULL) Priority of the task ( 0 is the lowest priority) Task handle (can be NULL) Core id where the task will run (0 or 1) by giving all the arguments in xTaskCreatePinnedToCore()function. xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, NULL, 0); argument. xTaskCreatePinnedToCore(Task2code, "Task2", 10000, NULL, 1, NULL, 1); You can change the priority and stack size depending on the complexity of the task. function. These functions contain the code for the required task. In our case, the first task will blink the led and another task will fetch the temperature. So make two separate functions for each task outside the void setup function. after 0.5 seconds is implemented as shown below. Void Task1code( void * parameter) { Serial.print("Task1 running on core "); Serial.println(xPortGetCoreID()); for(;;) {//infinite loop digitalWrite(led, HIGH); delay(500); digitalWrite(led, LOW); delay(500); } } void Task2code( void * pvParameters ){ Serial.print("Task2 running on core "); Serial.println(xPortGetCoreID()); for(;;){ float t = dht.readTemperature(); Serial.print("Temperature: "); Serial.print(t); delay(2000); } } function also. Now the coding part is over, so just upload the code using Arduino IDE by choosing the ESP32 board in Tools menu. Make sure you have connected the DHT11 sensor to pin D13 of ESP32. Now the results can be monitored on Serial Monitor or Arduino IDE as shown below: Complex applications like real-time system can be built by running multiple tasks simultaneously using dual cores of ESP32. Code #include "DHT.h" #define DHTPIN 13 #define DHTTYPE DHT11 const int led = 2; DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(115200); pinMode(led, OUTPUT); dht.begin(); xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, NULL, 1); delay(500); xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, NULL, 0); delay(500); } void Task1code( void * pvParameters ){ Serial.print("Task1 running on core "); Serial.println(xPortGetCoreID()); for(;;){ digitalWrite(led, HIGH); delay(300); digitalWrite(led, LOW); delay(300); } } void Task2code( void * pvParameters ){ Serial.print("Task2 running on core "); Serial.println(xPortGetCoreID()); for(;;){ float h = dht.readHumidity(); float t = dht.readTemperature(); float f = dht.readTemperature(true); Serial.print("Temperature: "); Serial.print(t); Serial.print(" *C \n "); if (isnan(h) || isnan(t) || isnan(f)) { Serial.println("Failed to read from DHT sensor!"); return; } delay(2000); } } void loop() { } Video microcontroller-projects/arduino-fm-radio-using-rda5807

Arduino Based FM Radio using RDA5807

to catch those radio signals and transfer them to audio signals. In our previous tutorials, we also builtfew other FM Transmitters and Receivers that are listed below. Raspberry Pi FM Transmitter Raspberry Pi FM Receiver Radio FM Transmitter circuit FM Transmitter circuit without Inductor , sounds interesting right? So, let’s get started.

FM Radio General Working

in this project, which simplifies our circuit.

Components Required

Arduino Nano RDA5807 receiver Audio Amplifier Connecting wires Pot ᾠ100K Perf Board

RDA5807Receiver

diagram for the IC is given below. to communicate with the MCU, and the interface begins with starts condition, a command byte, and data bytes. The RDA5807 has 13 16-bit registers, each performing a particular function. The register addresses start with 00H, which is allotted to chip ID and ends with 0FH. In all 13 registers, some bits are reserved while some are R/W. Each register performs tasks like varying volume, changing channels, etc depending upon the bits assigned to them. We cannot directly use the module when connecting it to a circuit as the pins are closed by. So, I used a perf board and some male pins and soldered the module’s each pin to each male pin as shown in the pic below.

Audio Amplifier

Arduino FM Receiver Circuit Diagram

I did little changes in the amplifier. Instead of using two potentiometers in the amplifier, I used only one. I interchanged the pot, which is used to change the Gain, with a resistor. So now our project has two potentiometers one to tune, and one to change the volume. The potentiometer, which is used to tune the channel is connected with the Arduino nano. The center pin of the pot is connected to the A0 pin of the Arduino nano, and either of the remaining two pins is connected to the 5V and the other is connected to the GND. Another pot is used to control the volume of the radio and is connected as shown in the above fig. The pin A4 and A5 of the Arduino are connected to SDA and SCL pin of the RDA5807M. keep in mind that the receiver module works only on 3.3V. So, connect the 3v3 pin of the Nano to the VCC pin of the receiver module. Once the connections were made my set-up looked like this

Arduino FM Radio Code Explanation

The code will initialize the receiver module and then sets the channel with the preset frequency. When the value read by the nano at the A0 pin changes (by changing pot) the frequency changes which in turn changes the channel. The full code is given at the end of the page. We begin our program by adding the required wire library for communicating with RDA5807. Then, in the variable “channelᾠwe set the value of the channel. Whenever the radio starts it will get tuned to this channel automatically. #include <Wire.h> uint16_t channel = 187; Next, we will load bytes to each register on our RDA5807 IC to set our initial configuration. At this point, we are resetting the receiver. uint8_t boot_config[] = { /* register 0x02 */ 0b11000001, 0b00000011, /* register 0x03 */ 0b00000000, 0b00000000, /* register 0x04 */ 0b00001010, 0b00000000, /* register 0x05 */ 0b10001000, 0b00001111, /* register 0x06 */ 0b00000000, 0b00000000, /* register 0x07 */ 0b01000010, 0b00000010, }; After we reset the device, we can tune the device. For tunning the channel we only need to program the first 4 bytes. This part of the code will change the channel to the desired frequency. In I2C at first, we begin the transmission, Write or read the data and then end the transmission. In this receiver IC, we don’t have to specify the address as the datasheet clearly says that the I2C interface has a fixed start register i.e. 0x02h for a write operation, and 0x0Ah for a read operation. uint8_t tune_config[] = { /* register 0x02 */ 0b11000000, 0b00000001, /* register 0x03 */ (channel >> 2), ((channel & 0b11) << 6 ) | 0b00010000 }; In the setup, we initializing the boot configuration (reset) and then tuning to a channel by writing tuning configuration bytes to the RDA5807M. void setup() { Serial.begin(9600); pinMode(A0,INPUT); /* Conect to RDA5807M FM Tuner: */ Wire.begin(); Wire.beginTransmission(RDA5807M_ADDRESS); Wire.write(boot_config, BOOT_CONFIG_LEN); Wire.endTransmission(); Wire.beginTransmission(RDA5807M_ADDRESS); Wire.write(tune_config, TUNE_CONFIG_LEN); Wire.endTransmission(); } When using pot for tuning to a frequency, I had faced a problem. The values which are read by the A0 pin are not constant. There is a noise clubbed with the desired value. I used a 0.1uF ceramic capacitor connected between A0, and GND, though the noise got minimized, it is not up to the desired level. So, I had to do some changes to the code. At first, I noted down the readings which are affected by the noise. I found out that the maximum value of the noise is 10. So I wrote the program in such a way that, it will only consider the new value if the difference between the new value and the old value of that same pin is greater than 10 and then tunes to the desired channel. void loop() { int channel1 =187 ,avg=0, newA; static int oldA = 0; int result = 0; newA = analogRead(A0); if ((newA - oldA) > 10 || (oldA - newA) > 10){ Serial.println(newA); if(newA!= oldA){ channel = channel1+(newA/10); myChangeChannel(channel); oldA=newA; } } }//loop end array and then transmits the data to the RDA5807M IC using the I2C protocol. void myChangeChannel(int channel){ /* void if nothing is returned else int */ tune_config[2] = (channel >> 2); tune_config[3] = ((channel & 0b11) << 6 ) | 0b00010000; Wire.begin(); Wire.beginTransmission(RDA5807M_ADDRESS); Wire.write(tune_config, TUNE_CONFIG_LEN); Wire.endTransmission(); }

Working of Arduino FM Radio

When the module is powered up, our code resets the RDA5807-M IC and sets it to a channel of the user desired (Note: this frequency is taken as the base frequency upon which the frequency will be incremented). By changing the potentiometer (connected to A0), the values read by the Arduino Nano changes. If the difference between the new and old value is greater than 10, our code will consider this new value. The channel is changed depending upon the change in the new value from the old value. Increasing or decreasing the volume depends on the potentiometer, which is connected in between the pin 3 and GND. for other technical help. Code #include <Wire.h> /* Select the frequency we want to tune to by way * of selecting the channel for the desired frequency */ uint16_t channel = 187; /* * assuming band starts at 87.0MHz (per settings below) * and channel spacing of 100kHz (0.1MHz) (per settings below) * then channel can be derived as follows: * * channel = (<desired freq in MHz> - 87.0) / 0.1 * * which is the same as: * <10 x desired freq in MHz> - 870 */ #define RDA5807M_ADDRESS 0b0010000 // 0x10 #define BOOT_CONFIG_LEN 12 #define TUNE_CONFIG_LEN 4 /* * These bytes set our initial configuration * We don't bother to tune to a channel at this stage. * But instead initiate a reset. */ uint8_t boot_config[] = { /* register 0x02 */ 0b11000001, /* * DHIZ audio output high-z disable * 1 = normal operation * * DMUTE mute disable * 1 = normal operation * * MONO mono select * 0 = stereo * * BASS bass boost * 0 = disabled * * RCLK NON-CALIBRATE MODE * 0 = RCLK is always supplied * * RCLK DIRECT INPUT MODE * 0 = ??? not certain what this does * * SEEKUP * 0 = seek in down direction * * SEEK * 0 = disable / stop seek (i.e. don't seek) */ 0b00000011, /* * SKMODE seek mode: * 0 = wrap at upper or lower band limit and contiue seeking * * CLK_MODE clock mode * 000 = 32.768kHZ clock rate (match the watch cystal on the module) * * RDS_EN radio data system enable * 0 = disable radio data system * * NEW_METHOD use new demodulate method for improved sensitivity * 0 = presumably disabled * * SOFT_RESET * 1 = perform a reset * * ENABLE power up enable: * 1 = enabled */ /* register 0x03 */ /* Don't bother to tune to a channel at this stage*/ 0b00000000, /* * CHAN channel select 8 most significant bits of 10 in total * 0000 0000 = don't boher to program a channel at this time */ 0b00000000, /* * CHAN two least significant bits of 10 in total * 00 = don't bother to program a channel at this time * * DIRECT MODE used only when test * 0 = presumably disabled * * TUNE commence tune operation * 0 = disable (i.e. don't tune to selected channel) * * BAND band select * 00 = select the 87-108MHz band * * SPACE channel spacing * 00 = select spacing of 100kHz between channels */ /* register 0x04 */ 0b00001010, /* * RESERVED 15 * 0 * * PRESUMABLY RESERVED 14 * 0 * * RESERVED 13:12 * 00 * * DE de-emphasis: * 1 = 50us de-emphasis as used in Australia * * RESERVED * 0 * * SOFTMUTE_EN * 1 = soft mute enabled * * AFCD AFC disable * 0 = AFC enabled */ 0b00000000, /* * Bits 7-0 are not specified, so assume all 0's * 0000 0000 */ /* register 0x05 */ 0b10001000, /* * INT_MODE * 1 = interrupt last until read reg 0x0C * * RESERVED 14:12 * 000 * * SEEKTH seek signal to noise ratio threshold * 1000 = suggested default */ 0b00001111, /* * PRESUMABLY RESERVED 7:6 * 00 * * RESERVED 5:4 * 00 * * VOLUME * 1111 = loudest volume */ /* register 0x06 */ 0b00000000, /* * RESERVED 15 * 0 * * OPEN_MODE open reserved registers mode * 00 = suggested default * * Bits 12:8 are not specified, so assume all 0's * 00000 */ 0b00000000, /* * Bits 7:0 are not specified, so assume all 0's * 00000000 */ /* register 0x07 */ 0b01000010, /* * RESERVED 15 * 0 * * TH_SOFRBLEND threshhold for noise soft blend setting * 10000 = using default value * * 65M_50M MODE * 1 = only applies to BAND setting of 0b11, so could probably use 0 here too * * RESERVED 8 * 0 */ 0b00000010, /* * SEEK_TH_OLD seek threshold for old seek mode * 000000 * * SOFTBLEND_EN soft blend enable * 1 = using default value * * FREQ_MODE * 0 = using defualt value */ }; /* After reset, we can tune the device * We only need program the first 4 bytes in order to do this */ uint8_t tune_config[] = { /* register 0x02 */ 0b11000000, /* * DHIZ audio output high-z disable * 1 = normal operation * * DMUTE mute disable * 1 = normal operation * * MONO mono select * 0 = mono * * BASS bass boost * 0 = disabled * * RCLK NON-CALIBRATE MODE * 0 = RCLK is always supplied * * RCLK DIRECT INPUT MODE * 0 = ??? not certain what this does * * SEEKUP * 0 = seek in down direction * * SEEK * 0 = disable / stop seek (i.e. don't seek) */ 0b00000001, /* * SKMODE seek mode: * 0 = wrap at upper or lower band limit and contiue seeking * * CLK_MODE clock mode * 000 = 32.768kHZ clock rate (match the watch cystal on the module) * * RDS_EN radio data system enable * 0 = disable radio data system * * NEW_METHOD use new demodulate method for improved sensitivity * 0 = presumably disabled * * SOFT_RESET * 0 = don't reset this time around * * ENABLE power up enable: * 1 = enabled */ /* register 0x03 */ /* Here's where we set the frequency we want to tune to */ (channel >> 2), /* CHAN channel select 8 most significant bits of 10 in total */ ((channel & 0b11) << 6 ) | 0b00010000 /* * CHAN two least significant bits of 10 in total * * DIRECT MODE used only when test * 0 = presumably disabled * * TUNE commence tune operation * 1 = enable (i.e. tune to selected channel) * * BAND band select * 00 = select the 87-108MHz band * * SPACE channel spacing * 00 = select spacing of 100kHz between channels */ }; void setup() { Serial.begin(9600); pinMode(A0,INPUT); Wire.begin(); Wire.beginTransmission(RDA5807M_ADDRESS); Wire.write(boot_config, BOOT_CONFIG_LEN); Wire.endTransmission(); Wire.beginTransmission(RDA5807M_ADDRESS); Wire.write(tune_config, TUNE_CONFIG_LEN); Wire.endTransmission(); }//setup end void loop() { int channel1 =90,newA; static int oldA = 0; // set the oldA as HIGH int result = 0; newA = analogRead(A0); if ((newA - oldA) > 10 || (oldA - newA) > 10){ Serial.println(newA); if(newA!= oldA){ channel = channel1+(newA/10); myChangeChannel(channel); oldA=newA; } } uint16_t frequency = channel+870; uint16_t num1 = (frequency / 1000) % 10; uint16_t num2 = (frequency / 100) % 10; uint16_t num3 = (frequency / 10) % 10; uint16_t num4 = frequency % 10; Serial.print(num1); Serial.print(num2); Serial.print(num3); Serial.print(num4); Serial.print("--"); Serial.println(channel+870); }//loop end /* * Function to change channel on radio RDA5807 * Example: channel = 191 */ void myChangeChannel(int channel){ /* void if nothing is returned else int */ /* * first write new channel to tune_config massive */ tune_config[2] = (channel >> 2); tune_config[3] = ((channel & 0b11) << 6 ) | 0b00010000; Wire.begin(); Wire.beginTransmission(RDA5807M_ADDRESS); Wire.write(tune_config, TUNE_CONFIG_LEN); Wire.endTransmission(); } Video microcontroller-projects/rain-detector-using-arduino

Rain Detection System using Arduino and Rain Sensor

based on usage, but they all refer to the same sensor used in this project and they all work on the same principle.

Materials Required

Arduino UNO Rain sensor Buzzer Breadboard Connecting wires

Rain sensor

consists of two boards, namely Rain Board and Control Board. consists of two pins used to connect to the control board as shown below. and much more. which is shown below consists of 4 pins to connect the Arduino namely VCC, GND, D0, A0 and two more pins to connect the rain board module. In summary, the rain board module detects the rainwater, and the control board module is used to control the sensitivity and compare and convert the analog values to digital values.

Working of Rain Sensor

is simple to understand. During a sunny day, due to the dryness on the rain board module, it offers high resistance to the supply voltage. This voltage appears on the output pin of the rain board module as 5V. This 5V is read as 1023 if read by an analog pin of the Arduino. During rain, the rainwater causes an increase in the wetness on the rain board, which in turn results in the decrease in the resistance offered for the supply. As the resistance decreases gradually, the output voltage starts to decrease. By using this formula you can convert any analog voltage to t Arduino analog read value.

Circuit Diagram

The design is done using proteus, the physical modules are similar to the modules which are shown in the circuit diagram. The rain gauge module, which is shown in the circuit diagram is connected to the control board. The control board’s VCC pin is connected to the 5V supply. The ground pin is connected to ground. If needed, the D0 pin is connected to any digital pin of the Arduino, and that pin must be declared as an output pin in the program. The problem we face with the D0 pin is that we can’t get the exact value of the output voltage. If the output crosses the threshold voltage, then the control module can sense the change in the output. We need to operate the buzzer, even if there is a considerable change in the output voltage in the rain board module. Due to these reasons, the A0 pin is connected to the analog pin of Arduino, which makes monitoring the change in output easy. The buzzer, which is used as a signal to the user, can be connected to any digital pin of the Arduino. If the buzzer needs more than 5V, then try to connect a relay circuit or a transistor and then connecting the load to it.

Code Explanation

was written using the Arduino IDE. The complete code for this project is given at the end of the page. #define rainfall A0 #define buzzer 5 int value; int set=10; Defining pin A0 as rainfall, and pin 5 as a buzzer and declaring variable “valueᾠand “setᾠas integers and setting its variable set value to 10. This value can be changed according to the required level of operation. If you want the buzzer to activate, even when there is little rain set it to a minimum value void setup() { Serial.begin(9600); pinMode(buzzer,OUTPUT); pinMode(rainfall,INPUT); } Initializing the serial communication, and setting the buzzer. Setting the rainfall pin as an output pin and input pin. void loop() { value = analogRead(rainfall); Serial.println(value); value = map(value,0,1023,225,0); the function analogRead reads the value of the rain sensor. The function map maps the value of the rain sensor from the output pin, and assigns a value to the variable, ranging from 0 to 225. if(value>=set){ Serial.println("rain detected"); digitalWrite(buzzer,HIGH); If the read sensor value is greater than the set value, then the program enters the loop, prints the message on serial monitor and switches on the buzzer else{ digitalWrite(buzzer, LOW); The program enters the else function only when the value is less than the set value. This function will switch off the buzzer when the set value is higher than the value of the sensor, which tells that there is no rain.

Working of Arduino based Rain Detection system

, we defined that pins 5, and A0 are buzzer and rainfall. By doing this, we can change the pins in the defined part of the function, and the remaining part of the code will be untouched. This will make the programmer in editing the pins easily. is a map (value, min value, maximum value, value to be mapped for minimum value, value to be mapped for maximum value). The buzzer will be switched ON or OFF, depending on the set value and the output of the sensor. This value is compared in the if function, with the set value. If the value is greater than the set value, it will switch on the buzzer. If the value is less than the set value, the buzzer will be switched off. linked below. This is one application among the many, the same principle will be seen in windshield wipers, other home automation, agriculture sectors, etc. Hope you understood the project and enjoyed building something useful. If you have any questions, use the comment section below or use our forums for other technical questions. Code #define rainfall A0 #define buzzer 5 int value; int set=10; void setup() { Serial.begin(9600); pinMode(buzzer,OUTPUT); pinMode(rainfall,INPUT); } void loop() { value = analogRead(rainfall); Serial.println("LOL"); Serial.println(value); value = map(value,0,1023,225,0); Serial.println(value); if(value>=set){ Serial.println("rain detected"); digitalWrite(buzzer,HIGH); } else{ digitalWrite(buzzer,LOW); } delay(200); } Video microcontroller-projects/diy-arduino-pedometer-counting-steps-using-arduino-and-accelerometer

DIY Arduino Pedometer - Counting Steps using Arduino and Accelerometer

where the critical data have been sent to ThingSpeak to be monitored from anywhere.

Components Required

Arduino Nano ADXL 335 Accelerometer 16*2 LCD LCD I2C Module Battery

ADXL335Accelerometer

is a device which can convert acceleration in any direction to its respective variable voltage. This is accomplished by using capacitors (refer image), as the Accel moves, the capacitor present inside it, will also undergo changes (refer image) based on the movement, since the capacitance is varied, a variable voltage can also be obtained. Below are the images for Accelerometer from the front and back side along with the pin description- Vcc- 5 volt supply should connect at this pin. X-OUT- This pin gives an Analog output in x direction Y-OUT- This pin give an Analog Output in y direction Z-OUT- This pin gives an Analog Output in z direction GND- Ground ST- This pin used for set sensitivity of sensor , etc.

Circuit Diagram

is given below. X, Y, and Z pins of the accelerometer are connected with Analog pins (A1, A2 & A3) of Arduino Nano. To interface 16x2 LCD modules with Arduino, we are using the I2C module. SCL & SDA pins of the I2C module are connected to A5 and A4 pins of Arduino Nano, respectively. Complete connections are given in the below table:
Arduino NanoADXL335
3.3VVCC
GNDGND
A1X
A2Y
A3Z
Arduino NanoLCD I2C Module
5VVCC
GNDGND
A4SDA
A5SCL
setup on a breadboard And after successful testing we replicated it on Perfboard by soldering all the component on Perfboard as shown below:

How Pedometer Works?

A pedometer calculates the total no of steps taken by a person using the three components of motion that are forward, vertical, and side. The pedometer system uses an accelerometer to get these values. Accelerometer continuously updates the maximum and minimum values of the 3-axis acceleration after every defined no. of samples. The average value of these 3-axis (Max + Min)/2, is called the dynamic threshold level, and this threshold value is used to decide whether the step is taken or not. While running, the pedometer can be in any orientation, so the pedometer calculates the steps using the axis whose acceleration change is the largest. : Firstly the pedometer starts the calibration as soon as it gets powered. Then in the void loop function, it continuously gets the data from X, Y, and Z-axis. After that, it calculates the total acceleration vector from the starting point. Acceleration vector is the square root (x^2+y^2+z^2) of the X, Y, and Z-axis values. Then it compares the average acceleration values with the threshold values to count the step number. If the acceleration vector crosses the threshold value, then it increases the step count; otherwise, it discards the invalid vibrations.

Programming the Arduino Step Counter

is given at the end of this document. Here we are explaining some important snippets of this code. As usual, start the code by including all the required libraries. ADXL335 accelerometer does not require any library as it gives an analog output. #include <LiquidCrystal_I2C.h> After that, define the Arduino Pins, where the accelerometer is connected. const int xpin = A1; const int ypin = A2; const int zpin = A3; Define the threshold value for the accelerometer. This threshold value will be compared with the acceleration vector to calculate the number of steps. float threshold = 6; , function calibrates the system when it is powered. calibrate(); function, it will read the X, Y and Z-axis values for 100 samples. for (int a = 0; a < 100; a++) { xaccl[a] = float(analogRead(xpin) - 345); delay(1); yaccl[a] = float(analogRead(ypin) - 346); delay(1); zaccl[a] = float(analogRead(zpin) - 416); delay(1); After getting the 3-axis values, calculate the total acceleration vector by taking the square root of X, Y, and Z-axis values. totvect[a] = sqrt(((xaccl[a] - xavg) * (xaccl[a] - xavg)) + ((yaccl[a] - yavg) * (yaccl[a] - yavg)) + ((zval[a] - zavg) * (zval[a] - zavg))); Then calculate the average of the maximum and minimum acceleration vector values. totave[a] = (totvect[a] + totvect[a - 1]) / 2 ; Now compare the average acceleration with the threshold. If the average is greater than the threshold, then increase the step count and raise the flag. if (totave[a] > threshold && flag == 0) { steps = steps + 1; flag = 1; } If the average is greater than the threshold but the flag is raised, then do nothing. else if (totave[a] > threshold && flag == 1) { // Don’t Count } If the total average is less than threshold and flag is raised, then put the flag down. if (totave[a] < threshold && flag == 1) { flag = 0; } Print the number of steps on serial monitor and LCD. Serial.println(steps ); lcd.print("Steps: "); lcd.print(steps);

Testing the Arduino Pedometer

Once your hardware and code are ready, connect the Arduino to the laptop and upload the code. Now take the pedometer setup in your hands and start walking step by step, it should display the number of steps on LCD. Sometimes it increases the number of steps when pedometer vibrates very rapidly or very slowly. are given below. Code #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); const int xpin = A1; const int ypin = A2; const int zpin = A3; byte p[8] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; float threshold = 6; float xval[100] = {0}; float yval[100] = {0}; float zval[100] = {0}; float xavg, yavg, zavg; int steps, flag = 0; void setup() { Serial.begin(9600); lcd.begin(); lcd.backlight(); lcd.clear(); calibrate(); } void loop() { for (int w = 0; w < 16; w++) { lcd.write(byte(0)); delay(500); } int acc = 0; float totvect[100] = {0}; float totave[100] = {0}; float xaccl[100] = {0}; float yaccl[100] = {0}; float zaccl[100] = {0}; for (int a = 0; a < 100; a++) { xaccl[a] = float(analogRead(xpin) - 345); delay(1); yaccl[a] = float(analogRead(ypin) - 346); delay(1); zaccl[a] = float(analogRead(zpin) - 416); delay(1); totvect[a] = sqrt(((xaccl[a] - xavg) * (xaccl[a] - xavg)) + ((yaccl[a] - yavg) * (yaccl[a] - yavg)) + ((zval[a] - zavg) * (zval[a] - zavg))); totave[a] = (totvect[a] + totvect[a - 1]) / 2 ; Serial.println("totave[a]"); Serial.println(totave[a]); delay(100); if (totave[a] > threshold && flag == 0) { steps = steps + 1; flag = 1; } else if (totave[a] > threshold && flag == 1) { // Don't Count } if (totave[a] < threshold && flag == 1) { flag = 0; } if (steps < 0) { steps = 0; } Serial.println('\n'); Serial.print("steps: "); Serial.println(steps); lcd.print("Steps: "); lcd.print(steps); delay(1000); lcd.clear(); } delay(1000); } void calibrate() { float sum = 0; float sum1 = 0; float sum2 = 0; for (int i = 0; i < 100; i++) { xval[i] = float(analogRead(xpin) - 345); sum = xval[i] + sum; } delay(100); xavg = sum / 100.0; Serial.println(xavg); for (int j = 0; j < 100; j++) { yval[j] = float(analogRead(ypin) - 346); sum1 = yval[j] + sum1; } yavg = sum1 / 100.0; Serial.println(yavg); delay(100); for (int q = 0; q < 100; q++) { zval[q] = float(analogRead(zpin) - 416); sum2 = zval[q] + sum2; } zavg = sum2 / 100.0; delay(100); Serial.println(zavg); } Video microcontroller-projects/arduino-qr-code-generator

Generate a QR code using Arduino and display it on SSD1306 OLED

and demystify the following things: Basic Concept of the QR code. How it works. How to make your very own QR code using Arduino. And finally, display it in an OLED (SSD1306) screen.

So, What is this QR Code Anyway?

QR code (Quick Response code) is a matrix 2D code for reading data at high speed, developed by DENSO WAVE in 1994 for the automotive industry of Japan. A QR code compresses data very efficiently compared to the standard barcode, to achieve this it uses four standardized encoding modes (numeric, alphanumeric, byte/binary, and kanji), the technology was made "open sourceᾠi.e. available for everyone so, it gained popularity very rapidly. Significant advantages of QR Codes over conventional barcodes are larger data capacity and high fault tolerance. QR codes (and other data matrix codes) are designed to be read by special tools, not by humans, so there's only a specific amount we can understand by studying visually, although every code is different in various ways though they contain a few interesting common features by observing the circuitdigest.com QR code we will study some of them Finder Patterns: Large square boxes with a solid box inside in the three corners of the code make it easy to confirm that it’s a QR code since there are only three of them, so it's pretty obvious that in which way the code is oriented. Alignment Pattern: This makes it certain that whatever the orientation the code can be readable. Timing Pattern: This runs horizontally and vertically between the three finder patterns, using these lines the reader can determine the size of the code. Version Information: There are currently 40 different versions of the QR code standard, this section of the code determines the QR code version which is being used, for marketing version 1-7 used normally. Format Information: The format partners have information about error tolerance and data masking. Data Area: This section of the code contains all the data elements and error correction code along. Quit Zone: The spacing in every QR code is mandatory in order to differentiate the code from its surroundings. The image below will give you a clear idea about the code Other sections of the code are data and redundancy code. tutorial by Tan Jin Soon, EPCglobal Singapore Council. Synthesis Journal, 2008.
Symbol Size Min. 21x21 cell - Max. 177x177 cell (with 4-cells interval)
Information Type and VolumeNumeric Characters7,089 characters at maximum
Alphabets, Signs4,296 characters at maximum
Binary (8 bit)2,953 characters at maximum
Kanji Characters1,817 characters at maximum
Conversion efficiencyNumeric Characters Mode3.3 cells/character
Alphanumeric/Signs Mode5.5 cells/character
Binary (8 bit) Mode8 cells/character
Kanji Characters Mode (13 bit)13 cells/character
Error correction functionalityLevel LApprox. 7% of the symbol area restored at maximum
Level MApprox. 15% of the symbol area restored at maximum
Level QApprox. 25% of the symbol area restored at maximum
Level HApprox. 30% of the symbol area restored at maximum
Linking functionality Possible to be divided into 16 symbols at maximum

Generating your very own QR code

website website and if you look at the top side of the website you can see a list of options, in this tutorial we are generating a QR code for a URL, so we are going to Click on the URL tab and paste the URL for the Circuit Digest in the Enter URL section. Click on save. Give a file name for the output file. Select PNG as our preferred file format. and click save. The image below will give you a clear idea about the process , and many other microcontrollers. Bitmap array conversion can be done in below two steps: Converting the PNG to BMP format. Convert the BMP image to an array of HEX codes.

Converting the PNG to BMP format

website and in the image converter section and Click on the dropdown menu and select Convert to BMP Click Go The image below will give you a clear idea about the process: You will be presented with a new page looks like the below image: Click on the Choose Files tab and select the downloaded image In the Optional settings, panel type your desired size (we are using a 128x64 OLED) Click on Start conversion button You will be presented with the following page and after a few seconds your converted image will be downloaded if the download doesn't start automatically click on the download your file option:

Convert the BMP image to an array of HEX codes

The image below will give you a clear idea about the process You will be presented with a screen which has four options and we will discuss them in details Select image Image Settings Preview Output In this section we will select the image which we have just converted to BMP: In this section, we will set the canvas size, background color, scaling and centre options to our required value. Canvas size (we set to 128x64 because we are using an OLED with 128x64 pixel density). In this section, we can set the background color of the OLED (we choose it to be white). Scaling is set to the original size. Finally, in the centre option click on the horizontal and vertical checkboxes, this will make the image appear in the centre. The image below will give you a clear idea In the preview section we can see a clear preview of the image which will be displayed in the OLED like shown below: In the output section we will generate and copy the generated code, to do so follow the below steps: Code output format (we set it as Arduino code because we are using one). Identifier (this option sets the name for the generated array we leave it default as it is). Draw mode (We set the draw mode option to horizontal). And finally, we click on the generate code button this will generate the final output code. The image below will give you a clear idea

Circuit Diagram

:
GNDGND
3.3VVCC
D13CLK
D11MOSI
D8RES
D9SDC
D10CCS

Code Explanation

In the below section we will modify the code to display the previously generated HEX array to the OLED. Complete code with a working video is given at the end of this article. The Detail Explanation of the code is given below. First, include the downloaded library. #include "U8glib.h" // including the U8glib library Then define all the necessary pins for OLED. #define OLED_CLK_PIN 13 //Arduino Digital Pin D13: SCK #define OLED_MOSI_PIN 11 //Arduino Digital Pin D11: MOSI #define OLED_RES_PIN 10 //Arduino Digital Pin D10: SS #define OLED_SDC_PIN 9 //Arduino Digital Pin D9: OC1A #define OLED_CSS_PIN 8 //Arduino Digital Pin D13: ICP1 Initialize the u8glib Library. U8GLIB_SH1106_128X64 u8g(OLED_CLK_PIN, OLED_MOSI_PIN, OLED_RES_PIN, OLED_SDC_PIN, OLED_CSS_PIN); Then Include the generated image array. const uint8_t circuitdigest[] PROGMEM = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1c, 0x01, 0x87, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0c, 0x01, 0x87, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x8f, 0xf0, 0x7f, 0x31, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x8f, 0xf0, 0x7f, 0x33, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x81, 0x8f, 0x31, 0x80, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0x31, 0x80, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0xb1, 0x80, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0xc1, 0x98, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0xc1, 0x98, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, …….. ……‐󬬍 Draw function is used to draw the bitmap image (QR code) on OLED with the help of u8g.drawBitmapP function. void draw(void) { // graphic commands to redraw the complete screen should be placed here u8g.drawBitmapP( 0, 0, 16, 64, circuitdigest); ….. …‐󋈍 function, call all the necessary procedures to build the image on OLED void loop() { u8g.firstPage(); //A call to this procedure, marks the beginning of the picture loop. do { draw(); } while( u8g.nextPage() ); // A call to this procedure, marks the end of the body of the picture loop. // rebuild the picture after some delay delay(1000); } After completing the code, plug in the Arduino in the USB port of your computer, select your COM port and upload the code. If you have done everything correctly you will have a working display with a QR code on OLED. I hope you liked this project and enjoyed learning something new, keep reading keep learning and I will see you next time. Code /* */ #include "U8glib.h" // including the U8glib library #define OLED_CLK_PIN 13 //Arduino Digital Pin D13: SCK #define OLED_MOSI_PIN 11 //Arduino Digital Pin D11: MOSI #define OLED_RES_PIN 10 //Arduino Digital Pin D10: SS #define OLED_SDC_PIN 9 //Arduino Digital Pin D9: OC1A #define OLED_CSS_PIN 8 //Arduino Digital Pin D13: ICP1 U8GLIB_SH1106_128X64 u8g(OLED_CLK_PIN, OLED_MOSI_PIN, OLED_RES_PIN, OLED_SDC_PIN, OLED_CSS_PIN); /* make an object of the U8GLIB_SH1106_128X64 class and initialized the Pins of the arduino this method takes five arguments first (SCK_PIN,MOSI_PIN,CS_PIN,A0_pin,RESET_PIN) */ //the custom made circuitdigest Bitmap const uint8_t circuitdigest[] PROGMEM = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1c, 0x01, 0x87, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0c, 0x01, 0x87, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x8f, 0xf0, 0x7f, 0x31, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x8f, 0xf0, 0x7f, 0x33, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x81, 0x8f, 0x31, 0x80, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0x31, 0x80, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0xb1, 0x80, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0xc1, 0x98, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0xc1, 0x98, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0xc0, 0x67, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0xc0, 0x67, 0x33, 0x81, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x8f, 0x31, 0xe7, 0x33, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x8f, 0x31, 0xe7, 0x33, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0c, 0xce, 0x67, 0x30, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0c, 0xce, 0x67, 0x30, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x1c, 0x4e, 0x27, 0x38, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3e, 0x1f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3e, 0x1e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xe1, 0x8f, 0x3e, 0x60, 0x33, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xe1, 0x8f, 0x3e, 0x60, 0x33, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, 0xf0, 0xcf, 0xf8, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, 0xf0, 0xcf, 0xf8, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x83, 0x3e, 0x00, 0xcc, 0x67, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x83, 0x3e, 0x00, 0xcc, 0x67, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x7c, 0xff, 0xc3, 0xf1, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x7c, 0xff, 0xe7, 0xf3, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x7c, 0xff, 0xe7, 0xf1, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf9, 0x8f, 0x0e, 0x78, 0xf0, 0x7f, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf9, 0x8f, 0x0e, 0x78, 0xf0, 0x7f, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x19, 0xf3, 0xce, 0x18, 0x0f, 0x9e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x19, 0xe3, 0xce, 0x18, 0x0f, 0x9e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x07, 0x83, 0x0f, 0x80, 0xf3, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x07, 0x83, 0x0f, 0x80, 0xf3, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xc7, 0xe0, 0xf3, 0xe3, 0x7c, 0x40, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xe7, 0xf0, 0xf1, 0xe7, 0x3c, 0x61, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xe7, 0xf0, 0xf9, 0xe7, 0x3c, 0x60, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x19, 0x8c, 0x3e, 0x07, 0x00, 0x18, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x39, 0x9c, 0x3e, 0x07, 0x00, 0x18, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3e, 0x1f, 0x3f, 0x98, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3e, 0x1f, 0x3f, 0x98, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1f, 0x01, 0xff, 0x33, 0x9f, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0x01, 0xff, 0x33, 0x9f, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0x8f, 0xc7, 0x80, 0x3f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x8f, 0xcf, 0x80, 0x3f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x8f, 0xcf, 0x80, 0x3f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8c, 0x30, 0x60, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8c, 0x30, 0x60, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8c, 0xf1, 0xe0, 0x03, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8c, 0xf1, 0xe0, 0x03, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0xc1, 0x83, 0xcf, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, 0x8f, 0xc1, 0x87, 0xcf, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x8c, 0xff, 0xe1, 0xc0, 0x18, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x8c, 0xff, 0xe0, 0xc0, 0x18, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0x8c, 0xff, 0xf0, 0xc0, 0x18, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0c, 0x0e, 0x7f, 0x3f, 0xe7, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1c, 0x0e, 0x7f, 0x3f, 0xe7, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; void draw(void) { // graphic commands to redraw the complete screen should be placed here u8g.drawBitmapP( 0, 0, 16, 64, circuitdigest); /* drawBitmapP Method takes five arguments First: X-position (left position of the bitmap). Secound: Y-position (upper position of the bitmap). Third: Number of bytes of the bitmap in horizontal direction. The width of the bitmap is cnt/8. Fourth: Height of the bitmap. Fifth: Bitmap array. */ /* Draw a bitmap at the specified x/y position (upper left corner of the bitmap). Parts of the bitmap may be outside the display boundaries.The bitmap is specified by the array bitmap. A cleared bit means: Do not draw a pixel. A set bit inside the array means: Write pixel with the current color index.For a monochrome display, the color index 0 will usually clear a pixel and the color index 1 will set a pixel. */ } void setup() { // empty setup function as the library manages all internally } void loop() { u8g.firstPage(); //A call to this procedure, marks the beginning of the picture loop. do { draw(); } while( u8g.nextPage() ); // A call to this procedure, marks the end of the body of the picture loop. // rebuild the picture after some delay delay(1000); } Video microcontroller-projects/how-to-interface-bmp280-pressure-sensor-with-arduino

How to Interface BMP280 Pressure Sensor Module with Arduino

in one of our previous tutorials. link to open the respective Github page and add the header file to your Arduino IDE.

Components Required

Arduino BMP280 Connecting Wires Bread Board LCD- 16x2

BMP280 Pressure Sensor Module:

, which is equivalent to ±1 m difference in altitude. Due to these key features, it is mostly used in various applications. The BMP sensor consists of a Pressure sensing element, Humidity sensing element and Temperature sensing element which are further connected to Pressure front-end, Humidity front-end, and temperature front-end. These front end IC’s are sensitivity analog amplifiers that are used in the amplification of small signals. The output of this analog front-end IC’s is fed to ADC as an input signal. In this the analog values are converted to digital voltage and this voltage is fed to the logic circuits for further interface with the outside world. sleep mode, forced mode, and Normal Mode. In sleep mode, no measurements are performed and power consumption is at a minimum. In forced mode, a single measurement is performed according to the selected measurement and filter options. Normal mode continuously cycles between measurement and standby period, and the cycles time period will be defined by Tstandby. The current in the standby mode is slightly higher than the sleep mode.

Circuit diagram to interface BMP280 with Arduino:

to understand how to use Arduino with LCD displays. The VCCand GND pins of the sensor are connected to the 3v3 and GND pins of the Arduino. The SCL and SDA pins of the sensor are connected to the A5 and A4 of the Arduino board. The LCD connections are as follows
VSS and RWGND
RSD9
ED8
D4, D5, D6, D7D5,D4,D3,D2

Arduino Program to Interface BMP280 with Arduino:

can be found at the bottom of this page which can be uploaded directly to your Arduino board. The explanation of the same is given below These libraries are included for enabling the special functions. The #include <Adafruit_BMP280.h> header files we can directly read the values coming from the sensor. The #include <Wire.h> header is helpful in using I2C communication. The #include <LiquidCrystal.h> header is used to access the special function of LCD like lcd.print(), Lcd.setCursor(), etc. these header files can be downloaded using the link which is given above. The downloaded file will be in zip format. Now open Arduino select Sketch>include library>Add.zip library. Now add the downloaded file. #include <Wire.h> #include <SPI.h> #include <Adafruit_BMP280.h> #include <LiquidCrystal.h> Creating on object BMP for Adafruit_BMP280. An object file is created to access special functions. Adafruit_BMP280 bmp; // I2C Setting the pins of the Arduino to communicate with the LCD. Using these pins data will be transferred. LiquidCrystal LCD(9, 8, 5, 4, 3, 2); Initializing the LCD and Serial Communication. void setup() { lcd.begin(16,2); Serial.begin(9600); Serial.println(F("BMP280 test")); lcd.print("Welcome to "); lcd.setCursor(0,1); lcd.print("CIRCUIT DIGEST"); delay(1000); lcd.clear(); if (!bmp.begin()) { Serial.println(F("Could not find a valid BMP280 sensor, check the wiring!")); while (1); } This function works when the initializing of the bmp object is failed. /* Default settings from datasheet. */ bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */ Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */ Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */ Adafruit_BMP280::FILTER_X16, /* Filtering. */ Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */ } This part of the code prints the temperature on serial monitor and is for debugging purposes. void loop() { Serial.print(F("Temperature = ")); Serial.print(bmp.readTemperature()); Serial.println(" *C"); are used to invoke special functions and return the temperature and pressure values. lcd.print(bmp.readTemperature()); lcd.print(bmp.readPressure());

Working of Arduino BMP280 Pressure Sensor Interfacing Project

command prints the data from the position set by the programmer. If there is no position set for the LCD by default it takes (0,0) as the initial position, and continuous printing the data. The next data takes the position of the next column, and the procedure continues until it reaches the end of the row and shifts to the next row. and learned something useful. If you have any question leave them in the comment section below or use the forums for other technical questions. Code #include <Wire.h> #include <SPI.h> #include <Adafruit_BMP280.h> #include <LiquidCrystal.h> Adafruit_BMP280 bmp; // I2C //Adafruit_BMP280 bmp(BMP_CS); // hardware SPI //Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK); LiquidCrystal lcd(9, 8, 5, 4, 3, 2); void setup() { lcd.begin(16,2); Serial.begin(9600); Serial.println(F("BMP280 test")); lcd.print("Welcome to "); lcd.setCursor(0,1); lcd.print("CIRCUIT DIGEST"); delay(1000); lcd.clear(); if (!bmp.begin()) { Serial.println(F("Could not find a valid BMP280 sensor, check wiring!")); while (1); } /* Default settings from datasheet. */ bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */ Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */ Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */ Adafruit_BMP280::FILTER_X16, /* Filtering. */ Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */ } void loop() { Serial.print(F("Temperature = ")); Serial.print(bmp.readTemperature()); Serial.println(" *C"); lcd.setCursor(0,0); lcd.print("Temp= "); lcd.print(bmp.readTemperature()); Serial.print(F("Pressure = ")); Serial.print(bmp.readPressure()); Serial.println(" Pa"); lcd.setCursor(0,1); lcd.print("Press= "); lcd.print(bmp.readPressure()); Serial.print(F("Approx altitude = ")); Serial.print(bmp.readAltitude(1018)); /* Adjusted to local forecast! */ Serial.println(" m"); Serial.println(); delay(2000); } Video microcontroller-projects/wireless-doorbell-using-arduino

Wireless Doorbell using Arduino and RF Module

We all know of the wired doorbell systems which require wires and suitable outlets for it to work satisfactorily. As the wired doorbell system needs complicated wiring, it requires an experienced person to get the work done and it does not do good, in both working and appearance. Another problem with it is that, if you want to install a wired doorbell system for an existing house, it needs more effort and time for the installation. Due to the temperature and humidity, and other environmental factors, wires are damaged and will lead to a short circuit. This is where the wireless doorbell system gets into the picture. Even though the cost of the wireless Doorbell system is more, when compared to the wired doorbell system, the regular maintenance for the wireless Doorbell system is low when compared with the wired doorbell system, which requires an experienced person for maintenance purposes. When it comes to installation, wireless doorbell systems are very simple to install and requires no experience person for installation. In addition to this, wireless doorbell systems have additional features like camera, video recorder, etc and look stylish, and it can be easily installed in any part of the house as it is completely wireless. tutorials to build one.

Hardware Required:

RF module Arduino Buzzer Push-button Breadboard Connecting wires we will be using the 433 MHz Wireless RF modules. An RF module, which is a Radio Frequency module consists of two modules, one which receives the data called receiver, and the one which transmits the data called transmitter. by following the link. A transmitter consists of a SAW resonator, which is tuned to 433MHz frequency, a switching circuit, and a few passive components. We will discuss more on this later in this article An RF receiver is a simple circuit that consists of an RF tuned circuit, an amplifier circuit, and a phase lock loop circuit. An RF tuner is used to tune the circuit to a particular frequency, which needs to meet the transmitted frequency. An amplifier circuit is used to amplify a particular frequency from all other signals and to increase the sensitivity of the particular frequency. and a phase comparator connected in such a way that the oscillator frequency always matches the input signal as shown below. In the PLL circuit two signals i.e. from the reference signal and the signal from the voltage-controlled oscillator (VCO), is given as inputs to the phase detector and the output from the phase detector the difference between both the inputs, and this output is the phase difference of both the signals. This output contains frequency components, which are the sum and difference of the signals. So, this output is given as input to the low pass filter, which allows only low frequencies, and doesn’t allow the high-frequency signals to pass through. The output of the low pass filter is fed to a voltage-controlled oscillator (VCO), and this input acts as a value to the VOC, which must be changed to decrease the phase difference between both the signals. The change in the VCO takes place until the phase difference is minimal, or the output of the phase detector has a constant error output. This results in the loop lock situation. With all these components, the receiver receives the signal from the antenna which is then tuned by RF tuned circuit and this weak signal is amplified using OP-Amp, and this amplified signal is further used as input to PLL, which makes the decoder to lock onto the incoming digital bits which gives an output which is less in noise. the popular ones are Analog Modulation, Digital Modulation, Pulse Modulation, and Spread Spectrum. Out of these the most popular one used in a wireless transmission is digital modulation. The popular Digital modulation techniques are Amplitude Shift Keying, Frequency Shift Keying, Phase Shift Keying, Orthogonal Amplitude Modulation. In Amplitude Shift key modulation, the sinusoidal carrier will keep on generating continuous high-frequency carrier, and the signal which is to be modulated will be in the binary sequence, and these signals make the input to the switching circuit to be either high or low. As shown in the above figure, when the input is low, the switch will act as an open circuit, and the output will be zero. When the input to the switch is high, the output will be the carrier signal.

Arduino RF Transmitter Circuit Diagram

is shown below The Arduino pin 5 is connected to the one end of the doorbell switch, and the other end of the switch is connected to the supply voltage. A pull-down resistor of 10kohm is connected to pin 5 as shown in the fig. Pin 11 is connected to the data pin of the transmitter module. Vcc is connected to the supply voltage, and the ground pin of the transmitter module is grounded. In here I used a breadboard for connecting the modules, and a push-button is used as a doorbell switch.

Arduino RF Receiver Circuit Diagram

also has a buzzer is to play some melody when the button is pressed. pin of the Arduino. The receiver module consists of 4 pins in which one pin is grounded, and another one pin is for giving VCC supply, and the remaining two pins are used for data transfer. In the above diagram, a buzzer is connected to the digital 7th pin of the Arduino, and the 12th pin of the Arduino is connected to the receiver module output pin.

Arduino Transmitter Code Explanation

The complete code for the Arduino transmitter part is given at the bottom of this page. The explanation of the code is as follows. for Arduino from Github. #include <RH_ASK.h> #include <SPI.h> // Not actually used but needed to compile RH_ASK driver; Serial.begin() is used to find whether the RF transmitter module is working or not and I have initialized the PIN 5 (digital pin 5) as an Input pin and this acts as a door-bell switch. void setup() { Serial.begin(9600); // Debugging only pinMode(5,INPUT); This code is used to print the message “init failedᾠwhen the RF TX module does not initialize at starting of the program and this run only ones. if (!driver.init()) Serial.println("init failed"); function checks whether the pin is logic HIGH or LOW, i.e. if the doorbell switch is on the state or in an off state.The pointer msg contains the message which we want to send through a transmitter. One note is that we must know the number of characters we need to send. This will help in writing the receiver code. if(digitalRead(5)==HIGH){ const char *msg = "a"; command checks the length of the message, which is 1 in this case. The driver.send() commands sends the data to the tx module which are converted into waves. The command driver.waitPacketSent() is used to wait until the data is sent. driver.send((uint8_t *)msg, strlen(msg)); driver.waitPacketSent();

Arduino Receiver Code Explanation

You can directly use it with your hardware; the code explanation is as follows. These are the header files which are needed to be included to send or receive the data using the RF module. These libraries make the connection between the Arduino and the RF module simple. Without these, you have to manually write the code for connecting the RF module with the Arduino. #include <RH_ASK.h> #include <SPI.h> // Not actually used but needed to compile tutorial. #include "pitches.h" //add Equivalent frequency for musical note #include "themes.h" //add Note vale and duration to access the commands used for sending and receiving the data. RH_ASK driver; condition checks if the initialization is failed or not. void setup() { Serial.begin(9600); // Debugging purpose if (!driver.init()) Serial.println("init failed"); else Serial.println("done"); This whole code deals with the notes, pitches, and duration to be taken to the required melody void Play_Pirates() { for (int thisNote = 0; thisNote < (sizeof(Pirates_note)/sizeof(int)); thisNote++) { int noteDuration = 1000 / Pirates_duration[thisNote];//convert duration to time delay tone(8, Pirates_note[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 1.05; //Here 1.05 is tempo, increase to play it slower delay(pauseBetweenNotes); noTone(8); //stop music on pin 8 } } variable in binary form. void loop() { uint8_t buf[1]; uint8_t buflen = sizeof(buf); This code checks whether we received the correct data and if the received signal is correct it plays the song. if (driver.recv(buf, &buflen)) // Non-blocking Serial.println("Selected -> 'He is a Pirate' "); Play_Pirates(); Serial.println("stop");

Wireless Arduino Doorbell Working

and the music will start to play. . Code // ask_transmitter.pde // -*- mode: C++ -*- // Simple example of how to use RadioHead to transmit messages // with a simple ASK transmitter in a very simple way. // Implements a simplex (one-way) transmitter with an TX-C1 module #include <RH_ASK.h> #include <SPI.h> // Not actually used but needed to compile RH_ASK driver; // RH_ASK driver(2000, 2, 4, 5); // ESP8266 or ESP32: do not use pin 11 void setup() { Serial.begin(9600); // Debugging only pinMode(5,INPUT); if (!driver.init()) Serial.println("init failed"); } void loop() { if(digitalRead(5)==HIGH){ const char *msg = "a"; driver.send((uint8_t *)msg, strlen(msg)); driver.waitPacketSent(); delay(200); } } #include <RH_ASK.h> #include <SPI.h> // Not actualy used but needed to compile #include "pitches.h" //add Equivalent frequency for musical note #include "themes.h" //add Note vale and duration RH_ASK driver; void setup() { Serial.begin(9600); // Debugging only if (!driver.init()) Serial.println("init failed"); else Serial.println("done"); } void Play_Pirates() { for (int thisNote = 0; thisNote < (sizeof(Pirates_note)/sizeof(int)); thisNote++) { int noteDuration = 1000 / Pirates_duration[thisNote];//convert duration to time delay tone(8, Pirates_note[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 1.05; //Here 1.05 is tempo, increase to play it slower delay(pauseBetweenNotes); noTone(8); //stop music on pin 8 } } void loop() { uint8_t buf[1]; uint8_t buflen = sizeof(buf); if (driver.recv(buf, &buflen)) // Non-blocking { Serial.println("Selected -> 'He is a Pirate' "); Play_Pirates(); Serial.println("stop"); } } Video microcontroller-projects/how-to-interface-rfm69hcw-rf-module-with-arduino

How to Interface RFM69HCW RF Module with Arduino for Wireless Communication

and Wireless Doorbell using this 433MHz RF module. But often-times an ASK Hybrid Transmitter and receiver is just not enough, it's low range and one-way communication nature makes it unsuitable for many applications to check its working so that you can use it in projects of your choice. So, let’s get started.

RFM69HCW RF Module

and other data acquisition projects. +20 dBm - 100 mW Power Output Capability High Sensitivity: down to -120 dBm at 1.2 kbps Low current: Rx = 16 mA, 100nA register retention Programmable Pout: -18 to +20 dBm in 1dB steps Constant RF performance over a voltage range of module FSK, GFSK, MSK, GMSK and OOK modulations Built-in Bit Synchronizer performing Clock Recovery 115 dB+ Dynamic Range RSSI Automatic RF Sense with ultra-fast AFC Packet engine with CRC-16, AES-128, 66-byte FIFO Built-in temperature sensor High Link Budget Very Low Cost

RFM69HCW - Hardware Overview

, a set of unlicensed radio frequencies for low-power, short-range devices. Different frequencies are legal in different areas so that’s why the module has many different versions 315,433,868 and 915MHz. All major RF communication parameters are programmable and most of them can be dynamically set, also the RFM69HCW offers the unique advantage of programmable narrow-band and wide-band communication modes. Because of its comparatively low power and short-range, implementation of this module in a small project is not going to be an issue, but if you are thinking about making a product out of it be sure you are using the correct frequency for your location. So, what is this link budget and why it is so important? The link budget is like every other budget, something you have at the beginning and which you spend over time if your budget is used up you cannot spend more. is 140 dB so let’s check the biggest theoretical distance we can communicate, we set everything to zero and the distance to 500KM, Frequency to 433MHz and we get a horizontal received-power of 139.2 dBm Now, I set everything to zero and the distance to 9KM Frequency to 433MHz and We get a horizontal received-power of 104.3 dBm So with the above comparison, I think we can all agree that the RFM69 module is far better than the ASK Hybrid Transmitter and a receiver module. , the speed of light, which is 299.792.458 m/s. The wavelength for the 433 MHz band is thus 299.792.458 / 433.000.000 = 34,54 cm. Half of this is 17,27 cm and a quarter is 8,63 cm. The RFM69HCW has an operating voltage between 1.8V to 3.6V and can draw up to 130mA of current when it's transmitting. Below in the table, we can clearly see the power consumption of the module in different conditions If your chosen Arduino uses 5V logic levels to communicate with the peripheral's hooking up the module directly to Arduino will damage the module
IDDSLCurrent in Sleep mode-0.11uA
IDDIDLECurrent in Idle modeRC oscillator enabled-1.2-uA
IDDSTCurrent in Standby ModeCrystal oscillator enabled-1.251.5uA
IDDFScurrent in Synthesizer mode-9-uA
IDDRcurrent in Receive mode-16-uA
IDDTSupply current in Transmit mode with appropriate matching, stable across VDD rangeRFOP = +20 dBm, on PA_BOOST RFOP = +17 dBm, on PA_BOOST RFOP = +13 dBm, on RFIO pin RFOP = +10 dBm, on RFIO pin RFOP = 0 dBm, on RFIO pin RFOP = -1 dBm, on RFIO pin- - - - - -130 95 45 33 20 16- - - - - -mA mA mA mA mAmA
to communicate with the module. We are using Arduino nano's because the built-in internal regulator can manage the peak current very efficiently. The Fritzing diagram in the hardware section below will explain it more clearly to you. If your power supply cannot provide 130mA of peak current your Arduino may reboot or worse the module can fail to communicate properly, in this situation a large value capacitor with low ESR can improve the situation

RFM69 Module Pinouts and Description

ANTRF signal output/input.Power GroundGND
GNDAntenna ground (same as power ground)Digital I/O, software configuredDIO5
DIO3Digital I/O, software configuredReset trigger inputRST
DIO4Digital I/O, software configuredSPI Chip select inputNSS
3.3V3.3V Supply (at least 130 mA)SPI Clock inputSCK
DIO0Digital I/O, software configuredSPI Data inputMOSI
DIO1Digital I/O, software configuredSPI Data outputMISO
DIO2Digital I/O, software configuredPower GroundGND

Preparing Custom Development Board

When I bought the module it did not come with a breadboard compatible breakout board so we've decided to make one myself. If you might have to do the same then just follow the steps. Also, note that it is not mandatory to follow these steps, you can simply solder wires to the RF module and connect them to breadboard and it would still work. I am following this procedure only to get a stable and rugged set-up. Prepare the schematics for RFM69HCW module

Make the board layout on any PCB design software of your choice I printed the footprint on a copper board and dropped it in the etching solution Follow the procedure for both the boards and solder your module to the footprint. After soldering both my modules look like this below is given in the below figure

Materials Required

Here's the list of things you will need to communicate with the module Two RFM69HCW modules (with matching frequencies): 434 MHz (WRL-12823) Two Arduino (I am using Arduino NANO) Two logic level converters Two breakout boards (I am using a custom made breakout board) A push-button Four LED’s One 4.7K resistor four 220Ohms resistor Jumper wires Enameled copper wire (22AWG), to make the antenna. And finally soldering(if u already haven't done that)

Hardware connection

In this tutorial we are using Arduino nano which uses 5 volt logic but the RFM69HCW module uses 3.3 volt logic levels as you can clearly see in the above table so to properly communicate between two devices a logic level converter is mandatory, in the fritzing diagram below we have shown you how to hook up the Arduino nano to the RFM69 module.
D2DIO0-
D3-TAC_SWITCH
D4-LED_GREEN
D5-LED_RED
D9-LED_BLUE
D10NSS-
D11MOSI-
D12MISO-
D13SCK-
D2DIO0-
D9-LED
D10NSS-
D11MOSI-
D12MISO-
D13SCK-

Running the Example Sketch

In this tutorial, we're going to set up two Arduino RFM69 nodes and get them to communicate with each other. In the section below we will know how to get the module up and running with the help of the RFM69 library which is written by Felix Rusu of LowPowerLab. section of this link Plug in the USB of the Sender Node to your PC, a new COM port number should be added to the Arduino IDE's "Tools/Port" list, pen it down, now plug in the Receiver node another COM port should appear in the Tools/Port list, also pen it down, with the help of the port number we will upload the sketch to the sender and the receiver node. Open two Arduino IDE sessions by double-clicking the Arduino IDE icon after the first session loads up, it's mandatory to open two Arduino sessions because that's how you can open two Arduino serial monitor window and simultaneously monitor the output of two nodes Now when everything is set up we need to open the example code in both Arduino sessions to do so, goto and click it to open it Near the top of the code, look for #define NETWORKID and change the value to 0. With this Id, all of your nodes can communicate with each other. Look for the #define FREQUENCY change this to match the board frequency(mine is 433_MHz). Look for the #define ENCRYPTKEY this is your 16-bit encryption key. Look for #define IS_RFM69HW_HCW, and uncomment it if you are using an RFM69_HCW module And finally, look for #define NODEID it should be set as a RECEIVER by default Now upload the code to your Receiver Node that you have previously set up. Time to modify the Sketch for the Sender Node Now in the #define NODEID macro change it to SENDER and upload the code to your Sender Node. That's it, if u have done everything correctly u have two complete working models ready to test.

Working of the Example Sketch

After the successful upload of the Sketch you will observe the Red LED which is connected with the pin D4 of the Arduino lits up, now press the button in the Sender Node and you will observe that the Red LED turns off and the Green LED which is connected to the Pin D5 of the Arduino lights up as shown in the image below You can also observe Button Pressed! text in the Serial monitor window as shown below Now observe the Blue LED which is connected to the Pin D9 of the Sender Node, it will blink twice and in the Serial Monitor window of the Receive Node you will observe the following message and also the Blue LED which is connected to the D9 pin in the Receiver Node will lit up. If you see the above message in the Serial Monitor window of the receiver node and also if the LED lights up Congratulations! You have successfully communicated the RFM69 module with Arduino IDE. The complete working of this tutorial can also be found in the video given at the bottom of this page. , wireless pump controller with indicator, drones, robots, your cat... the sky's the limit! Hope you understood the tutorial and enjoyed building something useful. If you have any questions please leave them in the comment section or use the forums for other technical queries. Code // *************************************************************************************** // Sample RFM69 sketch for Moteino to illustrate: // - sending // - receiving // - automatic transmission control // - button reading/interrupts // *************************************************************************************** // When you press the button on the SENDER Moteino, it will send a short message to the // RECEIVER Moteino and wait for an ACK (acknowledgement that message was received) from // the RECEIVER Moteino. If the ACK was received, the SENDER will blink the onboard LED // a few times. The RECEIVER listens to a specific token, and it alternates the onboard LED // state from HIGH to LOW or vice versa whenever this token is received. // *************************************************************************************** // Hardware setup: // *************************************************************************************** // On the sender, hook up a momentary tactile button to D3 like this: // __-__ // __| |___ // GND ----> BTN ----> D3 (D11 on MoteinoMEGA) // Load this sketch on the RECEIVER with NODEID=RECEIVER (adjust in config section below) // Load this sketch on the SENDER with NODEID=SENDER (adjust in config section below) // RFM69 library and code by Felix Rusu - felix@lowpowerlab.com // Get libraries at: https://github.com/LowPowerLab/ // Make sure you adjust the settings in the configuration section below !!! // ********************************************************************************** // Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact // ********************************************************************************** // License // ********************************************************************************** // This program is free software; you can redistribute it // and/or modify it under the terms of the GNU General // Public License as published by the Free Software // Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will // be useful, but WITHOUT ANY WARRANTY; without even the // implied warranty of MERCHANTABILITY or FITNESS FOR A // PARTICULAR PURPOSE. See the GNU General Public // License for more details. // // Licence can be viewed at // http://www.gnu.org/licenses/gpl-3.0.txt // // Please maintain this license information along with authorship // and copyright notices in any redistribution of this code // ********************************************************************************** #include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69 #include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69 #include <SPI.h> //included with Arduino IDE #include <LowPower.h> //get library from: https://github.com/lowpowerlab/lowpower //**************************************************************************************************************** //**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! **** //**************************************************************************************************************** #define NETWORKID 100 //the same on all nodes that talk to each other #define RECEIVER 1 //unique ID of the gateway/receiver #define SENDER 2 #define NODEID RECEIVER //change to "SENDER" if this is the sender node (the one with the button) //Match frequency to the hardware version of the radio on your Moteino (uncomment one): #define FREQUENCY RF69_433MHZ //#define FREQUENCY RF69_868MHZ //#define FREQUENCY RF69_915MHZ #define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes! #define IS_RFM69HW_HCW //uncomment only for RFM69HW/HCW! Leave out if you have RFM69W/CW! //***************************************************************************************************************************** #define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL #define ATC_RSSI -75 //********************************************************************************************* #define SERIAL_BAUD 115200 #ifdef __AVR_ATmega1284P__ #define LED 15 // Moteino MEGAs have LEDs on D15 #define BUTTON_INT 1 //user button on interrupt 1 (D3) #define BUTTON_PIN 11 //user button on interrupt 1 (D3) #else #define LED 9 // Moteinos have LEDs on D9 #define BUTTON_INT 1 //user button on interrupt 1 (D3) #define BUTTON_PIN 3 //user button on interrupt 1 (D3) #endif #define LED_GREEN 4 //GREEN LED on the SENDER #define LED_RED 5 //RED LED on the SENDER #define RX_TOGGLE_PIN 7 //GPIO to toggle on the RECEIVER #ifdef ENABLE_ATC RFM69_ATC radio; #else RFM69 radio; #endif void setup() { Serial.begin(SERIAL_BAUD); radio.initialize(FREQUENCY,NODEID,NETWORKID); #ifdef IS_RFM69HW_HCW radio.setHighPower(); //must include this only for RFM69HW/HCW! #endif radio.encrypt(ENCRYPTKEY); #ifdef ENABLE_ATC radio.enableAutoPower(ATC_RSSI); #endif char buff[50]; sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915); Serial.println(buff); Serial.flush(); pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(LED, OUTPUT); attachInterrupt(BUTTON_INT, handleButton, FALLING); pinMode(LED_GREEN, OUTPUT); pinMode(LED_RED, OUTPUT); pinMode(RX_TOGGLE_PIN, OUTPUT); digitalWrite(LED_GREEN, LOW); digitalWrite(LED_RED, HIGH); } //******** THIS IS INTERRUPT BASED DEBOUNCING FOR BUTTON ATTACHED TO D3 (INTERRUPT 1) #define FLAG_INTERRUPT 0x01 volatile int mainEventFlags = 0; boolean buttonPressed = false; void handleButton() { mainEventFlags |= FLAG_INTERRUPT; } byte LEDSTATE=LOW; //LOW=0 void loop() { //******** THIS IS INTERRUPT BASED DEBOUNCING FOR BUTTON ATTACHED TO D3 (INTERRUPT 1) if (mainEventFlags & FLAG_INTERRUPT) { LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_ON); mainEventFlags &= ~FLAG_INTERRUPT; if (!digitalRead(BUTTON_PIN)) { buttonPressed=true; } } if (buttonPressed) { Serial.println("Button pressed!"); buttonPressed = false; if(LEDSTATE==LOW) { LEDSTATE=HIGH; digitalWrite(LED_GREEN, HIGH); digitalWrite(LED_RED, LOW); } else { LEDSTATE=LOW; digitalWrite(LED_GREEN, LOW); digitalWrite(LED_RED, HIGH); } if (radio.sendWithRetry(RECEIVER, "Hi", 2)) //target node Id, message as string or byte array, message length Blink(LED, 40, 3); //blink LED 3 times, 40ms between blinks } //check if something was received (could be an interrupt from the radio) if (radio.receiveDone()) { //print message received to serial Serial.print('[');Serial.print(radio.SENDERID);Serial.print("] "); Serial.print((char*)radio.DATA); Serial.print(" [RX_RSSI:");Serial.print(radio.RSSI);Serial.print("]"); Serial.println(); //check if received message is 2 bytes long, and check if the message is specifically "Hi" if (radio.DATALEN==2 && radio.DATA[0]=='H' && radio.DATA[1]=='i') { if(LEDSTATE==LOW) LEDSTATE=HIGH; else LEDSTATE=LOW; digitalWrite(LED, LEDSTATE); digitalWrite(RX_TOGGLE_PIN, LEDSTATE); } //check if sender wanted an ACK if (radio.ACKRequested()) { radio.sendACK(); Serial.print(" - ACK sent"); } } radio.receiveDone(); //put radio in RX mode Serial.flush(); //make sure all serial data is clocked out before sleeping the MCU LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_ON); //sleep Moteino in low power mode (to save battery) } void Blink(byte PIN, byte DELAY_MS, byte loops) { for (byte i=0; i<loops; i++) { digitalWrite(PIN,HIGH); delay(DELAY_MS); digitalWrite(PIN,LOW); delay(DELAY_MS); } } // ********************************************************************************** #include <RFM69.h> #include <RFM69_ATC.h> #include <SPI.h> #include <LowPower.h> //**************************************************************************************************************** //**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! **** //**************************************************************************************************************** #define NETWORKID 100 //the same on all nodes that talk to each other #define RECEIVER 1 //unique ID of the gateway/receiver #define SENDER 2 #define NODEID RECEIVER //change to "SENDER" if this is the sender node (the one with the button) //Match frequency to the hardware version of the radio on your Moteino (uncomment one): #define FREQUENCY RF69_433MHZ //#define FREQUENCY RF69_868MHZ //#define FREQUENCY RF69_915MHZ #define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes! #define IS_RFM69HW_HCW //uncomment only for RFM69HW/HCW! Leave out if you have RFM69W/CW! //***************************************************************************************************************************** #define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL #define ATC_RSSI -75 //********************************************************************************************* #define SERIAL_BAUD 115200 #ifdef __AVR_ATmega1284P__ #define LED 15 // Moteino MEGAs have LEDs on D15 #define BUTTON_INT 1 //user button on interrupt 1 (D3) #define BUTTON_PIN 11 //user button on interrupt 1 (D3) #else #define LED 9 // Moteinos have LEDs on D9 #define BUTTON_INT 1 //user button on interrupt 1 (D3) #define BUTTON_PIN 3 //user button on interrupt 1 (D3) #endif #define LED_GREEN 4 //GREEN LED on the SENDER #define LED_RED 5 //RED LED on the SENDER #define RX_TOGGLE_PIN 7 //GPIO to toggle on the RECEIVER #ifdef ENABLE_ATC RFM69_ATC radio; #else RFM69 radio; #endif void setup() { Serial.begin(SERIAL_BAUD); radio.initialize(FREQUENCY,NODEID,NETWORKID); #ifdef IS_RFM69HW_HCW radio.setHighPower(); //must include this only for RFM69HW/HCW! #endif radio.encrypt(ENCRYPTKEY); #ifdef ENABLE_ATC radio.enableAutoPower(ATC_RSSI); #endif char buff[50]; sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915); Serial.println(buff); Serial.flush(); pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(LED, OUTPUT); attachInterrupt(BUTTON_INT, handleButton, FALLING); pinMode(LED_GREEN, OUTPUT); pinMode(LED_RED, OUTPUT); pinMode(RX_TOGGLE_PIN, OUTPUT); digitalWrite(LED_GREEN, LOW); digitalWrite(LED_RED, HIGH); } //******** THIS IS INTERRUPT BASED DEBOUNCING FOR BUTTON ATTACHED TO D3 (INTERRUPT 1) #define FLAG_INTERRUPT 0x01 volatile int mainEventFlags = 0; boolean buttonPressed = false; void handleButton() { mainEventFlags |= FLAG_INTERRUPT; } byte LEDSTATE=LOW; //LOW=0 void loop() { //******** THIS IS INTERRUPT BASED DEBOUNCING FOR BUTTON ATTACHED TO D3 (INTERRUPT 1) if (mainEventFlags & FLAG_INTERRUPT) { LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_ON); mainEventFlags &= ~FLAG_INTERRUPT; if (!digitalRead(BUTTON_PIN)) { buttonPressed=true; } } if (buttonPressed) { Serial.println("Button pressed!"); buttonPressed = false; if(LEDSTATE==LOW) { LEDSTATE=HIGH; digitalWrite(LED_GREEN, HIGH); digitalWrite(LED_RED, LOW); } else { LEDSTATE=LOW; digitalWrite(LED_GREEN, LOW); digitalWrite(LED_RED, HIGH); } if (radio.sendWithRetry(RECEIVER, "Hi", 2)) //target node Id, message as string or byte array, message length Blink(LED, 40, 3); //blink LED 3 times, 40ms between blinks } //check if something was received (could be an interrupt from the radio) if (radio.receiveDone()) { //print message received to serial Serial.print('[');Serial.print(radio.SENDERID);Serial.print("] "); Serial.print((char*)radio.DATA); Serial.print(" [RX_RSSI:");Serial.print(radio.RSSI);Serial.print("]"); Serial.println(); //check if received message is 2 bytes long, and check if the message is specifically "Hi" if (radio.DATALEN==2 && radio.DATA[0]=='H' && radio.DATA[1]=='i') { if(LEDSTATE==LOW) LEDSTATE=HIGH; else LEDSTATE=LOW; digitalWrite(LED, LEDSTATE); digitalWrite(RX_TOGGLE_PIN, LEDSTATE); } //check if sender wanted an ACK if (radio.ACKRequested()) { radio.sendACK(); Serial.print(" - ACK sent"); } } radio.receiveDone(); //put radio in RX mode Serial.flush(); //make sure all serial data is clocked out before sleeping the MCU LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_ON); //sleep Moteino in low power mode (to save battery) } void Blink(byte PIN, byte DELAY_MS, byte loops) { for (byte i=0; i<loops; i++) { digitalWrite(PIN,HIGH); delay(DELAY_MS); digitalWrite(PIN,LOW); delay(DELAY_MS); } } Video microcontroller-projects/digital-notice-board-using-p10-led-matrix-display-and-arduino

LED Display Board using P10 LED Matrix Display and Arduino

P10 modules can be cascaded to build any size of the advertising board.

Required Components

Arduino UNO-1 32*16 P10 LED display module-1 16 Pin FRC connector-1 5V DC,3 AMP SMPS Connectors

Working of a P10 LED Matrix Module

is the most suitable for designing any size of outdoor or indoor LED display advertisement board. This panel has a total of 512 high brightness LEDs mounted on a plastic housing designed for best display results. Any number of such panels can be combined in any row and column structures to design an attractive LED signboard. The 32*16 module size means that there are 32 LEDs in each row and 16 LEDs in each column. So there is a total of 512 numbers of LEDs present in each module unit. Brightness: 3500-4500nits Max Power Consumption: 20W Voltage Input: DC 5V IP65 Waterproof 1W Pixel Configuration High Viewing Angle High Contrast Ratio Enable: This pin is used to control the brightness of the LED panel, by giving a PWM pulse to it. A, B: These are called multiplex select pins. They take digital input to select any multiplex rows. Shift clock (CLK), Store clock (SCLK) and Data: These are the normal shift register control pins. Here a shift register 74HC595 is used.

Circuit Diagram

is given below: Arduino UNO and P10 display modules are interconnected as per the pin mapping are shown below:
ENABLE9
A6
B7
CLK13
SCLK8
DATA11
GNDGND
rating accordingly.

P10 LED Module programming with Arduino

along with the video is given at the end of this tutorial. The stepwise description of the code is given below. , in our case we are using “Arial Black fontᾠfor the display. #include <SPI.h> #include <DMD.h> #include <TimerOne.h> #include "SystemFont5x7.h" #include "Arial_black_16.h" for the text scrolling on display board. #define ROW 1 #define COLUMN 1 #define FONT Arial_Black_16 DMD led_module(ROW, COLUMN); which checks for any incoming data from Arduino side through the SPI Terminals. If yes, then it will trigger an interrupt pin for doing certain events. void scan_module() { led_module.scanDisplayBySPI(); } is used to set all pixels are off initially to clear the display board. void setup() { Timer1.initialize(2000); Timer1.attachInterrupt(scan_module); led_module.clearScreen( true ); } function. led_module.selectFont(FONT); led_module.drawMarquee("Welcome to Circuit Digest",25, (32 * ROW), 0); shift the whole message from Right to Left directions using a certain time period. long start = millis(); long timming = start; boolean flag = false; while (!flag) { if ((timming + 20) < millis()) { flag = led_module.stepMarquee(-1, 0); timming = millis(); } } and LED matrix. Complete code and demonstration video is given below. Code #include <SPI.h> #include <DMD.h> #include <TimerOne.h> #include "SystemFont5x7.h" #include "Arial_black_16.h" #define ROW 1 #define COLUMN 1 #define FONT Arial_Black_16 DMD led_module(ROW, COLUMN); void scan_module() { led_module.scanDisplayBySPI(); } void setup() { Timer1.initialize(2000); Timer1.attachInterrupt(scan_module); led_module.clearScreen( true ); } void loop() { led_module.selectFont(FONT); led_module.drawMarquee("Welcome to Circuit Digest",25, (32 * ROW), 0); long start = millis(); long timming = start; boolean flag = false; while (!flag) { if ((timming + 20) < millis()) { flag = led_module.stepMarquee(-1, 0); timming = millis(); } } } Video microcontroller-projects/arduino-currency-counter-using-ir-and-color-sensor

Arduino Currency Counter using IR and Color Sensor

Required Components:

Arduino UNO TCS230 Colour sensor IR sensor Breadboard 16*2 Alphanumeric LCD Connecting Wires

TCS3200 Color Sensor Working

in which the sensor detects white light. The output signal of the TCS230 colour sensor is a square wave with a 50% duty cycle and its frequency is proportional to the light intensity of the selected filter.

Pinout of TCS3200 Color Sensor:

VDD- Voltage supply pin of Sensor. It is supplied with 5V DC. GND- Ground reference pin of a colour sensor S0, S1- Output frequency scaling selection inputs S2, S3- Photo-diode type selection inputs OUT- Output pin of a colour sensor OE- Enable pin for output frequency in this project, whose working can be understood by the following link.

Circuit Diagram

: Here, I have made a small structure like a POS currency swiping machine using cardboards. In this structure, a colour sensor and an IR sensor are fixed with the cardboard likeshown in the image below. is used to sense the presence of currency inside the slot and if there is a note, then the colour sensor will detect the color of the Note and send the color value to Arduino. And Arduino further calculates the currency value based on the color of the note.

Code Explanation

Here the stepwise explanation of the complete code is given below. First, include all the libraries in the program. Here we only need the LCD library to be included in the program. Then declare all the variables used in the code. #include <LiquidCrystal.h> int OutPut = 13; unsigned int frequency = 0; LiquidCrystal lcd(4, 6, 7, 8, 9, 10); int blue1; int red1; int green1; int a = 0, b = 0; int total = 1000; print the welcome message on LCD and define all the data directions of digital pins used in this project. Next, set the output frequency scaling of the colour sensor, in my case, it is set to 20% which can be set by giving HIGH pulse to S0 and LOW pulse to S1. void setup() { Serial.begin(9600); lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print(" Smart Wallet "); lcd.setCursor(0, 1); lcd.print(" Circuit Digest "); delay(2000); lcd.clear(); pinMode(2, OUTPUT);//S0 pinMode(3, OUTPUT);//S1 pinMode(11, OUTPUT);//S2 pinMode(12, OUTPUT);//S3 pinMode(13, INPUT);//OUT digitalWrite(2, HIGH); digitalWrite(3, LOW); } read all the data outputs from the sensors. The output from the IR sensor can be found by reading the A0 pin and output colour frequencies can be found by calling the individual functions written as red (), blue () and green (). Then print all of them on the Serial monitor. This is needed when we need to add a new currency to our project. int sensor = digitalRead(A0); int red1 = red(); int blue1 = blue(); int green1 = green(); Serial.println(red1); Serial.println(blue1); Serial.println(green1); Serial.println("-----------------------------"); Next, write all the conditions to check the output frequency of the colour sensor with the reference frequency which we have set before. If it matches, then deducts the specified amount from the wallet balance. if (red1>=20 && red1<=25 && blue1 >=30 && blue1 <=35 && green1 >=30 && green1 <=35 && a == 0 && sensor == HIGH) { a = 1; } else if (sensor == LOW && a == 1) { a = 0; if(total>=10) { lcd.setCursor(0, 1); lcd.print("10 Rupees!!!"); total=total-10; delay(1500); lcd.clear(); } } Here we have only set the conditions for 10 Rupees and 50 Rupees Note color, you can set more conditions to detect more no. of currency notes. The frequency output may be different in your case depending on the external lighting and sensor setup. So it is recommended to check the output frequency of your currency and set the reference value accordingly. lcd.setCursor(0, 0); lcd.print("Total Bal:"); lcd.setCursor(11, 0); lcd.print(total); delay(1000); The following function will get the output colour frequency of red content in the currency. Similarly, we can write other functions to get value for blue and green colour contents. int red() { digitalWrite(11, LOW); digitalWrite(12, LOW); frequency = pulseIn(OutPut, LOW); return frequency; } to detect the currency using the image, that way it will be more accurate and will be able to detect any currency. Code int OutPut = 13; unsigned int frequency = 0; #include <LiquidCrystal.h> LiquidCrystal lcd(4, 6, 7, 8, 9, 10); int blue1; int red1; int green1; int a = 0, b = 0; int total = 1000; void setup() { Serial.begin(9600); lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print(" Smart Wallet "); lcd.setCursor(0, 1); lcd.print(" Circuit Digest "); delay(2000); lcd.clear(); pinMode(2, OUTPUT);//S0 pinMode(3, OUTPUT);//S1 pinMode(11, OUTPUT);//S2 pinMode(12, OUTPUT);//S3 pinMode(13, INPUT);//OUT digitalWrite(2, HIGH); digitalWrite(3, LOW); } void loop() { int sensor = digitalRead(A0); int red1 = red(); int blue1 = blue(); int green1 = green(); Serial.println(red1); Serial.println(blue1); Serial.println(green1); Serial.println("-----------------------------"); if (red1>=20 && red1<=25 && blue1 >=30 && blue1 <=35 && green1 >=30 && green1 <=35 && a == 0 && sensor == HIGH) { a = 1; } else if (sensor == LOW && a == 1) { a = 0; if(total>=10) { lcd.setCursor(0, 1); lcd.print("10 Rupees!!!"); total=total-10; delay(1500); lcd.clear(); } } if (red1 >= 25 && red1 <= 30 && blue1 >= 30 && blue1 <= 33 && green1 >= 25 && green1 <=30 && b == 0 && sensor == HIGH) { b = 1; } else if (sensor == LOW && b == 1) { b = 0; if(total>=50) { lcd.setCursor(0, 1); lcd.print("50 Rupees!!!"); total=total-50; delay(1500); lcd.clear(); } } lcd.setCursor(0, 0); lcd.print("Total Bal:"); lcd.setCursor(11, 0); lcd.print(total); delay(1000); } int red() { digitalWrite(11, LOW); digitalWrite(12, LOW); frequency = pulseIn(OutPut, LOW); return frequency; } int blue() { digitalWrite(11, HIGH); digitalWrite(12, HIGH); frequency = pulseIn(OutPut, LOW); return frequency; } int green() { digitalWrite(11, LOW); digitalWrite(12, HIGH); frequency = pulseIn(OutPut, LOW); return frequency; } Video microcontroller-projects/arduino-home-automation-using-acoustic-connectivity-powered-by-chirp

Arduino Home Automation using Acoustic Connectivity powered by Chirp

added evidence to my thoughts. This is when I started thinking about an alternative wireless home automation solution that does not need Wi-Fi / Bluetooth to operate.

A Novel approach for Home Automation Devices using Chirp

method without using Wi-Fi or BLE. to run Chirp SDK for our project. , based on the message encoded in the data the Arduino board could perform any action like toggling an AC load controlling the RGB LED, etc. It might sound like a lot, but it is relatively simple and the complete instructions are given below. So let’s get started.

Playing Chirp Audio with Google Assistant

Open the Dialogflow console. You might have to sign-up if you have not done it yet. Then click on “Create New Agentᾠas shown below Give your new agent a name and then click on create. I have named my agent as “Circuitdgest_Automationᾍ Now you will be taken to the intents section. This is where you train your new agent for various intents. In our case we will write two intents, one is to turn on the light and the other is to turn off the light. You can write any number of intents based on the applications and commands that have to be understood by your Agent. By default, you will have the welcome intent, but let’s create a new one to turn on the light by clicking on “Create intentᾠand I will name this intent Lights on In the new page click on “Add Training Phrasesᾠand enter the command that has to be understood by your assistant in this case “Turn on the lightᾮ You can write any number of training phrases that convey the meaning of the same intent. Now scroll down and click on “Add Responseᾮ This is where we tell the assistant how to respond back if this particular intent is triggered. By default, you can enter text response here, but we need audio to be played our assistant, so click on the ᾫᾠsymbol near the “Defaultᾠtab and select Google assistant and then clock “Add responsesᾠand select “Simple Responsesᾮ Inside the simple response text box type in this code <speak> <audio src = "INSERT YOUR LINK"> </audio> Lights Turned ON </speak> It is a simple SSML code to play audio from a URL and then say “Lights Turned ONᾮ This audio should be the encoded audio from Chirp and it should be uploaded jovo.tech. Install the app and type in the message to be encoded and click on the Send button to listen to the encoded audio to upload your mp3 files and get a link for it. Now that you have got the link your response on dialog flow should look something like this Make sure you click on save to save this intent. Similarly, create another new intent turn off the lights. Again enter your training phrase and also your response. This time insert the link of the other audio file and ask it to say Lights turned off as shown below. Again make sure you save this as well. Now, on the left side click on the integrations tab and select Google assistant. This will help us test the application using Google assistant. Select the Google Assistant Application and click on “TESTᾍ This will take some time after which you will get the test screen as shown below. On the left corner, you can see a text box where you can type in your test commands and see how the application responds. You can also find some debugging applications on the left side of the screen. When you type “turn on reading lightsᾠit should play the chirp tone and say lights turned on, similar it should also for “Turn off reading lightsᾮ Once it works here, you can try it on any google assistant device like your phone or google home mini that connected to your Gmail ID. Just say talk to my test app and start controlling the device.

Preparing your Arduino Nano 33

Now on the hardware side, things have gotten pretty easy thanks to the Arduino Nano 33 BLE Sense board. Because the board has an in-built microphone and chirp libraries ready to deploy directly from your Arduino IDE. If you are completely new to this board then it is recommended that you read this “Getting started with Arduino Nano 33 BLEᾠArticle to understand more on this board. The circuit diagram to connect the relay module with nano 33 for home automation is shown below I have used Fritzing to draw the circuit diagram and since the nano 33 board is not yet available I have used the standard nano, but both have almost the same pinout. Again do remember that nano 33 operates on 3.3V so to connect a 5V relay you can use the Vin pin on the board. Since the nano 33 BLE sense board already has an onboard microphone we need not worry about it. But make sure your relay module can also work on 3.3V signal voltage because the GPIO pins of Nano 33 only get 3.3V hen high.

Programming Arduino using Chirp:

to your Arduino IDE for this program to compile. Arduino Chirp Communication ZIP File Download of Chirp to get your credentials. Also, make sure to select the configuration as 16khz-mono-embedded as shown below. Make note of the key, secret and config details because we have to use them in our Arduino program. Now open you Arduino program and move to the credentials.h tab and paste the corresponding values here. These credentials will vary from person to person and should be shared. The main program is the same as the example program, except inside the onReceivedCallback() we will add a small program to compare the obtained data with a pre-defined text. We have initialized a string variable called payload which will compare the actual value with a string and toggle the digital pin as required. We have also toggled the on-board LED light for acknowledgment. String payload = String(data); //Serial.println(payload); if (payload == "lights on") { digitalWrite(13,HIGH); digitalWrite(2,HIGH); Serial.println("Arduino has turned on the lights"); } if (payload == "lights off") { digitalWrite(13,LOW); digitalWrite(2,LOW); Serial.println("Arduino has turned off lights"); } to post them and I will try my best in answering them all. Code /**----------------------------------------------------------------------------- Example code using the Chirp SDK to receive data using the Arduino Nano 33 Sense board. @file Nano33SenseReceive.ino , and copy and paste your key, secret and config string for the "16khz-mono-embedded" protocol into the credentials.h file. This example will start listening for chirps and print to the terminal when anything is received. *Note*: this example can be used in conjunction with the send example, to send and receive data in the same application. *Important*: The example will not start until this Serial Monitor is opened. To disable this behaviour, comment out the while(!Serial) line. Circuit: - Arduino Nano 33 BLE board Copyright 2011-2019, Asio Ltd. All rights reserved. ----------------------------------------------------------------------------*/ #include <PDM.h> #include "chirp_sdk.h" #include "credentials.h" #define SAMPLE_RATE 16000 // Audio sample rate #define BUFFER_SIZE 256 // Audio buffer size // Global variables ------------------------------------------------------------ static chirp_sdk_t *chirp = NULL; short sampleBuffer[BUFFER_SIZE]; volatile int samplesRead; // Function definitions -------------------------------------------------------- void setupChirp(void); void chirpErrorHandler(chirp_sdk_error_code_t code); void onPDMdata(void); // Main ------------------------------------------------------------------------ void setup() { pinMode(13, OUTPUT); pinMode(2, OUTPUT); Serial.begin(115200); //while (!Serial); // Enable high frequency oscillator NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); setupChirp(); PDM.onReceive(onPDMdata); PDM.setGain(30); if (!PDM.begin(1, SAMPLE_RATE)) { Serial.println("Failed to start PDM!"); while (1); } } void loop() { if (samplesRead) { chirp_sdk_error_code_t err = chirp_sdk_process_shorts_input(chirp, sampleBuffer, samplesRead); chirpErrorHandler(err); samplesRead = 0; } } void onPDMdata() { int bytesAvailable = PDM.available(); PDM.read(sampleBuffer, bytesAvailable); samplesRead = bytesAvailable / sizeof(short); } // Chirp ----------------------------------------------------------------------- void onReceivingCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) { Serial.println("Receiving data..."); } void onReceivedCallback(void *chirp, uint8_t *payload, size_t length, uint8_t channel) { if (payload) { char *data = (char *)calloc(length + 1, sizeof(uint8_t)); memcpy(data, payload, length * sizeof(uint8_t)); Serial.print("Received data: "); Serial.println(data); String payload = String(data); //Serial.println(payload); if (payload == "lights on") { digitalWrite(13,HIGH); digitalWrite(2,HIGH); Serial.println("Arduino has turned on the lights"); } if (payload == "lights off") { digitalWrite(13,LOW); digitalWrite(2,LOW); Serial.println("Arduino has turned off lights"); } free(data); } else { Serial.println("Decode failed."); } } void chirpErrorHandler(chirp_sdk_error_code_t code) { if (code != CHIRP_SDK_OK) { const char *errorString = chirp_sdk_error_code_to_string(code); Serial.println(errorString); exit(42); } } void setupChirp(void) { chirp = new_chirp_sdk(CHIRP_APP_KEY, CHIRP_APP_SECRET); if (chirp == NULL) { Serial.println("Chirp initialisation failed."); return; } chirp_sdk_error_code_t err = chirp_sdk_set_config(chirp, CHIRP_APP_CONFIG); chirpErrorHandler(err); chirp_sdk_callback_set_t callback_set = { .on_state_changed = NULL, .on_sending = NULL, .on_sent = NULL, .on_receiving = onReceivingCallback, .on_received = onReceivedCallback }; err = chirp_sdk_set_callbacks(chirp, callback_set); chirpErrorHandler(err); err = chirp_sdk_set_input_sample_rate(chirp, SAMPLE_RATE); chirpErrorHandler(err); // A fixed frequency correction coefficient is needed to correct a clock // mismatch between the 16000Hz requested sample rate and the Nano's actual // audio sample rate. err = chirp_sdk_set_frequency_correction(chirp, 1.00812); chirpErrorHandler(err); err = chirp_sdk_start(chirp); chirpErrorHandler(err); Serial.println("Chirp SDK initialised."); Serial.flush(); } Video microcontroller-projects/arduino-nano-33-ble-sense-board-review-and-getting-started-guide

Arduino Nano 33 BLE Sense Review - What's New and How to Get Started?

module has some built-in sensors (will get into details later) while the Arduino Nano 33 IoT does not have them. In this article we will review the Arduino Nano 33 BLE sense board, introduce you to its features and functionalities and finally write a sample code to read the sensor values and display on serial monitor. So let’s get learning‐󬟍

Arduino Nano 33 BLE Sense

and the name “senseᾠindicates that it has on-board sensors like accelerometer, gyroscope, magnetometer, temperature and humidity sensor, Pressure sensor, Proximity sensor, Colour sensor, Gesture sensor, and even a built-in microphone. We will get into the details of BLE and other sensors later but for now this is how an Arduino Nano 33 BLE sense board looks straight of un-boxing.

Arduino Nano 33 BLE Sense Hardware Overview

it also provides some software improvements which we will discuss later. The sensors, LEDs, pushbuttons and other important stuff that you should know on your board are marked in the below image. and other smart portable devices like Fitness bands, Glucose monitoring, Pedometers, smartwatch, weather station, Home security etc where you will be using most of these sensors. And like always all these sensors have pre-built libraries for Arduino which you can use readily. At the end of this article we will read values from all these sensors and display it on the serial monitor. The sensor details on Arduino Nano 33 BLE sense board along with its required libraries are tabulated below
Accelerometer, Gyroscope, Magnetometer
Pressure
Temperature and Humidity
Proximity, Light, Colour, Gesture
Microphone
For more information on these sensors, you can visit the respective datasheet and also make sure you have added the entire provided library to your Arduino IDE to begin using them with your Arduino Nano 33 BLE sense board. To add a library you can use the given link to get to the respective GitHub page and download the ZIP file, then use Sketch -> Include Library -> Add.ZIP Library or you can also use the library manager on Arduino IDE and add these libraries. the Arduino Nano 44 BLE board has the following technical specifications Operating Voltage: 3.3V USB-Input Voltage: 5V Input-pin Voltage: 4.5V to 21V Chip: NINA-B3 ᾠRF52840 Clock: 64MHz Flash : 1MB SRAM: 256 KB Wireless Connectivity: Bluetooth 5.0 / BLE Interfaces: USB, I2C, SPI, I2S, UART Digital I/O Pins: 14 PWM Pins: 6 (8-bit resolution) Analog Pins: 8 (10-bit or 12-bit configurable)

Software improvements with Arduino Nano 33 BLE sense

during the delay time to save power and would jump back into operation once the delay is over. It is reported that this operation will consume 4.5uA less than a normal Arduino delay operation. That being said, the Mbed OS integration with Arduino IDE is relatively new and it is going to take some time before we can fully utilize the full power of Mbed OS with Arduino IDE. So for a quick start-up, we will write a program to read all the sensor's values and display it on the serial monitors.

Preparing your Arduino IDE for Arduino Nano 33 BLE sense

Launch your Arduino IDE and go to Tools -> Boards -> Board Manger to launch your Arduino Board manager. Now search for “Mbed OSᾠand install the package. It should take some time for the installation to complete. Once the installation is done, close the dialog box and connect your Arduino 33 board using a micro USB cable with your laptop. As soon as you connect the board windows will automatically start installing the required drivers for the board. Then open your Arduino IDE and select Tools -> Board -> Arduino Nano 33. Then also select the right COM port by checking Tools -> Port, mine is connected to port COM3 but yours might vary. After the port is selected your IDE bottom right corner should look like this Now to quickly check if everything is working we can use an example program, let’s try the one provided at File -> Examples -> PDM -> PDMSerialPlotter. This program will use the on-board microphone to listen for audio and plot it on a serial plotter. You can upload the program and check if the board and the IDE are working. , let’s hope someone from the wonderful Arduino Community comes up with a solution for this.

Program to read sensor data and display on Serial Monitor

If we do not use the BLE or core Mbed OS functionalities of the board the compile time was reasonable. So I wrote a simple sketch to read all the sensor values and display it on the serial monitor like show below The complete code to do the same is given at the bottom of this page, but make sure you have installed all the libraries mentioned above. The explanation of the code is as follows. Start the program by including all the required header files. Here we will be using all the four sensors except for the microphone #include <Arduino_LSM9DS1.h> //Include the library for 9-axis IMU #include <Arduino_LPS22HB.h> //Include library to read Pressure #include <Arduino_HTS221.h> //Include library to read Temperature and Humidity #include <Arduino_APDS9960.h> //Include library for colour, proximity and gesture recognition Inside the setup function we initialize the serial monitor at 9600 baud rate to display all the sensor values and also initialize all the required libraries. The code inside setup is shown below void setup(){ Serial.begin(9600); //Serial monitor to display all sensor values if (!IMU.begin()) //Initialize IMU sensor { Serial.println("Failed to initialize IMU!"); while (1);} if (!BARO.begin()) //Initialize Pressure sensor { Serial.println("Failed to initialize Pressure Sensor!"); while (1);} if (!HTS.begin()) //Initialize Temperature and Humidity sensor { Serial.println("Failed to initialize Temperature and Humidity Sensor!"); while (1);} if (!APDS.begin()) //Initialize Colour, Proximity and Gesture sensor { Serial.println("Failed to initialize Colour, Proximity and Gesture Sensor!"); while (1);} } Inside the loop function, we read the required sensor values from the library and then print them on the serial monitor. The syntax can be referred from the example program of each library, we have read the accelerometer, gyroscope, magnetometer, pressure, temperature, humidity and proximity sensor values and displayed them on the serial monitor. The code to measure the accelerometer value is shown below, likewise, we can measure for all sensors. //Accelerometer values if (IMU.accelerationAvailable()) { IMU.readAcceleration(accel_x, accel_y, accel_z); Serial.print("Accelerometer = ");Serial.print(accel_x); Serial.print(", ");Serial.print(accel_y);Serial.print(", ");Serial.println(accel_z); } delay (200);

Arduino Nano 33 BLE- Uploading the code

Uploading the code to Nano 33 is similar to any other boards, but do note that the board has two COM ports. When you click on the upload button the Arduino IDE compiles the code and then resets the board automatically through software command, this will put the board in boot loader mode and upload your code. Because of this, once the upload is done you might notice that the Arduino IDE has automatically changed its COM port to a different number and you might want to change it back before you open your serial monitor. So this is pretty much my experience with the Arduino Nano 33 board so far, I will try building something with its sensors and BLE features sometime later in the future. How was your experience with the board? What would you want me to build with it? Leave the answers in the comment section and we will discuss more. Code #include <Arduino_LSM9DS1.h> //Include the library for 9-axis IMU #include <Arduino_LPS22HB.h> //Include library to read Pressure #include <Arduino_HTS221.h> //Include library to read Temperature and Humidity #include <Arduino_APDS9960.h> //Include library for colour, proximity and gesture recognition void setup(){ Serial.begin(9600); //Serial monitor to display all sensor values if (!IMU.begin()) //Initialize IMU sensor { Serial.println("Failed to initialize IMU!"); while (1);} if (!BARO.begin()) //Initialize Pressure sensor { Serial.println("Failed to initialize Pressure Sensor!"); while (1);} if (!HTS.begin()) //Initialize Temperature and Humidity sensor { Serial.println("Failed to initialize Temperature and Humidity Sensor!"); while (1);} if (!APDS.begin()) //Initialize Colour, Proximity and Gesture sensor { Serial.println("Failed to initialize Colour, Proximity and Gesture Sensor!"); while (1);} } float accel_x, accel_y, accel_z; float gyro_x, gyro_y, gyro_z; float mag_x, mag_y, mag_z; float Pressure; float Temperature, Humidity; int Proximity; void loop() { //Accelerometer values if (IMU.accelerationAvailable()) { IMU.readAcceleration(accel_x, accel_y, accel_z); Serial.print("Accelerometer = ");Serial.print(accel_x); Serial.print(", ");Serial.print(accel_y);Serial.print(", ");Serial.println(accel_z); } delay (200); //Gyroscope values if (IMU.gyroscopeAvailable()) { IMU.readGyroscope(gyro_x, gyro_y, gyro_z); Serial.print("Gyroscope = ");Serial.print(gyro_x); Serial.print(", ");Serial.print(gyro_y);Serial.print(", ");Serial.println(gyro_z); } delay (200); //Magnetometer values if (IMU.magneticFieldAvailable()) { IMU.readMagneticField(mag_x, mag_y, mag_z); Serial.print("Magnetometer = ");Serial.print(mag_x); Serial.print(", ");Serial.print(mag_y);Serial.print(", ");Serial.println(mag_z); } delay (200); //Read Pressure value Pressure = BARO.readPressure(); Serial.print("Pressure = ");Serial.println(Pressure); delay (200); //Read Temperature value Temperature = HTS.readTemperature(); Serial.print("Temperature = ");Serial.println(Temperature); delay (200); //Read Humidity value Humidity = HTS.readHumidity(); Serial.print("Humidity = ");Serial.println(Humidity); delay (200); //Proximity value if (APDS.proximityAvailable()) { Proximity = APDS.readProximity(); Serial.print("Proximity = ");Serial.println(Proximity); } delay (200); Serial.println("_____________________________________________________"); delay(1000); } Video microcontroller-projects/login-to-windows-computers-using-rc522-rfid-tag-and-arduino

Login to Windows Computers using RFID tag and Arduino

and much more. But still, it is a pain for me to log in to my office computer every time I get back to it after a short break. Project I can unlock system very fast and without typing any passwords, also later I am planning to use my office ID card as the RFIDtag since my ID card already has an RFID tag in it and I can program the Arduino to verify it. Sounds interesting right, so let’s get started…‐󋈍

Materials Required:

Arduino UNO (any Arduino can be used) RC522 RFID reader RFID tags Connecting wires USB cable

RC522 RFID Module:

module is shown below. like RFID Door Lock RFID Attendance system RFID Security system RFID Voting Machine shown above is connected to Arduino and the Arduino itself is connected to the computer. When a RFID tag is placed near this reader, the Arduino reads the rfid tag ID number and sends it to computer.

Circuit Diagram:

is given below. As you can see the connections are pretty simple. Since the RFID module works with SPI communication we have connected the MISO,MOSI,SCK and NSS pin to the SPI pins of the Arduino Uno board. The RFID module is powered by the 5V pin of the Arduino. The Arduino UNO itself will be always connected to Laptop and hence we can get it powered by the laptop USB port. The connection details are listed in table below.
RFIDRC522ARDUINO
VCC3.3V
GNDGND
RSTD9
MISOD12
MOSID11
SCKD13
SDA/NSSD10

Setting up the RFID Unlock System:

After the circuit is built, as shown above, connect the USB cable between Arduino and the system (laptop or PC). Now the user needs to find the com port for Arduino. To find com port you can either use device manager or you can find it in Arduino IDE as shown below. My COM port number here is 1; yours might be different make a note of this COM port number as it will be used later. Then place the RFID tag over RFID reader and you will see the 5 values on the serial monitor. The user needs to copy it and close the serial monitor. My values are shown in the serial monitor snapshot below. Download the rfid_configuration folder from the given link below. The link will download a ZIP file with four items in it. After extracting the ZIP file get into the folder named 32 bit or 64-bit folder (according to your operating system) and open the notepad named RFIDcredentials.txt. Paste the RFID values and update the system user name and password. If you want to add two cards then add the same credential in the second row as shown below. Then save and close this file. Now come back and open the RFIDCredSettings notepad and update the Arduino port in it then save and close. Again my COM port number is 1, update it with your COM port number. Leave the rest to default values as shown below. Now copy all four items and paste them in C:\Windows\System32. If it asks for any permission just give or click on yes. Now run register file to register the changes. When you run the Register file you might get the following dialog box. Press yes then ok. Now lock the system and the user will see another user optionavailable with your current user. Now the user can unlock the system by using RFID card. Meaning, now we do not need to input the password, just place RFID tag over RFID reader and windows will be unlocked immediately.

RFID Arduino Code:

installed already you can download and add it from the following link. #include <SPI.h> #include <MFRC522.h> #define RST_PIN 9 #define SS_PIN 10 MFRC522 mfrc522(SS_PIN, RST_PIN); MFRC522: : MIFARE_KEY; and RFID reader void setup() { serial.begin(9600); while(!Serial); SPI.begin(); mfrc522.PCD_Init(); for(byte i = 0; i < 6; i++) Key.KeyByte[i] = 0xFF; serial.print('>'); } Now in loop function, we are waiting for the card. void loop() { if( ! mfrc522.PICC_IsNewCardPresent() ) return; if( ! mfrc522.PICC_ReadCardSerial() ) return; send_tag_val (mfrc522.uid.uidByte, mfrc522.uid.size); delay(1000); } If the card found send_tag_val called an RFID tag data will be transferred to the system using serial print. This serial print value will be compared with the file that we placed earlier and if it a match the windows will unlock itself. void send_tag_val (byte *buffer, byte buffersize) { serial.print("ID"); for (byte i = 0; i < buffersize; i++) { serial.print(buffer[i], DEC); serial.print(" "); } serial.printIn(0, DEC); serial.print('>'); } The complete working of the project is shown in the video given below. Hope you understood the project and enjoyed building it. If you have any problems leave them in the comment section. Also, feel free to use the forums for other technical questions. Code #include <SPI.h> #include <MFRC522.h> #define RST_PIN 9 #define SS_PIN 10 MFRC522 mfrc522(SS_PIN, RST_PIN); MFRC522::MIFARE_Key key; void setup() { Serial.begin(9600); while (!Serial); SPI.begin(); mfrc522.PCD_Init(); for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; Serial.print('>'); } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) return; if ( ! mfrc522.PICC_ReadCardSerial()) return; send_tag_val(mfrc522.uid.uidByte, mfrc522.uid.size); delay(1000); } void send_tag_val(byte *buffer, byte bufferSize) { Serial.print("ID:"); for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i], DEC); Serial.print(" "); } Serial.println(0, DEC); Serial.print('>'); } Video microcontroller-projects/alexa-controlled-home-automation-using-arduino-and-wifi-module-esp8266

Alexa Controlled Home Automation using Arduino and ESP-01 Wi-Fi Module

Hardware Components Used:

Arduino UNO ESP-01 Module Amazon Alexa echo dot CP2102 USB-TTL Converter Breadboard 5V Relay Module AC Appliances Jumpers

Programming ESP-01 Module using CP2102 USB-TTL Converter:

Here ESP-01 is programmed using a CP2102 USB-TTL converter; it can also be programmed using an Arduino UNO board. Here in my case, I have used a CP2102 module and the steps for doing this are explained below. by following the link. Power supply pin of ESP-01 which can be supplied with 3.3V DC Ground reference pin of ESP-01 Used as UART Transmitter pin Used as UART Receiver Pin It is used to reset the Module and it is an active LOW pin. It is the chip enable pin which is an active HIGH pin. This pin serves two purposes. One is as General purpose Input/output and other is to enable Programming mode of ESP-01 This is a General purpose Input/output pin.

Connection of ESP-01 with CP2102 module:

Connect the ESP-01 module with the CP2102 USB-TTL converter module as per the table below.
After successful completion of the connection above, the circuit should look something like below: ᾠas shown in the image below: menu and select the COM port which we got in the previous stage.

Programming of ESP-01 Module for Alexa Home Automation

#include <Arduino.h> #include <ESP8266WiFi.h> #include "fauxmoESP.h" In this step, we have to define all the credentials which are required to connect ESP-01 with the internet. Update your network SSID and password data in the program. #define SSID "*******" #define pass "*******" " #define device1 "bedroom light" #define device2 "bedroom fan" #define device3 "smart socket" is used to connect the ESP-01 Module to the internet which takes the network’s SSID and password as its arguments. WiFi.mode(WIFI_STA); WiFi.begin(ssid,pass); which we have created earlier. fauxmo.createServer(true); fauxmo.setPort(80); fauxmo.enable(true); fauxmo.addDevice(device1); fauxmo.addDevice(device2); fauxmo.addDevice(device3); fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) { if (strcmp(device_name, device1) == 0) { if (state) Serial.print("1"); else Serial.print("2"); } } function. void loop() { fauxmo.handle(); } Now upload the complete code given at the end to ESP-01 Module and ensure for successful uploading. : After that, it’s time to upload the code in Arduino. The code for Arduino is very simple. It only receives the characters sent from ESP-01 modules through its UART terminals and compares it to send the turn ON/OFF signal to the Relay. The Complete program for Arduino is shown below: char data; void setup() { Serial.begin(115200); pinMode(7, OUTPUT); pinMode(6, OUTPUT); pinMode(5, OUTPUT); digitalWrite(7, LOW); digitalWrite(6, LOW); digitalWrite(5, LOW); } void loop() { if(Serial.available() > 0) { data = Serial.read(); Serial.print(data); Serial.print("\n"); if(data == '1') digitalWrite(7, HIGH); else if(data == '2') digitalWrite(7, LOW); else if(data == '3') digitalWrite(6, HIGH); else if(data == '4') digitalWrite(6, LOW); else if(data == '5') digitalWrite(5, HIGH); else if(data == '6') digitalWrite(5, LOW); } } After successful uploading, the code to Arduino, Next connect the hardware according to the schematics given below.

Circuit diagram

is shown below: Similarly, we have also built a relay module on a Perfboard:

Setup Amazon Alexa App for Home Automation

ᾠand then select discover devices. Then your Alexa app should search for the device which may take up to 45 seconds. ᾍ ᾠand it should return your feedback saying “Okayᾬ and the light should turn on. Similarly, we can test for all other commands. will look: Complete code for ESP-01 with a demonstration video is given below. Code #include <Arduino.h> #include <ESP8266WiFi.h> #include "fauxmoESP.h" #define ssid "admin" #define pass "12345678" #define device1 "bedroom light" #define device2 "bedroom fan" #define device3 "smart socket" fauxmoESP fauxmo; void wifi() { WiFi.mode(WIFI_STA); WiFi.begin(ssid,pass); while (WiFi.status() != WL_CONNECTED) { delay(100); } } void setup() { Serial.begin(115200); wifi(); fauxmo.createServer(true); fauxmo.setPort(80); fauxmo.enable(true); fauxmo.addDevice(device1); fauxmo.addDevice(device2); fauxmo.addDevice(device3); fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) { Serial.printf("[MAIN](%s) state: %s\n",device_name, state ? "ON" : "OFF"); if (strcmp(device_name, device1) == 0) { if (state) Serial.print("1"); else Serial.print("2"); } if (strcmp(device_name, device2) == 0) { if (state) Serial.print("3"); else Serial.print("4"); } if (strcmp(device_name, device3) == 0) { if (state) Serial.print("5"); else Serial.print("6"); } }); } void loop() { fauxmo.handle(); } Video microcontroller-projects/arduino-ac-light-dimmer-using-triac

AC Light Dimmer using Arduino and TRIAC

to control the phase of AC supply voltage. : IR Remote Controlled TRIAC Dimmer Circuit Arduino Based LED Dimmer using PWM 1 Watt LED Dimmer Circuit Power LED Dimmer using ATmega32 Microcontroller

Components Used:

Arduino UNO-1 MCT2E optocoupler -1 MOC3021 optocoupler -1 BT136 TRIAC-1 (12-0)V, 500mA Step down transformer-1 1K,10K, 330ohm Resistors 10K Potentiometer AC Holder with Lamp AC wires Jumpers Before going further we will learn about Zero crossing, TRIAC,and optocoupler.

Zero Crossing Detection Technique

of the AC signal. In India, the frequency of AC signal is 50 HZ and as it is alternating in nature. Hence, every time the signal comes to Zero point, we have to detect that point and after that trigger the TRIAC as per the power requirement. The Zero crossing point of an AC signal is shown below:

TRIAC Working

purpose. As shown in the figure above, the TRIAC is triggered at a firing angle of 90 degrees by applying a small gate pulse signal to it. The time “t1ᾠis the delay time which we have to give as per our dimming requirement. For example, in this case as the firing angle is 90 percent, hence the power output will also be halved and hence the lamp will also glow with half intensity. here.

Optocoupler

by following the link.

Circuit Diagram:

is given below: I have soldered a circuit of TRIAC and Optocoupler MOC3021 on a perf board. After soldering it will look like below: on perf boardfor connecting it to Transformer for AC supply: will look like below:

Programming Arduino for AC Light Dimmer:

video is given at the end. Here we have explained the code stepwise for better understating. is declared to store the value of the dimming step which we will use in the program. int LAMP = 4; int dim_val=0; , when it detects any interrupts at its pin. void setup() { pinMode(LAMP, OUTPUT); attachInterrupt(digitalPinToInterrupt(2), zero_cross, CHANGE); } , read the analog value from potentiometer which is connected at A0. Then map it to a value range of (10-49). To find out this we have to do a small calculation. Earlier I have told that, each half cycle is equivalent to 10,000 microseconds. So, let we need to control the dimming in 50 steps (which is an arbitrary value. You can also change it). I have taken the minimum step as 10, not Zero, because 0-9 steps give approximately the same power output and it is not recommended practically to take the maximum step number. So, I have taken the maximum step as 49. Then each step time can be calculated as 10000/50= 200 microseconds. This will be used in the next part of the code. void loop() { int data=analogRead(A0); int data1 = map(data, 0, 1023,10,49); dim_val=data1; } Here the dimming time can be calculated by multiplying the individual step time with no. of steps. Then after this delay time, the TRIAC can be triggered using a small high pulse of 10 microseconds which is sufficient to turning on a TRIAC. void zero_cross() { int dimming_time = (200*dim_val); delayMicroseconds(dimming_time); digitalWrite(LAMP, HIGH); delayMicroseconds(10); digitalWrite(LAMP, LOW); }

Working of Arduino Lamp Dimmer Circuit

Below are the pictures of showing three stages of dimming the AC bulb using Arduino and TRIAC. is given below /> Code int LAMP = 4; int dim_val=0; void setup() { pinMode(LAMP, OUTPUT); attachInterrupt(digitalPinToInterrupt(2), zero_cross, CHANGE); } void zero_cross() { int dimming_time = (200*dim_val); delayMicroseconds(dimming_time); digitalWrite(LAMP, HIGH); delayMicroseconds(10); digitalWrite(LAMP, LOW); } void loop() { int data=analogRead(A0); int data1 = map(data, 0, 1023,10,49); dim_val=data1; } Video microcontroller-projects/diy-arduino-wireless-programming-shield-using-bluetooth-module

DIY Arduino Wireless Programming Shield using Bluetooth Module

Components Used:

Arduino UNO HC05 Bluetooth Module Perfboard Male, Female Headers Jumpers 1K,2.2K Resistors 0.1uF capacitor 9V Battery

HC-05 Bluetooth Module

using HC-05 and other Bluetooth module. +5V: Power supply pin of HC05 which can be given with +5V. GND: Ground pin. TX: Used as Transmitter pin in UART. RX: Used as Receiver pin in UART. EN/KEY: Enable pin of HC05. It can be left in floating state or can be connected to 3.3V supply to enable HC05. If it is connected to Ground then module will be disabled. It is also used to make HC05 in AT command mode. STATE: Status pin which is LOW in case of not connected to any device and HIGH when connected to any device.

Programming Arduino UNO for AT commands:

through Serial monitor. Program is very simple and attached at the end of this tutorial, here we are explaining the program line by line. First include the header file for software serial library and define the Transmitter and Receiver pins for Software serial in Arduino, which are pin 3 and 2 in this case. #include <SoftwareSerial.h> SoftwareSerial HC05(2,3); function, define the baud rates for both Hardware serial ports and Software serial ports. Here we have taken them as 9600 and 38400 respectively. void setup() { Serial.begin(9600); Serial.println("Enter AT commands:"); HC05.begin(38400); } function, there are two conditions- one is when any command is given to HC05 and it writes them at Arduino serial Monitor. Another condition is when any command is given at Arduino serial monitor and it will send them to HC05. void loop() { if (HC05.available()) Serial.write(HC05.read()); if (Serial.available()) HC05.write(Serial.read()); }

Configuration of HC05 in AT Command Mode:

First of all, connect the components as per circuit diagram below. Then follow the steps below to put the module in AT command mode. To enter in the AT mode of HC05, we need to use the KEY button. First long press the key button until the module LED start blinking at an interval of 2 seconds. If the LED starts blinking in every 2 seconds interval means the module is in command mode. We can now give AT commands to it using the Serial monitor of Arduino IDE. If the module doesn’t have any key button in it, then we can connect the KEY/EN pin of the module to 3.3 volt pin to switch the module in command mode. Once the sketch is uploaded into Arudino, open the serial monitor at 9600 baud rate, select CR+NL, and you should be able to send AT commands to the HC-05. After successful completion of the above steps, now send the appropriate AT commands to configure the HC05. Send the following AT commands one by one at Arduino serial Monitor and in return it should an OK response. Otherwise, recheck the connections and try it again. It is the basic Test command of HC05. Every time we transmit AT, it must return OK. This command will restore the default setting of HC05. The default settings are for slave mode, password=1234 and baud rate=38400 bits/sec. This command will set the name of the HC05 module. In my case I have given the name as “CIRCUIT DIGESTᾮ This command will configure the HC05 in slave mode. This command sets the PIO LEDs drive configurations. This will change the baud rate to 115200 with 0 stop bit and 0 parity. This will initialize the SPP profile of the module.

Circuit Connection for Arduino Wireless Programming

After successfully sending AT commands to Arduino, just remove all the connections and rebuild it as per the schematics below. After the complete soldering, it will look like below: Then just place this shied on Arduino as per image below, and then connect the Arduino to 9V battery Power supply. option. When it asks for pairing code, enter ᾱ234ᾠas your password. Then you will get an acknowledgement for successful device pairing. This will show two COM ports, one is for incoming and other for outgoing. We have to write down the outgoing COM port number as we need it further while uploading the program. , as shown above. After that click on upload button and it should be successfully uploaded to your Arduino board. below and enjoy the wireless and hasslefree programming!!! Code #include <SoftwareSerial.h> SoftwareSerial HC05(2,3); void setup() { Serial.begin(9600); Serial.println("Enter AT commands:"); HC05.begin(38400); } void loop() { if (HC05.available()) Serial.write(HC05.read()); if (Serial.available()) HC05.write(Serial.read()); } Video microcontroller-projects/sending-sensor-data-to-android-phone-using-arduino-nrf24l01-over-bluetooth-ble

Sending Sensor Data to Android Phone using Arduino and NRF24L01 over Bluetooth (BLE)

but for other microcontrollers like Arduino, nRF24L01 can be used. This RF module can be also used as BLE module to send the data to other Bluetooth device like smartphones, computer etc.

How Bluetooth Low Energy (BLE) is different?

The BLE was adopted due to its power consumption features as it was able to run for an extended period of time using just a coin cell. Compared to other wireless standards, the rapid growth of BLE has gone further faster because of its phenomenal applications in smartphones, tablets, and mobile computing.

BLE Capability of NRF24L01 Module

, follow this tutorial. tutorial. Today the BLE functionality of this module will be explained by sending sensor data to a smart phone. Here this nRF24L01 module will be interfaced with Arduino Microcontroller and the DHT11 sensor temperature data will be sent to official Nordic BLE android application.

Components Required

Arduino UNO nRF24L01 BLE Module DHT11 Temperature and Humidity Sensor Jumpers Arduino IDE Nordic BLE Android Application (nRF Temp 2.0 for BLE or nRF Connect for Mobile)

Starting with nRF24L01 Module

The pinouts of a standard nRF24L01 module is shown below: Also they have a wide address range of 125 unique ID’s, hence in a closed area we can use 125 of these modules without interfering with each other.

Arduino NRF24L01ModuleCircuit Diagram

Interfacing nRF24L01 with Arduino for BLE communication

The nRF24L01 works on SPI, so the interfacing will be using SPI Protocol. The complete code and video will be attached at the end of this tutorial. Android app guide is also explained in the video. Here the nRF24L01 module is used to communicate with Smartphone App of Nordic. to use BLE functions. #include <SPI.h> #include <RF24.h> #include <BTLE.h> #include <DHT.h> The DHT type is initialized as DHT11 since we are using DHT11. The DHT is connected to GPIO Pin 4 and nRF module’s CE and CSN pins are connected to Pin 9 and 10 respectively. #define DHTPIN #define DHTTYPE DHT11 DHT22 DHT dht(DHTPIN, DHTTYPE); RF24 radio(9, 10); BTLE btle(&radio); with the Bluetooth Local Name with max 8 characters long. Serial.begin(9600); dht.begin(); btle.begin("CD Temp"); Add a debug line for showing an error message if DHT loses its power or anything unexpected happens. float temp = dht.readTemperature(); //read temperature data if (isnan(h) || isnan(t)) { Serial.println(F("Failed to read from DHT sensor!")); return; } Also send the Temperature value to BLE Module. The BLE module will advertise the Temperature data. The android app can search the BLE module and receive the sensor data. nrf_service_data buf; buf.service_uuid = NRF_TEMPERATURE_SERVICE_UUID; buf.value = BTLE::to_nRF_Float(temp); if (!btle.advertise(0x16, &buf, sizeof(buf))) { Serial.println("BTLE advertisement failed..!"); } When done, just hop to the next channel. btle.hopChannel(); Since the DHT sensor documentation recommends to keep a delay of a minimum 2 seconds after one reading, so add a delay of 2 seconds. delay(2000); android application like shown below. Complete procedure of pairing and getting the data on android app is also explained in the video: Code ) works with nRF24L01. and the works for Nordic's It reads temperature from a DHT11 and sends it via BTLE. Works with Nordic Semiconductor apps such as "nRF Connect for Mobile" and "nRF Temp 2.0 for BLE" Pin Mapping: GND -> GND on the Arduino VCC -> 3.3v on the Arduino CE -> PIN 9 on the Arduino CSN -> PIN 10 on the Arduino SCK -> PIN 13 on the Arduino Uno MOSI -> PIN 11 on the Arduino Uno MISO -> PIN 12 on the Arduino Uno IRQ -> not used */ #include <SPI.h> #include <RF24.h> #include <BTLE.h> #include <DHT.h> // dht11 temperature and humidity sensor library #define DHTPIN 4 // what digital pin we're connected to #define DHTTYPE DHT11 // select dht type as DHT 11 or DHT22 DHT dht(DHTPIN, DHTTYPE); RF24 radio(9, 10); // CE, CSN BTLE btle(&radio); void setup() { Serial.begin(9600); delay(1000); Serial.print("BLE and DHT Starting... "); Serial.println("Send Temperature Data over BTLE"); dht.begin(); // initialise DHT11 sensor btle.begin("CD Temp"); // 8 chars max Serial.println("Successfully Started"); } void loop() { float temp = dht.readTemperature(); //read temperature data if (isnan(h) || isnan(t)) { // Check if any reads failed and exit early (to try again). Serial.println(F("Failed to read from DHT sensor!")); return; } Serial.print(" Temperature: "); Serial.print(t); Serial.println("°C "); nrf_service_data buf; buf.service_uuid = NRF_TEMPERATURE_SERVICE_UUID; buf.value = BTLE::to_nRF_Float(temp); if (!btle.advertise(0x16, &buf, sizeof(buf))) { Serial.println("BTLE advertisement failed..!"); } btle.hopChannel(); delay(2000); } Video microcontroller-projects/arduino-sleep-modes-and-how-to-use-them-to-reduce-power-consumption

Arduino Sleep Modes and How to use them to Save the Power

Power consumption is a critical issue for a device running continuously for a long time without being turned off. So to overcome this problem almost every controller comes with a sleep mode, which help developers to design electronic gadgets for optimal power consumption. Sleep mode puts the device in power saving mode by turning off the unused module.

Arduino Sleep Modes

Sleep Modes allow the user to stop or turn off the unused modules in the Microcontroller which significantly reduce the power consumption. Arduino UNO, Arduino Nano and Pro-mini comes with ATmega328P and it has a Brown-out Detector (BOD) which monitors the supply voltage at the time of sleep mode. There are six sleep modes in ATmega328P: For entering into any of the sleep mode we need to enable the sleep bit in the Sleep Mode Control Register (SMCR.SE). Then the sleep mode select bits select the sleep mode among Idle, ADC noise reduction, Power-Down, Power-Save, Standby and External Standby. or a Reset can wake up the Arduino from the sleep mode. Arduino can be waked up any time by using external or internal interrupt. LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF); for setting various low power modes in arduino.So first download and install the library from the given link and use the above code to put the Arduino in Idle Sleep Mode. By using the above code, the Arduino will go into a sleep of eight seconds and wake up automatically. As you can see in the code that the idle mode turns off all the timers, SPI, USART, and TWI (2-wire interface). mode by the following methods: External Reset Watchdog System Reset Watchdog Interrupt Brown-out Reset 2-wire Serial Interface address match External level interrupt on INT Pin change interrupt Timer/Counter interrupt SPM/EEPROM ready interrupt Power-Down mode stops all the generated clocks and allows only the operation of asynchronous modules. It can be enabled by writing the SM[2,0] bits to ᾰ10ᾮ In this mode, the external oscillator turns OFF, but the 2-wire serial interface, watchdog and external interrupt continues to operate. It can be disabled by only one of the method below: External Reset Watchdog System Reset Watchdog Interrupt Brown-out Reset 2-wire Serial Interface address match External level interrupt on INT Pin change interrupt Arduino Code for Power-Down Periodic Mode: LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); The code is used to turn on the power-down mode. By using the above code, the Arduino will go into a sleep of eight seconds and wake up automatically. We can also use the power-down mode with an interrupt, where the Arduino will go into sleep but only wakes up when an external or internal interrupt is provided. Arduino Code for Power-Down Interrupt Mode: void loop() { // Allow wake up pin to trigger interrupt on low. attachInterrupt(0, wakeUp, LOW); LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); // Disable external pin interrupt on wake up pin. detachInterrupt(0); // Do something here } To enter into the power-save mode we need to write the SM[2,0] pin to ᾰ11ᾮ This sleep mode is similar to the power-down mode, only with one exception i.e. if the timer/counter is enabled, it will remain in running state even at the time of sleep. The device can be waked up by using the timer overflow. If you are not using the time/counter, it is recommended to use Power-down mode instead of power-save mode. The standby mode is identical to the Power-Down mode, the only difference in between them is the external oscillator kept running in this mode. For enabling this mode write the SM[2,0] pin to ᾱ10ᾮ This mode is similar to the power-save mode only with one exception that the oscillator is keep running. The device will enter into the Extended Standby mode when we write the SM[2,0] pin to ᾱ11ᾮ The device will take six clock cycles to wake up from the extended standby mode. Below are the requirements for this project, after connecting the circuit as per the circuit diagram. Upload the sleep mode code into Arduino using Arduino IDE. Arduino will enter into the idle sleep mode. Then check the current consumption into the USB ammeter. Else, you can also use a clamp meter for the same.

Components Required

Arduino UNO DHT11 Temperature and Humidity Sensor USB Ammeter Breadboard Connecting Wires , follow the link. Here we are using USB Ammeter to measure the voltage consumed by Arduino in sleep mode.

USB Ammeter

, which instantly display the values of current and voltage consumed by the attached device. These values flips in an interval of every three seconds. Operating voltage range: 3.5V to 7V Maximum current rating: 3A Compact size, easy to carry No external supply needed Testing USB devices Checking load levels Debugging battery chargers Factories, electronics products and personal use

Circuit Diagram

, the Arduino is plugged into the USB ammeter. Then the USB ammeter is plugged into the USB port of the laptop. Data pin of the DHT11 sensor is attached to the D2 pin of the Arduino.

Code Explanation

The complete code for the project with a video is given at the end. follow the link.Then we have defined the Arduino pin number to which the data pin of the DHT11 is connected and created a DHT object. #include <dht.h> #include <LowPower.h> #define dataPin 2 dht DHT; here the 9600 is the baud rate. We are using Arduino’s built-in LED as an indicator for the sleep mode. So, we have set the pin as output, and digital write low. void setup() { Serial.begin(9600); pinMode(LED_BUILTIN,OUTPUT); digitalWrite(LED_BUILTIN,LOW); } Hence, the temperature and humidity data is printed serially on the serial monitor. void loop() { Serial.println("Get Data From DHT11"); delay(1000); digitalWrite(LED_BUILTIN,HIGH); int readData = DHT.read11(dataPin); // DHT11 float t = DHT.temperature; float h = DHT.humidity; Serial.print("Temperature = "); Serial.print(t); Serial.print(" C | "); Serial.print("Humidity = "); Serial.print(h); Serial.println(" % "); delay(2000); and making the built in LED Low. After that Arduino sleep mode is enabled by using the command mentioned below in the code. of the Arduino and gives a sleep of eight seconds. It turns the ADC, Timers, SPI, USART, 2-wire interface into the OFF condition. Serial.println("Arduino:- I am going for a Nap"); delay(1000); digitalWrite(LED_BUILTIN,LOW); LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF); Serial.println("Arduino:- Hey I just Woke up"); Serial.println(""); delay(2000); } , which significantly reduce the power consumed by the Arduino weather station. Code #include <dht.h> #include <LowPower.h> #define dataPin 2 dht DHT; void setup() { Serial.begin(9600); pinMode(LED_BUILTIN,OUTPUT); digitalWrite(LED_BUILTIN,LOW); } void loop() { Serial.println("Get Data From DHT11"); delay(1000); digitalWrite(LED_BUILTIN,HIGH); int readData = DHT.read11(dataPin); // DHT11 float t = DHT.temperature; float h = DHT.humidity; Serial.print("Temperature = "); Serial.print(t); Serial.print(" C | "); Serial.print("Humidity = "); Serial.print(h); Serial.println(" % "); delay(2000); Serial.println("Arduino:- I am going for a Nap"); delay(200); digitalWrite(LED_BUILTIN,LOW); LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF); Serial.println("Arduino:- Hey I just Woke up"); Serial.println(""); delay(2000); } #include <dht.h> #define dataPin 2 dht DHT; void setup() { Serial.begin(9600); pinMode(LED_BUILTIN,OUTPUT); digitalWrite(LED_BUILTIN,LOW); } void loop() { digitalWrite(LED_BUILTIN,HIGH); int readData = DHT.read11(dataPin); // DHT11 float t = DHT.temperature; float h = DHT.humidity; Serial.print("Temperature = "); Serial.print(t); Serial.print(" C | "); Serial.print("Humidity = "); Serial.print(h); Serial.println(" % "); delay(2000); } Video microcontroller-projects/controlling-nema-17-stepper-motor-with-arduino-and-a4988-stepper-driver-module

Controlling NEMA 17 Stepper Motor with Arduino and A4988 Stepper Driver Module

28-BYJ48 has relatively lower torque than the other stepper motors like NEMA 14, NEMA17. Nema17 stepper motor has higher torque and higher operating voltage than 28-BYJ48. Here a potentiometer will also be attached to control the direction of stepper motor.

Component Required

Arduino UNO NEMA17 Stepper Motor A4988 Stepper Driver Module 47 μf Capacitor Potentiometer

NEMA17 Stepper Motor

means it covers 1.8 degrees in every step. Wiring diagram for NEMA17 is given below. These wire are connected in two split windings. Black, Yellow, Green wires are part of first winding where Black is center tap, and Yellow and Green are coil end while Red, White, and Blue is part of a second winding, in which White is center tap and Red and Blue are coil end wires. Normally center tap wires left disconnected. Steps Per Revolution for a particular stepper motor is calculated using the step angle of that stepper motor. So in the case, NEMA 17 step angle is 1.8 deg. Steps per Revolution = 360/ step angle 360/1.8 = 200 Steps Per Revolution Rated Voltage: 12V DC Step Angle: 1.8 deg. No. of Phases: 4 Motor Length: 1.54 inches 4-wire, 8-inch lead 200 steps per revolution, 1.8 degrees Operating Temperature: -10 to 40 °C Unipolar Holding Torque: 22.2 oz-in which involves stepper motor.

A4988 Stepper Driver Module

A stepper driver module controls the working of a stepper motor. Stepper drivers send the current to stepper motor through various phases. is a microstepping driver module that is used to control bipolar stepper motors. This driver module has a built-in translator that means that we can control the stepper motor using very few pins from our controller. You can select the different step resolutions using the resolution selector pins ((MS1, MS2, and MS3). The truth table for these pins is given below:
MS1MS2MS3Microstep Resolution
LowLowLowFull Step
HighLowLow Step (Half Step)
LowHighLow Step (Quarter Step)
HighHighLow1/8 Step (Eighth Step)
HighHighHigh1/16 Step (Sixteenth Step)
Max. Operating Voltage: 35V Min. Operating Voltage: 8V Max. Current Per Phase: 2A Microstep resolution: Full step, step, step, 1/8 and 1/16 step Reverse voltage protection: No Dimensions: 15.5 × 20.5 mm (0.6‑�0.8‑�

Circuit Diagram

Step pin is used for controlling the steps while the direction pin is used to control the direction. Stepper motor is powered using a 12V power source, and the A4988 module is powered via Arduino. Potentiometer is used to control the direction of the motor. given in below table.
1VMOT+ve Of Battery
2GND-ve of Battery
3VDD5V of Arduino
4GNDGND of Arduino
5STPPin 3 of Arduino
6DIRPin 2 of Arduino
71A, 1B, 2A, 2BStepper Motor

Code Explanation

is given at the end of this tutorial, here we are explaining the complete program to understand the working of the project. After that define the no of steps for the NEMA 17. As we calculated, the no. of steps per revolution for NEMA 17 is 200. #include <Stepper.h> #define STEPS 200 because the motor is connected through the driver module. Stepper stepper(STEPS, 2, 3); #define motorInterfaceType 1 function. Maximum motor speed for NEMA 17 is 4688 RPM but if we run it faster than 1000 RPM torque falls of quickly. void setup() { stepper.setSpeed(1000); than it will move ten steps in the clockwise direction and if the current value is less than previous value than it will move ten steps in the counter-clockwise direction. potVal = map(analogRead(A0),0,1024,0,500); if (potVal>Pval) stepper.step(10); if (potVal<Pval) stepper.step(-10); Pval = potVal; Now connect the Arduino with your laptop and upload the code into your Arduino UNO board using Arduino IDE, select the Board and port no and then click on the upload button. below. If you have any doubts regarding this project, post them in the comment section below. Code #include <Stepper.h> #define STEPS 200 // Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver Stepper stepper(STEPS, 2, 3); // Pin 2 connected to DIRECTION & Pin 3 connected to STEP Pin of Driver #define motorInterfaceType 1 int Pval = 0; int potVal = 0; void setup() { // Set the maximum speed in steps per second: stepper.setSpeed(1000); } void loop() { potVal = map(analogRead(A0),0,1024,0,500); if (potVal>Pval) stepper.step(10); if (potVal<Pval) stepper.step(-10); Pval = potVal; } Video microcontroller-projects/how-to-control-solenoid-valve-using-arduino

How to control a Solenoid Valve with Arduino

has a plunger-type solenoid coil inside it, which when energized by AC power source will move a small rod up and down. This rod will hit the metal plates placed on either side of the solenoid to produce the soothing ding dong sound. It is also used as starters in vehicles or as a valve in RO and sprinkler systems. We previously build an automatic water dispenser using Arduino and Solenoid, now we will learn the controlling of Solenoid with Arduino in more detail.

How Does a Solenoid Valve Work?

It has a coil wound over a conductive material, this set-up acts as an electromagnet. The advantage of an electromagnet over natural magnet is that it can be turned on or off when required by energizing the coil. Thus when the coil is energized then according to faradays law the current-carrying conductor has a magnetic field around it, since the conductor is a coil the magnetic field is strong enough to magnetize the material and create a linear motion. The operation principle is similar to relay, it has a coil inside it, which when energized, pulls the conductive material (piston) inside it, thus allowing the flow of liquid. And when de-energized it pushes the piston back in the previous position using the spring and again blocks the flow of liquid. for this particular Solenoid valve.

Components Required

Arduino UNO Solenoid Valve IRF540 MOSFET Pushbutton ᾠ2 nos. Resistor (10k, 100k) Diode ᾠ1N4007 Breadboard Connecting Wires

Circuit Diagram

is given below:

Programming Code Explanation

Here we are explaining the complete program to understand the working of the project Firstly we have defined digital pin 9 as output for the solenoid and digital pin 2 and 3 as input pins for buttons. void setup() { pinMode(9, OUTPUT); pinMode(2, INPUT); pinMode(3, INPUT); } turn on or off the solenoid based on status of digital pin 2 and 3, where two push buttons are connected to turn on and off the solenoid. void loop() { if(digitalRead(2)==HIGH) { digitalWrite(9,HIGH); delay(1000); } else if(digitalRead(3)==HIGH) { digitalWrite(9,LOW); delay(1000); } }

Controlling a Solenoid Valve from an Arduino

is given at the end of this tutorial. pin of the Arduino. As IRF540 is an N-Channel MOSFET, so when its gate terminal gets HIGH, it allow the flow of current from drain to source and turn the solenoid on. Similarly, when we press the button 2, Arduino sends a LOW logic to the gate terminal of the MOSFET IRF540 which makes the solenoid turn off. Code void setup() { pinMode(9, OUTPUT); pinMode(2, INPUT); pinMode(3, INPUT); } void loop() { if(digitalRead(2)==HIGH) { digitalWrite(9,HIGH); delay(1000); } else if(digitalRead(3)==HIGH) { digitalWrite(9,LOW); delay(1000); } } Video microcontroller-projects/control-nema-17-stepper-motor-with-arduino-using-drv8825-stepper-motor-driver

Control a NEMA 17 Stepper Motor with Arduino and DRV8825

28-BYJ48 has relatively lower torque than the other stepper motors like NEMA 14, NEMA17.

Components Required

Arduino UNO NEMA17 Stepper Motor DRV8825 Stepper Driver Module 47 μf Capacitor Potentiometer

Nema 17 Stepper Motor Driver- DRV8825

A stepper driver module controls the working of a stepper motor. Stepper drivers send the current to stepper motor through various phases. has a built-in translator that means that it can control both speed and direction of a bipolar stepper motor like NEMA 17 using only two pins, i.e. STEP and DIR. STEP pin is used to control the steps, and DIR pin is used to control the direction of rotation. DRV8825 has a maximum output capacity of 45V and ± 2.2 A. This driver can operate stepper motor in six different step modes i.e. full-step, half-step, quarter-step, eighth-step, sixteenth-step, and thirty-second-step. You can change the step resolution using the microstep pins (M0, M1 & M2). By setting appropriate logic levels to these pins, we can set the motors to one of the six-step resolutions. The truth table for these pins is given below:
M0M1M2Microstep Resolution
LowLowLowFull Step
HighLowLow Step (Half Step)
LowHighLow Step (Quarter Step)
HighHighLow1/8 Step (Eighth Step)
LowLowHigh1/16 Step (Sixteenth Step)
HighLowHigh1/32 step (Thirty-second Step)
LowHighHigh1/32 step (Thirty-second Step)
HighHighHigh1/32 step (Thirty-second Step)
Max. Operating Voltage: 45 V Min. Operating Voltage: 8.2 V Max. Current Per Phase: 2.5 A PCB Size: 15 mm x 20 mm Six step resolution: Full step, step, step, 1/8, 1/16 and 1/32 step Adjustable output current via potentiometer Automatic current decay mode detection Over-temperature shutdown circuit Under-voltage lockout Over-current shutdown

Difference between DRV8825 and A4988 Nema 17 Motor Drivers

A4988 and DRV8825 both have similar pinout and applications, but these modules have some differences in no. of micro steps, operating voltage, etc. Some key differences are given below: The DRV8825 offers six-step modes, whereas the A4988 offers five-step modes. Higher step modes result in smoother, quieter operation. Minimum STEP pulse duration for DRV8825 is 1.9μs, while for A4988 STEP pulse duration is 1μs. The DRV8825 can deliver slightly more current than the A4988 without any additional cooling. Location of the current limit potentiometer is different in both modules. The DRV8825 can be used with a higher voltage motor power supply. The SLEEP pin on the DRV8825 is not pulled up by default like it is on the A4988. Instead of the supply voltage pin, DRV8825 has FAULT output pin.

Circuit Diagram

are given in below table.
1VMOT+ve Of Battery
2GND-ve of Battery
3RST5V of Arduino
4SLP5V of Arduino
5GNDGND of Arduino
6STPPin 3 of Arduino
7DIRPin 2 of Arduino
8B2, B1, A1, A2,Stepper Motor
Measure the current between two points GND and the potentiometer and adjust it to the required value.

Code Explanation

is given at the end of this tutorial, here we are explaining the complete program to understand the working of the project. After that define the no of steps for the NEMA 17. The no. of steps per revolution for NEMA 17 is 200. #include <Stepper.h> #define STEPS 200 After that, specify the pins to which driver module is connected and define the motor interface type as Type1 because the motor is connected through the driver module. Stepper stepper(STEPS, 2, 3); #define motorInterfaceType 1 function. Maximum motor speed for NEMA 17 is 4688 RPM but if we run it faster than 1000 RPM torque falls of quickly. void setup() { stepper.setSpeed(800); is higher than the previous value, than it will move ten steps in the clockwise direction and if the current value is less than previous value than it will move ten steps in the counter-clockwise direction. potVal = map(analogRead(A0),0,1024,0,500); if (potVal>Pval) stepper.step(10); if (potVal<Pval) stepper.step(-10); Pval = potVal; Now connect the Arduino with your laptop and upload the code into your Arduino UNO board using Arduino IDE, select the Board and port no and then click on the upload button. is shown in the video below. If you have any doubts regarding this project, post them in the comment section below. Code #include <Stepper.h> #define STEPS 200 //#define dirPin 2 //#define stepPin 3 // Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver: Stepper stepper(STEPS, 2, 3); #define motorInterfaceType 1 int Pval = 0; int potVal = 0; void setup() { // Set the maximum speed in steps per second: stepper.setSpeed(800); // pinMode(stepPin, OUTPUT); // pinMode(dirPin, OUTPUT); } void loop() { potVal = map(analogRead(A0),0,1024,0,500); if (potVal>Pval) stepper.step(10); if (potVal<Pval) stepper.step(-10); Pval = potVal; } Video microcontroller-projects/arduino-sound-level-measurement

Measure Sound/Noise Level in dB with Microphone and Arduino

in a small classroom or living room. , if you have a better meter you can use that for calibration. Do note that this project does not aim to measure dB accurately and will just give values as close as possible to the actual value.

Materials Required:

Arduino UNO Microphone LM386 10K variable POT Resistors and Capacitors

Circuit Diagram:

and the circuit more or less remains the same. The gain of this particular op-amp can be set from 20 to 200 using a resistor or capacitor across pin 1 and 8. If they are left free the gain will be set as 20 by default. For our project we the maximum gain possible by this circuit, so we use a capacitor of value 10uF between the pins 1 and 8, note that this pin is polarity sensitive and the negative pin of capacitor should be connected to pin 8. The complete amplifier circuit is powered by the 5V pin from the Arduino. The Capacitor C2 is used to filter the DC noise from Microphone. Basically when the microphone senses sound the sound waves will be converted to AC signals. This AC signal might have some DC noise coupled with it which will be filtered by this capacitor. Similarly, even after amplification a capacitor C3 is used to filter any DC noise that might have been added during amplification.

Using Regression Method to Calculate dB from ADC Value:

Example program from Arduino to check if we are getting valid ADC values from our microphone. Now we have to convert this ADC values to dB. if you want to give it a try. which could be downloaded from play store for free. There many such types of application and you can download anything of your choice. These applications use the phone’s inbuilt microphone to detect the noise level and display it on our mobile. They are not very accurate, but would surely work for our task. So let’s begin by installing the Android application, mine when opened looked something like this below As I said earlier the relation between dB and Analog values will not be linear hence we need to compare these two values at different intervals. Just note down the value of ADC being displayed on the screen for different dB displayed on your mobile phone. I took about 10 readings and they looked like this below, you might vary a bit Open an excel page and type in these values, for now on we will be using Excel to find the regression values for the above number. Before that let's plot a graph and check how they both relate to, mine looked like this below. Basically, it will convert this irregular blue line to the closest possible straight line (black line) and give us the equation of that straight line. This equation can be used to find the equivalent value of dB for every value of ADC that the Arduino measures. In excel we have a plug-in for data analysis which will automatically calculate the regression for your set of values and publish its data. I am not going to cover how to do it with excel since it outside the scope of this project, also its easy for you to Google and learn it. Once you calculate the regression for the value, excel will give some values like shown below. We are interested only in the numbers that are highlighted below. Once you get these numbers you will be able to form the below equation like ADC = (11.003* dB) ᾠ83.2073 From which you can derive the dB to be dB = (ADC+83.2073) / 11.003 You might have to drive your own equation since the calibration might differ. However, keep this value safe for we will need it while programming the Arduino.

Arduino Program to measure Sound level in dB:

The complete program to measure dB is given below, few important lines are explained below In these above two lines, we read the ADC value of pin A0 and convert it to dB using the equation that we just derived. This dB value might not we accurate to the true dB value but, remains pretty much close to the values displayed on the mobile application. adc= analogRead(MIC); //Read the ADC value from amplifer dB = (adc+83.2073) / 11.003; //Convert ADC value to dB using Regression values To check if the program is working properly we have also added an LED to digital pin 3 which is made to go high for 1 sec when the Arduino measures a loud noise of above 60dB. if (dB>60) { digitalWrite(3, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(3, LOW); }

Working of Arduino Sound Level Meter:

Once you are ready with the code and hardware, just upload the code and open your serial monitor to look at the dB values measured by your Arduino. I was testing this code in my room where there was not much noise except for the traffic outside and I got the below values on my serial monitor and the android application also displayed something close to this at the end of this page. You can use to project to detect sound in the room and check if there is any activity or how much noise is generated in each classroom or something like that. I have just made an LED to go high for 2 seconds if there is sound recorded above 60dB. The working is oddly satisfying, but can sure be used for projects and other basic prototypes. With few more digging I found that the problem was actually with the hardware, which was still giving me noise now and then. So I tried out other circuits which is used in the spark fun microphone boards that has a low-pass and high-pass filter. I have explained the circuit below for you to try.

Amplifier with Filters Circuit:

in this sound level measurement circuit so that accuracy can be increased. These filters are designed to allow frequency only from 8Hz to 10KHz, since the low pass-filter will filter anything below 8Hz and the High Pass filter will filter anything above 15KHz. This frequency range is select is because my condenser microphone works only from 10Hz to 15KHZ as shown in the datasheet below. If your frequency demand changes then you can use the below formulae to calculate the value of Resistor and capacitor for your required frequency. Frequency (F) = 1/(2πRC) for modifying the values of Frequency and calculating the regression values. The former circuit worked satisfactory for my expectations, so I never tried this one. If you happen to try this circuit do let me know if it functions better than the previous one through the comments. Code const int MIC = 0; //the microphone amplifier output is connected to pin A0 int adc; int dB, PdB; //the variable that will hold the value read from the microphone each time void setup() { Serial.begin(9600); //sets the baud rate at 9600 so we can check the values the microphone is obtaining on the Serial Monitor pinMode(3, OUTPUT); } void loop(){ PdB = dB; //Store the previous of dB here adc= analogRead(MIC); //Read the ADC value from amplifer //Serial.println (adc);//Print ADC for initial calculation dB = (adc+83.2073) / 11.003; //Convert ADC value to dB using Regression values if (PdB!=dB) Serial.println (dB); if (dB>60) { digitalWrite(3, HIGH); // turn the LED on (HIGH is the voltage level) delay(2000); // wait for a second digitalWrite(3, LOW); } //delay(100); } Video microcontroller-projects/arduino-controlled-water-fountain-using-sound-sensor

Arduino Controlled Musical Fountain using Sound Sensor

There are several water fountains which unconditionally sprinkle water with some interesting lighting effects. So I wandered about designing an innovative water fountain which can respond to external music and sprinkle water depending on the music beats. Isn’t it sound interesting?

Material required

Arduino Nano Sound sensor Module 12V Relay Module DC Pump LEDs Connecting wires Vero board or Breadboard

Working of a Sound sensor

, it can be used to detect whether there is any sound beyond the set threshold limit. The module output is a digital signal which indicates that the sound is greater or lesser than the threshold.

Sound Sensor Circuit Diagram

If the input signal is greater than the reference signal then the output of the OPAMP will be high and vice versa. sections to learn more about its working.

Musical Water Fountain Circuit Diagram

, the sound sensor is powered with 3.3V supply of Arduino Nano and the output pin of the sound sensor module is connected to the analog input pin (A6) of Nano. You can use any of the analog pin, but make sure to change that in the program. The relay module and DC pump is powered by an external 12VDC power supply as shown in the figure. The input signal of relay module is connected to digital output pin D10 of Nano. For lighting effect I chose two different colours of LED and connected them to two digital output pins (D12, D11) of Nano. , the COM contact of the relay is get connected to the NO contact and the current gets a closed circuit path to flow across the pump to activate the water flow. Otherwise the pump will remain OFF. The HIGH/LOW pulses are generated from Arduino Nano depending on the sound input. After soldering the complete circuit on perfboard, it will look like below: :

Programming Arduino Nano for Dancing Fountain

is given at the bottom of the page. But here I am just explaining that by parts for better understanding: The first part of the program is to declare the necessary variables for assigning pin numbers that we are going to use in the next blocks of program. Then define a constant REF with a value which is the reference value of for the sound sensor module. The assigned value 700 is the bytes equivalent value of the output electrical signal of the sound sensor. int sensor = A6; int redled = 12; int greenled = 11; int pump = 10; #define REF 700 function to assign the INPUT/OUTPUT data direction of the pins. Here sensor is taken as INPUT and all other devices are used as OUTPUT. void setup() { pinMode(sensor,INPUT); pinMode(redled,OUTPUT); pinMode(greenled,OUTPUT); pinMode(pump,OUTPUT); } int sensor_value = analogRead (sensor); loop is used to compare the input analog signal with the Reference value. If it is greater than the reference, then all the output pins are given HIGH output so that all the LEDs and Pump are activated, else everything remains OFF. Here we have also given a delay of 70 Milliseconds to distinct the ON/OFF time of the Relay. if (sensor_value>REF) { digitalWrite(greenled,HIGH); digitalWrite(redled,HIGH); digitalWrite(pump,HIGH); delay(70); } else { digitalWrite(greenled,LOW); digitalWrite(redled,LOW); digitalWrite(pump,LOW); delay(70); } is given below. Code int sensor = A6; int redled = 12; int greenled = 11; int pump = 10; #define REF 700 void setup() { pinMode(sensor,INPUT); pinMode(redled,OUTPUT); pinMode(greenled,OUTPUT); pinMode(pump,OUTPUT); } void loop() { int sensor_value = analogRead (sensor); if (sensor_value>REF) { digitalWrite(greenled,HIGH); digitalWrite(redled,HIGH); digitalWrite(pump,HIGH); delay(70); } else { digitalWrite(greenled,LOW); digitalWrite(redled,LOW); digitalWrite(pump,LOW); delay(70); } } Video microcontroller-projects/arduino-pcf8591-adc-dac-module-interfacing

Interfacing a PCF8591 ADC/DAC Module with Arduino

, ADC0808. Below you can find various examples of ADC with different microcontrollers: How to Use ADC in Arduino Uno? Raspberry Pi ADC Tutorial Interfacing ADC0808 with 8051 Microcontroller 0-25V Digital Voltmeter using AVR Microcontroller How to use ADC in STM32F103C8 How to use ADC in MSP430G2 How to use ADC in ARM7 LPC2148 Using ADC Module of PIC Microcontroller with MPLAB and XC8

Required Components

Arduino UNO PCF8591 ADC Module 100K Pot Jumper Cables

PCF8591 ADC/DAC Module

and J6 is connected to select the adjustable voltage access circuit. To access these circuits you have to use the addresses of these jumpers: 0x50 for J6, 0x60 for J5 and 0x70 for J4. There are two LEDs on board D1 and D2- D1 shows the output voltage intensity and D2 shows the intensity of supply voltage. Higher the output or supply voltage, higher the intensity of LED D1 or D2. You can also test these LEDs by using a potentiometer on VCC or on AOUT pin.

Interfacing PCF8591 ADC/DAC Modulewith Arduino

Interfacing of PCF8591 with Arduino is very easy. In this interfacing example, we will read the analog values from any of the analog pins and change those values by a 100K pot. Firstly, connect VCC and GND to 5V and GND of Arduino. Next, connect the SDA and SCL to A4 and A5 of Arduino. Now, connect a 100K pot with AIN0 as shown in figure. For LCD, data pins (D4-D7) are connected to digital pins D5-D2 of Arduino and RS and EN pins are connected to D12 and D11 of Arduino. V0 of LCD is connected to pot and a 100k pot, which is used to control the brightness of LCD.

Programmingfor Arduino PCF8591 Analog to Digital Conversion (ADC)

is given at the end of this tutorial. C communication and LCD display. #include<Wire.h> #include <LiquidCrystal.h> Then define some macros. The first macro is for defining the address of data bus for IC and second macro is for defining the address of first input pin of module, where the input from pot is given. #define PCF8591 (0x90 >> 1) #define AIn0 0x00 Next define the pin connections of LCD with Arduino and initialize the value which we are getting at analog pin. const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); int Value = 0; C communication. And in the second line, we’ve initialized the LCD display on which we are printing the analog values. Learn more about interfacing 16x2 LCD with Arduino here. void setup() { Wire.begin(); lcd.begin(16,2); } function, the first line is to begin the transmission, i.e. it starts the PCF8591. The second line tells the IC to make the analog measurement at the first analog input pin. Third line ends the transmission and fourth line gets the measured data from analog pin. void loop() { Wire.beginTransmission(PCF8591); Wire.write(AIn0); Wire.endTransmission(); Wire.requestFrom(PCF8591, 1); variable defined earlier. And in next lines, print that value to the LCD. Value=Wire.read(); lcd.print("ADC Value="); lcd.print(Value); delay(500); lcd.clear();} Finally upload the code in Arduino and run it. The analog values will start showing up on LCD display. Adjust the pot’s knob, and you will see the gradual change in the values. Code #include <LiquidCrystal.h> #include<Wire.h> #define PCF8591 (0x90 >> 1) #define AIN0 0x00 const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); int Value = 0; void setup() { Wire.begin(); lcd.begin(16,2); } void loop() { Wire.beginTransmission(PCF8591); Wire.write(AIN0); Wire.endTransmission(); Wire.requestFrom(PCF8591, 1); Value = Wire.read(); lcd.print("ADC Value="); lcd.print(Value); delay(500); lcd.clear(); } Video microcontroller-projects/charlieplexing-arduino-to-control-12-leds-with-4-gpio-pins

Charlieplexing Arduino - Controlling 12 LEDs with 4 GPIO Pins

, a bunch of LEDs, and some sensors, then you are already out of pins. In that situation, you can charlieplex LEDs to reduce the number of pins.

Components Required

Arduino UNO LED (12) 4 Resistor (330 ohms) Jumper Wires Breadboard

Circuit Diagram

Basically, in this circuit diagram, 12 LEDs are connected with 4 Arduino pins through resistors. Each pin of Arduino is connected with three LEDs. There are six groups of LEDs, and in each group, 2 LEDs are connected, and both LEDs are parallel with each other but with opposite polarity so that only one LED turn on at a time. So according to the circuit diagram to turn on led 1, there needs to be a HIGH signal on pin A and a LOW signal on pin B, and pin C and D needs to be disconnected. The same procedure will be followed for the other LEDs. The full table of pin settings for each LED are given below:
LEDPin 8Pin 9Pin 10Pin 11
1HIGHLOWINPUTINPUT
2LOWHIGHINPUTINPUT
3INPUTHIGHLOWINPUT
4INPUTLOWHIGHINPUT
5INPUTINPUTHIGHLOW
6INPUTINPUTLOWHIGH
7HIGHINPUTLOWINPUT
8LOWINPUTHIGHINPUT
9INPUTHIGHINPUTLOW
10INPUTLOWINPUTHIGH
11HIGHINPUTINPUTLOW
12LOWINPUTINPUTHIGH
After the connections my hardware looks like the image below. As you can see from image there are six groups of LEDs and in each group 2 LEDs are connected opposite to each other. The Arduino UNO module is powered by USB port.

Code Explanation

is given at the end of this tutorial, here we are explaining the complete program to understand the working of the project. In the starting of Arduino code define all the pin at which LEDs are connected. After that, define the total number of LEDs and led state. #define A 8 #define B 9 #define C 10 #define D 11 #define PIN_CONFIG 0 #define PIN_STATE 1 #define LED_Num 12 Now create a matrix for turning on and off LEDs in a sequence, you can change the sequence by changing the pin state and pin configuration. According to this matrix, LED1 will be turned on first then LED2 and so on. int matrix[LED_No.][2][4] = { // PIN_CONFIG PIN_STATE // A B C D A B C D { { OUTPUT, OUTPUT, INPUT, INPUT }, { HIGH, LOW, LOW, LOW } }, { { OUTPUT, OUTPUT, INPUT, INPUT }, { LOW, HIGH, LOW, LOW } }, { { INPUT, OUTPUT, OUTPUT, INPUT }, { LOW, HIGH, LOW, LOW } }, ……………………………. …………………………‐󬬼/strong> , the program will execute the LED_COUNT matrix to turn on and off LEDs in the given sequence. void loop() { for( int l = 0; l < LED_Num; l++ ) { lightOn( l ); delay( 1000 / LED_Num ); } Now connect the Arduino with the laptop and choose the board and port correctly and then click the Upload button. After uploading the code, your LEDs should start blinking. You can use this method to control more number of LEDs. For example, if you want to control 20 LEDs, just edit the matrix and add the conditions for remaining LEDs. below. Code #define A 8 #define B 9 #define C 10 #define D 11 #define PIN_CONFIG 0 #define PIN_STATE 1 #define LED_Num 12 int matrix[LED_Num][2][4] = { // PIN_CONFIG PIN_STATE // A B C D A B C D { { OUTPUT, OUTPUT, INPUT, INPUT }, { HIGH, LOW, LOW, LOW } }, { { OUTPUT, OUTPUT, INPUT, INPUT }, { LOW, HIGH, LOW, LOW } }, { { INPUT, OUTPUT, OUTPUT, INPUT }, { LOW, HIGH, LOW, LOW } }, { { INPUT, OUTPUT, OUTPUT, INPUT }, { LOW, LOW, HIGH, LOW } }, { { OUTPUT, INPUT, OUTPUT, INPUT }, { HIGH, LOW, LOW, LOW } }, { { OUTPUT, INPUT, OUTPUT, INPUT }, { LOW, LOW, HIGH, LOW } }, { { OUTPUT, INPUT, INPUT, OUTPUT }, { HIGH, LOW, LOW, LOW } }, { { OUTPUT, INPUT, INPUT, OUTPUT }, { LOW, LOW, LOW, HIGH } }, { { INPUT, OUTPUT, INPUT, OUTPUT }, { LOW, HIGH, LOW, LOW } }, { { INPUT, OUTPUT, INPUT, OUTPUT }, { LOW, LOW, LOW, HIGH } }, { { INPUT, INPUT, OUTPUT, OUTPUT }, { LOW, LOW, HIGH, LOW } }, { { INPUT, INPUT, OUTPUT, OUTPUT }, { LOW, LOW, LOW, HIGH } } }; void lightOn( int led ) { pinMode( A, matrix[led][PIN_CONFIG][0] ); pinMode( B, matrix[led][PIN_CONFIG][1] ); pinMode( C, matrix[led][PIN_CONFIG][2] ); pinMode( D, matrix[led][PIN_CONFIG][3] ); digitalWrite( A, matrix[led][PIN_STATE][0] ); digitalWrite( B, matrix[led][PIN_STATE][1] ); digitalWrite( C, matrix[led][PIN_STATE][2] ); digitalWrite( D, matrix[led][PIN_STATE][3] ); } void setup() {} void loop() { for( int l = 0; l < LED_Num; l++ ) { lightOn( l ); delay( 1000 / LED_Num ); } } Video microcontroller-projects/wireless-rf-communication-between-arduino-and-raspberry-pi-using-nrf24l01

Wireless RF Communication using nRF24L01 Module

. The complete code for both of the section with working video will be attached at the end of this tutorial.

The nRF24L01 RF Module

is shown below (typically 3.3V) and consumes very less current of only 12mA during normal operation which makes it battery efficient and hence can even run on coin cells. Even though the operating voltage is 3.3V most of the pins are 5V tolerant and hence can be directly interfaced with 5V microcontrollers like Arduino. Another advantage of using these modules is that, each module has 6 Pipelines. Meaning, each module can communicate with 6 other modules to transmit or receive data. This makes the module suitable for creating star or mesh networks in IoT applications. Also they have a wide address range of 125 unique ID’s, hence in a closed area we can use 125 of these modules without interfering with each other.

Circuit Diagram

which uses only two wires. The circuit diagram for connecting nRF24L01 with Raspberry Pi is also very simple and only the SPI interface is used to connect Raspberry Pi and nRF24l01.

Programming Raspberry Pi to Send Message using nRF24l01

import RPi.GPIO as GPIO import time import spidev from lib_nrf24 import NRF24 This means that you are referring to the pins by the "Broadcom SOC channel" number, these are the numbers after "GPIO"( for e.g. GPIO01,GPIO02‐󧬠These are not the Board Numbers. GPIO.setmode(GPIO.BCM) This address is important in order to communicate with the Arduino receiver. The address will be in the hex code. pipes = [[0xE0, 0xE0, 0xF1, 0xF1, 0xE0], [0xF1, 0xF1, 0xF0, 0xF0, 0xE0]] Begin the radio using GPIO08 as CE and GPIO25 as CSN pins. radio.begin(0, 25) Set payload size as 32 bit, channel address as 76, data rate of 1 mbps and power levels as minimum. radio.setPayloadSize(32) radio.setChannel(0x76) radio.setDataRate(NRF24.BR_1MBPS) radio.setPALevel(NRF24.PA_MIN) Open the pipes to start writing the data and print the basic details of nRF24l01. radio.openWritingPipe(pipes[0]) radio.printDetails() Prepare a message in the string form. This message will be sent to Arduino UNO. sendMessage = list("Hi..Arduino UNO") while len(sendMessage) < 32: sendMessage.append(0) Start writing to the radio and keep on writing the complete string till the radio is available. Along with it, note down the time and print a debug statement of message delivery. while True: start = time.time() radio.write(sendMessage) print("Sent the message: {}".format(sendMessage)) send radio.startListening() If the string is completed and pipe is closed then print a debug message of timed out. while not radio.available(0): time.sleep(1/100) if time.time() - start > 2: print("Timed out.") # print error message if radio disconnected or not functioning anymore break Stop listening to the radio and close the communication and restart the communication after 3 seconds to send another message. radio.stopListening() # close radio time.sleep(3) # give delay of 3 seconds is given at the end of tutorial. Executing the program is very easy after following the below steps: Save the Python Program and Library files in the same folder. My program file name for Sender is nrfsend.py and also every files are in the same folder Go to Command Terminal of Raspberry Pi. And locate the python program file by using “cdᾠcommand. Then open the folder and write command ᾼstrong>sudo python3 your_program.pyᾠand hit enter. You will be able to see the basic details of nRf24 and the radio will start sending the messages after every 3 seconds. The message debug will display after sending is done with all characters sent. Now we will see the same program as receiver in the Arduino UNO.

Programming Arduino UNO to Receive Message using nRF24l01

library and also the nRF24l01 is interfaced with SPI so include SPI library. #include<SPI.h> #include <Wire.h> Include RF24 and LCD library for accessing the RF24 and LCD functions. #include<RF24.h> #include <LiquidCrystal_I2C.h> The LCD address for I2C is 27 and it is a 16x2 LCD so write this into the function. LiquidCrystal_I2C lcd(0x27, 16, 2); The RF24 is connected with standard SPI pins along with CE in pin 9 and CSN in pin 10. RF24 radio(9, 10) ; Start the radio, set the power level and set channel to 76. Also set the pipe address same as Raspberry Pi and open the pipe to read. radio.begin(); radio.setPALevel(RF24_PA_MAX) ; radio.setChannel(0x76) ; const uint64_t pipe = 0xE0E0F1F1E0LL ; radio.openReadingPipe(1, pipe) ; Begin the I2C communication and initialise the LCD display. Wire.begin(); lcd.begin(); lcd.home(); lcd.print("Ready to Receive"); Start listening to the radio for incoming messages and set the message length as 32 bytes. radio.startListening() ; char receivedMessage[32] = {0} If radio is attached then start reading the message and save it. Print the message to serial monitor and also print to the display until the next message arrives. Stop the radio to listen and retry after some interval. Here it is 10 micro seconds. if (radio.available()) { radio.read(receivedMessage, sizeof(receivedMessage)); Serial.println(receivedMessage) ; Serial.println("Turning off the radio.") ; radio.stopListening() ; String stringMessage(receivedMessage) ; lcd.clear(); delay(1000); lcd.print(stringMessage); } given at the end to the Arduino UNO and wait for the message to be received. for more detailed discussion. below. Code import RPi.GPIO as GPIO # import gpio import time #import time library import spidev from lib_nrf24 import NRF24 #import NRF24 library GPIO.setmode(GPIO.BCM) # set the gpio mode # set the pipe address. this address shoeld be entered on the receiver alo pipes = [[0xE0, 0xE0, 0xF1, 0xF1, 0xE0], [0xF1, 0xF1, 0xF0, 0xF0, 0xE0]] radio = NRF24(GPIO, spidev.SpiDev()) # use the gpio pins radio.begin(0, 25) # start the radio and set the ce,csn pin ce= GPIO08, csn= GPIO25 radio.setPayloadSize(32) #set the payload size as 32 bytes radio.setChannel(0x76) # set the channel as 76 hex radio.setDataRate(NRF24.BR_1MBPS) # set radio data rate radio.setPALevel(NRF24.PA_MIN) # set PA level radio.setAutoAck(True) # set acknowledgement as true radio.enableDynamicPayloads() radio.enableAckPayload() radio.openWritingPipe(pipes[0]) # open the defined pipe for writing radio.printDetails() # print basic detals of radio sendMessage = list("Hi..Arduino UNO") #the message to be sent while len(sendMessage) < 32: sendMessage.append(0) while True: start = time.time() #start the time for checking delivery time radio.write(sendMessage) # just write the message to radio print("Sent the message: {}".format(sendMessage)) # print a message after succesfull send radio.startListening() # Start listening the radio while not radio.available(0): time.sleep(1/100) if time.time() - start > 2: print("Timed out.") # print errror message if radio disconnected or not functioning anymore break radio.stopListening() # close radio time.sleep(3) # give delay of 3 seconds # > #include<SPI.h> // spi library for connecting nrf #include <Wire.h> // i2c libary fro 16x2 lcd display #include<RF24.h> // nrf library #include <LiquidCrystal_I2C.h> // 16x2 lcd display library LiquidCrystal_I2C lcd(0x27, 16, 2); // i2c address is 0x27 RF24 radio(9, 10) ; // ce, csn pins void setup(void) { while (!Serial) ; Serial.begin(9600) ; // start serial monitor baud rate Serial.println("Starting.. Setting Up.. Radio on..") ; // debug message radio.begin(); // start radio at ce csn pin 9 and 10 radio.setPALevel(RF24_PA_MAX) ; // set power level radio.setChannel(0x76) ; // set chanel at 76 const uint64_t pipe = 0xE0E0F1F1E0LL ; // pipe address same as sender i.e. raspberry pi radio.openReadingPipe(1, pipe) ; // start reading pipe radio.enableDynamicPayloads() ; radio.powerUp() ; Wire.begin(); //start i2c address lcd.begin(); // start lcd lcd.home(); lcd.print("Ready to Receive"); // print starting message on lcd delay(2000); lcd.clear(); } void loop(void) { radio.startListening() ; // start listening forever char receivedMessage[32] = {0} ; // set incmng message for 32 bytes if (radio.available()) { // check if message is coming radio.read(receivedMessage, sizeof(receivedMessage)); // read the message and save Serial.println(receivedMessage) ; // print message on serial monitor Serial.println("Turning off the radio.") ; // print message on serial monitor radio.stopListening() ; // stop listening radio String stringMessage(receivedMessage) ; // change char to string lcd.clear(); // clear screen for new message delay(1000); // delay of 1 second lcd.print(stringMessage); // print received mesage } delay(10); } Video microcontroller-projects/diy-arduino-uno-power-supply-shield

DIY Arduino Power Supply Shield with 3.3v, 5v and 12v Output Options

When developing electronic projects, the power supply is one of the most important part of whole project and there is always need of multiple output voltage power supply. This is because different sensors need different input voltage and current to run efficiently. In this scenario, a power supply which can output multiple voltages becomes very important. There are options that an engineer can use for external power supply like RPS (regulated power supply) or AC adaptors but then multiple power supplies will be needed and the whole system will become bulky. : DIY Arduino Motor Driver Shield DIY Arduino Relay Driver Shield DIY Arduino Wi-Fi Shield DIY LED VU Meter as Arduino Shield

Components Required

LM317 ᾠ1 Unit LM7805 ᾠ1 Unit LED(Any Color) ᾠ1 Unit 12V DC Barrel Jack ᾠUnit 220Ω Resistor ᾠ1 Unit 560Ω Resistor ᾠ2 Units 1uF Capacitor ᾠ2 Units 0.1uF Capacitor ᾠ1 Unit Burg Pins(20 mm) ᾠ52 Units

Circuit Diagram

It is important to place an output capacitor between the output of LM7805 and Ground. Similarly between the LM317 and Ground. Keep in mind that all grounds should be common and the required track width should be chosen depending upon the current flowing through the circuit.

Fabricating the PCB for Arduino Power Supply Shield

After making the circuit ready, it’s the time to go ahead with designing our PCB using the PCB design software. As stated earlier we are using EasyEDA PCB Designer, so we just need to convert the schematic to a PCB Board. When you convert the schematic into board, you also need to place the components in the places according to the design. After converting the schematic above to board my PCB looked like below. and send it to the PCBGOGO manufacturer online or you can change the board layout according to your custom design and application.

Ordering the PCB from PCBGoGo

Now when the complete design is ready it is time to get them fabricated. To get thePCB done is quite easy, simply follow the steps below , sign up if this is your first time. Then, in the PCB Prototype tab enter the dimensions of your PCB, the number of layers and the number of PCB you require. Assuming the PCB is 80cm×80cm you can set the dimensions as shown below. button. You will be taken to a page where to set few additional parameters if required like the material used track spacing etc. But mostly the default values will work fine. The only thing that we have to consider here is the price and time. As you can see the Build Time is only 2-3 days and it just costs only $5 for our PSB. You can then select a preferred shipping method based on your requirement. verifies if your Gerber file is valid before proceeding with the payment. This way you can sure that your PCB is fabrication friendly and will reach you as committed.

Assembling the PCB

After the board was ordered, it reached me after some days though courier in a neatly labelled well-packed box and like always the quality of the PCB was awesome. Get the soldering kit and start placing all the components in the right pads of the PCB Board. The soldering is easy to finish as there is not much components used in this project. When the soldering is finished your board should look like below. the burg pins used is of male to male 20 mm connectors. You can use Male to Female Burg pins depending upon the availability. The20mmburg pins aresuitable forArduino Shield and fits well for onArduinoUNO.

Testing the Power Supply Arduino Shield

without damaging the components. You can check all the output voltage i.e. 3.3V, 5V and 12V using a digital multimeter. If all went good including designing and soldering of the components then you will be able to note down the exact output voltage at the output pins. for the shield is given below. for more help. Video microcontroller-projects/arduino-based-morse-code-generator

Arduino based Morse Code Generator

Morse code is developed by Samuel F.B. and further used in telegraphy for transferring secret information. It was most used at the time of World War II. A Morse code can be performed by tapping, flashing light or writing. The Morse code is available in two versions, the original and the international morse code. In the international morse code, the original version is modified by removing spaces and designing the dashes in a specific length. The Morse code is available for encoding alphabets and numbers. It is mainly used in the radio and ocean communication and also a part of training for soldiers. SOS full form is Save Our Souls created as a universal distress signal represents danger. The below image shows the Morse code for the alphabets from A to Z. which will take any character as an input from serial monitor and convert it into Morse code equivalent beeps by buzzer.

Components Required

Arduino Uno Buzzer Breadboard Jumper wires

Circuit Diagram

to display the dash and dots.

Programming Explanation

is given at the end, here we are explaining the program to understand the working of the project. The below code is used to receive the character string and then convert it into morse code. char stringToMorseCode[] = ""; Then define the pin for the buzzer connected to the Arduino and the pitch for the sound generated by that buzzer. Then we are defining the length of dot and dash. int audio8 = 8; // output audio on pin 8 int note = 1200; // music note/pitch int dotLen = 100; // length of the morse code 'dot' int dashLen = dotLen * 3; // length of the morse code 'dash' is used to change the lower case characters into uppercase. Then it creates sound according to every character. void loop() { char inChar = 0; char inData[100] = ""; // data length of 6 characters String variable = ""; String variable1 = ""; int index1 = 0; if ( Serial.available() > 0 ) { while (Serial.available() > 0 && index1 < 100) { delay(100); inChar = Serial.read(); inData[index1] = inChar; index1++; inData[index1] = '\0'; } variable.toUpperCase(); for (byte i = 0 ; i < 100 ; i++) { variable.concat(String(inData[i])); } delay(20); are used to create the sound for dot and dash respectively. void MorseDot() { tone(audio8, note, dotLen); // start playing a tone delay(dotLen); // hold in this position } void MorseDash() { tone(audio8, note, dashLen); // start playing a tone delay(dashLen); // hold in this position } function have the code for all the alphabets. So, whenever we type any alphabet, the respective morse code is taken from this function to create the particular sound. void GetChar(char tmpChar) { switch (tmpChar) { case 'a': MorseDot(); delay(100); MorseDash(); delay(100); break; … … … default: break; } } Now upload the code into Arduino using Arduino IDE and type any character into the serial monitor and hit the enter button to send the characters to the Arduino. Here we have typed ‘SOSᾠwhich is a universal distress signal, to create the sound for the same. below. Code char stringToMorseCode[] = ""; int audio8 = 8; // output audio on pin 8 int note = 1200; // music note/pitch int dotLen = 100; // length of the morse code 'dot' int dashLen = dotLen * 3; // length of the morse code 'dash' void setup() { Serial.begin(9600); } void loop() { char inChar = 0; char inData[100] = ""; // data length of 6 characters String variable = ""; String variable1 = ""; int index1 = 0; if ( Serial.available() > 0 ) { // Read from Rx from atmega16 while (Serial.available() > 0 && index1 < 100) // read till 6th character { delay(100); inChar = Serial.read(); // start reading serilly and save to variable inData[index1] = inChar; index1++; inData[index1] = '\0'; // Add a null at the end } variable.toUpperCase(); // convert to uppercase for (byte i = 0 ; i < 100 ; i++) { variable.concat(String(inData[i])); // concat strings } delay(20); } String stringToMorseCode = String(variable); for (int i = 0; i < sizeof(stringToMorseCode) - 1; i++) { char tmpChar = stringToMorseCode[i]; tmpChar = toLowerCase(tmpChar); GetChar(tmpChar); } } void MorseDot() { tone(audio8, note, dotLen); // start playing a tone delay(dotLen); // hold in this position } void MorseDash() { tone(audio8, note, dashLen); // start playing a tone delay(dashLen); // hold in this position } void GetChar(char tmpChar) { switch (tmpChar) { case 'a': MorseDot(); delay(100); MorseDash(); delay(100); break; case 'b': MorseDash(); delay(100); MorseDot(); delay(100); MorseDot(); delay(100); MorseDot(); delay(100); break; case 'c': MorseDash(); delay(100); MorseDot(); delay(100); MorseDash(); delay(100); MorseDot(); delay(100); break; case 'd': MorseDash(); delay(100); MorseDot(); delay(100); MorseDot(); delay(100); break; case 'e': MorseDot(); delay(100); break; case 'f': MorseDot(); delay(100); MorseDot(); delay(100); MorseDash(); delay(100); MorseDot(); delay(100); break; case 'g': MorseDash(); delay(100); MorseDash(); delay(100); MorseDot(); delay(100); break; case 'h': MorseDot(); delay(100); MorseDot(); delay(100); MorseDot(); delay(100); MorseDot(); delay(100); break; case 'i': MorseDot(); delay(100); MorseDot(); delay(100); break; case 'j': MorseDot(); delay(100); MorseDash(); delay(100); MorseDash(); delay(100); MorseDash(); delay(100); break; case 'k': MorseDash(); delay(100); MorseDot(); delay(100); MorseDash(); delay(100); break; case 'l': MorseDot(); delay(100); MorseDash(); delay(100); MorseDot(); delay(100); MorseDot(); delay(100); break; case 'm': MorseDash(); delay(100); MorseDash(); delay(100); break; case 'n': MorseDash(); delay(100); MorseDot(); delay(100); break; case 'o': MorseDash(); delay(100); MorseDash(); delay(100); MorseDash(); delay(100); break; case 'p': MorseDot(); delay(100); MorseDash(); delay(100); MorseDash(); delay(100); MorseDot(); delay(100); break; case 'q': MorseDash(); delay(100); MorseDash(); delay(100); MorseDot(); delay(100); MorseDash(); delay(100); break; case 'r': MorseDot(); delay(100); MorseDash(); delay(100); MorseDot(); delay(100); break; case 's': MorseDot(); delay(100); MorseDot(); delay(100); MorseDot(); delay(100); break; case 't': MorseDash(); delay(100); break; case 'u': MorseDot(); delay(100); MorseDot(); delay(100); MorseDash(); delay(100); break; case 'v': MorseDot(); delay(100); MorseDot(); delay(100); MorseDot(); delay(100); MorseDash(); delay(100); break; case 'w': MorseDot(); delay(100); MorseDash(); delay(100); MorseDash(); delay(100); break; case 'x': MorseDash(); delay(100); MorseDot(); delay(100); MorseDot(); delay(100); MorseDash(); delay(100); break; case 'y': MorseDash(); delay(100); MorseDot(); delay(100); MorseDash(); delay(100); MorseDash(); delay(100); break; case 'z': MorseDash(); delay(100); MorseDash(); delay(100); MorseDot(); delay(100); MorseDot(); delay(100); break; default: break; } } Video microcontroller-projects/how-to-use-adps9960-rgb-and-gesture-sensor-with-arduino

How to Use APDS9960 RGB and Gesture Sensor with Arduino

Required Components

Arduino UNO APDS9960 RGB and Gesture Sensor 16x2 LCD DPDT Switch 100K pot and 10K resistor Jumper Cables

Introduction to APDS-9960 Digital Proximity RGB & Gesture Sensor

APDS9960 is a multifunction sensor. It can detect gestures, ambient light and RGB values in light. This sensor can also be used as a proximity sensor and is mostly used in smartphones, to disable the touchscreen while attending a call. This sensor consists four photodiodes. These photodiodes detect the reflected IR energy which is transmitted by an on-board LED. So whenever any gesture is performed then this IR energy gets obstructed and reflects back to the sensor, now the sensor detects the information (direction, velocity) about the gesture and converts it into digital information. This sensor can be used to measures the distance of obstacle by detecting reflected IR light. It has UV and IR blocking filters for sensing RGB colors and it produce 16-bit data for each color. C communication. And VL pin is optional power pin for the on-board LED if the PS jumper is not connected. If the PS jumper is closed then you only need to power VCC pin, it will provide power to both - the module and the IR LED.

Circuit Diagram

are very simple. We will use a DPDT button to switch between the two modes RGB Sensing and Gesture Sensing. Firstly the I2C communication pins SDA and SCL of APDS9960 are connected to Arduino pin A4 and A5 respectively. As stated earlier the operating voltage for the sensor is 3.3v so, VCC and GND of APDS9960 are connected to 3.3V and GND of Arduino. The interrupt pin (INT) of APDS9960 is connected to D2 pin of Arduino. , data pins (D4-D7) are connected to digital pins D6-D3 of Arduino and RS and EN pins are connected to D6 and D7 of Arduino. V0 of LCD is connected to pot and a 100K pot is used to control the brightness of LCD. For the DPDT buttons we’ve used only 3 pins. The second pin is connected to D7 pin of Arduino for input and the other two are connected to GND and VCC followed by a 10K resistor.

Programming Arduino for Gesture and Color Sensing

is given at the end of this tutorial. Now in search bar type “Sparkfun APDS9960ᾠand click on the install button when you see the library. And we are ready to go. Let’s get started. is used for the APDS9960 sensor. #include <LiquidCrystal.h> #include <Wire.h> #include <SparkFun_APDS9960.h> Now in next lines we’ve defined the pins for button and LCD. const int buttonPin = 7; const int rs = 12, en = 11, d4 = 6, d5 = 5, d6 = 4, d7 = 3; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); for the interrupt service routine. #define APDS9960_INT 2 int buttonState; int isr_flag = 0; Next an object is created for the SparkFun_APDS9960, so that we can access the gesture movements and fetch the RGB values. SparkFun_APDS9960 apds = SparkFun_APDS9960(); uint16_t ambient_light = 0; uint16_t red_light = 0; uint16_t green_light = 0; uint16_t blue_light = 0; initializes the LCD. void setup() { buttonState = digitalRead(buttonPin); pinMode(APDS9960_INT, INPUT); pinMode(buttonPin, INPUT); apds.init(); lcd.begin(16, 2); } variable defined earlier. Now in next lines we are checking the values from button, if it is high then we enable the light sensor and if it is low then initialize gesture sensor. here. void loop() { buttonState = digitalRead(buttonPin); if (buttonState == HIGH) { apds.enableLightSensor(true); } And if it can read values then, compare the values of the three colors and whichever is highest, print that color to the LCD. if (buttonState == HIGH) { if ( !apds.readAmbientLight(ambient_light) || !apds.readRedLight(red_light) || !apds.readGreenLight(green_light) || !apds.readBlueLight(blue_light) ) { lcd.print("Error reading light values"); } else { if (red_light > green_light) { if (red_light > blue_light) { lcd.print("Red"); delay (1000); lcd.clear(); } ……. ……‐󬬼/strong> to zero and attach the interrupt. else if (buttonState == LOW) { if ( isr_flag == 1 ) { detachInterrupt(0); handleGesture(); isr_flag = 0; attachInterrupt(0, interruptRoutine, FALLING); } } variable 1, so that the interrupt service can be initialized. void interruptRoutine(). { isr_flag = 1; } function is defined in the next part. This function firstly checks for the availability of gesture sensor. If it is available then it reads the gesture values and checks which gesture it is (UP, DOWN, RIGHT, LEFT, FAR, NEAR) and prints the corresponding values to LCD. void handleGesture() { if ( apds.isGestureAvailable() ) { switch ( apds.readGesture() ) { case DIR_UP: lcd.print("UP"); delay (1000); lcd.clear(); break; case DIR_DOWN: lcd.print("DOWN"); delay (1000); lcd.clear(); break; case DIR_LEFT: lcd.print("LEFT"); delay (1000); lcd.clear(); break; case DIR_RIGHT: lcd.print("RIGHT"); delay (1000); lcd.clear(); break; case DIR_NEAR: lcd.print("NEAR"); delay (1000); lcd.clear(); break; case DIR_FAR: lcd.print("FAR"); delay (1000); lcd.clear(); break; default: lcd.print("NONE"); delay (1000); lcd.clear(); } } } gesture keep your hand far from sensor then take it near and remove it. and take red, blue and green objects one by one near to the sensor. It will print the color of the object. Code #include <LiquidCrystal.h> #include <Wire.h> #include <SparkFun_APDS9960.h> const int buttonPin = 7; const int rs = 12, en = 11, d4 = 6, d5 = 5, d6 = 4, d7 = 3; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); #define APDS9960_INT 2 int buttonState; int isr_flag = 0; SparkFun_APDS9960 apds = SparkFun_APDS9960(); uint16_t ambient_light = 0; uint16_t red_light = 0; uint16_t green_light = 0; uint16_t blue_light = 0; void setup() { buttonState = digitalRead(buttonPin); pinMode(APDS9960_INT, INPUT); pinMode(buttonPin, INPUT); apds.init(); lcd.begin(16, 2); } void loop() { buttonState = digitalRead(buttonPin); if (buttonState == HIGH) { apds.enableLightSensor(true); } else if (buttonState == LOW) { attachInterrupt(0, interruptRoutine, FALLING); apds.enableGestureSensor(true); } if (buttonState == HIGH) { if ( !apds.readAmbientLight(ambient_light) || !apds.readRedLight(red_light) || !apds.readGreenLight(green_light) || !apds.readBlueLight(blue_light) ) { lcd.print("Error reading light values"); } else { if (red_light > green_light) { if (red_light > blue_light) { lcd.print("Red"); delay (1000); lcd.clear(); } else { lcd.print("Blue"); delay (1000); lcd.clear(); } } else if (green_light > blue_light) { lcd.print("Green"); delay (1000); lcd.clear(); } else { lcd.print("Blue"); delay (1000); lcd.clear(); } } } else if (buttonState == LOW) { if ( isr_flag == 1 ) { detachInterrupt(0); handleGesture(); isr_flag = 0; attachInterrupt(0, interruptRoutine, FALLING); } } } void interruptRoutine() { isr_flag = 1; } void handleGesture() { if ( apds.isGestureAvailable() ) { switch ( apds.readGesture() ) { case DIR_UP: lcd.print("UP"); delay (1000); lcd.clear(); break; case DIR_DOWN: lcd.print("DOWN"); delay (1000); lcd.clear(); break; case DIR_LEFT: lcd.print("LEFT"); delay (1000); lcd.clear(); break; case DIR_RIGHT: lcd.print("RIGHT"); delay (1000); lcd.clear(); break; case DIR_NEAR: lcd.print("NEAR"); delay (1000); lcd.clear(); break; case DIR_FAR: lcd.print("FAR"); delay (1000); lcd.clear(); break; default: lcd.print("NONE"); delay (1000); lcd.clear(); } } } Video microcontroller-projects/arduino-can-tutorial-interfacing-mcp2515-can-bus-module-with-arduino

Arduino CAN Tutorial - Interfacing MCP2515 CAN BUS Module with Arduino

, designers use much reliable automobile communication protocols like LIN, CAN, FlexRay etc. Sounds interesting right! So, let’s get started.

Introduction to CAN

bus designed for industrial and automotive applications. It is a message-based protocol used for communication between multiple devices. When multiple CAN devices are connected together like shown below, the connection forms a network acting like our central nervous system allowing any device to speak with any other device in the node. for bi-directional data transmission as shown above. Typically the communication speed for CAN ranges from 50 Kbps to 1Mbps and the distance can range from 40 meters at 1Mbps to 1000 meters at 50kpbs. which helps to send and respond to messages in CAN bus. The identifier is also known as a CAN ID or also known as PGN (Parameter Group Number).It is used to identify the CAN devices present in a CAN network. The length of the identifier is either 11 or 29 bits based on the type of CAN protocol used. Standard CAN: 0-2047 (11-bit) -1 (29-bit) This is the actual sensor/control data that has to be send form one device to another. The size data can be anywhere from 0 to 8 bytes in length. Data Length Code (DLC): 0 to 8 for the number of data bytes present. ,meaning the CAN signal (0 or 1) is represented by the potential difference between CAN_L and CAN_H. Ifthe difference is positive and larger than a certain minimum voltage then it is 1 and if the difference is negative it is a 0. Normally a twisted pair cable is used for CAN communication. A single 120-ohm resistor isgenerallyused at the two ends of the CAN network as shown in image, this is because the line needs to be balanced and tied to same potential.

Comparison of CAN over SPI & I2C

, let us compare the features of SPI and I2C with CAN
ParameterSPII2CCAN
Speed 3Mbps to 10MbpsStandard: 100Kbps 10KBps to 1MBps Also depends upon length of wire used
Fast: 400 Kbps
Highspeed:3.4Mbps
TypeSynchronousSynchronousAsynchronous
Number of Wires3+ (MISO, MOSI, SCK, SS1, SS2…SS(n))2 wires (SDA, SCL)2 wires (CAN_H, CAN_L)
DuplexFull DuplexHalf DuplexHalf Duplex

CAN Protocol Applications

Because of the robustness and reliability of CAN protocol, they are used in industries like Automotive, Industrial machines, Agriculture, Medical Equipment etc. As wiring complexity is reduced in CAN they are mainly used in automotive applications like car. Low cost to implement and also hardware components price is also less. Easy to add and remove the CAN bus devices.

How to use CAN protocol in Arduino

is used. This CAN module is interfaced with Arduino by using the SPI communication. Let’s see about more about MCP2515 in detail and how it is interfaced with Arduino. The connection between MCP2515 and MCU is through SPI. So, it is easy to interface with any microcontroller having SPI interface. For beginners who want to learn CAN Bus, this module will act as a good start. This CAN SPI board is ideal for industrial automation, home automation and other automotive embedded projects. Uses High-speed CAN transceiver TJA1050 Dimension: 40×28mm SPI control for expand Multi CAN bus interface 8MHZ crystal oscillator 120Ω terminal resistance Has independent key, LED indicator, Power indicator Supports 1 Mb/s CAN operation Low current standby operation Up to 112 nodes can be connected
VCC5V Power input pin
GNDGround pin
CSSPI SLAVE select pin (Active low)
SOSPI master input slave output lead
SISPI master output slave input lead
SCLKSPI Clock pin
INTMCP2515 interrupt pin
bus module MCP2515.

Components Required

Arduino UNO Arduino NANO DHT11 16x2 LCD Display MCP2515 CAN Module ᾠ2 10k Potentiometer Breadboard Connecting Wires

MCP2515ArduinoCircuit Diagram

MPC2515 - VCC+5V
MPC2515 - GNDGND
MPC2515 - CSD10 (SPI_SS)
MPC2515 - SOD12 (SPI_MISO)
MPC2515 - S ID11 (SPI_MOSI)
MPC2515- - SCKD13 (SPI_SCK)
MPC2515 - INTD2
DHT11 - VCC+5V
DHT11 - GNDGND
DHT11- - OUTA0
Component - Pin
MPC2515 - VCC+5V
MPC2515 - GNDGND
MPC2515 - CS10 (SPI_SS)
MPC2515 - SO12 (SPI_MISO)
MPC2515 - SI11 (SPI_MOSI)
MPC2515 - SCK13 (SPI_SCK)
MPC2515 - INT2
LCD - VSSGND
LCD - VDD+5V
LCD - V0To 10K Potentiometer Centre PIN
LCD - RS3
LCD - RWGND
LCD - E4
LCD - D45
LCD - D56
LCD - D67
LCD - D78
LCD - A+5V
LCD - KGND

Connection between two MCP2515 CAN modules

Once all the connections were made, my hardware looked like this below

Programming Arduino for CAN communication

First we have to install a library for CAN in Arduino IDE. Interfacing MCP2515 CAN Module with the Arduino becomes easier by using the following library. Download the ZIP file of Arduino CAN MCP2515 Library. From the Arduino IDE: Sketch -> Include Library -> Add .ZIP Library (Arduino UNO) both of which can be found at the bottom of this page. The explanation for the same is as follows. Before writing program for sending and receiving data make sure you have installed the library following the above steps and the CAN module MCP2515 is initialized in your program as following. In order to create connection with MCP2515 follow the steps: 1. Set the pin number where SPI CS is connected (10 by default) MCP2515 mcp2515(10); 2. Set baud rate and oscillator frequency mcp2515.setBitrate(CAN_125KBPS, MCP_8MHZ); Available Baud Rates: CAN_5KBPS, CAN_10KBPS, CAN_20KBPS, CAN_31K25BPS, CAN_33KBPS, CAN_40KBPS, CAN_50KBPS, CAN_80KBPS, CAN_83K3BPS, CAN_95KBPS, CAN_100KBPS, CAN_125KBPS, CAN_200KBPS, CAN_250KBPS, CAN_500KBPS, CAN_1000KBPS. Available Clock Speeds: MCP_20MHZ, MCP_16MHZ, MCP_8MHZ 3. Set modes. mcp2515.setNormalMode(); mcp2515.setLoopbackMode(); mcp2515.setListenOnlyMode();

CAN Transmitter Side Code Explanation (Arduino Nano)

to CAN bus. #include <SPI.h> #include <mcp2515.h> #include <DHT.h> Now the pin name of DHT11 (OUT pin) that is connected with the A0 of Arduino Nano is defined #define DHTPIN A0 is defined as DHT11. #define DHTTYPE DHT11 struct data type for storing CAN message format. struct can_frame canMsg; Set the pin number where SPI CS is connected (10 by default) MCP2515 mcp2515(10); And also, object dht for class DHT with DHT pin with Arduino Nano and DHT type as DHT11 is initialized. DHT dht(DHTPIN, DHTTYPE); Begin the SPI communication by using following statement SPI.begin(); And then use below statement to begin to receive Temperature and humidity values from DHT11 sensor. dht.begin(); Next the MCP2515 is being RESET using the following command mcp2515.reset(); of 500KBPS and 8MHZ as clock mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ); And the MCP2525 is set at normal mode mcp2515.setNormalMode(); The following statement gets the Humidity and Temperature value and stores in an integer variable h and t. int h = dht.readHumidity(); int t = dht.readTemperature(); and rest all data with 0. canMsg.can_id = 0x036; canMsg.can_dlc = 8; canMsg.data[0] = h; //Update humidity value in [0] canMsg.data[1] = t; //Update temperature value in [1] canMsg.data[2] = 0x00; //Rest all with 0 canMsg.data[3] = 0x00; canMsg.data[4] = 0x00; canMsg.data[5] = 0x00; canMsg.data[6] = 0x00; canMsg.data[7] = 0x00; we use the following statement. mcp2515.sendMessage(&canMsg); So now the temperature and humidity data are sent as message to CAN bus.

CAN Receiver Side Code Explanation (Arduino UNO)

Here the Arduino UNO receives the Temperature and Humidity from CAN bus and display the data received in LCD. #include <SPI.h #include <mcp2515.h> #include <LiquidCrystal.h> Next the LCD pins that are used in connecting with the Arduino UNO are defined. const int rs = 3, en = 4, d4 = 5, d5 = 6, d6 = 7, d7 = 8; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); struct can_frame canMsg; Set the pin number where SPI CS is connected (10 by default) MCP2515 mcp2515(10); First the LCD is set at 16x2 mode and a welcome message is displayed. lcd.begin(16,2); lcd.setCursor(0,0); lcd.print("CIRCUIT DIGEST"); lcd.setCursor(0,1); lcd.print("CAN ARDUINO"); delay(3000); lcd.clear(); Begin the SPI communication by using following statement. SPI.begin(); Next the MCP2515 is being RESET using the following command. mcp2515.reset(); Now the MCP2515 is set speed of 500KBPS and 8MHZ as clock. mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ); And the MCP2525 is set at normal mode. mcp2515.setNormalMode(); condition. if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) , the data [0] that has humidity value and data [1] that has temperature value. Both values are stored in an integer x and y. int x = canMsg.data[0]; int y = canMsg.data[1]; After receiving the values, the temperature and humidity values are displayed in 16x2 LCD display using following statement. lcd.setCursor(0,0); lcd.print("Humidity : "); lcd.print(x); lcd.setCursor(0,1); lcd.print("Temp : "); lcd.print(y); delay(1000); lcd.clear();

Working of CAN communication in Arduino

Arduino as you can see in the below image. I have also used my AC remote to check if the temperature displayed on the LCD is close to actual room temperature. for other technical questions. Code CAN Transmitter Code (Arduino Nano): #include <SPI.h> //Library for using SPI Communication #include <mcp2515.h> //Library for using CAN Communication #include <DHT.h> //Library for using DHT sensor #define DHTPIN A0 #define DHTTYPE DHT11 struct can_frame canMsg; MCP2515 mcp2515(10); DHT dht(DHTPIN, DHTTYPE); //initilize object dht for class DHT with DHT pin with STM32 and DHT type as DHT11 void setup() { while (!Serial); Serial.begin(9600); SPI.begin(); //Begins SPI communication dht.begin(); //Begins to read temperature & humidity sesnor value mcp2515.reset(); mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz mcp2515.setNormalMode(); } void loop() { int h = dht.readHumidity(); //Gets Humidity value int t = dht.readTemperature(); //Gets Temperature value canMsg.can_id = 0x036; //CAN id as 0x036 canMsg.can_dlc = 8; //CAN data length as 8 canMsg.data[0] = h; //Update humidity value in [0] canMsg.data[1] = t; //Update temperature value in [1] canMsg.data[2] = 0x00; //Rest all with 0 canMsg.data[3] = 0x00; canMsg.data[4] = 0x00; canMsg.data[5] = 0x00; canMsg.data[6] = 0x00; canMsg.data[7] = 0x00; mcp2515.sendMessage(&canMsg); //Sends the CAN message delay(1000); } CAN Receiver Code (Arduino UNO): #include <SPI.h> //Library for using SPI Communication #include <mcp2515.h> //Library for using CAN Communication #include <LiquidCrystal.h> //Library for using LCD display const int rs = 3, en = 4, d4 = 5, d5 = 6, d6 = 7, d7 = 8; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); //Define LCD display pins RS,E,D4,D5,D6,D7 struct can_frame canMsg; MCP2515 mcp2515(10); // SPI CS Pin 10 void setup() { lcd.begin(16,2); //Sets LCD as 16x2 type lcd.setCursor(0,0); //Display Welcome Message lcd.print("CIRCUIT DIGEST"); lcd.setCursor(0,1); lcd.print("CAN ARDUINO"); delay(3000); lcd.clear(); SPI.begin(); //Begins SPI communication Serial.begin(9600); //Begins Serial Communication at 9600 baudrate mcp2515.reset(); mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz mcp2515.setNormalMode(); //Sets CAN at normal mode } void loop() { if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) // To receive data (Poll Read) { int x = canMsg.data[0]; int y = canMsg.data[1]; lcd.setCursor(0,0); //Display Temp & Humidity value received at 16x2 LCD lcd.print("Humidity : "); lcd.print(x); lcd.setCursor(0,1); lcd.print("Temp : "); lcd.print(y); delay(1000); lcd.clear(); } } Video microcontroller-projects/arduino-vl6180-tof-range-finder-sensor-for-distance-measurement

Interfacing VL6180 ToF Range Finder Sensor with Arduino for Distance Measurement

). This measurement can then be used to calculate the velocity or path length. It can also be used to learn about the particle or properties of the medium such as composition or flow rate. The traveling object can be detected directly or indirectly. : Arduino & Ultrasonic Sensor Based Distance Measurement Measure Distance using Raspberry Pi and HCSR04 Ultrasonic Sensor How To Measure Distance Between Two Ultrasonic Sensors The time of flight method can also be used to estimate the electron mobility. Actually, it was designed for the measurement of low-conductive thin films, later it was adjusted for common semiconductors. This technique is used for organic field effect transistors as well as metal-dielectric-metal structures. By the application of the laser or voltage pulse, the excess charges are generated. is used for range finding it is very powerful when emitting light rather than sound. Compared to ultrasound it provides faster reading, higher accuracy and greater range still maintaining its low weight, small size, and low power consumption characteristics. This sensor also tells the Light intensity value in LUX.

VL6180XTime-of-Flight (ToF) Range Finder Sensor

a benefit over other sensors because it’s more accurate and immune to noise. are provided in it.

Circuit Diagram

(Serial Clock), a data line and clock line. is shown below: Connect theRSTPin of LCD to the pin 6 ofArduinothrough the10Kresistor. Connect the CE Pin of LCD to the pin 7 ofArduinothrough the10Kresistor. Connect the DC Pin of LCD to the pin 5 ofArduinothrough the10Kresistor. Connect the DIN Pin of LCD to the pin 4 ofArduinothrough the10Kresistor. Connect theCLKPin of LCD to the pin 3 ofArduinothrough the10Kresistor. Connect theVCCPin of LCD to the 3.3V pin ofArduino. Connect theGNDPin of LCD to theGNDofArduino. Connect theSCLpin ofVL6180to A5 pin ofArduino Connect theSDApin ofVL6180to A4 pin ofArduino Connect theVCCpin ofVL6180to 5V pin ofArduino Connect theGNDpin ofVL6180toGNDpin ofArduino

Adding required Libraries forVL6180ToFSensor

for communication. Four or five pins are required for interfacing this LCD. The link for download this library is given below: is the core graphics library for LCD displays, providing a common syntax and set of graphics primitives (points, lines, circles, etc). It needs to be paired with a hardware specific library for each display device we use (to handle the lower level functions). The link for download this library is given below: interface. This library allows you to read the distance and light outputs from the sensor, and outputs the data via a serial connection. The link for download this library is given below: IDE. Then upload the library that you downloaded from the above links. IDE.

Programming and Working Explanation

is given at the end of this tutorial, here we are explaining the complete program to understand the working of the project. In this program majority of the parts are handled by the libraries that we added so you do not need to worry about that. sensor is working properly or not, if it is not working then show an error message. In the following part we are setting up the display, you can change the contrast to your desired value here I am setting it as 50 void setup() { Serial.begin(115200); //Start Serial at 115200bps Wire.begin(); //Start I2C library delay(100); // delay . if (sensor.VL6180xInit() != 0) { Serial.println("FAILED TO INITALIZE"); //Initialize device and check for errors }; sensor.VL6180xDefautSettings(); //Load default settings to get started. delay(1000); // delay 1s display.begin(); // init done // you can change the contrast around to adapt the display // for the best viewing! display.setContrast(50); display.display(); // show splashscreen display.clearDisplay(); } setup the instructions to display the values on LCD screen. Here we are displaying two values, one is the “Ambient light level in Luxᾠ(One lux is actually one lumen per square meter area), and second one is “Distance measured in mmᾮ To display different values on a LCD screen define the position of each text that should display on the LCD screen by using “display.setCursor(0,0);ᾮ void loop() { display.clearDisplay(); //Get Ambient Light level and report in LUX Serial.print("Ambient Light Level (Lux) = "); Serial.println(sensor.getAmbientLight(GAIN_1)); display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(0,0 ); display.println("Light Level"); display.setCursor(0,12); display.println(sensor.getAmbientLight(GAIN_1)); //Get Distance and report in mm Serial.print("Distance measured (mm) = "); Serial.println(sensor.getDistance()); display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(0, 24); display.println("Distance(mm)="); display.setCursor(0, 36); b = sensor.getDistance(); display.println(b); display.display(); delay(500); } After uploading the program, open the serial monitor and it should show the output as shown below. range finders are used in smartphones, portable touchscreen devices, Tablet, laptop, gaming devices and Domestic appliances/industrial devices. . Code #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_PCD8544.h> #include <Wire.h> #include <SparkFun_VL6180X.h> #define VL6180X_ADDRESS 0x29 VL6180x sensor(VL6180X_ADDRESS); Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 7, 6); float b; void setup() { Serial.begin(115200); //Start Serial at 115200bps Wire.begin(); //Start I2C library delay(100); // delay . if (sensor.VL6180xInit() != 0) { Serial.println("FAILED TO INITALIZE"); //Initialize device and check for errors }; sensor.VL6180xDefautSettings(); //Load default settings to get started. delay(1000); // delay 1s display.begin(); // init done // you can change the contrast around to adapt the display // for the best viewing! display.setContrast(50); display.display(); // show splashscreen display.clearDisplay(); } void loop() { display.clearDisplay(); //Get Ambient Light level and report in LUX Serial.print("Ambient Light Level (Lux) = "); Serial.println(sensor.getAmbientLight(GAIN_1)); display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(0,0 ); display.println("Light Level"); display.setCursor(0,12); display.println(sensor.getAmbientLight(GAIN_1)); //Get Distance and report in mm Serial.print("Distance measured (mm) = "); Serial.println(sensor.getDistance()); display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(0, 24); display.println("Distance(mm)="); display.setCursor(0, 36); b = sensor.getDistance(); display.println(b); display.display(); delay(500); } Video microcontroller-projects/ir-thermometer-using-arduino-and-ir-temperature-sensor

Make a Non-Contact Infrared Thermometer with MLX90614 IR Temperature Sensor

; hence it can not only be used to measure component temperatures but can also be used for measuring body temperature, surface temperature, Heat ventilation and much more. Of course, these thermal guns are readily available in the market from renowned manufacturers like Fluke, Flir etc. But they are not light on your pockets and on top of that what is more fun than building your own gadgets. So let’s get started‐󋈍

Materials Required

Arduino Pro Mini MLX90614 Infrared Temperature Sensor OLED Display ᾠSSD1306 Laser Diode 9V Battery Push button Battery Clip Connecting wires

MLX90614 Infrared Thermometer

below: Digital Thermometer using LM35 and Microcontroller IoT Digital Thermometer using NodeMCU and LM35 IoT Weather Station using NodeMCU: Monitoring Humidity, Temperature and Pressure over Internet Raspberry Pi Weather Station: Monitoring Humidity, Temperature and Pressure over Internet , follow the link. Operating Voltage: 3.6V to 5V Object Temperature Range: -70°C to 382.2°C Ambient Temperature Range: -40°C to 125°C Resolution/Accuracy: 0.02°C , for our sensor the field of view is about 80°. to know where the sensing area of the sensor is currently pointing at. I found that the values were reliable if the gun is pointed at 2cm away from the object and the accuracy goes down as we move away.

Arduino MLX90614 Thermometer Circuit Diagram

The circuit diagram for Infrared Thermometer is pretty simple. The complete circuit is shown below, it was created using Fritzing software. Since the Fritzing Software did not support a part for MLX90614 sensor we have used a note to mention its connections as shown above, also we have used a red colour LED in place of a laser diode. The entire circuit is powered by the 9V battery through a push button. When the push button is pressed the 9V battery is connected to the RAW pin of Arduino which is then regulated to 5V using the on-board voltage regulator. This 5V is then used to power the OLED module, Sensor and Laser diode. if you require the laser beam to be more powerful.

Designing the Casing for Temperature Gun

To make the project more interesting and practically usable we have 3D modeled and printed our outer casing for our thermal gun. The design involves two parts, one is the top part which acts as the body of the gun housing the Arduino controller, OLED, Sensor and the Laser diode. The other is the bottom part which acts as a handle of the gun housing the battery and push button. The Push button here acts as the trigger. The model looks like this below. The Design Files are available for download from thingiverse; you can download the design and print one using your 3D printer or also modify it to suit your needs. The download link is given below or can do some tweaks according to your requirements. The model was then saved as STL file and converted into G-code using Cura. I used my Tevo tarantula printer to print both my parts and then screwed them together. It is also possible to print both the parts as single piece if you printer supports it. The slicing setting for my print is shown below It took me nearly6 hours to print both the parts, once printed hardware connections was made my -directly soldering wires directly to the Arduino pins using 7-pin and 4-pin Relimate connectors (RMC) for the sensor and OLED display respectively. The OLED was then mounted in the printed part using screws while the sensor and Laser diode was mounted using hot glue. The power pins (Raw, Gnd) were then slid down through a wire for the handle part which consists of the push button and battery. This wires was then connected to the battery though the push button. The Once the assembly is done the thermal gun looked like this below You can proceed with designing a cover for the top part, but I decided to leave it open so that I can tweak it later in future if required.

Programming for Arduino MLX90614 Infrared Thermometer

The Library can be downloaded from below link Here the same program will be explained in small snippets. Here the Wire library (in-built) is used to communicate using I2C protocol and the SparkFunML90614 library is used to for communicating with the sensor. The SPI, GFX and SSD1306 libraries are used for communicating with 4-wire SPI protocol to the OLED display module. #include <Wire.h> #include <SparkFunMLX90614.h> #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> to which we have made the connection. Since the module works with SPI we have used the SPI pins of the Arduino. There are OLED displays that works with I2C protocol as well, but we can’t use them here since the I2C pins are already occupied by the thermometer sensor. #define OLED_MOSI 9 #define OLED_CLK 10 #define OLED_DC 11 #define OLED_CS 12 #define OLED_RESET 13 Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); if you need the values to be in Fahrenheit (F). Finally we initialize the OLED display and clear its display. Also the screen of OLED is rotated by 180 degree for easier mounting option in the casing. void setup() { Serial.begin(9600); therm.begin(); therm.setUnit(TEMP_C); display.begin(SSD1306_SWITCHCAPVCC); display.clearDisplay(); display.setRotation(2); } , we read the value of temperature from the sensor and convert it into String to be displayed in the OLED display. We have also printed the value on the serial monitor for debugging purpose. We have also incremented a variable called runner which is produce a small animation on the screen every time the value of the temperature sensor is updated successfully, this will help us know if the reading is stuck for some reason. if (therm.read()) // On success, read() will return 1, on fail 0. { temperature = String(therm.object(), 2); Serial.print("Object: "); Serial.print(temperature); Serial.println("C"); display.clearDisplay(); runner++; delay(5); }

Testing Arduino Thermal Gun

Once the Arduino code is ready we can upload it to our hardware using an external TTL programmer or FTDI board since the pro mini does not have one on-board. Then simply press the push button to trigger the thermal gun and you will notice the laser beam falling on the object and the temperature of the object being displayed on the OLED screen as shown below. Here I have used it to measure the temperature of a component as pointed by the laser beam. for more technical questions. Code /*********************************** Code for Arduino MLX90614 Contactless thermometer MLX90614 I2C connection OLED 4-wire SPI connection Dated: 7-6-2019 Code by: Aswint Raj **********************************/ #include <Wire.h> #include <SparkFunMLX90614.h> #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // If using software SPI (the default case): #define OLED_MOSI 9 #define OLED_CLK 10 #define OLED_DC 11 #define OLED_CS 12 #define OLED_RESET 13 Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); IRTherm therm; void setup() { Serial.begin(9600); therm.begin(); therm.setUnit(TEMP_C); display.begin(SSD1306_SWITCHCAPVCC); display.clearDisplay(); display.setRotation(2); } String temperature; char runner; void loop() { if (therm.read()) // On success, read() will return 1, on fail 0. { temperature = String(therm.object(), 2); Serial.print("Object: "); Serial.print(temperature); Serial.println("C"); display.clearDisplay(); runner++; delay(5); } display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(display.width()/4,display.height()/12); if (therm.object()>=100) display.setCursor(display.width()/4,display.height()/12); display.println(temperature); display.drawLine(display.width()/runner,display.height() - display.height()/2.5, display.width()/runner+1, display.height() - display.height()/2.5, WHITE); display.setCursor(0,display.height()-display.height()/4); display.setTextSize(1); display.println(" Arduino Thermlgun"); display.setCursor(display.width()- display.width()/4,display.height()/12); display.println("deg C"); display.display(); if (runner>20) runner=0; } Video microcontroller-projects/arduino-based-digital-protractor-using-mpu6050-gyroscope

DIY Arduino Digital Protractor using MPU6050 Gyroscope

Before going into details let's learn about Gyroscope sensor.

What is an Accelerometer and Gyroscopic sensor?

is used to measure the acceleration. It actually senses both the static and dynamic acceleration. For example, mobile phones use accelerometer sensor to sense that the mobile is on landscape mode or portrait mode. We previously used Accelerometer with Arduino to build many projects like: Ping Pong Game using Arduino and Accelerometer Arduino Based Vehicle Accident Alert System using GPS, GSM and Accelerometer Accelerometer Based Hand Gesture Controlled Robot using Arduino Earthquake Detector Alarm using Arduino is used to measure angular velocity that uses earth’s gravity to determine the orientation of the object in motion. Angular velocity is the rate of change of angular position of a rotating body. For example, todays mobiles use gyroscopic sensors to play mobile games according to the orientation of the mobile phone. Also, VR headset uses gyroscope sensor to have views in 360 orientation , accelerometer and gyroscope are present on a single PCB to find the orientation, position and velocity. Used in Drones for direction control Self-balancing robots Robotic arm control Tilt sensor Used in Mobile phones, Video game consoles Humanoid Robots Used in Aircraft, Automotive etc.

MPU6050 Accelerometer and Gyroscopic Sensor Module

) which consists of a 3-axis Accelerometer and 3-axis Gyroscope inside it. It also has temperature sensor. It can measure: Acceleration Velocity Orientation Displacement Temperature inside it which is powerful enough to perform complex calculation and thus free up the work for Microcontroller. can be interfaced to a Microcontroller using the AD0 pin. Power Supply: 3-5V Communication: I2C protocol Built-in 16-bit ADC provides high accuracy Built-in DMP provides high computational power Can be used to interface with other IIC devices like magnetometer Configurable IIC Address In-built Temperature sensor
Pin NumberPin NameUse
1VccProvides power for the module, can be +3V to +5V. Typically +5V is used
2GroundConnected to Ground of system
3Serial Clock (SCL)Used for providing clock pulse for I2C Communication
4Serial Data (SDA)Used for transferring Data through I2C communication
5Auxiliary Serial Data (XDA)Can be used to interface other I2C modules with MPU6050. It is optional
6Auxiliary Serial Clock (XCL)Can be used to interface other I2C modules with MPU6050. It is optional
7AD0If more than one MPU6050 is used a single MCU, then this pin can be used to vary the address
8Interrupt (INT)Interrupt pin to indicate that data is available for MCU to read.

Components Required

Arduino UNO MPU6050 Gyroscope Module 16x2 LCD Display Potentiometer 10k SG90-Servo Motor Protractor Image

Circuit Diagram

is given below:
VCC+5V
GNDGND
SCLA5
SDAA4
RED (VCC)+5V
ORANGE (PWM)9
BROWN (GND)GND
VSSGND
VDD+5V
V0To Potentiometer Centre PIN For Controlling Contrast of the LCD
RS2
RWGND
E3
D44
D55
D66
D77
A+5V
KGND

Programming Explanation

is given at the end of this tutorial. and its shaft is projected on protractor image indicating the angle of the inclined MPU6050. Programming for this tutorial is simple. Let’s see it in detail. First include all the required libraries - Servo Motor library for using Servo, LCD library for using LCD and Wire library for using I2C communication. and displayed the x,y,z coordinate values on 16x2 LCD. #include <Servo.h> #include <LiquidCrystal.h> #include <Wire.h> Next define LCD display pins RS, E, D4, D5, D6, D7 that are connected with Arduino UNO. LiquidCrystal lcd(2,3,4,5,6,7); Next the I2C address of the MPU6050 is defined. const int MPU_addr=0x68; object for using Servo class and three variables to store X, Y and Z axis values. Servo myservo; int16_t axis_X,axis_Y,axis_Z; Next minimum and maximum value is set as 265 and 402 for measuring angle from 0 to 360. int minVal=265; int maxVal=402; function first I2C communication is started and transmission has begun with MPU6050 with address of 0x68. Wire.begin(); Wire.beginTransmission(MPU_addr); Put the MPU6050 in Sleep Mode by writing 0x6B and then awake the it by writing 0 Wire.write(0x6B); Wire.write(0); After making MPU6050 active, end the transmission Wire.endTransmission(true); Here the PWM pin of Servo motor is connected with Arduino UNO pin 9. myservo.attach(9); As soon as we power up the circuit the LCD displays a welcome message and clear it after 3 seconds lcd.begin(16,2); //Sets LCD in 16X2 Mode lcd.print("CIRCUIT DIGEST"); delay(1000); lcd.clear(); lcd.setCursor(0,0); lcd.print("Arduino"); lcd.setCursor(0,1); lcd.print("MPU6050"); delay(3000); lcd.clear(); Again, the I2C communication is begun with MPU6050. Wire.beginTransmission(MPU_addr); Then start with register 0x3B (ACCEL_XOUT_H) Wire.write(0x3B); Now the process is restarted by set end transmission as false but the connection is active. Wire.endTransmission(false); After that now request the data from the 14 registers. Wire.requestFrom(MPU_addr,14,true); Now respected axis register values (x, y, z) are obtained and stored in variables axis_X,axis_Y,axis_Z. axis_X=Wire.read()<<8|Wire.read(); axis_Y=Wire.read()<<8|Wire.read(); axis_Z=Wire.read()<<8|Wire.read(); Then map those values from 265 to 402 as -90 to 90. This is done for all the three axes. int xAng = map(axis_X,minVal,maxVal,-90,90); int yAng = map(axis_Y,minVal,maxVal,-90,90); int zAng = map(axis_Z,minVal,maxVal,-90,90); Formula to calculate x value in degree (0 to 360) is given below. Here we convert only x because the servo motor rotation is based on x value movement. x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI); X angle value, from 0 to 360 deg, is converted into 0 to 180. int pos = map(x,0,180,0,180); Then write the angle value to rotate the servo on protractor image and Print those values on the 16x2 LCD display. myservo.write(pos); lcd.setCursor(0,0); lcd.print("Angle"); lcd.setCursor(0,1); lcd.print(x); delay(500); lcd.clear(); Complete code and video for this project is given below. Code #include <Servo.h> //Include Servo Motor library for using Servo #include <LiquidCrystal.h> //Include LCD library for using LCD #include <Wire.h> //Include WIre library for using I2C LiquidCrystal lcd(2,3,4,5,6,7); //Define LCD display pins RS,E,D4,D5,D6,D7 const int MPU_addr=0x68; //I2C MPU6050 Address Servo myservo; //myservo object for class servo int16_t axis_X,axis_Y,axis_Z; int minVal=265; int maxVal=402; double x; double y; double z; int pos = 0; void setup() { Wire.begin(); //Begins I2C communication Wire.beginTransmission(MPU_addr); //Begins Transmission with MPU6050 Wire.write(0x6B); //Puts MPU6050 in Sleep Mode Wire.write(0); //Puts MPU6050 in power mode Wire.endTransmission(true); //Ends Trasmission myservo.attach(9); //Servo PWM pin as 9 in UNO lcd.begin(16,2); //Sets LCD in 16X2 Mode lcd.print("CIRCUIT DIGEST"); delay(1000); lcd.clear(); lcd.setCursor(0,0); lcd.print("Arduino"); lcd.setCursor(0,1); lcd.print("MPU6050"); delay(2000); lcd.clear(); } void loop() { Wire.beginTransmission(MPU_addr); //Begins I2C transmission Wire.write(0x3B); //Start with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU_addr,14,true); //Request 14 Registers from MPU6050 axis_X=Wire.read()<<8|Wire.read(); //Obtain 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) axis_Y=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_YOUT_H) & 0x3C (ACCEL_YOUT_L) axis_Z=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_ZOUT_H) & 0x3C (ACCEL_ZOUT_L) int xAng = map(axis_X,minVal,maxVal,-90,90); int yAng = map(axis_Y,minVal,maxVal,-90,90); int zAng = map(axis_Z,minVal,maxVal,-90,90); x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI); //Formula to calculate x values in degree int pos = map(x,0,180,0,180); // As X value is from 0 to 360 deg myservo.write(pos); // Write angle obtained 0 to 180 to servo lcd.setCursor(0,0); lcd.print("Angle"); lcd.setCursor(0,1); lcd.print(x); delay(500); lcd.clear(); } Video microcontroller-projects/lora-based-gps-tracker-using-arduino-and-lora-shield

Lora Based GPS Tracker using Arduino and LoRa Shield

before proceeding further. which is legal ISM band here, hence you might have to select a module based on your country. That being said, let’s get started‐󋈍

Materials Required

Arduino Lora Shield ᾠ2Nos (PCB design available for download) Arduino Uno ᾠ2Nos SX1278 433MHz LoRa Module ᾠ2 433MHz Lora Antenna NEO-6M GPS Module LCD Display Module Connecting wires

Arduino LoRa Shield

is given below .

Fabricating PCB for LoRa Shield

Now that our circuit is ready, we can proceed with designing our PCB. I opened by PCB design software and began forming my tracks. Once the PCB design was complete my board looked something like this shown below You can also download the design files in GERBER format and fabricate it to get your boards. The Gerber file link is given below Now, that our Design is ready it is time to get them fabricated. To get thePCB done is quite easy, simply follow the steps below , sign up if this is your first time. Then, in the PCB Prototype tab enter the dimensions of your PCB, the number of layers and the number of PCB you require. Assuming the PCB is 80cm×80cm you can set the dimensions as shown below. button. You will be taken to a page where to set few additional parameters if required like the material used track spacing etc. But mostly the default values will work fine. The only thing that we have to consider here is the price and time. As you can see the Build Time is only 2-3 days and it just costs only $5 for our PSB. You can then select a preferred shipping method based on your requirement. verifies if your Gerber file is valid before proceeding with the payment. This way you can sure that your PCB is fabrication friendly and will reach you as committed.

Assembling the PCB

After the board was ordered, it reached me after some days though courier in a neatly labeled well-packed box and like always the quality of the PCB was awesome. I turned on my soldering rod and started assembling the Board. Since the Footprints, pads, vias and silkscreen are perfectly of the right shape and size I had no problem assembling the board. Once the soldering was complete the board looked like this below, as you can see it fits snug on my Arduino Uno Board. we will need two shields one for receiver and the other for transmitter. So I proceeded with soldering another PCB, both the PCB with LoRa module and LCD is shown below. As you can see only the receiver LoRa shied (left one) has an LCD connected it, the transmitter side only consists of the LoRa module. We will further connect a GPS module to the transmitter side as discussed below.

Connecting GPS module to LoRa Transmitter

The module operates in 5V and communicates using Serial communication at 9600 baud rate. Hence we power the module to +5V pin of Arduino and connect the Rx and Tx pin to digital pin D4 and D3 respectively as shown below , follow the link. This data will be large and most time we have to phrase it manually to obtain the desired result. Lucky for us there is a library called TinyGPS++ which does all the heavy lifting for us. You also have to add the LoRa library if you have not done it yet. So let’s download both the library from below link library. Once you are ready with the hardware and library we can proceed with Programming our Arduino boards.

Programming Arduino LoRa as GPS Transmitter

Make sure you have installed the libraries for GPS module and LoRa module before proceeding with the code. In this section we will look at the transmitter code. Like always we begin the program by adding the required libraries and pins. Here the SPI and LoRa library is used for LoRa communication and the TinyGPS++ and SoftwareSerial library is used for GPS communication. The GPS module in my hardware is connected to pin 3 and 4 and hence we also define that as follows #include <SPI.h> #include <LoRa.h> #include <TinyGPS++.h> #include <SoftwareSerial.h> // Choose two Arduino pins to use for software serial int RXPin = 3; int TXPin = 4; ᾠfor communication with our NEO-6M GPS module. Also note that I have used 433E6 (433 MHz) as my LoRa operating frequency you might have to change it based on the type of module you are using. void setup() { Serial.begin(9600); gpsSerial.begin(9600); while (!Serial); Serial.println("LoRa Sender"); if (!LoRa.begin(433E6)) { Serial.println("Starting LoRa failed!"); while (1); } LoRa.setTxPower(20); } function. while (gpsSerial.available() > 0) if (gps.encode(gpsSerial.read())) if (gps.location.isValid()) { gives the longitude co-ordinate. Since we will be printing them on the 16*2 LCD we have to mention when to shit to second line, hence we use the keyword “cᾠto intimate the receiver to print the following information on line 2. LoRa.beginPacket(); LoRa.print("Lat: "); LoRa.print(gps.location.lat(), 6); LoRa.print("c"); LoRa.print("Long: "); LoRa.print(gps.location.lng(), 6); Serial.println("Sent via LoRa"); LoRa.endPacket();

Programming Arduino LoRa as GPS receiver

The transmitter code is already sending the value of latitude and longitude co-ordinates, now the receiver has to read these values and print on the LCD. Similarly here we add the library for LoRa module and LCD display and define to which pins the LCD is connected to and also initialize the LoRa module like before. #include <SPI.h> //SPI Library #include <LoRa.h> //LoRa Library #include <LiquidCrystal.h> //Library for LCD const int rs = 8, en = 7, d4 = 6, d5 = 5, d6 = 4, d7 = 3; //Mention the pin number for LCD connection LiquidCrystal lcd(rs, en, d4, d5, d6, d7);//Initialize LCD method void setup() { Serial.begin(9600); //Serial for Debugging lcd.begin(16, 2); //Initialise 16*2 LCD lcd.print("Arduino LoRa"); //Intro Message line 1 lcd.setCursor(0, 1); lcd.print("Receiver"); //Intro Message line 2 delay(2000); if (!LoRa.begin(433E6)) { //Operate on 433MHz Serial.println("Starting LoRa failed!"); lcd.print("LoRa Failed"); while (1); } } ᾠvariable. If packets are received then we proceed with reading them as characters and print them on the LCD. The program also checks if the LoRa module is sending the keyword “cᾬ if yes then prints the remaining information on the second line. if (packetSize) { // If packet received Serial.print("Received packet '"); lcd.clear(); while (LoRa.available()) { char incoming = (char)LoRa.read(); if (incoming == 'c') { lcd.setCursor(0, 1); } else { lcd.print(incoming); } }

Arduino LoRa GPS Tracker Working

Once the hardware and program is ready we can upload both the codes in the respective Arduino modules and power them using a 12V adapter or USB cable. When the Transmitter is powered you can notice the blue LED on the GPS module blinking, this indicates that the module is looking for satellite connection to get co-ordinates. Meanwhile the Receiver module will power on and display a welcome message on the LCD screen. Once the transmitter sends the information the receiver module will display it on its LCD as shown below to get the location on map as shown below. for other technical queries. Code #include <SPI.h> #include <LoRa.h> #include <TinyGPS++.h> #include <SoftwareSerial.h> // Choose two Arduino pins to use for software serial int RXPin = 3; int TXPin = 4; // Create a TinyGPS++ object TinyGPSPlus gps; SoftwareSerial gpsSerial(RXPin, TXPin); void setup() { Serial.begin(9600); gpsSerial.begin(9600); while (!Serial); Serial.println("LoRa Sender"); if (!LoRa.begin(433E6)) { Serial.println("Starting LoRa failed!"); while (1); } LoRa.setTxPower(20); } void loop() { while (gpsSerial.available() > 0) if (gps.encode(gpsSerial.read())) if (gps.location.isValid()) { Serial.println("Sending to LoRa"); LoRa.beginPacket(); LoRa.print("Lat: "); LoRa.print(gps.location.lat(), 6); LoRa.print("c"); LoRa.print("Long: "); LoRa.print(gps.location.lng(), 6); Serial.println("Sent via LoRa"); LoRa.endPacket(); } } /*Program to receive the value of temperature and Humidity via LoRa and prin on LCD *Dated: 24-06-2019 *For: www.circuitdigest.com */ #include <SPI.h> //SPI Library #include <LoRa.h> //LoRa Library #include <LiquidCrystal.h> //Library for LCD const int rs = 8, en = 7, d4 = 6, d5 = 5, d6 = 4, d7 = 3; //Mention the pin number for LCD connection LiquidCrystal lcd(rs, en, d4, d5, d6, d7);//Initialize LCD method void setup() { Serial.begin(9600); //Serial for Debugging lcd.begin(16, 2); //Initialise 16*2 LCD lcd.print("Arduino LoRa"); //Intro Message line 1 lcd.setCursor(0, 1); lcd.print("Receiver"); //Intro Message line 2 delay(2000); if (!LoRa.begin(433E6)) { //Operate on 433MHz Serial.println("Starting LoRa failed!"); lcd.print("LoRa Failed"); while (1); } } void loop() { int packetSize = LoRa.parsePacket(); if (packetSize) { // If packet received Serial.print("Received packet '"); lcd.clear(); while (LoRa.available()) { char incoming = (char)LoRa.read(); if (incoming == 'c') { lcd.setCursor(0, 1); } else { lcd.print(incoming); } } } } Video microcontroller-projects/arduino-based-text-to-speech-converter

Arduino based Text to Speech (TTS) Converter

converts normal text into Speech. This tech enables the system to speak out the text in a human voice. There are many examples of Text to Speech conversions like the announcements at public transport, the customer care calls, voice assistants in your smartphones, or the navigation menu of any machine. You can even find the TTS in Microsoft Word where you set it to speak out the text written in the document. by using Google voice keyboard. This step involves the conversion of the symbols, numbers and abbreviationsinto words that can be read by the machines like ᾿ᾠwill be converted into “question markᾮ The phonemes are the small parts of spoken words i.e. these are the sounds that make sentences. This step is really essential so that machine can speak the words as humans do. This step can be achieved by different methods like by recording the human voice for different words/phrases or by generating basic sound frequencies and pile them up as phonemes or by copying human speaking mechanism.

Required Components

Arduino board A speaker An Amplifier Circuit Regulated Power Supply Connecting Wires

Circuit Diagram

Circuit diagram for it is shown below: If you don’t have the exact value of resistors and capacitors then use the close value ones.

Connecting Speaker to Arduino

The connections are super easy once you make the amplifier circuit. Connect the power supply to the amplifier circuit and connect the digital pin 3 of your Arduino to 10K resistor and connect the ground of Arduino to ground of the circuit. Now connect the speaker by connecting its negative terminal to ground and positive terminal to the 220μF capacitor and connect the power supply.

Programming Arduino for TTS (Text To Speech)

Now the Library Manager will be on your screen. In the search bar type Talkie and click on the install button. The library will get installed. This library is very handy and it has over 1000 words and commands. It has several examples, you can try them all but here we are using a simple code to explain the working. etc. You can also try them out. is used to use the pause we are using. #include "Talkie.h" #include "Vocab_US_Large.h" #include "Vocab_Special.h" Now define an object ‘valueᾠto use the commands: Talkie voice; is to take a short pause while repeating the alert message. And the next commands are just simple words that imply: DANGER DANGER STORM IN THE NORTH. void setup() { } void loop() { voice.say(spPAUSE2); voice.say(sp2_DANGER); voice.say(sp2_DANGER); voice.say(sp3_STORM); voice.say(sp3_IN); voice.say(sp3_THE); voice.say(sp3_NORTH); } Finally upload the code in the Arduino and connect the power supply to it. As soon as you power up the circuit you will start hearing the alerts! If you don’t get a clear sound then try adjusting the knob of pot or check if the Arduino is getting proper power supply and make sure that the GND of Arduino is connected to ground of the circuit. are given below. Code #include "Talkie.h" #include "Vocab_US_Large.h" #include "Vocab_Special.h" Talkie voice; void setup() { } void loop() { voice.say(spPAUSE2); voice.say(sp2_DANGER); voice.say(sp2_DANGER); voice.say(sp3_STORM); voice.say(sp3_IN); voice.say(sp3_THE); voice.say(sp3_NORTH); } Video microcontroller-projects/diy-gesture-controlled-arduino-air-mouse-using-accelerometer

DIY Gesture Controlled Arduino Based Air Mouse using Accelerometer

Ever wondered how our world is moving towards the immersive reality. We are continuously finding new ways and methods to interact with our surrounding using virtual reality, mixed reality, augmented reality etc. New devices are coming out every day with these fast pacing technologies to impress us by their new interactive technologies. , this will give you a complete idea of how this technology works. to interact with systems just by moving the console in the air, but instead of using 3-dimensional coordinate references, we are only going to use 2-dimensional coordinate references so we can imitate the actions of the computer mouse since the mouse works in two dimensions X and Y. is very simple, we will use an accelerometer to get the value of the acceleration of the actions and motions of the “Air mouseᾠalong the x and y-axis, and then based on the values of the accelerometer we will control the mouse cursor and perform certain actions with the help of the python software drivers running on computer.

Pre-requisites

Arduino Nano (any model) Accelerometer ADXL335 Module Bluetooth HC-05 Module Push buttons Python Installed computer

Circuit Diagram

you need an accelerometer that gives out the acceleration along the X and Y-axis and to make the whole system wireless a Bluetooth module is used to transfer the signal wirelessly to your system. with our previous projects: Arduino Based Vehicle Accident Alert System using GPS, GSM and Accelerometer Ping Pong Game using Arduino and Accelerometer Accelerometer Based Hand Gesture Controlled Robot using Arduino Earthquake Detector Alarm using Arduino using different microcontrollers including Arduino. Here we have used three push buttons - one for triggering the Air mouse, and other two for left and right click as shown in the belowimage:

Process Flow for the Air Mouse

The flow chart shows the process flow of Arduino based Air Mouse: 1. The system continuously checks for the mechanical trigger to be pressed until it is not pressed we can work out normally with the computers mouse. 2. When the system detects button press, the control for the mouse transferred to the air mouse. 3. As the trigger button is pressed the system starts to transfer the readings of the mouse to the computer. The system reading consists of the accelerometer readings, and the readings for the left and right click. 4. The system readings consist of the data stream of 1 byte or 8 bits, in which the first three bits consist of the X-coordinates, second three bits consist of the Y-coordinates, the second last bit is the status bit for getting the status of the left click of the mouse and the last bit is the status bit for getting the status of the right click. 5. The value of the first three bits i.e. X-coordinate can range from 100<=Xcord<=999, whereas the value for the Y-coordinate can range from the 100<=Ycord<=800. The values for the right click and left click are the binary values either 0 or 1 in which 1 indicates the click is made and 0 that click is not made by the user. affect the position of the cursor a known delay of 4 seconds is kept after every click of the trigger button of the mouse. 7. For the right and left click in the air mouse, we have to first press either left or right pushbutton, and after that, we have to press the trigger button to move to the position of the air mouse where we want.

Programming the Arduino for Air Mouse

is given at the end, below are the important snippets from the code. As previously said we will hook up the Bluetooth module with the software serial pins. So to set the software serial we need to declare the library of software serial and set up the pins for Tx and Rx. In Arduino Nano and Uno Pin 2 and 3 can work as a software serial. Next, we declare the Bluetooth object from the software serial library to set up the pin for the Tx and Rx. #include <SoftwareSerial.h> const int rxpin = 2, txpin = 3; SoftwareSerial bluetooth(rxpin, txpin); const int x=A0; const int y=A1; int xh, yh; int xcord, ycord; const int trigger = 5; int lstate = 0; int rstate = 0; const int lclick = 6; const int rclick = 7; const int led = 8; function, we are going to set the variables to tell the program whether they will act as input or output. The trigger button would be set up as input pull-up, and the left and right clicks are declared as input and set up as High to make them act as input pullups. Also set the baud rate for the serial and Bluetooth communication to 9600. void setup() { pinMode(x,INPUT); pinMode(y,INPUT); pinMode(trigger,INPUT_PULLUP) pinMode(lclick,INPUT); pinMode(rclick,INPUT); pinMode(led, OUTPUT); digitalWrite(lclick,HIGH); digitalWrite(rclick,HIGH); Serial.begin(9600); bluetooth.begin(9600); } loop which will continuously monitor the digital state of the pull-up trigger, as it goes low it will pass it further for the processing. whose values initially were set up to 0. , set the value of those variables according to the digital status of the left and right click button to check whether the buttons are pressed or not. function and would map those values to the screen size to get the mouse pointer moving across the whole screen. Since the screen size is the pixels in the screen, we need to set it up accordingly and as we need the output value to be three digits we have deliberately set up the range for the X as 100<=X<=999 and similarly the value for the Y as 100<=Y<=800. Remember, the pixels are being read from the top left corner i.e. the top left corner has the value (0,0), but since we have declared three digits for the x and y our values would be read from the point (100,100). functions they help in getting the values on serial monitor and over your system via Bluetooth. At last, due to the bouncing of a button a single value may be repeated which would cause a mouse cursor to linger over a single position, so to get rid of this we have to add this delay. void loop() { digitalWrite(led,LOW); while(digitalRead(trigger)==LOW) { digitalWrite(led, HIGH); lstate = digitalRead(lclick); rstate = digitalRead(rclick); xh=analogRead(x); yh=analogRead(y); xcord=map(xh,286,429,100,999); ycord=map(yh,282,427,100,800); Serial.print(xcord); Serial.print(ycord); if (lstate == LOW) Serial.print(1); else Serial.print(0); if (rstate == LOW) Serial.print(1); else Serial.print(0); bluetooth.print(xcord); bluetooth.print(ycord); if (lstate == LOW) bluetooth.print(1); else bluetooth.print(0); if (rstate == LOW) bluetooth.print(1); else bluetooth.print(0); delay(4000); } }

Python Driver Script for Computer

is a scripting language and by scripting here we mean that it helps us to get the control of the other program, as here we are controlling the mouse cursor. So open your python shell and get the following libraries installed using below commands: pip install serial pip install pyautogui is library for python to get control over the GUI features, in this case, mouse. is operating at. For this you have to get connected the Bluetooth module to your system and then in system settings you have to check out which com port is it connected to. Next thing is to read the serial communication from the Bluetooth to the system and to keep it going continuously keep rest of code in a continuous loop with the help of while 1. and set up its length to 8 bits. Next, divide the bits for the cursor coordinates and clicks by slicing them over, and then further slice down the cursor bits into X and Y coordinates separately. Same goes for the left and right click. Now from the communication, we are getting a byte string and we need to convert it into an integer so that they can fit in for the coordinates, we do this by decoding them and then typecasting them into integers. function, which takes as arguments those integer coordinates and moves the cursor to that position. Next check for the clicks, we do this by using the last two bits and pyautogui's click function, its default click is left one, however we can set it into right by declaring button value to right, we can also define the number of clicks to set it off to a double click by setting up the clicks parameter to 2. : import serial import pyautogui ser=serial.Serial('com3',9600) while 1: k=ser.read(8) cursor=k[:6] click=k[6:] x=cursor[:3] y=cursor[3:] l=click[0] r=click[1] xcor=int(x.decode('utf-8')) ycor=int(y.decode('utf-8')) pyautogui.moveTo(xcor,ycor) if l==49: pyautogui.click(clicks=2) elif r==49: pyautogui.click(button='right', clicks=2)

Testing the Arduino Air Mouse

So for operating the Air Mouse attach a power source to it. It can be from the Arduino Nano USB slot or from the 5v regulated power supply using 7805 IC. Then run the python driver script by setting the com port that your Bluetooth is connected to. As the script runs you would see a time lag in the blinking of the Bluetooth it means it's connected to your system. Then for operating it click the trigger button and you would see the position of the coordinates would change and if you want the left or right click, then first press left or right pushbutton and trigger button together, you would see the action of the click at a changed location of the cursor. below. Code import serial import pyautogui ser=serial.Serial('com3',9600) while 1: k=ser.read(8) cursor=k[:6] click=k[6:] x=cursor[:3] y=cursor[3:] l=click[0] r=click[1] xcor=int(x.decode('utf-8')) ycor=int(y.decode('utf-8')) pyautogui.moveTo(xcor,ycor) if l==49: pyautogui.click(clicks=2) elif r==49: pyautogui.click(button='right', clicks=2) #include <SoftwareSerial.h> const int rxpin = 2, txpin = 3; SoftwareSerial bluetooth(rxpin, txpin); const int x=A0; const int y=A1; int xh, yh; int xcord, ycord; const int trigger = 5; int lstate = 0; int rstate = 0; const int lclick = 6; const int rclick = 7; const int led = 8; void setup() { pinMode(x,INPUT); pinMode(y,INPUT); pinMode(trigger,INPUT_PULLUP); pinMode(lclick,INPUT); pinMode(rclick,INPUT); pinMode(led, OUTPUT); digitalWrite(lclick,HIGH); digitalWrite(rclick,HIGH); Serial.begin(9600); bluetooth.begin(9600); } void loop() { digitalWrite(led,LOW); while(digitalRead(trigger)==LOW) { digitalWrite(led, HIGH); lstate = digitalRead(lclick); rstate = digitalRead(rclick); xh=analogRead(x); yh=analogRead(y); xcord=map(xh,286,429,100,999); ycord=map(yh,282,427,100,800); Serial.print(xcord); Serial.print(ycord); if (lstate == LOW) Serial.print(1); else Serial.print(0); if (rstate == LOW) Serial.print(1); else Serial.print(0); bluetooth.print(xcord); bluetooth.print(ycord); if (lstate == LOW) bluetooth.print(1); else bluetooth.print(0); if (rstate == LOW) bluetooth.print(1); else bluetooth.print(0); delay(4000); } } Python driver script import serial import pyautogui ser=serial.Serial('com3',9600) while 1: k=ser.read(8) cursor=k[:6] click=k[6:] x=cursor[:3] y=cursor[3:] l=click[0] r=click[1] xcor=int(x.decode('utf-8')) ycor=int(y.decode('utf-8')) pyautogui.moveTo(xcor,ycor) if l==49: pyautogui.click(clicks=2) elif r==49: pyautogui.click(button='right', clicks=2) Video microcontroller-projects/how-to-flash-the-firmware-on-cloned-hm-10-ble-module-using-arduino-uno

How to Flash the Firmware on Clone HM-10 BLE Module using Arduino Uno

What is a Cloned HM-10 Module?

Cloned HM-10 modules are similar to the Genuine HM-10 module. But to save the extra cost while manufacturing, the manufacturers removed the external oscillator and leaves the space for the External Oscillator. The manufacture used the internal oscialltor of HM-10 module for saving the cost. Also, the firmware is different than the genuine HM-10 module. Chinese manufacturer Jinan Huamao Technology is developer of the board and the firmware. The Manufacturer has stated on the official documentation that there are several clones available in the market.

How to distinguish between Genuine and Clone HM10 BLE Modules

, there are some points to do that. else it is the Chinese Cloned HM10. 2. The second way to find is by connecting the HM10 with any Serial Module and sending AT commands. If the HM-10 doesn’t reply to AT commands, then it is a Cloned HM-10 module.

How to change or Flash the firmware of Clone HM-10 BLE Module

In order to change the firmware, we really need a good hand on soldering. Once you change the firmware of the HM10 module. You will be able to access all its functions. There are two methods to flash the cloned HM10 module: 1.The first method includes the SmartRF Flash Programmer from Texas Instruments. 2. And the second method includes the Arduino as programmer for HM-10. So lets start the steps in Flashing the HM-10 module using Arduino UNO as Programmer. As said earlier, the soldering will be required to connect HM-10 with Arduino. We need to solder the wires to the DEBUG_CLOCK, DEBUG_DATA, RESET_N pins of HM-10. Then complete procedure is explained in next sections.

Components Required

Arduino (UNO, Pro Mini) USB to TTL converter for connect Arduino to the PC (in case of arduino pro mini or similar) CC2541 board: HM-10, CC41 Some Jumper Wires Soldering Iron (To solder the wire to HM-10 Board) Arduino IDE CCLoader Arduino Sketch CCloader Windows Program HM-10 Firmware (Extract the Zip file)

HM-10 Pin Out

Circuit Diagram

Steps to Update Firmware in HM10 Bluetooth Module using Arduino Uno

(.bin file, CCloaderArduino.ino, CCLoader.exe) related to flash the firmware. Open the sketch with Arduino IDE Setup the baud rate, Board, COM Port, Programmer etc. Compile and Upload the sketch to the UNO Board. after soldering the wires on HM-10 board:
DEBUG_CLOCKPin 7Pin 5
DEBUG_DATAPin 8Pin 6
RESET_NPin 11Pin 4
GNDPin 13GND
3.3 VPin 12V
). The CC2541hm10v540.bin file need to be extracted as it will be downloaded in Zip format. 5. Write and execute the command in format like : CCLoader.exe <COM Port> <Firmware.bin> 0 Replace the COM Port with your COM Port number (e.g 2,3,4,5). Don’t write COM5 or COM4 just write the Number of Port. Also replace the Firmware.bin file excluding <> signs with your’s file name. Note that if you are using Arduino Uno then use ᾰᾠand if you are using other Arduino e.g. Micro then change 0 to 1 In my case the command looks like: C:\Users\Abhiemanyu Pandit\Desktop\HM10>CCloader.exe 4 CC2541hm10v540.bin 0 C:\Users\Abhiemanyu Pandit\Desktop\HM10>CCloader123.exe 5 CC2541.bin 0 You must put the Firmware.bin file in the same folder where CCloader is located. 6. After executing the above command the firmware will start uploading, just wait for it to finish. When it is finished the Command prompt will look like below. and the CC2541 is now have the genuine HM-10 Firmware. 7. Now if you want to upgrade or degrade the firmware then you need not follow these same steps again. Just Connect the HM-10 Module with a USB to TTL converter with Rx, Tx, Vcc, GND and do the Normal steps to upgrade firmware. Video microcontroller-projects/matlab-data-logging-analysis-and-visualization-plotting-dht11-sensor-readings-on-matlab

MATLAB Data Logging, Analysis and Visualization: Plotting DHT11 Sensor readings on MATLAB

MATLAB is one of the most popular software which can not only present the results in graphical format but also can be easily integrated with hardware and microcontrollers. If you are new to MATLAB you can check our previous MATLAB tutorials for better understating: Getting started with MATLAB: A Quick Introduction Interfacing Arduino with MATLAB - Blinking LED DC Motor Control Using MATLAB and Arduino Serial Communication between MATLAB and Arduino Getting Started with Image Processing using MATLAB

Components Required

MATLAB Installed Laptop (version above or R2016b) Arduino UNO DHT11 Temperature and Humidity Sensor

Circuit Diagram

Arduino Code for DHT11 interfacing with MATLAB

for logging and visualizing temperature and humidity data into MATLAB is given at the end. Let’s understand how the code is working. First include the library for DHT11 sensor which is ‘DHT.hᾮ #include <DHT.h> Then define the DHT11 data pin connected to the Arduino. In our case, it is pin number 4. #define DHTPIN 4 initialize the serial and the DHT11 sensor. void setup() { Serial.begin(9600); delay(2000); dht.begin(); // initialise DHT11 sensor } Then print these values on the serial monitor, so that the MATLAB will be able to read the values serially. void loop() { float temp = dht.readTemperature(); //read temperature data float humi = dht.readHumidity(); //read temperature data Serial.print(temp); Serial.print(humi); delay(2000); }

MATLAB Code for Logging and Plotting the Data

in MATLAB, as shown in the below image. for DHT11 sensor data logging is given at the end of the project. Start with defining a variable for the serial communication from MATLAB to Arduino. COM18 is the port at which my Arduino is connected, you can change accordingly. s = serial('COM18'); we are reading the temperature and humidity data respectively. fopen(s) out = fscanf(s) Temp(i)=str2num(out(1:4)); Humi(i)=str2num(out(5:9)); Now, after pasting the complete code into the editor window. Click on the ‘runᾠbutton to process the code, as shown in the below image. Wait until the MATLAB shows busy in the bottom left corner of the screen, as shown in the below image. This indicated that the MATLAB is processing the code. If the code executes without any error, the real-time graph window will appear on the screen, as shown below. Here, the data will update in every two seconds, as two seconds is the time taken by the DHT11 sensor to send the data to the serial port. , double click on the respective variable in the workspace window, as shown in the below image. . Code #include <DHT.h> #define DHTPIN 4 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); delay(2000); dht.begin(); // initialise DHT11 sensor } void loop() { float temp = dht.readTemperature(); //read temperature data float humi = dht.readHumidity(); //read temperature data Serial.print(temp); Serial.print(humi); delay(2000); } s = serial('COM18'); time=100; i=1; while(i<time) fopen(s) fprintf(s, 'Your serial data goes here') out = fscanf(s) Temp(i)=str2num(out(1:4)); subplot(211); plot(Temp,'g'); axis([0,time,20,50]); title('Parameter: DHT11 Temperature'); xlabel('---> time in x*0.02 sec'); ylabel('---> Temperature'); grid Humi(i)=str2num(out(5:9)); subplot(212); plot(Humi,'m'); axis([0,time,25,100]); title('Parameter: DHT11 Humidity'); xlabel('---> time in x*0.02 sec'); ylabel('---> % of Humidity '); grid fclose(s) i=i+1; drawnow; end delete(s) clear s Video microcontroller-projects/arduino-whistle-detector-switch

Arduino Whistle Detector Switch using Sound Sensor

is also a fun project to do.

Materials Required

Arduino UNO Sound Sensor Module Relay Module AC Lamp Connecting Wires Breadboard

Sound Sensor Working

, let’s take a look at the sound sensor. The sound sensor used in this module is shown below. The working principle of most sound sensors available in the market is similar to this, although the appearance might change a bit. Basically diaphragm inside the microphone vibrates to the sound waves in the atmosphere which produces electrical signal on its output pin. But these signals will be of very low magnitude (mV) and hence cannot be processed directly by a microcontroller like Arduino. Also by default sound signals are analog in nature hence the output from the microphone will be a sine wave with variable frequency, but microcontrollers are digital devices and hence work better with square wave.

Measuring Audio Frequency on Oscilloscope

This sound sensor module will convert the sound waves in the atmosphere into square waves who’s frequency will be equal to the frequency of the sound waves. So by measuring the frequency of the square wave we can find the frequency of the sound signals in the atmosphere. To make sure things are working as they are supposed I connected the sound sensor to my scope to probe its output signal as shown in the video below.

Whistle Detector Arduino Circuit Diagram

is show below. The circuit was drawn using Fritzing software. The Sound sensor and the Relay module is powered by the 5V pin of the Arduino. The output pin of the Sound sensor is connected to the digital pin 8 of the Arduino, this is because of the timer property of that pin and we will discuss more about this in the programming section. The Relay module is triggered by pin 13 which is also connected to the in-built LED on the UNO board. On the AC supply side the neutral wire is directly connected to the Common(C) pin of the Relay module while the Phase is connected to the Normally Open (NO) pin of the relay through the AC load (light bulb). This way when the relay is triggered the NO pin will be connected with C pin and thus the light bulb will glow. Else the blub will remain turned off. Once the connections are made, my hardware looked something like this. Working with AC circuit could get dangerous, be cautious while handling live wires and avoid short circuits. A circuit breaker or adult supervision is recommended for people who are not experienced with electronics. You have been warned!!

Measuring Frequency with Arduino

to measure frequency to get accurate results. This library uses the internal timer interrupt on pin 8 to measure how long a pulse stays ON. Once the time is measure we can calculate the frequency using the formulae F=1/T. However since we are using the library directly we need not get into the register details and math of how frequency is measured. Library can be downloaded from the link below: Frequency Measure Library by pjrc functionality on pin 9 and 10 on UNO since the timer will be occupied by this library. Also these pins will change if other boards are used.

Programming your Arduino for detecting Whistle

can be found at the bottom of this page. In this heading I will explain the program by breaking it into small snippets. library already as explained in above heading. The variable state represents the state of the LED and the variables frequency and continuity is used to output the measured frequency and its continuity respectively. #include <FreqMeasure.h>//https://github.com/PaulStoffregen/FreqMeasure double sum=0; int count=0; bool state = false; int frequency; int continuity =0; function to initialize the pin 8 for measuring the frequency. We also declare that pin 13 (LED_BUILTIN) is output. void setup() { Serial.begin(9600); FreqMeasure.begin(); //Measures on pin 8 by default pinMode(LED_BUILTIN, OUTPUT); } To avoid error due to noise we measure 100 samples and taken an average of that. The code to do the same is shown below. if (FreqMeasure.available()) { // average several reading together sum = sum + FreqMeasure.read(); count = count + 1; if (count > 100) { frequency = FreqMeasure.countToFrequency(sum / count); Serial.println(frequency); sum = 0; count = 0; } } function here to check the value of the frequency for your whistle. In my case the value received was from 1800Hz to 2000Hz. The whistle frequency of most people will fall in this particular range. But even other sounds like music or voice might fall under this frequency so to distinguish them we will monitor for continuity. If the frequency is continuous for 3 times then we confirm it to be a whistle sound. So, if the frequency is between 1800 to 2000 then we increment the variable called continuity. if (frequency>1800 && frequency<2000) { continuity++; Serial.print("Continuity -> "); Serial.println(continuity); frequency=0;} If the value of continuity reaches or exceeds three, then we change the state of the LED by toggling the variable called state. If the state is already true we change it to false and vise versa. if (continuity >=3 && state==false) {state = true; continuity=0; Serial.println("Light Turned ON"); delay(1000);} if (continuity >=3 && state==true) {state = false; continuity=0; Serial.println("Light Turned OFF"); delay(1000);}

Arduino Whistle Detector Working

Once the code and the hardware are ready we can start testing it. Make sure the connections are correct and power up the module. Open the serial monitor and start whistling, you can notice the value of continuity being incremented and finally turning on or off the Lamp. A sample snap shot of my serial monitor is shown below. for other technical quires. Code /*Arduino Whitsle Detector Switch Program * Detects the whistles from pin 8 and toggles pin 13 * Dated: 31-5-2019 * Website: www.circuitdigest.com */ #include <FreqMeasure.h>//https://github.com/PaulStoffregen/FreqMeasure void setup() { Serial.begin(9600); FreqMeasure.begin(); //Measures on pin 8 by default pinMode(LED_BUILTIN, OUTPUT); } double sum=0; int count=0; bool state = false; float frequency; int continuity =0; void loop() { if (FreqMeasure.available()) { // average several reading together sum = sum + FreqMeasure.read(); count = count + 1; if (count > 100) { frequency = FreqMeasure.countToFrequency(sum / count); Serial.println(frequency); sum = 0; count = 0; } } if (frequency>1800 && frequency<2000) { continuity++; Serial.print("Continuity -> "); Serial.println(continuity); frequency=0;} if (continuity >=3 && state==false) {state = true; continuity=0; Serial.println("Light Turned ON"); delay(1000);} if (continuity >=3 && state==true) {state = false; continuity=0; Serial.println("Light Turned OFF"); delay(1000);} digitalWrite(LED_BUILTIN, state); } Video microcontroller-projects/how-to-use-bh1750-ambient-light-sensor-with-arduino

How to Use BH1750 Ambient Light Sensor with Arduino

Introduction to BH1750 Digital Light Sensor Module

, which can be used to auto adjust the brightness of display in mobiles, LCD displays, or to turn on/off the headlights in cars based upon the outdoor lighting conditions. is shown below: (lx), so it does not require any further calculations. Lux is the unit to measure Light intensity. It measures the intensity according to the amount of light hitting on a particular area. One lux is equal to to one lumen per square meter. This sensor has a wide range and high resolution (1-65535lx) and in addition, the measurement variation is also small (about +/-20%). It can also work independently without any external component. can also be used to control the devices based on lighting conditions but its not that accurate. We have used LDR sensor to build many light controlled applications: Arduino Light Sensor Circuit using LDR Dark Detector using LDR and 555 Timer IC Simple LDR Circuit to Detect Light Arduino Color Mixing Lamp using RGB LED and LDR

Arduino BH1750 Ambient Light SensorCircuit Diagram

is shown below. C communication. As we know the operating voltage for the sensor is 3.3v so VCC and GND of BH1750 are connected to 3.3V and GND of Arduino. For LCD, data pins (D4-D7) are connected to digital pins D2-D5 of Arduino and RS and EN pins are connected to D6 and D7 of Arduino. V0 of LCD is connected to pot and a 10k pot is used to control the brightness of LCD.

Programming Arduino for interfacing BH1750 Light Sensor

is very easy. Although there is a library available for this sensor, but we can also use it without that. C protocol. #include<Wire.h> #include<LiquidCrystal.h> function, we’ve initialized both LCD and sensor and printed the opening message on LCD. void setup() { Wire.begin(); lcd.begin(16,2); lcd.print(" BH1750 Light "); lcd.setCursor(0,1); lcd.print("Intensity Sensor"); delay(2000); } function is used to read registers where 2 indicates the number of registers. function is used to go to the desired register by entering the address of that register in it. int BH1750_Read(int address) { int i=0; Wire.beginTransmission(address); Wire.requestFrom(address, 2); while(Wire.available()) { buff[i] = Wire.read(); i++; } Wire.endTransmission(); return i; } void BH1750_Init(int address) { Wire.beginTransmission(address); Wire.write(0x10); Wire.endTransmission(); } function returns the value of register count and we are reading only 2 registers. So when it reaches to 2, the program starts printing the LUX values of light intensity. Then a formula is used to get the values from both the registers and divide them by 1.2, which is the measurement accuracy. void loop() { int i; uint16_t value=0; BH1750_Init(BH1750address); delay(200); if(2==BH1750_Read(BH1750address)) { value=((buff[0]<<8)|buff[1])/1.2; lcd.clear(); lcd.print("Intensity in LUX"); lcd.setCursor(6,1); lcd.print(value); } delay(150); } below. Code #include<Wire.h> #include<LiquidCrystal.h> int BH1750address = 0x23; byte buff[2]; LiquidCrystal lcd (7,6,5,4,3,2); //RS, E, D4, D5, D6, D7 void setup() { Wire.begin(); //Serial.begin(9600); lcd.begin(16,2); lcd.print(" BH1750 Light "); lcd.setCursor(0,1); lcd.print("Intensity Sensor"); delay(2000); } void loop() { int i; uint16_t value=0; BH1750_Init(BH1750address); delay(200); if(2==BH1750_Read(BH1750address)) { value=((buff[0]<<8)|buff[1])/1.2; lcd.clear(); lcd.print("Intensity in LUX"); lcd.setCursor(6,1); lcd.print(value); //Serial.print(val); //Serial.println("[lux]"); } delay(150); } int BH1750_Read(int address) { int i=0; Wire.beginTransmission(address); Wire.requestFrom(address, 2); while(Wire.available()) { buff[i] = Wire.read(); i++; } Wire.endTransmission(); return i; } void BH1750_Init(int address) { Wire.beginTransmission(address); Wire.write(0x10); Wire.endTransmission(); } Video microcontroller-projects/rs-485-modbus-serial-communication-with-arduino-as-master