• 1

    ..

  • 2

    ...

  • 3

    ...

Showing posts with label avr atmega16. Show all posts
Showing posts with label avr atmega16. Show all posts

Saturday, 26 April 2014

LCD 4 BIT INTERFACING WITH AVR MICROCONTROLLERS ATMEGA8,16,32,64

LCD 4 BIT INTERFACING WITH AVR MICROCONTROLLERS ATMEGA8,16,32,64

   This is the header file for LCD 4-bit mode interfacing with AVR Microcontroller series such as Atmega 16, 32, 64, 8, etc. It is coded in GCC & supports all AVR GCC compliers.

   This is designed for 16×2 LCD, but can be exteneded upto 20×4 LCD.
   Contains all functions with different cursor styles, string display from ram & flash rom, bcd, signed & unsigned  integer 8-bit and 16-bit numbers, shift left, shift right, etc.

Monday, 7 April 2014

SY-HS 220 Humidity Sensor Interfacing with AVR Atmega (8/16/32)

SY HS220 is the Relative Humidity Sensor with near linear output reference to relative humidity.
Its opereating RH percentage is 30-90% with Output Voltage range 990-2970mV.

Here we've interfaced SY HS220 with AVR ATMEGA8 microcontroller and display %RH in LCD.

Circuit Diagram:

undefined
ElecDude: HS220 AVR Circuit
Code:
/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Author: ElecDude
         admin@elecdude.com      

Copyright - 2014 - ElecDude

DISCLAIMER:

 THIS SOURCE FILE MAY BE USED AND DISTRIBUTED WITHOUT      
 RESTRICTION PROVIDED THAT THIS COPYRIGHT STATEMENT IS NOT 
 REMOVED FROM THE FILE AND THAT ANY DERIVATIVE WORK CONTAINS
 THE ORIGINAL COPYRIGHT NOTICE AND THE ASSOCIATED DISCLAIMER.

 This is provided without any  express or implied warranties,
 including, but not limited  to, the implied warranties of merchantability
 and fitnessfor a particular purpose. FOR EDUCATIONAL PURPOSE ONLY.

~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
                          SY-HS 220 Humidity Sensor
     Input voltage = 5.0V                    Operating Temperature = 0-60'C
    Operating Humidity = 30-90% RH        Output Voltage = 990-2970mV
    Std.output = 1.98V   at 25`C 60%RH    Accuracy = +/-5%RH  at 25'C & 60%RH

Normal Values
%RH   mV
 30      990
 40     1300
 50     1650
 60     1980
 70     2310
 80     2640
 90     2970

    V-RH RATIO = 0.30301    by linear slope
    %RH = RATIO * Vout

ADC    Vadc = Vref * adcval/1024

If Vref= Vcc= 4.96, then
    %RH= Vout * 0.30301
       = Vref * adcval/1024 * 0.30301
    %RH= 0.0001467 * adcval
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~*/


#define F_CPU 1000000UL
/*****************MACRO's DEFINITION*********************************/
#ifndef BIT
#define BIT(x)    _BV(x)
#endif
#ifndef SETBIT
#define SETBIT(x,b)     x|=_BV(b);
#endif
#ifndef CLEARBIT
#define CLEARBIT(x,b)     x&=~_BV(b);
#endif
#ifndef TOGGLEBIT
#define TOGGLEBIT(x,b)     x^=_BV(b);
#endif
#ifndef CHECKBIT
#define CHECKBIT(x,b)     (x & _BV(b))
#endif

#include <avr/io.h>
#include <util/delay.h>
void WaitMs(unsigned int ms) // waits (pauses) for ms milliseconds
{
    unsigned int m;
    for(m=0;m<=ms/10;m++)
    {
        _delay_ms(10);
    }
}

#include "ADCHEAD.H"
#include "lcd.c"

#define PRT PIND
#define sw1 0
#define sw2 1
#define sw3 2
#define TIME 100
register unsigned char i asm("r17");

#define R 0.148
unsigned char count=0x00,chng=1;
unsigned int val,th;
char d2[]="00.0%";
void UpdateVal()
{
    float rh;
    uint16_t x;
    rh=R*val; //xx.y
    x=rh*10; //xxy
    d2[3]= (x%10) | 0x30;//ones
    x/=10;
    d2[1]= (x%10) | 0x30;//tens
    x/=10;
    d2[0]= (x%10) | 0x30;//hund
}

int main()
{
      CLEARBIT(DDRC,4)//set as i/p for adc
    CLEARBIT(DDRC,5)
    DDRD=0xF8;//enable PD as i/p & en pull ups
    PORTD=0x07;
    SETBIT(DDRB,7)
    SETBIT(PORTB,7)
   
    _delay_ms(10);
    LCD_init(COFF);
    _delay_ms(100);
    LCD_putsPXY(3,0,"Welcome to");
    LCD_putsPXY(4,1,"ElecDude");
    ADC_init();
   
    WaitMs(800);//wait for some time to initialise
    LCD_clear();
    SetCH(0x05); //PC5=HS220's Vout
    val=0;i=0;
    LCD_putsPXY(0,0,"Relativ Humidity");
    while(1)
        {
            TOGGLEBIT(PORTB,7)
            val+=ADC_readcurch();
            i++;       
            if(i==4)
             {
                val=val/4;
                UpdateVal();
                LCD_putsXY(5,1,d2);
                i=0; val=0; //clear after update
             }// endof if(i==4)
         WaitMs(200);
        }//end of while
return 0;
}

ADCHEAD.H

#define ADC_ENABLE()         SETBIT(ADCSRA,ADEN)        //Macro to enable ADC Module.
#define ADC_DISABLE()         ADCSRA &= 0x7F            //Macro to disable ADC MOdule.
#define ADC_START_CONV()     SETBIT(ADCSRA,ADSC)        //Macro to start ADC conversion.
//#define ADC_STOP_CONV()        CLEARBIT(ADCSRA,ADSC)    //Macro to stop ADC conversion.
#define ADC_CLEAR_ADIF()     CLEARBIT(ADCSRA,ADIF)        //Macro to clear ADC Interrupt flag.

#define VREF 4.96        //Defines the VREF used.
/*            Value in Volts = ADC Value * (VREF/1024)
            ADC resolution = 4.96/1024 = 4.84mV            */
/*************************************************************************************
                    ACD initialization routine
*/

void ADC_init(void)    //Function used to initialise the ADC Module.
{
    ADMUX = 0x45;         //Select the channel ADC5, AVcc, ADC right adjust, chn=0-5
    ADCSRA = 0x83;     // 

    _delay_ms(150);     //Provide adequate delay to initialise the analog circuitry.

}


#define ADC_read() ADC
/* To read & return adc value from a channel (chn=> 0 to 5)    */
#define SetCH(chn) ADMUX=(ADMUX & 0xF0) | (chn & 0x07)
                                        // 07- because Max 5 channels for ATM8
int ADC_readch(unsigned char chn)       
{
    ADMUX= (ADMUX & 0xF0) | (chn & 0x0F);
    ADC_CLEAR_ADIF(); //Clear ADC Interrupt Flag
    ADC_START_CONV(); //Start ADC Conversion.
    while(!(CHECKBIT(ADCSRA,ADIF)));//wait for conversion complete
    return(ADC_read());//----read values & return
}

/* TO READ FROM CURRENTLY SET CHANNEL IN ADCMUX.
    Note: This function doesn't change the ADC channel & uses the value set in ADCMUX
          So set the required channel before calling this function   */

int ADC_readcurch()       
{
    ADC_CLEAR_ADIF(); //Clear ADC Interrupt Flag
    ADC_START_CONV(); //Start ADC Conversion.
    while(!(CHECKBIT(ADCSRA,ADIF)));//wait for conversion complete
    return(ADC_read());//----read values & return
}

/***/


Output:

Tuesday, 25 February 2014

DS1307 RTC AVR atmega16 - Digital Clock

        Here is a simple digital watch which displays time, date & day in 16x2 lcd. DS1307 RTC is used for the time & date watch and AVR Atmega16 (8/32/64) is used as the display driver. It reads RTC time, date, day from ds1307 throught I2C bus and process it for displaying and displays it in the LCD.


Click here to view our DS1307 tutorial & header file for AVR GCC.
Circuit diagram  for DS1307 RTC Digital Watch with AVR is  as follows: 
 
Figure 1 - Circuit diagram
Connect a BUZZER  at pin PD6 if needed.
  
                To initialize DS1307 with the required time use this program first. It sets time as 12:45:32 & date as 24 Feb 14, Tuesday, by default. If you need to change, do it in BCD format.
 
/*************   WRITE TIME IN DS1307 ***********************/
#ifndef BIT
#define BIT(x)    _BV(x)
#endif

#ifndef SETBIT
#define SETBIT(x,b)     x|=_BV(b);
#endif

#ifndef CLEARBIT
#define CLEARBIT(x,b)   x&=~_BV(b);
#endif

#ifndef TOGGLEBIT
#define TOGGLEBIT(x,b) x^=_BV(b);
#endif

#ifndef CHECKBIT
#define CHECKBIT(x,b)   (x & _BV(b))
#endif

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

/* waits (pauses) for ms milliseconds */
void WaitMs(unsigned int ms)
{
      unsigned int m;

      for(m=0;m<=ms/10;m++)
      {
            _delay_ms(10);
      }
}
#define nop() asm __volatile__ ("nop\t\n")


#include "lcd.c"
#include "ds1307.h"

#define M(x) ( (x&0xF0)>>4 | 0x30 )
#define L(x) ( (x&0x0F) | 0x30 )

unsigned char h,m,s; //,pwrd=1;  //,aP;
#define ReadTime() DSReadTime(&h,&m,&s)
#define WriteTime() DSWriteTime(h,m,s)
unsigned char dd,mm,yy,dy;
#define ReadDate() DSReadDate(&dd,&mm,&yy)
#define WriteDate() DSWriteDate(dd,mm,yy)

                    //01 34 678
char T[9];  //="hh:mm:ss*";
char D[11]; //="dd/mm/yy";

#define disptim() LCD_putsXY(4,0,T)
#define dispd() LCD_putsXY(0,1,D)

void upt()
{
T[0]=M(h);
T[1]=L(h);
T[3]=M(m);
T[4]=L(m);
T[6]=M(s);
T[7]=L(s);
//if(aP)          LCD_putc('P');    else        LCD_putc('A');   
}

void upd()
{
D[0]=M(dd);
D[1]=L(dd);
D[3]=M(mm);
D[4]=L(mm);
 D[8]=M(yy);      D[9]=L(yy);
//if(aP)          LCD_putc('P');    else        LCD_putc('A');   
}


int main()
{
 D[2]='/';  D[5]='/'; D[6]='2'; D[7]='0';
 T[2]=':';  T[5]=':';
 DDRB=0x00;
 PORTB=0xFE;  // sw_init();
 LCD_init(COFF);
 LCD_clear();
 LCD_putsPXY(0,0,"WeLcOmE....");
 buzz(); buzz();

 DSinit();
#ifdef MODE_12HR
#else
 T[8]='\0';//24hour mode  default 24hour mode
#endif

 _delay_ms(50);

//for write time
WaitMs(900);
h=0x12; m=0x45; s=0x32; //time = 12:45:32
dd=0x24; mm=0x02; yy=0x14; dy=0x02;  //date is 24 feb 2014 Tuesday
WriteTime();
WriteDate();
DSWriteDay(dy);
WaitMs(900);

ReadTime();
ReadDate();
DSReadDay(&dy);
upt();upd();
disptim();
dispd();

while(1)
      {
            _delay_us(50);                     
            sleep_mode();    
            nop();
      }
 return 0;
}


THE PROGRAM FOR CLOCK IS AS FOLLOWS…….
                The DS1307 is initialized to produce 1Hz at SOUT pin (pin7). This pin is connected to INT0 of ATMEGA to generate an interrupt. The ISR is coded to read time, date, day from DS1307 & display it in LCD. After ISR execution, it enter the main while loop, which makes the CPU to enter Sleep mode. This is implemented to reduce power consumption.

/*********MACRO's DEFINITION**************/
#ifndef BIT
#define BIT(x)  _BV(x)
#endif

#ifndef SETBIT
#define SETBIT(x,b) x|=_BV(b);
#endif

#ifndef CLEARBIT
#define CLEARBIT(x,b)      x&=~_BV(b);
#endif

#ifndef TOGGLEBIT
#define TOGGLEBIT(x,b)     x^=_BV(b);
#endif

#ifndef CHECKBIT
#define CHECKBIT(x,b)      (x & _BV(b))
#endif
/*******************************************************************/

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

/* waits (pauses) for ms milliseconds */
void WaitMs(unsigned int ms)
{
     unsigned int m;

     for(m=0;m<=ms/10;m++)
     {
           _delay_ms(10);
     }
}
#define nop() asm __volatile__ ("nop\t\n")


#include "lcd.c"
#include "ds1307.h"

#define M(x) ( (x&0xF0)>>4 | 0x30 )
#define L(x) ( (x&0x0F) | 0x30 )

unsigned char h,m,s; //,pwrd=1;  //,aP;
#define ReadTime() DSReadTime(&h,&m,&s)
#define WriteTime() DSWriteTime(h,m,s)
unsigned char dd,mm,yy,dy;
#define ReadDate() DSReadDate(&dd,&mm,&yy)
#define WriteDate() DSWriteDate(dd,mm,yy)

                  //01 34 678
char T[9]; //="hh:mm:ss*";
char D[11];     //="dd/mm/yy";

#define disptim() LCD_putsXY(4,0,T)
#define dispd() LCD_putsXY(0,1,D)

void upt()
{
T[0]=M(h);
T[1]=L(h);
T[3]=M(m);
T[4]=L(m);
T[6]=M(s);
T[7]=L(s);
//if(aP)        LCD_putc('P');  else       LCD_putc('A'); 
}

void upd()
{
D[0]=M(dd);
D[1]=L(dd);
D[3]=M(mm);
D[4]=L(mm);    
 D[8]=M(yy);    D[9]=L(yy);
//if(aP)        LCD_putc('P');  else       LCD_putc('A'); 
}

void buzz()
{
     SETBIT(PORTD,6)
     _delay_ms(350);
     CLEARBIT(PORTD,6)
}

ISR(INT0_vect)
{//1 int0
     ReadTime();
     ReadDate();
     DSReadDay(&dy);
#ifdef MODE_12HR
//12hour mode
     if( (h&0x20)==0x20)
           { aP=1; T[8]='P';}
     else
           { aP=0; T[8]='A';}
     h=h&0x1F;
#else
  h=h&0x3F; //24hour mode  default 24hour mode
#endif

     upt();upd();
     disptim();
     dispd();
    
     LCD_puts("  ");
     dy=dy & 0x07;
     if(dy==0x01) LCD_puts("SUN");
     else if(dy==0x02) LCD_puts("MON");
     else if(dy==0x03) LCD_puts("TUE");
     else if(dy==0x04) LCD_puts("WED");
     else if(dy==0x05) LCD_puts("THU");
     else if(dy==0x06) LCD_puts("FRI");
     else if(dy==0x07) LCD_puts("SAT");
}

int main()
{
 D[2]='/'; D[5]='/'; D[6]='2'; D[7]='0';
 T[2]=':'; T[5]=':';
 DDRB=0x00;
 PORTB=0xFE;  // sw_init();
 LCD_init(COFF);
 LCD_clear();
 LCD_puts2XY(4,0,"WeLcOmE...");
 LCD_puts2XY(0,1,"www.elecdude.com");
 buzz(); buzz();

 DSinit();
#ifdef MODE_12HR
#else
 T[8]='\0';//24hour mode  default 24hour mode
#endif

 _delay_ms(50);
DDRD = (1<<7) | (1<<6) | (0<<2);
 SETBIT(PORTD,2)
 SETBIT(GICR,INT0)
 MCUCR|= ( (1<<ISC01)|(0<<ISC00) );
   //ext int0 @falling edge(10)           
 set_sleep_mode(SLEEP_MODE_IDLE);
 SETBIT(TIMSK,OCIE0) //T0 compate int
 OCR0=0x15;
 TCNT0=0x00;
 TCCR0=0x00;
LCD_clear();
 WaitMs(900);
 sei();
 while(1)
     {
           _delay_us(50);                 
           sleep_mode();  
           nop();
     }
 return 0;
}

OUTPUT SNAPSHOT:

digital watch: elecdude.com


If you want to add beep every hour, just add in ISR.
Declare a variable hpre=0x00;
CODE:
if(hpre!=h)
     { buzz(); hpre=h;}

Like this you can add a pre-defined alarm at required time.


If you've any queries with this, logon to forum.elecdude.info & post it.
Thankyou.



Here is a simple digital watch which displays time, date & day in 16x2 lcd. DS1307 RTC is used for the time & date watch and AVR Atmega16 (8/32/64) is used as the display driver. It reads RTC time, date, day from ds1307 throught I2C bus and process it for displaying and displays it in the LCD.

Digital Watch


Click here to view our DS1307 tutorial & header file for AVR GCC.

Circuit diagram  for DS1307 RTC Digital Watch with AVR is  as follows:
 
Figure 1 - Circuit diagram
Connect a BUZZER  at pin PD6 if needed.
 
                To initialize DS1307 with the required time use this program first. It sets time as 12:45:32 & date as 24 Feb 14, Tuesday, by default. If you need to change, do it in BCD format.
/*************   WRITE TIME IN DS1307 ***********************/
#ifndef BIT
#define BIT(x)    _BV(x)

Thursday, 13 February 2014

INTERFACING SWITCH WITH AVR MICROCONTROLLER WITH INTERRUPT

           Switches are used to do intended actions or a task when pressed. This is most common in embedded devices. But polling a key press can cause more code to repeat until a valid key is recognized & power will be wasted.

           One solution is to use the keys with interrupt. So the ISR will be made to do the task of the key. In the main loop this task is removed so the MCU can be put into sleep mode, where an interrupt will make MCU to wake up. Here we present a simple code with 3 switches connected to interrupt the CPU when pressed. Note that Sleep mode is not used in this project, but it is simple to add.

CLICK HERE TO VIEW SLEEP MODE EXAMPLE.


         In this example we have used AVR Atmega8 microcontroller, the keypress ISR determines which key is pressed & displays it in USART. Note that the ISR returns only when the pressed is released. This is added for proper key de-bounce action, but much longer key press can cause lock-up until it is released. So triple check the circuit connections for errors & short circuits before powering up. This is optional & can be removed.

Circuit Diagram:

Program:
THIS WORK IS INTENDED TO BE USED FOR HOBBY & LEARNING PURPOSE ONLY. NO PART OF THIS CAN BE PUBLISHED OR USED IN COMMERCIAL PRODUCTS WITHOUT A WRITTEN PERMISSION FROM ELECDUDE.

#define F_CPU 1000000UL

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

/*****************MACRO's DEFINITION*********************************/
#define BIT(x)        (1 << (x))    //Set a particular bit mask
#define CHECKBIT(x,b)     (x & BIT(b))    //Checks bit status
#define SETBIT(x,b)     x|=BIT(b);    //Sets the particular bit
#define CLEARBIT(x,b)     x&=~BIT(b);    //Sets the particular bit
#define TOGGLEBIT(x,b)     x^=BIT(b);    //Toggles the particular bit
unsigned char ch='A';
#include "USART.h"

//ISR_ALIAS(INT1_vect, INT0_vect);//1->0
ISR(INT0_vect)
{
    ch=PINC; //read key status
    while(bit_is_clear(PIND,2)); //wait for de-bounce
    ch=((~ch) & 0x07);
    uart_puts_p("Switch ");
    switch(ch)
     {
      case 1:uart_putc('1');break;
      case 2:uart_putc('2');break;
      case 4:uart_putc('3');break;
     }
    uart_puts_p(" is pressed\n\r");
}

int main()
{
    PORTD=0xFF;//enable pull ups @ PD
            //int1 posedge        int0 posedge
    MCUCR|=(0<<ISC11)
|(0<<ISC10)|(1<<ISC01)|(0<<ISC00);
    GICR |= (0<<INT1)|(1<<INT0);//enable INT1 & INT0

    DDRD=0x00;//for i/P
   
    DDRB=0xFF;
    DDRC=0xF0;
    PORTC=0x0F;
   
    uart_init(9600,2);
    _delay_ms(50);
    uart_puts_p("Welcome...\n\r");
    sei();

     while(1)
         {
        //
        //
        }
 return 0;
}

// waits (pauses) for ms milliseconds
void WaitMs(unsigned int ms)
{
    unsigned int m;

    for(m=0;m<=ms/10;m++)
    {
        _delay_ms(10);
    }
}
Click here to goto USART example download.

Proteus Simulation Output Snapshot:






If you enjoyed this post plz let us know your views via comments.
This helps us to do much more better.
Thankyou.

Search Here...