2020-12-01 19:40:58 -05:00
|
|
|
/*
|
|
|
|
strobe_esp32.cpp
|
|
|
|
|
|
|
|
Part of WiFlash_esp32
|
|
|
|
|
|
|
|
Copyright (c) 2020 Kevin Matz (kevin.matz@gmail.com)
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
|
|
copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include "strobe_esp32.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
calculate period from DMX value
|
|
|
|
*/
|
|
|
|
uint32_t hz_to_micros(uint8_t dmx) {
|
|
|
|
if (dmx == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
// ( millis / ( percent * scalor ) + offset ) * micros
|
|
|
|
return (1000 / (((dmx / 255.0) * 24.5) + 0.5)) * 1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
calculate duration from DMX value
|
|
|
|
*/
|
|
|
|
uint32_t dr_to_micros(uint8_t dmx) {
|
|
|
|
// (( percent * scalor) + offset) * micros
|
|
|
|
return (((dmx / 255.0) * .5 ) + .01 ) * 1000 * 1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Constructor
|
|
|
|
*/
|
2020-12-04 09:44:58 -05:00
|
|
|
Strobe::Strobe(uint16_t universe, uint16_t address) {
|
2020-12-01 19:40:58 -05:00
|
|
|
m_universe = universe;
|
|
|
|
m_address = address;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
call durring setup()
|
|
|
|
*/
|
|
|
|
bool Strobe::begin(uint8_t pin, uint8_t pwm) {
|
2020-12-04 09:44:58 -05:00
|
|
|
bool success = true;
|
2020-12-01 19:40:58 -05:00
|
|
|
// set state
|
|
|
|
m_pwm = pwm;
|
|
|
|
m_state = STROBE_INACTIVE;
|
|
|
|
m_level = 0;
|
|
|
|
|
|
|
|
// configure hardware
|
|
|
|
ledcAttachPin(pin, m_pwm); // Attach GPIO to PWM timer
|
|
|
|
ledcSetup(m_pwm, 2400, 15); // 2.4KHz PWM, 15 bit resolutio
|
|
|
|
ledcWrite(m_pwm, m_level); // LED to 0%
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Strobe::update(void * args) {
|
|
|
|
// stop stobing on sACN loss of signal
|
|
|
|
// if (millis() - m_e131->stats.last_seen > 10000) {
|
|
|
|
// Serial.println("No Signal!");
|
|
|
|
// m_int = 0;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// intensity changes start/stop the cycle
|
|
|
|
if (m_int == 0) {
|
|
|
|
// intensity off breaks the cycle
|
|
|
|
m_state = STROBE_INACTIVE;
|
|
|
|
} else {
|
|
|
|
if (m_state == STROBE_INACTIVE) {
|
|
|
|
// going active
|
|
|
|
m_state = STROBE_ACTIVE_ON;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// time based cycle changes
|
|
|
|
if (m_state == STROBE_ACTIVE_ON ||
|
|
|
|
m_state == STROBE_ACTIVE_OFF) {
|
|
|
|
uint32_t now, elapsed, period, durr;
|
|
|
|
now = micros();
|
|
|
|
|
|
|
|
elapsed = now - m_time;
|
|
|
|
period = hz_to_micros(m_rat);
|
|
|
|
durr = dr_to_micros(m_dur);
|
|
|
|
|
|
|
|
if (elapsed > period || // hz period completed
|
|
|
|
now < m_time) { // micros() wraps 32 bits every ~70 min.
|
|
|
|
// cycle restarts
|
|
|
|
m_state = STROBE_ACTIVE_ON;
|
|
|
|
m_time = now;
|
|
|
|
} else if (elapsed > durr) { // durration period completed
|
|
|
|
// cycle enters dark phase
|
|
|
|
m_state = STROBE_ACTIVE_OFF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set LED output
|
|
|
|
if (m_state == STROBE_ACTIVE_ON) {
|
|
|
|
setLevel(m_int);
|
|
|
|
} else {
|
|
|
|
setLevel(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Write a 15bit level to PWM
|
|
|
|
*/
|
|
|
|
void Strobe::setLevel(uint16_t level) {
|
|
|
|
if (level != m_level) {
|
|
|
|
m_level = level;
|
|
|
|
ledcWrite(m_pwm, ((m_level >> 1) & 0xffff)); // write at 15 bit PWM
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Strobe::recvData(e131_packet_t *packet) {
|
|
|
|
//Serial.println(m_e131->stats.num_packets);
|
|
|
|
m_int = packet->property_values[m_address + 0] << 8 |
|
|
|
|
packet->property_values[m_address + 1];
|
|
|
|
m_dur = packet->property_values[m_address + 2];
|
|
|
|
m_rat = packet->property_values[m_address + 3];
|
|
|
|
}
|