At sometime or another you may run out of pins on your Arduino board and need to extend it with shift registers. This example is based on the 74HC595. The datasheet refers to the 74HC595 as an “8-bit serial-in, serial or parallel-out shift register with output latches; 3-state.” In other words, you can use it to control 8 outputs at a time while only taking up a few pins on your microcontroller. You can link multiple registers together to extend your output even more.
In this lesson, we will show how to use the 74HC595 8-bit shift register with Osoyoo Uno boards.
Before I go through the circuit, let’s have a quick look at what the chip is doing, so that we can understand what the code has to do.
The first thing that should be cleared up is what “bits” are, for those of you who aren’t familiar with binary. When we refer to a “bit”, we are referring to one of the numbers that make up the binary value. Unlike normal numbers though, we typically consider the first bit to be the right most one. So, if we take the binary value 10100010, the first bit is actually 0, and the eighth bit is 1. It should also be noted, in case it wasn’t implied, each bit can only be 0 or 1.
The chip contains eight pins that we can use for output, each of which is associated with a bit in the register. In the case of the 74HC595 IC, we refer to these as QA through to QH. In order to write to these outputs via the Arduino, we have to send a binary value to the shift register, and from that number the shift register can figure out which outputs to use. For example, if we sent the binary value 10100010, the pins highlighted in green in the image below would be active and the ones highlighted in red would be inactive.
This means that the right most bit that we specify maps to QH, and the left most bit maps to QA. An output is considered active when the bit mapped to it is set to 1. It is important to remember this, as otherwise you will have a very hard time knowing which pins you are using!
The chip also has an OE (output enable) pin, this is used to enable or disable the outputs all at once. You could attach this to a PWM capable Arduino pin and use ‘analogWrite’ to control the brightness of the LEDs. This pin is active low, so we tie it to GND.
Now that we have a basic understanding of how we use bit shifting to specify which pins to use, we can begin hooking it up to our Arduino!
Arduino includes a special function called ‘shiftOut’ that is designed specifically for sending data to shift registers. Here is the full sketch, the discussion of how it works follows on from it.
Build the circuit as below:
It is probably easiest to put the 74HC595 chip in first, as pretty much everything else connects to it. Put it so that the little U-shaped notch is towards the top of the breadboard. Pin 1 of the chip is to the left of this notch.
All but one of the outputs from the ‘595 are on the left hand side of the chip, hence, for ease of connection, that is where the LEDs are too.
After the chip, put the resistors in place. You need to be careful that none of the leads of the resistors are touching each other. You should check this again, before you connect the power to your Arduino. If you find it difficult to arrange the resistors without their leads touching, then it helps to shorten the leads so that they are lying closer to the surface of the breadboard.Next, place the LEDs on the breadboard.
The longer positive LED leads must all be towards the chip, whichever side of the breadboard they are on.
It now just remains to attach the jumper leads as shown above. Do not forget the one that goes from pin 8 of the IC to the GND column of the breadboard.
Load up the sketch listed a bit later and try it out. Each LED should light in turn until all the LEDs are on, and then they all go off and the cycle repeats.
After above operations are completed, connect the Arduino board to your computer using the USB cable. The green power LED (labelled PWR) should go on. Load up the following sketch onto your Arduino.
int latchPin = 5; int clockPin = 6; int dataPin = 4; byte leds = 0; void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); } void loop() { leds = 0; updateShiftRegister(); delay(500); for (int i = 0; i < 8; i++) { bitSet(leds, i); updateShiftRegister(); delay(500); } } void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); }
The first thing we do is define the three pins we are going to use. These are the Arduino digital outputs that will be connected to the latch, clock and data pins of the 74HC595.
int latchPin = 5; int clockPin = 6; int dataPin = 4;
Next, a variable called ‘leds’ is defined. This will be used to hold the pattern of which LEDs are currently turned on or off. Data of type ‘byte’ represents numbers using eight bits. Each bit can be either on or off, so this is perfect for keeping track of which of our eight LEDs are on or off.
byte leds = 0;
The ‘setup’ function just sets the three pins we are using to be digital outputs.
void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); }
The ‘loop’ function initially turns all the LEDs off, by giving the variable ‘leds’ the value 0. It then calls ‘updateShiftRegister’ that will send the ‘leds’ pattern to the shift register so that all the LEDs turn off. We will deal with how ‘updateShiftRegister’ works later.
The loop function pauses for half a second and then begins to count from 0 to 7 using the ‘for’ loop and the variable ‘i’. Each time, it uses the Arduino function ‘bitSet’ to set the bit that controls that LED in the variable ‘leds’. It then also calls ‘updateShiftRegister’ so that the leds update to reflect what is in the variable ‘leds’.
There is then a half second delay before ‘i’ is incremented and the next LED is lit.
void loop() { leds = 0; updateShiftRegister(); delay(500); for (int i = 0; i < 8; i++) { bitSet(leds, i); updateShiftRegister(); delay(500); } }
The function ‘updateShiftRegister’, first of all sets the latchPin to low, then calls the Arduino function ‘shiftOut’ before putting the ‘latchPin’ high again. This takes four parameters, the first two are the pins to use for Data and Clock respectively.
The third parameter specifies which end of the data you want to start at. We are going to start with the right most bit, which is referred to as the ‘Least Significant Bit’ (LSB).
The last parameter is the actual data to be shifted into the shift register, which in this case is ‘leds’.
void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); }
If you wanted to turn one of the LEDs off rather than on, you would call a similar Arduino function (bitClear) on the ‘leds’ variable. This will set that bit of ‘leds’ to be 0 and you would then just need to follow it with a call to ‘updateShiftRegister’ to update the actual LEDs.
A few seconds after the upload finishes, each LED should light in turn until all the LEDs are on, and then they all go off and the cycle repeats.
One pin of the 74HC595 that I have not mentioned is a pin called ‘Output Enable’. This is pin 13 and on the breadboard, it is permanently connected to Ground. This pin acts as a switch, that can enable or disable the outputs – the only thing to watch for is it is ‘active low’ (connect to ground to enable). So, if it is connected to 5V, all the outputs go off. Whereas if it is connected to Ground, those outputs that are supposed to be on are on and those that should be off are off.
Build the circuit as below:
We can use this pin along with the ‘analogWrite’ function, to control the brightness of the LEDs using PWM.
To do this, all you need to do, is to change the connection to pin 13 of the 74HC595 so that instead of connecting it to Ground, you connect it to pin 3 of the Arduino.
Load the sketch below, will once all the LEDs have been lit gradually fade them back to off.
int latchPin = 5; int clockPin = 6; int dataPin = 4; int outputEnablePin = 3; byte leds = 0; void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(outputEnablePin, OUTPUT); } void loop() { setBrightness(255); leds = 0; updateShiftRegister(); delay(500); for (int i = 0; i < 8; i++) { bitSet(leds, i); updateShiftRegister(); delay(500); } for (byte b = 255; b > 0; b--) { setBrightness(b); delay(50); } } void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); } void setBrightness(byte brightness) // 0 to 255 { analogWrite(outputEnablePin, 255-brightness); }
If you’ve completed all these steps correctly you should have something similar to that in the gif below.
The digital temperature and humidity sensor DHT11 inside contains a chip that does analog to digital conversion and spits out a digital signal with the temperature and humidity, compatible with any MCUs, ideal for those who want some basic data logging stuffs. It’s very popular for electronics hobbyists because it is very cheap but still providing great performance.
In this lesson, we will first go into a little background about humidity, then we will explain how the DHT11 measures humidity. After that, we will show you how to connect the DHT11 to an Arduino and give you some example code so you can use the DHT11 in your own projects.
The DHT11 is a basic, ultra low-cost digital temperature and humidity sensor. It uses a capacitive humidity sensor and a thermistor to measure the surrounding air, and spits out a digital signal on the data pin (no analog input pins needed). Its fairly simple to use, but requires careful timing to grab data.
Only three pins are available for use: VCC, GND, and DATA. The communication process begins with the DATA line sending start signals to DHT11, and DHT11 receives the signals and returns an answer signal. Then the host receives the answer signal and begins to receive 40-bit humiture data (8-bit humidity integer + 8-bit humidity decimal + 8-bit temperature integer + 8-bit temperature decimal + 8-bit checksum).
The DHT11 measures relative humidity. Relative humidity is the amount of water vapor in air vs. the saturation point of water vapor in air. At the saturation point, water vapor starts to condense and accumulate on surfaces forming dew.
The saturation point changes with air temperature. Cold air can hold less water vapor before it becomes saturated, and hot air can hold more water vapor before it becomes saturated.
The formula to calculate relative humidity is:
Relative humidity is expressed as a percentage. At 100% RH, condensation occurs, and at 0% RH, the air is completely dry.
The DHT11 detects water vapor by measuring the electrical resistance between two electrodes. The humidity sensing component is a moisture holding substrate with electrodes applied to the surface. When water vapor is absorbed by the substrate, ions are released by the substrate which increases the conductivity between the electrodes. The change in resistance between the two electrodes is proportional to the relative humidity. Higher relative humidity decreases the resistance between the electrodes, while lower relative humidity increases the resistance between the electrodes.
The DHT11 measures temperature with a surface mounted NTC temperature sensor (thermistor) built into the unit.
With the plastic housing removed, you can see the electrodes applied to the substrate, an IC mounted on the back of the unit converts the resistance measurement to relative humidity. It also stores the calibration coefficients, and controls the data signal transmission between the DHT11 and the Arduino:
There are two different versions of the DHT11 you might come across. One type has four pins, and the other type has three pins and is mounted to a small PCB. The PCB mounted version is nice because it includes a surface mounted 10K Ohm pull up resistor for the signal line. Here are the pin outs for both versions:
Before you can use the DHT11 on the Arduino, you’ll need to install the DHT library. It has all the functions needed to get the humidity and temperature readings from the sensor. It’s easy to install, just download the DHT.zip file and open up the Arduino IDE. Then go to Sketch>Include Library>Add .ZIP Library and select the DHT.zip file.
Build the circuit as below:
Simply ignore pin 3 of DHT11, its not used. You will want to place a 10K resistor between VCC and the data pin, to act as a medium-strength pull up on the data line. The Arduino has built in pullups you can turn on but they’re very weak, about 20-50K
This diagram shows how we will connect for the testing sketch. Connect data to pin 3, you can change it later to any pin.
After above operations are completed, connect the Arduino board to your computer using the USB cable. The green power LED (labelled PWR) should go on. Load up the following sketch onto your Arduino.
#include<dht.h> dht DHT; // if you require to change the pin number, Edit the pin with your arduino pin. #define DHT11_PIN 3 void setup() { Serial.begin(9600); Serial.println("The real time Temperature and Humidity is :"); } void loop() { // READ DATA int chk = DHT.read11(DHT11_PIN); Serial.print(" Humidity: " ); Serial.print(DHT.humidity, 1); Serial.println('%'); Serial.print(" Temparature "); Serial.print(DHT.temperature, 1); Serial.println('C'); delay(2000); }
A few seconds after the upload finishes, open the Serial Monitor, you should now see the humidity and temperature readings displayed at one second intervals.
Note: Please make sure you have choosed the correct port and the correct baudrate for you project.
A nice way to display the humidity and temperature readings is on a 1I2C 1602LCD. To do this, first follow our tutorial on How to Set Up an LCD Display on an Arduino, then follow below operations and complete this project.
Build the circuit as below:
After above operations are completed, connect the Arduino board to your computer using the USB cable. The green power LED (labelled PWR) should go on.Open the Arduino IDE and choose corresponding board type and port type for you project. Then load up the following sketch onto your Arduino.
#include <Wire.h> #include <LiquidCrystal_I2C.h> #include <dht.h> dht DHT; LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display #define DHT11_PIN 3 void setup() { lcd.begin(16,2); lcd.init(); // initialize the lcd // Print a message to the LCD. lcd.backlight(); lcd.clear(); lcd.print("Humidity & temp"); delay(3000); lcd.clear(); lcd.print("Starting....."); delay(3000); } void loop() { // READ DATA int chk = DHT.read11(DHT11_PIN); lcd.clear(); delay(500); lcd.setCursor(0, 0); // print from 0 to 9: lcd.print("Temp: "); lcd.print(DHT.temperature, 1); lcd.print(" C"); // set the cursor to (16,1): lcd.setCursor(0,1); lcd.print("Humidity: "); lcd.print(DHT.humidity, 1); lcd.print(" %"); delay(2000); }
A few seconds after the upload finishes, you should now see the value of current humidity and temperature displayed on the LCD.
In this lesson,we will show how to use an active buzzer to make some noise.
Arduino IDE (version 1.6.4+)
As a type of electronic buzzer with integrated structure, buzzers, which are supplied by DC power, are widely used in computers, printers, photocopiers, alarms, electronic toys, automotive electronic devices, telephones, timers and other electronic products for voice devices. Buzzers can be categorized as active and passive ones (see the following picture). Turn the pins of two buzzers face up, and the one with a green circuit board is a passive buzzer, while the other enclosed with a black tape is an active one.
The difference between an active buzzer and a passive buzzer is:
An active buzzer has a built-in oscillating source, so it will make sounds when electrified. But a passive buzzer does not have such source, so it will not tweet if DC signals are used; instead, you need to use square waves whose frequency is between 2K and 5K to drive it. The active buzzer is often more expensive than the passive one because of multiple built-in oscillating circuits.In this lesson, we use the active buzzer.
Note:
The active buzzer has built-in oscillating source, so it will beep as long as it is electrified, but it can only beep with a fixed frequency.
In this part, the only thing on the breadboard is the active buzzer. One pin of the active buzzer goes to GND connection and the other to digital pin 12.Build the circuit as below:
After above operations are completed, connect the Arduino board to your computer using the USB cable. The green power LED (labelled PWR) should go on.
You can download the sketch from this link or copy below code to your Arduino IDE window:
int buzzer = 12;//the pin of the active buzzer
void setup() {
pinMode(buzzer,OUTPUT);//initialize the buzzer pin as an output
}
void loop() {
unsigned char i;
while(1)
{ //output an frequency
for(i=0;i<80;i++) {
digitalWrite(buzzer,HIGH);
delay(1);//wait for 1ms
digitalWrite(buzzer,LOW);
delay(1);//wait for 1ms
} //output another frequency
for(i=0;i<100;i++) {
digitalWrite(buzzer,HIGH);
delay(2);//wait for 2ms
digitalWrite(buzzer,LOW);
delay(2);//wait for 2ms
}
}
}
Open the Arduino IDE and select corresponding board type and port type for your Arduino board.
After compile this sketch, simply click the “Upload” button in the environment. Wait a few seconds – you should see the RX and TX leds on the board flashing. If the upload is successful, the message “Done uploading.” will appear in the status bar.
A few seconds after the upload finishes, you should hear the buzzer beep.
Note again:
The active buzzer has built-in oscillating source, so it will beep as long as it is electrified, but it can only beep with a fixed frequency.
In this tutorial we are going to design a Barometric Pressure Measuring System using BMP180 and ARDUINO. First of all for interfacing BMP180 to ARDUINO, we need to download a library specifically designed for BMP180. This library is available at: https://github.com/adafruit/Adafruit-BMP085-Library After attaching that library, we can call special functions which will ease working with BMP180 sensor.
This pressure sensor is a BMP-180 based digital barometric pressure sensor module and is functional compatible with older BMP-085 digital pressure sensor with less power consumption smaller in size and more accurate. BMP180 combines barometric pressure, temperature and altitude. The I2C allows easy interface with any microcontroller. On board 3.3V LDO regulator makes this board fully 5V supply compatible. BMP-180 can measure pressure range from 300 to 1100hPa (+9000m to -500m relating to sea level) with an accuracy down to 0.02hPa (0.17m) in advance resolution mode. BMP-180 is an improved replacement for BMP-085 sensor. BMP-180 uses piezo-resistive technology for high accuracy, linearity, EMC robustness and stability for a longer period of time.
Features:
Specifications:
The BMP180 consists of a piezo-resistive sensor, an analog to digital converter and a control unit with E2PROM and a serial I2C interface. The BMP180 delivers the uncompensated value of pressure and temperature.The microcontroller sends a start sequence to start a pressure or temperature measurement. After converting time, the result value (pressure or temperature respectively) can be read via the I2C interface. For calculating temperature in °C and pressure in hPa, the calibration data has to be used. These constants can be read out from the BMP180 E2PROM via the I2C interface at software initialization.The sampling rate can be increased up to 128 samples per second (standard mode) for dynamic measurement. In this case, it is sufficient to measure the temperature only once per second and to use this value for all pressure measurements during the same period.
You can use any method you like to make your connections to the board. For this example, we’ll solder on a five-pin length of male-male header strip, and use male/female jumper wires to connect the BMP180 to your Arduino.
Solder a 5-pin length of male-male header to the board. You can solder it to either side; the bottom is more useful for breadboards, and the top is more useful for jumper wires.
Note that the BMP180 is sensitive to moisture. When you’re done soldering, do not clean off the flux by rinsing the board in water or other fluids.
In the following sections, we can see how to interface the breakout board with Osoyoo UNO. The breakout board has 5 pins which are mentioned below. The board has 3.3V regulator. So you can use either 5V or 3.3V as supply voltage.
SDA | I2C data | Any pin labeled SDA, or:
|
||||||
SCL | I2C clock | Any pin labeled SCL, or:
|
||||||
GND | ground | GND | ||||||
VCC | 3.3V/5V power supply | 3.3V/5V | ||||||
3.3V | 3.3V | 3.3V |
The BMP180 was designed to accurately measure atmospheric pressure. Atmospheric pressure varies with both weather and altitude; you can measure both of these using this sensor. Here’s how:
The definition of pressure is a force “pressing” on an area. A common unit of pressure is pounds per square inch (psi). One pound, pressing on one square inch, equals one psi. The SI unit is newtons per square meter, which are called pascals (Pa).
There are lots of situations in which pressure can be measured (gravity, pull, etc.), but right now we’re interested in atmospheric pressure, which is the force that the air around you is exerting on everything. The weight of the gasses in the atmosphere creates atmospheric pressure. One doesn’t normally notice that air weighs anything, but if you took a one inch wide column of air from sea level to the top of the atmosphere, it would weigh about 14.7 pounds. (A 1 cm wide column of air would weigh about 1 kg.) This weight, pressing down on the footprint of that column, creates the atmospheric pressure that we can measure with sensors like the BMP180.
Because that inch-wide column of air weighs about 14.7 pounds, and is pressing on one square inch, it follows that the average sea level pressure is about 14.7 pounds per square inch (psi), or 101325 pascals. This will drop about 4% for each 1000 feet (or 300 meters) you ascend. The higher you get, the less pressure you’ll see, because the column to the top of the atmosphere is that much shorter and therefore weighs less. This is useful to know, because by measuring the pressure and doing some math, you can determine your altitude.
Fun fact: The air pressure at 12,500 feet (3810 meters) is only half of that at sea level. In other words, half of the mass of the atmosphere is below 12,500 feet, and the air at 12,500 feet is half as dense as that at sea level. No wonder you have a harder time breathing up there.
The BMP180 outputs absolute pressure in pascals (Pa). One pascal is a very small amount of pressure, approximately the amount that a sheet of paper will exert resting on a table. You will more often see measurements in hectopascals (1 hPa = 100 Pa) or kilopascals (1 kPa = 1000 Pa). The Arduino library we’ve provided outputs floating-point values in hPa, which also happens to equal one millibar (mbar).
Here are some conversions to other pressure units:
1 hPa = 100 Pa = 1 mbar = 0.001 bar
1 hPa = 0.75006168 Torr
1 hPa = 0.01450377 psi (pounds per square inch)
1 hPa = 0.02953337 inHg (inches of mercury)
1 hpa = 0.00098692 atm (standard atmospheres)
Because temperature affects the density of a gas, and density affects the mass of a gas, and mass affects the pressure (whew), atmospheric pressure will change dramatically with temperature. Pilots know this as “density altitude”, which makes it easier to take off on a cold day than a hot one because the air is more dense and has a greater aerodynamic effect.
To compensate for temperature, the BMP180 includes a rather good temperature sensor as well as a pressure sensor. To perform a pressure reading, you first take a temperature reading, then combine that with a raw pressure reading to come up with a final temperature-compensated pressure measurement. (Don’t worry, the Arduino library makes all of this very easy.)
As we just mentioned, if your application requires measuring absolute pressure, all you have to do is get a temperature reading, then perform a pressure reading (see the example sketch for details). The final pressure reading will be in hPa = mbar. If you wish, you can convert this to a different unit using the above conversion factors.
Note that the absolute pressure of the atmosphere will vary with both your altitude and the current weather patterns, both of which are useful things to measure.
The atmospheric pressure at any given location on earth (or anywhere with an atmosphere) isn’t constant. The complex interaction between the earth’s spin, axis tilt, and many other factors result in moving areas of higher and lower pressure, which in turn cause the variations in weather we see every day. By watching for changes in pressure, you can predict short-term changes in the weather. For example, dropping pressure usually means wet weather or a storm is approaching (a low-pressure system is moving in). Rising pressure usually means that clear weather is approaching (a high-pressure system is moving through).
But remember that atmospheric pressure also varies with altitude. The absolute pressure in Denver (altitude 5280′) will always be lower than the absolute pressure in San Francisco (altitude 52′). If weather stations just reported their absolute pressure, it would be difficult to directly compare pressure measurements from one location to another (and large-scale weather predictions depend on measurements from as many stations as possible).
To solve this problem, weather stations always remove the effects of altitude from their reported pressure readings by mathematically adding the equivalent fixed pressure to make it appear as if the reading was taken at sea level. When you do this, a higher reading in San Francisco than Denver will always be because of weather patterns, and not because of altitude.
To do this, there is a function in the library called seaLevel(P,A)
. This takes absolute pressure (P) in hPa, and the station’s current altitude (A) in meters, and removes the effects of the altitude from the pressure. You can use the output of this function to directly compare your weather readings to other stations around the world.
For more information, here is a good Wikipedia article on mean sea level pressure.
Since pressure varies with altitude, you can use a pressure sensor to measure altitude (with a few caveats).
The average pressure of the atmosphere at sea level is 1013.25 hPa (or mbar). This drops off to zero as you climb towards the vacuum of space. Because the curve of this drop-off is well understood, you can compute the altitude difference between two pressure measurements (p and p0) by using this equation:
There are two ways you can take advantage of this.
There’s a function in the library called altitude(P,P0)
that lets you accomplish both of these things. If you give it the sea level pressure (1013.25 hPa) for p0, and your local pressure for p, it will give you your altitude above sea level. If you use a local pressure measurement for p0, subsequent p pressure readings will give you your change in altitude from the baseline.
Now for the caveats:
Accuracy: How accurate is this? The theoretical noise level at the BMP180s highest resolution is 0.25m (about 10 inches), though in practice we see noise on the order of 1m (40 inches). You can improve the accuracy by taking a large number of readings and averaging them, although this will slow down your sample rate and response time.
Weather: You should also remember that pressure changes due to weather will affect your altitude readings. The best accuracy will be obtained if you take a “fresh” p0 when you need it and don’t rely on it to be accurate for extended periods due to changes in the weather.
Maximum altitude: The BMP180 can’t measure all the way down to vacuum (or up to space). It’s advertised lower limit is about 300 hPa (or mbar), which corresponds to an altitude of about 3000m or 30,000 feet. People have flown these to higher altitudes and gotten useful results, but this isn’t guaranteed or likely to be accurate. (You might consider using GPS for high-altitude measurements).
Minimum altitude: Similarly, this sensor isn’t suited for large pressures either. The advertised upper limit is 1100 hPa=mbar (or 16 psi), which is about 500 feet below sea level (that’s in air – the BMP180 isn’t submersible in water). This sensor isn’t a good choice for submersible or compressed-gas measurements.
Here are some important recommendations for making correct measurements and protecting the BMP180.
Each device has an I2C address that it uses to accept commands or send messages. For Uno board, this address usually is 0x27. But sometimes the address might be changed 0x37,0x24 …., So let’s go and look for the one on your device.
Download ic2_scanner sketch zip file , then unzip and load it into Arduino IDE. By opening up the serial monitor in the upright corner, Arduino will scan the address range looking for a reply. Most Arduino board will show 0x27, however it be other number.
Write down the Address that you have found, you may need it in the next step.
Create a new project and paste the code below originally developed by Leo Nutz. It does not use any external libraries to communicate and perform measurement conversions. Less practical but also a little more compact than an external library which can prove very useful in an Arduino project.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
/*********************************************************************
BMP180 /BMP085 sensor
Test program without external library
www.projetsdiy.fr
From original version of Leo Nutz, www.ALTDuino.de
**********************************************************/
#include
#define ADDRESS_SENSOR 0x77 // Addresse du capteur
int16_t ac1, ac2, ac3, b1, b2, mb, mc, md; // Store sensor PROM values from BMP180
uint16_t ac4, ac5, ac6; // Store sensor PROM values from BMP180
// Ultra Low Power OSS = 0, OSD = 5ms
// Standard OSS = 1, OSD = 8ms
// High OSS = 2, OSD = 14ms
// Ultra High Resolution OSS = 3, OSD = 26ms
const uint8_t oss = 3; // Set oversampling setting
const uint8_t osd = 26; // with corresponding oversampling delay
float T, P; // Variables globales pour la température et la pression
void setup()
{
Serial.begin(9600);
while(!Serial){;} // On attend que le port série soit disponible
delay(5000);
Wire.begin(); // Active le bus I2C
init_SENSOR(); // Initialise les variables
delay(100);
}
void loop()
{
int32_t b5;
b5 = temperature(); // Lit et calcule la température (T)
Serial.print(“Temperature: “);
Serial.print(T, 2);
Serial.print(“*C, “);
P = pressure(b5); // Lit et calcule la pressure (P)
Serial.print(“Pression: “);
Serial.print(P, 2);
Serial.print(” mbar, “);
Serial.print(P * 0.75006375541921, 2);
Serial.println(” mmHg”);
Serial.println(“”);
delay(1000); // Delai entre chaque mesure
}
/**********************************************
Initialise les variables du capteur
**********************************************/
void init_SENSOR()
{
ac1 = read_2_bytes(0xAA);
ac2 = read_2_bytes(0xAC);
ac3 = read_2_bytes(0xAE);
ac4 = read_2_bytes(0xB0);
ac5 = read_2_bytes(0xB2);
ac6 = read_2_bytes(0xB4);
b1 = read_2_bytes(0xB6);
b2 = read_2_bytes(0xB8);
mb = read_2_bytes(0xBA);
mc = read_2_bytes(0xBC);
md = read_2_bytes(0xBE);
Serial.println(“”);
Serial.println(“Données de calibration du capteur :”);
Serial.print(F(“AC1 = “)); Serial.println(ac1);
Serial.print(F(“AC2 = “)); Serial.println(ac2);
Serial.print(F(“AC3 = “)); Serial.println(ac3);
Serial.print(F(“AC4 = “)); Serial.println(ac4);
Serial.print(F(“AC5 = “)); Serial.println(ac5);
Serial.print(F(“AC6 = “)); Serial.println(ac6);
Serial.print(F(“B1 = “)); Serial.println(b1);
Serial.print(F(“B2 = “)); Serial.println(b2);
Serial.print(F(“MB = “)); Serial.println(mb);
Serial.print(F(“MC = “)); Serial.println(mc);
Serial.print(F(“MD = “)); Serial.println(md);
Serial.println(“”);
}
/**********************************************
Calcul de la pressure
**********************************************/
float pressure(int32_t b5)
{
int32_t x1, x2, x3, b3, b6, p, UP;
uint32_t b4, b7;
UP = read_pressure(); // Lecture de la pression renvoyée par le capteur
b6 = b5 – 4000;
x1 = (b2 * (b6 * b6 >> 12)) >> 11;
x2 = ac2 * b6 >> 11;
x3 = x1 + x2;
b3 = (((ac1 * 4 + x3) << oss) + 2) >> 2;
x1 = ac3 * b6 >> 13;
x2 = (b1 * (b6 * b6 >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (uint32_t)(x3 + 32768)) >> 15;
b7 = ((uint32_t)UP – b3) * (50000 >> oss);
if(b7 < 0x80000000) { p = (b7 << 1) / b4; } else { p = (b7 / b4) << 1; } // ou p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (–7357 * p) >> 16;
return (p + ((x1 + x2 + 3791) >> 4)) / 100.0f; // Retourne la pression en mbar
}
/**********************************************
Lecture de la température (non compensée)
**********************************************/
int32_t temperature()
{
int32_t x1, x2, b5, UT;
Wire.beginTransmission(ADDRESS_SENSOR); // Début de transmission avec l’Arduino
Wire.write(0xf4); // Envoi l’adresse de registre
Wire.write(0x2e); // Ecrit la donnée
Wire.endTransmission(); // Fin de transmission
delay(5);
UT = read_2_bytes(0xf6); // Lecture de la valeur de la TEMPERATURE
// Calcule la vrai température
x1 = (UT – (int32_t)ac6) * (int32_t)ac5 >> 15;
x2 = ((int32_t)mc << 11) / (x1 + (int32_t)md);
b5 = x1 + x2;
T = (b5 + 8) >> 4;
T = T / 10.0; // Retourne la température in celsius
return b5;
}
/**********************************************
Lecture de la pression
**********************************************/
int32_t read_pressure()
{
int32_t value;
Wire.beginTransmission(ADDRESS_SENSOR); // Début de transmission avec l’Arduino
Wire.write(0xf4); // Envoi l’adresse de registre
Wire.write(0x34 + (oss << 6)); // Ecrit la donnée
Wire.endTransmission(); // Fin de transmission
delay(osd);
Wire.beginTransmission(ADDRESS_SENSOR);
Wire.write(0xf6);
Wire.endTransmission();
Wire.requestFrom(ADDRESS_SENSOR, 3);
if(Wire.available() >= 3)
{
value = (((int32_t)Wire.read() << 16) | ((int32_t)Wire.read() << 8) | ((int32_t)Wire.read())) >> (8 – oss);
}
return value; // Renvoie la valeur
}
/**********************************************
Lecture d’un byte sur la capteur BMP
**********************************************/
uint8_t read_1_byte(uint8_t code)
{
uint8_t value;
Wire.beginTransmission(ADDRESS_SENSOR);
Wire.write(code);
Wire.endTransmission();
Wire.requestFrom(ADDRESS_SENSOR, 1);
if(Wire.available() >= 1)
{
value = Wire.read();
}
return value;
}
/**********************************************
Lecture de 2 bytes sur la capteur BMP
**********************************************/
uint16_t read_2_bytes(uint8_t code)
{
uint16_t value;
Wire.beginTransmission(ADDRESS_SENSOR);
Wire.write(code);
Wire.endTransmission();
Wire.requestFrom(ADDRESS_SENSOR, 2);
if(Wire.available() >= 2)
{
value = (Wire.read() << 8) | Wire.read(); // Récupère 2 bytes de données
}
return value; // Renvoie la valeur
}
|
The Adafruit library (Adafruit_BMP085) has not been updated. It is still based on the BMP085. Unlike the Sparkfun bookshop, the altitude estimate is (almost) correct.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#include
#include
/***************************************************
This is an example for the BMP085 Barometric Pressure & Temp Sensor
Designed specifically to work with the Adafruit BMP085 Breakout
—-> https://www.adafruit.com/products/391
These displays 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
****************************************************/
// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
// Connect GND to Ground
// Connect SCL to i2c clock – on ‘168/’328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect SDA to i2c data – on ‘168/’328 Arduino Uno/Duemilanove/etc thats Analog 4
// EOC is not used, it signifies an end of conversion
// XCLR is a reset pin, also not used here
Adafruit_BMP085 bmp;
void setup() {
Serial.begin(9600);
if (!bmp.begin()) {
Serial.println(“Could not find a valid BMP085 sensor, check wiring!”);
while (1) {}
}
}
void loop() {
Serial.print(“Temperature = “);
Serial.print(bmp.readTemperature());
Serial.println(” *C”);
Serial.print(“Pressure = “);
Serial.print(bmp.readPressure());
Serial.println(” Pa”);
// Calculate altitude assuming ‘standard’ barometric
// pressure of 1013.25 millibar = 101325 Pascal
Serial.print(“Altitude = “);
Serial.print(bmp.readAltitude());
Serial.println(” meters”);
// you can get a more precise measurement of altitude
// if you know the current sea level pressure which will
// vary with weather and such. If it is 1015 millibars
// that is equal to 101500 Pascals.
Serial.print(“Real altitude = “);
Serial.print(bmp.readAltitude(101500));
Serial.println(” meters”);
Serial.println();
delay(500);
}
|
The Sparkfun library is available here. Two examples are provided, one of which incorporates an estimate of the altitude according to the formula described below.
In this project, we will show what is MQ-5 Sensor and how to use it with the Arduino board.
MQ-7 Semiconductor Sensor for Combustible Gas
Sensitive material of MQ-7 gas sensor is SnO2, which with lower conductivity in clean air. It make detection by method of cycle high and low temperature, and detect CO when low temperature (heated by 1.5V). The sensors conductivity is more higher along with the gas concentration rising. When high temperature (heated by 5.0V), it cleans the other gases adsorbed under low temperature. Please use simple electrocircuit, Convert change of conductivity to correspond output signal of gas concentration.
MQ-7 gas sensor has high sensitity to Carbon Monoxide. The sensor could be used to detect different gases contains CO, it is with low cost and suitable for different application.
According to its datasheet, the MQ-7 carbon monoxide sensor detects 20 to 2000 ppm of CO in air. Here is its sensitivity characteristic curve:
This is a graph of Rs/R0 vs. gas concentration in ppm. Rs is the resistance of the sensor in target gas while R0 is the resistance in clean air. We will use this graph later when we create our code.
This breakout board is more convenient as it converts resistance variations to voltage variations. Here is its schematic diagram:
There are two ways to read the output from the MQ-7. One is through the DOUT pin which gives a high when the concentration threshold is reached and low otherwise. The threshold can be varied by adjusting the trimmer on the breakout board which is Rp in the schematic.
Meanwhile, the AOUT pin gives varying voltage representing the CO concentration. We can convert the voltage reading to ppm if we look at the characteristic curve above. The relationship between concentration in ppm and RS/R0 is:
Connect the MQ 7 Sensro and the Arduino Board as below digram:
const int AOUTpin=0;//the AOUT pin of the hydrogen sensor goes into analog pin A0 of the arduino const int DOUTpin=8;//the DOUT pin of the hydrogen sensor goes into digital pin D8 of the arduino const int ledPin=13;//the anode of the LED connects to digital pin D13 of the arduino int limit; int value; void setup() { Serial.begin(115200);//sets the baud rate pinMode(DOUTpin, INPUT);//sets the pin as an input to the arduino pinMode(ledPin, OUTPUT);//sets the pin as an output of the arduino } void loop() { value= analogRead(AOUTpin);//reads the analaog value from the hydrogen sensor's AOUT pin limit= digitalRead(DOUTpin);//reads the digital value from the hydrogen sensor's DOUT pin Serial.print("Hydrogen value: "); Serial.println(value);//prints the hydrogen value Serial.print("Limit: "); Serial.print(limit);//prints the limit reached as either LOW or HIGH delay(100); if (limit == HIGH){ digitalWrite(ledPin, HIGH);//if limit has been reached, LED turns on as status indicator } else{ digitalWrite(ledPin, LOW);//if threshold not reached, LED remains off } }
The first block of code defines all the pin connections of the sensor and the LED. Since the AOUTpin connects to analog pin A0, it is initialized to 0. Since the DOUTpin connects to digital pin D8, it is initialized to 8. Since the LED connects to digital pin D13, it is initialized to 13. 2 variables, limit and value, are also declared. These will be used to store the value of the analog pin AOUT and digital pin DOUT.
The next block of code sets the baud rate and declares the DOUTpin as input and the ledPin as output. This is because the sensor is an input to the arduino for the arduino to read and process the sensor value. And the LED is an output will serves an indicator if the sensor has detected alcohol.
The next block of code reads the sensor pin AOUT and stores the value in the integer value. It also reads the sensor pin DOUT and stores the value in the integer limit. We then print the alcohol value, which will be a numeric value ranging from either 0 (no alcohol detected) to 1023 (maximum level of carbon monoxide that can be read). We will aslo print the limit which will either be HIGH or LOW. If the CO detected is under the threshold level, the value of limit returned will be low. If the CO detected is above the threshold, the value of limit returned will be HIGH.
If the value is HIGH, the LED will turn on. If the value is low, the LED will remain off.
In this project, we will show what is MQ-5 Sensor and how to use it with the Arduino board.
The gas sensitive material used in MQ-5 gas sensor is SnO2, which is of lower electrical conductivity in clean air. When there is combustible gas in the environment where sensor resides, the electrical conductivity of the sensor increases with the increase of the combustible gas concentration in the air. The change of electrical conductivity can be converted to the output signal corresponding to that of the gas concentration by using a simple circuit.
The sensitivity of MQ-5 gas sensor to propane, propane and methane is quite high, and the methane and propane can be well detected. This sensor can detect a variety of combustible gases, especially natural gas, making it a low-cost sensor for a variety of applications.
In this tutorial, we are using the MQ5 Gas sensor module (which is widely available in market) . This module has two output possibilities – an analog out (A0) and a digital out (D0). The analog out can be used to detect Gas leakage and to measure volume of Gas leakage (by doing proper calculation of the sensor output inside program) in specific units (say ppm). The digital out can be used to detect Gas leakage and hence trigger an alert system (say a sound alarm or an sms activation etc). The digital out gives only two possible outputs – High and Low (hence its more suited for detection of gas leak than to measure volume of gas presence).
Item | Parameter | Min | Typical | Max | Unit |
---|---|---|---|---|---|
VCC | Working Voltage | 4.9 | 5 | 5.1 | V |
PH | Heating consumption | 0.5 | – | 800 | mW |
RL | Load resistance | adjustable | |||
RH | Heater resistance | – | 31±10% | – | Ω |
Rs | Sensing Resistance | 10 | – | 60 | kΩ |
Scope | Detecting Concentration | 200 | – | 10000 | ppm |
Note
The sensor value only reflects the approximated trend of gas concentration in a permissible error range, it DOES NOT represent the exact gas concentration. The detection of certain components in the air usually requires a more precise and costly instrument, which cannot be done with a single gas sensor. If your project is aimed at obtaining the gas concentration at a very precise level, then we do not recommend this gas sensor.
This is pretty simple. Connect the D0 pin of MQ5 module to any digital pin of arduino. Lets connect D0 to pin 7 of arduino. Now we need to give power supply (Vcc) and complete the circuit by connecting to ground (Gnd). Refer the circuit diagram given below. Take a +5V connection from arduino and connect it to Vcc of MQ5 module. Finally connect the GND pin of MQ5 module to GND of arduino. That’s all and we have finished the circuit.
MQ-5 Sensor | OSOYOO UNO Board |
VCC | +5V |
GND | GND |
D0 | D7 |
Note:- MQ5 sensor has preheating requirement. We advise to keep the sensor powered on (from arduino) for some 15 minutes before applying gas to it.
int sensor=7; float gas_value; void setup() { pinMode (sensor,INPUT); Serial.begin(9600); } void loop() { gas_value=digitalRead(sensor); Serial.println(gas_value); }
Note:- To apply a “gas leak” to MQ5 sensor, you can simply use a cigarette or cigar lighter! Press the trigger switch of cigarette lighter gently (gentle enough so as gas leaks and spark is not triggered) to get gas leaked continuously and place the lighter near MQ5 sensor.
The screenshots below shows serial monitor readings of arduino before applying gas leak and after applying gas leak. Before applying gas leak, MQ5 captures atmospheric air concentration only (we get a HIGH in our digital out pin and is measured by arduino as 1, as shown in serial monitor).
When we apply a “gas leak”, the heating element inside MQ5 gets heated up and output voltage varies (we get a LOW in our D0 pin and is measured by arduino as 0, as shown in serial monitor output screenshot )
The connections are very simple, just like we interfaced MQ5 using digital out pin. In this method, instead of DO, connect analog out pin AO of MQ5 to any of the arduino analog pins. In this tutorial, we are connecting analog out pin of MQ5 to A0 pin of Arduino. Connect Vcc and Ground properly as shown in circuit diagram and we are finished wiring part. Now there’s a little change in the program part. Instead of digitalRead, we need analogRead command of arduino to read sensor values. Output values are also different, instead of 0 and 1 we have a series of integer values ranging from 0 to 1023.
MQ-5 Sensor | OSOYOO UNO Board |
VCC | +5V |
GND | GND |
A0 | A0 |
int sensor=A0; float gas_value; void setup() { pinMode (sensor,INPUT); Serial.begin(9600); } void loop() { gas_value=analogRead(sensor); Serial.println(gas_value); }
The outputs as seen in serial monitor of arduino are given below. Let’s first see the default output values (when no gas leak is applied) where MQ5 senses atmospheric air concentration only.
Okay! Now let’s apply some “gas leak” by pressing the switch of a cigar lighter gently! You can see the output value is in the range of 800+ as opposed to very low values (in the range of 40’s) when there is no gas leak.
We have seen the sensor reading in different states – in digital out mode and in analog out mode. We know the sensor reading in different conditions for both output modes- i.e – when there is no gas leak and when there is gas leak.
In this project, we will go over how to build a smoke sensor circuit with an arduino board.
The smoke sensor we will use is the MQ-2. This is a sensor that is not only sensitive to smoke, but also to flammable gas.
The MQ-2 smoke sensor reports smoke by the voltage level that it outputs. The more smoke there is, the greater the voltage that it outputs. Conversely, the less smoke that it is exposed to, the less voltage it outputs.
The MQ-2 smoke sensor is sensitive to smoke and to the following flammable gases:
The resistance of the sensor is different depending on the type of the gas.
The smoke sensor has a built-in potentiometer that allows you to adjust the sensor sensitivity according to how accurate you want to detect gas.
1. Wide detecting scope
2. High sensitivity and fast response
3. Long life and stable
4. Simple drive circuit
Due to its fast response time and high sensitivity, measurements can be taken as soon as possible. The sensor sensitivity can be adjusted by using the potentiometer.
Symbol | Parameter Name | Technical Condition | Remarks |
VC | Circuit voltage | 5V±0.1 | AC or DC |
VH | Heating voltage | 5V±0.1 | AC or DC |
RL | Load resistance | adjustable | |
RH | Heater resistance | 33Kohm±5% | Room temperature |
PH | Heating consumption | Less than 800mW |
Symbol | Parameter Name | Technical Condition | Remarks |
TO | Operating Temp. | -20°C-50°C | |
TS | Storage Temp. | -20°C-70°C | |
RH | Relative Humidity | <95% | |
O2 | Oxygen Concentration | 21%(standard condition) Oxygen concentration can affect sensitivity | Minimum value is 2% |
Symbol | Parameter Name | Technical Condition | Remarks |
RS | Sensor Resistance | 3Kohm-30Kohm (1000ppm iso-butane) | Detecting concentration scope: 200ppm-5000ppm LPG and propane 300ppm-5000ppm butane 5000ppm-20000ppm methane 300ppm-5000ppm H2 100ppm-2000ppm Alcohol |
α (3000ppm/1000ppm iso-butane) | Concentration slope rate | ≤0.6 | |
Standard detecting Condition | Temp.: 20°C±2°C VC: 5V±0.1 Humidity:65%±5% VH:5V±0.1 |
||
Preheating Time | Over 24 hours |
The MQ2 has an electrochemical sensor, which changes its resistance for different concentrations of varied gasses. The sensor is connected in series with a variable resistor to form a voltage divider circuit , and the variable resistor is used to change sensitivity. When one of the above gaseous elements comes in contact with the sensor after heating, the sensor’s resistance change. The change in the resistance changes the voltage across the sensor, and this voltage can be read by a microcontroller. The voltage value can be used to find the resistance of the sensor by knowing the reference voltage and the other resistor’s resistance. The sensor has different sensitivity for different types of gasses. The sensitivity characteristic curve is shown below for the different type of gasses.
The voltage that the sensor outputs changes accordingly to the smoke/gas level that exists in the atmosphere. The sensor outputs a voltage that is proportional to the concentration of smoke/gas.
In other words, the relationship between voltage and gas concentration is the following:
Working Mechanism
The output can be an analog signal (A0) that can be read with an analog input of the Arduino or a digital output (D0) that can be read with a digital input of the Arduino.
Note
The sensor value only reflects the approximated trend of gas concentration in a permissible error range, it DOES NOT represent the exact gas concentration. The detection of certain components in the air usually requires a more precise and costly instrument, which cannot be done with a single gas sensor. If your project is aimed at obtaining the gas concentration at a very precise level, then we don’t recommend this gas sensor.
In this example, the sensor is connected to A0 pin. The voltage read from the sensor is displayed. This value can be used as a threshold to detect any increase/decrease in gas concentration.
void setup() {
Serial.begin(9600);
}
void loop() {
float sensor_volt;
float sensorValue;
sensorValue = analogRead(A0);
sensor_volt = sensorValue/1024*5.0;
Serial.print("sensor_volt = ");
Serial.print(sensor_volt);
Serial.println("V");
delay(1000);
}
These examples demonstrate ways to know the approximate concentration of Gas. As per the data-sheet of the MQx sensors, these equations are tested for standard conditions and are not calibrated. It may vary based on change in temperature or humidity.
void setup() {
Serial.begin(9600);
}
void loop() {
float sensor_volt;
float RS_air; // Get the value of RS via in a clear air
float R0; // Get the value of R0 via in H2
float sensorValue;
/*--- Get a average data by testing 100 times ---*/
for(int x = 0 ; x < 100 ; x++)
{
sensorValue = sensorValue + analogRead(A0);
}
sensorValue = sensorValue/100.0;
/*-----------------------------------------------*/
sensor_volt = sensorValue/1024*5.0;
RS_air = (5.0-sensor_volt)/sensor_volt; // omit *RL
R0 = RS_air/9.8; // The ratio of RS/R0 is 9.8 in a clear air from Graph (Found using WebPlotDigitizer)
Serial.print("sensor_volt = ");
Serial.print(sensor_volt);
Serial.println("V");
Serial.print("R0 = ");
Serial.println(R0);
delay(1000);
}
void setup() {
Serial.begin(9600);
}
void loop() {
float sensor_volt;
float RS_gas; // Get value of RS in a GAS
float ratio; // Get ratio RS_GAS/RS_air
int sensorValue = analogRead(A0);
sensor_volt=(float)sensorValue/1024*5.0;
RS_gas = (5.0-sensor_volt)/sensor_volt; // omit *RL
/*-Replace the name "R0" with the value of R0 in the demo of First Test -*/
ratio = RS_gas/R0; // ratio = RS/R0
/*-----------------------------------------------------------------------*/
Serial.print("sensor_volt = ");
Serial.println(sensor_volt);
Serial.print("RS_ratio = ");
Serial.println(RS_gas);
Serial.print("Rs/R0 = ");
Serial.println(ratio);
Serial.print("\n\n");
delay(1000);
}
The circuit we will build is shown below.
So to power the smoke sensor, we connect pin 2 of the smoke sensor to the 5V terminal of the arduino and terminal 3 to the GND terminal of the arduino. This gives the smoke sensor the 5 volts it needs to be powered.
The output of the sensor goes into analog pin A0 of the arduino. Through this connection, the arduino can read the analog voltage output from the sensor. The arduino board has a built-in analog-to-digital converter, so it is able to read analog values without any external ADC chip.
Depending on the value that the arduino reads determines the action that will occur with the circuit. We will make it in our code that if the sensor outputs a voltage above a certain threshold, the buzzer will go off, alerting a user that smoke has been detected.
These are all the physical connections in order for our circuit to work.
Being that we’ve just gone over the circuit schematic for the smoke sensor circuit, all we need know is the code necessary to upload to the arduino for this smoke alarm cicrcuit to work.
The code that we need to upload is shown below.
/*Code for MQ-2 Smoke Sensor Circuit Built with an Arduino Board*/
const int sensorPin= 0;
const int buzzerPin= 13;
int smoke_level;
void setup() {
Serial.begin(115200); //sets the baud rate for data transfer in bits/second
pinMode(sensorPin, INPUT);//the smoke sensor will be an input to the arduino
pinMode(buzzerPin, OUTPUT);//the buzzer serves an output in the circuit
}
void loop() {
smoke_level= analogRead(sensorPin); //arduino reads the value from the smoke sensor
Serial.println(smoke_level);//prints just for debugging purposes, to see what values the sensor is picking up
if(smoke_level > 200){ //if smoke level is greater than 200, the buzzer will go off
digitalWrite(buzzerPin, HIGH);
}
else{
digitalWrite(buzzerPin, LOW);
}
}
The first block of code declares and initializes 3 variables. The sensorPin represents the smoke sensor. It is initialized to 0, because it will be connected to analog pin A0 of the arduino board. The next variable, buzzerPin, represents the pin that the anode of the buzzer will be connected to; it is initialized to 12 because it will be connected to digital pin D12 of the arduino board. And the variable, smoke_level, represents the amount of smoke that the smoke sensor picks up.
The next block of code defines the baud rate and the input and output of the circuit. The sensorPin, which is the smoke sensor pin, serves as the input of the circuit. This sensor is input into the arduino so that the arduino can read and process the value. The buzzerPin serves as the output. If the smoke level is above a certain threshold, the output of the circuit, the buzzer, will go off.
The next block of code uses the analogRead() function to read the value from the sensorPin (the smoke sensor). This will be a numerical value from 0 to 1023. 0 represents no smoke, while 1023 represents smoke at the absolute maximum highest level. So the variable, smoke_level, represents the smoke level that can range from 0 to 1023. We put a line to print this value just for debugging purposes, so that you can see what values are being returned from this function. In our code, we make it so that if the smoke level rises above 200, we will trigger the buzzer to sound by sending the digital pin D12 high. So 200 is our threshold level. If the smoke level is below this value, then the buzzer does not go off.
This last block of code was the loop() function. This is the part of code that repeats over and over in an infinite loop. This means that our code is always checking to see what the smoke_level is, so that it can know whether to trigger the buzzer or not.
And this is how a smoke sensor works with