Advertisement
Guest User

Untitled

a guest
Apr 19th, 2022
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.24 KB | None | 0 0
  1. /* This is an example sketch to send battery, temperature, and GPS location data to
  2. * the cloud via either HTTP GET and POST requests or via MQTT protocol. In this
  3. * sketch we will send to dweet.io, a free cloud API, as well as to ThingsBoard.io,
  4. * a very powerful and free IoT platform that allows you to visualize data on dashboards.
  5. *
  6. * SETTINGS: You can choose to post only once or to post periodically
  7. * by commenting/uncommenting line 57 ("#define samplingRate 30"). When this line is
  8. * commented out the AVR microcontroller and MCP9808 temperature sensor are put to
  9. * sleep to conserve power, but when the line is being used data will be sent to the
  10. * cloud periodically. This makes it operate like a GPS tracker!
  11. *
  12. * PROTOCOL: You can use HTTP GET or POST requests and you can change the URL to pretty
  13. * much anything you want. You can also use MQTT to publish data to different feeds
  14. * on Adafruit IO. You can also subscribe to Adafruit IO feeds to command the device
  15. * to do something! In order to select a protocol, simply uncomment a line in the #define
  16. * section below!
  17. *
  18. * DWEET.IO: To check if the data was successfully sent to dweet, go to
  19. * http://dweet.io/get/latest/dweet/for/{IMEI} and the IMEI number is printed at the
  20. * beginning of the code but can also be found printed on the SIMCOM module itself.
  21. *
  22. * IoT Example Getting-Started Tutorial: https://github.com/botletics/SIM7000-LTE-Shield/wiki/GPS-Tracker-Example
  23. * GPS Tracker Tutorial Part 1: https://www.instructables.com/id/Arduino-LTE-Shield-GPS-Tracking-Freeboardio/
  24. * GPS Tracker Tutorial Part 2: https://www.instructables.com/id/LTE-Arduino-GPS-Tracker-IoT-Dashboard-Part-2/
  25. *
  26. * Author: Timothy Woo (www.botletics.com)
  27. * Github: https://github.com/botletics/SIM7000-LTE-Shield
  28. * Last Updated: 3/31/2021
  29. * License: GNU GPL v3.0
  30. */
  31.  
  32. #include "Adafruit_FONA.h" // https://github.com/botletics/SIM7000-LTE-Shield/tree/master/Code
  33.  
  34. // You don't need the following includes if you're not using MQTT
  35. // You can find the Adafruit MQTT library here: https://github.com/adafruit/Adafruit_MQTT_Library
  36. #include "Adafruit_MQTT.h"
  37. #include "Adafruit_MQTT_FONA.h"
  38.  
  39. // Define *one* of the following lines:
  40. //#define SIMCOM_2G // SIM800/808/900/908, etc.
  41. //#define SIMCOM_3G // SIM5320
  42. #define SIMCOM_7000
  43. //#define SIMCOM_7070
  44. //#define SIMCOM_7500
  45. //#define SIMCOM_7600
  46.  
  47. // Uncomment *one* of the following protocols you want to use
  48. // to send data to the cloud! Leave the other commented out
  49. #define PROTOCOL_MQTT_CLOUDMQTT // CloudMQTT
  50.  
  51. /************************* PIN DEFINITIONS *********************************/
  52. #define FONA_RST 7 // No RST pin for SIM7070
  53. #define FONA_PWRKEY 12
  54. #define FONA_TX 8
  55. #define FONA_RX 7
  56.  
  57. uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
  58. uint8_t type;
  59. char imei[16] = {0}; // MUST use a 16 character buffer for IMEI!
  60. #define LED 13 // Just for testing if needed!
  61.  
  62. // Hardware serial is also possible!
  63. HardwareSerial *fonaSerial = &Serial;
  64.  
  65.  
  66. // Use this one for LTE CAT-M/NB-IoT modules (like SIM7000)
  67. // Notice how we don't include the reset pin because it's reserved for emergencies on the LTE module!
  68. Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();
  69. /************************* MQTT SETUP *********************************/
  70. // For CloudMQTT find these under the "Details" tab:
  71. #define MQTT_SERVER ""
  72. #define MQTT_SERVERPORT
  73. #define MQTT_USERNAME ""
  74. #define MQTT_KEY ""
  75.  
  76. /****************************** OTHER STUFF ***************************************/
  77. // For sleeping the AVR
  78. #include <avr/sleep.h>
  79. #include <avr/power.h>
  80.  
  81. char URL[200]; // Make sure this is long enough for your request URL
  82. char body[100]; // Make sure this is long enough for POST body
  83. char latBuff[12], longBuff[12], locBuff[50], speedBuff[12],
  84. headBuff[12], altBuff[12], tempBuff[12], battBuff[12];
  85.  
  86. void setup() {
  87. Serial.begin(115200);
  88. Serial.println(F("*** SIMCom Module IoT Example ***"));
  89.  
  90. #ifdef LED
  91. pinMode(LED, OUTPUT);
  92. digitalWrite(LED, LOW);
  93. #endif
  94.  
  95. pinMode(FONA_RST, OUTPUT);
  96. digitalWrite(FONA_RST, HIGH); // Default state
  97.  
  98. fona.powerOn(FONA_PWRKEY); // Power on the module
  99. moduleSetup(); // Establishes first-time serial comm and prints IMEI
  100. fonaSerial->begin(115200); // Default SIM7000 baud rate
  101.  
  102. // Set modem to full functionality
  103. fona.setFunctionality(1); // AT+CFUN=1
  104.  
  105. fona.setNetworkSettings(F("internet")); // For Hologram SIM card
  106.  
  107.  
  108.  
  109.  
  110.  
  111. // Perform first-time GPS/GPRS setup if the shield is going to remain on,
  112. // otherwise these won't be enabled in loop() and it won't work!
  113. while (!fona.enableGPS(true)) {
  114. Serial.println(F("Failed to turn on GPS, retrying..."));
  115. delay(2000); // Retry every 2s
  116. }
  117. Serial.println(F("Turned on GPS!"));
  118.  
  119. // Turn on GPRS
  120. while (!fona.enableGPRS(true)) {
  121. Serial.println(F("Failed to enable GPRS, retrying..."));
  122. delay(2000); // Retry every 2s
  123. }
  124. Serial.println(F("Enabled GPRS!"));
  125.  
  126. }
  127.  
  128. void loop() {
  129. // Connect to cell network and verify connection
  130. // If unsuccessful, keep retrying every 2s until a connection is made
  131. while (!netStatus()) {
  132. Serial.println(F("Failed to connect to cell network, retrying..."));
  133. delay(2000); // Retry every 2s
  134. }
  135. Serial.println(F("Connected to cell network!"));
  136. delay(500); // I found that this helps
  137.  
  138. float latitude, longitude, speed_kph, heading, altitude;
  139. // Get a fix on location, try every 2s
  140. // Use the top line if you want to parse UTC time data as well, the line below it if you don't care
  141. // while (!fona.getGPS(&latitude, &longitude, &speed_kph, &heading, &altitude, &year, &month, &day, &hour, &minute, &second)) {
  142. while (!fona.getGPS(&latitude, &longitude, &speed_kph, &heading, &altitude)) {
  143. Serial.println(F("Failed to get GPS location, retrying..."));
  144. delay(2000); // Retry every 2s
  145. }
  146. Serial.println(F("Found 'eeeeem!"));
  147. Serial.println(F("---------------------"));
  148. Serial.print(F("Latitude: ")); Serial.println(latitude, 6);
  149. Serial.print(F("Longitude: ")); Serial.println(longitude, 6);
  150. Serial.print(F("Speed: ")); Serial.println(speed_kph);
  151. Serial.print(F("Heading: ")); Serial.println(heading);
  152. Serial.print(F("Altitude: ")); Serial.println(altitude);
  153. /*
  154. // Uncomment this if you care about parsing UTC time
  155. Serial.print(F("Year: ")); Serial.println(year);
  156. Serial.print(F("Month: ")); Serial.println(month);
  157. Serial.print(F("Day: ")); Serial.println(day);
  158. Serial.print(F("Hour: ")); Serial.println(hour);
  159. Serial.print(F("Minute: ")); Serial.println(minute);
  160. Serial.print(F("Second: ")); Serial.println(second);
  161. */
  162. Serial.println(F("---------------------"));
  163.  
  164. // Post something like temperature and battery level to the web API
  165. // Construct URL and post the data to the web API
  166.  
  167. // Format the floating point numbers
  168. dtostrf(latitude, 1, 6, latBuff);
  169. dtostrf(longitude, 1, 6, longBuff);
  170. dtostrf(speed_kph, 1, 0, speedBuff);
  171. dtostrf(heading, 1, 0, headBuff);
  172. dtostrf(altitude, 1, 1, altBuff);
  173.  
  174. // Also construct a combined, comma-separated location array
  175. // (many platforms require this for dashboards, like Adafruit IO):
  176. sprintf(locBuff, "%s,%s,%s,%s", speedBuff, latBuff, longBuff, altBuff); // This could look like "10,33.123456,-85.123456,120.5"
  177.  
  178. // Construct the appropriate URL's and body, depending on request type
  179. // In this example we use the IMEI as device ID
  180.  
  181.  
  182. // Let's use CloudMQTT! NOTE: connecting and publishing work, but everything else
  183. // still under development!!!
  184. char MQTT_CLIENT[16] = " "; // We'll change this to the IMEI
  185.  
  186. // Let's begin by changing the client name to the IMEI number to better identify
  187. strcpy(MQTT_CLIENT, imei); // Copy the contents of the imei into the char array "MQTT_client"
  188.  
  189. // Connect to MQTT broker
  190. if (!fona.TCPconnect(MQTT_SERVER, MQTT_SERVERPORT)) Serial.println(F("Failed to connect to TCP/IP!"));
  191. // CloudMQTT requires "MQIsdp" instead of "MQTT"
  192. if (!fona.MQTTconnect("MQIsdp", MQTT_CLIENT, MQTT_USERNAME, MQTT_KEY)) Serial.println(F("Failed to connect to MQTT broker!"));
  193.  
  194. // Publish each data point under a different topic!
  195. Serial.println(F("Publishing data to their respective topics!"));
  196. // if (!fona.MQTTpublish("latitude", latBuff)) Serial.println(F("Failed to publish data!")); // Can send individually if needed
  197. // if (!fona.MQTTpublish("longitude", longBuff)) Serial.println(F("Failed to publish data!"));
  198. if (!fona.MQTTpublish("location", locBuff)) Serial.println(F("Failed to publish data!")); // Combined data
  199. if (!fona.MQTTpublish("speed", speedBuff)) Serial.println(F("Failed to publish data!"));
  200. if (!fona.MQTTpublish("heading", headBuff)) Serial.println(F("Failed to publish data!"));
  201. if (!fona.MQTTpublish("altitude", altBuff)) Serial.println(F("Failed to publish data!"));
  202. if (!fona.MQTTpublish("temperature", tempBuff)) Serial.println(F("Failed to publish data!"));
  203. if (!fona.MQTTpublish("voltage", battBuff)) Serial.println(F("Failed to publish data!"));
  204.  
  205. // Disconnect from MQTT broker
  206. // if (!fona.MQTTdisconnect()) Serial.println(F("Failed to close connection!"));
  207.  
  208. // Close TCP connection
  209. if (!fona.TCPclose()) Serial.println(F("Failed to close connection!"));
  210.  
  211.  
  212.  
  213. }
  214.  
  215. void moduleSetup() {
  216. // SIM7000 takes about 3s to turn on and SIM7500 takes about 15s
  217. // Press Arduino reset button if the module is still turning on and the board doesn't find it.
  218. // When the module is on it should communicate right after pressing reset
  219.  
  220. // Hardware serial:
  221.  
  222. fonaSerial->begin(115200); // Default SIM7000 baud rate
  223. if (! fona.begin(*fonaSerial)) {
  224. Serial.println(F("Couldn't find FONA"));
  225. }
  226.  
  227.  
  228. // The commented block of code below is an alternative that will find the module at 115200
  229. // Then switch it to 9600 without having to wait for the module to turn on and manually
  230. // press the reset button in order to establish communication. However, once the baud is set
  231. // this method will be much slower.
  232. /*
  233. fonaSerial->begin(115200); // Default LTE shield baud rate
  234. fona.begin(*fonaSerial); // Don't use if statement because an OK reply could be sent incorrectly at 115200 baud
  235. Serial.println(F("Configuring to 9600 baud"));
  236. fona.setBaudrate(9600); // Set to 9600 baud
  237. fonaSerial->begin(9600);
  238. if (!fona.begin(*fonaSerial)) {
  239. Serial.println(F("Couldn't find modem"));
  240. while(1); // Don't proceed if it couldn't find the device
  241. }
  242. */
  243.  
  244. type = fona.type();
  245. Serial.println(F("FONA is OK"));
  246. Serial.print(F("Found "));
  247. switch (type) {
  248. case SIM800L:
  249. Serial.println(F("SIM800L")); break;
  250. case SIM800H:
  251. Serial.println(F("SIM800H")); break;
  252. case SIM808_V1:
  253. Serial.println(F("SIM808 (v1)")); break;
  254. case SIM808_V2:
  255. Serial.println(F("SIM808 (v2)")); break;
  256. case SIM5320A:
  257. Serial.println(F("SIM5320A (American)")); break;
  258. case SIM5320E:
  259. Serial.println(F("SIM5320E (European)")); break;
  260. case SIM7000:
  261. Serial.println(F("SIM7000")); break;
  262. case SIM7070:
  263. Serial.println(F("SIM7070")); break;
  264. case SIM7500:
  265. Serial.println(F("SIM7500")); break;
  266. case SIM7600:
  267. Serial.println(F("SIM7600")); break;
  268. default:
  269. Serial.println(F("???")); break;
  270. }
  271.  
  272. // Print module IMEI number.
  273. uint8_t imeiLen = fona.getIMEI(imei);
  274. if (imeiLen > 0) {
  275. Serial.print("Module IMEI: "); Serial.println(imei);
  276. }
  277. }
  278.  
  279.  
  280. bool netStatus() {
  281. int n = fona.getNetworkStatus();
  282.  
  283. Serial.print(F("Network status ")); Serial.print(n); Serial.print(F(": "));
  284. if (n == 0) Serial.println(F("Not registered"));
  285. if (n == 1) Serial.println(F("Registered (home)"));
  286. if (n == 2) Serial.println(F("Not registered (searching)"));
  287. if (n == 3) Serial.println(F("Denied"));
  288. if (n == 4) Serial.println(F("Unknown"));
  289. if (n == 5) Serial.println(F("Registered roaming"));
  290.  
  291. if (!(n == 1 || n == 5)) return false;
  292. else return true;
  293. }
  294.  
  295. // Function to connect and reconnect as necessary to the MQTT server.
  296. // Should be called in the loop function and it will take care if connecting.
  297.  
  298. // Turn off the MCU completely. Can only wake up from RESET button
  299. // However, this can be altered to wake up via a pin change interrupt
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement