Just to be sure I didn't post a wrong sketch, But what happens is that I get 4 or 5 pulses from D4 when D6 is high. This happens when I reset or do a cold start and looking with scope.
// replaced on 7/22/18 mod on 4/18/2019 changed to go simple transformer control of pos / neg trigger
// update 7/14/2017 added correct math and setting for position of pickup
// revision 10 10/28/2016 adds charging pulse with Timer 2
// lowest RPM = 615 with charge pulse to keep OCR2A <= 255
// CDI Tester Pulse Generator Serial Output Arduino Code
// 8/17 added code for pulse out width
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config display for hd44780 chip
int pot1 = A1; // select the input pin for the pot for rpm
int pot2 = A2; // select the input pin for the pot for pickup location in degrees
// int pot3 = A3; // select the input pin for the pot for length of bar on flywheel in degrees
int potValue = 0; // variable to store the value coming from the sensor
int pickupValue = 0; // position of pickup in degrees
int potWidth = 0; // variable to set length of bar on flywheel
int timerTopValue = 12500; // changed from timerTopValue = 0
int outputPin = 4; // select the pin for the output for trigger pulse, changed from 8
int chargePin = 7; // select the pin for the output for charge pulses
volatile boolean trigger = false;
volatile unsigned long delayPeriod;
unsigned long copy_delayPeriod;
volatile unsigned long delayPeriodStart;
float delayDegrees; // changed from int to float for decimal place display
int RPM;
int pickup;
// int barLength;
int pulseWidth;
volatile boolean interruptFlag;
unsigned long analogReadInterval = 500; // read pots and map
unsigned long lastAnalogRead;
// const byte setFallingSwitch = 5;
// char risefall = 'R'; // default rising mode
const byte setChargePulseSwitch = 6;
boolean chargePulse = false ; // default dc powered mode
volatile byte timeSliceCount = 0; // TDC 0 degrees
void setup() {
// Serial.begin(115200);
// Serial.println("starting...");
lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines, turn on backlight
lcd.setCursor(1, 0); // lcd display setup of unchanging headings
lcd.print("RPM:"); // print fixed characters
lcd.setCursor(12, 0);
lcd.print("Deg");
lcd.setCursor(1, 1);
lcd.print("Pos:");
// lcd.setCursor(12, 1);
// lcd.print("Bar:");
lcd.setCursor(1, 2);
lcd.print("Us Delay:");
lcd.setCursor(1, 3);
lcd.print("Deg Advance:");
pinMode(outputPin, OUTPUT); // declare the outputPin as an OUTPUT
pinMode(chargePin, OUTPUT); // declare the chargePin as an OUTPUT
// pinMode (setFallingSwitch, INPUT_PULLUP); // check for a LOW input to indicate switch is closed to ground
pinMode(setChargePulseSwitch, INPUT_PULLUP);
if (digitalRead(setChargePulseSwitch) == LOW)
chargePulse = true; // AC CDI
// Timer1 default set up .5ms trigger pulse every 50 ms
TCCR1A = 0;
TCCR1B = (1 << WGM12); // CTC mode to OCR1A
OCR1A = timerTopValue;
TIMSK1 |= (1 << OCIE1A); // interrupt enable compareA
TIMSK1 |= (1 << OCIE1B); // interrupt enable compareB
OCR1B = 500; // sets trigger pulse width, 500 = 2Ms, 250 = 1Ms, 125 = .5Ms, set to 1250 for 5013 *********************************************
TCCR1B |= (1 << CS11) | (1 << CS10); // prescaler 64 4us/tick
// Timer2 default setup charge pulse 12 periods 30 degrees each; only 5 get turned on
// charge pulse timing interval = Timer1 trigger period/12 = timerTopValue/96
TCCR2A = 0;
TCCR2B = 0;
TCCR2A = 1 << WGM20; // lsb of mode 7 pwm to OCR2A
TCCR2B = 1 << WGM22; // msb of mode 7 pwm to OCR2A;
OCR2A = timerTopValue / 96; // 96 = 12*4*2 (#periods, prescaler difference, up/down timer mode )
TIMSK2 = 0;
TIMSK2 = 1 << TOIE2; // enable overflow interrupt
// actually start timer in ISR(TIMER1_COMPA_vect
// to prevent out of sync charge pulse, no prescaler set here
attachInterrupt(digitalPinToInterrupt(3), delayPeriodTiming, FALLING);
}
void loop()
{
if (millis() - lastAnalogRead >= analogReadInterval)
{
lastAnalogRead += analogReadInterval;
potValue = analogRead(pot1); // rpm
pickupValue = analogRead(pot2); // pickup position
// barLength = analogRead(pot3); // length of bar for pickup
// Timer2 OCR2A requires max value 255 => 615 lowest RPM
if (chargePulse)
{
RPM = map(potValue, 0, 1023, 615, 10000);
pickup = map(pickupValue, 0, 1023, 10, 75); // so advance will read based on delay, 57 for yamaha 350 2 pu, 74 for 1 pu, 72 for tw200, 25 for 5013
pulseWidth = (60000000/RPM)/360; // time for 1° in uS
// barSize = map(barLength, 0, 1023, 10, 60); // 10 for yamaha 350 2 pu, 60 for 1 pu, 60 for tw200
// RPM = 615; // for my serial test purposes 615-3800
}
else
{
RPM = map(potValue, 0, 1023, 500, 3800);
pickupValue = map(pickupValue, 0, 1023, 0, 50); // to set position of pickup so advance will read
// pulseWidth = map(barLength, 0, 1023, 71, 44); // add Width to non charging case
// RPM = 500; // for my serial test purposes 500-3800
}
timerTopValue = 15000000UL / RPM;
OCR1B = pulseWidth;
// if (digitalRead(setFallingSwitch) == LOW) // set Falling
// {
// risefall = 'F';
// }
// else
// {
// risefall = 'R';
// }
lcd.setCursor(6, 0);
lcd.print(" "); // print blank spaces to clear old data
lcd.setCursor(6, 0);
lcd.print(RPM); // print rpm
lcd.setCursor(16, 0);
lcd.print(" ");
lcd.setCursor(16, 0);
lcd.print(pulseWidth, 1); // print us per degree
lcd.setCursor(6, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
lcd.print(pickup); // print pickup coil position
// lcd.setCursor(16, 1);
// lcd.print(" ");
// lcd.setCursor(16, 1);
// lcd.print(barLength); // length of bar
lcd.setCursor(11, 2);
lcd.print(" ");
lcd.setCursor(11, 2);
lcd.print(copy_delayPeriod);
lcd.setCursor(14, 3);
lcd.print(" ");
lcd.setCursor(14, 3);
lcd.print(delayDegrees, 1); // delayDegrees, 1);
}
if (trigger == true && interruptFlag == true )
{
trigger = false;
interruptFlag = false;
noInterrupts();
copy_delayPeriod = delayPeriod;
interrupts();
delayDegrees = pickup - (360.0 * (copy_delayPeriod) / (timerTopValue * 4.0)); // for decimal place in deg display.
// degreesAdvance = pickupValue - delayDegrees; // added
}
}
ISR(TIMER1_COMPA_vect) {
OCR1A = (timerTopValue); // value to set delay between pulses to trigger cdi
digitalWrite(chargePin, LOW); // guarantee off charge pin at trigger
digitalWrite(outputPin, HIGH); // turn on pin trigger
// if (risefall == 'R') // switch not set; default Rising trigger
{
delayPeriodStart = micros(); // start looking for response as pulse rises
trigger = true;
}
// start Timer 2 for charge pulses
if (chargePulse)
{
timeSliceCount = 0;
TCNT2 = 0;
OCR2A = timerTopValue/96; // set 12 periods
TCCR2B |= 1 << CS22 | 1 << CS21; //prescaleer 256 16us/tick
}
}
ISR(TIMER1_COMPB_vect) {
digitalWrite(outputPin, LOW);
// if (risefall == 'F') // switch set for Falling trigger
{
delayPeriodStart = micros(); // start looking for response as pulse falls
trigger = true;
}
}
void delayPeriodTiming()
{
delayPeriod = micros() - delayPeriodStart;
interruptFlag = true;
}
ISR(TIMER2_OVF_vect)
// 5 pulses of 30 degrees starting at 60 degrees
// ON at 60,120,180,240,300 = 2,4,6,8,10
// OFF at 90,150,210,270,330 = 3,5,7,9,11
{
if (timeSliceCount != 0 && timeSliceCount % 2 == 0)
{
digitalWrite (chargePin, HIGH);
}
else // if (timeSliceCount == 0 || timeSliceCount % 2 == 1)
{
digitalWrite(chargePin, LOW);
}
timeSliceCount++;
if (timeSliceCount == 12)
{
timeSliceCount = 0;
// stop Timer2 by clearing prescaler bits
TCCR2B &= ~1<< CS22;
TCCR2B &= ~1<< CS21;
}
}