Arduino Micro d17 input_pullup doesn't work

Hi !
I am working on the sim racing gearbox controlled by an Arduino Micro (not Pro, processor ATmega32U4).
It is mostly 6 buttons pushed by a mechanism.
Here is the thing : there is two additionnal switches for the sequential mode, linked to pin D16(MOSI) and D17(SS).
These two pins are configured as Input_Pullup, but D17 keeps floating.... Other guys from the closed beta encountered the same problem :confused:
Here is the diagram :

The code is below. It is mostly :

int downPin = 16; //for sequential

int upPin = 17;

void setup() {
Serial.begin(38400);
pinMode(downPin, INPUT_PULLUP);
pinMode(upPin, INPUT_PULLUP);
...
if (digitalRead(upPin) == LOW ) {
Serial.println("UP");
}

//Creative commons CC NC SA
// V1.0
// V1.01 The reverse gear was wrong
// V2.0   - The debug function has been rewritten in order to avoid any lag. You don't need to disable it anymore.
//        - Added the Pattern Calibration function
//        - Reverse gear has been fixed
// V2.1   - New code for "guide REV2"

#include "Joystick.h"
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_MULTI_AXIS, 17, 0,
                   true, true, false, false, false, false, false, false, true, true, false);

// Awesome Features for YOU !!! comment to disable

//#define USE_ACCEL
//#define USE_BRAKE
//#define USE_CLUTCH
//#define USE_ANALOG_HANDBRAKE
//#define USE_DIGITAL_HANDRAKE
#define DIGITALSEQUENTIAL         // In this mode, upshift and downshift are buttons that need to be assigned. It should be compatible with any game
//#define SMARTSEQUENTIAL           // In this mode, by example if you are in 3th, and upshift, the arduino will engage the 4th speed. It doesn't work on PC2
#define DEBUG
//#define BUTTONPLATEMOD

bool normalMount = false; //true : all the mechanism is at the front. false : all the mechanism is at the rear.






//------------------------------------------------------------------

int PositionPin[6] = {4, 5, 14, 15, A4, A5};  //set the wiring for the button plate mod.

int reverseSwitchPin = 6;
int gearForReverse = 12; //Set the gear you need to reach to be in reverse. For the moment, only 6th is mechanicaly possible
int HallSensorPinForGear[] = {7, 7, 8, 9, 10, 11, 12};
int downPin = 16;        //for sequential
int upPin = 17;
int previousUpPinState = 0;
int previousDownPinState = 0;
bool seqMode = false;
bool sendDebug = false;
int unsigned long lastDebug = 0;
int DebugRefreshRate = 250;

//------------------------------------------------------------------

int gear = 0;  // 0 default to neutral
unsigned long currentMillis = 0;
int lastShift = millis();
int shiftDelay = 125;
unsigned long previousMillis = 0;
int lastGear = 0;
int currentButtonState[17] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int lastButtonState[17] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

int getCurrentGear() {
#if defined(DEBUG)
  if (sendDebug) {
    if (seqMode) {
#if defined(SMARTSEQUENTIAL)
      Serial.print("SmartSequential");
#endif
#if defined(DIGITALSEQUENTIAL)
      Serial.print("Sequential Mode, ");
#endif
    }
    else {
      Serial.print("H Mode, ");
    }
  }

  if (sendDebug) {
    Serial.print("UpPin & downPin = ");
    Serial.print(!digitalRead(upPin));
    Serial.print(", ");
    Serial.print(!digitalRead(downPin));
    Serial.println(" (idle state is 0,0)");
  }
#endif
  if (previousUpPinState == 1 || previousDownPinState == 1) {
    if (digitalRead(upPin) == LOW || digitalRead(downPin) == LOW ) {
      return gear;
    }
    else {
      previousUpPinState = 0;
      previousDownPinState = 0;
    }
  }
  for (int i = 1;  i < 7 ; i++) {
    if (digitalRead(HallSensorPinForGear[i]) == LOW) {
      seqMode = false; //if one gear is engaged, you aren't in seqmode
    }
  }
  if ((digitalRead(HallSensorPinForGear[1]) == HIGH && digitalRead(HallSensorPinForGear[2]) == HIGH
       && digitalRead(HallSensorPinForGear[3]) == HIGH && digitalRead(HallSensorPinForGear[4]) == HIGH
       && digitalRead(HallSensorPinForGear[5]) == HIGH && digitalRead(HallSensorPinForGear[6]) == HIGH) || (seqMode  == true)) { // if no gear engaged, check if we are doing sequential
#if defined(SMARTSEQUENTIAL)
    SmartSequential();
#endif
#if defined(DIGITALSEQUENTIAL)
    DigitalSequential();
#endif
  }
#if defined(DEBUG)
  if (sendDebug) {
    Serial.println("1 2 3 4 5 6");
    for (int i = 1;  i < 7 ; i++) {

      Serial.print(!digitalRead(HallSensorPinForGear[i]));
      Serial.print(" ");
    }
    Serial.println(" ");
  }
#endif
  if (seqMode == false) {
    gear = 0;
  } //0 is neutral


  for (int i = 1;  i < 7 ; i++) {
    if (digitalRead(HallSensorPinForGear[i]) == LOW) {
      gear = i ;
      seqMode = false;
    }
  }
  if (digitalRead(gearForReverse) == LOW && digitalRead(reverseSwitchPin) == LOW) {
    gear = -1; //-1 is reverse
  }


#if defined(DEBUG)
  if (sendDebug) {
    Serial.print("Gear is : ");
    Serial.println(gear);
    Serial.print("ReverseGear : ");
    Serial.println(!digitalRead(reverseSwitchPin));
    Serial.println("");
  }
#endif

  return gear;
}
void setup() {

  Serial.begin(38400);

  setPin(normalMount);


  for (int i = 6; i < 13; i++) {
    pinMode(i, INPUT_PULLUP);
  }
  
  pinMode(downPin, INPUT_PULLUP);

  pinMode(upPin, INPUT_PULLUP);
#if defined(BUTTONPLATEMOD)
  for (int i = 0; i < 6; i++) {
    pinMode(PositionPin[i], INPUT_PULLUP);
  }
#endif
  int lastAcceleratorState = analogRead(AcceleratorPin);
  int lastBrakeState = analogRead(BrakePin);
  int lastClutchState = analogRead(ClutchPin);
  int lastHandbrakeState = analogRead(HandbrakePin);
  Joystick.begin();
  Joystick.setAcceleratorRange(minAccelerator, maxAccelerator);
  Joystick.setBrakeRange(minBrake, maxBrake);
  Joystick.setXAxisRange(minClutch, maxClutch);
  Joystick.setYAxisRange(minHandbrake, maxHandbrake);

  delay(500); //security delay to flash the code

}

void loop() {
    
#if defined(DEBUG)
  if (millis() - lastDebug > DebugRefreshRate) {
    sendDebug = true;
    lastDebug = millis();
  }
#endif

  getCurrentGear();
#if defined(BUTTONPLATEMOD)
  buttonPlateMod();
#endif
  setButtonState(gear);

  sendDebug = false;
}

void setButtonState(int gear) {
  if (gear == -1) {
    currentButtonState[0] = 1; //gear = 0 is reverse , is associated with currentButtonState[0]
  }
  else {
    currentButtonState[0] = 0;
  }
  for (int i = 1; i < 7; ++i) {
    if (i == gear) {
      currentButtonState[i] = 1; //0 to 6 is for gears, 7/8 is for seq,9 to 15 is for button plate 0 is reverse, 1 is 1st....6 is 6th
    }
    else {
      currentButtonState[i] = 0;
    }
  }

  for (int i = 0; i < 16; i++)
  {
    if (currentButtonState[i] != lastButtonState[i])
    { Joystick.setButton(i, currentButtonState[i]);
      lastButtonState[i] = currentButtonState[i];
    }
  }
}

void DigitalSequential() {
  currentButtonState[7] = 0;
  currentButtonState[8] = 0;

  currentMillis = millis();

#if defined(DEBUG)
  if (sendDebug) {
    Serial.println("DigitalSequential");
  }
#endif

  if (digitalRead(upPin) == LOW ) {
    if ( currentMillis - lastShift < shiftDelay) {
      return;
    }
    else {
      lastShift = currentMillis;
    }

#if defined(DEBUG)
    if (sendDebug) {
      Serial.println("UP");
    }
#endif
    currentButtonState[7] = 1;
    previousUpPinState = 1;
    seqMode = true;
    return ;
  }

  if (digitalRead(downPin) == LOW) {
    if ( currentMillis - lastShift < shiftDelay) {
      return;
    }
    else {
      lastShift = currentMillis;
    }
#if defined(DEBUG)
    if (sendDebug) {
      Serial.println("DOWN");
    }
#endif
    previousDownPinState = 1;
    seqMode = true;
    currentButtonState[8] = 1;
    return;
  }
  return;
}

@Lebois

Your topic was Moved to it's current location / section as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

That looks like a pinout drawing, not a schematic. A complete schematic with all power and ground connections shown including links to each piece of hardware would help a lot. You might want to add a few comments to the code.

Don't use pin D17.

I know the Leonardo and the Pro Micro, but I do not know the specific things about the "Arduino Micro".
The schematic has the label "RXLED/SS" for pin D17 (that is "PB0" of the microcontroller) and there is a 1k resistor with a LED to GND connected to pin D17. That is the "RX" LED.
Perhaps the LED is turned on in the USB-serial code.

For the Leonardo, the pins are defined in this pins_arduino.h.
It has: #define LED_BUILTIN_RX 17. It puts the RX LED at PB0, which is pin 17. So pin 17 is indeed used for the RX led.
The Micro has a few changes in its pins_arduino.h. But the only difference seems to be an other initialization for the LEDs.

Because of the LED, it can not be used as a input. I don't know if it can be used as a OUTPUT, since the USB-serial code might control it.

Pin D0 and D1 can be used as normal digital pins. They are not used to upload a sketch (as with the Arduino Uno). Uploading a sketch and the serial monitor is via the USB directly into the ATmega32U4 microcontroller.

There is a whole list of problems with the sketch. It might do what it is supposed to do, but the code is not nice.
Reading buttons and remember the state is not straightforward. The overall structure of the code is not straightforward.
The digitalRead() returns HIGH or LOW, therefor I prefer to use HIGH or LOW.
The function getCurrentGear() returns a global variable, that is an indication of messy code.
The function setButtonState() has a parameter called 'gear', but there is also a global variable called 'gear'.

Thank you so much @koepel ! I switched to D0/D1 and it works ! I will also take your remarks into account ! Thanks again !

Well, of course it can be used as a an input! No problems!

It is just that whatever you use to drive that input must be capable of driving the LED to HIGH. INPUT_PULLUP is a very weak pullup, if nothing else is connected it will cause the LED to glow dimly but it will be unlikely to pull sufficiently high to register such a logic level.

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.