Skip to content

Instantly share code, notes, and snippets.

@jbobrow
Last active January 11, 2023 04:44
Show Gist options
  • Save jbobrow/ec4ccb06bdc218c551f8289a4f91502f to your computer and use it in GitHub Desktop.
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.
/*
* 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