Terms of service
Let's keep it simple




Brokking.net - Video: Improve your Arduino programming skills - Open drain

Improve your Arduino programming skills - Open drain

This page contains the full script that I used for making this video.

Hello and welcome to another one of my videos. In this video I would like to talk about open drain, what it is, why it's useful and how to get it to work on an Arduino.

First, what is open drain? Well, open drain as the name suggests is like a sink drain. When I pull the plug water can flow down the drain. And when I close the drain nothing happens and I can fill the sink again to any level as long as it does not overflow.

Same is true when the term open drain is used in electronics. Roughly stated: the open drain is nothing more than a switch that is connected to ground. When the switch is closed current can flow through the switch to ground. When the switch is open nothing happens and the output is fully isolated. When isolated it's possible to change the voltage level as long as it does not exceed the maximum rating of the device.

A very well-known example where open drain outputs are used is the I2C or two wire interface that is commonly used for communication between various devices. Every device on the I2C bus only has the ability to connect the data and clock line to ground. The data and clock lines are pulled high via these two resistors.

Normally digitals outputs are connected to either ground or plus 5V and are never left floating like with the open drain. This way the microcontroller has the ability to pull a signal high and low.

Now you might ask yourself why is this so interesting? Well, recently I connect this STM32 BluePill, which is a 3.3V microcontroller to this 5V ATtiny.

When I upload a program via the FTDI programmer the ATtiny automatically resets the STM32 and activates the boot function. This way I don't have to manually move the boot jumper and reset the STM32 before uploading a new program.

And yes, I could use the micro USB connector and a bootloader. However these are unreliable and gave me trouble once in a while on different computers. And it might also be necessary to install an extra resistor to get it to work. Another option is the ST-link that requires extra drivers.

Long story short, after taking various options into account and staying as close to the original Arduino environment as possible this was for me the most reliable and user friendly option while still keeping the USB and ST-link options open.

As explained in my previous STM32 videos not all inputs of the STM32 are 5V tolerant. As you can see here the reset can only handle 3.3V. Meaning that I have to divide the voltage to get 3.3V. This of course can easily be done with a voltage divider. But when I checked the schematic of the BluePill I noticed that the reset pin is connected to 3.3V via a 10k resistor.

Simply putted the only thing needed to reset the STM32 is a connection to ground same as the reset button. And as already explained, this can easily be done with an open drain output.

But when checking the pinMode function it only states INPUT, OUTPUT, and INPUT_PULLUP. No open drain. Does this mean that an open drain output is not possible with the Arduino?

Let's take a step back and check the individual pinMode functions. Input means that the specified pin is left floating and it's state can be checked with the digitalRead function.

In the datasheet of the ATmega328P we can find the input leakage current of 1uA when a signal is connected. And when we do the math we get an idea of the input resistance.

When a pin is set as output the pin is connected to either ground or +5V and the maximum current that can be handled by the pin must be limited to 20mA as stated in the datasheet.

So when I connect pin 3 to +5V and ground via a 2k voltage divider and connect the oscilloscope the voltage is approximately 2.5V. This is because all pins are set to input by default. Meaning that pin 3 is kept floating.

When I now run the blink sketch on pin 3 the pinMode function changes the pin function from input to output. And you can see that the voltage on the oscilloscope changes from 0 to +5V every second. Meaning that the pin is connected to ground when low and +5V when high.

Ok, back to the open drain. What we need is floating when 1 and connected to ground when 0. So, 1 is the same as pinMode set to input, and 0 is the same as pinMode set to output including a digitalWrite low.

Let's have a look at the datasheet again. Here you can see that all I/O functions are controlled with only 3 registers: the data register, the data direction register and the input pin register.

If you have no idea what a register is and how to use it I recommend to check out this video that I made about registers. You can find a link in the description.

The data register will set the output high or low when the pin is configured as an output. Where 0 means output low and a 1 represents output high.

The data direction register is used to define the port as an input or an output. Where 0 means input and a 1 will set the pin as an output.

Finally the read only input pin register. This register will automatically change when the pin has a high or low level. This register is read when you use the digitalRead function.

Because these three registers are reset to zero by default all pins are set to input by default. This represents the 1-state of the open drain.

To get the open drain 0 we need to change the data direction register. Because the data register is 0 by default the pin will automatically be connected to ground.

As you can see, the only thing that we need to do to create an open drain is to change the data direction register. Now, you could use pinMode for this. But I prefer to directly change the register as it is much faster.

The only thing left to do is to locate the bit in the correct register that we need to change. The answer can be found on the schematic of the Arduino Uno. Here you can see that pin 3 is connected to port D3 of the ATmega328P.

This means that we need to change the Data Direction Register 3 bit. And that is done in this program.

This line will set the Data Direction D3 bit to 0 that will set the pin as input and create a floating pin. This is the 1-staste of the open drain output.

This line will set the Data Direction D3 bit to 1 that will set the pin as an output. Because the data register is set to 0 by default the output is directly connected to ground. This is the 0-state of the open drain.

And when I check the output on the oscilloscope you can see that the voltage changes between 0 and approximately 2.5V. And this is the desired behavior that I can now use for resetting the 3.3V reset pin of the STM32 BluePill.

The last thing that I would like to address is the differences in datasheets. If you download the latest ATmega328P datasheet from microchip.com you will notice that the bit names are different. These bitnames are not declared in the Arduino environment and will give you errors during compilation. So make sure to use the correct datasheet. I will put a link in the description for the one that I have used during this video.

Ok, I hope you enjoyed this video and if so please don't forget to give it a thumbs up. Thank you for watching and see you next time.