#include #include #include #include #include #include #include // Web server configuration const char* ssid = "ESP_ping"; const char* password = "pong"; const char* PARAM_INPUT_1 = "output"; const char* PARAM_INPUT_2 = "state"; AsyncWebServer server(80); struct pin { int id; int is_extender; }; struct tube { uint16_t height; uint16_t target; struct { Servo hard; struct pin pin; int last_angle; int equilibrium; } servo; struct { VL53L0X hard; struct pin gpio; struct pin xshut; } tof; int last_measure[5]; int last_pos_index; int id; }; const struct pin all_xshuts[6] = { {.id = 7, .is_extender = 1}, {.id = 0, .is_extender = 1}, {.id = 1, .is_extender = 1}, {.id = 6, .is_extender = 1}, {.id = 5, .is_extender = 1}, {.id = 4, .is_extender = 1} }; const struct pin all_servos[6] = { {.id = 32, .is_extender = 0}, {.id = 33, .is_extender = 0}, {.id = 18, .is_extender = 0}, {.id = 2, .is_extender = 1}, {.id = 3, .is_extender = 1}, {.id = 19, .is_extender = 0} }; struct tube all_tubes[6]; const int TUBES_COUNT = 6; const float minHeight = 50; const float maxHeight = 445; int minServo = 0; int maxServo = 150; Adafruit_PCF8574 pcf8574; void scan_I2c(){ byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) { Serial.print("0"); } Serial.println(address,HEX); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) { Serial.print("0"); } Serial.println(address,HEX); } } if (nDevices == 0) { Serial.println("No I2C devices found\n"); } else { Serial.println("done\n"); } delay(5000); } uint16_t mesureHeight(int i){ uint16_t h = all_tubes[i].tof.hard.readRangeContinuousMillimeters(); //Serial.printf("measure: %d\n", h); if (h > 2000){ //Serial.printf("returning height\n"); return all_tubes[i].height; } else { //Serial.printf("returning: %d\n", h); return h; } } void change_pin(struct pin pin, int state) { if (pin.is_extender) { pcf8574.digitalWrite(pin.id, state); } else { digitalWrite(pin.id, state); } } void changePinMode(struct pin pin, int state) { if (pin.is_extender) { pcf8574.pinMode(pin.id, state); } else { pinMode(pin.id, state); } } // Web Server configuration const char index_html[] PROGMEM = R"rawliteral( Balle Ping Pong flottante

Balle Ping Pong flottante

%BUTTONPLACEHOLDER% )rawliteral"; String processor(const String& var){ //Serial.println(var); if(var == "BUTTONPLACEHOLDER"){ String buttons = ""; buttons += "
"; buttons += "
"; buttons += "
"; buttons += "
"; buttons += "
"; buttons += "
"; return buttons; } return String(); } void wifisetup() { Serial.print("Setting AP (Access Point)…"); WiFi.softAP(ssid); IPAddress IP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(IP); // Route for root / web page server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", index_html, processor); }); // Send a GET request to /update?output=&state= server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) { int inputMessage1; int inputMessage2; // GET input1 value on /update?output=&state= if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_2)) { inputMessage1 = request->getParam(PARAM_INPUT_1)->value().toInt(); inputMessage2 = request->getParam(PARAM_INPUT_2)->value().toInt(); Serial.printf("Received web command: %d %d\n", inputMessage1, inputMessage2); all_tubes[inputMessage1].target = inputMessage2; } else { // Error inputMessage1 = -1; inputMessage2 = -1; } Serial.print("GPIO: "); Serial.print(inputMessage1); Serial.print(" - Set to: "); Serial.println(inputMessage2); request->send(200, "text/plain", "OK"); }); // Start server server.begin(); } // Tube configuration void setup_all_tofs() { // Reset all TOFs by turning them up and low for (int i = 0; i < TUBES_COUNT; ++i) { changePinMode(all_xshuts[i], OUTPUT); change_pin(all_xshuts[i], LOW); } for (int i = 0; i maxHeight) { Serial.printf("%dmm %d°\n",h, angle); ++angle; all_tubes[i].servo.hard.write(angle); delay(300); h = mesureHeight(i); } angle -= 5; all_tubes[i].servo.last_angle = angle; all_tubes[i].servo.hard.write(all_tubes[i].servo.last_angle); all_tubes[i].servo.equilibrium = angle; Serial.printf("Tube %d calibrated.\n", i); } void setup_servo(){ for (int i = 0; i