I've been playing around with the native USB port on the Atmega32U4 chip (on a Promicro board). It has the Arduino bootloader in it. My code is as follows:
#include <Arduino.h>
// Definitions
#define BAUD_RATE 115200 // Serial port baud rate
// Variables
uint16_t ticker = 0;
bool tick = 0;
// Interrupt Service Routine
ISR(TIMER3_OVF_vect)
{
TCNT3 = 40535; // Timer Preload for 100ms interval
tick = 1;
}
// Setup
void setup() {
// Setup timer3 for 100ms overflow interrupt
TCCR3A = 0; // Init Timer1A
TCCR3B = 0; // Init Timer1B
TCCR3B |= B00000011; // Set Prescale to 64
TCNT3 = 40535; // Timer Preload
TIMSK3 |= B00000001; // Enable Timer Overflow Interrupt
// Set up the RX_LED on Port B, pin 0
DDRB |= 0b00000001;
PORTB |= 0b00000001; // Initialise the RX_LED to ON
}
// Loop
void loop() {
if (tick){
Serial.begin(BAUD_RATE);
Serial.print('\r');
Serial.print("Count = ");
Serial.print(ticker, DEC);
Serial.end();
toggleLED();
ticker++;
tick = 0;
}
}
void toggleLED(void){
PORTB ^= (1 << PORTB0); // Toggle the RX_LED
}
Out of reset, the 32U4 sends the output to the USB port and toggles the led on Port B, pin 0 on a 100ms interval, as expected. When I connect a terminal to the USB port from the PC end, it continues exactly as before and the data is there. This is what I expected. What I wanted was the micro to spit its data out on the USB port, whether or not the port is being read at the other end.
The weird bit starts when the USB connection is terminated at the PC end. Once disconnected, the time interval changes to about a second (not sure of the exact timing) based on the blink rate of the led on B0.
Then, if I reconnect to the port from the PC, it goes back to the 100ms interval. Thereafter, when the USB port is connected, the interval is 100ms and when disconnected, it's ~1sec. The system is happy to connect and reconnect, no problem, but the timing changes. Until the 32U4 is reset, then it starts at the 100ms interval without a connection. The problem starts on the first disconnection of the USB port from the PC end.
Additionally, I have tried this with the 'Serial.begin()' and the obligatory 'while(!Serial){}' in the setup function. Same behaviour on USB disconnect. I've also tried using Timer1. Same thing.
I understand that there is no easy or good way to detect whether something is connected to the USB port at the far end. This is the first chip I've used that has a native USB port, which is the main reason I picked it. Previously I've always used serial to USB converter chips on a USART port and this has not been a problem. This behaviour in the 32U4 might make it unusable for some projects unless I can figure out what's happening.
My questions are as follows:
Why do the timers seem to work differently once the native USB connection gets closed at the far end?
Is this something to do with 'Serial()' and/or the Arduino built-in code, or is it a hardware issue on the native USB port inside the 32U4?
I'd be grateful for any recommendations to try and figure out what's actually going on.