I am trying to get an interrupt that happens once every 5sec to alter the output of a PWM port. In the main loop the PWM is set to some value that is read from a POT. What I want is that if I set the PWM output to 50% continuously, but every 5 seconds the PWM goes to 100% output for 300ms then goes back to the POT value 50%. It keeps doing it as long as it is powered. The current code does not work as I want. Seems the ISR can't do heavy lifting like set a pin or alter the PWM 50% to 100%. So I tried whatever popped into my mind. Switch cases, if then....passing flags. I just can't get what I described above to work. I would appreciate any help.
I have an add on for later, it will have a SDcard logging feature but will worry about that later.
Thanks! Nick
#include <TimerOne.h>
// The code below allows the user to set the Preload current, Surge current and cycle time. This controls a dynamic motor brake platform to simulate motor momentary stall conditions
// In normal operation the arduino generates a PWM steady state output, the ISR comes through periodically and generates a new current draw for a window of time then returning back to the preload current PWM setting.
//
const int Drive = 6;
int SurgeFlag = 0;
int voltage;
void setup(void)
{
pinMode(Drive, OUTPUT);
Timer1.initialize(3000000);
Timer1.attachInterrupt(Surge);
Serial.begin(9600);
}
// The interrupt will send a surge current 255 value to PWM. The surge frequency is controlled by the interrupt Timer1.initialize()
void Surge(void)
{
SurgeFlag = SurgeFlag + 1;
}
// The main program will read ADC value and set PWM for preload current
void loop(void)
{
noInterrupts();
voltage = analogRead(A0); // ADC reads 0 - 1023
voltage = voltage/4; // scale ADC 0 - 255 to set min/max PWM range
analogWrite(Drive, voltage);
interrupts();
if (SurgeFlag == 1) {
digitalWrite(6, HIGH);
SurgeFlag = 0;
delay(2000);
}
}
Variables shared with interrupt routines must be declared volatile. Furthermore, multibyte shared variables must be protected from corruption, when accessed by the main program, as follows:
noInterrupts();
int surge_copy = SurgeFlag;
interrupts();
...
if (surge_copy == 1) {
Use an 8 bit variable to avoid the above, if possible.
There is no need to disable interrupts for the analog read/write.
Hi, I am interested in using the millis. I am trying my logic to work as following:
running all the time PWM A0- 10k pot set to 30%, every 2000ms I set the PWM to 100% for 300ms, then back to 30% in a loop. I have tried a lot of things and now my code is gibberish, scrapping it to start all over.
I like that Millis lets you drop through to the main C loop and not locked into a routine until finished. It will make saving the data to SD easy. I just can't wrap my head around how to use Millis for the timing described above. I would appreciate help with it.
PS:
Hi,
Oops Sorry @macgman2000 it was a typo.
please correct:
unsigned long myTime1 = 0;
unsigned long myTime2 = 0;
// The code below allows the user to set the Preload current, Surge current and cycle time. This controls a dynamic motor brake platform to simulate motor momentary stall conditions
// In normal operation the arduino generates a PWM steady state output, the ISR comes through periodically and generates a new current draw for a window of time then returning back to the preload current PWM setting.
//
const int Drive = 6;
int voltage;
unsigned long myTime1 = 0;
unsigned long myTime2 = 0;
//------------------------------------------------------------------
void setup(void)
{
pinMode(Drive, OUTPUT);
Serial.begin(9600);
myTime2 = millis();
}
//------------------------------------------------------------------
// The main program will read ADC value and set PWM for preload current
void loop(void)
{
voltage = analogRead(A0); // ADC reads 0 - 1023
voltage = voltage / 4; // scale ADC 0 - 255 to set min/max PWM range
analogWrite(Drive, voltage);
if (millis() - myTime2 >= 5000) // If past 5 seg
{
myTime1 = millis(); // Init mytime1
while (millis() - myTime1 < 300) // While myTime1 < 300 ms
{
analogWrite(Drive, 255); // PWM max
}
myTime2 = millis(); // Init mytime2
}
}
Very weird problem came up. This only works for 4 or 5 passes through the inner 300ms loop then stops. The only thing responsive is A0 connected to a pot, I can vary it and it changes PWM output. Otherwise the 300ms stops executing the while loop.