Since
the introduction of the Arduino open source prototyping platform, there has
been a rapid increase in interest from inventors, designers, artists, engineers
and above all, the hobbyist. The Arduino platform has opened the door to a
whole new world of invention that, with just a few basic pointers, will get
even a novice building their own unique prototypes.
The
Arduino microcontroller boards are relatively cheap, the programming software
(Integrated Development Environment; IDE) is free and can be downloaded from
the Arduino website. The programming environment is written in Java and based
on Processing, avr-gcc, and other open source software. The components required
to build prototype systems start from just a few pence.
To
follow the instructions here, most of the Arduino boards will suffice; though
this section was written with the Arduino Uno Revision 3 in mind.
The
first thing that you notice when you receive your new Uno is that it is so
small; not as large as it appeared in the advert. Its dimensions are only 2.7
inches long and 2.1 inches wide; packed with lots of features and large enough
for what we need. Normally, the Uno has a USB cable bundled with it.
The
board can be powered from the DC power jack (7 - 12V), the USB connector (5V),
or the VIN pin of the board (7-12V).
Throughout
the examples, we will only be using the USB connector which will conveniently
draw the power from your computer to power the board as well as acting as an
interface to upload program s and monitor output.
Next
you will notice that the board has lots of pins running along the edges. All we
need to know at this stage is that there are pins for power, ground, 14 digital
input/output pins and 6 analog inputs. There’s an ATmega328 microcontroller
chip and the board has 32KB of flash memory for storing programs. That’s it;
all we need to know to work through all of the following examples.
As
well as the USB connection, we will be using jumper wires to connect various
components, usually via a breadboard to the Arduino. It is assumed that you have
downloaded and installed Arduino IDE (Integrated Development Environment) from
the Arduino software download page http://arduino.cc/en/main/software and have
connected your Arduino to the computer using the standard USB cable (A plug to
B plug).
The Arduino IDE
The
Arduino Integrated Development Environment (IDE) is laid out logically and
you’ll soon learn to navigate around the more important functions within a few
minutes.
Arduino IDE
Connect
your Arduino to your computer using a USB connector and launch the Arduino IDE.
Check that the correct board is selected in the IDE:
Selecting Correct
Arduino Board
Selecting
Once
you are satisfied that the settings reflect your specific Arduino board and COM
port set up, you are ready to begin.
Don’t
get too worried about the IDE, you can keep referring back to these diagrams as
and when you feel the need to. Every step of each setup is explained fully, so
you shouldn’t need to come back here very often.
Throughout,
the example code is included in the text but it may be easier for you if you
copy the code from my blog at the following address and then paste it into the
Arduino IDE:
http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html
One
of the most widely used electronic components is the humble light emitting
diode, commonly known as LED. They are extensively used as indicator lights
(for example standby lights on computers and TVs, status lights on a motorcar
dashboard, advertising signs and endless other applications), are straight
forward to use and are relatively cheap to buy.
LED
Let’s
begin by looking at simply getting and LED to flash on and off. This example
program comes with the Arduino IDE so you won’t need to do any programming. Set
up an LED to digital pin 13 via a 220 ohm resistor and GND on the Arduino like
so:
Basic Blink Circuit
Diagram
Note
that the longer leg of the LED (the anode) should connected to pin 13 via the
220 ohm resistor and the shorter leg (cathode) to GND. Using the drop down
menus in the Arduino IDE, select: “Files”, “Examples”, “Basic”, “Blink” to load
the Blink program.
Let’s
take a look at the program. Firstly, you will notice lines of text beginning
with “/*” and ending with “*/”. These are symbols used for blocks of comments.
They tell the microcontroller not to use this when executing the program. Also
there is text that is preceded by two slashes “//”. This is used for shorter
comments; everything to the right of the two slashes on that line is a comment
and will be ignored when the program is executed. These two methods of adding
comments to a program are very useful and will be used in the examples that
follow to explain what’s going on at each step of the program.
/*
Blink
Repeatedly
turns on the LED for one second, then off for one second */
int
led = 13; //
give the LED a name
// the setup routine runs once when you
press reset:
void
setup() {
pinMode
(led, OUTPUT); // initialize the digital
pin as an output.
}
//
the loop routine runs over and over again forever:
void
loop() {
digitalWrite
( led, HIGH); // turn the LED on (voltage
level HIGH)
delay
(1000); // wait for a second
digitalWrite
(led, LOW); // turn the LED off (voltage
level
LOW)
delay(1000); // wait for a second
}
Upload
the program to the Arduino by clicking the “Upload” button in the IDE. Once the
program is uploaded you will see the LED blinking on and off every second. The
Arduino Uno board already has an LED attached to pin 13 on the board itself. If
you run this example with no hardware attached, you should see that LED blink
on and off.
Try
altering the delay lines in the program to alter the timing of the blinking.
You should note that the delay is in milliseconds so delay(1000) will give a
delay of one second, delay(10000) will give a delay of ten seconds, and so on.
So
far, you have connected the components to a breadboard, connected the
breadboard to the Arduino and uploaded a program to the Arduino. Having
successfully achieving this, you are now ready to try out different components.
RGB LED
The
red, green, blue (RGB) common anode LED has the ability to show a multitude of
colours. As the name suggests, it can be red, green or blue, or any combination
of these colours. This makes it very useful if we want to show different
colours by using just one LED or show an unusual colour (not red, green, or
blue). This type of LED has four pins; one for each colour and one that is the
common anode.
RGB Common
Anode LED
Looking
at the RGB LED, you will see that one of the pins is markedly longer than the
other three, this is the common anode. If you hold the LED so that there is
only one pin to the left of the common anode (as in the picture above), the
left pin is the red cathode, the pin directly right of the common anode is the
blue cathode and the pin on the extreme right is the green cathode.
Put
the LED into a breadboard and wire it to the Arduino as follows:
Red
pin to Arduino pin 9
Common
anode pin to Arduino pin 11 via a 220 ohm resistor
Blue
pin to Arduino pin 6
Green
pin to Arduino pin 3
RGB Common Anode Circuit
Diagram
The
following program is based on code written by Dain Unicorn and EgoPlast. You
can use the code as a basis for experimenting with the RGB component and
hopefully adapt it for inclusion in future, larger projects.
Upload
the following program code (also available from
http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html ):
byte
RedLED = 9; //red pin to Arduino pin 9
byte
BluLED = 6; //blue pin to Arduino pin 6
byte
GrnLED = 3; //green pin to Arduino pin 3
// define our variables...
int
RedFade;
int
BluFade;
int
GrnFade;
void
setup () {
//define
the pins as output....
pinMode
(11, OUTPUT); //common anode on Arduino pin 11
pinMode
(RedLED, OUTPUT);
pinMode
(BluLED, OUTPUT);
pinMode
(GrnLED, OUTPUT);
}
void
loop () {
digitalWrite(11,HIGH);
// Enable the circuit
analogWrite(RedLED,
255); //Turns off the RED Element
analogWrite(GrnLED,
255); //Turns off the GREEN Element
analogWrite(BluLED,
255); //Turns off the BLUE Element
delay(1000);
//
Red Element fade
for(int
fadeValue = 255 ; fadeValue >= 100; fadeValue -=5) { analogWrite(RedLED,
fadeValue);
delay(20);
}
for(int
fadeValue = 100 ; fadeValue <= 255; fadeValue +=5) { analogWrite(RedLED,
fadeValue);
delay(20);
}
//
Green Element Fade
for(int
fadeValue = 255 ; fadeValue >= 100; fadeValue -=5) { analogWrite(GrnLED,
fadeValue);
delay(20);
}
for(int
fadeValue = 100 ; fadeValue <= 255; fadeValue +=5) { analogWrite(GrnLED,
fadeValue);
delay(20);
}
//
Blue Element Fade
for(int
fadeValue = 255 ; fadeValue >= 100; fadeValue -=5) { analogWrite(BluLED,
fadeValue);
delay(20);
}
for(int
fadeValue = 100 ; fadeValue <= 255; fadeValue +=5) { analogWrite(BluLED,
fadeValue);
delay(20);
}
//
Red+Green Elements Fade
for(int
fadeValue = 255 ; fadeValue >= 100; fadeValue -=5) { analogWrite(RedLED,
fadeValue); analogWrite(GrnLED, fadeValue);
delay(20);
}
for(int
fadeValue = 100 ; fadeValue <= 255; fadeValue +=5) { analogWrite(RedLED,
fadeValue); analogWrite(GrnLED, fadeValue);
delay(20);
}
//
Green+Blue Elements Fade
for(int
fadeValue = 255 ; fadeValue >= 100; fadeValue -=5) { analogWrite(GrnLED,
fadeValue); analogWrite(BluLED, fadeValue);
delay(20);
}
for(int
fadeValue = 100 ; fadeValue <= 255; fadeValue +=5) { analogWrite(GrnLED,
fadeValue); analogWrite(BluLED, fadeValue);
delay(20);
}
//
Blue+Red Elements Fade
for(int
fadeValue = 255 ; fadeValue >= 100; fadeValue -=5) { analogWrite(RedLED,
fadeValue); analogWrite(BluLED, fadeValue);
delay(20);
}
for(int
fadeValue = 100 ; fadeValue <= 255; fadeValue +=5) { analogWrite(RedLED,
fadeValue); analogWrite(BluLED, fadeValue);
delay(20);
}
//
All Elements Fade
for(int
fadeValue = 255 ; fadeValue >= 100; fadeValue -=5) { analogWrite(RedLED,
fadeValue);
analogWrite(GrnLED,
fadeValue);
analogWrite(BluLED,
fadeValue);
delay(20);
}
for(int
fadeValue =100 ; fadeValue <= 255; fadeValue +=5) { analogWrite(RedLED,
fadeValue); analogWrite(GrnLED, fadeValue); analogWrite(BluLED, fadeValue);
delay(20);
}
analogWrite(RedLED,100);
analogWrite(GrnLED,50);
analogWrite(BluLED,0);
delay(1000);
}
Once
the sketch is running, you will see the LED fading between colours; pretty
cool, eh? This program, though relatively long, is organised into distinct
sections to show how the effects can be achieved. At this stage, you don’t need
to understand all what’s going on in the program, once you have more
experience, that’s when you’ll probably want to learn more.
Traffic Light
Display Module
These
small modules are designed for inclusion in model projects. As the name
suggests, they can be used in projects and simulations involving traffic
lights.
The
module consists of three LEDs; red, yellow and green. You will need to connect
these up to separate pins on the Arduino so that you can make them turn on and
off individually. In the example below, I have connected the LED pins as
follows:
Green
LED Arduino pin 8
Yellow
LED Arduino pin 9
Red
LED Arduino pin
10
We
need to decide on the sequence that the LEDs should turn on and off. Real
traffic lights (in the
Red
Red/Yellow
Yellow
Green
Yellow
By
putting pauses (delay commands) between each step of the sequence, you can
achieve a pretty good representation of real traffic lights.
Connect
the module to the Arduino as described and upload the following sketch:
int
GREEN = 8;
int
YELLOW = 9;
int
RED = 10;
void
setup() {
// put your setup code here, to run once:
pinMode(GREEN, OUTPUT);
pinMode(YELLOW, OUTPUT);
pinMode(RED, OUTPUT);
}
void
loop() {
digitalWrite (RED, HIGH);
delay(10000);
digitalWrite (YELLOW, HIGH);
delay(3000);
digitalWrite (RED, LOW);
digitalWrite (YELLOW, LOW);
digitalWrite (GREEN, HIGH);
delay(10000);
digitalWrite (GREEN, LOW);
digitalWrite (YELLOW, HIGH);
delay(3000);
digitalWrite (YELLOW, LOW);
}
You
will see that the sequence is continuously followed and, as the sketch is
mainly a loop, the sequence will just continue to run and run.
Try
experimenting by altering the delay times to achieve a more realistic
representation of real traffic lights.
10 Segment Bar
Graph LED
Connecting
the 10 segment bar graph LED to an Arduino and altering the display by using a
potentiometer will be examined. The example turns on the individual LEDs of the
module based on the value of an analog sensor. The example can also be
performed using 10 individual LEDs in place of the 10 segment bar graph LED.
Each
of the LED pins on one side of the module is connected to GND via a 220 ohm
resistor. The corresponding pins on the opposite side of the module are
connected to digital pins 2 to 11 on the Arduino. A potentiometer is connected
to Analog pin 0 as well as GND and 5V as shown in the diagram below.
/*
LED bar graph adapted from the Arduino
tutorial at http://www.arduino.cc/en/Tutorial/BarGraph
*/
//
these constants won't change:
const
int analogPin = A0; // the pin that the
potentiometer is attached to
const
int ledCount = 10; // the number of
LEDs in the bar graph
int
ledPins[] = {
2, 3, 4, 5, 6, 7, 8, 9, 10, 11
}; // an array of pin numbers to which LEDs are
attached
void
setup() {
// loop over the pin array and set them all
to output:
for (int thisLed = 0; thisLed < ledCount;
thisLed++) {
pinMode(ledPins[thisLed], OUTPUT);
}
}
void
loop() {
// read the potentiometer:
int sensorReading = analogRead(analogPin);
// map the result to a range from 0 to the number
of LEDs:
int ledLevel = map(sensorReading, 0, 1023, 0,
ledCount);
// loop over the LED array:
for (int thisLed = 0; thisLed < ledCount;
thisLed++) {
// if the array element's index is less
than ledLevel,
// turn the pin for this element on:
if (thisLed < ledLevel) {
digitalWrite(ledPins[thisLed], HIGH);
}
// turn off all pins higher than the
ledLevel:
else {
digitalWrite(ledPins[thisLed], LOW);
}
}
}
Upload
the program to the Arduino. As you turn the potentiometer, you will see that
the LEDs change according to the position of the potentiometer.
Rather
than a potentiometer, an analog sensor could be substituted and the data from
the sensor would be represented on the 10 segment bar graph module. Other
potential applications of the 10 segment bar graph include ……..
A
sensor, or detector, is a device that measures a physical quantity and coverts
it into a signal. This signal can then be read. Sensors are very common and are
all around us in everyday situations. They include devices for measuring
temperature, light, motion, humidity, moisture, vibration, electrical field,
magnetic field and sound.
In
this section, I have illustrated how to set up and use several of these
sensors. There are details of their connection to an Arduino as well as
explanations for using and/or manipulating their signal.
Elsewhere
in this book, I have documented how sensor data can be logged using various
software techniques and saved in different formats.
Tilt Sensor
A
tilt sensor can be a useful component in numerous projects. Fixed to objects,
it switches between two states if moved or tilted. The SW-520D is a simple ball
tilt switch which has two pins. With the two pins level, a 10° tilt will close
the contacts, thus altering the “state”.
As
well as the sensor, we will also attach an LED so that we will have a visual
indication of the sensors state. Firstly connect an LED to pin 13 and GND
directly on the Arduino. The rest of the wiring is straight forward i.e.
connect one of the pins of the sensor to ground and the other pin to a 10k ohm
pull up resistor and to Arduino pin 6.
Tilt Sensor Circuit
Diagram
Upload
the following program (also available from http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html
):
const
int sensorPin = 6; // tilt sensor pin
const
int ledPin = 13; // LED pin
int
sensorState = 0; // define our
variable
void
setup() {
Serial.begin(9600); // enable serial output and baud
rate
pinMode(ledPin,
OUTPUT); // define LED pin as
output
pinMode(sensorPin,
INPUT); // define sensor pin as
output
}
void
loop(){
String
s; // create a string variable called s
sensorState
= digitalRead(sensorPin); // state = value of the pin
Serial.print(sensorState);
Serial.println();
}
When
the sensor is moved, its state (either FLAT or TILT) will be displayed in the
Serial Monitor of the IDE and the light will flash correspondingly. Move the
breadboard that is housing the tilt sensor to see this happening.
TILT
SERIAL SHOT FROM IDE?
Temperature Sensor
Here,
we are going to use an LM35 precision analog temperature sensor. It has 3-pins;
5V, GND temperature.
As
you look at the flat face of the sensor with the pins hanging downwards, the
left pin is the 5V pin and should be attached to the 5V pin of the Arduino. The
right pin of the sensor is ground and should be connected to the Arduino GND
pin. Finally, the central pin should be connected directly to Analog input pin
0 of the Arduino. Notice that we are not using a breadboard here. This is
because if we were to use a breadboard, the temperature wouldn’t be very
stable. If you must use a breadboard, you would be well advised to add some
sort of filter.
Temperature Sensor
Circuit Diagram
Upload
the following and open the Serial Monitor. You should see the temperature
reading value being updated every second. If you grab hold of the sensor or
breathe on it, you should see the temperature rise. Try altering the delay so
that you see the temperature being updated at different intervals (remember
that this is milliseconds so delay(1000); pauses for one second).
#define
tempPin 0 // sensor attached
to analog pin 0
int
Temp = 0; // set up a
variable
void
setup() {
Serial.begin(9600); // enable serial output and baud rate
}
void
loop(){
analogRead(tempPin); // read the pin value
Temp
= (5.0 * analogRead(tempPin) * 100.0) / 1024;
//see below
Serial.print("Temp
"); // print “Temp”
Serial.print(Temp); // print the value
Serial.println(""); // print a blank line
delay(1000); // wait 1 second
}
When
the Arduino is using the 5V reference with 10bit analog to digital conversion
(ADC) it has a 1024 count. Therefore, we have to perform the following
calculation on the sensor measurement to give true temperature in Centigrade.
Temp
= (5.0 * analogRead(tempPin) * 100.0) / 1024
Look
at the following lines of code:
Serial.print("Temp
"); // print the word “Temp” in
the Serial
Monitor
Serial.print(Temp); // print the value in the Serial
Monitor
Serial.println(""); // print a blank line in the
Serial Monitor
Rather
than just have a number being displayed, I have added a couple of lines so the
word “Temp” is displayed before the value and " degrees centigrade"
after the value. I have also included a line to print a blank line.
Temperature Serial
Monitor Display
This
makes the display look neater and easier to read. Try adding some different
text or more spaces. You could also try altering the time between readings.
You
could use the temperature sensor as part of a la4rger weather station project.
Light Sensor
Light
sensors, also known as photo resistors or light dependant resistors (LDR) are
generally quite basic and un-calibrated. In this example, I have used a GL5537
LDR but there are plenty of others that perform equally as well. The LDR
changes its resistance depending on the amount of light and we can measure this
change using one of the Arduino analog pins.
The
LDR has only two pins so connect one of these pins to GND (ground) and the
other pin to a 10k ohm pull up resistor and to Arduino
analog pin 0 as shown below.
Photo Resistor Circuit
Diagram
Upload
the following program (also available from
http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html ) and open
the Serial Monitor.
#define
lightPin 0 //
data pin
int
Light = 0; //
our variable
void
setup() {
Serial.begin(9600); //
enable serial output and baud rate
}
void
loop(){
analogRead(lightPin); //
read the pin value
Light
= analogRead(lightPin); //
Light variable = value that was read
Serial.println
(Light); //
Print the value in the Serial Monitor
delay(1000); // Wait for 1 second
}
Placing
your hand (or piece of paper) over the sensor results in a change of values
displayed. The more light, the lower the reading.
As
the measured resistance varies greatly from bright light to darkness, we need
to either use a lookup table or perform calculations on the readings to convert
to lux values.
The
following program converts the measurements to lux (also available at
http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html ):
#define
lightPin 0
int
Light = 0;
void
setup() {
Serial.begin(9600);
}
void
loop()
{
Light
= toLux(analogRead(lightPin)); //perform
conversion
Serial.println
(Light);
delay(1000);
}
//
Change the ADC reading to lux.
/* Vcc 5
Pullup 10000
lux ohms Voltage ADC Scaling
0 1023
1 200000 4.76 975 -0.020937188
10 30000 3.75 768 -0.043428309
80 5000 1.67 341 -0.1640625
120 4000 1.43 293 -0.8203125
150 3000 1.15 236 -0.533203125
250 2000 0.83 171 -1.5234375
300 1800 0.76 156 -3.45703125
800 700 0.33 67 -5.604580966
*/
int
toLux(int adc)
{
//return
(map(adc, 0, 1023, 900, 0)); simple linear model
if
(adc > 868)
return
300 + 5.6 * (adc - 868); else if (adc > 853)
return
250 + 3.46 * (adc - 853); else if (adc > 788)
return
150 + 1.52 * (adc - 788); else if (adc > 731)
return
120 + 0.53 * (adc - 731); else if (adc > 683)
return
80 + 0.82 * (adc - 683); else if (adc > 256)
return
10 + 0.16 * (adc - 256); else
return
0.04 * adc;
}
The
first program (without the conversion to lux) would be sufficient if you just
want to detect the difference between light and shadow, if a light is on or off
or there is just a change in brightness.
These
inexpensive sensors can be readily bought on the internet. They can be used as
part of larger projects such as monitoring light around the home and switching
lights on and off depending on levels of light detected.
DHT-11 Temperature
and Humidity Sensor
A
very popular sensor that you may wish to use is the DHT-11 humidity sensor.
This is a digital humidity and temperature sensor and has four pins. The
measurement resolution of this module is 1°C or 1% relative humidity. Here, it
will just be used for measuring relative humidity; measurement of temperature is better done with the more
accurate and sensitive LM35 (see previous).
Simply
connect Data pin to Arduino digital input pin 7 and the indicated pins to +5V
and GND as illustrated.
Humidity Sensor Circuit
Diagram
In
this example we will be using a library as part of the code. Libraries provide
extra functionality for use in programs and are referenced from within the
program. You will need to download the DHT 11 library and install it.
https://github.com/ghadjikyriacou/DHT11lib/blob/master/dht11.h
Instructions
for installing Arduino libraries can be on the Arduino website found at
http://arduino.cc/en/Guide/Libraries . Once the library has been installed,
upload the following code (also available from
http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html ) and open
the Serial Monitor:
#include
“dht11.h” // use the dht11 library
int
Humidity, hCheck;
#define
humidityPin 7 // define humidity pin
as pin 7
dht11
DHT11;
void
setup()
{
pinMode(10,
OUTPUT);
Serial.begin(9600);
}
void
loop()
{
hCheck
= DHT11.read(humidityPin);
if(hCheck
!= 0)
Humidity
= 255; //this must be an error else
Humidity
= DHT11.humidity;
Serial.print
(Humidity); //print the measurement
Serial.print
(" % Relative Humidity"); //print
some text
Serial.println
(""); //print a
blank line
delay
(1000); //wait for 1 second
}
You
will see that the humidity measurement is updated in the Serial Monitor once
every second.
Serial Monitor
Display of Humidity Measurements
If
you breathe on the detector, you should see the humidity measurement change.
Try altering the delay interval or the way that the data is displayed in the
Serial Monitor. This sensor can be used in conjunction with other sensors/modules
as part of larger projects, for example a weather monitoring station.
PIR Motion
Detector
PIR motion detectors are widespread as they are used in many
security systems to detect events such as trespass or other motion. The modules
themselves are quite inexpensive and can be readily bought from numerous
sources on the internet.
They have a range of detection of about 6–7m and are highly sensitive. When
the PIR motion sensor detects
motion, it outputs a 5V signal to the Arduino and
triggers an interrupt. The circuit diagram is relatively simple:
PIR Motion Detector
Wiring Diagram
Connect
the input pin to Arduino pin 2, GND to GND and 5V to 5V. I have also added an
LED to pin 13, which has also been connected to GND.
Once
the circuit is set up, construct an Arduino sketch similar to the one below.
int
ledPin = 13; // the pin for the LED
int
inputPin = 2; // input pin (for PIR sensor)
int
pirState = LOW; //
we start, assuming no motion detected
int
val = 0; // variable for reading the pin
status
void
setup() {
pinMode(ledPin, OUTPUT); //
declare LED as output
pinMode(inputPin, INPUT); //
declare sensor as input
Serial.begin(9600);
}
void
loop(){
val = digitalRead(inputPin); //
read input value
if (val == HIGH) { //
check if the input is HIGH
digitalWrite(ledPin, HIGH); //
turn
if (pirState == LOW) { // we have just turned on
Serial.println("Motion detected!"); // We only want to print on the
output change, not state
pirState = HIGH;
}
} else {
digitalWrite(ledPin, LOW); // turn LED OFF
if (pirState == HIGH){ // we have just turned off
Serial.println("Motion
ended!"); // We only
want to print on the output change, not state
pirState = LOW;
}
}
}
If
motion is detected the LED turns on. If no motion is detected, the LED remains
turned off.
I
have developed this simple sketch further. When motion is detected a message is
displayed in the serial monitor, an LED is lit and a IR signal is sent to a
camera instructing it to take a
photograph.
This would be a great application for say photographing wildlife, birds in
motion and sporting events.
I
tried this out by setting up my camera close to a garden bird feeder. When a
bird triggered the sensor, the camera took a photograph. There is not much
extra coding needed to be added to the previous sketch as you will see below.
You will have to experiment with the camera settings and remove any latency in
the set up. To decrease latency, writing to the serial port and switching the
LED on and off could be removed from the sketch.
You
will have to include the multiCameraIrControl.h library and select your own
camera so that the IR emitter sends the correct code.
Connections
are as follows:
The
PIR is connected to digital pin 4
The
LED is connected to digital pin 9 via a 220 ohm resistor
The
IR is emitter connected to pin 13 (long arm) and grounded (short arm)
Arduino
sketch:
#include
<multiCameraIrControl.h>
Nikon
D5000(13); // digital pin 13 for
IR Emitter
int
inputPin = 4; // digital pin 4 for PIR
int
ledPin = 9; // digital pin 9 for LED
int
pirState = LOW; // we start, assuming no motion detected
int
val = 0;
void
setup(){
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inputPin, INPUT); // declare sensor as input
Serial.begin(9600);
}
void
loop(){
val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin, HIGH); // turn
if (pirState == LOW) { // we have just turned on
Serial.println("Motion
detected!");// We only want to print on the output change, not state
pirState = HIGH;
D5000.shutterNow(); //This sends the signal for
the camera to take a photograph
}
}
else {
digitalWrite(ledPin, LOW); // turn LED OFF
if (pirState == HIGH){ // we have just turned off
Serial.println("Motion
ended!") // We only want to print
on the output change, not state
pirState = LOW;
}
}
As
shown above, these modules are quite straightforward to use and can be
incorporated into many projects, for instance in security or robotic
applications.
Ultrasound Distance Measurement
The HC-SR04 ultrasonic sensor uses sonar to determine distance to an
object. It offers excellent non-contact range detection with high accuracy and
stable readings. The range is from 2cm to 400 cm (1” to 13 feet).
There
are four pins on the sensor module and these should be connected to as follows:
HC SR04 Arduino
VCC 5v
GND GND
Echo
pin
7
Trig pin
8
Ultrasound Sensor Wiring
Diagram
The
sketch was compiled from referencing many similar sketches that are available
in the public domain.
Arduino
sketch:
#define
echoPin 7 //
Echo Pin
#define
trigPin 8 //
Trigger Pin
#define
LEDPin 13
// Onboard LED
int
maximumRange = 200;
// Maximum range needed
int
minimumRange = 0;
// Minimum range needed
long
duration, distance;
// Duration used to calculate distance
void
setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
}
void
loop() {
digitalWrite(trigPin,
LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
//Calculate the distance (in cm) based on the
speed of sound.
distance = duration/58.2;
if (distance >= maximumRange || distance
<= minimumRange){
/* Send a negative number to computer and Turn
LED OFF
to indicate "out of range" */
Serial.println("-1");
digitalWrite(LEDPin, LOW);
}
else {
/* Send the distance to the computer using
Serial protocol, and
turn
Serial.println(distance);
digitalWrite(LEDPin, HIGH);
}
//Delay 500ms before next reading.
delay(500);
}
If
you upload the sketch and then open the serial monitor you will see the output.
By moving an object to various distances in front of the detector, you should
see the distance displayed changed as in the screen shot below.
The
serial plotter can be used to show trends, as illiustrated below:
The
HC SR04 Ultrasonic Sensor can be used in many projects. One that springs to
mind would be to use it in a model car or robot as part of a collision
avoidance feature.
Soil Moisture
Sensor
This sensor measures
the volumetric content of water in the soil and gives the moisture level as output. The sensor is equipped with both analog and digital output, so it
can be used in both analog and digital mode.
Below
is a schematic diagram of the Arduino circuit, though for convenience, I used a
solderless breadboard.
Soil Moisture Sensor
Connections
Once
the circuit has been set up, construct an Arduino sketch similar to the one
below and upload it to the Arduino.
void
setup() {
Serial.begin(9600); // initialize serial communication at
9600 bits per second
}
void
loop() {
int sensorValue = analogRead(7)/10; // read the input on analog pin 7 and divide the value by 10
Serial.print("Moisture Reading
");
Serial.print(sensorValue); // print out the value
Serial.println (" ");
delay(2000); // delay between readings for
stability
}
Once
the sketch is uploaded, open the serial monitor.
Soil Moisture Detector
Serial Monitor Output
Though
the accuracy of these sensors is questionable, they can still be used in
various projects that require soil moisture level data.
An
advanced project maybe to monitor the moisture level in a plant pot and if the
level falls below a certain level, you could trigger a pump to deliver a
certain amount of water. This would be a good way of caring for you houseplants
whilst on holiday.
Sound Sensor
A sound sensor can, and is, a very useful
item. It can be used to trigger lights, doors, alarms etc or even used to
control a smart vehicle.
The sensor detects sound through a
microphone and this sound is passed through a LM393 op amp. The particular one
used here has an operating voltage of 3.3V-5V and has a signal output indicator
LED which comes on when a sound is detected. The output is low when there is
sound and high when there is no sound (i.e. LOW and HIGH pin states
respectively.
The three pin version of
this module connects to the Arduino as follows:
VCC 5V
GND GND
OUT Digital pin 8
As
the output is digital, we can only detect when there is sound detected or not.
If we wanted to detect relative levels of sound, we would need a module that
has an analog output.
Connect the module
to your Arduino as above and then connect the Arduino to your computer. Compile
a sketch to read the digital state of the input on pin 8. Here is sketch that I
have compiled:
int
soundDetectedPin = 8;
int
soundDetectedVal = HIGH;
void
setup()
{
Serial.begin(9600);
pinMode
(soundDetectedPin, INPUT) ;
}
void
loop()
{
soundDetectedVal = digitalRead (soundDetectedPin)
;
digitalRead(soundDetectedPin);
if
(soundDetectedVal == HIGH)
Serial.println("Quiet");
else
if (soundDetectedVal == LOW)
Serial.println("Noise");
delay
(1000);
}
Once uploaded onto
the Arduino, open the Serial Monitor and make some noise. You will see that the
message changes as the sensor detects the sounds. You may need to alter the
sensitivity by using the onboard potentiometer.
By
making the delay shorter, the system will become more responsive.
The
following sketch is a bit more complex and has been adapted from the one at
Henry’s Bench: http://henrysbench.capnfatz.com/henrys-bench/arduino-sensors-and-input/arduino-sound-detection-sensor-tutorial-and-user-manual/
int
soundDetectedPin = 8; //
Use Pin 8 as input
int
soundDetectedVal = HIGH; // sound
measurement
boolean
bAlarm = false;
unsigned
long lastSoundDetectTime; // Record the time that the sound was measured
int
soundAlarmTime = 500; // Number of milliseconds to keep the sound alarm high
void
setup ()
{
Serial.begin(9600);
pinMode (soundDetectedPin, INPUT) ; // input from the Sound Detection
Module
}
void
loop ()
{
soundDetectedVal = digitalRead
(soundDetectedPin) ; // read the
sound alarm time
if (soundDetectedVal == LOW) // If
we hear a sound
{
lastSoundDetectTime = millis(); // record the time of the sound
alarm
// The following is so you don't scroll on the
output screen
if (!bAlarm){
Serial.println("SOUND
DETECTED");
bAlarm = true;
}
}
else
{
if( (millis()-lastSoundDetectTime) >
soundAlarmTime && bAlarm){
Serial.println("quiet");
bAlarm = false;
}
}
}
Load
the sketch and open the Serial Monitor. Initially, nothing will be displayed.
Make some noise and "SOUND DETECTED” will be displayed. This will remain
onscreen until sound ceases to be detected; then "quiet" will be
displayed. Here is a screenshot that I achieved by turning a radio on and off:
This module could be used
in projects for home security or traffic safety.
Microwave Radar Sensor
This module uses Doppler
radar technology and has auto-sensing capabilities. It has high sensitivity,
with a sensing distance of about 10 meters.
These sensors are widely
used in automatic lighting systems and anti-theft alarms. As this module uses a Doppler radar sensor, the
target must be moving toward or away from the sensor for activation to occur.
By triggering a sound/light signal when the
module detects movement, the module can be integrated into larger projects.
Connect the sensor to the
Arduino as follows:
XXXXXXXX
Using the same sketch as
for the PIR sensor earlier:
int ledPin = 13; //
the pin for the LED
int inputPin = 2; // input pin (for PIR sensor)
int pirState = LOW; // we start, assuming no motion
detected
int val = 0; // variable for reading
the pin status
void setup() {
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inputPin, INPUT); // declare sensor as input
Serial.begin(9600);
}
void loop(){
val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin, HIGH); // turn
if (pirState == LOW) { // we have just turned on
Serial.println("Motion detected!") ;
// We only want to print on the output change, not state
pirState = HIGH;
}
} else {
digitalWrite(ledPin, LOW); // turn LED OFF
if (pirState == HIGH){ // we have just turned off
Serial.println("Motion
ended!"); // We only want to print
on the output change, not state
pirState = LOW;
}
}
}
Upload the sketch and open
the serial monitor and move an object intermittently in front of the detector.
You should see something similar to the diagram below.
Think of a project that can utilise the functionality
of this module. Maybe a project involving security, safety lighting of
industrial control could be developed.
Reed Sensor
The Reed sensor module is also
known as a magnetron module or reed switch.
It has a working voltage
3.3V-5V, with a digital output which is capable of switching output (0 and 1)
This module can be
incorporated into program-controlled switches, copiers, washing machines,
refrigerators, cameras, electromagnetic relays, electronic weighing scales,
level meters, gas meters, water meters and so on
WIRING XXXXXXXXXXXXXXXX
Sketch
int Reed = 8;
int val ;
void setup ()
{
Serial.begin(9600);
pinMode (Reed, INPUT);
}
void loop ()
{
val = digitalRead (Reed) ;
if (val == HIGH)
{
Serial.println("Switch closed");
}
else
{
Serial.println("Switch open");
}
delay(2000);
}
Hall
Effect Sensor
A Hall Effect sensor is a
transducer that varies its output voltage in response to a magnetic field. Hall
effect sensors are used for proximity switching, positioning, speed detection,
and current sensing applications.[1]
In a Hall Effect sensor, a
thin strip of metal has a current applied along it. In the presence of a
magnetic field, the electrons in the metal strip are deflected toward one edge,
producing a voltage gradient across the short side of the strip (perpendicular
to the feed current). Hall effect sensors have an advantage over inductive
sensors in that, while inductive sensors respond to a changing magnetic field
which induces current in a coil of wire and produces voltage at its output,
Hall effect sensors can detect static (non-changing) magnetic fields.
Connect the VCC of the
sensor to the 5V pin of the Arduino. Connect GND to GND and connect the AO to
pin of the sensor to Analog pin 0 of the
Arduino. Upload the following sketch.
int sensorPin = A0; // input pin for the sensor
int sensorValue = 0; // variable for the sensor value
void setup() {
Serial.begin(9600);
pinMode (sensorPin, INPUT)
;
}
void loop() {
// read the value from the sensor:
sensorValue = analogRead(sensorPin);
Serial.println(sensorValue);
delay(100);
}
Open the Serial plotter.
You will see that every 100 milliseconds, a value will appear. This is the
analog value of pin 10 (the Hall sensor). By moving a magnet various distances
from the Hall sensor, you will see the values change.
To illustrate the changing
magnetic field, close the serial monitor and open Maker Plot. Select the
correct port and baud rate. Alter the values of the x and y axes to cater for
your data and begin collecting.
The Hall Effect sensor
analog values are plotted in black. As the magnet gets nearer to the sensor,
the analog value decreases.
Applications
xxx
Heartbeat Sensor
uses
bright infrared (IR) LED and a phototransistor to detect the pulse of the
finger, a red LED flashes with each pulse. Pulse monitor works as follows: The
LED is the light side of the finger, and phototransistor on the other side of
the finger, phototransistor used to obtain the flux emitted, when the blood
pressure pulse by the finger when the resistance of the photo transistor will
be slightly changed. The project's schematic circuit as shown, We chose a very
high resistance resistor R1, because most of the light through the finger is
absorbed, it is desirable that the phototransistor is sensitive enough. Resistance
can be selected by experiment to get the best results. The most important is to
keep the shield stray light into the phototransistor. For home lighting that is
particularly important because the lights at home mostly based 50HZ or 60HZ
fluctuate, so faint heartbeat will add considerable noise.
When
running the program the measured values are printed. To get a real heartbeat
from this could be challenging.
Sound Sensing:
Piezoelectric Element
A Piezoelectric element can be used to detect vibration, in this case, a
knock on a door, table, or other solid surface. It’s an electronic device that
generates a voltage when it's physically deformed by a vibration, sound wave,
or mechanical strain. Similarly, when you put a voltage across a piezo, it
vibrates and creates a tone. Piezoelectric elements can be used both to play
tones and to detect tones.
Piezoelectric elements are polarized, meaning that
voltage passes through them (or out of them) in a specific direction. Connect
the black wire (the lower voltage) to ground and the red wire (the higher
voltage) to analog pin 0. Additionally, connect a 1-megohm resistor in parallel
to the Piezo element to limit the voltage and current produced by the
piezoelectric element and to protect the analog input. Piezoelectric
elements are polarized, meaning that voltage passes through them (or out of
them) in a specific direction.
It
is possible to acquire piezoelectric
elements without a plastic housing. These will look like a metallic
disc, and are easier to use as input sensors. PIezo sensors work best when
firmly pressed against, taped, or glued their sensing surface.
The
sketch below reads the piezoelectric output using the analogRead() command,
encoding the voltage range from 0 to 5 volts to a numerical range from 0 to
1023 in a process referred to as analog-to-digital conversion, or ADC.
If the sensor output is stronger than a certain threshold, your board
will send the string "Knock!" to the computer over the serial
port.Try raising or lowering this value to increase your sensor's overall
sensitivity.
Connect the black wire (the lower voltage) to ground
and the red wire (the higher voltage) to analog pin 0. Additionally, connect a
1-megohm resistor in parallel to the piezoelectric element to limit the voltage
and current produced by the piezo and to protect the analog input.
It
is possible to acquire piezo elements without a plastic housing. These will
look like a metallic disc, and are easier to use as input sensors. PIezo
sensors work best when firmly pressed against, taped, or glued their sensing
surface.
https://www.arduino.cc/en/tutorial/knock
In
the code below, the incoming piezo data is compared to a threshold value set by
the user. Try raising or lowering this value to increase your sensor's overall
sensitivity.
/* This sketch reads a piezo element to detect a
knocking sound. It reads an analog pin and compares the result to a set
threshold. If the result is greater than the threshold, it writes "knock"
to the serial port, and toggles the LED on pin 13.
The circuit:
- positive connection of the piezo
attached to analog in 0
- negative connection of the piezo
attached to ground
- 1 megohm resistor attached from
analog in 0 to ground
*/
//
these constants won't change:
const
int ledPin = 13; // LED connected to
digital pin 13
const
int knockSensor = A0; // the piezo is connected to analog pin 0
const
int threshold = 100; // threshold value
to decide when the detected sound is a knock or not
//
these variables will change:
int
sensorReading = 0; // variable to
store the value read from the sensor pin
int
ledState = LOW; // variable used
to store the last LED status, to toggle the light
void
setup() {
pinMode(ledPin, OUTPUT); // declare the
ledPin as as OUTPUT
Serial.begin(9600); // use the serial port
}
void
loop() {
// read the sensor and store it in the
variable sensorReading:
sensorReading = analogRead(knockSensor);
// if the sensor reading is greater than the
threshold:
if (sensorReading >= threshold) {
// toggle the status of the ledPin:
ledState = !ledState;
// update the LED pin itself:
digitalWrite(ledPin, ledState);
// send the string "Knock!" back
to the computer, followed by newline
Serial.println("Knock!");
}
delay(100);
// delay to avoid overloading the serial port buffer
}
Gas
Sensor
MQ2 is one of the commonly
used gas sensors in MQ sensor series. ... MQ2 Gas sensor works on 5V DC and
draws around 800mW. It can detect LPG, Smoke, Alcohol, Propane, Hydrogen,
Methane and Carbon Monoxide concentrations anywhere from 200 to 10000ppm.
Atmospheric Pressure (Altimeter)
xxx
Capacitive Touch
Sensor
The
TTP233B capacitive touch sensor can be used as an alternative to the tactile
push button in numerous applications.
WIn the normal
state, the module output low, low power consumption; When a finger touches the
corresponding position, the module output high, if not touched for 12 seconds,
switch to low-power mode. Low power consumption
Power supply for 2 ~ 5.5V
DC
Can replace the traditional
touch of a button
.
Blah
blahxxxxxxxxxxxxxx
/*
Author:
Danny van den Brande. Arduinosensors.nl. BlueCore Tech.
Hello
world! Today i made a code for the TTP233B capacitive touch sensor.
Its
very simple and you can toggle on and off a led/relay or whatever you wanna
add.
*/
#define
TouchSensor 9 // Pin for capactitive touch sensor
int
relay = 2;
boolean
currentState = LOW;
boolean
lastState = LOW;
boolean
RelayState = LOW;
void
setup() {
Serial.begin(9600);
pinMode(relay, OUTPUT);
pinMode(TouchSensor, INPUT);
}
void
loop() {
currentState = digitalRead(TouchSensor);
if (currentState == HIGH &&
lastState == LOW){
Serial.println("pressed");
delay(1);
if (RelayState == HIGH){
digitalWrite(relay, LOW);
RelayState = LOW;
} else {
digitalWrite(relay, HIGH);
RelayState = HIGH;
}
}
lastState = currentState;
}
Flame Detection
Sensor
The
4 pin flame detection sensor is generally an infrared (IR) receiver which can
detect IR radiation between 760 nm and 1100 nm.
To
test the module, a flame should be set of approximately 80cm from the sensor.
If using a flame larger than that given by a lighter, this will be detected at
a greater distance.
The
module has a detection angle of 60 degrees and sensitivity is adjustable using
the on-board digital potentiometer. It has an operating voltage of 3.3V to 5V
and outputs of both digital and analog.
VCC:
VCC 3.3-5V.
GND:
GND.
DO:
TTL switch signal output.
AO:
Analog Output.
void
setup()
{
Serial.begin(9600);
}
void
loop()
{
analogRead(A0);
Serial.println(analogRead(A0));
delay
(200);
}
summary
Sensor Wrap
This
has been a brief introduction to some very useful sensors; hopefully you have
been inspired to experiment with them. Try attaching more than one to the
Arduino, not forgetting that you will have to amalgamate the code for each
individual sensor.
There
are many other (mostly inexpensive) sensors on the market that you may wish to
investigate.
Accelerometer and
Gyroscope
Image
The MPU 6050 module has a 3-axis
accelerometer, a 3-axis gyroscope and a temperature sensor built into a single
chip called an inertial measurement unit (IMU). This module is also called
six-axis motion tracking device or 6 DoF (six Degrees of Freedom) device,
because of its 6 outputs, or the 3 accelerometer outputs and the 3 gyroscope
outputs.
Connect the MPU 6050 module to the
Arduino as follows:
MPU 6050 Arduino
VCC: +5V
GND: GND
SCL: Analog
pin 5
SDA: Analog
pin 4
XDA: Not
connected
XCL: Not
connected
INT: Digital
pin 2
Connect a 4.7k ohm resistor between SCL
and ground, and another 4.7k ohm resistor between SDA and ground.
We will need sketch that will be capable
of getting the seven data readings and displaying them on the serial monitor.
The sketch will collect the following:
AcX: accelerometer reading in the X
direction
AcY: accelerometer reading in the Y
direction
AcZ: accelerometer reading in the Z direction
Tmp: temperature reading
GyX: gyroscope reading about the X-axis
GyY: gyroscope reading about the Y-axis
GyZ: gyroscope reading about the Z-axis
The following was adapted from the
example by Jeremy S. Cook at https://www.arrow.com/en/research-and-events/articles/arduino-accelerometer-tutorial-adding-input-to-your-project
(accessed 31 September 2019).
#include<Wire.h>
const int MPU_addr=0x68; // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
Wire.begin();
Wire.beginTransmission(MPU_addr);
Wire.write(0x6B); // PWR_MGMT_1
register
Wire.write(0); // set to zero
(wakes up the MPU-6050)
Wire.endTransmission(true);
Serial.begin(9600);
}
void loop(){
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B); // starting
with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr,14,true);
// request a total of 14 registers
AcX=Wire.read()<<8|Wire.read();
// 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY=Wire.read()<<8|Wire.read();
// 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ=Wire.read()<<8|Wire.read();
// 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp=Wire.read()<<8|Wire.read();
// 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX=Wire.read()<<8|Wire.read();
// 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY=Wire.read()<<8|Wire.read();
// 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ=Wire.read()<<8|Wire.read();
// 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
Serial.print(" | AcX = "); Serial.print(AcX);
Serial.print(" | AcY = "); Serial.print(AcY);
Serial.print(" | AcZ = "); Serial.print(AcZ);
Serial.print(" | Tmp = ");
Serial.print(Tmp/340.00+36.53);
//equation for temperature in degrees C from datasheet
Serial.print(" | GyX = "); Serial.print(GyX);
Serial.print(" | GyY = "); Serial.print(GyY);
Serial.print(" | GyZ = "); Serial.println(GyZ);
delay(333);
}
Copy and upload the sketch to the Arduino
and open the serial monitor.
Each of the seven sensor data readings
appear on a single line. The next readings appear every third of a second
(333ms). If you move the sensor in various directions and planes, the values will
change.
The data collection can also be viewed by
making use of the Maker Plot standard interface. Here, as above, the data sets
are reported on a single line every third of a second.
As plotting multiple data sets in Maker
Plot requires serial data to be comma-delimited, you will need to alter the
serial print statements in the Arduino sketch to add commas. Below is a simple
way to do this:
Serial.print (AcX);
Serial.print(",");
Serial.print(AcY);
Serial.print(",");
Serial.print(AcZ);
Serial.print(",");
Serial.print(AcZ);
Serial.print(",");
Serial.print(Tmp/340.00+36.53);
Serial.print(",");
Serial.print(GyX);
Serial.print(",");
Serial.print(GyY);
Serial.print(",");
Serial.print(GyZ);
Once the new sketch is uploaded to the
Arduino, Maker Plot can be opened and a graphical representation of the sensor
data can be seen. If the sensor is moved to different positions and to
different orientations, each line being plotted will change (except, maybe, for
the temperature data set). You should observe a plot similar to the one below.
Summary and applications xxxxxxxxxxxx
We
are all familiar with typing on a keyboard or clicking a mouse to relay
information to some sort of processor. Here we will look how we can connect a
component to the Arduino, press something and then have the Arduino act
accordingly. Firstly we will use the most simple of these components, the
momentary tactile push button switch, then we will progress to a variety of
other input devices.
Push Button Switch
Push
button switches are easy to set up and can be used in innumerable situations.
When pressed, they connect two points in a circuit. This basic example turns on
an LED when the button is pressed. As well as breadboard, wires and the button
itself, you will need a 10k ohm resistor. Here is the circuit diagram:
Push Button Switch and
LED Circuit Diagram
Upload
the following program that is based on the button example on the Arduino
website at http://arduino.cc/en/tutorial/button (also available at
http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html ):
const
int buttonPin = 2; //
the pushbutton pin
const
int ledPin = 13; //
the LED pin
//
variables will change:
int
buttonState = 0; //
variable for reading the pushbutton status
void
setup() {
pinMode(ledPin,
OUTPUT); //
initialize the LED pin as an output
pinMode(buttonPin,
INPUT); //
initialize the pushbutton pin as an input
}
void
loop(){
buttonState
= digitalRead(buttonPin); //
read the state of the pushbutton
//if
pushbutton, the buttonState is HIGH:
if (buttonState == HIGH) {
digitalWrite(ledPin,
HIGH); //
turn LED on
}
else
{ digitalWrite(ledPin, LOW); // turn LED
off
}
}
This
basic circuit and program can serve as part of much more complex projects. Try
building a circuit that incorporates a push button (or more than one button)
with an LCD to turn the LCD on and/or off. You can use other component and
control them by push bouttons.
Potentiometer
A potentiometer is a simple knob/dial that provides a
variable resistance. The result of varying the resistance in a system can then
be read by the Arduino as an analog value.
The circuit set up for
the following example is quite simple.
Potentiometer Connection
Diagram
Attach the centre pin of a potentiometer to
pin A1, and the outside pins to +5V and ground. Upload and run the following
sketch.
void
setup() {
Serial.begin(9600); // initialize serial communication at 9600 bits per
second:
}
void
loop() {
int sensorValue = analogRead(A1);
// read the input on analog pin 1
Serial.println(sensorValue); // print value
delay(1000); // delay 1 second between reads for
stability
}
Once
the sketch is uploaded, open the serial monitor. If you turn the knob on the
potentiometer you will see the values change either up or down depending on
whether you turn the knob clockwise or anticlockwise.
Potentiometer Serial
Monitor Output
Once
you are more experienced and building projects that contain several components,
I’m sure that you will find the need to use at least one potentiometer.
4x4 Matrix Keypad
The
4x4 matrix keypads are very accessible and you can pick them up quite cheaply
on the internet. They are used extensively in industry and can be easily
incorporated into numerous projects.
The
arrangement of the keys is
1
2 3 A
4
5 6 B
7
8 9 C
*
0 # D
There
is a ribbon with 8 wires running from the bottom of the keypad. With the keypad
face up, the wires connect in sequence from left to right to Arduino digital
pins 2 - 9. Don't use digital pins 0 and 1 on the Arduino Uno, since they are
used for serial communication.
The
Arduino Keypad library (Keypad.h ) is available from the Arduino Playground.
Note:
I also have an I2C version of this example (01/24/13).
The
following code is based on that by http://bradsduino.blogspot.co.uk and
illustrates the basic functionality. Upload the program (also available from
http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html ) and open
the Serial Monitor.
#include
<Keypad.h>
const
byte ROWS = 4;
const
byte COLS = 4;
char
keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte
rowPins[ROWS] = {2,3,4,5}; //connect to row pinouts byte colPins[COLS] =
{6,7,8,9}; //connect to column pinouts
Keypad
keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void
setup(){
Serial.begin(9600);
}
void
loop(){
char
key = keypad.getKey();
if
(key != NO_KEY){
Serial.println(key);
}
}
As
each key is pressed, the key’s corresponding character appears on a separate
line in the Serial Monitor. This is very useful and can be incorporated into
numerous projects. For example, press a particular key, do something; press
another key, do something else. Try experimenting by incorporating different
components elsewhere in this book and their programs to develop your own unique
projects.
Button Matrix
xxx
Sound
is all around us and it is very useful as an indicator or as a warning. Think
of the beeping at a zebra crossing, a fire alarm, a police siren; all
distinguishable and all memorable. We may want to use sound in our future
projects so this chapter will introduce you to two very basic, but highly
versatile components.
Continuous Buzzer
A
continuous buzzer can have many uses and are a very convenient way of adding
sound or alarms to projects.
5V Continuous Buzzer
The
5 volt continuous buzzer has only two pins so we need to connect the shorter
one to GND and the other to a digital pin on the Arduino; in this example it is
connected to digital pin 13.
Once
you have connected the buzzer, load the following simple program (also
available from
http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html ):
int
buzzer = 13; //define buzzer pin
void
setup()
{
pinMode(buzzer,
OUTPUT); //buzzer pin as OUTPUT
}
void
loop() {
digitalWrite(buzzer,
HIGH); // make voltage HIGH,
turn the LED on
digitalWrite(buzzer,
LOW); // make voltage LOW, turn
the LED off
delay(1000); // wait for a second
}
This
very simple program turns the buzzer on, then off, then waits for a second
before repeating. Experiment by altering the delay time and putting extra delay
commands into the program. For instance edit the program so that it looks like
the following and see the difference of adding just one extra delay command:
int
buzzer = 13; //define buzzer pin
void
setup()
{
pinMode(buzzer,
OUTPUT); //buzzer pin as OUTPUT
}
void
loop() {
digitalWrite(buzzer,
HIGH); // turn the LED on by making the voltage HIGH
delay(1000); // wait for a second
digitalWrite(buzzer,
LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
With
some imagination and dedication, I’m sure that you can design a project that
makes use of a continuous buzzer. Try adding a button or two to your circuit to
activate/deactivate the buzzer or add several buttons and write a sketch so
that each button activates the buzzer for different lengths of time.
Piezoelectric
Speaker
A
piezoelectric speaker can play, as well as detect tones and can, with a little
help, enable us to play actual melodies. By using the Arduino capability of
producing pulse width modulation (PWM) signals, we are able to alter the pitch
of the sound. If you need to know more about PWM, details can be found here:
http://webzone.k3.mah.se/k3dacu/projects/ivrea/motor/pwm.html
Usually,
the two wires of the piezoelectric speaker are coloured. The black wire should
be connected to GND and the red wire connected to the output (in this case,
digital pin 10 of the Arduino).
Here
is a very basic program that will play a single note (also available from
http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html ):
const
int speakerPin =10; // speaker is on digital
pin 10
void
setup() {
pinMode(speakerPin,
OUTPUT);
}
void
loop() {
int
speakerVal = 349; //input
speakerVal to alter the note
//the
value of 349 corresponds to the note F (see bleow)
tone(speakerPin,
speakerVal); // calculate and play
the tone
}
The
required note frequencies to compose melodies using the set up can be found at
http://www.phy.mtu.edu/~suits/notefreqs.html , a summary of which is:
C
262 Hz
C#
277 Hz //middle C
D 294 Hz D# 311 Hz
E 330 Hz
F 349 Hz F# 370 Hz
G 392 Hz G# 415 Hz
A 440 Hz A# 466 Hz
B 493 Hz
C 523 Hz C# 554 Hz
D 587 Hz D# 622 Hz
Try
changing the note that is played and try adding extra lines of code to add more
notes. By adding various delay commands and different notes you should be able
to compose a simple melody. I’m sure that you will have hours of fun with this,
whilst also gaining valuable experience by working with the program.
Sound Recording
Playback Module
ISD1820
Sound Voice Recording Playback Module With Mic Sound Audio Microphone
1,
the main chip: ISD1820
2,
size: 38mm * 42.5mm
3,
the working voltage: DC 3 ~ 5V
4,
the main features of
An
easy to use 10 seconds of voice recording
2,
high-quality, natural voice restored
3,
can be used as propaganda module
4,
with a loop, jog playback, single-pass play function
5,
available single-chip control
6,
the module can directly drive a small speaker 8 ohm 0.5W
7
does not require single-chip audio recording can be achieved;
Power
supply: 3-5V, which can be accessed on the needle row power;
Sound
recording control: button control or microcontroller, control lines IO has led;
Buttons
control audio recording method of operation:
REC
button: Recording button, you can hold down the recording, release the button
to stop recording;
RLAYE
key: Trigger mode playback, click on to play the current voice of the whole;
PLAYL
key: jog mode playback, press and hold until playback, release to stop
playback;
RPL
Jumper: loop playback mode control, loop;
FT
Jumper: Straight control, allows direct access to the speaker microphone voice
playback;
There
a several infrared sensors on the market but I have found that the HX1836 is a
versatile, reliable and inexpensive universal detector. They are easy to set up
and before long you’ll have everything working at the push of a button. Lately,
I’ve see more and more “infra red modules” appearing on the market. These
consist of an HX1836 detector mounted on a board and a small NEC remote control
handset. If you only have the detector, don’t worry as most remote control
handsets that you might find lying around should be fine for this. In the past,
I have used an old satellite TV handset that was about to be put in the bin.
Firstly,
you will need to connect the infrared receiver then get the codes from an
infrared remote control handset.
HX1836 Universal
Detector
As
you look at the X on the face of the detector, the pins are –
Right VCC (5V)
Middle GND
Left IN Attach this to digital pin 9 on the Arduino
Firstly,
carefully put the pins of the detector into a breadboard and run jumper wires
from these to the relevant Arduino pins. If your detector is on a board, you
can wire directly from the board pins to the Arduino.
Once
wired up, we need to see if it’s working properly. So upload the following
program to the Arduino.
#include
<IRremote.h> // use the IRremote library
int RECV_PIN = 9; // IR receive
pin is digital pin 9
IRrecv
irrecv(RECV_PIN);
decode_results
results;
void
setup()
{
Serial.begin(9600); //
enable serial output and baud rate
irrecv.enableIRIn(); //
Start the receiver
}
void
loop() {
if
(irrecv.decode(&results)) {
irrecv.resume();
Serial.println(results.value,
DEC); // display value in
Serial Monitor
irrecv.resume(); // receive the next
value
}
}
If
we now open the Serial Monitor and start pressing the buttons on the handset,
you will see the corresponding button codes displayed:
If
you wish to use the handset in a project, you will need to make a note of the
codes that correspond to the keys that you wish to use. For example, if you
want to turn on an LED by pressing “1” on the keypad, you will have to use the
value 16724175 in your program.Here are the key codes from the NEC remote
control handset
CH- CH CH+
16753245 16736925 16769565
<< >> >
16720605 16712445 16761405
- + EQ
16769055 16754775 16748655
0 100+ 200+
16738455 16750695 16756815
1 2 3
16724175 16718055 16743045
4 5 6
16716015 16726215 16734885
7 8 9
16728765 16730805 16732845
If
you add an LED to digital pin 13, as in the earlier chapter on LEDs, you can
turn it on and off by pressing the “1” key using the program below (also
available from
#include
<IRremote.h> //use
the IRremote library
int led = 13; //LED
on pin 13
int RECV_PIN = 9; //detector on pin 9
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{pinMode(led,
OUTPUT); //LED
pin as output
Serial.begin(9600);
irrecv.enableIRIn(); // Start
the receiver
}
void
loop() {
digitalWrite(led,
LOW); //LED off
if
(irrecv.decode(&results)) {
//irrecv.resume();
Serial.println(results.value);
irrecv.resume(); // Receive the
next value
}
if
(results.value == 16724175) //if
button 1 pressed
{
digitalWrite(led,
HIGH); //turn LED on
delay
(2000); //keep
LED on for 2 seconds
digitalWrite(led,
LOW); //turn LED off
}
else
digitalWrite(led, LOW);
}
Try
experimenting with more than one LED or, better still, change the colour of an
RGB common anode LED by pressing different buttons on the handset.
Remote
control using such a method can be incorporated into numerous, varied projects.
The DS1302 Real
Time Clock (RTC) module is introduced trickle charge the clock chip, containing
a real-time clock / calendar and 31 bytes of static RAM, via a simple serial
interface to communicate with the microcontroller.
Real-time clock /
calendar circuit provides seconds, minutes, hours, days, weeks, months, years
of
information, the
number of days per month and leap year automatically adjust the number of days.
Clock can be done by the AM / PM or 12
decided to use 24
hour format. Between the DS1302 and the microcontroller can simply use the
synchronous serial communication mode, used
only three port
lines: (1) RST Reset (2) I / O data lines (3) SCLK serial clock. Clock / RAM
read / write data to a byte or up to 31 bytes of character
set way
communication. DS1302 low-power work to maintain the data and clock information
when power is less than 1mW
Real time clock
with the year 2100 to calculate the seconds, minutes, hours, days, weeks,
months, years, the ability, as well as the ability to leap
year adjustment
1.31 8 temporary
data storage RAM
2.Serial I / O
port pin makes the least number of ways
3.Wide range of
operating voltage 2.0 5.5V
4.Current 2.0V,
less than 300nA
5.Read / write
clock or RAM data transmission when there are two single-byte transmit and
multi-byte character sets transfer mode
6.8-pin DIP
package or optional 8-pin SOIC package assembly according to the surface
7.simple 3-wire
interface
8.Vcc = 5V and
TTL-compatible
9.Optional
industrial temperature range -40 to +85
10.Dual power tube
for the main power and backup power supply
Parameters:
1.PCB a single
panel, size: 42mm * 24mm * 12mm(max)
Net weight:10g
Package weight:20g
Color:green (as
the picture shows)
2 with 4 holes, about
3.1mm in diameter
3 genuine spare
battery for the celestial sphere CR2032, Voltage 3V, current is 260mAh,
non-rechargeable batteries.
4
5.DS1302 made
large 8-pin DIP chip, chip, IC Block below for easy replacement and plug the
chip
6 module operating
voltage compatible 3.3V/5V, 5V and 3.3V microcontrollers can be connected with
7 Operating
temperature: 0℃ --- 70 ℃
Wiring (to provide
the program, for example, can take any IO port, the port defined in the program
can be modified):
RTC Module Arduino
VCC +5
V/3.3V
GND GND
CLK pin
6
DAT pin
7
RST pin
8
Sketch to set time and observe the
time.
//This code is to
use with DS1302 RTC module, it permits you to setup the actual time and date
//And you can
visualize them on the serial monitor
//This code is a
modified version of the code provided in virtuabotixRTC library
//Refer to
Surtrtech Youtube chhannel/Facebook page for more information
#include
<virtuabotixRTC.h> //Library used
//Wiring: CLK
-> 6 , DAT -> 7, Reset -> 8
virtuabotixRTC
myRTC(6, 7, 8); //If you change the wiring change the pins here also
void setup() {
Serial.begin(9600);
// Set the current
date, and time in the following format:
// seconds, minutes, hours, day of the week,
day of the month, month, year
// myRTC.setDS1302Time(10, 31, 12, 3, 01, 06,
2020); //Here you write your actual time/date as shown above
//but remember to "comment/remove"
this function once you're done
//The setup is done only one time and the module
will continue counting it automatically
}
void loop() {
// This allows for the update of variables for
time or accessing the individual elements.
myRTC.updateTime();
// Start printing
elements as individuals
Serial.print("Current Date / Time:
");
Serial.print(myRTC.dayofmonth); //You can
switch between day and month if you're using American system
Serial.print("/");
Serial.print(myRTC.month);
Serial.print("/");
Serial.print(myRTC.year);
Serial.print(" ");
Serial.print(myRTC.hours);
Serial.print(":");
Serial.print(myRTC.minutes);
Serial.print(":");
Serial.println(myRTC.seconds);
// Delay so the
program doesn't print non-stop
delay(1000);
}
.
The
TEA5767 FM radio receiver is extensively used and as such is readily available
and can be picked up on on-line outlets for just a few pounds There is an
aerial socket (and extendible aerial is usually included in the package) and a
small earphone/headphone socket.
Wiring
to the Arduino is simple as there are only four pins to connect. As well as
connecting VCC to VCC and GND tot GND, connect the SDA pin to pin A4 of the
Arduino and connect the SLC pin to pin A5 of the Arduino. For convenience, this
is best using a breadboard, If all parts of this section are to be performed, a
large breadboard to accommodate the components will be needed,
The
first sketches below show how to listen to a single station and how to scan
(via input via the Serial Monitor). Later, a potentiometer is added to enable
easier frequency selection. An amplifier is then added and, finally a Nokia
5110 LCD is added to display information.
(a) Single Frequency
The
following sketch tunes the radio receiver to one specific frequency. Try
altering the frequency in the sketch to that of a familiar radio station. You
will need to connect earphones or headphones so you can hear the output.
#include
<Wire.h>
#include
<TEA5767Radio.h>
TEA5767Radio
radio = TEA5767Radio();
void
setup()
{
Wire.begin();
radio.setFrequency(98.5); // pick your own
frequency
}
void
loop()
{
}
(b) Scan Frequencies
The
next sketch enables the user to scan channels by entering + or – in the serial
monitor.
//Libraries:
#include
<TEA5767.h>
#include
<Wire.h>
//Constants:
TEA5767
Radio; //Pinout SLC and SDA - Arduino uno pins A5 and A4
//Variables:
double
old_frequency;
double
frequency;
int
search_mode = 0;
int
search_direction;
unsigned
long last_pressed;
unsigned
char buf[5];
int
stereo;
int
signal_level;
double
current_freq;
unsigned
long current_millis = millis();
int
inByte;
int
flag=0;
void
setup () {
//Init
Serial.begin(9600);
Radio.init();
Radio.set_frequency(95.2); //On power on go
to station 95.2
//95.2
}
void
loop () {
if (Serial.available()>0) {
inByte = Serial.read();
if (inByte == '+' || inByte == '-'){ //accept only + and - from keyboard
flag=0;
}
}
if (Radio.read_status(buf) == 1) {
current_freq = floor (Radio.frequency_available (buf) /
100000 + .5) / 10;
stereo = Radio.stereo(buf);
signal_level = Radio.signal_level(buf);
//By using flag variable the message will
be printed only one time.
if(flag == 0){
Serial.print("Current freq: ");
Serial.print(current_freq);
Serial.print("MHz Signal: ");
//Strereo or mono ?
if (stereo){
Serial.print("STEREO ");
}
else{
Serial.print("MONO ");
}
Serial.print(signal_level);
Serial.println("/15");
flag=1;
}
}
//When button pressed, search for new station
if (search_mode == 1) {
if (Radio.process_search (buf,
search_direction) == 1) {
search_mode = 0;
}
}
//If forward button is pressed, go up to next
station
if (inByte == '+') {
last_pressed = current_millis;
search_mode = 1;
search_direction = TEA5767_SEARCH_DIR_UP;
Radio.search_up(buf);
}
//If backward button is pressed, go down to
next station
if (inByte == '-') {
last_pressed = current_millis;
search_mode = 1;
search_direction = TEA5767_SEARCH_DIR_DOWN;
Radio.search_down(buf);
}
delay(500);
}
Open
the serial monitor and alter the frequency (by entering + or -} and the station
details will be displayed.
(c) Add A Potentiometer To Scan Frequencies
By
adding a 10K potentiometer, selection of radio frequency is made easier, With
the TEA5767 connected as above, connect the potentiometer GND to GND of the
Arduino and VCC of the potentiometer to VCC of the Arduino. Finally, connect
the centre pin of the potentiometer to pin A0 of the Arduino.
Upload
the following sketch to the Arduino.
#include
<Wire.h>
unsigned
char frequencyH = 0;
unsigned
char frequencyL = 0;
unsigned
int frequencyB;
double
frequency = 0;
void
setup()
{
Wire.begin();
frequency = 98.5; //starting frequency
setFrequency();
Serial.begin(9600);
}
void
loop()
{
int reading = analogRead(0);
//frequency = map((float)reading, 0.0,
1024.0, 87.5, 108.0);
frequency = ((double)reading * (108.0 -
87.5)) / 1024.0 + 87.5;
frequency = ((int)(frequency * 10)) / 10.0;
setFrequency();
// Serial.println("Frequency; ");
//Serial.println(frequency);
// Serial.print(current_freq);
Serial.print("Signal: ");
Serial.print(frequency);
Serial.print("MHz: ");
Serial.println(" ");
}
void
setFrequency()
{
frequencyB = 4 * (frequency * 1000000 +
225000) / 32768;
frequencyH = frequencyB >> 8;
frequencyL = frequencyB & 0XFF;
delay(100);
Wire.beginTransmission(0x60);
Wire.write(frequencyH);
Wire.write(frequencyL);
Wire.write(0xB0);
Wire.write(0x10);
Wire.write((byte)0x00);
Wire.endTransmission();
delay(100);
}
Open
the Serial Monitor and adjust the potentiometer. You will see that the
frequency changes as you turn the potentiometer one way or the other. You will
also hear the signal change as you do this.
(d) Add An Amplifier
Rather
than listen to the radio through earphones or headphones, the signal from the
TEA5767 module can be fed to an amplifier, the amplifier output can then be
relayed to speakers.
I
chose a YMX 807 2.2 DC 5V 20W 2.1 Dual 2 Channel 3D Surround Digital Stereo
Class-D Amplifier Board. See the Amplifiers Section of this book for more
information. These modules can be bought online for less than £5. Of course you
can choose to use a different amplifier but be careful to follow the data sheet
wiring when connecting it to your project.
You
will need to acquire a cable with a 3.5mm jack at one end. This will connect to
the TEA5767 earphone/headphone socket. I stripped the other end of the cable
that I had to reveal three wires. The black wire should be connected to GND of
the Arduino (via the breadboard outlined earlier). The other two wires should
be connected to the YMX 807 board where there are R and L inputs, There is also
a GND which should be connected to GND on the breadboard. The speaker outputs
on the YMX 807 board should be connected to a pair of speakers, though a
connecting to a single speaker may be adequate. Finally connect the VCC and GND
on the YMX 807 board to the Arduino VCC and GND via the breadboard.
Once
all connections are made, upload the sketch from “(c)” above. You will still be
able to alter the frequency using the potentiometer but now you will be able to
alter the volume and tone by using the knobs on the YMX 807 board,
Now
that the project is building nicely, it’s time to add a visual display.
(e) Add A Nokia
5110 LCD Display
Here
is the next part of the FM Radio project. If we want our radio project to be
“stand-alone”, we need to have some sort
of visual display so the we can see the frequencies that are received rather
than have to view these through an attached computer via the Serial Monitor.
The Nokia 5110 LCD is an ideal for this purpose as it id straightforward to
use, is readily available and is reasonably priced. (See the Visual Displays
section of this book for further information).
The
LCD should be connected to the Arduion (via the breadboard) as follows,
Nokia
5110 Arduino
RST 12
CE 11
DC 10
DIN 9
CLK 8
VCC 5V
LIGHT GND (for the backlight)
GND GND
As
this project has developed, more components have been added so I have
constructed the diagram below to confirm connections.
Note
that I couldn’t find a YMX 807 Fritzing part and I have used an alternative
amplifier part. Make sure that you connect your chosen amplifier by following
information on the relevant data sheet.
Also
note that I have only connected one speaker to the amplifier. You can of course
connect a second speaker if your amplifier allows it.
Photo(s)
Once
you have everything connected, you need to upload the sketch. The following
sketch is based on the one available at http://educ8s.tv/arduino-fm-radio-project/
#include
<TEA5767N.h>
//https://github.com/mroger/TEA5767
#include
<LCD5110_Graph.h> //http://www.rinkydinkelectronics.com/library.php?id=48
LCD5110
lcd(8,9,10,12,11);
TEA5767N
radio = TEA5767N();
extern
unsigned char BigNumbers[];
extern
unsigned char TinyFont[];
extern
uint8_t splash[];
extern
uint8_t signal5[];
extern
uint8_t signal4[];
extern
uint8_t signal3[];
extern
uint8_t signal2[];
extern
uint8_t signal1[];
int
analogPin = 0;
int
val = 0;
int
frequencyInt = 0;
float
frequency = 0;
float
previousFrequency = 0;
int
signalStrength = 0;
void
setup()
{
radio.setMonoReception();
radio.setStereoNoiseCancellingOn();
initScreen();
showSplashScreen();
Serial.begin(9600);
}
void
loop() {
for(int i;i<30;i++)
{
val = val + analogRead(analogPin);
delay(1);
}
val = val/30;
frequencyInt = map(val, 2, 1014, 8700,
10700); //Analog value to frequency from 87.0 MHz to 107.00 MHz
float frequency = frequencyInt/100.0f;
if(frequency - previousFrequency >= 0.1f
|| previousFrequency - frequency >= 0.1f)
{
lcd.clrScr();
radio.selectFrequency(frequency);
printSignalStrength();
printStereo();
printFrequency(frequency);
previousFrequency = frequency;
}
lcd.clrScr();
printSignalStrength();
printStereo();
printFrequency(frequency);
delay(50);
val = 0;
}
void
initScreen()
{
lcd.InitLCD();
lcd.setFont(BigNumbers);
lcd.clrScr();
}
void
showSplashScreen()
{
lcd.drawBitmap(0, 0, splash, 84, 48);
lcd.update();
delay(3000);
lcd.clrScr();
lcd.update();
}
void
printFrequency(float frequency)
{
String frequencyString = String(frequency,1);
if(frequencyString.length() == 4)
{
lcd.setFont(BigNumbers);
lcd.print(frequencyString,14,12);
lcd.update();
}
else
{
lcd.setFont(BigNumbers);
lcd.print(frequencyString,0,12);
lcd.update();
}
}
void
printStereo()
{
boolean isStereo = radio.isStereo();
if(isStereo)
{
lcd.setFont(TinyFont);
lcd.print("STEREO",55,2);
}
}
void
printSignalStrength()
{
signalStrength = radio.getSignalLevel();
String signalStrenthString =
String(signalStrength);
if(signalStrength >=15)
{
lcd.drawBitmap(1, 1, signal5, 17 , 6);
}else if(signalStrength >=11 &&
signalStrength <15)
{
lcd.drawBitmap(1, 1, signal4, 17 , 6);
}
else if(signalStrength >=9 &&
signalStrength <11)
{
lcd.drawBitmap(1, 1, signal3, 17 , 6);
}
else if(signalStrength >=7 &&
signalStrength <9)
{
lcd.drawBitmap(1, 1, signal2, 17 , 6);
}
else if(signalStrength <7)
{
lcd.drawBitmap(1, 1, signal1, 17 , 6);
}
}
(f)
Add Remote Control
SUMMARY
Earlier
whilst we were looking at sensors, we were generating a lot of data. This data,
though displayed in the Serial Monitor, has been lost forever as we had no
means of saving it. If you are logging data, the chances are that you will want
to save it for later analysis.
Storage: SD Card
Module
One
of the easiest ways to store data for the sensors is the familiar SD storage
card. An SD Card Modules can be easily found and are quite reasonably priced.
The
SD Card Module has eight pins, which are all labelled. The pin out scheme that
I use is as follows:
SD
Card Arduino
GND GND
MISO 12
SCK 13
MOSI 11
CS 4
5V
3V 3V
IRQ
Note
that the SD Card Module can be used with either 5V or 3V connected to the
Arduino. The following programs have been adapted from the examples that are
freely available in the Examples Section of the Arduino IDE. You will need to
ensure that you have the SD Card library (“SD.h”) installed.
List The
Contents Of An SD Card
Firstly, save some files to
the SD card using your computer our laptop. Upload the following program (based
on the “CardInfo” file from the Arduino IDE):
This example shows how print out the files in
a
directory on a SD card
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
created
Nov 2010 by David A. Mellis
modified 9 Apr 2012 by Tom Igoe
modified 2 Feb 2014 by Scott Fitzgerald
modified 6 May 2018 by Robert Dodgson
This example code is in the public domain.
*/
#include
<SPI.h>
#include
<SD.h>
File
root;
void
setup() {
// Open serial communications and wait for
port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect.
Needed for native USB port only
}
Serial.print("
if (!SD.begin(4)) {
Serial.println("initialization
failed!");
return;
}
Serial.println("initialization
done.");
root = SD.open("/");
printDirectory(root, 0);
Serial.println("done!");
}
void
loop() {
// nothing happens after setup finishes.
}
void
printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
Once the sketch is uploaded,
open the Serial Monitor. You will see the SD card contents displayed.
Write To An SD Card
To
write to a file, we firstly need to create that file on the SD card. Open up a
new file using Microsoft Notepad or similar, then save it as
"test.txt" to the SD card. Upload the following program (also
available from http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html
):
#include
<SD.h> // use the SD library
File
myFile; // define the file
void
setup()
{
Serial.begin(9600);
Serial.print("
pinMode(10,
OUTPUT);
if
(!SD.begin(10)) {
Serial.println("initialization
failed!");
return;
}
Serial.println("initialization
done.");
// open the file. Note that only one
file can be open at a time,
// so you have to close this one before
opening another.
myFile
= SD.open("test.txt", FILE_WRITE);
if
(myFile) {
// if the file opened, write to it:
Serial.print("Writing to test.txt..."); myFile.println("testing
1, 2, 3.");
myFile.close(); // close the file:
Serial.println("done.");
}
else
{
// if the file didn't open, print an
error: Serial.println("error opening test.txt");
}
}
void
loop()
{
// nothing happens after setup
}
If
you put your SD card in the SD card slot of your computer and open the file
"test.txt", you will see that the Arduino has written the text
“testing 1, 2, 3." to the file. This is very useful as this program can be
used for the basis of a project. For example, you could set up a temperature
sensor and log the data to an SD card for future manipulation and analysis.
Data Logging To Excel: GoBetwino
Earlier we saw how data from the Arduino can be stored on an SD
card. Explained here is a method of logging data in real time and storing it in
a spreadsheet file. There are a few methods available to do this but my
preferred method is to use GoBetwino.
GoBetwino is kind of a "generic proxy" for Arduino. It's a
program running on a PC (Windows only), that will act on behalf of Arduino and
do some of the things that Arduino can't do on its own. So it works like a go
between, hence the name.
GoBetwino is free, comes with a detailed user manual (see Appendix 1),
and sample Arduino sketches to show how it can be used.
GoBetwino is listens on the
serial port, for "commands” (coming from Arduino in our case), and in
response it will do something for Arduino and possibly return something to
Arduino. Without going into too much detail of its extensive capabilities,
updating a spreadsheet with real time data collected from sensors by an Arduino
will be illustrated.
Once you have downloaded GoBetwino, open the program and navigate
to “Commands” then “Edit Command”..
You
need to create a command of the SPRID type called SPXL as shown in the
screenshot below. Note that you will have to insert the name and location of
the spreadsheet that you wish to be populated with the data. (Your spreadsheet
should be created before you begin to collect data).
Setting
Up The SPXL Command
Now that GoBetwino is ready, you will
need to set up the Arduino to generate some data to log. In the example below I have added a
temperature sensor (LM 35) to analog pin 0 and a humidity sensor (DHT-11) to
pin 7.
Below is an Arduino sketch that will send
the temperature and humidity data via a serial port to GoBetwino.
#include <dht11.h>
int serInLen = 25;
char serInString[25];
int pId =0;
int result;
#define tempPin 0
#define humidityPin 7
void setup()
{
Serial.begin(9600);
Serial.println("#S|SPXL|[]#"); // start EXCEL
readSerialString(serInString, 5000);
// wait 5 seconds for answer from Gobetwino (=porcess
ID)
pId= atoi(serInString);
// convert result to integer
sendValues();
// send some data to Excell
}
void loop()
{
//delay(5000);
}
void sendValues()
{
char buffer[5];
int temp;
int humidity;
for (int i=1; i<=15; i++){
//Read the two sensor values
temp=(5*analogRead(tempPin)*100)/1024;
humidity=analogRead(7);
//Send the values as though it was typed into Excel using the SENDK
command
// This is the total line that is sent: #S,SENDK,[pId; potValue1 {TAB}
potValue2 {DOWN} {LEFT} ]#
Serial.print("#S|SENDK|[");
Serial.print(itoa((pId), buffer, 10));
Serial.print("&");
Serial.print(itoa((temp), buffer, 10));
Serial.print(" {TAB} ");
Serial.print(itoa((humidity), buffer, 10));
Serial.print(" {DOWN} ");
Serial.print(" {LEFT} ");
Serial.println("]#");
// wait up to 1000 ms for answer from Gobetwino, answer will be in
serInString, answer is 0 if all is OK
readSerialString(serInString, 1000);
//Deal with answer here - omitted in this
example
delay(2000);
}
// Now we have sent the 2 sensor values 15 times, so save and close the
XL sheet.
Serial.print("#S|SENDK|[");
Serial.print(itoa((pId), buffer, 10));
Serial.print("& ");
Serial.print("%Fg%Fa"); //= ALT f
ALT g = save and exit in danish
Excell
Serial.println("]#");
//
Wait 2 seconds for the save to finish
delay(2000);
//
wait up to 1000 ms for answer from Gobetwino, answer will be in serInString,
answer is 0 if all is OK
readSerialString(serInString, 1000);
//
Next e-mail the XL sheet to someone
Serial.println("#S|MXL|[]#");
//
wait up to 1000 ms for answer from Gobetwino, answer will be in serInString,
answer is 0 if all is OK
readSerialString(serInString, 1000);
}
//read a string from the serial and store
it in an array
//you must supply the array variable -
will return if timeOut ms passes before the sting is read so you should
//check the contents of the char array
before making any assumptions.
void readSerialString (char *strArray,long
timeOut)
{
long startTime=millis();
int i;
while (!Serial.available()) {
if (millis()-startTime >= timeOut) {
return;
}
}
while (Serial.available() && i < serInLen) {
strArray[i] = Serial.read();
i++;
}
}
Upload the sketch and, once loaded and
connected, launch Excel.
You
will see that the data is logged in the spreadsheet and a graph of the data is
plotted in real time. I set the Arduino sketch to collect a series of 15 sets
of data; after that series, a dialog box will automatically open suggesting
that you save the spreadsheet containing the logged data.:
If
you look at the GoBetwino program as data is being collected, you will see the
progress of the processes:
Try
experimenting with the other functionality of GoBetwino and incorporate it in
some of your future experiments and projects.
Data Logging To
Excel: PLX-DAQ
Parallax Data Acquisition tool (PLX-DAQ) software is an
add-in for Microsoft Excel and can acquire up to 26 channels of data from
microcontrollers and drops the numbers into columns as they arrive. PLX-DAQ
provides easy spreadsheet analysis of data collected in the field, laboratory
analysis of sensors and real-time equipment monitoring
It
can be downloaded from this link:
https://www.parallax.com/downloads/plx-daq
Set
up a circuit with a DHT-11 humidity detector and an LM 35 temperature sensor.
If you study the sketch below, you will hopefully get an understanding of how
to use the necessary commands to populate the PLX-DAQ spreadsheet.
The
LM 35 is attached to Arduino pin A0 and the DHT-11 is attached to Arduino pin
D7.
/*
Data is sent to an Excel spreadsheet through PLX-DAQ data acquisition software:
http://www.parallax.com/downloads/plx-daq
*/
#include
<DHT.h> //DHT-11
library
#define
tempPin 0 //temperature
sensor pin
#define
humidityPin 7 //DTH-11
sensor pin
int
x = 0; //
For PLX-DAQ
int
row = 0; // For PLX-DAQ
int
i = 0;
void
setup(){
Serial.begin(9600); //
Set baud rate
//Set
up the column headers in Excel
Serial.println("LABEL,
Time, Temp (C), Humidity");
delay(1000); // Wait 1 second
}
void loop(){
//Initialize
and define the variables
int temp;
int humidity;
temp=(5*analogRead(tempPin)*100)/1024;
humidity=analogRead(7);
Serial.print("DATA,");
Serial.print
("TIME,");
Serial.print(temp);
Serial.print(",");
Serial.println(humidity);
row++; // For PLX-DAQ
x++;
// For PLX-DAQ
delay(10000); //Set delay to 10 seconds between
readings
}
Upload the sketch and, once loaded and
connected, launch the PLX-DAQ spreadsheet. I have modified the spreadsheet that
I downloaded to include the temperature and humidity data series for graphing.
You will need to enable the macros and
accept the warning regarding active x controls as the spreadsheet loads. Select
the baud rate (9600 for Arduino) and the port that your Arduino is connected
to. Click “Connect”. Your data should begin to be logged into the spreadsheet.
By
selecting the “Sample Data With Plots” tab you will see that as well as your
temperature and humidity data being logged, there is a graph that is being
updated after each reading. You may need to alter the series settings for the
graph.
The
data in the PLX-DAQ spreadsheet is updated every 10 seconds (set in the Arduino
sketch),. You can alter this to suit your requirements.
The
PLX-DAQ spreadsheet is very good at logging data and can be used to log data
from a whole range of sensors and experiments. You can log up to 26 channels
and you can alter the spreadsheet to illustrate your data to suit your
requirements. As you develop your skills and ideas, this tool could become a
valuable constituent of you projects.
Please
see the PLX-DAQ documentation in Appendix 2.
Data Logging:
MakerPlot
MakerPlot is Windows® software for
plotting analog and digital data generated by microcontrollers and other
devices with ASCII serial outputs. No proprietary hardware is required –
just a serial connection from the microcontroller or other device to the
PC.
With dozens of meters, buttons, switches and text boxes the user has
full control of the screen interface design and how information is displayed,
plotted, logged to files, printed and more.
Your microcontroller also has the ability to read information directly
from the interfaces for interactive measurement, plotting and control.
Full details and how to
purchase, along with how to download a free trail of MakerPlot can be found
here (though once tried, you will probably want to purchasing it):
http://makerplot.com/home.html
After
downloading and launching MakerPlot, the user is greeted with a myriad of
applications. If they look closer there is a button to access even more on a
second page.
There
is a very comprehensive guide and ten Arduino code samples accessible from the
main interface.
There
are well over a dozen applications available but for the purpose of this work,
only a couple of them will be explored. If you download MakerPlot, I’m sure
that you will have hours of enjoyment trying out the various applications.
Below
are a couple of screenshots that show the applications that are available:
Firstly,
set up the circuit for monitoring temperature and humidity as in Arduino Data
Logging To Excel : PLX-DAQ as earlier in this Section. We will also use the
same Arduino sketch as before.
Connect
your Arduino to the computer via a USB cable and launch the MakerPlot
application. From the first screen, select “Run Standard Interface”.
You
will be greeted by a logically-displayed interface.
We
will be collecting temperature and humidity data every 10 seconds so we need to
alter the axes accordingly. I set the x-axis to 2.5 minutes and the y-axis to
100:
Now
select the port and baud rate (9600 for Arduino):
Select
“Log To File” in the bottom panel.
MakerPlot
is now ready to receive the sensor data.
Click
the Control Switch to begin data acquisition.
Above
is the resulting sensor data plot. The humidity values are in red and the
temperature values are in black. Open the std_dat.txt file to see the raw data.
Here is a screenshot of a portion of my raw data file:
You
can save this file and then import into Excel for some further
analysis/plotting.
I
have only briefly covered a small part of this software package. I’m sure that
you will experiment with the other applications within it.
In
earlier chapters we have looked at data displayed in the Serial Monitor and we
have also managed to store data on an SD card. What if we want to display data
that is generated on a stand-alone Arduino that isn’t connected to a computer? The
answer is that we need some sort of display. There are numerous sizes and types
of displays available, each differently suited to the application they are used
in. This chapter will concentrate on the most common of them.
7-Segment Display
The
seven segment display is widely used in everyday situations as they are clear
to see and are very versatile.
Blah
blah blah
Arduino 7-Segment
Display Circuit
With
the dot showing in the bottom right hand corner, insert 220 ohm resistors as
shown in the diagram above.
The
following sketch demonstrates how to display numbers by counting down from 9 to
0. Note, this sketch was written for the 7-segment common anode, alterations
will need to be made if you have a 7-segment common cathode.
Once
the circuit is set up, create a sketch similar to the one below which
illustrates how to display different digits.
//
Arduino 7 segment display example software
//
Adapted from
http://www.hacktronics.com/Tutorials/arduino-and-7-segment-led.html
//
License: http://www.opensource.org/licenses/mit-license.php (Go crazy)
//
Define the LED digit pattens, from 0 - 9
//
Note that these patterns are for common anode displays
//
For common cathode displays, change the 1's to 0's and 0's to 1's
//
1 = LED on, 0 = LED off, in this order:
// Arduino
pin: 2,3,4,5,6,7,8
byte
seven_seg_digits[10][7] = {
{0,0,0,0,0,0,1 }, // = 0
{ 1,0,0,1,1,1,1 }, // = 1
{ 0,0,1,0,0,1,0 }, // = 2
{ 0,0,0,0,1,1,0 }, // = 3
{ 1,0,0,1,1,0,0 }, // = 4
{ 0,1,0,0,1,0,0 }, // = 5
{ 0,1,0,0,0,0,0 }, // = 6
{ 0,0,0,1,1,1,1 }, // = 7
{
0,0,0,0,0,0,0 }, // = 8
{ 0,0,0,1,1,0,0 } // = 9
};
void
setup() {
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
writeDot(0);
// start with the "dot" off
}
void
writeDot(byte dot) {
digitalWrite(9, dot);
}
void
sevenSegWrite(byte digit) {
byte pin = 2;
for (byte segCount = 0; segCount < 7;
++segCount) {
digitalWrite(pin,
seven_seg_digits[digit][segCount]);
++pin;
}
}
void
loop() {
for (byte count = 10; count > 0; --count)
{
delay(1000);
sevenSegWrite(count - 1);
}
delay(4000);
}
SUMMARY
XXXXXXXXXXXXX
TM1637 Seven Segment Display
Modules based on TM1637 provide two signal connections (CLK and DIO) and
two power connections (VCC and GND). Signal pins can be connected to any pair
of digital pins of the Arduino. Signal pins configuration is defined at the top
of library header file, where it can be modifed.
Upload the following sketch via the
Arduino IDE.
#include <TM1637.h>
TM1637 tm(2, 3);
void setup()
{
tm.begin();
tm.setBrightness(4);
}
void loop()
{
// Display Integers:
tm.display(1234);
delay(1000);
// Display float:
tm.display(2.65);
delay(1000);
// Display String:
tm.display("PLAY");
delay(1000);
tm.display("STOP");
delay(1000);
}
The sketch demonstrates how to display
different type of values on the display such as numbers, letters and
punctuation. The following sketch counts from -99 to +9999.
#include <TM1637.h>
// Instantiation and pins configurations
// Pin 3 - > DIO
// Pin 2 - > CLK
TM1637 tm(2, 3);
void setup()
{
tm.init();
}
void loop()
{
for (int i = -100 ; i < 10000; i++) {
tm.display(i);
delay(1000);
}
}
Finally,
the last sketch a clock that counts from 12:00 to 12:59
then
turns the display off. To restart the clock, simply press the reset button on
the Arduino.
#include
<TM1637.h>
//
Instantiation and pins configurations
//
Pin 3 - > DIO
//
Pin 2 - > CLK
TM1637
tm1637(2, 3);
void
setup()
{
tm1637.init();
tm1637.setBrightness(5);
}
void
loop()
{
for (int minutes = 12 ; minutes< 60;
minutes++) {
for (int seconds = 0; seconds < 60;
seconds++) {
tm1637.display(seconds + minutes *
100);
delay(1000); // Waits for 1 second = 1000
millisecond.
tm1637.switchColon();
if (minutes == 12 &&
seconds == 59) {
// Turns the display off and
keeps it off, until setBrightness() with different values is called
// The display setting are
saved!
// tm1637.offMode(); Turns the
display off, but the display will turn on, as soon as the loop continues
// This is due to the fact that
offMode() doesn't save the brightness value.
tm1637.setBrightness(0);
}
}
}
The
above examples show how versatile this module is and can be incorporated into
numerous larger projects.
16x2 LCD Display
The
16x2 LCD display is very common and can be used in numerous situations and
projects. They come with a variety of text and background colours, so pick the
one that best suits the situation or your taste. These LCDs either come with
header pins already attached, or with header pins that you have to solder on
yourself. There are also an increasing number of outlets selling these LCDs as
a shield with the LCD connected to a board which has buttons connected; the
whole thing having the ability to just slot onto the Arduino. Here, we will
assume that your LCD has the pins already attached.
Firstly,
place the LCD onto a breadboard, leaving enough room for a 10k ohm
potentiometer (variable resistor). This is used to brighten or dim the display
on the LCD. You will also need a 220 ohm resistor. Now, wire up the pins of the
LCD to the Arduino as in the diagram below:
In
the program, we will need to use the LiquidCrystal library. This allows us to
control LCD displays that are compatible with the Hitachi HD44780 driver. The
program below is quite straight forward and will display the words “Hello
World” and the time in seconds since the Arduino was last reset on the LCD.
(This program also available from
http://robertthomasson.blogspot.co.uk/2013/09/byte-size-starter.html ):
#include
<LiquidCrystal.h> //
include the library code
// initialize the library with the
numbers of the interface pins LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void
setup() {
lcd.begin(16,
2); // set up the LCD's number of
columns
and rows
lcd.print("hello,
world!"); // Print a message to the
LCD
}
void
loop() {
lcd.setCursor(0,
1); // set the cursor to column
0, line 1
lcd.print(millis()/1000); // print the number of seconds since reset
}
The
code is based on the Liquid Crystal example by Tom Igoe which can be found on
the Arduino website at http://arduino.cc/en/Tutorial/LiquidCrystal
Note
that the cursor is set to line 1 for printing of the number of seconds.
Line
1 is the second row, as line 0 is the first row.
We
now have an easy way of displaying text on the 16x2 LCD. Try altering the text
or getting it to display temperature data. The module can be used for many
projects where there is a need to visualize data or information.
Nokia 5110 LCD
Display
The
Nokia 5110 84x48 LCD graphics display was used on millions of mobile phones in
the late 1990's and due to their simple connections they are easily integrated
into electronics projects. They are inexpensive, versatile and are very
reliable. They are available “as is” or can be purchased with header pins
already attached.
Nokia 5110 LCD Module
Follow
the pin out scheme below. Pins on bottom, screen face up, looking left to
right.
Nokia 5110 Arduino
RST 6
CE 7
DC 5
DIN 4
CLK 3
VCC 3V
LIGHT GND (for the backlight)
GND GND
Now,
upload the following code
#define
PIN_SCE 7
#define
PIN_RESET 6
#define
PIN_DC 5
#define
PIN_SDIN 4
#define
PIN_SCLK 3
#define
LCD_C LOW
#define
LCD_D HIGH
#define
LCD_X 84
#define
LCD_Y 48
static
const byte ASCII[][5] =
{
{0x00,
0x00, 0x00, 0x00, 0x00} // 20
,{0x00,
0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00,
0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14,
0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24,
0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23,
0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36,
0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00,
0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00,
0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00,
0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14,
0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08,
0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00,
0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08,
0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00,
0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20,
0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e,
0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00,
0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42,
0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21,
0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18,
0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27,
0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c,
0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01,
0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36,
0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06,
0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00,
0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00,
0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08,
0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14,
0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00,
0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02,
0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32,
0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e,
0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f,
0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e,
0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f,
0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f,
0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f,
0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e,
0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f,
0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00,
0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20,
0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f,
0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f,
0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f,
0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f,
0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e,
0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f,
0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e,
0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f,
0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46,
0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01,
0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f,
0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f,
0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f,
0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63,
0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07,
0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61,
0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00,
0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02,
0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00,
0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04,
0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40,
0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00,
0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20,
0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f,
0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38,
0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38,
0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38,
0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08,
0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c,
0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f,
0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00,
0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20,
0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f,
0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00,
0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c,
0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c,
0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38,
0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c,
0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08,
0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c,
0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48,
0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04,
0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c,
0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c,
0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c,
0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44,
0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c,
0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44,
0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00,
0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00,
0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00,
0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10,
0x08, 0x08, 0x10, 0x08} // 7e ←
,{0x78,
0x46, 0x41, 0x46, 0x78} // 7f →
};
void
LcdCharacter(char character)
{
LcdWrite(LCD_D,
0x00);
for
(int index = 0; index < 5; index++)
{
LcdWrite(LCD_D,
ASCII[character - 0x20][index]);
}
LcdWrite(LCD_D,
0x00);
}
void
LcdClear(void)
{
for
(int index = 0; index < LCD_X * LCD_Y / 8; index++)
{
LcdWrite(LCD_D,
0x00);
}
}
void
LcdInitialise(void)
{
pinMode(PIN_SCE,
OUTPUT);
pinMode(PIN_RESET,
OUTPUT);
pinMode(PIN_DC,
OUTPUT);
pinMode(PIN_SDIN,
OUTPUT);
pinMode(PIN_SCLK,
OUTPUT);
digitalWrite(PIN_RESET,
LOW);
digitalWrite(PIN_RESET,
HIGH);
LcdWrite(LCD_C,
0x21 ); // LCD Extended Commands.
LcdWrite(LCD_C,
0xB1 ); // Set LCD Vop (Contrast).
LcdWrite(LCD_C,
0x04 ); // Set Temp coefficient. //0x04
LcdWrite(LCD_C,
0x14 ); // LCD bias mode 1:48. //0x13
LcdWrite(LCD_C,
0x0C ); // LCD in normal mode.
LcdWrite(LCD_C,
0x20 );
LcdWrite(LCD_C,
0x0C );
}
void
LcdString(char *characters)
{
while
(*characters)
{
LcdCharacter(*characters++);
}
}
void
LcdWrite(byte dc, byte data)
{
digitalWrite(PIN_DC,
dc);
digitalWrite(PIN_SCE,
LOW);
shiftOut(PIN_SDIN,
PIN_SCLK, MSBFIRST, data);
digitalWrite(PIN_SCE,
HIGH);
}
void
setup(void)
{
LcdInitialise();
LcdClear();
LcdString("Hello
World!");
}
void
loop(void)
{
}
There
are plenty more examples freely available on the internet that will enable you
to display text effects such as scrolling text as well as examples for
displaying graphics.
SUMMARY
XXXXXXXXXXXXXX
1.8 inch TFT With SD Card Slot
These
modules are very handy if you want to add a splash of colour to your projects.
Whether you want to display data, information or images, this TFT should help
you achieve your goals.
The
wiring diagram may look a bit busy but persevere with it as the rewards are
well worth the patience and effort.
1.8 inch TFT With SD
Card Reader
Once
you have built the circuit you can upload the following sketch or any TFT
sketch that come with the Arduino IDE.
The
first sketch test will show many different effects that you can achieve
/***************************************************
This is a library for the Adafruit 1.8"
SPI display.
This
library works with the Adafruit 1.8" TFT Breakout w/SD card
----> http://www.adafruit.com/products/358
The
1.8" TFT shield
----> https://www.adafruit.com/product/802
The
1.44" TFT breakout
---->
https://www.adafruit.com/product/2088
as
well as Adafruit raw 1.8" TFT display
----> http://www.adafruit.com/products/618
Check out the links above for our tutorials
and wiring diagrams
These displays use SPI to communicate, 4 or 5
pins are required to
interface (RST is optional)
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.
MIT license, all text above must be included
in any redistribution
****************************************************/
#include
<Adafruit_GFX.h> // Core
graphics library
#include
<Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include
<Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include
<SPI.h>
//
For the breakout, you can use any 2 or 3 pins
//
These pins will also work for the 1.8" TFT shield
#define
TFT_CS 10
#define
TFT_RST 8 // you can also connect this to the Arduino
reset
// in which case, set
this #define pin to -1!
#define
TFT_DC 9
#define
sclk 13
#define
mosi 11
//
Option 1 (recommended): must use the hardware SPI pins
//
(for UNO thats sclk = 13 and sid = 11) and pin 10 must be
//
an output. This is much faster - also required if you want
//
to use the microSD card (see the image drawing example)
//
For 1.44" and 1.8" TFT with ST7735 use
Adafruit_ST7735
tft = Adafruit_ST7735(TFT_CS, TFT_DC,
TFT_RST);
//
For 1.54" TFT with ST7789
//Adafruit_ST7789
tft = Adafruit_ST7789(TFT_CS, TFT_DC,
TFT_RST);
//
Option 2: use any pins but a little slower!
//#define
TFT_SCLK 13 // set these to be whatever
pins you like!
//#define
TFT_MOSI 11 // set these to be whatever
pins you like!
//Adafruit_ST7735
tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
float
p = 3.1415926;
void
setup(void) {
Serial.begin(9600);
Serial.print("Hello! ST77xx TFT
Test");
// Use this initializer if you're using a
1.8" TFT
tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab
// Use this initializer (uncomment) if you're
using a 1.44" TFT
//tft.initR(INITR_144GREENTAB); // initialize a ST7735S chip, black tab
// Use this initializer (uncomment) if you're
using a 0.96" 180x60 TFT
//tft.initR(INITR_MINI160x80); // initialize a ST7735S chip, mini display
// Use this initializer (uncomment) if you're
using a 1.54" 240x240 TFT
//tft.init(240, 240); // initialize a ST7789 chip, 240x240 pixels
Serial.println("Initialized");
uint16_t time = millis();
tft.fillScreen(ST77XX_BLACK);
time = millis() - time;
Serial.println(time, DEC);
delay(500);
// large block of text
tft.fillScreen(ST77XX_BLACK);
testdrawtext("Lorem ipsum dolor sit
amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt
feugiat. Maecenas enim
delay(1000);
// tft print function!
tftPrintTest();
delay(4000);
// a single pixel
tft.drawPixel(tft.width()/2, tft.height()/2,
ST77XX_GREEN);
delay(500);
// line draw test
testlines(ST77XX_YELLOW);
delay(500);
// optimized lines
testfastlines(ST77XX_RED, ST77XX_BLUE);
delay(500);
testdrawrects(ST77XX_GREEN);
delay(500);
testfillrects(ST77XX_YELLOW, ST77XX_MAGENTA);
delay(500);
tft.fillScreen(ST77XX_BLACK);
testfillcircles(10, ST77XX_BLUE);
testdrawcircles(10, ST77XX_WHITE);
delay(500);
testroundrects();
delay(500);
testtriangles();
delay(500);
mediabuttons();
delay(500);
Serial.println("done");
delay(1000);
}
void
loop() {
tft.invertDisplay(true);
delay(500);
tft.invertDisplay(false);
delay(500);
}
void
testlines(uint16_t color) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(0, 0, x, tft.height()-1,
color);
}
for (int16_t y=0; y < tft.height(); y+=6)
{
tft.drawLine(0, 0, tft.width()-1, y,
color);
}
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(tft.width()-1, 0, x,
tft.height()-1, color);
}
for (int16_t y=0; y < tft.height(); y+=6)
{
tft.drawLine(tft.width()-1, 0, 0, y,
color);
}
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(0, tft.height()-1, x, 0,
color);
}
for (int16_t y=0; y < tft.height(); y+=6)
{
tft.drawLine(0, tft.height()-1,
tft.width()-1, y, color);
}
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(tft.width()-1, tft.height()-1,
x, 0, color);
}
for (int16_t y=0; y < tft.height(); y+=6)
{
tft.drawLine(tft.width()-1, tft.height()-1,
0, y, color);
}
}
void
testdrawtext(char *text, uint16_t color) {
tft.setCursor(0, 0);
tft.setTextColor(color);
tft.setTextWrap(true);
tft.print(text);
}
void
testfastlines(uint16_t color1, uint16_t color2) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t y=0; y < tft.height(); y+=5)
{
tft.drawFastHLine(0, y, tft.width(),
color1);
}
for (int16_t x=0; x < tft.width(); x+=5) {
tft.drawFastVLine(x, 0, tft.height(),
color2);
}
}
void
testdrawrects(uint16_t color) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawRect(tft.width()/2 -x/2,
tft.height()/2 -x/2 , x, x, color);
}
}
void
testfillrects(uint16_t color1, uint16_t color2) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=tft.width()-1; x > 6; x-=6)
{
tft.fillRect(tft.width()/2 -x/2,
tft.height()/2 -x/2 , x, x, color1);
tft.drawRect(tft.width()/2 -x/2,
tft.height()/2 -x/2 , x, x, color2);
}
}
void
testfillcircles(uint8_t radius, uint16_t color) {
for (int16_t x=radius; x < tft.width();
x+=radius*2) {
for (int16_t y=radius; y < tft.height();
y+=radius*2) {
tft.fillCircle(x, y, radius, color);
}
}
}
void
testdrawcircles(uint8_t radius, uint16_t color) {
for (int16_t x=0; x < tft.width()+radius;
x+=radius*2) {
for (int16_t y=0; y <
tft.height()+radius; y+=radius*2) {
tft.drawCircle(x, y, radius, color);
}
}
}
void
testtriangles() {
tft.fillScreen(ST77XX_BLACK);
int color = 0xF800;
int t;
int w = tft.width()/2;
int x = tft.height()-1;
int y = 0;
int z = tft.width();
for(t = 0 ; t <= 15; t++) {
tft.drawTriangle(w, y, y, x, z, x, color);
x-=4;
y+=4;
z-=4;
color+=100;
}
}
void
testroundrects() {
tft.fillScreen(ST77XX_BLACK);
int color = 100;
int i;
int t;
for(t = 0 ; t <= 4; t+=1) {
int x = 0;
int y = 0;
int w = tft.width()-2;
int h = tft.height()-2;
for(i
= 0 ; i <= 16; i+=1) {
tft.drawRoundRect(x, y, w, h, 5, color);
x+=2;
y+=3;
w-=4;
h-=6;
color+=1100;
}
color+=100;
}
}
void
tftPrintTest() {
tft.setTextWrap(false);
tft.fillScreen(ST77XX_BLACK);
tft.setCursor(0, 30);
tft.setTextColor(ST77XX_RED);
tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(ST77XX_YELLOW);
tft.setTextSize(2);
tft.println("Hello World!");
tft.setTextColor(ST77XX_GREEN);
tft.setTextSize(3);
tft.println("Hello World!");
tft.setTextColor(ST77XX_BLUE);
tft.setTextSize(4);
tft.print(1234.567);
delay(1500);
tft.setCursor(0, 0);
tft.fillScreen(ST77XX_BLACK);
tft.setTextColor(ST77XX_WHITE);
tft.setTextSize(0);
tft.println("Hello World!");
tft.setTextSize(1);
tft.setTextColor(ST77XX_GREEN);
tft.print(p, 6);
tft.println(" Want pi?");
tft.println(" ");
tft.print(8675309, HEX); // print 8,675,309
out in HEX!
tft.println(" Print HEX!");
tft.println(" ");
tft.setTextColor(ST77XX_WHITE);
tft.println("Sketch has been");
tft.println("running for: ");
tft.setTextColor(ST77XX_MAGENTA);
tft.print(millis() / 1000);
tft.setTextColor(ST77XX_WHITE);
tft.print(" seconds.");
}
void
mediabuttons() {
// play
tft.fillScreen(ST77XX_BLACK);
tft.fillRoundRect(25, 10, 78, 60, 8,
ST77XX_WHITE);
tft.fillTriangle(42, 20, 42, 60, 90, 40,
ST77XX_RED);
delay(500);
// pause
tft.fillRoundRect(25, 90, 78, 60, 8,
ST77XX_WHITE);
tft.fillRoundRect(39, 98, 20, 45, 5,
ST77XX_GREEN);
tft.fillRoundRect(69, 98, 20, 45, 5,
ST77XX_GREEN);
delay(500);
// play color
tft.fillTriangle(42, 20, 42, 60, 90, 40,
ST77XX_BLUE);
delay(50);
// pause color
tft.fillRoundRect(39, 98, 20, 45, 5,
ST77XX_RED);
tft.fillRoundRect(69, 98, 20, 45, 5,
ST77XX_RED);
// play color
tft.fillTriangle(42, 20, 42, 60, 90, 40,
ST77XX_GREEN);
}
The
second example illustrates how to access a graphics file (in this case a
bitmap) on an SD card and display the image on the screen.
/***************************************************
This is a library for the Adafruit 1.8"
SPI display.
This
library works with the Adafruit 1.8" TFT Breakout w/SD card
----> http://www.adafruit.com/products/358
The
1.8" TFT shield
----> https://www.adafruit.com/product/802
The
1.44" TFT breakout
---->
https://www.adafruit.com/product/2088
as
well as Adafruit raw 1.8" TFT display
----> http://www.adafruit.com/products/618
Check out the links above for our tutorials
and wiring diagrams
These displays use SPI to communicate, 4 or 5
pins are required to
interface (RST is optional)
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.
MIT license, all text above must be included
in any redistribution
****************************************************/
#include
<Adafruit_GFX.h> // Core
graphics library
#include
<Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include
<Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include
<SPI.h>
#include
<SD.h>
//
TFT display and SD card will share the hardware SPI interface.
//
Hardware SPI pins are specific to the Arduino board type and
//
cannot be remapped to alternate pins.
For Arduino Uno,
//
Duemilanove, etc., pin 11 = MOSI, pin 12 = MISO, pin 13 = SCK.
#define
TFT_CS 10 // Chip select line for TFT display
#define
TFT_RST 9 // Reset line for TFT (or see below...)
//Use
this reset pin for the shield!
//#define
TFT_RST -1 // you can also connect this to the Arduino
reset!
#define
TFT_DC 8 // Data/command line for TFT
#define
SD_CS 4 // Chip select line for SD card
//
For 0.96", 1.44" and 1.8" TFT with ST7735 use
Adafruit_ST7735
tft = Adafruit_ST7735(TFT_CS, TFT_DC,
TFT_RST);
//
For 1.54" TFT with ST7789
//Adafruit_ST7789
tft = Adafruit_ST7789(TFT_CS, TFT_DC,
TFT_RST);
void
setup(void) {
Serial.begin(9600);
while (!Serial) {
delay(10);
// wait for serial console
}
pinMode(TFT_CS, OUTPUT);
digitalWrite(TFT_CS, HIGH);
pinMode(SD_CS, OUTPUT);
digitalWrite(SD_CS, HIGH);
// Use this initializer if you're using a
1.8" TFT
tft.initR(INITR_BLACKTAB);
// Use this initializer (uncomment) if you're
using a 1.44" TFT
//tft.initR(INITR_144GREENTAB);
// Use this initializer (uncomment) if you're
using a 0.96" 180x60 TFT
//tft.initR(INITR_MINI160x80); // initialize a ST7735S chip, mini display
// Use this initializer (uncomment) if you're
using a 1.54" 240x240 TFT
//tft.init(240, 240); // initialize a ST7789 chip, 240x240 pixels
tft.fillScreen(ST77XX_BLUE);
Serial.print("
if (!SD.begin(SD_CS)) {
Serial.println("failed!");
return;
}
Serial.println("OK!");
File root = SD.open("/");
printDirectory(root, 0);
root.close();
// change the name here!
//jpgDraw("DSC_0020.JPG", 0, 0);
bmpDraw("parrot.bmp", 0, 0);
// wait 5 seconds
delay(5000);
}
void
loop() {
//
uncomment these lines to draw bitmaps in different locations/rotations!
/*
tft.fillScreen(ST7735_BLACK); // Clear
display
for(uint8_t i=0; i<4; i++) // Draw 4 parrots
bmpDraw("parrot.bmp", tft.width()
/ 4 * i, tft.height() / 4 * i);
delay(1000);
tft.setRotation(tft.getRotation() + 1); //
Inc rotation 90 degrees
*/
}
//
This function opens a Windows Bitmap (BMP) file and
//
displays it at the given coordinates.
It's sped up
//
by reading many pixels worth of data at a time
//
(rather than pixel by pixel). Increasing
the buffer
//
size takes more of the Arduino's precious RAM but
//
makes loading a little faster. 20 pixels
seems a
//
good balance.
#define
BUFFPIXEL 20
void
bmpDraw(char *filename, uint8_t x, uint16_t y) {
File
bmpFile;
int
bmpWidth, bmpHeight; // W+H in
pixels
uint8_t
bmpDepth; // Bit
depth (currently must be 24)
uint32_t bmpImageoffset; // Start of image data in file
uint32_t rowSize; // Not always = bmpWidth; may
have padding
uint8_t
sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
uint8_t
buffidx = sizeof(sdbuffer); // Current position in sdbuffer
boolean
goodBmp = false; // Set to
true on valid header parse
boolean
flip = true; // BMP is stored bottom-to-top
int
w, h, row, col;
uint8_t
r, g, b;
uint32_t pos = 0, startTime = millis();
if((x >= tft.width()) || (y >=
tft.height())) return;
Serial.println();
Serial.print(F("Loading image '"));
Serial.print(filename);
Serial.println('\'');
// Open requested file on SD card
if ((bmpFile = SD.open(filename)) == NULL) {
Serial.print(F("File not
found"));
return;
}
// Parse BMP header
if(read16(bmpFile) == 0x4D42) { // BMP
signature
Serial.print(F("File size: "));
Serial.println(read32(bmpFile));
(void)read32(bmpFile); // Read & ignore
creator bytes
bmpImageoffset = read32(bmpFile); // Start
of image data
Serial.print(F("Image Offset:
")); Serial.println(bmpImageoffset, DEC);
// Read DIB header
Serial.print(F("Header size: "));
Serial.println(read32(bmpFile));
bmpWidth
= read32(bmpFile);
bmpHeight = read32(bmpFile);
if(read16(bmpFile) == 1) { // # planes --
must be '1'
bmpDepth = read16(bmpFile); // bits per
pixel
Serial.print(F("Bit Depth: "));
Serial.println(bmpDepth);
if((bmpDepth == 24) &&
(read32(bmpFile) == 0)) { // 0 = uncompressed
goodBmp = true; // Supported BMP format
-- proceed!
Serial.print(F("Image size:
"));
Serial.print(bmpWidth);
Serial.print('x');
Serial.println(bmpHeight);
// BMP rows are padded (if needed) to
4-byte boundary
rowSize = (bmpWidth * 3 + 3) & ~3;
// If bmpHeight is negative, image is
in top-down order.
// This is not canon but has been
observed in the wild.
if(bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}
// Crop area to be loaded
w = bmpWidth;
h = bmpHeight;
if((x+w-1) >= tft.width()) w = tft.width() - x;
if((y+h-1) >= tft.height()) h =
tft.height() - y;
// Set TFT address window to clipped
image bounds
tft.setAddrWindow(x, y, x+w-1, y+h-1);
for (row=0; row<h; row++) { // For
each scanline...
// Seek to start of scan line. It might seem labor-
// intensive to be doing this on
every line, but this
// method covers a lot of gritty
details like cropping
// and scanline padding. Also, the seek only takes
// place if the file position
actually needs to change
// (avoids a lot of cluster math in
SD library).
if(flip) // Bitmap is stored
bottom-to-top order (normal BMP)
pos = bmpImageoffset + (bmpHeight -
1 - row) * rowSize;
else // Bitmap is stored top-to-bottom
pos = bmpImageoffset + row *
rowSize;
if(bmpFile.position() != pos) { //
Need seek?
bmpFile.seek(pos);
buffidx = sizeof(sdbuffer); //
Force buffer reload
}
for (col=0; col<w; col++) { // For
each pixel...
// Time to read more pixel data?
if (buffidx >= sizeof(sdbuffer))
{ // Indeed
bmpFile.read(sdbuffer,
sizeof(sdbuffer));
buffidx = 0; // Set index to
beginning
}
// Convert pixel from BMP to TFT
format, push to display
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
tft.pushColor(tft.color565(r,g,b));
} // end pixel
} // end scanline
Serial.print(F("Loaded in
"));
Serial.print(millis() - startTime);
Serial.println(" ms");
} // end goodBmp
}
}
bmpFile.close();
if(!goodBmp) Serial.println(F("BMP
format not recognized."));
}
//
These read 16- and 32-bit types from the SD card file.
//
BMP data is stored little-endian, Arduino is little-endian too.
//
May need to reverse subscript order if porting elsewhere.
uint16_t
read16(File f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); //
LSB
((uint8_t *)&result)[1] = f.read(); //
MSB
return result;
}
uint32_t
read32(File f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read(); //
LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); //
MSB
return result;
}
void
printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
I
have included the sketches so that they can be used as a physical reference for
the construction of code for various shapes, colours and effects.
SUMMARY
XXXXXXXXXXXXX
OLED
The 0.96 inch OLED display uses I2C communication and is made of 128 by 64 individual OLED
pixels. The fact that the display uses I2C communication means that it can
communicate with a microcontroller using just 2 pins. The two pins correspond to SDA and SCL and
we connect these to pins x and 19 on the Arduino, respectively.
The wiring
scheme for the Arduino is as follows:
Pin Label Arduino
pin I2C Function
GND Ground Ground
VCC 5V Power
SDA Analog 4 SDA (serial data in)
SCL Analog 5 SCL
(I2C clock)
Note that these
are the pin connections for the Arduino Uno, if you have a different boord you
will need to check which pins to connect to.
We need to
generate some data to display so I have connected the data pin of a DHT-11
temperature and humidity sensor to digital pin 2 of the Arduino.
Arduino DHT-11 OLED Circuit
Once you have
the Arduino OLED circuit constructed, open the Arduino IDE and construct a
program to display temperature and humidity from the DHT-11 sensor on the OLED
display.
/*This had been
adapted from the original sketch by Rui Santos
at http://randomnerdtutorials.com */
#include
<Wire.h>
#include
<Adafruit_GFX.h>
#include
<Adafruit_SSD1306.h>
#include
<DHT.h>
#define DHTPIN
2 // what pin we're connected to
#define DHTTYPE
DHT11 // DHT 11
#define
OLED_RESET 4
Adafruit_SSD1306
display(OLED_RESET);
// Initialize
DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN,
DHTTYPE);
void setup()
{
Wire.begin();
dht.begin(); // initialize dht
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
Serial.begin(9600);
}
void
displayTempHumid(){
delay(2000);
// Reading temperature or humidity takes
about 250 milliseconds!
float h = dht.readHumidity();
// Read temperature as Celsius
float t = dht.readTemperature();
// Read temperature as Fahrenheit
float f = dht.readTemperature(true);
// Check if any
reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
display.clearDisplay(); // clearing the
display
display.setTextColor(WHITE); //setting the
color
display.setTextSize(1); //set the font size
display.setCursor(5,0); //set the cursor
coordinates
display.print("Failed to read from DHT
sensor!");
return;
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0,0);
display.print("Humidity: ");
display.print(h);
display.print(" %\t");
display.setCursor(0,10);
display.print("Temperature: ");
display.print(t);
display.print(" C");
display.setCursor(0,20);
display.print("Temperature: ");
display.print(f);
display.print(" F");
}
void loop()
{
displayTempHumid();
display.display();
}
The display of
data should look something like this:
Try altering the circuit and
program to display other sensor data or even just to display text. This small
display is so easy to work with as connecting it up is so simple. I’m sure it
will feature in your future projects.
Motors
are everywhere. From robots and printers to industrial assembly lines and
elevators, they are invaluable to modern day living.
Motors
come in all shapes and sizes and for the purpose of this book, I will keep the
subject down to the most common small motors that can be powered and controlled
by the Arduino.
Servo Motor
Servo
motors can be found in the likes of printers and scanners. Generally they can
turn between 0 and 180 degrees and it is by selecting the degree(s) that it
turns it enables us to incorporate them in some precise applications.
The
TowerPro SG90 9G is an inexpensive servo motor which can be bought online for
only a few pounds, They generally come with an assortment of blade attachments.
Wiring
the motor to the Arduino is simple as there are only three wires to connect.
Black GND
Red 5V
Yellow Digital pin 9
On
the following pages is a sketch that you can either copy or adapt for your
projects. It starts by setting the servo angle variable (servoAngle) to 0
degrees. There then follows a routine to turn the motor to various angles
whilst pausing between each movement. Finally, there is a section which touches
on speed.
Servo Motor Wiring
Diagram
#include
<Servo.h>
int
servoPin = 9;
Servo
servo;
int
servoAngle = 0; // servo position in degrees
void
setup()
{
Serial.begin(9600);
servo.attach(servoPin);
}
void loop()
{
//control
the servo's direction and the position of the motor
servo.write(45); //
Turn servo Left to 45 degrees
delay(1000); //
Wait 1 second
servo.write(90); // Turn servo back to 90 degrees (center
position)
delay(1000); //
Wait 1 second
servo.write(135); // Turn servo Right to 135 degrees
delay(1000); //
Wait 1 second
servo.write(90); // Turn servo back to 90 degrees (center
position)
delay(1000);
//end
control the servo's direction and the position of the motor
//control
the servo's speed
//if
you change the delay value (from example change 50 to 10), the speed of the
servo changes
for(servoAngle = 0; servoAngle < 180;
servoAngle++) //move the micro servo
from 0 degrees to 180 degrees
{
servo.write(servoAngle);
delay(50);
}
for(servoAngle = 180; servoAngle > 0;
servoAngle--) //now move back the micro
servo from 0 degrees to 180 degrees
{
servo.write(servoAngle);
delay(10);
}
//end control the servo's speed
}
Try
altering the program to explore the capabilities of the servo. These small
motors could prove invaluable in your projects and it won’t break the bank
buying them.
Stepper Motor with
ULN2003 Driver
controlling
a 28BYJ-48 stepper motor with the ULN2003 driver board and Arduino
Connect
the ULN2003 driver board to four digital pins on the Arduino as follows:
Arduino ULN2003 Board
Pin
8 IN1
Pin
9 IN2
Pin
10 IN3
Pin
11 IN4
Upload
the following sketch
/*
Example sketch to control a 28BYJ-48 stepper motor with ULN2003 driver board
and Arduino UNO. More info: https://www.makerguides.com */
//
Include the Arduino Stepper.h library:
#include
<Stepper.h>
//
Define number of steps per rotation:
const
int stepsPerRevolution = 2048;
//
Wiring:
//
Pin 8 to IN1 on the ULN2003 driver
//
Pin 9 to IN2 on the ULN2003 driver
//
Pin 10 to IN3 on the ULN2003 driver
//
Pin 11 to IN4 on the ULN2003 driver
//
Create stepper object called 'myStepper', note the pin order:
Stepper
myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);
void
setup() {
// Set the speed to 5 rpm:
myStepper.setSpeed(5);
// Begin Serial communication at a baud rate
of 9600:
Serial.begin(9600);
}
void
loop() {
// Step
one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// Step one revolution in the other
direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);
}
The
motor will turn clockwise and then anticlockwise. If you open the serial
monitor you will see the status of the movement displayed:
DC Motor: L298N H-Bridge
A direct current, or DC, motor is
the most common type of motor. DC motors normally have just two
leads, one positive and one negative.
The speed of the DC motor can be altered by controlling the input voltage to
the motor. Controlling the
rotation direction requires us to inverse the direction of the current flow
through the motor. The most common method of doing that is by using an H-Bridge
The L298N is a dual H-Bridge motor driver which allows speed
and direction control of up to two DC motors at the same time.
Set up one DC motor using the L298N driver.
Arduino L298N H-
Once
the circuit is set up, construct a sketch similar to the one below:
//
connect motor controller pins to Arduino digital pins
//
motor one
int
enA = 10; //pin
10 on Arduino
int
in1 = 6; //pin
6 on Arduino
int
in2 = 5; //pin
5 on Arduino
void
setup()
{
// set the motor control pins to outputs
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
}
void
demo()
{
// this function will run the motor across
the range of speeds
// note that maximum speed is determined by
the motor itself and the
operating voltage
// the PWM values sent by analogWrite() are
fractions of the maximum speed possible by the hardware
//
turn on motor
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// accelerate from zero to maximum speed
for (int i = 0; i < 256; i++)
{
analogWrite(enA, i);
delay(20);
}
// decelerate from maximum speed to zero
for (int i = 255; i >= 0; --i)
{
analogWrite(enA, i);
delay(20);
}
// now turn off motor
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
}
void
loop()
{
delay(1000);
demo();
delay(1000);
}
This
simple sketch illustrates how to control the speed of the DC motor. By
experimenting with speeds and delays, you will soon be able to master the
control of the motor. Study and/or adapt the sketch at “Arduino - DC Motor
& Android” in the Android section to get a greater understanding of DC
motor control.
DC Motor: IRF520 MOFSET Module
The
IRF520 MOFSET module is a breakout board for the IRF520 transistor. It can
switch heavy DC loads from a single digital pin of a microcontroller. It can
drive a DC motor for robotics applications, but the module can also be used to
control most high current DC loads. It has screw terminals to interface the
loads as well as for attaching to an external power source. There is an LED
indicator that provides a visual indication of when a load is being switched.
The
specification of the module that is used here includes:
Voltage:
3.3V, 5V
Output
voltage: 0-24V
Output
current: <5A
Using
the IRF520 module, you can adjust the output by using pulse width modulation
(PWM). As the Arduino can drive up to 24V, this allows the driving of such
components as LED lights, DC motors, miniature pumps, solenoid valves as well
as the PWM dimming of LED lights. All this can be achieved in a seemingly
stepless manner.
This
example uses the HCMotor library to control a DC motor via a potentiometer
connected to analogue pin A0. The motor is connected to digital pin 7 on the
Arduino via the IRF520 MOFSET module.
Connect
the components as in the diagram below. Note that you will need an external DC
power supply for the DC motor. I used a battery pack containing two AAA
batteries which I connected to the terminals on the IRF520 module.
Once
the circuit is set up, construct a sketch similar to the one below and upload
it to the Arduino.
/*
This
sketch is adapted from the one at :http://forum.hobbycomponents.com/viewtopic.php?f=76&t=1872
The
HCMotor library was downloaded from:
https://github.com/HobbyComponents/HCMotor
*/
#include
"HCMotor.h"
/*
Set the pin that will control the motor. Note that it doesn't have to be a PWM
pin, any digital pin will do */
#define
MOTOR_PIN 7
/*
Set the analogue pin the potentiometer will be connected to. */
#define
POT_PIN A0
/*
Create an instance of the library */
HCMotor
HCMotor;
void
setup()
{
/* Initialise the library */
HCMotor.Init();
/* Attach motor 0 to digital pin 7. The first
parameter specifies the motor number, the second is the motor type, and the
third is the digital pin that will control the motor */
HCMotor.attach(0, DCMOTOR, MOTOR_PIN);
/* Set the duty cycle of the PWM signal in
100uS increments.
Here 100 x 100uS = 1mS duty cycle. */
HCMotor.DutyCycle(0, 100);
}
void
loop()
{
int Speed;
/* Read the analogue pin to determine the
position of the pot. The map function takes this value which could be anywhere
between 0 - 1024 and reduces it down to match the duty cycle range of 0 - 100
*/
Speed = map(analogRead(POT_PIN), 0, 1024, 0,
100);
/* Set the on time of the duty cycle to match
the position of the pot. */
HCMotor.OnTime(0, Speed);
}
The
IRF520 MOFSET module is a very handy way of controlling DC motors and can be
used in numerous projects where motor control is needed.
DC Motor: PWM Speed Control Module
If you want to cut down on
number of wires and connections when controlling a DC motor, you can always use
a PWM speed control module. These don’t require a microcontroller, you just
need to connect the motor and a DC power supply. Below, the Arduino is used to
supply 5V and facilitate a GND connection for the module.
The particular module that I used is a DC 4.5V-35V 5A 90W Speed Regulator. This can
be used to adjust the speed of a DC motor and can also be used as a dimmer
control for lights (LEDs).
This particular variant has
a potentiometer that can be turned off which totally turns off the power supply
to the motor. They tend to have the following features:
High voltage and high
current resettable fuse
Over current automatic
disconnection
Power off for cooling and
automatic recovery
Default disconnection of
short circuit point.
The operating voltage can
be switched to 4.5V-35V by bridging the connectors marked '4.5V-35V' on the
PCB.
Specifications:
Operating Voltage: DC
4.5V-35V
Output Current: 0-5A
Control Power: 90W (Max.)
Quiescent Current: 7uA
(Standby)
PWM Duty Cycle: 1% -100%
PWM Frequency: 20 kHz
Here, we will just use the
Arduino as a power source and use the knob to adjust the voltage and hence the
speed of the DC motor.
The module has four
connection points and can be connected to the Arduino and DC motor as follows:
Module
Motor (1) DC Motor
Motor (2) DC Motor
V+ Arduino 5V
V- Arduino GND
Once the connections are
made and power is attached to the Arduino, the speed of the DC motor can be
controlled by turning the knob on the module.
As well being used for DC
motor speed control, the voltage regulator module can be used for LED dimmer
control
Radio Frequency:
TX-C1 433MHz
The
433MHz transmitter/receiver module opens up a whole new world for the
microcontroller enthusiast. As you get both the transmitter and receiver, you
can have two Arduino boards communicating with each other. The example below
uses 2 Arduino boards.
Transmitter: This is to
be set up on Arduino number 1.
Once
the circuit has been built, construct a sketch similar to the one below that
will transmit data; in this case it will transmit the word “hello”. Upload it
to Arduino number 1.
#include
<RH_ASK.h>
#include
<SPI.h> // Not actually used but needed to compile
RH_ASK
driver;
void
setup()
{
Serial.begin(9600); // Debugging only
if (!driver.init())
Serial.println("init
failed");
}
void
loop()
{
const char *msg = "Hello World!";
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
delay(1000);
}
Now
that the transmitter is configured, we need to be able to receive the message.
Receiver: This is to
be set up on Arduino number 2.
Again,
as with the transmitter, the receiver circuit is quite simple.. I have added an
LED and this will flash to indicate that a message has been received.
Construct
a sketch similar to the one below and upload it to Arduino number 2.
#include
<RH_ASK.h>
#include
<SPI.h> // Not actualy used but needed to compile
RH_ASK
driver;
void
setup()
{
Serial.begin(9600); // Debugging only
if (!driver.init())
Serial.println("init
failed");
}
void
loop()
{
uint8_t buf[12];
uint8_t buflen = sizeof(buf);
if (driver.recv(buf, &buflen)) // Non-blocking
{
int i;
// Message with a good checksum received,
dump it.
Serial.print("Message: ");
Serial.println((char*)buf);
}
}
You
will need keep the receiver (Arduino number 2) connected to the computer via a USB
cable to view the messages that is received, The transmitter (Arduino number 1)
can be powered independently and doesn’t need to be connected to the computer.
With
the receiver (Arduino number 2) connected, open the serial monitor of the
Arduino IDE.
Serial Monitor Output of
Received Messages
Now
you have two Arduino boards communicating with each other.
These
RF modules are really good fun and very useful. I have incorporated them into
many projects including a remote weather station which sends sensor data from
my garden to a receiver inside my house that is connected to a computer.
There
are endless applications for this module and you will have great enjoyment
experimenting and incorporating them into your projects.
WiFi
Bluetooth
For
all of the Arduino Android examples, you will need to enable Bluetooth on the
Arduino. This can be done by connecting a Bluetooth module, such as the HC-0x
to the Arduino as follows:
Bluetooth
Module Arduino
VCC 3.3V
GND GND
TXD RXD
RXD TXD
Remember
to disconnect TX and RX pins (0 and 1 on the Arduino) when uploading any
sketches.
Arduino HC-05 Bluetooth
Module Circuit
Ethernet
https://www.arduino.cc/en/Guide/ArduinoEthernetShield
The shield must be assigned
a MAC address and a fixed IP address using the Ethernet.begin() function. A MAC
address is a globally unique identifier for a particular device. Current
Ethernet shields come with a sticker indicating the MAC address you should use
with them. For older shields without a dedicated MAC address, inventing a
random one should work, but don't use the same one for multiple boards. Here is
an example of how to assign a MAC address:
byte mac[] = { 0xDE, 0xAD,
0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
Valid IP addresses depend
on the configuration of your network. It is possible to use DHCP to dynamically
assign an IP to the shield. Optionally, you can also specify a network gateway
and subnet. The shield used in the following examples is a HanRun HR911105A
Ethernet shield with in-board micro SD card slot.
You will need to use a
terminal window and Telnet for some of the examples below. Telnet is disabled
by default. Tto enable it follow these steps:
Type “Settings” in the
Windows search box on the menu bar
Click “Apps & Features”
In left bar select
"Turn Windows features on or off"
Find "Telnet
Client" and tick the box
Click "OK"
Launch the Command Prompt
by typing “Command Prompt” into the search box on the menu bar and clicking the
app returned. Alternatively, you can also type Windows Key + R to open the Run
command dialog. Type “cmd” and press the Enter key. Type “telnet” and press
Enter to access the Telnet Client.
Chat Server
This
example explains how to set up a simple server that distributes any incoming
messages to all connected clients. To use, open a terminal window, Telnet to
your devices IP address, and type away. Any incoming text will be sent to all
connected clients (including the one typing). Additionally, you will be able to
see the client's input in your serial monitor as well.
The
Ethernet shield allows you to connect a WizNet Ethernet controller to the
Arduino or Genuino boards via the SPI bus. It uses pins 10, 11, 12, and 13 for
the SPI connection to the WizNet. Later models of the Ethernet shield also have
an SD Card on board. Digital pin 4 is used to control the slave select pin on
the SD card.
The
shield should be connected to a network with an ethernet cable. You will need
to change the network settings in the program to correspond to your network.
Note, depending on which Ethernet shield hardware shield that you are using,
you need to comment / uncomment the libraries at the beginning of the sketch.
Use Ethernet.h with the Arduino Ethernet Shield or Ethernet2.h with the Arduino
Ethernet Shield 2 and Leonardo Ethernet.
Attach the Ethernet shield to the Arduino. Launch the Arduinio IDE and
select the connected board. Navigate to the program by selecting “File”,
“Examples”, “Ethernet”, “ChatServer”. Upload the program to your Arduino then open
the Serial Monitor at 9600 baud rate.
Type Windows Key + R to open the Run command dialog. Type “cmd” and
press the Enter key. Type telnet and hit Enter to access the Telnet Client.
Type “telnet 192.168.1.177 23” to connect to the server. Telnet defaults
to port 23; this is included in the program code (
EthernetServer server(23); ). Open the Arduino Serial Monitor:
Once connected to the server from the Telnet client, you will see “We
have a new client” printed in the Serial Monitor of the Arduino server. If you
type anything in the Telnet window, this will be displayed in the Serial
Monitor.
DHCP Chat Server
This example
connects to a Telnet server using an Ethernet shield. Messages from the server
are printed out via the serial port. Messages can be sent to the remote server
serially as well. The Serial Monitor works well for this purpose.
This version
attempts to get an IP address using DHCP. An IP address can be assigned via
DHCP when Ethernet.begin(mac) is called. Be careful, when using the DHCP
extensions, sketch size increases significantly.
Attach the Ethernet shield to the Arduino. Launch the Arduinio IDE and
select the connected board. Navigate to the program by selecting “File”, “Examples”,
“Ethernet”, “DhcpChatServer”. Upload the program to your Arduino then open
the Serial Monitor at 9600 baud rate.
Type Windows Key + R to open the Run command dialog. Type “cmd” and
press the Enter key. Type telnet and hit Enter to access the Telnet Client.
Type “telnet 192.168.1.177 23” to telnet to your device's IP address and
type something. Telnet defaults to port 23; this is included in the program.
Open the Arduino Serial Monitor:
Once connected to the server from the Telnet client, you will see “We
have a new client” printed in the Serial Monitor of the Arduino server. If you
type anything in the Telnet window, this will be displayed in the Serial
Monitor.
Web Client
This example shows you how
to make a HTTP request using an Ethernet shield. It returns a Google search for
the term "arduino". The results of this search are viewable as HTML
in the Serial Monitor.
Attach the Ethernet shield
to the Arduino. Launch the Arduinio IDE and select the connected board.
Navigate to the program by selecting “File”, “Examples”, “Ethernet”, “WebClient”.
Upload the program to your Arduino then open the Serial Monitor at 9600
baud rate.
You will see the results of
the search scrolling on the Serial Monitor. This will go on for some considerable
time as a search for “arduino” on Google would produce over 335 million items.
Try altering the search criteria by altering this line in the program:
client.println("GET /search?q=arduino
HTTP/1.1");
Web Client Repeating
This example shows how to
make repeated HTTP requests using an Ethernet shield. This example uses DNS, by
assigning the Ethernet client with a MAC address, IP address, and DNS address.
It connects to http://www.arduino.cc/latest.txt. The content of the page is
viewable in the Serial Monitor.
Attach the Ethernet shield
to the Arduino. Launch the Arduinio IDE and select the connected board.
Navigate to the program by selecting “File”, “Examples”, “Ethernet”, “WebClientRepeating”. Upload the program to your Arduino then open
the Serial Monitor at 9600 baud rate.
Web Server
This example explains how
to host a simple HTML page that displays analog sensor values. Using the
Ethernet library, your device will be able to answer a HTTP request with your
Ethernet shield. After opening a browser and navigating to your Ethernet
shield's IP address, your Arduino will respond with just enough HTML for a
browser to display the input values from all six analog pins.
Attach the Ethernet shield
to the Arduino. Launch the Arduinio IDE and select the connected board.
Navigate to the program by selecting “File”, “Examples”, “Ethernet”, “WebServer”.
Upload the program to the Arduino. This
simple web server shows the value of the analog input pins on a
connected smart device such as mobile phone or tablet. Open the serial monitor
and you will see the server ip address. Copy the ip address into a browser of a
smart device. On the smart device you will see the value of the five analog
pins on the (Arduino) server. The Serial Monitor will display the status of any
connection.
This can form the basis of
many projects that require remote access to data. Also see the “Android”
Section for other examples of using the Arduino with Android.
Barometric Pressure Web Server
: outputs the values from a barometric
pressure sensor as a web page.
Sending and Receiving String via UDP
This example,uses an Ethernet Shield and an Arduino to
send and receive text strings via the UDP protocol (Universal Datagram Packet).
This sketch receives UDP message strings, prints them to the serial port and
sends an "acknowledge" string back to the sender, Another device is
needed to send to and from. The Processing sketch included at the end of the
code will send to and receive from an Arduino running this example. You will
need to copy this code and upload it to a second device using the Processing
IDE. The IDE can be downloaded from https://www.processing.org/download/
Attach the Ethernet shield
to the Arduino. Launch the Arduinio IDE and select the connected board.
Navigate to the program by selecting “File”, “Examples”, “Ethernet”, “UDPSendReceiveString”. Upload the program to the Arduino.
UdpNtpClient
: Query a Network Time Protocol (NTP) server
using UDP.
DNS Web Client
This example connects to a
named server using an Ethernet shield. The sketch illustrates how to connect
using DHCP and DNS. When calling Ethernet.begin(mac), the Etehrnet library
attempts to obtain an IP address using DHCP. Using DHCP significantly adds to
the sketch size; be sure there is enough space to run the program. DNS lookup
happens when client.connect(servername,port) is called. servername is a URL
string, like "www.arduino.cc". This example connects to the website http://www.google.com and searches “Arduino”. The results can be
viewed in the Arduino Serial Monitor..
Attach the Ethernet shield
to the Arduino. Launch the Arduinio IDE and select the connected board. Upload
the following program to the Arduino.
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the
shield
byte mac[] = { 0x00, 0xAA, 0xBB,
0xCC, 0xDE, 0x02 };
char serverName[] = "www.google.com";
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
void setup() {
// Open serial communications and
wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to
connect. Needed for Leonardo only
}
// start the Ethernet
connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to
configure Ethernet using DHCP");
// no point in carrying on, so
do nothing forevermore:
while(true);
}
// give the Ethernet shield a
second to initialize:
delay(1000);
Serial.println("connecting...");
// if you get a connection,
report back via serial:
if (client.connect(serverName,
80)) {
Serial.println("connected");
// Make a HTTP request:
client.println("GET
/search?q=arduino HTTP/1.0");
client.println();
}
else {
// kf you didn't get a
connection to the server:
Serial.println("connection failed");
}
}
void loop()
{
// if there are incoming bytes
available
// from the server, read them
and print them:
if (client.available()) {
char c = client.read();
Serial.print(c);
}
// if the server's disconnected,
stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
// do nothing forevermore:
while(true);
}
}
DHCP Address Printer
This sketch uses the DHCP extensions to the Ethernet
library to get an IP address via DHCP and print the address obtained using an Arduino
Ethernet shield.
DHCP is used to assign an IP address when
Ethernet.begin(mac) is called. Using DHCP significantly increases the size of a
sketch. Using the localIP() function, the assigned IP address is sent out via
the Serial Monitor.Attach the Ethernet shield to the Arduino.
Launch the Arduinio IDE and
select the connected board. Navigate to the program by selecting “File”,
“Examples”, “Ethernet”,
“DhcpAddressPrinter”. Upload the
program to the Arduino. Open the Serial Monitor and you will see the assigned
ip address.
Telnet Client
This example connects to a
Telnet server using an Ethernet shield. Messages from the server are printed
out via the serial port. Messages can be sent to the remote server serially as
well. The Serial monitor works well for this purpose.
Upload the following
program to the Arduino.
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and
IP address for your controller below.
// The IP address will be
dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress
ip(192,168,1,177);
// Enter the IP address of
the server you're connecting to:
IPAddress server(1,1,1,1);
// Initialize the Ethernet
client library
// with the IP address and
port of the server
// that you want to connect
to (port 23 is default for telnet;
// if you're using
Processing's ChatServer, use port
10002):
EthernetClient client;
void setup() {
// start the Ethernet connection:
Ethernet.begin(mac, ip);
// Open serial communications and wait for
port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect.
Needed for Leonardo only
}
// give the Ethernet shield a second to
initialize:
delay(1000);
Serial.println("connecting...");
// if you get a connection, report back via
serial:
if (client.connect(server, 10002)) {
Serial.println("connected");
}
else {
// if you didn't get a connection to the
server:
Serial.println("connection
failed");
}
}
void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char c = client.read();
Serial.print(c);
}
// as long as there are bytes in the serial
queue,
// read them and send them out the socket if
it's open:
while (Serial.available() > 0) {
char inChar = Serial.read();
if (client.connected()) {
client.print(inChar);
}
}
// if the server's disconnected, stop the
client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
// do nothing:
while(true);
}
}
You'll need a telnet server to test this with. Processing's ChatServer
example (part of the network library) works well,
running on port 10002. It can be
found as part of the examples in the Processing application, available at http://processing.org/. Enter the IP address of the server you're
connecting to at this line of code in the program:
IPAddress server(1,1,1,1);
ICs blah blah
Nlklkjlk
Jojkljlk
Dot Bar Display LM3914N-1
Shift Register 74HC595N
A shift register is an integrated circuit that converts serial
information to parallel. It requires 3 pins (as well as power and ground) from
a microcontroller but allows us to have a total of 8 outputs. Earlier in this
Section we have seen that we used one pin on the Arduino to control one LED but
by using a shift register, we can control 8 LEDs using only pins 3 pins.
For
illustration purposes, the examples below will use the 74HC595N shift register and will use digital pins
8, 11 and 12 on the Arduino to control it. Pin 11 is connected to the serial
data pin, pin 12 is connected to the clock pin and pin 8 is connected to the
latch pin.
The
8 LEDs are connected with their shorter legs (cathodes) to GND, whilst their
longer legs (anodes) are connected to the shift register output pins via 220
ohm resistors.
74HC595N
Shift Register
Connections To Arduino
We
will begin with the sketch below which scrolls up and down the LEDs in order.
The code is pretty easy to follow and it illustrates how ro achieve the turning
on and off of the LEDs.
Counting
The
first example counts from 0 t0 255 and displays the number on the LEDs.
// Adapted from
https://www.arduino.cc/en/tutorial/ShiftOut
int
latchPin = PB1; //Pin connected to ST_CP of 74HC595
int
clockPin = PB4; //Pin connected to SH_CP
of 74HC595
int
dataPin = PB0; //Pin connected to DS of 74HC595
void
setup() {
//set pins to output so you can control the
shift register
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void
loop() {
// count from 0 to 255 and display the number
// on the LEDs
for (int numberToDisplay = 0; numberToDisplay
< 256; numberToDisplay++) {
// take the latchPin low so
// the LEDs don't change while you're
sending in bits:
digitalWrite(latchPin, LOW);
// shift out the bits:
shiftOut(dataPin, clockPin, MSBFIRST,
numberToDisplay);
//take the latch pin high so the LEDs will
light up:
digitalWrite(latchPin, HIGH);
// pause before next value:
delay(500);
}
}
Upload to the Arduino using the IDE.
Using
An Array
The second example uses an array to turn the LEDs on
and off. The connections are as in the example above.
/*
Shift Register Example
Turning on the outputs of a 74HC595 using an
array
Hardware:
* 74HC595 shift register
* LEDs attached to each of the outputs of the
shift register
*/
//Pin connected
to ST_CP of 74HC595
int latchPin =
PB1;
//Pin connected
to SH_CP of 74HC595
int clockPin =
PB4;
////Pin
connected to DS of 74HC595
int dataPin =
PB0;
//holders for
infromation you're going to pass to shifting function
byte data;
byte
dataArray[10];
void setup() {
//set pins to output because they are
addressed in the main loop
pinMode(latchPin, OUTPUT);
Serial.begin(9600);
//Binary notation as comment
dataArray[0] = 0xFF; //0b11111111
dataArray[1] = 0xFE; //0b11111110
dataArray[2] = 0xFC; //0b11111100
dataArray[3] = 0xF8; //0b11111000
dataArray[4] = 0xF0; //0b11110000
dataArray[5] = 0xE0; //0b11100000
dataArray[6] = 0xC0; //0b11000000
dataArray[7] = 0x80; //0b10000000
dataArray[8] = 0x00; //0b00000000
dataArray[9] = 0xE0; //0b11100000
//function that blinks all the LEDs
//gets passed the number of blinks and the
pause time
blinkAll_2Bytes(2,500);
}
void loop() {
for (int j = 0; j < 10; j++) {
//load the light sequence you want from
array
data = dataArray[j];
//ground latchPin and hold low for as long as
you are transmitting
digitalWrite(latchPin, 0);
//move 'em out
shiftOut(dataPin, clockPin, data);
//return the latch pin high to signal chip
that it
//no longer needs to listen for information
digitalWrite(latchPin, 1);
delay(300);
}
}
// the heart of
the program
void
shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low
//internal function setup
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
//clear everything out just in case to
//prepare shift register for bit shifting
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
//for each bit in the byte myDataOut
//NOTICE THAT WE ARE COUNTING DOWN in our for
loop
//This means that %00000001 or "1"
will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--) {
digitalWrite(myClockPin, 0);
//if the value passed to myDataOut and a
bitmask result
// true then... so if we are at i=6 and our
value is
// %11010100 it would the code compares it
to %01000000
// and proceeds to set pinState to 1.
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
//Sets the pin to HIGH or LOW depending on
pinState
digitalWrite(myDataPin, pinState);
//register shifts bits on upstroke of clock
pin
digitalWrite(myClockPin, 1);
//zero the data pin after shift to prevent
bleed through
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
}
//blinks the whole register based on the number of
times you want to
//blink "n" and the pause between them
"d"
//starts with a moment of darkness to make sure the
first blink
//has its full visual effect.
void blinkAll_2Bytes(int n, int d) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin, clockPin, 0);
digitalWrite(latchPin, 1);
delay(200);
for (int x =
0; x < n; x++) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 255);
shiftOut(dataPin, clockPin, 255);
digitalWrite(latchPin, 1);
delay(d);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin,
clockPin, 0);
digitalWrite(latchPin, 1);
delay(d);
}
}
Linking
Shift Registers
To get even more……
Wiring etc
Dual Binary Counters
//**************************************************************//
// Name
: shiftOutCode, Dual Binary Counters //
// Author
: Carlyn Maw, Tom Igoe //
// Date
: 25 Oct, 2006 //
// Version : 1.0
//
// Notes
: Code for using a 74HC595 Shift Register //
// : to count from 0 to 255 //
//**************************************************************//
//Pin connected to ST_CP of
74HC595
int latchPin = PB1;
//Pin connected to SH_CP of
74HC595
int clockPin = PB4;
////Pin connected to DS of
74HC595
int dataPin = PB0;
void setup() {
//Start Serial for debuging purposes
Serial.begin(9600);
//set pins to output because they are
addressed in the main loop
pinMode(latchPin, OUTPUT);
}
void loop() {
//count up routine
for (int j = 0; j < 256; j++) {
//ground latchPin and hold low for as long
as you are transmitting
digitalWrite(latchPin, 0);
//count up on GREEN LEDs
shiftOut(dataPin, clockPin, j);
//count down on RED LEDs
shiftOut(dataPin, clockPin, 255-j);
//return the latch pin high to signal chip
that it
//no longer needs to listen for information
digitalWrite(latchPin, 1);
delay(1000);
}
}
void shiftOut(int myDataPin,
int myClockPin, byte myDataOut) {
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low
//internal function setup
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
//clear everything out just in case to
//prepare shift register for bit shifting
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
//for each bit in the byte myDataOut
//NOTICE THAT WE ARE COUNTING DOWN in our for
loop
//This means that %00000001 or "1"
will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--) {
digitalWrite(myClockPin, 0);
//if the value passed to myDataOut and a
bitmask result
// true then... so if we are at i=6 and our
value is
// %11010100 it would the code compares it
to %01000000
// and proceeds to set pinState to 1.
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
//Sets the pin to HIGH or LOW depending on
pinState
digitalWrite(myDataPin, pinState);
//register shifts bits on upstroke of clock
pin
digitalWrite(myClockPin, 1);
//zero the data pin after shift to prevent
bleed through
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
}
There
are more example sketches for use with a single 74HC595N shift register in
Appendix 1.
Shift Register SN74HC165
https://www.theengineeringprojects.com/2018/11/arduino-74hc165-interfacing-increase-input-pins.html
From the data sheet: The SNx4HC165 devices are 8-bit parallel-load shift
registers that, when clocked, shift the data toward a serial (QH) output.
Parallel-in access to each stage is provided by eight individual direct data
(A–H) inputs that are enabled by a low level at the shift/load (SH/LD) input.
The SNx4HC165 devices also feature a clock-inhibit (CLK INH) function and a
complementary serial (QH) output.
Ie
increase input pins
works
on the principal of Parallel In Serial Out.
Pin out
This is the one for the code
https://www.theengineeringprojects.com/2018/11/arduino-74hc165-interfacing-increase-input-pins.html
74HC165 will take 8 parallel inputs from different sensors or buttons
etc and will send them to serial OUT Pin, which will be connected to Arduino.
So, if you are working on a project where you want to get data of 15 or 20
digital sensors then you can use this shift register and just using a single
pin of Arduino you can read data of all those sensors. We can only get digital
inputs, we can’t get analog input through this shift register. So, let’s get
started with Arduino 74HC165 Interfacing:
Fore wiring diag - Can’t grab code http://wei48221.blogspot.com/2015/06/how-to-use-shift-register-74hc165_25.html
Circuit
10k ohm resistors
Fritzing
Code
#define NUMBER_OF_SHIFT_CHIPS
1#define DATA_WIDTH
NUMBER_OF_SHIFT_CHIPS * 8
int LoadPin = 8;
int EnablePin = 9;
int DataPin = 11;
int ClockPin = 12;
unsigned long pinValues;
unsigned long oldPinValues;
void setup()
{
Serial.begin(9600);
pinMode(LoadPin, OUTPUT);
pinMode(EnablePin, OUTPUT);
pinMode(ClockPin, OUTPUT);
pinMode(DataPin, INPUT);
digitalWrite(ClockPin, LOW);
digitalWrite(LoadPin, HIGH);
pinValues = read_shift_regs();
print_byte();
oldPinValues = pinValues;
}
void loop()
{
pinValues = read_shift_regs();
if(pinValues != oldPinValues)
{
print_byte();
oldPinValues = pinValues;
}
}
unsigned long read_shift_regs()
{
long bitVal;
unsigned long bytesVal = 0;
digitalWrite(EnablePin, HIGH);
digitalWrite(LoadPin, LOW);
delayMicroseconds(5);
digitalWrite(LoadPin, HIGH);
digitalWrite(EnablePin, LOW);
for(int i = 0; i <
DATA_WIDTH; i++)
{
bitVal =
digitalRead(DataPin);
bytesVal |= (bitVal
<< ((DATA_WIDTH-1) - i));
digitalWrite(ClockPin,
HIGH);
delayMicroseconds(5);
digitalWrite(ClockPin,
LOW);
}
return(bytesVal);
}
void print_byte() {
byte i;
Serial.println("*Shift
Register Values:*\r\n");
for(byte i=0;
i<=DATA_WIDTH-1; i++)
{
Serial.print("P");
Serial.print(i+1);
Serial.print(" ");
}
Serial.println();
for(byte i=0; i<=DATA_WIDTH-1;
i++)
{
Serial.print(pinValues
>> i & 1, BIN);
if(i>8){Serial.print("
");}
Serial.print(" ");
}
Serial.print("\n");
Serial.println();Serial.println();
}
Line Decoder SN74HCT138N
The SN74HCT138N
is a 3-to-8
line decoder/demultiplexer inverting. The 74HC138 / 74HCT138 decoders accept
three binary weighted address inputs (A0, A1, A2) and when enabled, provide 8
mutually exclusive active LOW outputs (Y0 to Y7).
The 74HCT138N is a 3-to-8
DEMUX, Inverting. That means that it can turn 3 digital outputs into 8 digital
outputs. Inverting means that the encoded output will actually be LOW, not HIGH
as would be expected. That means that if you encode, for instance, a 4, the 4rd
pin (Y3, as this is zero based) will be LOW while pins 0, 1, 2, 4, 5, 6 and 7
will be HIGH. For the purposes of this demonstration. Inverting and not
Inverting are exactly the same.
Pinout
Truth table:
Wiring
74HC138N Arduino
A0 D2
A1 D3
A2 D4
E3 D5
E1 GND
E2 GND
VCC 5V
GND GND
Y0-Y4 LED1 - 5
E1
and E2 are LOW (GND), therefore, E3 (connected to Arduino pin D5 is HIGH.
The following program will cycle through the 5
connected LEDs.
const
int selA0 = 2;
const
int selA1 = 3;
const
int selA2 = 4;
const
int E3 = 5;
void
setup()
{
//
initialize the control outputs
pinMode(selA0,
OUTPUT);
pinMode(selA1,
OUTPUT);
pinMode(selA2,
OUTPUT);
pinMode(E3,
OUTPUT);
digitalWrite(selA0,
LOW);
digitalWrite(selA1,
LOW);
digitalWrite(selA2,
LOW);
digitalWrite(E3,
HIGH);
}
void
loop()
{
/*turn
on LED 1 */
digitalWrite(selA0,
LOW);
digitalWrite(selA1,
LOW);
digitalWrite(selA2,
LOW);
delay(1000);
/*turn
on LED 2 */
digitalWrite(selA0,
HIGH);
digitalWrite(selA1,
LOW);
digitalWrite(selA2,
LOW);
delay(1000);
/*turn
on LED 3 */
digitalWrite(selA0,
LOW);
digitalWrite(selA1,
HIGH);
digitalWrite(selA2,
LOW);
delay(1000);
/*turn
on LED 4 */
digitalWrite(selA0,
HIGH);
digitalWrite(selA1,
HIGH);
digitalWrite(selA2,
LOW);
delay(1000);
/*turn
on LED 5 */
digitalWrite(selA0,
LOW);
digitalWrite(selA1,
LOW);
digitalWrite(selA2,
HIGH);
delay(1000);
The CD4051BE is an 8 channel analog
multiplexer / demultiplexer device that selects one of 8 analog signals and
forwards the selected input into a single line. It can be use in both
directions, to receive signal from sensors or to send signal (power supply
usually) to a sensor.
To select a particular channel in/out pin (y
pin; pins 11, 10 and 9 in the diagram above), you have to write to S0, S1 and
S2 with values of either LOW or HIGH. The table below shows the values that
should be written to address each of the channel in/out y pins.
|
Pin |
S0 |
S1 |
S2 |
|
y0 |
LOW |
LOW |
LOW |
|
y1 |
HIGH |
LOW |
LOW |
|
y2 |
LOW |
HIGH |
LOW |
|
y3 |
HIGH |
HIGH |
LOW |
|
y4 |
LOW |
LOW |
HIGH |
|
y5 |
HIGH |
LOW |
HIGH |
|
y6 |
LOW |
HIGH |
HIGH |
|
y7 |
HIGH |
HIGH |
HIGH |
To illustrate the selection
of channel in/out pins, I have constructed a simple sketch that will monitor
temperature (LM35 sensor) and light (LDR sensor) using just two of the data
pins on the IC.
y0 (LOW, LOW, LOW) will be
the temperature sensor and
y1 (HIGH, LOW, LOW) will be
the light sensor.
Connect the Arduino to the
CD4051BE via a solderless breadboard as follows:
|
CD4051BE |
Arduino |
|
Pin 16 (Vcc) positive
supply voltage |
5V |
|
Pin 6 (E) enable input
(active LOW) |
GND |
|
Pin 7 (Vee) negative
supply voltage |
GND |
|
Pin 8 (gnd) ground (0V) |
GND |
|
Pin 11 (S0) |
Digital pin 2 |
|
Pin 10 (S1) |
Digital pin 3 |
|
Pin 9 (S2) |
Digital pin 4 |
|
Pin 3 (Z) |
Analog pin 0 |
Once you have constructed
the circuit, write and upload a sketch similar to the one below that will
monitor pins y0 and y1 (temperature and light respectively).
#define InputPin 0 //
Input pin
int Input = 0; //
our variable
void setup() {
pinMode(2, OUTPUT); // s0
pinMode(3, OUTPUT); // s1
pinMode(4, OUTPUT); //
s2
Serial.begin(9600); // enable serial output
}
void loop(){
//Temperature Y0
digitalWrite(2, LOW); // s0
digitalWrite(3, LOW); // s1
digitalWrite(4, LOW); // s2
analogRead(InputPin); //
read the pin value
Input =
analogRead(InputPin);
Input =
(5*analogRead(InputPin)*100.0) / 1024;
Serial.println
(Input); // Print the value
delay(1000); //
Wait for 1 second
//Light Y1
digitalWrite(2, HIGH); //s0
digitalWrite(3, LOW); //
s1
digitalWrite(4, LOW); //
s2
analogRead(InputPin); //
read the pin value
Input =
analogRead(InputPin);
Serial.println
(Input); // Print the value
delay(1000);
}
The
above example efficiently reads from two channel in/out pins. You may want to
monitor more data channels and the CD4051BE enables up to eight channels to be
accessed. This is very useful as, by only using a few pins on the Arduino, you
can add more peripheral hardware and program the microcontroller to perform
other tasks whilst monitoring / collecting multiple data sources.
To
illustrate reading data from all eight channel in/out pins, I have constructed
an example that uses eight potentiometers.
Firstly,
connect each of the potentiometers to both GND and 5V on a solderless
breadboard. Connect the data pin (centre pin) of each of the potentiometers to
a separate channel in/out pin of the CD4051BE.
Connect the Arduino to the
CD4051BE via a solderless breadboard as in the previous example.
here
is the circuit diagram.
The
program is generally based on the previous one that monitored two sensors.
Firstly, the input pin is defined as analog pin 0 on the Arduino :
#define
InputPin 0 // Input pin
- analog pin
int
Input = 0; //
Define the variable
Then
the program setup defines the digital pins to be used to send either “LOW” or
“HIGH” signals to s0, s1 and s2:
pinMode(2, OUTPUT); // s0 digital pin
pinMode(3, OUTPUT); // s1 digital pin
pinMode(4, OUTPUT); // s2 digital pin
Serial
output is then enabled:
Serial.begin(9600); // enable serial output
The
loop contains the values to be written for S1, S2 and S3 which will, in turn
enable us to read each channel in/out pin (y0 to y7).
For
example, to read y0 (the first potentiometer, we need to write LOW, LOW, LOW to
s0, s1 and s2. This is done by using the digitalWrite command. Eg
digitalWrite(2,
LOW);
After
s0, s1 and s2 are written to, Analog pin 0 is read and the reading displayed on
the serial monitor followed by a comma.
This
process is repeated for all potentiometers (connected to channel in/out pints
y0 to y7). After all eight potentiometers have been read and the readings displayed,
the next set of readings will displayed on a new line. Below is the complete
program.
//4051
Mux-Demux 8 potentiometers
#define
InputPin 0 // Input pin
- analog pin
int
Input = 0; //
Define the variable
void
setup() {
pinMode(2, OUTPUT); // s0 digital pin
pinMode(3, OUTPUT); // s1 digital pin
pinMode(4, OUTPUT); // s2 digital pin
Serial.begin(9600); // enable serial output
}
void
loop(){
//y0
digitalWrite(2, LOW); // s0
digitalWrite(3, LOW); // s1
digitalWrite(4, LOW); // s3
analogRead(InputPin); // read the pin value
Input
= analogRead(InputPin);
Serial.print
(Input); // Print the value
Serial.print
(","); // comma
separator
delay(1000); // Wait for 1 second
//y1
digitalWrite(2, HIGH); // s0
digitalWrite(3, LOW); // s1
digitalWrite(4, LOW); // s3
analogRead(InputPin); // read the pin value
Input
= analogRead(InputPin);
Serial.print
(Input); // Print the value
Serial.print
(","); // comma
separator
delay(1000); // Wait for 1 second
//y2
digitalWrite(2, LOW); // s0
digitalWrite(3, HIGH); // s1
digitalWrite(4, LOW); // s3
analogRead(InputPin); // read the pin value
Input
= analogRead(InputPin);
Serial.print
(Input); // Print the value
Serial.print
(","); // comma
separator
delay(1000); // Wait for 1 second
//y3
digitalWrite(2, HIGH); // s0
digitalWrite(3, HIGH); // s1
digitalWrite(4, LOW); // s3
analogRead(InputPin); // read the pin value
Input
= analogRead(InputPin);
Serial.print
(Input); // Print the value
Serial.print
(","); // comma
separator
delay(1000); // Wait for 1 second
//y4
digitalWrite(2, LOW); // s0
digitalWrite(3, LOW); // s1
digitalWrite(4, HIGH); // s3
analogRead(InputPin); // read the pin value
Input
= analogRead(InputPin);
Serial.print
(Input); // Print the value
Serial.print
(","); // comma
separator
delay(1000); // Wait for 1 second
//y5
digitalWrite(2, HIGH); // s0
digitalWrite(3, LOW); // s1
digitalWrite(4, HIGH); // s3
analogRead(InputPin); // read the pin value
Input
= analogRead(InputPin);
Serial.print
(Input); // Print the value
Serial.print
(","); // comma
separator
delay(1000); // Wait for 1 second
//y6
digitalWrite(2, LOW); // s0
digitalWrite(3, HIGH); // s1
digitalWrite(4, HIGH); // s3
analogRead(InputPin); // read the pin value
Input
= analogRead(InputPin);
Serial.print
(Input); // Print the value
Serial.print
(","); // comma
separator
delay(1000); // Wait for 1 second
//y7
digitalWrite(2, HIGH); // s0
digitalWrite(3, HIGH); // s1
digitalWrite(4, HIGH); // s3
analogRead(InputPin); // read the pin value
Input
= analogRead(InputPin);
Serial.print
(Input); // Print the value
Serial.print
(","); // comma
separator
delay(1000); // Wait for 1 second
Serial.println
();
}
Save
the program and upload it to the Arduino. Open the serial monitor and alter
each potentiometer. You should see the values change in the serial monitor.
You
may wish to view the data graphically. This can be done using the serial
plotter but using the many features of Maker Plot, you can customize the
graphical output. Here is an example using the above program that I achieved
using the Standard Interface application in Maker Plot.
Summary
– daisy chains…..
Amplifiers
LM386 Low Voltage Audio Power Amplifier
UA7416N Operational Amplifier
TDA2822M Dual Low Voltage Power Amplifier
LM324 Single Supply Quad Operational Amplifier
YMX 807 2.2 DC 5V 20W 2.1 Dual 2 Channel 3D Surround Digital Stereo
Class-D Amplifier
Serial I2C EEPROM
AT24C256
From wiki: EEPROM (also
E2PROM) stands for Electrically Erasable Programmable Read-Only Memory and is a
type of non-volatile memory used in computers, integrated in microcontrollers
for smart cards and remote keyless system, and other electronic devices to
store relatively small amounts of data but allowing individual bytes to be
erased and reprogrammed
AT24C256
Serial EEPROM I2C Interface EEPROM is a data storage module.
There
are pins for power supply, …… power indicator on the board;
Because
this chip is I2C, it only uses the analog pins 4 & 5 (SDA and SCL), and of
course the power (5V) and GND.
Connect
as follows:
Arduino
analog pin 4 to EEPROM pin 5
Arduino
analog pin 5 to EEPROM pin 6
Arduino
5V to EEPROM pin 8
Suggested
Arduino GND to EEPROM pin 1,2,3,4 but I left pins 1,2 and 3 open, ie not
connected to anything.
Be
sure to leave pin 7 of the EEPROM open or tie it to GND otherwise the EEPROM
will be write protected.
Adapted
from http://arduinolearning.com/learning/basics/interfacing-to-a-24lc256-eeprom.php
#include
<Wire.h> // for I2C
#define
eeprom_address 0x50 // device address
byte
d=0;
void
setup()
{
Serial.begin(115200); // Initialize the
serial
Wire.begin();
//write data out
Serial.println("Writing data.");
for (int i=0; i<10; i++)
{
writeData(i,i);
}
Serial.println("Complete");
//read data back
Serial.println("
for (int i=0; i<10; i++)
{
Serial.print(i);
Serial.print(" : ");
d=readData(i);
Serial.println(d, DEC);
}
Serial.println("Complete");
}
//
writes a byte of data in memory location eaddress
void
writeData(unsigned int eaddress, byte data)
{
Wire.beginTransmission(eeprom_address);
// set the pointer position
Wire.write((int)(eaddress >> 8));
Wire.write((int)(eaddress & 0xFF));
Wire.write(data);
Wire.endTransmission();
delay(10);
}
//
reads a byte of data from memory location eaddress
byte
readData(unsigned int eaddress)
{
byte result;
Wire.beginTransmission(eeprom_address);
// set the pointer position
Wire.write((int)(eaddress >> 8));
Wire.write((int)(eaddress & 0xFF));
Wire.endTransmission();
Wire.requestFrom(eeprom_address,1); // get
the byte of data
result = Wire.read();
return result;
}
void
loop()
{
}
EEPROM AT24C02
Intro
Wiring
AT24C02 Arduino
SDA A4
SCL A5
GND GND
VCC 3,3V
#include <Wire.h>
void eeprom_i2c_write(byte
address, byte from_addr, byte data) {
Wire.beginTransmission(address);
Wire.write(from_addr);
Wire.write(data);
Wire.endTransmission();
}
byte eeprom_i2c_read(int
address, int from_addr) {
Wire.beginTransmission(address);
Wire.write(from_addr);
Wire.endTransmission();
Wire.requestFrom(address, 1);
if(Wire.available())
return Wire.read();
else
return 0xFF;
}
void setup() {
Wire.begin();
Serial.begin(9600);
for(int i = 0; i < 10; i++) {
eeprom_i2c_write(B01010000, i, 'a'+i);
delay(100);
}
Serial.println("Writen to
memory!");
}
void loop() {
for(int i = 0; i < 10; i++) {
byte r = eeprom_i2c_read(B01010000, i);
Serial.print(i);
Serial.print(" - ");
Serial.print(r);
Serial.print("\n");
delay(1000);
}
}
NE555 Frequency
Adjustable Pulse Generator
The
NE555 Frequency Adjustable Pulse Generator is a square wave pulse generator
module based on the ubiquitous NE555 timer IC. The module can be powered from a
wide power supply range (4.5 to 12V) and will produce a continuous square wave
output between 15Hz to 24KHz which can be set by the on-board multi-turn
potentiometer.
I
the example below we will monitor the analog output whilst altering the on-board
multi-turn potentiometer. Connect the module to Arduino (GND to GND, VCC to 5V
and output to analog pin A0).
Upload the
following sketch to the Arduino.
void setup()
{
Serial.begin(9600);
}
void loop()
{
analogRead(A0);
Serial.println(analogRead(A0));
delay(200);
}
Open the serial
monitor. Alter the the on-board multi-turn potentiometer.and you will see the
values change in the serial monitor.
By using a graphical program such as Maker Plot, the
evidence that the output from the module is in fact a square wave pattern
becomes evident.
Blah
blah blah
Blurp
on Android mobile devices and smartphones, IOT
App
Inventor
Develop
what’s been previously learnt in the book
Bluetooth Module
For
all of the Arduino Android examples, you will need to enable Bluetooth on the
Arduino. This can be done by connecting a Bluetooth module, such as the HC-0x
to the Arduino (as previously outlined in the Bluetooth of the Communication
section earlier). Here are the details again.
Bluetooth
Module Arduino
VCC 3.3V
GND GND
TXD RXD
RXD TXD
Remember
to disconnect TX and RX pins (0 and 1 on the Arduino) when uploading any
sketches.
Arduino HC-05 Bluetooth
Module Circuit
LED Control
The
first project is based on the simple Blink sketch that can be installed from
the example sketches on the Arduino IDE. The long leg of the LED should be
connected to pin 13 via a 220 ohm resistor and the shorter leg attached to GND
on the Arduino:
Arduino HC-05 Bluetooth Module
& LED Circuit
Upload
the following sketch:
/*
led_bluetooth_basic
Original
code - Mayoogh Girish
*/
char
data = 0; //Variable
for storing received data
void
setup()
{
Serial.begin(9600); //Sets the baud for serial data transmission
pinMode(13, OUTPUT); //Sets
digital pin 13 as output pin
}
void
loop()
{
if(Serial.available() > 0) //
Send data only when you receive data:
{
data = Serial.read(); //Read
the incoming data & store into data
Serial.print(data); //Print
Value inside data in Serial monitor
Serial.print("\n");
if(data == 'a') //Checks
whether value of data is equal to 1
digitalWrite(13, HIGH); //If value is “a” then LED turns ON
else
if(data == 'b') // Checks whether value of data is equal to 0
digitalWrite(13, LOW); //If
value is “b” then LED turns OFF
}
}
App Inventor:
Create
a new project. Set Screen to contain two labels (one for heading and one for
Bluetooth status). Create two buttons (one for switching the LED on and one for
switching the LED off). Add a clock and a Bluetooth client to the project.
Using horizontal and vertical arrangements, you can design the screen to suit
your own preferences; I have kept mine quite straight forward as can be seen in
the diagram below.
Emulator Screen Shot Of
The LED App
Now
we need some programming to make it all work. Go to the Blocks Editor and build
the following block for our ListPicker; this sets up the list of available
Bluetooth devices for the user to choose from.
The
second block connects to the device after selection.
The
next block informs the user whether the Android device is connected or not to
the HC-05 module via Bluetooth. Depending the connection status, the text and
colour of text in Label2 will change.
Finally,
here are the blocks for the two buttons:
If
Button1 is pressed, the letter “a” is sent to the Arduino. The LED will turn
on.
If
Button2 is pressed, the letter “b” is sent to the Arduino. The LED will turn
off.
Save
the project and download it either to your computer or Android device. Install
the app on an Android device and run it.
Once
the Bluetooth module is set connected to the Arduino you can develop more
projects and apps, especially as you already have the basic app blocks from
this example to build upon.
Temperature
Monitoring
We
have seen how to send data from an Android device to the Arduino, now we are
going to receive temperature sensor data. We will use the LM 35 precision
temperature sensor as described and connected to the Arduino earlier in this
book.
We
set up the Bluetooth communication as before
In
the Design View, we need to design an interface. I have designed a simple
interface with……….xxxxxxx
Arduino
sketch:
#define
tempPin 0 // sensor attached
to analog pin 0
int
Temp = 0; // set up a
variable
void
setup() {
Serial.begin(9600); // enable serial output and baud
rate
void
loop(){
analogRead(tempPin); // read the pin value
Temp
= (5.0 * analogRead(tempPin) * 100.0) / 1024;
//see below
Serial.print("Temp
"); // print “Temp”
Serial.print(Temp); // print the value
Serial.println(""); // print a blank line
delay(1000); // wait 1 second
}
*/When
the Arduino is using the 5V reference with 10bit analog to digital conversion
(ADC) it has a 1024 count. Therefore, we have to perform the following
calculation on the sensor measurement to give true temperature in Centigrade.*/
Temp
= (5.0 * analogRead(tempPin) * 100.0) / 1024
Look
at the following lines of code:
Serial.print("Temp
"); // print the word “Temp” in
the Serial
Monitor
Serial.print(Temp); // print the value in the Serial
Monitor
Serial.println(""); // print a blank line in the
Serial Monitor
Rather
than just have a number being displayed, I have added a couple of lines so the
word “Temp” is displayed before the value and " degrees centigrade"
after the value. I have also included a line to print a blank line.
Android TV Remote
Control
Obtaining
TV remote control codes and using an infrared emitter to use those codes was
introduced earlier. This will now be developed so that an Android device can
control the TV. Firstly, an HC-05 Bluetooth module and an infrared transmitter
need to be connected to the Arduino:
HC-05 Bluetooth Module
& IR Emitter Connections
The
following sketch uses the codes from a Sky+ HD remote control but it can easily
be adapted to contain the codes from any remote control. Load the sketch on to
the Arduino.
#include
<IRremote.h>
/*
SKY+
HD BUTTON HEX CODES
0xC05C01,24
BUTTON 1
irsend.sendRC6(0xC05C01,24);
C05C02 BUTTON 2
C05C03 BUTTON 3
C05C04 BUTTON 4
C05C05 BUTTON 5
C05C06 BUTTON 6
C05C07 BUTTON 7
C05C08 BUTTON 8
C05C09 BUTTON 9
C05C00 BUTTON 0
C05C5C SELECT
OR
chenge middle two digits from 5C to 01
TURN
ON/OFF irsend.sendRC6(0xC05C0C,24);
C00101
BUTTON 1
*/
IRsend
irsend;
//const
int buttonPin = 2; // the number of the pushbutton pin if using a button to send
the signal
const
int ledPin = 3;
//int
buttonState = 0; /
/ variable for reading the pushbutton status
char
data = 0; //Variable
for storing received data
void
setup()
{
Serial.begin(9600);
pinMode(13,
OUTPUT); //Sets digital pin 13 as output
pin
pinMode(ledPin, OUTPUT);
}
void
loop() {
if(Serial.available() > 0) // Send data only when you receive data:
{
data = Serial.read(); //Read the incoming data & store
into data
Serial.print(data); //Print Value inside data in Serial
monitor
Serial.print("\n");
if(data == 'a') // Checks whether value of data
is equal to 1
digitalWrite(13, HIGH); //If value is 1 then LED turns ON
else if(data == 'b') //
Checks whether value of data is equal to 0
digitalWrite(13, LOW); //If value is 0 then LED turns OFF
else if(data == '1') //
Button 1
irsend.sendRC6(0xC05C01,24);
else if(data == '2') //
Button 2
irsend.sendRC6(0xC05C02,24);
else if(data == '3') //
Button 3
irsend.sendRC6(0xC05C03,24);
else if(data == '4') //
Button 4
irsend.sendRC6(0xC05C04,24);
else if(data == '5') //
Button 5
irsend.sendRC6(0xC05C05,24);
else if(data == '6') //
Button 6
irsend.sendRC6(0xC05C06,24);
else if(data == '7') //
Button 7
irsend.sendRC6(0xC05C07,24);
else if(data == '8') //
Button 8
irsend.sendRC6(0xC05C08,24);
else if(data == '9') //
Button 9
irsend.sendRC6(0xC05C09,24);
else if(data == '0') //
Button 0
irsend.sendRC6(0xC05C00,24);
else if(data == 'A') //
Button SELECT
irsend.sendRC6(0xC05C5C,24);
delay(500); // wait for half a
second
}
}
App inventor
Emulator Screenshot Of The TV Remote Control App
On
Screen1, set up your required buttons, a ListPicker and add a Bluetooth Client
(I’ve added a background image to this example).
In
the Blocks Editor the same blocks relating to the ListPicker in the LED example
can be used again here:
The
individual buttons need to be configured. In this example, the ASCII codes for
the corresponding numbers have been used. Here is an example of some of my
button codes:
i.e.
ASCII code “52” corresponds to the number “4”, ASCII code “55” corresponds to
the number “7” and so on.
Now,
if you were to lose your TV remote control over a holiday period and the shops
were all closed, you can build your own and use your Android device to operate
your TV.
Servo Motor
Control
#include
<Servo.h>
Servo
ser; //
create servo object to control a servo
int
poser = 90;
// initial position of servo
int
value; //
initial value of input
void
setup()
{
Serial.begin(9600);
// Serial comm begin at 9600bps
ser.attach(9); //
server is connected at pin 9
}
void
loop()
{
while(Serial.available()) //read while
data is present
{
value
= Serial.read(); //value
= serial read data from Android device
poser
= value ; //position of servo motor
equals the value read from Android device
ser.write(poser); // the servo will
move according to position
delay(15);
}
}
App
Inventor:
DC Motor Control
Blah
Blah
blah
Arduino
sketch:
int
motorVoltage;
int
enA = 10;
//pin 7 on L293D
int
in1 = 6;
//pin 8 on L293D
int
in2 = 5; //pin
9 on L293D
int
state;
int
flag=0; //makes sure that the serial only prints once
the state
int
stateStop=0;
void
setup() {
// sets the pins as outputs:
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
motorVoltage=60; // sets enable1Pin and enable2Pin high so
that motor can turn on:
digitalWrite(enA, HIGH);
// initialize serial communication at 9600
bits per second:
Serial.begin(9600);
}
void
loop() {
//if some date is sent, reads it and saves
in state
if(Serial.available() > 0){
state = Serial.read();
flag=0;
}
// if the state is 'F' the DC motor will go
FORWARD
if (state == 'F') {
// set speed to 60 out of possible range
0~255
analogWrite(enA, motorVoltage);
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
if(flag == 0){
Serial.println("Go
Forward!");
flag=1;
}
}
// if the state is 'B' the motor will
REVERSE
else if (state == 'B') {
// set speed to 60 out of possible
range 0~255
analogWrite(enA, motorVoltage);
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
if(flag == 0){
Serial.println("Reverse!");
flag=1;
}
}
// if the state is 'S' the motor will STOP
else if (state == 'S' || stateStop == 1) {
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
if(flag == 0){
Serial.println("STOP!");
flag=1;
}
stateStop=0;
}
// if the state is 'R' the motor will SPEED
UP
else if (state == 'R') {
analogWrite (enA, motorVoltage++);
delay (200);
if(flag == 0){
Serial.println("Speed Up");
flag=1;
}
delay(1500);
state=3;
}
// if the state is 'L' the motor will SLOW
DOWN
else if (state == 'L') {
// set speed to slow down
{
analogWrite (enA, motorVoltage--);
delay (200);
}
//digitalWrite(in1, LOW);
//digitalWrite(in2, HIGH);
if(flag == 0){
Serial.println("Slow
Down");
flag=1;
}
delay(1500);
state=3;
}
}
blah
App Inventor
Wouldn’t
it be good to have more than one sensor in a system? Here is a project that
incorporates sensors for light, temperature, humidity and tilt. There is a 16x2
LED to display data and a potentiometer is also included.
The
basic weather station components’ set-ups are outlined earlier in this Section
and here they are brought together.
Once
the circuit has been constructed, you will need to construct a sketch similar
to the one below to collect, process and display the data.
//
This demo code uses 4 different sensors and an LCD module
//
to demonstrate reading a displaying continuous sensor data.
//
Data is read from a mechanical tilt sensor to show FLAT or TILT
//
An LDR is used to measure light level and is roughly converted to Lux
//
A DHT11 is used to measure Humidity in %RH
//
Finally an LM35 is used to measure temperature in degrees centigrade
//
//
This code may be freely used and copied.
//
//
Gareth Davies - June 2012
//
////////////////////////////////////////////////
#include
<LiquidCrystal.h>
#include
<dht11.h>
LiquidCrystal
lcd(12, 11, 5, 4, 3, 2);
int
Temp, Light, Humidity, hCheck;
boolean
Tilt;
#define
tempPin 0
#define
lightPin 1
#define
tiltPin 6
#define
humidityPin 7
dht11
DHT11;
//
initialise LCD library and pins
void
setup() {
lcd.begin(16, 2);
pinMode(tiltPin, INPUT);
}
void
loop()
{
Temp = (5.0 * analogRead(tempPin) * 100.0) /
1024;
delay(10);
Light = toLux(analogRead(lightPin));
hCheck = DHT11.read(humidityPin);
if(hCheck != 0)
Humidity = 255; //Must be an error
else
Humidity = DHT11.humidity;
Tilt = (digitalRead(tiltPin) == LOW);
showData(Temp, Light, Humidity, Tilt);
delay(1000);
}
//
Change the ADC reading to Lux. Assumes a 10K pull up resistor to 5V
/* Vcc 5
Pullup 10000
Lux Ohms Voltage ADC Scaling
0 1023
1 200000 4.76 975 -0.020937188
10 30000 3.75 768 -0.043428309
80 5000 1.67 341 -0.1640625
120 4000 1.43 293 -0.8203125
150 3000 1.15 236 -0.533203125
250 2000 0.83 171 -1.5234375
300 1800 0.76 156 -3.45703125
800 700 0.33 67 -5.604580966
*/
int
toLux(int adc)
{
//
return (map(adc, 0, 1023, 900, 0)); simple linear model
if (adc > 975)
return 1;
else if (adc > 768)
return 1 + 0.04 * (adc - 768);
else if (adc > 341)
return 10 + 0.16 * (adc - 341);
else if (adc > 293)
return 80 + 0.82 * (adc - 293);
else if (adc > 236)
return 120 + 0.53 * (adc - 236);
else if (adc > 171)
return 150 + 1.52 * (adc - 171);
else if (adc > 156)
return 250 + 3.46 * (adc - 156);
else
return 300 + 5.6 * (adc - 67);
}
void
showData (int temp, int light, int humidity, boolean tilt)
{
String s1, s2, s3;
String spaces = " ";
s1 = String(temp) + char(0xdf) +
"C";
s2 = String (light) + "Lux";
s3 = s1 + spaces.substring(0, 16 -
s1.length() - s2.length()) + s2;
lcd.setCursor(0,0);
lcd.print(s3);
if(humidity == 255)
s1 = "ERROR";
else
s1 = String(humidity) + "%";
if (tilt)
s2 = "TILT";
else
s2 = "FLAT";
s3 = s1 + spaces.substring(0, 16 -
s1.length() - s2.length()) + s2;
lcd.setCursor(0,1);
lcd.print(s3);
}
An
SD Card module could be added to the project to store the data as it is
collected. A buzzer could be added and code written for the buzzer to sound when
any of the sensor readings fall outside of pre-determined ranges of values.
No comments:
Post a Comment