Larry - yes I did mean what I wrote. I want LSnovolt to remain unchanged regardless of the state of LSstartnxt
UK Helibob
Here you go
// ---
// Leadscrew Motor Startup Test on Mega2560 board
// 10 Aug 2021 fixed line 144 needs strcopy() God knows why
// Simple test of Starting Leadscrew Motor.
// Run Motor at full power until Startpulses received then swap to demand power.
// Demand set with simple pot for now.
//
// Uses 4 * 20 LCD for communication
// LiquidCrystal_I2C.h: https://github.com/johnrickman/LiquidCrystal_I2C
#include <Wire.h> // Library for I2C communication
#include <LiquidCrystal_I2C.h> // Library for LCD
// Wiring: SDA pin is connected to SDA (20) and SCL pin to SCL(21).
// Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered)
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4); // Change to (0x27,16,2) for 16x2 LCD.
// Motor wiring. Red =12v, Black = Gnd connect to arduino ground
// White is change direction. Manual for now. Turn power off before grounding(?)
// Blue is PWC output to motor control connect to Arduino pin 5
volatile byte LSmotorpin = 5;
//yellow is FG pulse signal - use Timer 5 via pin 47
byte FGpulsepin = 47;
// No of pulses at full power to start up motor ( 9 pulses/rev of motor)
int Startpulses = 175;
//Speed input via Pot slider connects to pin A0
const int LSSpeedInPin = A0; //Speed input potentiometer pin
int potvalue = 0; //input value read
//variables for timing loop
unsigned long Loopmillisecond; //milisecond store for last time loop ran
int Loopwait = 500; //length of wait between refreshes (every half second)
//Basic variables for Leadscrew speed measurement
volatile unsigned long LSlastmillisec = 0; //value of millisec last time counter cleared
unsigned long LSthismillisec = 0; //new value of milisec
int t5count = 0; //number of pulses counted since LSlastmillisec
float lsrpm = 0; //Leadscrew rpm figure
float LSelapsed = 0; //for floating point calculation
char lsrpmstring[6] = "000.0";
//Control variables for Leadscrew Power
int LSsetpoint = 0; //Lead Screw Set point
int LStarget = 0; //Lead screw operator target
volatile byte LSpowervalue = 0; //Lead Screw PWM Power out
volatile byte LSRunpower = 0; //remember Powervalue for interrupt
volatile byte LSKickvalue = 180; //startup value for initial kick
bool LSstartnxt = true; //flag to initiate start sequence
volatile bool LSstarting = false; //flag set when motor is in start phase
// Includes Run/Stop/Novolt code
// Leadscrew Run Stop variables
byte LSrunpin = 2; //switch short to ground for RUN O/C for Stop
bool LSrunstate = false;
bool LSnovolt = false; //stays false until switch goes to stop
char LSrunstring[5] = "Stop"; //string for Run/Stop status
//debugging
char runstop[5] = "stop"; //for debug
int temp=0; //for debug
//Output Array for Display
char line0[21];
char line1[21];
char line2[21];
char line3[21];
// Update display routine
void updatedisplay() {
lcd.setCursor(0,0);
lcd.print(line0);
lcd.setCursor(0,1);
lcd.print(line2);
lcd.setCursor(0,2);
lcd.print(line1);
lcd.setCursor(0,3);
lcd.print(line3);
}
// Interrupt service routine for timer 5 overflow at leadscrew start goes here <----------
//Uses Timer 5 with OCR5A as TOP //this needs work
//Initialised when Leadscrew Run/Stop goes to Run
//Reset leadscrew motor and speed counter to count mode (Clear bit 3 in TCCR5B)
ISR(TIMER5_COMPA_vect)
{
LSstarting = false; //reset the starting status
LSpowervalue = LSRunpower; //reset power value to target
OCR3A = LSpowervalue; //adjust motor power
TCCR5B = TCCR5B & B11110111 ; //clears the bit that enables OCR5A CTC mode - goes to count mode.
TCNT5 = 0; //reset pulse counter to zero
LSlastmillisec = millis(); //set timing of reset
TIMSK5 = TIMSK5 & B11111101; //disable interrupt
}
void setup() {
// Initiate the LCD:
lcd.init();
lcd.backlight();
//Enable runpin with pullup
pinMode(LSrunpin, INPUT_PULLUP);
LSnovolt = false; //don't start at init regardless of switch position
//Set Up leadscrew motor and speed counter
pinMode(LSmotorpin, OUTPUT); //set up motorpin as output
TCCR3B = TCCR3B & B11111000 | B00000010; // for PWM frequency of 32khzHz on D2,D3 & D5
OCR3A = 0; //turn off power
//set up to read speed pulses
pinMode (FGpulsepin, INPUT_PULLUP); //input pin for timer
TCCR5A = B00000000; //Ensure normal mode
TCCR5B = B00000000;
}
void loop()
{
// Motor startup Code goes here to run once
if (LSstartnxt && LSrunstate && LSstarting) { //true if LSStartnxt has been set and LSrunstate has been called true
//set up pin 47 to interrupt after Startpulses
TCNT5 = 0; //reset the counter to zero
OCR5A = Startpulses; //set up counter for number of pulses at full power
TCCR5B = B10001110 ; //clock timer 5 on external rising edge for speed pulses CS10,11,12 see P 154 in manual high bit enables noise suppression bit 3 enables CTC mode
TIMSK5 = B00000010; //enable interupt on match
LSsetpoint = LStarget; //set setpoint to current target
LSRunpower = map(LSsetpoint, 0, 100, 0, 255); //Map to LSRunpower for once started
LSpowervalue = LSKickvalue; //set power for startup kick
LSstartnxt = false; //clear flag so we only do this once
analogWrite (LSmotorpin, LSpowervalue); //and tell the motor to go
}
//read run stop switch every pass.
if (digitalRead(LSrunpin) == HIGH) { //if High switch is at run
LSrunstate = LSnovolt; //Lead screw runstate stays false unless LSnovolt is true
if (LSstartnxt) LSstarting = LSrunstate; //if running and LSStartnxt is set, then tell motor to execute startup routine
LSnovolt = LSnovolt;
strcpy(runstop, "run "); //for debugging IF COMMENTED OUT analogWRITE FAILS TO EXECUTE
}
else {
LSnovolt = true; //Leadscrew switch at stop so novolt can be set true
LSrunstate = false; //Turn everything off
strcpy(LSrunstring, "Stop");
analogWrite (LSmotorpin, 0); //and tell the motor to stop
LSstarting = false; //for Debugging?
LSsetpoint = 0;
LSpowervalue = 0;
LSstartnxt = true; //set up to restart
}
while (millis() > Loopmillisecond + Loopwait) { //every Loopwait miliseconds
Loopmillisecond = millis(); //update the time
//get the speed demand
potvalue = analogRead(LSSpeedInPin);
//map values between in and out
LStarget = map(potvalue, 0, 1023, 0, 100);
//if running normally (LSStarting is false) so reset variables
if (LSrunstate && !LSstarting) {
LSsetpoint = LStarget; //set setpoint to current target in case it's changed
LSpowervalue = map(LSsetpoint, 0, 100, 0, 255); //Map to Powervalue
strcpy(LSrunstring, "Run ");
//control the motor
analogWrite (LSmotorpin, LSpowervalue);
// and compute the leadscrew motor speed
LSthismillisec = millis(); // time now - may overflow after 50 days running!!
t5count = TCNT5; //grab the count
TCNT5 = 0; //reset to zero
LSelapsed = LSthismillisec - LSlastmillisec;
lsrpm = (t5count * (111 / LSelapsed)); // calculate speed
LSlastmillisec = LSthismillisec; //remember the time
dtostrf(lsrpm, 5, 1, lsrpmstring); //output shaft speed to one decimal place for display
}
// Print data values on LCD //Needs Work <-----------------
sprintf(line0, "Switch= %-5d", t5count);
sprintf(line1, "Power= %-5d " , LSpowervalue);
sprintf(line2, "Leadscrew= %s", lsrpmstring);
sprintf(line3, "LS target= %-4d %s", LSsetpoint, LSrunstring);
updatedisplay();
}
//otherwise wait for the interrupt
// The End
}