The Adafruit Feather 32u4 FONA - our take on an 'all-in-one' Arduino-compatible + audio/sms/data capable cellular board with built in USB and battery charging. For a complete list of device features and specs, check out the Feather product page

In the following tutorial, Ubidots will demonstrate how to setup and program the Adafruit Feather 32u4 FONA using the Arduino IDE to display data in your Ubidots account.

Requirements  

Step 1. Feather FONA Setup using the Arduino IDE

1. Download the latest release of the Arduino IDE if you not already have it. 

2. Open the Arduino IDE, select Files -> Preferences and enter the URL below into the Additional Board Manager URLs field. You can add multiple URLs by separating them with commas:

https://adafruit.github.io/arduino-board-index/package_adafruit_index.json

3. Open Boards Manager from Tools -> Board -> Boards Manager and install the Adafruit AVR Boards. To simply find the correct device, select contributed from the type option and search Adafruit AVR Boards within the search bar. Next, select the most recent version and press install: 

 4.  Close and reboot the Arduino IDE  it to ensure that all the boards are properly installed. 

5. Plug the Feather board into your computer and select the Adafruit Feather 32u4 from dropdown menus beginning with Tools > Board.

NOTE: If you are working with Windows, you will likely need to follow these additional steps to install the correct driver.

6. To ensure the right functionality of the Arduino IDE setup with the Adafruit Feather boards, upload the Blink example provided from Files > Examples > Basic > Blink. Once the board is properly setup, please continue with this guide. 

NOTE: If you have any issues uploading the sample sketch into the board, this guide will help you boot the board manually. Also, if you are working Ubuntu or Linux, please visit this guide for additional troubleshooting resources.

7. Go to the Adafruit library repository to download the Adafruit FONA library. To download this library, click the green button called "Clone or download" and select "Download ZIP".

8. Now back in the Arduino IDE, click on Sketch -> Include Library -> Add .ZIP Library and select the .ZIP file of Adafruit_FONA-master.zip and then “Accept” or “Choose”. Once the library is successfully included you will receive the message "Library added to your libraries".  

Step 2. Hardware Setup

1. Battery + USB Power: Whereas other Feathers boards can run direct from 3.3V USB or battery, the Feather FONA manages the battery and USB power differently. With this board you must have a Lipoly/Lilon battery plugged in at all times. For more specific technical information see check out this help section.

2. Insert a micro SIM, attach a GSM antenna, and connect battery and micro USB.  

3. Plug the board into to your computer. 

Step 3. Programming & Ubidots account setup

With the following example you will be able to publish ANALOG readings taken from the A0 pin of the Feather 32u4 FONA to Ubidots.

1. To post your first value to Ubidots, open the Arduino IDE and paste the code below. Once you have pasted the code, you will need to assign the APN (Access Point Name) of your operator, the USER and PASSWORD if are required for your operator, plus your individual, unique Ubidots TOKEN

/********************************
 * Libraries included
 *******************************/
#include <SoftwareSerial.h>
#include <stdlib.h>
#include "Arduino.h"
 
/********************************
 * Constants and objects
 *******************************/
 
#define DEFAULT_BUFFER_SIZE      64

#define FONA_RX  9
#define FONA_TX  8
#define FONA_RST 4

#define SERVER "translate.ubidots.com"
#define PORT "9012"

#define APN  "...."  // The APN of your operator
#define USER ""  // if your apn doesnt have username just leave it ""
#define PASS ""  // if your apn doesnt have password just leave it ""
#define TOKEN "...."  // Replace it with your Ubidots token
#define METHOD "POST"
#define USER_AGENT  "adafruit"
#define VERSION  "1.0"
#define DEVICE_LABEL  "feather-fona"
#define VARIABLE_LABEL  "temperature"


bool _debug = true;
char buffer[DEFAULT_BUFFER_SIZE];
 
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);

/********************************
 * Main Functions
 *******************************/
void setup() {
    Serial.begin(115200);
    pinMode(A0, INPUT);
    delay(2000);
    while(!setApn(APN, USER, PASS));
}

void loop() {
    char* request = (char *) malloc(sizeof(char) * 300);
    char str_val[15];
   
    float sensor_value = analogRead(A0);

    dtostrf(sensor_value, 4, 2, str_val);
    sprintf(request, "%s/%s|%s|%s|%s=>%s:%s|end", USER_AGENT, VERSION, METHOD, TOKEN, DEVICE_LABEL, VARIABLE_LABEL, str_val);
    //sprintf(request, "%s|%s|%s","adafruit/1.0|POST", TOKEN, "fona=>test:17.00|end");
    sendToUbidots(request);
    free(request);
}

/********************************
 * Auxiliar Functions
 *******************************/
bool sendMessageAndwaitForOK(char* message, uint16_t timeout = 4000) {
    fonaSS.println(message);
    if (strstr(readData(timeout), "OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error"));
        }
            return false;
        }
    return true;
}

bool setApn(char* apn, char* user, char* pwd) {
    checkFona();
    fonaSS.println(F("AT"));
    if (strstr(readData(2000), "OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT"));
        }
        return false;
    }
    fonaSS.println(F("AT+CREG?"));
    if (strstr(readData(2000), "+CREG:") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT"));
        }
        return false;
    }
    fonaSS.println(F("AT+CSQ"));
    if (strstr(readData(2000), "OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+CSQ"));
        }
        return false;
    }
    fonaSS.println(F("AT+CGATT?"));
    if (strstr(readData(10000), "OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+CGATT"));
        }
        return false;
    }
    fonaSS.println(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""));
    if (strstr(readData(10000), "OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+SAPBR CONTYPE"));
        }
        return false;
    }
    fonaSS.print(F("AT+SAPBR=3,1,\"APN\",\""));
    fonaSS.print(apn);
    fonaSS.println(F("\""));
    if (strstr(readData(3000), "OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+SAPBR APN"));
        }
        return false;
    }
    fonaSS.print(F("AT+SAPBR=3,1,\"USER\",\""));
    fonaSS.print(user);
    fonaSS.println(F("\""));
    if (strstr(readData(10000), "OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+SAPBR USER"));
        }
        return false;
    }
    fonaSS.print(F("AT+SAPBR=3,1,\"PWD\",\""));
    fonaSS.print(pwd);
    fonaSS.println("\"");
    if (strstr(readData(3000), "OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+SAPBR PASSWORD"));
        }
        return false;
    }
    fonaSS.println(F("AT+SAPBR=1,1"));
    if (strstr(readData(4000), "OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+SAPBR=1,1 Connection ip"));
        }
        return false;
    }
    fonaSS.println(F("AT+SAPBR=2,1"));
    if (strstr(readData(4000), "+SAPBR:") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+SAPBR=2,1 no IP to show"));
        }
        return false;
    }
    return true;
}

bool module_begin() {
    pinMode(FONA_RST, OUTPUT);
    digitalWrite(FONA_RST, HIGH);
    delay(500);
    digitalWrite(FONA_RST, LOW);
    delay(500);
    digitalWrite(FONA_RST, HIGH);
    delay(500);
    Serial.println(F("Attempting to open comm with ATs"));
    int16_t timeout = 10000;
    while (timeout > 0) {
        if (sendMessageAndwaitForOK("AT"))
            break;
        delay(500);
        timeout -= 500;
    }
    if (timeout <= 0) {
        Serial.println(F("Timeout: No response to AT... last ditch attempt."));
        sendMessageAndwaitForOK("AT");
        delay(100);
        sendMessageAndwaitForOK("AT");
        delay(100);
        sendMessageAndwaitForOK("AT");
        delay(100);
        return false;
    }
    sendMessageAndwaitForOK("ATE0");
    delay(100);
    return true;
}

bool sendToUbidots(char* request) {
 
    fonaSS.println(F("AT+CIPMUX=0"));
    if (strstr(readData(4000), "OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+CIPMUX"));
        }
        return false;
    }
    fonaSS.print(F("AT+CIPSTART=\"TCP\",\""));
    fonaSS.print(SERVER);
    fonaSS.print(F("\",\""));
    fonaSS.print(PORT);
    fonaSS.println(F("\""));
    if (strstr(readData(4000), "CONNECT OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+CIPSTART"));
        }
        return false;
    }
    fonaSS.print(F("AT+CIPSEND="));
    fonaSS.println(dataLen(request));
    if (strstr(readData(4000), ">") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+CIPSEND"));
        }
        return false;
    }
    fonaSS.write(request);
    if (strstr(readData(4000), "SEND OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error sending variables"));
        }
        return false;
    }
    fonaSS.println(F("AT+CIPCLOSE"));
    if (strstr(readData(4000), "CLOSE OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+CIPCLOSE"));
        }
        return false;
    }
    fonaSS.println(F("AT+CIPSHUT"));
    if (strstr(readData(4000), "SHUT OK") == NULL) {
        if (_debug) {
            Serial.println(F("Error with AT+CIPSHUT"));
        }
        return false;
    }
    return true;
}

int dataLen(char* variable) {
  uint8_t dataLen = 0;
  for (int i = 0; i <= 250; i++) {
    if (variable[i] != '\0') {
      dataLen++;
    } else {
      break;
    }
  }
  return dataLen;
}

bool checkFona() {
    fonaSS.begin(4800);
    delay(2000);
    module_begin();
    if (!sendMessageAndwaitForOK("ATE0", 6000)) {
        Serial.print("Couldn't find FONA");
        while (1) {
            Serial.println("ERROR");
        }
        return false;
    }
    return true;
}

char* readData(uint16_t timeout) {
    uint16_t replyidx = 0;
    char replybuffer[254];
    int secconds = 0;
    while (!fonaSS.available() && secconds < timeout) {
        secconds++;
    }
    while (timeout--) {
        if (replyidx >= 254) {
            break;
        }
        while (fonaSS.available()) {
            char c =  fonaSS.read();
            if (c == '\r') continue;
            if (c == 0xA) {
                if (replyidx == 0)   // the first 0x0A is ignored
                    continue;
            }
            replybuffer[replyidx] = c;
            replyidx++;
        }
        while (!fonaSS.available() && timeout > 0) {
            timeout--;
            delay(1);
        }

        if (timeout == 0) {
            if (fonaSS.available()) {
                timeout = 1000;
            } else {
                break;
            }
        }
    }
    replybuffer[replyidx] = '\0';  // null term
    if (_debug) {
        Serial.println("Response of FONA:");
        Serial.println(replybuffer);
    }
    return replybuffer;
}

2. Verify your code within the Arduino IDE. To do this, in the top left corner of our Arduino IDE you will see the "Check Mark" icon press it to verify your code. 

3. Upload the code into your Feather 32u4 FONA. To do this, choose the "right-arrow" icon beside the "check mark" icon. 

4. To verify the connectivity of the device and the data sent, open the serial monitor by selecting the "magnifying glass" icon in the top right corner of the Arduino IDE. 

5. Confirm your data in Ubidots. Now you should see the published data in your Ubidots account, locate the device called "adafruit" and visualize your data. 

Result

With this simple tutorial we are able to POST data to Ubidots with the ease of the Arduino IDE and a Feather 32u4 FONA. If your desire send more than one variable to Ubidots, reference Ubidots REST API to learn how to build the request properly. :) 

Now its time to create Ubidots Dashboards to visualize your data and deploy your internet connected monitoring solution!  Happy Hacking! :) 

 

 

Did this answer your question?