Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* This is an example sketch to send battery, temperature, and GPS location data to
- * the cloud via either HTTP GET and POST requests or via MQTT protocol. In this
- * sketch we will send to dweet.io, a free cloud API, as well as to ThingsBoard.io,
- * a very powerful and free IoT platform that allows you to visualize data on dashboards.
- *
- * SETTINGS: You can choose to post only once or to post periodically
- * by commenting/uncommenting line 57 ("#define samplingRate 30"). When this line is
- * commented out the AVR microcontroller and MCP9808 temperature sensor are put to
- * sleep to conserve power, but when the line is being used data will be sent to the
- * cloud periodically. This makes it operate like a GPS tracker!
- *
- * PROTOCOL: You can use HTTP GET or POST requests and you can change the URL to pretty
- * much anything you want. You can also use MQTT to publish data to different feeds
- * on Adafruit IO. You can also subscribe to Adafruit IO feeds to command the device
- * to do something! In order to select a protocol, simply uncomment a line in the #define
- * section below!
- *
- * DWEET.IO: To check if the data was successfully sent to dweet, go to
- * http://dweet.io/get/latest/dweet/for/{IMEI} and the IMEI number is printed at the
- * beginning of the code but can also be found printed on the SIMCOM module itself.
- *
- * IoT Example Getting-Started Tutorial: https://github.com/botletics/SIM7000-LTE-Shield/wiki/GPS-Tracker-Example
- * GPS Tracker Tutorial Part 1: https://www.instructables.com/id/Arduino-LTE-Shield-GPS-Tracking-Freeboardio/
- * GPS Tracker Tutorial Part 2: https://www.instructables.com/id/LTE-Arduino-GPS-Tracker-IoT-Dashboard-Part-2/
- *
- * Author: Timothy Woo (www.botletics.com)
- * Github: https://github.com/botletics/SIM7000-LTE-Shield
- * Last Updated: 3/31/2021
- * License: GNU GPL v3.0
- */
- #include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
- // You don't need the following includes if you're not using MQTT
- // You can find the Adafruit MQTT library here: https://github.com/adafruit/Adafruit_MQTT_Library
- #include "Adafruit_MQTT.h"
- #include "Adafruit_MQTT_FONA.h"
- // Define *one* of the following lines:
- //#define SIMCOM_2G // SIM800/808/900/908, etc.
- //#define SIMCOM_3G // SIM5320
- #define SIMCOM_7000
- //#define SIMCOM_7070
- //#define SIMCOM_7500
- //#define SIMCOM_7600
- // Uncomment *one* of the following protocols you want to use
- // to send data to the cloud! Leave the other commented out
- #define PROTOCOL_MQTT_CLOUDMQTT // CloudMQTT
- /************************* PIN DEFINITIONS *********************************/
- #define FONA_RST 7 // No RST pin for SIM7070
- #define FONA_PWRKEY 12
- #define FONA_TX 8
- #define FONA_RX 7
- uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
- uint8_t type;
- char imei[16] = {0}; // MUST use a 16 character buffer for IMEI!
- #define LED 13 // Just for testing if needed!
- // Hardware serial is also possible!
- HardwareSerial *fonaSerial = &Serial;
- // Use this one for LTE CAT-M/NB-IoT modules (like SIM7000)
- // Notice how we don't include the reset pin because it's reserved for emergencies on the LTE module!
- Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();
- /************************* MQTT SETUP *********************************/
- // For CloudMQTT find these under the "Details" tab:
- #define MQTT_SERVER ""
- #define MQTT_SERVERPORT
- #define MQTT_USERNAME ""
- #define MQTT_KEY ""
- /****************************** OTHER STUFF ***************************************/
- // For sleeping the AVR
- #include <avr/sleep.h>
- #include <avr/power.h>
- char URL[200]; // Make sure this is long enough for your request URL
- char body[100]; // Make sure this is long enough for POST body
- char latBuff[12], longBuff[12], locBuff[50], speedBuff[12],
- headBuff[12], altBuff[12], tempBuff[12], battBuff[12];
- void setup() {
- Serial.begin(115200);
- Serial.println(F("*** SIMCom Module IoT Example ***"));
- #ifdef LED
- pinMode(LED, OUTPUT);
- digitalWrite(LED, LOW);
- #endif
- pinMode(FONA_RST, OUTPUT);
- digitalWrite(FONA_RST, HIGH); // Default state
- fona.powerOn(FONA_PWRKEY); // Power on the module
- moduleSetup(); // Establishes first-time serial comm and prints IMEI
- fonaSerial->begin(115200); // Default SIM7000 baud rate
- // Set modem to full functionality
- fona.setFunctionality(1); // AT+CFUN=1
- fona.setNetworkSettings(F("internet")); // For Hologram SIM card
- // Perform first-time GPS/GPRS setup if the shield is going to remain on,
- // otherwise these won't be enabled in loop() and it won't work!
- while (!fona.enableGPS(true)) {
- Serial.println(F("Failed to turn on GPS, retrying..."));
- delay(2000); // Retry every 2s
- }
- Serial.println(F("Turned on GPS!"));
- // Turn on GPRS
- while (!fona.enableGPRS(true)) {
- Serial.println(F("Failed to enable GPRS, retrying..."));
- delay(2000); // Retry every 2s
- }
- Serial.println(F("Enabled GPRS!"));
- }
- void loop() {
- // Connect to cell network and verify connection
- // If unsuccessful, keep retrying every 2s until a connection is made
- while (!netStatus()) {
- Serial.println(F("Failed to connect to cell network, retrying..."));
- delay(2000); // Retry every 2s
- }
- Serial.println(F("Connected to cell network!"));
- delay(500); // I found that this helps
- float latitude, longitude, speed_kph, heading, altitude;
- // Get a fix on location, try every 2s
- // Use the top line if you want to parse UTC time data as well, the line below it if you don't care
- // while (!fona.getGPS(&latitude, &longitude, &speed_kph, &heading, &altitude, &year, &month, &day, &hour, &minute, &second)) {
- while (!fona.getGPS(&latitude, &longitude, &speed_kph, &heading, &altitude)) {
- Serial.println(F("Failed to get GPS location, retrying..."));
- delay(2000); // Retry every 2s
- }
- Serial.println(F("Found 'eeeeem!"));
- Serial.println(F("---------------------"));
- Serial.print(F("Latitude: ")); Serial.println(latitude, 6);
- Serial.print(F("Longitude: ")); Serial.println(longitude, 6);
- Serial.print(F("Speed: ")); Serial.println(speed_kph);
- Serial.print(F("Heading: ")); Serial.println(heading);
- Serial.print(F("Altitude: ")); Serial.println(altitude);
- /*
- // Uncomment this if you care about parsing UTC time
- Serial.print(F("Year: ")); Serial.println(year);
- Serial.print(F("Month: ")); Serial.println(month);
- Serial.print(F("Day: ")); Serial.println(day);
- Serial.print(F("Hour: ")); Serial.println(hour);
- Serial.print(F("Minute: ")); Serial.println(minute);
- Serial.print(F("Second: ")); Serial.println(second);
- */
- Serial.println(F("---------------------"));
- // Post something like temperature and battery level to the web API
- // Construct URL and post the data to the web API
- // Format the floating point numbers
- dtostrf(latitude, 1, 6, latBuff);
- dtostrf(longitude, 1, 6, longBuff);
- dtostrf(speed_kph, 1, 0, speedBuff);
- dtostrf(heading, 1, 0, headBuff);
- dtostrf(altitude, 1, 1, altBuff);
- // Also construct a combined, comma-separated location array
- // (many platforms require this for dashboards, like Adafruit IO):
- sprintf(locBuff, "%s,%s,%s,%s", speedBuff, latBuff, longBuff, altBuff); // This could look like "10,33.123456,-85.123456,120.5"
- // Construct the appropriate URL's and body, depending on request type
- // In this example we use the IMEI as device ID
- // Let's use CloudMQTT! NOTE: connecting and publishing work, but everything else
- // still under development!!!
- char MQTT_CLIENT[16] = " "; // We'll change this to the IMEI
- // Let's begin by changing the client name to the IMEI number to better identify
- strcpy(MQTT_CLIENT, imei); // Copy the contents of the imei into the char array "MQTT_client"
- // Connect to MQTT broker
- if (!fona.TCPconnect(MQTT_SERVER, MQTT_SERVERPORT)) Serial.println(F("Failed to connect to TCP/IP!"));
- // CloudMQTT requires "MQIsdp" instead of "MQTT"
- if (!fona.MQTTconnect("MQIsdp", MQTT_CLIENT, MQTT_USERNAME, MQTT_KEY)) Serial.println(F("Failed to connect to MQTT broker!"));
- // Publish each data point under a different topic!
- Serial.println(F("Publishing data to their respective topics!"));
- // if (!fona.MQTTpublish("latitude", latBuff)) Serial.println(F("Failed to publish data!")); // Can send individually if needed
- // if (!fona.MQTTpublish("longitude", longBuff)) Serial.println(F("Failed to publish data!"));
- if (!fona.MQTTpublish("location", locBuff)) Serial.println(F("Failed to publish data!")); // Combined data
- if (!fona.MQTTpublish("speed", speedBuff)) Serial.println(F("Failed to publish data!"));
- if (!fona.MQTTpublish("heading", headBuff)) Serial.println(F("Failed to publish data!"));
- if (!fona.MQTTpublish("altitude", altBuff)) Serial.println(F("Failed to publish data!"));
- if (!fona.MQTTpublish("temperature", tempBuff)) Serial.println(F("Failed to publish data!"));
- if (!fona.MQTTpublish("voltage", battBuff)) Serial.println(F("Failed to publish data!"));
- // Disconnect from MQTT broker
- // if (!fona.MQTTdisconnect()) Serial.println(F("Failed to close connection!"));
- // Close TCP connection
- if (!fona.TCPclose()) Serial.println(F("Failed to close connection!"));
- }
- void moduleSetup() {
- // SIM7000 takes about 3s to turn on and SIM7500 takes about 15s
- // Press Arduino reset button if the module is still turning on and the board doesn't find it.
- // When the module is on it should communicate right after pressing reset
- // Hardware serial:
- fonaSerial->begin(115200); // Default SIM7000 baud rate
- if (! fona.begin(*fonaSerial)) {
- Serial.println(F("Couldn't find FONA"));
- }
- // The commented block of code below is an alternative that will find the module at 115200
- // Then switch it to 9600 without having to wait for the module to turn on and manually
- // press the reset button in order to establish communication. However, once the baud is set
- // this method will be much slower.
- /*
- fonaSerial->begin(115200); // Default LTE shield baud rate
- fona.begin(*fonaSerial); // Don't use if statement because an OK reply could be sent incorrectly at 115200 baud
- Serial.println(F("Configuring to 9600 baud"));
- fona.setBaudrate(9600); // Set to 9600 baud
- fonaSerial->begin(9600);
- if (!fona.begin(*fonaSerial)) {
- Serial.println(F("Couldn't find modem"));
- while(1); // Don't proceed if it couldn't find the device
- }
- */
- type = fona.type();
- Serial.println(F("FONA is OK"));
- Serial.print(F("Found "));
- switch (type) {
- case SIM800L:
- Serial.println(F("SIM800L")); break;
- case SIM800H:
- Serial.println(F("SIM800H")); break;
- case SIM808_V1:
- Serial.println(F("SIM808 (v1)")); break;
- case SIM808_V2:
- Serial.println(F("SIM808 (v2)")); break;
- case SIM5320A:
- Serial.println(F("SIM5320A (American)")); break;
- case SIM5320E:
- Serial.println(F("SIM5320E (European)")); break;
- case SIM7000:
- Serial.println(F("SIM7000")); break;
- case SIM7070:
- Serial.println(F("SIM7070")); break;
- case SIM7500:
- Serial.println(F("SIM7500")); break;
- case SIM7600:
- Serial.println(F("SIM7600")); break;
- default:
- Serial.println(F("???")); break;
- }
- // Print module IMEI number.
- uint8_t imeiLen = fona.getIMEI(imei);
- if (imeiLen > 0) {
- Serial.print("Module IMEI: "); Serial.println(imei);
- }
- }
- bool netStatus() {
- int n = fona.getNetworkStatus();
- Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
- if (n == 0) Serial.println(F("Not registered"));
- if (n == 1) Serial.println(F("Registered (home)"));
- if (n == 2) Serial.println(F("Not registered (searching)"));
- if (n == 3) Serial.println(F("Denied"));
- if (n == 4) Serial.println(F("Unknown"));
- if (n == 5) Serial.println(F("Registered roaming"));
- if (!(n == 1 || n == 5)) return false;
- else return true;
- }
- // 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.
- // Turn off the MCU completely. Can only wake up from RESET button
- // However, this can be altered to wake up via a pin change interrupt
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement