// https://wokwi.com/projects/365913963074043905
// for https://forum.arduino.cc/t/need-to-know-if-the-project-i-have-planed-can-be-done/1121026/37
const int ledPin = A2;
int onFractionPct = 10 ;
long onTime = 0;
struct ToggleTimerPin {
uint8_t pin;
unsigned long last ;
unsigned long onTime ;
unsigned long offTime;
uint8_t state ;
unsigned long period;
void setPeriod(unsigned long val) {
period = val;
offTime = val - onTime;
}
void setOnTime(unsigned long val) {
onTime = val;
offTime = period - val;
}
void setDutyPPQ(unsigned val, int Q) { // Parts per fixed-point Q
onTime = (period * val) >> Q;
offTime = period - onTime;
}
void setDutyF(float val) {
onTime = (period * val);
offTime = period - onTime;
}
} myLed = {ledPin, 0, 10, 100};
//unsigned long period = 1000000UL * 1000UL / 20000;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(myLed.pin, OUTPUT);
myLed.setPeriod( 1000000UL * 1000UL / 20000); // 20Hz
}
void loop() {
updateSpeed();
handleLed(myLed);
}
void updateSpeed(void) {
static int lastADC = -1;
int myADC = analogRead(A0);
if (myADC != lastADC) {
lastADC = myADC;
// myLed.onTime = myADC * period / 1023UL;
myLed.setDutyPPQ(myADC,10);
//myLed.offTime = period - myLed.onTime;
Serial.print("A0:");
Serial.print(myADC);
Serial.print(" ratio:");
Serial.print(myLed.onTime);
Serial.print(':');
Serial.print(myLed.offTime);
Serial.print(" Duty:");
Serial.print(myLed.onTime * 100.0 / myLed.period, 4);
Serial.print("% Hz:");
Serial.print(1.0e6 / myLed.period, 3);
Serial.print(" \n");
}
}
void handleLed(ToggleTimerPin & led) {
unsigned long now = micros();
if (led.state) { // on?
if (now - led.last > led.onTime ) { // on -> off
// Serial.print('_');
if (led.offTime > 0 ) {
digitalWrite(led.pin, LOW);
}
led.state = 0;
led.last += led.onTime;
// led.last = now;
}
} else { // off
if (now - led.last > led.offTime ) { // off -> on
// Serial.print('+');
if (led.onTime > 0) {
digitalWrite(led.pin, HIGH);
}
led.state = 1;
led.last += led.offTime;
// led.last = now;
}
}
}