Using IO pins on ATMEGA16U2 without interfering with bootloader

Hi all. I am almost sure what I want to do is possible, but I'm having no luck finding information on how. First off, what I'm doing TODAY. I have a custom board with a DIY Arduino Uno R3 on it (ATMEGA16U2/ATMEGA328P-AU) and an additional ATMEGA328P-AU. The second 328 is running custom firmware to control a specific mechanical device, and the DIY Uno communicates with the second 328 using preset serial commands on a SoftwareSerial port.

Now what I'd like to do: I want to move the custom firmware from the second 328 chip onto the ATMEGA16U2, thereby eliminating the second 328 altogether.

What I THINK I know:

  • It seems that Hoodloader 2 allows access to the 7 ATMEGA16U2 pins on the Arduino Uno, so I assume it allows access to all the pins on the chip if they're on a board with appropriate traces and pins.
  • I THINK this allows the bootloader on the ATMEGA328P to act as normal.
  • I THINK this does not interfere with Serial.print() through the USB

What I don't know/can't find:

  • What form does the code take when interfacing with the ATMEGA16U2 pins? I can't find any examples
  • Would the resulting chip work with the Arduino IDE without modification?
  • Has anyone does this before, and are there posts/blogs I'm just not seeing?

Thanks for the help.

If you are using genuine schematic for Arduino Uno R3 (https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf ) you out of luck. The ATMEGA16U2 has access only to two ATMEGA328P pins (TX/RX or digital pins 0/1)

what does the 328p on your Uno? can't it handle both things?

Sorry, I wasn’t clear. This is my own board design so I’ll have access to all the pins in any configuration.

Regarding why the ATMEGA328 can’t do it all. There is a fairly complex robot control algorithm that runs continuously on the second ATMEGA328 right now. The purpose is to allow the Arduino clone portion of the board to be erased or otherwise messed with without affecting the robot control algorithm (it defaults to a particular state when it doesn’t receive any instructions). If I can move this control algorithm, which never gets updated, to the Atmega16u2 I can ditch a whole bunch of components from the design.

Bpip:
Sorry, I wasn’t clear. This is my own board design so I’ll have access to all the pins in any configuration.

Regarding why the ATMEGA328 can’t do it all. There is a fairly complex robot control algorithm that runs continuously on the second ATMEGA328 right now. The purpose is to allow the Arduino clone portion of the board to be erased or otherwise messed with without affecting the robot control algorithm (it defaults to a particular state when it doesn’t receive any instructions). If I can move this control algorithm, which never gets updated, to the Atmega16u2 I can ditch a whole bunch of components from the design.

I understand.
the 16u2 runs a firmware sketch to handle the USB connection for 328p. the firmware source is in arduino/avr/firmwares/atmegaxxu2
The 328p bootloader doesn't know about 16u2 or any other USB or RS232 adapter. It listens on UART pins.

Bpip:

  • It seems that Hoodloader 2 allows access to the 7 ATMEGA16U2 pins on the Arduino Uno, so I assume it allows access to all the pins on the chip if they’re on a board with appropriate traces and pins.

Correct. Here is the Hoodloader2 pin mapping for the ATmega16U2:

D0 - PB0 PCINT0
D1 - PB1 PCINT1
D2 - PB2 PCINT2
D3 - PB3 PCINT3
D4 - PB4 PCINT4
D5 - PB5 PCINT5
D6 - PB6 PCINT6
D7 - PB7 PCINT7 TIMER1C
D8 - [NC] PC7 INT4
D9 - [NC] PC6 PCINT8 TIMER1A
D10 - [NC] PC5 PCINT9 TIMER1B
D11 - [NC] PC4 PCINT10
D12 - [NC] PC2 PCINT11
D13 - [NC] PD0 INT0 TIMER0B
D14 - [NC] PD1 INT1
D15 - PD2 INT2 USART1 RX
D16 - PD3 INT3 USART1 TX
D17 - PD4 INT4 RXLED
D18 - PD5 PCINT12 TXLED
D19 - [NC] PD6 INT5
D20 - PD7 INT7 328 / 2560 RESET

Bpip:

  • I THINK this allows the bootloader on the ATMEGA328P to act as normal.

Essentially, yes. The upload procedure is different though. Here are the instructions:

Bpip:

  • I THINK this does not interfere with Serial.print() through the USB

I’m not sure about that (I’ve never used Hoodloader2). It’s pretty well documented though and you can always just do an experiment to get the answer.

Bpip:

  • What form does the code take when interfacing with the ATMEGA16U2 pins? I can’t find any examples

Just like any other Arduino code. Think of the ATmega16U2 as a second Arduino. Let’s say you wanted to blink the RX LED (which is connected to the ATmega16U2’s PD4 on a regular Arduino board:

const byte LEDpin = 17;
const unsigned int duration = 1000;

void setup() {
  pinMode(LEDpin, OUTPUT);
}

void loop() {
  digitalWrite(LEDpin, HIGH);
  delay(duration);
  digitalWrite(LEDpin, LOW);
  delay(duration);
}

Keep in mind that’s the sketch you upload to the ATmega16U2. If you want to be able to control the behavior of the ATmega16U2 from the ATmega328P then you will need to write a sketch for the ATmega16U2 that receives commands from the ATmega328P and then acts accordingly. Then you will write another sketch for the ATmega328P that sends commands to the ATmega16U2. Of course the communication can go both ways. It’s all up to you how you want to write the code.

Bpip:

  • Would the resulting chip work with the Arduino IDE without modification?

What “chip” are you talking about? You certainly are going to need to install Hoodloader2. You are also going to need to burn the Hoodloader2 bootloader to the ATmega16U2, as explained here:

Bpip:

  • Has anyone does this before, and are there posts/blogs I’m just not seeing?

What do you mean by “this”. Certainly the author of Hoodloader2 has done all sorts of messing about with the ATmega16U2 on their Arduino boards. However, this is not something that’s very commonly done by the community. Usually you will see people attempt it when they need keyboard/mouse/joystick emulation but they bought an Uno. This is a fairly complicated project and typically the people who bought the wrong board and are not hooked enough on Arduino to think it’s worth just buying a Leonardo or Micro that provides the functionality they need out of the box are beginners who end up having a terrible struggle. I have very rarely seen that end well. I’m certain there are more experienced people who have done cool things with the combination of the two microcontrollers but I haven’t happened to run across any of that, other than Hoodloader2 itself.

Excellent! The pin maps and documentation links really help. I gather from the response that hoodloader treats the ATMEGA16u2 as a separate “Arduino”, so the ATMEGA16u2 would get one sketch, the atmega328p a separate sketch. I’ll dig into the linked documents to see if I can figure it out.

Bpip:
I gather from the response that hoodloader treats the ATMEGA16u2 as a separate “Arduino”, so the ATMEGA16u2 would get one sketch, the atmega328p a separate sketch.

That's correct.