Skip to content

PWM generation on multiple pins #75

@deepparikh

Description

@deepparikh

Hello,
I am using the timer library to generate 100 Hz PWM on four pins, which can have different duty cycles. In my current implementation, the timer misses one cycle every 500ms or so, where it just skips the timer.in delay and proceeds with the delay function immediately i.e. switching the pin high and then low immediately. Could you please share your thoughts on the probable cause for this ?

`#include <arduino-timer.h>

Timer<10> timer;
float frequency; // Frequency in Herz
double period;
double onFor[]={0,0,0,0};
long previous;

// Output pins for solenoid valves
#define Valve1 2 // Valve 1
#define Valve2 3 // Valve 2
#define Valve3 4 // Valve 3
#define Valve4 5 // Valve 4

bool switch_high(void *) {
//Serial.println(*onFor);

previous = millis();
// PWM1
if (onFor[0] > 0) {
digitalWrite(Valve1, 1); // Switch to high
}
if (onFor[0] < period) {
timer.in(onFor[0], switch_low1);
}

// PWM2
if (onFor[1] > 0) {
digitalWrite(Valve2, 1); // Switch to high
}
if (onFor[1] < period) {
timer.in(onFor[1], switch_low2);
}

// PWM3
if (onFor[2] > 0) {
digitalWrite(Valve3, 1); // Switch to high
}
if (onFor[2] < period) {
timer.in(onFor[2], switch_low3);
}

// PWM4
if (onFor[3] > 0) {
digitalWrite(Valve4, 1); // Switch to high
}
if (onFor[3] < period) {
timer.in(onFor[3], switch_low4);
}

// Serial.print(onFor[0]); Serial.print(";");
// Serial.print(onFor[1]); Serial.print(";");
// Serial.print(onFor[2]); Serial.print(";");
// Serial.print(onFor[3]); Serial.println();;
//Serial.print(period); Serial.println();;
return true;
}

bool switch_low1(void *) {
// Serial.print(millis()-previous);Serial.print(";");
digitalWrite(Valve1, 0); // Switch to low
return false;
}

bool switch_low2(void *) {
// Serial.print(millis()-previous);Serial.print(";");
digitalWrite(Valve2, 0); // Switch to low
return false;
}

bool switch_low3(void *) {
// Serial.print(millis()-previous);Serial.print(";");
digitalWrite(Valve3, 0); // Switch to low
return false;
}

bool switch_low4(void *) {
Serial.print(onFor[3]);Serial.print(";");
Serial.print(millis()-previous);Serial.println();
digitalWrite(Valve4, 0); // Switch to low
return false;
}

void setup() {
pinMode(Valve1, OUTPUT); // set Valve1 pin to OUTPUT
pinMode(Valve2, OUTPUT); // set Valve2 pin to OUTPUT
pinMode(Valve3, OUTPUT); // set Valve3 pin to OUTPUT
pinMode(Valve4, OUTPUT); // set Valve4 pin to OUTPUT

digitalWrite(Valve1, 0); // Switch to low
digitalWrite(Valve2, 0); // Switch to low
digitalWrite(Valve3, 0); // Switch to low
digitalWrite(Valve4, 0); // Switch to low

frequency = 100;
period = 1000 / frequency;
Serial.begin(9600);

onFor[0] = 0;
onFor[1] = 0;
onFor[2] = 0;
onFor[3] = 0;

timer.every(period, switch_high);
}

void loop()
{
//int sensorValue = analogRead(A5); // Range is 0 to 1023
//float dutyCycle = sensorValue*100.0 / 1023.0;
float dutyCycle[] = { 98, 0, 0, 98 };
onFor[0] = period * (dutyCycle[0] / 100.0);
onFor[1] = period * (dutyCycle[1] / 100.0);
onFor[2] = period * (dutyCycle[2] / 100.0);
onFor[3] = period * (dutyCycle[3] / 100.0);
timer.tick(); // tick the timer
}`

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions