Posts with «tronixlabs» label

Tutorial – L298N Dual Motor Controller Modules and Arduino

Learn how to use inexpensive L298N motor control modules to drive DC and stepper motors with Arduino. This is chapter fifty-nine of our huge Arduino tutorial series.

You don’t have to spend a lot of money to control motors with an Arduino or compatible board. After some hunting around we found a neat motor control module based on the L298N H-bridge IC that can allows you to control the speed and direction of two DC motors, or control one bipolar stepper motor with ease.

The L298N H-bridge module can be used with motors that have a voltage of between 5 and 35V DC. With the module used in this tutorial, there is also an onboard 5V regulator, so if your supply voltage is up to 12V you can also source 5V from the board.

So let’s get started!

First we’ll run through the connections, then explain how to control DC motors then a stepper motor. At this point, review the connections on the L298N H-bridge module.

Consider the following image – match the numbers against the list below the image:

  1. DC motor 1 “+” or stepper motor A+
  2. DC motor 1 “-” or stepper motor A-
  3. 12V jumper – remove this if using a supply voltage greater than 12V DC. This enables power to the onboard 5V regulator
  4. Connect your motor supply voltage here, maximum of 35V DC. Remove 12V jumper if >12V DC
  5. GND
  6. 5V output if 12V jumper in place, ideal for powering your Arduino (etc)
  7. DC motor 1 enable jumper. Leave this in place when using a stepper motor. Connect to PWM output for DC motor speed control.
  8. IN1
  9. IN2
  10. IN3
  11. IN4
  12. DC motor 2 enable jumper. Leave this in place when using a stepper motor. Connect to PWM output for DC motor speed control.
  13. DC motor 2 “+” or stepper motor B+
  14. DC motor 2 “-” or stepper motor B-

Controlling DC Motors

To control one or two DC motors is quite easy with the L298N H-bridge module. First connect each motor to the A and B connections on the L298N module. If you’re using two motors for a robot (etc) ensure that the polarity of the motors is the same on both inputs. Otherwise you may need to swap them over when you set both motors to forward and one goes backwards!

Next, connect your power supply – the positive to pin 4 on the module and negative/GND to pin 5. If you supply is up to 12V you can leave in the 12V jumper (point 3 in the image above) and 5V will be available from pin 6 on the module. This can be fed to your Arduino’s 5V pin to power it from the motors’ power supply. Don’t forget to connect Arduino GND to pin 5 on the module as well to complete the circuit.

Now you will need six digital output pins on your Arduino, two of which need to be PWM (pulse-width modulation) pins. PWM pins are denoted by the tilde (“~”) next to the pin number, for example:

Finally, connect the Arduino digital output pins to the driver module. In our example we have two DC motors, so digital pins D9, D8, D7 and D6 will be connected to pins IN1, IN2, IN3 and IN4 respectively. Then connect D10 to module pin 7 (remove the jumper first) and D5 to module pin 12 (again, remove the jumper).

The motor direction is controlled by sending a HIGH or LOW signal to the drive for each motor (or channel). For example for motor one, a HIGH to IN1 and a LOW to IN2 will cause it to turn in one direction, and  a LOW and HIGH will cause it to turn in the other direction.

However the motors will not turn until a HIGH is set to the enable pin (7 for motor one, 12 for motor two). And they can be turned off with a LOW to the same pin(s). However if you need to control the speed of the motors, the PWM signal from the digital pin connected to the enable pin can take care of it.

This is what we’ve done with the DC motor demonstration sketch. Two DC motors and an Arduino Uno are connected as described above, along with an external power supply. Then enter and upload the following sketch:

// connect motor controller pins to Arduino digital pins
// motor one
int enA = 10;
int in1 = 9;
int in2 = 8;
// motor two
int enB = 5;
int in3 = 7;
int in4 = 6;
void setup()
{
  // set all the motor control pins to outputs
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}
void demoOne()
{
  // this function will run the motors in both directions at a fixed speed
  // turn on motor A
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  // set speed to 200 out of possible range 0~255
  analogWrite(enA, 200);
  // turn on motor B
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  // set speed to 200 out of possible range 0~255
  analogWrite(enB, 200);
  delay(2000);
  // now change motor directions
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH); 
  delay(2000);
  // now turn off motors
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}
void demoTwo()
{
  // this function will run the motors across the range of possible speeds
  // note that maximum speed is determined by the motor itself and the operating voltage
  // the PWM values sent by analogWrite() are fractions of the maximum speed possible 
  // by your hardware
  // turn on motors
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH); 
  // accelerate from zero to maximum speed
  for (int i = 0; i < 256; i++)
  {
    analogWrite(enA, i);
    analogWrite(enB, i);
    delay(20);
  } 
  // decelerate from maximum speed to zero
  for (int i = 255; i >= 0; --i)
  {
    analogWrite(enA, i);
    analogWrite(enB, i);
    delay(20);
  } 
  // now turn off motors
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);  
}
void loop()
{
  demoOne();
  delay(1000);
  demoTwo();
  delay(1000);
}

So what’s happening in that sketch? In the function demoOne() we turn the motors on and run them at a PWM value of 200. This is not a speed value, instead power is applied for 200/255 of an amount of time at once.

Then after a moment the motors operate in the reverse direction (see how we changed the HIGHs and LOWs in thedigitalWrite() functions?).

To get an idea of the range of speed possible of your hardware, we run through the entire PWM range in the function demoTwo() which turns the motors on and them runs through PWM values zero to 255 and back to zero with the two for loops.

Finally this is demonstrated in the following video – using our well-worn tank chassis with two DC motors:

Controlling a Stepper Motor

Stepper motors may appear to be complex, but nothing could be further than the truth. In this example we control a typical NEMA-17 stepper motor that has four wires:

It has 200 steps per revolution, and can operate at at 60 RPM. If you don’t already have the step and speed value for your motor, find out now and you will need it for the sketch.

The key to successful stepper motor control is identifying the wires – that is which one is which. You will need to determine the A+, A-, B+ and B- wires. With our example motor these are red, green, yellow and blue. Now let’s get the wiring done.

Connect the A+, A-, B+ and B- wires from the stepper motor to the module connections 1, 2, 13 and 14 respectively. Place the jumpers included with the L298N module over the pairs at module points 7 and 12. Then connect the power supply as required to points 4 (positive) and 5 (negative/GND).

Once again if your stepper motor’s power supply is less than 12V, fit the jumper to the module at point 3 which gives you a neat 5V power supply for your Arduino.

Next, connect L298N module pins IN1, IN2, IN3 and IN4 to Arduino digital pins D8, D9, D10 and D11 respectively. Finally, connect Arduino GND to point 5 on the module, and Arduino 5V to point 6 if sourcing 5V from the module.

Controlling the stepper motor from your sketches is very simple, thanks to the Stepper Arduino library included with the Arduino IDE as standard.

To demonstrate your motor, simply load the stepper_oneRevolution sketch that is included with the Stepper library, for example:

Finally, check the value for

	const int stepsPerRevolution = 200;

in the sketch and change the 200 to the number of steps per revolution for your stepper motor, and also the speed which is preset to 60 RPM in the following line:

	myStepper.setSpeed(60);

Now you can save and upload the sketch, which will send your stepper motor around one revolution, then back again. This is achieved with the function

	myStepper.step(stepsPerRevolution); // for clockwise
	myStepper.step(-stepsPerRevolution); // for anti-clockwise

Finally, a quick demonstration of our test hardware is shown in the following video:

So there you have it, an easy an inexpensive way to control motors with your Arduino or compatible board. 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 fourth 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.

Tronixstuff 25 Nov 11:54

Tutorial – PCF8574 backpacks for LCD modules and Arduino

Learn how to use inexpensive serial backpacks with character LCD modules with your Arduino. This is chapter fifty-eight of our huge Arduino tutorial series.

Introduction

Using LCD modules with your Arduino is popular, however the amount of wiring requires time and patience to wire it up correctly – and also uses a lot of digital output pins. That’s why we love these serial backpack modules – they’re fitted to the back of your LCD module and allows connection to your Arduino (or other development board) with only four wires – power, GND, data and clock.

You can use this with LCD modules that have a HD44780-compatible interface with various screen sizes. For example a 16 x 2 module:

The backpack can also be used with 20 x 4 LCDs. The key is that your LCD must have the interface pads in a single row of sixteen, so it matches the pins on the backpack – for example:

Hardware Setup

Now let’s get started. First you need to solder the backpack to your LCD module. While your soldering iron is warming up, check that the backpack pins are straight and fit in the LCD module, for example:

Then solder in the first pin, while keeping the backpack flush with the LCD:

If it’s a bit crooked, you can reheat the solder and straighten it up again. Once you’re satisfied with the alignment, solder in the rest of the pins:

Now to keep things neat, trim off the excess header pins:

Once you’ve finished trimming the header pins, get four male to female jumper wires and connect the LCD module to your Arduino as shown in the following image and table. Then connect your Arduino to the computer via USB:

Software Setup

The next step is to download and install the Arduino I2C LCD library for use with the backpack. First of all, rename the “LiquidCrystal” library folder in your Arduino libraries folder. We do this just to keep it as a backup.

If you’re not sure where your library folder can be found – it’s usually in your sketchbook folder, whose location can usually be found in the Arduino IDE preferences menu:

Next, visit https://bitbucket.org/fmalpartida/new-liquidcrysta… and download the latest file, currently we’re using v1.2.1. Expanding the downloaded .zip file will reveal a new “LiquidCrystal” folder – copy this into your Arduino libraries folder.

Now restart the Arduino IDE if it was already running – or open it now. To test the module we have a demonstration sketch prepared, simply copy and upload the following sketch:

/* Demonstration sketch for PCF8574T I2C LCD Backpack 
Uses library from https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads GNU General Public License, version 3 (GPL-3.0) */
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C	lcd(0x27,2,1,0,4,5,6,7); // 0x27 is the I2C bus address for an unmodified backpack

void setup()
{
  // activate LCD module
  lcd.begin (16,2); // for 16 x 2 LCD module
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
}

void loop()
{
  lcd.home (); // set cursor to 0,0
  lcd.print(" tronixlabs.com"); 
  lcd.setCursor (0,1);        // go to start of 2nd line
  lcd.print(millis());
  delay(1000);
  lcd.setBacklight(LOW);      // Backlight off
  delay(250);
  lcd.setBacklight(HIGH);     // Backlight on
  delay(1000);
}

After a few moments the LCD will be initialised and start to display our URL and the value for millis, then blink the backlight off and on – for example:

If the text isn’t clear, or you just see white blocks – try adjusting the contrast using the potentiometer on the back of the module.

How to control the backpack in your sketch

As opposed to using the LCD module without the backpack, there’s a few extra lines of code to include in your sketches. To review these, open the example sketch mentioned earlier.

You will need the libraries as shown in lines 3, 4 and 5 – and initialise the module as shown in line 7. Note that the default I2C bus address is 0x27 – and the first parameter in the LiquidCrystal_I2C function.

Finally the three lines used in void setup() are also required to initialise the LCD. If you’re using a 20×4 LCD module, change the parameters in the lcd.begin() function.

From this point you can use all the standard LiquidCrystal functions such as lcd.setCursor() to move the cursor and lcd.write() to display text or variables as normal. The backlight can also be turned on and off with lcd.setBacklight(HIGH) or lcd.setBacklight(LOW).

You can permanently turn off the backlight by removing the physical jumper on the back of the module.

Changing the I2C bus address

If you want to use more than one module, or have another device on the I2C bus with address 0x27 then you’ll need to change the address used on the module. There are eight options to choose from, and these are selected by soldering over one or more of the following spots:

There are eight possible combinations, and these are described in Table 4 of the PCF8574 data sheet which can be downloaded from the NXP website. If you’re unsure about the bus address used by the module, simply connect it to your Arduino as described earlier and run the I2C scanner sketch from the Arduino playground.

We hope you enjoyed this tutorial and you can make use of it. Finally, if you enjoyed this tutorial, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a fourth 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.
Tronixstuff 24 Sep 12:57

Tutorial – PCF8574 backpacks for LCD modules and Arduino

Learn how to use inexpensive serial backpacks with character LCD modules with your Arduino. This is chapter fifty-eight of our huge Arduino tutorial series.

Introduction

Using LCD modules with your Arduino is popular, however the amount of wiring requires time and patience to wire it up correctly – and also uses a lot of digital output pins. That’s why we love these serial backpack modules – they’re fitted to the back of your LCD module and allows connection to your Arduino (or other development board) with only four wires – power, GND, data and clock.

You can use this with LCD modules that have a HD44780-compatible interface with various screen sizes. For example a 16 x 2 module:

The backpack can also be used with 20 x 4 LCDs. The key is that your LCD must have the interface pads in a single row of sixteen, so it matches the pins on the backpack – for example:

Hardware Setup

Now let’s get started. First you need to solder the backpack to your LCD module. While your soldering iron is warming up, check that the backpack pins are straight and fit in the LCD module, for example:

Then solder in the first pin, while keeping the backpack flush with the LCD:

If it’s a bit crooked, you can reheat the solder and straighten it up again. Once you’re satisfied with the alignment, solder in the rest of the pins:

Now to keep things neat, trim off the excess header pins:

Once you’ve finished trimming the header pins, get four male to female jumper wires and connect the LCD module to your Arduino as shown in the following image and table. Then connect your Arduino to the computer via USB:

Software Setup

The next step is to download and install the Arduino I2C LCD library for use with the backpack. First of all, rename the “LiquidCrystal” library folder in your Arduino libraries folder. We do this just to keep it as a backup.

If you’re not sure where your library folder can be found – it’s usually in your sketchbook folder, whose location can usually be found in the Arduino IDE preferences menu:

Next, visit https://bitbucket.org/fmalpartida/new-liquidcrysta… and download the latest file, currently we’re using v1.2.1. Expanding the downloaded .zip file will reveal a new “LiquidCrystal” folder – copy this into your Arduino libraries folder.

Now restart the Arduino IDE if it was already running – or open it now. To test the module we have a demonstration sketch prepared, simply copy and upload the following sketch:

/* Demonstration sketch for PCF8574T I2C LCD Backpack 
Uses library from https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads GNU General Public License, version 3 (GPL-3.0) */
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C	lcd(0x27,2,1,0,4,5,6,7); // 0x27 is the I2C bus address for an unmodified backpack

void setup()
{
  // activate LCD module
  lcd.begin (16,2); // for 16 x 2 LCD module
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
}

void loop()
{
  lcd.home (); // set cursor to 0,0
  lcd.print(" tronixlabs.com"); 
  lcd.setCursor (0,1);        // go to start of 2nd line
  lcd.print(millis());
  delay(1000);
  lcd.setBacklight(LOW);      // Backlight off
  delay(250);
  lcd.setBacklight(HIGH);     // Backlight on
  delay(1000);
}

After a few moments the LCD will be initialised and start to display our URL and the value for millis, then blink the backlight off and on – for example:

If the text isn’t clear, or you just see white blocks – try adjusting the contrast using the potentiometer on the back of the module.

How to control the backpack in your sketch

As opposed to using the LCD module without the backpack, there’s a few extra lines of code to include in your sketches. To review these, open the example sketch mentioned earlier.

You will need the libraries as shown in lines 3, 4 and 5 – and initialise the module as shown in line 7. Note that the default I2C bus address is 0x27 – and the first parameter in the LiquidCrystal_I2C function.

Finally the three lines used in void setup() are also required to initialise the LCD. If you’re using a 20×4 LCD module, change the parameters in the lcd.begin() function.

From this point you can use all the standard LiquidCrystal functions such as lcd.setCursor() to move the cursor and lcd.write() to display text or variables as normal. The backlight can also be turned on and off with lcd.setBacklight(HIGH) or lcd.setBacklight(LOW).

You can permanently turn off the backlight by removing the physical jumper on the back of the module.

Changing the I2C bus address

If you want to use more than one module, or have another device on the I2C bus with address 0x27 then you’ll need to change the address used on the module. There are eight options to choose from, and these are selected by soldering over one or more of the following spots:

There are eight possible combinations, and these are described in Table 4 of the PCF8574 data sheet which can be downloaded from the NXP website. If you’re unsure about the bus address used by the module, simply connect it to your Arduino as described earlier and run the I2C scanner sketch from the Arduino playground.

We hope you enjoyed this tutorial and you can make use of it. Finally, if you enjoyed this tutorial, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a fourth 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.

The post Tutorial – PCF8574 backpacks for LCD modules and Arduino appeared first on tronixstuff.

Tronixstuff 24 Sep 12:57

Tutorial – Arduino and TFT Color Touch Screen

Learn how to use an inexpensive TFT colour  touch LCD shield with your Arduino. This is chapter twenty-nine of our huge Arduino tutorial series.

Updated 07/02/2014

There are many colour LCDs on the market that can be used with an Arduino, and in this tutorial we’ll explain how to use a model that is easy to use, has a touch screen, doesn’t waste all your digital output pins – and won’t break the bank. It’s the 2.8″ TFT colour touch screen shield from Tronixlabs:

And upside down:

As you can imagine, it completely covers an Arduino Uno or compatible board, and offers a neat way to create a large display or user-interface.  The display has a resolution of 320 x 240 pixels, supports up to 65536 colours and draws around 250mA of current from the Arduino’s internal 5V supply. 

And unlike other colour LCDs, this one doesn’t eat up all your digital output pins – it uses the SPI bus for the display (D10~D13), and four analogue pins (A0~A3) if you use the touch sensor. However if you also use the onboard microSD socket more pins will be required. 

With some imagination, existing Arduino knowledge and the explanation within you’ll be creating all sorts of displays and interfaces in a short period of time. Don’t be afraid to experiment!

Getting started

Setting up the hardware is easy – just plug the shield on your Arduino. Next, download the library bundle from here. Inside the .zip file is two folders – both which need to be copied into your …Arduino-1.0.xlibraries folder. Then you will need to rename the folder “TFT_Touch” to “TFT”. You will notice that the Arduino IDE already contains a library folder called TFT, so rename or move it.

Now let’s test the shield so you know it works, and also to have some quick fun. Upload the paint example included in the TFT library – then with a stylus or non-destructive pointer, you can select colour and draw on the LCD – as shown in this video. At this point we’d like to note that you should be careful with the screen – it doesn’t have a protective layer.

Afraid the quality of our camera doesn’t do the screen any justice, however the still image looks better:

Using the LCD 

Moving on, let’s start with using the display. In your sketches the following libraries need to be included using the following lines before void setup():

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>

… and then the TFT library is initialised in void setup()

Tft.TFTinit();

Now you can use the various functions to display text and graphics. However you first need to understand how to define colours.

Defining colours

Functions with a colour parameter can accept one of the ten ten predefined colours – RED, GREEN, BLUE, BLACK, YELLOW, WHITE, CYAN, BRIGHT_RED, GRAY1 and GRAY2, or you can create your own colour value. Colours are defined with 16-but numbers in hexadecimal form, with 5 bits for red, 6 for green and 5 for blue – all packed together. For example – in binary:

MSB > RRRRRGGGGGGRRRRR < LSB

These are called RGB565-formatted numbers – and we use these in hexadecimal format with our display. So black will be all zeros, then converted to hexadecimal; white all ones, etc. The process of converting normal RGB values to RGB565 would give an aspirin a headache, but instead thanks to Henning Karlsen you can use his conversion tool to do the work for you. Consider giving Henning a donation for his efforts.

Displaying text

There are functions to display characters, strings of text, integers and float variables:

  Tft.drawChar(char, x, y, size, colour);          // displays single character variables
  Tft.drawString(string, x, y, size, colour);      // displays arrays of characters
  Tft.drawNumber(integer, x, y, size, colour);     // displays integers
  Tft.drawFloat(float, x, y, size, colour);        // displays floating-point numbers

In each of the functions, the first parameter is the variable or data to display; x and y are the coordinates of the top-left of the first character being displayed; and colour is either the predefined colour as explained previously, or the hexadecimal value for the colour you would like the text to be displayed in – e.g. 0xFFE0 is yellow.

The drawFloat() function is limited to two decimal places, however you can increase this if necessary. To do so, close the Arduino IDE if running, open the file TFTv2.cpp located in the TFT library folder – and search for the line:

INT8U decimal=2;

… then change the value to the number of decimal places you require. We have set ours to four with success, and the library will round out any more decimal places. To see these text display functions in action,  upload the following sketch:

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>

char ascii = 'a';
char h1[] = "Hello";
char h2[] = "world";
float f1 = 3.12345678;

void setup()
{
  Tft.TFTinit(); 
}

void loop()
{
  Tft.drawNumber(12345678, 0, 0, 1, 0xF800);
  Tft.drawChar(ascii,0, 20,2, BLUE);
  Tft.drawString(h1,0, 50,3,YELLOW);
  Tft.drawString(h2,0, 90,4,RED);  
  Tft.drawFloat(f1, 4, 0, 140, 2, BLUE);      
}

… which should result in the following:

To clear the screen

To set the screen back to all black, use:

Tft.fillScreen();

Graphics functions

There are functions to draw individual pixels, circles, filled circles, lines, rectangles and filled rectangles. With these and a little planning you can create all sorts of images and diagrams. The functions are:

Tft.setPixel(x, y, COLOUR);                  
// set a pixel at x,y of colour COLOUR

Tft.drawLine(x1, y1, x2, y2, COLOUR);        
// draw a line from x1, y1 to x2, y2 of colour COLOUR

Tft.drawCircle(x, y, r, COLOUR);             
// draw a circle with centre at x, y and radius r of colour COLOUR

Tft.fillCircle(x, y, r, COLOUR);             
// draw a filled circle with centre at x, y and radius r of colour COLOUR

Tft.drawRectangle(x1, y1, x2, y2 ,COLOUR);   
// draw a rectangle from x1, y1 (top-left corner) to x2, y2 (bottom-right corner) of colour COLOUR

Tft.Tft.fillRectangle(x1, y1, x2, y2 ,COLOUR);   
// draw a filled rectangle from x1, y1 (top-left corner) to x2, y2 (bottom-right corner) of colour COLOUR

The following sketch demonstrates the functions listed above:

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>

int x, y, x1, x2, y1, y2, r;

void setup()
{
  randomSeed(analogRead(0));
  Tft.TFTinit(); 
}
void loop()
{
  // random pixels
  for (int i=0; i<500; i++)
  {
    y=random(320);
    x=random(240);
    Tft.setPixel(x, y, YELLOW);
    delay(5);
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen

    // random lines
  for (int i=0; i<50; i++)
  {
    y1=random(320);
    y2=random(320);    
    x1=random(240);
    x2=random(240);    
    Tft.drawLine(x1, y1, x2, y2, RED);   
    delay(10);
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen

    // random circles
  for (int i=0; i<50; i++)
  {
    y=random(320);
    x=random(240);
    r=random(50);
    Tft.drawCircle(x, y, r, BLUE); 
    delay(10);
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen

    // random filled circles
  for (int i=0; i<10; i++)
  {
    y=random(320);
    x=random(240);
    r=random(50);
    Tft.fillCircle(x, y, r, GREEN); 
    delay(250);
    Tft.fillCircle(x, y, r, BLACK);     
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen

    // random rectangles
  for (int i=0; i<50; i++)
  {
    y1=random(320);
    y2=random(320);    
    x1=random(240);
    x2=random(240);    
    Tft.drawRectangle(x1, y1, x2, y2, WHITE);   
    delay(10);
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen

    // random filled rectangles
  for (int i=0; i<10; i++)
  {
    y1=random(320);
    y2=random(320);    
    x1=random(240);
    x2=random(240);    
    Tft.fillRectangle(x1, y1, x2, y2, RED);   
    delay(250);
    Tft.fillRectangle(x1, y1, x2, y2, BLACK);       
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen
}

… with the results shown in this video.

Using the touch screen

The touch screen operates in a similar manner to the other version documented earlier, in that it is a resistive touch screen and we very quickly apply voltage to one axis then measure the value with an analogue pin, then repeat the process for the other axis.

You can use the method in that chapter, however with our model you can use a touch screen library, and this is included with the library .zip file you downloaded at the start of this tutorial.

The library does simplify things somewhat, so without further ado upload the touchScreen example sketch included with the library. Open the serial monitor then start touching the screen. The coordinates of the area over a pixel being touch will be returned, along with the pressure – as shown in this video.

Take note of the pressure values, as these need to be considered when creating projects. If you don’t take pressure into account, there could be false positive touches detected which could cause mayhem in your project.

Now that you have a very simple method to determine the results of which part of the screen is being touched – you can create sketches to take action depending on the touch area. Recall from the example touch sketch that the x and y coordinates were mapped into the variables p.x and p.y, with the pressure mapped to p.z. You should experiment with your screen to determine which pressure values work for you.

In the following example, we don’t trigger a touch unless the pressure value p.z is greater than 300. Let’s create a simple touch-switch, with one half of the screen for ON and the other half for OFF. Here is the sketch:

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>
#include <TouchScreen.h> 

// determine the pins connected to the touch screen hardware
// A0~A3
#define YP A2   // must be an analog pin, use "An" notation!
#define XM A1   // must be an analog pin, use "An" notation!
#define YM 14   // can be a digital pin, this is A0
#define XP 17   // can be a digital pin, this is A3 

#define TS_MINX 116*2
#define TS_MAXX 890*2
#define TS_MINY 83*2
#define TS_MAXY 913*2

// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// The 2.8" TFT Touch shield has 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM);

void setup() 
{
  Serial.begin(9600);
  Tft.TFTinit(); 
  Tft.fillScreen(); // clear screen
}

void loop() 
{
  // a point object holds x y and z coordinates
  Point p = ts.getPoint();
  p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);
  Serial.println(p.y);
  if (p.y < 160 && p.z > 300) // top half of screen?
  {
    // off
    Tft.fillCircle(120, 160, 100, BLACK);     
    Tft.drawCircle(120, 160, 100, BLUE); 
  } else if (p.y >= 160 && p.z > 300)
  {
    // on
    Tft.fillCircle(120, 160, 100, BLUE); 
  }
}

What’s happening here? We divided the screen into two halves (well not physically…) and consider any touch with a y-value of less than 160 to be the off area, and the rest of the screen to be the on area. This is tested in the two if functions – which also use an and (“&&”) to check the pressure. If the pressure is over 300 (remember, this could be different for you) – the touch is real and the switch is turned on or off.

… and a quick demonstration video of this in action.

Displaying images from a memory card

We feel this warrants a separate tutorial, however if you can’t wait – check out the demo sketch which includes some example image files to use.

Conclusion

By now I hope you have the answer to “how do you use a touch screen LCD with Arduino?” and had some fun learning with us. You can get your LCD from Tronixlabs. 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.

Tutorial – Arduino and TFT Color Touch Screen

Learn how to use an inexpensive TFT colour  touch LCD shield with your Arduino. This is chapter twenty-nine of our huge Arduino tutorial series.

Updated 07/02/2014

There are many colour LCDs on the market that can be used with an Arduino, and in this tutorial we’ll explain how to use a model that is easy to use, has a touch screen, doesn’t waste all your digital output pins – and won’t break the bank. It’s the 2.8″ TFT colour touch screen shield from Tronixlabs:

And upside down:

As you can imagine, it completely covers an Arduino Uno or compatible board, and offers a neat way to create a large display or user-interface.  The display has a resolution of 320 x 240 pixels, supports up to 65536 colours and draws around 250mA of current from the Arduino’s internal 5V supply. 

And unlike other colour LCDs, this one doesn’t eat up all your digital output pins – it uses the SPI bus for the display (D10~D13), and four analogue pins (A0~A3) if you use the touch sensor. However if you also use the onboard microSD socket more pins will be required. 

With some imagination, existing Arduino knowledge and the explanation within you’ll be creating all sorts of displays and interfaces in a short period of time. Don’t be afraid to experiment!

Getting started

Setting up the hardware is easy – just plug the shield on your Arduino. Next, download the library bundle from here. Inside the .zip file is two folders – both which need to be copied into your …\Arduino-1.0.x\libraries folder. Then you will need to rename the folder “TFT_Touch” to “TFT”. You will notice that the Arduino IDE already contains a library folder called TFT, so rename or move it.

Now let’s test the shield so you know it works, and also to have some quick fun. Upload the paint example included in the TFT library – then with a stylus or non-destructive pointer, you can select colour and draw on the LCD – as shown in this video. At this point we’d like to note that you should be careful with the screen – it doesn’t have a protective layer.

Afraid the quality of our camera doesn’t do the screen any justice, however the still image looks better:

Using the LCD 

Moving on, let’s start with using the display. In your sketches the following libraries need to be included using the following lines before void setup():

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>

… and then the TFT library is initialised in void setup()

Tft.TFTinit();

Now you can use the various functions to display text and graphics. However you first need to understand how to define colours.

Defining colours

Functions with a colour parameter can accept one of the ten ten predefined colours – RED, GREEN, BLUE, BLACK, YELLOW, WHITE, CYAN, BRIGHT_RED, GRAY1 and GRAY2, or you can create your own colour value. Colours are defined with 16-but numbers in hexadecimal form, with 5 bits for red, 6 for green and 5 for blue – all packed together. For example – in binary:

MSB > RRRRRGGGGGGRRRRR < LSB

These are called RGB565-formatted numbers – and we use these in hexadecimal format with our display. So black will be all zeros, then converted to hexadecimal; white all ones, etc. The process of converting normal RGB values to RGB565 would give an aspirin a headache, but instead thanks to Henning Karlsen you can use his conversion tool to do the work for you. Consider giving Henning a donation for his efforts.

Displaying text

There are functions to display characters, strings of text, integers and float variables:

Tft.drawChar(char, x, y, size, colour);          // displays single character variables
  Tft.drawString(string, x, y, size, colour);      // displays arrays of characters
  Tft.drawNumber(integer, x, y, size, colour);     // displays integers
  Tft.drawFloat(float, x, y, size, colour);        // displays floating-point numbers

In each of the functions, the first parameter is the variable or data to display; x and y are the coordinates of the top-left of the first character being displayed; and colour is either the predefined colour as explained previously, or the hexadecimal value for the colour you would like the text to be displayed in – e.g. 0xFFE0 is yellow.

The drawFloat() function is limited to two decimal places, however you can increase this if necessary. To do so, close the Arduino IDE if running, open the file TFTv2.cpp located in the TFT library folder – and search for the line:

INT8U decimal=2;

… then change the value to the number of decimal places you require. We have set ours to four with success, and the library will round out any more decimal places. To see these text display functions in action,  upload the following sketch:

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>

char ascii = 'a';
char h1[] = "Hello";
char h2[] = "world";
float f1 = 3.12345678;

void setup()
{
  Tft.TFTinit(); 
}

void loop()
{
  Tft.drawNumber(12345678, 0, 0, 1, 0xF800);
  Tft.drawChar(ascii,0, 20,2, BLUE);
  Tft.drawString(h1,0, 50,3,YELLOW);
  Tft.drawString(h2,0, 90,4,RED);  
  Tft.drawFloat(f1, 4, 0, 140, 2, BLUE);      
}

… which should result in the following:

To clear the screen

To set the screen back to all black, use:

Tft.fillScreen();

Graphics functions

There are functions to draw individual pixels, circles, filled circles, lines, rectangles and filled rectangles. With these and a little planning you can create all sorts of images and diagrams. The functions are:

Tft.setPixel(x, y, COLOUR);                  
// set a pixel at x,y of colour COLOUR

Tft.drawLine(x1, y1, x2, y2, COLOUR);        
// draw a line from x1, y1 to x2, y2 of colour COLOUR

Tft.drawCircle(x, y, r, COLOUR);             
// draw a circle with centre at x, y and radius r of colour COLOUR

Tft.fillCircle(x, y, r, COLOUR);             
// draw a filled circle with centre at x, y and radius r of colour COLOUR

Tft.drawRectangle(x1, y1, x2, y2 ,COLOUR);   
// draw a rectangle from x1, y1 (top-left corner) to x2, y2 (bottom-right corner) of colour COLOUR

Tft.Tft.fillRectangle(x1, y1, x2, y2 ,COLOUR);   
// draw a filled rectangle from x1, y1 (top-left corner) to x2, y2 (bottom-right corner) of colour COLOUR

The following sketch demonstrates the functions listed above:

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>

int x, y, x1, x2, y1, y2, r;

void setup()
{
  randomSeed(analogRead(0));
  Tft.TFTinit(); 
}
void loop()
{
  // random pixels
  for (int i=0; i<500; i++)
  {
    y=random(320);
    x=random(240);
    Tft.setPixel(x, y, YELLOW);
    delay(5);
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen

    // random lines
  for (int i=0; i<50; i++)
  {
    y1=random(320);
    y2=random(320);    
    x1=random(240);
    x2=random(240);    
    Tft.drawLine(x1, y1, x2, y2, RED);   
    delay(10);
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen

    // random circles
  for (int i=0; i<50; i++)
  {
    y=random(320);
    x=random(240);
    r=random(50);
    Tft.drawCircle(x, y, r, BLUE); 
    delay(10);
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen

    // random filled circles
  for (int i=0; i<10; i++)
  {
    y=random(320);
    x=random(240);
    r=random(50);
    Tft.fillCircle(x, y, r, GREEN); 
    delay(250);
    Tft.fillCircle(x, y, r, BLACK);     
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen

    // random rectangles
  for (int i=0; i<50; i++)
  {
    y1=random(320);
    y2=random(320);    
    x1=random(240);
    x2=random(240);    
    Tft.drawRectangle(x1, y1, x2, y2, WHITE);   
    delay(10);
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen

    // random filled rectangles
  for (int i=0; i<10; i++)
  {
    y1=random(320);
    y2=random(320);    
    x1=random(240);
    x2=random(240);    
    Tft.fillRectangle(x1, y1, x2, y2, RED);   
    delay(250);
    Tft.fillRectangle(x1, y1, x2, y2, BLACK);       
  }
  delay(1000); 
  Tft.fillScreen(); // clear screen
}

… with the results shown in this video.

Using the touch screen

The touch screen operates in a similar manner to the other version documented earlier, in that it is a resistive touch screen and we very quickly apply voltage to one axis then measure the value with an analogue pin, then repeat the process for the other axis.

You can use the method in that chapter, however with our model you can use a touch screen library, and this is included with the library .zip file you downloaded at the start of this tutorial.

The library does simplify things somewhat, so without further ado upload the touchScreen example sketch included with the library. Open the serial monitor then start touching the screen. The coordinates of the area over a pixel being touch will be returned, along with the pressure – as shown in this video.

Take note of the pressure values, as these need to be considered when creating projects. If you don’t take pressure into account, there could be false positive touches detected which could cause mayhem in your project.

Now that you have a very simple method to determine the results of which part of the screen is being touched – you can create sketches to take action depending on the touch area. Recall from the example touch sketch that the x and y coordinates were mapped into the variables p.x and p.y, with the pressure mapped to p.z. You should experiment with your screen to determine which pressure values work for you.

In the following example, we don’t trigger a touch unless the pressure value p.z is greater than 300. Let’s create a simple touch-switch, with one half of the screen for ON and the other half for OFF. Here is the sketch:

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>
#include <TouchScreen.h> 

// determine the pins connected to the touch screen hardware
// A0~A3
#define YP A2   // must be an analog pin, use "An" notation!
#define XM A1   // must be an analog pin, use "An" notation!
#define YM 14   // can be a digital pin, this is A0
#define XP 17   // can be a digital pin, this is A3 

#define TS_MINX 116*2
#define TS_MAXX 890*2
#define TS_MINY 83*2
#define TS_MAXY 913*2

// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// The 2.8" TFT Touch shield has 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM);

void setup() 
{
  Serial.begin(9600);
  Tft.TFTinit(); 
  Tft.fillScreen(); // clear screen
}

void loop() 
{
  // a point object holds x y and z coordinates
  Point p = ts.getPoint();
  p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);
  Serial.println(p.y);
  if (p.y < 160 && p.z > 300) // top half of screen?
  {
    // off
    Tft.fillCircle(120, 160, 100, BLACK);     
    Tft.drawCircle(120, 160, 100, BLUE); 
  } else if (p.y >= 160 && p.z > 300)
  {
    // on
    Tft.fillCircle(120, 160, 100, BLUE); 
  }
}

What’s happening here? We divided the screen into two halves (well not physically…) and consider any touch with a y-value of less than 160 to be the off area, and the rest of the screen to be the on area. This is tested in the two if functions – which also use an and (“&&”) to check the pressure. If the pressure is over 300 (remember, this could be different for you) – the touch is real and the switch is turned on or off.

… and a quick demonstration video of this in action.

Displaying images from a memory card

We feel this warrants a separate tutorial, however if you can’t wait – check out the demo sketch which includes some example image files to use.

Conclusion

By now I hope you have the answer to “how do you use a touch screen LCD with Arduino?” and had some fun learning with us. You can get your LCD from Tronixlabs. 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 TFT Color Touch Screen appeared first on tronixstuff.

Tutorial – pcDuino GPIO with Arduino IDE

Introduction

In this tutorial we’ll explain how to use the GPIO pins of the Arduino implementation in the pcDuino v2 and v3. As the v3 is now available you can use it as well, and it’s interchangeable with the v2. Although the pcDuino v2 is Arduino-compatible, there are a few differences that you need to be aware of – in order to make your projects a success and also to avoid any costly mistakes.

This tutorial builds on the knowledge from the initial review, so if pcDuino v2 is new to you please review this article before moving on. In this instalment we’ll run through the following:

  • ADC (analogue to digital)
  • Digital input and outputs
  • PWM (pulse-width modulation)
  • I2C bus
  • SPI bus

Using ADC pins

Just like an Arduino Uno or compatible, the pcDuino v2 has six ADC pins, in the expected locations:

Using the pcDuino v2’s ADC pins is quite straight forward, however you just need to remember a few things about the hardware – that the maximum input voltage on A0 and A1 is 2V – and 3.3V for A2~A5.

Although there is an AREF pin on the board, this function isn’t supported at the time of writing. From the software perspective A0 and A1’s values have a 6-bit resolution and can fall between 0 and 63 (0~2V), otherwise the others have a 12-bit resolution and thus return values between 0 and 4095 (0~3.3V). Using the ADC pins is simple, and demonstrated in the following sketch:

// pcDuino v2 ADC demonstration

#include <core.h> // for pcDuino

int a0, a1, a2, a3, a4, a5;

void setup() 
{
}

void loop() 
{
  // read all the ADCs
  a0 = analogRead(0);
  a1 = analogRead(1);
  a2 = analogRead(2);
  a3 = analogRead(3);
  a4 = analogRead(4);
  a5 = analogRead(5);
  // display ADC values to console
  printf(A0, A1,   A2,   A3,   A4,   A5\n);
  printf(%d  %d  %d  %d  %d  %d\n, a0, a1, a2, a3, a4, a5);
  printf(n);
  delay(1000);
}

… which results with the following in the console:

Digital outputs

The pcDuino v2’s implementation of digital outputs aren’t anything out of the ordinary – except that you are limited to a maximum voltage of 3.3V instead of the usual 5V. Furthermore you can only source 4mA from each pin. However if you have some 5V-only shields that you must use with your pcDuino v2 – there is a Voltage Translation board that can be used to solve the problem:

However using 3.3V for new designs shouldn’t be an issue – new sensors, ICs and so on should be 3.3V-compatible. And with the pcDuino v2 you get an extra four digital I/O pins, located next to the SPI grouping as shown below:

These are simply addressed as D14~D17. Now back for a quick demonstration with the typical LEDs. As the current sourced from each GPIO pin cannot exceed 4mA, you need to use a resistor to keep things under control. Using the LED wizard, by entering a 3.3V supply, 2.1V forward voltage for our LEDs and a 4mA current – the resistor value to use is 330Ω.

If you’re having a lazy attack and use 560Ω, the current will be around 2.5mA with acceptable results. We’ve done just that with the following demonstration sketch:

// pcDuino v2 digital output demonstration

#include <core.h> // for pcDuino

void setup() 
{
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);  
  digitalWrite(4, LOW);  
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);  
}

void loop() 
{
  for (int i = 4; i < 8; i++)
  {
    digitalWrite(i, HIGH);
    delay(250);
    digitalWrite(i, LOW);
  }
}

… and the results in this video.

Digital inputs

When using the digital pins as inputs, just treat them as normal except they have a maximum input voltage of 3.3V for HIGH. Again – just keep thinking “3.3V”.

Using the I2C data bus

The I2C bus (or “two wire interface”) is a common serial data bus used for interfacing all manner of devices with a microcontroller. You can find a background on the I2C bus and Arduino tutorial here. Just like an Arduino Uno R3, the I2C bus pins are both A4 and A5 (for SCL and SDA) and can also be found up near D13, for example.

The limitations for the pcDuino v2’s version of I2C bus are few – the maximum speed is 200 kHz, it only uses 7-bit addresses and you can’t use the pcDuino in slave mode. However there are 2.2kΩ pullup resistors which can save using them with external circuitry.

We demonstrate the I2C bus by writing data to and reading it from a Microchip 24LC256 EEPROM (which is handy in itself as there isn’t any EEPROM function on the pcDuino v2). This is demonstrated with an Arduino Uno in part two of our I2C tutorials.

Connection is very easy – pins 1 to 4 of the EEPROM are connected to GND, pin 5 to SDA, pin 6 to SCL, pin 7 to GND and pin 8 to 3.3V. Finally a 0.1uF capacitor is placed across 3.3V and GND.

The sketch to read and write values to the EEPROM is simple, and apart from the #include <core.h> for the pcDuino all the other functions operate as normal.

// pcDuino I2C demonstration

#include <core.h> // for pcDuino
#include <Wire.h>   for I2C
#define chip1 0x50  device bus address for EEPROM

// always have your values in variables
unsigned int pointer = 69;  // we need this to be unsigned, as you may have an address  32767
byte d=0;  // example variable to handle data going in and out of EERPROMS

void setup()
{
  Wire.begin();  // wake up, I2C!
}

void writeData(int device, unsigned int add, byte data) 
// writes a byte of data 'data' to the chip at I2C address 'device', in memory location 'add'
{
  Wire.beginTransmission(device);
  Wire.write((int)(add  8)); // left-part of pointer address
  Wire.write((int)(add & 0xFF)); // and the right
  Wire.write(data);
  Wire.endTransmission();
  delay(10);
}

byte readData(int device, unsigned int add) 
// reads a byte of data from memory location 'add' in chip at I2C address 'device' 
{
  byte result;  // returned value
  Wire.beginTransmission(device);  // these three lines set the pointer position in the EEPROM
  Wire.write((int)(add  8));  // left-part of pointer address
  Wire.write((int)(add & 0xFF)); // and the right
  Wire.endTransmission();
  Wire.requestFrom(device,1); // now get the byte of data...
  result = Wire.read();
  return result;  // and return it as a result of the function readData
}

void loop()
{
  printf(Writing data...\n);
  for (int a=0; a10; a++)
  {
    writeData(chip1,a,a);
  }
  printf(Reading data...\n);
  for (int a=0; a10; a++)
  {
    d=readData(chip1,a);    
    printf(Pointer %d holds %d.\n,a,d);
  }
}

… which results with the following output in the console:

As you now know, using I2C isn’t hard at all. A lot of beginners shy away from it – or run screaming for the nearest library for their part. You don’t need libraries – spend a little time now learning about I2C and you’re set for life.

Using the SPI data bus

Again we have some SPI tutorials for Arduino, so check them out first if the concept is new to you. Writing to an SPI device with the pcDuino v2 isn’t tricky at all, you have the 3.3V hardware limitation and the SPI pins are in the same location (D10~D13) or in a separate group on the board:

Furthermore the maximum SPI speed is 12 MHz and the pcDuino v2’s  implementation of SPI can only work as a master. However in the sketch there are a few differences to note. To demonstrate this we’ll control a Microchip MCP4162 digital rheostat via SPI to control the brightness of an LED. Here is the circuit:

And now for the sketch. Take note of the fourth line in void setup() –  this is used to set the SPI bus speed to 12 MHz. You can also reduce the speed with other multipliers such as 32, 64 and 128 to slow it down even further. The other point to note is the use of SPI.transfer(). With the pcDuino v2 there are two parameters – the first is the data to send to the SPI device, and the second is either

SPI_CONTINUE

if there is another byte of data following immediately, or

SPI_LAST

if that is the last byte for that immediate transfer. You can see this use of the paramters within the function setValue() in the demonstration sketch below.

// pcDuino SPI demonstration

#include <core.h>  // for pcDuino
#include <SPI.h>
int ss = 10;
int del = 1000;

void setup()
{
  SPI.begin();
  SPI.setDataMode(SPI_MODE3);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  pinMode(ss, OUTPUT);
  digitalWrite(ss, HIGH);
}

void setValue(int value)
{
  digitalWrite(ss, LOW);
  SPI.transfer(0, SPI_CONTINUE);
  SPI.transfer(value, SPI_LAST);
  digitalWrite(ss, HIGH);
}

void loop()
{
  setValue(255);
  delay(del);
  setValue(223);
  delay(del);
  setValue(191);
  delay(del);
  setValue(159);
  delay(del);
  setValue(127);
  delay(del);
  setValue(95);
  delay(del);
  setValue(63);
  delay(del);
  setValue(31);
  delay(del);
  setValue(0);
  delay(del);
}

When using the SPI bus, relevant data will appear in the console, for example:

And finally the demonstration video to show you it really works – you can see the output voltage from the rheostat and the matching LED brightness.

Receiving data from the SPI bus is equally as simple, however at the time of writing we don’t have an SPI device to demonstrate this, so please refer the SPI part of the pcDuino guide. Finally, you can’t use PWM on D10 or D11 when using the SPI bus in your sketch.

Pulse-width modulation

You can simulate analogue output using PWM with a pcDuino v2 – however there are two types of PWM pins available. The first is found on digital pins D3, D9, D10 and D11 – they are simulated PWM – and have a low range of zero to twenty at 5 Hz. There are two hardware PWM pins – D5 and D6, which  run at 520Hz and have the full range of 0~255 available in analogWrite(). Once again – they output 3.3V. Furthermore, you can’t use pinMode() functions or the SPI bus if using D10 and/or D11 for PWM.

Conclusion

Now you should have an understanding of the features and limitations of using GPIO pins with your pcDuino v2 Arduino sketches. 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 Tutorial – pcDuino GPIO with Arduino IDE appeared first on tronixstuff.

Tronixstuff 29 Jan 04:12
adc  arduino  gpio  i2c  input  output  pcduino  pwm  review  spi  tronixlabs  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.

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.

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.