Hi all Im trying to get an interrupt working in this program that will completely reset the program on the rising edge of a input pin connected to digital pin 3. Ive looked at online examples' and I think that digital pin 3 is interrupt 1. Ive tried coding it a couple different ways Identifying the input pin and also identifying the interrupt number. the sketch uploads fine but a look at the Arduino Uno board while the program is running allows me to confirm that the pin 3 is indeed receiving a rising edge and when it dose the reset function is not running. I suspect im not creating the interrupt properly
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// as of 5/28/2025 this version works but the next version should activly send the shifter to nutral
// on activation of the interupt
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <AccelStepper.h>
#include <Servo.h>
#define motorInterfaceType 1
Servo throttleServo; // create servo object to control a throttleServo
//******************************************************PINS*************************************************************
#define startIndicator 2 // just a switch to ground pin 9 should be ok to bounce a little as in
// this case the loop is interupted a bunch of times but will settle in an actual state
// the chattering noise of the servo on start swich activation cretes an audible noise
// helping the operator to know they are in start mode kind of like a your blinker
//is on
#define magnetSwitchStepper 3 // this is the shifter mag switch on the shifter stepper motor .its an input,
// this is because mag switch operates the nutral sence relay
// and the relay feeds 5 volts to a debounce circut.thru its comon and
// NC contaacts.When voltage falls below 5 volt threshold a 2n2222 transistor
// that was holding pin 3 down turns off thus interup should activate on rising
// edge
#define servoPin 4 //
#define stepperDirecton 10 //
#define outputA 5 // output of the rotry encoder input to the ardrino
#define outputB 7 // output of the rotry encoder input to the ardrino
#define stepperEnable 8 // OUTPUT from pin 8 to stepper driver 5 volts high
#define stepperMove 6 //
//************************************************************************************************************************
int currentStateA;
int lastStateA;// one of the 2 outputs from the rotery encoder
int controlMultiplier = 1; ; //various spots throuout program. The counter will be amplified
//to result in less or more control travel for same control movment
// so far counter Multipliers are F,R,FN,RN when the program first begins
// controlMultiplier will be one so no amplification needed
// forward, reverse,between forward and nutral and between reverse and nutral
float F = 3.4;
float R = 3.4;// changed from 4.4 to 3.4 on 5/27/2024 1103 pm
float FN = 1;// changed from 2 to one 5/28/2025
float RN = 1;// changed from 2 to one 5/28/2025
float counter;// esentually the rotery encoder posision
AccelStepper ForwardReverseStepper(motorInterfaceType, stepperMove, stepperDirecton);
//#####################################################################
int diagnosticMode = 0; // change to 1 to enter diagnostic test mode
//####################################################################
// the next 4 lines are map constants
float X = 500; // servo throtle in forward "From High" portion of map instruction
float Y = 4900; // servo throtle in forward "to High" portion of map instruction
float Z = 500; // stepper control between reverse and Nutral also forward and nutral "from high"
float D = 4900; // stepper control between reverse and Nutral also forward and nutral "to thgh"
// the next 2 lines are the exzact number of steps away from 0 that we want to be in gear
// so figue out the exzact number of steps to forward
//to be perfectly in forward from Nutral vise versa from 0 to Reverse
// then reverse then probibly be a good idea to change expectedCCWCurrentStepperPosision
// to somthing more understandable like absoluteForwardGearlocationincounter
int expectedCCWCurrentStepperPosision = 1300; //expectedCWCurrentStepperPosision
int expectedCWCurrentStepperPosision = -1300;//expectedCCWCurrentStepperPosision
float A;
float B;
float C ;
// the next line is the highest the servo will travel set to prevent exceding
//max throttle in miliseconds
int fullThrottleServoPosision = 2500;
// the next line is the lowest the servo will travel
//set to prevent exceding idle throttle in miliseconds too low engine may die or overheat
int IdleRPMhServoPosision = 1000;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//#################################################################################################
//#################################################################################################
// The shifter stepper has to be kept below a certin
//point to not shift past forward gear also
// this next line is a (counter point ,point at wich it moves into gear) it must be set high
//enough so that the manual control feeling is still there..
//you are controling the stepper speed and direction manually up intill this number. Hit this number and
// it just takes over and shifts for you. So if not set high enough it will feel like
// it slamed into gear before you wanted it to.. too low and you will have no or not enough travel of the lever
//between forward
// and nutral.. set this number corectly and during boat operation it will feel like this number dosent need to exsist
//the way it works is the stepper stops at this point for a milisecond and without throtle movment
// procedes to an exzact number of steps that we want for our gear posision to be in forward,aka
// "expectedForwardCurrentStepperPosision",
//it's that secondary number that actually determins that gear
// posision. If you change this you must first change
//the other to be just above or below this,and you
// must convert forom counter to number of steps to change the other not being carful can really create
// a back and forth situation right before the shift.KEEP TRACK of old settings and watch for over
// adjusting of the numbers. //
// any time you change a number note the date and time of the change and the old number like this example below
// 5/21/2025 10 am changed high stepper posision from -900 to -800 EXPEREMENT to alter shift posision
//#################################################################################################
//#################################################################################################
int highStepperPosision = -900 ; // 5/21/2025 10 am changed high stepper posision from -900 to -800 EXPEREMENT to alter shift posision
// Like above only backwards the next line
// is the (counter pointer) that the stepper
//will stop moving under
// control of the lever
// and begin to advance to "'or retreat to'" the reverse posision .Furthermore
// the actual posision is
//expressed in steps and determind by "expectedCCWCurrentStepperPosision" // it is not yet known if ccw and cw are inverted
int LowhstepperPosision = 900;
int ForwardGearStop = 60; // gear shifting the spot at wich you have gone into
//forward gear or out
//of forward gear ...
// Just like above the Reverse gear stop is were we wish to stop controling gears and advance the
// trottle instead of shifter on motor. likwise stop controling the throtle and
//change gears instead depending on how you look at it
int ReverseGearStop = -60; // gear shifting the spot at wich you have gone into R gear or out
//of reverse
int forwardThrotleStart = 49; //This is a counter pointer for the beginning of throtle movment in forward
int reverseThrottleStart = -49 ; //This is a counter pointer for the beginning of throtle movment in reverse
int startServoPosision = 1000;//Kind of self explanitory its were we want the throtle
//to be set when we pull on the starter rope.its going to need an input to tell it the engine
// needs starting and the same input to delete this action and revert to lever posision comands.
int currentStepperPosision = 0;// 1500 microseconds is writen as 1500. Every time the program starts
// we assume the stepper is in 0 or Nutral center
int currentServoPosision = IdleRPMhServoPosision;// we will start this at idle
//unless the start swich is closed
int comingOutofNutralTowardsForward = 12;
int comingOutofNutralToReverse = -12;
int forceToNutralLowSpot = -8;
int forceToNutralHighSpot = 8;
void(* resetFunc) (void) = 0;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void setup() {
void(* resetFunc) (void) = 0;//declare reset function at address 0
attachInterrupt(digitalPinToInterrupt(1), weAreinNutral, RISING);//CHANGED FROM FALLING 5/21/2025 138PM
ForwardReverseStepper.setMaxSpeed(3900);
ForwardReverseStepper.setAcceleration(3900);
ForwardReverseStepper.setSpeed(3900);
ForwardReverseStepper.moveTo(0);
pinMode(magnetSwitchStepper, INPUT_PULLUP);
pinMode(stepperEnable, OUTPUT);
pinMode(stepperDirecton, OUTPUT);
pinMode(stepperMove, OUTPUT);
pinMode(startIndicator, INPUT_PULLUP);
pinMode(outputA, INPUT_PULLUP);// this is output from the encoder input to the controler
pinMode(outputB, INPUT_PULLUP);// this is output from the encoder input to the controler
// previus 2 lines switched from input to input pull up 5/22/2025 omron encoder replaced with teass encodernew encoder
// usses apn open colector output
// Serial.begin(1200);// comented out 5/27/2025 1045 pm
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Read the initial state of outputA on the rotory encoder and declare
//it to be identical to to the last state of A
lastStateA = digitalRead(outputA);
}
//**************************************************************************************************************
void loop()
//*********************************************************************************************************************
{
if (diagnosticMode != 1 ) {
theMainprogram();
}
// diagnostic mode can be here
}
void theMainprogram()
{
currentStateA = digitalRead(outputA);// program started
// Read A again did it change?
if (currentStateA != lastStateA && currentStateA == 1) {
if (digitalRead(outputB) != currentStateA) {
counter = (counter + controlMultiplier); //
} else {
// Encoder is rotating CW so increment
counter = (counter - controlMultiplier); //
}
}
//**********************************************************************************
// the servo control for throtle in forward ............. ie rotating CW Blue 7 White 6
//***********************************************************************************
if (counter > forwardThrotleStart) {
controlMultiplier = F;
// next 3 lines are to give the stepper a last chance to
//get that stepper to the desired gear if
// it did not make it there due to uncounted
//steps ie moving lever too fast!!
// right now however were all about
//throtle control for servo in forward
// and these 3 lines are ancalary
// ForwardReverseStepper.moveTo(expectedCWCurrentStepperPosision);
// while (ForwardReverseStepper.currentPosition() != expectedCWCurrentStepperPosision)
// ForwardReverseStepper.run();
// previous 3 lines are acounting for
//uncounted steps/missed steps. (stepper motor has no closed loop operation)
// it will loose steps its inevatable
//during a while comand.
//Proper adjustment of forward gear stop (forwardGearStop)
//and (expectedCWCurrentStepperPosision) is criticaly dependant on one another
// they need to be close together but not too close. you have to plan for how
//many steps wont get counted and set the (expectedCWCurrentStepperPosision)
//to the exzact posision. leaving the forward gear stop to be some number chosen
// a little below the target so that as long as you count enough steps to get above the target
// the software gets you the rest of the way there
//Idealey (LowhstepperPosision) and (highStepperPosision)should
//be determind after (expectedCWCurrentStepperPosision) and(expectedCCWCurrentStepperPosision)
// map function eqasion ahould be solved backwards to compute the counter posision.
// or just play with it but do document changes I just played with it but crazy control inputs
// could mess things up thats why there is a nutral lock that resets the counter each time you go thru or into nutral
digitalWrite(stepperEnable, HIGH);// disable the shifter stepper .High disables. We
//are now about to throtle up in forward
throttleServo.attach(servoPin); // enable throttle servo attaches the servo on pin servoPin
//exmap(counter, fromLow, fromHigh, toLow, toHigh)
A = map(counter, 0 , X, 0, Y);// should amplify the throttle posision a higher
//"to high"moves throtle faster
//might help it stay cought up but the more you
//amplify the more you amplify the error result from
// lost steps
B = A - 1 ; // I thought this was going to be b = a minus the
// reverse gear stop so throttle 0 would be counter zero its not
// wkg why ?so just droped in a 0 to make it work
// leaving in in case will need.
//
// Next linelimits range of values
//to between Idle rpm and full throtle
B = constrain(B, IdleRPMhServoPosision , fullThrottleServoPosision);
currentServoPosision = B; // a declaration
throttleServo.writeMicroseconds(currentServoPosision); // moves the servo position according
// to the
// scaled
}
//**************************************************************************************
// Servo control for throtle in reverse......................
// ****************************************** ******************************************
if (counter <= reverseThrottleStart) {
controlMultiplier = R;
// next 3 lines are a last chance to get that stepper to the desired gear
// ForwardReverseStepper.moveTo(expectedCCWCurrentStepperPosision);// this variable
//must be set carfully
// see coments control multiplier
// while (ForwardReverseStepper.currentPosition() != expectedCCWCurrentStepperPosision)
// ForwardReverseStepper.run();
digitalWrite(stepperEnable, HIGH); //disable stepper, High disables we
//are soon to throtle up in reverse
throttleServo.attach(servoPin); // enable throttle servo
// this attaches the
//servo on pin servoPin
A = map(counter, 0 , X, 0, -Y);
B = A - 0;// I thought this was going to be B equal to "a minus
//reverse gear stop" so throttle 0 would be counter zero seems not matter
// next linelimits range of values to between Idle rpm and full throtle
B = constrain(B, IdleRPMhServoPosision , fullThrottleServoPosision);
currentServoPosision = B;
throttleServo.writeMicroseconds(currentServoPosision);
}
//***********************************************************************
// (Stepper) control between Forward and nutral
// **********************************************************************
if ((counter <= ForwardGearStop ) && (counter > comingOutofNutralTowardsForward)) {
controlMultiplier = FN; // more agressive travel amplitude less agresive travel amplitude
digitalWrite(stepperEnable, LOW);// low enables
throttleServo.writeMicroseconds(currentServoPosision); //one last chance to get that
//throtle servo to the Idle posision
throttleServo.detach();// disable servo
// exmap(counter, fromLow, fromHigh, toLow, toHigh)
C = map(counter, 0 , Z, 0, D); //stepper should respond faster as tolow and to high
// get farther appart this in conjunction with control multiplier sets responsivness
// next linelimits range of values to between forward and Nutral
C = constrain(C, LowhstepperPosision , highStepperPosision); //
digitalWrite(stepperEnable, LOW);// stepper Low Enables we
//are soon to move gears
currentStepperPosision = C;
ForwardReverseStepper.moveTo(currentStepperPosision);
ForwardReverseStepper.run();
}
//***********************************************************************
// (Stepper) control between reverse and nutral
// **********************************************************************
if ((counter >= ReverseGearStop ) && (counter < comingOutofNutralToReverse)) {
controlMultiplier = RN; // more agressive travel amplitude less agresive travel amplitude
digitalWrite(stepperEnable, LOW);// low enables
throttleServo.writeMicroseconds(currentServoPosision); //one last chance to get that
///throtle servo to the Idle posision
throttleServo.detach();// disable servo
// exmap(counter, fromLow, fromHigh, toLow, toHigh)
C = map(counter, 0 , -Z, 0, -D); //stepper should respond faster as "fromhigh" and "tohigh"
// get farther appart
// next linelimits range of values to between reverse and Nutral
C = constrain(C, LowhstepperPosision , highStepperPosision); //
currentStepperPosision = C;
ForwardReverseStepper.moveTo(currentStepperPosision);
ForwardReverseStepper.run();
}
//***********************************************************************
// (Stepper) control between comingOutofNutralToReverse and 0
// **********************************************************************
if ((counter >= comingOutofNutralToReverse ) && (counter <= forceToNutralLowSpot))
{
digitalWrite(stepperEnable, LOW);// low enables
while (ForwardReverseStepper.currentPosition() != 0) {
ForwardReverseStepper.moveTo(0);
ForwardReverseStepper.run();
digitalWrite(stepperEnable, LOW);// low enables
counter = 0;
controlMultiplier = 1;
}
}
//***********************************************************************
// (Stepper) control between 0 and comingOutofNutralToForward
// **********************************************************************
if ((counter >= forceToNutralHighSpot ) && (counter <= comingOutofNutralTowardsForward))
{
digitalWrite(stepperEnable, LOW);// low enables
while (ForwardReverseStepper.currentPosition() != 0) {
ForwardReverseStepper.moveTo(0);
ForwardReverseStepper.run();
counter = 0;
controlMultiplier = 1;
}
}
lastStateA = currentStateA;
startCheck;
}
void startCheck() {
digitalRead (startIndicator);
if (startIndicator == 0)// changed to 0 from 1 5/21/2025 1117 am also line 345 while start indicator
{
throttleServo.attach(servoPin); // attaches the servo on pin servoPin
while (startIndicator == 0) {
throttleServo.writeMicroseconds(startServoPosision);// in microseconds
}
}
throttleServo.writeMicroseconds(IdleRPMhServoPosision);// in microseconds
throttleServo.detach();// disable servo
}
//_______________________________________________________________________
//__________________________ISR____________________________________
//_______________________________________________________________________
//ISR function
void weAreinNutral () {
counter = 0;
resetFunc(); //c
}
//__________________________________________________________________________
//____________THE END_____________
//__________________________________________________________________________