Posts with «tronixstuff» label

Kit Review – Altronics/Silicon Chip ISD2590 Digital Message Recorder

Introduction

Every month Australian electronics magazine Silicon Chip publishes a variety of projects, and in February 1994 they published the “90 Second Digital Message Recorder” project. That was a long time ago, however you can still find the kit today at Altronics (and at the time of writing, on sale for AU$26), and thus the subject of our review.

The kit offers a simple method of recording and playing back 90 seconds of audio, captured with an electret microphone. When mounted in a suitable enclosure it will make a neat way of leaving messages or instructions for others at home.

Assembly

The kit arrives in typical Altronics fashion:

… and includes everything required including IC sockets for the ISD2590 and the audio amplifier:

The PCB missed out on silk-screening – which is a pity:

however it is from an original design from twenty years ago. The solder mask is neat and helps prevent against lazy soldering mistakes:

Finally the detailed instructions including component layout and the handy Altronics reference guide are also included. After checking and ordering the resistors, they were installed first along with the links:

 If you have your own kit, there is a small error in the instructions. The resistor between the 2k2 and the 10uF electrolytic at the top of the board is 10k0 not 2k2. Moving on, these followed by the capacitors and other low-profile components:

The rest of the components went in without any fuss, and frankly it’s a very easy kit to assemble:

 The required power supply is 6V, and a power switch and 4 x AA cell holder is included however were omitted for the review.

How it works

Instead of some fancy microcontrollers, the kit uses an ISD2590P single chip voice recording and playback IC:

It’s a neat part that takes care of most of the required functions including microphone preamp, automatic gain control, and an EEPROM to store the analogue voltage levels that make up the voice sample. The ISD2590 samples audio at 5.3 kHz which isn’t CD quality, but enough for its intended purpose.

Apart from some passive components for power filtering, controls and a speaker amplifier there isn’t much else to say. Download the ISD2590 data sheet (pdf), which is incredibly detailed including some example circuits.

Operation

Once you apply power it’s a simple matter of setting the toggle switch on the PCB down for record, or up for playback. You can record in more than one session, and each session is recorded in order until the memory is full. Then the sounds can be played back without any fuss.

The kit is supplied with the generic 0.25W speaker which is perhaps a little weak for the amplifier circuit in the kit, however by turning down the volume a little the sound is adequate. In this video you can see (and hear) a quick recording and playback session.

Conclusion

This kit could be the base for convenient message system – and much more interesting than just scribbling notes for each other. Or you could built it into a toy and have it play various tunes or speech to amuse children. And for the price it’s great value to experiment with an ISD2590 – just use an IC socket. Or just have some fun  – we did.  Full-sized images are available on flickr

And if you enjoyed this article, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop”.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our forum – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Kit Review – Altronics/Silicon Chip ISD2590 Digital Message Recorder appeared first on tronixstuff.

Tronixstuff 23 Jan 03:34

Online data analysis with Arduino and plotly

Introduction

It’s 2014 and the Internet-of-Things is flying along at a rapid rate with all sorts of services and devices that share data and allow control via the Internet. In the spirit of this we look a new service called plotly.

This is a “collaborative data analysis and graphing tool” which allows you to upload your own data to be analysed in many ways, and then graph the results using all sorts of plot types.

With plotly you can run your own mathematical functions over your data, run intense statistical analysis and use or edit one of the many APIs (PythonMATLABRJuliaRESTArduino, or Perl) to increase the level of customisation. Plotly works in conjunction with Google Drive to store your data, however this can be exported and imported without any issues. Futhermore plotly works best in Google Chrome.

For our review we’ll look at using plotly to quickly display and analyse data received from an Internet-connected Arduino – our EtherTen, or you can use almost any Arduino and Ethernet shield. The system isn’t completely documented however by revieiwng our example sketch and some experimenting with the interface plotly is very much usable, even in its current beta format.

Getting started with plotly

You will need to setup a plotly account, and this is simply accomplished from their main site. Some of you may be wondering what plotly costs – at the time of writing plotly is free for unlimited public use (that is – anyone can see your data with the right URL), but requires a subscription for extended private use. You can find the costs at the plans page.

Once you have a plotly account, visit your plotly home page, whose URL is https://plot.ly/~yourusername/# – then click “edit profile”. Another window will appear which amongst other things contains your plotly API key – make a note of this as you will need it and your username for the Arduino sketch.

Next, you’ll need some Arduino or compatible hardware to capture the data to log and analyse. An Arduino with an Ethernet or WiFi connection, and appropriate sensors for your application. We have our EtherTen that takes readings from a temperature/humidity sensor and a light level sensor:

Now you need a new Arduino library, which is available from the plotly API page. Lots of APIs there… Anyhow, click “Arduino” and you will arrive at the github page. Download the entire .zip file, and extract the plotly_ethernet folder into Arduino libraries folder which in most installations can be found at ..Arduino-1.0.xlibraries. 

Finally we’ll use a demonstration sketch provided by plotly and modify this to our needs, which can be downloaded from github. We’ll go through this sketch and show you what to update – so have a quick look and then at out example sketch at the end of this section.

First, insert any code required to get data from your sensors and store the data in a variable – do this so the values can be used in void loop. Next, update the MAC address and the IP address of your Ethernet-enabled Arduino with the following lines:

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte my_ip[] = { 192,168,0,77 };

and change the MAC and IP if necessary. If Arduino and Ethernet is new to you, check out the tutorial. Now look for the following two lines and enter your plotly username and API key:

plotly.username = "yourplotlyusername";
plotly.api_key = "yourplotlyAPIkey";

Next – it’s a good idea to set your time zone, so the time in plots makes sense. Add the following two lines in void setup():

plotly.timestamp = true; 
plotly.timezone = "Australia/Melbourne";

You can find a list of time zones available for use with plotly here. Now you need to determine how many traces and points to use. A trace is one source of data, for example temperature. For now you will have one point, so set these parameters using the following lines:

int nTraces=x; // x = number of traces
int nPoints=1;

For example, we will plot temperature, humidity and light level – so this requires three traces. The next step is to set the filename for the plot, using the following line:

char filename[] = "simple_example";

This will be sent to plotly and your data will be saved under that name. At the point in your sketch where you want to send some data back to plotly, use:

plotly.open_stream(nPoints, nTraces, filename, layout);

… then the following for each trace:

plotly.post(millis(),data);

where data is the variable to send back to plotly. We use millis() as our example is logging data against time.

To put all that together, consider our example sketch with the hardware mentioned earlier:

// Code modified from example provied by plot.ly

#include <SPI.h>
#include <Ethernet.h>
#include "plotly_ethernet.h"
#include "DHT.h"

// DHT Sensor Setup
#define DHTPIN 2               // We have connected the DHT to Digital Pin 2
#define DHTTYPE DHT22          // This is the type of DHT Sensor (Change it to DHT11 if you're using that model)
DHT dht(DHTPIN, DHTTYPE);      // Initialize DHT object
plotly plotly;                 // initialize a plotly object, named plotly

//initialize plotly global variables
char layout[]="{}";
char filename[] = "Office Weather and Light"; // name of the plot that will be saved in your plotly account -- resaving to the same filename will simply extend the existing traces with new data

float h, t, ll;
int lightLevel;

// Ethernet Setup
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // doesn't really matter
byte my_ip[] = { 192, 168, 1, 77 }; // google will tell you: "public ip address"

void startEthernet(){
  Serial.println("Initializing ethernet");
  if(Ethernet.begin(mac) == 0){
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, my_ip);
  }
  Serial.println("Done initializing ethernet");
  delay(1000);
}

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
  }

  dht.begin(); // initialize dht sensor reading
  startEthernet();    // initialize ethernet

    // Initialize plotly settings
  plotly.VERBOSE = true; // turn to false to suppress printing over serial
  plotly.DRY_RUN = false; // turn to false when you want to connect to plotly's servers 
  plotly.username = "yourplotlyusername"; // your plotly username -- sign up at https://plot.ly/ssu or feel free to use this public account. password of the account is "password"
  plotly.api_key = "yourplotlyapikey"; // "public_arduino"'s api_key -- char api_key[10]
  plotly.timestamp = true; // tell plotly that you're stamping your data with a millisecond counter and that you want plotly to convert it into a date-formatted graph
  plotly.timezone = "Australia/Melbourne"; // full list of timezones is here:https://github.com/plotly/arduino-api/blob/master/Accepted%20Timezone%20Strings.txt
}

void loop() 
{
  // gather data to plot
  h = dht.readHumidity(); // read humitidy from DHT pin
  t = dht.readTemperature();
  lightLevel = analogRead(A5);
  ll = lightLevel / 100; // reduce the value from the light sensor

  // Open the Stream
  plotly.open_stream(1, 3, filename, layout); // plotlystream(number_of_points, number_of_traces, filename, layout)

  plotly.post(millis(),t); // post temperature to plotly (trace 1)
  delay(150);
  plotly.post(millis(),h); // post humidity to plotly (trace 2)
  delay(150);
  plotly.post(millis(),lightLevel); // post light sensor readout to plotly (trace 3)

  for(int i=0; i<300; i++)
  { // (once every five minutes)
    delay(1000);
  }
}

After wiring up the hardware and uploading the sketch, the data will be sent until the power is removed from the Arduino.

Monitoring sensor data

Now that your hardware is sending the data off to plotly, you can check it out in real time. Log into plotly and visit the data home page – https://plot.ly/plot – for example:

Your data file will be listed – so just click on the file name to be presented with a very basic graph. Over time you will see it develop as the data is received, however you may want to alter the display, headings, labels and so on. Generally you can click on trace labels, titles and so on to change them, the interface is pretty intuitive after a few moments. A quick screencast of this is shown in this video.

To view and analyse the raw data – and create all sorts of custom plots, graphs and other analysis – click the “view data in grid” icon which is the second from the left along the bar:

At which point your data will be displayed in a new tab:

From this point you can experiment to your heart’s content – just don’t forget to save your work. In a short amount of time your data can be presented visually and analysed with ease:

Conclusion

Although plotly is still in beta form, it works well and the developers are responsive to any questions – so there isn’t much more to say but give it a try yourself, doing so won’t cost you anything and you can see how useful plotly is for yourself. And if you enjoyed this article, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop”.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our forum – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.
Tronixstuff 21 Jan 05:29
analysis  api  arduino  data  ethernet  internet  iot  of  online  plotly  things  tronixstuff  tutorial  

Online data analysis with Arduino and plotly

Introduction

It’s 2014 and the Internet-of-Things is flying along at a rapid rate with all sorts of services and devices that share data and allow control via the Internet. In the spirit of this we look a new service called plotly.

This is a “collaborative data analysis and graphing tool” which allows you to upload your own data to be analysed in many ways, and then graph the results using all sorts of plot types.

With plotly you can run your own mathematical functions over your data, run intense statistical analysis and use or edit one of the many APIs (PythonMATLABRJuliaRESTArduino, or Perl) to increase the level of customisation. Plotly works in conjunction with Google Drive to store your data, however this can be exported and imported without any issues. Futhermore plotly works best in Google Chrome.

For our review we’ll look at using plotly to quickly display and analyse data received from an Internet-connected Arduino – our EtherTen, or you can use almost any Arduino and Ethernet shield. The system isn’t completely documented however by revieiwng our example sketch and some experimenting with the interface plotly is very much usable, even in its current beta format.

Getting started with plotly

You will need to setup a plotly account, and this is simply accomplished from their main site. Some of you may be wondering what plotly costs – at the time of writing plotly is free for unlimited public use (that is – anyone can see your data with the right URL), but requires a subscription for extended private use. You can find the costs at the plans page.

Once you have a plotly account, visit your plotly home page, whose URL is https://plot.ly/~yourusername/# – then click “edit profile”. Another window will appear which amongst other things contains your plotly API key – make a note of this as you will need it and your username for the Arduino sketch.

Next, you’ll need some Arduino or compatible hardware to capture the data to log and analyse. An Arduino with an Ethernet or WiFi connection, and appropriate sensors for your application. We have our EtherTen that takes readings from a temperature/humidity sensor and a light level sensor:

Now you need a new Arduino library, which is available from the plotly API page. Lots of APIs there… Anyhow, click “Arduino” and you will arrive at the github page. Download the entire .zip file, and extract the plotly_ethernet folder into Arduino libraries folder which in most installations can be found at ..\Arduino-1.0.x\libraries. 

Finally we’ll use a demonstration sketch provided by plotly and modify this to our needs, which can be downloaded from github. We’ll go through this sketch and show you what to update – so have a quick look and then at out example sketch at the end of this section.

First, insert any code required to get data from your sensors and store the data in a variable – do this so the values can be used in void loop. Next, update the MAC address and the IP address of your Ethernet-enabled Arduino with the following lines:

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte my_ip[] = { 192,168,0,77 };

and change the MAC and IP if necessary. If Arduino and Ethernet is new to you, check out the tutorial. Now look for the following two lines and enter your plotly username and API key:

plotly.username = "yourplotlyusername";
plotly.api_key = "yourplotlyAPIkey";

Next – it’s a good idea to set your time zone, so the time in plots makes sense. Add the following two lines in void setup():

plotly.timestamp = true; 
plotly.timezone = "Australia/Melbourne";

You can find a list of time zones available for use with plotly here. Now you need to determine how many traces and points to use. A trace is one source of data, for example temperature. For now you will have one point, so set these parameters using the following lines:

int nTraces=x; // x = number of traces
int nPoints=1;

For example, we will plot temperature, humidity and light level – so this requires three traces. The next step is to set the filename for the plot, using the following line:

char filename[] = "simple_example";

This will be sent to plotly and your data will be saved under that name. At the point in your sketch where you want to send some data back to plotly, use:

plotly.open_stream(nPoints, nTraces, filename, layout);

… then the following for each trace:

plotly.post(millis(),data);

where data is the variable to send back to plotly. We use millis() as our example is logging data against time.

To put all that together, consider our example sketch with the hardware mentioned earlier:

// Code modified from example provied by plot.ly

#include <SPI.h>
#include <Ethernet.h>
#include "plotly_ethernet.h"
#include "DHT.h"

// DHT Sensor Setup
#define DHTPIN 2               // We have connected the DHT to Digital Pin 2
#define DHTTYPE DHT22          // This is the type of DHT Sensor (Change it to DHT11 if you're using that model)
DHT dht(DHTPIN, DHTTYPE);      // Initialize DHT object
plotly plotly;                 // initialize a plotly object, named plotly

//initialize plotly global variables
char layout[]="{}";
char filename[] = "Office Weather and Light"; // name of the plot that will be saved in your plotly account -- resaving to the same filename will simply extend the existing traces with new data

float h, t, ll;
int lightLevel;

// Ethernet Setup
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // doesn't really matter
byte my_ip[] = { 192, 168, 1, 77 }; // google will tell you: "public ip address"

void startEthernet(){
  Serial.println("Initializing ethernet");
  if(Ethernet.begin(mac) == 0){
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, my_ip);
  }
  Serial.println("Done initializing ethernet");
  delay(1000);
}

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
  }

  dht.begin(); // initialize dht sensor reading
  startEthernet();    // initialize ethernet

    // Initialize plotly settings
  plotly.VERBOSE = true; // turn to false to suppress printing over serial
  plotly.DRY_RUN = false; // turn to false when you want to connect to plotly's servers 
  plotly.username = "yourplotlyusername"; // your plotly username -- sign up at https://plot.ly/ssu or feel free to use this public account. password of the account is "password"
  plotly.api_key = "yourplotlyapikey"; // "public_arduino"'s api_key -- char api_key[10]
  plotly.timestamp = true; // tell plotly that you're stamping your data with a millisecond counter and that you want plotly to convert it into a date-formatted graph
  plotly.timezone = "Australia/Melbourne"; // full list of timezones is here:https://github.com/plotly/arduino-api/blob/master/Accepted%20Timezone%20Strings.txt
}

void loop() 
{
  // gather data to plot
  h = dht.readHumidity(); // read humitidy from DHT pin
  t = dht.readTemperature();
  lightLevel = analogRead(A5);
  ll = lightLevel / 100; // reduce the value from the light sensor

  // Open the Stream
  plotly.open_stream(1, 3, filename, layout); // plotlystream(number_of_points, number_of_traces, filename, layout)

  plotly.post(millis(),t); // post temperature to plotly (trace 1)
  delay(150);
  plotly.post(millis(),h); // post humidity to plotly (trace 2)
  delay(150);
  plotly.post(millis(),lightLevel); // post light sensor readout to plotly (trace 3)

  for(int i=0; i<300; i++)
  { // (once every five minutes)
    delay(1000);
  }
}

After wiring up the hardware and uploading the sketch, the data will be sent until the power is removed from the Arduino.

Monitoring sensor data

Now that your hardware is sending the data off to plotly, you can check it out in real time. Log into plotly and visit the data home page – https://plot.ly/plot – for example:

Your data file will be listed – so just click on the file name to be presented with a very basic graph. Over time you will see it develop as the data is received, however you may want to alter the display, headings, labels and so on. Generally you can click on trace labels, titles and so on to change them, the interface is pretty intuitive after a few moments. A quick screencast of this is shown in this video.

To view and analyse the raw data – and create all sorts of custom plots, graphs and other analysis – click the “view data in grid” icon which is the second from the left along the bar:

At which point your data will be displayed in a new tab:

From this point you can experiment to your heart’s content – just don’t forget to save your work. In a short amount of time your data can be presented visually and analysed with ease:

Conclusion

Although plotly is still in beta form, it works well and the developers are responsive to any questions – so there isn’t much more to say but give it a try yourself, doing so won’t cost you anything and you can see how useful plotly is for yourself. And if you enjoyed this article, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop”.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our forum – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Online data analysis with Arduino and plotly appeared first on tronixstuff.

Tronixstuff 21 Jan 05:29
analysis  api  arduino  data  ethernet  internet  iot  of  online  plotly  things  tronixstuff  tutorial  

Tutorial – Arduino Mega and SM5100B GSM Cellular

Connect your Arduino Mega or compatible to the cellular network with the SM5100 GSM module shield from Tronixlabs. If you have an Arduino Uno or compatible, visit this page. If you are looking for tutorials using the SIMCOM SIM900 GSM module, click here.

This is chapter twenty-seven of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.

Updated 18/01/2014

Introduction

The purpose of this tutorial is to have your Arduino Mega to communicate over a GSM mobile telephone network using a shield based on the SM5100B module from Tronixlabs. We’ve written this as the shield from Sparkfun used in the previous tutorial was somewhat fiddly for use with an Arduino Mega – so this shield is a more convenient alternative:

Our goal is to illustrate various methods of interaction between an Arduino Mega and the GSM cellular network using the shield shown above, with which you can then use your existing knowledge to build upon those methods. Doing so isn’t easy – but it isn’t that difficult.

Stop! Please read first:

  • It is assumed that you have a solid understanding of how to program your Arduino. If not, start from chapter zero
  • Sending SMS messages and making phone calls cost real money, so it would be very wise to use a prepaid cellular account or one  that allows a fair amount of calls/SMS
  • The GSM shield only works with “2G” GSM mobile networks operating on the 850, 900 and PCS1800 MHz frequencies. If in doubt, ask your carrier first
  • Australians – you can use any carrier’s SIM card
  • Canadians – this doesn’t work with Sasktel
  • North Americans – check with your cellular carrier first if you can use third-party hardware (i.e. the shield)
  • I cannot offer design advice for your project nor technical support for this article.
  • If you are working on a college/university project and need specific help – talk to your tutors or academic staff. They get paid to help you.
  • Please don’t make an auto-dialler…

 

Getting started

Before moving forward there us one vital point you need to understand – the power supply. The GSM shield can often require up to 2A of current in short bursts – especially when turned on, reset, or initiating a call.

However your Arduino board can only supply just under 1A. It is highly recommended that you use an external regulated power supply of between 9 and 12 VDC capable of delivering 2A of current – from an AC adaptor, large battery with power regulator, etc. Otherwise there is a very strong probability of damaging your shield and Arduino. When connecting this supply use the Vin and GND pins. Do not under any circumstances power the Arduino and shield from just the USB power.

Next – use an antenna! The wire hanging from the shield is not an antenna. YOU NEED THE ANTENNA! For example:

Furthermore, care needs to be taken with your GSM shield with regards to the aerial lead-module connection, it is very fragile:

Pressing the hardware reset button on the shield doesn’t reset the GSM module – you need to remove the power for a second. And finally, download this document (.pdf). It contains all the AT and ERROR codes that will turn up when you least expect it. Please review it if you are presented with a code you are unsure about.

Wow – all those rules and warnings?

The sections above may sound a little authoritarian, however I want your project to be a success. With the previous iterations of the tutorial people just didn’t follow the instructions – so we hope you do.

Initial check – does it work?

This may sound like a silly question, but considering the cost of the shield and the variables involved, it is a good idea to check if your setup is functioning correctly before moving on. From a hardware perspective for this article, you will need your Arduino board, the GSM shield with activated SIM card and an aerial, and the power supply connected.

Next you need to set the serial line jumpers. These determine which of the four hardware serial ports we use to communicate with the GSM module. Place a jumper over each of the RX1 and TX1 pairs as shown in the following image. By doing this the communication with the GSM module is via Serial1 in our sketches, leaving Serial for normal communications such as the serial monitor.

Make sure your SIM card is set to not require a PIN when the phone is turned on. You can check and turn this requirement off with your cellphone. 

For our initial test, upload the following sketch:

// Example 27.1

char incoming_char=0;      // Will hold the incoming character from the Serial Port.
void setup()
{
  //Initialize serial ports for communication.
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial.println("Starting SM5100B Communication...");
}
void loop()
{
  //If a character comes in from the cellular module...
  if(Serial1.available() >0)
  {
    incoming_char=Serial1.read();    // Get the character from the cellular serial port.
    Serial.print(incoming_char);  // Print the incoming character to the terminal.
  }
  //If a character is coming from the terminal to the Arduino...
  if(Serial.available() >0)
  {
    incoming_char=Serial.read();  // Get the character coming from the terminal
    Serial1.print(incoming_char);    // Send the character to the cellular module.
  }
}

Then connect the GSM shield, aerial, insert the SIM card and apply power. Open the serial monitor box in the Arduino IDE and you should be presented with the following:

It will take around fifteen to thirty seconds for the text above to appear in full. What you are being presented with is a log of the GSM module’s actions. But what do they all mean?

  • +SIND: 1 means the SIM card has been inserted;
  • the +SIND: 10 line shows the status of the in-module phone book. Nothing to worry about there for us at the moment;
  • +SIND: 11 means the module has registered with the cellular network
  • +SIND: 3 means the module is partially ready to communicate
  • and +SIND: 4 means the module is registered on the network, and ready to communicate

All the SIND data and other codes the module will give you are listed in the AT command guide we suggested you download. Please use it – any comments such as “What’s +SIND:5?” will be deleted.

From this point on, we will need to use a different terminal program, as the Arduino IDE’s serial monitor box isn’t made for full two-way communications. You will need a terminal program that can offer full two-way com port/serial communication. For those running MS Windows, an excellent option is available here.

It’s free, however consider donating for the use of it. For other operating systems, people say this works well. So now let’s try it out with the terminal software. Close your Arduino IDE serial monitor box if still open, then run your terminal, set it to look at the same serial port as the Arduino IDE was. Ensure the settings are 9600, 8, N, 1. Then reset your Arduino and the following should appear:

The next step is to tell the GSM module which network frequency(ies) to use. View page 127 of the AT command document. There is a range of frequency choices that our module can use. If you don’t know which one to use, contact the telephone company that your SIM card came from. Australia – use option 4. Find your option, then enter:

AT+SBAND=x

(where X is the value matching your required frequency) into the terminal software and click SEND. Then press reset on the Arduino and watch the terminal display. You should hopefully be presented with the same text as above, ending with +SIND: 4. If your module returns +SIND: 4, we’re ready to move forward.

If your terminal returned a +SIND: 8 instead of 4, double-check your hardware, power supply, antenna, and the frequency band chosen. If all that checks out call your network provider to see if they’re rejecting the GSM module on their network.

Our next test is to call our shield. So, pick up a phone and call it. Your shield will return data to the terminal window, for example:

As you can see, the module returns what is happening. I let the originating phone “ring” three times, and the module received the caller ID data (sorry, blacked it out). Some telephone subscribers’ accounts don’t send caller ID data, so if you don’t see your number, no problem. “NO CARRIER” occurred when I ended the call. +SIND: 6,1 means the call ended and the SIM is ready.

Have your Arduino “call you”

The document (.pdf) you downloaded earlier contains a list of AT commands – consider this a guide to the language with which we instruct the GSM module to do things. Let’s try out some more commands before completing our initial test. The first one is:

ATDxxxxxx

which dials a telephone number xxxxxx. For example, to call (212)-8675309 use:

ATD2128675309

The next one is:

ATH

which “hangs up” or ends the call. So, let’s reach out and touch someone. In the terminal software, enter your ATDxxxxxxxx command, then hit send. Let your phone ring. Then enter ATH to end the call. If you are experimenting and want to hang up in a hurry, you can also hit reset on the Arduino and it will end the call as well as resetting the system.

So by now you should realise the GSM module is controlled by these AT commands. To use an AT command in a sketch, we use the function:

Serial1.println()

Remember that we used Serial1 as the jumpers on the shield board are set to connect the GSM module to the Serial1 hardware serial port. For example, to dial a phone number, we would use:

Serial1.println("ATD2128675309");

To demonstrate this in a sketch, consider the following simple sketch which dials a telephone number, waits, then hangs up. Replace xxxxxxxx with the number you wish to call:

// Example 27.2

void setup()
{ 
  Serial.begin(9600);
  Serial1.begin(9600);
  delay(10);
  Serial.println("starting delay");
  delay(30000); // give the GSM module time to initialise, locate network etc.
  // this delay time varies. Use example 27.1 sketch to measure the amount
  // of time from board reset to SIND: 4, then add five seconds just in case
}

void loop()
{
  Serial.println("dialling");
  Serial1.println("ATDxxxxxxxxxx"); // dial the phone number xxxxxxxxx
  // change xxxxxxxxxx to your desired phone number (with area code)
  delay(20000); // wait 20 seconds.
  Serial.println("hang up");
  Serial1.println("ATH"); // end call
  do // remove this loop at your peril
  { 
    delay(1); 
  }
  while (1>0);
}

The sketch in example 27.2 assumes that all is well with regards to the GSM module, that is the SIM card is ok, there is reception, etc. The long delay function in void setup() is used to allow time for the module to wake up and get connected to the network. Later on we will read the messages from the GSM module to allow our sketches to deal with errors and so on. However, you can see how we can simply dial a telephone. And here’s a quick video for the non-believers.

Send an SMS from your Arduino

Another popular function is the SMS or short message service, or text messaging. Before moving forward, download and install Meir Michanie’s SerialGSM Arduino library from here. Some of you might be thinking “why are we using a software serial in the following sketch?”. Short answer – it’s just easier.

Sending a text message is incredibly simple – consider the following sketch:

// Example 27.3

#include <SerialGSM.h>
#include <SoftwareSerial.h>
SerialGSM cell(19,18);

void setup()
{ 
  delay(30000); // wait for GSM module
  cell.begin(9600);
}

void sendSMS()
{
  cell.Verbose(true); // used for debugging
  cell.Boot(); 
  cell.FwdSMS2Serial();
  cell.Rcpt("+xxxxxxxxx"); // replace xxxxxxxxx with the recipient's cellular number
  cell.Message("Contents of your text message");
  cell.SendSMS();
}
void loop()
{
  sendSMS();
  do // remove this loop at your peril
  { 
    delay(1); 
  }
  while (1>0);
}

It’s super-simple – just change the phone number to send the text message, and of course the message you want to send. The phone numbers must be in international format, e.g. Australia 0418 123456 is +61418123456 or USA (609) 8675309 is +16098675309. And the results:

Reach out and control something

Now let’s discuss how to make something happen by a simple telephone call. And the best thing is that we don’t need the the GSM module to answer the telephone call (thereby saving money) – just let the module ring a few times. How is this possible? Very easily. Recall Example 27.1 above – we monitored the activity of the GSM module by using our terminal software.

In this case what we need to do is have our Arduino examine the text coming in from the serial output of the GSM module, and look for a particular string of characters.

When we telephone the GSM module from another number, the module returns the text as shown in the image below:

We want to look for the text “RING”, as (obviously) this means that the GSM shield has recognised the ring signal from the exchange. Therefore need our Arduino to count the number of rings for the particular telephone call being made to the module. (Memories – Many years ago we would use public telephones to send messages to each other.

For example, after arriving at a foreign destination we would call home and let the phone ring five times then hang up – which meant we had arrived safely). Finally, once the GSM shield has received a set number of rings, we want the Arduino to do something.

From a software perspective, we need to examine each character as it is returned from the GSM shield. Once an “R” is received, we examine the next character. If it is an “I”, we examine the next character. If it is an “N”, we examine the next character. If it is a “G”, we know an inbound call is being attempted, and one ring has occurred.

We can set the number of rings to wait until out desired function is called. In the following example, when the shield is called, it will call the function doSomething() after three rings.

The function doSomething() controls two LEDs, two red,  two green. Every time the GSM module is called for 3 rings, the Arduino alternately turns on or off the LEDs. Using the following sketch as an example, you now have the ability to turn basically anything on or off, or call your own particular function:

// Example 27.4

char inchar; // Will hold the incoming character from the Serial Port.
int numring=0;
int comring=3; 
int onoff=0; // 0 = off, 1 = on

int led1 = 9;
int led2 = 10;
int led3 = 11;
int led4 = 12;

void setup()
{
  // prepare the digital output pins
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);

  //Initialize GSM module serial port for communication.
  Serial1.begin(9600);
  delay(30000); // give time for GSM module to register on network etc.
}

void doSomething()
{
  if (onoff==0)
  {
    onoff=1;
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);    
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);    

  } 
  else
    if (onoff==1)
    {
      onoff=0;
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);    
      digitalWrite(led3, HIGH);
      digitalWrite(led4, HIGH);  
    }
}

void loop() 
{
  //If a character comes in from the cellular module...
  if(Serial1.available() >0)
  {
    inchar=Serial1.read(); 
    if (inchar=='R')
    {
      delay(10);
      inchar=Serial1.read(); 
      if (inchar=='I')
      {
        delay(10);
        inchar=Serial1.read();
        if (inchar=='N')
        {
          delay(10);
          inchar=Serial1.read(); 
          if (inchar=='G')
          {
            delay(10);
            // So the phone (our GSM shield) has 'rung' once, i.e. if it were a real phone
            // it would have sounded 'ring-ring'
            numring++;
            if (numring==comring)
            {
              numring=0; // reset ring counter
              doSomething();
            }
          }
        }
      }
    }
  }
}

And now for a quick video demonstration. Each time a call to the shield is made, the pairs of LEDs alternate between on and off. Although this may seem like an over-simplified example, with your existing Arduino knowledge you now have the ability to run any function by calling your GSM shield.

 

Control Digital I/O via SMS

Now although turning one thing on or off is convenient, how can we send more control information to our GSM module? For example, control four or more digital outputs at once? These sorts of commands can be achieved by the reception and analysis of text messages.

Doing so is similar to the method we used in example 27.4. Once again, we will analyse the characters being sent from the GSM module via its serial out. However, there are two AT commands we need to send to the GSM module before we can receive SMSs, and one afterwards. The first one you already know:

AT+CMGF=1

Which sets the SMS mode to text. The second command is:

AT+CNMI=3,3,0,0

This command tells the GSM module to immediately send any new SMS data to the serial out. An example of this is shown in the terminal capture below:

Two text messages have been received since the module was turned on. You can see how the data is laid out. The blacked out number is the sender of the SMS. The number +61418706700 is the number for my carrier’s SMSC (short message service centre). Then we have the date and time. The next line is the contents of the text message – what we need to examine in our sketch.

The second text message in the example above is how we will structure our control SMS. Our sketch will wait for a # to come from the serial line, then consider the values after a, b, c and d – 0 for off, 1 for on. Finally, we need to send one more command to the GSM module after we have interpreted our SMS:

AT+CMGD=1,4

This deletes all the text messages from the SIM card. As there is a finite amount of storage space on the SIM, it is prudent to delete the incoming message after we have followed the instructions within. But now for our example. We will control four digital outputs, D9~12. For the sake of the exercise we are controlling an LED on each digital output, however you could do anything you like.

Although the sketch may seem long and complex, it is not – just follow it through and you will see what is happening:

// Example 27.5

char inchar; // Will hold the incoming character from the Serial Port.

int led1 = 9;
int led2 = 10;
int led3 = 11;
int led4 = 12;

void setup()
{
  // prepare the digital output pins
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);

  //Initialize GSM module serial port for communication.
  Serial1.begin(9600);
  delay(30000); // give time for GSM module to register on network etc.
  Serial1.println("AT+CMGF=1"); // set SMS mode to text
  delay(200);
  Serial1.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt 
  delay(200);
}

void loop() 
{
  //If a character comes in from the cellular module...
  if(Serial1.available() >0)
  {
    inchar=Serial1.read(); 
    if (inchar=='#')
    {
      delay(10);
      inchar=Serial1.read(); 
      if (inchar=='a')
      {
        delay(10);
        inchar=Serial1.read();
        if (inchar=='0')
        {
          digitalWrite(led1, LOW);
        } 
        else if (inchar=='1')
        {
          digitalWrite(led1, HIGH);
        }
        delay(10);
        inchar=Serial1.read(); 
        if (inchar=='b')
        {
          inchar=Serial1.read();
          if (inchar=='0')
          {
            digitalWrite(led2, LOW);
          } 
          else if (inchar=='1')
          {
            digitalWrite(led2, HIGH);
          }
          delay(10);
          inchar=Serial1.read(); 
          if (inchar=='c')
          {
            inchar=Serial1.read();
            if (inchar=='0')
            {
              digitalWrite(led3, LOW);
            } 
            else if (inchar=='1')
            {
              digitalWrite(led3, HIGH);
            }
            delay(10);
            inchar=Serial1.read(); 
            if (inchar=='d')
            {
              delay(10);
              inchar=Serial1.read();
              if (inchar=='0')
              {
                digitalWrite(led4, LOW);
              } 
              else if (inchar=='1')
              {
                digitalWrite(led4, HIGH);
              }
              delay(10);
            }
          }
          Serial1.println("AT+CMGD=1,4"); // delete all SMS
        }
      }
    }
  }
}

And a demonstration video showing this in action.

Conclusion

So there you have it – controlling your Arduino Mega’s digital outputs via a normal telephone or SMS. Now it is up to you and your imagination to find something to control, sensor data to return, or get up to other shenanigans. This shield and antenna is available from Tronixlabs. If you enjoyed this article, you may find this of interest – controlling AC power outlets via SMS. And if you enjoyed this article, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop”.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our forum – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Tutorial – Arduino Mega and SM5100B GSM Cellular appeared first on tronixstuff.

Tronixstuff 18 Jan 07:04

Tutorial – Arduino and MediaTek 3329 GPS

Learn how to use MediaTek 3329-based GPS shields with Arduino in Chapter 19 of our Arduino Tutorials. The first chapter is here, the complete series is detailed here. If you have an EM406A GPS module, please visit the separate tutorial. Updated 15/01/2014

Introduction

In this instalment we will introduce and examine the use of the Global Positioning System receivers with Arduino systems. What is the GPS? In very simple terms, a fleet of satellites orbit the earth, transmitting signals from space. Your GPS receiver uses signals from these satellites to triangulate position, altitude, compass headings, etc.; and also receives a time and date signal from these satellites.

The most popular GPS belongs to the USA, and was originally for military use – however it is now available for users in the free world.

Interestingly, the US can switch off or reduce accuracy of their GPS in various regions if necessary, however many people tell me this is not an issue unless you’re in a combat zone against the US forces. For more information, have a look at Wikipedia or the USAF Space Command GPS Ops Centre site. As expected,  other countries have their own GPS as well – such as Russia, China, and the EU is working on one as well.

So – how can us mere mortals take advantage of a multi-billion dollar space navigation system just with our simple Arduino? Easy – with an inexpensive GPS receiver and shield. In this tutorial we’ll use a GPS shield based on the MediaTek3329 GPS receiver from Tronixlabs.

Unlike the EM406A used in the other tutorial, the whole lot is all on one shield – and after some experimenting has better reception. Plus there’s an onboard SD card socket which we’ll use for a GPS logging device. The only catch is that you need to solder the stacking headers yourself. (update – if purchased from Tronixlabs these will be fully assembled):

Apart from the GPS shield we’ll also be using a typical Arduino-compatible LCD shield and of course an Arduino Uno or compatible. Finally before getting started, you need to set the two jumpers on the GPS shield as shown in the following image:

By doing this the serial data lines from the GPS receiver can be connected to Arduino D2 and D3 – which we will use with SoftwareSerial. The benefit of doing it this way is that you can then upload sketches without any hardware changes and also use the serial monitor and GPS at the same time. So let’s get started.

Testing your GPS shield

Simply connect your GPS shield as described above to your Arduino Uno or compatible, and upload the following sketch:

// Example 19.1

#include <SoftwareSerial.h>
SoftwareSerial GPS(2,3); // configure software serial port - 

void setup()
{
  GPS.begin(9600);
  Serial.begin(9600);
}
void loop()
{
  byte a;
    if (GPS.available() > 0 )
  {
    a = GPS.read(); // get the byte of data from the GPS
    Serial.write(a);
  }
}

Note the use of SoftwareSerial in the sketch. As mentioned earlier, the GPS data is transferred to the Arduino via D2/D2 – which we set up as a software serial port.

If possible try to get your hardware close to a window, then open the serial monitor window. The first time you power up your receiver, it may take a  minute or so to lock onto the available satellites, this period of time is the cold start time.

The subsequent times you power it up, the searching time is reduced somewhat as our receiver stores some energy in a supercap (very high-value capacitor) to remember the satellite data, which it will use the next time to reduce the search time (as it already has a “fair idea” where the satellites are).

Moving on, after a few moments you should be presented with a scrolling wall of text, for example:

What on Earth does all that mean? For one thing the hardware is working correctly. Excellent! Now how do we decode these space-signals… They are called NMEA codes. Let’s break down one and see what it means. For example, the line:

$GPRMC,100748.000,A,3754.9976,S,14507.0283,E,0.00,263.36,140114,,,A*70

  • $GPRMC tells us the following data is essential point-velocity-time data;
  • 100748.000 is the universal time constant (Greenwich Mean Time) – 10:07:48 (hours, minutes, seconds). So you now have a clock as well.
  • A is status – A for active and data is valid, V for void and data is not valid.
  • 3754.9976  is degrees latitude position data = 37 degrees, 54.9976′
  • S for south (south is negative, north is positive)
  • 14507.0283 is degrees longitude position data = 145 degrees, 07.0283′
  • E for east (east is positive, west is negative)
  • 0.00 is my speed in knots over ground. This shows the inaccuracy  that can be caused by not having a clear view of the sky
  • 263.36 – course over ground (0 is north, 180 is south, 270 is west, 90 is east)
  • 140114 is the date – 14th January 2014
  • the next is magnetic variation for which we don’t have a value
  • checksum number

Thankfully the data is separated by commas. This will be useful later when you log the data to a text file using the SD card, as you will then be able to use the data in a spreadsheet very easily. For more explanation about the data, here is the NMEA Reference Manual that explains them all.

Extracting the GPS data

You can’t decode all that NMEA on the fly, so thankfully there is an Arduino library to do this for us – TinyGPS. So head over to the library website, download and install the library before continuing.

Now with the same hardware from the previous example, upload the following sketch:

// Example 19.2

#include <TinyGPS.h>
#include <SoftwareSerial.h>
SoftwareSerial GPS(2,3); // configure software serial port 

// Create an instance of the TinyGPS object
TinyGPS shield;

void setup()
{
  GPS.begin(9600);
  Serial.begin(9600);
}

// The getgps function will interpret data from GPS and display on serial monitor
void getgps(TinyGPS &gps)
{
  // Define the variables that will be used
  float latitude, longitude;
  // Then call this function
  shield.f_get_position(&latitude, &longitude);
  Serial.println("--------------------------------------------------------------");
  Serial.print("Lat: "); 
  Serial.print(latitude,5); 
  Serial.print(" Long: "); 
  Serial.println(longitude,5);

  int year;
  byte month, day, hour, minute, second, hundredths;
  shield.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);

  // Print data and time
  Serial.print("GMT - ");
  Serial.print(hour, DEC);
  Serial.print(":");
  if (minute<10)
  {
    Serial.print("0");
    Serial.print(minute, DEC);
  } 
  else if (minute>=10)
  {
    Serial.print(minute, DEC);
  }
  Serial.print(":");
  if (second<10)
  {
    Serial.print("0");
    Serial.print(second, DEC);
  } 
  else if (second>=10)
  {
    Serial.print(second, DEC);
  }
  Serial.print(" ");
  Serial.print(day, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.println(year, DEC);
  Serial.print("Altitude ");
  Serial.print(gps.f_altitude());
  Serial.print("m ");
  Serial.print(gps.f_speed_kmph());
  Serial.println("km/h");
}

void loop()
{
  byte a;
  if ( GPS.available() > 0 ) // if there is data coming from the GPS shield
  {
    a = GPS.read(); // get the byte of data
    if(shield.encode(a)) // if there is valid GPS data...
    {
      getgps(shield); // then grab the data and display it on the LCD
    }
  }
}

How this works is quite simple. In void loop() the sketch waits for data to come from the GPS receiver, and then checks if it’s valid GPS data. Then it passes over to the function getgps() which uses the function:

shield.f_get_position

to extract the location data and place it in two variables. Next, another function:

shield.crack_datetime

will extract the date and time data, and place them in the pre-determined variables. Finally the use of

gps.f_altitude

and

gps.f_speed_kmph

can be assigned to variables as they store the altitude and speed respectively. These functions will be commonly used across all the examples, so you can see how they can be used.

To test the sketch, position the hardware and open the serial monitor. After a moment you should be presented with the GPS data in a much more useful form, for example:

At this point you should be able to form ideas of how to harness that data and display or work with it in a more useful way. Useful hint – you can enter coordinates directly into Google Maps to see where it is, for example:

 A portable GPS display

Now that you can extract the GPS data, it’s a simple matter of sending it to an LCD shield for display. Just add the LCD shield to your hardware and upload the next sketch. Be sure to change the values in the LiquidCrysal LCD… line if your shield uses different digital pins.

// Example 19.3

#include <TinyGPS.h>
#include <SoftwareSerial.h>
SoftwareSerial GPS(2,3); // configure software serial port 

// Create an instance of the TinyGPS object
TinyGPS shield;

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

void setup()
{
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("tronixstuff.com");
  GPS.begin(9600);
  delay(1000);
  lcd.clear();  
}

// The getgps function will interpret data from GPS and display on serial monitor
void getgps(TinyGPS &gps)
{
  // Define the variables that will be used
  float latitude, longitude;
  // Then call this function
  shield.f_get_position(&latitude, &longitude);
  lcd.setCursor(0,0);
  lcd.print("Lat: "); 
  lcd.print(latitude,5); 
  lcd.print("  ");
  lcd.setCursor(0,1);
  lcd.print("Long: "); 
  lcd.print(longitude,5);
  lcd.print(" ");  
}

void loop()
{
  byte a;
  if ( GPS.available() > 0 ) // if there is data coming from the GPS shield
  {
    a = GPS.read(); // get the byte of data
    if(shield.encode(a)) // if there is valid GPS data...
    {
      getgps(shield); // then grab the data and display it on the LCD
    }
  }
}

Again, position the hardware and your current position should be shown on the LCD, for example:

A GPS Clock

Armed with the same hardware you can also create a GPS clock. With this you can finally have a reference clock and end all arguments about the correct time without calling the speaking clock. Just use the same hardware from the previous example and upload the following sketch:

// Example 19.4

#include <TinyGPS.h>
#include <SoftwareSerial.h>
SoftwareSerial GPS(2,3); // configure software serial port 

// Create an instance of the TinyGPS object
TinyGPS shield;

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

void setup()
{
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("tronixstuff.com");
  GPS.begin(9600);
  delay(1000);
  lcd.clear();  
}

// The getgps function will interpret data from GPS and display on serial monitor
void getgps(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  shield.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);

  // Print data and time
  lcd.setCursor(0,0);
  lcd.print("GMT - ");
  lcd.print(hour, DEC);
  lcd.print(":");
  if (minute<10)
  {
    lcd.print("0");
    lcd.print(minute, DEC);
  } 
  else if (minute>=10)
  {
    lcd.print(minute, DEC);
  }
  lcd.print(":");
  if (second<10)
  {
    lcd.print("0");
    lcd.print(second, DEC);
  } 
  else if (second>=10)
  {
    lcd.print(second, DEC);
  }

  lcd.setCursor(0,1);  
  lcd.print(day, DEC);
  lcd.print("/");
  lcd.print(month, DEC);
  lcd.print("/");
  lcd.print(year, DEC);

}

void loop()
{
  byte a;
  if ( GPS.available() > 0 ) // if there is data coming from the GPS shield
  {
    a = GPS.read(); // get the byte of data
    if(shield.encode(a)) // if there is valid GPS data...
    {
      getgps(shield); // then grab the data and display it on the LCD
    }
  }
}

Now position the hardware again, and after a moment the time will appear – as shown in this video.

Unless you live in the UK or really need to know what GMT/UTC is, a little extra work is required to display your local time. First you will need to know in which time zone you are located – find it in this map.

If your time zone is positive (e.g. GMT +10) – you need to add 10 to your hour value, and if it’s over 23 you then subtract 24 to get the correct hours.

If your time zone is negative (e.g. GMT – 5) – you need to subtract 5 from your hour value, and if it’s under zero  you then add 24 to get the correct hours.

GPS Speedometer

Just as with the clock, it’s easy to display the speed readings with the LCD. Using the same hardware as above, enter and upload the following sketch:

// Example 19.5

#include <TinyGPS.h>
#include <SoftwareSerial.h>
SoftwareSerial GPS(2,3); // configure software serial port 

// Create an instance of the TinyGPS object
TinyGPS shield;

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

void setup()
{
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("tronixstuff.com");
  GPS.begin(9600);
  delay(1000);
  lcd.clear();  
}

// The getgps function will interpret data from GPS and display on serial monitor
void getgps(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths, kmh, mph;
  shield.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);

  // Print data and time
  lcd.setCursor(0,0);
  kmh=gps.f_speed_kmph();

  lcd.print(kmh, DEC);
  lcd.print(" km/h      ");
/*  
  mph = kmh * 1.6;
  lcd.print(mph, DEC);
  lcd.print(" MPH   ");
*/
}

void loop()
{
  byte a;
  if ( GPS.available() > 0 ) // if there is data coming from the GPS shield
  {
    a = GPS.read(); // get the byte of data
    if(shield.encode(a)) // if there is valid GPS data...
    {
      getgps(shield); // then grab the data and display it on the LCD
    }
  }
}

Now position the hardware again, and after a moment your speed should appear. You might get some odd readings if indoors, as the receiver needs data from several satellites to accurately determine your speed. The sketch is written for km/h, however you can replace the display lines with the section that is commented out to display miles per hour.

So at this point find a car and driver, an external power supply and go for a drive. You may find the GPS speed is quite different to the vehicle’s speedometer.

Build a GPS logging device

And for our final example, let’s make a device that captures the position, speed and time data to SD card for later analysis. The required hardware is just the GPS shield and Arduino Uno or compatible board – plus an SD memory card that is formatted to FAT16. SDXC cards may or may not work, they’re quite finicky – so try and get an older standard card.

Now enter and upload the following sketch:

// Example 19.6

#include <SD.h>
#include <TinyGPS.h>
#include <SoftwareSerial.h>
SoftwareSerial shield(2,3); // configure software serial port 

// Create an instance of the TinyGPS object
TinyGPS gps;

void setup()
{
  pinMode(10, OUTPUT);
  shield.begin(9600);
  Serial.begin(9600);
  // check that the microSD card exists and can be used v
  if (!SD.begin(10)) {
    Serial.println("Card failed, or not present");
    // stop the sketch
    return;
  }
  Serial.println("SD card is ready");
}

void getgps(TinyGPS &gps)
{
  float latitude, longitude;
  int year;
  byte month, day, hour, minute, second, hundredths;

  //decode and display position data
  gps.f_get_position(&latitude, &longitude); 
  File dataFile = SD.open("DATA.TXT", FILE_WRITE);
  // if the file is ready, write to it
  if (dataFile) 
  {
    dataFile.print("Lat: "); 
    dataFile.print(latitude,5); 
    dataFile.print(" ");
    dataFile.print("Long: "); 
    dataFile.print(longitude,5);
    dataFile.print(" ");  
    // decode and display time data
    gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);
    // correct for your time zone as in Project #45
    hour=hour+11; 
    if (hour>23)
    {
      hour=hour-24;
    }
   if (hour<10)
    {
      dataFile.print("0");
    }  
    dataFile.print(hour, DEC);
    dataFile.print(":");
    if (minute<10) 
    {
      dataFile.print("0");
    }
    dataFile.print(minute, DEC);
    dataFile.print(":");
    if (second<10)
    {
      dataFile.print("0");
    }
    dataFile.print(second, DEC);
    dataFile.print(" ");
    dataFile.print(gps.f_speed_kmph());
    dataFile.println("km/h");     
    dataFile.close(); // this is mandatory   
    delay(10000); // record a measurement about every 10 seconds
  }
}

void loop() 
{
  byte a;
  if ( shield.available() > 0 )  // if there is data coming into the serial line
  {
    a = shield.read();          // get the byte of data
    if(gps.encode(a))           // if there is valid GPS data...
    {
      getgps(gps);              // grab the data and display it on the LCD
    }
  }
}

This will append the data to a text file whose name is determine in line 34 of the sketch. If you are using a different GPS shield or a separate SD card shield you may need to change the digital pin value for the chip select line, which is found in lines 14 and 18. The data in our example is logged every ten seconds, however you can change the frequency using the delay() function in line 73.

When you’re ready to start capturing data, simply insert the card and power up the hardware. It will carry on until you turn it off, at which point the data file can be examined on a PC. As an example capture, I took the hardware for a drive, and ended with a file containing much data – for example:

For a more graphical result, you can import the data using a third-party service into Google Maps to get a better idea of the journey. But first, the text file requires a little work. Open it as a text file using a typical spreadsheet, which will then ask how to organise the columns. Delimit them with a space, for example:

Which will give you a spreadsheet of the data. Now delete all the columns except for the latitude and longitude data, and add a header row as such:

Now save that file as an .xls spreadsheet. Next, visit the GPS Visuliser website, and upload the file using the box in the centre of the page. Select “Google Maps” as the output format, and your trip will be presented – for example:

There are many options on the visualiser site, so if you end up using it a lot – consider giving them a donation.

Conclusion

Now you have some easy example sketches that demonstrate how to extract and work with data from your GPS shield. For the curious, the static GPS locations displayed in this tutorial are not our current location. And if you enjoyed this article, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop”.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our forum – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Tutorial – Arduino and MediaTek 3329 GPS appeared first on tronixstuff.

Review – pcDuino v2

Introduction

Updated 29/01/2014 All pcDuino v2 tutorials

Update! The pcDuino version 3 is now available

In the last twelve months or so several somewhat inexpensive single-board computers have burst onto the market, and of those was the pcDuino. This has now evolved into the pcDuino v2,  the topic of our review. The pcDuino v2 is billed as the “mini PC + Arduino”, a combination with much promise. Out of the box it runs a version of Ubuntu 12.04 on Linaro 12.07, or can also run Android Ice Cream Sandwich if so desired.

The pcDuino v2 is a single-board computer like many others, however with some interesting additions – the most interesting being the Arduino-shield hardware connections and pcDuino v2 Arduino development environment. We’ll first run through the pcDuino v2 as a Linux computer, and then delve into the Arduino-compatibility. But first, our test board… which arrived safely in a neat box:

… which contains the pcDuino v2 itself:

At first glance you can see the various points of interest, such as the Allwinner A10, which is a 1GHz ARM Cortex A8 CPU:

… the Realtek WiFi add-on board (which is fitted to the pcDuino v2):

… and also a USB socket (for keyboard, mouse, USB hub and so on), a microUSB for USB OTG use, a full-sized HDMI socket for full HD video, RJ45 Ethernet socket,  a microSD socket for expansion, and the Hynix flash memory ICs. From the pcDuino v2 website, the specifications are:

Hardware:

  • CPU – 1GHz ARM Cortex A8
  • GPU – OpenGL ES2.0, OpenVG 1.1 Mali 400 core
  • DRAM – 1GB
  • Onboard Storage – 2GB Flash, microSD card (TF) slot for up to 32GB
  • Video Output – HDMI
  • OS – Linux3.0 + Ubuntu 12.04/Android ICS 4.0
  • Extension Interface Arduino Headers
  • Network interface – 10/100Mbps RJ45 and on-board WiFi module
  • USB Host port 1
  • Requires – Power 5V, 2000mA
  • Overall Size 125mm X 52mm

Software

  • OS – Ubuntu 12.04 (pre-loaded) or Android ICS 4.0
  • APIs – all the Arduino shield pins are accessible with the provided API. 

    It consists of API to access the following interfaces: UART, ADC, PWM, GPIO, I2C, SPI

  • Programming language support – C, C++ with GNU tool chain, Java with standard Android SDK, Python. 

However at the time of writing all models with the date stamp of 17/09/2013 (and newer) have 4G of onboard flash storage – a great little bonus. With the addition of an inexpensive microSD card you can add up to an additional 32 G of storage.

Getting Started

This is the crunch-point for many products – how does one get started? With the pcDuino – very easily. Apart from the computer itself, you’ll need a monitor with HDMI inputs and speakers, a USB keyboard and mouse (with a USB hub – or one of those keyboard/trackpad combinations) and a power supply. The pcDuino v2 requires up to 2A at 5V – a higher-rated plugpack than usual. Don’t be tempted to use a normal USB socket – the pcDuino v2 will not work properly on the available current.

So after plugging all that in with the power the last to connect – the pcDuino v2 fires up in around five seconds, quickly running through the Ubuntu startup process and ended with the configuration screen in around five seconds:

After setting the time zone, language, screen resolution (full HD) and so on it was another ten seconds to the desktop:

At this point we found by accident that the A10 CPU runs hot – in some warmer permanent installations it could use a heatsink. But I digress. We now have a “normal” computer experience – the WiFi found the home network without any issue and the Chromium web browser runs well considering the speed and the RAM (1G) of the pcDuino v2:

The next step is to format the extra onboard storage, which can be done with the usual tool:

We just formatted it to ext4 and moved on. The included software is nothing unexpected, there’s the Chromium web browser, office-style applications, terminal, XBMC, remote-desktop viewer and of course you can hit up the Ubuntu package manager and install what you need.

It’s easy to get carried away and forget you’re not using a typical multi-GHz computer so bear that in mind when software runs a little slower than expected. However working with WordPress and Google Docs inside Chromium was acceptable, and a fair amount of this review was written using the pcDuino v2.

Excluding the Arduino development environment which we look at in the next section, pre-installed programming tools include Python (v2.7), C/C++ with GNU tool chain and Java with the standard Android SDK. At this point we haven’t tried the pcDuino with the Android operating system, however plan to do so in the near future and this will be the subject of a separate article.

At this point we’d say that the pcDuino v2 is a winner in the SBC (single-board computer) stakes, as you don’t need to worry about external WiFi, or deliberating about which version of an OS to use and then having to download it to an SD card and so on… the pcDuino v2 just works as a computer out of the box.

The pcDuino v2 as an Arduino

At this point we’d like to note that the pcDuino v2 is not an Arduino circuit wired up to a computer (such as the Arduino team did with the Yun). Instead, the pcDuino v2 is a computer that can emulate an Arduino – and has the GPIO pins and shield sockets onboard.

So when you run a sketch on the pcDuino v2’s version of the Arduino IDE – the sketch is compiled and then executed using the CPU, not an ATmega microcontroller. Speaking of which, the IDE is a modified version of 1.5.3 which appears identical to the usual IDE:

In fact when you compile and upload that blink.ino sketch everything runs as normal, and a small LED situated near D2/3 will blink as normal. However you do need to use more #include statements, for example #include <core.h> for all sketches. When uploading a sketch, a new window appears that will be blank, as shown below – this window needs to stay open otherwise the sketch won’t run

One of the benefits of using the pcDuino v2 is the extra space available for sketches – a quick compile shows that you can have a fair bit more than your typical ATmega328 – in our example we had 104,857,600 bytes available:

We don’t have a sketch that large, but at least you have some headroom to create them if necessary.

Arduino Hardware support

The shield header sockets are in the standard R3 configuration – and all GPIO is 3.3V and not 5V tolerant. However there is a conversion shield available if necessary. There are also some extra GPIO pins available – another eight, as shown in the following image:

At the time of writing there is support for GPIO use, SPI (up to 12 MHz, master-only), I2C (up to 200 kHz, at 7-bit and master-only), a UART (serial on D0/D1), PWM and ADC on A0~5.

However ADC is a little different, due to the internal reference voltages of the Allwinner CPU. Take note of the following as if you exceed the maximum voltages you could damage your board. Pins A0 and A1 are 6-bit ADCs, which return values from 0 ~ 63, which range from 0V to 2V. Pins A2~A5 are 12-bit ADCs, which return values  from 0 ~ 4095, which range across the full 0V to 3.3V.

There isn’t access to the usual serial monitor in the Arduino IDE as such, instead you need to use an external, hardware-based solution such as connecting a USB-serial adaptor to pins D0/D1 and using another PC as the terminal. And when you press ‘reset’ on your Arduino shields – it resets the entire computer, just not the Arduino emulation – (learned that the hard way!).

However you can output text and data to the console window that appears after uploading a sketch – and doing so is pretty easy, just use prinf as you would in C or C++. For example, the following sketch:

#include <core.h>

// example code from http://www.cplusplus.com/reference/cstdio/printf/

void setup() {
  // put your setup code here, to run once:

}

void loop() 
{
   printf ("Characters: %c %c \n", 'a', 65);
   printf ("Decimals: %d %ld\n", 1977, 650000L);
   printf ("Preceding with blanks: %10d \n", 1977);
   printf ("Preceding with zeros: %010d \n", 1977);
   printf ("Some different radices: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
   printf ("floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);
   printf ("Width trick: %*d \n", 5, 10);
   printf ("%s \n", "A string");
  delay(1000);
}

produces the following output in the console window:

It would be recommended to read this guide about using the pcDuino v2 as an Arduino which highlights pretty well everything to get you started, including the notes on interrupts and PWM – and this page which explains the headers on the pcDuino v2. Finally, as the “Arduino” is emulated you cannot use the on-board networking capabilities of the pcDuino v2 such as Ethernet, instead you use a shield as you would with a normal Arduino.

At first glance it may seem that the pcDuino v2 is difficult, which it is not. One needs instead to consider their needs and then work with the available features. Just like many other new development boards and systems, the pcDuino v2 (and pcDuino platform) is still quite new – but growing – so more features and compatibility will appear over time.

How much faster is the pcDuino v2 against a normal Arduino board?

There should be a great difference between the Arduino’s microcontroller and the A10 CPU, even taking into account running the OS and emulation. To test this, we’ll use a sketch written by Steve Curd from the Arduino forum. It calculates Newton Approximation for pi using an infinite series. The pcDuino v2 version of the sketch is below:

//
// Pi_2
//
// Steve Curd
// December 2012
//
// This program approximates pi utilizing the Newton's approximation.  It quickly
// converges on the first 5-6 digits of precision, but converges verrrry slowly
// after that.  For example, it takes over a million iterations to get to 7-8
// significant digits.
//
// I wrote this to evaluate the performance difference between the 8-bit Arduino Mega,
// and the 32-bit Arduino Due.
// 

#include <core.h> // for pcDuino v2
#include "Serial.h"

#define ITERATIONS 100000L    // number of iterations
#define FLASH 1000            // blink LED every 1000 iterations

void setup() {
  pinMode(13, OUTPUT);        // set the LED up to blink every 1000 iterations
  Serial.begin(57600);
}

void loop() {

  unsigned long start, time;
  unsigned long niter=ITERATIONS;
  int LEDcounter = 0;
  boolean alternate = false;
  unsigned long i, count=0;
  float x = 1.0;
  float temp, pi=1.0;

  Serial.print("Beginning ");
  Serial.print(niter);
  Serial.println(" iterations...");
  Serial.println();

  start = millis();  
  for ( i = 2; i < niter; i++) {
    x *= -1.0;
    pi += x / (2.0f*(float)i-1.0f);
    if (LEDcounter++ > FLASH) {
      LEDcounter = 0;
      if (alternate) {
        digitalWrite(13, HIGH);
        alternate = false;
      } else {
        digitalWrite(13, LOW);
        alternate = true;
      }
      temp = 40000000.0 * pi;
    }
  }
  time = millis() - start;

  pi = pi * 4.0;

  Serial.print("# of trials = ");
  Serial.println(niter);
  Serial.print("Estimate of pi = ");
  Serial.println(pi, 10);

  Serial.print("Time: "); Serial.print(time); Serial.println(" ms");

  delay(10000);
}

As mentioned earlier, you can’t see the IDE serial monitor, so an external PC needs to be used. We connected a USB-serial adaptor running at 3.3V I/O to a PC:

Now back to the sketch. An Arduino Mega 2560 can do the calculation in 5765 ms, a Due 690 ms, and the fastest I saw the emulated Arduino in the pcDuino v2 do it was 9 ms:

Wow, that’s quick. However take note that the completion time was all over the place. When it was 9ms, the only application open was the pcDuino v2 Arduino IDE. The completion time increased when opening other applications such as Chromium, formatting a microSD card and so on.

Why is that? As the pcDuino v2 is emulating an Arduino, the CPU needs clock cycles to take care of that and all the other OS tasks – whereas a straight Arduino just runs the code generated by the IDE and compiler. Nevertheless the speed increase is welcome, and opens up all sorts of possibilities with regards to deeper calculations in sketches they may taken too long on existing hardware.

Support and Community

From what I can tell there is a growing base of users (including this one) and like everything else this will help the pcDuino platform develop and evolve over time. There is a Linksprite “Learning Centre” with a growing pcDuino v2 section, the website, wiki, and support forum which are useful sources of information and discussion.

Conclusion – so far

The pcDuino v2 is a great mix of single-board computer and Arduino-compatible power. There is a small learning curve, however the performance gains are more than worth it. Another USB socket wouldn’t go astray, and the documentation and support will increase over time. However we really liked the fact it’s totally plug-and-play with the onboard storage, OS and WiFi.

And finally a plug for my own store – tronixlabs.com – offering a growing range and Australia’s best value for supported hobbyist electronics from adafruit, DFRobot, Freetronics, Seeed Studio and much more.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our forum – dedicated to the projects and related items on this website.

The post Review – pcDuino v2 appeared first on tronixstuff.

Tronixstuff 13 Jan 01:15

Tutorial – Arduino and SIM900 GSM Modules

Use the SIM900 GSM modules with Arduino in Chapter 55 of our Arduino Tutorials. The first chapter is here, the complete series is detailed here. Updated 14/02/2014

Introduction

The goal of this tutorial is to illustrate various methods of interaction between an Arduino Uno (or compatible) and the GSM cellular network using a SIM900 GSM shield, with which you can then use your existing knowledge to build upon those methods. Updated 08/01/2014.

Apart from setting up the shield we’ll examine:

  • Making a telephone call from your Arduino
  • Sending an SMS text message
  • Receiving text messages with the shield and displaying them on the serial monitor
  • Simple controlling of the host Arduino by calling it from another telephone
  • Controlling the Arduino via SMS text message

We’ll be using a SIMCOM SIM900 GSM module shield. (If you’re looking for tutorials on the Spreadtrum SM5100 modules, start here). There must be scores of Arduino shields or modules using the SIM900, so as you can imagine each one may be a little bit different with regards to the hardware side of things – so we’re assuming you have an understanding of how hardware and software serial works as well as supply voltages and the hardware side of the Arduino world.

As for the specific shield to use, we just chose the cheapest one available at the time – which turned out to be the “SIM900 GPRS/GSM Arduino shield” from tronixlabs.com:

However with a little research and work on your part, the sketches provided should also work with any SIM900 module/shield and Arduino – as long as you have the appropriate serial and power settings.

Getting Started

A little preparation goes a long way, so make sure you’ve covered the following points:

  • Regarding your cellular provider. Do you have coverage on a GSM 850 MHz, GSM 900 MHz, DCS 1800 MHz or PCS 1900 MHz network?  When we say GSM that means 2G – not 3G, 4G or LTE. Will they allow the use of non-supported devices on the network? Some carriers will block IMEI numbers that were not provided by their sales channel. Or you may have to call the provider and supply the IMEI of your GSM module to allow it on the network. Finally, it would be wise to use either a prepaid or an account that offers unlimited SMS text messaging – you don’t want any large bills if things go wrong.
  • Power. Do you have adequate power for your SIM900 module? Some shields will use more current than the Arduino can supply (up to 2A), so you may need an external high-current supply. The Linksprite shield we use needs 5V up to 2A into the onboard DC socket. Otherwise, check with your supplier.
  • Antenna. If your module/shield etc. doesn’t have an antenna – get one. You do need it.
  • Turn off the PIN lock on the SIM card. The easiest way to do this is to put the SIM in a handset and use the menu function.
  • And as always, please don’t make an auto-dialler…

Furthermore, download the SIM900 hardware manual (.pdf) and the AT command manual (.pdf), as we’ll refer to those throughout the tutorial.

Power

There is a DC socket on the shield, which is for a 5V power supply:

Although the data from Linksprite claims the shield will use no more than 450 mA, the SIMCOM hardware manual (page 22) for the module notes that it can draw up to 2A for short bursts. So get yourself a 5V 2A power supply and connect it via the DC socket, and also ensure the switch next to the socket is set to “EXT”.

Furthermore, you can turn the GSM module on and off with the power button on the side of the shield, and it defaults to off during an initial power-up. Therefore you’ll need to set D9 to HIGH for one second in your sketch to turn the module on (or off if required for power-saving). Don’t panic, we’ll show how this is done in the sketches below.

Software Serial

We will use the Arduino software serial library in this tutorial, and the Linksprite shield has hard-wired the serial from the SIM900 to a set of jumpers, and uses a default speed of 19200. Make sure you your jumpers are set to the “SWserial” side, as shown below:

And thus whenever an instance of SoftwareSerial is created, we use 7,8 as shown below:

SoftwareSerial SIM900(7, 8); // RX, TX

If you shield is different, you’ll need to change the TX and RX pin numbers. This also means you can’t use an Arduino Leonardo or Mega (easily). Finally – note this for later – if your shield is having problems sending data back to your Arduino you may need to edit the SoftwareSerial library – read this for more information.

Wow – all those rules and warnings?

The sections above may sound a little authoritarian, however we want your project to be a success. Now, let’s get started…

A quick test…

At this point we’ll check to make sure your shield and locate and connect to the cellular network. So make sure your SIM card is active with your cellular provider, the PIN lock is off, and then insert it and lock the SIM card  to the carrier on the bottom of the shield:

Then plug the shield into your Uno, attach 5V power to the DC socked on the GSM shield, and USB from the Uno to the PC. Press the “PWRKEY” button on the side of the shield for a second, then watch the following two LEDs:

The bright “STATUS” LED will come on, and then the “NETLIGHT” LED will blink once every 800 milliseconds- until the GSM module has found the network, at which point it will blink once every three seconds. This is shown in the following video:

Nothing can happen until that magic three-second blink – so if that doesn’t appear after a minute, something is wrong. Check your shield has the appropriate power supply, the antenna is connected correctly, the SIM card is seated properly and locked in- and that your cellular account is in order. Finally, you may not have reception in that particular area, so check using a phone on the same network or move to a different location.

Making a telephone call from your Arduino

You can have your Arduino call a telephone number, wait a moment – then hang up. This is an inexpensive way of alerting you of and consider the following sketch:

// Example 55.1

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8); // configure software serial port

void setup()
{
  SIM900.begin(19200);               
  SIM900power();  
  delay(20000);  // give time to log on to network. 
}

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  digitalWrite(9, HIGH);
  delay(1000);
  digitalWrite(9, LOW);
  delay(5000);
}

void callSomeone()
{
  SIM900.println("ATD + +12128675309;"); // dial US (212) 8675309
  delay(100);
  SIM900.println();
  delay(30000);            // wait for 30 seconds...
  SIM900.println("ATH");   // hang up
}

void loop()
{
  callSomeone(); // call someone
  SIM900power();   // power off GSM shield
  do {} while (1); // do nothing
}

The sketch first creates a software serial port, then in void setup() starts the software serial port, and also turns on the GSM shield with the function SIM900power (which simply sets D9 high for a second which is the equivalent of pressing the power button). Notice the delay function in void setup – this gives the GSM module a period of time to locate and log on to the cellular network. You may need to increase (or be able to decrease) the delay value depending on your particular situation. If in doubt, leave it as a long period.

The process of actually making the call is in the function callSomeone(). It sends a string of text to the GSM module which consists of an AT command. These are considered the “language” for modems and thus used for various tasks. We use the ATD command to dial (AT… D for dial) a number. The number as you can see in the sketch needs to be in world-format. So that’s a “+” then the country code, then the phone number with area code (without the preceding zero).

So if your number to call is Australia (02) 92679111 you would enter +61292679111. Etcetera. A carriage return is then sent to finalise the command and off it goes dialling the number. Here’s a quick video demonstration for the non-believers:

After thirty seconds we instruct the module to hand up with another AT command – “ATH” (AT… H for “hang up”), followed by turning off the power to the module. By separating the call feature into a function – you can now insert this into a sketch (plus the preceding setup code) to call a number when required.

Sending an SMS text message

This is a great way of getting data from your Arduino to almost any mobile phone in the world, at a very low cost. For reference, the maximum length of an SMS text message is 160 characters – however you can still say a lot with that size limit. First we’ll demonstrate sending an arbitrary SMS. Consider the following sketch:

// Example 55.2

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);

void setup()
{
  SIM900.begin(19200);
  SIM900power();  
  delay(20000);  // give time to log on to network. 
}

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  digitalWrite(9, HIGH);
  delay(1000);
  digitalWrite(9, LOW);
  delay(5000);
}

void sendSMS()
{
  SIM900.print("AT+CMGF=1\r");                                                        // AT command to send SMS message
  delay(100);
  SIM900.println("AT + CMGS = \"+12128675309\"");                                     // recipient's mobile number, in international format
  delay(100);
  SIM900.println("Hello, world. This is a text message from an Arduino Uno.");        // message to send
  delay(100);
  SIM900.println((char)26);                       // End AT command with a ^Z, ASCII code 26
  delay(100); 
  SIM900.println();
  delay(5000);                                     // give module time to send SMS
  SIM900power();                                   // turn off module
}

void loop()
{
  sendSMS();
  do {} while (1);
}

The basic structure and setup functions of the sketch are the same as the previous example, however the difference here is the function sendSMS(). It used the AT command “AT+CMGF” to tell the GSM module we want to send an SMS in text form, and then “AT+CMGS” followed by the recipient’s number. Once again note the number is in international format. After sending the send SMS commands, the module needs  five seconds to do this before we can switch it off. And now for our ubiquitous demonstration video:

 

You can also send text messages that are comprised of numerical data and so on – by compiling the required text and data into a string, and then sending that. Doing so gives you a method to send such information as sensor data or other parameters by text message.

For example, you might want to send daily temperature reports or hourly water tank levels. For our example, we’ll demonstrate how to send a couple of random numbers and some text as an SMS. You can then use this as a framework for your own requirements. Consider the following sketch:

// Example 55.3

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);
int x,y;
String textForSMS;

void setup()
{
  SIM900.begin(19200);
  SIM900power();  
  delay(20000);  // give time to log on to network. 
  randomSeed(analogRead(0));
}

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  digitalWrite(9, HIGH);
  delay(1000);
  digitalWrite(9, LOW);
  delay(7000);
}

void sendSMS(String message)
{
  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(100);
  SIM900.println("AT + CMGS = \"+12128675309\"");  // recipient's mobile number, in international format
  delay(100);
  SIM900.println(message);                         // message to send
  delay(100);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(100); 
  SIM900.println();
  delay(5000);                                     // give module time to send SMS
  SIM900power();                                   // turn off module
}

void loop()
{
  x = random(0,255);
  y = random(0,255);
  textForSMS = "Your random numbers are ";
  textForSMS.concat(x);
  textForSMS = textForSMS + " and ";
  textForSMS.concat(y);
  textForSMS = textForSMS + ". Enjoy!";  
  sendSMS(textForSMS);
  do {} while (1);
}

Take note of the changes to the function sendSMS(). It now has a parameter – message, which is a String which contains the text to send as an SMS. In void loop() the string variable textForSMS is constructed. First it contains some text, then the values for x and y are added with some more text. Finally the string is passed to be sent as an SMS. And here it is in action:

Receiving text messages and displaying them on the serial monitor 

Now let’s examine receiving text messages. All we need is to send two AT commands inside void setup() and then repeat every character sent from the shield to the serial monitor. The first command to use is AT+CMGF=1  which sets the SMS mode to text (as used in the previous example) and the second is AT+CNMI=2,2,0,0 – which tells the GSM module to send the contents of any new SMS out to the serial line. To demonstrate this, set up your hardware as before, upload the following sketch:

// Example 55.4

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);

char incoming_char=0;

void setup()
{
  Serial.begin(19200); // for serial monitor
  SIM900.begin(19200); // for GSM shield
  SIM900power();  // turn on shield
  delay(20000);  // give time to log on to network.

  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(100);
  SIM900.print("AT+CNMI=2,2,0,0,0\r"); 
  // blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100);
}

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  digitalWrite(9, HIGH);
  delay(1000);
  digitalWrite(9, LOW);
  delay(7000);
}

void loop()
{
  // Now we simply display any text that the GSM shield sends out on the serial monitor
  if(SIM900.available() >0)
  {
    incoming_char=SIM900.read(); //Get the character from the cellular serial port.
    Serial.print(incoming_char); //Print the incoming character to the terminal.
  }
}

… then open the serial monitor, check it’s set to 19200 bps and wait around thirty seconds. You will see some odd characters, then the “OK” responses from the GSM module. Now send a text message to the shield – the time/date stamp, sender and message will appear, for example:

To preserve my sanity the number used in the demonstrations will be blanked out.

Simple controlling of the host Arduino by calling it from another telephone

When we call our shield from another telephone, it sends the text “RING” out to serial, then “NO CARRIER” when you hang up – which can be harnessed to create a simple dial-in remote control. Use the sketch from the previous example to test this – for example:

You can also display the number calling in by using the AT command AT+CLIP=1. To do this, just add the following lines to void setup() in the previous sketch:

SIM900.print("AT+CLIP=1\r"); // turn on caller ID notification
delay(100);

Now when a call is received, the caller’s number appears as well – for example:

Note that the caller ID data for incoming calls isn’t in the international format as it was with SMSs. This will vary depending on your country, so check it out for yourself.

So how can we control the Arduino by calling in? By counting the number of times the shield sends “RING” to the Arduino (just as we did with the other GSM shield). To do this we simply count the number of times the word “RING” comes in from the shield, and then after the third ring – the Arduino will do something.

For our example we have two LEDs connected (via 560Ω resistors) to D12 and D13. When we call the shield and let it ring three times, they will alternate between on and off. Enter and upload the following sketch:

// Example 55.5

#include <SoftwareSerial.h> 
char inchar; // Will hold the incoming character from the GSM shield
SoftwareSerial SIM900(7, 8);

int numring=0;
int comring=3; 
int onoff=0; // 0 = off, 1 = on

void setup()
{
  Serial.begin(19200);
  // set up the digital pins to control
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT); // LEDs - off = red, on = green
  digitalWrite(12, HIGH);
  digitalWrite(13, LOW);

  // wake up the GSM shield
  SIM900power(); 
  SIM900.begin(19200);
  SIM900.print("AT+CLIP=1\r"); // turn on caller ID notification
  delay(100);  
}

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  digitalWrite(9, HIGH);
  delay(1000);
  digitalWrite(9, LOW);
  delay(7000);
}

void doSomething()
{
  if (onoff==0)
  {
    onoff=1;
    digitalWrite(12, HIGH);
    digitalWrite(13, LOW);
    Serial.println("D12 high D13 low");
  } 
  else
    if (onoff==1)
    {
      onoff=0;
      digitalWrite(12, LOW);
      digitalWrite(13, HIGH);
      Serial.println("D12 low D13 high");
    }
}

void loop() 
{
  if(SIM900.available() >0)
  {
    inchar=SIM900.read(); 
    if (inchar=='R')
    {
      delay(10);
      inchar=SIM900.read(); 
      if (inchar=='I')
      {
        delay(10);
        inchar=SIM900.read();
        if (inchar=='N')
        {
          delay(10);
          inchar=SIM900.read(); 
          if (inchar=='G')
          {
            delay(10);
            // So the phone (our GSM shield) has 'rung' once, i.e. if it were a real phone
            // it would have sounded 'ring-ring' or 'blurrrrr' or whatever one cycle of your ring tone is
            numring++;
            Serial.println("ring!");
            if (numring==comring)
            {
              numring=0; // reset ring counter
              doSomething();
            }
          }
        }
      }
    }
  }
}

You can change the number of rings before action with the variable comring, and the action to take is in the function void doSomething(). Finally you can watch a short video of this in action.


We can also modify this system so it only allows control by callers from one number  –  as long as caller ID works on your system (well it should… it’s 2014 not 1996). So in the next example the system will only call the function doSomething if the call is from a certain number. The sketch works in the same manner as last time – but instead of counting the word “RING”, it will compare the incoming caller’s ID number against one in the sketch.

It may look a little clunky, but it works. In the following example sketch, the number is 2128675309 – so just change the digits to check in void loop():

// Example 55.6

#include <SoftwareSerial.h> 
char inchar; // Will hold the incoming character from the GSM shield
SoftwareSerial SIM900(7, 8);

int onoff=0; // 0 = off, 1 = on

void setup()
{
  Serial.begin(19200);
  // set up the digital pins to control
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT); // LEDs - off = red, on = green
  digitalWrite(12, HIGH);
  digitalWrite(13, LOW);

  // wake up the GSM shield
  SIM900power(); 
  SIM900.begin(19200);
  delay(20000);  // give time to log on to network.
  SIM900.print("AT+CLIP=1\r"); // turn on caller ID notification
  delay(100);  
}

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  digitalWrite(9, HIGH);
  delay(1000);
  digitalWrite(9, LOW);
  delay(7000);
}

void doSomething()
{
  if (onoff==0)
  {
    onoff=1;
    digitalWrite(12, HIGH);
    digitalWrite(13, LOW);
    Serial.println("D12 high D13 low");
  } 
  else
    if (onoff==1)
    {
      onoff=0;
      digitalWrite(12, LOW);
      digitalWrite(13, HIGH);
      Serial.println("D12 low D13 high");
    }
}

void loop() 
{
  if(SIM900.available() >0)
  {   
    inchar=SIM900.read(); 
    if (inchar=='2')
    {
      delay(10);
      inchar=SIM900.read(); 
      if (inchar=='1')
      {
        delay(10);
        inchar=SIM900.read(); 
        if (inchar=='2')
        {
          delay(10);
          inchar=SIM900.read(); 
          if (inchar=='8')
          {
            delay(10);
            inchar=SIM900.read(); 
            if (inchar=='6')
            {
              delay(10);
              inchar=SIM900.read(); 
              if (inchar=='7')
              {
                delay(10);
                inchar=SIM900.read(); 
                if (inchar=='5')
                {
                  delay(10);
                  inchar=SIM900.read(); 
                  if (inchar=='3')
                  {
                    delay(10);
                    inchar=SIM900.read();
                    if (inchar=='0')
                    {
                      delay(10);
                      inchar=SIM900.read(); 
                      if (inchar=='9')
                      {
                        Serial.println("do sometehing");
                        delay(10);
                        // now the number is matched, do something
                        doSomething();
                        // arbitrary delay so the function isn't called again on the same phone call
                        delay(60000);
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

The large delay after calling doSomething() exists to stop the same action being called twice (or more) on the same inbound call. Anyhow, you should now have a grasp on interrogating the data from the shield. Which leads us to the final section…

Controlling the Arduino via SMS text message

As you did with the caller ID data, you can also control the Arduino via SMS fairly easily, and have more options. In our example we’ll explain how to control four digital output pins via SMS. The example works in two stages. First it will wait for an SMS to be received, and then have the contents sent to the Arduino via serial just as we did earlier with the example 55.4. The next stage is to filter out the commands in the text message as we did with example 55.6.

The commands (that is, the contents of your text message to the Arduino) will be in the form

#axbxcxdx

where ‘x’ will be 0 (for off) and 1 (for on) – and a, b, c and d will relate to digital pins 10, 11, 12 and 13. For example, to turn on D10, 11 and turn off D12, D13 you would compose your SMS as #a1b1c0d0. After processing the SMS we use the AT command AT+CMGD=1,4 to delete all the SMSs from the SIM card, otherwise it will fill up and reject further commands. Moving on, here’s the example sketch:

// Example 55.7

#include <SoftwareSerial.h> 
char inchar; // Will hold the incoming character from the GSM shield
SoftwareSerial SIM900(7, 8);

int led1 = 10;
int led2 = 11;
int led3 = 12;
int led4 = 13;

void setup()
{
  Serial.begin(19200);
  // set up the digital pins to control
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);

  // wake up the GSM shield
  SIM900power(); 
  SIM900.begin(19200);
  delay(20000);  // give time to log on to network.
  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(100);
  SIM900.print("AT+CNMI=2,2,0,0,0\r"); 
  // blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100);
  Serial.println("Ready...");
}

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  digitalWrite(9, HIGH);
  delay(1000);
  digitalWrite(9, LOW);
  delay(7000);
}

void loop() 
{
  //If a character comes in from the cellular module...
  if(SIM900.available() >0)
  {
    inchar=SIM900.read(); 
    if (inchar=='#')
    {
      delay(10);

      inchar=SIM900.read(); 
      if (inchar=='a')
      {
        delay(10);
        inchar=SIM900.read();
        if (inchar=='0')
        {
          digitalWrite(led1, LOW);
        } 
        else if (inchar=='1')
        {
          digitalWrite(led1, HIGH);
        }
        delay(10);
        inchar=SIM900.read(); 
        if (inchar=='b')
        {
          inchar=SIM900.read();
          if (inchar=='0')
          {
            digitalWrite(led2, LOW);
          } 
          else if (inchar=='1')
          {
            digitalWrite(led2, HIGH);
          }
          delay(10);
          inchar=SIM900.read(); 
          if (inchar=='c')
          {
            inchar=SIM900.read();
            if (inchar=='0')
            {
              digitalWrite(led3, LOW);
            } 
            else if (inchar=='1')
            {
              digitalWrite(led3, HIGH);
            }
            delay(10);
            inchar=SIM900.read(); 
            if (inchar=='d')
            {
              delay(10);
              inchar=SIM900.read();
              if (inchar=='0')
              {
                digitalWrite(led4, LOW);
              } 
              else if (inchar=='1')
              {
                digitalWrite(led4, HIGH);
              }
              delay(10);
            }
          }
          SIM900.println("AT+CMGD=1,4"); // delete all SMS
        }
      }
    }
  }
}

The example hardware has four LEDs via 560Ω resistors on the digital outputs being controlled. Finally, you can watch a short demonstration in this video.

Conclusion

After working through this tutorial you should have an understanding of how to use the SIM900 GSM shields to communicate and control with an Arduino. And if you enjoyed the tutorial, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop”.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our forum – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Tutorial – Arduino and SIM900 GSM Modules appeared first on tronixstuff.

Old Kit Review – Talking Electronics Fluorescent Simulator

Introduction

Slowly we’re working through the stock of old kits, and in this article we have the “Fluorescent Lamp” simulator from Talking Electronics. To save repeating myself you can read more about Talking Electronics here and watch interviews of the founder Colin Mitchell here.

So why would you want to simulate a fluoro’ tube anyway? Model railways! When your model world moves from day to night, it’s neat to have street lights and so on “flicker” on just like the real thing. And thus you can create this effect as well. It can drive incandescent lamps up to 12V, and allowing it to be powered easily from most layouts.

The kit was originally described in the Talking Electronics book “Electronics for Model Railways” (volume 1) which was full of useful and interesting electronics to liven up any layout. The book may now out of print however at the time of writing this you can download or view most of the projects from the index column of the Talking Electronics website… or contact Talking Electronics if they have any copies of the book (or kit) to sell.

Assembly

Time was not kind to the kit, to be frank it was surprising to find one at all:

(Just a note for any over-enthusiastic readers, Talking Electronics is no longer at the address on the bag shown above). However it was complete and ready for assembly. The PCB has a silk-screen with the required component placement information, polarities and so on – a first for the time:

The instructions and “how it works” are not included with the kit as you were meant to have the book, however TE have made them available as a separate download (.pdf) The kit included everything required to get started, and there’s an LED which replicates the effect so you can test the board without having to watch the connected bulb (which may be a distance away). Finally an IC socket is included

The actual assembly process was very straight forward, which simply required starting with the low-profile components and working up to the large ones:

The only problem with the PCB was the holes – looks like only one drill size had been used (apart from the mounting holes) which made getting that rectifier diode in a little tricky. Otherwise it was smooth sailing.

Not having a model railway at the moment left me with the simple example of the onboard LED and a small incandescent globe to try with the circuit. You can see the kit working in this video.

John – Why do you publish these “Old Kit Reviews”?

They’re more of  a selfish article, like many electronics enthusiasts I have enjoyed kits for decades – and finding kits from days gone by is a treat. From various feedback some of you are enjoying them, so they will continue for fun and some nostalgia. If you’re not interested, just ignore the posts starting with “Old”!

Conclusion

For a kit from the mid-1980s, this would have solved the problem neatly for model railway enthusiasts. By using two or more of the kits with different capacitor values, many model lights could blink on with seemingly random patterns. However it’s 2014 so you could use a PIC10F200 or ATtiny45 and reduce the board space and increase the blinking potential.

Nevertheless, it was an interesting example of what’s possible with a digital logic IC. Full-sized images and a lot more information about the kit are available on flickr. And if you enjoyed this article, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop”.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our forum – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Old Kit Review – Talking Electronics Fluorescent Simulator appeared first on tronixstuff.

Project – Arduino “Book Monster”

Introduction

Recently we saw a neat project by the people from Evil Mad Scientist – their “Peek-O-Book“, a neat take on a book with a shy monster inside, based on hardware from their Snap-O-Lantern kit. Not wanting to fork out for the postage to Australia we decided to make our own version, of which you can follow along.

This is a fun project that doesn’t require too much effort and has a lot of scope for customisation. There’s no right or wrong when making your own (or this one!) so just have fun with it.

Construction

First, you’ll need a book of some sort, something large enough to hide the electronics yet not too large to look “suspicious” – then cut the guts out to make enough space for the electronics. Then again it’s subjective, so get whatever works for you. Coincidentally we found some “dummy books” (not books for dummies) that were perfect for the job:

After spraying the inside with matt black paint, the inside is better suited for the “eyes in the dark” effect required for the project:

The “book” had a magnet and matching metal disk on the flap to aid with keep the cover shut, however this was removed as it will not allow for smooth opening with the servo.

The electronics are quite simple if you have some Arduino or other development board experience. Not sure about Arduino? You can use any microcontroller that can control a servo and some LEDs. We’re using a Freetronics LeoStick as it’s really small yet offers a full Arduino Leonardo-compatible experience, and a matching Protostick to run the wires and power from:

By fitting all the external wiring to the Protostick you can still use the main LeoStick for other projects if required. The power is from 4 x AA cells, with the voltage reduced with a 1n4004 diode:

And for the “eyes” of our monster – you can always add more if it isn’t too crowded in the book:

We’ll need a resistor as well for the LEDs. As LEDs are current driven you can connect two in series with a suitable dropping resistor which allows you to control both if required with one digital output pin. You can use the calculator here to help determine the right value for the resistor.

Finally a servo is required to push the lid of the book up and down. We used an inexpensive micro servo that’s available from Tronixlabs:

The chopsticks are cut down and used as an extension to the servo horn to give it more length:

Don’t forget to paint the arm black so it doesn’t stand out when in use. We had a lazy attack and mounted the servo on some LEGO bricks held in with super glue, but it works. Finally, here is the circuit schematic for our final example – we also added a power switch after the battery pack:

To recap  – this is a list of parts used:

After some delicate soldering the whole lot fits neatly in the box:

Arduino Sketch

The behaviour of your “book monster” comes down to your imagination. Experiment with the servo angles and speed to simulate the lid opening as if the monster is creeping up, or quickly for a “pop-up” surprise. And again with the LED eyes you can blink them and alter the brightness with PWM. Here’s a quick sketch to give you an idea:

int angle;
int d; // for delays
int ledPin = 9; // LEDs on digital pin 9

#include <Servo.h>
Servo myservo;

void setup()
{
  myservo.attach(4); // servo control pin on digital 4
  pinMode(9, OUTPUT); 
  randomSeed(analogRead(0));
  myservo.write(10);
  delay(5000);
}

void behaviour1()
{
  for (angle = 10; angle <=40; angle++)
  {
    myservo.write(angle);
    delay(50);
  }
  digitalWrite(ledPin, HIGH);
  delay(250);
  digitalWrite(ledPin, LOW);
  delay(250);  
  digitalWrite(ledPin, HIGH);
  delay(250);
  digitalWrite(ledPin, LOW);
  delay(250);    
  digitalWrite(ledPin, HIGH);
  delay(1000);
  digitalWrite(ledPin, LOW);
  delay(250);    
  digitalWrite(ledPin, HIGH);
  delay(1000);
  digitalWrite(ledPin, LOW);
  delay(250);    
  digitalWrite(ledPin, HIGH);
  delay(1000);
  digitalWrite(ledPin, LOW);
  delay(250);    
  for (angle = 40; angle >=10; --angle)
  {
    myservo.write(angle);
    delay(5);
  }
}

void loop()
{
  behaviour1();
  delay(random(60000));
}

You can watch our example unit in this video.

Frankly the entire project is subjective, so just do what you want.

Conclusion

Well that was fun, and I am sure this will entertain many people. A relative is a librarian so this will adorn a shelf and hopefully give the children a laugh. Once again, thanks to the people from Evil Mad Science for the inspiration for this project – so go and buy something from their interesting range of kits and so on.

And if you enjoyed this article, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop”.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our forum – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Project – Arduino “Book Monster” appeared first on tronixstuff.

Arduino Tutorials – Chapter 42 – Numeric Keypads

Learn how to use various numeric keypads with your Arduino.

This is chapter forty-two of our huge Arduino tutorial seriesUpdated 16/12/2013

Numeric keypads can provide a simple end-user alternative for various interfaces for your projects. Or if you need a lot of buttons, they can save you a lot of time with regards to construction. We’ll run through connecting them, using the Arduino library and then finish with a useful example sketch.

Getting Started

Numeric keypads are available from many retailers, and no matter where you get them from, make sure you can get the data sheet, as this will make life easier when wiring them up. Here are the two examples for our tutorial, from Futurlec (slow and cheap):

 Again, the data sheet is important as it will tell you which pins or connectors on the keypad are for the rows and columns, for example the black keypad shown above. If you don’t have the data sheet – you will need to manually determine which contacts are for the rows and columns.

This can be done using the continuity function of a multimeter (the buzzer). Start by placing one probe on pin 1, the other probe on pin 2, and press the keys one by one. Make a note of when a button completes the circuit, then move onto the next pin. Soon you will know which is which. For example, on the example keypad pins 1 and 5 are for button “1″, 2 and 5 for “4″, etc…

Furthermore some keypads will have the pins soldered to the end, some will not. With our two example keypads, the smaller unit had the pins – and we soldered pins to the large white unit:

At this point please download and install the keypad Arduino library. Now we’ll demonstrate how to use both keypads in simple examples. 

Using a 12 digit keypad

We’ll use the small black keypad from Futurlec, an Arduino Uno-compatible and an LCD with an I2C interface for display purposes. If you don’t have an LCD you could always send the text to the serial monitor instead.

Wire up your LCD then connect the keypad to the Arduino in the following manner:
  • Keypad row 1 to Arduino digital 5
  • Keypad row 2 to Arduino digital 4
  • Keypad row 3 to Arduino digital 3
  • Keypad row 4 to Arduino digital 2
  • Keypad column 1 to Arduino digital 8
  • Keypad column 2 to Arduino digital 7
  • Keypad column 3 to Arduino digital 6

If your keypad is different to ours, take note of the lines in the sketch from:

// keypad type definition

As you need to change the numbers in the arrays rowPins[ROWS] and colPins[COLS]. You enter the digital pin numbers connected to the rows and columns of the keypad respectively.

Furthermore, the array keys stores the values displayed in the LCD when a particular button is pressed. You can see we’ve matched it with the physical keypad used, however you can change it to whatever you need. But for now, enter and upload the following sketch once you’re satisfied with the row/pin number allocations:

/* Numeric keypad and I2C LCD
   https://tronixstuff.com/tutorials > chapter 42
   Uses Keypad library for Arduino
   http://www.arduino.cc/playground/Code/Keypad
   by Mark Stanley, Alexander Brevig */

#include "Keypad.h"
#include "Wire.h" // for I2C LCD
#include "LiquidCrystal_I2C.h" // for I2C bus LCD module 
// http://www.dfrobot.com/wiki/index.php/I2C/TWI_LCD1602_Module_(SKU:_DFR0063)
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

// keypad type definition
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
 {{'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}};

byte rowPins[ROWS] = {
  5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  8, 7, 6}; // connect to the column pinouts of the keypad

int count=0;

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
  lcd.init();          // initialize the lcd
  lcd.backlight(); // turn on LCD backlight
}

void loop()
{
  char key = keypad.getKey();
  if (key != NO_KEY)
  {
    lcd.print(key);
    count++;
    if (count==17)
    {
      lcd.clear();
      count=0;
    }
  }
}

And the results of the sketch are shown in this video.

So now you can see how the button presses can be translated into data for use in a sketch. We’ll now repeat this demonstration with the larger keypad.

Using a 16 digit keypad

We’ll use the larger white 4×4 keypad from Futurlec, an Arduino Uno-compatible and for a change the I2C LCD from Akafugu for display purposes. (We reviewed these previously). Again, if you don’t have an LCD you could always send the text to the serial monitor instead. Wire up the LCD and then connect the keypad to the Arduino in the following manner:

  • Keypad row 1 (pin eight) to Arduino digital 5
  • Keypad row 2 (pin 1) to Arduino digital 4
  • Keypad row 3 (pin 2) to Arduino digital 3
  • Keypad row 4 (pin 4) to Arduino digital 2
  • Keypad column 1 (pin 3) to Arduino digital 9
  • Keypad column 2 (pin 5) to Arduino digital 8
  • Keypad column 3 (pin 6) to Arduino digital 7
  • Keypad column 4 (pin 7) to Arduino digital 6
Now for the sketch – take note how we have accommodated for the larger numeric keypad:
  • the extra column in the array char keys[]
  • the extra pin in the array colPins[]
  • and the byte COLS = 4.
/* Numeric keypad and I2C LCD
   https://tronixstuff.com/tutorials > chapter 42
   Uses Keypad library for Arduino
   http://www.arduino.cc/playground/Code/Keypad
   by Mark Stanley, Alexander Brevig */

#include "Keypad.h"
#include "Wire.h" // for I2C LCD
#include "TWILiquidCrystal.h"
// http://store.akafugu.jp/products/26
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] =
 {{'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}};
byte rowPins[ROWS] = {
  5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  9, 8, 7, 6}; //connect to the column pinouts of the keypad
int count=0;

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.print("Keypad test!");  
  delay(1000);
  lcd.clear();
}

void loop()
{
  char key = keypad.getKey();
  if (key != NO_KEY)
  {
    lcd.print(key);
    Serial.print(key);
    count++;
    if (count==17)
    {
      lcd.clear();
      count=0;
    }
  }
}

And again you can see the results of the sketch above in this video.

And now for an example project, one which is probably the most requested use of the numeric keypad…

Example Project – PIN access system

The most-requested use for a numeric keypad seems to be a “PIN” style application, where the Arduino is instructed to do something based on a correct number being entered into the keypad. The following sketch uses the hardware described for the previous sketch and implements a six-digit PIN entry system. The actions to take place can be inserted in the functions correctPIN() and incorrectPIN(). And the PIN is set in the array char PIN[6]. With a little extra work you could create your own PIN-change function as well. 

// PIN switch with 16-digit numeric keypad
// https://tronixstuff.com/tutorials > chapter 42

#include "Keypad.h"
#include <Wire.h>
#include <TWILiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] =
{
  {
    '1','2','3','A'  }
  ,
  {
    '4','5','6','B'  }
  ,
  {
    '7','8','9','C'  }
  ,
  {
    '*','0','#','D'  }
};
byte rowPins[ROWS] = {
  5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  9, 8, 7, 6}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char PIN[6]={
  '1','2','A','D','5','6'}; // our secret (!) number
char attempt[6]={ 
  '0','0','0','0','0','0'}; // used for comparison
int z=0;

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.print("PIN Lock ");
  delay(1000);
  lcd.clear();
  lcd.print("  Enter PIN...");
}

void correctPIN() // do this if correct PIN entered
{
  lcd.print("* Correct PIN *");
  delay(1000);
  lcd.clear();
  lcd.print("  Enter PIN...");
}

void incorrectPIN() // do this if incorrect PIN entered
{
  lcd.print(" * Try again *");
  delay(1000);
  lcd.clear();
  lcd.print("  Enter PIN...");
}

void checkPIN()
{
  int correct=0;
  int i;
  for ( i = 0;   i < 6 ;  i++ )
  {

    if (attempt[i]==PIN[i])
    {
      correct++;
    }
  }
  if (correct==6)
  {
    correctPIN();
  } 
  else
  {
    incorrectPIN();
  }

  for (int zz=0; zz<6; zz++) 
  {
    attempt[zz]='0';
  }
}

void readKeypad()
{
  char key = keypad.getKey();
  if (key != NO_KEY)
  {
    attempt[z]=key;
    z++;
    switch(key)
    {
    case '*':
      z=0;
      break;
    case '#':
      z=0;
      delay(100); // for extra debounce
      lcd.clear();
      checkPIN();
      break;
    }
  }
}

void loop()
{
  readKeypad();
}

The project is demonstrated in this video.

Conclusion

So now you have the ability to use twelve and sixteen-button keypads with your Arduino systems. I’m sure you will come up with something useful and interesting using the keypads in the near future.

Stay tuned for upcoming Arduino tutorials by subscribing to the blog, RSS feed (top-right), twitter or joining our Google Group. And if you enjoyed the tutorial, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop” from No Starch Press.