Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
7 years, 2 months ago.
How to count incoming pulses so that it changes LED blink frequency more like logarithmically
Suppose I want to blink LED on a regular basis once per, say 1.5 seconds, but if the frequency of incoming signal is increasing (0-up to 2khz.) I want LED to blink faster and faster with each increase almost like logarithmically. The range would be from 0 up to maybe 2khz. I was working this out by using if statements, but I did it with several frequency stages which results in a huge steps. However, I was thinking if there is any way to do this by increasing the blinking smoothly?
I know this code below is far from good, but it does approximately what I wanted.
#include "mbed.h"
#define ON 1
#define OFF 0
DigitalOut myled(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);
PwmOut PWM(p21); // pwm out
InterruptIn pulseInterrupt(p5); // Input pulse signal here
int pulseCount;
void highPulseDetected() { // incoming pulse counter
pulseCount++;
}
int main() {
pulseCount = 0;
pulseInterrupt.rise(&highPulseDetected); //attach counter address to the ISR upon rising edge
while(1) {
PWM.period(pulseInterrupt); // generate pwm to feed back in for counting
PWM = 0.5;
wait_ms(100);
PWM = 0;
pc.printf("%d\n\r", pulseCount++);
if(pulseCount <= 102) {
myled = ON;
wait(0.1);
myled = OFF;
wait(1);
pulseCount = 0;
}
else if(pulseCount <= 202){
myled2 = ON;
wait(0.1);
myled2 = OFF;
wait(0.6);
pulseCount = 0;
}
else if(pulseCount <= 302){
myled3 = ON;
wait(0.1);
myled3 = OFF;
wait(0.4);
pulseCount = 0;
}
else if(pulseCount <= 402){
myled4 = ON;
wait(0.1);
myled4 = OFF;
wait(0.1);
pulseCount = 0;
}
else if(pulseCount <= 502){
myled = ON;
wait(0.1);
myled = OFF;
wait(0.07);
pulseCount = 0;
}
else if(pulseCount >= 602){
myled2 = ON;
wait(0.1);
myled2 = OFF;
wait(0.02);
pulseCount = 0;
}
}
}
1 Answer
7 years, 2 months ago.
Hello Saulius,
Interesting task. Below is another attempt for a solution:
#include "mbed.h"
DigitalOut led(LED1);
InterruptIn input(p5); // input line
Timeout timeout;
volatile bool counting = false;
volatile uint32_t counter;
float period;
const float GATE_TIME = 1.0f; // period of time to count pulses within (in seconds)
const float K = 1; // to be tuned
const float MIN_COUNT = pow(10.0f, 1.5f); // 10^1.5
//ISR to count pulses
void onPulse(void) {
if (counting)
counter++;
}
// ISR to stop pulse counting
void stopCounting(void) {
counting = false;
}
// Entry point
int main(void) {
input.rise(callback(&onPulse)); // assign an ISR to pulse counting
led = 1;
while (1) {
if (!counting) {
period = 1 / log(MIN_COUNT + K * counter);
counter = 0;
timeout.attach(callback(&stopCounting), GATE_TIME);
counting = true;
}
wait(period);
led = !led;
}
}