Thứ Sáu, 14 tháng 12, 2018

GSM Based AC Appliance Control

This project would show you how to control an AC appliance remotely from anywhere using your mobile phone. This kind of project is useful in various applications. Say for example a farmer can switch ON or OFF the motor pump present near his field remotely. In this way he need not travel all the way to the field to control it, especially at night times.
Components Required
1.     ATMega16 Development board
2.     LCD board
3.     SIM 300/900 GSM Module
4.     12V/2A Power Supply
5.     SIM card with balance (or at least message offer maybe)
6.     SPDT Relay Switch
7.     Transistor BC547
8.     Diode 1N4007
9.     10k Resistor
10.   A PC or a Laptop (Optional. Needed in case of debugging)
Initial Setup
See my previous tutorial “GSM BASED INTRUDER ALERTER” if you are using the GSM modem for the first time.
gsm

About Relays

The switches at our home need to be operated manually by hand or “mechanically triggered” in order to work. If we need to control the switch using a microcontroller which does nothing but produces 5V or 0V at its output pins then we would require extra mechanical arrangements like a servo with an arm, to press the switch. Instead of building such complicated arrangements we can go with a relay. These can directly be controlled by electrical means.

Working of Relay
gsm

gsm
The above shown diagram is of a SPDT (Single Pole Double Throw) Relay. It consists of 5 terminals. Two of them are from the coil where the input to drive the relay is supposed to be given. The other three are NO (Normally Open), NC (Normally Closed) and COM (Common).
When no input is given to the coil, there is no magnetic field produced. So the “NC” and “COM” terminals are connected and the “NO” terminal is left free.
gsm
When the input is given, the current flowing through the coil produces magnetic field (Basic physics) and thus attracting the lever, which breaks the connection between “COM” à “NC” and makes a connection between “COM” à “NO” terminals.
Again when the input is removed, the spring attached to the lever pulls it back and “COM” à “NC” connection is re-established.
Free-wheeling diode
There is a problem in connecting a relay directly to an electronic circuit. When the input power is suddenly removed to switch OFF the relay, a voltage spike occurs due to the presence of the inductive load (The coil inside the relay is an inductor right?). This voltage spike can permanently damage the electronic circuit to which the relay is connected to. And thus we require a diode.
A diode connected in reverse bias with respect to the input supply, will prevent the voltage spike (produced by the relay when the supply is suddenly switched OFF) from reaching the other part of the control circuit.
gsm
Next, we need something to supply enough current to the relay input so that it doesn’t trip unexpectedly. So we use a transistor in between microcontroller and relay. And the circuit becomes like this:
gsm
Advantages of Relay
No degradation of the switched signal.
1.     Offers isolation between the AC supply and the Circuit.
2.     Lower Impedance and easier to interface.
3.     Robust.

Code Explanation

The code is build mostly around the library files “GSM.h” (Thanks to Engineers Garage tutorials) and “LCD.h” which contain the necessary functions for GSM modem interfacing and LCD interfacing.
GSM.h contains the following functions:
gsm_init() : Does the initial testing like checking for response after sending “AT\r”, checks for the presence of SIM card, Network and then sets the modem into Text Mode.
gsm_read() : Tries to read the message stored at location ‘1’ of the SIM. If there is a message then it stores the first 9 characters of it in the array “msg[]”. Then checks if the string in “msg[]” matches with the keyword or not.
gsm_delete() : Deletes the message stored at location ‘1’ of the SIM.
gsm_waitfor(char c) : Waits for a particular characters specified in the variable ‘c’ . If the wait is longer than the timer set in the Watch Dog timer then the whole program resets.
Algorithm
1.     Set PB2 as output and initialize the LCD function
2.     Initialize the GSM modem and set the Message format to text mode.
3.     Delete the message at location ‘1’ on the SIM.
4.     Enter an infinite loop and check for an incoming message constantly.
5.     If there is an incoming message, then store the number and the 1st nine characters of the message in the arrays “number[]” and “msg[]”.
6.     Display the phone number and the message on the LCD screen.
7.     Compare the saved message with the keyword “Motor on ”and if they match then set PB2 to high state.
8.     Compare the saved message with the keyword “Motor off” and if they match then set PB2 to low state.
9.     Delete the read message and go to the next iteration.
Trouble shooting
1.     LCD doesn’t show anything/ Shows blocks on the first line
Adjust the potentiometer connected to the contrast pin/Make sure all the connections are right.
2.     Motor doesn’t get turned ON
Check whether you are sending the correct message or not. Remember you need to add a space after “Motor on” and no space after “Motor off”. Check the LCD after sending the message to see if the controller is grasping your text correctly.



Circuit:

GSM Based AC Appliance Control circuit diagram
Code:


/*
 * gsmEG.c
 *
 * Created: 3/14/2014 1:21:32 PM
 *  Author: GANESH SELVARAJ
 */ 
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <string.h>
#include "GSM.h"
#include "lcd.h"
void gsm_read()
{
int k;
clrscr();
LCD_write_string("System Activated");
gotoxy(1,16);
UART_Transmit_string("AT+CMGR=1\r");
gsm_waitfor('\r');
gsm_waitfor('\n');
if(UART_Receive()=='+')
{
gsm_waitfor('M');
if(UART_Receive()=='G')
{
gsm_waitfor('A');
gsm_waitfor(',');
gsm_waitfor('"');
for(k=0;k<13;k++)
number[k] = UART_Receive();
gsm_waitfor(',');
gsm_waitfor(',');
gsm_waitfor('+');
gsm_waitfor('\n');
for(k=0;k<9;k++)
msg[k]=UART_Receive();
gsm_waitfor('K');
gsm_waitfor('\n');
_delay_ms(300);
clrscr();
LCD_write_string("Ph:");
LCD_write_string(number);
gotoxy(1,0);
LCD_write_string("Msg:");
LCD_write_string(msg);
_delay_ms(2000);
if(!strcmp(msg,"Motor on "))
{
PORTB |= (1<<PB2);
}
if(!strcmp(msg,"Motor off"))
{
PORTB &= ~(1<<PB2);
}
gsm_delete();
}
}
_delay_ms(1000);
}
int main(void)
{
DDRB  |= (1<<PB2);
lcd_init();
LCD_write_string("Initializing... ");
gsm_init();
gsm_delete();
while(1)
{
gsm_read();
}
return 0;
}



GSM




#ifndef GSM
#define GSM
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include "lcd.h"
char msg[10];
char number[14];
int i,j;
void UART_Init( unsigned int baud );
void UART_Transmit_char( unsigned char data );
unsigned char UART_Receive( void );
void UART_Transmit_string( char *string );
void UART_Init( unsigned int baud )
{
  /* Set baud rate */
  UBRRH = (unsigned char)(baud>>8);
  UBRRL = (unsigned char)baud;
  /* Enable receiver and transmitter */
  UCSRB = (1<<RXEN)|(1<<TXEN);
  /* Set frame format: 8data, 1stop bit */
  UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);
}
void UART_Transmit_char( unsigned char data )
{
  /* Wait for empty transmit buffer */
  while ( !( UCSRA & (1<<UDRE)) )
  ;
  /* Put data into buffer, sends the data */
  UDR = data;
}
unsigned char UART_Receive( void )
{
  /* Wait for data to be received */
   while ( !(UCSRA & (1<<RXC)) )
   ;
   /* Get and return received data from buffer */
   return UDR;
}
void UART_Transmit_string( char string[] )
{
  int i=0;
  while ( string[i] > 0)
  UART_Transmit_char(string[i++]);
}
/*************************************************************/
void gsm_init(void);
void gsm_read(void);
void gsm_send(char *number,char *string);
void gsm_delete(void);
void gsm_waitfor(char c);
void gsm_waitfor(char c)
{
//enabling watchdogtimer with a time of 2.1secs
wdt_enable(7);
//waiting for the byte to be received
while(UART_Receive()!= c);
//resetting watchdogtimer and turning off the watchdogtimer
wdt_reset();
wdt_disable();
}
void gsm_init()
{
UART_Init(103); // baudrate=9600
gotoxy(1,0);
LCD_write_string(" Testing Modem  ");
_delay_ms(500);
UART_Transmit_string("AT\r");
gsm_waitfor('O');
gsm_waitfor('K');
gotoxy(1,0);
LCD_write_string("   Modem : OK   ");
_delay_ms(1000);
INS:
gotoxy(1,0);
LCD_write_string(" Checking SIM   ");
_delay_ms(500);
UART_Transmit_string("AT+CSMINS?\r");
gsm_waitfor( '\n');
gsm_waitfor(',');
if(UART_Receive() == '2')
{ 
gotoxy(1,0);
LCD_write_string("  SIM NOTFOUND  ");
_delay_ms(1000);
goto INS;
}
else if(UART_Receive() == '1');
gsm_waitfor( 'K');
gsm_waitfor( '\n');
gotoxy(1,0);
LCD_write_string("   SIM FOUND    ");
_delay_ms(1000);
REG:
gotoxy(1,0);
LCD_write_string(" Network Status ");
_delay_ms(500);
UART_Transmit_string("AT+CREG?\r");
gsm_waitfor( '\n');
gsm_waitfor(',');
if(UART_Receive() == '2')
{
gotoxy(1,0);
LCD_write_string("Network NotFound");
_delay_ms(1000);
goto REG;
}
else if(UART_Receive() == '1');
gsm_waitfor( 'K');
gsm_waitfor( '\n');
gotoxy(1,0);
LCD_write_string(" Network Found  ");
_delay_ms(1000);
UART_Transmit_string("AT+CMGF=1\r");
gotoxy(1,0);
LCD_write_string("Setting Textmode");
gsm_waitfor('O');
gsm_waitfor('K');
gotoxy(1,0);
LCD_write_string("  Textmode set  ");
_delay_ms(1000);
}
void gsm_delete()
{
UART_Transmit_string("AT+CMGD=1\r");
gsm_waitfor('K');
gsm_waitfor('\n');
_delay_ms(500);
}
#endif



LCD





#include<avr/io.h>
#include<util/delay.h>
#include<inttypes.h>
#include "lcd.h"
void LCD_write_string(const char *str) //store address value of t                                        he string in pointer *str
{
int i=0;
while(str[i]!='\0') // loop will go on till the NULL character in                           the string
{
if (str[i]=='*')
{
i++;
int8_t cc=str[i]-'0';
if(cc>=0 && cc<=7)
{
dis_data(cc);
}
else
{
dis_data('%');
dis_data(str[i]);
}
}
else dis_data(str[i]); // sending data on LCD byte by byte
i++;
}
return;
}
void lcd_init() // function for initialize
{
DDRA=0xFF;
dis_cmd(0x02); // to initialize LCD in 4-bit mode.
dis_cmd(0x28); //to initialize LCD in 2 lines, 5X7 dots and 4bit                     mode.
dis_cmd(0x0C);
dis_cmd(0x06);
dis_cmd(0x0E);
custom_char();
gotoxy(0,0);
}
void dis_cmd(char cmd_value)
{
char cmd_value1;
cmd_value1 = ((cmd_value>>4) & 0x0F); //shift 4-bit and mask
lcdcmd(cmd_value1); // send to LCD
cmd_value1 = cmd_value & 0x0F; //mask lower nibble because PA4-PA                                 7 pins are used.
lcdcmd(cmd_value1); // send to LCD
}
void dis_data(char data_value)
{
char data_value1;
data_value1=((data_value>>4)&0x0F);
lcddata(data_value1);
data_value1=data_value&0x0F;
lcddata(data_value1);
}
void lcdcmd(char cmdout)
{
PORTA=cmdout;
PORTA&=~(1<<rs);
PORTA&=~(1<<rw);
PORTA|=(1<<en);
_delay_ms(1);
PORTA&=~(1<<en);
}
void lcddata(char dataout)
{
PORTA=dataout;
PORTA|=(1<<rs);
PORTA&=~(1<<rw);
PORTA|=(1<<en);
_delay_ms(1);
PORTA&=~(1<<en);
}
void clrscr()
{
_delay_ms(10);
dis_cmd(0x01);
_delay_ms(100);
}
void gotoxy(char a,char b)
{
if(a==0)  a=0b10000000;
else if(a==1) a=0b11000000;
else if(a==2) a=0b10010100;
else if(a==3) a=0b11010100;
dis_cmd(a+b); 
}
void custom_char()
{
unsigned char c[]={0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x0E, 0x0E, 0x04, //Char0
0x1F, 0x11, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x04,  //Char1
0x01, 0x01, 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, //Char2
0x00, 0x00, 0x00, 0x04, 0x04, 0x14, 0x14, 0x14, //Char3
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, //Char4
0x00, 0x00, 0x0A, 0x00, 0x04, 0x1F, 0x0A, 0x04, //Char5
0x00, 0x04, 0x0A, 0x11, 0x1F, 0x00, 0x00, 0x00, //Char6
0x00, 0x00, 0x00, 0x1F, 0x11, 0x0A, 0x04, 0x00, //Char7
};
uint8_t a[]={72,80,88,96,104,112,120,64};
uint8_t i,j;
for(i=0;i<sizeof(a);i++)
{
dis_cmd(a[i]);
for(j=0;j<sizeof(c);j++)
{
dis_data(c[j]);
}
}

}






lcd



#ifndef LCD_H_
#define LCD_H_
#define rs PA7
#define rw PA6
#define en PA4
void lcd_init();
void dis_cmd(char);
void dis_data(char);
void lcdcmd(char);
void lcddata(char);
void clrscr();
void gotoxy(char,char);
void LCD_write_string(const char *);
void custom_char();
#endif/*
 * gsmEG.c
 *
 * Created: 3/14/2014 1:21:32 PM
 *  Author: GANESH SELVARAJ
 */ 
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <string.h>
#include "GSM.h"
#include "lcd.h"
void gsm_read()
{
int k;
clrscr();
LCD_write_string("System Activated");
gotoxy(1,16);
UART_Transmit_string("AT+CMGR=1\r");
gsm_waitfor('\r');
gsm_waitfor('\n');
if(UART_Receive()=='+')
{
gsm_waitfor('M');
if(UART_Receive()=='G')
{
gsm_waitfor('A');
gsm_waitfor(',');
gsm_waitfor('"');
for(k=0;k<13;k++)
number[k] = UART_Receive();
gsm_waitfor(',');
gsm_waitfor(',');
gsm_waitfor('+');
gsm_waitfor('\n');
for(k=0;k<9;k++)
msg[k]=UART_Receive();
gsm_waitfor('K');
gsm_waitfor('\n');
_delay_ms(300);
clrscr();
LCD_write_string("Ph:");
LCD_write_string(number);
gotoxy(1,0);
LCD_write_string("Msg:");
LCD_write_string(msg);
_delay_ms(2000);
if(!strcmp(msg,"Motor on "))
{
PORTB |= (1<<PB2);
}
if(!strcmp(msg,"Motor off"))
{
PORTB &= ~(1<<PB2);
}
gsm_delete();
}
}
_delay_ms(1000);
}
int main(void)
{
DDRB  |= (1<<PB2);
lcd_init();
LCD_write_string("Initializing... ");
gsm_init();
gsm_delete();
while(1)
{
gsm_read();
}
return 0;
}



GSM




#ifndef GSM
#define GSM
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include "lcd.h"
char msg[10];
char number[14];
int i,j;
void UART_Init( unsigned int baud );
void UART_Transmit_char( unsigned char data );
unsigned char UART_Receive( void );
void UART_Transmit_string( char *string );
void UART_Init( unsigned int baud )
{
  /* Set baud rate */
  UBRRH = (unsigned char)(baud>>8);
  UBRRL = (unsigned char)baud;
  /* Enable receiver and transmitter */
   UCSRB = (1<<RXEN)|(1<<TXEN);
   /* Set frame format: 8data, 1stop bit */
   UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);
}
void UART_Transmit_char( unsigned char data )
{
   /* Wait for empty transmit buffer */
   while ( !( UCSRA & (1<<UDRE)) )
   ;
   /* Put data into buffer, sends the data */
   UDR = data;
}
unsigned char UART_Receive( void )
{
  /* Wait for data to be received */
  while ( !(UCSRA & (1<<RXC)) )
  ;
  /* Get and return received data from buffer */
  return UDR;
}
void UART_Transmit_string( char string[] )
{
   int i=0;
   while ( string[i] > 0)
   UART_Transmit_char(string[i++]);
}
/*************************************************************/
void gsm_init(void);
void gsm_read(void);
void gsm_send(char *number,char *string);
void gsm_delete(void);
void gsm_waitfor(char c);
void gsm_waitfor(char c)
{
//enabling watchdogtimer with a time of 2.1secs
wdt_enable(7);
//waiting for the byte to be received
while(UART_Receive()!= c);
//resetting watchdogtimer and turning off the watchdogtimer
wdt_reset();
wdt_disable();
}
void gsm_init()
{
UART_Init(103); // baudrate=9600
gotoxy(1,0);
LCD_write_string(" Testing Modem  ");
_delay_ms(500);
UART_Transmit_string("AT\r");
gsm_waitfor('O');
gsm_waitfor('K');
gotoxy(1,0);
LCD_write_string("   Modem : OK   ");
_delay_ms(1000);
INS:
gotoxy(1,0);
LCD_write_string(" Checking SIM   ");
_delay_ms(500);
UART_Transmit_string("AT+CSMINS?\r");
gsm_waitfor( '\n');
gsm_waitfor(',');
if(UART_Receive() == '2')
{ 
gotoxy(1,0);
LCD_write_string("  SIM NOTFOUND  ");
_delay_ms(1000);
goto INS;
}
else if(UART_Receive() == '1');
gsm_waitfor( 'K');
gsm_waitfor( '\n');
gotoxy(1,0);
LCD_write_string("   SIM FOUND    ");
_delay_ms(1000);
REG:
gotoxy(1,0);
LCD_write_string(" Network Status ");
_delay_ms(500);
UART_Transmit_string("AT+CREG?\r");
gsm_waitfor( '\n');
gsm_waitfor(',');
if(UART_Receive() == '2')
{
gotoxy(1,0);
LCD_write_string("Network NotFound");
_delay_ms(1000);
goto REG;
}
else if(UART_Receive() == '1');
gsm_waitfor( 'K');
gsm_waitfor( '\n');
gotoxy(1,0);
LCD_write_string(" Network Found  ");
_delay_ms(1000);
UART_Transmit_string("AT+CMGF=1\r");
gotoxy(1,0);
LCD_write_string("Setting Textmode");
gsm_waitfor('O');
gsm_waitfor('K');
gotoxy(1,0);
LCD_write_string("  Textmode set  ");
_delay_ms(1000);
}
void gsm_delete()
{
UART_Transmit_string("AT+CMGD=1\r");
gsm_waitfor('K');
gsm_waitfor('\n');
_delay_ms(500);
}
#endif



LCD



#include<avr/io.h>
#include<util/delay.h>
#include<inttypes.h>
#include "lcd.h"
void LCD_write_string(const char *str) //store address value of t                                        he string in pointer *str
{
int i=0;
while(str[i]!='\0') // loop will go on till the NULL character in the string
{
if (str[i]=='*')
{
i++;
int8_t cc=str[i]-'0';
if(cc>=0 && cc<=7)
{
dis_data(cc);
}
else
{
dis_data('%');
dis_data(str[i]);
}
}
else dis_data(str[i]); // sending data on LCD byte by byte
i++;
}
return;
}
void lcd_init() // function for initialize
{
DDRA=0xFF;
dis_cmd(0x02); // to initialize LCD in 4-bit mode.
dis_cmd(0x28); //to initialize LCD in 2 lines, 5X7 dots and 4bit mode.
dis_cmd(0x0C);
dis_cmd(0x06);
dis_cmd(0x0E);
custom_char();
gotoxy(0,0);
}
void dis_cmd(char cmd_value)
{
char cmd_value1;
cmd_value1 = ((cmd_value>>4) & 0x0F); //shift 4-bit and mask
lcdcmd(cmd_value1); // send to LCD
cmd_value1 = cmd_value & 0x0F; //mask lower nibble because PA4-PA7 pins are used.
lcdcmd(cmd_value1); // send to LCD
}
void dis_data(char data_value)
{
char data_value1;
data_value1=((data_value>>4)&0x0F);
lcddata(data_value1);
data_value1=data_value&0x0F;
lcddata(data_value1);
}
void lcdcmd(char cmdout)
{
PORTA=cmdout;
PORTA&=~(1<<rs);
PORTA&=~(1<<rw);
PORTA|=(1<<en);
_delay_ms(1);
PORTA&=~(1<<en);
}
void lcddata(char dataout)
{
PORTA=dataout;
PORTA|=(1<<rs);
PORTA&=~(1<<rw);
PORTA|=(1<<en);
_delay_ms(1);
PORTA&=~(1<<en);
}
void clrscr()
{
_delay_ms(10);
dis_cmd(0x01);
_delay_ms(100);
}
void gotoxy(char a,char b)
{
if(a==0)  a=0b10000000;
else if(a==1) a=0b11000000;
else if(a==2) a=0b10010100;
else if(a==3) a=0b11010100;
dis_cmd(a+b); 
}
void custom_char()
{
unsigned char c[]={0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x0E, 0x0E, 0x04, //Char0
0x1F, 0x11, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x04,  //Char1
0x01, 0x01, 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, //Char2
0x00, 0x00, 0x00, 0x04, 0x04, 0x14, 0x14, 0x14, //Char3
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, //Char4
0x00, 0x00, 0x0A, 0x00, 0x04, 0x1F, 0x0A, 0x04, //Char5
0x00, 0x04, 0x0A, 0x11, 0x1F, 0x00, 0x00, 0x00, //Char6
0x00, 0x00, 0x00, 0x1F, 0x11, 0x0A, 0x04, 0x00, //Char7
};
uint8_t a[]={72,80,88,96,104,112,120,64};
uint8_t i,j;
for(i=0;i<sizeof(a);i++)
{
dis_cmd(a[i]);
for(j=0;j<sizeof(c);j++)
{
dis_data(c[j]);
}
}
}





lcd



#ifndef LCD_H_
#define LCD_H_
#define rs PA7
#define rw PA6
#define en PA4
void lcd_init();
void dis_cmd(char);
void dis_data(char);
void lcdcmd(char);
void lcddata(char);
void clrscr();
void gotoxy(char,char);
void LCD_write_string(const char *);
void custom_char();
#endif

Không có nhận xét nào:

Đăng nhận xét

Bài đăng mới nhất

Hướng dẫn sử dụng Cân điện tử Fujihatsu FTC-01

Hướng dẫn sử dụng Cân điện tử Fujihatsu FTC-01 # candientu ,  # fujihatsu ,  # candientufujihatsu  #candientu,  # candientufujhatsu , #fuji...

Bài đăng phổ biến