Skip to content

Instantly share code, notes, and snippets.

@Thiemann96
Last active February 22, 2021 11:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Thiemann96/6ce9d5d99a38341c380ac2c53deb6401 to your computer and use it in GitHub Desktop.
Save Thiemann96/6ce9d5d99a38341c380ac2c53deb6401 to your computer and use it in GitHub Desktop.
Arduino Sketch for the futurium project
#include <BMX055.h>
#include <senseBoxIO.h>
#include <SPI.h>
#include <Wire.h>
#include <WiFi101.h>
#include "SparkFun_Ublox_Arduino_Library.h"
#include <NewPing.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_BMP280.h>
#include <SDS011-select-serial.h>
#define TRIGGER_LEFT 1
#define ECHO_LEFT 2
#define TRIGGER_RIGHT 3
#define ECHO_RIGHT 4
#define SENSOR_MAX_RANGE 400
#define OLED_RESET 4
// BMX055 Accl I2C address is 0x18(24)
#define Addr_Accl 0x18
// BMX055 Gyro I2C address is 0x68(104)
#define Addr_Gyro 0x68
// BMX055 Mag I2C address is 0x10(16)
#define Addr_Mag 0x10
#define DEBUG_ENABLED
Adafruit_SSD1306 display(OLED_RESET);
NewPing left(TRIGGER_LEFT, ECHO_LEFT, SENSOR_MAX_RANGE);
NewPing right(TRIGGER_RIGHT, ECHO_RIGHT, SENSOR_MAX_RANGE);
char sz[64];
char gps_dateTime[] = "2000-01-01T00:00:00Z";
typedef struct gpsPosition
{
char *dateTime = gps_dateTime;
float latitude;
float longitude;
float altitude;
} gpsPosition;
//One gpsPosition for each round of measurements
gpsPosition currentPosition;
const long interval1s = 1000;
const long interval10s = 10000;
long time_start = 0;
long time_actual_1s = 0;
long time_actual_10s = 0;
Adafruit_BMP280 BMP;
SDS011 SDS(Serial1);
char timestamp[64];
char buffer[750];// buffer for sprintf
String finalBuffer;
// Variables for BMX
int accX;
int accY;
int accZ;
// Rotation
int rotX;
int rotY;
int rotZ;
// Magnet
int magX;
int magY;
int magZ;
int sumAccZ;
int sumAccY;
int sumAccX;
int sumMagZ;
int sumMagY;
int sumMagX;
int sumRotZ;
int sumRotY;
int sumRotX;
// buffer for median filter
int lastReadingsRight[5];
int lastReadingsLeft[5];
int nrReadingsRight = 0;
int nrReadingsLeft = 0;
int medianResultRight;
int medianResultLeft;
// Wifi Credentials
const char *ssid = "NETZWERKNAME";
const char *pass = "PASSWORT";
BMX055 bmx;
int status = WL_IDLE_STATUS;
WiFiClient client;
IPAddress gateway;
int lastXValue = 0;
int lastYValue = 0;
int lastZValue = 0;
int distanceL = 0;
int distanceR = 0;
long latitude;
long longitude;
const char *header = "lat,lng,timestamp,sumAccX,sumAccY,sumAccZ,sumMagX,sumMagY,sumMagZ,sumRotX,sumRotY,sumRotZ,distLeft,distRight,temp,press,pm25,pm10";
/////////////////////////////////////////////
void initDisplay() {
#ifdef DEBUG_ENABLED
Serial.println("starting display");
#endif
display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
display.display();
delay(100);
display.clearDisplay();
}
void updateDisplay() {
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE, BLACK);
display.println("senseBox running...");
display.println(buffer);
display.display();
}
void printWifiInstructions() {
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE, BLACK);
display.println("Oeffnen Sie den Hotspot mit folgenden Daten");
display.print("SSID: ");
display.println(ssid);
display.print("Passwort:");
display.println(pass);
display.display();
}
void printWifiPassed() {
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE, BLACK);
display.println("Verbunden! Gleich geht es los ...");
display.display();
}
void sendToServer(String csv) {
bool connected = false;
char charBuf[csv.length()];
csv.toCharArray(charBuf, csv.length());
#ifdef DEBUG_ENABLED
Serial.println(header);
Serial.println(charBuf);
Serial.println("Connecting to web server...");
#endif
if (client.connect(gateway, 8080)) {
#ifdef DEBUG_ENABLED
Serial.println("connected to server");
#endif
// Make a HTTP request:
client.println("POST /data HTTP/1.1");
client.print("Host:");
client.println(gateway);
client.println("Content-Type:text/plain");
client.println("Connection: close");
client.print("Content-Length:");
client.println(csv.length());
client.println();
client.println(charBuf);
client.println();
#ifdef DEBUG_ENABLED
Serial.println("Message sent");
#endif
}
}
void sendActivation(){
if (client.connect(gateway, 8080)) {
#ifdef DEBUG_ENABLED
Serial.println("connected to server");
#endif
// Make a HTTP request:
client.println("GET /activation");
client.print("Host:");
client.println(gateway);
client.println("Connection: close");
client.println();
#ifdef DEBUG_ENABLED
Serial.println("Message sent");
#endif
}}
void connectToWifi() {
printWifiInstructions();
// Check WiFi Bee status
if (WiFi.status() == WL_NO_SHIELD)
{
#ifdef DEBUG_ENABLED
Serial.println(F("WiFi shield not present"));
#endif
// don't continue:
while (true)
;
}
uint8_t status = WL_IDLE_STATUS;
// attempt to connect to Wifi network:
while (status != WL_CONNECTED)
{
#ifdef DEBUG_ENABLED
Serial.print(F("Attempting to connect to SSID: "));
Serial.println(ssid);
#endif
// Connect to WPA/WPA2 network. Change this line if using open or WEP
// network
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
#ifdef DEBUG_ENABLED
Serial.print(F("Waiting 10 seconds for connection..."));
#endif
delay(10000);
#ifdef DEBUG_ENABLED
Serial.println(F("done."));
gateway = WiFi.gatewayIP();
Serial.println(gateway);
sendActivation();
#endif
printWifiPassed();
}
}
//////////////////////////////////////////////////
void initUltrasonic() {
//pinmodes for ultrasonic
pinMode(1, OUTPUT);
pinMode(2, INPUT);
pinMode(3, OUTPUT);
pinMode(4, INPUT);
for (int i = 0; i < 5; i++) lastReadingsRight[i] = 400;
for (int i = 0; i < 5; i++) lastReadingsLeft[i] = 400;
}
#define swap(a,b) a ^= b; b ^= a; a ^= b;
#define sort(a,b) if(a>b){ swap(a,b); }
int median(int a, int b, int c, int d, int e)
{
sort(a, b);
sort(d, e);
sort(a, c);
sort(b, c);
sort(a, d);
sort(c, d);
sort(b, e);
sort(b, c);
// this last one is obviously unnecessary for the median
//sort(d,e);
return c;
}
int getDistance(char side) {
int distance;
if (side == 'l') {
distance = left.ping_cm();
}
if (side == 'r') {
distance = right.ping_cm();
}
if (distance == 0) {
distance = 400;
}
return distance;
}
int getMedianRight() {
int placeholder_medianR = medianResultRight;
medianResultRight = median(
lastReadingsRight[0],
lastReadingsRight[1],
lastReadingsRight[2],
lastReadingsRight[3],
lastReadingsRight[4]);
if (medianResultRight == 0) {
// take the last median instead
medianResultRight = placeholder_medianR;
}
}
int getMedianLeft() {
int placeholder_medianL = medianResultLeft;
medianResultLeft = median(
lastReadingsLeft[0],
lastReadingsLeft[1],
lastReadingsLeft[2],
lastReadingsLeft[3],
lastReadingsLeft[4]
);
if (medianResultLeft == 0) {
// take the last median instead
medianResultLeft = placeholder_medianL;
}
return medianResultLeft;
}
void getAccAmplitudes() {
// Acceleration Amplitude calc
int amplitudeAccX = abs(accX - ( bmx.getAccelerationX() * 100) );
int amplitudeAccY = abs(accY - ( bmx.getAccelerationY() * 100) );
int amplitudeAccZ = abs(accZ - ( bmx.getAccelerationZ() * 100) );
accX = bmx.getAccelerationX() * 100;
accY = bmx.getAccelerationY() * 100;
accZ = bmx.getAccelerationZ() * 100;
sumAccX += amplitudeAccX;
sumAccY += amplitudeAccY;
sumAccZ += amplitudeAccZ;
}
void getRotAmplitudes() {
int placeholderRotX = (int)(0);
int placeholderRotY = (int)(0);
int placeholderRotZ = (int)(0);
bmx.getRotation(&placeholderRotX , &placeholderRotY, &placeholderRotZ);
int amplitudeRotX = abs(rotX - placeholderRotX);
int amplitudeRotY = abs(rotY - placeholderRotY);
int amplitudeRotZ = abs(rotZ - placeholderRotZ);
rotX = placeholderRotX;
rotY = placeholderRotY;
rotZ = placeholderRotZ;
sumRotX += amplitudeRotX;
sumRotY += amplitudeRotY;
sumRotZ += amplitudeRotZ;
}
void getMagAmplitudes() {
// Mag Amplitude calc
int placeholderMagX = (int)(0);
int placeholderMagY = (int)(0);
int placeholderMagZ = (int)(0);
bmx.getMagnet(&placeholderMagX , &placeholderMagY, &placeholderMagZ);
int amplitudeMagX = abs(magX - placeholderMagX);
int amplitudeMagY = abs(magY - placeholderMagY);
int amplitudeMagZ = abs(magZ - placeholderMagZ);
magX = placeholderMagX;
magY = placeholderMagY;
magZ = placeholderMagZ;
sumMagX += amplitudeMagX;
sumMagY += amplitudeMagY;
sumMagZ += amplitudeMagZ;
}
void initGPS() {
Wire.begin();
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
{
#ifdef DEBUG_ENABLED
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
#endif
while (1);
}
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
myGPS.setNavigationFrequency(2); //Produce two solutions per second
myGPS.setAutoPVT(true); //Tell the GPS to "send" each solution
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
}
void setup() {
// put your setup code here, to run once:
#ifdef DEBUG_ENABLED
Serial.begin(9600);
//while (!Serial);
#endif
senseBoxIO.powerNone();
delay(1000),
senseBoxIO.powerAll();
delay(100);
initDisplay();
connectToWifi();
bmx.beginAcc(0x3);
bmx.beginGyro();
bmx.beginMagn();
BMP.begin(0x76);
Serial1.begin(9600);
initUltrasonic();
initGPS();
}
void loop() {
if (myGPS.getPVT()) {
latitude = myGPS.getLatitude();
longitude = myGPS.getLongitude();
sprintf(timestamp, "%02d-%02d-%02dT%02d:%02d:%02dZ",
myGPS.getYear(),
myGPS.getMonth(),
myGPS.getDay(),
myGPS.getHour(),
myGPS.getMinute(),
myGPS.getSecond());
}
if (latitude != 0 and longitude != 0 ) {
// when gps is available
time_start = millis();
// calculate distance and bmx values whenever possible
getAccAmplitudes();
getRotAmplitudes();
getMagAmplitudes();
lastReadingsRight[nrReadingsRight++ % 5] = getDistance('r');
lastReadingsLeft[nrReadingsLeft++ % 5] = getDistance('l');
// do this every 10 seconds
if (time_start > time_actual_10s + interval10s) {
time_actual_10s = millis();
#ifdef DEBUG_ENABLED
Serial.println("Reading from String...");
#endif
sendToServer(finalBuffer);
finalBuffer = "";
updateDisplay();
}
// do this every 1 second
if (time_start > time_actual_1s + interval1s) {
time_actual_1s = millis();
float pressure = BMP.readPressure();
float temp = BMP.readTemperature();
uint8_t attempt = 0;
float pm10, pm25;
while (attempt < 5) {
bool error = SDS.read(&pm25, &pm10);
if (!error) {
break;
}
attempt++;
}
int pm10int = pm10 * 100;
int pm25int = pm25 * 100;
int tempInt = temp * 100;
int pressInt = temp * 100;
//Serial.println("Writing to SD");
sprintf_P(buffer, PSTR("%d,%d,%s,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n"),longitude,latitude,timestamp, sumAccX, sumAccY, sumAccZ, sumMagX, sumMagY, sumMagZ, sumRotX, sumRotY, sumRotZ, getMedianLeft(), getMedianRight(), tempInt, pressInt, pm25int, pm10int);
finalBuffer.concat(buffer);
// reset sum variables for further calc
sumAccZ = 0;
sumAccY = 0;
sumAccX = 0;
sumMagX = 0;
sumMagY = 0;
sumMagZ = 0;
sumRotX = 0;
sumRotY = 0;
sumRotZ = 0;
}
}
else {
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(WHITE, BLACK);
display.println("No GPS available");
display.display();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment