PIC SMS Controller using PIC16F688
the purpose of this project is to help fellow hobbyist and students
credits to http://www.electronicslab.ph
Author: Alyas from Philippines
This is an SMS controller using a PIC16F688. Why a PIC16F688? Well for one, I have this in my parts bin and second of all, it is like an LF series part number operating from 2.0V up to 5.5V. I am using this on a Nokia mobile phone where the voltage level is around 2.7V. But it can also be used directly on GSM modems. This SMS controller utilizes textmode AT commands as the communication protocol.
Below is the base hardware schematic where the code is based. Once I finalize the code, I will also finalize the hardware schematic. The code is already working but still needs improvement and additional features. I am open to more suggestions on additional features or how to further optimize or improve the code.
Features:
Very minimalist with 4 output ports and 4 alarm input ports.
The 4 output ports (namely OUT1, OUT2, OUT3 and OUT4) can be controlled (turned ON or OFF) using predefined keyword commands sent to the attached mobile( or gsm modem) to the SMS controller.
OUT1_HIGH to turn on OUT1 port and LED D1
OUT1_LOW to turn off OUT1 port and LED D1
OUT2_HIGH to turn on OUT1 port and LED D2
OUT2_LOW to turn off OUT1 port and LED D2
OUT3_HIGH to turn on OUT1 port and LED D3
OUT3_LOW to turn off OUT1 port and LED D3
OUT4_HIGH to turn on OUT1 port and LED D4
OUT4_LOW to turn off OUT1 port and LED D4
The 4 alarm input ports when set or driven low will by default set or turn on OUT1 (which could be connected to a siren) and send a corresponding SMS Alert message to a predefined Mobile number of the port that was triggered. It also has a configurable alarm trigger timer (by default 5 mins) such that if the alarm is continously active or continously being triggered within 5 minutes, it will only send 1 SMS alert message within a 5 min. interval for a specific alarm input port.
There is no polling on the received SMS but rather received SMS is delivered directly to SMS Controller. You should modify the AT+CNMI settings that work on your phone. Also, SMS alert message are also sent directly to the network and not initially save then sent from the phone memory.
All in all, code size is 1008 of 4096 program words and RAM used is 117 bytes of 256 bytes so there is still enough room for additional features. Compiler used is Hitech C.
BTW, I am simulating this on proteus and an actual Nokia mobile phone attached to my pc.
Below is the code: main.c
/****************************************/ /* SMS Controller using PIC16F688 */ /* PIC16F688 SMS Controller v0.02 */ /* */ /* by */ /* KentronicsPH */ /* KentronicsPH.blogspot.com */ /* [email protected] */ /* */ /* YOU ARE FREE TO USE THIS S/W */ /* AT YOUR OWN RISK! */ /* I scrounged up this code from */ /* various sources, compiler sample */ /* codes and files, advices from */ /* forums and other MCU related */ /* websites and modifying them for */ /* my own purpose. */ /* */ /* This is not a professional s/w, */ /* the purpose of which is to help */ /* fellow hobbyist and students */ /* a guide to code their own SMS */ /* controller. */ /****************************************/ #include <htc.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include "usart.h" #ifndef _XTAL_FREQ #define _XTAL_FREQ 8000000 #endif #define OUT1_HIGH RC0 = 1; #define OUT2_HIGH RC1 = 1; #define OUT3_HIGH RC2 = 1; #define OUT4_HIGH RC3 = 1; #define OUT1_LOW RC0 = 0; #define OUT2_LOW RC1 = 0; #define OUT3_LOW RC2 = 0; #define OUT4_LOW RC3 = 0; #define LED_IND_ON RA5 = 1; #define LED_IND_OFF RA5 = 0; /* Alarm trigger delay If alarm has been triggered and remains triggered, SMS Controller will only send an SMS message once for every no. of ticks where 1 tick is about 250ms */ #define alarm_filter 1200 #define mobile_no_01 "+639123456789" /* PIC16F688 Configuration Fuses */ __CONFIG(FCMDIS & IESODIS & BORDIS & PWRTEN & WDTDIS & INTIO); /* Function Declarations */ void Setup_Interrupts(void); void Setup_16F688HW(); void TMR1_INC(void); void Setup_Timer1(); /* Global Variables */ unsigned int alarm_timer1; unsigned int alarm_timer2; unsigned int alarm_timer3; unsigned int alarm_timer4; unsigned char alarm_flag1; unsigned char alarm_flag2; unsigned char alarm_flag3; unsigned char alarm_flag4; /* Functions */ void interrupt isr() { if (RCIF) { Write_RXBuff(); } if (TMR1IF) { TMR1_INC(); } } void Setup_Interrupts(void) { INTCON = 0; GIE = 1 ; PEIE = 1 ; RCIE = 1; TMR1IE = 1; //enable timer1 interrupt } void Setup_16F688HW(void) { OSCCON = 0b01110001; // Internal Oscillator 8MHz ANSEL = 0x00; // All ADC off CMCON0 = 0x07; // Comparators off /* Digital Inputs, TRIS = 1 (Input) */ TRISA0 = 1; // RA0 as alarm input 1 TRISA1 = 1; // RA1 as alarm input 2 TRISA2 = 1; // RA2 as alarm input 3 TRISA3 = 1; // RA3 as alarm input 4 //Digital Outputs, TRIS = 0 (Output) */ TRISA5 = 0; // LED indicator TRISC0 = 0; // RC0 as alarm output 1 TRISC1 = 0; // RC1 as alarm output 2 TRISC2 = 0; // RC2 as alarm output 3 TRISC3 = 0; // RC3 as alarm output 4 OUT1_LOW RC0 = 0; OUT2_LOW RC1 = 0; OUT3_LOW RC2 = 0; OUT4_LOW RC3 = 0; LED_IND_OFF RA5 = 0; } void SMS_ATE0(void) // Sends echo command off { while (1) { Reset_RXBuff(); printf("ATE0\r"); __delay_ms(300); if (strstr(RXBuff, "\r\nOK\r\n\0") != 0) break; } } void SMS_ATCMGF(void) { while (1) { Reset_RXBuff(); printf("AT+CMGF=1\r"); __delay_ms(300); if (strstr(RXBuff, "\r\nOK\r\n\0") != 0) break; } } void SMS_ATCNMI() { while (1) { Reset_RXBuff(); printf("AT+CNMI=2,2,2,2,0\r"); __delay_ms(300); //wait for "> " character if (strstr(RXBuff, "\r\nOK\r\n") != 0) break; } } void SMS_Send_SM(const char * message, const char * pnum) { printf("AT+CMGS=\"%s\"\r", pnum); __delay_ms(300); Reset_RXBuff; printf("%s\x1a", message); } void TMR1_INC(void) { TMR1IF = 0; TMR1H = 11; TMR1L = 220; alarm_timer1++; alarm_timer2++; alarm_timer3++; alarm_timer4++; if (alarm_timer1 > = alarm_filter) { alarm_flag1 = 0; alarm_timer1 = 0; } if (alarm_timer2 > = alarm_filter) { alarm_flag2 = 0; alarm_timer2 = 0; } if (alarm_timer3 > = alarm_filter) { alarm_flag3 = 0; alarm_timer3 = 0; } if (alarm_timer4 > = alarm_filter) { alarm_flag4 = 0; alarm_timer4 = 0; } } void Setup_Timer1() // interrupt every 250ms { TMR1H = 11; TMR1L = 220; T1CON = 0b00110101; } void main(void) { Setup_16F688HW(); Setup_Interrupts(); Setup_Timer1(); uart_init(); // set up the USART - settings defined in usart.h __delay_ms(1000); SMS_ATE0(); SMS_ATCMGF(); SMS_ATCNMI(); LED_IND_ON; //Indicates PIC-Phone comms is OK! alarm_timer1 = 0; alarm_flag1 = 0; alarm_timer2 = 0; alarm_flag2 = 0; alarm_timer3 = 0; alarm_flag3 = 0; alarm_timer4 = 0; alarm_flag4 = 0; while (1) { /* ALARM MONITORING */ if (RA0 == 0) { if (alarm_flag1 == 0 ) { OUT1_HIGH; SMS_Send_SM("IN1 ON", mobile_no_01); alarm_flag1 = 1; alarm_timer1 = 0; __delay_ms(5000); } } if (RA1 == 0) { if (alarm_flag2 == 0 ) { OUT1_HIGH; SMS_Send_SM("IN2 ON", mobile_no_01); alarm_flag2 = 1; alarm_timer2 = 0; __delay_ms(5000); } } if (RA2 == 0) { if (alarm_flag3 == 0 ) { OUT1_HIGH; SMS_Send_SM("IN3 ON", mobile_no_01); alarm_flag3 = 1; alarm_timer3 = 0; __delay_ms(5000); } } if (RA4 == 0) { if (alarm_flag4 == 0 ) { OUT1_HIGH; SMS_Send_SM("IN4 ON", mobile_no_01); alarm_flag4 = 1; alarm_timer4 = 0; __delay_ms(5000); } } /* COMMAND MONITORING */ Reset_RXBuff(); __delay_ms(100); if (strstr(RXBuff, "OUT1_HIGH") != 0) { OUT1_HIGH; } else if (strstr(RXBuff, "OUT1_LOW") != 0) { OUT1_LOW; } else if (strstr(RXBuff, "OUT2_HIGH") != 0) { OUT2_HIGH; } else if (strstr(RXBuff, "OUT2_LOW") != 0) { OUT2_LOW; } else if (strstr(RXBuff, "OUT3_HIGH") != 0) { OUT3_HIGH; } else if (strstr(RXBuff, "OUT3_LOW") != 0) { OUT3_LOW; } else if (strstr(RXBuff, "OUT4_HIGH") != 0) { OUT4_HIGH; } else if (strstr(RXBuff, "OUT4_LOW") != 0) { OUT4_LOW; } } }
usart.c
/****************************************/ /* SMS Controller using PIC16F688 */ /* PIC16F688 SMS Controller v0.02 */ /* */ /* by */ /* KentronicsPH */ /* KentronicsPH.blogspot.com */ /* [email protected] */ /* */ /* YOU ARE FREE TO USE THIS S/W */ /* AT YOUR OWN RISK! */ /* I scrounged up this code from */ /* various sources, compiler sample */ /* codes and files, advices from */ /* forums and other MCU related */ /* websites and modifying them for */ /* my own purpose. */ /* */ /* This is not a professional s/w, */ /* the purpose of which is to help */ /* fellow hobbyist and students */ /* a guide to code their own SMS */ /* controller. */ /****************************************/ #define _usart_c_ #include <htc.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include "usart.h" bank2 unsigned char RXBuff[rxbuffsize]; volatile unsigned char wptr; void putch(unsigned char byte) { /* output one byte */ while(!TXIF) /* set when register is empty */ continue; TXREG = byte; } /* void puts(const unsigned char * s) { while (*s) putch(*s++); } void puts2(unsigned char * s) { while (*s) putch(*s++); } */ unsigned char getch() { /* retrieve one byte */ while(!RCIF) /* set when register is not empty */ continue; return RCREG; } unsigned char getche(void) { unsigned char c; putch(c = getch()); return c; } void Write_RXBuff(void) { if ((RCSTA & 0b00000110) == 0) { RXBuff[wptr] = toupper(RCREG); //putch(RXBuff[wptr]); wptr++; if (wptr > (rxbuffsize -1)) wptr = 0; } else /* There is an error! */ { CREN = 0; CREN = 1; } } void Reset_RXBuff(void) { wptr = 0; memset(RXBuff, 0, rxbuffsize); }
usart.h
/****************************************/ /* SMS Controller using PIC16F688 */ /* PIC16F688 SMS Controller v0.02 */ /* */ /* by */ /* KentronicsPH */ /* KentronicsPH.blogspot.com */ /* [email protected] */ /* */ /* YOU ARE FREE TO USE THIS S/W */ /* AT YOUR OWN RISK! */ /* I scrounged up this code from */ /* various sources, compiler sample */ /* codes and files, advices from */ /* forums and other MCU related */ /* websites and modifying them for */ /* my own purpose. */ /* */ /* This is not a professional s/w, */ /* the purpose of which is to help */ /* fellow hobbyist and students */ /* a guide to code their own SMS */ /* controller. */ /****************************************/ #ifndef _SERIAL_H_ #define _SERIAL_H_ #define BAUD 9600 #define FOSC 8000000L #define NINE 0 /* Use 9bit communication? FALSE=8bit */ #define DIVIDER ((int)(FOSC/(16UL * BAUD) -1)) #define HIGH_SPEED 1 #if NINE == 1 #define NINE_BITS 0x40 #else #define NINE_BITS 0 #endif #if HIGH_SPEED == 1 #define SPEED 0x4 #else #define SPEED 0 #endif #if defined(_16F87) || defined(_16F88) #define RX_PIN TRISB2 #define TX_PIN TRISB5 #elif defined(_16F688) #define RX_PIN TRISC5 #define TX_PIN TRISC4 #else #define RX_PIN TRISC7 #define TX_PIN TRISC6 #endif /* Serial initialization */ #define uart_init()\ RX_PIN = 1; \ TX_PIN = 1; \ SPBRG = DIVIDER; \ RCSTA = (NINE_BITS|0x90); \ TXSTA = (SPEED|NINE_BITS|0x20) #define rxbuffsize 80 void putch(unsigned char); /* void puts(const unsigned char * s); void puts2(unsigned char * s); */ unsigned char getch(void); unsigned char getche(void); void Write_RXBuff(void); void Reset_RXBuff(void); #ifndef _uasrt_c_ extern bank2 unsigned char RXBuff[rxbuffsize]; extern volatile unsigned char wptr; #endif #endif
the phone supports text mode AT commands..
as you can see in the picture there is a small module in the end of the cable.. i dont know what is that..
I dont know if i can use any ordinary cable and just get the rX and tX pins
Hi I'm very new to this. The code comes up with a lot of errors. Do you have a ASM file format?BeginStudent
We ( 8051projects.net) don't have any information about this project.
In this thread, one of our members (romel_emperado) is just bringing it to our attention.
The code seems to be written for the Hitech c compiler.
It should compile with the right version of the Hitech c compiler.
I haven't actually tried this project since there is one module that I cannot find in our market, instead I created my own version but it is based on 8051 Uc and soncy ericson phone..