Need help with programming FONA

This is a special forum devoted to educators using Adafruit and Arduino products for teaching.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
d32en
 
Posts: 5
Joined: Sat Mar 21, 2015 2:12 am

Need help with programming FONA

Post by d32en »

Hi! I have successfully connected Fona + Uno, can send and receive SMS , but I do not know how to write code that will allow me to decode the received sms and enable output.
please show me the direction . Thank you!

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Need help with programming FONA

Post by adafruit_support_rick »

You want to parse the SMS messages you receive? What is the format of the messages?

User avatar
d32en
 
Posts: 5
Joined: Sat Mar 21, 2015 2:12 am

Re: Need help with programming FONA

Post by d32en »

adafruit_support_rick wrote:You want to parse the SMS messages you receive? What is the format of the messages?
Hi! Yes , I want to parse the message and perform an action using output UNO.
The format of the message may be of the type "OUT 1 ON", "OUT 1 OFF"

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Need help with programming FONA

Post by adafruit_support_rick »

OK, so you have your sms message in a buffer. Let's call it smsBuffer.
smsBuffer is a character array containing the SMS message.

You can now use the sscanf function to parse out your message. You have three fields in your message: the command "OUT", the pin number, and the pin value, "ON" or "OFF". sscanf uses a format string to identify the expected fields in a character buffer, and it parses them out to a set of variables. It returns the number of fields it successfully parsed.

Code: Select all

char command[4];  //command string
int pin;   //pin number
char cmdValue[4];     // value string
int numFields = (smsBuffer, "%s %d %s", command, &pin, cmdValue);
In the format string, '%s' means match a string of non-whitespace characters. %d means match a decimal number.

In your code, make sure that numFields is equal to 3 before you proceed with anything.

You can use the strncmp function to check the values of command and cmdValue. strcmp return 0 when its two string arguments match:

Code: Select all

if (3 == numFields)
{
  if (0 == strncmp(command, "OUT", 3))
  {
    if (0==strncmp(cmdValue, "ON", 2))
    {
      digitalWrite(pin, HIGH);
    }
    else
    {
      if (0==strncmp(cmdValue, "OFF", 3))
      {
        digitalWrite(pin, LOW);
      }
    }
  }
}

User avatar
d32en
 
Posts: 5
Joined: Sat Mar 21, 2015 2:12 am

Re: Need help with programming FONA

Post by d32en »

adafruit_support_rick wrote:OK, so you have your sms message in a buffer. Let's call it smsBuffer.
smsBuffer is a character array containing the SMS message.

You can now use the sscanf function to parse out your message. You have three fields in your message: the command "OUT", the pin number, and the pin value, "ON" or "OFF". sscanf uses a format string to identify the expected fields in a character buffer, and it parses them out to a set of variables. It returns the number of fields it successfully parsed.

Code: Select all

char command[4];  //command string
int pin;   //pin number
char cmdValue[4];     // value string
int numFields = (smsBuffer, "%s %d %s", command, &pin, cmdValue);
In the format string, '%s' means match a string of non-whitespace characters. %d means match a decimal number.

In your code, make sure that numFields is equal to 3 before you proceed with anything.

You can use the strncmp function to check the values of command and cmdValue. strcmp return 0 when its two string arguments match:

Code: Select all

if (3 == numFields)
{
  if (0 == strncmp(command, "OUT", 3))
  {
    if (0==strncmp(cmdValue, "ON", 2))
    {
      digitalWrite(pin, HIGH);
    }
    else
    {
      if (0==strncmp(cmdValue, "OFF", 3))
      {
        digitalWrite(pin, LOW);
      }
    }
  }
}

I feel very sorry , but I forgot to say that I am a beginner programmer , very beginner ...
maybe it's blatantly on my part, but you can get the complete code ( at least from a possible ) with an explanation .
And so I am very grateful for the help.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Need help with programming FONA

Post by adafruit_support_rick »

Sorry, but I really can't program your project for you.

User avatar
d32en
 
Posts: 5
Joined: Sat Mar 21, 2015 2:12 am

Re: Need help with programming FONA

Post by d32en »

thanks for the quick help

User avatar
d32en
 
Posts: 5
Joined: Sat Mar 21, 2015 2:12 am

Re: Need help with programming FONA

Post by d32en »

Need help finding errors in the sketch .
Need your help in finding errors in the sketch .
I want to connect FONA + Arduino Uno, the sketch was kindly provided by Adafrtuit.
The process of compiling does not end very long time , what is it please help!

http://ubidots.com/docs/devices/FONA.html

Code: Select all

/* Chip McClelland - Cellular Data Logger
     BSD license, Please keep my name and the required Adafruit text in any redistribution

  This sketch will connect to Ubidots and periodically upload the current temperature and humidity as well as the number
  of times a PIR sensor has detected a person. The counts are then reset and you can access the data on your Ubidots account.


  IDE: Arduino 1.0 or later
  I had to add the following line to the Adafruit_FONA.cpp file: typedef

  char PROGMEM prog_char;

  Otherwise this code would not compile

  Hardware - Adafruit Fona GSM Board
  Temperature Sensor - Dummy Code for now
  Person Counter - Dummy Code for now

  I made use of the Adafruit Fona library and parts of the example code

  /***************************************************
  This is an example for our Adafruit FONA Cellular Module

  Designed specifically to work with the Adafruit FONA
  ----> http://www.adafruit.com/products/1946
  ----> http://www.adafruit.com/products/1963

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution

  ****************************************************/

  /***************************************************
  This code has been modified Sep 15 2014
  by Mateo Vélez - Metavix - for Ubidots Inc.

  This code is in the public domain.
  ****************************************************/



#include <HardwareSerial.h>
#include "Adafruit_FONA.h"

#define FONA_RX 1
#define FONA_TX 0
#define FONA_RST 4
#define FONA_KEY 6
#define FONA_PS 7

#define HWSERIAL Serial1


char replybuffer[255];

HardwareSerial fonaSS = Serial1;
Adafruit_FONA fona = Adafruit_FONA(&fonaSS, FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);


int Interval = 10000;             // Time between measurements in seconds
int KeyTime = 2000;               // Time needed to turn on the Fona
unsigned long Reporting = 30000;  // Time between uploads to Ubidots
unsigned long TimeOut = 30000;    // How long we will give an AT command to comeplete
unsigned long LastReading = 0;    // When did we last read the sensors - they are slow so will read between sends
unsigned long LastReporting = 0;  // When did we last send data to Ubidots
uint8_t n=0;
int f = 0;
int PersonCount = 0;

void setup() {
  delay(3000);
  HWSERIAL.begin(4800);
  Serial.begin(9600);

  Serial.println("Started setup");

  pinMode(FONA_KEY,OUTPUT);                                    // This is the pin used to turn on and off the Fona
  TurnOnFona();
  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));   // See if the FONA is responding
  if (! fona.begin(4800)) {                                    // make it slow so its easy to read!
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  GetConnected();
  Serial.println(F("FONA is OK"));
  TurnOffFona();

}


void loop() {
  Serial.println("in Loop");
  delay(2000);
  int value = analogRead(A0);
  if (LastReporting + Reporting <= millis()) {   // This checks to see if it is time to send to Ubidots
    TurnOnFona();                                // Turn on the module
    GetConnected();                              // Connect to network and start GPRS
    Send2Ubidots(String(value));                 // Send data to Ubidots
    GetDisconnected();                           // Disconnect from GPRS
    TurnOffFona();                               // Turn off the modeule
    LastReporting = millis();
  }

  if (LastReading + Interval <= millis()) {     // This checks to see if it is time to take a sensor reading
    f ++;                 //Do some math to convert the Celsius to Fahrenheit
    PersonCount ++;
    Serial.print(F("The current Temperature is: "));
    Serial.print(f);                             //Send the temperature in degrees F to the serial monitor
    Serial.print(F("F "));
    LastReading = millis();                     // Record the time of the last sensor readings
  }


}

// This function is to send the sensor data to Ubidots - each step is commented in the serial terminal
void Send2ubidots(String value)
{

  int num;
  String le;
  String var;
  var = "{\"value\":"+ value + "}";           //value is the sensor value
  num = var.length();
  le = String(num);                           //this is to calcule the length of var

  Serial.print(F("Start the connection to Ubidots: "));
  if (SendATCommand("AT+CIPSTART=\"tcp\",\"things.ubidots.com",\"80\"",'C','T')) {
    Serial.println("Connected");
  }
  Serial.print(F("Begin to send data to the remote server: "));
  if (SendATCommand("AT+CIPSEND",'\n','>')) {
    Serial.println("Sending");
  }
 fona.println("POST /api/v1.6/variables/550d213776254253aa33d33c/values HTTP/1.1");           // My  ID #
 fona.println("Content-Type: application/json");
 fona.println("Content-Length: "+le");
 fona.println("X-Auth-Token: dGC0eEi6DlJzPEhR22qZKJdrz9Ddr3dXLfFvh8uXQwnHcjmm7HMQesvX2ij0");                                    // My Ubidots Token #
 fona.println("Host: things.ubidots.com");
 fona.println();
 fona.println(var);
 fona.println();
 fona.println((char)26);                                       //This ends the JSON SEND with a carriage return
 Serial.print(F("Send JSON Package: "));
 if (SendATCommand("",'2','0')) {                              // The 200 code from Ubidots means it was successfully uploaded
    Serial.println("Sent");
     PersonCount = 0;
  }
  else {
    Serial.println("Send Timed out, will retry at next interval");
  }
 // delay(2000);
 Serial.print(F("Close connection to Ubidots: "));              // Close the connection
 if (SendATCommand("AT+CIPCLOSE",'G','M')) {
    Serial.println("Closed");
  }
}

boolean SendATCommand(char Command[], char Value1, char Value2) {
 unsigned char buffer[64];                                  // buffer array for data recieve over serial port
 int count = 0;
 int complete = 0;
 unsigned long commandClock = millis();                      // Start the timeout clock
 fona.println(Command);
 while(!complete && commandClock <= millis()+TimeOut)         // Need to give the modem time to complete command
 {
   while(!fona.available() && commandClock <= millis()+TimeOut);
   while(fona.available()) {                                 // reading data into char array
     buffer[count++]=fona.read();                            // writing data into array
     if(count == 64) break;
   }
   Serial.write(buffer,count);                           // Uncomment if needed to debug
   for (int i=0; i <= count; i++) {
     if(buffer[i]==Value1 && buffer[i+1]==Value2) complete = 1;
   }
 }
 if (complete ==1) return 1;                              // Returns "True"  - "False" sticks in the loop for now
 else return 0;
}

void TurnOnFona()
{
  Serial.print("Turning on Fona: ");
  while(digitalRead(FONA_PS))
  {
    digitalWrite(FONA_KEY,LOW);
    unsigned long KeyPress = millis();
    while(KeyPress + KeyTime >= millis()) {}
    digitalWrite(FONA_KEY,HIGH);
  }
  fona.begin(4800);
  Serial.println("success!");
}

void GetConnected()
{
  do
  {
    n = fona.getNetworkStatus();  // Read the Network / Cellular Status
    Serial.print(F("Network status "));
    Serial.print(n);
    Serial.print(F(": "));
      if (n == 0) Serial.println(F("Not registered"));
      if (n == 1) Serial.println(F("Registered (home)"));
      if (n == 2) Serial.println(F("Not registered (searching)"));
      if (n == 3) Serial.println(F("Denied"));
      if (n == 4) Serial.println(F("Unknown"));
      if (n == 5) Serial.println(F("Registered roaming"));
  } while (n != 1);
}

void GetDisconnected()
{
  fona.enableGPRS(false);
  Serial.println(F("GPRS Serivces Started"));
}

void TurnOffFona()
{
  Serial.print("Turning off Fona: ");
  while(digitalRead(FONA_PS))
  {
    digitalWrite(FONA_KEY,LOW);
    unsigned long KeyPress = millis();
    while(KeyPress + KeyTime >= millis()) {}
    digitalWrite(FONA_KEY,HIGH);
  }
  Serial.println("success!");
}

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Need help with programming FONA

Post by adafruit_support_rick »

Wow - what a mess. Fist of all, that sketch is using an outdated version of the FONA library. Second, it's not written for a Uno - it's written for a Leonardo or a Mega. Third, it had several syntax errors. I presume I fixed them correctly.

Anyway, this version of the sketch at least compiles. You will have to connect FONA TX to Uno pin 2, and FONA RX to Uno pin 3:

Code: Select all

/* Chip McClelland - Cellular Data Logger
     BSD license, Please keep my name and the required Adafruit text in any redistribution

  This sketch will connect to Ubidots and periodically upload the current temperature and humidity as well as the number
  of times a PIR sensor has detected a person. The counts are then reset and you can access the data on your Ubidots account.


  IDE: Arduino 1.0 or later
  I had to add the following line to the Adafruit_FONA.cpp file: typedef

  char PROGMEM prog_char;

  Otherwise this code would not compile

  Hardware - Adafruit Fona GSM Board
  Temperature Sensor - Dummy Code for now
  Person Counter - Dummy Code for now

  I made use of the Adafruit Fona library and parts of the example code

  /***************************************************
  This is an example for our Adafruit FONA Cellular Module

  Designed specifically to work with the Adafruit FONA
  ----> http://www.adafruit.com/products/1946
  ----> http://www.adafruit.com/products/1963

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution

  ****************************************************/

  /***************************************************
  This code has been modified Sep 15 2014
  by Mateo Vélez - Metavix - for Ubidots Inc.

  This code is in the public domain.
  ****************************************************/



#include <SoftwareSerial.h>
#include "Adafruit_FONA.h"

#define FONA_RX 1
#define FONA_TX 0
#define FONA_RST 4
#define FONA_KEY 6
#define FONA_PS 7

//#define HWSERIAL Serial1


char replybuffer[255];

SoftwareSerial fonaSS = SoftwareSerial(2,3);
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);


int Interval = 10000;             // Time between measurements in seconds
int KeyTime = 2000;               // Time needed to turn on the Fona
unsigned long Reporting = 30000;  // Time between uploads to Ubidots
unsigned long TimeOut = 30000;    // How long we will give an AT command to comeplete
unsigned long LastReading = 0;    // When did we last read the sensors - they are slow so will read between sends
unsigned long LastReporting = 0;  // When did we last send data to Ubidots
uint8_t n=0;
int f = 0;
int PersonCount = 0;

void setup() {
  delay(3000);
  fonaSS.begin(4800);
  Serial.begin(9600);

  Serial.println("Started setup");

  pinMode(FONA_KEY,OUTPUT);                                    // This is the pin used to turn on and off the Fona
  TurnOnFona();
  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));   // See if the FONA is responding
  if (! fona.begin(fonaSS)) {                                    // make it slow so its easy to read!
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  GetConnected();
  Serial.println(F("FONA is OK"));
  TurnOffFona();

}


void loop() {
  Serial.println("in Loop");
  delay(2000);
  int value = analogRead(A0);
  if (LastReporting + Reporting <= millis()) {   // This checks to see if it is time to send to Ubidots
    TurnOnFona();                                // Turn on the module
    GetConnected();                              // Connect to network and start GPRS
    Send2ubidots(String(value));                 // Send data to Ubidots
    GetDisconnected();                           // Disconnect from GPRS
    TurnOffFona();                               // Turn off the modeule
    LastReporting = millis();
  }

  if (LastReading + Interval <= millis()) {     // This checks to see if it is time to take a sensor reading
    f ++;                 //Do some math to convert the Celsius to Fahrenheit
    PersonCount ++;
    Serial.print(F("The current Temperature is: "));
    Serial.print(f);                             //Send the temperature in degrees F to the serial monitor
    Serial.print(F("F "));
    LastReading = millis();                     // Record the time of the last sensor readings
  }


}

// This function is to send the sensor data to Ubidots - each step is commented in the serial terminal
void Send2ubidots(String value)
{

  int num;
  String le;
  String var;
  var = "{\"value\":"+ value + "}";           //value is the sensor value
  num = var.length();
  le = String(num);                           //this is to calcule the length of var

  Serial.print(F("Start the connection to Ubidots: "));
  if (SendATCommand("AT+CIPSTART=\"tcp\",\"things.ubidots.com\",\"80\"",'C','T')) {
    Serial.println("Connected");
  }
  Serial.print(F("Begin to send data to the remote server: "));
  if (SendATCommand("AT+CIPSEND",'\n','>')) {
    Serial.println("Sending");
  }
 fona.println("POST /api/v1.6/variables/550d213776254253aa33d33c/values HTTP/1.1");           // My  ID #
 fona.println("Content-Type: application/json");
 fona.print("Content-Length: "); fona.println(le);
 fona.println("X-Auth-Token: dGC0eEi6DlJzPEhR22qZKJdrz9Ddr3dXLfFvh8uXQwnHcjmm7HMQesvX2ij0");                                    // My Ubidots Token #
 fona.println("Host: things.ubidots.com");
 fona.println();
 fona.println(var);
 fona.println();
 fona.println((char)26);                                       //This ends the JSON SEND with a carriage return
 Serial.print(F("Send JSON Package: "));
 if (SendATCommand("",'2','0')) {                              // The 200 code from Ubidots means it was successfully uploaded
    Serial.println("Sent");
     PersonCount = 0;
  }
  else {
    Serial.println("Send Timed out, will retry at next interval");
  }
 // delay(2000);
 Serial.print(F("Close connection to Ubidots: "));              // Close the connection
 if (SendATCommand("AT+CIPCLOSE",'G','M')) {
    Serial.println("Closed");
  }
}

boolean SendATCommand(char Command[], char Value1, char Value2) {
 unsigned char buffer[64];                                  // buffer array for data recieve over serial port
 int count = 0;
 int complete = 0;
 unsigned long commandClock = millis();                      // Start the timeout clock
 fona.println(Command);
 while(!complete && commandClock <= millis()+TimeOut)         // Need to give the modem time to complete command
 {
   while(!fona.available() && commandClock <= millis()+TimeOut);
   while(fona.available()) {                                 // reading data into char array
     buffer[count++]=fona.read();                            // writing data into array
     if(count == 64) break;
   }
   Serial.write(buffer,count);                           // Uncomment if needed to debug
   for (int i=0; i <= count; i++) {
     if(buffer[i]==Value1 && buffer[i+1]==Value2) complete = 1;
   }
 }
 if (complete ==1) return 1;                              // Returns "True"  - "False" sticks in the loop for now
 else return 0;
}

void TurnOnFona()
{
  Serial.print("Turning on Fona: ");
  while(digitalRead(FONA_PS))
  {
    digitalWrite(FONA_KEY,LOW);
    unsigned long KeyPress = millis();
    while(KeyPress + KeyTime >= millis()) {}
    digitalWrite(FONA_KEY,HIGH);
  }
  fona.begin(fonaSS);
  Serial.println("success!");
}

void GetConnected()
{
  do
  {
    n = fona.getNetworkStatus();  // Read the Network / Cellular Status
    Serial.print(F("Network status "));
    Serial.print(n);
    Serial.print(F(": "));
      if (n == 0) Serial.println(F("Not registered"));
      if (n == 1) Serial.println(F("Registered (home)"));
      if (n == 2) Serial.println(F("Not registered (searching)"));
      if (n == 3) Serial.println(F("Denied"));
      if (n == 4) Serial.println(F("Unknown"));
      if (n == 5) Serial.println(F("Registered roaming"));
  } while (n != 1);
}

void GetDisconnected()
{
  fona.enableGPRS(false);
  Serial.println(F("GPRS Serivces Started"));
}

void TurnOffFona()
{
  Serial.print("Turning off Fona: ");
  while(digitalRead(FONA_PS))
  {
    digitalWrite(FONA_KEY,LOW);
    unsigned long KeyPress = millis();
    while(KeyPress + KeyTime >= millis()) {}
    digitalWrite(FONA_KEY,HIGH);
  }
  Serial.println("success!");
}

Locked
Please be positive and constructive with your questions and comments.

Return to “For Educators”