Hi, I have done some testing and here is my revision of the code. Pins 6, 5, 4 do not update, require a reboot, how to have them reset parameters when they are changed?
No charge pulses on pin 7.
LCD would not work until I moved the code from line 248 to 129 and from 259 to 123
Tom
//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
int 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
int RPM;
int pickup;
int barWidth;
int pulseWidth;
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(20, 4); // initialize the lcd for 20 chars 4 lines, turn on backlight
lcd.setCursor(0, 0); // lcd display setup of unchanging headings
lcd.print("RPM:"); // print fixed characters
lcd.setCursor(9, 0);
lcd.print("Mode:"); //to display code choice R or F
lcd.setCursor(1, 1);
lcd.print("Pos:");
lcd.setCursor(9, 1);
lcd.print("Width:");
lcd.setCursor(1, 2);
lcd.print("Us Delay:");
lcd.setCursor(1, 3);
lcd.print("Deg Advance:");
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(4, 0);
lcd.print(RPM);
lcd.setCursor(14, 0);
lcd.print(" ");
lcd.setCursor(14, 0);
lcd.print(risefall); //print R or F at upper right side
lcd.setCursor(16, 0);
if (firstPulsePos)
lcd.print("+");
else
lcd.print("-");
lcd.setCursor(18, 0);
if (chargePulse)
lcd.print("AC");
else
lcd.print("DC");
lcd.setCursor(6, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
lcd.print(pickup);
lcd.setCursor(16, 1);
lcd.print(" ");
lcd.setCursor(16, 1);
lcd.print(pulseWidth);
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;//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(19, 0); //moved to line 129
//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(17, 0); // moved to line 123
//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;
}