Arduino Unexpected Behavior on RX/TX Pins

Hi everyone, I currently have an Arduino code project based on the Nano which I'm programming to a standalone ATMega 328P on a custom board of mine. Since my project doesn't require serial communication, I'm using the TX/RX ports as general I/O. The only issue is that the TX/RX pins respectively are being held at Vcc and Gnd, despite setting them as outputs. You can watch the voltage dip/rise by a few hundred milivolts when trying to toggle the output state on them, but they stay fairly constant.

After several hours of head scratching and questioning my layout/swapping IC's and components, I decided to create a piece of test code in Atmel AVR to set what are normally TX/RX on Arduino boards as general purpose outputs and toggle them high and low which worked perfectly fine.

Therefore, it seems the Arduino compiler is doing something weird with those two pins, like defaulting to a serial enabled state possibly? I'm wondering how to prevent it from doing this so I can use those pins as I/O.

Thanks in advance.

How are you programming the chip ?

1 Like

do you have Serial.begin() in the code?

I am using avrdude to upload the hex file via ISP.

Nope. Even with the absolute minimum code I have the issue. In the below code, only the "FORWARD_OUTPUT" pin toggles with the other two being stuck low/high. But like I mentioned, with the same pins in Atmel Studio, all 3 outputs toggle.

#define RAPID_OUTPUT 0
#define REVERSE_OUTPUT 1
#define FORWARD_OUTPUT 2

void setup() {
    pinMode(RAPID_OUTPUT, OUTPUT);
    pinMode(REVERSE_OUTPUT, OUTPUT);
    pinMode(FORWARD_OUTPUT, OUTPUT);
    
    digitalWrite(RAPID_OUTPUT, LOW);
    digitalWrite(REVERSE_OUTPUT, LOW);
    digitalWrite(FORWARD_OUTPUT, LOW);
}

void loop() {
    digitalWrite(FORWARD_OUTPUT, 1);
    digitalWrite(REVERSE_OUTPUT, 1);
    digitalWrite(RAPID_OUTPUT, 1);
    delay(2000);

    digitalWrite(FORWARD_OUTPUT, 0);
    digitalWrite(REVERSE_OUTPUT, 0);
    digitalWrite(RAPID_OUTPUT, 0);    
    delay(2000);
}

Can you post a schematic of a your custom board?
Also, when the RESET pin of the MCU is tied to GND and the RESET state is maintained, are the TXD pin and RXD pin is get floating?
If not, the cause may be in the circuit of your custom board.

Does your code contain a bootloader, when you upload via ICSP? The bootloader enables but doesn't subsequently disable the UART control on pins 0 and 1 so they are still driven by UART after bootloader ends and your code starts, that is, if you ARE having a bootloader. Try Serial.end() in setup(). It disables the TX and RX.

Do you get the same effect after disconnecting the programmer from the “stand alone “ ATmega328P then doing a power fail restart ?

Serial.end() worked! That line would have saved me half a day of troubleshooting, thank you and everyone for replying.

So, I never explicitly programmed the Arduino bootloader into the chip. I've only been uploading the .hex file compiled from the Arduino program which I don't think has anything to do with it? I'm new at this so I'm not totally certain.

depending on where you procure the chip, they can come with a bootloader pre-installed.

I learnt something too, I did not realise the bootloader had side effects on the UART control pins.

I'm beginning to learn something as well. I thought that if you uploaded a sketch using a programmer connected to the ICSP pins, the bootloader, if present, would have been overwritten.
There is something clearly odd here because the OP is not the first person to use pins 0 and 1 for something other that serial which, from the described symptoms, would appear to be impossible.

The OP states:

Also, if you output the compiled binary from the Arduino IDE menu, two hex files, one with the bootloader and one without the bootloader, will be output.
We don't know which one the OP has programmed with avrdude.

OK. I think I see. The Arduino IDE, when it generates an AVRDUDE command string for uploading a sketch, adds a '-D' option to it, which suppresses the complete deletion of the flash memory.
I guess the OP will have copied that

This is an example:

C:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\6v6gt\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:C:\Users\6v6gt\AppData\Local\Temp\arduino_build_529199/Blink.ino.hex:i 

This is NOT true of Optiboot, used on Uno and newer “genuine” Nanos.
The UART is most definitely disabled before starting the sketch (the whole chip is reset)

I was only reading the code where it sets the TXEN and RXEN bits. I've read the optiboot before in more details. I now remember the mcu was indeed reset so OP's issue was caused by other sources. Thanks westfw!

Just to clarify, the command I've been using is:
avrdude.exe -p m328p -c usbasp -P usb -U flash:w:"filename.hex":i

Also I have been using the non-bootloader hex during every upload.

What happens if you add "-e" (chip erase) ? That should for-sure remove any bootloader. (although, I thought that that was default behavior for ISP programming, since it's essentially necessary for correct programming.)