Hello again from the land of audio ones and zeros.
I am continuing to move away from using the Arduino IDE for my microcontroller programming needs.
This time I continue to move towards a more "pure C" approach. I mostly am doing this to learn how processors, microcontrollers and peripherals work "at a deep level"; Arduino's IDE sometimes shields you from that.
The move to C won't necessarily save time or make projects easier to finish however. The AudioDiWHY mantra: why make things easy?
I began this learning process a long time ago--post here.
For this pursuit I am using Arduino Unos and Atmel Studio 7 as well as an Atmel ICE programmer.
Leaving the Arduino IDE we quickly see something new (for me anyway): learning C programming is hard! Pointers? References? Registers? Mallocs? Dereferencing? Ampersands? .h files. At first, you have to love it. No one else will.
But like most other things, once you're in the pool, things start to warm up.
I have decided to try to write my own library for I2C....I can use one that's already done (e.g. here) but it is more educational to write my own or at least modify an existing one to the point I can understand how it--and I2C--works. Update: 2-24-21 libraries are done, or at least work for the basics. See the post here.
|
Clockwise: Bona-Fide Uno, Atmel Ice Programmer, Sacrificial Uno Clono |
I didn't get far. Early on in this process I bricked my first Uno. I messed with its fuses (info here--be careful) and yes, it stopped working and could no longer be programmed.
Much swearing ensued, and then I realized--why am I cursing? It turns out I had a few extra 328P's, and the clone used a through hole IC (so, I got lucky, I could just remove the dead chip with a chip puller and put in a new one).
Fixed!
Can I save the broken MPU? Probably, information about that (for ATTINY anyway) is here. Is it worth the time? The blown up MPU is a USD$2.50 part. Nope.
(Which begs the question: why the tantrums? It must be other things in my life right (like Covid?) Can I blame it on my parents? Why not. Growing up my dad worked on cars all the time and was constantly swearing at them, kicking them, getting in a terrible mood because of them. And he loves cars! WTF? Whatever. It was how he rolled, but for me, it serves no purpose; it's not cathartic and it makes me a way worse tech.)
Enough!
OK on to the next problem. After working perfectly for a few days, the Clone Uno's UART stopped working. Why? well it could be a lot of things, perhaps related to aforementioned fuse issues, but maybe not.
I want to fix this logically.
For starters, maybe it's not the microcontroller at all. Is it the terminal program (TeraTerm: good program, free, here) I am using?
Hooking up a few known good UART devices into the PC running TeraTerm--yields, at best, mixed results. Sometime I saw data in the terminal output, sometimes not. The program should run without issue 100% of the time. So yes, that might be it.
I booted my old Linux system, here, I know Putty works on the laptop...but the old laptop won't boot. Overall not my day. I'll fix that later.
Back to the W10 system. Welcome to Microsoft Windows hell, where everything that could be easy isn't....these guys are too smart for their own good and light cigars with $500 bills. Sometimes I'd get cryptic messages like "you don't have rights to use COM port 20", even when running TeraTerm with full rights. This one got me stuck for a bit. COM20? Why isn't Tera Term using COM3?
In windows you use Device Manager to change your COM port configuration but that appeared to be no help until I found the webpage here. You have to show "hidden devices" to delete or modify the "invisible COM ports".
So: run device manager (start > run > devmgmt.msc) and then "View > hidden devices". Yes, I had 18--count 'em--18 hidden com ports. Right click > Deleted them.
Wow, that felt good.
Plugged back in the UNO. COM3! Yes!!!!! Now find the COM port in device manager: right click > Port Settings tab > Advanced. I can change the COM port number now.
To make sure it all worked, I set the Uno's USB serial port from COM3 to COM4. Yes, that works too, so this is fixed.
|
You need device manager's "advanced properties" to show you your stale COM ports. |
So why did this COM20 setting occur? Speculation: I must have messed up my com ports while experimenting with FDTI chips (post
here).
OK, TeraTerm and my COM port configuration are fixed. Does everything work now? No! The Windows term program works again, but UART on the Uno clone still doesn't work.
Looking at the UART output with Sigrok Pulseview--post about getting Pulseview working is
here--right off the pins on the UNO clone--the UART signals from the microcontroller appear to be OK. But out of the UNO's USB port it is still broken.
To fix that's let's look at how the UNO works for serial communication. A geniuine UNO board has a second atmel MPU: a
16u2, to do its USB to serial conversion. So there are 2 MPUs on an Uno, and the 16u2 is there primarily to convert USB to serial. I didn't know this; so is it an issue with the 16u2?
I don't know how to check that. There is an ICSP connector for the 16u2, but if I brick this 2nd CPU I have no idea how I'd fix it, and I need to keep moving here. Maybe I messed up the UART on the 328P <> 16u2 when screwing around with my newbie C I2C code?
OK, let's send everything back to stock Arduino using Atmel Studio. If the USB serial signal works in an Arduino environment it might tell us something more about our issue. And: Burning the Arduino bootloader and setting the 16u2 and 328P MPUs back to their initial Arduino settings is a good thing to know how to do.
Turns out with Atmel Ice, and maybe other programmers, it's not hard. Good video describing how to do this is
here.
You hook the Atmel ice programmer (ICE is a different programmer than the programmer in the video but the process is exactly the same) up to the UNO, then flash the appropriate optiboot*.hex file into it.
OK where do you find the optiboot hex file? For me, on my Windows 10 system, it was here:
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\arduino\avr\bootloaders\optiboot\optiboot_atmega328.hex
But you knew that right?
Anyway: using Atmel Studio, flash the UNO and then choose the above hex file. That gets Arduino bootloader back into the microprocessor.
And: Remember that 0 (no X below) is active with AVR fuses! You knew this as well right?
UNO ARDUINO FUSE SETTINGS:
BODLEVEL = 2V7
RSTDISBL = [ ]
DWEN = [ ]
SPIEN = [X]
WDTON = [ ]
EESAVE = [ ]
BOOTSZ = 256W_3F00
BOOTRST = [X]
<--HAD TO CHANGE THIS; use Optiboot bootloader
CKDIV8 = [ ] <--HAD TO CHANGE THIS; Uno expects /8 clock
CKOUT = [ ]
SUT_CKSEL = EXTXOSC_8MHZ_XX_16KCK_14CK_65MS <--HAD TO CHANGE THIS; use external Crystal on Uno board
EXTENDED = 0xFD (valid)
HIGH = 0xDE (valid)
LOW = 0xFF (valid)
With that done, the UNO clone works again as an Arduino....good. Lesson learned: if you use an UNO to practice Pure C programming, make sure it has a PDIP chip (some use SMD, not easy to replace) so if you "brick" the chip you can swap in a new one easily.
I can run a serial test ino file, and now I can see serial out in the TeraTerm program. Fixed!
So we know the hardware is OK.
Let's try running test code again using some "pure C" UART code from Atmel studio. Ha!!!
Works now! Simple C serial UART test code for Atmel Studio, targeting an UNO, where printf()'s will show up on your serial terminal program set to 8N1, is posted here. You can use that to test your setup if you ever want to experiment with UARTS, Atmel microcontrollers, and AVR C.
BTW The SPI > serial arduino bootloader/hardware/dual MPU UNO paradigm is complex, more so than I realized when I started this project. Read more
here. Interesting.
And, happy day: Keeping kool I fixed my ancient Linux system as well, but that's outside the
scope of AudioDiWhy. Putty works again.....the clone UNO to Linux putty works again as well.....here's a poor photo of the term and MPU UART at work:
|
Nice to see text on the right! I was lost, now I'm found. |
Finally I needed to get debugging working. Inline bebugging (good vid is the concept is
here) is not well implemented in the Arduino IDE, so I have been using Atmel's setup for this for a long time now....Atmel uses a proprietary debugging protocol called "
Debugwire" for inline debugging for some of their chips. Compare this to industry standard,
JTAG--which isn't supported on an UNO.
Sadly DebugWire is not well documented for us makers--e.g.: good luck finding an Atmel document saying how the protocol is laid out. But it is still useful once set up correctly.
Getting this going for a newbie like me was a bit terrifying at first because I read all over that it's easy to brick your UNO with DebugWire. But again--the Atmel 328P is a $2.50 part. If I blow it up so be it. It's the cost of learning how this technology really works.
Here's how to get DebugWire going.
On my Uno clone I had to cut the trace you see below; debugwire won't work without this trace cut.
that's it--other than this, you can use DebugWire to program and debug an UNO without issue.
|
DeBugWire works with the indicated trace cut, but Arduino IDE won't. |
Really good blog post about the hardware mod for this
here. A takeaway: You get into Atmel Studio as always, but choose "DebugWIRE" as your tools for Atmel studio and not "ISP".
Here is how to do that:
First make sure your project builds without errors.
Once that's done, in Atmel Studio 7, left double click on the project you want to debug in solution explorer (by default "solution explorer" is the column on the right). A set of tools appears in a column on the left.
Click on "build" then, choose your programmer. Then from the dropdown to the right of that, choose "DebugWire". Click OK.
The software will ask you if you want to change your fuse settings; terrifying! But let the software do this for you. For me, it works. And--when you are done w/ debugwire make sure to switch back to normal ICSP programming mode again ("debug > Disable DebugWIRE and disconnect"). This resets the fuses back to how they were.
You can only get out of debugWire when you are in debugwire....otherwise this option isn't available. So I try to always end my DebugWire session after I am done debugging, otherwise things get confusing.
BTW: If you want to use the UNO for Arduino again you have to reconnect the trace you just cut and reburn the bootloader.
Before I did anything the reset trace looked to me like it was already cut, but using a continuity tester, it wasn't. Had to cut it.
With that cut, yep, debug wire works. Followed all the instructions as per the video
here to get basic debugging going. It worked and it's useful, you can see your variable values at breakpoints, as well as see how all registers are set (Debug > windows > IO).
Good luck doing any inline debugging with the Arduino IDE--you can't--so arguably inline debugging alone is reason enough to switch to Atmel studio + Atmel ICE for 328P projects, perhaps.
One more thing: for any sort of logic projects it's useful I think to have LEDs with 330ohm resistors in series in your junk box. I have found myself using these frequently when doing the above MPU/MCU bench work. Instead of having to breadboard dumb LED/resistor pairs every time, I built 10 of these on a single perf board. This took maybe 20 minutes and has saved a lot of time since.
|
"You need Schoolin" |
OK, onward to my I2C library....time to brick something again.....then back to zero. Ons and Offs! How much work could this be? The main takeaway for me this time: getting upset about an electronics issue makes no sense. Keep cool, take breaks, and figure it out. The sun will come up tomorrow regardless. See ya next time.