I am using a nice little Arduino pro mini to run this code, and I have one problem with it.
The code generates trains of pulses, in this case 6 at a time, 200µS long, and with 1530 µS inbetween them.
The program has 2 sections, one calles "oneShot". I have no problem with that one.
The other is called "ranDom", and in that one I have a problem with an "IF" statement which gets ignored.
The "IF" statement is related to a millis timer, which takes it's time limit from a random generator which runs previous to the "IF" statement.
When I try to create a break in the pulse trains with the "IF" statement I get no break, but if I use the random delay number from the random generator (at present between 300mS and 2000mS) in a simple "delay ();" then the program pauses as it should, and resumes afterwards.
I have no problem with the short microseconds delays, but would like to recoup the long milliseconds delays for future tasks, should they arise. (Or just because long delays are bad practice.)
*ranDom() is in line 37 - 67 and the problematic "IF" statement is in line 62, commented out here to show how the program functions well with the "delay" instead.
#include <digitalWriteFast.h>
int outpulse = 100;
int burstPulses = 6; // microseconds of burstlength
int pulseLength = 200; // microseconds of on-time
int OffTime = 1530; // microseconds of off-time ( 100BPS = 10000, 500BPS = 2000, 600BPS = 1530 )
int Frequency_Value = 1000; // baseret på 1 sec mellem lynene, -randomisering
int Random_Frequency_Value;
unsigned long currentMicros = 0;
unsigned long previousMicros = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
const byte interruptPin2 = 2; // modtager signal til one shot
const byte interruptPin3 = 3; // modtager signal til random
void setup()
{
Serial.begin(9600);
pinMode(9, OUTPUT); //til sync output pulse
pinMode(12, OUTPUT); //til coil 1 Fiberled
attachInterrupt(digitalPinToInterrupt(interruptPin2), oneShotISP, RISING);
attachInterrupt(digitalPinToInterrupt(interruptPin3), ranDomISP, RISING);
}
void loop()
{}
void ranDomISP()
{
previousMillis = millis();
ranDom();
}
void ranDom()
{
for (int h = 1; h = 1; )
{
digitalWrite (9, HIGH);
delayMicroseconds (outpulse);
digitalWrite (9, LOW);
for (int i = 1; i <= burstPulses; i++)
{
cli(); //disabler interrupts for mindre jitter
digitalWriteFast (12, HIGH); //sets pin12 HIGH
delayMicroseconds(pulseLength); // pulselength
digitalWriteFast (12, LOW);
sei(); // interrupts tilbage så klokken kører igen
delayMicroseconds (OffTime); // Offtime
}
randomSeed( analogRead(4) + analogRead(5) + analogRead(8) + analogRead(10) + analogRead(11) );
Random_Frequency_Value = random ((0.3 * Frequency_Value), (2 * Frequency_Value));
delay (Random_Frequency_Value);
currentMillis = millis();
//if (currentMillis - previousMillis >= Random_Frequency_Value)
{
previousMillis = currentMillis;
}
}
}
void oneShotISP()
{
oneShot();
}
void oneShot()
{
digitalWrite (9, HIGH);
delayMicroseconds (outpulse);
digitalWrite (9, LOW);
for (int i = 1; i <= burstPulses; i++)
{
cli(); //disabler interrupts for mindre jitter
digitalWriteFast (12, HIGH); //sets pin12 HIGH
delayMicroseconds(pulseLength); // pulselength
digitalWriteFast (12, LOW);
sei(); // interrupts tilbage så klokken kører igen
delayMicroseconds (OffTime); // Offtime
}
}
You should not be delaying in an ISR. In general, millis() does not increment during an ISR. Also, you should NOT be spending milliseconds in an ISR anyhow! The processor has other work to do (like incrementing the millis() counter).
Is there a time constraint regarding the time from when pin 2 or pin 3 goes HIGH and when the pulse train should begin? You may not need interrupts at all.
AS I see it, the interrupt is related to the isp.
as soon as this isp pointe the processor to the void ranDom it is executing an ordinary program, and nit an ISP or ISR.
But I may be wrong...
perhape, but I only execute the isp one time, per day, then the program runs for the remaining hours of the day. Shut down in the evening, and restart in the morning.
At that point the code has not returned from the ISR so the rules as to what you can/can't do in an ISR still apply wether or not you call another function
Interrupts are not for elegance. They are for events that require low latency responses. For example, pulling data off a buffer before it gets overwritten. If you needed a quick response in this application you would probably want to chain timer events in order to generate the pulse train. If not, I would just do it in loop().
void ranDomISP()
{
ranDom();
}
It is invoked by the interrupt that is called when pin
3 is pulled high.
As you see, it is short and sweet, as it should be.
You also see that it hands the processor over to theprogram: (which unfortunately will not format correctly here, the first 8 lines)
void ranDom()
{
for (int h = 1; h = 1; )
{
digitalWrite (9, HIGH);
delayMicroseconds (outpulse);
digitalWrite (9, LOW);
for (int i = 1; i <= burstPulses; i++)
{
cli(); //disabler interrupts for mindre jitter
digitalWriteFast (12, HIGH); //sets pin12 HIGH
delayMicroseconds(pulseLength); // pulselength
digitalWriteFast (12, LOW);
sei(); // interrupts tilbage så klokken kører igen
delayMicroseconds (OffTime); // Offtime
}
randomSeed( analogRead(4) + analogRead(5) + analogRead(8) + analogRead(10) + analogRead(11) );
Random_Frequency_Value = random ((0.3 * Frequency_Value), (2 * Frequency_Value));
delay (Random_Frequency_Value);
}
}
This program contains a long milliseconds delay, the actual length being calculated in the random function, and which is between 300 and 2000 milliseconds.
The processor calculates this delay, and ececutes it flawlessly, does this not mean that as soon as the ISR has executed, the processot is back to normal, and fully recovered from whatever constraints the interrupt imposed upon it?
The important thing to remember is that the interrupt isn't over until after ranDom() returns
(The compiler may even have inclined ranDom() !)
Your code tags need some work.
No it is not short. Remove the call to ranDom() and replace it with the contents of of the ranDom() function. Is it short then? NO! You have a delay that could be up to 2 seconds! In an ISR!