Hi all,
Recently I designed a PCB based on ATmega328P which supposed to read Duty Cycle coming in on input 2 through galvanic isolation and drive one of 5 segments of LEDs based on it's value. Circuit is to be used as a shift light on a drag racing bike. Electronically the circuit works, I'm able to see high/ low state of the input and drive any of the LEDs manually. Unfortunately I'm lacking basic coding skills to make it work the way I want it. So far the code can read either 0% or 100% duty cycle, therefore nothing is happening. I would greatly appreciate any feedback or constructive criticism form more experienced coders!
//~~~LED DRIVER
int led1 = 3;
int led2 = 5;
int led3 = 6;
int led4 = 9;
int led5 = 10;
int timer1 = 230; // light on time leds
int timer1d = 15; // deley between different lights
int timer2 = 70; // blinks on shift light
int bright = 150; // LED brightness Value between 0 and 255
//~~~SIGNAL SETUP
int Signal_1 = 40; // PWM required to turn led 1 on
int Signal_2 = 50; // PWM required to turn led 2 on
int Signal_3 = 60; // PWM required to turn led 3 on
int Signal_4 = 70; // PWM required to turn led 4 on
int Signal_5 = 80; // PWM required to turn led 5 on
int Signal_buff = 1; // threshold for PWM comming in
//~~~PWM SETUP
volatile unsigned long fall_Time = 0; // Placeholder for microsecond time when last falling edge occured.
volatile unsigned long rise_Time = 0; // Placeholder for microsecond time when last rising edge occured.
volatile byte dutyCycle = 0; // Duty Cycle %
volatile unsigned long lastRead = 0; // Last interrupt time (needed to determine interrupt lockup due to 0% and 100% duty cycle)
void PinChangeISR0() { // Pin 2 (Interrupt 0) service routine
lastRead = micros(); // Get current time
if (digitalRead(2) == LOW) {
// Falling edge
fall_Time = lastRead; // Just store falling edge and calculate on rising edge
}
else {
// Rising edge
unsigned long total_Time = rise_Time - lastRead; // Get total cycle time
unsigned long on_Time = fall_Time - rise_Time; // Get on time during this cycle
total_Time = total_Time / on_Time; // Divide it down
dutyCycle = 100 / total_Time; // Convert to a percentage
rise_Time = lastRead; // Store rise time
}
}
void Intro()
{
analogWrite(led1, bright);
delay(timer1);
analogWrite(led1, 0);
delay(timer1d);
//******
analogWrite(led2, bright);
delay(timer1);
analogWrite(led2, 0);
delay(timer1d);
//******
analogWrite(led3, bright);
delay(timer1);
analogWrite(led3, 0);
delay(timer1d);
//******
analogWrite(led4, bright);
delay(timer1);
analogWrite(led4, 0);
delay(timer1d);
//******
analogWrite(led5, bright);
delay(timer2);
analogWrite(led5, 0);
delay(timer2);
analogWrite(led5, bright);
delay(timer2);
analogWrite(led5, 0);
delay(timer2);
analogWrite(led5, bright);
delay(timer2);
analogWrite(led5, 0);
delay(timer2);
analogWrite(led5, bright);
delay(timer2);
analogWrite(led5, 0);
delay(timer2);
analogWrite(led5, bright);
delay(timer2);
analogWrite(led5, 0);
delay(timer2);
//******
analogWrite(led4, bright);
delay(timer1);
analogWrite(led4, 0);
delay(timer1d);
//******
analogWrite(led3, bright);
delay(timer1);
analogWrite(led3, 0);
delay(timer1d);
//******
analogWrite(led2, bright);
delay(timer1);
analogWrite(led2, 0);
delay(timer1d);
//******
analogWrite(led1, bright);
delay(timer1);
analogWrite(led1, 0);
delay(timer1d);
//******
}
void RPM()
{
static unsigned long oldLastRead = lastRead;
Serial.print("Duty Cycle = ");
if (oldLastRead != lastRead) {
Serial.print(dutyCycle);
oldLastRead = lastRead;
//~~~~~
if ((dutyCycle <= Signal_1 + Signal_buff) && (dutyCycle >= Signal_1 - Signal_buff)) {
analogWrite(led1, bright);
Serial.print("Led 1 ON ");
}
else {
analogWrite(led1, 0 );
}
//~~~~~
if ((dutyCycle <= Signal_2 + Signal_buff) && (dutyCycle >= Signal_2 - Signal_buff)) {
analogWrite(led2, bright);
Serial.print("Led 2 ON ");
}
else {
analogWrite(led2, 0 );
}
//~~~~~
if ((dutyCycle <= Signal_3 + Signal_buff) && (dutyCycle >= Signal_3 - Signal_buff)) {
analogWrite(led3, bright);
Serial.print("Led 3 ON ");
}
else {
analogWrite(led3, 0 );
}
//~~~~~
if ((dutyCycle <= Signal_4 + Signal_buff) && (dutyCycle >= Signal_4 - Signal_buff)) {
analogWrite(led4, bright);
Serial.print("Led 4 ON ");
}
else {
analogWrite(led4, 0 );
}
//~~~~~
if ((dutyCycle <= Signal_5 + Signal_buff) && (dutyCycle >= Signal_5 - Signal_buff)) {
analogWrite(led5, bright);
Serial.print("Led 5 ON ");
}
else {
analogWrite(led5, 0 );
}
}
else { // No interrupt since last read so must be 0% or 100%
if (digitalRead(2) == LOW) {
Serial.print("0");
}
else {
Serial.print("100");
}
}
Serial.println("%");
delay(100);
}
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
Serial.begin(115200);
pinMode(2, INPUT);
Serial.println(F("ISR Pin 2 Configured For Input."));
attachInterrupt(0, PinChangeISR0, CHANGE);
Serial.println(F("Pin 2 ISR Function Attached."));
Intro();
}
void loop() {
RPM();
}