I am building a transmission controller for an off road vehicle. I have copied code and ideas from the forum and have it working on a breadboard now. i just need to add one more feature i cant figure out.
int gear = 1;
// output pins for the relays
int solA = 7;
int solB = 6;
// input pins for up down / with pullup resistors
int gearup = 9;
int geardown = 10;
void setup(){
pinMode(solA, 1);
pinMode(solB, 1);
pinMode(gearup,0);
pinMode(geardown,0);
}
void loop(){
if(gear == 1){
digitalWrite(solA,1);
digitalWrite(solB,0);
}
if(gear == 2){
digitalWrite(solA,1);
digitalWrite(solB,1);
}
if(gear == 3){
digitalWrite(solA,0);
digitalWrite(solB,1);
}
if(gear == 4){
digitalWrite(solA,0);
digitalWrite(solB,0);
}
//takes care of gear switching
delay(180);//delay to prevent going through gears too quick from holding the button or pressing too long
gear += digitalRead(geardown) - digitalRead(gearup); // non debounced! But may not be a problem because of the delay by gear change
if(gear < 1) gear = 1;
if(gear > 4) gear = 4;
//limits to actual gearset
}
i need the unit to be able to tell when i put the shifter in drive to start the loop. I would like to use pin 11 as an input and apply voltage for it to start the 1-4,4-1 sequence. right now i have the unit powering down while not in drive.
Hi,
Welcome to the forum.
Why don't you start with gear = 0, and have an if statement for 0 that puts/keeps the box in neutral?
Look up select .. case statement in Arduino References.
Tom... 
ok so the best examples i could find were using else if commands. i tried this but am not doing something right.
int gear = 0;
// output pins for transistor controlled solenoids
int solA = 7;
int solB = 6;
// input pins for up down / with pullup resistors
int gearup = 9;
int geardown = 10;
// input pin for nss
int nss = 11;
void setup(){
pinMode(solA, 1);
pinMode(solB, 1);
pinMode(gearup,0);
pinMode(geardown,0);
pinMode(nss,INPUT_PULLUP);
}
void loop(){
if(nss == HIGH){
digitalWrite(solA,0);
digitalWrite(solB,0);
}
// intention is when nss pin 11 is open it will show neutral no sol energized
else if(nss == LOW){
digitalWrite(solA,1);
digitalWrite(solB,0);
}
//intention is when nss is pulled low by grounding it will start in first gear
if(gear == 1){
digitalWrite(solA,1);
digitalWrite(solB,0);
}
if(gear == 2){
digitalWrite(solA,1);
digitalWrite(solB,1);
}
if(gear == 3){
digitalWrite(solA,0);
digitalWrite(solB,1);
}
if(gear == 4){
digitalWrite(solA,0);
digitalWrite(solB,0);
}
//takes care of gear switching
delay(180);//delay to prevent going through gears too quick from holding the button or pressing too long
gear += digitalRead(geardown) - digitalRead(gearup); // non debounced! But may not be a problem because of the delay by gear change
if(gear < 1) gear = 1;
if(gear > 4) gear = 4;
//limits to actual gearset
}
it will still switch gears up and down as it is supposed to but will not change with the change in nss input.
Is the last bit of code a feasible alternative or is it not going to work? I still haven't been able to get it to do what I'm trying to do.
Hi,
Did you look up
switch .. case statement instead of lots of if's?
Tom... 
Yes I did look up switch case. I just haven't been able to figure out how to re-write what I have to work that way.
I have made progress on the controller. I am still missing one small step though. I have it noted in my code. i would like to detect the change of state on an input pin and set the solenoids accordingly. Thanks for any input.
int GEAR = 1;
// output pins for transistor controlled solenoids
int SOLA = 7;
int SOLB = 6;
// input pins for up down / with pullup resistors
int GEARUP = 9;
int GEARDOWN = 10;
// input pin for neutral safety switch(nss)
int NSS = 8;
int currState = 1;
int prevState = 1;
void setup() {
pinMode(SOLA, OUTPUT);
pinMode(SOLB, OUTPUT);
pinMode(GEARUP, INPUT);
pinMode(GEARDOWN, INPUT);
pinMode(NSS, INPUT_PULLUP);
}
void loop() {
//intention is to read the state change on NSS input and set selenoids when change is detected.
// not working as desired.
currState = (digitalRead(NSS));
if ( currState != prevState) {
digitalWrite(SOLA, 1);
digitalWrite(SOLB, 0);
}
// intention is when nss pin 8 is high it will show GEAR 4 when the shift lever is in park,
// reverse or neutral the soleniod state for gear 4 serves as a neutral.
// working as desired.
while (digitalRead(NSS) == 1) {
digitalWrite(SOLA, 0);
digitalWrite(SOLB, 0);
}
if (GEAR == 1) {
digitalWrite(SOLA, 1);
digitalWrite(SOLB, 0);
}
if (GEAR == 2) {
digitalWrite(SOLA, 1);
digitalWrite(SOLB, 1);
}
if (GEAR == 3) {
digitalWrite(SOLA, 0);
digitalWrite(SOLB, 1);
}
if (GEAR == 4) {
digitalWrite(SOLA, 0);
digitalWrite(SOLB, 0);
}
//takes care of gear switching
delay(180);//delay to prevent going through gears too quick from holding the button or pressing too long
GEAR += digitalRead(GEARDOWN) - digitalRead(GEARUP); // non debounced! But may not be a problem because of the delay by gear change
if (GEAR < 1) GEAR = 1;
if (GEAR > 4) GEAR = 4;
//limits to actual gearset
}
Hi,
You are comparing currState to prevState, but you don't update prevState to currState at the end of the loop.
I can't see why you can't have Gear 0 for neutral.
Then count 0 , 1, 2, 3.
I gather you are only counting up to get the code working, before adding gear down shifts.
Tom... 
It does shift up and down as it is currently written. I want it to read the NSS and every time it goes from high to low set the solenoids to first gear ready to up shift. The NSS is ready the movement of the shift lever from neutral to drive. This transmission is in my rock crawler. When on the trail I very frequently shift between neutral and drive but it is important that first gear be available as soon as the shifter is placed in the drive position.
Hi,
Did you fix the ;
You are comparing currState to prevState, but you don't update prevState to currState at the end of the loop.
Tom.... 
Still trying to figure out how to fix that little issue.
Hi,
delay(180);//delay to prevent going through gears too quick from holding the button or pressing too long
GEAR += digitalRead(GEARDOWN) - digitalRead(GEARUP); // non debounced! But may not be a problem because of the delay by gear change
if (GEAR < 1) GEAR = 1;
if (GEAR > 4) GEAR = 4;
//limits to actual gearset
prevState = currState;
}
Put it there at the end of the loop, ready to be checked at the top of the loop.
Tom... 
This is still evading me! What i am trying to write is " each time NSS ( digital pin 8) goes from high to low write solenoid 1 high, solenoid 2 low". This will provide first gear each time the gear shift is moved from neutral to drive. Do i not have the int's correct? I will admit my brain is not at its sharpest right now after staying up all night trying to make this work!
int GEAR = 1;
// output pins for transistor controlled solenoids
int SOLA = 7;
int SOLB = 6;
// input pins for up down / with pullup resistors
int GEARUP = 9;
int GEARDOWN = 10;
// input pin for neutral safety switch(nss)
int NSS = 8;
int currState = 0;
int prevState = 1;
void setup() {
pinMode(SOLA, OUTPUT);
pinMode(SOLB, OUTPUT);
pinMode(GEARUP, INPUT);
pinMode(GEARDOWN, INPUT);
pinMode(NSS, INPUT_PULLUP);
}
void loop() {
//intention is to read the state change on NSS input and set selenoids when change is detected.
// not working as desired.
currState = (digitalRead(NSS));
if ( currState != prevState) {
digitalWrite(SOLA, 1);
digitalWrite(SOLB, 0);
}
// intention is when nss pin 8 is high it will show GEAR 4 when the shift lever is in park,
// reverse or neutral the soleniod state for gear 4 serves as a neutral.
// working as desired.
while (digitalRead(NSS) == 1) {
digitalWrite(SOLA, 0);
digitalWrite(SOLB, 0);
}
if (GEAR == 1) {
digitalWrite(SOLA, 1);
digitalWrite(SOLB, 0);
}
if (GEAR == 2) {
digitalWrite(SOLA, 1);
digitalWrite(SOLB, 1);
}
if (GEAR == 3) {
digitalWrite(SOLA, 0);
digitalWrite(SOLB, 1);
}
if (GEAR == 4) {
digitalWrite(SOLA, 0);
digitalWrite(SOLB, 0);
}
//takes care of gear switching
delay(180);//delay to prevent going through gears too quick from holding the button or pressing too long
GEAR += digitalRead(GEARDOWN) - digitalRead(GEARUP); // non debounced! But may not be a problem because of the delay by gear change
if (GEAR < 1) GEAR = 1;
if (GEAR > 4) GEAR = 4;
//limits to actual gearset
prevState = currState;
}