Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
|
You are living in a high-rise estate and when taking your waste to the central collection point you are annoyed always pick the wrong time: All wastebins are full. This may lead to illegal disposal beside wastebins, areas around the building or forests, and my lead to others start dumping their waste there, too. These practices are harmful to the environment and will attract vermin. This can be viewed for 2 different civilisations, first I was thinking of developed european areas, but in not so well developed areas the waste management depends on bringing the waste to a central point in the village, there the danger of just burning the waste or dropping it anywere and destroying the environment is higher.
What are you going to build to solve this problem? How is it different from existing solutions? Why is it useful?Subscribe to a notification on your phone, telling you when the level of waste is low at the central collection point. Usual services are for the housemaintainer telling when wastebins are full and wait for collection, this service is for the people living there, not wasting time and get disappointed when they get not rid of thiere waste and do not try to dispose the garbage in a harmful way.
How does your solution work? What are the main features? Please specify how you will use the AVR-IoT Cellular Mini in your solution.I put a level detection on the central collection point waste bins and provide a simple website to register for a sms subscription service and show level of emptiness. The AVR-IoT Cellular Mini is connected to the sensor and sends regular data to a webservice. Learn from the collected data and predict empty wastebins for the future days to give a next best possibility to go to the wastebins.
Notes:
Exchanged included SIM with iotcreators.com, it's free without time limit, has message limits
provision.io needs to be run FIRST with default certificat to be able to use https to iot platform https://github.com/microchip-pic-avr-solutions/avr-iot-cellular-arduino-library/blob/main/examples/provision/provision.ino
Wanted to use VL53L0X, which did not deliver plausible values, maybe library related, just tried one; so I switched to VL53L1X.
Visualisation and notification via e-mail is done with adafruit iot platform io.adafruit.com. e-mail is send max. once per day.
E-mail notification is set per API call; That's how it looks like:
Housing build with LEGO
Mounting has to be done inside the wastebin to monitor at top
Measurement takes place every hour
Optional: logging via MQTT, set variable to true
Copy config.h.template to config.h and insert your io.adafruit.com credentials, and optional MQTT parameters.
ResultI would call it a MVP for further exploration...
Was nice to figure out how to work with the AVR board.
Obstacles along the way- Setup MS Code + AVR plugin + Arduino IDE + current arduino-cli on macOS
Quite some try and error along the settings in MS Code AVR plugin.
There are some hints on the internet, but no complete guide which would cover this. - To get the code then to the device, I used the 'checkmark' in MS Code and then copied the resulting hex on the commandline to the device.
This is the most efficient way for me - To get more technical documentation and updates for the modem, or even the DM-Light Tool, you have to beg Sequans to gain access.
Not to mention that all tools are Windows only... - Finding a dumb powerbank, that does not shutdown if the curent is too low ;-)
All these modern powerbanks shutdown after some time if the ARV board is in powersave mode. - Communication with the modem via AT commands.
Somehow after powering up or waking up from sleep, the first commands return strings are incomplete, cut off or even empty, using the avr-iot-cellular-arduino-library.
#include <Arduino.h>
#include <log.h>
#include <sequans_controller.h>
#include <led_ctrl.h>
#include <lte.h>
#include <mqtt_client.h>
#include <low_power.h>
#include <mcp9808.h>
#include <veml3328.h>
#include <Wire.h>
#include <VL53L0X.h>
#include "SparkFun_VL53L1X.h"
#include <http_client.h>
#include "config.h"
VL53L0X sensor_50;
SFEVL53L1X sensor_51;
#define DOMAIN "io.adafruit.com"
#define MQTT_ENABLED false
#define MQTT_USE_TLS false
#define MQTT_KEEPALIVE 60
#define MQTT_USE_ECC false
ResponseResult response_result;
// make strings big enough, to not have to care about them
static char response[1024] = "";
static char reason[255] = "";
static char result[1024] = "";
static char x[1024] = "";
static char message[1024] = "";
static char adaiobase[1024] = "";
static int err;
static char *ptr;
static char deviceid[20]; // = "avr-123456789012345\0";
static char simid[21]; // = "12345678901234567890\0";
static int CESQ;
static volatile bool switchir = false;
static volatile bool pinir = false;
static bool error = true;
static int maxwhile = 0;
static int distance;
static float voltage;
static int temperature;
static HttpResponse hresponse;
static void switchInterrupt(void) {
switchir = true;
digitalWrite(PIN_PB2, LOW); // user led on
}
void(* resetFunc) (void) = 0; //declare reset function @ address 0
// VL53L0X https://github.com/pololu/vl53l0x-arduino 0x29
// VL53L1X https://github.com/sparkfun/SparkFun_VL53L1X_Arduino_Library 0x29
void setup() {
Log.begin(115200);
Log.info(F("setup"));
LowPower.configurePowerDown();
SequansController.begin();
// telekom.nl sim iotcreators.com APN
response_result = SequansController.writeCommand(F("AT+CGDCONT=1,\"IPV4V6\",\"m2m.public.nl\""),response,sizeof(response));
if (response_result != ResponseResult::OK) {
Log.errorf(F("AT+CGDCONT: %s\r\n"),response);
}
// Returns result codes in words
response_result = SequansController.writeCommand(F("ATV1"),response,sizeof(response));
if (response_result != ResponseResult::OK) {
Log.errorf(F("ATV1: %s\r\n"),response);
}
// get deviceid
response_result = SequansController.writeCommand(F("AT+CGSN=1"),response,sizeof(response));
if (response_result != ResponseResult::OK) {
Log.errorf(F("1AT+CGSN=1: %s\r\n"),response);
} else {
Log.infof(F("1AT+CGSN=1: %s\r\n"),response);
SequansController.writeCommand(F("AT+CGSN=1"),response,sizeof(response));
Log.infof(F("2AT+CGSN=1: %s\r\n"),response);
if (response[0] == '\0') {
response_result = SequansController.writeCommand(F("AT^RESET"),response,sizeof(response));
if (response_result == ResponseResult::OK) {
Log.infof(F("AT^RESET: %s\r\n"),response);
response_result = SequansController.writeCommand(F("AT+CGSN=1"),response,sizeof(response));
if (response_result == ResponseResult::OK) {
Log.infof(F("3AT+CGSN=1: %s\r\n"),response);
if (response[0] == '\0') {
// the response was alway incomplete or empty until here: giving up, start over
resetFunc();
}
} else {
Log.errorf(F("4AT+CGSN=1: %s\r\n"),response);
}
} else {
Log.errorf(F("AT^RESET: %s\r\n"),response);
}
} else {
SequansController.writeCommand(F("AT+CGSN=1"),response,sizeof(response));
}
}
// TODO: check for 2 " +CGSN: "dsadadasdasad"
Log.infof(F("AT^RESET or AT+CGSN=1: %s\r\n"),response);
ptr = strtok(response, ": \"\r\n");
// validate deviceid 15
if (strlen(ptr) != 15) {
// I hate SequansController it is just not reliable....(this was before I increased strings to 1024)
response_result = SequansController.writeCommand(F("AT+CGSN=1"),response,sizeof(response));
ptr = strtok(response, ": \"\r\n");
if (strlen(ptr) != 15) {
resetFunc();
}
}
// finaly deviceid
snprintf(deviceid, sizeof(deviceid), "avr-%s", ptr);
// start mobile connection
err = Lte.begin(60000,true);
if (err) {
Log.infof(F("lte: %d\r\n"),err);
} else {
Log.errorf(F("lte: %d\r\n"),err);
}
// get simid
response_result = SequansController.writeCommand(F("AT+SQNCCID"),response,sizeof(response));
if (response_result != ResponseResult::OK) {
Log.errorf(F("AT+SQNCCID: %s\r\n"),response);
}
Log.infof(F("AT+SQNCCID: %s\r\n"),response);
ptr = strtok(response, "\"");
ptr = strtok(NULL, "\"");
snprintf(simid, sizeof(simid), "%s", ptr);
// get modem firmware version
response_result = SequansController.writeCommand(F("AT+CGMR"),response,sizeof(response));
if (response_result != ResponseResult::OK) {
Log.errorf(F("AT+CGMR: %s\r\n"),response);
}
// AT+CGMR UE8.0.5.13
ptr = strtok(response, "\r\n");
strcpy(message, "{");
strcat(message, ptr);
strcat(message, ", ");
strcat(message, deviceid);
strcat(message, ", I:");
strcat(message, simid);
strcat(message, ", S:");
// get modem serial number
response_result = SequansController.writeCommand(F("ATI2"),response,sizeof(response));
if (response_result != ResponseResult::OK) {
Log.errorf(F("AT+SQNCCID: %s\r\n"),response);
}
ptr = strtok(response, ": \"\r\n");
ptr = strtok(NULL, ": \"\r\n");
strcat(message, ptr);
// SERIAL: G2P211234567890
// get device ip at+cgpaddr
LedCtrl.begin();
if (MQTT_ENABLED) {
err = MqttClient.begin(deviceid,MQTT_BROKER,MQTT_PORT,MQTT_USE_TLS,MQTT_KEEPALIVE,MQTT_USE_ECC,MOSQUITTO_USERNAME,MOSQUITTO_PASSWORD,30000,true);
if (err) {
Log.infof(F("mqtt: %d\r\n"),err);
} else {
Log.errorf(F("mqtt: %d\r\n"),err);
}
connectToMQTT();
strcat(message, "}");
String message_to_publish = String(message);
strcpy(response, "hackster/waste/");
strcat(response, deviceid);
strcat(response, "/boot");
err = MqttClient.publish(response, message_to_publish.c_str());
Log.infof(F("publish: boot, %d %s %s"),err,response,message);
}
Mcp9808.begin();
Veml3328.begin();
Veml3328.shutdown();
// user led
pinConfigure(PIN_PB2, PIN_DIR_OUTPUT);
// switchir / pinir input
pinConfigure(PIN_PD2, PIN_DIR_INPUT | PIN_PULLUP_ON); // for debugging ir with sw1
attachInterrupt(PIN_PD2, switchInterrupt, FALLING);
Log.infof(F("------pins: %d\r\n"), digitalRead(PIN_PD2));
// inventory of both i2c busses to find sensors on qwiic
Wire.begin();
Wire1.begin();
// find tof sensors, tried several ones, have to check other libraries....todo
Log.infof(F("------vl53l0x-------\r\n"));
sensor_50.setBus(&Wire1);
sensor_50.setTimeout(500);
err = sensor_50.init();
Log.infof(F("-------------i %d\r\n"),err);
Log.infof(F("------vl53l1x-------\r\n"));
err = sensor_51.begin(Wire1);
Log.infof(F("-------------i %d\r\n"),err);
// start communication with adafruit iot platform
// todo: auto provision htts, instead of provision.ino
if (!HttpClient.configure(DOMAIN, 443, true)) {
Log.info(F("Failed to configure https client\r\n"));
}
// try to read group with deviceid name, it it fails we know we need to create it.
strcpy(message, "/api/v2/");
strcat(message, IO_USERNAME);
strcpy(adaiobase, message);
strcpy(message, adaiobase);
strcat(message, "/groups/");
strcat(message, deviceid);
hresponse = HttpClient.get (message, IO_KEY);
Log.infof(F("GET - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
String response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256); // if more chars are displayed it gets garbish
Log.infof(F("1Response: %s\r\n"), response_data.c_str());
}
if (hresponse.status_code == 404) {
strcpy(message, adaiobase);
strcat(message, "/groups");
strcpy(result, "name=");
strcat(result, deviceid);
hresponse = HttpClient.post (message, result, IO_KEY, HttpClient.CONTENT_TYPE_MULTIPART_FORM_DATA);
Log.infof(F("POST - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256);
Log.infof(F("6Response: %s\r\n"), response_data.c_str());
}
}
// create feeds in group, just fire the request, if we get 400 status we know they already exist
strcpy(message, adaiobase);
strcat(message, "/groups/");
strcat(message, deviceid);
strcat(message, "/feeds");
hresponse = HttpClient.post (message, "{\"feed\": {\"name\": \"distance\"}}", IO_KEY, HttpClient.CONTENT_TYPE_APPLICATION_JSON);
Log.infof(F("POST - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256);
Log.infof(F("2Response: %s\r\n"), response_data.c_str());
}
hresponse = HttpClient.post (message, "{\"feed\": {\"name\": \"temperature\"}}", IO_KEY, HttpClient.CONTENT_TYPE_APPLICATION_JSON);
Log.infof(F("POST - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256);
Log.infof(F("3Response: %s\r\n"), response_data.c_str());
}
hresponse = HttpClient.post (message, "{\"feed\": {\"name\": \"battery\"}}", IO_KEY, HttpClient.CONTENT_TYPE_APPLICATION_JSON);
Log.infof(F("POST - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256);
Log.infof(F("3Response: %s\r\n"), response_data.c_str());
}
hresponse = HttpClient.post (message, "{\"feed\": {\"name\": \"signal\"}}", IO_KEY, HttpClient.CONTENT_TYPE_APPLICATION_JSON);
Log.infof(F("POST - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256);
Log.infof(F("3Response: %s\r\n"), response_data.c_str());
}
// create email action
strcpy(message, adaiobase);
strcat(message, "/feeds/");
strcat(message, deviceid);
strcat(message, ".distance");
hresponse = HttpClient.get (message, IO_KEY);
Log.infof(F("GET - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256);
Log.infof(F("2Response: %s\r\n"), response_data.c_str());
strcpy(response, response_data.c_str());
ptr = strtok(response, "}");
ptr = strtok(NULL, "}");
ptr = strtok(ptr, ":,");
ptr = strtok(NULL, ":,");
Log.infof(F("id: %s\r\n"), ptr);
strcpy(reason, ptr);
}
strcpy(message, adaiobase);
strcat(message, "/actions");
hresponse = HttpClient.get (message, IO_KEY);
Log.infof(F("GET - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
if (hresponse.status_code > 0) {
response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256);
Log.infof(F("2Response: %s\r\n"), response_data.c_str());
}
if (hresponse.data_size < 150) {
strcpy(message, adaiobase);
strcat(message, "/actions");
strcpy(response, "{\"trigger\":{\"feed_id\":");
strcat(response, reason);
strcat(response, ",\"operator\":\"gt\",\"value\":\"300\",\"action\":\"email\",\"to_feed_id\":null,\"action_feed_id\":");
strcat(response, reason);
strcat(response, ",\"action_value\":null,\"trigger_type_id\":null,\"status\":\"started\",\"notify_limit\":1440,\"notify_on_reset\":null,\"body_template\":\"The {{feed_name}} feed has a new value: {{value}} at {{created_at}}\",\"subject_template\":\"{{{{feed_name}}}} feed has a new value: {{{{value}}}}\",\"timer_wait\":10,\"timer_extend\":null,\"form_encoded\":null,\"trigger_type\":\"reactive\",\"description\":\"If distance is greater than 300 then email me the distance value.\"}}");
hresponse = HttpClient.post (message, response, IO_KEY, HttpClient.CONTENT_TYPE_APPLICATION_JSON);
Log.infof(F("POST - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
if (hresponse.status_code > 0) {
response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256);
Log.infof(F("2Response: %s\r\n"), response_data.c_str());
}
}
}
}
// get service data if we got ratelimited
strcpy(message, adaiobase);
strcat(message, "/throttle");
hresponse = HttpClient.get(message, IO_KEY);
Log.infof(F("GET - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256);
Log.infof(F("6Response: %s\r\n"), response_data.c_str());
}
// get signal strength, now that we transmitted smth.
response_result = SequansController.writeCommand(F("AT+CESQ"),response,sizeof(response));
err = SequansController.extractValueFromCommandResponse(response,5,result,sizeof(result));
if (err) {
Log.infof(F("AT+CESQ: %s; "),result);
CESQ = atoi(result)-140;
Log.infof(F("AT+CESQ: %d\r\n"),CESQ);
}
// celebrate finishing setup
LedCtrl.startupCycle();
}
void loop() {
Log.infof("- - L O O P - -\r\n");
static int i=0;
distance = 0;
i++;
strcpy(reason, "hourly");
Log.infof(F("------pins: %d\r\n"), digitalRead(PIN_PD2));
// since we might just had finished low power mode
Mcp9808.wake();
// check if switch was pressed
if (switchir) {
Log.info(F("switchInterrupt"));
delay(1000);
digitalWrite(PIN_PB2, HIGH); // user led off
switchir = false;
strcpy(reason, "test");
}
// i2c inventory on both busses
Log.infof("- - WIRE - -\r\n");
for(int i=1; i<128; i++){
Wire.beginTransmission(i);
error = Wire.endTransmission();
if(error == 0){
Log.infof(F("-------------0x%x\r\n"),i);
} else {
//Log.infof(F("%d-%d"),i,error);
}
}
Log.infof("- - WIRE1 - -\r\n");
for(int i=1; i<128; i++){
Wire1.beginTransmission(i);
error = Wire1.endTransmission();
if(error == 0){
Log.infof(F("-------------0x%x\r\n"),i);
} else {
//Log.infof(F("%d-%d"),i,error);
}
}
Log.infof("- - - -\r\n");
// try to get measurements from tof sensors with several libraries
// init function from setup does not check deep enough
Log.infof("- - VL53L0X - -\r\n");
maxwhile = sensor_50.readRangeSingleMillimeters();
Log.infof("distance in mm: %d\r\n",maxwhile);
if (sensor_50.timeoutOccurred()) {
Log.error(" TIMEOUT\r\n");
} else {
if (maxwhile > 1) {
distance = maxwhile;
}
}
Log.infof("- - VL53L1X - -\r\n");
sensor_51.startOneshotRanging();
maxwhile = 0;
while (!sensor_51.checkForDataReady() && maxwhile < 1000) {
delay(1);
maxwhile+=1;
}
if (maxwhile == 1000) {
Log.errorf("- - dataready exeeeeded !!!!!!!!!!!!!!!!!!!!!!!!! - -\r\n");
}
distance = sensor_51.getDistance();
Log.infof("distance: %d\r\n",distance);
Log.infof("- - - -\r\n");
SequansController.writeCommand(F("AT+CGSN=0"),response,sizeof(response));
Log.infof(F("AT+CGSN=0: %s\r\n"),response);
connectToNetwork(); // here modem takes leds over
// build hourly mqtt reporting
strcpy(message, "{");
strcat(message, deviceid);
strcat(message, ", I:");
strcat(message, simid);
// dummy, since I had problems with empty+uncomplete responses
response_result = SequansController.writeCommand(F("AT+CESQ"),response,sizeof(response));
// get network operator MC/NC
response_result = SequansController.writeCommand(F("AT+COPS?"),response,sizeof(response));
if (response_result == ResponseResult::OK) {
Log.infof(F("AT+COPS?: %s\r\n"),response);
}
err = SequansController.extractValueFromCommandResponse(response,2,result,sizeof(result));
if (err) {
ptr = strtok(result, ": \"\r\n");
strcat(message, ", MC/NC:");
strcat(message, ptr);
}
// get TAC/CI
// get connection mode: LTE-M or NBIOT
response_result = SequansController.writeCommand(F("AT+CEREG?"),response,sizeof(response));
if (response_result == ResponseResult::OK) {
Log.infof(F("AT+CEREG: %s\r\n"),response);
}
err = SequansController.extractValueFromCommandResponse(response,2,result,sizeof(result));
if (err) {
ptr = strtok(result, ": \"\r\n");
strcat(message, ", TAC:");
strcat(message, ptr);
}
err = SequansController.extractValueFromCommandResponse(response,3,result,sizeof(result));
if (err) {
ptr = strtok(result, ": \"\r\n");
strcat(message, ", CI:");
strcat(message, ptr);
}
err = SequansController.extractValueFromCommandResponse(response,4,result,sizeof(result));
if (err) {
Log.infof(F("extractValueFromCommandResponse: %s\r\n"),result);
if (atoi(result) == 7) {sprintf(x, ", LTEM");}
if (atoi(result) == 9) {sprintf(x, ", NBIOT");}
}
strcat(message, x);
// get date/time
response_result = SequansController.writeCommand(F("AT+CCLK?"),response,sizeof(response));
if (response_result == ResponseResult::OK) {
Log.infof(F("AT+CCLK?: %s\r\n"),response);
}
// get voltage of battery
voltage = LowPower.getSupplyVoltage();
Log.infof(F("The voltage supplied is: %.2f\r\n"), voltage);
snprintf(response, sizeof(response), ", bat:%.2f", (double) voltage);
strcat(message, response);
// get temperture
temperature = int(Mcp9808.readTempC());
Log.infof(F("Temperature (*C): %d\r\n"), temperature);
snprintf(response, sizeof(response), ", t:%d", temperature);
strcat(message, response);
snprintf(response, sizeof(response), ", d:%d", distance);
strcat(message, response);
snprintf(response, sizeof(response), ", %d", CESQ);
strcat(message, response);
snprintf(response, sizeof(response), ", up:%2d", i);
strcat(message, response);
snprintf(response, sizeof(response), ", p:%d", digitalRead(PIN_PD2));
strcat(message, response);
if (MQTT_ENABLED) {
connectToMQTT();
strcat(message, "}");
String message_to_publish = String(message);
strcpy(response, "hackster/waste/");
strcat(response, deviceid);
strcat(response, "/");
strcat(response, reason);
err = MqttClient.publish(response, message_to_publish.c_str());
Log.infof(F("publish: %d %d %s %s"),i,err,response,message);
}
// send values to adafruit iot platform
strcpy(message, adaiobase);
strcat(message, "/groups/");
strcat(message, deviceid);
strcat(message, "/data");
strcpy(result, "{\"feeds\": [ {\"key\": \"temperature\", \"value\": \"");
snprintf(response, sizeof(response), "%d", temperature);
strcat(result, response);
strcat(result, "\"}, {\"key\": \"distance\", \"value\": \"");
snprintf(response, sizeof(response), "%d", distance);
strcat(result, response);
strcat(result, "\"}, {\"key\": \"battery\", \"value\": \"");
snprintf(response, sizeof(response), "%.2f", (double) voltage);
strcat(result, response);
strcat(result, "\"}, {\"key\": \"signal\", \"value\": \"");
snprintf(response, sizeof(response), "%d", CESQ);
strcat(result, response);
strcat(result, "\"}]}");
Log.infof(F("path %s\r\n"),message);
Log.infof(F("data %s\r\n"),result);
hresponse = HttpClient.post (message, result, IO_KEY, HttpClient.CONTENT_TYPE_APPLICATION_JSON);
Log.infof(F("POST - HTTP status code: %u, data size: %u\r\n"), hresponse.status_code, hresponse.data_size);
String response_data = HttpClient.readBody();
if (response_data != "") {
response_data.remove(256);
Log.infof(F("4Response: %s\r\n"), response_data.c_str());
}
// get signal strength ...
response_result = SequansController.writeCommand(F("AT+CESQ"),response,sizeof(response));
err = SequansController.extractValueFromCommandResponse(response,5,result,sizeof(result));
if (err) {
Log.infof(F("AT+CESQ: %s\r\n"),result);
Log.infof(F("AT+CESQ: %d\r\n"),atoi(result)-140);
CESQ = atoi(result)-140;
}
// celebrate another loop finish
LedCtrl.startupCycle();
// go to sleep
Mcp9808.shutdown();
LowPower.powerDown(3540); // 60 min - 1 min for working through the loop ;-) - try to hit same minute every hour
//LowPower.powerDown(3600);
//delay(3600000); // 60min
//delay(600000); // 10min
}
static void connectToNetwork() {
if (!Lte.isConnected()) {
while (!Lte.begin(60000,true)) {} // hint: timesout, no danger of endless
Log.infof(F("REConnected to operator: %s\r\n"), Lte.getOperator().c_str());
}
}
static void connectToMQTT() {
int i =0;
if (Lte.isConnected()) {
if (!MqttClient.isConnected()) {
while ((i < 10) && !MqttClient.begin(deviceid,MQTT_BROKER,MQTT_PORT,MQTT_USE_TLS,MQTT_KEEPALIVE,MQTT_USE_ECC,MOSQUITTO_USERNAME,MOSQUITTO_PASSWORD,30000,true)) {
i++;
}
Log.info(F("REConnected to MqttClient"));
}
} else {
Log.error(F("no network, droping MqttClient connect"));
}
}
/************************ Adafruit IO Config *******************************/
// visit io.adafruit.com if you need to create an account,
// or if you need your Adafruit IO key.
#define IO_USERNAME "xxxxxx"
#define IO_KEY "X-AIO-Key: aio_xxxxxx"
/************************ mqtt Config *******************************/
#define MQTT_BROKER "iot.xxxxxxx.com"
#define MQTT_PORT 1234
#define MOSQUITTO_USERNAME "xxxxxxx"
#define MOSQUITTO_PASSWORD "xxxxxxx"
Comments