CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Trying to Control an LED via SMS, please HELP !
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

Trying to Control an LED via SMS, please HELP !
PostPosted: Mon May 03, 2010 4:31 am     Reply with quote

Hi, this is my code to control an LED via sms but it's not working.

#include <16F876A.h>
#include <string.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7,errors)

#int_rda
void dispose_chars() {
char ts;
ts=getch(); // dispose phone's replies
}

void main() {
char ch;
char s1[12];
char s2[6]="307";
char s3[7]="5603";
int i,j;
char *ptr1;
char *ptr2;

start:
delay_ms(500);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);

puts("ATE0"); // phone replies "OK"
delay_ms(1000);
puts("at+csms=1"); // phone replies "OK"
delay_ms(1000);
puts("at+cnmi=1,2,0,0,1");
delay_ms(1000); //phone replies "OK"

disable_interrupts(INT_RDA);

while(true){

ch=getch();
switch(ch){

case '7': // look for '7' in incoming string
for(i=0; i<3; i++)
s1[i]=getch();
break;

case 'C':
for(j=0; j<4; j++) //look for 'C' in incoming string
s1[j]=getch();
break;
}

ptr1=strstr(s1, s2);
ptr2=strstr(s1, s3);

if(ptr2){
output_low(pin_B7);
output_low(pin_C4);
puts("at+cnmi=1,2,0,0,1"); // The phone responds "OK" here. But the program freezes and I am
// unable to turn the LED on again. Prog. works ok if I leave out this line !
// But I need it to re-initialise the phone !
}

if(ptr1)
output_high(pin_B7);
}
}

Can anyone check to see what I am doing wrong ?
Thanks in advance.
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue May 25, 2010 8:04 am     Reply with quote

hi,

i posted a working code that does this.

it controls 4 LEDs via SMS. you send !LED1 1 and led #1 goes on,
you send !LED1 0 and led #1 goes off....

same for leds 1,2,3 and 4....

its on the code library under "recieving Txt Messages "

http://www.ccsinfo.com/forum/viewtopic.php?t=42527

hope that helps.... its not perfect but it works.

gabriel
_________________
CCS PCM 5.078 & CCS PCH 5.093
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Tue May 25, 2010 9:15 am     Reply with quote

@ Gabriel.
Even prior to your reply I've read your code over and over and there are many parts of it I really don't understand. I'm extremely new to C programming and I am only now begining to understand the fundamental concepts of it.
Also, I'm using a Siemens A76 mobile which DOES NOT support text mode. It supports PDU mode only Mad . Your project is exactly what I am trying to accomplish. Can you help me understand your code a little more ?

e.g
Code:
int GET_CMD()
{
   const char CMD1[8][7]={"Led1 0","Led1 1","Led2 0","Led2 1","Led3 0","Led3 1","Led4 0","Led4 1"};

   int offset=0;
   int store_counter=0;
   counter_search=0;


   while((Recieve_String[counter_search]!='!')&&(counter_search<69)) // wait till command indicator is found '!'
   {
      counter_search++;
   }

   counter_search=counter_search+1;             // increment one to actual first letter of command
   store_Counter=counter_search;                // store current position for multiple searches
   NEXT_CMD=0;                                  // NEXT_CMD keeps track of the command being read, thus used

   while((HitCounter!=6)&&(NEXT_CMD<8))                     // compare to all commands in list.
   {
      counter_search=store_Counter;                // initialize counter search with stored counter value.
      offset=0;                                    // since value of counter is unknown use a separate counter for the const array
      HitCounter=0;                                // counts number of equal letters found.

      while((HitCounter!=6)&&(offset<=6))          // keeps the counters in check...to not overshoot. and compares the strings
      {
         if(Recieve_String[counter_search]==CMD1[NEXT_CMD][offset])  // if letter is found
            HitCounter++;
            offset++;
            counter_search++;
      }

      if(HitCounter==6)          // if 6 chars found...exit..
      {
         Return(1);
      }

      NEXT_CMD++;                // if increase to search next command.

   }

   Return(0);
}



If you feel you are wasting forum time please feel free to PM me.


Sal
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

.
PostPosted: Tue May 25, 2010 12:15 pm     Reply with quote

the function you question is actually quite simple...

i have a 2 demensional constant array holding the different possible commands...
the comands are just the strings im trying to find in the sms i sent to the cellphone conected to the PIC.

i find it easier to keep all commands the same length. my function is set to use commands 6 char long.

upon requesting the sms to the phone it will send a very large string containing the date, origin phone number, contact name if its on the memory, etc, etc and somewhere in that long string, closer to the end of it you will get the actuall text you sent via sms....

(my circular buffer fills up twice.... and the txt happens to fall completely into the second fill, i was lucky.... if your circular buffer loops back in the middle of your txt string... you are screwed....) (there are ways arround this, i was just lazy)

so i look in my buffer for a delimiter which signals the start of the text i sent.... i chose "!" .... i have to send "!" as the first char of my sms.....

when i find it on my buffer... i store the position.

then i start comparing character by character my buffer array to my constant array and counting the number of charracters that match. if i dont get 6 identical & continuos matches i go on to the next command and so on... if i never get 6 identical & continuos matches.... i exit... and command not found.

hope that helps....

gabriel
_________________
CCS PCM 5.078 & CCS PCH 5.093
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue May 25, 2010 12:19 pm     Reply with quote

also, i was wondering

why do you say your phone does not support txt mode ?

Code:
puts("at+csms=1"); // phone replies "OK"


looks like text mode to me..... are you sure you phone is responding with an "ok"?

check out the order and the commands i send to my phone....

i think your missing some....


or..... get the same phone i use? hahahaha kidding.

gabriel
_________________
CCS PCM 5.078 & CCS PCH 5.093
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

missing some things ....
PostPosted: Tue May 25, 2010 12:22 pm     Reply with quote

Code:
puts("at+csms=1"); // phone replies "OK"


you dont send "enter" or "return".... ever.....starting to wonder....
_________________
CCS PCM 5.078 & CCS PCH 5.093
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Tue May 25, 2010 1:54 pm     Reply with quote

Thanks for replying...

But just so you know:

1. AT+CMGF is the AT command for selecting SMS message format. There are two possible modes as far as I know...

0 = PDU format
1 = Text format

My mobile only has MODE = 0 = PDU !

2. The "puts" function automatically appends a new line(\n) and a carriage return(\r) when the function is executed. Hence there is no need to use any (0x0D) or (0x0A) as you did. This is only necessary if you are using a PRINTF function.

3. AT+CSMS means "Select Message Service" this has nothing to do with the format of the message that the mobile outputs to a terminal such as your computer's serial port.

Now, what exactly are you wondering about ?

Sal.
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue May 25, 2010 2:28 pm     Reply with quote

... you got me there with the "puts" function.... i read "putc" .... i was reading fast, didnt bother to read again.....wondered if you even tested your code....my bad.

sorry.... Embarassed


did my explanation of the GET_CMD work for you?

g
_________________
CCS PCM 5.078 & CCS PCH 5.093
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue May 25, 2010 2:38 pm     Reply with quote

Code:
puts("at+cnmi=1,2,0,0,1");
delay_ms(1000); //phone replies "OK"

disable_interrupts(INT_RDA);


i dont understand why you turn of your interrupts.... you wont know when new chars come in?


how about puting a buffer to get all of the celphones response and then search for your string on it?

also

Code:
if(ptr2){
output_low(pin_B7);
output_low(pin_C4);
puts("at+cnmi=1,2,0,0,1"); // The phone responds "OK" here. But the program freezes and I am
// unable to turn the LED on again. Prog. works ok if I leave out this line !
// But I need it to re-initialise the phone !
}


when you send CNMI again, your interrupts are disabled and your PICS rs 232 buffer overflows (max 2 chars) probably causing the lock up....

hope that helps...

what part of the "caribbean"are you in?

g
_________________
CCS PCM 5.078 & CCS PCH 5.093
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Wed May 26, 2010 5:18 am     Reply with quote

@Gabriel

You said "my circular buffer fills up twice.... and the txt happens to fall completely into the second fill"

Where exactly is your circular buffer and how do you read from it ?

Take a look at my new approach can you tell where I'm going wrong ?
Code:
#int_rda
void serial_isr() {
buffer[i]=getc();
i++;
if(i==24)
i=0;           // Buffer full ...reset it !!
}

BYTE bgetc() {
BYTE c;

while(i>0) ;
c=buffer[i]; //        I think my problem lies here
i++;
return(c);
}
void main(){
delay_ms(1000);
enable_interrupts(global);
enable_interrupts(int_rda);
i,j=0;

while(TRUE){

if(i>0){                           
ch=bgetc();                     
   if(ch=='\r'){                 
     s0[j]='\0';             
     j=0;                           
     
     ptr1=strstr(s0, s1);
     ptr2=strstr(s0, s2);       
     
     if(ptr1)
     output_high(pin_c4);
     if(ptr2)
     output_low(pin_c4);
    }
else{
     s0[j]=ch;           
     if(j<19)
     j++;                           
    }
}
}
}




Sal.

BTW the ans. to your question is T&T
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Wed May 26, 2010 7:49 am     Reply with quote

Code:
BYTE bgetc() {
BYTE c;

while(i>0) ;
c=buffer[i]; //        I think my problem lies here
i++;
return(c);
}


i really dont understand what you are trying to do there....

while(i>0) ; why are you waiting here? what for? until when exactly? until your buffer resets? if your buffer is empty and no chars have reached this part... the condition will fail....i dont get it..
also, if your intention is just to wait in the while loop

while(i>0){} would work ...... while (i>0); looks funky.... i remember somthing about not putting semicolons after while loops.....


i think your doing alot of unnessesary work and need to focus on smaller tasks....


.... my circular buffer is in my ISR ... much like you did on the previous code....

a circular buffer its just an array that loops .... when it fills up it starts to over write the older entries.... say Array[5] fills up, when position 4 is ocupied, the next char will be saved in possition 0, then the next in possition 1 and so on until possition 4 is reached... at which point it loops back to possition cero,,,,, loops... circular buffer....

Code:
int_rda
void serial_isr() {
buffer[i]=getc();
i++;
if(i==24)
i=0;           // Buffer full ...reset it !!
}


do this

build your ISR like the one you have now... a larger buffer wouldnt hurt... i use 70 chars.....

now... send your commands... wait for the comand to execute and your cell will respond... filling your buffer up.... then look for the string in the buffer......i always reset my buffer after each command so that each command over writes the previous.... you only need to do it when you call for the cell to spit out the txt msg cause you are not really checking for the "ok" or any other reply.... but from what i see.. you are trying to use the CNMI alert as the trigger to toggle your LED and not the actual sms content....which one is it?

using the CNMI alert is much simpler and requires no parsing of any buffer....
but then again... ANY sms will toggle on/off the LED or what ever you are trying to control....


gabriel
_________________
CCS PCM 5.078 & CCS PCH 5.093
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Wed May 26, 2010 11:19 am     Reply with quote

OK. Advice taken. I tried doing something like this but when I enter "123" nothing happens. I expected to turn on pin_c4........then turn it off again with "321". .............THIS IS VERY FRUSTRATING !!!!!!
Code:
#int_rda
void serial_isr() {
buffer[i]=getc();
i++;
if(i==31)
i=0;           // Buffer full !!
}

void main(){
delay_ms(1000);
enable_interrupts(global);
enable_interrupts(int_rda);
i=0;

while(TRUE){
                            //Now have a character
ch=buffer[i];                      //get the character
   if(ch=='\r'){                 //Have a carriage return
     buffer[i]='\0';             //null terminate string
     i=0;                           //reset to start looking again
     
     ptr1=strstr(buffer, s1);
     ptr2=strstr(buffer, s2);       //Now do the searches
     
     if(ptr1)
     output_high(pin_c4);
     if(ptr2)
     output_low(pin_c4);
    }                             //and update the counter
    }
}
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Wed May 26, 2010 3:20 pm     Reply with quote

Forget your code... ill take you from the start....baby steps....im by no means trying to be condescending or anything.... honest attempt at helping... organizing and working in small steps is the first issue....

scratch your code ( start a new project)

write a program that can print to hyperterminal

AT \r
AT+CPMS (and its according set up for your phone...) \r
AT+CMGF (PDU mode..if not supported..set the mode you do support) \r
AT+CNMI (and its according set up for your phone...) \r

include a delay of 1 second after sending the \r after the command. during this one second... your phone will accept the command and reply.... for now... you could care less what it is answering....

and lets stop here for now....

at this point your cellphone will be ready and upon recieving an SMS
it will output a string like : "+CMTI" .... but you still dont care....

as your ISR routine use this:

Code:
#INT_RDA
void SerialInt()
{
   Recieve_String[counter_read]=getchar();
   counter_read++;
   if(counter_read==69)counter_read=0;
}


you need to declare as globals the array:
Char Recieve_String[70];
and
Int counter_read;


be sure to enable interrupts....

even though you have the ISR and you are storing the characters comming in from the phone.... dont even try to play with the buffer or search anything on it ... YET.

so at this point you can print the commands you want to send to the phone on hyperterminal...with the appropiate delays between them and you should have also set up a working ISR with a circular buffer ( i gave you the code for it) ....


i think this should be simple enough and will get you on the right path...

this should be a VERY short program .... post the full code...

gabriel...
_________________
CCS PCM 5.078 & CCS PCH 5.093
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Wed May 26, 2010 6:37 pm     Reply with quote

Ok after 8 months of trying, I'm starting over and putting my confidence into your hands...

As you requested:

Code:
#include <16F876A.h>
#include <string.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7)

Char Recieve_String[70];
Int counter_read;

#INT_RDA
void SerialInt()
{
   Recieve_String[counter_read]=getchar();
   counter_read++;
   if(counter_read==69)counter_read=0;
}

void main() {

delay_ms(500);
enable_interrupts(global);
enable_interrupts(int_rda);

puts("ATE0");              // Used to turn echo off.
delay_ms(1000);         
puts("at+clip=1");     
delay_ms(1000);                   
puts("at+cpms=mt,mt,mt");
delay_ms(1000);           // wait for phone to reply
puts("at+csms=1");
delay_ms(1000);              // wait for phone to reply
puts("at+cnmi=1,2,0,0,1");
delay_ms(1000);             // wait for phone to reply
}
 


This program prints the above commands to the screen in CCS's SIOW.
I can see my mobile responding accordingly each time.
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Thu May 27, 2010 5:49 am     Reply with quote

wicked.....

now your program sets the phone to recieve txt...

well youve basically set up an alarm that will tell you when you have an incoming sms..... (at+Cnmi)

also youve set up the memory locations to save and read the incoming sms.... i dont know the settings from your phone but i suggest you use the memory locations of the phone... not the sim card.... use the most basic / local mem location you have.... i will assume "mt" is the same as the "ME" i use for my phone...... but i digress....



so your program now just runs once and it stops....you never loop. .... will do that later.

you can do 2 things from here... depending on your specific needs implement which ever one you want..

ONE:
1) you can reset your buffer counter ( Counter_read)
2) make a while loop that stays in there untill you recieve a character from the phone....this should happen when you recieve an sms....and it should be a string like "+CNMI"..... you will know you have recieved a char because "counter_read" will not be CERO any more...
3) when you exit the while loop... wait 1 sec to allow all remaining chars to arrive....
4) you can trigger an event now.... aka toggle led...

the problem with this set up is that any sms will trigger an event....


or

TWO:
1) you can reset your buffer counter ( Counter_read)
2) make a while loop that stays in there untill you recieve a character from the phone....this should happen when you recieve an sms....and it should be a string like "+CNMI"..... you will know you have recieved a char because "counter_read" will not be CERO any more...
3) when you exit the while loop... wait 1 sec to allow all remaining chars to arrive....
4) execute the "read SMS" AT command AT+CMGR=1
5) decode your sms and use the txt string as a command for a specific action....this is harder ...obviously but its not that complicated...

you need to decide what you want to do.

for now the new task is:

reset counter_read = 0;
prepare a while loop after your last AT command + delay
this while loop does nothing, it just waits until counter_read becomes other than 0......when counter_read is other than cero.... exit the loop and light a LED.... just for kicks....

when you have your program running with these small additions

hook up your cellphone... let the code run and when its stuck in the loop waiting for a char... send it one sms....

the cellphone "should" output the +CNMI alert, breaking out of the loop and lighting your LED;


gabriel
_________________
CCS PCM 5.078 & CCS PCH 5.093
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group