Connecting Adafruit 32u4 FONA to Losant


#1

I just got an Adafruit 32u4 FONA device which I would like to connect to Losant.
Adafruit has a Arduino library (https://github.com/adafruit/Adafruit_MQTT_Library), but the connection method seems to only support these parameters: Cllient(network interface), Server, Server Port, username, password).

When trying to merge the sample Fona code with the Losant mqtt library, the client (Adafruit_FONA) dosen’t work:
device.connectSecure(FonaClient, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);

Do you have any suggestions how to get the FONA connect to Losant via mqtt or any other (preferrably secure) method?


#2

Yes! We have our own Arduino MQTT library:

It uses a secure TLS connection by default. So, no issues there as well.

Let me know if you have anymore questions or need an example. I’d love to help more


#3

Yes I’m using the Losant mqtt library.
But as mentioned in the initial message, I’m not able to get it working with a Adafruit Feather 32u4 FONA device.
Here is my code:

#include <Losant.h>
#include <Adafruit_SleepyDog.h>
#include <Adafruit_FONA.h>
#include <SoftwareSerial.h>

/*************************** FONA Pins ***********************************/

// Default pins for Feather 32u4 FONA
#define FONA_RX  9
#define FONA_TX  8
#define FONA_RST 4

SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

/************************* Adafruit Feather 32u4 FONA setup *********************************/

// 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.
#define FONA_APN       "online.telia.se"
#define FONA_USERNAME  ""
#define FONA_PASSWORD  ""

/************************* Losant Setup *********************************/

#define LOSANT_PORT 1883
#define LOSANT_BROKER "broker.losant.com"
#define LOSANT_DEVICE_ID "my_device_id"
#define LOSANT_ACCESS_KEY "my_access_key"
#define LOSANT_ACCESS_SECRET  "my_access_secret"

// FONAconnect is a helper function that sets up the FONA and connects to
// the GPRS network. See the fonahelper.cpp tab above for the source!
boolean FONAconnect(const __FlashStringHelper *apn, const __FlashStringHelper *username, const __FlashStringHelper *password);
LosantDevice device(LOSANT_DEVICE_ID);

// Toggles and LED on or off.
void toggle() {
	Serial.println("Toggling LED.");
	//ledState = !ledState;
	//digitalWrite(LED_PIN, ledState ? HIGH : LOW);
}

// Called whenever the device receives a command from the Losant platform.
void handleCommand(LosantCommand *command) {
	Serial.print("Command received: ");
	Serial.println(command->name);

	if (strcmp(command->name, "toggle") == 0) {
		toggle();
	}
}

void connect() {

	//WiFi.begin(WIFI_SSID, WIFI_PASS);

	//while (WiFi.status() != WL_CONNECTED) {
	//	delay(500);
	//	Serial.print(".");
	//}

	// Connect to Losant.
	device.connectSecure(fona, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);

	while (!device.connected()) {
		delay(500);
	}
}

void setup()
{
	// Watchdog is optional!
	//Watchdog.enable(8000);

	Serial.begin(115200);

	device.onCommand(&handleCommand);

	Serial.println(F("Losant MQTT demo"));

	//mqtt.subscribe(&onoffbutton);

	Watchdog.reset();
	delay(5000);  // wait a few seconds to stabilize connection
	Watchdog.reset();

	// Initialise the FONA module
	while (!FONAconnect(F(FONA_APN), F(FONA_USERNAME), F(FONA_PASSWORD))) {
		Serial.println("Retrying FONA");
	}

	Serial.println(F("Connected to Cellular!"));

	Watchdog.reset();
	delay(5000);  // wait a few seconds to stabilize connection
	Watchdog.reset();

	connect();

}

void loop()
{

	bool toReconnect = false;
	//if(!fona.)

}

Here is the error message I get when trying to compile:

Build options changed, rebuilding all
C:\Users\gean\Documents\Arduino\Fona_Losant_mqtt\Fona_Losant_mqtt.ino: In function ‘void connect()’:

Fona_Losant_mqtt:68: error: no matching function for call to ‘LosantDevice::connectSecure(Adafruit_FONA&, const char [37], const char [65])’

device.connectSecure(fona, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);

Any help please?


#4

Sorry Geir. I see your issue now.

Overall, our libraries are not set up to use the FONA connection libraries, yet. However, here is what I would suggest:

You can use MQTT directly with Losant:

https://docs.losant.com/mqtt/overview/

Since Adafruit’s MQTT libraries support the FONA hardware, we can use this library to connect to Losant via MQTT. We don’t have that device here ( so I couldn’t test ), but I changed the example code to what should work. Starting form the example, all you need to do is connect to Losant instead of Adafruit.io.

/***************************************************
  Adafruit MQTT Library FONA Example
  Designed specifically to work with the Adafruit FONA
  ----> http://www.adafruit.com/products/1946
  ----> http://www.adafruit.com/products/1963
  ----> http://www.adafruit.com/products/2468
  ----> http://www.adafruit.com/products/2542
  These cellular modules use TTL Serial to communicate, 2 pins are
  required to interface.
  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.
  MIT license, all text above must be included in any redistribution
 ****************************************************/
#include <Adafruit_SleepyDog.h>
#include <SoftwareSerial.h>
#include "Adafruit_FONA.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_FONA.h"

/*************************** FONA Pins ***********************************/

// Default pins for Feather 32u4 FONA
#define FONA_RX  9
#define FONA_TX  8
#define FONA_RST 4
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

/************************* WiFi Access Point *********************************/

  // 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.
#define FONA_APN       ""
#define FONA_USERNAME  ""
#define FONA_PASSWORD  ""

/************************* Adafruit.io Setup *********************************/

#define LOSANT_SERVER      "broker.losant.com"
#define LOSANT_SERVERPORT  1883
#define LOSANT_ACCESS_KEY    "my-access-key"
#define LOSANT_ACCESS_SECRET         "my-access-secret"
#define LOSANT_DEVICE_ID         "my-device-id"

/************ Global State (you don't need to change this!) ******************/

// Setup the FONA MQTT class by passing in the FONA class and MQTT server and login details.
Adafruit_MQTT_FONA mqtt(&fona, LOSANT_SERVER, LOSANT_SERVERPORT, LOSANT_DEVICE_ID, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);

// You don't need to change anything below this line!
#define halt(s) { Serial.println(F( s )); while(1);  }

// FONAconnect is a helper function that sets up the FONA and connects to
// the GPRS network. See the fonahelper.cpp tab above for the source!
boolean FONAconnect(const __FlashStringHelper *apn, const __FlashStringHelper *username, const __FlashStringHelper *password);

/****************************** Feeds ***************************************/

// Publish Losant state
// Notice MQTT paths for Losant follow the form: losant/<device-id>/state
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, "losant/" + LOSANT_DEVICE_ID "/state");

// subscribe  Losant commands
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, "losant/" + LOSANT_DEVICE_ID "/command");

/*************************** Sketch Code ************************************/

// How many transmission failures in a row we're willing to be ok with before reset
uint8_t txfailures = 0;
#define MAXTXFAILURES 3

void setup() {
  while (!Serial);

  // Watchdog is optional!
  //Watchdog.enable(8000);
  
  Serial.begin(115200);

  Serial.println(F("Adafruit FONA MQTT demo"));

  mqtt.subscribe(&onoffbutton);

  Watchdog.reset();
  delay(5000);  // wait a few seconds to stabilize connection
  Watchdog.reset();
  
  // Initialise the FONA module
  while (! FONAconnect(F(FONA_APN), F(FONA_USERNAME), F(FONA_PASSWORD))) {
    Serial.println("Retrying FONA");
  }

  Serial.println(F("Connected to Cellular!"));

  Watchdog.reset();
  delay(5000);  // wait a few seconds to stabilize connection
  Watchdog.reset();
}

uint32_t x=0;

void loop() {
  // Make sure to reset watchdog every loop iteration!
  Watchdog.reset();

  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();

  Watchdog.reset();
  // Now we can publish stuff!
  Serial.print(F("\nSending photocell val "));
  Serial.print(x);
  Serial.print("...");
  if (! photocell.publish(x++)) {
    Serial.println(F("Failed"));
    txfailures++;
  } else {
    Serial.println(F("OK!"));
    txfailures = 0;
  }

  Watchdog.reset();  
  // this is our 'wait for incoming subscription packets' busy subloop
  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    if (subscription == &onoffbutton) {
      Serial.print(F("Got: "));
      Serial.println((char *)onoffbutton.lastread);
    }
  }

  // ping the server to keep the mqtt connection alive, only needed if we're not publishing
  //if(! mqtt.ping()) {
  //  Serial.println(F("MQTT Ping failed."));
  //}

}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
    Serial.println(mqtt.connectErrorString(ret));
    Serial.println("Retrying MQTT connection in 5 seconds...");
    mqtt.disconnect();
    delay(5000);  // wait 5 seconds
  }
  Serial.println("MQTT Connected!");
}

With this code you can still publish state and receive device commands from Losant. For more MQTT info, check out:

https://docs.losant.com/mqtt/overview/


#5

Now I finally got the code to compile after a minor change to get it work (mind I’m new to C++):
I declared:
const char* PublishFeed = “losant/MyDeviceId/state”;
const char* SubscribeFeed = “losant/MyDeviceId/command”;
And changed:
// Notice MQTT paths for Losant follow the form: losant//state
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, PublishFeed);

// subscribe Losant commands
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, SubscribeFeed);

But I do get this response:

"
AT+CIPSTART=“TCP”,“broker.losant.com”,“1883”
<— OK
<— CONNECT OK
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
AT+CIPSEND=118
0x10 0x74 0x0 0x4 0x4D 0x51 0x54 0x54 0x4 0xFFFFFFC2 0x1 0x2C 0x0 0x0 0x0 0x24 0x35 0x66 0x63 0x62 0x32 0x38 0x30 0x62 0x2D 0x35 0x34 0x35 0x38 0x2D 0x34 0x33 0x35 0x38 0x2D 0x38 0x37 0x39 0x61 0x2D 0x34 0x31 0x36 0x64 0x30 0x66 0x63 0x66 0x36 0x65 0x39 0x34 0x0 0x40 0x32 0x31 0x64 0x31 0x33 0x33 0x61 0x31 0x32 0x35 0x65 0x30 0x37 0x61 0x30 0x39 0x34 0x34 0x35 0x30 0x30 0x66 0x64 0x37 0x30 0x64 0x32 0x63 0x66 0x32 0x37 0x36 0x32 0x61 0x31 0x37 0x63 0x36 0x35 0x34 0x38 0x62 0x63 0x35 0x66 0x63 0x62 0x38 0x31 0x30 0x34 0x34 0x30 0x31 0x31 0x30 0x66 0x32 0x66 0x66 0x35 0x36 0x66 0x37
<— >
<— SEND OK
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,4
4 bytes available
1 bytes read
0x20
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,3
3 bytes available
1 bytes read
0x2
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,2
2 bytes available
2 bytes read
0x0 0x2
The Client identifier is correct UTF-8 but not allowed by the Server
Retrying MQTT connection in 5 seconds…
"
Any suggestion?


#6

Ah Sorry! This was a typo in the example I sent along.

However, that error means you need to pass in a Client ID( Device ID ) when authentication MQTT. You should change the mqtt initialization to this:

// Setup the FONA MQTT class by passing in the FONA class and MQTT server and login details.
Adafruit_MQTT_FONA mqtt(&fona, LOSANT_SERVER, LOSANT_SERVERPORT, LOSANT_DEVICE_ID, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);


#7

Now I get the response “Connection failed”:
AT+CIPSTART=“TCP”,“broker.losant.com”,“1883”
<— OK
<— CONNECT OK
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
AT+CIPSEND=142
0x10 0xFFFFFF8C 0x0 0x4 0x4D 0x51 0x54 0x54 0x4 0xFFFFFFC2 0x1 0x2C 0x0 0x18 0x35 0x37 0x33 0x39 0x63 0x38 0x64 0x64 0x61 0x30 0x34 0x33 0x65 0x36 0x30 0x31 0x30 0x30 0x35 0x31 0x36 0x37 0x39 0x30 0x0 0x24 0x35 0x66 0x63 0x62 0x32 0x38 0x30 0x62 0x2D 0x35 0x34 0x35 0x38 0x2D 0x34 0x33 0x35 0x38 0x2D 0x38 0x37 0x39 0x61 0x2D 0x34 0x31 0x36 0x64 0x30 0x66 0x63 0x66 0x36 0x65 0x39 0x34 0x0 0x40 0x32 0x31 0x64 0x31 0x33 0x33 0x61 0x31 0x32 0x35 0x65 0x30 0x37 0x61 0x30 0x39 0x34 0x34 0x35 0x30 0x30 0x66 0x64 0x37 0x30 0x64 0x32 0x63 0x66 0x32 0x37 0x36 0x32 0x61 0x31 0x37 0x63 0x36 0x35 0x34 0x38 0x62 0x63 0x35 0x66 0x63 0x62 0x38 0x31 0x30 0x34 0x34 0x30 0x31 0x31 0x30 0x66 0x32 0x66 0x66 0x35 0x36 0x66 0x37
<— >
<— SEND OK
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
—> AT+CIPRXGET=4
<— +CIPRXGET: 4,0
0 bytes available
—> AT+CIPSTATUS
<— OK
<— STATE: CONNECT OK
Connection failed
Retrying MQTT connection in 5 seconds…


#8

This may seem like an obvious question. But, can you verify you have the correct values for the Losant setup:

#define LOSANT_SERVER                   "broker.losant.com"
#define LOSANT_SERVERPORT          1883
#define LOSANT_ACCESS_KEY         "my-access-key"
#define LOSANT_ACCESS_SECRET   "my-access-secret"
#define LOSANT_DEVICE_ID              "my-device-id"

For example, you’ll need to replace the following: my-access-key, my-access-secret, my-device-id


#9

The LOSANT_SERVER and LOSANT_SERVERPORT is as above, but the rest is replaced with values copied and pasted from Losant.
I created a new device, and verified that the device and access key was correct. I successfully connected with another device with the same access key and access secret in February. Is there anyway to retrieve and verify the access secret?
I still get the same response.


#10

Any idea why I get “Connection failed” response @anaptfox?
I’m working on a POC for a potential customer, so it’s quite critical that I cannot connect to Losant.
Is it possible for you to test with a Feather 32u4 FONA?


#11

We don’t have that device here in the office. So, I can’t test directly but we can try to debug this.

Connection Failed generally means that the device can’t connect to the network. However, it connected to the network before when you received the The Client identifier is correct UTF-8 but not allowed by the Server error.

Could you paste your updated code?


#12

You should really get one, it’s an awesome little device :wink:
Here is the code, I have removed my keys, but I’ll send the original to you by mail:

    /***************************************************
    Adafruit MQTT Library FONA Example
    Designed specifically to work with the Adafruit FONA
    ----> http://www.adafruit.com/products/1946
    ----> http://www.adafruit.com/products/1963
    ----> http://www.adafruit.com/products/2468
    ----> http://www.adafruit.com/products/2542
    These cellular modules use TTL Serial to communicate, 2 pins are
    required to interface.
    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.
    MIT license, all text above must be included in any redistribution
    ****************************************************/
    #include <SoftwareSerial.h>
    #include <Adafruit_SleepyDog.h>
    #include "Adafruit_FONA.h"
    #include "Adafruit_MQTT.h"
    #include "Adafruit_MQTT_FONA.h"

    /*************************** FONA Pins ***********************************/

    // Default pins for Feather 32u4 FONA
    #define FONA_RX  9
    #define FONA_TX  8
    #define FONA_RST 4
    SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);

    Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

    /************************* WiFi Access Point *********************************/

    // 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.
    #define FONA_APN       "online.telia.se"
    #define FONA_USERNAME  ""
    #define FONA_PASSWORD  ""

    /************************* Adafruit.io Setup *********************************/

    #define LOSANT_SERVER			"broker.losant.com"
    #define LOSANT_SERVERPORT		1883
    #define LOSANT_ACCESS_KEY		"My_Access_Key"
    #define LOSANT_ACCESS_SECRET	"My-Secret"
    #define LOSANT_DEVICE_ID		"My_Device_Id"
    const char* PublishFeed =		"losant/My_Device_Id/state";
    const char* SubscribeFeed =		"losant/My_Device_Id/command";

    /************ Global State (you don't need to change this!) ******************/

    // Setup the FONA MQTT class by passing in the FONA class and MQTT server and login details.
    Adafruit_MQTT_FONA mqtt(&fona, LOSANT_SERVER, LOSANT_SERVERPORT, LOSANT_DEVICE_ID, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);

    // You don't need to change anything below this line!
    #define halt(s) { Serial.println(F( s )); while(1);  }

    // FONAconnect is a helper function that sets up the FONA and connects to
    // the GPRS network. See the fonahelper.cpp tab above for the source!
    boolean FONAconnect(const __FlashStringHelper *apn, const __FlashStringHelper *username, const __FlashStringHelper *password);

    /****************************** Feeds ***************************************/

    // Publish Losant state
    // Notice MQTT paths for Losant follow the form: losant/<device-id>/state
    Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, PublishFeed);

    // subscribe  Losant commands
    Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, SubscribeFeed);

    /*************************** Sketch Code ************************************/

    // How many transmission failures in a row we're willing to be ok with before reset
    uint8_t txfailures = 0;
    #define MAXTXFAILURES 3

    void setup() {
    	while (!Serial);

    	// Watchdog is optional!
    	//Watchdog.enable(8000);

    	Serial.begin(115200);

    	Serial.println(F("Adafruit FONA MQTT demo"));

    	mqtt.subscribe(&onoffbutton);

    	Watchdog.reset();
    	delay(5000);  // wait a few seconds to stabilize connection
    	Watchdog.reset();

    	// Initialise the FONA module
    	while (!FONAconnect(F(FONA_APN), F(FONA_USERNAME), F(FONA_PASSWORD))) {
    		Serial.println("Retrying FONA");
    	}

    	Serial.println(F("Connected to Cellular!"));

    	Watchdog.reset();
    	delay(5000);  // wait a few seconds to stabilize connection
    	Watchdog.reset();
    }

    uint32_t x = 0;

    void loop() {
    	// Make sure to reset watchdog every loop iteration!
    	Watchdog.reset();

    	// Ensure the connection to the MQTT server is alive (this will make the first
    	// connection and automatically reconnect when disconnected).  See the MQTT_connect
    	// function definition further below.
    	MQTT_connect();

    	Watchdog.reset();
    	// Now we can publish stuff!
    	Serial.print(F("\nSending photocell val "));
    	Serial.print(x);
    	Serial.print("...");
    	if (!photocell.publish(x++)) {
    		Serial.println(F("Failed"));
    		txfailures++;
    	}
    	else {
    		Serial.println(F("OK!"));
    		txfailures = 0;
    	}

    	Watchdog.reset();
    	// this is our 'wait for incoming subscription packets' busy subloop
    	Adafruit_MQTT_Subscribe *subscription;
    	while ((subscription = mqtt.readSubscription(5000))) {
    		if (subscription == &onoffbutton) {
    			Serial.print(F("Got: "));
    			Serial.println((char *)onoffbutton.lastread);
    		}
    	}

    	// ping the server to keep the mqtt connection alive, only needed if we're not publishing
    	//if(! mqtt.ping()) {
    	//  Serial.println(F("MQTT Ping failed."));
    	//}

    }

    // Function to connect and reconnect as necessary to the MQTT server.
    // Should be called in the loop function and it will take care if connecting.
    void MQTT_connect() {
    	int8_t ret;

    	// Stop if already connected.
    	if (mqtt.connected()) {
    		return;
    	}

    	Serial.print("Connecting to MQTT... ");

    	while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
    		Serial.println(mqtt.connectErrorString(ret));
    		Serial.println("Retrying MQTT connection in 5 seconds...");
    		mqtt.disconnect();
    		delay(5000);  // wait 5 seconds
    	}
    	Serial.println("MQTT Connected!");
    }

#13

Hi Taron.
Below is my updated code:

/***************************************************
Adafruit MQTT Library FONA Example
Designed specifically to work with the Adafruit FONA
----> http://www.adafruit.com/products/1946
----> http://www.adafruit.com/products/1963
----> http://www.adafruit.com/products/2468
----> http://www.adafruit.com/products/2542
These cellular modules use TTL Serial to communicate, 2 pins are
required to interface.
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.
MIT license, all text above must be included in any redistribution
****************************************************/
#include <SoftwareSerial.h>
#include <Adafruit_SleepyDog.h>
#include "Adafruit_FONA.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_FONA.h"

/*************************** FONA Pins ***********************************/

// Default pins for Feather 32u4 FONA
#define FONA_RX  9
#define FONA_TX  8
#define FONA_RST 4
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

/************************* WiFi Access Point *********************************/

// 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.
#define FONA_APN       "online.telia.se"
#define FONA_USERNAME  ""
#define FONA_PASSWORD  ""

/************************* Adafruit.io Setup *********************************/

#define LOSANT_SERVER                             "broker.losant.com"
#define LOSANT_SERVERPORT                         1883
#define LOSANT_ACCESS_KEY                         "5fcb280b-5458-4358-879a-416d0fcf6e94"
#define LOSANT_ACCESS_SECRET            "21d133a125e07a0944500fd70d2cf2762a17c6548bc5fcb810440110f2ff56f7"
#define LOSANT_DEVICE_ID             "5910d96a816fff0001b92430"
const char* PublishFeed =                         "losant/5910d96a816fff0001b92430/state";
const char* SubscribeFeed =                       "losant/5910d96a816fff0001b92430/command";

/************ Global State (you don't need to change this!) ******************/

// Setup the FONA MQTT class by passing in the FONA class and MQTT server and login details.
Adafruit_MQTT_FONA mqtt(&fona, LOSANT_SERVER, LOSANT_SERVERPORT, LOSANT_DEVICE_ID, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);

// You don't need to change anything below this line!
#define halt(s) { Serial.println(F( s )); while(1);  }

// FONAconnect is a helper function that sets up the FONA and connects to
// the GPRS network. See the fonahelper.cpp tab above for the source!
boolean FONAconnect(const __FlashStringHelper *apn, const __FlashStringHelper *username, const __FlashStringHelper *password);

/****************************** Feeds ***************************************/

// Publish Losant state
// Notice MQTT paths for Losant follow the form: losant/<device-id>/state
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, PublishFeed);

// subscribe  Losant commands
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, SubscribeFeed);

/*************************** Sketch Code ************************************/

// How many transmission failures in a row we're willing to be ok with before reset
uint8_t txfailures = 0;
#define MAXTXFAILURES 3

void setup() {
            while (!Serial);

            // Watchdog is optional!
            //Watchdog.enable(8000);

            Serial.begin(115200);

            Serial.println(F("Adafruit FONA MQTT demo"));

            mqtt.subscribe(&onoffbutton);

            Watchdog.reset();
            delay(5000);  // wait a few seconds to stabilize connection
            Watchdog.reset();

            // Initialise the FONA module
            while (!FONAconnect(F(FONA_APN), F(FONA_USERNAME), F(FONA_PASSWORD))) {
                         Serial.println("Retrying FONA");
            }

            Serial.println(F("Connected to Cellular!"));

            Watchdog.reset();
            delay(5000);  // wait a few seconds to stabilize connection
            Watchdog.reset();
}

uint32_t x = 0;

void loop() {
            // Make sure to reset watchdog every loop iteration!
            Watchdog.reset();

            // Ensure the connection to the MQTT server is alive (this will make the first
            // connection and automatically reconnect when disconnected).  See the MQTT_connect
            // function definition further below.
            MQTT_connect();

            Watchdog.reset();
            // Now we can publish stuff!
            Serial.print(F("\nSending photocell val "));
            Serial.print(x);
            Serial.print("...");
            if (!photocell.publish(x++)) {
                         Serial.println(F("Failed"));
                         txfailures++;
            }
            else {
                         Serial.println(F("OK!"));
                         txfailures = 0;
            }

            Watchdog.reset();
            // this is our 'wait for incoming subscription packets' busy subloop
            Adafruit_MQTT_Subscribe *subscription;
            while ((subscription = mqtt.readSubscription(5000))) {
                         if (subscription == &onoffbutton) {
                                     Serial.print(F("Got: "));
                                     Serial.println((char *)onoffbutton.lastread);
                         }
            }

            // ping the server to keep the mqtt connection alive, only needed if we're not publishing
            //if(! mqtt.ping()) {
            //  Serial.println(F("MQTT Ping failed."));
            //}

}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
            int8_t ret;

            // Stop if already connected.
            if (mqtt.connected()) {
                         return;
            }

            Serial.print("Connecting to MQTT... ");

            while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
                         Serial.println(mqtt.connectErrorString(ret));
                         Serial.println("Retrying MQTT connection in 5 seconds...");
                         mqtt.disconnect();
                         delay(5000);  // wait 5 seconds
            }
            Serial.println("MQTT Connected!");
}

I have tested the code in both Arduino 1.8.2 and Visual Studio 2017, the response is the same.

Best regards,
Geir Andersen


#14

We are buying one for the office now! :slight_smile:

However, Did you happen to grab the fonahelper.cpp?

You should place that file in the same directory as your .ino file.

I’m reviewing your code now.


#15

Yes, when trying running the code in Arduino I copied fonahelper.cpp into the same folder as the .ino file.
In Visual Studio 2017 I included the file in the project (otherwise it wouldn’t compile at all).


#16

The following response is from the Setup, the bold resposes are from fonahelper.cpp, proving it is used:

Initializing FONA…(May take 3 seconds)
Attempting to open comm with ATs
—> AT
<—
—> AT
<—
—> AT
<— AT
—> AT
<— AT
—> AT
<— AT
—> AT
<— AT
—> AT
<— AT
—> ATE0
<— ATE0
—> ATE0
<— OK
—> AT+CVHU=0
<— OK
—> ATI
<— SIM800 R13.08

OK

+CPIN: READY

—> AT+GMM
<— SIMCOM_SIM800H

OK

FONA is OK
Checking for network…
—> AT+CREG?
<— +CREG: 0,2
—> AT+CREG?
<— +CREG: 0,2
—> AT+CREG?
<— +CREG: 0,2
—> AT+CREG?
<— +CREG: 0,2
—> AT+CREG?
<— +CREG: 0,2
—> AT+CREG?
<— +CREG: 0,2
—> AT+CREG?
<— +CREG: 0,2
—> AT+CREG?
<— +CREG: 0,2
—> AT+CREG?
<— +CREG: 0,1
Disabling GPRS
—> AT+CIPSHUT
<— SHUT OK
—> AT+SAPBR=0,1
<— +CME ERROR: operation not allowed
Enabling GPRS
—> AT+CIPSHUT
<— SHUT OK
—> AT+CGATT=1
<— OK
—> AT+SAPBR=3,1,“CONTYPE”,“GPRS”
<— OK
—> AT+SAPBR=3,1,“APN”,“online.telia.se
<— OK
—> AT+CSTT=“online.telia.se”,"",""
<— OK
—> AT+SAPBR=3,1,“USER”,""
<— OK
—> AT+SAPBR=3,1,“PWD”,""
<— OK
—> AT+SAPBR=1,1
<— OK
—> AT+CIICR
<— OK
Connected to Cellular


#17

hmm. That’s helpful!

I have an idea. Since this looks like MQTT connection issues ( not network ) I’m testing out the Adafruit MQTT library with another board to see if I get successful results.


#18

Great @anaptfox, really appreciate your efforts!


#19

Just want to keep you updated. I am seeing the same thing. I’m digging into the Adafruit MQTT library to see what’s going on.


#20

Geir

Unfortunately, I don’t have great news. Another one of our engineers and I really tried to debug this issue. We found a problem in the Adafruit Library. I have filed an issue:

https://github.com/adafruit/Adafruit_MQTT_Library/issues/79

Long story short, the library doesn’t follow the spec properly and limits the MQTT connection packet to 127 bytes. Because we have to pass an access key, access secret, and device id, the packet is a bit larger than that.

I don’t have a great solution for you now. But, the Adafruit 32u4 FONA is currently out of stock. I’m gonna grab a similar board with the same chip to test.