The time had come! The brain of the project will be growing from now on, no excuses left!
Combining all the possible instructions of the microcontroller to achieve the desired behaviour can be tough. That's why the goal of this week is to learn the basics about microcontroller programming.
In order to do that, I read the full datasheet of the ATmega168A. There I learned about the architecture and its possibilities. Obviously I didn't memorize everything because I know I can take a look at that document in case I need any of the described features.
I had worked with PIC microcontrollers previously, but reading about all its features didn't come as a surprise.
To start a program from scratch is always a tough job, but if you are not 100% sure that the hardware that is going to support that program is working as expected, the process can become frustrating. Where's the error? Is it on the board? Could it be in the software?, or... just everywhere?!
That's why I decided to start programming the board using the echo example, as Neil suggested. Everything behaved as expected. In a few minutes the board was answering to the keystrokes through the serial port.
Loading the program was as easy as executing the makefile with the "program-usbtiny" parameter and waiting until it was loaded in the microcontroller.
To take it one step further, I analyzed the code of the serial example with interruptions. Once I understood the configuration section and how everything worked, I started playing around with the instructions.
Now, each time a keystroke is sent to the microcontroller through the serial port, it sends the whole buffer and the led blinks. If the board button is pressed, the led blinks, a "Pressed" word is sent through the serial port, and the buffer is erased. From then on, the user can send a new sentence to the microcontroller without overlapping it with the one before.
Initially everything seemed to work fine, but after a few keystrokes I realized that some strange characters were being sent and received through the serial port. After some research I got to the conclusion that my program was not being correctly synchronized with the serial port of my computer. Changing and reordering some instructions solved the problem, or at least that's what I thought.
That solution (without having to change the model of the microcontroller or the pins of the components) made me realize that the synchronization issue was not a trivial problem to solve; if I changed the instruction order, the serial port may read/write incorrect values.
Anyhow I didn't like the solution. It should work regardless of the instruction order.
Finally, I got to the conclusion that the serial buffer was not empty. I changed the code to send an empty char (0) before sending the whole array. That worked perfectly, the program works even changing the order of some of the commands.
In the example above I was using the PCINT0_vect to manage the interruption of the on-board button. Luckily, last week I added two extra sockets in order to use the free ports if needed. Using a true hole button and a protoboard, I wrote a program that controls the falling and/or rising edges of the button connected to the INT0 pin. Using that information, the program blinks a led.
Generating a controlled output signal might be useful in a near future to control output devices such us stepper motors. Therefore, I decided to spend some time understanding the Attiny44 timers.
This program uses a CTC timer to make two leds blink. One connected to the OC0A and OC0B ports. Additionally, it triggers an interruption that increases the OCR0A counter. This way the time between blinks varies. Once OCR0A reaches the 0xFF value, its value is changed to 0.
Both leds were blinking too fast to be appreciated by a human eye. I changed the fuses to divide the clock by 8.
Using a PWM modulation, I wrote a program that changes the intensity of a led (connected to the OC0A pin) when a button is pressed.
Another interesting language to program the microcontroller is assembler.
Using assembler instructions the programmer can control and explode all the microcontroller possibilities, and optimize the code. On the other hand, the programming process can become tougher and frustrating.
In order to get familiar with this language and microprocessor I decided to create a very simple program that turns on and off a led while pressing the button. This can be done within a loop or using interruptions.
My first approach was to use a loop, but I finally used an interrupt.
At first sight, I knew that my project would need to use serial communications quite often. Taking into consideration the problems I faced with the echo example, the ATtiny44 might not be my best chance to develop the project.
The ATmega168 is. So let's build an Arduino board. I will be using the Fabkit model by now.
Once again the letters of the FabKit board were not milled as expected,... I will go on trying to solve that problem.
To check that everything works as expected, I loaded a very simple program (based on Neil's one) that makes the led blink as many times as the iteration of the loop that is being run.
This program made me realize that there was a problem: the led was not blinking. After reading multiple times the code and making sure that everything was OK, I got to the conclusion that there must have been a hardware error: the led was not pointing to the right direction. Once I fixed that problem, it started blinking properly.
I wanted to install the Arduino Bootloader. After configuring the IDE as described in the FabKit tutorial the bootloader was correctly uploaded. But when I tried to load the Blink example... I got an error:
avrdude stk500_getsync() not in sync resp=0x00
This error was a complete nightmare. Searching the Internet, the "solutions" I found were not fixing the problem. After trying to load the Bootloader and the program in several computers and getting always the same error, I solved the problem by running the Arduino IDE as the system administrator. To do that in MAC OS X (I am currently using OS X 10.10 - Yosemite) the executed command is:
~$ sudo /Applications/Arduino.app/Contents/MacOS/JavaAppLauncher
Then, the Bootloader and the program were loaded correctly. The strangest thing is that I don't have to open the IDE as administrator any more. Since I did that once, everything seems to be working perfectly.