Programming help needed- GPRS POST for FONA 3G library

Adafruit cellular platform - SMS and IoT over celluar

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
biod101
 
Posts: 183
Joined: Sun Apr 19, 2015 4:21 pm

Re: Programming help needed- GPRS POST for FONA 3G library

Post by biod101 »

Thanks to you all for your hard work on this. I have been distracted by my real 9-5 job with little time to contribute, but I'm going to carve out some time this Friday to test the latest.

smgs
 
Posts: 194
Joined: Thu Dec 10, 2015 7:25 am

Re: Programming help needed- GPRS POST for FONA 3G library

Post by smgs »

I think this snippet of my Arduino Syntax for doing either a http(s) get or post, is close it just needs to be correctly formatted:

Code: Select all

  Serial.println("We are now about to run code to download or recieve a web page from a Test Apache Server in AWS");
  // Open a http session, on port 80, type 1 defines request runnning without SSL, i.e. straight http (type 2 would be https)
  fona.sendCheckReply(F("AT+CHTTPSOPSE=\"52.63.126.1\",80,1"), ok_reply);
  delay(300); //wait between AT commands
  // Send a http request of a particular length, ours is 38 characters, where <cr> would be one character etc.
  fona.write("AT+CHTTPSSEND=38");
  // cr = carriage return
  // lf = line feed
  fona.write("<cr><lf>GET / HTTP/1.1<cr><lf>Host:52.63.126.1<cr><lf><cr><lf>");
  delay(5000); //wait 5 seconds for the http request to go out
  // Recieve the https response from the server after sending the https request
  fona.sendParseReply(F("AT+CHTTPSRECV=365"), F("+CHTTPSRECV:"), httpResponse);

  delay(9000); //wait between AT commands


  // Try one of frankieinmelbournes ideas around using the chttpopse with the GET command syntax
  // we are trying to hit request bin...
  Serial.println("Try and post some data to request bin just for funseys, using a different method to above");
  fona.sendCheckReply(F("AT+CHTTPSOPSE=\"http://requestb.in/1nbtxin1\",80,1"), ok_reply);
  delay(300); //wait between AT commands
  fona.sendCheckReply(F("AT+CHTTPSSEND=75"), ok_reply);
  fona.write("This is some data from my FONA 3G Device that I am putting on the Internets");
  delay(5000); //wait between AT commands

  
  // Try the same thing but with a crack at guessing what some http headers should look like
  // we are trying to hit request bin... with 75 1's + some http header syntax
  Serial.println("Same post again in a different syntax");
  fona.sendCheckReply(F("AT+CHTTPSOPSE=\"http://requestb.in/1nbtxin1\",80,2"), ok_reply);
  fona.sendCheckReply(F("AT+CHTTPSSEND=123"), ok_reply);
  fona.sendCheckReply(F("<cr><lf>POST / HTTP/1.1 <cr><lf>Host:requestb.in<cr><lf>Accept:111111111111111111111111111111111111111111111111111111111111111111111111111<cr><lf>"), ok_reply);
Please Note:
I have modified my FONA library header file to move a couple of protected classes into the public space so i can try and use them: (Adafruit_FONA.h")

Code: Select all

class Adafruit_FONA_3G : public Adafruit_FONA {

 public:
  Adafruit_FONA_3G (int8_t r) : Adafruit_FONA(r) { _type = FONA3G_A; }

    boolean getBattVoltage(uint16_t *v);
    boolean playToolkitTone(uint8_t t, uint16_t len);
    boolean hangUp(void);
    boolean pickUp(void);
    boolean enableGPRS(boolean onoff);
    boolean enableGPS(boolean onoff);
	boolean parseReply(FONAFlashStringPtr toreply,
		float *f, char divider, uint8_t index);

    boolean sendParseReply(FONAFlashStringPtr tosend,
		FONAFlashStringPtr toreply,
		float *f, char divider = ',', uint8_t index=0);
		
 protected:

};

#endif
This is the output that I am getting on the Serial Monitor:

Code: Select all

We are now about to run code to download or receive a web page from a Test Apache Server in AWS
	---> AT+CHTTPSOPSE="52.63.126.1",80,1
	<--- 
	---> AT+CHTTPSRECV=365
	<--- OK
Try and post some data to request bin just for funseys, using a different method to above
	---> AT+CHTTPSOPSE="http://requestb.in/1nbtxin1",80,1
	<--- ERROR
	---> AT+CHTTPSSEND=75
	<--- >
Same post again in a different syntax
	---> AT+CHTTPSOPSE="http://requestb.in/1nbtxin1",80,2
	<--- 
	---> AT+CHTTPSSEND=123
	<--- 
	---> <cr><lf>POST / HTTP/1.1 <cr><lf>Host:requestb.in<cr><lf>Accept:111111111111111111111111111111111111111111111111111111111111111111111111111<cr><lf>
	<--- OK
Stopping and closing the HTTPS Stack!
	---> AT+CHTTPSCLSE
	<--- 
	---> AT+CHTTPSSTOP
	<--- 
	---> AT+NETCLOSE
	<--- OK
Failed to turn off
Strangley it seems this code is getting close to actually working, also wierdly is that it doesn't disconnect from the GPRS. This really drains the little battery I have, will need to purchase a new one me thinks.

User avatar
biod101
 
Posts: 183
Joined: Sun Apr 19, 2015 4:21 pm

Re: Programming help needed- GPRS POST for FONA 3G library

Post by biod101 »

Okay - finally carving out a little time for this.

As a sidenote, when logging in today- I spotted activity on a related thread started awhile back. Just as an FYI, see last post by "upndown".

viewtopic.php?f=54&t=103879

I'll point that thread to this one shortly.

User avatar
biod101
 
Posts: 183
Joined: Sun Apr 19, 2015 4:21 pm

Re: Programming help needed- GPRS POST for FONA 3G library

Post by biod101 »

To help me catch up, I've set up some code that will allow me to repeat the AT command sequences you all have tested. My goal is to be able to test the sequence via the Arduino IDE terminal window. What follows is just the setup code and serial passthrough function copied from FONAtest. This does not echo my AT command, but it does send the response from the 3G hardware. This is helping me avoid using other networking applications I'm not familiar with. (i.e. "Coolterm"?)

Code: Select all

#include "Adafruit_FONA.h"

// pins are defined for ProTrinket
#define FONA_RX 8
#define FONA_TX 3 
#define FONA_RST 4

char replybuffer[255];
#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);

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

uint8_t type;

void setup() {
  while (!Serial);

  Serial.begin(115200);
  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));

  fonaSerial->begin(4800);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
}


void loop()
{
  while (Serial.available()) {
            delay(1);
            fona.write(Serial.read());
          }
          if (fona.available()) {
            Serial.write(fona.read());
          }
}
Last edited by biod101 on Fri Feb 17, 2017 7:07 pm, edited 1 time in total.

User avatar
biod101
 
Posts: 183
Joined: Sun Apr 19, 2015 4:21 pm

Re: Programming help needed- GPRS POST for FONA 3G library

Post by biod101 »

Okay - regarding the prior post:
here is the sequence that opens the network, starts HTTPS, opens an HTTPS Session, sends 22 chars, closes the session, closes the network:
AT+NETOPEN

OK

+NETOPEN: 0
AT+CHTTPSSTART

OK
AT+CHTTPSOPSE="www.google.com",443,2

OK
AT+CHTTPSSEND=22

>get get getttttttttttt

OK
AT+CHTTPCLSE

ERROR
AT+CHTTPSCLSE

OK
AT+NETCLOSE

+NETCLOSE: 0

OK
I tried this using the terminal window and serial pass through tunnel.

Results:

AT+NETOPEN - returns same response as frankie's; fast blinky light on 3G- looking good!
AT+CHTTPSSTART - looking good....
AT+CHTTPSOPSE="www.google.com",443,2 - returns an error :(
(since it didn't work, skipping next CHTTP command)
AT+CHTTPSCLSE - error :(
AT+NETCLOSE - returns same response as Frankie's (OK); but fast blinky light on 3G suggests I'm still in GPRS mode.

I then have to restart my terminal window to get the hardware out of GPRS mode. I did try this three separate times to make sure I didn't have any errors in the commands - same pattern every time. On that note, I'll try looking at the other posts and modified libraries and see if I can replicate those particular success.

User avatar
frankieinmelbourne
 
Posts: 9
Joined: Sat Aug 15, 2015 6:06 am

Re: Programming help needed- GPRS POST for FONA 3G library

Post by frankieinmelbourne »

hey biod101

When I was using the serial passthrough channel from the FONA library I was getting the same response (error) as you, after the AT command that tries to connect to google.
But the problem did not appear when the same sequence of command was sent to the FONA using CoolTerm. CoolTerm (look it up on google, or even sparkfun have a nice guide) is a software that allows to communicate using serial port via a USB connection. The sequence that I posted is taken directly from CoolTerm. So the Fona library (the pass through channel at least) is somehow stopping the connection.
Also, similar to you, I had to restart the shield after the errors occurred...

User avatar
biod101
 
Posts: 183
Joined: Sun Apr 19, 2015 4:21 pm

Re: Programming help needed- GPRS POST for FONA 3G library

Post by biod101 »

Thanks Frankie- it helps to have this context.

Regarding:
frankieinmelbourne wrote:When I was using the serial passthrough channel from the FONA library I was getting the same response (error) as you, after the AT command that tries to connect to google. But the problem did not appear when the same sequence of command was sent to the FONA using CoolTerm.
I understand the workaround, but this is sticking point (at least for my application) since I need to fall back on those FONA libraries for my remotely-deployed environmental setup which is using a Trinket to drive the 3G-FONA. From the thread, it looks like some libraries have been developed that will address the need- I will try experimenting with those first chance I get.

Cheers.

User avatar
frankieinmelbourne
 
Posts: 9
Joined: Sat Aug 15, 2015 6:06 am

Re: Programming help needed- GPRS POST for FONA 3G library

Post by frankieinmelbourne »

I'll try them too.
Let's keep this forum active as we (hopefully) make progress.

smgs
 
Posts: 194
Joined: Thu Dec 10, 2015 7:25 am

Re: Programming help needed- GPRS POST for FONA 3G library

Post by smgs »

Try modifying your basic serial sketch to send a BANNED like this:

Code: Select all

fona.sendCheckReply(F("AT+CHTTPSOPSE=\"http://requestb.in/1nbtxin1\",80,2"), ok_reply);
  fona.sendCheckReply(F("AT+CHTTPSSEND=123"), ok_reply);
  fona.sendCheckReply(F("<cr><lf>POST / HTTP/1.1 <cr><lf>Host:requestb.in<cr><lf>Accept:111111111111111111111111111111111111111111111111111111111111111111111111111<cr><lf>"), ok_reply);
Before you can send that command your setup needs to enable the GPRS function on the FONA.

I think the fona.sendCheckReply is accessible without modifying the headers in the FONA library.

smgs
 
Posts: 194
Joined: Thu Dec 10, 2015 7:25 am

Re: Programming help needed- GPRS POST for FONA 3G library

Post by smgs »

This is the full sketch code that should get you close to being able to send a http post via the Arduino:

Code: Select all

/*
 * Author: S M G
 * Date: 20/02/2017
 * Description: Test GPRS Post on the FONA 3G
 * We are attempting to post to the Request Bin
 * You need to change this URL:
 * http://requestb.in/1nbtxin1\
 * 
 * To be a valid URL for your own request Bin or other website for testing post of https data
 */

#include "Adafruit_FONA.h"

#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4

// We default to using software serial. If you want to use hardware serial
// (because softserial isnt supported) comment out the following three lines 
// and uncomment the HardwareSerial line
#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

// Use this one for FONA 3G
Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);
  
//declare the variables we are using in this sketch for the FONA type and some replies etc
uint8_t type;
uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
char  ok_reply = "OK";
char http;
char httpResponse;


void setup() {
  // put your setup code here, to run once:

 while (!Serial);

  Serial.begin(115200);
  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));

  fonaSerial->begin(4800);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case FONA3G_A:
      Serial.println(F("FONA 3G (American)")); break;
    case FONA3G_E:
      Serial.println(F("FONA 3G (European)")); break;
    default: 
      Serial.println(F("???")); break;
  
  } // end of the switch type section
} //end of the Setup Loop

void loop() {
  // put your main code here, to run repeatedly:

  if (fona.available())
    Serial.write(fona.read());

  while (fona.available()) {
    //wait a few seconds before we start the loop
    delay (1000); 

    // Optionally configure a GPRS APN, username, and password.
    // You might need to do this to access your network's GPRS/data
    // network.  Contact your provider for the exact APN, username,
    // and password values.  Username and password are optional and
    // can be removed, but APN is required.
    fona.setGPRSNetworkSettings(F("internet"), F(""), F(""));

    //wait a few more seconds since we have setup the fona network settings for GPRS
    delay (1000);     
    
    // The default FONA way to turn on GPRS
    if (!fona.enableGPRS(true))
      Serial.println(F("Failed to turn on the 3G GPRS module"));
    else
        Serial.println(F("We have turned on the GPRS Function for the 3G FONA module"));

    /* 
    * Start of attempt to try and get a web page...
    * This assumes we have a valid GPRS connection running, it is not clever in any way or doing any pre-checks
    */
    getHTMLPage();
    delay(300);
    disableHTTPS();
      
    delay(100000); // A really long pause so we can disconnect or turn off the FONA
    
  } //end while fona.available loop 
} //end of loop

void enableHTTPS() {
  // turn HTTPS Stack on
    
  Serial.println(F("Starting the HTTPS Stack!"));
  fona.sendParseReply(F("AT+CHTTPSSTART"), F("+CHTTPSSTART"), http);
  Serial.println("Reply was: "); Serial.print(http );
  
} //end of enableHTTPS stack code

void disableHTTPS() {
  // turn HTTPS Stack on

  delay(300); //wait between AT commands
  Serial.println(F("Stopping and closing the HTTPS Stack!"));
  fona.sendCheckReply(F("AT+CHTTPSCLSE"), ok_reply);
  delay(600); //wait between AT commands
  fona.sendCheckReply(F("AT+CHTTPSSTOP"), ok_reply);
  delay(600); //wait between AT commands
  // turn GPRS off
  if (!fona.enableGPRS(false))
    Serial.println(F("Failed to turn off"));
  else
    Serial.println(F("We've turned off your GPRS Connection"));
} //end of enableHTTPS stack code

void getHTMLPage() {
  
  Serial.println("We are now about to run code to download or recieve a web page from a Test Apache Server in AWS");
  // Open a http session, on port 80, type 1 defines request runnning without SSL, i.e. straight http (type 2 would be https)
  fona.sendCheckReply(F("AT+CHTTPSOPSE=\"52.63.126.1\",80,1"), ok_reply);
  delay(300); //wait between AT commands
  // Send a http request of a particular length, ours is 38 characters, where <cr> would be one character etc.
  fona.write("AT+CHTTPSSEND=38");
  // cr = carriage return
  // lf = line feed
  fona.write("<cr><lf>GET / HTTP/1.1<cr><lf>Host:52.63.126.1<cr><lf><cr><lf>");
  delay(5000); //wait 5 seconds for the http request to go out
  // Recieve the https response from the server after sending the https request
  fona.sendParseReply(F("AT+CHTTPSRECV=365"), F("+CHTTPSRECV:"), httpResponse);

  delay(9000); //wait between AT commands


  // Try one of frankieinmelbournes ideas around using the chttpopse with the GET command syntax
  // we are trying to hit request bin...
  Serial.println("Try and post some data to request bin just for funseys, using a different method to above");
  fona.sendCheckReply(F("AT+CHTTPSOPSE=\"http://requestb.in/1nbtxin1\",80,1"), ok_reply);
  delay(300); //wait between AT commands
  fona.sendCheckReply(F("AT+CHTTPSSEND=75"), ok_reply);
  fona.write("This is some data from my FONA 3G Device that I am putting on the Internets");
  delay(5000); //wait between AT commands

  
  // Try the same thing but with a crack at guessing what some http headers should look like
  // we are trying to hit request bin... with 75 1's + some http header syntax
  Serial.println("Same post again in a different syntax");
  fona.sendCheckReply(F("AT+CHTTPSOPSE=\"http://requestb.in/1nbtxin1\",80,2"), ok_reply);
  fona.sendCheckReply(F("AT+CHTTPSSEND=123"), ok_reply);
  fona.sendCheckReply(F("<cr><lf>POST / HTTP/1.1 <cr><lf>Host:requestb.in<cr><lf>Accept:111111111111111111111111111111111111111111111111111111111111111111111111111<cr><lf>"), ok_reply);

  
} // end of the GETHTML Page code
A few notes. Go to this website:
https://requestb.in/
Hit the big green "Create a Request Bin" button and follow the prompts.

If you want to do a manual(ish) test of your new request bin to see how it works then try this website:
http://requestmaker.com/

Let us know if you have any more luck than I did. It didn't send to the Request Bin website for me, but I think it's mostly a syntax problem, maybe it will get you guys closer than you are currently with sending the commands via Arduino code though.

SMG

smgs
 
Posts: 194
Joined: Thu Dec 10, 2015 7:25 am

Re: Programming help needed- GPRS POST for FONA 3G library

Post by smgs »

gerrit wrote:I got POST, GET and PUT request working. Checkout out my fork of the FONA library (mraa branch).
To make a simple POST request, you would need to run FONAtest ( executable of examples/FONAtest/FONAtest.cpp) and type in "U" to unlock the sim card, "G" to open a gprs connection and then "W" to send a post request.

This works on my intel edison but might also work on the raspberry pi ...
I just re-went over your library Gerrit, it's very cool, I like the POST PUT and GET functions you've written up, Will do some testing on the Arduino and see if I can get it to run on there.

Do you have an example of how you actually call those libraries, i.e. the equivalant of a sketch for your intel edison?

smgs
 
Posts: 194
Joined: Thu Dec 10, 2015 7:25 am

Re: Programming help needed- GPRS POST for FONA 3G library

Post by smgs »

gerrit looks to use different line feed and new line characters, I'd been using "<lr>" "<lf>" etc, but maybe we need to try different line feed characters while hooked into the FONA serial interface to get things tested before putting it together into a sketch.

I'm getting a bit over it all today, thinking about just switching to a rasberry pi instead.

smgs
 
Posts: 194
Joined: Thu Dec 10, 2015 7:25 am

Re: Programming help needed- GPRS POST for FONA 3G library

Post by smgs »

Anyone get a chance to try out my sketch and see if it fails the same for you as it did for me?

Also saw something interesting in some code from a guy working on a fona 800 and sending the AT+SDJR command to check if his module is being jammed. He used the fona.write command to send one character at a time:

Code: Select all

        while (1) {//AT+CSCLK=0
          fona.write('A');
          fona.write('T');
          fona.write('+');
          fona.write('S');
          fona.write('J');
          fona.write('D');
          fona.write('R');
          fona.write('=');
          fona.write('1');
          fona.write(',');
          fona.write('1');
          fona.write(',');
          fona.write('5');
          //fona.write('0');
          //fona.write('0');
          fona.write(',');
          fona.write('1');
          fona.write('\r');
          fona.write('\n');
          Serial.write("AT+SJDR=1,3,50,1\r\n");
          delay(1000);
Seems needlessly annoying way to send commands, but it could be worth a try when sending AT commands like the https Open Session command which we seem to be getting stuck with....

User avatar
m4rtinmp
 
Posts: 1
Joined: Thu Feb 16, 2017 11:19 am

Re: Programming help needed- GPRS POST for FONA 3G library

Post by m4rtinmp »

I was able to submit data to a MySql database using 3G module, an arduino and a php script:

Code: Select all


#include "Adafruit_FONA.h"

#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4

char replybuffer[255];

#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);
uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
uint8_t type;

void setup() {
  while (!Serial);

  Serial.begin(115200);
  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));

  fonaSerial->begin(4800);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case FONA800L:
      Serial.println(F("FONA 800L")); break;
    case FONA800H:
      Serial.println(F("FONA 800H")); break;
    case FONA808_V1:
      Serial.println(F("FONA 808 (v1)")); break;
    case FONA808_V2:
      Serial.println(F("FONA 808 (v2)")); break;
    case FONA3G_A:
      Serial.println(F("FONA 3G (American)")); break;
    case FONA3G_E:
      Serial.println(F("FONA 3G (European)")); break;
    default: 
      Serial.println(F("???")); break;
  }

  delay(1000);
  Serial.println("\r\nSetting up things...\r\n"); 
  sendReceiveATCommand("AT+CREG?",2000);
  sendReceiveATCommand("AT+CGSOCKCONT=1,\"IP\",\"ba.amx\"", 4000);
  sendReceiveATCommand("AT+CSOCKAUTH=1,1,\"claro\",\"claro\"", 4000);
}

void loop() {

  Serial.println("\r\nStarting to send commands...\r\n"); 
  sendReceiveATCommand2("AT+CHTTPACT=\"BANNED.org.pe\",80", "\r\n+CHTTPACT: REQUEST","\r\nERROR", 30000);
  delay(100);
  Serial.print("GET /php/w004317i.php?&Lat=35&Lon=35 HTTP/2.0\r\n");
  fonaSS.print("GET /php/w004317i.php?&Lat=32&Lon=32 HTTP/2.0\r\n");
  delay(100);
  Serial.print("Host: BANNED.org.pe\r\n");
  fonaSS.print("Host: BANNED.org.pe\r\n");
  delay(100);
  Serial.print("Connection: close\r\n\r\n");
  fonaSS.print("Connection: close\r\n\r\n");
  delay(100);
  fonaSS.write(0x1A);
  delay(100);

  String result_;
  char result_char_[512];
  unsigned long milliseconds_ = 5000;
  unsigned long startTime_ = millis();
  Serial.print("Http answer received: ");
  while (millis() - startTime_ < milliseconds_) {
    if (fonaSS.available()) {
      char c = fonaSS.read();
      Serial.write(c);
      result_ += c;
      result_.toCharArray(result_char_, 512);
      if(strcasestr(result_char_,"+CHTTPACT: 0"))
      {
        milliseconds_ = 0;
      }
    }
  }
  Serial.print("\r\n\r\n");
  sendReceiveATCommand2("AT+NETCLOSE","\r\nOK","\r\nERROR",4000);
}


String sendReceiveATCommand(const char *toSend, unsigned long milliseconds) {
  String result;
  Serial.print("Sending: ");
  Serial.println(toSend);
  fonaSS.println(toSend);
  unsigned long startTime = millis();
  Serial.print("Received: ");
  while (millis() - startTime < milliseconds) {
    if (fonaSS.available()) {
      char c = fonaSS.read();
      Serial.write(c);
      result += c;  // append to the result string
    }
  }
Serial.println();  // new line after timeout.
return result;
}

String sendReceiveATCommand2(const char *toSend, const char *toCheck1, const char *toCheck2, unsigned long milliseconds) {
  char answer_check [3];
  String result;
  char result_char[50];
  Serial.print("Sending: ");
  Serial.println(toSend);
  fonaSS.println(toSend);
  unsigned long startTime = millis();
  Serial.print("Received: ");
  while (millis() - startTime < milliseconds) {
    if (fonaSS.available()) {
      char c = fonaSS.read();
      Serial.write(c);
      result += c;  // append to the result string
      result.toCharArray(result_char, 50);
      if(strcasestr(result_char,toCheck1) || strcasestr(result_char,toCheck2))
      {
        milliseconds = 0;
      }
    }    
  }
Serial.println();  // new line after timeout.
return result;
}
I used a modified version of sendReceiveATCommand function found here.

sendReceiveATCommand function send a command to 3G module and only expect for a defined time and waits for the result.
sendReceiveATCommand2 function send a command to 3G module and compare the result to a given string, when there's a match it stops waiting. (My intention is to submit data as fast as posible)

I have been tested and it seems to work fine.

I still have a couple of questions about this module, is it just me or why can I just used a serial tunnel like with SIM808 and SIM900 versions?

User avatar
Jaron_Trax
 
Posts: 3
Joined: Wed Mar 01, 2017 2:40 am

Re: Programming help needed- GPRS POST for FONA 3G library

Post by Jaron_Trax »

Hi Guys,

Firstly, thank you for starting this thread, its been very easy reading and helpful thus far.
I too have been playing with the 5320 chipset, although I am VERY new at this, however I've successfully been able to read information and send SMS's based on set points etc, plus a few other things for my small project, though now I am working on delivering data (very much like the example in this thread) via POST to a PHP file to insert into a MYSQL database. Hence why this thread has gained my interest.I have one small hiccup - and once sorted I would like to jump in and help others achieve the result were all working on here.

The issue is this... I have directly copied the code in the first post of this thread, modified the TX/RX/RST pins to suit my wiring, and also changed the LCD library to "LiquidCrystal.h" and configure the pins accordingly, though I am unsuccessful with the fonaReg command. The RSSI and netStat both remain at "0" and I cannot get past this.
If I dump the FONA example code direct from Adafruit onto the Uno, open the serial monitor, invoke the "n" or "i" commands and perfect - the FONA returns a register result and good RSSI. WTF?

I have spent days going through the libraries, coping code from the example here into the FONA example and vice versa, but for the life of me I cannot pin point the issue. It is like the FONA example has something hidden that I am missing.

I'll paste the code here and see if anyone can see where I am going wrong

Code: Select all


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


String myUrl; // for posting myChannel and Sensor Values to ThingSpeak
String myChannel; // URL channel for posting to thingspeak
String myBat; // string for adding voltage field to myUrl
String myStage; // string for adding stage field to myUrl

#define FONA_RX  3
#define FONA_TX  2
#define FONA_RST 9
#define FONA_RI  7
#define FONA_KEY 10
#define SENS_TRIG A3 // Attach to pin 4 on range sensor
#define SENS_READ A4 // same as pin 12 on FONA; attach to pin 3 on range sensor

// this is a large buffer for replies- keep this for future functionality
char replybuffer[255];

// We default to using software serial. If you want to use hardware serial
// (because softserial isnt supported) co\mment out the following three lines 
// and uncomment the HardwareSerial line

#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

// Hardware serial is also possible!
//  HardwareSerial *fonaSerial = &Serial1;

// Use this for FONA 800 and 808s
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
// Use following for FONA 3G and comment above line out
// Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
uint8_t type;    // placeholder to return type of FONA

uint8_t gStatus; // FONA GPRS status
uint8_t nStatus; // FONA network status
uint8_t sStatus; // FONA power status
uint8_t dStatus; // FONA search status

// RSSI variables
uint8_t n; // RSSI status
int8_t r;  // signal mapped to dBm

// FONA battery
uint16_t vbat;   

// Rangefinder variables
uint16_t sensRead; // variable for storing sensor read
float mV;          // calcualted millivolts
float distCm;      // distance in cm
float distIn;      // distance in inches

// Setu LCD
LiquidCrystal lcd(8, 11, 4, 5, 6, 7);

void setup() {

 // Fire up the LCD
 lcd.begin(16,2);
 screenClear();
 lcd.print(F("Hello, world!"));
 delay(3000);

 // Pin for powering Fona on/off
 pinMode(FONA_KEY, OUTPUT);
 digitalWrite(FONA_KEY, HIGH);

 // Pin for resetting Feather
 // pinMode(FEAT_RST, OUTPUT);
 // digitalWrite(FEAT_RST, LOW);

 // Pin for triggering sensor
 pinMode(SENS_TRIG, OUTPUT);
 digitalWrite(SENS_TRIG, LOW); // pin on sensor is pulled high internally, but
                               // sensor will stop ranging when low
 // Pin for reading sensor                             
 pinMode(SENS_READ, INPUT);    // pin is analog, so should be input by default;
                               // just being explicit
  // Build the string

  // myChannel and myURL reset at top of loop
  myChannel = "http://184.106.153.149/update?key=BANNED"; // includes channel key - hidden for public sharing.
  myUrl = ""; 

  gStatus; // GPRS status
  nStatus; // Network status
  sStatus; // FONA status

}

void loop() {

// Notify user I am in the loop

 screenClear();
 lcd.print(F("Start loop."));
 delay(2000);

// initialize my variables

 gStatus = 0; // GPRS status
 nStatus = 0; // Network status
 sStatus = 0; // FONA state status
 dStatus = 0; // FONA search status
 
 vbat = 0; // milivolts

 sensRead = 0; // analog pin reading on ultrasonic
 mV = 0; // analog pin reading on ultrasonic converted to mV
 distCm = 0; // distance in cm
 distIn = 0; // distance in inches

 n = 0; // RSSI status
 r = 0; // signal mapped to dBm

// Turn FONA on
 fonaOn(); //sets sStatus to 1 if fona is turned on successfully


 if(sStatus == 1) { // FONA is on
  
  screenClear();
  lcd.print(F("Delay 15 sec. ")); 
  delay(15000); // Give FONA time to register 
  screenClear();

  // Check registration

  fonaReg();

  if(nStatus == 1) {
    
   // FONA registered on network :)
   // okay to invest in a stage reading
   
   rangeFind();

   // Turn GPRS on

   screenClear();
   lcd.print(F("GPRS on 3s "));
   delay(3000);  
   screenClear();
   GPRS_on(); // function will set gStatus to 1 if GPRS turns on okay.

   if(gStatus) { // GPRS turned on okay

    // ready to post;
    // read parameters
   
    myBatVolt();
    myBat = String(vbat);
    myStage = String(distIn);
    myUrl = myChannel + "&field1=" + myBat +"&field2=" + myStage;

    screenClear();
    lcd.print(F("GPRS post 3s"));
    delay(3000);

    // post the string to ThingSpeak
    
    GPRS_post();

    // GPRS off

    screenClear();
    lcd.print(F("GPRS off 3s"));
    delay(3000); 
    GPRS_off();
   }
  }
 
  else { // FONA not registered on network
  
   screenClear();
   lcd.print(F("FONA not reg."));
   lcd.setCursor(0,1);
   lcd.print(F("End routine"));  
   delay(2000);  
  }
 // FONA off

 screenClear();
 lcd.print(F("FONA off 3s"));
 delay(3000);
 fonaOff(); 
}
 
else { // FONA not detected
  screenClear();
  lcd.print(F("FONA problem"));
  lcd.setCursor(0,1);
  lcd.print(F("End routine"));  
  delay(2000);
}

// Pause for power savings - FONA is off here.

 screenClear();
 lcd.print(F("Pause 30m"));
 delay(1800000); 
 
} 

// Functions to make loop more readable

void screenClear() {
  lcd.clear();
  lcd.setCursor(0,0);  
}

void keyToggle() {
 screenClear();
 lcd.print(F("Toggling "));
 digitalWrite(FONA_KEY, LOW);
 delay(2000);
 digitalWrite(FONA_KEY, HIGH);
 screenClear();
 lcd.print(F("Done "));
}

void fonaOn() {
  screenClear();
  lcd.print(F("Checking FONA"));
  fonaSerial->begin(4800);
    
  if(! fona.begin(*fonaSerial)) { // FONA is off at start of loop
   lcd.setCursor(0,1);
   lcd.print(F("No FONA "));
   delay(2000);
   keyToggle(); // turns FONA on
   screenClear();
   
   // next block added per Rick's recommendation
   // to call/check fona.begin after FONA on key toggle
   if (! fona.begin(*fonaSerial)) {
   lcd.print(F("Still no FONA"));
   delay(2000);
   sStatus = 0;
   }
   else {     
    lcd.print(F("FONA now on"));
    delay(2000);
    sStatus = 1;
   }
  }

 // all is good   
  else { // FONA is on at start of loop
    lcd.setCursor(0,1);
    lcd.print(F("FONA Found"));
    delay(2000);
    sStatus = 1;
  }
}


void fonaOff() {
  // following line added per Adafruit recommendation
  fonaSerial->end();
  
  screenClear();
  lcd.print(F("Turn FONA Off "));
  delay(2000);

// use key toggle 
  keyToggle();
  sStatus =0;
}

void GPRS_on() { 

// Turn GPRS on //

 screenClear();
 lcd.print(F("Entering GPRS "));
 delay(2000);
 lcd.setCursor(0,1); 

/// --> solid blue light here <-- /// 
/// --> Problem appears to be network related;
/// --> Cannot get GPRS to turn on in FONAtest either

// turn GPRS on
 if (!fona.enableGPRS(true)) {
  lcd.print(F("Failed to turn on"));
  gStatus = 0;
 } 
 else {
  lcd.print(F("GPRS on"));
  gStatus = 1;
 } 
}

void GPRS_post() {

 screenClear();
 lcd.print(F("GPRS on; delay 5s"));
 delay(5000);
     
 // Get website URL and ping it
 uint16_t statuscode;
 int16_t length;
 char url[256];
      
 // Need to read a string into an array, 
 // since fona.HTTP_GET_start() is expecting an array for url. 
 // First, define My url from channel and sensor value    

 screenClear();
 lcd.print(F("Posting. "));
 delay(2000);

 // Get myUrl into the array url
 myUrl.toCharArray(url,256);

 // Serial.println(myUrl);
 screenClear();
 lcd.println(myUrl);
 delay(2000); 

 // Make the post
 if (!fona.HTTP_GET_start(url, &statuscode, (uint16_t *)&length)) {
  screenClear();
  // post failed
  lcd.print(F("Post bad. "));
  delay(1000);
 }      
 else {
  // Post success
  screenClear();      
  lcd.print(F("Post good. "));
  delay(1000);
 }

 fona.HTTP_GET_end();
 /// Code to POST ends /// 

} 

void GPRS_off() {

 /// Turn GPRS off ///
 screenClear();
 if (!fona.enableGPRS(false))  {
  lcd.print(F("GPRS off bad. "));
 } 
 else {
  lcd.print(F("GPRS off ok. "));
  delay(1000);
 }
}

void myBatVolt() {

 screenClear();
 // read the battery voltage and percentage
      
 if (! fona.getBattVoltage(&vbat)) {
  lcd.print(F("Bat. read fail"));
 } else {
  lcd.print(F("VBat = ")); lcd.print(vbat); lcd.print(F(" mV"));
 }
 delay(2000);
 screenClear();  
}

void callStat() {

 // screenClear();
 int8_t callstat = fona.getCallStatus();
 delay(2000);
}

void netStat() {

 screenClear();
 // read the network/cellular status
 nStatus = fona.getNetworkStatus();
 lcd.print(F("Network status "));
 lcd.print(nStatus);
 lcd.print(F(": "));
 lcd.setCursor(0,1);
 if (nStatus == 0) lcd.print(F("Not reg"));
 if (nStatus == 1) lcd.print(F("Reg (home)"));
 if (nStatus == 2) lcd.print(F("Searching"));
 if (nStatus == 3) lcd.print(F("Denied"));
 if (nStatus == 4) lcd.print(F("Unknown"));
 if (nStatus == 5) lcd.print(F("Reg roam"));  
}

// following function not needed anymore thanks to Rick's recommendation
/*
void featReset() {

 screenClear();
 lcd.print(F("Reseting FEAT"));
 delay(3000);
 digitalWrite(FEAT_RST, LOW);
 delay(200);
 digitalWrite(FEAT_RST, HIGH);
 delay(1000);
 dStatus = 0;
}
*/

void fonaRSSI() {
  
 // read the RSSI
 n = fona.getRSSI();
 r;

 // Serial.print(F("RSSI = ")); Serial.print(n); Serial.print(": ");
 if (n == 0) r = -115;
 if (n == 1) r = -111;
 if (n == 31) r = -52;
 if ((n >= 2) && (n <= 30)) {
  r = map(n, 2, 30, -110, -54);
 }
    //    Serial.print(r); Serial.println(F(" dBm"));
}

void fonaReg() {
  
  while(1) {
   netStat();
   delay(2000);
   if(nStatus == 1) {
    screenClear();
    lcd.print(F("Registered"));
    break;
   }  
  else {        
   screenClear();
   fonaRSSI();
   lcd.print(F("Searching @ "));
   lcd.print(r);
   
   delay(3000);
   dStatus += 1;
   if(dStatus > 5) {
    screenClear();
    lcd.print(F("Time Out"));
    delay(3000);  
    break;
   }
  }    
 }
}


void rangeFind() {
  
 digitalWrite(SENS_TRIG, HIGH); // high will trigger the sensor; 
 delay(3000);                   // drive high for >20 usec to engage;
                                // give the sensor some time to stabilize

 // first reading is always a little off,
 // so read three times and take third reading.
                           
 for(int i = 0; i<=2; i++) {
  sensRead = analogRead(SENS_READ);  
  mV = (sensRead*3.3/1023)*1000; 
  delay(3000);
  
  // note that sensor is powered form 3V pin (3.3 V regulated by the FONA);
  // put a noise filter on power supply- this may be the issue (?)
  
 }                                                           
                   
 distCm = mV/3.2;               // ~3.2 mv per cm "approximate" per specs.
                                // via analog pin (pin 3) on sonar rangefinder 
 distIn = distCm / 2.54;
 
 screenClear();

 
 // need to investigate other options for calculating the 
 
 lcd.print(F("Sensor reports: "));
 lcd.setCursor(0,1);


 lcd.print(distIn); lcd.print(F(" in."));
 delay(1000);

 digitalWrite(SENS_TRIG, LOW); // turn off the range finder
 delay(1000); // wait 2 seconds until next reading
 
}

Thanking you all in advance !

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

Return to “FONA”