#include #include #include "Adafruit_VL53L0X.h" #include #include #include #include /* #include "terminal.hpp" // // ATTENTION : pour que les commandes se déclarent automatiquement au démarrage // auprès du terminal, le fichier conteant la fonction setup() et loop() doit // être mis en derniere position dans la liste des fichiers lors de l'édition // des liens. // Dans platformio, pour faire cela, il suffit de commencer le nom du fichier // contenant les fonctions loop() et setup() par la lettre z. // Par exemple : zzz_main.cpp. // extern terminal_n::Terminal terminal; TERMINAL_PARAMETER_INT( terminal, power_mode, // variable name to declare "power_mode", // EEPROM name (15 char. max), // If you dont want to save in EEPROM, set "" "the power mode", // description 0, // default constructor value false, // auto save in eeprom after command modification terminal_n::filter_nothing, // function to filter the value terminal_n::do_nothing // function executed at the end of the command ); TERMINAL_COMMAND(terminal, ping, "Print pong followoing by the received arguments") { terminal.print("pong"); for (uint32_t i=0; i Balle Ping Pong flottante

Balle Ping Pong flottante

%BUTTONPLACEHOLDER% )rawliteral"; // Replaces placeholder with button section in your web page String processor(const String& var){ //Serial.println(var); if(var == "BUTTONPLACEHOLDER"){ String buttons = ""; buttons += "
"; buttons += "
"; buttons += "
"; buttons += "
"; buttons += "
"; return buttons; } return String(); } auto mesureHeight(Adafruit_VL53L0X lox, struct tube *tube){ VL53L0X_RangingMeasurementData_t measure; lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout! if (measure.RangeStatus != 4) { // phase failures have incorrect data float height = measure.RangeMilliMeter; if (height < 1000.0){ tube->height = height; return height; } else { Serial.println("Incoherent measurement. Returning previous one."); return tube->height; } } else { //Serial.println(" out of range "); return tube->height; } } 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) { String inputMessage1; String 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(); inputMessage2 = request->getParam(PARAM_INPUT_2)->value(); all_tubes[0].target = inputMessage2.toFloat(); } else { inputMessage1 = "No message sent"; inputMessage2 = "No message sent"; } Serial.print("GPIO: "); Serial.print(inputMessage1); Serial.print(" - Set to: "); Serial.println(inputMessage2); request->send(200, "text/plain", "OK"); }); // Start server server.begin(); } Adafruit_PCF8574 pcf8574; 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); } } Adafruit_VL53L0X tofs_talk_through[6] = {Adafruit_VL53L0X(), Adafruit_VL53L0X(), Adafruit_VL53L0X(), Adafruit_VL53L0X(), Adafruit_VL53L0X(), Adafruit_VL53L0X()}; void init_tube(struct tube *tube, char id, struct pin servo_pin, struct pin gpio, struct pin xshut) { Serial.print(" Initialiazing tube #"); Serial.println((int) id); tube->id = id; tube->servo.pin = servo_pin; tube->tof.gpio = gpio; tube->tof.xshut = xshut; tube->height = 250.0f; tube->target = 250.0f; change_pin(gpio, HIGH); change_pin(xshut, HIGH); //change_pin(servo_pin, HIGH); Serial.println("Beginning boot sequence VL53L0X"); /* if (!tofs_talk_through[id].begin()) { Serial.println(F("Failed to boot VL53L0X")); Serial.println((int)id); while(1); }*/ while (!tofs_talk_through[id].begin()) { Serial.println(F("Failed to boot VL53L0X")); Serial.println("Adafruit VL53L0X XShut set Low to Force HW Reset"); digitalWrite(xshut.id, LOW); delay(100); digitalWrite(xshut.id, HIGH); Serial.println("Adafruit VL53L0X XShut set high to Allow Boot"); delay(5000); } tofs_talk_through[id].setAddress(0x30 + id); tube->servo.hard.attach(tube->servo.pin.id); tube->servo.hard.write(minServo); delay(5000); Serial.println("Setuping downards"); float h = mesureHeight(tofs_talk_through[id], tube); Serial.println(h); int angle = minServo; while (h > maxHeight) { ++angle; tube->servo.hard.write(angle); delay(300); h = mesureHeight(tofs_talk_through[id], tube); } angle -= 5; tube->servo.last_angle = angle; tube->servo.hard.write(tube->servo.last_angle); tube->servo.equilibrium = angle; Serial.println("Done."); } void setup_all_tubes() { const struct pin all_xshuts[6] = { {.id = 17, .is_extender = 0}, {.id = 2, .is_extender = 1}, {.id = 3, .is_extender = 1}, {.id = 7, .is_extender = 1}, {.id = 5, .is_extender = 1}, {.id = 1, .is_extender = 1} }; const struct pin all_gpios[6] = { {.id = 5, .is_extender = 0}, {.id = 18, .is_extender = 0}, {.id = 19, .is_extender = 0}, {.id = -1, .is_extender = 1}, {.id = 6, .is_extender = 1}, {.id = 0, .is_extender = 1} }; const struct pin all_servos[6] = { {.id = 32, .is_extender = 0}, {.id = 33, .is_extender = 0}, {.id = 23, .is_extender = 0}, {.id = 16, .is_extender = 0}, {.id = 14, .is_extender = 0}, {.id = 2, .is_extender = 0} }; // 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); } delay(1000); /* for (int i = 0; i < TUBES_COUNT; ++i) { change_pin(all_xshuts[i], HIGH); } delay(10); for (int i = 0; i < TUBES_COUNT; ++i) { change_pin(all_xshuts[i], LOW); } */ for (int i = 0; i < TUBES_COUNT; ++i) { init_tube(all_tubes, i, all_servos[i], all_gpios[i], all_xshuts[i]); } } void setup() { Serial.begin(115200); // Starts the serial communication while (! Serial) { delay(1); } if (!pcf8574.begin(0x38, &Wire)) { Serial.println("Couldn't find PCF8574"); while (1); } for (uint8_t p=0; p<8; p++) { pcf8574.pinMode(p, OUTPUT); } Serial.println("PCF8574 seemks OK"); wifisetup(); //terminal.setup(&Serial); setup_all_tubes(); Serial.println("Done setuping have funning"); } auto heightRatio(float height){ return max(min(1.0f, (height - minHeight) / (maxHeight-minHeight)), 0.0f); } int servoPosition(float ratio){ return (ratio * maxServo) + ((1-ratio) * minServo); } void loop() { //terminal.update(); for (int i = 0; i < TUBES_COUNT; i++) { struct tube *tube = all_tubes + i; /* Serial.print("Tube "); Serial.println(tube->id); */ tube->height = mesureHeight(tofs_talk_through[tube->id], tube); /* Serial.print("Measure = "); Serial.println(tube->height); */ int angle = 0; float diff = tube->height - tube->target; if (abs(diff) > 5.0f) { angle = tube->servo.equilibrium + (diff * 1 / (7)); } else if (abs(diff) > 2.0f) { angle = tube->servo.equilibrium + (diff * 1 / (7)); } else { angle = tube->servo.equilibrium; } /* Serial.print("angle = "); Serial.print(angle); Serial.print("; equilibrium = "); Serial.println(tube->servo.equilibrium); */ tube->servo.last_angle = min(max(angle, minServo), maxServo); /* Serial.print("Diff = "); Serial.print(diff); Serial.print("; Requested = "); Serial.print(tube->target); Serial.print("; Angle = "); Serial.println(tube->servo.last_angle); */ tube->servo.hard.write(tube->servo.last_angle); } for (int i = 0; iheight); Serial.print("\t"); } Serial.println(); delay(1); }