diff --git a/MotionToPhotonMeter.ino b/MotionToPhotonMeter.ino index 034cfd781300f8708a28296bbfe3d4150a2182db..bf538428ed1e3a10678154231c36d3001f6f28c2 100644 --- a/MotionToPhotonMeter.ino +++ b/MotionToPhotonMeter.ino @@ -1,199 +1,184 @@ -#include <ESP32Servo.h> -#include "MotionToPhotonServer.h" -#include "esp_task_wdt.h" - -/* Forward Declarations */ -void startMeasureing(unsigned int numberOfSamples); -unsigned int getPhotoDiodeReading(); -void setThresholdValue(unsigned int newThreshold); -unsigned int getDeflectionValue(); -void setDeflectionValue(unsigned int newDeflection); -unsigned int getThresholdValue(); -String getStatus(); -unsigned int getCurrentNumberOfResults(); -void zeroServo(); -void abortMeasurement(); - -/* Enums */ -enum Status {Ready = 0, Measuring = 1}; -String Status_Text[2] = {"Ready", "Measuring"}; -enum InternalStatus {Zeroed, NotZeroed, Stopping}; - -/* Hardware */ -Servo rotation_servo; -#define PhotoPin 33 -#define ServoPin 12 -#define SensePin 4 -#define ButtonPin 23 - -/* Global Values */ -int zeroValueForServo = 0; -unsigned int deflection = 10; -long startTime = -1; -int triggerValue = 2500; -#define Timeout 10000000L -unsigned int requested_measurements = -1; -Status current_status = Status::Ready; -InternalStatus current_internal_status = InternalStatus::NotZeroed; - -/* Result Storage */ -#define result_buffer_length 10000 -unsigned long result_buffer[result_buffer_length]; -unsigned int result_number = 0; - -/* Server */ -MotionToPhotonServer server(result_buffer, result_buffer_length, getPhotoDiodeReading, getThresholdValue, setThresholdValue, getDeflectionValue, setDeflectionValue, getStatus, startMeasureing, getCurrentNumberOfResults, abortMeasurement); - -/* Multicore */ -TaskHandle_t TaskCore0; -TaskHandle_t TaskCore1; - -void core1( void * pvParameters ){ - while(true){ - if(current_status != Status::Measuring){ - delay(5); //just small delay - continue; - } - - if(current_internal_status == InternalStatus::NotZeroed - && result_number < requested_measurements){ - zeroServo(); //Rearm - - do{ - delay(2000 + random(1,11)); // Two seconds + random delay - }while(getPhotoDiodeReading() < triggerValue); //Prevent false resets - - rotation_servo.write(zeroValueForServo - deflection); //deflection movement - } - - if((current_internal_status == InternalStatus::Zeroed || current_internal_status == InternalStatus::Stopping) - && digitalRead(SensePin)){ - current_internal_status = InternalStatus::Stopping; - startTime = micros(); - } - - if(current_internal_status == InternalStatus::Stopping - && getPhotoDiodeReading() < triggerValue){ - result_buffer[result_number] = micros() - startTime; - Serial.println("Time: " + String(result_buffer[result_number])); - result_number++; - current_internal_status = InternalStatus::NotZeroed; - - //Finished Measurements - if(result_number >= requested_measurements){ - current_status = Status::Ready; - requested_measurements = -1; - } - } - - // Timeout - if(current_internal_status == InternalStatus::Stopping && (micros() - startTime) > Timeout){ - current_internal_status = InternalStatus::NotZeroed; - } - } -} - -void core0( void * pvParameters ){ - while(true){ - server.serve(); - } -} - -void setup() { - Serial.begin(115200); - - rotation_servo.setPeriodHertz(50); // standard 50 hz servo - rotation_servo.attach(ServoPin, 540, 2470); - - rotation_servo.write(0); - - pinMode(PhotoPin, INPUT); - pinMode(SensePin, INPUT_PULLDOWN); - - randomSeed(analogRead(PhotoPin) + analogRead(0)); //Initalize Random seed - - server.setup(); - - esp_task_wdt_init(6000,false); - xTaskCreatePinnedToCore( - core0, // Task function. - "Server", // name of task. - 10000, // Stack size of task - NULL, // parameter of the task - 2, // priority of the task - &TaskCore0, // Task handle to keep track of created task - 0); // pin task to core 0 - delay(500); - xTaskCreatePinnedToCore( - core1, // Task function. - "Meter", // name of task. - 10000, // Stack size of task - NULL, // parameter of the task - 2, // priority of the task - &TaskCore1, // Task handle to keep track of created task - 1); // pin task to core 1 - delay(500); - disableCore0WDT(); - disableCore1WDT(); -} - -void loop(){} //Still needed for arduino core to work - -void startMeasureing(unsigned int numberOfSamples){ - if(numberOfSamples > result_buffer_length) return; - memset(result_buffer, 0l, result_buffer_length * sizeof(long)); //clear buffer - result_number = 0; - requested_measurements = numberOfSamples; - current_status = Status::Measuring; -} - -unsigned int getPhotoDiodeReading(){ - return analogRead(PhotoPin); -} - -void abortMeasurement(){ - current_status = Status::Ready; - requested_measurements = -1; - rotation_servo.write(0); - current_internal_status = InternalStatus::NotZeroed; -} - -void setThresholdValue(unsigned int newThreshold){ - triggerValue = newThreshold; -} - -unsigned int getThresholdValue(){ - return triggerValue; -} - -unsigned int getDeflectionValue(){ - return deflection; -} - -void setDeflectionValue(unsigned int newDeflection){ - deflection = newDeflection; -} - -String getStatus(){ - return Status_Text[current_status]; -} - -unsigned int getCurrentNumberOfResults(){ - return max(result_number, 0u); -} - -void zeroServo(){ - //start a little lower than last time - zeroValueForServo -= 5; - rotation_servo.write(zeroValueForServo); - delay(50); - - do{ - zeroValueForServo++; - rotation_servo.write(zeroValueForServo); - delay(100); - } while (!digitalRead(SensePin)); - Serial.println("Servo zeroed at: " + String(zeroValueForServo)); - - current_internal_status = InternalStatus::Zeroed; -} +#include "MotionToPhotonServer.h" +#include "esp_task_wdt.h" + +/* Enums */ +enum Status {Ready = 0, Measuring = 1}; +String Status_Text[2] = {"Ready", "Measuring"}; +enum InternalStatus {DefaultReady, Moved}; + +/* Forward Declarations */ +void startMeasurements(unsigned int numberOfSamples); +unsigned int getPhotoDiodeReading(); +void setThresholdValue(unsigned int newThreshold); +unsigned int getThresholdValue(); +String getStatus(); +unsigned int getCurrentNumberOfResults(); +void setLEDExternal(bool LedMoved); +void setLED(InternalStatus Status); +void abortMeasurement(); + +/* Hardware */ +#define PhotoPin 32 +#define Marker1Pin 16 +#define Marker2Pin 17 + +/* Global Values */ +long startTime = -1; +int triggerValue = 2500; +#define Timeout 10000000L +unsigned int requested_measurements = -1; +Status current_status = Status::Ready; +InternalStatus current_internal_status = InternalStatus::DefaultReady; + +/* Result Storage */ +#define result_buffer_length 10000 +unsigned long result_buffer[result_buffer_length]; +unsigned int result_number = 0; + +/* Server */ +MotionToPhotonServer server(result_buffer, result_buffer_length, getPhotoDiodeReading, getThresholdValue, setThresholdValue, getStatus, startMeasurements, getCurrentNumberOfResults, abortMeasurement, setLEDExternal); + +/* Multicore */ +TaskHandle_t TaskCore0; +TaskHandle_t TaskCore1; + +void core1( void * pvParameters ){ + while(true){ + //just small delay while not measuring to not spend to much power in idle + if(current_status == Status::Ready){ + delay(5); + continue; + } + + // Starting next measurement + if(current_internal_status == InternalStatus::DefaultReady && result_number < requested_measurements){ + //Wait for screen to become black again and prevent false resets + for(int i = 0; i < 10; i++){ + do{ + delay(100 + random(1,20)); + }while(getPhotoDiodeReading() < triggerValue); + } + + //Switch marker location and start clock + setLED(InternalStatus::Moved); + startTime = micros(); + } + + //Stop/Record measurement value + if(current_internal_status == InternalStatus::Moved && getPhotoDiodeReading() < triggerValue){ + result_buffer[result_number] = micros() - startTime; + Serial.println("Time: " + String(result_buffer[result_number])); + result_number++; + setLED(InternalStatus::DefaultReady); //Reset to ready + + //Finished Measurements + if(result_number >= requested_measurements){ + current_status = Status::Ready; + requested_measurements = -1; + } + } + + // Timeout, Reset without Measurement + if(current_internal_status == InternalStatus::Moved && (micros() - startTime) > Timeout){ + setLED(InternalStatus::DefaultReady); + } + } +} + +void core0( void * pvParameters ){ + while(true){ + server.serve(); + } +} + +void setup() { + Serial.begin(115200); + + pinMode(PhotoPin, INPUT); + pinMode(Marker1Pin, OUTPUT); + pinMode(Marker2Pin, OUTPUT); + + setLED(InternalStatus::DefaultReady); + + randomSeed(analogRead(PhotoPin) + analogRead(0)); //Initalize Random seed + + server.setup(); + + esp_task_wdt_init(6000,false); + xTaskCreatePinnedToCore( + core0, // Task function. + "Server", // name of task. + 10000, // Stack size of task + NULL, // parameter of the task + 2, // priority of the task + &TaskCore0, // Task handle to keep track of created task + 0); // pin task to core 0 + delay(500); + xTaskCreatePinnedToCore( + core1, // Task function. + "Meter", // name of task. + 10000, // Stack size of task + NULL, // parameter of the task + 2, // priority of the task + &TaskCore1, // Task handle to keep track of created task + 1); // pin task to core 1 + delay(500); + disableCore0WDT(); + disableCore1WDT(); +} + +void loop(){} //Still needed for arduino core to work + +void startMeasurements(unsigned int numberOfSamples){ + if(numberOfSamples > result_buffer_length) return; + + memset(result_buffer, 0l, result_buffer_length * sizeof(long)); //clear buffer + result_number = 0; + requested_measurements = numberOfSamples; + + setLED(InternalStatus::DefaultReady); + current_status = Status::Measuring; +} + +unsigned int getPhotoDiodeReading(){ + return analogRead(PhotoPin); +} + +void abortMeasurement(){ + current_status = Status::Ready; + requested_measurements = -1; + + setLED(InternalStatus::DefaultReady); +} + +void setThresholdValue(unsigned int newThreshold){ + triggerValue = newThreshold; +} + +void setLED(InternalStatus Status){ + if(Status == InternalStatus::DefaultReady){ + digitalWrite(Marker1Pin, HIGH); + digitalWrite(Marker2Pin, LOW); + } else { + digitalWrite(Marker1Pin, LOW); + digitalWrite(Marker2Pin, HIGH); + } + current_internal_status = Status; +} + +void setLEDExternal(bool LedMoved){ + if(current_status == Status::Measuring) return; //Do not set while measuring + setLED(LedMoved ? InternalStatus::Moved : InternalStatus::DefaultReady); +} + +unsigned int getThresholdValue(){ + return triggerValue; +} + +String getStatus(){ + return Status_Text[current_status]; +} + +unsigned int getCurrentNumberOfResults(){ + return max(result_number, 0u); +} diff --git a/MotionToPhotonServer.cpp b/MotionToPhotonServer.cpp index de95b06da4721eeb9299678bc4193e8214f9121b..91e118776dd66ba6d7d1ea6beda0a253c5438b55 100644 --- a/MotionToPhotonServer.cpp +++ b/MotionToPhotonServer.cpp @@ -2,16 +2,26 @@ /* Server Setup */ - MotionToPhotonServer::MotionToPhotonServer(unsigned long* result_buffer_, unsigned int result_buffer_length_, unsigned int (* getPhotodiodeReadingFunction)(), unsigned int (* getThresholdFunction)(), void (* setThresholdFunction)(unsigned int), unsigned int (* getDeflectionFunction)(), void (* setDeflectionFunction)(unsigned int), String (* getStatusFunction)(), void (* startMeasureFunction)(unsigned int), unsigned int (* getCurrentNumberOfResultsFunction)(), void (* abortMeasurementFunction)()) { + MotionToPhotonServer::MotionToPhotonServer( + unsigned long* result_buffer_, + unsigned int result_buffer_length_, + unsigned int (* getPhotodiodeReadingFunction)(), + unsigned int (* getThresholdFunction)(), + void (* setThresholdFunction)(unsigned int), + String (* getStatusFunction)(), + void (* startMeasureFunction)(unsigned int), + unsigned int (* getCurrentNumberOfResultsFunction)(), + void (* abortMeasurementFunction)(), + void (* setLedMovedFunction)(bool) + ) { getPhotodiodeReading = getPhotodiodeReadingFunction; getThreshold = getThresholdFunction; setThreshold = setThresholdFunction; - getDeflection = getDeflectionFunction; - setDeflection = setDeflectionFunction; getStatus = getStatusFunction; startMeasure = startMeasureFunction; abortMeasurement = abortMeasurementFunction; getCurrentNumberOfResults = getCurrentNumberOfResultsFunction; + setLedMoved = setLedMovedFunction; result_buffer = result_buffer_; result_buffer_length = result_buffer_length_; } @@ -34,8 +44,8 @@ server.on("/sensor", [this](){this->pageSensor();}); server.on("/setThreshold", [this](){this->pageSetThreshold();}); server.on("/getThreshold", [this](){this->pageGetThreshold();}); - server.on("/setDeflection", [this](){this->pageSetDeflection();}); - server.on("/getDeflection", [this](){this->pageGetDeflection();}); + server.on("/setLedDefault", [this](){this->pageSetLedDefault();}); + server.on("/setLedMoved", [this](){this->pageSetLedMoved();}); server.on("/abort", [this](){this->pageAbort();}); server.onNotFound([this](){this->pageNotFound();}); @@ -73,19 +83,14 @@ server.send(200, "text/plain", String(getThreshold())); } - void MotionToPhotonServer::pageSetDeflection(){ - if(server.args() <= 0){ - server.send(400, "text/plain", "No parameters given. Give d=<deflection>"); - return; - } - unsigned int deflection = String(server.arg(0)).toInt(); - - setDeflection(deflection); + void MotionToPhotonServer::pageSetLedDefault(){ + setLedMoved(false); server.send(200, "text/plain", "Ok."); } - void MotionToPhotonServer::pageGetDeflection(){ - server.send(200, "text/plain", String(getDeflection())); + void MotionToPhotonServer::pageSetLedMoved(){ + setLedMoved(true); + server.send(200, "text/plain", "Ok."); } void MotionToPhotonServer::pageSensor(){ diff --git a/MotionToPhotonServer.h b/MotionToPhotonServer.h index a73cc9c31bca2064a11ebf0bb981c21bebc1f954..630a56c2f7a2e55a021d767c371b3ae0ff4467c4 100644 --- a/MotionToPhotonServer.h +++ b/MotionToPhotonServer.h @@ -10,11 +10,10 @@ class MotionToPhotonServer private: unsigned int (* getPhotodiodeReading)(); unsigned int (* getThreshold)(); - unsigned int (* getDeflection)(); unsigned int (* getCurrentNumberOfResults)(); String (* getStatus)(); void (* setThreshold)(unsigned int); - void (* setDeflection)(unsigned int); + void (* setLedMoved)(bool); void (* startMeasure)(unsigned int); void (* abortMeasurement)(); @@ -41,8 +40,8 @@ class MotionToPhotonServer void pageStatus(); void pageSetThreshold(); void pageGetThreshold(); - void pageSetDeflection(); - void pageGetDeflection(); + void pageSetLedDefault(); + void pageSetLedMoved(); void pageMeasure(); void pageResults(); void pageIndex(); @@ -54,7 +53,15 @@ class MotionToPhotonServer public: /* Server functions */ - MotionToPhotonServer(unsigned long* result_buffer_, unsigned int result_buffer_length_, unsigned int (* getPhotodiodeReadingFunction)(), unsigned int (* getThresholdFunction)(), void (* setThresholdFunction)(unsigned int), unsigned int (* getDeflectionFunction)(), void (* setDeflectionFunction)(unsigned int), String (* getStatusFunction)(), void (* startMeasureFunction)(unsigned int), unsigned int (* getCurrentNumberOfResultsFunction)(), void (* abortMeasurementFunction)()); + MotionToPhotonServer(unsigned long* result_buffer_, unsigned int result_buffer_length_, + unsigned int (* getPhotodiodeReadingFunction)(), + unsigned int (* getThresholdFunction)(), + void (* setThresholdFunction)(unsigned int), + String (* getStatusFunction)(), + void (* startMeasureFunction)(unsigned int), + unsigned int (* getCurrentNumberOfResultsFunction)(), + void (* abortMeasurementFunction)(), + void (* setLedMoved)(bool)); void setup(); void serve(); diff --git a/data/index.html b/data/index.html index 41edadff3afb382d67252404914903f5228e9ae1..5c7c52ec642eda4edb6fcd0ece3d1ed6be635629 100644 --- a/data/index.html +++ b/data/index.html @@ -2,6 +2,8 @@ <html> <head> <meta charset="ISO-8859-1"> + <title>Calibratio V1.1</title> + <!-- Hello you there, reading the code! This was coded by Sebastian Pape aka PapeCoding.de --> <style> * { font-family: Arial, Helvetica, sans-serif; @@ -64,6 +66,14 @@ function getSensor(){ document.getElementById("lightSensor").textContent = makeRequest("sensor"); } + + function setLEDDefault(){ + makeRequest("setLedDefault"); + } + + function setLEDMoved(){ + makeRequest("setLedMoved"); + } function setThreshold(){ if(document.getElementById("sensorThreshold").checkValidity()){ @@ -75,16 +85,6 @@ document.getElementById("sensorThreshold").value = makeRequest('getThreshold'); } - function setDeflection(){ - if(document.getElementById("servoDeflection").checkValidity()){ - makeRequest('setDeflection?d=' + document.getElementById("servoDeflection").value); - } - } - - function getDeflection(){ - document.getElementById("servoDeflection").value = makeRequest('getDeflection'); - } - /* Statistics */ function sum(array) { var num = 0; @@ -132,7 +132,6 @@ document.addEventListener('DOMContentLoaded', (event) => { getThreshold(); - getDeflection(); getStatus(); getSensor(); }); @@ -140,8 +139,8 @@ </head> <body style="display: flex; flex-direction: row; align-items: center; flex-wrap: wrap; justify-content: center;"> <div class="box niceBorder" style="flex: 0 1 75%; text-align: center; padding: 20px;"> - <div style="font-size: 3em">Calibratio</div><br /> - This device measures the movement to photon latency! + <div style="font-size: 3em">Calibratio V1.1</div><br /> + This device measures the movement to photon latency. No moving parts this time! </div> <div style="display: flex; flex-direction: column; align-items: stretch; flex-wrap: wrap; justify-content: center;"> <div id="statistics" class="box niceBorder" style="width: 500px; height: 80px;"></div> @@ -164,9 +163,9 @@ <div class="button" onclick="setThreshold()">Set!</div> </div> <div class="box niceBorder"> - <div style="padding: 5px;">Servo Deflection:</div> - <input type="number" id="servoDeflection" min="1" max="360"> - <div class="button" onclick="setDeflection()">Set!</div> + <div style="padding: 5px;">Manual LED Setting:</div> + <div class="button" style="display:inline-block" onclick="setLEDDefault()">Default</div> + <div class="button" style="display:inline-block" onclick="setLEDMoved()">Moved</div> </div> <div class="box niceBorder"> <div style="padding: 5px;">Times to Meassure:</div>