torsdag den 11. december 2014

Embedded Hello World

In my previous post, I showed you how to set up the tool chain for programming the raw AtMega328p that is on the Arduino platform. Now this can also be used with other chips from the AVR family. All you have to do is to change the appropriate variable in the Makefile.

This time I will go through a "Hello World" kind of programming example to show what is needed to get the chip to do something. The embedded software version of 'Hello World' is making an LED blink, so this is what I'll do here.

I will assume that you have the Arduino hardware platform at hand, so in order not to add any hardware to that, I will use the LED attached to 'pin 13' as the blinking on. As the pin numbering on the Arduino platform is specific to that PCB, we will need to translate that into the pin numbering of the actual chip. To do that we will need the schematic of the PCB. For my examples I will use the Arduino Duemilanove - a board I had lying around from previous projects.

The schematics are found here.

Another important document to get a hold of the datasheet for the microcontroller. That will tell you all the nitty gritty details about the specific chip. I found one at Atmel, that makes these chips.

The code

Getting down to business, out "Hello World" example is seen below:
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    // Set Port B pins as all outputs
    DDRB = 0xff;

    while(1)
    {
        // Sets pin 5 of port B
        PORTB |= _BV(5); 
        // waits 500 ms
        _delay_ms(500);
        // Resets pin 5 of port B
        PORTB &= ~(_BV(5));
        // Waits 1000 ms
        _delay_ms(1000);
    }

    return 0;
}
According to the schematic, 'pin 13' of the Arduino Board corresponds to pin 19 of the Atmega328p chip, which in turn is pin 5 of Port B. In the code we are doing things with just this port and pin.

From the top of the code, we first include the specific headers:
  • avr/io.h: defines a lot of useful constants and macros for AVR chips.
  • util/delay.h: provides the delay function.
The defines used in this code is as follows:
  1. DDRB: Data direction register for port B
  2. PORTB: Data register for port B
  3. _BV(val): Returns an 8 bit binary value with the 'val' bit set. EG. _BV(5) returns b00100000
For simplicity I have set all the pins of port B to outputs. You can set them individually if needed. This is seen in the way I set and reset the pin connected to the LED. With the OR and AND operations in combination with the _BV() macro, I only 'touch' that single bit.

And with the while(1)-loop, the microcontroller just keeps on blinking. Unlike a PC-apps, endless loops are good in embedded systems - if they were not there, the device would just stop working and had to be reset after each run.

Set and reset of pins

Every time you want to change the state of one output pin you have to change the state of a group of pins called a port. A port in this case is 8-bit 'wide'. This means that every time you want to change one pit, you have to write 8 bit to a register. THis is where the _BV() macro comes in handy. However you have to apply the changes in a certain way as to not change the entire register. In the code snippet, I've applied the changes using logical operations.

For setting an output pin to logical 1 (one) we use the OR-operation with the output of the _BV() macro. This way we're sure that it's set to 1 regardless of the previous state, but we don't touch the other pins. The _BV() output is used as a so called bitmask to achieve the desired effect.

For setting an output pin to logical 0 (zero) we use the AND-operation, but this time we have to invert the output of the _BV() operation. If we want to reset pin 5 as in the code above we have to apply b'11011111' to the port with the AND operation. This effectively sets pin 5 to 0 and leaves the rest as is.

For further explenation of the bitwise operations check out Wikipedia.

This was only a small example of what is possible with microcontrollers. To really exploit them, it takes an in depth knowledge of the different hardware components in the available chip - and in the surrounding electronic circuitry. In later posts I will show how to use these different hardware components as different ways to turn on that LED.

fredag den 28. november 2014

Arduino without the bootloader.

Like me, you might have been playing around with the Arduino and found it rather fun and/or interesting to write code to tell how the little platform should act. Maybe with a sensor and an LCD display to show the read out or you might have used it to control a little car or something else with a motor or servo. The Arduino is a great way to get started fairly easy with microcontrollers like the Atmega328 that is on the Arduino printed circuit board. With the inspiration from Processing the guys behind Arduino has made it easy with a few lines of code quickly to get functionality up and running.

After a while you might want to dig deeper and control all those hardware goodies in the Atmega328 chip yourself without the help of the Arduino and the bootloader. Oh well, you might just have run out of memory in your projects and want to get rid of the bootloader.

Good thing there is a way to program the AVR chip without the bootloader then. However this takes a bit more effort and a different way of talking to the chip via USB. Here's how I do it in Arch Linux - but it may apply to Debian based Linux distros as well.

The following assumes knowledge on how to use the terminal as most commands is executed there.

The programmer

First off you need to get a programmer to put the software in your chip. There are a lot of different devices out there, but I decided to get the USBtinyISP from Lady Ada.
Picture courtesy of www.ladyada.net
This programmer comes as a kit so it takes a bit of soldering, but it's cheap and some times that's what counts. It works great just the same.

To make this programmer work without superuser privileges you need to make file with the following contents only:
SUBSYSTEM=="usb",ATTRS{idVendor}=="1781",ATTRS{idProduct}=="0c9f",GROUP="users",MODE="0666"
In my case I've named it 'arduino.rules'. You can name it what you want, but it has to end on .rules . This file is then put in the /etc/udev/rules.d/ folder. You will need to be root for this operation.
This file is used by the system to decide what to do with a device that matches those attributes. In this case it grants the rights of '0666' to the users in the group 'users'. So make sure your own user account is a member of that user group - or change it to your liking. A further explanation on the contents of this file can be found here.

The makefile

In a Linux environment you have a nifty tool called make. This program executes a set of commands listed in a file called makefile or Makefile. For programming the Atmega328p chip my makefile looks like this:

CC=avr-gcc
UPLOADER = avrdude
CONVERTER = avr-objcopy

FILENAMES = main.c
PROJECT = blinky
MCU = atmega328p # ATmega328 (Arduino)
PROGRAMMER = usptiny

all: compile hex

compile:
    @echo "Cross compiling..."
    $(CC) -Wall -mmcu=$(MCU) -Os -D F_CPU=16000000 $ $(FILENAMES) -o $(PROJECT).out
    @echo "Done compiling"

hex: $(PROJECT).out
    @echo "Converting to hex..."
    $(CONVERTER) -j .text -j .data -O ihex $(PROJECT).out $(PROJECT).hex
    @echo "Done converting"

upload: $(PROJECT).hex
    avrdude -c usbtiny -P usb -p m328p -U flash:w:$(PROJECT).hex:i

clean: *.out *.hex
    @echo "Cleaning project...."
    rm *.out *.hex


(For a tutorial on makefiles look here.)

The above makefile shows the use of avr-gcc, avrdude and avr-objcopy. These tools can be optained by issueing the following command:
sudo pacman -S avrdude gcc-avr avr-libc
These are also dependencies of the Arduino IDE, so if you already have this up and running the makefile should run.






This makefile uses avr-gcc to compile the main.c file specifically for the selected microcontroller with the selected clock frequency. It is then converted to .hex file using avr-objcopy. This makes it ready for upload to the MCU - a task which is handled by avrdude.

The updated makefile is found at my GitHub page


We are now ready to move on to actual programming which will be described in the next post.

søndag den 22. april 2012

Popup panel with Sencha Touch 2

So I started working on a webapp with a JavaScript framework called Sencha Touch 2. As this version is fairly new - I believe it was released within the past 3-6 months - people are still trying to figure it out. At least I am. With only a week of experience with this framework I am not an expert, but I will allow myself to present an example I've spent a couple of days searching the web for the right way to do and now I think I've figured out the 'Sencha Touch 2'-way of doing it.

What I'm talking about is popup box. If you need some quick input from the user, but don't want to spend a part of the original user interface on a textbox or selection list or whatever that are only needed on a rare basis, this kind of popup are a great way to go. With the MVC-model that are used in Sencha Touch 2 there are certain steps that needs to be done for it to work.

The goal of this example is to make a custom panel appear with the click/tap of a button and then make it go away by clicking/tapping with a button on that panel. So here's how I did:

In this example I've started with the most basic app created using the Sencha SDK Tool by entering the following command in my Command Prompt.
sencha generate app <appname> <path\to\app>
 The use of this tool is described in the 'Getting Started' video at www.sencha.com.
When that's up and running I stripped it down to the bare minimum leaving only the start view in a Home.js file and saw that that was good. I then added a button to the home screen like this:

1:  {  
2:     xtype: 'button',  
3:     text: 'View Pop up',  
4:     action: 'showPopup',  
5:  }  

Note the use of the action config that we will be using later. That is all that it takes in the view. No more is needed in that file at all.

Next I made the panel that will be appear when clicking/tapping that button. The code looks like this:


1:  Ext.define('GS.view.Popup',{  
2:    extend: 'Ext.form.Panel',  
3:      
4:    xtype: 'popupbox',  
5:      
6:    config:{  
7:      itemId: 'popbox',  
8:      floating: true,  
9:      centered: true,  
10:     modal: true,  
11:     height: 200,  
12:     width: 300,  
13:     showAnimation: { type: 'slide', direction: 'left'},  
14:     styleHtmlContent: true,  
15:     html: 'Hi, I\'m a popup',  
16:     items:[  
17:       {  
18:         xtype: 'button',  
19:         action: 'hide',  
20:         text: 'Close',  
21:         ui: 'confirm',  
22:         docked: 'bottom',  
23:       }  
24:     ]  
25:    }  
26:  });  

Worth noting here is modal that greys out the area around the popup making it inaccessible and showAnimation, that tells how the popup will appear on the screen. I've decided it to slide in from the right going left. Again the button has an action. Also note the itemId that will be used to reference the panel, when we need it. After adding this panel to the list of views in app.js we can turn our attention to the interesting part: adding a controller to the party and make it do stuff.

First we add a file to the controller folder. I named mine Main.js, Then add the line:

1:  controllers: ['Main'],  

to the app.js file just above the views. Now the application knows about your controller and you can begin adding code to the controller file. Let's take it one bite at a time. The first part of the controller file looks like this:

1:  Ext.define('GS.controller.Main',{  
2:      extend: 'Ext.app.Controller',  
3:      config:{  
4:          refs:  
5:              {  
6:                  popup: {  
7:                      selector: 'formpanel #popbox',  
8:                      xtype: 'popupbox',  
9:                      autoCreate: true,  
10:                  }  
11:              }  
12:      },  

The refs uses ComponentQuery with the selector to search for a reference to given component - here its our popup. With the autoCreate it checks if it's been created before it's used, if not it will be created.
In the next part we make use of the action configs from before:

1:      init: function() {  
2:          this.control({  
3:              'button[action=showPopup]': {  
4:                  tap: 'showPopup'  
5:              },  
Feel free to comment
6:              'button[action=hide]':{  
7:                  tap: 'hide'  
8:              }  
9:          });  
10:      },  

Here we initiates the controller by setting up listeners to the two buttons with the specific actions to listen for the tap event on those buttons. When tapped it will execute the functions shown below.

1:      showPopup: function(){  
2:          var popup = this.getPopup();  
3:          Ext.Viewport.add(popup);  
4:          popup.show();  
5:      },  
6:        
7:      hide: function(){  
8:          var popup = this.getPopup();  
9:          popup.hide({type: 'slideOut', direction: 'right'});  
10:      }  
11:  });  

Both functions uses the autogenerated getter method to retrieve a reference to the popup panel. In the show function the panel gets added to the Viewport and then show()'ed. In the hide function it is hidden  with the selected animation. For some reason the show animation needs to be a config in the panel, but the hide animation is an argument to the hide method. If you have a reason for this feel free to comment on it :)

That's all there is too it and should give the following result:
Screenshot of app without popup

Screenshot of app showing the popup

torsdag den 29. september 2011

Meeting Hub part 2: Software

In the previous post I talked about the 4x4x4 LED cube. This post will be about the software to drive the LED cube from an Arduino. I will assume you know about connecting your Arduino board to a computer and transfer programming code from the Arduino IDE to the board through the USB-interface.

The connection to the LED cube is via a serial-to-parallel shiftregister. This is a way to handle lots of connections with only a few outputs from the microcontroller - in this case the Arduino. I use the 74HC595 shiftregister as described in this tutorial. Using two cascaded shiftregisters means you will have to use the shiftOut command two times in succession in order to service all 16 outputs.

As mentioned in the previous post we will use the concept of multiplexing to light up all the LEDs. This means we will turn on one layer at a time so fast you can't see the switching. The sequence in my code is as follows:

  1. Turn off LEDS
  2. shiftOut 2 times for all 16 LEDs in the layer - setting high the wanted LEDs
  3. Turn on the given layer by pulling the common cathode low.
  4. wait a bit
  5. start over.
With the configuration of the LEDs in the cube an LED will light when a HIGH is set on the data output (the 2 bytes shifted out) and a LOW set on the Layer Select bits (separate output).
I've put this sequence in a function of its own that will 'repaint' the 'image' on the cube a given amount of time - void setCube(int* image, int repeats) This also takes the 'image' as a parameter which is a pointer to an array of 4 integers that tells which LEDs to turn on in the cube. An integer for each layer.

With this it is now possible to visualize any pattern on the 4x4x4 cube. Let your imagination get to work :)

Demo source code is given as an Arduino sketch
Below is a video of the demo sketch in action.

fredag den 16. september 2011

Meeting Hub part 1: LED cube 4x4x4

A week ago I was at the amazing hackerspace conference Meeting Hub #1 at Platform 4, Aalborg, Denmark. This great venue for art & technology and other geeks :) Among other thing it's housing the local hackerspace www.hal9k.com.
This weekend I took part as a drop-in hacker in the Open Hackerspace they've made available. It was a great opportunity to experience what the concept of hacking and the spirit of a hackerspace was all about. And I did enjoy my time there and met a lot of new people. Maybe I'll see them again.
To honor some requests about the documentation on my project their I opened this blog and this time I will post the hardware for the 4x4x4 LED cube. This is inspired by the youtube post from Make Magezine about an LED cube. Theirs is only 3x3x3 but the concept is sort of the same. The schematics is posted below both as a png-file and an eagle-file. The ladder makes it easy to modifiable.
The circuit consists of a couple of cascaded serial to parrallel shift-register. This means they are connected to make the parallel output flow from one to the next to make it serial input with 16-bit parallel outputs. Each output will in turn drive an LED through a resistor. I've chosen a 270 Ohms resistor to limit the current on each output to 10 milliAmps(mA).
In the schematics I've only included one layer of LEDs. Obviously you will have to make 4 of such layers as described in the youtube-video from Make. SL1 in the schematic will connect to the common cathode of each layer and turn it on. As and LED only lights up when the current flows one way through it the cathode needs to be set LOW in order to make the given layer light up. This concept will be described in a later post about the software. For now all you need to know is which resistor value you need. This depends on your kind of LED and how much current you want to run through them. According to the datasheet this should be around 20 mA but just to be on the safe side choose a bit lower :)

In my setup I have a 270 Ohms resistor to limit the current to around 10mA. This is found by way of Ohms. Your LEDs might require a different a different value, but a good rule of thumb suggest that an LED takes a 2VDC voltage drop which leaves 3 V for the resistor when a 5VDC supply voltage is applied. But please consult your datasheet of your LEDs to make certain. Better safe than sorry :)

To follow the concept of multiplexing the output of the shift registers is connected to the anode of each LED (or resistor in this case but it's the same side of the LED) and the cathode is connected together for each layer to make it possible to select each layer. That's why SL1 is not fully connected.

This will hook up nicely with the Arduino or any microcontroller circuit with 7 pins to control it: 3 for controlling the shift registers (SL2) and one for each layer from SL1. More on these connections and how to use them in the next post where I will be talking about the software to control the LED-cube.

Please feel free to post any relevant questions if you have any.

... and get out there and make something.

Here's the schematic for Eagle.
ledcube.sch

søndag den 11. september 2011

Introduction

Welcome to my blog.
Here I will be describing geekeries of any kind related to software programming and electronics and things in between.