Last active
February 22, 2021 11:44
-
-
Save Thiemann96/6ce9d5d99a38341c380ac2c53deb6401 to your computer and use it in GitHub Desktop.
Arduino Sketch for the futurium project
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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