Hello. I'm trying to communicate with a device that insists on using 1200 baud serial and am having trouble getting the Nano Every to work at that baud rate. The simple code below fails to print anything on the serial port monitor. Any other baud rate works just fine. What am I doing wrong, or is there a work around? Thanks for any help or advice!
Code based on simple blink routine that doesn't work:
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 13 as an output.
pinMode(13, OUTPUT);
Serial.begin(1200);
while (!Serial) {
; // wait for serial port to connect.
}
Serial.println("Hello Computer"); // This NEVER is printed at 1200 baud. Any other rate is OK.
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Thank you for the link cattledog. That's interesting information. However, I'm not sure where the baud_setting is casted to int16_t, and how I might change it to uint16_t ? Is there any other fix, or has this already been implemented in a library somewhere?
Also, just as a FYI, this speed limitation apparently only exists on the USB serial port. I have successfully used secondary serial ports on the Nano Every to communicate at 1200 baud with the target device that needs 1200. Unfortunately that doesn't really help in the design I'm working on which needs to work at 1200 from the USB port.
Thanks cattledog! I had seen that link, but implementing it looks to be outside my competence zone. I was hoping this change might have found it's way into an alternative library I could incorporate. I also didn't get a warm fuzzy feeling this was an approved work around. It feels like an issue in process. At best it sounds like it only fixes the problem at 1200 baud.
I had seen that link, but implementing it looks to be outside my competence zone.
Editing a text file should be well within your competence zone. The Arduino core for the Nano Every is in the Arduino15 folder.
The path in windows is
C:\Users\YourName\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\cores\arduino\UART.cpp
Using the text editor of your choice navigate to that file on your computer. Open it, and look for lines 167 and 168. Make the change below and save the file. Let us know if it indeed gets you 1200 baud.
Line 167 // assign the baud_setting, a.k.a. BAUD (USART Baud Rate Register)
Line 168 //(*_hwserial_module).BAUD = (int16_t) baud_setting;
(*_hwserial_module).BAUD = (uint16_t) baud_setting;
Hi cattledog, Thanks so much for your help! I really appreciate your input. Finding the file on my computer was the help I needed. Editing it was trivial. Unfortunately, it did not make the code snip work. I even tried an #include <UART.h> in the initialization.
I'll have to double check tomorrow with some lab gear, but I suspect my Nano Every is clocked at 20 MHz. At least that's the spec sheet I read. The "megaavr/issues/46" link states that 1200 baud would be achievable with a 16 MHz clock, but not 20 MHz. Is there a way to slow down the clock speed on the Nano Every?
According to this formula, it's not possible to have a UART baud of 1200 because you need the BAUD register to be 66666, but the BAUD register is only 16 bits (max of 65535)
Thank you Hzrnbgy. I added the commands you suggested to my setup. That successfully slowed the clock to 10 MHz since the blink routine rate went from 1 second to 2. So your code was correct. I would never have figured that out in a million years by myself. However the routine still doesn't produce the "Hello computer" output to serial at 1200 baud.
Just as a test, I tried setting the routine to 4800 baud. It produced the correct output at 2400 baud on the port monitor. Unfortunately, when I set the routine to 2400 baud it still didn't produce any output on the monitor whatsoever, and definitely not at the desired 1200 baud. (I can usually see characters of some sort on the monitor even if the speeds are not in sync.)
So obviously I'm still missing something. But I really appreciate the help everyone has provided. I think we're getting closer. BTW, I will be unable to do further tests or replies for the next 18-20 hours, so please be patient with me. Thanks!
Here's the code as it stands right now. I backed out the changes to the UART.cpp file suggested earlier. It didn't make a difference either way.
// the setup function runs once when you press reset or power the board
void setup() {
// Slow clock down from 20 MHz to 10 so 1200 baud works
CPU_CCP = 0xD8;
CLKCTRL_MCLKCTRLB = CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm;
USART0_BAUD = 33333;
// initialize digital pin 13 as an output.
pinMode(13, OUTPUT);
Serial.begin(1200); // Also doesn't work if set to 2400. Works at 4800 to yield 2400 baud out.
while (!Serial) {
; // wait for serial port to connect.
}
Serial.println("Hello Computer"); // This line never appears on monitor when test fails.
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
You may want to consider switching from the Arduino megaavr core to the MCUDude MegaCoreX. It is available through the boards manager. It claims to support 1200 baud at 16 Mhz.
From "Read Me"
Another thing to watch out for is the lowest possible baudrates when running at 16 or 20 MHz. At 16 MHz the lowest baud rate is 1200 baud. When running at 20 MHz the lowest is 2400 baud. This is caused by the way the internal baud rate generator works. If you need lower baud rates you'll either have to reduce the main clock speed or use the software serial library instead.
The spec sheet is wrong, the box the Nano Every came in is wrong, the processor is set to run at 16MHz in the Arduino boards package and that is what it has always been (can be changed by editing the boards.txt file). The clock speed of the Nano Every is not crystal controlled, it always uses the internal oscillator, and the speed is set by fuses that are written every time code is loaded to the device. Use MCUdude's MegaCoreX boards package and you will have a menu to set the clock speed under the Tools menu in the IDE.
Put a delay after Serial.begin() in setup - unless it has been fixed, while(!Serial) does not work properly on the Nano Every, so you will likely never see the "Hello Computer" message.
That would tend to indicate that the serial hardware in the atmega4809 is actually working correctly, and the USB interface is the problem. As I pointed out in my previous post, while (!Serial) does not work properly on a Nano Every, put a delay after Serial.begin to give time for the USB connection to be established, I would start with 500mS, I forget how short the delay can be.
I understand that there may be issues with while(!Serial), but I don't understand the need to use that command on a Nano Every. It is required for native usb architectures but the Nano Every has a SamD11 chip as a USB to TTL converter and is not native USB.
There is a noticeable time between when a sketch is loaded and the USB to Serial will work, enough that you will lose anything printed immediately after Serial.begin. May be related to the SamD11 having to perform the progeamming function instead of just being a USB to Serial.
Thanks to all who have provided ideas and insights! The community support has really been appreciated. I've tried moving the "baud 3333;" statement to after Serial.begin(), and I added 2 to 4 seconds of delay also after Serial.begin(). Nothing has made any difference. Just to make sure something else hadn't gone off the rails, I tried using Serial.begin(4800); This worked just fine, although due to the slower clock the result came out at 2400 baud. Unfortunately, Serial.begin(2400); didn't work either at 2400 or 1200 baud.
At this point, I'm in agreement with david_2018's post that the serial hardware is probably working correctly, but the SamD11 chip being used for the USB connection is just not capable of supporting speeds much less than 2400, regardless of clock speed.
Fortunately, I'm in the prototype stage, so I'll investigate MCUDude MegaCoreX hardware, or use of a separate UART in front of the Nano Every since it seems the Every's USB is useless for my purposes. I have a number of other options too... it's just all of them are more work.
this speed limitation apparently only exists on the USB serial port. I have successfully used secondary serial ports on the Nano Every to communicate at 1200 baud with the target device that needs 1200. Unfortunately that doesn't really help in the design I'm working on which needs to work at 1200 from the USB port.
If you turn on "verbose" for uploading, you'll see a message go by:
Forcing reset using 1200bps open/close on port /dev/cu.usbmodem147121
So 1200bps is a "magic" baudrate with side-effects. I'm not surprised that it doesn't work on the USB/Serial port.
You could try setting the baud rate to a slightly different bitrate that should still be compatible with a 1200bps link, but not trigger the magic behavior. 1201 or 1199bps, for instance. If your "other side" permits such.
OTOH, I don't understand how you can "require" the USB/Serial port to operate at 1200bps. That bitrate exists for a few mm on the Every board itself, and then it's converted to USB messages that zip along at 12Mbps, at which point the actual baud rate ought to be irrelevant to anyone else. Unlike the older Nanos, the UART one the usb/serial connection is NOT shared with any other pins.
OTTH, you could re-program the SAMD11 firmware. While the minimum supported bitrate ought to be CLK/8192 (48MHz/8192 = 5859), the CLK part need not me the same clock as the rest of the SAMD11 chip...
Could you give some hint at what kind of device functions as a USB host device and requires that it be connected to a usb to serial converter operating at 1200 baud?
Sure. The device I'm trying to integrate into the larger design is actually a PIC microcontroller that has been developed by amateur radio operator K1EL. The device is called the WinKeyer3, and it is used by radio operators to communicate using high speed Morse code. (Sounds archaic, but it has legitimate purposes and there are a few hundred thousand ops around the world who are quite good at this.) Of course, by digital standards, Morse is very slow so a 1200 baud rate is more than adequate to keep up with a human hand and/or ear. The WinKeyer 3 supports 9600 baud, and I've been successful getting that integrated into the design. Unfortunately, there's a boatload of existing software that only expects to see 1200 baud so the migration to 9600 is a work in process and not well supported at the present. Also, gear using earlier WinKeyer and WinKeyer2 chips only supports 1200 baud. Hence the need for a USB port that works at 1200 baud. Once I'm past the initial interface, I can reframe the rate to whatever I want/need. At least that's the plan. -- Courtney KD6X