GSM

Hi, can you help me understand this code:

char Rx_data[50];
unsigned char Rx_index = 0;
char msg[160];
void send_msg(char *number, char *msg)
{
  char at_cmgs_cmd[30] = {'\0'};
  char msg1[160] = {'\0'};
  char ctl_z = 0x1A;

  sprintf(msg1, "%s%c", msg, ctl_z);
  sprintf(at_cmgs_cmd, "AT+CMGS=\"%s\"\r\n",number);
  
  sendGSM(at_cmgs_cmd);
  delay(100);
  delay(100);
  delay(100);
  sendGSM(msg1);
  delay(100);
}

void sendGSM(char *string){
  Serial.write(string);
  delay(90);
}

i wanted to use this to send an sms when a certain level is reached, it indeed send an sms but it continuously sends, how can i make it send a single text message?

this is how i use it to send:

void loop(){
if(x>y){
send_msg("09xxxxxxxxx", "LIMIT HAS BEEN REACHED");

thank you so much for the help guys.. :slight_smile:

You need to establish values for x and y, of course. Whatever that entails, checking the value of the millis() function or some external input (switch closure changing the signal level on one of the digital inputs?)

AT+CMGS is a 'AT command' which is the typical method of controlling modems, such as the GSM unit you have. The command consists of the command itself, the number to dial, a newline, the SMS text to send and a command terminator (which you do not seem to include). a ctl-Z, esc or some such character is sent to tell the modem 'that's the entire message, now send it'.

Thank you so much JohnHoward, can you correct my codes? to make me understand, i am new to AT commands. This code send me 2 kinds of message. why is that so?

I already exhausted my limited knowledge regarding the subject. Sorry. I know that "AT+CMGS" is a single command and it requires certain data to follow for it to be a complete command for the modem. The code you showed actually just sends one command, in two steps.

Try Googling for GSM AT command or GSM modem. In particular, search for whatever the model number is for your module. http://sparkfun.com may be a useful place to look, too.

You may be more comfortable with other than English docs. I expect that your language of choice is equally available, perhaps Chinese from your name.

Good luck to you.

I have a list of AT command, my problem is how will i code it to send a single message and how to terminate that message. Thank you again, your help is greatly appreciated.

How about:

char message_has_been_sent = 0;

void loop()
{
  if (x > y && message_has_been_sent == 0) {
    send_msg("09xxxxxxxxx", "LIMIT HAS BEEN REACHED");
    message_has_been_sent = 1;
  }
}

Thank you for that suggestion sir gardner :).. I'll try it later..

It does not work sir :(. Any suggestion?

Sir it works! thank you! but it only send sms once. what if i wanted to send message if another condition is met? example..

char message_has_been_sent = 0;

void loop()
{
  if (x > y && message_has_been_sent == 0) {
    send_msg("09xxxxxxxxx", "LIMIT HAS BEEN REACHED");
    message_has_been_sent = 1;
  }

 if(w>z  && message_has_been_sent == 0) {
    send_msg("09xxxxxxxxx", "POWER LOST");
    message_has_been_sent = 1;
}
}

when x>y is first achieved it send the message but when w>z happens after x>y happen, it cannot send a message..

Thank you for the help! I appreciate it alot! :slight_smile:

what if i wanted to send message if another condition is met?

Then use another flag. Perhaps something called JoeSureHasACuteDaughter? Or, just maybe, a name that makes some sense to YOU.

Hi sir PaulS.. this is my code:

char message_has_been_sent2 = 0;
  char message_has_been_sent3 = 0;
  char message_has_been_sent4 = 0;
  char message_has_been_sent5 = 0;

void loop(){
 if(digitalRead(acpower) == LOW && message_has_been_sent2 == 0)
  {
    send_msg("09xxxxxxxxx", "POWER HAS BEEN LOST");
    message_has_been_sent2 = 1;
  }
  
  if(digitalRead(acpower) == HIGH && message_has_been_sent3 == 0)
  {
    send_msg("09xxxxxxxxx", "POWER OBTAINED");
    message_has_been_sent3 = 1;
  } 
  
  if (percent >= 20 && percent < 40 && message_has_been_sent4 == 0)
  {
    digitalWrite(twenty, HIGH); // 20% is consumed
    digitalWrite(forty, LOW); // 40% is consumed
    digitalWrite(sixty, LOW); // 60% is consumed
    digitalWrite(eighty, LOW); // 80% is consumed
    digitalWrite(hundred, LOW); // When the limit is reached, disconnect
    
    send_msg("09xxxxxxxxx", "20% Consumed");
    message_has_been_sent4 = 1;
  }
  
  if (percent >= 40 && percent < 60 && message_has_been_sent5 == 0)
  {
    digitalWrite(twenty, LOW); // 20% is consumed
    digitalWrite(forty, HIGH); // 40% is consumed
    digitalWrite(sixty, LOW); // 60% is consumed
    digitalWrite(eighty, LOW); // 80% is consumed
    digitalWrite(hundred, LOW); // When the limit is reached, disconnect
    
    send_msg("09xxxxxxxxx", "40% Consumed");
    message_has_been_sent5 = 1;
  }
}

my problem here is for example when power is lost the module will send to you the message "POWER LOST" and when the power is back it will send "POWER OBTAINED" however when the power is lost again the module wont send the message "POWER LOST". why is that so?

why is that so?

Because you are using dumb names.

powerLostMessageSent and powerRestoredMessageSent would make more sense. When power has been restored, it's no longer lost, is it? Why not reset that flag, then?

The flags should be bools, not ints, so you can use true and false, rather than 0 and 1.

how should i declare codes to make it reset? :slight_smile:

how should i declare codes to make it reset?

someFlagWithSomeStupidName = someOtherValue;