Hi Tom--
Here's what I have so far. I hope it is enough to use to get your hardware set up.
I've put some of the code into functions, used the new pin numbers, coded for the toggled switch presets. I have not coded anything with the charge pulses, Timer2, and how the charge pulses coordinate with the bipolar pulses.
I am using a much improved library for the i2c lcd. It's called hd44780 and is available through the library manager for download. It is auto configuring for the i2c address and the configuration of the driver pins. It is faster, and lets you change out display without having to figure out if it's any different from the previous one. Use these magic words at the head of the sketch.
#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
I've used a 16x2 with lcd.begin(16,2) in setup and you will need lcd.begin(20,4), and can adjust the the display code for what you want to show.
As before, I'm uncertain about how you want to present the time delay from the trigger pulse to the delayed response from the module. Delay/ Advance?
Let me know if this appears to be headed in the right direction.
//V1.0 set RPM potentiometer/configuration swtiches/hd44780 lcd/revised pin numbers
#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
//utility definitions
#define positive HIGH
#define negative LOW
#define firstPulse 0
#define secondPulse 1
//You can use pots to set RPM, pulseWidthDegrees, and barWidth
unsigned int RPM = 1200;//adjusted with potementiometer
unsigned int pulseWidthDegrees = 10;
unsigned int barWidthDegrees = 60;
int pickupPositionOffset = 0; //timing offset from TDC
unsigned long pulseWidthTime;//degrees converted to time
unsigned long timerTopValue;//sets 360 degree cycleTime
unsigned int timerTicksPerDegree;
//output pins
const byte chargePin = 7; //charge pulses
const byte pinB = 8; //to DAC pin 5
const byte pinA = 9; //to DAC pin 6 - 12, called 6
//configuration switch setup
const byte polaritySwitch = 4;
boolean firstPulsePos = positive; //first pulse polarity
const byte setFallingSwitch = 5;
char risefall = 'R'; //default rising mode start timing from rising edge
const byte setChargePulseSwitch = 6;
boolean chargePulse = false ; //AC CDI default is DC
const byte pot1 = A3; //input pin for pot which sets rpm
//return pulse interrupt variables
volatile boolean trigger = false;
volatile boolean interruptFlag;
volatile unsigned long delayPeriod;
unsigned long copy_delayPeriod;
volatile unsigned long delayPeriodStart;
float delayDegrees; // changed from int to float for decimal place display
void setup()
{
Serial.begin(115200);
//set outputs for 0v
pinMode(13, OUTPUT); //telltale led
digitalWrite(13, LOW);
pinMode(pinA, OUTPUT);
digitalWrite(pinA, LOW); //DAC 6 LOW
pinMode(pinB, OUTPUT);
digitalWrite(pinB, HIGH); //DAC 5 HIGH
pinMode(3, INPUT_PULLUP); //interrupt pin, return pulse drives low
pinMode(chargePin, OUTPUT); // declare the chargePin as an OUTPUT
// initialize LCD with number of columns and rows:
lcd.begin(16, 2);
lcd.setCursor(0, 0); // lcd display setup of unchanging headings
lcd.print("RPM:"); // print fixed characters
lcd.setCursor(9, 0);
lcd.print("Mode:");
lcd.setCursor(0, 1);
lcd.print("1stPulse:"); //first pulse + or -
lcd.setCursor(11, 1);
lcd.print("CP:"); //charge pulse AC CDI Y or N
setupTimer1();
setupSwitchPresets();
//15000000 timerTicksperMinute at 4 us per tick with prescaler 64
//timerTopValue = 12500 at 1200 RPM 50ms per revolution
timerTopValue = 15000000UL / RPM;
timerTicksPerDegree = timerTopValue / 360;
pulseWidthTime = pulseWidthDegrees * timerTicksPerDegree;
TCNT1 = 0;
OCR1B = pulseWidthTime;//timer ticks
attachInterrupt(digitalPinToInterrupt(3), delayPeriodTiming, FALLING);
delay(5000);//display setup parameters
lcd.setCursor(0, 1);
lcd.print("DelayDeg:");
}
void loop()
{
const unsigned long analogReadInterval = 250;//250; //read pots and map
static unsigned long lastAnalogRead = 0;
if (millis() - lastAnalogRead >= analogReadInterval)
{
//add other potentiometer adjustments here
lastAnalogRead += analogReadInterval;
RPM = map(analogRead(pot1), 0, 1023, 500, 4000);
//adjust timer values for RPM
timerTopValue = 15000000UL / RPM;
timerTicksPerDegree = timerTopValue / 360;
pulseWidthTime = pulseWidthDegrees * timerTicksPerDegree;
OCR1B = pulseWidthTime;
lcd.setCursor(4, 0);
lcd.print(" "); // print blank spaces to clear old data
lcd.setCursor(5, 0);
lcd.print(RPM);
lcd.setCursor(9, 1);
lcd.print(" ");
lcd.setCursor(10, 1);
lcd.print(delayDegrees);
}
if (trigger == true && interruptFlag == true )
{
trigger = false;
interruptFlag = false;
noInterrupts();
copy_delayPeriod = delayPeriod;//microseconds
interrupts();
//Serial.print(copy_delayPeriod);
//Serial.print('\t');
//divide by 4 to convert microseconds to timer ticks
delayDegrees = (copy_delayPeriod / 4) / timerTicksPerDegree;
//Serial.println(delayDegrees);
//delayDegrees = pickup - (360.0 * (copy_delayPeriod) / (timerTopValue * 4.0)); //for decimal place in deg display.
}
}
void setupTimer1()
{
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
//set Timer1 mode Fast PWM to ICR1
TCCR1B |= (1 << WGM13) | (1 << WGM12);
TCCR1A |= (1 << WGM11);
//start Timer apply prescaler
// TCCR1B |= (1 << CS12) | (1 << CS10); //1024 for led test 8us tick
TCCR1B |= (1 << CS11) | (1 << CS10); //64 for .5 us tick
//enable B OutputCompare and Overflow interrupts
TIMSK1 |= (1 << OCIE1B) | (1 << TOIE1);
}
ISR(TIMER1_OVF_vect)
{
//alternate ICR1 values to generate two outputs over 360 degrees
//360 degree cycle time broken into two pieces
//timerTopValue adjusted with RPM pot
//timerTicksPerDegree = timerTopValue / 360; //gets new value to update ICR1
static byte pulse = firstPulse;
if (pulse == firstPulse)
{
ICR1 = timerTicksPerDegree * (pulseWidthDegrees + barWidthDegrees); //first pulse and bar width
digitalWrite(13, HIGH);
if (firstPulsePos == true)
setPulse(positive);
else
setPulse(negative);
//set timing start at lead edge of first pulse
if (risefall == 'R')
{
delayPeriodStart = micros(); //start looking for response as pulse rises
trigger = true;
}
else //risefall == 'F' set timing at trailing edge of first pulse
{
//convert pulseWidthTime in timer ticks to microseconds
//prescaler 8 = 4us/timer tick
delayPeriodStart = micros() + pulseWidthTime * 4; //start looking for response as pulse rises
trigger = true;
}
pulse = secondPulse; //next pulse
}
else //second pulse
{
ICR1 = timerTicksPerDegree * (360 - (pulseWidthDegrees + barWidthDegrees)); //second pulse and dead band
digitalWrite(13, HIGH);
if (firstPulsePos)
setPulse(negative);
else
setPulse(positive);
pulse = firstPulse; //next pulse
}
}
ISR(TIMER1_COMPB_vect) {
digitalWrite(13, LOW); //turn off pulse for 0 volt
digitalWrite(pinA, LOW); //DAC 6 LOW
digitalWrite(pinB, HIGH); //DAC 5 HIGH
}
void setPulse(byte state) //state negative = LOW state positive = HIGH
{
digitalWrite(pinA, state ); //DAC 6 state
digitalWrite(pinB, state); //DAC 5 state
}
void setupSwitchPresets()
{
pinMode(setChargePulseSwitch, INPUT_PULLUP);
if (digitalRead(setChargePulseSwitch) == LOW)
chargePulse = true; //AC CDI
else
chargePulse = false;
lcd.setCursor(14, 1);
if (chargePulse)
lcd.print("Y");
else
lcd.print("N");
pinMode(polaritySwitch, INPUT_PULLUP);
if (digitalRead(polaritySwitch) == HIGH)
firstPulsePos = true; //first pulse positive
else
firstPulsePos = false; //first pulse negative
lcd.setCursor(9, 1);
if (firstPulsePos)
lcd.print("+");
else
lcd.print("-");
pinMode (setFallingSwitch, INPUT_PULLUP); //check for a LOW input to indicate switch is closed to ground
if (digitalRead(setFallingSwitch) == LOW) //set Falling
{
risefall = 'F';
}
else
{
risefall = 'R';
}
lcd.setCursor(14, 0);
lcd.print(risefall);
}
void delayPeriodTiming()
{
delayPeriod = micros() - delayPeriodStart;
interruptFlag = true;
}