Skip to main content
All CollectionsConnect your Devices
Connect an Adafruit Feather 32u4 FONA to Ubidots over TCP/UDP
Connect an Adafruit Feather 32u4 FONA to Ubidots over TCP/UDP

Visualize a system or environment's data with the Feather 32u4 FONA and Ubidots.

Sergio M avatar
Written by Sergio M
Updated over 2 months ago

The Adafruit Feather 32u4 FONA - an 'all-in-one' Arduino-compatible + audio/sms/data capable cellular board with built in USB and battery charging is a one stop shop for the lion's share of cellular IoT solutions. 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 where it can be put to work.

Requirements

Step-By-Step

  1. Feather FONA setup using the Arduino IDE

  2. Hardware Setup

  3. Sending (POST) Data to Ubidots

  4. Summary

1. Feather FONA Setup using the Arduino IDE

To begin working with the Adafruit Feather 32u4 FONA you need to setup the board using the Arduino IDE. For this, please refer to the step "3. Board & Platform Management" of the following guide:

1. To ensure the the Arduino IDE's correct functionality with the Adafruit Feather board, 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 on Ubuntu or Linux, please visit this guide for additional troubleshooting resources.

2. 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".

3. 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".  

2. Hardware Setup

1. Battery + USB Power: Whereas other Feather 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 additional documentation, check out this help section.

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

3. Plug the board into to your computer.

3. Sending (POST) Data to Ubidots

With the following sample code you will be able to publish the 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 sample code below. Once you have pasted the code, you will need to assign your unique Ubidots TOKEN and the APN (Access Point Name) of your cellular provider with username and password.

/********************************
 * 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 "industrial.api.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. 

4. Summary 

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! :) 

Other readers have also found useful...

 

 

Did this answer your question?