Programming an atmega328p via raspberry pi gpio and avrdude incompatible with logic level shifter?

I have been trying to get an Arduino Nano (atmega328p) to communicate with a Raspberry Pi (Zero W) over serial using avrdude, and the I'm getting some confusing results. I know that the RPi runs on 3.3V logic and the Nano runs on 5V logic, so it is not recommended to directly connect the two, so I have been using a bidirectional level shifter to communicate between the two. This has resulted in the error message :

avrdude: AVR device not responding
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.   

However, when I connect the same pins without the level shifter (again, not reccommended, but in many tutorials) I instead get the expected message:

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: safemode: hfuse reads as DA
avrdude: safemode: efuse reads as F8

avrdude: safemode: hfuse reads as DA
avrdude: safemode: efuse reads as F8
avrdude: safemode: Fuses OK (E:F8, H:DA, L:FF)

avrdude done.  Thank you.

So, what gives? Why would the level shifter be causing a problem. I double checked that pulling each side low would cause the same result on the other side of the level shifter, so it seems to be working properly. I'm just confused, and was hoping somebody could provide some insight.


If you use a USB cable, then you can upload the sketch. There is a command line version of Arduino that runs on a Zero W without desktop.

Yes, I have been able to upload via USB. This is for bread-boarding a future project that will connect to multiple atmega's over SPI, and I want to use the serial programming interface safely over GPIO. It's not so much an issue of getting a sketch to the board, but getting serial programming to work.

It's possible that information about the specific type of level shifter you are using might be relevant. If you are using a module you could post a link to where you bought it from.

Yes! I should have posted that:

A RX and TX signal is a TTL-signal with strong high and low levels.
A I2C signal has weak high levels, because only a pullup resistor pulls the signal high. When a I2C signal is no longer low, then it slowly flutters upwards and hopefully becomes high someday. Very nice pictures here:

When you use a I2C level shifter, then you have turned a strong signal into a weak signal. Combine that with bad wiring and it will fail.
Can you show a photo of your wiring ?

It's good to know that about I2C, maybe I need some different shifters? As for the wiring, I'm fairly sure it's solid. Everything is connected via jumpers so it looks like a bit of a mess, and iit looks like I'm only allowed to post one picture as a new user, so hopefully you can follow all the connections.

The bottom arduino is the one I'm trying to program, and the jumpers connected together make it easier to swap between the level shifter and the pi directly. Thanks for the help!

I don't see a problem, so I assume that a signal is too weak or too slow with the level shifters.

To make the level shifters work, all the LV must get 3.3V and all the HV must get 5V. That seems okay.
Is the signal for the reset also going through the level shifter ? That might be a problem.
You could add a few decoupling capacitors for the 3.3V and 5V power on each breadboard.
The GND path is going through a number of wires and breadboard connections. You could connect all GND to a single strip on the breadboard.

I went through an simplified the circuit quite a bit to include fewer jumpers, and it doesn't seem to be a wiring issue.

I also tried adding 1uF caps to the power rails, just to see, and that didn't affect anything.

Directly connecting Reset to the pi while the others were connected via the level shifter also didn't work.

Assuming that it is rise time of the level shifter that is causing the issue, like in that post you shared, how should I go about adding pull up resistors? Just connect them between HV/LV and the pins of the shifter?

It's times like this I wish I owned an oscope or logic analyzer. :roll_eyes:

Thanks again for helping me troubleshoot.

30 euros/dollars for a LHT00SU1
It is a Logic Analyzer plus one analog channel.
Software : sigrok / PulseView and a tool "Zadig" is needed in Windows.
Turn off the analog channel to be able to sample the digital inputs at a high rate.

There are already 10k pullup resistors on the low side and 10k pullup resistors at the high side. You can add an extra 4k7 pullup on high side and 4k7 pullup on the low side.
However, I prefer that you buy normal digital level shifters. Not that bi-directional I2C rubbish.