Latest Entries »

 

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 or 0.032 msec

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

VIDEO TUTORIALS ON TIMER0 :

 

Timers/counters are an independent unit inside AVR. They  run independently of what task CPU is performing. In this post we’ll explore the TIMER 0 Interrupts of AVR ATMEGA 16 .The previous post was on External Interrupts , this TIMER 0 is Internal Interrupt.

AVR ATMEGA 16 has 3 timers TIMER0 ,TIMER 1 & TIMER 2.Of these TIMER 1 is 16 bit Timer while others are 8 bit timers.

8-bit timer is capable of counting 2^8=256 steps from 0 to 255

Similarly a 16 bit timer is capable of counting 2^16=65536 steps from 0 to 65535. Due to this feature, timers are also known as counters. When the timer returns to its initial value of zero , We say that the timer/counter overflows.

Timer Events

  1. OVERFLOW

In normal operation overflow occurs when the count value passes 0XFF & becomes 00

Timer 0 is a 8 bit timer. It basically means it can count from 0 to 2^8 255. The operation of timer 0 is straight forward. The TCNT0 register hold the timer Count and it is incremented on every timer “tick”. If the timer is turned on it ticks from 0 to 255 and overflows. If it does so, a Timer OverFlow Flag (TOV) is set.

The Flags are present inside the Register TIFR which is common for all 3 timers.

 

2. COMPARE MATCH

Another interesting feature is that a value can be set in the Output Compare Register (OCR0), and whenever TCNT0 reaches that value, the Output Compare Flag (OCF0) flag is Set.

We say Compare Match has occurred  when the count value equals the contents of the output compare register

In this post we handle these above 2 events using the Interrupt concept.

 

OVERFLOW INTERRUPT

TCNT0 is the register that holds the current value of Timer

You can read from or write to this register to set your own time.

Timer0 works by incrementing this TCNT0a counter variable, also known as a counter register. The counter register can count to a value 0XFF , as Timer 0 is 8 bit .

The timer increments this counter one step at a time until it reaches its maximum value (255), at which point the counter overflows, and resets back to zero. The timer sets a flag (OVF0) bit .

You can check this flag inside TIFR register manually, or you can also have the timer trigger an interrupt (TOIE0) as soon as the flag is set. An  Interrupt Service Routine (ISR) is called automatically to run code of your choice when the timer overflows.

The ISR will reset the overflow flag behind the scenes automatically

 

TIMER0 uses 2 8 bit DATA REGISTERS  TCNT0 , OCR0

If you enable TCNT0 the register will increment from 0 counts upto 255 then overflos & start counting again ,

OCR0 never increments.You need to set a value bet 0 & 255

2 conditions occur OVERFLOW , COMPARE MATCH (TCNT0=OCR0)

The corresponding ISR vector name to be used in the ISR Function

ISR (TIMER0_OVF_vect) {}    for Overflow interrupt

ISR (TIMER0_COMP_vect) {}    for Compare Interrupt

 

Now let us Calculate the period of clock source .We use an external crystal oscillator of 8MHz

Period = 1/ clock freq = 1/8000000 = 0.125 usec

Timer counter overflows 256 * 0.000125ms = 0.032 msec

For 1 sec delay 10000/0.032 = 31250

Timer0 counter has to overflow 31250 times to generate one sec delay.

 

To increase the time delay we can reduce the clock applied to counter applying a prescaler

Prescalers of 1 ,8, 256  or  1024 can be applied by setting the CS0:2 bits of TCCR0 register

TCCR0 is the TIMER COUNTER CONTROL REGISTER for TIMER0

PRESCALER decides the speed of increment of TCNT0

Prescaler = 0 timer off

Prescaler = 1 speed of clock on which uc runs

= 2 clk/8      = 3 clk/64      =4 clk/256 ,       =5 clk/1024

=6 ext clock falling edge count ,   =7 ext clock at p0 pin rising edge count

Let us select prescaler of 1024

 

Programming steps:

1. Initialize TNCNT0 to value 0.

2. Program Prescaler by setting CS bits of TCCR0.

3. Set Timer OverFlow Interrupt TOIE0 bit of TIMSK register.

4. Enable global interrupt by sei () command.

5. Write code for ISR function with vector name TIMER0_OVF_vect

 

 

1. Code using OVERFLOW Interrupt that blinks LED at PD6 at 1 second interval

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

#include <avr/io.h>

#include <avr/interrupt.h>

 

volatile uint8_t count;

int main (void)

{

DDRD |= (1<<6); //PD6 as output

TCNT0 = 0;

count = 0;

TCCR0 |= (1<<CS02) | (1<<CS00); // PRESCALER 1024

TIMSK = (1<<TOIE0);

sei();

while(1)  {}

}

 

ISR (TIMER0_OVF_vect)

{

if (count == 31)

{

PORTD ^= (1<<6);

count=0;

}

else

count++;

}

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

To start with we include the 2 Header files & then declare a variable count.

volatile uint8_t count;

Here we use the keyword Volatile , as the variable is a Global one & will be used inside  the ISR Function.If you do not use the volatile keyword & use the variable within ISR , the AVR-GCC compiler may report error while optimizing the code.

As we connect an LED at PD6 we make it as OUTPUT using left shift operator.

We then initialize the TCNT0 & the count variable to 0.

To set the prescaler as 1024 we need to set the bits CS00 & CS02 to 1inside the TCCR0 Register.

TCCR0 |= (1<<CS02) | (1<<CS00);

 

tccr0_1

Next step is to enable the TIMER OVERFLOW INTERRUPT TOIE0 inside the

TIMSK Register

TIMSK = (1<<TOIE0);

clip_image006

Enable the Global interrupt using

sei();

which sets the I bit of SREG.

Next we’ve to write the code for ISR Function.

Correct Vector name must be used in this function.As we use the overflow interrupt select the correct vector name from the vector table  TIMER0_OVF_vect

gfgf

ISR (TIMER0_OVF_vect)

{

if (count == 31)

{

PORTD ^= (1<<6);

count=0;

}

else

count++;

}

Let us see the calculation how we arrived at value 31 in the if condition.

The clock is external crystal 8MHz.We apply a prescaler of 1024.

Now the clock freq to counter becomes 8000000/1024 = 7812.5 Hz

Time period = 1/freq = 1/7812.5 = 0.000128usec or 0.128 milli sec

Overflow occurs every 256*0.128 = 32.768 msec

To generate a time delay of 1 sec 1000/32.768 =  30.5 or 31

So the counter TCNT0 has to overflow 31 times to generate A TIME DELAY OF 1 SEC.

As done in previous example , save this file as main.c

Save  the MFILE  inside the same folder.You can use the same MFILE  as of the previous post example.(Remember to save the C file as main.c)

Make ALL from WINAVR’s Programmers Notepad to create HEX file & then click Program to upload the file.Now the LED at PD6 blinks exactly at 1 second interval.

 

CTC mode operation:

Clear Timer on Compare Match It is better to use instead of Normal mode because in CTC mode, frequency can be easily adjusted.

When the Timer is triggered, register TCNT0 starts counting.

Timer0 has a OCR0 (Output Compare Register), which is continuously compared with TCNT0 register.

In CTC mode whenever match occurs, OCF0 (Output Compare Flag) will set to 1. If continuous wave form generation is required, OCF0 must be reset again.

Alternatively, if OCIE0 (Output Compare interrupt) and Global interrupt flags in SREG are set, OCF0 will reset automatically after interrupt execution.
The bits WGM0 [1:0] are programmed to select waveform generation mode. For enabling CTC set the bit WGM01

Programming steps:

1. Select CTC mode by programming WGM0 [1:0] bit.

2. Program Prescaler by setting CS bits of TCCR0.

3. Load Compare register OCR0 with a value between 0 & 255

4. Set compare Interrupt OCIE0 bit of TIMSK register.

5. Enable global interrupt by sei () command.

 

6. Write code for ISR function with vector name TIMER0_COMP_vect

 

clip_image008

OCF0 – Output Compare Flag 0 — Bit 1 of TIFR

is set whenever a compare match occurs. It is cleared automatically whenever the corresponding ISR is executed. Alternatively it is cleared by writing ‘1’ to it.

 

———————–

#include <avr/io.h>
#include <avr/interrupt.h>

void  timer_init(void)
{
// set up timer with prescaler = 1024 and CTC mode
TCCR0 = (1 << WGM01) ;
TCCR0=  (1 << CS00) | ( 1<<CS02);
// initialize counter
TCNT0 = 0;
// initialize compare value
OCR0 = 220;
// enable compare interrupt
TIMSK |= (1 << OCIE0);
// enable global interrupts
sei();

}

ISR (TIMER0_COMP_vect)
{
PORTD ^= (1 << 6);
}

int main(void)
{

DDRD |= (1 << 6);
timer_init();

while(1)
{
// do nothing
}
}

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

 

TCCR0 = (1 << WGM01) ;

We enable the CTC mode in the TCCR0 Register by setting the bit WGM01

clip_image010

 

clip_image012

We then set the prescaler to 1024 by setting the bits CS00 & CS02

TCCR0=  (1 << CS00) | ( 1<<CS02);

Initialize the TCNT0 Register with 0 value & then load the Output Compare Register with a value 220

OCR0 = 220;

As the TIMER0 is 8 bit timer we can only load the counter with a value between 0 & 255 .This will not create a longer delay & the LED will blink fast , almost stable.In the next post we’ll see the TIMER1 capable of generating longer delay as TIMER1 is 16 bit .

Next enable the Compare Interrupt  OCIE0 within the TIMSK Register

TIMSK |= (1 << OCIE0);
TIMSK_0

Enable the Global interrupt using sei();

Inside the ISR function we just toggle the LED at PD6

ISR (TIMER0_COMP_vect)
{
PORTD ^= (1 << 6);
}

Note the usage of correct Vector name TIMER0_COMP_vect

Compile the code as done in previous examples & see the LED blinking very fast , as we could generate delay in millisec only using Compare mode.

HARDWARE INTERRUPT USING OC Pins

Instead of enabling the Interrupt we can make use of the OUTPUT COMPARE pins of AVR

The Output Compare Pins are seen as OC pins OC0 at PB3 for Timer0

 

clip_image014

 

Programming steps:

1. Select CTC mode by programming WGM0 [1:0] bit.
2. Program COM0 [1:0] bits and select “toggle OC0 if compare match”.

3. Set OC0 (PB3) pin as output pin.
4. Set OCIE0 bit of TIMSK register.

5. Enable global interrupt by “sei ()” command.

 

 

Mode    WGM0[1:0]    Mode
0    00    Normal
1    01    PWM,Phase Correct
2    10    CTC
3    11    Fast PWM

The Register TCCR0 also consists COM0 [1:0] bits. These bits are used to select functionality of OC0 pin. Following table shows function of COM 0[1:0]:

COM0[1:0]    Description
00                Normal,OC0 disconnected
01                Toggle OC0 on compare match
10                Clear OC0 on compare match
11               Set OC0 on compare match

 

#include <avr/io.h>

#include <avr/interrupt.h>

void timer_init(void)

{

// set up timer with prescaler = 1024 and CTC mode

TCCR0 |= (1 << WGM01)|(1 << CS00)|(1 << CS02);

// set up timer OC0 pin (PB3) in toggle mode

TCCR0 |= (1 << COM00);

// initialize counter

TCNT0 = 0;

// initialize compare value

OCR0 = 220;

}

int main(void)

{

// connect led to pin PB3

DDRB |= (1 << 3);

// initialize timer

timer_init();

// loop forever

while(1)  {}

}

OC0  is toggled automatically  no need to keep track of any flag bits or ISR

cooltext753793315   cooltext753790696

AVR – ATMEGA16 – EXTERNAL INTERRUPTS

Interrupts in AVR can be external (port pin sensing) or internal (Timers,ADC,UART,etc..)

When Interrupt occurs , the following things are done by AVR

1. AVR controller stops the current program execution and saves the context.

2.  Control jumps to Interrupt Service Routine (ISR). (Each interrupt have an associated ISR which is a piece of code executed when an interrupt occurs.)

3.  Execution of ISR is performed automatically..

4.  When ISR is complete, the Controller resumes processing where it left off before the interrupt occurred.(main program resumes)

Interrupt sources of AVR are

PORT PINS INT0 (PD2), INT1 (PD3) , INT2 (PB2) & RESET

RESET is unmaskable interrupt & has the highest priority.

Other interrupt sources are Internal to AVR like -Timer , UART , ADC ,SPI , I2C ,etc..

This post is on the PORT PIN Interrupts i.e., EXTERNAL INTERRUPT

EXT_INT

Let us connect an LED at PD0 & a switch at PD2.

PD2 is where Interrupt INT0 is sensed.

PD0 – LED

PD2 – SWITCH

 

LED_SW

Steps to configure the Interrupt:

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

1. Set INT0 bit in the General Interrupt Control Register (GICR)

2. Configure MCU Control Register (MCUCR) to select interrupt type( let us configure for Falling edge).

3. Set Global Interrupt(I-bit) Enable bit in the AVR Status Register(SREG) sei()

4. Handle the interrupt in the Interrupt Service Routine code.

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

 

General Interrupt Control Register (GICR)

In the GICR register enable the bit6 which configures INT0 Interrupt

It’s a good practice to mention the bit name itself in the code

GICR |= (1<<INT0) ;

Here we use the left shift operator to make the bit INT0 as 1

image

 

Type of INTERRUPT ( Rising Edge or Falling edge) is decided by setting bits 0 & 1of MCUCR Register

The MCUCR contains configuration bits which tells what signals will trigger INT0 and INT1

For this you need to set the ISC bits ( Interrupt Sense Control )

ISC00 & ISC01 configures the INT0 interrupt type.These are bits 0 & 1.

 

image

As seen in fig. above set this to Falling edge trigger by making ISC01 as 1.

MCUCR |= (1<< ISC01) ; (or you can also write MCUCR =0x02;)

Mentioning the bit name is always a good practice in coding

Now the Interrupt on INT0 is Falling edge-triggered (meaning that the interrupt is triggered when the signal changes from high to low)

image

We’ve connected a Reset type micro switch at PD2. When the switch is pressed 1 is applied to PD2 & when switch is released 0 is applied .Falling edge level triggering is from High to Low edge.

MCUCR is to configure INT0 & INT1 Interrupts.

 

INT2 is configured by another Register MCUCSR

INT2 can only be used as an edge-triggered interrupt.(no level trigger)

image

 

Now enable the Global Interrupt by setting the I-bit in SREG

It is the master control for all interrupts in AVR micro-controller.

This is done by calling sei();

When Interrupt occurs the ISR – Interrupt Service Routine is called automatically.Inside the ISR function we toggle the LED state.

ISR(INT0_vect)

{

PORTD ^= (1<<0);

}

The vector name used in this ISR is INT0_vect

Correct vector name to be used in the ISR function .Select it from the table below :

image

 

Complete code

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

#include <avr/io.h>

#include <avr/interrupt.h>

int main (void)

{

DDRD = (1<< 0) ; // PORT pin PD0 is Output

PORTD | = (1<<0); // PD0 is High normally

GICR = (1<< INT0); // enable INT0 Interrupt

MCUCR |= (1<< ISC01) ; // configure Falling Edge Trigger

sei(); // Enable Global Interrupt

while(1) {}

}

ISR(INT0_vect) // Interrupt Service Routine

{

PORTD ^= (1<<0);

}

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

 

We use Programmers Notepad of WINAVR to develop the C code.

Save the file as main.c inside a folder.

Open the MFILE utility of WINAVR to create the MFILE required for compilation.

Select the MCU type as ATMEGA16 , port as usb & programmer as usbasp.

Usbasp is not in the list of programmer.You need to select any one in the list & then Enable Editing.

Now you can edit your selection to usbasp

Save the MFILE in the same folder where you’ve stored the main.c file.

Click on Tools à MakeAll to compile & then Tools à Program to upload the hex file .

Now the LED at PD0 glows.

When switch connected to PD2 is pressed & then released , a Interrupt occurs (falling edge)

The LED at PD0 changes state to LOW.

Again press the switch & release , the LED changes state to HIGH.

VIDEO DEMO :

Links to previous posts :

https://alselectro.wordpress.com/2017/06/20/avr-self-learning-kit-getting-started/

https://alselectro.wordpress.com/2017/08/13/avr-self-learning-kit-interfacing-16-x-2-lcd-in-8-bit-mode/

 

In this tutorial we shall explore how to connect 16 X 2 LCD with ATMEGA 16 on Development board.

By 2 ways we can connect , first one is 8 bit mode & the second is 4 bit mode

 

DEMO_BOARD

This post is on 8 BIT MODE

In 8 bit mode all port pins of a Port , say PORT B is assigned for DATA communication.

For CONTROL we need 3 more pins RS , RW & EN

RS is REGISTER SELECT RS=0 Command Register of LCD selected , RS=1 DATA Register is selected

RW is READ/WRITE pin when RW=1 LCD is in Read mode , when RW=0 LCD is in WRITE mode

Generally LCD is used to display data.So mostly RW is connected to GND ( RW=0)

PB0 to PB7 – D0 to D7 of LCD

PD4 (PIN 18) — > RS

PD5 (PIN 19)– > RW

PD6 (PIN 20) — > EN

The backlight connection & Contrast pot are taken care in the development board.

 

LCD_DATA_CTRL_PIN_CON

 

We use PROGRAMMERS NOTEPAD of WINAVR to develop the C code & Hex file .

WINAVR is a lightweight excellent tool for AVR Programming compared to the AVR STUDIO ( which is a huge download)

You can download WINAVR

https://sourceforge.net/projects/winavr/files/latest/download?source=files

Its only 29MB download & easy to install.

Once WINAVR is installed , you can see the Programmers Notepad & MFILE inside the WINAVR Folder.

winavr

Open Programmers Notepad to type in the C code.

To start with the code , include the 2 Header files on the top . avr/io.h defines all Port Registers & port pins of AVR IC & the util/delay.h is responsible for the Delay we use in the code.

 

#include <avr/io.h>

#include <util/delay.h>

 

Next we define the LCD Function definitions like

 

void LCD_send_command(unsigned char cmnd);

void LCD_send_data(unsigned char data);

void LCD_init(void);

 

Above all are user defined Functions & we’ve to write code for these functions.

For better code readability & reuse of coded we use # define statements

 

#define DATA_PORT PORTB

#define DATA_DDR DDRB

#define CNTRL_PORT PORTD

#define CNTRL_DDR DDRD

#define RS_PIN 4

#define RW_PIN 5

#define ENABLE_PIN 6

 

PORTB is defined as DATA_PORT & PORTD is defined as CNTRL_PORT , DDRB as DATA_DDR, DDRD as CNTRL_DDR

In the code , wherever DATA_PORT is mentioned it is replaced with PORTD & wherever CNTRL_PORT is mentioned is replaced with PORTD.

Also pins PD4 is defined as RS_PIN , PD5 as RW_PIN , PD6 as ENABLE_PIN .Its enough to mention only the pin number. Instead of PD5 you can mention only 5.

Later if you decide to change the port pins assigned to LCD , you need to change it in the #define statements and the rest of the code is left as it is.

First let us see the LCD_init() function which initializes the LCD

 

void LCD_init()

{

_delay_ms(10);

LCD_send_command(0x38);

LCD_send_command(0x0E);

LCD_send_command(0x01);

_delay_ms(10);

LCD_send_command(0x06);

}

 

To initialize the LCD we send the HEX values as command.The HEX command codes are

clip_image002

We send HEX value 0x38 to define 16 x 2 LCD 2lines & character size is 5 x 7

0x0E forDisplay ON & cursor blinking

0x06 to increment cursor

& 0x01 to Clear Screen

We send Command using Function LCD_sendcommand

Which accepts parameter as unsigned char

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

void LCD_send_command(unsigned char cmnd)

{

DATA_PORT = cmnd;

CNTRL_PORT &= ~(1<< RW_PIN);

CNTRL_PORT &= ~(1<< RS_PIN);

 

CNTRL_PORT |= (1<< ENABLE_PIN);

_delay_us(2);

CNTRL_PORT &= ~(1<< ENABLE_PIN);

_delay_us(100);

}

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

Command received as unsigned char is assigned to DATA_PORT

RW pin is made LOW to enable Write operation

RS pin is made LOW to select COMMAND REGISTER

ENABLE pin is made HIGH & after a small delay made LOW ( pulse)

In the same way DATA is sent to LCD for Display using the following function :

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

void LCD_send_data(unsigned char data)

{

DATA_PORT = data;

CNTRL_PORT &= ~(1<< RW_PIN);

CNTRL_PORT |= (1<< RS_PIN);

 

CNTRL_PORT |= (1<< ENABLE_PIN);

_delay_us(2);

CNTRL_PORT &= ~(1<< ENABLE_PIN);

_delay_us(100);

}

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

 

Data received as unsigned char is assigned to DATA_PORT

RW pin is made LOW to enable Write operation

RS pin is made HIGH to select DATA REGISTER

ENABLE pin is made HIGH & after a small delay made LOW ( pulse)

The next function takes 2 variables y & x & moves the cursor to that location on LCD

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

void LCD_goto(unsigned char y, unsigned char x)

{

unsigned char firstAddress[] = {0x80,0xC0,0x94,0xD4};

LCD_send_command(firstAddress[y-1] + x-1);

_delay_ms(10);

}

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

 

 

Following is the Function to print String characters on LCD

We put a string in memory location & use it as a Pointer

While String is greater than 0 , all the characters represented or pointed by the string variable is sent to LCD for printing

 

void LCD_print(char *string)

{

while(*string > 0)

{

LCD_send_data(*string++);

}

}

 

In the LCD_blink() function we send command , a hex value 0x08 to make the display OFF & after a delay we send a command Hex 0x 0C to ON the display, thus generating a blink effect

 

void LCD_blink()

{

LCD_send_command(0x08);

_delay_ms(250);

LCD_send_command(0x0C);

_delay_ms(250);

}

 

To clear the display we send command Hex 0x01 as seen in the LCD_clear function below

 

void LCD_clear(void)

{

LCD_send_command(0x01);

_delay_ms(100);

}

 

Finally in the main Function we declare PORTD as Output , as well as PORTC as OUTPUT.

This is done by assigning 0x FF to CNTRL_DDR ( PORTD) & DATA_DDR (PORTB)

Then we clear the LCD , Initialize it & go to first position & print the String

 

int main(void)

{

CNTRL_DDR = 0xFF;

CNTRL_PORT = 0x00;

DATA_DDR = 0xFF;

DATA_PORT = 0x00;

 

LCD_clear();

LCD_init();

LCD_goto(1,2);

LCD_print(“ALSELECTRO.COM”);

LCD_goto(2,3);

LCD_print(“16×2 LCD DEMO”);

 

 

Complete code for 8bit LCD MODE is as below :

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

 

#include <avr/io.h>

#include <util/delay.h>

#define F_CPU 8000000UL // FCPU Definition for util/delay used in AVR STUDIO only

 

/*LCD function declarations */

void LCD_send_command(unsigned char cmnd);

void LCD_send_data(unsigned char data);

void LCD_init(void);

void LCD_goto(unsigned char y, unsigned char x);

void LCD_print(char *string);

void LCD_blink(void);

void LCD_clear(void);

 

#define DATA_PORT PORTB

#define DATA_DDR DDRB

#define CNTRL_PORT PORTD

#define CNTRL_DDR DDRD

#define RS_PIN 4

#define RW_PIN 5

#define ENABLE_PIN 6

 

int main(void)

{

CNTRL_DDR = 0xFF;

CNTRL_PORT = 0x00;

DATA_DDR = 0xFF;

DATA_PORT = 0x00;

 

LCD_clear();

LCD_init();

LCD_goto(1,2);

LCD_print(“ALSELECTRO.COM”);

LCD_goto(2,3);

LCD_print(“16×2 LCD DEMO”);

 

while(1)

{

}

}

 

/* This function sends a command ‘cmnd’ to the LCD module*/

void LCD_send_command(unsigned char cmnd)

{

DATA_PORT = cmnd;

CNTRL_PORT &= ~(1<< RW_PIN);

CNTRL_PORT &= ~(1<< RS_PIN);

 

CNTRL_PORT |= (1<< ENABLE_PIN);

_delay_us(2);

CNTRL_PORT &= ~(1<< ENABLE_PIN);

_delay_us(100);

}

 

/* This function sends the data ‘data’ to the LCD module*/

void LCD_send_data(unsigned char data)

{

DATA_PORT = data;

CNTRL_PORT &= ~(1<< RW_PIN);

CNTRL_PORT |= (1<< RS_PIN);

 

CNTRL_PORT |= (1<< ENABLE_PIN);

_delay_us(2);

CNTRL_PORT &= ~(1<< ENABLE_PIN);

_delay_us(100);

}

 

void LCD_init()

{

_delay_ms(10);

LCD_send_command(0x38);

LCD_send_command(0x0E);

LCD_send_command(0x01);

_delay_ms(10);

LCD_send_command(0x06);

}

 

/* This function moves the cursor the line y column x on the LCD module*/

 

void LCD_goto(unsigned char y, unsigned char x)

{

unsigned char firstAddress[] = {0x80,0xC0,0x94,0xD4};

LCD_send_command(firstAddress[y-1] + x-1);

_delay_ms(10);

}

void LCD_print(char *string)

//put a string in memory location & use it as POINTER

{

while(*string > 0)

{

LCD_send_data(*string++);

}

}

 

void LCD_blink()

{

LCD_send_command(0x08);

_delay_ms(250);

LCD_send_command(0x0C);

_delay_ms(250);

}

 

void LCD_clear(void)

{

LCD_send_command(0x01);

_delay_ms(100);

}

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

Download code from here

Save the file inside a folder with .C extension.

Now open the MFILE of WINAVR & set the MCU as ATMEGA16 , Port as usb , Programmer as usbasp.

To make programmer as usbasp , you need to enable editing & type in usbasp against Programmer.

If the C code is saved as main.c , then you need not change the Target in Makefile.

Save the Makefile inside the same folder where .c file exists.

Click on Tools à MakeALL to generate HEX file & then click on Program to upload the HEX file on to the ATMEGA16 chip.

To create a Header file , watch the following video :

 

cooltext753793315  cooltext753790696

This post is intended to assist you getting started with AVR DEVELOPMENT SELF LEARNING KIT.

It supports 40 pin AVR ICs like ATMEGA 16 /32 & a ZIF socket is provided to host the chip.All PORT pins are extended with berg pins for easy connections with peripherals.

For Analog input testing 2 nos variable pot are provided & for testing Digital inputs 4 nos switches are provided.A 4×4 keypad matrix is on board.

4 NOS 7 SEGMENT DISPLAY with driver circuit is provided.Other features include , EEPROM 24C16 , RTC  DS1307, UART MAX232 , MOTOR DRIVER ULN2003. An LCD can be plugged with the port provided.

An ISP connector accepts USBASP programmer through a 10 pin FRC Header.

 

board2

 

Download sample code ,WINAVR , USBASP DRIVER, AVRPAL.NET from HERE

Watch this video for details of installing USBASP driver & getting started with AVR Kit.

 

Connect the USBASP AVRDUDE with ISP connector & USB cable to your port on PC.Power up the kit with the 12v/1A adapter provided.Once the driver is installed , under Device manager USBASP appears

Image 1

 

WINAVR is used to develop C code & upload HEX file on to the Target chip.WINAVR has a PROGRAMMERS NOTEPAD which is the IDE we use to develop code.

MFILE in WINAVR helps us to create the rules for making.This MAKE FILE must be saved within the same folder where you saved the C file.Compared to ATMEL STUDIO ( a HUGE Download) WINAVR is small & powerful.

Image 2

 

To start with create an empty Folder , say LED ,inside your drive.Here is where we’ll be saving all our files.

Open PROGRAMMERS NOTEPAD & type in the following C code.

Save the file as LED.c inside the folder we created earlier.

Do not forget the .C Extension.

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

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
DDRC = 0xFF; //Makes PORTC  as Output

while(1) //infinite loop
{
PORTC = 0b00000001 ; // LED ON at PC0
_delay_ms(100); // delay

PORTC = 0b00000000 ; // LED OFF at PC0
_delay_ms(100); // delay

}
}

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

The code starts with PREPROCESSOR Directives

# include <avr/io.h>     defines all PORT names & pins of AVR

# include <util/delay.h>   defines the delay timing

Then starts the MAIN function under which we first declare PORTC pis as all OUTPUT.

Notre that in AVR we use 1  to declare OUTPUT & a 0 to declare as INPUT (REVERSE TO PIC programming)

I/O Pins of AVR has 2 to 3 functions & each PORT is associated with 3 REGISTERS

For e.g PORTC is associated with 3 registers

DDRC —>  DATA DIRECTION REGISTER  Configures   Port as INPUT (0) or OUTPUT  (1)

PORTC —> Write Data to PORT Pins

PINC   —> READ DATA from PORT Pins

 

Next is the indefinite loop while(1)

Inside which we make PORTC bit 0 as HIGH & all other pins LOW.

This is achieved by Binary notation

PORTC = 0b00000001 ;

After a delay

  _delay_ms(100);

we make PORTC bit 0 as LOW

PORTC = 0b00000000 ;

Now we need to create the RULES for Making which is done through MFILE of WINAVR

Open MFILE.Click on MakeFile

Select MCUtYPE as ATmega16

Port as usb

Programmer as usbasp.

 

Image 5

 

Under Progammer usbasp  is not listed. Select any other type like STK500 & then click on Enable Editing.

Now you’re allowed to make changes.Type in usbasp against Programmer.

Image 9

Scroll up to locate TARGET=main

Change this main to your C file name without any .c extension

Image 6

Save the Makefile inside the same folder where your C code is stored.

Image 7

Now click on MAKE ALL to generate HEX file.

Tools –> Program to load the HEX file automatically on to the target chip.

Image 4

Now let us see how to use the BITWISE OPERATORS in C code

To improve code clarity & to leave generation of  1s & 0s to the compiler we use SHIFT OPERATORS.

For e.g  instead of writing 0b0010 0000

we can write    0b0000 0001 <<5

or simply         1<<5     This is left shift operation.

0B0001 0000 << 3   will result 0B1000 0000    SHIFTING LEFT 3 TIMES

To generate  0B1110 1111    SHIFT FIRST & THEN INVERT IT

~(1<<5)

 

SETTING A BIT

To set an individual BIT we use the OR OPERATOR  |

e.g   DDRD = 0b0000 0001    To SET bit 4

SHIFT it 4 times to get 0b0001 0000

OR this result with DDRD Register

DDRD = DDRD | (0b00000001 <<4);

DDRD = DDRD | (1<<4); 

or you  can write simply   DDRD |= (1<<4);

Only BIT 4 is SET & other bits not affected.

You can also define a constant & use it

# define LED 4

DDRD |= (1<<LED);

 

CLEAR A BIT

e.g  DDRD = 0b0101 0101;

To clear the bit 2 (shown in bold letter above)

start with binary no.    0b0000 0001

Left SHIT 2 TIMES  to get  0b0000 0100

Invert this to get    0b1111 1011

use the & OPERATOR with DDRD Register

 

#define switch 2

DDRD &= ~ (1<< SWITCH);

 

CHECKING A BIT WHETHER 1 OR 0

To check status of 4th bit of PIND Register

Notice the use of PIN Register here

#define switch 4

status = (PIND & (1<< SWITCH) !=0);

 

 

TOGGLING A BIT

To toggle 4th bit of PORT D

PORTD = 0B0000 0000

START with 0b0000 0001   shift by 4 times to get

0b0001 000

X OR with PORTD

#define LED 4

PORTD ^= (1<< LED);

Every time this statement is executed the LED changes state

 

Following is the code with BITWISE operators implemented.

We use OR EQUAL LEFT SHIFT to declare portC as output

Inside while loop PORTC BIT 0 is made ON & then OFF after a delay , which is repeated for ever.

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

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
DDRC |= (1 << PC0); //Makes PORTC PC0 Pin22 as Output

while(1) //infinite loop
{
PORTC |= (1 << PC0); //Turns ON LED at PC0 or PORTC=0b00000001
_delay_ms(100); // delay

PORTC &= ~(1 << PC0); //Turns OFF LED or PORTC=0b00000000
_delay_ms(100); // delay
}
}

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

 

cooltext753793315    cooltext753790696

Arduino ProMini , as the name indicates , is a miniature version of UNO .It runs on 16 MHz crystal ,ATMEGA328 ,but lacks USB connectivity. There are 5V  (16MHz) & 3.3V (8MHz) versions. In this demo I use the 5v version.

 

ArduinoProMini000b

 

There is a voltage regulator on board so it can accept voltage up to 12VDC. If you’re supplying unregulated power to the board, be sure to connect to the RAW pin and not VCC.

Vcc accepts only 5v.

The latest version of this board breaks out the ADC6 and ADC7 pins ,also adds footprints for optional I2C pull-up resistors.

To upload code on to pro mini , a USB-TTL adapter is required.There are many types of  USB adapters available.The most reliable one that works up to Windows 10  is the one built on CP2102 IC .

CP2102 adapters are available in 2 variants .One with 6 pins that include the DTR  , Data Terminal Ready , which handles the RESET required by the promini board.

The other board is commonly available one with 5 pins.Here RESET must be done manually on promini while code is uploaded.

 

CP12

 

CP13

 

First let us upload code using the 6 pin version .

The connections are

PROMINI                USB-TTL

DTR   —–>   DTR

TxO   —–>  Rx

RxI    ——> Tx

Vcc   ——> 5v

GND  ——> GND

In some Promini boards the DTR pin is printed as GRN.

pro1

Plug in the USB board to PC & open the Device Manager . If the driver is installed previously , a COM port will be allotted.Otherwise , download the silicon labs cp2102 driver from here & install.

 

Image 1

Open the Arduino IDE , feed in the COM port allotted.

Select Board as Arduino Pro or Pro Mini , Programmer as USBasp.

In newer versions of IDE there is option to select type of ProMini board.Under Processor select ATmega328 5v,16MHz

Image 2

From Examples open the BL;INK sketch

Image 3

Click on UPLOAD button.

The DTR pin of USB board takes care of the RESET  & your code will be uploaded to PROMINI without any manual reset.

 

Image 4

Uploading code using a 5 pin version , needs a manual RESET on PROMINI.

The connections are

PROMINI                USB-TTL

TxO   —–>  RxD

RxI    ——> TxD

Vcc   ——> 5v

GND  ——> GND

 

IMG_20170512_165334

Plug in the USB to PC & note the COM Port allotted.

Open Arduino IDE .Feed in the COM port , select board as Arduino Pro or Promini & Programmer as USBASP

From Examples , open the BLINK Sketch

Image 2.1

Click on UPLOAD button.

Image 2.6

Watch out for the message at the bottom of IDE.

“ Compiling Sketch “ message appears first.

Then it changes to “Uploading”

Image 2.2

As  soon as you see “Uploading” message , gently press the RESET Key on Promini.

This should be done instantly , as soon as you see “UPLOADING” message.

Image 2.3

 

IMG_20170512_164431

If the KEY Press is at the right time , your code will be uploaded successfully.

Image2.4

 

You can also use your UNO board to upload code on Promini.

To use the UNO board , you need to by pass the bootloader .For this  upload an empty code to UNO or connect the RST pin to GND

Connecting RST pin to GND bypasses the bootloader & only the serial converter IC located near the USB socket is used as USB-TTL.

The connection here is STRAIGHT & not reverse

Tx of Arduino UNO goes to Tx of Promini

Rx of UNO goes to Rx of Promini

Gnd to Gnd

c12

 

Connect the USB cable to PC & open the IDE.

Select the port where UNO is connected.

Image 2.5

 

Select the board as Arduino Pro or ProMini

Image 3.1

Open the BLINK sketch & UPLOAD.

Watch out the message at the bottom of IDE.

Initially “Compiling Sketch “ appears.

Then the message changes to UPLOADING…

 

Image 6

Once you see UPLOADING… message  , press the RESET key on PROMINI.

 

IMG_20170512_171519

 

The code is now Uploaded successfully.

Image 7

Support VIDEO :

cooltext753793315   cooltext753790696

In the previous post we’ve seen how to connect the Arduino ETHERNET SHIELD to a Router directly  & upload LM35 data to Thingspeak.

What if  you do not have physical access to your Router & your Laptop is connected over WIFI to the Router. Or you cannot run a RJ45 cable from Router to Ethernet shield.

The procedure we follow is similar to the one we did for connecting Raspberry PI to Laptop.

Link here

First step is to enable SHARING of your existing internet.In my case , Laptop is connected to Router

over WIFI.

Open Control Panel –> Network & Internet –> Network & Sharing Center

Click on the existing internet connection

Image 1

On the next screen click PROPERTIES &  then SHARING

Image 2

Tick mark to ENABLE SHARING of Internet connection

Image 3

 

Now plug in the USB cable to Arduino & then connect the RJ45 Straight cable from shield to the RJ45

Port of LAPTOP.

ETH_SETUP

As soon as you connect the RJ45 cable you can see an UNIDENTIFIED NETWORK

 

Image 4

 

Click on that new Network , select PROPERTIES.

On the next screen double click on Internet Protocol version 4 (TCP/IPV4)

Image 5

You can see an IP address like 192.168.137.1.

Note that this is the new Gateway IP of the new network formed by Ethernet shield.If you do not see any IP , just select the “ Use the following IP “ &  feed in manually the IP.

 

Image 6

Now RUN  –> CMD  > IPCONFIG /ALL

to verify the IP.

Under Ethernet adapter the Gateway IP of new network is displayed.

Note that this is the GATEWAY IP & Ethernet shield will be allotted IP in this range  .

 

Image 7

Let us try some built in example codes.

Under Examples  –> Ethernet –> select  DhcpAddressPrinter

This will print the IP allotted to the Shield.

Image8

Upload the code & open up the Serial monitor.

The IP allotted to the shield here is 192.168.137.30  which is in range of new Gateway .

Image 9

 

Next example is WEBSERVER

Image 10

 

Open the WEBSERVER code .

You need to change the IP Address as 192.168.137.xxx

 

Image11

 

Here change it to 192.168.137.177 where the SERVER will be started. Note the usage of comma instead of dot between each byte.

Image 12

 

Upload the code & open the serial monitor to verify that SERVER is started.

Image 13

You can use your Browser as CLIENT.

Type in the IP 192.168.137.177 to access the server.

On the Serial monitor “Client connected “ information will apper.

Image 14

On the browser you can see the values of ANALOG Pins of Arduino.

As nothing is connected to the Analog pins , you get random values.

Image 17

 

Next example is the TELNETCLIENT

Image 2

 

Open the code.

Here Ethernet shield is used  as CLIENT & you need to change the IP of client in range with the new Gateway  192.168.137.177

Next is the IP of the SERVER . This may be another PC or Android phone connected to the same Network .

Here the SERVER is started on PC with IP 192.168.0.103

Note that this IP is in the range of Gateway of Router 192.168.0.xxx

Image 3

Scroll down further & note the PORT number on which the SERVER will LISTEN.

Here it is 10002.

Upload the code on to Arduino.

Image 4

To test the setup , you need to start a SERVER on another PC on the same network with IP 192.168.0.103

For this we use HERCULES software. DOWNLOAD HERE

Click on TCP Server tab on Hercules , feed in the port number 10002 & click LISTEN.

The server is started on PC with IP 192.168.0.103 , so , no need to enter the IP

Image 5

Now open the Serial Monitor of Arduino where SHIELD is declared as CLIENT.

You can see the “Connected..”  feed back from the Server.

Type in some characters on Arduino side , as well as Hercules side to verify 2 way communication.

Image 6

Instead of PC & HERCULES you can use your Android mobile ( to be connected over WIFI to the same Network).

On your mobile install TCP TOOLS

mobile1

Open TCP SERVER

The IP of Android device is shown with default port 8080.Click on LISTEN

In the TELNET CLIENT code you need to change the SERVER IP t from 1,1,1,1

to  192.168.0.102 & then change the port of server to 8080 & then upload to Arduino

 

mobile 2

Once code is uploaded open the Serial monitor.

On mobile you see the IP of CLIENT connected

mobile3

Test 2 way communication by typing in characters.

mobile4

 

mobile5

 

Next we shall test the code which sends LM35 Data to THINGSPEAK SERVER.

You can check my previous post for details

Upload the same code without any change in IP.

IT WORKS FOR BOTH RANGE OF ipS 192.168.0.xxx    &   192.168.137.xxx

Image 7

Open the Serial Monitor to see the data being uploaded to THINGSPEAK.

Image 8

WATCH THIS VIDEO  :

cooltext753793315   cooltext753790696

Ethernet shield acts as wired Gateway between your Arduino & Internet.

This post demonstrates how to upload  temperature data from LM35 sensor to the server on THINGSPEAK.Before starting you should know how to connect the shield to Network.

There are 2 options by which your shield is connected to the Network.

First is the direct connection to your Router .You’ve an available RJ-45 port on your Router & you directly use a straight RJ45 cable to plug Ethernet shield to Router .Your PC/Laptop is also connected to the same Router either by wire or through WIfi (if your Router is WIFI capable).

Second is the indirect connection.Your shield is connected to your Laptop’s RJ45 with wire.Your Laptop is connected to Router through WIFI.In this case you need to bridge the connections or use the shield as unidentified second network with a different IP.

In this post we use the first Direct connection to Router method.

Check this connection image where my Ethernet shield is connected directly to  Router.My PC is also connected to the same Router by WIFI . Router is provided Internet access by the Internet Service Provider ACT.

 

eth_connect1

 

eth2

 

To start with let us fix the IP of Ethernet shield STATIC , so that it is always the same on every boot up of Router.

From your PC  RUN –> CMD

Type in  ipconfig /all

The Default Gateway here is 192.168.0.1 which is the IP of the Router.

All clients connected to this Router will be assigned IP in this range 192.168.0.xxx  where the last byte is from 2 to 255 (allotted on first come basis)

Image 1

In the above screenshot you can see (ipV4 address), my PC is assigned IP 192.168.0.101.

IP is assigned automatically by Router , only when the DHCP is enabled in Router setting.

Type in your browser 192.168.0.1 , the gateway IP & feed in your Router’s username & password  (generally both are “admin”)

Under DHCP settings ensure that DHCP is Enabled.

Image 2

 

Now click on the DHCP CLIENT LIST to know the devices connected to the Router.

In my case 2 devices connected.One is my PC which is allotted IP 192.168.0.101

& the second device is Ethernet shield which is allotted 192.160.0.100.

But in our code we use IP 192.168.0.150 .

Let us change the IP to 192.168.0.150 & make it STATIC.

ip_allot1

Click on  ADDRESS RESERVATION  under DHCP

& then click ADD NEW

dhcp_res1

 

Feed in the MAC address of the Ethernet shield & the reserved IP as 192.168.0.150

The MAC address is the one you used in the code.This may be random unless you use more than one shield in the same network.

ADDNEW

Click on SAVE & then REBOOT your Router to enable the changes made.

dhcp_res2

Now under DHCP Client list you can see your shield allotted 192.168.0.150 & permanent (means STATIC IP)

dhcdp_res3

 

lm35

Connect the 1st pin of LM35 to 5v of Ethernet shield , 3rd pin to GND. 2nd pin is connected to A0

Analog pin.

Connect the USB cable from ARDUINO to PC & note the PORT allotted.The RJ45 STRAIGHT CABLE is connected from Ethernet shield to Router directly.

Upload the following code on to Arduino.You need not change the MAC address.

You need to change the Gateway IP as per your Router & also change the IP of shield in this range.

Also you need to change the THINGSPEAK API according to your CHANNEL setting

Download Arduino CODE Here

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

#include <SPI.h>
#include <Ethernet.h>

int pin = 0; // analog pin
int tempc = 0,tempf=0; // temperature variables
int samples[8]; // variables to make a better precision
int maxi = -100,mini = 100; // to start max/min temperature
int i;

// Local Network Settings
byte mac[]     = { 0xD4, 0xA8, 0xE2, 0xFE, 0xA0, 0xA1 }; // Must be unique on local network
byte ip[]      = { 192,168,0,150 };                // Must be unique on local network
byte gateway[] = { 192,168,0,1};
byte subnet[]  = { 255, 255, 255, 0 };

// ThingSpeak Settings
char thingSpeakAddress[] = “api.thingspeak.com”;
String writeAPIKey = “QGBA1G3872XSHBAC”;    // Write API Key for a ThingSpeak Channel
const int updateInterval = 10000;        // Time interval in milliseconds to update ThingSpeak

// Variable Setup
long lastConnectionTime = 0;
boolean lastConnected = false;
int failedCounter = 0;

// Initialize Arduino Ethernet Client
EthernetClient client;

void setup()
{

Serial.begin(9600);
Ethernet.begin(mac, ip, gateway, subnet);
delay(1000);
Serial.print(“ETHERNET SHIELD ip  is     : “);
Serial.println(Ethernet.localIP());
// Start Ethernet on Arduino
startEthernet();
}

void loop()
{

tempc = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;

String analogPin0 = String(tempc);

// Print Update Response to Serial Monitor
if (client.available())
{
char c = client.read();
Serial.print(c);
}

// Disconnect from ThingSpeak
if (!client.connected() && lastConnected)
{
Serial.println();
Serial.println(“…disconnected.”);
Serial.println();

client.stop();
}

// Update ThingSpeak
if(!client.connected() && (millis() – lastConnectionTime > updateInterval))
{
updateThingSpeak(“field1=”+analogPin0);
}

lastConnected = client.connected();
}

void updateThingSpeak(String tsData)
{
if (client.connect(thingSpeakAddress, 80))
{
client.print(“POST /update HTTP/1.1\n”);
client.print(“Host: api.thingspeak.com\n”);
client.print(“Connection: close\n”);
client.print(“X-THINGSPEAKAPIKEY: “+writeAPIKey+”\n”);
client.print(“Content-Type: application/x-www-form-urlencoded\n”);
client.print(“Content-Length: “);
client.print(tsData.length());
client.print(“\n\n”);

client.print(tsData);

lastConnectionTime = millis();

if (client.connected())
{
Serial.println(“Connecting to ThingSpeak…”);
Serial.println();

failedCounter = 0;
}
else
{
failedCounter++;

Serial.println(“Connection to ThingSpeak failed (“+String(failedCounter, DEC)+”)”);
Serial.println();
}

}
else
{
failedCounter++;

Serial.println(“Connection to ThingSpeak Failed (“+String(failedCounter, DEC)+”)”);
Serial.println();

lastConnectionTime = millis();
}
}

void startEthernet()
{

client.stop();

Serial.println(“Connecting Arduino to network…”);
Serial.println();

delay(1000);

// Connect to network amd obtain an IP address using DHCP
if (Ethernet.begin(mac) == 0)
{
Serial.println(“DHCP Failed, reset Arduino to try again”);
Serial.println();
}
else {
Serial.println(“Arduino connected to network using DHCP”);
Serial.println();
Serial.println(“Data being uploaded to THINGSPEAK Server…….”);
Serial.println();
}

delay(1000);
}

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

ip_allot

 

You need to sign up with www.thingspeak.com  to upload your data to the server.

Open your account on THINGSPEAK & select MYCHANNELS under CHANNELS

thing2

Click on NEW CHANNEL

thing3

Feed in Name & Description of your channel & under FIELD1 enter name of field like TEMPERATURE

Scroll down & Enable PUBLIC VIEW.

thing4

Save the CHANNEL & then click on API KEY tag

thing5

Note down the WRITE API KEY

thing6

Replace this code with yours inside the Arduino code.

thing7

Upload the code.

Please ensure that you’ve changed following settings in your code before uploading:

1. Gate way IP of your Router.

2. IP address of your Shield in range with gateway IP.

3. Thingspeak  API WRITE KEY from your Channel

upload

Once uploaded you can open the Serial Monitor of Arduino , to see data being uploaded to the Server

eth_connected1

On your THINGSPEAK Channel click on Public View to see the Graphical representation of the LM35 data being uploaded.

thing1

If you get Arduino Failed to connect to Network,  then you need to check the IP address credentials again.

 

HTTP POST Method to write data on to server

 

In the Arduino code data is converted to STRING type & uploaded to Thingspeak. Thingspeak server accepts only String type data.,

The HTTPS method used in code is POST method .Other HTTPS methods are  GET ( to read data), PUT ( to update data), DELETE ( to delete data).

Understand the basics of this method which we will be using in upcoming posts of ESP8266 & other IOT related projects.

We use POST to submit data to THINGSPEAK Server.

POST request is a bunch of STRINGs.

Each request line is separated & ends with a newline.

——————————–

client.print(“POST /update HTTP/1.1\n”);
client.print(“Host: api.thingspeak.com\n”);
client.print(“Connection: close\n”);
client.print(“X-THINGSPEAKAPIKEY: “+writeAPIKey+”\n”);
client.print(“Content-Type: application/x-www-form-urlencoded\n”);
client.print(“Content-Length: “);
client.print(tsData.length());
client.print(“\n\n”);

——————————

The first string is the Message STARTLINE which has 3 elements separated by SPACE

POST /update HTTP/1.1\n

First element is the URI –Uniform Resource Identifier ( not URL) which is nothing but the method POST all in capital letters. Next element is the protocol /update & the 3rd element is the version  HTTP/1.1 . At the end  \n is used for new line , or you can use println instead of print.

Once we send the message start line string, then we need to  send different header fields. The HEADSER FIELDS are  predefined fields that give the Thingspeak server , information about our POST request. Apart from standard fields , there’s some non-standard fields.

If it’s a non-standard field, the header name is usually preceded by an x. Each header field that we send is going to be its own string, separated by a newline.

We’re going to send following different Headers :

1.Host header field,

2.Connection header field,

3.The x ThingSpeak API key header field,

4.Content type header field,

5.  Content length header field.

1} For ThingSpeak, the host is going to be —–>   api.thingspeak.com.

2) For the connection header, we specify close, and that’s because after we make our request and after we get our response, we want to close the connection with the server. There’s no need to keep that connection open between sending information, so we close it.

3) The X-ThingSpeak API key header is a non-standard header, and that is going to be set to our Write API key that we can find out  from our ThingSpeak channel.

4) The content type header is going to indicate the kind of media that we planned on sending in the header body, In HTTP there are two ways to POST data:

application/x-www-form-urlencoded

and

multipart/form-data.

We use the first one as we update string data.

For application/x-www-form-urlencoded, the body of the HTTP message sent to the server is essentially one  query string — name/value pairs are separated by the ampersand (&), and names are separated from values by the equals symbol (=).

5) The content length header specifies the size of the media that we’re going to be sending in bytes.

 

Once we’ve set the header fields, the last thing we do is send the message body.

The message body is the actual data that we want to update & post to the server. Just like the message start line, and just like the header fields, the message body is going to be a string of text. The message body is  separated from the header fields by two newlines.

client.print(tsData.length());
client.print(“\n\n”);     // 2 new lines

client.print(tsData);

Those two newlines are what let the server know that  we’re done with the header fields & we’re moving on to the message body.

Our message body is simply listing the field that we want to update with an equals sign followed by the value that we want to update it as.

updateThingSpeak(“field1=”+analogPin0);

If we want to do multiple fields, we separate them with the “and” sign. There’s no spaces in this message body

We’ve got the message start line. We’re identifying the method, the URI, the resource we want to use, and the protocol type. Then we specify the header fields. This is giving information to the server about the request that we’re making.

Finally, we have the actual message that we’re sending.

That makes up a basic HTTP POST  request

VIDEO TUTORIAL :

 

cooltext753793315   cooltext753790696

 

 

pic2    pic3

 

PICKIT3  seems to be a DEGRADED version of PICKIT2 . PIC may be a Microcontroller Giant , but a newer version of Toolkit should be more user friendly than the previous versions.In case of PIC the design Team has never bothered this.

Following are the Changes made in PICKIT3 , which many have criticized  :

1. The little useful standalone program  PICKIT2 to fuse HEX files is scrapped now.There is no standalone program to fuse HEX files.Now you need to install MPLAB IPE along with MPLAB X IDE & use that for fusing target IC with HEX file.

2. PROGRAMMER TO GO function of PICKIT2 is scrapped in PICKIT3.

This function allows a PIC MCU memory image to be downloaded into the PICKIT 2 unit for later programming into a specific PIC MCU. No software or PC is required to program devices once the PICkit 2 unit is set up for Programming-To-Go

3. TARGET is not powered automatically in PICKIT3. In PICKIT2 Automatic Power feature is enabled by default.In case of PICKIT3 you need to CONFIGURE manually , else you get TARGET NOT FOUND error.

4.PICKIT3 does not detect DEVICE automatically.You need to select the device from drop down list.

5.PICKIT3 uses PIC24 series MCU , while PICKIT2 was designed on PIC18 series.But PICKIT2 seems to be faster than PICKIT3.

6.If you change the target IC , Firmware upgrade happens every time in PICKIT3 , an annoying feature.   

As MICROCHIP has stopped production & support to PICKIT2 we’ve to live with PICKIT3.Let us now see the solutions for common problems faced in using this “ADVANCED Device”.

You can fuse the HEX file from within MPLAB X IDE or through MPLAB IPE..

MPLAB X IDE Method :

From within MPLAB IDE click the Icon with down Arrow image “Make & Program Device Main Project”.

The project is now BUILD.

Once you get BUILD SUCCESSFUL in the OUTPUT Window , the IDE will try to connect with PICKIT3 Programmer

 

mp1

 

But you get TARGET NOT FOUND error.

 

mp2

Click on RUN –>set project configuration –>CUSTOMIZE

 

mp4

On the new window select PICKIT3

MP5

Under OPTIONS CATGEGORIES drop down select POWER

 

mp6

Tick mark “Power Target circuit from Pickit3”

& select voltage level as 5.0

 

mp7

Click OK & then click on the  “Make & Program Device Main Project” again

Now the target is detected & HEX file fused on to target.

mp9

Method 2 : Through MPLAB IPE

From MPLAB IDE click RUN –> BUILD MAIN PROJECT  to create the HEX file.

MP10

The HEX file is created inside the PROJECT File –> dist –> default –> production

Note the location of HEX file.

Image 6

Now open MPLAB IPE the Integrated Programming Environment

 

Image 17

Select the IC , here PIC16F877A , Apply & then click on CONNECT

Image 7

 

You get Target Not found ERROR.

Image 8

Click  SETTINGS –> ADVANCED MODE

Image 9

 

To enter Advanced mode you need to type in the password –     microchip

Image 1

Now a new set of buttons appear on left side.

Click on POWER button

Image 11

Select Vdd as 5.0 & then tick mark “POWER TARGET CIRCUIT FROM TOOL”

Image 12

Now click on OPERTATE button

Image 13

The target is found & connected now.

Click the browse button & navigate to select the HEX file stored.

Image 14

Click PROGRAM button to fuse the target chip with selected HEX file.

Image 15

 

Image 16

 

cooltext753793315   cooltext753790696

Generally Raspberry PI is connected to a Router as an individual computer.In case you do not have access to your Router you can very well connect PI to Laptop through an ETHERNET STRAIGHT Cable.

The available RJ45 cable in the market is mostly STRAIGHT cable & not CROSS OVER one.

Before connecting the PI to Laptop , open your Network & sharing center & click on your Internet connection.Mine is on Wireless Network

 

Image 4

On the next screen click on the  properties button.

 

Image 5

Under SHARING tab Tick mark “Allow other network users…..”

Click OK to enable Network SHARING.

Image 6

Now let us enable SECURED SHELL – SSH on Raspberry PI OS , so that it can be accessed over network.

This can be done by connecting RPI to a HDMI TV & a keyboard.

Under terminal open RASPI-CONFIG & enable SSH under Advanced options.

But in this post I consider a Headless mode , presuming that you do not have access to a TV or keyboard.You need a CARD READER for this purpose.

Place the SD card with Raspbian OS on to the card reader & plug it to ypur laptop.

Note down the Drive letter allotted.Here it is I:\  in my case

 

Image 1

Run CMD & type in following

echo >I:\ssh

Now a file named ssh without any extension is created under \boot.

Image 2

 

Image 3

While PI is booted up then , it looks out for the file named ssh.

If it finds one , it enables SSH & then deletes the file you created.

This is how SSH is enabled in the new Raspbian OS.By default SSH is disabled in new OS for security reasons.

Plug the SD card on to PI & connect the ETHERNET cable to Laptop’s RJ45 slot.

Power up the PI to see a new Unidentified network .

Image 7

Click on that new Local Area Connection that appears & then click properties.

On the next screen , double click on Internet Protocol Version 4(TCP/IPv4)

 

Image 8

Now you see the IP address of the new Network created.

Here it is 192.168.137.1 which is the GATEWAY IP of the new Network.

PI will be allotted IP within this range 192.168.137.xxx

Image 10

To know the IP of RPI we make use of ADVANCED IP SCANNER

Download from here & install the scanner

http://filehippo.com/download_advanced_ip_scanner/download/a518016bdff73f05b5f25826e519a493/

Open the IP Scanner program & type in the Range to scan as 192.168.137.1 to 192.168.137.254

Image 11

Click on the scan button.

The IP scanner will detect the Raspberry PI & displays its IP along with host name & MAC address.

The host name is

raspberrypi.mshome.net   & the IP is

192.168.137.240

Image 12

You can use either the host name or the IP to access the PI.

We make use of an X Forwarding software called MOBAXTERM for a Graphical Interface.

You can use XMING server , but a separate SSH client like PUTTY is needed for that.

MOBAXTERM is a standalone freeware with an inbuilt SSH Client.

http://mobaxterm.mobatek.net/download-home-edition.html

Download the X Server

Image 13

Fire up the MobaXterm_Personal application.

Image 14

Click on SESSION & then SSH

Image 15

 

Under Remote Host type in the host name of RPI   raspberrypi.mshome.net

 

hostname

or you can use the IP address of PI we obtained from IP Scanner earlier.

Image 16

Now you get the login window.

Login username is pi & password is raspberry

Image 17

 

Now you are logged into Raspberry PI & you get the ~$ prompt

Image 18

 

To open Graphical interface , type in

startlxde

 

Image 19

 

You get a warning message SSH is ON .

Image 20

Click OK to see the DEBIAN SWIRL desktop.

 

Image 21

 

Image 22

 

Image 24

 

Image25

 

To enable WIFI & internet access , watch this video :

 

 

cooltext753793315  cooltext753790696

 

 

 

 

 

 

 

 

 

 

Image 13