As someone who aspires to become Tony Stark. I am very excited about this class. Without devices talking to each other, we can have no exciting future. This MQTT protocol allows us to deliver messages at what feels like light speed. So that we can do things with info gathered from far away places in what feels like real time. Game changing. Many applications these days are simple monitoring with no output, but soon, we will have other machines listening to these sensors, so that they execute automated functions upon receipt of certain messages. Now that I am finally uncovering this knowledge for myself, I am so very excited for all the wondrous possibilities this opens!
My goal for the class is to create a magic wand. This will use an accelerometer and other sensors to draw in data that is sent to a central server. An app on the central server will then train LSTM models from that data, so that unique sequences can be generated by the user for any future purpose.
So the first step is to get an accelerometer to send data, as it’s the most critical component.
This is the code for the accelerometer, which I did get working and sending data to the server. It was quite the headache to learn, however, that arrays are of a fixed memory size upon assignment in Arduino, meaning they cannot be added to after being created. They can only have assignments of 0. So, in order to send large data sets, I had to define an array size that made sense, and send it once I filled the array. I’m not sure if the code below is perfect, but it certainly did the trick. I put some necessary login data lines in a separate config header file.
#include <SparkFun_ADXL345.h> // SparkFun ADXL345 Library // MQTT headers #include <SPI.h> #ifdef ARDUINO_SAMD_MKR1010 #include <WiFi101.h> #define WL_NO_MODULE WL_NO_SHIELD #else #include <WiFiNINA.h> #endif #include <ArduinoMqttClient.h> #include "config.h" WiFiSSLClient net; MqttClient mqtt(net); String accelerometerTopic = "itp/" + DEVICE_ID + "/accelerometer"; // Publish every 10 seconds for the workshop. Real world apps need this data every 5 or 10 minutes. unsigned long publishInterval = 5 * 1000; unsigned long lastMillis = 0; int button = 6; int state = false; int xData[50]; int yData[50]; int zData[50]; //int posMoment[3]; int i = 0; /******************** SETUP ********************/ /* Configure ADXL345 Settings */ void setup() { Serial.begin(9600); // Start the serial terminal Serial.println("Connecting WiFi"); connectWiFi(); pinMode(button, INPUT); setAxl(); if (WiFi.status() != WL_CONNECTED) { connectWiFi(); } if (!mqtt.connected()) { connectMQTT(); } } void loop() { // poll for new MQTT messages and send keep alives mqtt.poll(); if (digitalRead(button) == HIGH && state == false) { state = true; delay(200); } else if (digitalRead(button) == HIGH && state == true) { state = false; delay(200); } if (state == true) { // // Accelerometer Readings int x, y, z; adxl.readAccel(&x, &y, &z); // Read the accelerometer values and store them in variables declared above x,y,z xData[i] = x; yData[i] = y; zData[i] = z; i++; } else if (state == false) { Serial.println("waiting"); } if (millis() - lastMillis > publishInterval) { lastMillis = millis(); mqtt.beginMessage(accelerometerTopic); Serial.println("begin message"); for (int k = 0; k <= 49; k++){ mqtt.print("x: "); mqtt.print(xData[k]); mqtt.print(", y: "); mqtt.print(yData[k]); mqtt.print(", z: "); mqtt.print(zData[k]); mqtt.print(" | "); Serial.print("x: "); Serial.print(xData[k]); Serial.print("y: "); Serial.print(yData[k]); Serial.print("z: "); Serial.println(zData[k]); xData[k] = 0; yData[k] = 0; zData[k] = 0; } Serial.println("end message"); mqtt.endMessage(); i = 0; } delay(100); } void connectWiFi() { // Check for the WiFi module if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue while (true); } Serial.print("WiFi firmware version "); Serial.println(WiFi.firmwareVersion()); Serial.print("Attempting to connect to SSID: "); Serial.print(WIFI_SSID); Serial.print(" "); while (WiFi.begin(WIFI_SSID, WIFI_PASSWORD) != WL_CONNECTED) { // failed, retry Serial.print("."); delay(20); } Serial.println("Connected to WiFi"); printWiFiStatus(); } void connectMQTT() { Serial.print("Connecting MQTT..."); mqtt.setId(DEVICE_ID); mqtt.setUsernamePassword(MQTT_USER, MQTT_PASSWORD); while (!mqtt.connect(MQTT_BROKER, MQTT_PORT)) { Serial.print("."); delay(200); } Serial.println("connected."); } void printWiFiStatus() { // print your WiFi IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); }
After many trials and errors, finally figured it out! Sending data! Too large? Readable? I felt splitting the statements by | and having each direction end with : would make it a simple regex task later. Though I have never used regex, so maybe not? It might be simpler to send each direction in a separate topic, then I could just send numbers, and that would be a super easy reconstruction task in javascript, now that I think about it. And probably easier on the arduino side as well.