STM32L476
Dependencies: MbedJSONValue SDFileSystem WConstants mbed-dev DS1820 TinyGPSPlus epd1in54
Fork of A_SSL_Main by
Diff: main.cpp
- Revision:
- 9:4ac09d77e2a0
- Parent:
- 8:bc5a3b2ff424
- Child:
- 10:a4526c9b8332
--- a/main.cpp Sun Sep 09 23:08:02 2018 +0000 +++ b/main.cpp Wed Nov 07 03:42:37 2018 +0000 @@ -1,7 +1,10 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// Company: Silent Sensors Ltd +// Project: Silent Hub +// Author: Waleed Elmughrabi +//////////////////////////////////////////////////////////////////////////////////////////////////////// + #include "mbed.h" -#include "stm32l496g_discovery.h" -#include "stm32l496g_discovery_lcd.h" -#include "stm32l496g_discovery_sd.h" #include "DS1820.h" #include "epd1in54.h" #include "stdio.h" @@ -12,52 +15,35 @@ #include "MbedJSONValue.h" #include <string> -#define TX5 PB_6 -#define RX5 PG_10 + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// Definitions and initialization +//////////////////////////////////////////////////////////////////////////////////////////////////////// +#define TX5 PC_10 +#define RX5 PC_11 #define GPSBaud 9600 -#define Serial0Baud 115200 +#define SerialBaud 115200 #define SD_FILE_SYSTEM_H SDFileSystem* fs; FILE* fp; - - - -Serial GPSSerial(TX5, RX5); TinyGPSPlus tgps; -void displayInfo(void); - -int i = 0; - - - -//DS18B20 temperature sensor - Serial serial(USBTX, USBRX); - DS1820 ds1820(PG_15); //pin name connected to the DS1820 data pin - float t; - float tempSerial; - float tCompare = 0; - int ab=1; - - SDFileSystem sd(PI_3, PC_2, PD_3, PB_12, "sd"); +Serial serial(USBTX, USBRX,112500); //Local terminal Baud rate +DS1820 ds1820(PB_2); //pin name connected to the DS1820 data pin +SDFileSystem sd(PB_5, PB_4, PB_3, PB_12, "sd"); //uSD SPI //E-ink Display -// Control -PinName rst; -PinName dc; -PinName busy; -//SPI communication -PinName mosi; -PinName miso; -PinName sclk; -PinName cs; +PinName rst; PinName dc; PinName busy; PinName mosi; PinName miso; PinName sclk; PinName cs; unsigned char frame_black[EPD_HEIGHT*EPD_WIDTH/8]; - +Epd epd = Epd(PB_5, PB_4, PB_3, PA_8, PC_4, PC_7, PB_10); +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// -//function to determine if within polygon geofence -//first argument is an integer, the rest are floats -//The last vertix should be the same as the first vertix -int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy) +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// Polygon geofence +// the last vertix should be the same as the first vertix +//////////////////////////////////////////////////////////////////////////////////////////////////////// +int pnpoly(int nvert, double *vertx, double *verty, double testx, double testy) { int i, j, c = 0; for (i = 0, j = nvert-1; i < nvert; j = i++) { @@ -67,14 +53,45 @@ } return c; } - +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// -int inCircle(float radius, float xcentre, float ycentre, float testx, float testy) +double distanceBetween(double lat1, double long1, double lat2, double long2) { - float distance; + // returns distance in meters between two positions, both specified + // as signed decimal-degrees latitude and longitude. Uses great-circle + // distance computation for hypothetical sphere of radius 6372795 meters. + // Because Earth is no exact sphere, rounding errors may be up to 0.5%. + // Courtesy of Maarten Lamers + double delta = radians(long1-long2); + double sdlong = sin(delta); + double cdlong = cos(delta); + lat1 = radians(lat1); + lat2 = radians(lat2); + double slat1 = sin(lat1); + double clat1 = cos(lat1); + double slat2 = sin(lat2); + double clat2 = cos(lat2); + delta = (clat1 * slat2) - (slat1 * clat2 * cdlong); + delta = sq(delta); + delta += sq(clat2 * sdlong); + delta = sqrt(delta); + double denom = (slat1 * slat2) + (clat1 * clat2 * cdlong); + delta = atan2(delta, denom); + return delta * 6372795; +} +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// Circle geofonce +//////////////////////////////////////////////////////////////////////////////////////////////////////// +int inCircle(double xcentre, double ycentre, double xedge, double yedge, double testx, double testy) +{ + double distance; int test; - distance = (sqrt((testx-xcentre)*(testx-xcentre)+(testy-ycentre)*(testy-ycentre))); - + double radius; + + radius = distanceBetween(xcentre, ycentre, xedge, yedge); + distance = distanceBetween(xcentre, ycentre, testx, testy); + if(distance < radius){ test = 1; } @@ -83,51 +100,13 @@ } return (test); } - -//GPS acquisition -void displayInfo(void) -{ - serial.printf("Location: "); - if (tgps.location.isValid()) - { - serial.printf("%3.6f, %3.6f", tgps.location.lat(), tgps.location.lng()); - } - else - { - serial.printf("INVALID"); - } - - serial.printf(" - Date/Time: "); - if (tgps.date.isValid()) - { - serial.printf("%d/", tgps.date.year()); - if (tgps.date.month() < 10) serial.printf("0"); - serial.printf("%d/", tgps.date.month()); - if (tgps.date.day() < 10) serial.printf("0"); - serial.printf("%d", tgps.date.day()); - } - else - { - serial.printf("INVALID"); - } - - serial.printf(" "); - if (tgps.time.isValid()) - { - if (tgps.time.hour() < 10) serial.printf("0"); - serial.printf("%d:", tgps.time.hour()); - if (tgps.time.minute() < 10) serial.printf("0"); - serial.printf("%d:", tgps.time.minute()); - if (tgps.time.second() < 10) serial.printf("0"); - serial.printf("%d\r\n", tgps.time.second()); - } - else - { - serial.printf("INVALID\r\n"); - } -} +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// Temperature sensor read +//////////////////////////////////////////////////////////////////////////////////////////////////////// float getTemp() { float t; @@ -136,230 +115,259 @@ ds1820.startConversion(); wait(1.0); t = ds1820.read(); // read temperature - tCompare; - serial.printf("temp = %3.1f\r\n", t); // Display temp on terminal - - } else + serial.printf("temp = %3.2f\r\n", t); // Display temp on terminal + } else serial.printf("No DS1820 sensor found!\r\n"); - - + return t; +} +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// - - mosi = PB_5; - miso = PB_4; - sclk = PA_5; - cs = PA_15; - rst = PI_6; - dc = PG_6; - busy = PI_11; +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// Epd display +//////////////////////////////////////////////////////////////////////////////////////////////////////// +int Display(float t, int g) +{ - char cVal[32]; - //char* t_str; - sprintf(cVal,"%.2f", t); - - + char cValt[32]; + sprintf(cValt,"%.2f", t); memset(frame_black, 0xFF, sizeof(unsigned char)*EPD_HEIGHT*EPD_WIDTH/8); - Epd epd = Epd(mosi, miso, sclk, cs, dc, rst, busy); - - if (epd.Init(lut_full_update) != 0) { return -1; } /*Write strings to the buffer */ - epd.DrawStringAt(frame_black, 50, 30, cVal, &Font24, COLORED); - epd.DrawStringAt(frame_black, 28, 10, "Temperature", &Font16, COLORED); + epd.DrawStringAt(frame_black, 0, 10, "Temperature:", &Font24, COLORED); + epd.DrawStringAt(frame_black, 60, 30, cValt, &Font24, COLORED); + epd.DrawStringAt(frame_black, 0, 70, "In Geofence?", &Font24, COLORED); + if (g == 1){ + epd.DrawStringAt(frame_black, 60, 90, "In G1", &Font24, COLORED); + } + else { + epd.DrawStringAt(frame_black, 60, 90, "No", &Font24, COLORED); + } /* Display the frame_buffer */ epd.SetFrameMemory(frame_black, 0, 0, epd.width, epd.height); epd.DisplayFrame(); epd.Sleep(); - return t; + return 1; + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// SD card functions +//////////////////////////////////////////////////////////////////////////////////////////////////////// +int new_file(char* adr_file)//fonction to write on new file +{ + FILE *fp = fopen(adr_file, "w"); + if(fp == NULL) { + serial.printf("Unable to write the file\r\n"); + return -1; + } else { + fprintf(fp, "----New File----\r\n"); + fclose(fp); + serial.printf("File successfully written!\r\n"); + return 0; //success + } } -int sdCardTest() +int read_file(char* adr_file)//fct to read a file { -//SD card - // Create and mount SDFileSystem - /*fs = new SDFileSystem(PI_3, PC_2, PD_3, PB_12, "sd"); // mosi, miso, sck, cs - serial.printf("Mounting file system...\r\n"); - int err = fs->mount(); - serial.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); - if (err) - return err; - - // Open the file. - serial.printf("Opening file '/sd/mytest/sdtest.txt'... "); - fp = fopen("/sd/mytest/sdtest.txt", "w+"); - serial.printf("%s\r\n", (!fp ? "Failed :(\r\n" : "OK\r\n")); - - if (!fp) { - // Check whether directory '/sd/mytest' exists. - serial.printf("\r\nChecking directory '/sd/mytest'...\r\n"); - struct stat info; - err = stat("/sd/mytest", &info); - if (err) { - serial.printf("Directory '/sd/mytest' does not exist.\r\n"); - serial.printf("Trying to create it..."); - err = mkdir("/sd/mytest", 0777); - serial.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); - if (err) - return err; + char c; + FILE *file; + serial.printf("\r\nRead: %s\r\n", adr_file); + file = fopen(adr_file, "r"); + if (file) { + while (!feof(file)) { + c = getc(file); + serial.putc(c); } - - // Create a new 'sdtest.txt' file. - serial.printf("File not found, creating a new one...\r\n"); - fp = fopen("/sd/mytest/sdtest.txt", "w+"); - serial.printf("%s\r\n", (!fp ? "Failed :(" : "OK")); - if (!fp) { - error("error: %s (%d)\r\n", strerror(errno), -errno); - return errno; - } + fclose(file); + return 0; //success } - for (int i = 0; i < 10; i++) { - serial.printf("Writing numbers (%d/%d)... ", i, 10); - err = fprintf(fp, " %d\r\n", i); - if (err < 0) { - serial.printf("Fail :(\r\n"); - - error("error: %s (%d)\r\n", strerror(errno), -errno); - } else - serial.printf("OK\r\n"); - } - - serial.printf("Writing numbers (%d/%d)... OK\r\n\r\n", 10, 10); - err = fclose(fp); - serial.printf("Closing file '/sd/mytest/sdtest.txt'... "); - //serial.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); - //if (err) - // return err; - */ - //Mount the filesystem - sd.mount(); - - //Perform a write test - printf("\nWriting to SD card..."); - FILE *fp = fopen("/sd/sdtest.txt", "w"); - if (fp != NULL) { - fprintf(fp, "We're writing to an SD card!"); - fclose(fp); - printf("success!\n"); - } else { - printf("failed!\n"); - } - - //Perform a read test - printf("Reading from SD card..."); - fp = fopen("/sd/sdtest.txt", "r"); - if (fp != NULL) { - char c = fgetc(fp); - if (c == 'W') - printf("success!\n"); - else - printf("incorrect char (%c)!\n", c); - fclose(fp); - } else { - printf("failed!\n"); - } - - //Unmount the filesystem - sd.unmount(); - - + return -1; } -//ToDo: pass arguments, organise inner subobjects, currently dummy values -string jsonSerializeDeviceToSystem() +int add_data(char* adr_flie, char* msg)//fct to update a file +{ + FILE *fp = fopen(adr_flie, "a"); + if(fp == NULL) { + serial.printf("Unable to update the file\r\n"); + return 0; //success + } else { + fprintf(fp, msg); + fclose(fp); + serial.printf("\r\nFile successfully update/written!\r\n"); + return -1; + } +} +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// JSON serialize +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//ToDo: pass arguments, currently some dummy values +string jsonSerializeDeviceToSystem(int deviceID, float xtest, float ytest, float liquidTemp, int tday, int tmonth, int tyear, int thour, int tmin, int tsec) { MbedJSONValue statusReport; std::string s; - + char SDtime[100]; + sprintf(SDtime,"%d/%d/%d - %d:%d:%d\r\n", tday, tmonth, tyear, thour, tmin, tsec); + //fill the object - statusReport["timestamp"]= "2018-04-23T18:25:43.511Z"; - statusReport["device"] = "DEVICE-1"; - statusReport["latitude"]= 57.1234; - statusReport["longitude"] = -4.567; - statusReport["geoFence"] = 1; - statusReport["container"] = 12.3; + statusReport["timestamp"]= SDtime; + statusReport["device"] = deviceID; + statusReport["latitude"]= ytest; + statusReport["longitude"] = xtest; + statusReport["geoFenceEntery"] = 1; + statusReport["geoFenceleft"] = 1; + statusReport["container"] = liquidTemp; statusReport["heater"] = 34.5; statusReport["batteryVoltage"] = 4.98; - statusReport["network"] = "Vodafone UK"; + statusReport["network"] = "Tele2"; statusReport["signalStrength"] = -89; //serialize it into a JSON string s = statusReport.serialize(); - serial.printf("status: %s\r\n",s ); - // - + //serial.printf("status: %s\r\n",s ); + return s; } +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// JSON parse +//////////////////////////////////////////////////////////////////////////////////////////////////////// +double jsonParseSystemToDevice(const char * parameter, int msg_index) +{ +MbedJSONValue journey; +const char * system_message = "{\"config\":[5.0,1.0,1.0,240.0],\"route1\":[1.0,0.0,1.0,1.0,1.0,1.0,54.5983852,-1.5708491,54.5969549,-1.5663735],\"route2\":[2.0,0.0,1.0,1.0,1.0,1.0,54.6542957,-1.4459836,54.6495902,-1.4430425],\"route3\":[3.0,0.0,1.0,1.0,1.0,1.0,54.7051416,-1.5638412,54.7101814,-1.5615844],\"route4\":[4.0,0.0,1.0,1.0,1.0,1.0,54.6298560,-1.3059736,54.6267899,-1.3075833],\"route5\":[5.0,0.0,1.0,1.0,1.0,2.0,5.0,54.6710093,-1.4587418,54.6730758,-1.4461951,54.6672642,-1.4436423,54.6678548,-1.4562232,54.6710093,-1.4587418]}"; + +parse(journey, system_message); +double msg; msg = journey[parameter][msg_index].get<double>(); return msg; +} +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// int main() { + Serial GPSSerial(TX5, RX5); GPSSerial.baud(GPSBaud); wait(0.001); + DigitalOut SD_EN(PB_12); //SD SPI enable (active low) + DigitalOut Epd_EN(PA_8); //Epd SPI enable (active low) + + Epd_EN = 1; //Disable Epd SPI to only enable uSD + new_file("/sd/coordinate.txt"); //create new "empty" juste wrote "New file" + Epd_EN = 0; //Enable Epd + + //Variables + int deviceID = 1; + double xtest,ytest; + int tyear,tmonth,tday,thour,tmin,tsec; - - //Variables - int inpoly; - float x[5] = { 1,4,4,1,1}; - float y[5] = { 1,1,4,4,1}; - float xtest; - float ytest; - char xtestchar[32]; - char ytestchar[32]; - float cx = 1; - float cy = 50; - float r = 15; - int ans = 0; float liquidTemp = 0; - std::string srr; + char chr_s[600]; + std::string s; wait(2); - - while(1){ - //inCircle(r, cx, cy, xtest, ytest); - //serial.printf("rx = 0x%02X\n", aRxBuffer); - //tempSerial = getTemp(t); - //inpoly = pnpoly(5,x, y, xtest,ytest); - //serial.printf("inpoly = %d\r\n", inpoly); - //ans = inCircle(r, cx, cy, xtest, ytest); - //serial.printf("distance = %3.1f\r\n", ans); - // GPS - //if(gps.sample()){ - // serial.printf("%f\t%c\t%f\t%c\t%f\t%f\t%f\n\r",gps.longitude, gps.ns,gps.latitude,gps.ew, gps.alt, gps.geoid, gps.time); - // serial.printf("%d:%d:%d",gps.hour,gps.minute,gps.seconed); - // } - sdCardTest(); + while(1) { //wait (1); - - /* - if (tgps.encode(GPSSerial.getc())) + + if(tgps.encode(GPSSerial.getc())) { - displayInfo(); - xtest = tgps.location.lng(); - ytest = tgps.location.lat(); - sprintf(xtestchar,"%.2f", xtest); - sprintf(ytestchar,"%.2f", ytest); - - serial.printf("\r\n %3.6f, %3.6f, \r\n", ytest, xtest); - ans = inCircle(r, cx, cy, xtest, ytest); + xtest = tgps.location.lat(); ytest = tgps.location.lng(); //Location + tyear = tgps.date.year(); tmonth = tgps.date.month(); tday = tgps.date.day(); //Date + thour = tgps.time.hour(); tmin = tgps.time.minute(); tsec = tgps.time.second(); //Time + + //this part is just for local terminal monitoring + serial.printf("\r\nLocation: %3.6f, %3.6f, Date: %d-%d-%d, Time: %d:%d:%d \r\n", xtest, ytest, tday, tmonth, tyear, thour, tmin, tsec); + wait(5); //little delay to prevent double writing liquidTemp = getTemp(); - serial.printf("\r\n In geofence = %d: \r\n", ans); + + //geofence testing + const char * parameter; + int msg_index; + double geofencesNum; + parameter = "config"; + msg_index = 0; + geofencesNum = jsonParseSystemToDevice(parameter,msg_index); + serial.printf("\r\nNumber of geofences: %2.0f", geofencesNum); + + int geotest = 0; + int count=1; + int count2; + double geo_lat_c; double geo_long_c; double geo_lat_e; double geo_long_e; + while ((count <= geofencesNum)&&(geotest == 0)) + { + char geo_extract[6]; + sprintf(geo_extract,"route%d",count); + parameter = geo_extract; + msg_index = 5; + + if (jsonParseSystemToDevice(geo_extract,msg_index) == 1) //circular geofence + { + msg_index = 6; geo_lat_c = jsonParseSystemToDevice(parameter,msg_index); + serial.printf("\r\n%4.8f", geo_lat_c); + msg_index = 7; geo_long_c = jsonParseSystemToDevice(parameter,msg_index); + serial.printf("\r\n%4.8f", geo_long_c); + msg_index = 8; geo_lat_e = jsonParseSystemToDevice(parameter,msg_index); + serial.printf("\r\n%4.8f", geo_lat_e); + msg_index = 9; geo_long_e = jsonParseSystemToDevice(parameter,msg_index); + serial.printf("\r\n%4.8f", geo_long_e); + + geotest = inCircle(geo_lat_c, geo_long_c, geo_lat_e, geo_long_e, xtest, ytest); + Display(liquidTemp, geotest); + serial.printf("\r\nGeofence number = %d: \r\nIn geofence = %d:\r\n", count, geotest); + } + + if (jsonParseSystemToDevice(geo_extract,msg_index) == 2) //polygon geofence + { + msg_index = 6; //The start of coordinates in the message + int vertices = jsonParseSystemToDevice(geo_extract,msg_index); //number of polygon vertices + double geo_lat[vertices]; + double geo_long[vertices]; + msg_index = 7; + for (count2=0; count2 < vertices; count2++ ) + { + geo_lat[count2] = jsonParseSystemToDevice(geo_extract,msg_index); + geo_long[count2] = jsonParseSystemToDevice(geo_extract,msg_index+1); + msg_index = msg_index + 2; + serial.printf("\r\ncount2: %d",count2); + serial.printf("\r\n vertices lat: %4.8f vertices long: %4.8f\r\n",geo_lat[count2],geo_long[count2]); + } + + + wait (1); + + geotest = pnpoly(vertices, geo_long, geo_lat, ytest, xtest); + Display(liquidTemp, geotest); + serial.printf("\r\nGeofence number = %d: \r\nIn geofence = %d:\r\n", count, geotest); + } + count++; + } + + //msg to be saved on SD and published + s = jsonSerializeDeviceToSystem(deviceID, xtest, ytest, liquidTemp, tday, tmonth, tyear, thour, tmin, tsec); + sprintf(chr_s,s.c_str()); + + + /* + Epd_EN = 1; + read_file("/sd/coordinate.txt"); + add_data("/sd/coordinate.txt",chr_s); + Epd_EN = 0; */ - - srr = jsonSerializeDeviceToSystem(); - //char srrrr=srr.c_str(); - //const char srr = sr.c_str(); - - sd.mount(); - FILE *fp = fopen("/sd/logtest.txt", "w"); - fprintf(fp, srr.c_str()); - sd.unmount(); - /* + } if (millis() > 5000 && tgps.charsProcessed() < 10) @@ -368,21 +376,11 @@ // while(true); break; } + - - } - serial.printf("%d\r\n",i); - i++; - wait(1.0); - */ - wait(5); - } - - - } -} +