Auto trans controller

Hey all,

Thank you everyone for your time so far. Thanks to @alto777 i have managed to install the shifter into the car. I have also modified the original code and changed the neo pixels to a 7 segment display. I have managed to get this sorted.

However I am hoping I can get some help with the gear up and gear down buttons. I am wanting the button to only change the state when pressed once. Currently if i hold the button it will automatically go through all 4 states. But for a fail safe i want it to be pressed once change the state then register that the button has been released before being able to change to the next gear. I have posted the current code but would someone please point me in the right direction of how to code the switch?

type or paste code here// Pin Definitions
const int SS1R = 2;
const int SS2R = 3;
const int FCSR = 4;
const int LUSR = 5;
const int GUS = 7;
const int GDS = 8;
const int ICRS = 13;
const int COIL1_4 = 9;
const int COIL2_3 = 10;
const int S7A = A4;
const int S7B = A5;
const int S7C = A1;
const int S7D = A0;
const int S7E = 12;
const int S7F = A3;
const int S7G = A2;

void setup() {
// Initialize pins
  pinMode(SS1R, OUTPUT);
  pinMode(SS2R, OUTPUT);
  pinMode(FCSR, OUTPUT);
  pinMode(LUSR, OUTPUT);
  pinMode(GUS, INPUT_PULLUP);
  pinMode(GDS, INPUT_PULLUP);
  pinMode(ICRS, INPUT_PULLUP);
  pinMode(COIL1_4, OUTPUT);
  pinMode(COIL2_3, OUTPUT);
  pinMode(S7A, OUTPUT);
  pinMode(S7B, OUTPUT);
  pinMode(S7C, OUTPUT);
  pinMode(S7D, OUTPUT);
  pinMode(S7E,OUTPUT);
  pinMode(S7F,OUTPUT);
  pinMode(S7G, OUTPUT);
  

  // Start at G1
  transitionToG1();
}

int theGear = 1;    // what gear are we in global

void loop() {
    static int currentState = 1;

    if (digitalRead(GUS) == LOW) {
      theGear++; if (theGear >= 4) theGear = 4;
    }

    if (digitalRead(GDS) == LOW) {
      theGear--; if (theGear <= 0) theGear = 1;
    }

    static int currentGear = -1;    // no, it does not!

// new gear?
    if (theGear != currentGear) {
      currentGear = theGear;

      switch (theGear) {
      case 1 :
        transitionToG1();
        break;
      case 2 :
        transitionToG2();
        break;
      case 3 :
        transitionToG3();
        break;
      case 4 :
        transitionToG4();
        break;

      default :
        Serial.println("logic error");
        for (; ; );
        break;
      }
    }

    if (digitalRead(ICRS) == LOW) {
        digitalWrite(COIL1_4, LOW);
        digitalWrite(COIL2_3, LOW);
        while (digitalRead(ICRS) == LOW); // Wait until ICRS goes HIGH
        digitalWrite(COIL1_4, HIGH);
        digitalWrite(COIL2_3, HIGH);
    }
}

void transitionToG1() {
    digitalWrite(SS1R, HIGH);
    digitalWrite(SS2R, HIGH);
    digitalWrite(FCSR, HIGH);
    digitalWrite(LUSR, LOW);
    digitalWrite(S7A, LOW);
    digitalWrite(S7B, HIGH);
    digitalWrite(S7C, HIGH);
    digitalWrite(S7D, LOW);
    digitalWrite(S7E, LOW);
    digitalWrite(S7F, LOW);
    digitalWrite(S7G, LOW);
    triggerCoils();
}

void transitionToG2() {
    digitalWrite(SS1R, HIGH);
    digitalWrite(SS2R, LOW);
    digitalWrite(FCSR, HIGH);
    digitalWrite(LUSR, LOW);
    digitalWrite(S7A, HIGH);
    digitalWrite(S7B, HIGH);
    digitalWrite(S7C, LOW);
    digitalWrite(S7D, HIGH);
    digitalWrite(S7E, HIGH);
    digitalWrite(S7F, LOW);
    digitalWrite(S7G, HIGH);
    triggerCoils();
}

void transitionToG3() {
    digitalWrite(SS1R, LOW);
    digitalWrite(SS2R, LOW);
    digitalWrite(FCSR, HIGH);
    digitalWrite(LUSR, HIGH);
    digitalWrite(S7A, HIGH);
    digitalWrite(S7B, HIGH);
    digitalWrite(S7C, HIGH);
    digitalWrite(S7D, HIGH);
    digitalWrite(S7E, LOW) ;
    digitalWrite(S7F, LOW);
    digitalWrite(S7G, HIGH);
    triggerCoils();
}

void transitionToG4() {
    digitalWrite(SS1R, LOW);
    digitalWrite(SS2R, HIGH);
    digitalWrite(FCSR, LOW);
    digitalWrite(LUSR, HIGH);
    digitalWrite(S7A, LOW);
    digitalWrite(S7B, HIGH);
    digitalWrite(S7C, HIGH);
    digitalWrite(S7D, LOW);
    digitalWrite(S7E, LOW);
    digitalWrite(S7F, HIGH);
    digitalWrite(S7G, HIGH);
    triggerCoils();
}

void triggerCoils() {
    digitalWrite(COIL1_4, LOW);
    digitalWrite(COIL2_3, LOW);
    delay(125);
    digitalWrite(COIL1_4, HIGH);
    digitalWrite(COIL2_3, HIGH);
}

Here is the Wokwi layout as well

Rein de plus simple.

This

  if (digitalRead(GDS) == LOW) {

acts when the button is down. As you observe, staying on the button means it comes around again soon enough and shifts again.

You need to act on the change of the button, not the state.

There's a hole thing to learn about doing that, see the IDE example I think it is 02. digital State change detection, and read this competent article that goes along with

https://docs.arduino.cc/built-in-examples/digital/StateChangeDetection/

I usually leave it at that, but these days I've been recommending the ezButton library, which gets my highest praise "it doesn't suck". Not to be confused with EZButtonā€¦ about which I have no opinion.

Here is an example. It could not be ezier.

/*
 * Created by ArduinoGetStarted.com
 *
 * This example code is in the public domain
 *
 * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-button-library
 *
 * This example detects the pressed and released events of a button without debounce.
 */

#include <ezButton.h>

ezButton button(7);  // create ezButton object that attach to pin 7;

void setup() {
  Serial.begin(9600);
  button.setDebounceTime(25);  //... added - this is necessary
}

void loop() {
  button.loop(); // MUST call the loop() function first

  if(button.isPressed())
    Serial.println("The button is pressed");

  if(button.isReleased())
    Serial.println("The button is released");
}

Basically at each loop you give the library a chance to read the buttons, then your code can use library functions to detect, then act upon, pressing, releasing, being down and being up.

I added one line to the example the library author published. I believe by default the library does not do debouncing, so I added the 25 millisecond denounce time call.

So to wet your appetite for that little bit of learning time, that troublesome line could end up being something like

  if (myEZUpButton.isPressed()) {

and the body of that if statement will only execute when the button goes from not pressed to pressed. Once. Per. Press.

My sense of where you are at is that you can read the example I linked and get this sorted w/o too much trouble.

I have to say that one day you should learn how to do it without the library, even if you decide to continue to use ezButtons. It's a nice little programming challenge and drags you over a few things worth knowing.

a7

3 Likes