Last active
January 11, 2023 04:44
-
-
Save jbobrow/ec4ccb06bdc218c551f8289a4f91502f to your computer and use it in GitHub Desktop.
A quick sketch and notes on the sketch in the header. Not a functioning solution, but a sketch with a slightly different approach. Needs to be tested.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Rough Sketch for Sentiments Box | |
* modified code by Jonathan Bobrow | |
* updated 1.10.2023 | |
* | |
* Goals: | |
* 1. Avoid using an arbitrary number for triggering the sensor | |
* Solution: remove noise from the sensor and make it adapt to it's environment | |
* by keeping a running average and then comparing the last value or N values to the average | |
* 2. Remove dependencies on delays | |
* Reasoning: Animating without delays allows the sensors and the display to run at their own pace. | |
* Currently, it is difficult to tell if the delays can result in missed signal. | |
* | |
* The code below is not tested, but is commented with the intended goals. | |
* The array length is arbitrary as well as the delta... these of course would need to be tested | |
* | |
* Suggestion: Having a way to Serial print the values witnessed would help inform the decisions for thresholds greatly | |
* The HW doesn't have a great way to be connected to the ESP32 and have the sensors connected as well... | |
*/ | |
// use first channel of 16 channels (started from zero) | |
#define LEDC_CHANNEL_0 0 | |
// use 13 bit precission for LEDC timer | |
#define LEDC_TIMER_13_BIT 13 | |
// use 5000 Hz as a LEDC base frequency | |
#define LEDC_BASE_FREQ 5000 | |
// fade LED PIN (replace with LED_BUILTIN constant for built-in LED) | |
#define RED_LED_PIN 13 | |
#define LED_PIN 25 | |
#define IR_LED_PIN 14 | |
#define SENSOR_POWER_PIN 32 | |
#define SENSOR_DATA_PIN 27 | |
#define SENSOR_DELTA_VALUE 20 // amount of change necessary to trigger... | |
#define TIME_TO_SLEEP 100 | |
int brightness = 0; // how bright the LED is | |
int sensorState = 0; | |
int emitterOnTime = 100; | |
int waitStart = 900; | |
int fadeTime = 900; | |
int fadeTimeInterval = 30; | |
int fadeAmount = 255 / (fadeTime / fadeTimeInterval); | |
int endWait = 300; | |
// an array of values to store the last X (in this case 100) values and soften the raw data | |
#define SENSOR_VALUES_LENGTH 100 | |
#define SENSOR_SAMPLE_LENGTH 10 | |
// TODO: Pick a total size and a sample size that smooths the data to have a good running avg, | |
// and doesn't smooth the sample too much to be able to notice the change | |
int sensorValues[NUM_SENSOR_VALUES_TOTAL] = {}; | |
// rather than using delays, we can be in a state of animating | |
bool isAnimatingLEDS = false; | |
// to avoid using delays, we'll need to know how much time passed since our last loop (probably very little) | |
uint32_t timeOfLastAnimationLoop = 0; | |
// Arduino like analogWrite | |
// value has to be between 0 and valueMax | |
void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) { | |
// calculate duty, 8191 from 2 ^ 13 - 1 | |
uint32_t duty = (8191 / valueMax) * min(value, valueMax); | |
// write duty to LEDC | |
ledcWrite(channel, duty); | |
} | |
void setup() { | |
pinMode(RED_LED_PIN,OUTPUT); | |
pinMode(IR_LED_PIN, OUTPUT); | |
pinMode(SENSOR_POWER_PIN, OUTPUT); | |
pinMode(SENSOR_DATA_PIN, INPUT); | |
// Setup timer and attach timer to a led pin | |
ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT); | |
ledcAttachPin(LED_PIN, LEDC_CHANNEL_0); | |
// turn on the IR LED | |
digitalWrite(IR_LED_PIN,HIGH); | |
// turn on the IR LED Sensor | |
digitalWrite(SENSOR_POWER_PIN,HIGH); | |
digitalWrite(SENSOR_DATA_PIN, HIGH); // TODO: Check, why is this being driven high? | |
} | |
void loop() { | |
// move the sensor values back in the array | |
for(int i = sensorValuesLength-1; i > 0; i--) { | |
sensorValues[i] = sensorValues[i-1]; | |
} | |
// read the values from the sensor, store at index 0 in the array | |
sensorValues[0] = analogRead(SENSOR_DATA_PIN); | |
// Calculate average sensor value (this is the environment) | |
uint32_t totalValue = 0; | |
for(int i = 0; i < SENSOR_VALUES_LENGTH; i++) { | |
totalValue += sensorValues[i]; | |
} | |
int avgValue = totalValue / SENSOR_VALUES_LENGTH; | |
// Calculate the average sample sensor value (this is a less noisy recent reading) | |
uint32_t sampleTotalValue = 0; | |
for(int i = 0; i < SENSOR_SAMPLE_LENGTH; i++) { | |
sampleTotalValue += sensorValues[i]; | |
} | |
int avgSampleValue = sampleTotalValue / SENSOR_SAMPLE_LENGTH; | |
// if the current value deviates too much | |
// TODO: Measure what delta is meaningful here | |
if( abs( avgValue - avgSampleValue ) > SENSOR_DELTA_VALUE ) { | |
if( !isAnimatingLEDS ) { | |
// let's start the animation | |
isAnimatingLEDS = true; | |
brightness = 255; | |
} | |
else { | |
// the animation has already begun, nothing to do here | |
} | |
} | |
// animate the LEDS | |
if(isAnimatingLEDS) { | |
if( millis() - timeOfLastAnimationLoop > fadeTimeInterval ) { | |
timeOfLastAnimationLoop = millis(); | |
ledcAnalogWrite(LEDC_CHANNEL_0, brightness); | |
brightness = brightness - fadeAmount; | |
if(brightness <= 0) { | |
brightness = 0; | |
isAnimatingLEDS = false; | |
} | |
} | |
} | |
else { | |
ledcAnalogWrite(LEDC_CHANNEL_0, 0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment