This article is in a series about making a shelf with lights controlled by an AVR. Read about - designing and building the book-case - understanding Mosfets - and coding the AVR, and improving it using Atmel Studio
A returning stick in my wheels of programming is the lack of a decent step by step debugger. Often I fly off a mental cliff wondering what hit me, and how I caused this mess.
My previous setup with Notepad++, AVRDude and ArduinoISP worked well, but wouldn’t let me go through my code step by step to evaluate and debug. I found that Atmel Studio has step by step debugging of code. Since the cheap and versatile Atmega168 chips use are from the same manufacturer, I gave the free Atmel Studio a try.
The coding environment is a little slow at startup, but does the work elegantly. It has nice color codings for C, and it has quick setup features to get going with making. Atmel studio is based on Microsoft Visual Studio Express 2010, which I am familiar with from some game programming in Python and C#. So with the already mentioned debug function built in, this is a better tool than my previous setup.
But Microsoft Visual Studio takes care of the C coding and the color layout, the big feature of Atmel Studio is the parts library, readily available datasheets, and the Simulator. The simulator shows every register in the chip, and indicates if a bit is set or zero, and if it changed in the latest clock cycle. The parts library I haven’t dived into as I am quite satisfied with the Atmega168 for now, and I’m used to look for datasheets online anyway, so the biggest feature for me (without looking for more features) is the simulator, which I will talk more about.
I do appreciate the strong datasheets for the Atmega AVR’s, but nothing beats seeing every change that occurs in the processor as the code progresses, in terms of understanding (not in terms of speed). Let’s bring in my shelf light project to show better how the simulator helped me.
PWM fader
Preparing for the Wife Acceptance Test (WAT) of my homemade shelf, built after the expensive one she wants to buy, adding a fade function to my shelf lighting will give me some extra points, and increase the chances of my shelf (and AVR) ending up in the living room.
In my original code, PWM switched the lights to another intensity at every button press. Now I’m adding a gradient to the way the lights change. So for a case where I wanted the lights to reduce gently down to a given setting, the code ended up like this:
//set output to medium while(OCR2B > 100){ OCR2B -= 1; _delay_ms(5); }
Now, before I added the _delay_ms(5), I got no fading effect of the lights. I checked the datasheet over and over again, and looked at other peoples code, but I could not see how my code differed from anyone else, or why my code failed.
In the Atmel Studio Simulator I can see what happens every tick of time in the CPU (and timers), and I found that the OCR2B register is only updated with a new value whenever the Timer reaches 255 (or zero), to avoid a broken PWM signal. When I set a new OCR2B value for almost every clock tick (it takes some ticks for each while loop), the OCR2B might not be set before the while loop has been run so many times that the fading is over.
I probably wouldn’t have understood this without the visualization from the simulator in Atmel Studio, but I found that the light intensity changed after every fade cycle, when I let the code run freely to wait for a new click on the button. So I clicked my way through 255 timer steps, to get my suspicion verified, to find that the OCR2B register was updated with the value I set only when the timer tipped over from max to min.
The solution was to add a very short delay, to allow the timer to reach to 255 and loop back to zero, and set the new value of OCR2B, and hence fade the light down for every loop.
I haven’t figured out the timer registers fully, there are some flags that can be set and zeroed out, maybe one of these can be used to get a faster setting of the OCR2B register.
The studio feels like home
Atmel Studio has been a very good new friend on my path, where software and hardware merges in an AVR. The visualization from the simulator and the debugger has made coding experience much better. Not that I necessarily make less mistakes, but Atmel Studio equips me with some much clearer glasses in the struggle against deep cliffs and frustrating hours.
BTW: I’m not very fan of using the _delay
function, as it locks the CPU down to doing nothing. In my later code I will try to implement use of the timers built into the Atmega for making breaks, such as wait until the timer1 has counted to 255 10k times before progressing.
BTW2: I can only handle a certain amount of software challenges pr day, so I quickly gave up using the Atmel Studio to run AVRDude and ArduinoISP to burn my code to my chip. Maybe another day I’ll feel braver.