PS3 Ubuntu 10.04 – Summary Guide

OK. So I broke my Ubuntu installation on my PS3, again. Happens all too regularly, I’m afraid. And, I’m not smart enough to fix it once it is borked. So, here’s how I start from scratch to get a Ubuntu 10.04 installation working on my PS3, from nothing.

So, starting from the firmware 3.15 on PS3 Phat. Anything later and sorry, Sony has stolen the OtherOS feature from you. Too bad, you loose. Sony has screwed you.

First thing, you need to visit PSUbuntu to get some hints. Many on them are dated (in terms of the Ubuntu release described), but still a fountain of knowledge.

Step 1. Installing the OtherOS Bootloader. There are a number of them mentioned, but only one that I’ve found handles the ext4 file system, required / desired by later Ubuntu installation systems. The petitboot bootloader is available in different versions, but this one is the one I use It needs to be stored in a USB dongle in a /ps3/otheros/ directory so that the PS3 system can find it to install.

Step 2. Have the Ubuntu 10.04 LTS CD available and have it inserted when you reboot to OtherOS loader from the PS3 OS. The latest version can be obtained from here. I generally use the alternate version, but i guess the desktop version works just as well.

Step 3. Install the Ubuntu 10.04 system, following all the relevant prompts. Blah. Blah.

Step 4. First thing is to get some more swap. There is a full instruction here

Ripping off the instructions from PSUbuntu:

sudo gedit /etc/modules
add “ps3vram” at the end of the file

save the file and get back to the terminal
sudo gedit /etc/rc.local
scroll until you see these lines of code:

exit 0

Before add the following:
mkswap /dev/ps3vram
swapon -p 1 /dev/ps3vram

Step 5. Make the monitor work properly. The instruction here is a little outdated. The introduction of upstart into Ubuntu has made the older instructions obsolete.

First thing is to install the fbset tool.

sudo apt-get install fbset

And then use it according to the instructions here to find out the right amount of cropping necessary to make the screen fit. Once you have the right size (dependent on your monitor) then create a file like this in /etc/init/

# fbset – set system frame buffer
#
# This task is run on startup to set the system frame buffer for Pioneer 720p
# First you need to sudo apt-get install fbset
# then this file gets put in /etc/init/

description    “set system framebuffer”

start on startup

task
exec fbset -a -xres 1216 -yres 680 -vxres 1216 -vyres 680

Once this file is created, with the fbset characteristics appropriate to the monitor you’re using, then also create a soft link in /etc/init.d/ to the standard upstart script. Look at other soft links in the same /etc/init.d/ directory to get the idea.

sudo ln -s /lib/init/upstart-job /etc/init.d/fbset

This makes sure that the fbset command gets properly executed.

Last thing is to modify the file in /etc/kboot.conf to use the overscan mode which means adding 128 to the resolution you’ve selected. For 720p I am using the following line:

linux=’/boot/vmlinux initrd=/boot/initrd.img root=/dev/ps3da2 video=ps3fb:mode:131′

This should get the screen resolution set correctly.

Step 6. Compile a new kernel, for the Cell Broadband Engine. There are some instructions on generic Ubuntu Kernels here, which are accurate and simple (even for me).

I found that I only need to ask for these packages, and everything else is brought in too.

sudo apt-get install fakeroot build-essential qt3-dev-tools libqt3-mt-dev

Don’t forget to set the concurrency to make best use of dual-core PowerPC CBE.

export CONCURRENCY_LEVEL=3

When using the xconfig tool, there are two options that should be selected compile for POWER4 and optimise for Cell Broadband Engine. Also, the kernel tick can be set to 300Hz or 1000Hz to get a bit better responsiveness.

fakeroot make-kpkg –initrd –append-to-version=”your-version-identifier” kernel-image kernel-headers modules_image

Following the instructions, there are two additional steps that need to be completed to get the kernel to work properly.

Check you have the tools to build a initrd image

sudo apt-get install initramfs-tools

Build the initrd image following command for building the initrd image

sudo update-initramfs -c –k 2.6.3x.xx.custom

Version 2.6.3x.xx.custom is the directory name which appears in /lib/modules/ after installing modules)
The initrd image will be generated /boot/ directory

I create some soft links in the /boot directory, to save me having to modify the /etc/kboot.conf file

sudo ln -s vmlinux.2.6.3x.xx.custom vmlinux.custom

sudo ln -s initrd.2.6.3x.xx.custom.img initrd.custom.img

Then, create linkages in the /etc/kboot.conf file so that you can refer to the new kernel and initrd image from the boot command line. For example.

linux.custom=’/boot/vmlinux.custom initrd=/boot/initrd.custom.img root=/dev/ps3da2 video=ps3fb:mode:131′

Ok now I’ve found that I need to rebuild the initramfs on the original and old linux versions, otherwise they won’t boot. Costs nothing except a few seconds to do this anyway.

sudo update-initramfs -c –k all

Step 7. Ok. Now go to town. Everything else works perfectly on my machine. Update it. Add multimedia.  Whatever.

Wii Linux & Homebrew – Summary Guide

I’m writing this down so that the steps I’ve taken to get a full debian Lenny GNU/Linux machine onto my Wii don’t get forgotten in the haze of my memory.

When the Wii and PS3 were just released, back in 2006, I had one on pre-order and picked it up just before Christmas. I remember considering the use case for a console in my home. Whilst I could appreciate the PS3 for its ability to play Blueray (at that time still in competition with DVD-HD), and to be a Linux compute device, I really couldn’t see anyone at our home sitting in front of the lounge screen button mashing on a controller. The Wiimote however was another story…

Over the past four years we’ve collected a shelf full of Wii games, all of which are fun because of the Wiimote. We can shoot, fish, bowl, and bat, all because of the Wiimote. It was a great decision back then, which I’ve never regretted. Because of its utility as a games machine, until now I had restrained myself from hacking about on the Wii, so not to spoil the user experience.

I’ve also purchased a PS3, which I purchased second hand when I heard that the PS3slim would no longer support OtherOS. It plays Blueray, and runs Ubuntu. I’ve never purchased a game for it and, given Sony’s decision to force me to choose between the OtherOS feature or the PlayStation Network, I will NEVER buy anything from Sony again. But I digress…

As background, my Wii was purchased in 2006 and therefore has the oldest boot1 and boot2 code. Unfortunately, I’ve upgraded the System Software at every opportunity, so it is currently running the current System version 4.3. It is Australian released, which means that it is a European version in terms of firmware.

The destination for this process is to have a GNU/Linux operating system, including a windowing desktop, running on the Wii. Whilst I’ve been using Ubuntu for most of my home computers, the initial target for this build is debian Lenny.

Finding the first vulnerability – Indiana Pwns – Using LEGO Indiana Jones

Investigating the alternatives for hacking the Wii revealed that of all of the alternatives mentioned, there was only one that would work for my device, on System version 4.3.

Taken from the WiiBrew description:

The Indiana Pwns is a safe way to enable homebrew  on a Wii without hardware modification. The Indiana Pwns is achieved by playing a hacked game save for LEGO Indiana Jones which executes a homebrew application from an external SD card. The Indiana Pwns was created by Team Twiizers.

This is actually the most expensive and time intensive part of the entire process. Expensive, because you have to buy a (imho stupid) game. Time consuming because you have to play through the first section until it allows you to save game, before you can use the vulnerability. But, don’t worry there is a walk through available to speed things along, and you actually can’t ever die in a LEGO game.

Once you’ve saved a game, then use the Indiana Pwns code to load the Homebrew Channel loader and the BootMii code.

EDIT: Just in; Team Twiizers and roto have created the Return of the Jodi exploit. This exploits the same buffer overflow issue as Indiana Pwns, but the game is more available in stores.

BootMii & boot2

BootMii is the path to get total control over the Wii hardware. Because I have an older Wii, released before 2008, I can use the boot2 method to get early control before the Wii System is even loaded. This method provides the best (fastest and most complete) access to hardware, and is the most proof against Nintendo removing my good work. 

As I have System Menu 4.3 I actually have boot2v4 installed. So its clear that the BootMii code can modify this most recent version of the boot2 code with no issue.

BootMii boot2 is written to the Wii as part of the Homebrew Channel installer program, and once it is installed we pwn the Wii, and we can choose to load the Wii System Menu or boot to another operating system, such as debian GNU/Linux, depending on which SD card we have in the slot.

Once BootMii is installed, there is no reason to ever see it again. However, from the Homebrew Channel (which we get to next) there is a option to open it, and it has a configuration file that can be modified to get it to change is boot options. For example, I configured it to boot directly to the Wii System Menu, so that the User Experience is exactly as Nintendo intended. Alternatively, when I use my debian SD card, it boots straight into debian GNU/Linux.

Homebrew Channel (as a diversion), and Homebrew Browser

While we’re going along with this hacking thing, why not install something useful for the whole family. The Homebrew Channel opens the Wii to the world of FOSS games, media players, and utilities.

The Homebrew Channel loads any application copied onto the SD card, and even easier the Homebrew Browser is a live updating online market of free stuff for the Wii. So far we love Jelly Car the most of any of the games we’ve tried on Homebrew.

Update: Until recently I was not able to find an application to play DVDs from my Wii. The System Menu 4.3 code prevented use of IOS202 and other methods. However WiiMC 1.1 has just been released, that uses IOS58 to get access to the USB, and it works perfectly. Will even install a Channel on the main menu, so that there is no need to go into the Homebrew Channel to launch WiiMC. It also plays SMB shares, so that NAS stored video, music and pictures can be played.

But, I digress…

GC-Linux Mike Kernel

Well, every GNU system needs a kernel, and in our case it is supplied as the MIKE kernel by GC Linux. Most of the devices and modifications for the Wii platform have been integrated into the Linux main line code as of 2.6.33.

Until then GC Linux have prepared two alternative kernels based on IOS, if you’ve a new Wii and can’t get to boot2, or based on MINI (the simple open alternative for IOS) which can launch directly from boot2, and has higher performance & hardware compatibility.

The Kernel images also differentiate based on the screen resolution you’re using. Given that you’ve a component cable to connect the Wii to your big screen, then you’ll need one of the 480p versions (PAL or NTSC) for MINI.

Whiite Linux

Whiite Linux is a full implementation of GNU/Linux for the Wii. There are two components necessary for this. As the kernel component is taken care of by the GC Linux MIKE, the other component required is a file system, and that is available as a tarball.

The instructions on the GC Linux installation page are complete. Well, at least they are now I’ve added the piece about setting the locale correctly. Without a locale set, perl gets really borked, and then applications that draw character based windows on the text screen (such as aptitude) don’t look
good at all (bordering on unusable).

You’ll also need to have some swap configured. the Wii only has 24MB + 64MB of RAM, and this will run out quickly if you start to have some services running.

So you can get comfortable with Whiite Linux now. apt-get as much stuff as you want.

xfce Desktop & Xorg Drivers

To get desktop running is a little more complicated. I choose to use xfce, as it is easily supported by debian in a package, that gets everything needed. It will take a while to download, and install, but this saves caring about what is installed, and what not.

apt-get install xfce-desktop

As part of this install, there will be questions about setting up xorg. Try to answer them benignly and sensibly, but don’t worry as it will fail in the end, and continue.

Now that we have everything we need need for the desktop installed, we have to worry about the special driver for Xorg on the Wii, called xf86-video-cube. There are some good instructions from Wiibrewfan4, that I’ve partially reproduced here, on how to prepare and install that driver.

Before doing that however, it is important to have a gcc, and make, and the standard utilities available.

apt-get install gcc, make

Now for getting the xf86-video-cube code and getting it ready.

Install cvs-client in order to get the lastest build of nuvalo’s cube xorg driver.

apt-get install cvs

Configure a cvs root somewhere where you have some space.

Get the source:

cvs -d:pserver:anonymous@gc-linux.cvs.sourceforge.net:/cvsroot/gc-linux login

cvs -z3 -d:pserver:anonymous@gc-linux.cvs.sourceforge.net:/cvsroot/gc-linux co -P xf86-video-cube

Before compiling Nuvalo’s cube_driver for Xorg, please install the following packages:

apt-get install module-init-tools pkg-config xserver-xorg-dev x11proto-randr-dev libxrandr-dev x11proto-video-dev x11proto-fonts-dev

cd to xf86-video-cube/ and type:

./configure && make && make install

configure will check that you have all the right pieces available, so watch its progress carefully, and just apt-get install anything that seems to be missing.

Following make install the driver installs itself to wrong location, so:

cp /usr/local/lib/xorg/modules/drivers/cube_driver.* /usr/lib/xorg/modules/

The last step is to configure the /etc/X11/xorg.conf file.

Because of the previous failure to configure xorg properly, there won’t be an xorg.conf file in the system. we can generate on with

dpkg-reconfigure xserver-xorg

Follow the questions as best as possible, which will generate a simple file, which can be edited as follows. I’ve attached my xorg.conf file for info.

Edit the file “/etc/X11/xorg.conf” and add a new video section:

Code:

Section “Device”
Identifier “WII/Gc Card”
Driver “cube”
EndSection

Edit the module section, and leave it as this:

Code:

Section “Module”

Load “dbe”
Load “ddc”
SubSection “extmod”

# Option “omit xfree86-dga”
# Option “omit XFree86-VidModeExtension”

EndSubSection
Load “type1”
Load “freetype”
Load “dri”

EndSection

Edit the screen section, and replace the next options:

Code:

Section “Screen”
….
Device “WII/Gc Card”
….
DefaultDepth 16
Subsection “Display”

Modes “640×480”

EndSubsection
EndSection

Now, reboot the Wii, and automagically it should boot to a debian X login prompt.

And, if you’re like me and didn’t add any additional users, you won’t be able to log in as root until you modify the session parameters.

Fun and games

Ok from this point things left to do are: get the Wiimote working and try to migrate to Ubuntu using debootstrap.

Both are subjects of further notes.

Freetronics freeRTOS Retrograde Real Time Clock (DS1307) – Part 3 Final

In Part 2  I promised to build a very stylish finished product, that could be displayed with pride. Well, I don’t think I’ve quite achieved that. But, at least now I consider the project finished, and now have the confidence to get on with other projects.

I have mounted some tiny servos, the funky white on blue LCD display, and the Freetronics 2010 board on some Craftwood. Cutting the hole for the LCD was a bit hit & miss, using a carving knife to shape the hole, and managing not to loose any fingers in the process.

Dsc04060Dsc02851

The hour servo is mounted at the bottom of the board, and travels clockwise from midnight, with noon vertical, until it re-tours to 0 on the stroke of midnight. The hour hand travels clockwise from 0 minutes at the bottom, over 30 minutes horizontal, to 59 minutes at the top of the stroke. At 0 minutes, the minute hand re-tours to 0 at the bottom. I find the movement of the servos on the stroke of the hour somewhat like a chime. Not too oppressive, but enough to draw my attention to the passing of another hour.

As the 4 line LCD has so much screen real estate, I have added the maximum and minimum temperature display, with hour, day and month when each extreme was reached.

Adding the LM335Z Temperature IC was discussed in Part 2. I found that the accuracy of the LM335Z IC could be improved by firstly knowing exactly what the Vcc was for operating the AVR device. Measuring this, and putting it in the calculation enabled enough accuracy to be found. Using the 5V regulator on the Freetronics 2010 delivered 4.97V for me, and this value is hard coded into the code. I have several LM335Z devices and they have different offsets, which is adjusted by modifying the subtraction in the Kelvin to Celsius calculation. As the LM335Z is accurate once the offset is established, there is no need to operate it in the “accurate” mode, IMHO, given we have software to make the adjustments it needs.

Dsc02855Dsc02852Dsc02854

The instability in the temperature readings discussed in Part 2 was caused by the long wires to the sensor. Once the device was fixed into the prototyping area on the 2010, together with bypass capacitor, the stability of readings improved greatly. However, during testing, I noted that the maximum values were reading very high. These false high maximum values were caused because the ADC process was sampling during a servo move. The servos consume a lot of power, and this causes voltage drop on Vcc. Hence the reference voltage for the ADC is no longer accurate.

Dsc02845Dsc02847

To prevent the ADC from operating during the servo moves, I simply used one of the freeRTOS semaphores I established previously. I use semaphores to control access to the LCD, the I2C and to the ADC. Use of a semaphore enables independent processes to share a single hardware resource without conflicts developing. The fix for the erroneous high maximums was done simply by taking the ADC semaphore (to prevent the ADC reading process from starting) during times when the servos are being instructed to move. Simple, with freeRTOS to manage the process interaction for me.

ERRATA

The code included in the updated source does not properly fix the issue of false maximum temperatures. It incorrectly releases the ADC semaphore immediately following resetting the PWM values. This means that the hands can still be moving when the ADC process gets unblocked which causes false maximums, because of voltage droop in Vcc, typically at midnight when both hands are in motion.

The fix is to move the vTaskDelay call between the set_PWM_hardware and xSemaphoreGive calls. I also increased it to 2000 milli Seconds too, to ensure the hands are really stopped before the ADC process gets unblocked.

set_PWM_hardware( servoHours_uS, servoMinutes_uS );

vTaskDelay( 2000 / portTICK_RATE_MS ); // a 2 second delay to ensure the hands have properly stopped.

xSemaphoreGive( xADCSemaphore );

 

END ERRATA

Another piece of code added since Part 2 is to write the maximum and minimum temperatures and the times the extremes occurred into the EEPROM available on the 2010. The functions to use the EEPROM are available in the AVR library and are very straightforward to use. Having a permanent record of temperature extremes is perhaps one thing this clock does, that other clocks in my house can’t do.

There are a lot of comments in the updated freeRTOS Retrograde Clock code, now hosted at Practical Arduino. As a reminder the code uses the AVR and Pololu Libraries, so these both need to be installed before you compile.

 

Freetronics freeRTOS Retrograde Real Time Clock on PS3 – Part 2a

Just for interest, I decided to see how the support for AVR or Arduino was on the PS3.

Using the standard tools on Ubuntu Lucid 10.4 from my OtherOS installation. A quick search for AVR on synaptic got the avr-lib, avr-gcc, and avrdude tools needed. No special versions, just straight off the repository.

Then, I followed the link to the Pololu Libraries in my Part 2 post, made the changes to OrangutanLCD.h as noted, hit make, and crossed my fingers. No issue. It all worked. sudo make install to put the files in right place.

OK. does the PS3 USB platform recognise the FTDI 232RL USB chip on the Freetronics 2010? Yes. Another hurdle cleared, with no issues.

With that step done, it was simple to download the retrograde files from Practical Arduino as noted in Post 2, extract them. Hit make program and off we go. avrdude works as expected, and the new code is loaded as normal.

I’d say the whole test was over faster than it has taken to type this note.

I should be over this, but I get so happy when technology just works… particularly when it is all free. Got to love your FOSS.

One small issue. There doesn’t seem to be a release of Arduino tools for PS3 (PowerPC). Pity about that. Perhaps in another repository…

Freetronics freeRTOS Retrograde Real Time Clock (DS1307) – Part 2

Part 2 of this project involved learning how to use hardware PWM to control servos. And, then to make the clock actually work with retrograde analogue hands.

First the functional definition. A retrograde movement in horological terms is where the indicators or hands spring back to their home or 0 position at the end of their cycle. So for a minute hand, after 59 minutes and 59 seconds, its next movement would be to reverse move to home at 0 minutes. For the hour hand this could happen after 12 hours or 24 hours. 24 hours is the case that I have chosen to implement. The idea is to have the hour hand trace out a day from sunrise in the east, to vertical noon, and to set in the west.

In part 1, I added the servo headers to align with the Arduino Digital Pins 5 & 6. These pins are driven by the Timer 0 PWM hardware. Following quite a few evenings trying to understand how to generate PWM using the hardware (OK, I’m a bit slow), I realised that it is not very easy to get a good servo signal out of Timer 0 or Timer 2.

To generate the right signal for a servo, you need to produce a pulse every 20mS (50Hz). The width of the pulse should be 1.5mS to get the neutral position. Depending on the servo design, pulses with width from around 0.8mS to around 2.2mS (repeated every 20mS) will drive it to either end of its range. Depending on the servo, 0.8mS may drive it clockwise or anticlockwise. I have both in the clock. For example, the “hour” servo goes clockwise with a wider pulse. The “minute” servo is the reverse case.

The main issue with Timer 0 and Timer 2 is that they are 8 bit timers, counting to 255 before resetting to 0 (ideally after 20mS). Since the required pulses are between 0.8mS and 2.2mS, there are only about 12 “positions” available for the servo to take. Not enough to allow a minute hand to indicate 60 different positions.

Therefore it became clear that, for this application, it was only possible to use the 16 bit Timer 1 to control the servos.

Setting up Timer 1 is relatively easy, once that decision had been made, so the code was implemented. But, this meant that I had to reconnect the servo headers to Arduino Digital Pin 9 and Pin 10, which are driven by the Timer 1 PWM hardware.

Also, in the pictures below, I have added a header to allow power, LCD backlight (32Ohm), and contrast (1kOhm), connections to the standardised HD44780 LCD.

Dsc02787Dsc02791Dsc02789

Ok, so here’s the issue. I’m using the Pololu Libraries for writing to the LCD, and the standard connection for the data line 4 on the HD44780 LCD goes to Arduino Pin 9. The same pin I need for the Timer 1 PWM. Ouch.

Modifying the library is not too difficult. We can move the Data line attached to Pin 9 onto Pin 11, and all is well. This is done in the following file.

~/libpololu-avr/src/OrangutanLCD/OrangutanLCD.h

The changes are noted in the #define lines below

#define LCD_DB4                PORTB3        // Was PORTB1. Use PORTB3 to avoid the Timer1 pins.
#define LCD_DB5                PORTB4        // PB4
#define LCD_DB6                PORTB5        // PB5
#define LCD_DB7                PORTD7        // PD7

//    PortB:     7 6 5 4 3 2 1 0
//  LCD Data:      2 1 0            Use DB3 to avoid Timer1 pins.
//  LCD Data:      2 1     0
//
//  PortD:     7 6 5 4 3 2 1 0
//  LCD Data:  3

#define LCD_PORTB_MASK            ((1 << LCD_DB4) | (1 << LCD_DB5) | (1 << LCD_DB6))  // Modified to avoid using DB1
#define LCD_PORTD_MASK            (1 << LCD_DB7)
#define LCD_PORTB_DATA(data)    ((data & 0x07) << 3)  // Modified the data mask to avoid using DB1
#define LCD_PORTD_DATA(data)    ((data & 0x08) << 4)

The below pictures show the LCD pin layout.
<blockquote”>Red = VCC

Black = GND

BLUE = Voltage for contrast or backlight

Orange = Data lines (4-bit: DB4 – DB7) PB3 (not PB1), PB4, PB5, and PD7. Arduino Digital pins 11 (not 9), 12, 13, and 7

Purple = Control lines (RS, R/W, E) PD2, PB0, and PD4. Arduino Digital pins 2, 8, and 4

Dsc02793Dsc02796

So now we have PWM for our retrograde analogue hands, and a LCD display.

But wait, there’s more…

There’s too much display going to waste, so let’s add something else… Hmm… Temperature, and time, make a min/max thermometer that can show what time each extreme temperature was reached during the day.

Quickly getting a LM335Z temperature sensor, I’m now testing whether the 10bit ADC is good enough to generate reasonable temperature readings from the device. At full range of 5000mV across 1024 levels, we have about 4.88mV per level. The LM355Z produces 10mV per degree, so we should be able to get 0.5 degree accuracy. If everything is perfect.

Currently the temperature gauge works, but the accuracy is still a work in progress, as are the min / max functions. The LM335Z has only two connections, and is biased by a single resistor (3200 Ohm), so it will fit into the board if that is all that is needed. Getting perfection may require addition of decoupling capacitors on AREF and across the sensor, but I’m still
experimenting with this.

Dsc02838Dsc02839

The overall working product is shown below. But wait, there’s more…

I was not happy with using resistors to tie up the SCL and SDA lines high for the I2C bus, as it should be possible to use the internal pull up resistors in some situations (according to the Atmel datasheet).

So using a new Freetronics 2010 from Little Bird Electronics, the clock is now rebuilt without external pull up resistors. The I2C code is modified to only pull up the lines between the start and stop bus instructions. The levels are messy (not showing sharp transitions in my SLO) but, never the less the code and the clock works.

The working device is shown below. Note the rather funky white on blue display I got from Sparkfun.

Dsc02842

In the years since this instruction was writen, I’ve migrated to Github. So the code is hosted here. The freeRTOS code is also posted on Github. I used the Pololu Library for writing to the display, so it needs to be installed along with the normal AVR libraries.

Part 3 will look at how to build a really stylish clock face that can be shown off in public

Freetronics 2010 (Arduino Duemilanova) freeRTOS Real Time Clock (DS1307) – Part 1

I was pondering the blank space on my 2010 recently, and combining that space with some other left over kit from Dogbot, I decided to make a dual retrograde analogue clock.

To build the clock I have the choice of either using NTP to sync a wireless enabled device, or use a RTC clock and re-set it every month or so. For this iteration, I’ve decided to go the RTC route.

Actually, reading this Tronixstuff page also got me going on the idea of using a DS1307 chip, and also Sparkfun makes a nice module that just happens to fit in the vacant space on the 2010. So, I bought one from LittleBird Electronics.

Only other thing to do was to add some servo headers, to get me going with the analogue clock face (using servos).

The picture below shows the layout. I tried a few different options, but this layout seems to only affect the legibility of the pin labelling. Other layouts mask the crystals close together, and I’m not sure how that would affect clock accuracy, or prevent the battery from being removed (9 years later).

Dsc02777

Yes, everything fits. Now to the soldering iron.

Dsc02779

Ok now it is soldered together, and everything looks reasonably fine.

Dsc02780Dsc02781

Now, on the test bed, I have the RTC clock working well using my beloved freeRTOS, and can get on with using the servos to drive analogue hands.

Dsc02785Dsc02784

In the years since this instruction was writen, I’ve migrated to Github. So the code is hosted here. The freeRTOS code is also posted on Github. I used the Pololu Library for writing to the display, so it needs to be installed along with the normal AVR libraries.

Part 2 looks at building the PWM control for the retrograde hands, and adding a temperature function.

Freetronics 2010 (Arduino Duemilanova) Overclocking & Review

Recently, I picked up a Freetronics 2010 from Little Bird Electronics.

Dsc02744

I thought that it would make a nice upgrade to my Dogbot test bed. It uses the same USB connector as Dogbot’s Pololu SVP, so it saves me from keeping different USB cables handy, but is in every way 100% the same as the Arduino Duemilanove that I’ve been using up to now.

But, everything I own is hacked in some way. So as usual, I thought that the 2010 could be improved, just as I’ve improved the Duemilanove before it, by overclocking it to 22.1184MHz.

Overclocking to 22.1184MHz

So why change the clock frequency to this odd number of 22.1184MHZ, and not to 20MHz which would be in specification?

It turns out that because of the binary and integer world the 2010 and the Duemilanova ATmega328p MCU live in, it is much better have a “nice” binary and integer friendly base frequency. Unfortunately, although 16MHz on a 2010 or Arduino sounds nice, from the point of view of integer programming, clock scaling, and UART interfacing, it is difficult to get clean integer numbers.

A small example.
16MHz clock scaled to 115200baud = 138.888888889 so rounding gives an error term.
20MHz clock scaled to 115200baud = 173.6111111111 so, again, rounding gives an error term.
22.1184MHz clock scaled to 115200baud = 192 with no rounding error.

Also, even though we are getting 16,000,000 instructions per second out of a standard?2010, and that should be enough for any application. I can get 22,118,400 or a 38% improvement for the cost of a few cents. So, why wouldn’t you?

What kind of issues can occur?

Well, over-clocking means that the ATmega328p is out of specification. But, I’m not too worried about pushing specification on this project, as the 328p is certified for an industrial operating temperature range, which is way outside of my operating temperature… There are also unverified reports of AVR ATmegas working successfully up to 32MHz.

In the overall scheme of things, raising the clock frequency on the AVR ATmega328p above specification by 10% to 22.1184MHz is no big deal.

Upgrading Process

1. Obtain a 22.1184MHz HC49/US crystal from Digikey They’re pretty cheap. Buy a bag in case of accidents.

Dsc02746Dsc02747

2. Use a knife tip under the existing 16MHz crystal to give you a lever to pressure it into removal, without burning your fingers. It will get very hot!

3. Turn over the board and use a soldering iron to heat the joints, whilst leaning on the knife to lever out the 16MHz crystal. Once it is removed, use some solder wick or similar to remove excess solder, and make it easier to insert and solder the new 22.1184MHz crystal.

Dsc02751Dsc02750Dsc02755

4. Building a new bootloader. In replacing the crystal, the 2010 is effectively bricked. You can no longer communicate with it using the standard bootloader. It is now running too fast and out of specification for avrdude to communicate with it, so we have to compile and burn a new boot loader before we go any further. I choose to use the Adaboot328 bootloader from Ladyada. It resolves a few known issues with Arduino compatible boards, and is easy to compile.

In the ATmegaBOOT_xx8.c file, change the UART baud rate to 115200, if you use avrdude for programming (if using Arduino IDE, do not change this from 19200). Who has time to wait around these days for 19200 baud, anyway?

/* set the UART baud rate */
#define BAUD_RATE?? 115200

In the Makefile, change the AVR_FREQ value to 22118400L for the adaboot328: TARGET.

adaboot328: TARGET = adaboot328
# Change clock frequency from 16000000L
adaboot328: AVR_FREQ = 22118400L

Then, compile the bootloader, and keep it safe.

5. Prepare an ISP. There are many alternative ways to do this, and here is not the place to describe the alternatives. Suffice to say that I used the AVRISP method in the Arduino-0018 IDE. I’ve struggled with avrdude (which I otherwise use for everything) as a bootloader ISP. I don’t know why, but I can’t make it work.

It happens that I have a standard Arduino clone available, which I prepare as the AVRISP, by uploading the following sketch File>Examples>ArduinoISP.

6. To be able to use Arduino IDE to burn our special bootloader, you have to replace the standard ATmegaBOOT_168_atmega328.hex bootloader file, found in ~arduino/bootloaders/atmega/ with our newly generated file. And, to make things simple, I just rename or remove the standard one, and replace it with our newly prepared and renamed bootloader with this name
ATmegaBOOT_168_atmega328.hex.

7. Connect our Freetronics 2010 up using the AVRISP connections, described on the Arduino web site. Make sure we have the right board type selected; it should be Duemilanova w/ ATmega328. Then using the Arduino IDE use Tools > Burn Bootloader > w/ Arduino as ISP.

Dsc02756

8. Program a sketch using either the Arduino IDE, or using avrdude, remembering that the baudrate is set to 115200. And, enjoy.

Conclusions regarding the Freetronics 2010.

Its a very well designed and produced device, that is 100% compatible with the Arduino Duemilanova. Some advantages are: the mounting holes are slightly larger so cable ties go through nicely, smaller USB connector is more common than the B connector used on Duemilanova, and there’s no solder in the holes for the X3 connector so it is easy to add headers to make it possible to burn its own bootloader (if you want).

It runs my freeRTOS build with no problems, as seen in this demo on my Dogbot test bed with a Robot Electronics Thermopile, and Sharp IR Distance sensor.

Dsc02760Dsc02761

DogBot – Post 5

So some time has passed and I’ve had some success with different aspects of my robot.

For simplicity, I’m using a test bed based on an Arduino Duemilianova connected to a Nerdkits sourced display. I’ve hooked the display up as if it was a Pololu Orangutan SV-328 and am using Pololu libraries to write to it. Also, I’ve been working on the actual SVP based robot, so both of which are working well.

The processor 328p is used for the Duemilianova and requires the use of the Timer0, which implies no Pololu motor library code is possible without conflicts. However this is not an issue, as the Duemilianova doesn’t have motor drives anyway. The actual DogBot has the 1284p which is used in the SVP and uses Timer3, which has no limitations on any known libraries to my knowledge.

The freeRTOS code is posted on the Pololu Forum, mostly just back-up as the application code is very immature.

At  this stage I’ve got all of the I2C bus based sensors working, based on code developed by Fleury. So, I can read the thermal sensor for its 8 pixels, and equally importantly, I can read the SRT10 Ultrasonic Sensor for distance in cm. One issue with the ultrasonic sensor is that its field of vision is so great that it basically detects anything “in front” of it. Good to not run into things, but pretty useless as a fine directional capability. It seems lucky that the Sharp IR distance sensors are very directional, and sufficiently accurate as a complement. The analog sensor readings are working well too, though I still have to create a ADC to cm regression.

From the point of view of sensing, it looks like the Sharp IR sensors will be the reference. With the SRT10 sonar being most relevant to create a “zone of safety” where I can be assured that the nearest object in a cone of 120deg is measured, but can’t be sure exactly which direction the object is. On the thermal side, I will get a vector (direction and temperature) from the sensing location, but no distance. But, that I knew and expected.

Putting some effort into designing the motor control, or Transport Task, has taken up my thoughts recently. I don’t want to link the odometry available from the quadrature encoders back into the mapping or routing task. Similarly, I don’t want to link the intertial navigation available from yaw and linear acceleration sensors into the motor task.

I think the transport task should simply take a vector,  relative to the the current pose of the robot, and execute these translation commands subject to feedback from odometry, leaving the inertial navigation to another task.

This fits well into the design of the hardware, as odometry can can be queried from the Pololu SVP ancillary processor, without blocking, and the motor PWM drivers can be also managed without blocking other tasks. This creates a self contained task that does not need to share resources with other tasks.

However, the inertial sensors are analogue readings and the ADC will need to be shared with the Sharp IR distances sensors. Creating the need for a semaphore, and blocking based on the availability of the ADC.

Because of the battery issues described in Post 4, I’ve had to remove the servo neck of the DogBot. Therefore, I will implement the option for motion to be along circular paths, as well as along a straight line. Motion along a straight line, with stationary rotations to create the correct pose prior to departure, are the best paths to arrive at the destination with the lowest risk and shortest path. However, with a fixed sensor head, straight lines don’t fill the map with information as they leave the sensors always pointing in the same direction.

If the DogBot proceeds from A to B via a circular route (if this is requested by the mapping or logistics task), then the sensors will be pointed at all directions from +90 to -90 degrees along the path to the destination. Allowing the travel time to be used effectively for data acquisition.

If I’m feeling smart, then I can create any number of route subdivisions, and force DogBot to describe a path of smooth semicircles to the destination, gathering sensor data along the route.

The inertial sensors can be run in a parallel task (using the ADC along with the Sharp IR sensors), with the odometry (from the ancillary processor) to cross check that the expected distances and directions are traveled. Whilst I think the odometry is more likely to be accurate, the map will be updated constantly so some inaccuracy should be expected and tolerated by the code.

My next step is to design this transport task. This task should take distance, bearing and path description (straight line, circle, sinusoidal, etc) and carry it out to the best of its ability (odometry PID data only). I expect resolving this effort will take the next few weeks, and perhaps longer.

Later work is to develop the logistics and routing task that will issue the navigation requests to the transport task.

Continued with Post 6 (one year later).

Dogbot – Post 4 – Hardware & freeRTOS Complete

Ok so some time later, I’ve finished building up the hardware.

It is basically a 4 level stack, with the two Li batteries on the bottom, followed by a proto board which carries the acceleration sensors, and distributes power and signal lines.

The top level is the Pololu SVP and its daughter display card (level 5).

25742_419162736067_610931067_5621385_2222535_n
25742_419162646067_610931067_5621384_4844593_n
25742_419162756067_610931067_5621386_5021337_n
25742_419162776067_610931067_5621388_4697390_n
25742_419162806067_610931067_5621389_6666628_n
25742_419162876067_610931067_5621390_4382446_n

What issues are there?

Well electrically none. All the signals are working perfectly, as demonstrated by the Pololu Analogue and Digital code, together with their motor and servo code. All the hardware seems to be functioning perfectly.

But, there are some problems.

The Li battery packs are incapable of providing enough current. I should have done a power budget before building. Everything works pretty well, although there is some voltage droop to 4.5V, until I turn on the neck servo. Then Vcc drops to 3.5V and the DogBot dies.

So the choices are to remove the servo, and program the scanning function using the body, or build a new boost power supply. At this stage I’m tending to think it would be better to just remove the neck servo, and use the chassis for scanning.

Also finished is the freeRTOS port, using Timer3 from the Atmel MegaAT1284, which is not found on other devices of this type. This allows me to have no conflicts with previously written code (using Timer0, Timer1, or Timer2). However, I will still need to go through all libraries to ensure that they don’t cause problems by being interrupted by the RTOS.

So now onto some heavy system design to work out exactly how to implement the mapping and searching functions, and how to drive in a straight line.

Wifi Dogbot – Post 3 – Pin Outs

Changed the processor to Pololu Orangutan SVP

*** PIN OUTS DEFINED

For the Orangutan SVP from http://www.pololu.com

Port Pin Orangutan (Alternate Functions) Function Notes

  • PA0 (ADC0) IR Analogue Distance Sensor GP2Y0A02YK0F (20cm-150cm) to ~2.8V – ORANGE
  • PA1 (ADC1) IR Analogue Distance Sensor GP2Y0A21YK0F (10-80cm) to ~2.8V – WHITE
  • PA2 (ADC2) LISY GIRO Z Axis Analogue Sensor to 3.3V – PURPLE
  • PA3 (ADC3) MMA7260QT Three Axis Accelerometer – X Axis Analogue to 3.3V – YELLOW
  • PA4 (ADC4) MMA7260QT Three Axis Accelerometer – Y Axis Analogue to 3.3V – BROWN
  • PA5 (ADC5) MMA7260QT Three Axis Accelerometer – Z Axis Analogue to 3.3V – GREEN
  • PA6 (ADC6) Motor1 Current sense – WHITE
  • PA7 (ADC7) Motor2 Current sense – WHITE
  • PB0 (T0) LCD control line RS Timer/Counter 0
  • PB1 (T1, CLKO) LCD control line R/W
  • PB2 (AIN0, INT2) LCD control line E
  • PB3 (AIN1, OC0A) Timer0 PWM output A? PIR (Digital LOW) – YELLOW (& RED & GREY)
  • PB4 (SPI_SS, OC0B *) Timer0 PWM output B
  • PB5 (SPI_MOSI) auxiliary processor control
  • PB6 (SPI_MISO) auxiliary processor control
  • PB7 (SPI_SCK)? auxiliary processor control
  • PC0 (I2C_SCL) Ultrasonic Ranger SRF10 Addr 0xE0 & Thermopile Addr 0xD2 – BROWN
  • PC1 (I2C_SDA) Ultrasonic Ranger SRF10 Addr 0xE0 & Thermopile Addr 0xD2 – ORANGE
  • PC2 LCD data line DB4 – user pushbutton (pressing pulls low)
  • PC3 LCD data line DB5 – user pushbutton (pressing pulls low)
  • PC4 LCD data line DB6 – green user LED (high turns LED on)
  • PC5 LCD data line DB7 – user pushbutton (pressing pulls low)
  • PC6 Motor2 direction control line – LEFT MOTOR
  • PC7 Motor1 direction control line – RIGHT MOTOR
  • PD0 (USART0_RXD0)
  • PD1 (USART0_TXD0) digital I/O red user LED (low turns LED on)
  • PD2 (USART1_RXD1, INT0)
  • PD3 (USART1_TXD1, INT1)
  • PD4 (OC1B) Timer1 PWM output B – Buzzer
  • PD5 (OC1A) Timer1 PWM output A – I/O servo SPWM? – Neck Servo
  • PD6 (OC2B) Timer2 PWM output B – Motor2 speed control line
  • PD7 (OC2A) Timer2 PWM output A – Motor1 speed control line
  • AREF VCC 3.3V Battery Supply

IN PHYSICAL ORDER

TOP RIGHT TO LEFT

  • PD5 (OC1A) Timer1 PWM output A – I/O servo SPWM – Neck Servo
  • Quadrature Sensor D – YELLOW (LEFT 2nd)
  • Quadrature Sensor C – WHITE (LEFT 1st)
  • Quadrature Sensor B – BLUE (RIGHT 2nd)
  • Quadrature Sensor A – BROWN (RIGHT 1st)
  • GND

BOTTOM RIGHT TO LEFT

  • VIN
  • GND
  • M1 OUT B – PURPLE (RIGHT)
  • M1 OUT A – GREY (RIGHT)
  • M2 OUT B – ORANGE (LEFT)
  • M2 OUT A – GREEN (LEFT)=
  • PD3 (USART1_TXD1, INT1)
  • PD2 (USART1_RXD1, INT0)
  • PD1 (USART0_TXD0) digital I/O red user LED (low turns LED on) blank
  • PD0 (USART0_RXD0) blank – reserved
  • PC1 (I2C_SDA) Ultrasonic Ranger SRF10 Addr 0xE0 & Thermopile Addr 0xD2 – ORANGE
  • PC0 (I2C_SCL) Ultrasonic Ranger SRF10 Addr 0xE0 & Thermopile Addr 0xD2 – BROWN
  • PB4 (SPI_SS, OC0B *) Timer0 PWM output B
  • PB3 (AIN1, OC0A)???? Timer0 PWM output A PIR (Digital LOW) – YELLOW (& RED & GREY)
  • PA0 (ADC0) IR Analogue Distance Sensor GP2Y0A02YK0F (20cm-150cm) to ~2.8V – ORANGE
  • PA1 (ADC1) IR Analogue Distance Sensor GP2Y0A21YK0F (10-80cm) to ~2.8V – WHITE
  • PA2 (ADC2) LISY GIRO Z Axis Analogue Sensor to 3.3V – PURPLE
  • PA3 (ADC3) MMA7260QT Three Axis Accelerometer – X Axis Analogue Sensor to 3.3V – YELLOW
  • PA4 (ADC4) MMA7260QT Three Axis Accelerometer – Y Axis Analogue Sensor to 3.3V – BROWN
  • PA5 (ADC5) MMA7260QT Three Axis Accelerometer – Z Axis Analogue Sensor to 3.3V – GREEN
  • PA6 (ADC6) Motor1 Current sense – WHITE – RIGHT MOTOR
  • PA7 (ADC7) Motor2 Current sense – WHITE – LEFT MOTOR
  • AREF VCC 3.3V Battery Supply (to centre board) – BLUE