/********* For display GxEPD_Example : test example for e-Paper displays from Waveshare and from Dalian Good Display Inc. // // Created by Jean-Marc Zingg based on demo code from Good Display, // available on http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html // // Supporting Arduino Forum Topics: // Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0 // Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0 // mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board // NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD // BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V *********/ /********* For communication Rui Santos Complete project details at https://RandomNerdTutorials.com/esp-now-one-to-many-esp32-esp8266/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. *********/ // include library, include base class, make path known #include //->display #include #include //#include "unease.h" //#include "Tree_0.h" //#include "Tree_of_unease_0.h" //#include "Tree_1.h" //#include "Tree_of_unease_1.h" //#include "Tree_2.h" //#include "Tree_of_unease_2.h" //#include "Tree_3.h" //#include "Tree_of_unease_3.h" #include "Tree_4.h" #include "Tree_of_unease_4.h" PublishingHouse :: RandomForest :: TreeOfUnease treeOfUnease; PublishingHouse :: RandomForest :: DecisionTree tree; //const int randSeed = 6730/; const int featureCount = 4; const int treeNumber = 4; int considerationStep = 0; String considerationTraces = String(); const int verticalOffset = 19; float lastObservation[featureCount] = { 0.0, 0.0, 0.0, 0.0 }; const char *answer; const int answerPrefixLength = 3; const char *answerPrefix[] = { "It might be ", "I think it is ", "I would say it is " }; /////////////////// ///DISPLAY/// ////////////////// // select the display class to use, only one #include // 1.54" b/w // FreeFonts from Adafruit_GFX //#include / //#include // #include #include //#include / //#include / #include #include #if defined(ESP32) // for SPI pin definitions see e.g.: // C:\Users\xxx\Documents\Arduino\hardware\espressif\esp32\variants\lolin32\pins_arduino.h GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16); // arbitrary selection of 17, 16 GxEPD_Class display(io, /*RST=*/ 16, /*BUSY=*/ 4); // arbitrary selection of (16), 4 #else // for SPI pin definitions see e.g.: // C:\Users\xxx\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard\pins_arduino.h GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class GxEPD_Class display(io, /*RST=*/ 9, /*BUSY=*/ 7); // default selection of (9), 7 #endif float getObservationValue (int key) { return lastObservation[key]; } /////////////////// ///COMMUNICATION/// ////////////////// //Structure example to receive data //Must match the sender structure // This is the main loop of the program. It is ran whenever the board // receives an observation. void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { Serial.println("received data"); clearDisplay(); display.println("Received an observation:"); memcpy(&lastObservation, incomingData, sizeof(lastObservation)); for(int i=0; i < featureCount; i++) { //lastObservation[i] = *incomingData[i]; Serial.println(lastObservation[i]); display.println(lastObservation[i]); } display.update(); delay(10 * 1000); classify(); } void clearDisplay (){ display.fillScreen(GxEPD_WHITE); display.setTextColor(GxEPD_BLACK); display.setFont(&FreeSans12pt7b); display.setCursor(0, verticalOffset); // display.update(); } void mightPrintUnease () { // Serial.println(random(2));/ // Serial.println(random(2));/ if (random(3) < 2) { clearDisplay(); display.fillScreen(GxEPD_BLACK); display.setTextColor(GxEPD_WHITE); display.setFont(&FreeSansOblique12pt7b); Serial.println("Printing an unease."); // display.println(tracesOfUnease[random(t/raceCount)]); display.update(); display.fillScreen(GxEPD_WHITE); display.setTextColor(GxEPD_BLACK); display.setFont(&FreeSans12pt7b); delay(15 * 1000); } } // Consider a given value, feature number and threshold. // If the value is lower than the threshold, answer yes // otherwise answer no. // // Once every three calls a trace of unease will be printed bool consider(float value, int feature, float threshold) { //mightPrintUnease(); clearDisplay(); Serial.println("Printing consideration"); clearDisplay(); Serial.println(considerationTraces); display.println(considerationTraces); // display.print("Step "); // display.print(considerationStep); display.print(".\nConsidering fea-\nture "); display.print(feature); display.print(", is it smaller\nthan "); display.print(threshold); display.print("?\n"); display.update(); delay(10 * 1000); considerationStep = considerationStep + 1; if (value < threshold) { display.println("Yes. Going left."); considerationTraces.concat(considerationStep); considerationTraces.concat(": L "); display.update(); delay(10 * 1000); return true; } else { display.println("No. Going right."); considerationTraces.concat(considerationStep); considerationTraces.concat(": R "); display.update(); delay(10 * 1000); return false; } } // Print the forwarded unease and consider the given value, // feature number and threshold. If the value is lower than the threshold, // return true otherwise false. bool considerWithUnease(const char *unease, float value, int feature, float threshold) { Serial.println("Printing unease"); clearDisplay(); Serial.println(unease); display.println(unease); // Test whether it's * ? display.update(); delay(20 * 1000); if (value < threshold) { return true; } else { return false; } } void classify () { considerationStep = 0; considerationTraces = String(); Serial.println("Starting classification"); if (random(3) == 0) { treeOfUnease.traverse(&getObservationValue, &considerWithUnease); } else { answer=tree.predict(&getObservationValue, &consider); clearDisplay(); // display.print("I say: "); display.print(answerPrefix[random(answerPrefixLength)]); display.print(answer); display.update(); } } void setup() { randomSeed(analogRead(26)); // Setup serial Serial.begin(115200); Serial.println(); Serial.println("setup"); display.init(115200); // enable diagnostic output on Serial Serial.println("Starting...\n"); // Setup WiFi // Set device as a Wi-Fi Station WiFi.mode(WIFI_STA); // print our mac address Serial.println(WiFi.macAddress()); // Init ESP-NOW if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); for(;;) { delay(1); } // do not initialize wait forever } Serial.println("initialized ESP-NOW"); // First output to the world! clearDisplay(); display.setRotation(2); // display.println("Hello!"); display.print("Tree "); display.print(treeNumber); display.print("\n"); display.println("You can reach me at"); display.println(WiFi.macAddress()); display.update(); delay(1000); // Register for a callback function that will be called when data is received esp_now_register_recv_cb(OnDataRecv); } void loop() { delay(500); // clearDisplay(); // if (dataReceived%2==0){ // Serial.println(); //// dataReceived_s= "whispers in my ears"; //// predicted= " an oak "; // } // else{ // Serial.println(clf.predict(irisSample, println, clear, delay)); //// dataReceived_s= "murmurations"; //// predicted= "an Iris"; // } }