Monday, May 2, 2011

Meet Mr. Clappidoo



INTRO


Let me introduce Mr. Clappidoo.

Clappidoo sits quietly and will not bother anyone, unless somebody carelessly puts an object in front of him.  Clappidoo will then wake-up and, depending on his "mood" of the moment, will either be:

  1. Angry.  His eyes will turn red and he will grunt at you.
  2. Happy.  His eyes will turn green, and he will chirp with joy.
  3. Confused.  His eyes will flicker randomly and his sound won't make much sense.
  4. Flirty.  His eyes will turn pink, and he will try to capture your heart.
  Clappidoo will go trough all these moods at random, and will go back to sleep if you remove the annoyance in front of him.


HOW DOES IT WORK?


  Many aspects of Clappidoo are similar to my Papydoo Project.  In fact, Clappidoo was an earlier project, and some concepts (and parts) were reused in Papydoo.



THE BASICS


  Clappidoo is built inside a small "chest like" balsa wood box with a hinged lid on top. The front lid locking hardware was removed, so the lid can always open freely.

  Clappidoo detects the presence of objects in front of it with the help of an infrared (IR) reflective proximity sensor.  This sensor has a fixed detection threshold of 10cm (about 4 inches). 

  Each eye contains a 5mm RGB LED, capable of producing any colour with variable PWM drive of each channel.

  The lid is actuated by a small "9g" R/C type servo.  These small servos, mostly designed for R/C aircrafts are very cheap (I bought 6 for $10 on Ebay) and easy to use.

  Clappidoo can make sounds, with the help of a small 8 ohms speaker, mounted inside the box.  The tones are generated by the microcontroller.

  Clappidoo is "always on the lookout", meaning always powered.  It is battery operated, and the three AA batteries last a few months with moderate usage.  Again, like with Papydoo, low-power considerations are essential.

The project is built around a Zilog Z8F042A 20DIP microcontroller.




THE IR SENSOR


IR proximity sensors are very easy to use.  Sharp is the leading manufacturer of these devices (to my knowledge).  Many models exist with various detection range and output type.

An IR LED illuminates the surface, and depending on the distance, a different reflexion path will land the reflected IR at different locations on an array of photo detectors.  There are 2 types of output for these sensors:  Digital or analog.

  The digital variety operates on a fixed distance range and will output a logic high or low if an object is detected within that distance.

  The analog variety outputs a varying voltage depending on the distance of the detected object, if any.  Using a comparator or an ADC, an adjustable distance threshold can be implemented in software.

  Clappidoo uses a digital, 10cm range sensor:  The Sharp GP2Y0D810Z0F.  This is a short range, small and inexpensive sensor, costing about $3.50 at DigiKey.  Some long range sensors can cost upward of $50.00 each.  During operation, the sensor continuously pulses the IR LED many times per seconds.  This means about 5 mA average current, which would quickly drain any battery operated circuit in days.  With Clappidoo, I cheat a little:  I only operate the sensor briefly (one detection cycle) every 1 second.  The trade off is Clappidoo can possibly miss objects staying in front of him less than 1 second.  The proximity sensor is packaged like an IC and has more than the usual 3 signals (VCC, Output, GND).  It has a "power down" pin, which can put the sensor in sleep mode with only 4-8uA quiescent current.  It can also operates over a wide voltage range:  2.7 to 6.2V.  This is more flexible than the usual fixed 5.0V of the larger sensors.  It needs an external 4.3 ohms resistor (I used two 2.2 ohms in series, the nearest I had) and two 0.1uF capacitors.  This sensor looks like a DIP package, but pin spacing isn't DIP.  See the sensor's data sheet for more details. I've mounted the sensor and its 3 external components on a separate small piece of perfboard and mounted it behind a large hole on the front of the wood box.  I've secured it with black hot melt glue, for an even finish.




THE MICROCONTROLLER


  I have the unusual habit of using Zilog eZ8 MCUs in many of my hobby projects.  I began using them many years ago in professional designs and stuck to the family and dev. tool chain.  When you do many projects with the same family of MCUs, there are lots of code re-use opportunities which makes doing projects easier.

  I also use Microchip PICs sometimes, especially the small 8 pins ones, like the 12F675, in many (very) simple projects.  I have some great Parallax Propeller project in store for future posts also.

The Zilog Z8F042A is an 8 bits microcontroller from Zilog's eZ8 XP family of devices.

Main features:
- 4K of flash ROM
- 1K of RAM
- 20MHz max clock freq.
- 5.5592 MHz internal oscillator
- 2 x 16 bits timer
- 20DIP package available
- ADC, UART, temp. sensor, voltage comparator, trans-impedance op-amp (not used in this project)
- Single pin programming and debugging (ICD)
- 2.7 to 3.6V operating voltage
 

  One of my "hacking / making" habit, which adds to the challenge of doing these kind of projects, is to come up with an idea, and build something mostly with what I have on hand.  Having a workshop loaded with parts kind of makes it possible also.

  I've had a small bunch of leftovers Zilog Z8F042A that were collecting dust and not used in any of my work related projects, so I've decided to use one of them here.  The present version of the code fills almost completely the 4K ROM.  An 8K ROM version, the Z8F082A would have been a better fit for this project, but I didn't have any around.  It would have allowed code size headroom for future improvements.

Check out my Papydoo Project Part 2 for more informations about programming and developing C code in the freely available Zilog Development Studio II tool chain. 



THE EYES


Two independent, four pins common anode RGB LEDs are used for illuminating the eyes.  Colours are produced by varying the intensity of each individual channels (red, green or blue) with pulse-width modulation (PWM).  Six PWM channels (three per LED) are necessary to accomplish this.  The Z8F042A has two hardware PWM (bundled with the timers).  That's not enough, and would monopolize the timers, which are used for other purposes.  So all six PWM channels are done in software.  Also, this MCU has four GPIO pins that feature controlled current direct LED drive.  This spares the resistors for four of the six LED channels.

  For a more interesting look, I ripped the eyes from a "chattering teeth" toy like this one:



  I sliced each eyeball in half with a Dremel cutter disc, and glued the front part (with the black dot) over each LED:


  These plastic globes acts as diffusers and colour rendering is better.  They are also phosphorescent, and actually glow lightly in complete darkness.



SOUND



  One of the MCU's timer is used to generate audio tones.  The timer outputs a 50% duty cycle square wave signal on one of the pin.  A push-pull current amplifier, done with two transistors, is used to drive the 8 ohms speaker directly.



SERVO



A servo moves its lever arm based on a received control signal.  The signal is a pseudo-PWM digital waveform.  The on-time of the signal must be between 1ms and 2ms, followed by an off period, to cover the 60 degrees position range (1ms = minimum, 1.5ms = centre, 2.0ms = maximum).  The signal is repeated every 20 milliseconds (the "update" rate).  These servos consume many milliamps, even when not moving, so they need to be turned off when Clappidoo is sleeping.  They have peak current demands of about 500mA when they start moving, so a capable power switch is required.  I use an IRF7343 power MOSFET pair (in a small 8 SOIC package) to power on or off the servo.  It can handle around 2A of current with minimal voltage drop.  The servo is operated directly from input voltage (4.5V) for maximum strength and speed.



VOLTAGE REGULATOR

At the time, I chose to use a micro power LP2950 fixed 3.3V TO-92 low-dropout voltage regulator.  This regulator is designed for low power applications and has a typical 75uA quiescent current drain.  It requires a low ESR capacitor (tantalum) for stable operation.  I thought 75uA quiescent was great, until I discovered the MCP1700 series later on, which consumes even less: 1.6uA!  All my newer builds uses the MCP1700 from now on.  The LP2950 has the same basic "in-ground-out" pinout as the ubiquitous 78Lxx regulators, but the MCP1700 doesn't.



THE FIRMWARE


  Again, like with Papydoo, the microcontroller spends its time sleeping and is waken-up by the watchdog timer every 1 second.  It turns on the IR sensor, wait the appropriate detection delay, then reads the sensor output.  If no object is detected, everything is turned off and Clappidoo goes back to sleep for another second.  If an object is detected, full wake-up ensue, and the microcontroller activates sound, the LEDs and the servo depending on the mood.

  Three timebase are used in the code, although only two genuine 16 bits timers are available in the Z8F042A.  The third timebase is the UART Baud Rate Generator, used as an interval timer because the UART is not needed in this project.  The BRG generates the main timebase used for PWM LED drive and the servo update sequence start.  Timer 1 is used in one-shot mode to generate the servo "on" portion of the pulse.  Timer 0 is used to generate sound tones on the timer's output signal.  LED PWM and servo waveform generation is interrupt driven, as not to bother the main C function.  The Zilog C compiler provides the "interrupt" keyword for transforming a C function in an interrupt service routine:

void interrupt My_ISR(void) {
 
  //... my interrupt service routine code here ...


}


  The eZ8 MCU uses prioritized vectored interrupts.  Each interrupt source has its own entry in the vector table.  The SET_VECTOR directive is used once in the code to add an ISR function to the vector table:

SET_VECTOR(Timer1, &My_ISR);


  LED colours are 4 bits (16 shades) per channel, meaning 12 bits RGB colour space (4096 colours).  One of the "non-obvious-at-first" aspect of the firmware was doing gradual "cross-fades" between two arbitrary colours.  This involves a "Bresenham line drawing" like algorithm.  Imagine each begin and end values of the 3 channels as a line's start and ending Y coordinate, and the X coordinate as the progression in time:  0 to 15.   


The full project source code can be downloaded from here.



SLEEP MODE CURRENT

  This is the current profile through a 10 ohms resistor. (50mV = 5mA).  This is a typical wake-up, sensor read, back to sleep sequence.  It lasts around 5ms with a current average of 20mA.  This would be 100uA averaged on 1 second.




SCHEMATIC

Here is the full schematic:


Clappidoo: A kids' favourite!

Wednesday, April 27, 2011

Project Papydoo - Part 2


This is a follow up to
Project Papydoo - Part 1

In Part 1 I've covered the hardware. Part 2 is about the firmware. There is also an introduction to the ZDS Studio II development environment, because its not as well known as the usual suspects (Atmel AVR, Microchip PIC, etc).


7. The Zilog ICD USB cable



Programming and debugging all recent Zilog MCUs is done with the same probe, or "smart cable". A serial RS-232, USB and Ethernet version is available. The USB version is bundled with most Zilog dev. boards, but can also be purchased separately from DigiKey or others for around $35. This probe does more than just in-circuit programming. It does full source-level in-circuit debugging (stop, trace, breakpoints, watches, registers content, etc.), all from 1 pin on the MCU.

The "native" connector on the ICD probe is a 2x3 pins ribbon cable header. Zilog has organized the pins layout so that its "reversal" proof, I guess.


Personally I don't like this connector. I've devised my own 3 pins .1" SIP connector with only the 3 signals: VCC, DBG and ground.



8. The Zilog Development Studio II IDE


Zilog freely provides a complete development environment suite called "Zilog Development Studio II" for the eZ8 (as well as other) family of Zilog microcontrollers. This is the complete, full-featured version. No demo, trial, or features limit. Its free and complete. Although some developers might find it lacking advanced features found in high-priced tool chains, everything is there for basic ANSI C or assembly development, programming and source-level debugging. For this project, I've used the recently released version 5.0.0. It features a more advanced source editor (with auto-completion, code block folding) and some other minor changes from the previous versions.

For people familiar with Microchip PIC, ZDS is like a less bloated version of Microchip MPLAB with an ANSI C compiler natively included. As far as I know, its mostly an MS Windows app., but heard some people running it inside Wine with Linux, and using the RS-232 ICD probe. See the Zilog forum for more details.


Doing projects in ZDS is very straightforward. You create a "New Project" from the file menu, answer a few questions about the MCU family used, memory size, C memory model, and then add source files to the project.

The full source code, released under a Creative Common license, is available for download at the end of this post.

The code is lightly documented and should make sense to most people familiar with C development on microcontrollers.

Their are a few minor things that I will explain in the following sections, for people unfamiliar with Zilog eZ8 MCUs.


9. eZ8 stop mode and C startup module

When the eZ8 enters stop mode (low power sleep), it stops executing code, turns off the oscillator and wait for an event to trigger a "wake-up", or recovery.

Recovery can come from a state change on an input pin, an external reset or the watchdog timer timing-out. The later is used to "wake-up" the eZ8 after about 1 second of sleep.

Unlike the Microchip PIC16F for instance, code execution doesn't resume where it left off, but at the reset vector. This causes problems with the default C startup module if you want to preserve states or variables content while in sleep. By default, the C startup code clears the RAM content (with zeros), and copy values from ROM for initialized variables. A custom version of the C startup module (startups.asm) was modified and included in the project's folder. This version doesn't clear the RAM on startup:


In the "main" function, a different code path is taken if the device is recovering from sleep, as oppose to a normal power-on reset.



10. "rom"? "near"? "far"?

The rest of the code is pretty straightforward stuff. It could easily be ported to PIC or AVR MCUs, apart from a few nuances in the C code: The "rom", "near" and "far" storage class modifier. The eZ8 is an Harvard architecture microprocessor: Code and data are stored in different address spaces. This poses problem with large arrays of constants (like character font table, menu text strings, ...). Zilog's ANSI C compiler allow the use of the "rom" storage class modifier for explicitly placing arrays in ROM, and generating the proper assembly code to access it:

char rom table[] = { [ ... large data set ...] } ;

The "near" storage class modifier is used in the code for compatibility purposes only, because some other members of the eZ8 family have more the 256 bytes of RAM and uses "far" pointers and the large memory model. In the small memory model, everything is "near".

Near pointers? Far pointers? This brings back memories from the days of x86 programming on MS-DOS :)


11. Bit Order Reversing

Being kind of lazy, I've used a character font table designed for a Nokia 5100 LCD mono display. The HT1632's frame buffer is almost identically structured, except the rows order are reversed: Row 0 is at the bottom of the display, versus the top for the Nokia LCD. This makes the font upside down when drawn in the frame buffer. Correcting the orientation implies reversing the bits order inside a byte: Bits 0 - 7 to bits 7 - 0. There are no efficient (and elegant) ways to do that in C, so I've used in-line assembly to call the BSWAP instruction who happens to do just that, in 1 instruction cycle.


12. Analog to digital converter (ADC)

The ADC of the Z8F083A is quite fast, at 2.8us per conversion. There is not much code that could get executed while waiting for the result. So when I initiate a conversion, I just wait for it to finish and get the result. The ADC is 10 bits and uses an internal 2.0 volt reference.


13. General Purpose Input / Output (GPIO)

The LED matrix operates at 5V, and the MCU operates at 3.3V.

Level translation to 5V is done by configuring output pins in "open-drain" mode, with external pull-up resistors to 5V.

The pushbutton input pin has an internal pull-up resistor enabled.


14. Source Code

The source code can be downloaded here