#arduino and #raspberrypi componentless “level shifting”

Arduinos work on 5V, and (Raspberry) Pis work on 3V (actually 3.3V). It is OK to send a 3V signal from the Pi to the Arduino, IIRC, the Arduino registers voltage high above 2.6V, and voltage low below 2.4V.

What about the other way around? Sending 5V from the Arduino to the Pi will likely fry the Pi’s pin. So what to do?

A dubious answer would be to use a voltage divider. I’ve seen that suggested in a number of contexts, but I don’t like it. Without knowing the impedance (resistance) of the device – in this case a pin – you don’t know the overall effect it will have on the divider. You could end up with a situation where you’re sending more voltage to the pin than you realised.

The usual answer it to use a logic level shifter:

They switch between the 3.3V voltage levels of the Pi, and the 5V levels of the Arduino. That’s a lot wires all over the place, though.

I was thinking about switches the other day, and it made me wonder if there was a simple way. My idea may not be universally applicable, but it would seem an appropriate use where circumstances permit

The idea here is that the Arduino can be toggled from a floating input to a level low output. Suppose your output pin is D10. Connect a resistor (e.g. 1K) between 3V and D10. Set D10 as an input. If you connect a voltmeter between the pin and ground, it will register 3V. You have created a pull-up like you might do for reading a switch, except that you use an external rather than internal pull-up, the high voltage is 3V instead of 5V, and you’re using it as an output rather than an input.

If you programmatically switch the pin to an output pin, then this will drive your voltage low, to 0V. You therefore have a way for a 5V pin to output 3V high, and 0V low. Perfect!

Here’s a simple test circuit:

Here’s the code:

#define SW 2
#define OUT 10

void setup() {
  pinMode(SW, INPUT_PULLUP);
  pinMode(OUT, INPUT);
}

void loop() {
  if (digitalRead(SW)) {
    pinMode(OUT, INPUT);
  } else {
    pinMode(OUT, OUTPUT);
  }
  delay(10);
}

Pressing the button sends the voltage low to 0V. Releasing the button gave me a voltmeter reading of 3.23V. You can, of course, reverse the logic between high and low.

It gets even better. If you connect it to your Pi, then you set the Pi’s pin to a pulled-up input. You then don’t need resistor, as the Pi’s internal pull-up resistor will pill the voltage level to 3V. Everything works as before.

I haven’t tried it with a Pi, but I don’t see why it shouldn’t work. Can anyone see any flaws in my argument?

About mcturra2000

Computer programmer living in Scotland.
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s