Ingo Electronics

valdymas sms žinutėmis - sms controller using Nokia 6110/5110 - sms remote control

Vienas iš nuotolinio valdymo būdų yra valdymas SMS žinutėmis (SMS Remote Control).
Pateiktoje schemoje  yra valdoma viena relė.
Schema veikia ir išbandyta su mob. tlf. Nokia 6110/5110.                                                                                                                        Nebandžiau, tačiau turėtų veikti ir su Nokia 6130, 6150, 6190, 5130, 5150, 5190, 3210, 3310.

Pirmoje mikrokontrolerio programos versijoje yra numerio atpažinimo ir skambinimo atlikus duotą komandą, funkcijos.
Prijungtame telefone SIM kortelė turi būti pilnai ištrinta ir joje pirmu numeriu įrašomas numeris iš kurio bus siunčiamos  SMS žinutės.  
SMS pasiusta iš kito numerio nebus priimama.
Taigi SIM kortelė turi būti paruošta sekančiai:
-Ištriname visus tlf. numerius iš SIM kortelės.
-Į SIM įvedamas numeris iš kurio bus siunčiamos SMS žinutės tokiu formatu pvz. 861012456.
-Ištriname visas SMS žinutes iš Outbox.
-Sukuriame SMS parašę tekstą pagal kurį bus įjungiama relė. (Pvz: On )
-Sukurtą SMS išsaugome. Žinutė Nr.1 bus išsaugota SIM kortelės Outbox.
-Sukuriame SMS parašę tekstą pagal kurį bus išjungiama relė. (Pvz: Off)
-Sukurtą SMS išsaugome. Žinutė Nr.2 bus išsaugota SIM kortelės Outbox.
P.S Kuriant SMS galima rašyti ne daugiau kaip 10 simbolių įskaitant tarpus, nes mikrokontrolerio programa tikrina                              tik pirmuosius 10 simbolių.
Telefonas prie schemos prijungiamas paprastu kabeliu trimis laidais.
Patogu tam panaudoti specialų kištuką, kuris prisijugia prie Nokia 6110/5110 duomenų lizdo.
Nepamiršti sujungti duomenų lizdo 4 ir 6 kontaktus prie to pačio laido, nes priešingu atveju tlf.neatsakys į mikrokontrolerio siunčiamas komandas.
Schema maitinama iš 12V (apie 500mA)  nuolatinės įtampos blokelio.
Schemoje naudojamas mikrokontroleris  PIC16F628A -20Mhz.
Įjungus maitinimą, sėkmingai pasileidus programai, mirgsi sisteminis šv.diodas D1. Jeigu šv.diodas nemirgsi, maitinimą  perjungti dar kartą.   

Trumpai mikrokontrolerio programa dirba sekančiai:
Mikrokontroleris su telefonu bendrauja Fbus komandomis, apie jas internete yra nemažai informacijos.
Įjungus maitinimą siunčiama komanda perskaityti telefono numerį įrašytą į SIM kortelę.
Perskaitytas numeris supakuojamas reikiamu formatu ir įrašomas į mikrokontrolerio atmintį.
Toliau programa pereina į budėjimo režimą, mirgsi šv.diodas D1, siunčiami UART sinchronizavimo impulsai.
Programa tikrina visus iš telefono gaunamus pranešimus.
Kai gaunamas pranešimas trumpam sumirgsi šv. diodas D2 
Jeigu tai nėra SMS žinutė, tai pranešimai yra ignoruojami ir vėl pereinama į budėjimo režimą.
Jeigu ateina SMS žinutė, programa patikrina ar sutampa siuntėjo numeris su numeriu įrašytu atmintyje.
Jeigu numeris sutampa, tikrinama kokia komanda atsiusta, jei tai yra komanda iš Outbox, komanda vykdoma.
Įsijungus relei RL1 šviečia šv. diodas D5.
Komandos ivykdymas yra patvirtinamas paskambinant vartotojui.
Po to gauta SMS žinutė yra ištrinama iš Inbox ir programa vėl pereina į budėjimo režimą.

 hex failas 1versija PIC16F628A (16Mhz kvarcas) programavimui:

Tiems kam idomu arba kas norėtų schemą pritaikyti kitokio tipo mikrokontroleriui ar kaip nors ją modifikuoti,
žemiau yra pateiktas programos C kodas mikroC  v6.2.1.0  kompiliatoriui.

BODEN_ON;  CP_OFF;  DATA_CP_OFF;  PWRTE_ON;  WDT_OFF;  LVP_OFF;  MCLRE_OFF;  HS_OSC


//SMS controleris Nokia 6110
//valdo viena rele,numerio atpazinimo funkcija,dial funkcija,hangup funkcija,delet_sms funkcija.

//PORTB.F3 - Sisteminis sv. diodas
//PORTB.F4 - UART Rx indikacija
//PORTB.F5 - Rele

//16.000 Mhz kvarcas
//PIC16F628A

unsigned char led;
unsigned char ver;
unsigned char Rx_Length;          
unsigned char TX_Max_Len;         
unsigned char Odd_Rx,Even_Rx;
unsigned char t;
unsigned char prevseq;
unsigned char firsttime;          
unsigned char Sequence_Number;
unsigned char sms_pq_length ;         // is Outbox supakuotos zinutes ilgis
unsigned char rec_sms_pqlength ;   //atsiustos supakuotos zinutes ilgis
unsigned char action;

unsigned char Phone_num[10];             //Phone_num[0x09 0x38 0x36 0x31 0x30 0x30 0x39 0x33 0x36 0x37]
                                                                                                  //0x09 - nesupakuoto numerio ilgis
unsigned char Phone_Num_Pack[7];   //Phone_Num_Pack[ 09 81 68 01 90 63 F7 ]
unsigned char TX_Buf[34];
unsigned char Rx_Buf[70];
unsigned char SMS_Message1[9];        //sudedama gauta is sim Outbox supakuota sms zinute1
unsigned char SMS_Message2[9];        //sudedama gauta is sim Outbox supakuota sms zinute2
unsigned char rec_sms_message[9];    //sudedama atsiusta supakuota sms zinute
unsigned char Read_SMS_Frame();      //Tikrina ar tai SMS ir ar is reikiamo numerio

void Phone_Number_Pack(unsigned char *Temp3,unsigned char  *Temp4);
void get_phone_number();                           //komanda gauti numeri is SIM
                                                             //gaunamas formatas Phone_num[0x09 0x38 0x36 0x31 0x30 0x30 0x39 0x33 0x36 0x37]
void get_sms_sim(unsigned char sms_num,unsigned char  *sms_msg);     //komanda gauti sms is Outbox
void Checksum();
void Checksum_Rx();
void Phone_Init();
void Send_ACK();
unsigned char  Read_Rx_msg(unsigned char type);  //tikrina pagal uzklausima gauta pranesima
void get_msg() ;           //kai suveikia UART tikrinama kokia tai zinute
unsigned char nextseq();
void clear_RX_Buf();
void clear_Message(unsigned char *data);
unsigned char check_action(unsigned char *sms_msg,unsigned char action);
void dial();
void hangup();
void delet_sms();

////////////////////////////////////////////////////////////////////////////////
void interrupt(){
if (Usart_Data_Ready()) {Rx_Buf[t++] = Usart_Read();PORTB.F4=1;if (t==69) {INTCON.GIE = 0;PORTB.F4=1;}; } ;

}
///////////////////////////////////////////////////////////////////////////////
void main (){
CMCON      = 0b00000111;     //Turn comparators off
VRCON = 0;                        //atramines itampos nustatymo registras
PIE1.RCIE =   1;                //leidzia USART read pertraukimus
INTCON.GIE =  0;           // global interrput enable
INTCON.PEIE = 1;         // Peripheral Interrupt Enable
TRISA      = 0b00000000;
TRISB      = 0b00000000;

PORTA=0;
PORTB=0;

Usart_Init(115200);

PORTB.F4=0;
firsttime=1;
led=0;
PORTB.F3=1;  //Sistem Led

Phone_Init();Phone_Init();Phone_Init();Phone_Init();Phone_Init();
get_phone_number();                    //gaunamas formatas Phone_num[0x09 0x38 0x36 0x31 0x30 0x30 0x39 0x33 0x36 0x37]
                                                                                                                             //0x09 - nesupakuoto numerio ilgis

Phone_Number_Pack(Phone_Num_Pack,Phone_num);      //supakuoja gauta is sim tlf. numeri sms formatu
                                                                                                                // Phone_Num_Pack[ 09 81 68 01 90 63 F7 ] 
                                           
get_sms_sim(0x01,SMS_Message1);

get_sms_sim(0x02,SMS_Message2);

INTCON.GIE = 1;
while(1){
INTCON.GIE = 1;
while (PORTB.F4 ==0 ) {Phone_Init();led++;if (led>10){PORTB.F3 = ~PORTB.F3 ;led=0;};};
get_msg();
}
}
///////////////////////////////////////////////////////////////////////////////
void get_msg(){
for(Ver = 0;Ver<69;Ver++){Usart_Write(0x55);};
Send_ACK();
INTCON.GIE = 0;
Read_SMS_Frame();
if (Read_SMS_Frame()==1) { //**
INTCON.GIE = 0;
//******skaiciuoja supakuotos zinutes ilgi *****************
if (Rx_buf[28] ==0x07) {rec_sms_pqlength = Rx_buf[5] - 45;}
else {rec_sms_pqlength = Rx_buf[5] - 44;};
//*****************************************************************************
clear_Message(rec_sms_message);
for (ver= 0;ver<rec_sms_pqlength;ver++){rec_sms_message[ver] = Rx_Buf[48+ver];};
//******************************************************************************
delay_ms(1000);
check_action(SMS_Message1,1);
if (check_action(SMS_Message1,1)==1) {PORTB.F5=1;dial();delay_ms(10000);delay_ms(5000);hangup();delet_sms();goto end };

delay_ms(1000);
check_action(SMS_Message2,2);
if (check_action(SMS_Message2,2)==2) {PORTB.F5=0;dial();delay_ms(10000);delay_ms(5000);hangup();delet_sms();goto end };

}; //**
end:
delay_ms(2000);
clear_RX_Buf();
INTCON.GIE = 1;
}
////////////////////////////////////////////////////////////////////////////////
unsigned char check_action(unsigned char *sms_msg,unsigned char action){
if(sms_msg[0]!= rec_sms_message[0]) return 0;
if(sms_msg[1]!= rec_sms_message[1]) return 0;
if(sms_msg[2]!= rec_sms_message[2]) return 0;
if(sms_msg[3]!= rec_sms_message[3]) return 0;
if(sms_msg[4]!= rec_sms_message[4]) return 0;
if(sms_msg[5]!= rec_sms_message[5]) return 0;
if(sms_msg[6]!= rec_sms_message[6]) return 0;
if(sms_msg[7]!= rec_sms_message[7]) return 0;
if(sms_msg[8]!= rec_sms_message[8]) return 0;
else return action;
}
////////////////////////////////////////////////////////////////////////////////
void clear_Message(unsigned char *data){
for(ver=0;ver<9;ver++){
data[ver]=0x00;};
}
////////////////////////////////////////////////////////////////////////////////
unsigned char  Read_SMS_Frame(){
if (
(Rx_Buf[0] != 0x1e)&&
(Rx_Buf[1] != 0x0c)&&
(Rx_Buf[2] != 0x00)&&
(Rx_Buf[3] != 0x02))                return 0;              //wrong header
if (
(Rx_Buf[33] != Phone_Num_Pack[3])&&
(Rx_Buf[34] != Phone_Num_Pack[4])&&
(Rx_Buf[35] != Phone_Num_Pack[5])&&
(Rx_Buf[36] != Phone_Num_Pack[6]))   return 0;       //wrong tlf. number
else return 1;
}
////////////////////////////////////////////////////////////////////////////////
void get_phone_number(){ //gaunamas formatas Phone_num[0x09 0x38 0x36 0x31 0x30 0x30 0x39 0x33 0x36 0x37]
start:                                                                                                         //0x09 - nesupakuoto numerio ilgis
delay_ms(100);
INTCON.GIE = 1;
clear_RX_Buf();
//*********************
//siunciam komanda gauti tlf numeri is sim
TX_Buf[0] = 0x1e; 
TX_Buf[1] = 0x00; 
TX_Buf[2] = 0x0c; 
TX_Buf[3] = 0x03;  //Type
TX_Buf[4] = 0x00;
TX_Buf[5] = 0x09;  //Length
TX_Buf[6] = 0x00;
TX_Buf[7] = 0x01;
TX_Buf[8] = 0x00;
TX_Buf[9] = 0x01;
TX_Buf[10] =0x03;
TX_Buf[11] =0x01;
TX_Buf[12] =0x00;
TX_Buf[13] =0x01;
TX_Buf[14] = nextseq();
TX_Buf[15] =0x00;
TX_Max_Len =18;
Checksum();
Phone_Init();
for(Ver = 0;Ver<TX_Max_Len;Ver++){
Usart_Write(TX_Buf[ver]);};
//******************************************************************************
while(t!=10)  continue ;
clear_RX_Buf();
while(t!=(Rx_Buf[5]+7)) continue;
Send_ACK();
INTCON.GIE = 0; PORTB.F4=0;
Read_Rx_msg(0x03);
if ( Read_Rx_msg(0x03)==1) {;;}
else  {delay_ms(1000);goto start;};
for (ver= 0;ver<(Rx_Buf[12]+1);ver++){Phone_num[ver] = Rx_Buf[12+ver];};
clear_RX_Buf();
}
////////////////////////////////////////////////////////////////////////////////
void Phone_Number_Pack(unsigned char *Temp3,unsigned char  *Temp4)
{       //supakuoja tlf. num. sms formatu Phone_Num_Pack[ 09 81 68 01 90 63 F7 ]
unsigned char High=0,Low=0,Ver1=0,Ver2=0;
Temp4[Temp4[0]+1]=0;
Temp3[0] = Temp4[0];
Temp3[1] = 0x81;
ver1=1;
for(ver=1;ver<Temp4[0];ver++){
Low = Temp4[Ver1] - 0x30;
if(Temp4[Ver1+1]!=0){High = Temp4[Ver1+1] - 0x30; Ver1=Ver1+2;}
else{High=15;Ver1=Ver1+2;}
Temp3[Ver2+2]=High*0x10+Low;
Ver2++;
}
}
/////////////////////////////////////////////////////////////////////////////////
void get_sms_sim(unsigned char sms_num,unsigned char  *sms_msg){
start:
delay_ms(100);
INTCON.GIE = 1;                //ijungiami pertraukimai
clear_RX_Buf();
Phone_Init();
//siunciam komanda gauti sms is Outbox
//****************************
TX_Buf[0] = 0x1e; 
TX_Buf[1] = 0x00; 
TX_Buf[2] = 0x0c; 
TX_Buf[3] = 0x02;  //Type
TX_Buf[4] = 0x00;
TX_Buf[5] = 0x0a;  //Length
TX_Buf[6] = 0x00;
TX_Buf[7] = 0x01;
TX_Buf[8] = 0x00;
TX_Buf[9] = 0x07;
TX_Buf[10] =0x02;
TX_Buf[11] = sms_num;
TX_Buf[12] =0x01;
TX_Buf[13] =0x64;
TX_Buf[14] =0x01;
TX_Buf[15] = nextseq();
TX_Max_Len =18;
Checksum();
Phone_Init();Phone_Init();
for(Ver = 0;Ver<TX_Max_Len;Ver++){
Usart_Write(TX_Buf[ver]);};
//******************************************************************************
while(t!=10) continue;
clear_RX_Buf();
while(t!=(Rx_Buf[5]+7)) continue;
Send_ACK();
INTCON.GIE = 0; PORTB.F4=0;              //isjungiami pertraukimai

Read_Rx_msg(0x14);
if ( Read_Rx_msg(0x14)==1) {delay_ms(500);}
else  {delay_ms(2000);goto start;};

if (Rx_buf[30]== 0x07)  {sms_pq_length = Rx_buf[5] - 47;}
else {sms_pq_length = Rx_buf[5] - 46;};                                      //skaiciuoja supakuotos zinutes ilgi

for(ver = 0;Ver<9;ver++) { if(Ver<sms_pq_length) {sms_msg[ver] = Rx_Buf[50+ver];}
else {sms_msg[ver] = 0x00;} ;};                   //primta sms sudeda i buf SMS_Message[9]
clear_RX_Buf();
}
////////////////////////////////////////////////////////////////////////////////
void Phone_Init(){
for(Ver = 0;Ver<=128;Ver++){
Usart_Write(0x55);
}
Delay_ms(100);
}
///////////////////////////////////////////////////////////////////////////////
void dial(){
get_phone_number();
TX_Buf[0] = 0x1e; 
TX_Buf[1] = 0x00; 
TX_Buf[2] = 0x0c; 
TX_Buf[3] = 0x01;  //Type
TX_Buf[4] = 0x00;
TX_Buf[5] = 0x19;  //Length
TX_Buf[6] = 0x00;
TX_Buf[7] = 0x01;
TX_Buf[8] = 0x00;
TX_Buf[9] = 0x01;
for (ver=0;ver<10;ver++) {Tx_Buf[10+ver] = Phone_num[ver];};
TX_Buf[20] =0x05;
TX_Buf[21] =0x01;
TX_Buf[22] =0x01;
TX_Buf[23] =0x05;
TX_Buf[24] = 0x81;
TX_Buf[25] = 0x01;
TX_Buf[26] = 0x00;
TX_Buf[27] = 0x00;
TX_Buf[28] = 0x01;
TX_Buf[29] = 0x01;
TX_Buf[30] = nextseq();
TX_Buf[31] =0x00;
TX_Max_Len =34;
Checksum();
Phone_Init();Phone_Init();Phone_Init();
for(Ver = 0;Ver<TX_Max_Len;Ver++){
Usart_Write(TX_Buf[ver]);};
}
///////////////////////////////////////////////////////////////////////////////
void hangup(){
TX_Buf[0]  =  0x1e;
TX_Buf[1]  =  0x00;
TX_Buf[2]  =  0x0c;
TX_Buf[3]  =  0x0c;  //Type
TX_Buf[4]  =  0x00;
TX_Buf[5]  =  0x09;  //Length
TX_Buf[6]  =  0x00;
TX_Buf[7]  =  0x01;
TX_Buf[8]  =  0x00;
TX_Buf[9]  =  0x42;
TX_Buf[10] =  0x01;
TX_Buf[11] =  0x0f;
TX_Buf[12] =  0x01;
TX_Buf[13] =  0x01;
TX_Buf[14] = nextseq();
TX_Buf[15] =  0x00;
TX_Max_Len =18;
Checksum();
Phone_Init();Phone_Init();//Phone_Init();
for(Ver = 0;Ver<TX_Max_Len;Ver++){
Usart_Write(TX_Buf[ver]);};

}
///////////////////////////////////////////////////////////////////////////////
void delet_sms(){
TX_Buf[0]  =  0x1e;
TX_Buf[1]  =  0x00;
TX_Buf[2]  =  0x0c;
TX_Buf[3]  =  0x14;  //Type
TX_Buf[4]  =  0x00;
TX_Buf[5]  =  0x08;  //Length
TX_Buf[6]  =  0x00;
TX_Buf[7]  =  0x01;
TX_Buf[8]  =  0x00;
TX_Buf[9]  =  0x0A;
TX_Buf[10] =  0x02; //Memory Type - SIM
TX_Buf[11] =  0x03; //Location where SMS message stored
TX_Buf[12] =  0x01;
TX_Buf[13] = nextseq();
TX_Max_Len =16;
Checksum();
Phone_Init();
for(Ver = 0;Ver<TX_Max_Len;Ver++){
Usart_Write(TX_Buf[ver]);};

}
///////////////////////////////////////////////////////////////////////////////
unsigned char nextseq(){
unsigned char n,n1;
    n=Sequence_Number;
    prevseq=n;
    ++Sequence_Number;
    Sequence_Number&=7;
      if(firsttime){firsttime=0;n1=0x60;}else n1=0x40;
    return (n+n1);
}
///////////////////////////////////////////////////////////////////////////////
void Checksum()  // siuntimui su Tx_Buf buferiu
{
 unsigned char Odd,Even,Temp1;
 Odd = TX_Buf[0];
 Even = TX_Buf[1];
 for(Temp1 = 2;Temp1<=TX_Max_Len-3;Temp1=Temp1+2)
 {
  Odd = Odd ^ TX_Buf[Temp1];
  Even = Even ^ TX_Buf[Temp1+1];
 }
 TX_Buf[TX_Max_Len-2] = Odd;
 TX_Buf[TX_Max_Len-1] = Even;
}
////////////////////////////////////////////////////////////////////////////////
void Checksum_Rx() //priemimui
{
unsigned char Temp1 ;
Odd_Rx = Rx_Buf[0];
Even_Rx = Rx_Buf[1];
for(Temp1 = 2;Temp1<=Rx_Length-3;Temp1=Temp1+2)
{
Odd_Rx = Odd_Rx ^ Rx_Buf[Temp1];
Even_Rx = Even_Rx ^ Rx_Buf[Temp1+1];
}
}
////////////////////////////////////////////////////////////////////////////////
void Send_ACK(){
TX_Buf[0] = 0x1e; 
TX_Buf[1] = 0x00; 
TX_Buf[2] = 0x0c; 
TX_Buf[3] = 0x7f;  //Type
TX_Buf[4] = 0x00;
TX_Buf[5] = 0x02;  //Length
TX_Buf[6] = Rx_Buf[3];
TX_Buf[7] = Rx_Buf[(Rx_Buf[5]+5)]-0x40; //sqn
TX_Max_Len =10;
Checksum();
for(Ver = 0;Ver<TX_Max_Len;Ver++){
Usart_Write(TX_Buf[ver]);};
}
///////////////////////////////////////////////////////////////////////////////
unsigned char  Read_Rx_msg(unsigned char type) {
if (
(Rx_Buf[0] != 0x1e)&&
(Rx_Buf[1] != 0x0c)&&
(Rx_Buf[2]!= 0x00))           return 0;
if (
Rx_Buf[3] != type )           return 0;       //wrong type
Rx_Length = Rx_Buf[5];
if ((Rx_Length%2)==0) {Rx_Length=Rx_Length+8;}
else {Rx_Length=Rx_Length+9;};
Checksum_Rx();
if ((Odd_Rx==Rx_Buf[Rx_Length-2])&& (Even_Rx==Rx_Buf[Rx_Length-1]))  return 1; //gud CRC
return 0;
}
///////////////////////////////////////////////////////////////////////////////
void clear_RX_Buf(){
for(ver=0;ver<69;ver++){Rx_Buf[ver]=0x00;};
PORTB.F4=0;
t=0;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////