My Pi Description

My Experiences With the Raspberry Pi -- Tracking My Learning -- My Pi Projects

Sunday, January 19, 2014

Gertboard - Programming With ATmega Registers

Arduino IDE Built-in Functions Vrs. Direct Register Programming

Functionally, what is the difference between this script:
and this script:
Answer: NOTHING
Note: In the sketches discussed here, to see if the LEDs on the Gertboard are ON or OFF, PB0 is connected to BUF1, PB1 to BUF2, PB2 to BUF3, PB3 to BUF4, PB4 to BUF5, and PB5 to BUF6.
Both scripts turn LEDs on the Gertboard ON and OFF. First, LEDs 1, 3, and 5 are ON with 2, 4, and 6 OFF. One second later, 1, 3, and 5 are OFF, and 2, 4, and 6 are ON. One second later, the process repeats itself, on and on. The first script uses functions built into the Arduino IDE. While the second script uses the Arduino IDE delay() function, the LEDs are controlled by writing directly to microcontroller registers. The second script is sure a lot shorter and takes up about half of the space in memory. I must admit that it does use a little trick that I'll discuss later. That trick can not be used with the first script. I tried to shorten the first script by using for loops and if/else statements in lines 12 - 27. I gave up because it didn't seem to save lines of code.
The built-in functions that are part of the Arduino IDE are a convenient way to interface with the ATmega I/O pins. The second script shows another method, and that is to communicate directly with registers within the microcontroller associated with those I/O pins. Registers are eight bit bytes that are addressable within the ATmega memory space. In most cases, each bit of a register can be either read or written to. Each bit, or a combination of bits control some function or produce some effect. Before you can deal with these registers you need knowledge of what the registers do. That knowledge comes from the ATmega datasheet from Atmel.
If you are not concerned about writing a few more lines of code or how many bytes get loaded into the microcontroller, what other reasons would there be for programming ATmegta registers? Here are a few reasons:
  • IT'S EASY TO DO. There is a library include file, iom328p.h for the ATmega328P, that defines all of the registers and register pins in exactly the same way that they are named in the datasheet. For example, in the second sketch, the line "DDRB=0b00111111;" correlates directly to 13.4.3 on page 92 of the datasheet. This is the datadirection register for port B. Writing a 1 to the lower six bit positions makes pins PB0 to PB5 outputs. "PORTB=0b00101010;" correlates to 13.4.2 on page 92. This will make PB1, PB3, and PB5 logic high, turning on their respective LEDs. The first line of that second script, "#include <avr/io.h>" looks to see what ATmega chip you are using and, in our case, the ATmega328P. When the script is compiled, the definitions in iom328p.h are used to figure out the locations within the ATmega to access.
  • There are things you can do that are not supported by the built-in functions. For example, even though you can do PWM to control a motor using analogWrite(), you are stuck with one frequency - about 490Hz. If your motor would rather work at 10khz, you can program the counter registers. There are a lot more things you can do or develop yourself. For instance, I wish to develop my own 1-Wire interface for use with my DS18B20 temperature sensors.
  • I found that the function delayMicroseconds() produces delays that area about 2/3 of the correct values. I noticed this first with my camera remote control project. I was looking for a pulse width of 284usec but had to program delayMicroseconds(415) to get 284usec. Testing with an oscilloscope, from a desired delay of 10 to 3000usec, I consistently measured about 67% of the desired value (the delay() function is pretty accurate). So, I plan to write my own function for microsecond delays. There are two 8 bit counter/timers and a 16 bit counter/timer accessible by registers that can be utilized.
  • For me, I like getting closer to the hardware when programming. It makes me feel more in control.
  • Gives me a chance to use those fun bitwise operators like OR, AND, and EXCLUSIVE OR and shift bigs right and shift bits left.
  • Here are most of the ATmega functions that are accessible through registers:
    • I/O Pins, both content, data direction, and pull-up resistors for inputs
    • The various counter timer registers and prescallers for 8 and 16 bit counter/timers. These also control the PWM oscillator functions at the I/O pins
    • SPI control, status, and data registers
    • Registers for the serial communications using the USARTs
    • Registers for the 2-Wire serial interface
    • Analog comparator
    • A to D converter
    • Interrupts
I said I like to use bitwise operators, and the EXCLUSIVE OR operator is the trick I used to make that second script so short. Line 7 turned three of the six LEDs on (PB1, PB3, and PB5). Line 12 is going to toggle those LEDs that are ON to OFF and those that are OFF to ON.
Line 12 uses a compound operator. Recall that =+ is a compound operator. The expression A =+ 1 is the equivalent to A = A + 1. In our line 12, the compound operator is =^ which is an EXCLUSIVE OR. It is the equivalent of PORTB = PORTB ^ 0b001111. The EXCLUSIVE OR compares two bits. If they are the same (both 0 or both 1) the result is a 0. If they are different, the result is a 1. Let's apply that to PORTB which we will assume is 00101010. Putting one number under the other let's see what we get:
  00101010 PORTB
  00111111 EXCLUSIVE OR with this binary number
  00010101 NEW PORTB value
Let's do that again:
  00010101 PORTB
  00111111 EXCLUSIVE OR with this binary number
  00101010 NEW PORTB value
Note we are back to where we started. I hope you can see that this operation will toggle the six LEDs ON and OFF.

Another Sketch Writing To I/O Pins

I would like to introduce another sketch. This one uses four bitwise operators. Between the two sketches we will have used all of the bitwise operators except for the shift right.
This sketch uses the same six LEDs on the Gertboard except only one LED is lit at any one time. It starts with all LEDs OFF, then lights each LED for one second starting with the LED connected to pin PB0. Each LED, down the line, is ON for one second. One second after PB5 is lit, the sequence starts over again at PB0.
Let's take a look at line 12. Here we have two bitwise operators, an OR compound operator, |=, and a SHIFT LEFT, operator, <<. If you are not familiar with this type of notation it surely looks strange.
Line 12 means we are going to take the current contents of the register PORTB, the register connected to pins PB0 through PB5, and OR them with some value so that PORTB is changed. I'll talk about what OR means in a minute. For now, the question is: what is that value we are going to use to change the contents of PORTB? Why, it is (1 << PORTB0), of course. What?? What does that mean? If you look into the include file, iom328p.h, (called by avr/io.h, the first line in the sketch) you will find that PORTB0 is defined as 0. In like manner, PORTB5 is defined as 5. You can see the pattern here. So, (1 << PORTB0) becomes (1 << 0). That means we take the number 1 and shift it left 0 times. That seems to make even less sense. It begins to make sense, however, if we look at 1 as 00000001. Nothing much happens to it if we shift it 0 times as in line 12 of the sketch. But, what about similar line 32. This means we shift 1 left by 5. Just move that 1 over 5 places to the left. This new value now becomes 00100000. Get it?
Now, we can talk about the OR operator. When we OR two binary digits, if either digit is a 1, the resulting value is a 1. A 0 result only corresponds to both digits being 0. So, if we started out with PORTB as 0b00000000 (all LEDs OFF) let's apply sketch line 12 and see what happens.
  00000000 PORTB
  00000001 OR with this binary number
  00000001 NEW PORTB value
This obviously turns the LED connected to PB0 ON, and that is the only one on. Now we wait one second and move on to sketch line 15, which is similar to line 12, except that the |= is replaced by &=, the AND compound operator. And, (1 << PORTB0) is now: !(1 << PORTB0). The exclamation point is the NOT symbol, for negation, another bitwise operator. We know that (1 << PORTB0) is 00000001. What then is !(00000001)? The answer is 11111110. Every bit is changed to its complement (1 becomes 0, 0 becomes 1).
The AND bitwise operator takes two bits and if either is a 0, or both are 0, the result will be a 0. The only way to get a 1 is if both bits are 1. So let's AND the contents of PORTB, 00000001, with 11111110:
  00000001 PORTB
  11111110 AND with this binary number
  00000000 NEW PORTB value
This turns the PB0 LED OFF. Obviously we could have written PORTB = 0; with the same effect, but what is the learning value in that? If you follow the logic you can see where sketch line 16, and beyond, turns the LED connected to PB1 one, for a second, before turning it off, and turning the next LED on, etc., etc.
Controlling those LEDs the way I did in that last sketch is rather silly. Lines 12 through 35 could have been written as:
PORTB = 0b00000001;
DELAY(1000);
PORTB = 0b00000010;
DELAY(1000);
      .
      .
      .
PORTB = 0b00100000;
DELAY(1000);
So why did I write all of that extra code? I wanted to illustrate the use of those bitwise functions because they are invaluable when writing to registers and memory. They are an elegant way of accessing individual bits in a field of other bits (our field is 8 bits because all ATmega registers are eight bits long). It's a way of altering some bits while leaving other bits alone. You could keep track of all the bits in a register at all times, but sometimes that is not possible. Other processes, either hardware or software, could change some bits in a register. You only want to access the bits you want to change and leave the others alone.
As you can see from what we have done before, if you wish to make a bit a 1, or assure it is a 1, OR it with a 1. OR the bits you don't want to change with a 0. Look at the example above.
If you wish to make a bit a 0, or assure it is a 0, AND it with a 0 and AND the others with a 1 to leave them alone. If you wish to toggle a bit, changing it from a 0 to a 1, or a 1 to a 0, EXCLUSIVE OR it with a 1, and EXCLUSIVE OR the others with a 0. If you study the examples above you can see how that works.

Sketch To Read From I/O Pins

I talked about writing to I/O pins in the previous sketches, so my last sketch shows an example of reading the logic level of an I/O pin:
This sketch sets pins PC0 to PC5 as inputs. Writing to PORTC will determine if an internal pull-up resistor will be connected to the pin. Writing a 1, connects the pull-ups. So writing 3F, in hexidecimal, writes a 1 to the lower 6 bits of the register.
Every second, the script sends the contents of PINC to the serial monitor running on the Pi. If PORTC is the register that outputs a logic level to the port C I/O pins, PINC is the register that records the logic level of external inputs of the port C I/O pins. If nothing is connected to an external pin, the internal pull-up resistor will set a logic 1 in the corresponding PINC register bit. If you connect that pin to ground, a logic 0 will be set in the register bit. Using the BIN built-in constant, will send the contents of the register in binary format.
If there is nothing connected to any of the port C pins, you will see:
  111111
  111111
  111111
etc.
However, if you connect PC0 to ground, for example, you will see:
  111110
  111110
etc. for as long as the ground is connected.

Wrapup

I hope this has been informative and if you are a beginner that you learned somethings useful.

Saturday, January 11, 2014

Gertboard - Changing ATmega328P Resonator Frequency

In my last post about my Camera Remote Controller project, I said I would discuss changing the ATmega resonator frequency.

Why Change The Frequency

Now why would you want to do that? Here is a good reason why: once you program the ATmega microprocessor via the RaspberryPi/Gertboard programmer you can remove the chip from the Gertboard and install it on your own PCB. That is what I did to make my Camera Remote Control project become useful rather than being a collection of loose parts and connections. Freed from the Gertboard you are no longer restricted to using a 12MHz external frequency source. You could power your project from 5V rather than the Gertboard's 3.3V allowing you to use a 16MHz resonator or a 16MHz crystal. Perhaps you found a script that was written for an Arduino that you would like to use. Most Arduinos run on 16MHz not 12MHz.
I got interested in this question because I stupidly ordered a bunch of 10MHz resonators. I did this because I failed to check the schematics and THOUGHT the resonator was 10MHz, not 12MHz. I discovered my error but figured the camera remote would work OK at 10MHz, so I wondered how the frequency is set.

Importance Of Clock Frequency

I guess I should talk about why the clock frequency is important. It's important if you are doing any timing. Timing is accomplished by using one of the Arduino IDE builtin functions such as delay(), delayMicroseconds(), micros(), and millis(), or by writing your own timing functions. It's also a consideration if you want to have a script work exactly the same on and off the Gertboard. If you have a project where the timing is not critical, and speed is not a factor, you could forget about an external clock source and use one of the ATmega internal clock options. More on this later.

Let's Change The Frequency

OK, if I still have your interest, what do you do if you want to change the clock frequency? Where is the clock frequency set? It is not set by programming any of the fuses or by programming any of the ATmega registers. It is set when you compile your script from whatever makefile is in use. Let's be clear about one thing here, I am talking about writing scripts, compiling them, and uploading them using the Arduino IDE. If that is the case, the makefile seems to be hidden from view. At least, I could not find it. However, there is a way to find out what is going on when you compile a script.
Bring up your Arduino IDE and go to "File/Preferences", then enable "Show verbose output during compilation". Compile any script. You will find it takes much, much longer and a lot of messages scroll by at the bottom of the window. You should see calls to avr-g++ and avr-gcc, each with several of parameters. One of those parameters will be "-DF_CPU=12000000". OK now that we see that, how do we change it? To answer that you have to know where the makefile knows that the parameter should be 12000000. It finds that information in the following file:
      /usr/share/arduino/hardware/arduino/boards.txt.
boards.txt contains configuration information for products that can use the Arduino IDE like the Gertboard. You can find sections for the Arduino Uno, the Arduino Nano, the LilyPad and many of others. Heading the file are the two sections for the Gertboard which were probably added by Gordon Henderson. One section is for each of the two ATmega ICs you could use with the Gertboard: the ATmega328 and the ATmega168. Assuming you are using the ATmega328, the line in boards.txt we are looking for is this one:
      gert328.build.f_cpu=12000000L.
To change the frequency, simply change the 12000000 to some other value. But, if you compile a sketch, change the value of f_cpu, and immediately recompile your sketch, you will not see a change (in verbose mode) to the parameters of avr-g++ and avr-gcc. When you recompile the same sketch that you last compiled, the Arduino IDE attempts to speed things up a bit (so it doesn't try your patience), and, apparently, does not look at boards.txt again. So, after changing board.txt, compile a different sketch or kill and restart the IDE. Then, you will see the change to -DF_CPU. As usual, make a backup copy of boards.txt before making any changes.
I tried this out by writing a sketch to toggle an LED on and off at a one minute rate. Changing the clock frequency as described above altered the cycle time in a predictable manner.

Changing The Clock Source

I have not personally tried changing the clock source as described in the following. But, I don't see why it would not work.
If timing is not important and your project does not have to work at lightning speed when you remove your ATmega chip from your Gertboard, and install in in your own hardware, you do not really have to install a resonator or crystal.
Before I continue, I strongly suggest you have a copy of the datasheet (it's hardly a sheet, it's 660 pages) for the microcontroller. You can find it here from Atmel. Make sure you download the first .pdf file under the picture. I'll assume you have this handy in the following discussions.
From Table 9-1 on page 27 you can see that, besides the three external clock options, there are two internal clocks built into the chip: a "Calibrated Internal RC Oscillator", which runs at 8MHz, and an "Internal 128KHz RC Oscillator". The default selection is the 8MHz calibrated oscillator. There is also a prescaller that divides the oscillator by any one of the eight values shown on Table 9-17 on page 37. The default value is to divide by 8. This prescaller will also divide the frequency of any of the external clock choices you may have choosen.
If the default choice is the 8MHz oscillator divided down to 1MHz, how does the Gertboard run at 12MHz? The answer is: The Gertboard does not use the default settings if you followed Gordon Henderson's direction for setting up the ATmega chip before using it. Whenever you use the Gertboard for the first time, or install a new ATmega chip on the Gertboard, you run a program called avrsetup. avrsetup programs several registers within the chip, namely the three fuse registers and a lock byte. We won't be talking about the lock byte because avrsetup just programs the lock byte to its default configuration.
If you are younger than about 50, you might wonder why they are called fuse registers. Miorocontroller chips, as well as other chips, like old PROMS (programmable read only memory), would be programmed by burning out fuseable links within the chip. A popped fuse represented a logic 0 while an intact fuse was a logic 1. Once the chip was programmed and you wanted to revise the information, you threw out the old chip and programmed a new one. I don't think any modern devices have fuses - but the name has endured. Mainly, these registers contain settings you want to setup before you do any serious programming because making changes later could mess up what you already programmed.
avrsetup programs these fuse registers for you by calling a program called avrdude. The three registers are the "Extended Fuse Byte", the "Fuse High Byte", and the "Fuse Low Byte". These are all eight bits in length. You can see what these registers do in section 28.2 starting on page 286. If you compare these registers with avrsetup you can see that the extended and high fuse registers are left at their defaults.
The low fuse register is definitely changed. The default value is 0x62 specifying the 8Hz calibrated oscillator and prescaller set to divide by 8. See Table 28-9 on pages 288 and 289 and Table 9-1 on page 27. avrsetup changes that setting to 0xE7 which selects the "Full Swing Crystal Oscillator", for the 12MHz resonator on the Gertboard, and prescalling set to 1.
Like boards.txt, avrsetup can be changed by the user. But, please, make the changes carefully and make a backup of avrsetup. If you would like to accept the 8MHz calibrated oscillator divided by 8, don't run avrsetup at all because all of the fuse registers and the lock byte will be set to the factory defaults.

Monday, January 6, 2014

Camera Remote Control - Free To Move

Last August I published four posts about my camera remote control project. I have a remote receiver/transmitter for actuating the shutter of my Canon G1X. The project was to replace the transmitter so I could control the shutter with a motion detector. Luckily I was able to find out that the receiver works at 433MHz.
The heart of the system consists of a 433MHz transmitter, a motion detector, and an ATmega328P microcontroller IC. Everything connected to my Gertboard, which sits atop my Raspberry Pi. The project was very successful but not terribly useful because it was basically a bunch of loose components and wires. And, it was tethered to a power cord. Here is what it looked like:
To make it useful, everything had to be separated from the Gertboard, RaspberryPi, and AC power. That's possible because the microcontroller, once programmed, retains its program. It was then just a matter of carefully removing the microcontroller from the Gertboard, wiring everything up, and putting it in a box. Oh, and using battery power rather than AC. Here you can see the completed camera remote in its enclosure and a really short demonstration of it in action:
And here is a photo of the inside of the box:
The circuit is built up on Adafruit's Perma-Proto Half-sized Breadboard PCB. The schematic follows here.
The original project used two LEDs that were part of the Gertboard. Of course, these were not available in the stand alone version, so I added two LEDs to the circuit. As before, one LED tracks the output of the motion detector. When the motion detector is triggered, its data signal output goes high for about a second. This time is variable and is controlled by a potentiometer on the detector PCB. This hold time prevents a series of rapid triggers. On the video above, that is why you see that LED on for about a second. The other LED is only on for the time it takes to send patterns to the RF transmitter - a very short time. In the video you have to look closely to see this flash. The LEDs are mounted in the top of the enclosure.
You can follow this link to see the diagram of the project as it was on the Gertboard, and to find links to the RF transmitter and the motion detector.
When it comes to purchasing components for these projects we always seem to mention Adafruit, SparkFun, and Element14/Newark Electronics. However, I find the best place to go for general electronic parts and hardware is Digi-Key . I could not find the enclosure, 12MHz resonator, and many of the nuts and bolts I needed elsewhere.
The Gertboard uses a 12MHz resonator, which I found was not a common part. 10MHz and 16MHz can be easily found. I wondered what to do if I decided to use a resonator of another frequency rather than 12MHz. I will report on that effort on another blog post. I did use the 12MHz resonator and was glad I did. I'll also report on that in a separate post.
The enclosure for the project is a Bud box. Digi-Key has a good assortment of these enclosures.
You may notice rather large series resistors for the LEDs - 10Kohm each. This limited the current to the LEDs to about 1ma. This was just fine because I used clear LEDs so it doesn't take much light to be visible. This also limited the battery current draw.
I used three AAA batteries in series to produce 4.5V for the project. The battery holder came from Adafruit and, unfortunately for me, had an on/off switch. The switch was in the way because it was on the side of the battery holder that I superglued to the side of the enclosure. It took a bit of work to remove enough of the switch to make it flush. The plastic was tough. Also, the width of the holder was about 1mm too wide. This interfered with the lid of the enclosure. I had to use a belt sander to take a little bit of plastic away. It wound up being a mess, and I need tape to hold the battery compartment lid on. The batteries should last a pretty long time. The circuit draws about 9ma. During the time the motion detector is triggered, the current rises to about 12ma.