1

I'm trying to use an ATMega328 board to control a board of a broken UPS device. I replaced all the internals of the UPS by custom components, so the only things which remain are the chassis and the front board.

On this board, there are five buttons, and three LEDs.

All those components are connected to the ground, each one through its own resistor. By connecting the different pins to the ground and to analog pins of the ATMega328 board, I can successfully detect when the buttons are pressed.

Things, however, get tricky when I want to turn the LEDs on. They have their anode connected to the ground (through a 47Ω resistor), and their cathode connected to a dedicated pin. This means that if I apply voltage to this pin, the LED remains off.

The LED, however, turns on if I connect the ground to a 5V pin on ATMega328 board and the cathode pin to the ground of the ATMega328 board. However, connecting the ground to 5V makes it impossible to read the state of the buttons (or should I wire them somehow specifically?)

Therefore, how do I feed negative current from the ATMega328 board?

There is a similar question on this subject, but while the author wants to “understand the underlying electronics of the arduino and microcontrollers in general,” I, instead, just want to know how to make it work. Reading the answers from the linked question, I have an impression that this is possible, but they don't explain how to do it.

2
  • what is negative current?
    – jsotola
    Feb 26, 2019 at 0:23
  • you may have mixed up the 5V and GND connections .... the buttons probably have pullup resistors, not pulldown resistors ..... same with the LEDs
    – jsotola
    Feb 26, 2019 at 0:47

2 Answers 2

3

If the LEDs turn on when you apply 5V to ground then what you have identified as GND on the board is actually VCC. There is no such thing as negative current: current is either sourced or sinked, depending if it’s exiting or entering into a node.

The diodes (LED) are one way valves, so you have a clear current direction: once that is established, identifying a button press can work either triggering when it gets LOW or when it gets HIGH, in other words that can be easily reversed.

If previously you where detecting a button press with digitalRead(BTN_PIN) == HIGH then just switch to digitalRead(BTN_PIN) == LOW and you have your solution.

0

The answer by Roberto Lo Giacco was helpful, but I still had hard time understanding what is happening and how should I wire the boards properly. Since others may encounter similar problems, I'll explain the solution in my own words.

Note that an answer to a similar question helped me as well.


When a digital pin is set to high with digitalWrite(LED_PIN, HIGH);, it's similar (probably not in electrical terms, but at least in terms of interface) to connecting to 5V what was previously connected to the pin.

Similarly, digitalWrite(LED_PIN, LOW); is similar to connecting to GND what was previously connected to the pin.

This means that when the LED is connected as usual, cathode to the GND and anode (through a resistor) to a digital pin:

  • digitalWrite(LED_PIN, HIGH); turns the LED on, and:
  • digitalWrite(LED_PIN, LOW); turns it off.

Now, if the cathode is connected to the digital pin, the anode (through a resistor) can be connected to 5V. In this situation:

  • digitalWrite(LED_PIN, HIGH); turns the LED off.
  • digitalWrite(LED_PIN, LOW); turns it on.

On the photo in my question, the black wire is connected to GND. Instead, it should be connected to 5V. Other wires remain unchanged.

When it comes to the buttons, in order to determine whether the button is pressed or not, I was doing this:

if (analogRead(ESC_PIN) == 0) {
    // The ESC button is pressed.
}

When the button wasn't pressed, the values from analogRead were quite random, ranging from 50 to 250, or something like that. A zero value would indicate that the button was pressed.

With the new wiring (5V instead of GND), the new values from analogRead range from 350 to 900 when the button is not pressed. When the button is down, the value becomes 1023. Therefore, the new condition is simply:

if (analogRead(ESC_PIN) == 1023) {
    // The ESC button is pressed.
}
4
  • 1
    Why using analogRead instead of digitalRead?!? Please consider analog sampling is a lot slower than reading a digital value... You said there are resistors connected to the buttons: those resistors should act as pull-down, forcing the non-pressed buttons to GND so that when you press the button the voltage jumps to 5V while the resistor limits the current flowing. Feb 26, 2019 at 23:46
  • @RobertoLoGiacco: because digitalRead always returns 1, independently of whether the button is pressed or not. Feb 27, 2019 at 21:38
  • Then the part in the question where you state all those components are “connected to ground with their own resistor” was wrong: there are no resistors in series with the buttons. Feb 27, 2019 at 22:16
  • Interesting. I found that they have each a resistor by testing the board with a multimeter, but given my low experience with electricity, I may have made a mistake. I was also under impression that if I don't use a resistor, I'll burn the board if I set pinMode to INPUT instead of INPUT_PULLUP. I'm happy this impression is wrong (since the board is still alive). Feb 27, 2019 at 23:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.