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 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

Wifi Dogbot – Post 2

Construction NOTES

   1. Build chassis platform for use indoors.

Chassis platfrom elements come from Pololu, so it will be good to use their Orangutan libararies wherever possible. I will need to modify them as the Arduino/Blackwidow runs at 16MHz (not at 20MHz).

Should I modify Arduino/Blackwidow to use 20MHz crystal, to save modifying all the Orangutan, and also to gain 33% more cycles/sec? Or, modify all the code and timing?

Webbot Lib is a library that addresses most issues associated with building robots. Version 1.15b is current now.
http://webbot.org.uk/iPoint/30.page

   2. Build motor controls to allow straight line, radius, and Bézier motion.

Basic information on how to get differential drive working.
http://www.societyofrobots.com/programming_differentialdrive.shtml

Then how to add PID control to the system.
http://www.societyofrobots.com/programming_PID.shtml

Some of the Orangutan & Pololu libraries are directly relevant:
OrangutanMotors – basis for control of the DC motors.
PololuQTRSensors – basis for reading the Quadrature sensors from Pololu.
PololuWheelEncoders – basis for reading the Encoders on the Wheels.

CourbeBezier Libraries are interesting for describing Bezier curves.
http://jppanaget.com/doku.php/wiki:bezier_curves

   3. Build emergency collision avoidance.

Some of the Orangutan & Pololu libraries are directly relevant:
OrangutanPulseln – basis for reading the short range sensors.
OrangutanDigital – basis for reading the short range sensors.

   4. Build long distance sensors.

A very good description of the chosen Sharp optical rangefinders.
http://www.societyofrobots.com/sensors_sharpirrange.shtml

And this is a description of the Sonar Ultrasonic rangefinders.
http://www.societyofrobots.com/sensors_sonar.shtml

Some of the Orangutan libraries are directly relevant:
OrangutanAnalog – basis for reading the Sharp Optical Rangers

   5. Build voice box – bark, growl, yap, whine, etc.

This code at Arduino might be useful.
http://www.arduino.cc/en/Tutorial/PlayMelody
http://www.arduino.cc/playground/Code/MusicalAlgoFun

   6. Build area mapping.

Using the wavefront technique seems very relevant, from Society of Robots
http://www.societyofrobots.com/programming_wavefront.shtml

   7. Build aggressive object collision avoidance.

Some of the Orangutan libraries are directly relevant:
OrangutanSPIMaster – can drive the interfaces with the WIFI device on Blackwidow.
OrangutanSPIMaster – can drive the interfaces on the Ultrasonic Ranger.

Use the 6DOF Atomic Gyros & Acelerometer code as basis

   8. Build aggression response.

Some of the Orangutan libraries are directly relevant:
OrangutanSPIMaster – can drive the interfaces on the Acceleration & Yaw sensors.
OrangutanSPIMaster – can drive the interfaces on the Ultrasonic Ranger.

   9. Build WiFi sensors & target mapping.

Some of the Orangutan libraries are directly relevant:
OrangutanSPIMaster – can drive the interfaces with the WIFI device on Blackwidow.

A general website for location technique comparisons
http://www.positioningtechniques.eu/lbs_technique_checker.asp

The RTLS from 802.11k is useful, as are the equations for solving based on iso-power intersections of two circles.
http://mathworld.wolfram.com/Circle-CircleIntersection.html
http://local.wasp.uwa.edu.au/~pbourke/geometry/2circle/
There is a C code example to be followed.

  10. Build intelligence logic to enable end result.

Webbot Lib is a library that addresses most issues associated with building robots.
http://webbot.org.uk/iPoint/30.page

Use the Seeker2 source where possible, from Society of Robots.
Research into finite state machines required.

Also there is an Experimental Robot Platform code that is being provided ERP_WebbotLib
that will be very relevant.
http://www.societyofrobots.com/robot_ERP.shtml

  11. Build Thermal sensors & target tracking.

Some of the Orangutan & Pololu libraries are directly relevant:
OrangutanServos – can drive the PCM interfaces to the pan servo for Thermopile Sensor (option).

WiFi Dogbot

I was looking for a “why” for investing my time in Atmel AVR devices, because with a “why” progress is always faster. I think making an autonomous robot with dog-like behaviour will make an excellent one / two year multi-layer project, that will be able to demonstrate itself at the end. Also it won’t consume too much cash.

This post is to create a problem description, expected outcomes, and path I’ll be taking. It will also be a reference when I forget where I was going with this.

Why?

  • Being able to find my ‘Droid when it has gone missing around the house, and (more reguarly) being able to find my wife’s Crackberry is a fairly regular occurrence. So, I’d like to build something that can find both of these WiFi enabled devices. Also, being able to search out iPhones and WiFi APs, like a drug sniffer dog, would be mildly entertaining for family and visitors.

Expected features

  • Autonomously seek out and approach WiFi sources in order of strength.
  • “Bark” when the device is in close proximity.
  • Navigate & travel at dog speed in an unfamiliar environment.
  • Avoid aggressive obstacles within the map. “Growl” at these obstacles.
  • Reorientate autonomously if an aggressive obstacle “picks up” or “plays”.

Optional features

  • Follow someone around whether or not they have a WiFi device.

Assumptions

  • The floor is flat. Litter can be avoided. -> a cheaper indoor chassis can be used.
  • The room is small. 10m x 10m map can be built, with translation as map edge approached. -> memory conservation.

Initial Plan

  1. Build chassis platform for use indoors.
  2. Build motor controls to allow straight line, radius, and B?zier motion.
  3. Build emergency collision avoidance.
  4. Build long distance sensors.
  5. Build voice box – bark, growl, yap, whine, etc.
  6. Build area mapping.
  7. Build aggressive object collision avoidance.
  8. Build aggression response.
  9. Build WiFi sensors & target mapping.
  10. Build intelligence logic to enable end result.
  11. Build Thermal sensors & target tracking.

Component sourcing

  • Chassis

1x Pololu 5″ inch Robot Chassis RRC04A http://www.robotgear.com.au/Product.aspx/Details/353
1x Pololu 42 x 19mm Wheel and Encoder Set http://www.robotgear.com.au/Product.aspx/Details/307
1x TB6612FNG Dual Motor Driver Carrier http://www.robotgear.com.au/Product.aspx/Details/319
1x Pololu Ball Caster with 1″ Plastic Ball http://www.robotgear.com.au/Product.aspx/Details/370
2x 30:1 Micro Metal Gearmotor http://www.robotgear.com.au/Product.aspx/Details/344

1x Arduino Duemilanove http://arduino.cc/en/Main/ArduinoBoardDuemilanove
(will be replaced in step 9.)
1x Arduino Proto Shield http://www.sparkfun.com/commerce/product_info.php?products_id=7914

  • Emergency Sensors

3x Pololu Carrier with Sharp GP2Y0D810Z0F Digital Distance Sensor 10cm
http://www.robotgear.com.au/Product.aspx/Details/309

  • Long Distance Sensors.

2x Sharp GP2Y0A02YK0F Analog Distance Sensor 20-150cm http://www.robotgear.com.au/Product.aspx/Details/272
1x SRF10 Dual Transducer Ultrasonic Ranger http://www.robot-electronics.co.uk/htm/srf10tech.htm

  • Voice Box.

1x Piezo Buzzer from NerdKits

  • Aggression Sensors.

1x MMA7260QT 3-Axis Accelerometer http://www.pololu.com/catalog/product/766
1x LISY300AL Single-Axis Gyro http://www.pololu.com/catalog/product/765

  • WiFi Sensor (and revised Microcontroller Platform).

1x BlackWidow 1.0 http://www.seeedstudio.com/depot/blackwidow-10-p-613.html

  • Thermal Sensor.

1x Thermopile Array http://www.robotgear.com.au/Product.aspx/Details/294

So, maybe the next post once some more details are to hand.