Blink LED program with Atmega328P (Arduino Uno) programmed via Raspberry PI.

I recently began playing with an Atmega328/P since I got some cheap from the internet. Without having experience with programming an Arduino before, I tried to get things going. Here are my findings.

Configuring the environment:

To configure and setup the environment I found 2 excellent resources:

Little things I had to deal with:

avrdude latest version 6.3 (Dec-2016)

Installing from the above package and not from drogon.net as suggested by Alexander Baran-Harper in the youtube video, requires the PIN mapping setup of the programmer section, by editing /usr/local/etc/avrdude.conf or /etc/avrdude.conf. Configuration is found in the first link (oozmaker.com)

Set the SUID bit to the executable

  • Compiling from source:
$ sudo chmod 4755 /usr/local/bin/avrdude
  • Install from package
$ sudo chmod 4755 /usr/bin/avrdude

Also, the two tutorials use different RESET pins in the avrdude.conf file. I chose PIN 8 (CE0) on the Raspberry PI.

Creating the program in C++

We will write our blink LED program in a .cpp file instead of .ino by using the hardware port registers. To read more, check the references section.


#include <util/delay.h>
#include <avr/io.h>
#define LED PB0

int main(void) {
// define PB0 as output, where PB0 is the 14th pin
// on the ATmega328 micro
DDRB |= (1 << LED);

while (1) {
PORTB |= (1 << LED); // switch on
_delay_ms(200);
PORTB &= ~(1 << LED); // switch off
_delay_ms(200);
}
return 0;
}

PORTB maps to Arduino digital pins 8 to 13, physical pins 14 to 19, with PB0 as digital pin 8 or physical pin 14.
The two high bits (6 & 7) map to the crystal pins and are not usable and are set to 0 as below.

PORTB |= (1 << LED);  // sets pin 8(PB0) pin to HIGH
PORTB &= ~(1 << LED);  // forces the corresponding PB0 bit to 0(LOW).
                       // All the other bits are left alone(safe to use).

DDRB is the Port B Data Direction Register which contains 8 bits corresponding to each pin and will set the pins as input (1) or output (0).

DDRB = B00111111;  // sets Arduino pins 8 to 13 as outputs;
DDRB = B00111101;  // sets Arduino pins 8 to 13 as outputs, pin 9 as output;
DDRB |= (1 << LED);  // forces the corresponding PB0 bit to be 1(output). 
                     // All the other bits are left alone(safe to use).

After the code is ready, follows make and upload of the .hex file to ATmega.

Using port manipulation has advantages and disadvantages.

Generally speaking, doing this sort of thing is not a good idea. Why not? Here are a few reasons:

  • The code is much more difficult for you to debug and maintain, and is a lot harder for other people to understand. It only takes a few microseconds for the processor to execute code, but it might take hours for you to figure out why it isn’t working right and fix it! Your time is valuable, right? But the computer’s time is very cheap, measured in the cost of the electricity you feed it. Usually it is much better to write code the most obvious way.
  • The code is less portable. If you use digitalRead() and digitalWrite(), it is much easier to write code that will run on all of the Atmel microcontrollers, whereas the control and port registers can be different on each kind of microcontroller.
  • It is a lot easier to cause unintentional malfunctions with direct port access. Notice how the line DDRD = B11111110; above mentions that it must leave pin 0 as an input pin. Pin 0 is the receive line (RX) on the serial port. It would be very easy to accidentally cause your serial port to stop working by changing pin 0 into an output pin! Now that would be very confusing when you suddenly are unable to receive serial data, wouldn’t it?

So you might be saying to yourself, great, why would I ever want to use this stuff then? Here are some of the positive aspects of direct port access:

  • You may need to be able to turn pins on and off very quickly, meaning within fractions of a microsecond. If you look at the source code in lib/targets/arduino/wiring.c, you will see that digitalRead() and digitalWrite() are each about a dozen or so lines of code, which get compiled into quite a few machine instructions. Each machine instruction requires one clock cycle at 16MHz, which can add up in time-sensitive applications. Direct port access can do the same job in a lot fewer clock cycles.
  • Sometimes you might need to set multiple output pins at exactly the same time. Calling digitalWrite(10,HIGH); followed by digitalWrite(11,HIGH); will cause pin 10 to go HIGH several microseconds before pin 11, which may confuse certain time-sensitive external digital circuits you have hooked up. Alternatively, you could set both pins high at exactly the same moment in time using PORTB |= B1100;
  • If you are running low on program memory, you can use these tricks to make your code smaller. It requires a lot fewer bytes of compiled code to simultaneously write a bunch of hardware pins simultaneously via the port registers than it would using a for loop to set each pin separately. In some cases, this might make the difference between your program fitting in flash memory or not!

References

Arduino hardware port registers
Arduino port manipulation

Advertisements

Piss against the rain

Working, visiting friends, spending quality time, going for some beers after an afternoon of drinking tea and all this crap… just decisions… and after a while, finally you go home. The weather is odd, wind blowing in gusts, few drops of rain falling now and then but increasingly; anyway storm is about to come but you don’t know for sure and when.

You are alone on the street, now and then a car passes by, you keep heading home on foot, confident that you’ll get there dry.

You faced the decision early when your friend told you to get a cab and go home safely, now the only option is to call for one but you feel like the place of no return is passed so you assume you will be fine.

You talked home and you are told that it’s raining so that you are in no position to reject such an opinion, still you keep going on foot.

You keep telling yourself that if you made it this far you can reach home safely.

Suddenly all this becomes a game. You make calculations based on:

  • the weather forecast on your mobile phone;
  • opinions of others, chances that the person from home didn’t look out the window and just heard the wind and the few drops of rain;
  • time to get home, about 30 minutes and discounting;
  • if you call a cab it takes a few minutes and if it starts raining this instant you’ll still get wet;
  • you segment your way home into manageable distances (e.g. from this tree till the next intersection and so on); each step you take and each milestone reached becomes rewarding;
  • in parallel you plan for contingencies and ask yourself: WHAT IF?
  • if it started raining your leather jacket will protect you for a short while so you have to be close from home; your backpack will protect your laptop and tablet the same amount of time;

You start moving faster and faster but this isn’t an effort anymore, it becomes survival. You look around and see that you are alone when everyone is at home comfortably and cozy, but this just isn’t the life for you, because if it were you’ve gottent the cab in the first place; still you enjoy fighting, being alone and struggling. This is pleasure for you, although it could be much easier and faster (at some cost, but without the trouble).

You see some gravel and kick it. The gravel gets inside your shoes, and this bothers you. You stirred the shit and now it’s following you. Deal with it you think, but it’s there a constant reminder not to do it again. You cannot stop to clear it out, you’ll lose all the advantage you have in front of the rain.

You keep going and thinking that if this was business or a relationship, your dedication and devotion would mean something, and felt you’ve earned something and that you deserve it and in some sense you did. You need no audience, you don’t need to prove anything to anyone, you just have to do something based on faith, trusting your assumptions. There is no sacrifice and no real effort in following what you believe in. And you know that if you keep going you’ll get there.

Conclusions:

  • Be judgmental; there’s always a cost when choosing the easiest solution; the hardest as well;
  • When everyone is going defensive or scared about the future, you have the option to be the one who keeps going;
  • When you stir the shit, it will follow you and draw you back;
  • Take risks; there is no guarantee that you reach destination as you planned, but you learn from failure and trying;
  • Listen to everyone, take into consideration and do it your way;
  • Learn from everything;
  • Be happy doing not necessarily succeeding;
  • Work hard;

Now… did it rain? It doesn’t really matter because the question is. Would you do it again? The answer should be YES because you can take all the metrics into account, listen to anyone, and make all the necessary calculations. In the end it’s all about leap of faith, hard work and little bit of luck.

Be ambitious and follow your dreams!