forked from ctdo/blitzer
feat: fluroclock, espnow remote, improvements and 11404
This commit is contained in:
parent
79f110c0ce
commit
c8f96c4b69
|
@ -14,3 +14,5 @@ board = d1_mini
|
||||||
framework = arduino
|
framework = arduino
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
lib_deps = me-no-dev/ESP Async WebServer@^1.2.3
|
lib_deps = me-no-dev/ESP Async WebServer@^1.2.3
|
||||||
|
upload_port=/dev/tty.usbserial-1320
|
||||||
|
monitor_port=/dev/tty.usbserial-1320
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include <fluroclock.h>
|
||||||
|
#include <ESP8266HTTPClient.h>
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
String url = "http://151.217.19.22/api/panel/numeric";
|
||||||
|
WiFiClient client;
|
||||||
|
HTTPClient http;
|
||||||
|
|
||||||
|
void setPanel(int, char);
|
||||||
|
|
||||||
|
void displaySpeed(float speed) {
|
||||||
|
char buffer[6];
|
||||||
|
dtostrf(speed, 6, 2, buffer);
|
||||||
|
setPanel(4, buffer[1]);
|
||||||
|
setPanel(3, buffer[2]);
|
||||||
|
setPanel(2, buffer[4]);
|
||||||
|
setPanel(1, buffer[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPanel(int panel_id, char value) {
|
||||||
|
http.begin(client, url.c_str());
|
||||||
|
http.addHeader("Content-Type", "application/json");
|
||||||
|
String request = "{\"panel_id\":\"";
|
||||||
|
request.concat(panel_id);
|
||||||
|
request.concat("\", \"value\": \"");
|
||||||
|
request.concat(value);
|
||||||
|
request.concat("\"}");
|
||||||
|
Serial.println(request);
|
||||||
|
http.POST(request);
|
||||||
|
http.end();
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef fluroclock_h
|
||||||
|
#define fluroclock_h
|
||||||
|
|
||||||
|
void displaySpeed(float speed);
|
||||||
|
#endif
|
|
@ -22,6 +22,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Blitzercontrol</h1>
|
<h1>Blitzercontrol</h1>
|
||||||
|
<button onclick="getData()">Refresh</button>
|
||||||
<h2>Highscore</h2>
|
<h2>Highscore</h2>
|
||||||
<span id="highscore">23km/h</span>
|
<span id="highscore">23km/h</span>
|
||||||
<h2>Letzte Messungen</h2>
|
<h2>Letzte Messungen</h2>
|
||||||
|
@ -54,17 +55,23 @@
|
||||||
fetch('/set?speed=' + thresholdFieldElem.value);
|
fetch('/set?speed=' + thresholdFieldElem.value);
|
||||||
}
|
}
|
||||||
function getData() {
|
function getData() {
|
||||||
fetch('/data.json')
|
const controller = new AbortController();
|
||||||
|
const id = setTimeout(() => controller.abort(), 1500);
|
||||||
|
fetch('/data.json', {
|
||||||
|
signal: controller.signal
|
||||||
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
clearTimeout(id);
|
||||||
highscoreElem.innerText = data.highscore + ' km/h';
|
highscoreElem.innerText = data.highscore + ' km/h';
|
||||||
let c = lastSpeeds.children;
|
let c = lastSpeeds.children;
|
||||||
for(let i=0; i<data.lastSpeeds.length; i++) {
|
for(let i=0; i<data.lastSpeeds.length; i++) {
|
||||||
c[i].innerText = data.lastSpeeds[i] + ' km/h';
|
c[i].innerText = data.lastSpeeds[i] + ' km/h';
|
||||||
}
|
}
|
||||||
|
thresholdFieldElem.value = data.threshold
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
window.setInterval(getData, 1000)
|
window.setInterval(getData, 5000)
|
||||||
getData();
|
getData();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
handleSetup();
|
handleSpeedSetup();
|
||||||
|
handleRemoteSetup();
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
beginWiFi();
|
beginWiFi();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
handleLoop();
|
handleSpeedLoop();
|
||||||
}
|
}
|
|
@ -3,4 +3,5 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <speed.h>
|
#include <speed.h>
|
||||||
#include <webserver.h>
|
#include <webserver.h>
|
||||||
|
#include <remote.h>
|
||||||
#endif
|
#endif
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include <remote.h>
|
||||||
|
|
||||||
|
// Create a struct_message called myData
|
||||||
|
struct_message recvRemoteData;
|
||||||
|
|
||||||
|
// callback function that will be executed when data is received
|
||||||
|
void OnDataRecv(uint8_t *mac, uint8_t *incomingData, uint8_t len)
|
||||||
|
{
|
||||||
|
Serial.println("received data");
|
||||||
|
String data = String((char *)incomingData);
|
||||||
|
if (data.equals("flash"))
|
||||||
|
{
|
||||||
|
flash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleRemoteSetup()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Init ESP-NOW
|
||||||
|
if (esp_now_init() != 0)
|
||||||
|
{
|
||||||
|
Serial.println("Error initializing ESP-NOW");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once ESPNow is successfully Init, we will register for recv CB to
|
||||||
|
// get recv packer info
|
||||||
|
esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
|
||||||
|
esp_now_register_recv_cb(OnDataRecv);
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef remote_h
|
||||||
|
#define remote_h
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <espnow.h>
|
||||||
|
#include <speed.h>
|
||||||
|
|
||||||
|
typedef struct struct_message {
|
||||||
|
int action;
|
||||||
|
} struct_message;
|
||||||
|
|
||||||
|
|
||||||
|
void handleRemoteSetup();
|
||||||
|
#endif
|
|
@ -25,6 +25,7 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Blitzercontrol</h1>
|
<h1>Blitzercontrol</h1>
|
||||||
|
<button onclick="getData()">Refresh</button>
|
||||||
<h2>Highscore</h2>
|
<h2>Highscore</h2>
|
||||||
<span id="highscore">23km/h</span>
|
<span id="highscore">23km/h</span>
|
||||||
<h2>Letzte Messungen</h2>
|
<h2>Letzte Messungen</h2>
|
||||||
|
@ -57,17 +58,22 @@ const char index_html[] PROGMEM = R"rawliteral(
|
||||||
fetch('/set?speed=' + thresholdFieldElem.value);
|
fetch('/set?speed=' + thresholdFieldElem.value);
|
||||||
}
|
}
|
||||||
function getData() {
|
function getData() {
|
||||||
fetch('/data.json')
|
const controller = new AbortController();
|
||||||
|
const id = setTimeout(() => controller.abort(), 1500);
|
||||||
|
fetch('/data.json', {
|
||||||
|
signal: controller.signal
|
||||||
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
clearTimeout(id);
|
||||||
highscoreElem.innerText = data.highscore + ' km/h';
|
highscoreElem.innerText = data.highscore + ' km/h';
|
||||||
let c = lastSpeeds.children;
|
let c = lastSpeeds.children;
|
||||||
for(let i=0; i<data.lastSpeeds.length; i++) {
|
for(let i=0; i<data.lastSpeeds.length; i++) {
|
||||||
c[i].innerText = data.lastSpeeds[i] + ' km/h';
|
c[i].innerText = data.lastSpeeds[i] + ' km/h';
|
||||||
}
|
}
|
||||||
|
thresholdFieldElem.value = data.threshold
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
window.setInterval(getData, 1000)
|
|
||||||
getData();
|
getData();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -3,94 +3,100 @@
|
||||||
#define PIN_SW1 D6
|
#define PIN_SW1 D6
|
||||||
#define PIN_SW2 D5
|
#define PIN_SW2 D5
|
||||||
#define PIN_TRIGGER D7
|
#define PIN_TRIGGER D7
|
||||||
volatile boolean sw1_flag = false;
|
|
||||||
volatile boolean sw2_flag = false;
|
|
||||||
|
|
||||||
unsigned long sw1_lastTime = 0;
|
unsigned long sw1_lastTime = 0;
|
||||||
unsigned long sw2_lastTime = 0;
|
unsigned long sw2_lastTime = 0;
|
||||||
|
unsigned long sw1_lastTime_e = 0;
|
||||||
|
unsigned long sw2_lastTime_e = 0;
|
||||||
|
|
||||||
float flashspeed = 20; // in kmh
|
float flashspeed = 20; // in kmh
|
||||||
unsigned long flashdeadtime = 1000; // in ms
|
unsigned long flashdeadtime = 1000; // in ms
|
||||||
float calib_distance = 0.062; // distance of sensors in meters
|
float calib_distance = 0.1; // distance of sensors in meters
|
||||||
float lastMeasuredSpeeds[10];
|
float lastMeasuredSpeeds[10];
|
||||||
float highscore = 0;
|
float highscore = 0;
|
||||||
|
|
||||||
unsigned long last_flash = 0;
|
unsigned long last_flash = 0;
|
||||||
|
bool flashNext = false;
|
||||||
|
|
||||||
#define SWDEBOUNCE 100000
|
#define SWDEBOUNCE 1000000
|
||||||
|
|
||||||
ICACHE_RAM_ATTR void interrupt_sw1();
|
ICACHE_RAM_ATTR void interrupt_sw1();
|
||||||
ICACHE_RAM_ATTR void interrupt_sw2();
|
ICACHE_RAM_ATTR void interrupt_sw2();
|
||||||
float getLastSpeed1();
|
float getLastSpeed();
|
||||||
float getLastSpeed2();
|
|
||||||
|
|
||||||
void handleSetup()
|
void handleSpeedSetup()
|
||||||
{
|
{
|
||||||
pinMode(PIN_SW1, INPUT_PULLUP);
|
pinMode(PIN_SW1, INPUT_PULLUP);
|
||||||
pinMode(PIN_SW2, INPUT_PULLUP);
|
pinMode(PIN_SW2, INPUT_PULLUP);
|
||||||
pinMode(PIN_TRIGGER, OUTPUT);
|
pinMode(PIN_TRIGGER, OUTPUT);
|
||||||
attachInterrupt(digitalPinToInterrupt(PIN_SW1), interrupt_sw1, FALLING);
|
|
||||||
attachInterrupt(digitalPinToInterrupt(PIN_SW2), interrupt_sw2, FALLING);
|
attachInterrupt(digitalPinToInterrupt(PIN_SW2), interrupt_sw2, FALLING);
|
||||||
|
attachInterrupt(digitalPinToInterrupt(PIN_SW1), interrupt_sw1, FALLING);
|
||||||
digitalWrite(PIN_TRIGGER, HIGH); // active low
|
digitalWrite(PIN_TRIGGER, HIGH); // active low
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleLoop()
|
void handleSpeedLoop()
|
||||||
{
|
{
|
||||||
// reset micros within the first half second to care for overflowing micros
|
// reset micros within the first half second to care for overflowing micros
|
||||||
if (micros() < 500000) {
|
if (micros() < 500000)
|
||||||
sw1_flag = false;
|
{
|
||||||
sw1_lastTime = 0;
|
sw1_lastTime = 0;
|
||||||
sw2_flag = false;
|
|
||||||
sw2_lastTime = 0;
|
sw2_lastTime = 0;
|
||||||
|
sw1_lastTime_e = 0;
|
||||||
|
sw2_lastTime_e = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (millis() < 500) {
|
if (millis() < 500)
|
||||||
|
{
|
||||||
last_flash = 0;
|
last_flash = 0;
|
||||||
}
|
}
|
||||||
if (sw1_flag)
|
if (sw1_lastTime > 0 && sw2_lastTime > 0 && sw2_lastTime - sw1_lastTime > 1200 && sw2_lastTime - sw1_lastTime < 10000000)
|
||||||
{
|
{
|
||||||
sw1_flag = false;
|
// 0,036 km/h - 300 km/h und sw2 nach sw1 ausgelöst
|
||||||
sw1_lastTime = micros();
|
doTrigger(getLastSpeed());
|
||||||
Serial.println("SW1");
|
sw2_lastTime = 0;
|
||||||
doTrigger(getLastSpeed1());
|
sw1_lastTime = 0;
|
||||||
}
|
}
|
||||||
if (sw2_flag)
|
|
||||||
{
|
{
|
||||||
sw2_flag = false;
|
/* code */
|
||||||
sw2_lastTime = micros();
|
}
|
||||||
Serial.println("SW2");
|
|
||||||
doTrigger(getLastSpeed2());
|
if (flashNext)
|
||||||
|
{
|
||||||
|
flashNext = false;
|
||||||
|
Serial.print("Flashing");
|
||||||
|
pinMode(PIN_TRIGGER, INPUT); // high impedance
|
||||||
|
delay(100);
|
||||||
|
pinMode(PIN_TRIGGER, OUTPUT);
|
||||||
|
digitalWrite(PIN_TRIGGER, LOW);
|
||||||
|
Serial.println("..");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void doTrigger(float speed)
|
void doTrigger(float speed)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (speed < 0.1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (millis() - last_flash > flashdeadtime)
|
if (millis() - last_flash > flashdeadtime)
|
||||||
{ // deadtime
|
{ // deadtime
|
||||||
last_flash = millis();
|
last_flash = millis();
|
||||||
|
|
||||||
if (speed >= flashspeed)
|
if (speed >= flashspeed)
|
||||||
{
|
{
|
||||||
addLastSpeed(speed);
|
addLastSpeed(speed);
|
||||||
Serial.print("> Speed=");
|
Serial.print("> Speed=");
|
||||||
Serial.print(speed);
|
Serial.print(speed);
|
||||||
Serial.println(" km/h");
|
Serial.println(" km/h - FLASH");
|
||||||
flash();
|
flash();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Serial.print(">> Speed=");
|
||||||
|
Serial.print(speed);
|
||||||
|
Serial.println(" km/h");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void flash() {
|
void flash()
|
||||||
Serial.println("Flash");
|
{
|
||||||
pinMode(PIN_TRIGGER, INPUT); // high impedance
|
flashNext = true;
|
||||||
delay(100);
|
|
||||||
pinMode(PIN_TRIGGER, OUTPUT);
|
|
||||||
digitalWrite(PIN_TRIGGER, LOW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addLastSpeed(float speed)
|
void addLastSpeed(float speed)
|
||||||
|
@ -100,32 +106,39 @@ void addLastSpeed(float speed)
|
||||||
lastMeasuredSpeeds[i] = lastMeasuredSpeeds[i + 1];
|
lastMeasuredSpeeds[i] = lastMeasuredSpeeds[i + 1];
|
||||||
}
|
}
|
||||||
lastMeasuredSpeeds[9] = speed;
|
lastMeasuredSpeeds[9] = speed;
|
||||||
if (highscore < speed) {
|
displaySpeed(speed);
|
||||||
|
if (highscore < speed)
|
||||||
|
{
|
||||||
highscore = speed;
|
highscore = speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ICACHE_RAM_ATTR void interrupt_sw1()
|
ICACHE_RAM_ATTR void interrupt_sw1()
|
||||||
{
|
{
|
||||||
if (sw1_lastTime + SWDEBOUNCE < micros())
|
if (sw1_lastTime_e + SWDEBOUNCE < micros())
|
||||||
{
|
{
|
||||||
sw1_flag = true;
|
sw1_lastTime_e = micros();
|
||||||
|
sw1_lastTime = micros();
|
||||||
|
Serial.print("SW1 - ");
|
||||||
|
Serial.println(micros());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ICACHE_RAM_ATTR void interrupt_sw2()
|
ICACHE_RAM_ATTR void interrupt_sw2()
|
||||||
{
|
{
|
||||||
if (sw2_lastTime + SWDEBOUNCE < micros())
|
if (sw2_lastTime_e + SWDEBOUNCE < micros())
|
||||||
{
|
{
|
||||||
sw2_flag = true;
|
sw2_lastTime_e = micros();
|
||||||
|
Serial.print("SW2 - ");
|
||||||
|
Serial.println(micros());
|
||||||
|
if (sw1_lastTime > 0)
|
||||||
|
{
|
||||||
|
sw2_lastTime = micros();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float getLastSpeed1()
|
float getLastSpeed()
|
||||||
{
|
{
|
||||||
return calib_distance / ((sw1_lastTime - sw2_lastTime) / 1000000.0) * 3.6;
|
return calib_distance / ((sw2_lastTime - sw1_lastTime + 11404) / 1000000.0) * 3.6; // lichtschranke 1 kaputt, hat delay, brauchen 11404 microsekunden mehr, trust me.
|
||||||
}
|
|
||||||
float getLastSpeed2()
|
|
||||||
{
|
|
||||||
return calib_distance / ((sw2_lastTime - sw1_lastTime) / 1000000.0) * 3.6;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef speed_h
|
#ifndef speed_h
|
||||||
#define speed_h
|
#define speed_h
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <fluroclock.h>
|
||||||
|
|
||||||
extern float flashspeed;
|
extern float flashspeed;
|
||||||
extern float highscore;
|
extern float highscore;
|
||||||
|
@ -9,8 +10,8 @@ extern float calib_distance;
|
||||||
|
|
||||||
extern float lastMeasuredSpeeds[10];
|
extern float lastMeasuredSpeeds[10];
|
||||||
void flash();
|
void flash();
|
||||||
void handleLoop();
|
void handleSpeedLoop();
|
||||||
void handleSetup();
|
void handleSpeedSetup();
|
||||||
void doTrigger(float speed);
|
void doTrigger(float speed);
|
||||||
void addLastSpeed(float speed);
|
void addLastSpeed(float speed);
|
||||||
#endif
|
#endif
|
|
@ -10,7 +10,12 @@ void beginWiFi() {
|
||||||
Serial.print(".");
|
Serial.print(".");
|
||||||
}
|
}
|
||||||
Serial.println("");
|
Serial.println("");
|
||||||
|
Serial.print("ESP8266 Board MAC Address: ");
|
||||||
|
Serial.println(WiFi.macAddress());
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print("ESP822 IP: ");
|
||||||
Serial.println(WiFi.localIP());
|
Serial.println(WiFi.localIP());
|
||||||
|
Serial.println(WiFi.channel());
|
||||||
server.on("/", HTTP_GET, [] (AsyncWebServerRequest *request) {
|
server.on("/", HTTP_GET, [] (AsyncWebServerRequest *request) {
|
||||||
request->send(200, "text/html", index_html);
|
request->send(200, "text/html", index_html);
|
||||||
});
|
});
|
||||||
|
@ -36,6 +41,8 @@ void beginWiFi() {
|
||||||
server.on("/data.json", HTTP_GET, [] (AsyncWebServerRequest *request) {
|
server.on("/data.json", HTTP_GET, [] (AsyncWebServerRequest *request) {
|
||||||
String response = "{\"highscore\":";
|
String response = "{\"highscore\":";
|
||||||
response.concat(highscore);
|
response.concat(highscore);
|
||||||
|
response.concat(", \"threshold\": ");
|
||||||
|
response.concat(flashspeed);
|
||||||
response.concat(",\"lastSpeeds\": [");
|
response.concat(",\"lastSpeeds\": [");
|
||||||
for(int i=0;i<10;i++) {
|
for(int i=0;i<10;i++) {
|
||||||
response.concat(lastMeasuredSpeeds[i]);
|
response.concat(lastMeasuredSpeeds[i]);
|
||||||
|
|
Loading…
Reference in New Issue