une 30aine passés sans pb entre les trames
Dependencies: ADS1015 ARNSRS_SENSORS DmTftLibrary MS5803_14BA SDFileSystem mbed
Fork of ARNSRS_SERVOS_USB_TFT by
main.cpp
- Committer:
- POTLESS_2
- Date:
- 2017-05-18
- Revision:
- 21:28a3f60b4bc2
- Parent:
- 20:bb8d2cea2076
- Child:
- 22:8e4ace42e4f5
File content as of revision 21:28a3f60b4bc2:
/* Stm32L476RG 2 servos BLE => Android */ #include "mbed.h" #include "SDFileSystem.h" #include "ARNSRS_SENSORS.h" #include <string> #include "DmTftHX8353C.h" #include "DmTftS6D0164.h" #include "DmTftIli9325.h" #include "DmTftIli9341.h" #include "DmTftSsd2119.h" #include "DmTftRa8875.h" //Ecrit dans le moniteur série de la tablette à 9600 bds si sur 1, penser à mettre NEED_CONSOLE_OUTPUT à 0 #define NEED_ANDROID_OUTPUT 0 //Ecrit dans le moniteur série de l'ordi à 9600 bds si sur 1 #define NEED_CONSOLE_OUTPUT 1 //Pour utiliser le traceur du moniteur Arduino. Mettre NEED_CONSOLE_OUTPUT 0 si utilisé. //En premier ouvrir le moniteur série pour régler la RTC, puis fermer et ouvrir le traceur série #define NEED_GRAPH_OUTPUT 0 //Datalog carte SD si sur 1 #define NEED_SD_DATA_LOG 0 #if NEED_ANDROID_OUTPUT #define ANDROID(...) { serialMonit.printf(__VA_ARGS__); } #else #define ANDROID(...) #endif #if NEED_CONSOLE_OUTPUT #define DEBUG(...) { serialMonit.printf(__VA_ARGS__); } //tft.drawString(0,0,__VA_ARGS__); #else #define DEBUG(...) #endif #if NEED_GRAPH_OUTPUT #define TRACE(...) { serialMonit.printf(__VA_ARGS__); } #else #define TRACE(...) #endif //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //TFT DmTftHX8353C tft(D2, D3, D4, D5, D6); /* DmTftHX8353C(PinName mosi, PinName clk, PinName cs, PinName dc, PinName rst) DM_TFT18_101 */ //Bool des pages bool FLAG_PAGE_1 = true; bool FLAG_PAGE_2 = false; //Changement de pages InterruptIn mybutton(USER_BUTTON); //Dessin du logo en t^te de page int bmpWidth, bmpHeight; uint8_t bmpImageoffset; extern uint8_t dmlogo[]; // LITTLE ENDIAN! uint16_t read16(uint8_t *src) { uint16_t d; uint8_t b; b = *src; d = *(src+1); d <<= 8; d |= b; return d; } // LITTLE ENDIAN! uint32_t read32(uint8_t *src) { uint32_t d; uint16_t b; b = read16(src); d = read16(src+2); d <<= 16; d |= b; return d; } void drawBmpFromFlash(int x, int y) { uint16_t pos = bmpImageoffset; uint16_t p; // pixel uint8_t g, b; int i, j; // line, column for(i=bmpHeight; i>0; i--) { for(j=0; j<bmpWidth; j++) { b = *(dmlogo+pos++); g = *(dmlogo+pos++); p = *(dmlogo+pos++); p >>= 3; p <<= 6; g >>= 2; p |= g; p <<= 5; b >>= 3; p |= b; // write out the 16 bits of color tft.setPixel(j+x, i+y, p); } } } int bmpReadHeader() { uint32_t fileSize; uint32_t headerSize; uint16_t bmpDepth; uint16_t pos = 0; if (read16(dmlogo) !=0x4D42){ // read magic byte return false; } pos += 2; // read file size fileSize = read32(dmlogo+pos); pos += 4; pos += 4; // Skip creator bytes bmpImageoffset = read32(dmlogo+pos); pos += 4; // read DIB header headerSize = read32(dmlogo+pos); pos +=4; bmpWidth = read32(dmlogo+pos); pos += 4; bmpHeight = read32(dmlogo+pos); pos += 4; if (read16(dmlogo+pos) != 1){ // number of color planes must be 1 return false; } pos += 2; bmpDepth = read16(dmlogo+pos); pos +=2; if (read16(dmlogo+pos) != 0) { // compression not supported! return false; } pos += 2; // Should really be 2?? return true; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //Contrôle des servos PwmOut servo1(PB_15); AnalogIn FeedBack1(PC_2); float Servo1_POS; float Limit_min_S1, Limit_max_S1; float Delta_FB_1; PwmOut servo2(PB_1); AnalogIn FeedBack2(PC_3); float Servo2_POS; float Limit_min_S2, Limit_max_S2; float Delta_FB_2; //Buffer pour Commandes servo char commande_servo[20]; int indexCommande; //Init de la lib ARNSRS; ARNSRS arnsrs; //COM Série vers l'ordi, Serial 2 par défaut Serial serialMonit (USBTX,USBRX); //Variable des capteurs int co2 = 0; int ppO2 = 0; float pression = 0; float Temp1 = 0; float Temp2 = 0; float Humi = 0; //RTC //Pour stocker le format date / heure string DateHeure; time_t seconds; //SD card SDFileSystem sd(D11, D12, D13, D10, "sd"); // MOSI, MISO, SCK, CS DigitalInOut csSDCard(D10, PIN_OUTPUT, PullUp, 1); FILE *fp; char fileName[32]; int points = 1; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// ///// Remap d'une valeur ///// //////////////////////////////////////////////////////////////////////////////// float remap(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } //////////////////////////////////////////////////////////////////////////////// //// Fonction pour créer et envoyer la chaine d'infos en BLE //// //////////////////////////////////////////////////////////////////////////////// //On balance deux float void build_send_Message_float(string com, float A, float B) { char buf[50]; sprintf(buf,"%s%.1f:%.1f\r\n", com.c_str(), A, B); ANDROID(buf); wait_ms(100); } //On balance deux int void build_send_Message_int(string com, int A, int B) { char buf[50]; sprintf(buf,"%s%d:%d\r\n", com.c_str(), A, B); ANDROID(buf); wait_ms(100); } //////////////////////////////////////////////////////////////////////////////// //// Fonction commande servos par port série //// //////////////////////////////////////////////////////////////////////////////// void Servo_USB(char message_Android []) { //Variables pour décomposition du message char *commande, *valeur; //La commande commande = strtok(message_Android, ",;"); DEBUG("Commande = %s\n", commande); //La valeur associée valeur = strtok(NULL, ",;"); DEBUG("Valeur = %s\n", valeur); //On compare la commande pour faire les actions //Commande servo1 if(strcmp(commande, "[S1]") == 0) { servo1 = atoi(valeur) / 100.f; DEBUG(" Servo 1 = %s\n", valeur); indexCommande = 0; } //Commande servo2 if(strcmp(commande, "[S2]") == 0) { servo2 = atoi(valeur) / 100.f; DEBUG("Servo 2 = %f\r\n", valeur); indexCommande = 0; } } void callbackServo() { commande_servo [indexCommande++] = serialMonit.getc(); } //////////////////////////////////////////////////////////////////////////////// //// Fonction qui change le nom du fichier ouvert pour le LOG //// //////////////////////////////////////////////////////////////////////////////// FILE *nextLogFile(void) { static unsigned int fileNumber = 0; FILE *filePtr = NULL; do { if (filePtr != NULL) fclose(filePtr); sprintf(fileName,"/sd/LOG_Capteurs_%04u.txt",fileNumber++); filePtr = fopen(fileName,"r"); } while (filePtr != NULL); return fopen( fileName,"w"); } //////////////////////////////////////////////////////////////////////////////// //// Réglage de l'heure par le moniteur série //// //////////////////////////////////////////////////////////////////////////////// void SetTime() { //Reglage date / heure depuis le terminal struct tm t; serialMonit.printf("Entrer la date et l'heure :\n"); serialMonit.printf("YYYY MM DD HH MM SS [enter]\n"); serialMonit.scanf("%d %d %d %d %d %d", &t.tm_year, &t.tm_mon, &t.tm_mday , &t.tm_hour, &t.tm_min, &t.tm_sec); t.tm_year = t.tm_year - 1900; t.tm_mon = t.tm_mon - 1; // set the time set_time(mktime(&t)); if(NEED_CONSOLE_OUTPUT == 0) serialMonit.printf("OK. Vous pouvez fermer le moniteur serie"); } //////////////////////////////////////////////////////////////////////////////// //// Initialisation DATA LOG //// //////////////////////////////////////////////////////////////////////////////// void init_DATALOG() { DEBUG("Initialisation SD card\r\n"); DEBUG("\r\n", ""); fp = nextLogFile(); if (!fp) { DEBUG("Probleme SD card...Fin du programme...\r\n"); //exit(0); } else { DEBUG("Nouveau fichier LOG cree = %s\r\n", fileName); DEBUG("\r\n", ""); } } //////////////////////////////////////////////////////////////////////////////// //// Fonction d'enregistrement des données sur carte SD //// //////////////////////////////////////////////////////////////////////////////// void DATA_LOG() { seconds = time(NULL); if (fp) { fprintf(fp, "%s,%d,%d,%f,%f,%f,%f\r\n", ctime(&seconds), co2 , ppO2, pression, Temp1, Temp2, Humi); DEBUG(" Enregistrement d'un point sur la carte SD\r\n"); DEBUG(" Nombre de points = %d\r\n", points); DEBUG("\r\n", ""); points++; } else { DEBUG(" Probleme carte SD\r\n"); } } //////////////////////////////////////////////////////////////////////////////// //// Calibration des limites de feedback des servos //// //////////////////////////////////////////////////////////////////////////////// void Calibration_servo() { //Servos, calibration du feedback DEBUG(" Check Servos :\r\n") DEBUG("\r\n"); servo1.period(0.001); servo2.period(0.001); //Rentrer les servos à fond servo1 = 0; servo2 = 0; wait(4); Limit_max_S1 = FeedBack1.read(); wait_ms(100); Limit_max_S2 = FeedBack2.read(); DEBUG(" FeedBack 1 MIN = %f\n", Limit_max_S1); DEBUG(" FeedBack 2 MIN = %f\n", Limit_max_S2); DEBUG("\r\n"); //Sortir les servos à fond servo1 = 1; servo2 = 1; wait(4); Limit_min_S1 = FeedBack1.read(); wait_ms(100); Limit_min_S2 = FeedBack2.read(); DEBUG(" FeedBack 1 MAX = %f\n", Limit_min_S1); DEBUG(" FeedBack 2 MAX = %f\n", Limit_min_S2); DEBUG("\r\n"); //Position milieu servo1 = 0.5; servo2 = 0.5; wait(2); //Mesure du delta consigne / feedback Delta_FB_1 = abs(remap(FeedBack1, Limit_max_S1, Limit_min_S1, 0, 100) - 50); Delta_FB_2 = abs(remap(FeedBack2, Limit_max_S2, Limit_min_S2, 0, 100) - 50); DEBUG(" Delta Servo 1 = %f\n", Delta_FB_1); DEBUG(" Delta Servo 2 = %f\n", Delta_FB_2); if(Delta_FB_1 > 10 || Delta_FB_1 > 10) DEBUG(" Delta Servos non satisfaisant..."); } //////////////////////////////////////////////////////////////////////////////// //// Fonction d'affichage de tout dans le moniteur série ou le traceur //// //////////////////////////////////////////////////////////////////////////////// void Debug_Complet() { //RTC seconds = time(NULL); DEBUG(" Date / Heure = %s\r\n", ctime(&seconds)); //Retour capteurs DEBUG(" CO2 = %d\r\n" , co2); DEBUG(" Humidite = %f\r\n" , Humi); DEBUG(" Temperature = %f\r\n" ,Temp1); //P / T sur MS5803 DEBUG(" Pression = %f\r\n", pression); DEBUG(" Temperature = %f\r\n", Temp2); //PPO2 sur ADS1015 DEBUG(" PPO2 = %d\r\n", ppO2); DEBUG("\r\n", ""); //Retour position des servos DEBUG(" FeedBack 1 = %3.2f%%\n", Servo1_POS); DEBUG(" FeedBack 2 = %3.2f%%\n", Servo2_POS); DEBUG("\r\n", ""); //Traceur TRACE("%d" , co2); TRACE(", "); TRACE("%d" , ppO2); TRACE(", "); TRACE("%f" , Humi); TRACE(", "); TRACE("%f" , Temp1); TRACE(", "); TRACE("%f" , Temp2); TRACE(", "); TRACE("%f" , pression); TRACE("\r\n"); } //////////////////////////////////////////////////////////////////////////////// /// PAGE tft 1 // //////////////////////////////////////////////////////////////////////////////// void tft_page_1() { FLAG_PAGE_2 = false; FLAG_PAGE_1 = true; //tft.clearScreen(BLACK); if (!bmpReadHeader()) { return; } drawBmpFromFlash(30, 2); tft.drawString(5,35, "CO2 "); tft.drawString(90,35, " ppm"); tft.drawString(5,55, "ppO2 "); tft.drawString(90,55, " mb"); tft.drawString(5,75, "T_1 "); tft.drawString(90,75, " C"); tft.drawString(5,95, "T_2 "); tft.drawString(90,95, " C"); tft.drawString(5,115, "Hum "); tft.drawString(90,115, " %"); tft.drawString(5,135, "P "); tft.drawString(90,135, " m"); tft.drawRectangle(0,0,126,32, WHITE); tft.drawRectangle(0,32,126,52, WHITE); tft.drawRectangle(0,52,126,72, WHITE); tft.drawRectangle(0,72,126,92, WHITE); tft.drawRectangle(0,92,126,112, WHITE); tft.drawRectangle(0,112,126,132, WHITE); tft.drawRectangle(0,132,126,152, WHITE); } //////////////////////////////////////////////////////////////////////////////// /// PAGE tft 2 // //////////////////////////////////////////////////////////////////////////////// void tft_page_2() { FLAG_PAGE_1 = false; FLAG_PAGE_2 = true; //tft.clearScreen(BLACK); if (!bmpReadHeader()) { return; } drawBmpFromFlash(30, 2); tft.drawString(5,35, "CO2 "); tft.drawString(90,35, " ppm"); tft.drawRectangle(0,0,126,32, WHITE); tft.drawRectangle(0,32,126,52, WHITE); } void pressed() { tft.clearScreen(BLACK); if (FLAG_PAGE_1){ tft_page_2(); } if (FLAG_PAGE_2){ tft_page_1(); } } //////////////////////////////////////////////////////////////////////////////// /// fonction initialisation // //////////////////////////////////////////////////////////////////////////////// void setup() { wait(2); //Réglage de l'heure //SetTime(); //Calibration des limites des servos pour remapper les feedback //Calibration_servo(); //Démarrage de l'écran DEBUG("Initialisation TFT\r\n"); tft.init(); tft_page_1(); //Initialisation du Data log if (NEED_SD_DATA_LOG == 1) init_DATALOG(); //Initialisation capteurs arnsrs.Sensors_INIT(false, 5, SPOOLING, DIGI_FILTER32, CALIB_AIR); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// procédure principale /// //////////////////////////////////////////////////////////////////////////////// int main() { setup(); //interruption sur le boutton user pour changer de page mybutton.fall(&pressed); //Commande éventuelle pour les servos serialMonit.attach(&callbackServo, Serial::RxIrq); while (1) { //CO2 / H / T sur Cozir co2 = arnsrs.requestCO2(); Humi = arnsrs.requestHUMI(); Temp1 = arnsrs.requestTEMP(); //P / T sur MS5803_14BA pression = arnsrs.requestPress(); Temp2 = arnsrs.requestTemp(); //PPO2 sur ADS1015 ppO2 = arnsrs.requestPpO2(false); //Retour position des servos Servo1_POS = remap(FeedBack1, Limit_max_S1, Limit_min_S1, 0, 100); Servo2_POS = remap(FeedBack2, Limit_max_S2, Limit_min_S2, 0, 100); //Debug Debug_Complet(); //Data LOG if (NEED_SD_DATA_LOG == 1) DATA_LOG(); //En accord avec app Android build_send_Message_int("t", co2, ppO2); build_send_Message_float("u", Temp1, Temp2); build_send_Message_float("v", Humi, pression); build_send_Message_float("f", Servo1_POS, Servo2_POS); Servo_USB(commande_servo); if(FLAG_PAGE_1) { tft.drawNumber(65,35,co2 ,3, false); tft.drawNumber(65,55,ppO2 ,3, false); tft.drawNumber(65,75,Temp1 ,3, false); tft.drawNumber(65,95,Temp2 ,3, false); tft.drawNumber(65,115,Humi ,3, false); tft.drawNumber(65,135,pression ,3, false); } if(FLAG_PAGE_2) { tft.drawNumber(65,35,co2 ,3, false); } } } //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////