I'm working on a project that uses a raspberry pi as a music player but some of the controls are going to be handled via an Arduino Nano. I need to pull GPIO 4 on the Raspberry Pi LOW in order to mute the audio. However, the Raspberry Pi uses 3.3V as a logic high so I don't think I can hook up a 5V pin on the arduino to it. Is there a way to set the Arduino pin to put out 3.3V instead of 5V on a specfic pin? What are my options here?
Probably the simplest solution is to use a resistive divider to scale the rpi input to 3V
Thanks, I'll go that route.
You're welcome.
Use a level shifter.
The BSS138 (a type of mosfet) with two pullup resistors is a common level shifting method, I think adafruit sells a board with a few of these on it, or you solder a BSS138 and the necessary resistors to a board of your own if you're designing a custom PCB. Th BSS138 is a bidirectional level shifter, the same circuit can be used just as easily when the Pi's pin is and output and the arduino's pin is an input as when vice-versa. You need one BSS138, and two resistors, for each separate data wire run between the Arduino and the Pi.
Assuming the Pi pin has an input pullup, I think you could do this, but I'm not certain as I've never tried doing it. Hopefully someone will tell us why it's wrong, or confirm it's okay.
const byte piPin = 2; // Change to the pin you want to use
void setup() {
pinMode (piPin, INPUT);
}
void loop() {
// Call piPinLow() when you want to set it low
// Call piPinNotLow() when you want to set it to not be low
}
void piPinLow() {
digitalWrite(piPin, LOW); // Probably not necessary
pinMode(piPin, OUTPUT);
}
void piPinNotLow() {
pinMode (piPin, INPUT);
}
My rationale is:
- When the Arduino pin mode is INPUT, it's floating, so as far as the Pi is concerned it won't see any voltage from the Arduino and the Pi's pull up will cause the Pi to see a high on its input pin.
- When the Arduino wants to take the Pi pin low, it changes the Arduino pin mode to OUTPUT, having already set the pin to low.
- The Arduino should never set its output pin to high, and the Pi should never receive 5V from the Arduino
Now that's an interesting idea.. Definitely curious to hear others thoughts.. would save me some soldering time and board space for sure.
So in your haste to get everything working, you accidentally wrote some code that set the output high.
As long as it's impossible for the Arduino to ever set its output pin high.
I was curious enough to try it.
I modified the code to include a signal to trigger my oscilloscope when the Nano was rebooted. The commented out lines aren't necessary, the Nano is already in that state by default after power up.
const byte piPin = 2; // Change to the pin you want to use
const byte scopeTriggerPin = 3; // For Oscilloscope only
void setup() {
// digitalWrite(scopeTriggerPin,LOW); // For Oscilloscope only
pinMode(scopeTriggerPin, OUTPUT); // For Oscilloscope only
delay(100); // For Oscilloscope only
digitalWrite(scopeTriggerPin, HIGH); // For Oscilloscope only
pinMode (piPin, INPUT);
}
void loop() {
// Call piPinLow() when you want to set it low
// Call piPinNotLow() when you want to set it to not be low
piPinLow();
delay(10);
piPinNotLow();
delay(10);
}
void piPinLow() {
// digitalWrite(piPin, LOW); // Probably not necessary
pinMode(piPin, OUTPUT);
}
void piPinNotLow() {
pinMode (piPin, INPUT);
}
This is how I wired it:
This is the oscilloscope trace after pressing the reset button on the Nano:
[Edit: I forgot to add a conclusion, which is that it works in the way I expected it to]
Jim, I don't understand your comment.
Was it intended to be "What if" rather than "So"?
If so, I agree it would be possible, with a code accident, to output 5V to the Pi.
When I want to guard against such errors (my code setting something to output mode when the pin it's driving is, or can be, an output too), I usually put a 1k resistor in series with the Arduino output pin.
IDK whether the Pi has protection diodes to catch over voltage on its inputs, I presume it does. I'm also assuming a pull up on the Pi >> 1k. In case of an accident applying 5V to the Arduino output, we'd have to drop 1.7V across the 1k resistor. So the protection diode would have to conduct 1.7mA, and dissipate about 1mW.
Well, then that kind of defeats the whole purpose of your great idea in that in did not require any additional parts or soldering as the OP had hoped.
If you are going to add one resistor you might as well add two as @EmilyJane suggested.
I guess you did mean "What if".
That's a fair point. When I put 1k series resistors in, it was code in a quite complicated state machine. The code was for controlling a Z80 from a Nano. The Z80 data bus can be floating, input, or output. I didn't trust myself to have not made mistakes in that code.
I'd trust myself not to make a mistake in this much more simple case.
I'm sure @hoss75 will select whatever they think is best for them.
Just wanted to update everyone that I decided to go with a transistor setup. seemed like the cleanest option even though it was a bit more work .