Hello everyone,
I'm using an Arduino Mega 2560 to create a trigger sequence with Timer4.
The interrupt generated by Timer4 will be used to start a PWM waveform, count the number of pulses, stop the PWM when a certain number of pulses have been generated, restart PWM on the next interrupt cycle.
The PWM pin is connected to an optocoupler that will go to an external device; the opto I'm using is a HCPL-0201 (Datasheet link) but I don't think it the cause of my problem.
Basically the problem is the PWM not restarting properly with the Timer4 interrupt and I'm getting a reduced pulse width with the first pulse generated.
The last pulse of the PWM sequence is also shortened, which is not what I want either.
Inverting the PWM and reducing the duty cycle to around 128 kinda works to get what I want, but feels like a bad workaround.
What I want to know is how do I reset the PWM state to get the ideal output shown in the 3rd, badly photoshopped, image.
Thanks in advance for your help!
Images attached are screen captures of my scope readout.
Link to images ( https://imgur.com/a/DElZj )
And my code is here:
#include <PinDefs.h> //contains list of pins to use, only kSyncPin = 12 is of interest here
#include <avr/io.h>
#include <TimerOne.h>
#include <TimerFour.h>
#include <DigitalPin.h>
byte resEnable = 1;
byte resStop = 0;
volatile boolean resFlag = 0;
unsigned long V1Time, V2Time;
const unsigned long syncPulsePeriod = 33333UL;
volatile unsigned long syncPulseCount = 0;
unsigned long syncPulseCountLimit = 18;
void inspirationIsr()
{
//Inspiration cycle done, switch to exp
//Serial.println("Inspiration ISR");
if ( resFlag == 0 )
{
fastDigitalWrite(kMuxLine[ 1 ], LOW);
fastDigitalWrite(kMuxLine[ 0 ], HIGH);
Timer4.setPeriod( V1Time);
Timer1.pwm(kSyncPin, 512);
Timer1.restart();
resFlag = 1;
}
else if ( resFlag == 1 )
{
fastDigitalWrite(kMuxLine[ 1 ], HIGH);
fastDigitalWrite(kMuxLine[ 0 ], LOW);
Timer4.setPeriod( V2Time);
resFlag = 0;
}
}
void syncIsr ()
{
syncPulseCount++;
if ( syncPulseCount >= syncPulseCountLimit )
{
//enough pulses have been produced, so stop pulse generation
syncPulseCount = 0;
Timer1.disablePwm(kSyncPin);
Timer1.stop();
}
}
void setup() {
//pinmode setup for spi devices on a bus
for ( byte slave = 0; slave < kNumSlaveSelects; ++slave )
{
// set slave select pins as output
pinMode( kSlaveSelect[ slave ], OUTPUT);
// make sure other devices are unselected (pin is HIGH) and setup spi
fastDigitalWrite( kSlaveSelect[ slave ], HIGH) ;
}
for ( byte mux = 0; mux < kNumMuxLines; ++mux )
{
//set mux selects as outputs
pinMode(kMuxLine[ mux ], OUTPUT);
//make sure mux selects are held LOW
fastDigitalWrite( kMuxLine[ mux ], LOW);
}
// end pinmode setup for spi devices on a bus
pinMode(kSyncPin, OUTPUT); //pin 12
V1Time = 300000UL;
V2Time = 300000UL;
noInterrupts();
Timer4.initialize( V1Time);
Timer4.attachInterrupt( inspirationIsr );
Timer4.start();
Timer1.initialize ( syncPulsePeriod );
Timer1.stop();
Timer1.attachInterrupt( syncIsr );
Timer1.pwm(kSyncPin, 512);
//TCCR1A |= _BV(COM1B0); //to set up inverted PWM
interrupts();
Serial.begin(19200);
Serial.println("Setup complete");
}
void loop()
{
}