feat: colored gradient by height
This commit is contained in:
parent
71432ff96c
commit
badb6ac5f0
149
prog/prog.ino
149
prog/prog.ino
@ -1,4 +1,4 @@
|
|||||||
#include <Adafruit_NeoPixel.h>
|
#include <FastLED.h>
|
||||||
#include <ESP32Servo.h>
|
#include <ESP32Servo.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <VL53L0X.h>
|
#include <VL53L0X.h>
|
||||||
@ -9,8 +9,9 @@
|
|||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
#include <avr/power.h>
|
#include <avr/power.h>
|
||||||
#endif
|
#endif
|
||||||
#define PIN 5
|
#define PIN_PIXELS 4
|
||||||
#define NUMPIXELS 6
|
#define NUM_PIXELS 6
|
||||||
|
#define TUBES_COUNT 6
|
||||||
|
|
||||||
// Web server configuration
|
// Web server configuration
|
||||||
const char* ssid = "ESP_ping";
|
const char* ssid = "ESP_ping";
|
||||||
@ -21,7 +22,7 @@ const char* PARAM_INPUT_2 = "state";
|
|||||||
|
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
|
|
||||||
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
|
CRGB leds[NUM_PIXELS];
|
||||||
|
|
||||||
struct pin {
|
struct pin {
|
||||||
int id;
|
int id;
|
||||||
@ -33,6 +34,7 @@ enum state {
|
|||||||
STATE_NONE,
|
STATE_NONE,
|
||||||
STATE_INIT,
|
STATE_INIT,
|
||||||
STATE_OK,
|
STATE_OK,
|
||||||
|
STATE_MOVING,
|
||||||
STATE_ERROR
|
STATE_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,39 +59,32 @@ struct tube {
|
|||||||
enum mode {
|
enum mode {
|
||||||
NONE,
|
NONE,
|
||||||
SINUS,
|
SINUS,
|
||||||
|
MAX_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mode current_mode = NONE;
|
enum mode current_mode = NONE;
|
||||||
|
|
||||||
|
|
||||||
const struct pin all_xshuts[6] = {
|
const struct pin all_xshuts[6] = {
|
||||||
{.id = 17, .is_extender = 0},
|
|
||||||
{.id = 2, .is_extender = 1},
|
|
||||||
{.id = 3, .is_extender = 1},
|
|
||||||
{.id = 5, .is_extender = 1},
|
|
||||||
{.id = 7, .is_extender = 1},
|
{.id = 7, .is_extender = 1},
|
||||||
{.id = 1, .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_gpios[6] = {
|
|
||||||
{.id = -1, .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] = {
|
const struct pin all_servos[6] = {
|
||||||
{.id = 32, .is_extender = 0},
|
{.id = 32, .is_extender = 0},
|
||||||
{.id = 33, .is_extender = 0},
|
{.id = 33, .is_extender = 0},
|
||||||
{.id = 23, .is_extender = 0},
|
{.id = 18, .is_extender = 0},
|
||||||
{.id = 16, .is_extender = 0},
|
{.id = 27, .is_extender = 0},
|
||||||
{.id = 4, .is_extender = 0},
|
{.id = 14, .is_extender = 0},
|
||||||
{.id = 2, .is_extender = 0}
|
{.id = 19, .is_extender = 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tube all_tubes[6];
|
struct tube all_tubes[6];
|
||||||
const int TUBES_COUNT = 2;
|
|
||||||
|
|
||||||
const float minHeight = 50;
|
const float minHeight = 50;
|
||||||
const float maxHeight = 445;
|
const float maxHeight = 445;
|
||||||
@ -164,25 +159,36 @@ void changePinMode(struct pin pin, int state) {
|
|||||||
void change_led(int id) {
|
void change_led(int id) {
|
||||||
Serial.print("Changing led color of #");
|
Serial.print("Changing led color of #");
|
||||||
Serial.println(id);
|
Serial.println(id);
|
||||||
int led_id = NUMPIXELS -1 - id;
|
int led_id = NUM_PIXELS - 1 - id;
|
||||||
switch (all_tubes[id].state) {
|
switch (all_tubes[id].state) {
|
||||||
case STATE_INIT: {
|
case STATE_INIT: {
|
||||||
pixels.setPixelColor(led_id, pixels.Color(255, 210, 70));
|
leds[led_id] = CRGB(255, 210, 70);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STATE_OK: {
|
case STATE_OK: {
|
||||||
pixels.setPixelColor(led_id, pixels.Color(0, 0, 190));
|
leds[led_id] = CRGB::Blue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STATE_MOVING: {
|
||||||
|
float ratio = (all_tubes[id].height) / (maxHeight);
|
||||||
|
if (ratio > 1.0) {
|
||||||
|
ratio = 1.0;
|
||||||
|
} else if (ratio < 0.0f) {
|
||||||
|
ratio = 0.0;
|
||||||
|
}
|
||||||
|
leds[led_id] = CHSV((int) (ratio * 128.0 + (1 - ratio) * 240.0) - 90, 255, 255);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STATE_ERROR: {
|
case STATE_ERROR: {
|
||||||
pixels.setPixelColor(led_id, pixels.Color(0, 190, 0));
|
leds[led_id] = CRGB::Red;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
pixels.setPixelColor(led_id, pixels.Color(3, 3, 3));
|
leds[led_id] = CRGB::Black;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FastLED.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Web Server configuration
|
// Web Server configuration
|
||||||
@ -209,6 +215,8 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
<body>
|
<body>
|
||||||
<h2>Balle Ping Pong flottante</h2>
|
<h2>Balle Ping Pong flottante</h2>
|
||||||
%BUTTONPLACEHOLDER%
|
%BUTTONPLACEHOLDER%
|
||||||
|
<button id="switch_mode">Changer mode</button>
|
||||||
|
<div id="mode"></div>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
function sendSliderValue(id, element) {
|
function sendSliderValue(id, element) {
|
||||||
@ -218,6 +226,17 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mode = 0;
|
||||||
|
|
||||||
|
document.getElementById('switch_mode').addEventListener('click', function() {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", "/switch_mode", true);
|
||||||
|
xhr.send();
|
||||||
|
mode += 1;
|
||||||
|
mode %= 2;
|
||||||
|
document.getElementById('mode').innerText = mode;
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -243,9 +262,6 @@ String processor(const String& var){
|
|||||||
|
|
||||||
|
|
||||||
void wifisetup() {
|
void wifisetup() {
|
||||||
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
|
|
||||||
clock_prescale_set(clock_div_1);
|
|
||||||
#endif
|
|
||||||
Serial.print("Setting AP (Access Point)…");
|
Serial.print("Setting AP (Access Point)…");
|
||||||
WiFi.softAP(ssid);
|
WiFi.softAP(ssid);
|
||||||
|
|
||||||
@ -260,6 +276,10 @@ void wifisetup() {
|
|||||||
|
|
||||||
// Send a GET request to <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
|
// Send a GET request to <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
|
||||||
server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
|
server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
|
||||||
|
if (current_mode != NONE) {
|
||||||
|
request->send(401, "text/plain", "NOK");
|
||||||
|
return;
|
||||||
|
}
|
||||||
int inputMessage1;
|
int inputMessage1;
|
||||||
int inputMessage2;
|
int inputMessage2;
|
||||||
// GET input1 value on <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
|
// GET input1 value on <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
|
||||||
@ -281,6 +301,12 @@ void wifisetup() {
|
|||||||
request->send(200, "text/plain", "OK");
|
request->send(200, "text/plain", "OK");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Send a GET request to <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
|
||||||
|
server.on("/switch_mode", HTTP_GET, [] (AsyncWebServerRequest *request) {
|
||||||
|
current_mode = static_cast<mode>(NONE + (current_mode + 1) % MAX_MODE);
|
||||||
|
request->send(200, "text/plain", "OK");
|
||||||
|
});
|
||||||
|
|
||||||
// Start server
|
// Start server
|
||||||
server.begin();
|
server.begin();
|
||||||
}
|
}
|
||||||
@ -303,7 +329,6 @@ void setup_all_tofs() {
|
|||||||
Serial.println(F("Failed to boot VL53L0X"));
|
Serial.println(F("Failed to boot VL53L0X"));
|
||||||
all_tubes[i].state = STATE_ERROR;
|
all_tubes[i].state = STATE_ERROR;
|
||||||
change_led(i);
|
change_led(i);
|
||||||
pixels.show();
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
all_tubes[i].tof.hard.setAddress(0x31 + i);
|
all_tubes[i].tof.hard.setAddress(0x31 + i);
|
||||||
@ -321,15 +346,20 @@ void calibrate_tube(int i){
|
|||||||
delay(5000);
|
delay(5000);
|
||||||
Serial.println("Setuping downards");
|
Serial.println("Setuping downards");
|
||||||
uint16_t h = mesureHeight(i);
|
uint16_t h = mesureHeight(i);
|
||||||
|
if (h < 100) {
|
||||||
|
all_tubes[i].state = STATE_ERROR;
|
||||||
|
Serial.printf("Tube %d HS ! (pas assez haut)\n", i);
|
||||||
|
change_led(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
int angle = minServo;
|
int angle = minServo;
|
||||||
while (h > maxHeight) {
|
while (h > maxHeight) {
|
||||||
Serial.printf("%dmm %d°\n",h, angle);
|
Serial.printf("%dmm %d°\n",h, angle);
|
||||||
++angle;
|
++angle;
|
||||||
if (angle > maxServo) {
|
if (angle > maxServo) {
|
||||||
all_tubes[i].state = STATE_ERROR;
|
all_tubes[i].state = STATE_ERROR;
|
||||||
Serial.printf("Tube %d HS !\n", i);
|
Serial.printf("Tube %d HS ! (moteur ne tourne pas ?)\n", i);
|
||||||
change_led(i);
|
change_led(i);
|
||||||
pixels.show();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
all_tubes[i].servo.hard.write(angle);
|
all_tubes[i].servo.hard.write(angle);
|
||||||
@ -343,7 +373,6 @@ void calibrate_tube(int i){
|
|||||||
Serial.printf("Tube %d calibrated.\n", i);
|
Serial.printf("Tube %d calibrated.\n", i);
|
||||||
all_tubes[i].state = STATE_OK;
|
all_tubes[i].state = STATE_OK;
|
||||||
change_led(i);
|
change_led(i);
|
||||||
pixels.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_servos() {
|
void setup_servos() {
|
||||||
@ -365,17 +394,17 @@ int servoPosition(float ratio){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
|
|
||||||
clock_prescale_set(clock_div_1);
|
|
||||||
#endif
|
|
||||||
Serial.begin(115200); // Starts the serial communication
|
Serial.begin(115200); // Starts the serial communication
|
||||||
while (! Serial) {
|
while (! Serial) {
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pixels.begin();
|
FastLED.addLeds<NEOPIXEL, PIN_PIXELS>(leds, NUM_PIXELS);
|
||||||
pixels.setBrightness(255);
|
FastLED.setBrightness(255);
|
||||||
pixels.show();
|
for (int i = 0; i < NUM_PIXELS; ++i) {
|
||||||
|
leds[i] = CRGB::Black;
|
||||||
|
}
|
||||||
|
FastLED.show();
|
||||||
|
|
||||||
setup_servos();
|
setup_servos();
|
||||||
delay(5000);
|
delay(5000);
|
||||||
@ -403,44 +432,33 @@ void setup() {
|
|||||||
for (int i = 0; i<TUBES_COUNT; i++){
|
for (int i = 0; i<TUBES_COUNT; i++){
|
||||||
calibrate_tube(i);
|
calibrate_tube(i);
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < TUBES_COUNT; ++i) {
|
||||||
|
if (all_tubes[i].state == STATE_OK) {
|
||||||
|
all_tubes[i].state = STATE_MOVING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sinus_center = 300;
|
int sinus_center = 300;
|
||||||
int sinus_radius = 100;
|
float sinus_radius = 100.0;
|
||||||
float step = 0;
|
float step = 0;
|
||||||
float rate = 0.01;
|
double rate = 0.000001;
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
||||||
|
if (current_mode == SINUS) {
|
||||||
|
Serial.printf("SINUS moving\n");
|
||||||
pixels.clear();
|
|
||||||
pixels.show();
|
|
||||||
Serial.println("Cleared");
|
|
||||||
delay(500);
|
|
||||||
for(int i=0; i<NUMPIXELS; i++) {
|
|
||||||
Serial.print("Set light");
|
|
||||||
Serial.println(i);
|
|
||||||
pixels.setPixelColor(i, pixels.Color(0, 150, 0));
|
|
||||||
pixels.show();
|
|
||||||
|
|
||||||
delay(500);
|
|
||||||
}
|
|
||||||
switch (current_mode) {
|
|
||||||
case SINUS: {
|
|
||||||
for (int i = 0; i < TUBES_COUNT; i++) {
|
for (int i = 0; i < TUBES_COUNT; i++) {
|
||||||
all_tubes[i].target = 300 + ((int) sinus_radius * sin(rate * (step + i * 0.1) * 3.14));
|
float angle = (rate * step + ((float) i) * 3.14/6.0) * 3.14;
|
||||||
|
all_tubes[i].target = sinus_center + ((int) sinus_radius * sin(angle * 3.14));
|
||||||
|
Serial.printf("%d - %d = => %f\n", all_tubes[i].height, all_tubes[i].target, angle);
|
||||||
}
|
}
|
||||||
step += 0.1;
|
step += 0.1;
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i<TUBES_COUNT; i++){
|
for (int i = 0; i<TUBES_COUNT; i++){
|
||||||
change_led(i);
|
change_led(i);
|
||||||
if (all_tubes[i].state != STATE_OK) {
|
if (all_tubes[i].state != STATE_MOVING) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
all_tubes[i].height = mesureHeight(i);
|
all_tubes[i].height = mesureHeight(i);
|
||||||
@ -458,14 +476,13 @@ void loop() {
|
|||||||
angle = all_tubes[i].servo.equilibrium;
|
angle = all_tubes[i].servo.equilibrium;
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.printf("%d - %d = %d => %d\n", all_tubes[i].height, all_tubes[i].target, diff, angle);
|
//Serial.printf("%d - %d = %d => %d\n", all_tubes[i].height, all_tubes[i].target, diff, angle);
|
||||||
|
|
||||||
|
|
||||||
all_tubes[i].servo.last_angle = min(max(angle, minServo), maxServo);
|
all_tubes[i].servo.last_angle = min(max(angle, minServo), maxServo);
|
||||||
all_tubes[i].servo.hard.write(all_tubes[i].servo.last_angle);
|
all_tubes[i].servo.hard.write(all_tubes[i].servo.last_angle);
|
||||||
|
|
||||||
}
|
}
|
||||||
pixels.show();
|
|
||||||
|
|
||||||
// Serial.println();
|
// Serial.println();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user