Latest Entries »

 

Installing USBASP drivers on Windows 8 or 10 is bit tricky. As these versions of Windows require DEVICE DRIVER VERIFICATION , they do not allow unsigned drivers like libusb.

For programming 8051 or AVR you need this driver.

You can install by following methods :

1. Disabling Windows driver enforcement on boot up. Follow this link

https://alselectro.wordpress.com/2013/11/02/usbasp-drivers-not-installing-on-win-8-pc/

This method requires SHIFT+ RESTART of Windows to enter advanced troubleshooting where we disable signature verification .After this you can install the libusb driver.

But in some laptops , this method fails on next Windows update.

 

2. Install libusb drivers using ZADIG application.

http://zadig.akeo.ie/

Zadig is meant to install a libusb compatible driver, for a device that does not yet have such a driver installed.

With the application running, you should see your USB device appear in the dropdown list

(click on the dropdown to see all devices).
You can also plug your USB device after Zadig is running, as the list is refreshed automatically. Its recommended to leave only the device you want to install a driver for, and unplug any other USB device.

 

You can also select the driver you want to install,( between WinUSB/ libusb-win32/libusb0 / libusbK )

Once you are satisfied with the selection and device description, simply click the Install Driver Button.

Caution :

If you select the wrong device,  Zadig will  replace its driver.

The responsibility is entirely yours try to pay attention to the device you select .Don’t just  press the install button on the first device you see,

If wrong driver is replaced , then some of your USB devices like wireless mouse may not work.

 

3. Best & Easy method

The USBASP windows driver was previously based on  libusb-win32. The certificate on the base drivers have expired and the library has now been superseded by libusbK.

 

Following is the procedure to install protostack USBASP driver.

At first when you connect the USBASP hardware to PC & open the Device Manager you see an exclamation mark against USBASP indicating that drivers not installed.

 

Image 2

If you open the PROGISP application ( to load HEX file on to8051) ,you see the PRG ISP icon greyed out ,as the programmer is not yet detected.

Image 1

 

Download the new USBASP driver from

https://protostack.com.au/download/USBasp-win-driver-x86-x64-v3.0.7.zip

This driver should work with version of Windows XP right through to 8.1 and the version 10 . (both 32 and 64 bit editions).

Because the driver is signed, there should be no need to disable driver certificate enforcement or use Zadig.

Unzip the downloaded folder.

Click on Install Driver application

Image 4

 

Image 5

 

Image 6

Once the driver is installed , under Device Manager you can see USABASP under

libusbK Usb devices

Image 7

Now ,open the PROGISP application to see the device ready.

Image 8

blog_image

Advertisements

SIM808 is all in one module with GSM , GPRS,GPS & BLUETOOTH.SIM808 is advanced compared to SIM908.

SIM808 has GNSS receiver which enables easy GPS FIX.

In this post we explore how to parse GPS data ( without using TNYGPS library) & send it through inbuilt GSM

SIM 808 has 2 antenna sockets one  for GSM  & other for GPS. A stub antenna is used for GSM & a magnetic external patch antenna is used for GPS.

Do not interchange these 2 antennae. The antenna socket nearest to SIM808 chip is for GPS.

IMG_20180502_112731

 

Connection between Arduino UNO & SIM808 is simple.

Gnd to Gnd

Tx of SIM808 to Rx of Arduino (soft serial digital pin 7)

Rx of SIM808 toTx of Arduino (soft serial digital pin 8)

A separate power adapter of 12v 2amp is required for SIM808 board.

Insert valid SIM on to the slot at the  back of SIM808 board

Power on & notice the NETWORK LED .It blinks fast initially & when it gets network it blinks slowly ,once per second.

 

sim808_2_ok

 

We’ll use a serial to usb cable to monitor SIM808 serial port. We can also test AT commands through this port ,before uploading Arduino code.

Connect the cable to PC & note the COM port allotted under Device Manager .

Another COM port is allotted to Arduino board.Note this also.

img1

Before uploading code on to Arduino , let us check the AT commands.

For this open a PUTTY Terminal & select SERIAL.

Feed in the COM port of the USB-RS232 cable &baud rate as 9600. & click open.

Image 1

 

Type in AT ,the SIM808 module responds with OK.

ATD is the command to dial a number

AT+CMGF=1 , AT+CMGS=”phone no.” are for sending SMS.

All GSM related commands are similar to that of SIM800 or SIM900.

Some cases of empty SMS delivery is reported .i.e you receive SMS on mobile but has got no message.

To solve this problem set the following parameter.

AT+CSMP=17,167,0,0

This has to be done before you set the module to Text mode using AT_CMGF=1

Image 2

GPS related AT Commands are similar to that of SIM 908.

 

GPS_AT

AT+CGPSPWR=1 sets the GPS engine ON

AT+CGPSRST=0 gives a COLD RESTART to GPS

AT+CGSINF=0 returns a single NMEA sentence of GPS.

AT+CGPSSTATUS?   returns the Status of GPS whether it has got FIX or not.

If GPS has not received FIX , the NMEA sentence will read all  0 s

Relocate the GPS antenna & wait for some time to get a FIX. If the GPS antenna faces open SKY you get a FIX within seconds.

Image 3

Once GPS gets a FIX , AT+CGPSINF=0 returns a valid NMEA sentence.

AT+CGPSINF=32  returns a single GPRMC sentence

 

Image 4

 

Now let us see the SIM808 specific GPS commands

SIM808 has inbuilt GNSS receiver

AT+CGNSPWR=1  turns on the GNSS power

AT+CGNSSEQ=”RMC”  parses the NMEA sentence related to GPRMC

Now issuing the command AT_CGNSINF returns a valid NMEA  GPRMC sentence

SIM808_GPS

 

Image 5

 

Now let us upload the code that parses RMC data &sends SMS with google maps link

 

Arduino code Download :

 

http://www.alselectro.com/files/SIM808.zip

 

—————————————————

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

char phone_no[] = “xxxxxxx”; // replace with your phone no.
String data[5];
#define DEBUG true
String state,timegps,latitude,longitude;

void setup() {
sim808.begin(9600);
Serial.begin(9600);
delay(50);

sim808.print(“AT+CSMP=17,167,0,0”);  // set this parameter if empty SMS received
delay(100);
sim808.print(“AT+CMGF=1\r”);
delay(400);

sendData(“AT+CGNSPWR=1”,1000,DEBUG);
delay(50);
sendData(“AT+CGNSSEQ=RMC”,1000,DEBUG);
delay(150);

}

void loop() {
sendTabData(“AT+CGNSINF”,1000,DEBUG);
if (state !=0) {
Serial.println(“State  :”+state);
Serial.println(“Time  :”+timegps);
Serial.println(“Latitude  :”+latitude);
Serial.println(“Longitude  :”+longitude);

sim808.print(“AT+CMGS=\””);
sim808.print(phone_no);
sim808.println(“\””);

delay(300);

sim808.print(“http://maps.google.com/maps?q=loc:”);
sim808.print(latitude);
sim808.print(“,”);
sim808.print (longitude);
delay(200);
sim808.println((char)26); // End AT command with a ^Z, ASCII code 26
delay(200);
sim808.println();
delay(20000);
sim808.flush();

} else {
Serial.println(“GPS Initializing…”);
}
}

void sendTabData(String command , const int timeout , boolean debug){

sim808.println(command);
long int time = millis();
int i = 0;

while((time+timeout) > millis()){
while(sim808.available()){
char c = sim808.read();
if (c != ‘,’) {
data[i] +=c;
delay(100);
} else {
i++;
}
if (i == 5) {
delay(100);
goto exitL;
}
}
}exitL:
if (debug) {
state = data[1];
timegps = data[2];
latitude = data[3];
longitude =data[4];
}
}
String sendData (String command , const int timeout ,boolean debug){
String response = “”;
sim808.println(command);
long int time = millis();
int i = 0;

while ( (time+timeout ) > millis()){
while (sim808.available()){
char c = sim808.read();
response +=c;
}
}
if (debug) {
Serial.print(response);
}
return response;
}

——————————————————-

Following is the serial port monitor screenshot.

Once the command AT+CGNSINF is issued ,it returns a valid RMC sentence.

The latitude,longitude is then parsed

SMS is then sent with parsed data appended to google maps link.

Image 7

 

Pleae note Code is written to send SMS every 20 secs.

phone1

phone6

VIDEO :

 

 

blog_image

In this post let us explore the GPS Module built on UBLOX Neo series & then parse the data to send SMS with google maps link.

Arduino UNO is used to control the GPS module.

The GPS module used here has provision for connecting an external magnetic patch antenna.This enable the GPS to get FIX  within seconds even while testing indoor.

To test the GPS we need an USB to TTL  module.Or we can use our Arduino itself with a small hack.

Connect the RST pin of Arduino to GND.This will bypass the bootloader of Arduino & we can use the serial IC of Arduino to communicate with GPS.

Connect Tx of GPS to TX of Arduino & Gnd toGnd.

Note that the connection is STRAIGHT here & not reverse .Remember this connection will be reverse while we actually upload code to Arduino & use it in regular mode.

We can power the GPS module from Arduino itself. Connect 5v of Arduino to 5v of GPS.

Wait for some time for the GPS to get FIX. Once a FIX is received a green LED flashes on the GPS board indicating that GPS is ready with data flow.

p1

Connect the USB of Arduinot o PC & open the DEVICE MANAGER to note the COM port allotted.

Open the Arduino IDE & select the PORT allotted.

Image 8

 

Image 9

Open the SERIALMONITOR to see the FLOW of NMEA sentences

We’re interested  in GPRMC which is the recommended minimum data for gps

There is an interesting link where we can decode the GPRMC sentence & understand the contents

https://rl.se/gprmc

Copy & paste a GPRMC sentence in this site to decode the contents.

Image3

 

If you notice a V  in GPRMC sentence ,it means GPS has not yet got a FIX. Relocate the antenna & wait for some time to receive a FIX & V changes to A .

Now the RMC sentence has all  the  data latitude,longitude,time,speed,altitude,etc..

Image 4

 

 

Image 10

 

Copy a portion of the data flow & paste it on to a Notepad.

Save it as text file with a name.

 

Image 11

 

To visualize the data , go to this link

http://www.gpsvisualizer.com/

Click on Choose file & select the notepad file saved.

Select the Output Format as GOOGLE MAPS  & click MAPIT.

Image 12

You can see the location on Map.

Image 13

 

Now your GPS is working.Let us go for a practical demo with Arduino.

To parse the data there are libraries that make life easier.

One such library is TINYGPS++ from Arduiniana

http://arduiniana.org/libraries/tinygpsplus/

Download the library ,unzip it.

Image 14

Rename it to TinyGPSPlus & copy paste to Arduino –> Libraries.

Image 15

Open the Arduino IDE to see a list of examples against TinyGPS++

Select the FULLEXAMPLE  code.

Image 16

Here Softwareserial is used & digital pins 4 is defined as RX , 3 as Tx

Connect the Tx of GPS to  Rx of Arduino (digital pin 4)

Gnd toGnd.

As we only receive data from GPS , a single connection is enough. Tx of GPS toRx of Arduino

Image 17

 

Now upload the code & open the Serial monitor on baud 115200.

No data is received

Image 19

This is because of BAUD RATE mismatch.

Change the GPS Baud (not the serial baud)  to 9600 & then upload.

 

Image 20

 

Now you get data which is displayed neatly on serial monitor.

Image 21

In the next example we shall parse the GPS data & send SMS as google maps link using a GSM.

For this we use the previous version of library TINYGPS .

https://github.com/mikalhart/TinyGPS

 

Image 22

Download the library & install it.

Here we use SIM900 GSM .A separate power source of 12v 1amp is required for GSM.

Connection between Arduino & GPS :

 

Tx of GPS connected to Rx of Arduino

 

Gnd to Gnd

5v of Arduino to 5v of GPS.

 

Connection between Arduino & GSM

 

Gnd to Gnd

Tx of GSM to Rx (soft serial pin 7) of Arduino

Rx of GSM to Tx (soft serial pin 8) of Arduino

 

IMG_20180421_162653

 

Download the code from here

http://www.alselectro.com/files/GPS_GSM.zip

 

In this code we make use of older version of TINYGPS library to parse the latitude,longitude data,

 

Image 23

The data parsed is then appended to google maps link&sent as SMS .

Every 20 seconds an SMS is sent.You can modify the code so that you get SMS only when you call to the GSM.

 

Image 24

 

Upload the code & get the SMS on themobile no. you provided in the code.

Touch on the SMS link to see the location of GPS.

 

IMG_20180421_170826         IMG_20180421_170829

 

IMG_20180421_170845

SUPPORT VIDEO :

 

blog_image.jpg

WemosD1 R1 board is now  the most preferred IOT WIFI Board .As the hardware resembles Arduino , it is most sought out  board for any IOT project , than NODEMCU.

To add a display I prefer to use the SERIAL LCD WITH I2C BACKPACK  .

The serial LCD is built on PCF8574 &  works on I2C Bus ,thus requires only 2 wires SCL & SDA apart from the power pins.

The LCD works on 5V & it can be sourced from D1 board itself.

 

IMG_20180416_130653

For more detailed information on this Serial LCD you can read my previous blog here :

https://alselectro.wordpress.com/2016/05/12/serial-lcd-i2c-module-pcf8574/

 

The connection between D1 board & LCD is simple .

Wemos D1      LCD

5v           —–  Vcc

Gnd        —- Gnd

SCL  D15  (GPIO5)  —    SCL

SDA  D14   (GPIO4)   — SDA

To start with download the latest Library from this link :

https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

From Arduino IDE  Sketch –> Include library –> Add ZIP Library

Browse to the location of the downloaded ZIP file & select it

Image 2

Now the Library for Serial LCD is installed.

Image 3

 

Under Tools selectthe board as WEMOS D1 R1 , upload speed as 115200, port is the one allotted  in Device manager &programmer USBASP.

Image 4

Read this previous blog post of getting started with D1 board, on how to install Arduino core using Boards Manager

https://alselectro.wordpress.com/2018/04/14/wifi-esp8266-development-board-wemos-d1/

 

Now we need to know the I2C Address of the LCD board connected to D1.

For this upload the following Scanner sketch.

http://www.alselectro.com/files/Library_codeexamples.zip

 

Image 5

 

Once uploaded,Open the serial monitor with 9600 baud setting.

The I2C HEX Address of the device is displayed .Here it is 0x27 .

Note that this address varies according to the manufacturer and the jumper solder on A0 A1 A2 pins on the backpack pcb.

 

Image 6

Now open the first example lcd_test.

In this example 2 header files are used

One is the Wire.h ,which is the I2C library that is built in already with IDE.

Second  is the LiquidCrystal_I2C.h which we installed initially.

Then we create an instance  lcd with parameters I2C Address  , EN , RW , RS , D4,D5,D6,D7

I2C address is the ine we got from the scanner code –0x27

EN,RW,RS are the pins of I2C board connected to LCD Enable ,Read/Write & Register Select respectively.

D4 to D7 are Data pins

 

Image 3

lcd,begin(16,2) initializes the 16 x 2 LCD

Then we set the backlight ON for the LCD

lcd.home()moves the cursor to Home position

lcd.print(“,,,,”) prints the message on 1st row.

lcd.setCursor(0,1) moves the cursor to second line.

 

Image 7

 

Upload the code to see the result on LCD.

The Contrast to LCD can be adjusted by the preset on the back.

 

IMG_20180416_164802

 

Here is the second example which prints the message typed on the Serial monitor.

 

Image 8

 

Image 9

VIDEO  :

blog_image

WEMOS D1 is a WIFI development board based on ESP8266 12E. The functioning is similar to that of NODEMCU , except that the hardware is built resembling Arduino UNO.

The D1 board can be configured to work on Arduino environment using BOARDS MANAGER.

So,its not necessary to use a separate Arduino board , the D1 itself can be programmed on Arduino IDE.This is handy in using with IOT projects. Further many Arduino SHIELDs are compatible with the D1 board.

Different versions of D1 boards are available in the market    R1  ,  R2  , MINI

As the name implies D1 Mini is a smaller version

R1 , R2 boards look like Arduino UNO board ,but version is not printed on board. On some boards WEMOS D1is printed , as the ESP12 chip is manufactured by WEMOS.

In some other boards it is printed just D1 ,where the ESP12 chip is that of AI Thinker.

As the ESP12 chip has only one ANALOG pin , on board there is only A0 & other analog pins are dummy .

Image 2

Image 3   Image 4

Use a MicroUSB cable to connect D1 with PC. Make sure that the cable is capable of handling both Data & power (some of the mobile cables can handle  only power & not data) .

Open the DEVICE MANAGER & note the COM PORT allotted to the module.

As the serial chip used on D1 is CH340 , you need to install the corresponding drivers.

Image 1

PIN CONFIGURATION

d1_pinout

Following is the pin configuration of R2 typeD1 Module.Note the changes in GPIO Pin position.

WEMOS_D1_R2

Open the Arduino IDE &  select this COM port.

From TOOLS  —>  BOARDS  —> BOARDS MANAGER install the package for ESP8266.

Prior to this , you need to provide the link from where the Boards manager will look for the package.

To do this copy the following Link

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Go to FILE  –> PREFERENCES on Arduino IDE

Paste the link against the Additional Boards Manager URLs ,seen at the bottom of preferences screen & click OK.

Image 1.1

Now open the TOOLS –> BOARDS –> BOARDS MANAGER

Image8

Search for ESP8266

Now you will find the package from ESP8266 Community.

Select the latest version from drop down & install it.

It takes a while & requires internet connection.

Image 2.1

Once the package is installed ,you can see the list of  boards under TOOLS –> BOARDS

Select the board as WEMOS D1 R1.

Select UPLOAD speed as 115200 &Programmer as USBASP

Image 3.1

Now open the  File –> Examples –> Basics –> BLINK sketch

No need to modify the sketch ,as we’re going to blink the built in LED (on the ESP chip , there is another LED on board which is mapped to pin14)

Click on UPLOAD

error

On some PCs you get a compile error ,stating that the file is being used by another process.

On some forums ,it is mentioned that the board is Duplicate .Its not the case, the reason is that some Antivirus program like McAfee does not allow the compilation process.

Open the Antivirus dashboard & TURN OFF the REAL TIME SCANNING for some time

error2

error3

You can also configure the Antivirus settings for an EXCEPTION to Arduino programs.

Now Upload the sketch.

error4

Once the code is uploaded, you can see the built in LED blinking on the chip

Next code is a WIFI scanner which scans for nearby SSIDs & display the names of WIFInetworks with RSSI signal power &encryption mode.

For this we include the Header file ESP8266WiFi.h

This is installed along with the Boards Manager & is a very powerful library.

You can get more information on this library from here :

https://alselectro.wordpress.com/2016/11/29/esp8266-wifi-library-on-arduino-ide/

Many useful Functions are there for this WiFi library.

WiFi.mode (WIFI_STA); 

The mode function of library is used to set the D1 board in STATION mode.

WiFi.scanNetworks();

scanNetworks function scans for nearby SSIDs & the result is an integer (number of surrounding WiFis) which is stored in a variable n

Then we print the SSID name,RSSI signal strength ( the lower the negative dB the stronger the signal), & Encryption mode (a * indicates SSID is password protected)

—————————————–

// D1 ESP8266 WiFi scanner

# include  “ESP8266WiFi.h”

void  setup () {

Serial . begin ( 9600 );
// set WiFi to station mode and disconnect from previous connection
WiFi.mode (WIFI_STA) ;
WiFi.disconnect ();
delay ( 100 );
}

void  loop () {
Serial . println ( “Start Scanning ..” );
// scan for nearby WiFi SSIDs & save their number into n
int n = WiFi.scanNetworks ();
// in case no Network found , print info
if (n == 0 ) {
Serial . println ( “No SSIDs nearby seen…” );
}

else   {
Serial . print (n);
Serial . println ( “WiFi network SSIDs nearby ….” );
// list all WiFi networks nearby
// name, signal strength and security method
for ( int i = 0 ; i <n; ++ i)
{
Serial . print (i + 1 );
Serial . print ( “:” );
Serial . print ( WiFi.SSID(i));
Serial . print ( “(” );
Serial .print ( WiFi.RSSI(i));
Serial . print ( “)” );
Serial . println (( WiFi.encryptionType (i) == ENC_TYPE_NONE)?”” : “*” );
delay ( 10 );
}
}
// Exit
Serial . println ( “” );
// pause for 15 seconds before new scan
delay ( 15000 );
}

———————————–

scan2

scan1

Support VIDEO:

 

blog_image.jpg

In this post we ‘ll control a relay through GSM by sending message.

Parts required  :

GSM SIM900 or SIM800

Relay board  (12v board with active HIGH , i.e if you send HIGH from Arduino then Rlay will be ON)

Arduino UNO

DC connector cable & 12v adapter

We’ll make it simple   By sending SMS $a1 Relay is made ON

BY sending SMS $a0 the Relay is switched OFF

GSM SIM900 board is used in this demo , but you can use SIM800 also. A valid SIM to be inserted in to the slot on GSM board. Do not use 4G SIM like JIO , as the SIM 800 / 900 is 2G /3G enabled.

GSM2

 

A 1 channel relay board is used which is a 12v relay & needs a HIGH to enable the relay. Note that if you use a relay board with opto coupler , it needs a LOW to switch ON the relay .In this demo we use a 12v , HIGH enable relay which uses a simple NPN transistor to switch ON the relay.

 

GSM3

i.e from Arduino Digital pin you send a HIGH to switch ON the relay.

 

Connection

Digital pin 8 of Arduino is connected to Relay board INPUT

Rx of Arduino to Tx of GSM , Tx of Arduino to Rx of GSM

GND of Arduino to GND of GSM

12V Adapter is used as power source. Power socket is provided on GSM & Arduino boards . DC connectors are used to power up GSM & Arduino .As Arduino has 5v regulator on board you can safely use 12v at power socket.

The +ve pin of Relay board is looped with +12v of adapter & -ve to GND of Relay board.

Ensure that all GND pins are made common , that of GSM , Arduino & Relay boards.

 

GSM5

 

Following is the Arduino code to be uploaded. Remember to disconnect wires at Rx/Tx while uploading code to Arduino.

You can Download the Code HERE

 

——————————

char inchar; // variable to store the incoming character

int Relay = 8;

 

void setup()

{

pinMode(Relay, OUTPUT);

digitalWrite(Relay, LOW);

Serial.begin(9600);

delay(2000);

Serial.println(“AT+CMGF=1”); // set mode to text

delay(100);

Serial.println(“AT+CNMI=2,2,0,0,0”);

// just to get a notification when SMS arrives &direct out SMS upon receipt to the GSM serial out

delay(100);

}

 

void loop()

{

//If a character comes in from the GSM…

if(Serial.available() >0)

{

inchar=Serial.read();

if (inchar==’$’)

{

delay(10);

inchar=Serial.read();

if (inchar==’a’)

{

delay(10);

inchar=Serial.read();

if (inchar==’0′)

{

digitalWrite(Relay, LOW);

Serial.println(“Relay OFF”);

}

else if (inchar==’1′)

{

Serial.println(“Relay ON”);

digitalWrite(Relay, HIGH);

}

delay(100);

Serial.println(“AT+CMGD=1,4”); // delete all SMS

delay(2000);

}

}

}

}

———————————–

A char variable inchar is used to store the incoming SMS

The relay pin is defined as DIGITAL pin 8

Inside setup function , the Relay pin is declared as OUTPUT using pinMode & then initially it is made LOW

Serial.begin(9600) ; starts Serial communication at baud 9600.

AT+CMGF=1 confirms TEXT mode operation of GSM .Notice the use of SerialPrintln which provides a Carriage Return

Serial.println(“AT+CNMI=2,2,0,0,0”);

// just to get a notification when SMS arrives &direct out SMS upon receipt to the GSM serial out

The AT command +CNMI is used to specify how newly arrived SMS messages should be handled. You can tell the GSM/GPRS modem or mobile phone either to forward newly arrived SMS messages directly to the PC, or to save them in message storage and then notify the PC about their locations in message storage.

Syntax: AT+CNMI=<mode>,<mt>,<bm>,<ds>,<bfr>

Description:

This command selects the procedure for message reception from the network.

Values:

<mode>: controls the processing of unsolicited result codes

Note: Only <mode>=2 is supported.

<mt>: sets the result code indication routing for SMS-DELIVERs. Default is 0.

0: No SMS-DELIVER indications are routed.

1: SMS-DELIVERs are routed using unsolicited code: +CMTI: “SM”,<index>

2: SMS-DELIVERs (except class 2 messages) are routed using unsolicited code: +CMT:…….

AT+CNMI is used anyway just to get a notification when a SMS arrives, in order to read the content of the stored SMS you have to use AT+CMGL= or AT+CMGR=…

 

Inside Loop

If any serial data is available it is assigned to inchar variable

If the first character is $ , the inchar variable is replaced with next Serial character

If the next character is a , again the inchar is replaced with next serial character

Finally , if the character is 1 , the pin 8 is made HIGH & relay is made ON

If the final character is 0 , pin 8 is made LOW , thus making the relay OFF.

SMS $a1 makes the Relay ON

SMS $a0 makes the Relay OFF

Only basic code is explained in this post to just ON or OFF the relay. Further improvements can be done like :

1. Relay status sent back as SMS to the caller

2. Programming can be done so that SMS from particular Master number only is considered

& SMS from other number will not control the relay

3. Pump starter can be made ON / OFF by using 2 relays .One relay contact used to START the motor & other to STOP .While connected with STARTER we need to momentarily switch ON / OFF the relays. This is similar to manually pressing the START or STOP button of the motor starter.

Support video :

blog_image

The  PIC 16F877A , AVR ATMEGA 16,32 , ATMEL 89S51 , 52 , ICs used in Arduino uno,mega all are 8 bit microcontrollers.

LPC2148 is more powerful 32 bit uC. It is ARM 7 controller

  • On-chip flash programmable memory is 512kb
  • It is a high speed controller 60 MHz operation
  • Two 10 bit ADC converters provide a total of 14 analog inputs
  • One 10- bit D/A converter
  • Two 32 bit timers/counters
  • 4- CCM (Capture Compare Modulation), 6-PWM, Watchdog timer
  • One RTC, 9 interrupts
  • One I2C protocol, SPI protocols, SSP protocol
  • Two UART serial communication protocols

For development we use KEIL environment.

We will use evaluation version of MDK-ARM for C programming. This software is available at

https://www.keil.com/download/product/

Install C51 KEIL & then the MDK-ARM

Image 1

For LPC2148 support you must install the MDK Legacy support files available at

http://www2.keil.com/mdk5/legacy

http://az717401.vo.msecnd.net/legacy/MDK79524.EXE

If this support is not installed , LPC2148 will not show up on the KEIL IC list

Image 2

Once the installation of KEIL is completed , open up KEIL

Project –> New uVision Project

1.newproject

Create a Folder for your project & provide a Filename & save.

2.filename

In the next window dropdown select Legacy Device & search for LPC2148.

Select the IC LPC2148 .

If LPC is not listed then check the legacy support installation

3.lpc

Click on Yes to add STARTUP file to project.

Different manufacturers for LPC2148 use same ARM CORE. So STARTUP file is required which initializes ARM Core Peripherals , define stack program , Interrupt vectors ,etc..

START UP file will be in ASSEMBLY language only & must be part of your program which takes care of HARDWARE INITIALIZATION.

4.startup

Now the PROJECT is created

5.projectwindow

Right click on SOURCE GROUP 1 & click “Add New item to Group Source Group 1”

6.add_c

Select C File & provide a name to your C file (without .c extension .Its added automatically)

 

7.cname

 

Image 8

Right click on TARGET1 & select OPTIONS FOR TARGET TARGET 1

Image 9

3 important settings to be done , before starting your C code.

Image 10

The Options for TARGET can also be accessed from  FLASH  –>  CONFIGURE FLASH TOOLS

Image 14

Following 3 settings to be done for proper compiing.

Under TARGET tab select “Use MICROLIB”

Image 11

Under OUTPUT tab select CREATE HEX FILE

Image 12

Under LINKER tab select “ USE MEMORY LAYOUT FROM TARGET DIALOG

Image 13

If the LINKER setting is not done , your C code will compile to HEX file .But on uploading you will not see any result.

Now click on your  .c file under Source Group & type in the following code :

———————

#include <lpc214x.h>

void delay_ms(unsigned int count)
{
unsigned int i=0,j=0;
for(i=0;i<count;i++)
{
for(j=0;j<3000;j++);
}
}

/* start the main program */
int main()
{
PINSEL1 = 0x000000;  //Configure the P1 Pins for GPIO;
IODIR 0= (1<<18); //Configure the P0.18 pin as OUTPUT;

while(1)
{
IOSET0 |= (1<<18);  //Make p0.18 pin as high
delay_ms(1000);

IOCLR0 |= (1<<18);   // Make p0.18 pin as low
delay_ms(1000);
}
}

——————————-

 

Image 15

The C code starts with inclusion of 2148 header file

#include <lpc214x.h>

 

Next is the DELAY function which accepts an integer parameter count & creates delay

 

void delay_ms(unsigned int count)
{
unsigned int i=0,j=0;
for(i=0;i<count;i++)
{
for(j=0;j<3000;j++);
}

Then starts the MAIN program

In LPC2148 each pin can perform 4 functions which is decided by setting PINSEL Register

Lpc2148 have two General Purpose I/O ports PORT0 & PORT1 ( both are 32-bit bi-directional ports).

In PORT0    P0.24, P0.26, P0.27 are not available for user & P0.31 is available for digital output only.

In PORT1 P1.0 to P1.15 is not available physically. Only P1.16 to P1.31 is available.

So out of 64 pins 45 pins are available for user

& these pins can perform multi functions decided by PINSEL Registers.

There are 3 such registers

PINSEL0 controls P0.0 to P0.15

PINSEL1 controls P0.16 to P0.31

PINSEL2 controls P1.16 to P1.31

PINSEL is 32 bit register , Each pin is allotted 2 bits so 16 x 2 = 32 , each PINSEL controls 16 pins

Check out the following table

PINSEL0-table-for-ARM-Microcontroller

For e.g take P0.1 , the position of the pin is bits 2 & 3 of PINSEL0

If these bits are  00 then P0.1 will perform as GPIO

If the bits are 01 , P0.1 will perform as RxD

If the bits are 10 , P0.1 will perform as PWM3

& if the bits are 11 , P0.1 will perform as EINT0

So if you want P0.1 as RxD , make the bits 2 & 3 as 01

0 0 0 0     0 0 0 0    0 0 0 0    0 0 0 0      0 0 0 0    0 0 0 0    0 0 0 0    0 1  0 0

PINSEL0 = 0X000000004;  is the code that makes it

 

By default , all pins perform as GPIO .Even if you do not define PINSEL , the pins will perform as GPIO.

But it’s a good coding practice to define PINSEL

 

Image25

 

In our code we use P0.18 to connect with an LED .P0.18 falls under PINSEL1

PINSEL1 = 0x000000;  //Configure the P1 Pins for GPIO;

 

Next we need to define the DIRECTION of the GPIO pin .2 Registers are available to control the Direction

IODIR0 – for PORT0 pins

IODIR1 – for PORT1 pins

Writing 1 makes the pin as OUTPUT

writing 0 makes the GPIO as INPUT


  To make P0.18 as OUTPUT write 1 at 18th bit

so IODIR0 = 0X00040000;  makes P0.18 as OUTPUT

Image 30

We can also use the BIIT OPERATOR ,

LEFT SHIFT binary 1   18 times makes P0.18 as OUTPUT

IODIR 0 |= (1<<18); //Configure the P0.18 pin as OUTPUT

Always use  |= operator , which makes other bits unaffected

You can follow any method bit operator or Hex notation.

Next is the never ending loop , inside which we make the P0.18 as HIGH & after a delay make it LOW

thus blinking the LED connected to it.

 

while(1)
{
IOSET0 |= (1<<18);  //Make p0.18 pin as high
delay_ms(1000);

       IOCLR0 |= (1<<18);   // Make p0.18 pin as low
delay_ms(1000);
}

2 Registers are used for this  IOSET & IOCLR

Writing 1 to IOSET register makes the pin HIGH

Writing 1 to IOCLR register makes the pin LOW

Writing 0 to these registers have no effect.

 

Save the code by clicking the SAVE icon

Click build icon or F7 button to build the project.

 

Image 16

 

If the code is perfect you get 0 errors & 0 warnings

Image 17

Now the HEX file is created .

Note the path of the HEX file , it is under your project folder –> OBJECTS

 

Image 18

There are 2 applications to upload the HEX file on to the LPC2148

FLASH MAGIC  & PHILIPS 2000 UTILITY

Open the FLASH MAGIC application

Image 19

Click on OPTIONS & put a tick mark against “ USE DTR & RTS

 

Image 20

Select the IC as LPC2148

Image 22

COM port is the one allotted under Device Manager.

Image 23

Baud Rate is 9600 & Interface is ISP

Click on BROWSE & navigate to the location of the HEX file (under OBJECTs Folder)

Image21

Select the HEX file & click START button to UPLOAD the HEX on to LPC2148.

Note that I’m using a development board with USB upload facility (CP2102 built in).Otherwise you need to press the ISP & RESET buttons together for uploading the HEX file.

Image 24

 

There is also DEBUG facility in KEIL.

Click on DEBUG icon to start debugging.

debug5

Under OPTIONS for Target , go to DEBUG tab & select

USE SIMULATOR

LOAD APPLICATION ON STARTUP

RUN TO MAIN

debugsetting

Under VIEW you can select the PORT0 to see the OUTPUT

debug3

VIDEO TUTORIALS :

cooltext753793315    cooltext753790696

In this post we’ll see how to control an LED connected to NODEMCU from a WebBrowser.

The WebBrowser is a CLIENT & the NodeMCU is the SERVER .

The Nodemcu has to be installed with Boards Manager Arduino core. Refer to the previous post on how to do this.

 

Image 1

 

Connect the long pin of LED to D2 pin of NodeMCU , short pin to GND through a 470E resistor.

Connect the NodeMCU to USB port of PC & note the COM port allotted.Feed in this COM port number in IDE & select the board as NodeMcu v1.0 (ESP12E).

Upload the following code.

 

You can Download the code used in this post HERE

————————————-

 

#include <ESP8266WiFi.h>
#define LED D2
const char* ssid = “SARAVANA-ACT”;
const char* password = “str5412stk4141”;
unsigned char status_led=0;

WiFiServer server(80);

void setup() {
Serial.begin(115200);
pinMode(LED, OUTPUT);
Serial.println();
Serial.println();
Serial.print(“Connecting to “);
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED )
{
delay(500);
Serial.print(“.”);
}
Serial.println(“”);
Serial.println(“WiFi connected”);
server.begin();
Serial.println(“Server started”);
Serial.println(WiFi.localIP());
}

void loop() {
WiFiClient client = server.available();
if (!client) {
return;
}

Serial.println(“new client”);
while(!client.available())
{
delay(1);
}
String req = client.readStringUntil(‘\r’);
Serial.println(req);
client.flush();
if (req.indexOf(“/ledoff”) != -1)
{
status_led=0;
digitalWrite(LED,LOW);
Serial.println(“LED OFF”);
}
else if(req.indexOf(“/ledon”) != -1)
{
status_led=1;
digitalWrite(LED,HIGH);
Serial.println(“LED ON”);
}
String web = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n”;
web += “<html>\r\n”;
web += “<body>\r\n”;
web += “<h1>LED Status</h1>\r\n”;
web += “<p>\r\n”;
if(status_led==1)
web += “LED On\r\n”;
else
web += “LED Off\r\n”;
web += “</p>\r\n”;
web += “</p>\r\n”;
web += “<a href=\”/ledon\”>\r\n”;
web += “<button>LED On</button >\r\n”;
web += “</a>\r\n”;
web += “</p>\r\n”;

web += “<a href=\”/ledoff\”>\r\n”;
web += “<button>LED Off</button >\r\n”;
web += “</a>\r\n”;

web += “</body>\r\n”;
web += “</html>\r\n”;

client.print(web);
}

——————————————-

First of all, we include the ESP8266WiFi library, which will make available the functionality needed for the ESP8266 to connect to a WiFi network.Then we define the D2 pin as LED where an Led is connected.

#include <ESP8266WiFi.h>
#define LED D2

The SSID name & password are stored in char variables.

A WiFiserver object called “server “ is created & we pass the port 80 where the server will be listening ( 80 is the default port of HTTP)

WiFiServer server(80);

In the setup() function serial monitor is started at baud 115200 & the LED pin is declared as Output.

The begin() function of WiFi class is used with parameters ssid & password to start connection to WiFIi

WiFi.begin(ssid, password);

We wait till the WiFi.status() becomes WL_CONNECTED which indicates that connection is established .Until then we print a dot every 500msec.

while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(“.”);
}

Once connection is established , an IP address is allotted to NodeMCU by your Router.We print the IP address using the localIP() function.

Serial.println(WiFi.localIP());

Inside the loop we create an object called client of class WiFiClient & assign the server.available() result (it returns true or false) to it.

WiFiClient client = server.available();

It waits for a client ( here a web browser is the client) to connect with.

Once a request is received  , the client.readStringUntil (‘\r”) will read the request till it encounters a  carriage return & assign it to a String variable req

String req = client.readStringUntil(‘\r’);

indexOf() function of String is used to find out ehether the request is ledoff or ledon.

if (req.indexOf(“/ledoff”) != -1)

The indexOf() function returns a –1 if no match found.

Accordingly the LED is made ON or OFF.

Now let us see how a HTML page is served to webbrowser when a client request is received

ode will be stored in strings that will be returned in the HTTP responses

we can declare it in a string and just return it when a HTTP request is performed on the desired URL.

 

String web = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n”;
web += “<html>\r\n”;
web += “<body>\r\n”;
web += “<h1>LED Status</h1>\r\n”;

 

First, we  return the 200 HTTP code (OK code). Then, we need to make sure that we specify the return content as text/html, so the browser will know that it should be interpreted and rendered as such

Finally, we pass the string with the HTML/CSS code

The <html> element represents the root of an HTML document. All other elements must be descendants of this element .

The <body> tag specifies where the body of the document starts .

The <h1> tag specifies the Heading of Webpage

The <p> tag specifies a paragraph and thus we use it to indicate our description message.

 

web += “<a href=\”/ledon\”>\r\n”;
web += “<button>LED On</button >\r\n”;

The <a> tag allows us to create a hyperlink by specifying the URL of a page and the message of the hyperlink. So, in the href attribute we specify the URL we want the user to be redirected to, and between the two tags we specify the message of the hyperlink.

In this case, we are specifying a path in the current address, so we don’t need to put the IP and the port. So, when a user clicks the hyperlink, the browser knows it will need to redirect the user to

http://IP Port/[href value]

As we will see later, the paths we are specifying in the href will correspond to the paths where the NodeMcu will be programmed to return the corresponding code.

the <br> tag is just a simple line break between the hyperlinks.

One thing that is very important is that we are specifying the HTML code inside a string, and thus some details need to be taken in consideration.

First, in order to leave the code structured, we should split the declaration of the string in multiple lines. To do so, we need to put the double quotes in each line so the compiler will know that it should be considered as a single string. So, the outermost quotes of the previous code are not from the HTML but from the declaration of a string in multiple lines.

Finally, every quote that is part of the HTML code (for example, the quotes around the URLs in the <a> tag) needs to be escaped with the \ character. So, the \ characters we see before the quotes are also not part of the HTML code but rather the escaping mechanism.

The <button> tag allows for the definition of a clickable button. One of its functionalities allows us to specify a function that is executed when the button is clicked

 

web += “<button>LED Off</button >\r\n”;

Now upload the code & open the serial monitor

Image 5_1

WiFi connection starts & displays IP if connection established.

Open your web browser & type in the IP you got from the serial monitor.

Once you click the Enter button , a CLIENT request is sent to NodeMCU.

Now the HTML page is served & buttons LED ON & LED OFF are displayed on the browser.

Image 6_1

If you click LED ON button , the message string “ledon” is added to URL & sent to Nodemcu.

The string is read and accordingly the LED will be ON or OFF.

Image 7_1

 

Here is another version of code where we use client.print() to serve the Webpage

 

———————————-

 

#include <ESP8266WiFi.h>
#define LED D2  // LED at GPIO4 D2

const char* ssid = “SARAVANA-ACT”;
const char* password = “str5412stk4141”;
unsigned char status_led=0;

WiFiServer server(80);

void setup() {
Serial.begin(115200);
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);

// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print(“Connecting to “);
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}
Serial.println(“”);
Serial.println(“WiFi connected”);

// Start the server
server.begin();
Serial.println(“Server started at…”);
Serial.println(WiFi.localIP());

}

void loop() {

// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}

// Wait until the client sends some data
Serial.println(“new client”);
while (! client.available())
{
delay (1);
}

// Read the first line of the request
String req = client.readStringUntil(‘\r’);
Serial.println(req);
client.flush();

// Match the request

if (req.indexOf(“/ledoff”) != -1)  {
status_led=0;
digitalWrite(LED, LOW);
Serial.println(“LED OFF”);
}
else if(req.indexOf(“/ledon”) != -1)
{
status_led=1;
digitalWrite(LED,HIGH);
Serial.println(“LED ON”);
}

// Return the response
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println(“Connection: close”);
client.println(“”);

client.println(“<!DOCTYPE HTML>”);
client.println(“<HTML>”);
client.println(“<H1> LED CONTROL </H1>”);
client.println(“<br />”);

client.println(“<a href=\”/ledon\”\”> <button style=’FONT-SIZE: 50px; HEIGHT: 200px;WIDTH: 300px; 126px; Z-INDEX: 0; TOP: 200px;’> LED ON </button> </a>”);
client.println(“<a href=\”/ledoff\”\”> <button style=’FONT-SIZE: 50px; HEIGHT: 200px; WIDTH: 300px; 126px; Z-INDEX: 0; TOP: 200px;’> LED OFF </button> </a>”);
client.println(“</html>”);

delay(1);
Serial.println(“Client disconnected”);
Serial.println(“”);

}
———————————–

Inside <button> tag we create a style to make big size buttons.

On clicking the respective buttons the LED is made ON or OFF.

 

Image 9

 

Image 10

 

Image 11

VIDEO DEMO :

cooltext753793315   cooltext753790696

NODEMCU is built on ESP8266 12E Module & is an excellent , economical IOT PLATFORM.

Generally it is shipped from factory with NODEMCU FIRMWARE which can be programmed with LUA Script.

In this post we shall install the ARDUINO CORE for ESP8266 on NODEMCU & start exploring how to use the ARDUINO IDE to code NODEMCU

nodemcu_pins1

 

To use the ARDUINO IDE , first thing is to install the ARDUINO CORE on to NODEMCU.

Open the ARDUINO IDE & under FILE –> PREFERENCES paste the link provided below :

Arduino Boards Manager file link is HERE

 

Image 1

under Tools –> BOARDS –> BOARDS MANAGER

search for ESP8266 & then click on it to install the latest version.

Image 2

 

Connect the NODEMCU to the USB of PC & open the DEVICE MANAGER to note the COM PORT allotted.If you see exclamation mark , then install the CP2102 driver for the NODEMCU.

Under Tools –>

select the board as NODEMCU V1.0 (ESP12E) , Port as the COM port alloted, Programmer as USBASP , UPLOAD SPEED as 115200.

Image 3

 

Under FILE –> EXAMPLES –> ESP8266 select the BLINK sketch

Image 4

 

Here the LED_BUILTIN is mapped to the inbuilt LED on board NODEMCU.

So , just click on the UPLOAD button.

Image 5

 

Once the sketch is compiled , the uploading starts , as seen at the bottom of the IDE.

It takes some time to upload ( i.e the reason to select upload speed 115200 , to make it fast)

as the code upload is like upgrading Firmware.

As the sketch is uploaded , the blue LED on the ESP chip (near WIFI antenna) flickers & finally the RED LED on board blinks.

In the next example let us connect an LED at pin D2 through a resistor.

D2 pin is GPIO4 of NODEMCU , but in the code we use the notation Dx to represent GPIO pin.

To control GPIO4 pin we use D2 in the code & not GPIO4 directly.

Image 7

 

In the blink code , the following line is added

#define LED_BUILTIN D2

Image 8

Upload the code to see the LED connected at DS2 blinking.

In the same way we can use ANALOG WRITE function to give a fade effect on the LED.

 

Now let us explore the NETWORKING capabilities of NODEMCU.

To start with we include the ESP8266WiFi.h header file.

The WIFI library is enhanced version of Arduino & is installed along with the Boards Manager.

This ESP8266WiFi  library has several classes, methods and properties  , which combines many powerful FUNCTIONS .

In the first line of sketch #include <ESP8266WiFi.h> we are including ESP8266WiFi library. This library provides ESP8266 specific Wi-Fi routines we are calling to connect to network.

After the header file  , we store the SSID name & Password as character arrays

#include <ESP8266WiFi.h>
char ssid[]=”SSID_NAME”;
char pass[]=”Password”;

Inside the setup function , Serial communication is started with 9600 baud & the name of SSID is printed.

void setup() {
Serial.begin(9600);
delay(500);
Serial.print(“Connecting to..”);
Serial.println(ssid);
delay(500);

WiFi.disconnect() function is called to disconnect any previous connections

While using the WiFi CLASS , there is no need to create WiFi Object.Simply call the function like

begin(),  SSID(), status(), disconnect(), scanNetworks(), localIP(), etc..

Actual connection to Wi-Fi is initialized by calling the begin() function.We pass on the 2 parameters to WiFi.begin() function to start the connection

  WiFi.disconnect();
WiFi.begin(ssid,pass);

We use a While loop to test the status of WiFi.status(). Here we check whether it returns WL_CONNECTED

IF not connected , a dot is printed every 500 msec.

while(WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.println(“.”);
}

Once connection is established , it jumps out of loop & prints the SSID name connected with.

if connection is established, and then lost for some reason, ESP will automatically reconnect to last used access point once it is again back on-line. This will be done automatically by Wi-Fi library, without any user intervention.

Serial.print(“SSID…”);
Serial.println (WiFi.SSID());
Serial.println(“Successfully connected!!!”);

 

Next the IP address allotted to the NODEMCU by the Router  (by DHCP method) is printed by calling the function WiFi.localIP()

The MAC address is printed using WiFi.macaddress()

 

Serial.print(“IP Address allotted to NodeMcu ESP..”);
Serial.println(WiFi.localIP());

Serial.print(“MAC Address of ESP…”);
Serial.println(WiFi.macAddress());

WiFi.printDiag(Serial) prints all the WiFi credentials like Channel , SSID name , Password , etc..

This specific function  prints out key Wi-Fi diagnostic information:

WiFi.printDiag(Serial);
}

void loop()
{
}

Upload the code & open the Serial monitor at baud 9600 to see the result.

 

Image 10

Next example is to scan the surrounding networks & print the name of SSIDs.

Here we use the function scanNetworks() which returns an Integer value on the number of surrounding SSIDs.

We assign this to an integer variable

int n = WiFi.scanNetworks();

& then in a For loop iterate to print out name of each surrounding SSIDs

 

for (int i=0; i<n; i++)

{

Serial.println(  WiFi.SSID (i) )

}

Image 11

 

Scan for available Wi-Fi networks in one run and return the number of networks that has been discovered.

WiFi.scanNetworks();

There is on Overload of this function that accepts two optional parameters to provide extended functionality of asynchronous scanning as well as looking for hidden networks

WiFi.scanNetworks(async,show_hidden);

Both function parameters are of boolean type. They provide the flowing functionality: * asysnc – if set to true then scanning will start in background and function will exit without waiting for result. To check for result use separate function scanComplete . * show_hidden – set it to true to include The in scan result networks with hidden SSID.

 

Image12

Download code samples HERE

Download ESP8266 Library document PDF HERE

VIDEO TUTORIALS :

 

 

cooltext753793315   cooltext753790696

 

VIDEO TUTORIAL ON TIMER1

 

 

ATMEGA 16/32 has 3 TIMERS —TIMER0 8 bit , TIMER 1 (16 Bit) , Timer 2 (8 bit).

In the previous post we tested with TIMER0 .

This post is related to TIMER 1 , particularly the INTERRUPT functions.

As we know Timers work by incrementing a counter variable called counter register. The counter register can count to a certain value, depending on its size. The timer increments this counter one step at a time until it reaches its maximum value, at which point the counter overflows, and resets back to zero.

Since Timer1 is 16 bits, it can hold a maximum value of (2^16 – 1), or 65535.

In order to increment the counter value at regular intervals, the timer must have access to a clock source.  The clock source generates a consistent repeating signal.  Every time the timer detects this signal, it increases its counter by one.

If clock source is 8MHz we’ll go through one clock cycle every 1 / 8000000 seconds, or 0.000000125 secs or 0.125 usec . That means Timer1 Counter takes 65535 * 0.000000125 = 0.0082

timer counts will elapse in 0.0082 secs

So , if we need a one second delay ( 1000msec) , 1000/0.0082 = 121951 which obviously higher than 65535 which is the highest count for TIMER1.

Here comes the need of PRESCALER

Clock source can be divided by 8 , 64, 256 , 1024 by setting the bits 0:2 of TCCR1B

After counting 65535 , The timer normally sets a flag (OverFlow Flag) bit to let you know an overflow has occurred.

In case of TIMER1 , COUNTER Register is made of 2 , 8 bit Registers TCCR1A & TCCR1B put together forms a 16 bit Register

You can check this flag manually, or you can also have the timer trigger an interrupt as soon as the flag is set. You can specify an Interrupt Service Routine (ISR) to run code of your choice when the timer overflows. The ISR will reset the overflow flag behind the scenes,

Following table shows the list of REGISTERs associated with TIMER1

clip_image002

clip_image004

TCCR1 is actually composed of two registers TCCR1A & TCCR1B

TCCR1A controls the compare modes & the pulse width modulation modes

TCCR1B controls the prescaler & input multiplexer & input capture modes

TCCR1B COUNTER SELECT bits 0:2 control the input to Timer1 .These 3 select bits provide clock signals that are absolutely identical to those of Timer0

clip_image006

When the timer counts past 65535 (0xFFFF) , it sets the Flag TOV1 (bit 2 of TIFR ) register.The registers TIFR & TIMSK are common for all 3 timers.

When Compare register is used , the OCF1B or OCF1A flag is set according to the channel (A or B) used for Compare operation.

clip_image008

Instead of manually checking the Flags in TIFR , Interrupts can be used to trigger ISR automatically when the particular Interrupt bit is Enabled in TIMSK register.

As seen below bits 2 to 5 are for TIMER1

If TOIE1 bit is enabled , on Timer 1 overflow , the corresponding Interrupt Service Routine ISR is called automatically & the code inside ISR is executed

clip_image010

Following is the list of Vector table.You have to use the correct VECTOR NAME in the ISR Function

clip_image012

From above table you can see RESET is on the top of table & is unmaskable ,having the highest priority

if Timer overflow interrupt TOIE1 is enabled , You need to use the ISR function Vector 9 in table

 

First example code is using OVERFLOW INTERRUPT.

Using this interrupt we blink an LED connected to PD6 – pin 20

We use the external crystal 8MHZ as clock source. ( High FUSE 0XD9 , LOW Fuse 0XFD)

To start with include the 2 Header files at the top of code.

Inside the Main Function PD6 pin is made as OUTPUT , as we’ve connected an LED at pin20.

DDRD |= (1<<6);

The prescaler we’ve selected is 256 .To apply this we need to set the bit CS12 in the TCCR1B register.In Timer1 the control register is of 2 parts TCCR1A & TCCR1B .

clip_image016

Prescaler select bits are found in TCCR1B.

clip_image020

TCCR1B |= (1<<CS12); // prescaler 256 selected , clock is now 8000000/256= 31250Hz

Next load the TCNT1 counter with the calculated value

TCNT1 = 49910;

Calculation is as follows :

Suppose we want to blink the LED at at the rate 2HZ , i.e., 0.5sec ( 500 milli secs) interval

We selected  prescaler 256

The clock frequency becomes 8000000 / 256 = 31250 Hz

Time for each Tick is 1 / 31250 = 0.000032 sec = 32usec

For 500 msec to elapse the count is 500 / 0.032 = 15625

Timer 1 counts from 0 to  65535 & overflows.

65535 – 15625 = 49910

So if you preload the counter with 49910 , the counter starts at 49910 & counts up to 65535 elapsing 15625 count & creating 500 msec delay

You can also use the Timer Calculator from

https://www.easycalculation.com/engineering/electrical/avr-timer-calculator.php

 

Next enable the Timer OverFlow Interrupt TOIE1 in the TIMSK Register

 

TIMSK |= (1<<TOIE1);

timsk

 

Enable the Global Interrupt using the command

sei();

 

Now we’ve to write the code for ISR with correct vector name TIMER1_OVF_vect

Inside the ISR Function we toggle the LED at PD6 & THEN AGAIN LOAD THE TCNT1 Register with the calcuated value.This is important as otherwise the TCNT1 will start counting from 0.

ISR (TIMER1_OVF_vect)

{

PORTD ^= (1<<6); // toggle LED

TCNT1 = 49910; // again load counter with calculated value

}

 

Complete code is here :

——————————

#include <avr/io.h>

#include <avr/interrupt.h>

 

int main (void)

{

DDRD |= (1<<6); // PD6 is Output

TCCR1B |= (1<<CS12); // prescaler 256 selected , clock is now 8000000/256= 31250Hz

TCNT1 = 49910; // load counter with calculated value

TIMSK |= (1<<TOIE1); // enable Timer overflow interrupt

sei();

while (1) {}

ISR (TIMER1_OVF_vect)

{

PORTD ^= (1<<6); // toggle LED

TCNT1 = 49910; // again load counter with calculated value

}

————————————-

Compile the code as we’ve done in previous examples & upload the HEX code to see the LED blinking at 500 msec delay.

You can also use the code creator for AVR from :

ONLINE AVR CODE creator

http://www.dioda.ro/avrwiz/index.html

 

CLEAR TIMER ON COMPARE MATCH CTC MODE

 

In previous above example we loaded the Counter with a calculated value & then waited for the counter to Overflow & used the Overflow interrupt to execute TIMER1_OVF_vect ISR

In compare mode, there is one compare register, where we can set value to compare with the Timer / counter register value. Once the compare value matches with timer / counter register value, compare match occurs. This compare match event can be used for waveform generation.

The Timer counts up until the value of the TCNT1 (Timer / counter register) register becomes equal to the content of OCRx (Compare register). As soon as TCNT1 becomes equal to the OCRx, compare match occurs and then timer will get cleared and OCFx flag will get set.

Hence, this comparison takes place  inside the AVR CPU hardware . Once the counts value becomes equal to the compare value, a flag in the status register is set and the timer is reset automatically.  Hence the name – CTC – Clear Timer on Compare

 

ctc_img1

 

 

Let us explore the code :

 

First we enable the CTC mode by setting the bit WGM12 bit of TCCR1B.

Prescaler selected is 256 by setting CS12 bit in TCCR1B

TCCR1B |= (1 << WGM12) | (1 << CS12);

 

clip_image016

The WGM bits are found in both the registers.But we need to set only the WGM12 bit to enable CTC. This bit is found inside TCCR1B Register. So no need to set the TCCR1A register.

ctc

We then initialize the TCNT1 value to start from 0.

When the TCNT1 value reaches a compare value , an interrupt is enabled.

This compare value is loaded into a  OCR1 x Register.

The Output Compare Register 1A – OCR1A and the Output Compare Register 1B – OCR1B are utilized for this purpose.

Since the compare value will be a 16-bit value (in between 0 and 65535), OCR1A and OCR1B are 16-bit registers. In ATMEGA16/32, there are two CTC channels – A and B. We can use any one of them or both. Let’s use OCR1A.

Let us load the Compare value as

OCR1A = 31250 ;

Calculation is as follows :

Clock is 8 MHz & we use a prescaler of 256

Now the clock to Timer1 is 8000000/256 = 31250 Hz

Time period is reciprocal of freq = 1/31250 = 0.000032 usec or 0.032 milli sec

To generate a delay of 500 ms 500ms/ 0.032 msec = 15625 counts

To generate 1 sec delay ( 1000millisec) 1000/0.032 = 31250

Now enable the OCIE1A Interrupt in TIMSK Register

tim

 

TIMSK |= (1 << OCIE1A);

Whenever a match occurs (TCNT1 becomes equal to OCR1A ), an interrupt is fired (as OCIE1A is set) and the OCF1A flag is set (we do not check this flag manually, as we use interrupt).

Now  we need an Interrupt Service Routine (ISR) to attend to the interrupt.

Executing the ISR clears the OCF1A flag bit automatically and the timer value (TCNT1) is reset.

The ISR is defined as follows with the correct vector name TIMER1_COMPA_vect

ISR (TIMER1_COMPA_vect)

{

PORTD ^= (1 << 6);

}

 

Complete code is as below :

———————————————-

#include <avr/io.h>

#include <avr/interrupt.h>

void timer1_init()

{

TCCR1B |= (1 << WGM12) | (1 << CS12);

TCNT1 = 0;

OCR1A = 31250;

TIMSK |= (1 << OCIE1A);

sei();

}

 

ISR (TIMER1_COMPA_vect)

{

PORTD ^= (1 << 6);

}

int main(void)

{

DDRD |= (1 << 6);

timer1_init();

while(1)  {}

}

———————————-

Compile & upload the HEX file to see the LED blinking at 1 sec interval

 

Hardware CTC Mode

Without Interrupt enable you can toggle or generate waveform on certain predefined OC pins which is called Hardware CTC , Output Compare

PB3, PD4, PD5 and PD7 represent the OUTPUT COMPARE pins

OC0 , OC1A, OC1B , OC2

These are the Output Compare pins of TIMER0, TIMER1 and TIMER2 respectively.

 

clip_image014_thumb2

 

 

Timer/Counter1 Control Register A

The TCCR1A Register bits 4 to 7 decide the Compare output mode of unit  A or B

These bits control the behaviour of the Output Compare (OC) pins. The behaviour changes depending upon the following modes:

· Non-PWM mode (normal / CTC mode)

· Fast PWM mode

· Phase Correct / Phase & Frequency Correct PWM mode

.  CTC Mode

clip_image022

 

clip_image024

 

clip_image018

Simply set the timer1 to the mode 01 as seen in table above.

Whenever a compare match occurs, the OC1A pin is automatically toggled.

Only PD5 or PD4 (OC1A or OC1B) can be controlled this way, which means that we should connect the LED to PD5 (since we are using channel A

 

————————————-

#include <avr/io.h>

#include <avr/interrupt.h>

void timer1_init()

{

TCCR1B |= (1 << WGM12)|(1 << CS11)|(1 << CS10);

// set up timer OC1A pin in toggle mode

TCCR1A |= (1 << COM1A0);

TCNT1 = 0;

// initialize compare value

OCR1A = 31250;

}

int main(void)

{

DDRD |= (1 << 5);

timer1_init();

while(1) {}

}

——————————————-

 

cooltext753793315    cooltext753790696