After eight years and much feedback from various readers, I’m proud to offer the second edition of my first book “Arduino Workshop”, from No Starch Press. This is a revised update to this very popular book which is aimed at any person who wants to make electronic devices using the Arduino platform – but has no experience in electronics, programming or microcontrollers.
The reader doesn’t need to buy or read any other book first to get started, from the beginning they are introduced to the basic concepts, required software installation and then introduced to various topics from blinking an LED to controlling devices remotely via a cellular phone.
Contents include:
Chapter 1: Getting Started Chapter 2: Exploring the Arduino Board and the IDE Chapter 3: First Steps Chapter 4: Building Blocks Chapter 5: Working with Functions Chapter 6: Numbers, Variables, and Arithmetic Chapter 7: Expanding Your Arduino Chapter 8: LED Numeric Displays and Matrices Chapter 9: Liquid Crystal Displays Chapter 10: Creating your own Arduino Libraries Chapter 11: Numeric Keypads Chapter 12: Accepting User Input with Touchscreens Chapter 13: Meet the Arduino Family Chapter 14: Motors and Movement Chapter 15: Using GPS with Your Arduino Chapter 16: Wireless Data Chapter 17: Infrared Remote Control Chapter 18: Reading RFID Tags Chapter 19: Data Buses Chapter 20: Real-time Clocks Chapter 21: The Internet Chapter 22: Cellular Communications
You can also review the entire book index from here.
Once the reader has progressed through “Arduino Workshop”, I have found that many people use it as a reference guide for various topics, and saves them time and effort. Instead of searching randomly for various videos, web pages or whatnot – this book offers solid, tried-and-tested information that can be relied on without worry.
Readers of the first edition will also be introduced to new chapters in this edition, such as learning how to create your own Arduino libraries, introduction to the new v2.0 IDE, using new types of LED displays, remote control of devices with LoRA wireless shields, an updated cellular chapter that uses contemporary 3G wireless, and more.
The book is printed using a convenient lie-flat technology, so you can have the book open to your side and not worry about the pages flapping about and losing your position while working on your projects. All the required code (or Arduino “sketches”) are included in the book, however you can also download them along with a list of parts and supplier information from the book’s website.
The Arduino platform in my opinion is still the easiest and most approachable way of learning about electronics and microcontrollers, and opens up a whole new world of creativity or even the pathway to a career in technology, and a copy of “Arduino Workshop” is the best guide to this world.
You can learn more about the book and order from the No Starch Press online store, amazon, kindle, or your preferred bookseller. Orders from No Starch Press also include a free electronic copy so you can get started immediately.
In this tutorial we look at how to use the neat LED Real Time Clock Temperature Sensor Shield for Arduino from PMD Way. That’s a bit of a mouthful, however the shield does offer the following:
four digit, seven-segment LED display
DS1307 real-time clock IC
three buttons
four LEDs
a active buzzer
a light-dependent resistor (LDR)
and a thermistor for measuring ambient temperature
The shield also arrives fully-assembled , so you can just plug it into your Arduino Uno or compatible board. Neat, beginners will love that. So let’s get started, by showing how each function can be used – then some example projects. In no particular order…
The buzzer
A high-pitched active buzzer is connected to digital pin D6 – which can be turned on and off with a simple digitalWrite() function. So let’s do that now, for example:
voidsetup(){// buzzer on digital pin 6pinMode(6,OUTPUT);}// the loop function runs over and over again forevervoidloop(){digitalWrite(6,HIGH);// turn the buzzer on (HIGH is the voltage level)delay(1000);// wait for a seconddigitalWrite(6,LOW);// turn the buzzer off by making the voltage LOWdelay(1000);// wait for a second}
If there is a white sticker over your buzzer, remove it before uploading the sketch. Now for a quick video demonstration. Turn down your volume before playback.
The LEDs
Our shield has four LEDs, as shown below:
They’re labelled D1 through to D4, with D1 on the right-hand side. They are wired to digital outputs D2, D3, D4 and D5 respectively. Again, they can be used with digitalWrite() – so let’s do that now with a quick demonstration of some blinky goodness. Our sketch turns the LEDs on and off in sequential order. You can change the delay by altering the variable x:
voidsetup(){// initialize digital pin LED_BUILTIN as an output.pinMode(2,OUTPUT);// LED 1pinMode(3,OUTPUT);// LED 2pinMode(4,OUTPUT);// LED 3pinMode(5,OUTPUT);// LED 4}intx=200;voidloop(){digitalWrite(2,HIGH);// turn on LED1delay(x);digitalWrite(2,LOW);// turn off LED1. Process repeats for the other three LEDsdigitalWrite(3,HIGH);delay(x);digitalWrite(3,LOW);digitalWrite(4,HIGH);delay(x);digitalWrite(4,LOW);digitalWrite(5,HIGH);delay(x);digitalWrite(5,LOW);}
And in action:
The Buttons
It is now time to pay attention to the three large buttons on the bottom-left of the shield. They look imposing however are just normal buttons, and from right-to-left are connected to digital pins D9, D10 and D11:
They are, however, wired without external pull-up or pull-down resistors so when initialising them in your Arduino sketch you need to activate the digital input’s internal pull-up resistor inside the microcontroller using:
pinMode(pin, INPUT_PULLUP);
Due to this, buttons are by default HIGH when not pressed. So when you press a button, they return LOW. The following sketch demonstrates the use of the buttons by lighting LEDs when pressed:
voidsetup(){// initalise digital pins for LEDs as outputspinMode(2,OUTPUT);// LED 1pinMode(3,OUTPUT);// LED 2pinMode(4,OUTPUT);// LED 3// initalise digital pins for buttons as inputs// and initialise internal pullupspinMode(9,INPUT_PULLUP);// button K1pinMode(10,INPUT_PULLUP);// button K2pinMode(11,INPUT_PULLUP);// button K3}voidloop(){if(digitalRead(9)==LOW){digitalWrite(2,HIGH);delay(10);digitalWrite(2,LOW);}if(digitalRead(10)==LOW){digitalWrite(3,HIGH);delay(10);digitalWrite(3,LOW);}if(digitalRead(11)==LOW){digitalWrite(4,HIGH);delay(10);digitalWrite(4,LOW);}}
You can see these in action via the following video:
The Numerical LED Display
Our shield has a nice red four-digit, seven-segment LED clock display. We call it a clock display as there are colon LEDs between the second and third digit, just as a digital clock would usually have:
The TM1636 itself is an interesting part, so we’ll explain that in a separate tutorial in the near future. For now, back to the shield.
To control the LED display we need to install an Arduino library. In fact the shield needs four, so you can install them all at once now. Download the .zip file from here. Then expand that into your local download directory – it contains four library folders. You can then install them one at a time using the Arduino IDE’s Sketch > Include library > Add .zip library… command:
The supplied library offers five functions used to control the display.
.num(x);
…this displays a positive integer (whole number) between 0 and 9999.
.display(p,d);
… this shows a digit d in location p (locations from left to right are 3, 2, 1, 0)
.time(h,m)
… this is used to display time data (hours, minutes) easily. h is hours, m is minutes
.pointOn();
.pointOff();
… these turn the colon on … and off. And finally:
.clear();
… which clears the display to all off. At the start of the sketch, we need to use the library and initiate the instance of the display by inserting the following lines:
#include <TTSDisplay.h>
TTSDisplay rtcshield;
Don’t panic – the following sketch demonstrates the five functions described above:
#include<TTSDisplay.h>TTSDisplayrtcshield;inta=0;intb=0;voidsetup(){}voidloop(){// display some numbersfor(a=4921;a<5101;a++){rtcshield.num(a);delay(10);}// clear displayrtcshield.clear();// display individual digitsfor(a=3;a>=0;--a){rtcshield.display(a,a);delay(1000);rtcshield.clear();}for(a=3;a>=0;--a){rtcshield.display(a,a);delay(1000);rtcshield.clear();}// turn the colon and offfor(a=0;a<5;a++){rtcshield.pointOn();delay(500);rtcshield.pointOff();delay(500);}// demo the time display functionrtcshield.pointOn();rtcshield.time(11,57);delay(1000);rtcshield.time(11,58);delay(1000);rtcshield.time(11,59);delay(1000);rtcshield.time(12,00);delay(1000);}
And you can see it in action through the video below:
The LDR (Light Dependent Resistor)
LDRs are useful for giving basic light level measurements, and our shield has one connected to analog input pin A1. It’s the two-legged item with the squiggle on top as shown below:
The resistance of LDRs change with light levels – the greater the light, the less the resistance. Thus by measuring the voltage of a current through the LDR with an analog input pin – you can get a numerical value proportional to the ambient light level. And that’s just what the following sketch does:
#include<TTSDisplay.h>TTSDisplayrtcshield;inta=0;voidsetup(){}voidloop(){// read value of analog inputa=analogRead(A1);// show value on displayrtcshield.num(a);delay(100);}
The Thermistor
A thermistor is a resistor whose resistance is relative to the ambient temperature. As the temperature increases, their resistance decreases. It’s the black part to the left of the LDR in the image below:
We can use this relationship between temperature and resistance to determine the ambient temperature. To keep things simple we won’t go into the theory – instead, just show you how to get a reading.
The thermistor circuit on our shield has the output connected to analog input zero, and we can use the library installed earlier to take care of the mathematics. Which just leaves us with the functions.
At the start of the sketch, we need to use the library and initiate the instance of the thermistor by inserting the following lines:
#include <TTSTemp.h>
TTSTemp temp;
… then use the following which returns a positive integer containing the temperature (so no freezing cold environments):
.get();
For our example, we’ll get the temperature and show it on the numerical display:
And our thermometer in action. No video this time… a nice 24 degrees C in the office:
The Real-Time Clock
Our shield is fitted with a DS1307 real-time clock IC circuit and backup battery holder. If you insert a CR1220 battery, the RTC will remember the settings even if you remove the shield from the Arduino or if there’s a power blackout, board reset etc:
The DS1307 is incredibly popular and used in many projects and found on many inexpensive breakout boards. We have a separate tutorial on how to use the DS1307, so instead of repeating ourselves – please visit our specific DS1307 Arduino tutorial, then return when finished.
Where to from here?
We can image there are many practical uses for this shield, which will not only improve your Arduino coding skills but also have some useful applications. An example is given below, that you can use for learning or fun.
Temperature Alarm
This projects turns the shield into a temperature monitor – you can select a lower and upper temperature, and if the temperature goes outside that range the buzzer can sound until you press it.
Here’s the sketch:
#include<TTSDisplay.h>#include<TTSTemp.h>TTSTemptemp;TTSDisplayrtcshield;booleanalarmOnOff=false;inthighTemp=40;intlowTemp=10;intcurrentTemp;voidLEDsoff(){// function to turn all alarm high/low LEDs offdigitalWrite(2,LOW);digitalWrite(4,LOW);}voidsetup(){// initalise digital pins for LEDs and buzzer as outputspinMode(2,OUTPUT);// LED 1pinMode(3,OUTPUT);// LED 2pinMode(4,OUTPUT);// LED 3pinMode(5,OUTPUT);// LED 4pinMode(6,OUTPUT);// buzzer// initalise digital pins for buttons as inputs// and initialise internal pullupspinMode(9,INPUT_PULLUP);// button K1pinMode(10,INPUT_PULLUP);// button K2pinMode(11,INPUT_PULLUP);// button K3}voidloop(){// get current temperaturecurrentTemp=temp.get();// if current temperature is within set limts// show temperature on displayif(currentTemp>=lowTemp||currentTemp<=highTemp)// if ambient temperature is less than high boundary// OR if ambient temperature is grater than low boundary// all is well{LEDsoff();// turn off LEDsrtcshield.num(currentTemp);}// if current temperature is above set high bounday, show red LED and// show temperature on display// turn on buzzer if alarm is set to on (button K3)if(currentTemp>highTemp){LEDsoff();// turn off LEDsdigitalWrite(4,HIGH);// turn on red LEDrtcshield.num(currentTemp);if(alarmOnOff==true){digitalWrite(6,HIGH);// buzzer on }}}// if current temperature is below set lower boundary, show blue LED and// show temperature on display// turn on buzzer if alarm is set to on (button K3)if(currentTemp<lowTemp){LEDsoff();// turn off LEDsdigitalWrite(2,HIGH);// turn on blue LEDrtcshield.num(currentTemp);if(alarmOnOff==true){digitalWrite(6,HIGH);// buzzer on }}}// --------turn alarm on or off-----------------------------------------------------if(digitalRead(11)==LOW)// turn alarm on or off{alarmOnOff=!alarmOnOff;if(alarmOnOff==0){digitalWrite(6,LOW);// turn off buzzerdigitalWrite(5,LOW);// turn off alarm on LED}// if alarm is set to on, turn LED on to indicate thisif(alarmOnOff==1){digitalWrite(5,HIGH);}delay(300);// software debounce}// --------set low temperature------------------------------------------------------if(digitalRead(10)==LOW)// set low temperature. If temp falls below this value, activate alarm{// clear display and turn on blue LED to indicate user is setting lower boundaryrtcshield.clear();digitalWrite(2,HIGH);// turn on blue LEDrtcshield.num(lowTemp);// user can press buttons K2 and K1 to decrease/increase lower boundary.// once user presses button K3, lower boundary is locked in and unit goes// back to normal statewhile(digitalRead(11)!=LOW)// repeat the following code until the user presses button K3{if(digitalRead(10)==LOW)// if button K2 pressed{--lowTemp;// subtract one from lower boundary// display new value. If this falls below zero, won't display. You can add checks for this yourself :)rtcshield.num(lowTemp);}if(digitalRead(9)==LOW)// if button K3 pressed{lowTemp++;// add one to lower boundary// display new value. If this exceeds 9999, won't display. You can add checks for this yourself :)rtcshield.num(lowTemp);}delay(300);// for switch debounce}digitalWrite(2,LOW);// turn off blue LED}// --------set high temperature-----------------------------------------------------if(digitalRead(9)==LOW)// set high temperature. If temp exceeds this value, activate alarm{// clear display and turn on red LED to indicate user is setting lower boundaryrtcshield.clear();digitalWrite(4,HIGH);// turn on red LEDrtcshield.num(highTemp);// user can press buttons K2 and K1 to decrease/increase upper boundary.// once user presses button K3, upper boundary is locked in and unit goes// back to normal statewhile(digitalRead(11)!=LOW)// repeat the following code until the user presses button K3{if(digitalRead(10)==LOW)// if button K2 pressed{--highTemp;// subtract one from upper boundary// display new value. If this falls below zero, won't display. You can add checks for this yourself :)rtcshield.num(highTemp);}if(digitalRead(9)==LOW)// if button K3 pressed{highTemp++;// add one to upper boundary// display new value. If this exceeds 9999, won't display. You can add checks for this yourself :)rtcshield.num(highTemp);}delay(300);// for switch debounce}digitalWrite(4,LOW);// turn off red LED}}
Operating instructions:
To set lower temperature, – press button K2. Blue LED turns on. Use buttons K2 and K1 to select temperature, then press K3 to lock it in. Blue LED turns off.
To set upper temperature – press button K1. Red LED turns on. Use buttons K2 and K1 to select temperature, then press K3 to lock it in. Red LED turns off.
If temperature drops below lower or exceeds upper temperature, the blue or red LED will come on.
You can have the buzzer sound when the alarm activates – to do this, press K3. When the buzzer mode is on, LED D4 will be on. You can turn buzzer off after it activates by pressing K3.
Display will show ambient temperature during normal operation.
You can see this in action via the video below:
Conclusion
This is a fun and useful shield – especially for beginners. It offers a lot of fun and options without any difficult coding or soldering – it’s easy to find success with the shield and increase your motivation to learn more and make more.
You can be serious with a clock, or annoy people with the buzzer. And at the time of writing you can have one for US$14.95, delivered. So go forth and create something.
A little research has shown that this shield was based from a product by Seeed, who discontinued it from sale. I’d like to thank them for the library.
This post brought to you by pmdway.com – everything for makers and electronics enthusiasts, with free delivery worldwide.
To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on twitter @tronixstuff.
This is a quick start guide for the Four Digit Seven Segment Display Module and Enclosure from PMD Way. This module offers a neat and bright display which is ideal for numeric or hexadecimal data. It can display the digits 0 to 9 including the decimal point, and the letters A to F. You can also control each segment individually if desired.
Each module contains four 74HC595 shift registers – once of each controls a digit. If you carefully remove the back panel from the enclosure, you can see the pin connections:
If you’re only using one display, use the group of pins at the centre-bottom of the board. From left to right the connections are:
Data out (ignore for single display use)
VCC – connect to a 3.3V or 5V supply
GND – connect to your GND line
SDI – data in – connect to the data out pin on your Arduino/other board
LCK – latch – connect to the output pin on your Arduino or other board that will control the latch
CLK – clock – connect to the output pin on your Arduino or other board that will control the clock signal
For the purposes of our Arduino tutorial, connect VCC to the 5V pin, GND to GND, SDI to D11, LCK to D13 and CLK to D12.
If you are connecting more than one module, use the pins on the left- and right-hand side of the module. Start with the connections from your Arduino (etc) to the right-hand side, as this is where the DIN (data in) pin is located.
Then connect the pins on the left-hand side of the module to the right-hand side of the new module – and so forth. SDO (data out) will connect to the SDI (data in) – with the other pins being identical for connection.
The module schematic is shown below:
Arduino Example Sketch
Once you have made the connections to your Arduino as outlined above, upload the following sketch:
// Demonstration Arduino sketch for four digit, seven segment display with enclosure
// https://pmdway.com/collections/7-segment-numeric-leds/products/four-digit-seven-segment-display-module-and-enclosure int latchPin = 13; // connect to LCK pin
intclockPin = 12; // connect to CLK pin
intdataPin = 11; // connect to SDI pin
int LED_SEG_TAB[]={
0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0x01,0xee,0x3e,0x1a,0x7a,0x9e,0x8e,0x01,0x00};
//0 1 2 3 4 5 6 7 8 9 dp . a b c d e f off
void setup()
{
//set pins to output so you can control the shift register
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void displayNumber(int value, boolean leadingZero)
// break down "value" into digits and store in a,b,c,d
{
int a,b,c,d;
a = value / 1000;
value = value % 1000;
b = value / 100;
value = value % 100;
c = value / 10;
value = value % 10;
d = value;
if (leadingZero==false) // removing leading zeros
{
if (a==0 && b>0) {
a = 18;
}
if (a==0 && b==0 && c>0) {
a = 18;
b = 18;
}
if (a==0 && b==0 && c==0) {
a = 18;
b = 18;
c = 18;
}
if (a==0 && b==0 && c==0 && d==0) {
a = 18;
b = 18;
c = 18;
d = 18;
}
}
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[d]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[c]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[b]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[a]);
digitalWrite(latchPin, HIGH);
}
void allOff() // turns off all segments
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, 0);
shiftOut(dataPin, clockPin, LSBFIRST, 0);
shiftOut(dataPin, clockPin, LSBFIRST, 0);
shiftOut(dataPin, clockPin, LSBFIRST, 0);
digitalWrite(latchPin, HIGH);
}
void loop()
{
for (int z=900; z<=1100; z++)
{
displayNumber(z, false);
delay(10);
}
delay(1000);
for (int z=120; z>=0; --z)
{
displayNumber(z, true);
delay(10);
}
delay(1000);
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[14]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[13]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[12]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[11]);
digitalWrite(latchPin, HIGH);
delay(1000);
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[16]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[15]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[14]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[13]);
digitalWrite(latchPin, HIGH);
delay(1000);
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[0]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[1]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[2]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[3]+1);
digitalWrite(latchPin, HIGH);
delay(1000);
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[7]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[6]+1);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[5]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_SEG_TAB[4]);
digitalWrite(latchPin, HIGH);
delay(1000);
}
After a moment you should see the display spring into action in the same way as in the demonstration video:
How does it work?
First we define which digital output pins are used for latch, clock and data on lines four to six. On line eight we have created an array which contains values that are sent to the shift registers in the module to display the possible digits and letters. For example, the first – 0xfc – will activate the segments to display a zero, 0x7a for the letter C, and so on.
From line 20 we’ve created a custom function that is used to send a whole number between zero and 9999 to the display. To do so, simply use:
void displayNumber(value, true/false);
where value is the number to display (or variable containing the number) – and the second parameter of true or false. This controls whether you have a leading zero displayed – true for yes, false for no.
For example, to display “0123” you would use:
displayNumber(123, true);
… which results with:
or to display “500” you would use:
displayNumber(500, false);
… which results with:
To turn off all the digits, you need to send zeros to every bit in the shift register, and this is accomplished with the function in the sketch called
allOff();
What about the decimal point?
To turn on the decimal point for a particular digit, add 1 to the value being sent to a particular digit. Using the code from the demonstration sketch to display 87.65 you would use:
In-depth explanation of how the module is controlled
As shown in the schematic above, each digit is controlled by a 74HC595 shift register. Each shift register has eight digital outputs, each of which control an individual segment of each digit. So by sending four bytes of data (one byte = eight bits) you can control each segment of the display.
Each digit’s segments are mapped as follows:
And the outputs from each shift register match the order of segments from left to right. So outputs 0~7 match A~G then decimal point.
For example, to create the number seven with a decimal point, you need to turn on segments A, B, C and DP – which match to the shift register’s outputs 0,1,2,8.
Thus the byte to send to the shift register would be 0b11100001 (or 225 in decimal or 0xE1 in hexadecimal).
Every time you want to change the display you need to re-draw all four (or more if more than one module is connected) digits – so four bytes of data are sent for each display change. The digits are addressed from right to left, so the first byte send is for the last digit – and the last byte is for the first digit.
There are three stages of updating the display.
Set the LCK (latch) line low
Shift out four bytes of data from your microcontroller
Note how the bytes in binary match the map of the digits and their position. For example, the first byte sent was for the fourth digit, and the segment A was turned on. And that’s all there is to it – a neat and simple display.
This post brought to you by pmdway.com – everything for makers and electronics enthusiasts, with free delivery worldwide.
To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on twitter @tronixstuff.
Oops. Blynk has changed in the last few years so we’ll be re-writing this post in the near future. Subscribe to the mailing list in the box on the right, or follow us on twitter @tronixstuff for updates.
You must be logged in to post a comment.