Saturday, September 11, 2010

Control Ipod

Austin Lu and Albert Ren
Source: http://instruct1.cit.cornell.edu/
Introduction

Have you ever imagined, "What does that cable I plug into my iPod every day actually do, and how do I take advantage of it for myself?" We did too, and that's what we aimed to do with our 476 project. The iPod is, of course, the popular digital music player developed by Apple. The heart of the project is to use the Mega32 microcontroller to transmit and receive commands from the iPod using the built-in Dock Connector, as opposed to cracking the iPod open and wiring it up. The Dock Connector is the little port at the bottom of the iPod that you would normally connect a white USB or FireWire sync cable into. Commands that are currently implemented include play, stop, fast forward and other basic commands that allow the user to enjoy music from the iPod, as well as the ability to display the current track's Title, Artist, and Album on an external LCD display.
This document is written for, primarily, the 476 graders! Just as importantly though, this document is intended for future 476 classes looking for interesting project ideas to tackle, because as far as we could tell, no one had attempted a project dealing with the iPod before. This document is also intended for those searching on the Internet for help on hacking their iPod.




High-Level Design

At first we were worried about the feasibility of the project. We had decided early on that we wanted a project with obvious user feedback. After speaking to Bruce Land about the concept of an iPod dock, we decided that it would be our final project -- what is more obvious than music starting or stopping?

A huge amount of our time involved researching the iPod communication protocol. The iPod's communication protocol through the Dock Connector is not actually publicly available from Apple. However, thanks to the reverse engineering efforts by many hobbyists, there is a lot of information about the protocol (termed the "Apple Accessory Protocol") available on the Internet.

It is possible that the protocol isn't public due to the "Made for iPod" licensing program, which lets accessory makers in the "iPod ecosystem" connect to the iPod and display certain logos on their packaging after licensing. This could present certain legal issues, as it may be considered some form of protected intellectual property. However, as the protocol has been obtained through reverse engineering methods and not through a breach of contract, we do not anticipate this to be a big factor. Additionally, this is only an educational exercise and not in any way intended to be a commercially viable product.

The structure of our project is to have the Atmel Mega32 controller talk to the iPod in both sending and receive mode through the iPod's Dock Connector. We would send commands over the serial pins on the Mega32 and receive on the appropriate iPod pins as well. We can verify that the commands worked by simply observing the iPod and checking to see that the iPod responded appropriately, e.g. with a volume change, skipped track, etc.

The only relevant standards that we use are 8-N-1 serial communication for talking to the iPod. The actual Apple Accessory Protocol is an Apple creation, so not quite a "standard" in a usual sense. Otherwise, we do not make any use of any other standards, such as IEEE or ISO standards. The iPod sends out responses for strings in ASCII format.





Design Aspects

Research

A large amount of work went into determining whether this idea was actually feasible. No one appears to have made any similar efforts in 476 final projects before, and though there is a similar idea in ECE 313, that course was designed around a standard CD player and controlled the player by shorting the buttons.

We initially found the iPod Dock Connector pin-out, which is available from pinouts.ru After that, we eventually found the Apple Accessory Protocol, which is detailed best on the iPod Linux wiki.



Important Pins on the iPod

Pin Use

1 Ground

11 Serial Ground

12 iPod RX; microcontroller transmits on this pin

13 iPod TX; microcontroller receives from this pin

21 iPod Accessory resistor: We use 500k

It's important to note which pins are the receive and transmit pins. On the pinouts.ru page, pin 13 is "Serial RxD," which means serial receive from the iPod's point of view. Mixing it up could confuse you unnecessarily for a few hours.

Once we had a pinout and what looked like usable, if unofficial, documentation of the protocol, we started looking at actual connectivity to the iPod. There were a few efforts done by other people to create their own docks, but these were not quite what we were looking for.

After a bit of searching, we managed to find a hobbyist's website that had the actual iPod connectors available for sale. Even better, they also had a custom PCB available for sale to break out all of the individual signals from each of the pins, which was very useful because the pins themselves are rather small.

A short while later, we ended up discovering a second source for our PCB, which cost about the same as the original source but came with the dock connector pre-soldered, which was very useful as it was probably going to be a better soldering job than we could hope to accomplish by ourselves. Additionally, unlike the other source, it would ship within the United States. Using First Class Mail, we received our component in about 2 days (shipped on Thursday from CO, received on Saturday).

Next, we had to determine what commands it is we wanted to implement. We decided that the basic control functions we're all familiar with - Play/Pause, Volume Up and Down, Skip Forward and Backward - must be implemented. We decided next that the "good to have" functions would be receiving data from the iPod and displaying it on the LCD screen, namely the current track's Title, Artist, and Album.

All of the control details can be reverse engineered using a breakout board with a pass-through connector (in other words, a female iPod connector) and a commercial accessory that implements the same feature. All you'd have to do is plug the accessory into the pass-through connector, the pass-through into the iPod, and listen in on the serial pin.

It turns out that the iPod has a set of "modes" that it categorizes the functions in. The basic set of functions all belong in Mode 2, while the "good to have" receiving functions are all Mode 4. We also use functions from Mode 0 in order to change the iPod mode. This is important, because it changes how you expect to send and receive the data packets with the iPod.

Communication with the iPod is conducted over a serial protocol with a standard 8N1 setting at 19200 baud. This means that each packet has 10 bits. The packet starts with a low start bit, 8 bits (1 byte) of information, no parity, and a high stop bit. Each packet has a very ordered structure, which is as follows:

Section Size of Section (in bytes) Value

Header 2 0xff 0x55

Length of packet 1 Indicates the number of bytes for mode, command, and parameter

Mode 1 Mode for this command

Command 2 Command we're sending or receiving

Parameter 0 to n Optional - Some commands use this to supply more info

Checksum 1 (0x100 - [actual values of length + mode + command + parameter]) & 0xff

This table is modified slightly for clarity from the iPodLinux page on the subject. This is the case for other tables that appear in this section as well.

Incidentally, each 8-bit chunk of data in a serial packet is transmitted in Little Endian mode. The serial protocol also idles at VCC-high when not sending.

The command codes for the functions we have selected are shown below:



Mode 0 Commands

Command Function

0x01 0x02 Switch to Mode 2

0x01 0x04 Switch to Mode 4



Mode 2 Commands

Command Function

0x00 0x00 Button Release

0x00 0x01 Play

0x00 0x02 Volume Up

0x00 0x04 Volume Down

0x00 0x08 Forward

0x00 0x10 Backward



Mode 4 Commands

Command Parameter (in bytes) Function

0x00 0x1e 0 Get Current Position in playlist

0x00 0x1f 4 Current Position Result

0x00 0x20 4 - current position Get title of current song

0x00 0x21 string - unknown length Title result

0x00 0x22 4 - current position Get artist of current song

0x00 0x23 string Artist result

0x00 0x24 4 - current position Get album of current song

0x00 0x25 string Artist result

We were led to believe that Mode 2 commands needed to be sent 66 times per second until button release. However, from our experience this is not necessary. The command only needs to be sent once for the iPod to act upon it. Once the command is sent though, it is necessary to sent a button release command to indicate, well, the button's release. Otherwise, the iPod is going to assume that the button is being held and will do what it normally does in such situations. For example, pressing Play without a Button Release will turn your iPod off (a tidbit that confused us for a little bit).

The Mode 4 commands that we implemented seem basic, but as far as we could tell, very few accessories currently on the market take advantage of the mode 4 commands. As far as we know, only iPod car-kits use the mode 4 commands; these car kits scroll similar information on the dashboard.

Mode 4 commands require that the iPod be switched into Mode 4 using a Mode 0 command, when the iPod will display "OK to disconnect" and cut off interaction with the physical on-iPod controls until the dock connector is removed. With exception of volume control, the standard Mode 2 commands are still accepted, even though it is currently in Mode 4. Annoyingly, switching into Mode 4 also pauses the currently playing track.

The current position numbering is transmitted in 4 bytes, with each byte in Big Endian notation. Do not confuse this with the Little Endian transmit inside the individual bytes. The returned strings for Title, Artist, and Album are null terminated.



Program Design

The state machine operates on a single assumption: the iPod talks back only when we want it to. If the iPod were to send a message when we were not expecting it, we would ignore the iPod. Additionally, we have helper functions that wait for input from the user which set flags to alert the state machine.

The state Command is the initial state of the microcontroller. In Command, we wait for the validcommand flag to be set from the button debouncer. This flag alerts the state machine to proceed to DecodeCommand. Otherwise, Command checks to see if the releaseflag has been set and whether the mode is set to 0x02. If it is, send the state machine to the button_release state.

The next state is DecodeCommand. DecodeCommand prepares the character array t_buffer to be transmitted through the UART. In this state, the two modes are differentiated -- if the button pressed was of mode 0x02, the length of the command is typically shorter. If the command was of mode 0x04, the counter mode4flag is set to 1, which will alert the state machine that the iPod will be responding. The state proceeds to Send.

In Send, mode4flag is checked. All the mode 0x04 commands require that the iPod switch to a mode 4 state. We discovered that the iPod readily accepts both mode 0 and mode 2 commands, but will not recognize mode 0x04 commands. Thus, there is a sequence of commands to execute before sending a mode 4 command. This sequence is embodied in the mode4sequence counter. We will send commands based on what mode4sequence is.

The first command in mode4sequence is a switch to mode 4 command. Then we wait several milliseconds before transmitting a "current song" command. We check to see if the command was successful (the iPod sends back the current track if the command was received, and sends back a failure if the command was incorrect). Finally, we send the mode 0x04 command that has the parameter currentsong to determine characteristics of the song. Again, we wait for the iPod to respond. The last command in mode4sequence is switching the iPod back to mode 2. We made this decision because in mode 2, we can use volume up and down. Additionally, the iPod screen is ugly when it enters mode 4. Whenever we wait for the iPod to respond, we will be in the "Receive" state. Upon a successful response, the state will return to the Send state. If the command was of mode 0x02, the state machine will transition to Command. To transmit a command, we call on the helper function puts_int().

We should only enter the Receive state if the command is of mode 4. Depending on what mode4sequence is, the state machine may re-enter the send state (switching iPod modes do not require responses), or the state machine waits for the Receive interrupt to set the r_ready flag. Upon receiving a buffer, the buffer is dissected and the iPod response is determined. Upon a successfully sending a command, the state machine changes mode4sequence, resets the failure counter and returns to the Send state to send the next command in the sequence. Upon a failure, the state machine increments the failure counter and returns to the send state without changing the sequence. This means that the command that failed will be sent again. Once the failure counter hits the failure threshold, or if we have exceeded our timeout limit, the state machine returns to the command state.

The button_release state should occur when the user has finished sending a mode 0x02 command. The t_buffer is set to the button release command, which is of mode 0x02, and is transmitted to the iPod. The state then proceeds to Send.





Helper functions we used:

initialize() sets up the LCD display and determines the baud rate that we use. Since the iPod transmits at 19200 bits per second, we set UBRRL to 51. Additionally, an interrupt is set to trigger every millisecond, which provides the clock for the state machine.

buttons() is called every millisecond, and checks to see if a button has been pressed or not. If the previous button (lastpress) is 0, and there is a button press (press != 0), then debouncecounter begins to increment. When debouncecounter reaches 40 (40 ms have passed), the validcommand flag is set high, and the debouncecounter is reset to -460. Thus, the debouncecounter also functions as a hold timer. After 500ms have passed, the validcommand flag is set high again, and the button press is sent again.

As it turns out, when an iPod receives a mode 0x02 command, it continues performing that operation until a button release command is sent. However, the iPod does not send any acknowledgment regarding mode 2 commands, unlike mode 4 commands. Thus, we decided to err on caution and simplicity, and send the command multiple times if the button is held down noticeably. It would be an interesting question to ask if the iPod functions similarly for internal button presses (e.g. on the click wheel). Clearly, volume up/down is handled differently on the iPod due to the wheel motion.

Finally, we have a helper function called lcd_scroll(). This helper function is called every 300 ms, and is used to scroll the title, artist, and album fields on our little 16x2 LCD screen. These fields need to be scrolled if the fields are longer than 16 bits, which would not display nicely on our LCD screen. It works by copying over the relevant part of r_buffer, namely the part that includes the string fields, to another array, lcdbuffer. That array is then copied over into a "scratch" LCD buffer, displaybuffer, which includes exactly what 16 characters are supposed to be displayed on the LCD. Thus, every 300 ms, we move the LCD display buffer over by 1 character and update the LCD screen. Additionally, we also loop around to the beginning when we hit the end of our string field, so the scroll itself loops too.

puts_int() starts transmitting t_buffer through the UART. It resets all through t_index and t_ready, then calls put_char() to transmit the first character of t_buffer. Afterwards, the interrupt transmits each character at a time.


Tricky Stuff
To send and receive, we initially used Bruce Land's serial transmission code and modified the stop conditions to checksums instead of null terminators. Additionally, the transmit interrupt would not stop at the appropriate place -- we rewrote the code so it was logically the same, but now would stop at the appropriate spot.

Within the receive interrupt, we realized that a parameter within an iPod response could erroneously match the checksum. For example, when sending back the album title "Good News for People Who Like Bad News," one of our implementations stopped at the space character (' ') because its ASCII code, 0x20, matches the incomplete computed checksum. The old implementation detected this match and considered it to be the end of the transmission, while the actual checksum was quite a few bytes later. After finding several checksum collisions, we changed the end condition of the receive interrupt to look at the length of r_buffer to prevent the premature setting of r_ready flags.

How the Send and Receive states intertwined was easily the trickiest part of the code. The sources we used did not explicitly tell us every response an iPod would give us -- for example, mode switching was not well documented and we were not aware of its necessity. Originally, we were planning to ignore responses that we did not care about. After spending some time in lab, we decided that this was not the correct approach, and spent time determining all the responses.

When the iPod leaves mode 4 and enters mode 2, the iPod can ignore commands! When the user presses the physical play button on the iPod, there are no issues. In contrast, the iPod ignores the serial Play command up to three times! We believe there is a command in the sequence missing that we are not aware of and/or is not documented. We cannot see what a "proper" commercial implementation does as we do not own an accessory that actually makes use of Mode 4 commands and, as a result, cannot intercept and spy on what other implementations do. Thus, to start playing a song after entering Mode 4, the user needs to hit the play button twice on our implementation.

Finally, John Sicilia showed us a clever way of checking the receive buffer using the LEDs. Light up the LEDs according to the character in the buffer, delay for several seconds, turn the LEDs off for some time, and then move on to the next character in the buffer. Prior to this method, we had been looking at the waveform on the oscilloscope, which works fine but is very time consuming. When there were issues like the checksum error, we would compare the oscilloscope waveform to the output from the LEDs. A sample of this technique is shown here; be sure to include delay.h:

for(k=0; k<11; k++)

{

PORTB = t_buffer[k];

delay_ms(5000);

PORTB = 0xFF;

delay_ms(500);

}

while(1);

Hardware Design

The microcontroller outputs a high and low voltage of 5V and 0V respectively. However, the iPod operates at a maximum of 3.3V for high. Thus, for the serial transmission line, we created a voltage divider, so that when the line is pulled to 5V, the iPod sees 3.3V. The high level schematic is below.

Additionally, the iPod only outputs a maximum of 3V when transmitting serially. We used an LF353 op-amp to increase the output voltage to 5V. The schematic for a non-inverting amplifier is shown below, where R2 is 1 kilo-Ohm and R1 is 2 kilo-Ohms. The Gain is 1+(R2/R1), where our values give a gain of 1.5.

Issues that we encountered

Everyone warns you about it, but somehow we got bit by it anyway. We're referring to, of course, having extra components for important things that you need. In our case, the critical piece was the PCB breakout board for the dock connector. It turns out that a pin inside the connector was no longer well connected with the pin connected to the board. This meant that our wire connection was good all the way from breadboard, to PCB, to the pin leading inside the dock connector, but the pin inside the dock connector was flaky. We had anticipated this and ordered another connector as a spare, but this took additional time and put time pressure on our schedule that we would've liked to do without.
Results

The serial commands sent to the iPod and the responses from the iPod were sent and received accurately, which we could verify by looking at the waveforms on an oscilloscope and also by the eventual display on the LCD. The LCD displays and scrolls correctly, and the iPod responds to each command appropriately and quickly, depending on how fast a person can push the button. Neither safety nor interference were much of a concern, as our design did not really pose much of an issue in these categories. Usability could possibly be improved, as the pushbuttons are currently on the STK and not in a particularly nice enclosure, for example. If this were a prototype for a commercial design, it would be easy to fix though.
Conclusions

The results of this project met our expectations. We wanted to both control and receive from an iPod with a microcontroller, and this was accomplished. Our design used the serial communication protocol 8-N-1, and for this we used Bruce Land's serial communication code as a jump-off point for our serial communication code. As mentioned before, the specifics of the iPod communication protocol came from researching the reverse engineering efforts of other hobbyists, and we communicated with a few of them if there we had specific questions about the protocol. The documentation of the protocol was fairly good but, as always with documentation and especially unofficial documentation, could have been improved and more clear. Hopefully our writeup here will clarify certain things that are confusing. We do not expect to have any patent opportunities with this project.

Future Design Aspirations

If we had more time available, we would have liked to implement an IR receiver with the microcontroller. Thus, a user could use an IR remote to send commands to the microcontroller, which would then be relayed to the iPod. We also could have implemented more mode 4 commands, with more pushbuttons being our main constraint. Additionally, future efforts could involve changing the 16x2 LCD for a more complicated and complex one that could allow displaying more information at once or even color images, such as album art or pictures. An audiophile may want to add something that uses the Line-Out component of the connector, as those pins are readily accessible as well.


Ethics

We believe that our project was consistent with the IEEE Code of Ethics. For example, we believe that our project is safe to individuals and the public at large, and we would promptly notify everyone if this ever changed. We believe that we have been honest about our project's performance and potential future efforts. We also hope that our project has made the iPod (and similar MP3 players for which control data can be obtained) an attractive option for future hobbyists and 476 students.

In the interest of full disclosure, one of us was formerly employed by Apple (then known as Apple Computer). It should be noted that none of the material referenced in this project or on this page resulted either directly or indirectly from any material obtained during employment or with any use of Apple-owned resources, such as hardware or documentation. We have made careful efforts to ensure that nothing done here would compromise any previous or (hopeful) future employment agreements and that we have respected intellectual property throughout.

No animals were harmed in the making of this project. Cornell students were merely deprived of sleep.

Wednesday, September 8, 2010

Infra-Red Remote Control Tester

Author: W. Foede
Copyright: Elektor Electronics

This little circuit is invaluable for quick go/no-go testing of just about any remote control transmitting infra-red (IR) light. The tester is battery-powered, built from just a handful of commonly available and inexpensive parts, and fits in a compact enclosure. Schmitt trigger gate IC1f is used as a quasi-analogue amplifier with, unusually, an infra-red emitting diode (IRED) type LD274 acting as the sensor element.

An R-C network, C1-R2, is used at the output of the gate because all IR remote controls transmit pulse bursts, and to prevent the output LED, D2, lighting constantly when day-light or another continuous source of IR light is detected.

Picture of the project:
Circuit diagram:

Parts layout:
PCB layout:

Cased project:
This creates a useful ‘quick test’ option: point the tester at direct daylight, and the indicator LED should light briefly. The sensitivity of the tester is such that IR light from remote control is detected at a distance of up to 50 cm. The circuit is designed for very low power consumption, drawing less than 1 mA from the battery when IR light is detected, and practically no current when no light is detected. Hence no on/off switch is required. The construction drawing shows how the tester may be ‘cased’ using a small ABS case from Conrad.

COMPONENTS LIST
Resistors:
R1,R2 = 10MW
Capacitor:
C1 = 10nF
Semiconductors:
D1 = LD274 (Siemens)
D2 = LED, 3mm, low-current
IC1 = 74HC14
Miscellaneous:
Bt1 = 3V Lithium cell with solder tags, e.g.type CR2045 (560 mAh)

LED torch

author: Rev. Thomas Scarborough
e-mail: scarboro@iafrica.com
web site: http://www.zen22142.zen.co.uk

A common problem with small torches is the short life-span both of the batteries and the bulb. The average incandescent torch, for instance, consumes around 2 Watts. The LED Torch in Fig. 1 consumes just 24 mW, giving it more than 80 times longer service from 4 AA alkaline batteries (that is, up to one month's continuous service). Although the torchs light output is modest, it is nonetheless quite sufficient to illuminate a pathway for walking.

The LED Torch is based on a 7555 timer running in astable mode (do not use an ordinary 555). A white LED (Maplin order code NR73) produces 400 mcd light output, which, when focussed, can illuminate objects at 30 metres. Try Conrad Electronic for what appears to be a stronger white LED (order code 15 37 45-11).
A convex lens with short focal length is placed in front of the LED to focus the beam. If banding occurs at the beams perimeter, use another very short focal length lens directly in front of the LED to smooth the beam.
If a different supply voltage is preferred, the value of resistor R3 is modified as follows:
9V - 470 Ohm
12V - 560 Ohm
Circuit diagram

See my "Wind-up Torch" feature article in the October 2000 edition of Everyday Practical Electronics for a completely battery-free go-everywhere torch.

Step-Down Converter Controller

source:
The TPS6420x controller is designed to operate from one to three series-connected cells or from a 3.3 V or 5 V supply obtained from a USB port. At its output it can produce 3.3 V at 2 A, suitable for powering a microcontroller-based system. With a suitable choice of external components (inductor, P-channel MOSFET and Schottky diode) the device can be operated over a wide range of possible output voltages and currents. A further advantage is its extremely low quiescent current consumption in power-down mode (100 nA typical) and in no-load operation (20 mA).

Also, if the input voltage is less than or equal to the desired output voltage, the device can connect the output directly to the input. Using just a few external components the TPS6420x can cover an output voltage range from 1.2 V up to the input voltage at up to 3 A, as long as a suitable P-channel MOSFET and Schottky diode are used. The device is an asynchronous step-down converter which, unlike the more widely-used PFM (pulse-frequency modulation) and PWM (pulse width modulation) types, involves a constant on-time and/or constant off-time.

Conventional controllers operate in PWM mode at medium to high loads, switching to PFM at lower loads in order to minimise switching losses. The controller described here also adjusts its switching frequency in accordance with the load to achieve a similar effect to the PFM/PWM controllers. The circuit diagram shows a classical step-down converter with an input voltage range from 3.3 V to 6 V and an output voltage of 3.3 V at a current of up to 2 A. The optional 33 m shunt resistor provides for current limiting.

Circuit diagram:
step-down converter controller circuit  schematic

step-down converter controller circuit  schematic



The TPS64202 offers a minimum on-time selectable between 1.6 ms, 0.8 ms, 0.4 ms and 0.2 ms and a fixed off-time of 300 ns. A MOSFET in the supply voltage path is switched on by the controller for as long as is necessary for the output voltage to reach its nominal value, or until the maximum permissible current, as determined by the shunt resistor, is reached. If the current does exceed this limit the MOSFET is switched off for 300 ns. If the nominal output voltage is reached, the MOSFET is switched off and remains in the off state until the output voltage once again falls below the nominal value.

At very low output currents the controller therefore operates in ‘discontinuous mode’ (DCM). Each switching cycle begins with the current at zero. It rises to the threshold or maximum value, and then falls again back to zero. At the moment of switch-off the Schottky diode causes the residual energy in the inductor to appear as a quickly-decaying oscillation at the resonant frequency of the output filter. This low-energy oscillation in discontinuous mode is normal and has no adverse effect on the efficiency of the converter.

It can be damped using the (optional) RC series network. At higher output currents the switch-down converter operates in continuous conduction mode (CCM). In this mode the inductor current never falls to zero. The output voltage is directly proportional to the switching mark-space ratio in this mode. If the Si2323 P-channel MOSFET from Vishay-Siliconix is not available, the IRLML6401 (12 V type) or IRLML6402 (20 V type) from IRF can be used instead.

Both these types have a higher on resistance, but do offer a lower gate capacitance. An alternative for the Schottky diode suggested is the MBRM140 (available from Digi-Key and Farnell), although this is in an SMB package rather than the Powermite package of the MBRM120. The voltage drop at 1 A is somewhat higher: 0.6 V instead of 0.45 V. The devices are manufactured by IRF and ON Semiconductor.

Literature at http://www.ti.com:
SOT23 Step-Down Controller, document reference number SLVS485
TPS6402 Evaluation Module (3.3 V, 2 A), document reference number SLVU09

Step-Down Converter Controller

source:
The TPS6420x controller is designed to operate from one to three series-connected cells or from a 3.3 V or 5 V supply obtained from a USB port. At its output it can produce 3.3 V at 2 A, suitable for powering a microcontroller-based system. With a suitable choice of external components (inductor, P-channel MOSFET and Schottky diode) the device can be operated over a wide range of possible output voltages and currents. A further advantage is its extremely low quiescent current consumption in power-down mode (100 nA typical) and in no-load operation (20 mA).

Also, if the input voltage is less than or equal to the desired output voltage, the device can connect the output directly to the input. Using just a few external components the TPS6420x can cover an output voltage range from 1.2 V up to the input voltage at up to 3 A, as long as a suitable P-channel MOSFET and Schottky diode are used. The device is an asynchronous step-down converter which, unlike the more widely-used PFM (pulse-frequency modulation) and PWM (pulse width modulation) types, involves a constant on-time and/or constant off-time.

Conventional controllers operate in PWM mode at medium to high loads, switching to PFM at lower loads in order to minimise switching losses. The controller described here also adjusts its switching frequency in accordance with the load to achieve a similar effect to the PFM/PWM controllers. The circuit diagram shows a classical step-down converter with an input voltage range from 3.3 V to 6 V and an output voltage of 3.3 V at a current of up to 2 A. The optional 33 m shunt resistor provides for current limiting.

Circuit diagram:
step-down converter controller circuit  schematic

step-down converter controller circuit  schematic



The TPS64202 offers a minimum on-time selectable between 1.6 ms, 0.8 ms, 0.4 ms and 0.2 ms and a fixed off-time of 300 ns. A MOSFET in the supply voltage path is switched on by the controller for as long as is necessary for the output voltage to reach its nominal value, or until the maximum permissible current, as determined by the shunt resistor, is reached. If the current does exceed this limit the MOSFET is switched off for 300 ns. If the nominal output voltage is reached, the MOSFET is switched off and remains in the off state until the output voltage once again falls below the nominal value.

At very low output currents the controller therefore operates in ‘discontinuous mode’ (DCM). Each switching cycle begins with the current at zero. It rises to the threshold or maximum value, and then falls again back to zero. At the moment of switch-off the Schottky diode causes the residual energy in the inductor to appear as a quickly-decaying oscillation at the resonant frequency of the output filter. This low-energy oscillation in discontinuous mode is normal and has no adverse effect on the efficiency of the converter.

It can be damped using the (optional) RC series network. At higher output currents the switch-down converter operates in continuous conduction mode (CCM). In this mode the inductor current never falls to zero. The output voltage is directly proportional to the switching mark-space ratio in this mode. If the Si2323 P-channel MOSFET from Vishay-Siliconix is not available, the IRLML6401 (12 V type) or IRLML6402 (20 V type) from IRF can be used instead.

Both these types have a higher on resistance, but do offer a lower gate capacitance. An alternative for the Schottky diode suggested is the MBRM140 (available from Digi-Key and Farnell), although this is in an SMB package rather than the Powermite package of the MBRM120. The voltage drop at 1 A is somewhat higher: 0.6 V instead of 0.45 V. The devices are manufactured by IRF and ON Semiconductor.

Literature at http://www.ti.com:
SOT23 Step-Down Controller, document reference number SLVS485
TPS6402 Evaluation Module (3.3 V, 2 A), document reference number SLVU09

Video object tracking


For our project, we wanted to push the video sampling and processing capabilities of the ATmega644 8-bit microcontroller. Using a high-speed analog-to-digital converter as an input device, we were able to sample a reasonably high-resolution grayscale image from a color camera's video output. Using this grayscale image, we are able to track objects and recognize shapes that stood out from the background by a customizable threshold.
From this system, we created a game called Human Tetris to show the shape recognizition capabillity. In this game, players must contort their bodies into shapes displayed on screen in a given amount of time. To demonstrate the potential for our device to expand to a larger game library, we also implemented a port of Brick Breaker. This game shows off the object tracking capability, where players must physically interact with the bouncing ball to keep it on screen and break bricks.


High Level Design

Almost all major gaming consoles are moving to user input systems involving tracking all or part of a player's body (see Nintendo Wii Remote, PlayStation Move, and XBox Project Natal). Our project setup is similar to Project Natal, which Microsoft claims to be a "controller-free gaming and entertainment experience", using a single sensor device (with at least camera and microphone) placed by the TV. We have demonstrated the feasibility of a basic motion-controlled gaming system using low-cost parts.
The system is based off of an ATmega644 microcontroller with two peripherals: a high-speed flash analog-to-digital converter, and an onscreen display device for video overlay. With just 4 kilobytes of RAM and a 20MHz clock speed, the MCU needs these peripherals to take some of the load off of its processing capabilities. Since we wanted to provide a real-time camera feed on the display (like a "mirror" for the player), and since the ATmega644 is not fast enough to generate a full color NTSC signal, we decided early on that we would use a color video camera module which outputs an NTSC signal directly.
The system accepts a color NTSC video signal, filters out the DC component, and samples the video stream at real-time speed. This sample is stored as a grayscale image in the MCU's memory which can be processed by the application. The onscreen display overlays shape information and game data for user interaction.

highlevel
High-level block diagram
Based on this system, we have implemented a video arcade game called Human Tetris, based on a Japanese game show event. In the game, contestants are faced with an oncoming solid wall with a shape cutout. The players must fit through the shape, or else they are thrown back into a pool of slime.

Our game displays a shape on the screen which the players must fit into within a short amount of time. If they succeed, they are faced with more difficult shapes and shorter amounts of time until they are inevitably "slimed". The game provides the player with real-time feedback by displaying the video on the screen with the device's interpretation of their shape.
Our project involves two standards: NTSC and SPI. NTSC is well-defined and is used as our input and output medium. SPI is more of an agreement than a standard, and our project uses it internally to the specifications of the microcontroller and on-screen display device.
Tetris is copyrighted and trademarked thoroughly, so attempts to turn this project into a product would have to be preceded by licensing talks or altering the aesthetics. "Human Tetris" is a commonly used description for the game show our game is based on, but the actual game play is not that of Tetris.

Hardware

Prototyping

Our finished product is neatly tucked onto a 2.5" x 3.8" custom printed circuit board, but for most of the design stage, we prototyped on an STK500, a solderless breadboard, and the ATmega644 custom target board. Our earliest prototyping simply involved working with the ATmega644 on the STK500, with the surface-mount peripherals soldered to breakout boards on a solderless breadboard, attached to the STK with long, loopy wires. We also used the large protoboards as an external power source to feed our substantial power requirements. Slowly, we weaned off our dependence on the STK and moved to using just the solderless breadboard and the target board, with an on-board power circuit. Once the PCB was set up, everything was contained

Design & Components

camera_mirror
Camera mounted in mirror enclosure
At the start, we decided in our high-level design that it was essential for the user to have real-time feedback of their position on the screen. This allows the player to correct their position on screen or move to an object. Since our microprocessor is not capable of outputting color NTSC, we decided to use a camera which outputs an NTSC signal directly. Then, we could split the signal for display and processing. We chose the CM-26N color video camera because it was moderately priced and simple to use: simply plug in power, and it outputs a video signal. It also has a few features we were not aware of when we bought it, such as auto-brightness. One thing that we did not realize until setting up the system was that a camera pointed at the player would not produce a "mirror" effect like desired; instead, if a player moves to the right, he will move left on the screen. To remedy this, we used a low-tech solution: we point the camera at a mirror to flip the image it sees and displays on the screen, so that the game feels more natural to the player.
The signal from the camera goes through an RC input filter which biases up the signal swing to about 0.5V to 2.0V. This is based on the MAX7456 datasheet's "Typical Operating Circuit", which specifies a 75 Ohm load resistor to ground and a 0.1uF input coupling capacitor. Originally we had intended to create two separate circuits for display and processing using current buffers, and a shift/gain op-amp for input into the analog-to-digital converter. However, it was simpler and worked just as well to use the same signal as an input to both devices; it did not produce any detrimental effects.
The signal from the camera went into the analog input of the TLC5540 flash ADC. Since this signal swung from about 0.5-2.0V, we set up a bottom reference voltage of 0V and a top reference voltage of 2.0V, using a combination of the ADC's internal voltage divider and a parallel resistor. This provided a good level of resolution for our application. We set up a clock output from the MCU to go into the sampling clock port of the ADC, so that we could control the clock speed through software. The 8-bit parallel output from the ADC went to the 8 pins on the MCU's port C. During prototyping, we experienced a lot of noise on these high-frequency digital signals, which produced some bad reads and unexpected behavior. The custom PCB brought these components must closer together with good traces between the two devices, which essentially eliminated all of these problems.


overall
Overall hardware components [large image]
The MAX7456 on-screen display (OSD) was used as our primary output device, to overlay characters and data on top of the video signal going from the camera to the TV. The SPI interface between the MCU and the OSD allowed high-speed communication for user feedback. It also took a lot of processing demands off of our MCU, since we could just tell the OSD what to do over SPI quickly, and the OSD would take care of the video overlay and timing issues. The OSD also provided some incredibly useful synchronization pulses for vertical sync and horizontal sync in the NTSC signal. We used these outputs to tell our MCU when to sample the video. We had a lot of trouble during the prototyping stage with bad writes to the OSD, most likely due to noise in the high-frequency communication on the SPI wires connecting the devices. Similar to the case with the ADC, when these components were carefully placed on the custom PCB, all of these issues disappeared, and the SPI communication could be cranked up to several MHz.
While we were originally planning on using the ATmega644 MCU, we wanted to sample the part, and we could only get samples of the ATmega644PA. These microprocessors are virtually identical (the 'P' is a low-power version of the chip, and the 'A' represents a manufacturing change). Virtually none of the hardware or software needed to be changed to accommodate this new chip. We opted to run the chip at the maximum clock speed of 20MHz for highest performance, but this is still below the threshold for direct video capturing or generation, which is why we had to use the two peripherals. We were also limited to the 4K of RAM, which limited the amount of pixels from the sampled image we could store. Otherwise, the MCU acted a central hub for the entire circuit: everything was controlled by the MCU, and it implemented all of the game and user interface logic. We determined that the current drawn by the total circuit was close to 0.6A (camera ~120mA, OSD ~430mA, flash ADC ~20mA, atmega644pa ~12mA), so we used a power adapter and created a power circuit that supplied up to 1 Amp of current. We used a 12V DC power supply, a 1A rectifier (1N4001), and a 5V voltage regulator (LM340T5). We also included a power switch to break the connection from the supply to the power circuit.
Our finished product contains an on-board power circuit with power switch, reset and user interface buttons, blinking LED heartbeat (with jumper to turn off), camera and program headers, exposed RX/TX ports for serial debugging, three surface mount chips (ADC, MCU, OSD), two crystals, several resistors and capacitors, a ground plane to reduce noise/interference, and an RCA jack for video output to a TV.

Custom PCB

custom_pcb
Close-up of custom PCB [large image]
About half way through the design stage, we realized that a custom PCB could be very beneficial to our project. After getting approval from Bruce Land, we decided that we would attempt to design and build a custom PCB after we had finalized our hardware design, budget and time permitting.
After we received and soldered components to the PCB, we found one small connection problem on the NTSC input circuit, which destroyed the signal. The resistor's lead in the RC circuit had to be moved to the other side of the capacitor [corrected PCB design file in schematics]. After a bit more debugging, the PCB worked perfectly. It essentially eliminated all of the noise and other issues we were having with our hardware. There were no longer any bad reads from the ADC or bad writes to the OSD. Everything behaved as it was designed, despite the high frequency signals we were sending between components.

Software

Our software consists of several major sections, corresponding to various hardware pieces and the various tasks required to achieve our goal. The first thing we developed was the driver for the on-screen display device, since that would be our only real output. Then we worked on getting video signal input. With input and output functioning, we moved on to data processing. Once we had a handle on how many resources we had left (in terms of memory and cycles), we moved onto writing the logic for program flow. With a simple shape-tracking library now at hand, we fleshed out the test code into Human Tetris and added Brick Breaker as a quick demonstration of the shape-tracking code's potential.

SPI Driver for On-screen Display

Talking to the MAX7456 On-Screen Display through the ATmega644's Serial Peripheral Interface proved to be an interesting challenge. Thankfully, someone had written an open-source library for doing so based on the ATmega162 architecture. Porting that to run on the ATmega644 was just a matter of reading data sheets and swapping register values for macros. However, the open-source library was based on bit-banging. Since Bruce Land covered using the ATmega644's hardware SPI in lecture, we upgraded our driver to use that. Writing to the SPI works very well, and works as fast or slow as we can set it. Unfortunately, we never got SPI reads to work and are not sure why. But since we only needed the MAX7456 for output and it has such a well-designed interface, this was not a problem. One way reading could have helped would have been to confirm writes, since noise was a major problem prior to using the PCB. To combat the noise, we just reset all configuration options right before every frame, and hoped for the best on transmitting the frame data.
Our first surprise lesson in writing all of the datasheet came when we tried flashing a complete set of new characters to the OSD's EEPROM character memory. Hardware constraints limit this action to only 8 characters at once (per on-off cycle). Since our output goals involved using the OSD to display much more than text, we needed a better option than programming and booting it 32 times over every time we altered our OSD images. Hooking up the OSD's reset line to an output that we could toggle allowed us to use one run of the microcontroller to program the entire character memory.
charset
Custom character set
Custom characters themselves were a cinch thanks to the same person that wrote the open source SPI driver. There exists a web page (see references) that will take a PNG image of all 256 characters and return a C header file of character data ready to be used by the open source driver. Our only issue here was that for some reason having an array of PROGMEM array pointers caused all the data to land in the Data memory, which was way above our 4kB limit. Using a rather long function to load the character data on a per-character basis solved the problem.
Part of our need for custom characters came from one of the OSD's limitations, it only displays 13 rows of 30 characters each in NTSC mode. Also each character pixel is either black, white, or transparent. But each character is 18x12, so NTSC "pixel" level display is still possible. We split each 18x12 character into a 3x2 grid of 6x6 sub-characters, giving us a 39 x 60 symbol screen resolution. 6 sub characters means 64 possible combinations of them, so we wrote makedots.m in Matlab to take a 6x6 pixel symbol and output all 64 combinations as an image ready to send to the character map conversion website. By keeping them in a clever order in PROGMEM, we could get our desired 18x12 output character by using 6 bit flags per character and then just adding the address of the blank to the sum. To get a 18x12 block from 6 pieces of 6x6 data, we just take the majority vote of the 6 pixels, with ties going to blanks.

NTSC Sampling

As one might imagine, getting a video signal into the ATmega644 proved to be quite a challenge. Talking to our flash ADC was rather trivial, since its only input from the micro controller was a clock. Things got less trivial when we realized the suggested clock minimum frequency was 5MHz, which is 1/4 of our own clock speed. We set up Timer 2 to control an output bit, so it could run independently of the CPU. Prior to using the PCB, we setteled for 1.25MHz as a balance between noise and temporal resolution. Once we had the PCB, running the ADC clock at 5MHz worked best.
ntscsignal
NTSC signal behavior. [Stanford EE 281, Laboratory Assignment #4 "TV Paint". See References]
With the clock set up, we had an 8 bit digital version of NTSC flying at our MCU. If we tried to read it all in, we would be out of RAM in 400 microseconds. Down-sampling was a necessity. 39x60 pixels not only down-sampled nicely to the OSD, it took up just over half our RAM. So we can only hold one "frame" at a time. Loading 39x60 out of a 242x338 signal meant sampling roughly every 6th pixel in every 6th line of an NTSC frame. Lucky for us, our OSD not only output NTSC, it output the horizontal and vertical sync pulses. We connected those directly to the ATmega644's hardware interrupts, so we could get fairly accurate responses to the start of every frame and the start of every line. The "porches" gave us time to context switch to the ISRs and do the book keeping necessary for down-sampling. 60 samples on a 51.5us line of data meant one sample every 0.85us, which is 17 cycles. To achieve this level of accuracy, we inserted NOPs into our C code until things lined up correctly. We also used microsecond delays and NOPs to center or reads along the visible data part of the horizontal line.
To get the sampling perfect, we needed something better than the imperfect display of our NTSC output. We connected up the UART and wrote a method to dump out a frame of data on to it. However, dumping a frame of data takes almost a minute, so we had to make it due so only after a button push. This made for excellent comparison of test images to read results, which were visualized using MATLAB. We also wrote a MATLAB function to read directly from the UART, which was sometimes more convenient. Viewing our raw data on the computer helped us notice when we had only a few pixels of either porch data or bad reads.

Input Filtering

A few pixels of bad reads would have been okay, but prior to using our PCB we had more than a few bad reads. There was substantial noise all over the circuit, and since we were mostly just moving data around, this was a big problem. We tried out several different approaches to filtering. First, we screened out all bad pixel reads and replaced them with the average of their neighbors. However, bad reads often occurred in clusters, so this did not work. Using a fixed gray value as a replacement worked better. Between down sampling and the noise, our output had a lot of flickering elements. Applying a simplified Gaussian Blur gave smoother results, but that went against our general goals of shape-matching. Averaging two frames of input together would have been great, but that would have required more RAM than we had. We tried out sampling more lines (so higher vertical resolution) and averaging on the fly, but the PCB arrived and squelched noise before we could get the timing right in that code.

Output Filtering

The PCB result was sharp and flawless, but the down-sampling effect was still causing an annoying flicker. Not wanting to have to slow down our game(s) just for the sake of flicker, we came up with a method of filtering our output based on our previous output, a moving average box filter of sorts. We still didn't have the memory to duplicate even a 13x30 output frame, but by repeating characters across many addresses we could use the address itself to store information. Looking at the last two lines of our character set, you can see we increment the address when there is positive info and decrement it when there is negative info. By capping the ends (so as to not overflow or underflow), we can display a nice running average over time with minimal memory and cycle cost. Our increments and decrements are set to 3, so it takes less than 3 frames for white to black changes and it takes at least 3 positives or negatives in a row to create a noise blip.
To avoid output flicker from frequently updating the OSD, we don't flush our output buffer to the OSD until the end of our main loop. Keeping this output buffer around is also what lets us do time-averaging of our output to avoid flicker. Another flicker that can appear is a nauseating collection of video signal artifacts when the OSD is displaying characters that are pixel level grids. For this reason our standard background is a loose 1 out of 4 pixels instead of a tight checkerboard pattern.

Timing

In order to run our games, we needed some sort of time base. Since we had a 20Mhz crystal and 20 is not a power of 2, we had to use Timer 1 to get a time base on the order of milliseconds. We settled on a 5ms time base as a balance between ISR executions and accuracy. That time base controls the game state and timers, but the main loop is actually triggered by the NTSC sync pulses. The vertical sync ISR activates the horizontal sync ISR for reading in a frame if a flag is set and the horizontal ISR sets the flag down when reading in a frame is complete. The main loop does the opposite, running when that flag is not set and raising it when finished. This way every time main executes it has fresh input. We run our tracking mode as fast as possible and our games at half that in order to make the OSD flicker less during gameplay.
We have 2 buttons for input, "toggle" and "enter", which are sufficient for a menu system. We run a de-bouncing flag-raising state machine to get meaningful input from sampling them at around 30Hz. We run a heartbeat LED at one second per cycle, so we can tell if things are working fine or not. In addition to the heartbeat LED, we keep a "Game Timer" at a 5-millisecond time base for game play purposes. We also sample the on-board ADC at 1Hz to get specified black level, which can be set by a trimpot to tune the game(s) to different environments. This live tuning is a bit more useful than just viewing exact values from a UART frame dump and guessing at a good threshold for detection.

Menu and System State

menu
Main menu
Our menu allows users to choose between the three games and the tracking mode. One button is used as a toggle to go to the next option and the other button is used as enter to select an option. The menu is a simple state machine. Each frame it displays the title, our names, and all the options with the current selection highlighted.
The state of the system is another state machine with states for menu, each of the games, tracking mode, and a win/lose screen. Each "frame" through the main loop activates the code for the appropriate state. The initial warning message is displayed for a few seconds the first time the menu state is activated, which is when the system turns on.

Games

The game state machines are based on the 1 millisecond base of "Game Time", and the logic is independent of the frame rate. This means we can speed up or slow down our frame rate as needed and not affect the game mechanics. The main state machine simply loads the input data from the video stream then calls out to game logic for each frame. In our game modes, we display the player's body as a collection of 12x18 character sized blocks for aesthetic value and decreased noise, as opposed to the 6x6 dots used for tracking mode.
Our Human Tetris game does the following. Each shape is displayed for 5 seconds. It is loaded into memory once, then player is displayed each frame using the moving average code (described above) to preserve the shape information. Once the shape and player are in the output buffer, simply looping through that buffer tells us how many "blocks" of the player's body are outside the shape. If more than a certain tolerance are outside, the player loses. If not, the game advances to the next shape until a victory screen is reached. The number of misses is only checked at the end of a shape's time.
We implemented a rather nice content pipeline for the Human Tetris shapes. One can place an arbitrary amount of images in a directory, and then run the MATLAB script imgs2progmem to get out a C header file with a single array holding all the shape data in program memory. The only restrictions are the input images must be 39 x 60 and black and white. It should be noted that the shapes are effectively stored as a bit vector (1 bit per block) in the C file. This compresses each shape to a mere 293 bytes, so we could fit a lot in program memory. The artist should keep in mind that the game currently displays shapes and players on a 13x30 grid (via averaging), so care should be taken when drawing the 39x60 sized shapes.
To demonstrate the extensibility of our shape tracking code, we also implemented a few other games:
brick_action
Example of Brick Breaker game
Our first additional game is Brick Breaker. The game world consists of bricks (3 characters wide), a bouncing ball, and the player's "bar" which is represented by character-sized blocks as in Human Tetris. The ball is actually on a 39x60 grid and is displayed as such. The ball bounces indefinitely and consistently. If it falls off the bottom of the screen the player loses a life. If it strikes a brick it damages the brick. If a player destroys all the (breakable) bricks before losing, the player will advance to the next level.
We have also added the Whack-A-Mole game to our project. The mole is composed of 2 rows of 3 characters, giving it a 36x36 pixel footprint. The moles are randomly drawn and removed, loosely based on the current time. The player must get his/her block representation onscreen to collide with a mole in order to "whack" it. Doing so removes the mole from the screen and awards the player with points. When the game time expires, the player's score and any remaining moles are visible.

Results

Speed and Accuracy

We can read in and display an image of 39x60 pixels at 30 frames per second. That is the meaningful maximum, since NTSC is actually only 30 frames per second of information. The signal runs at 60 frames per second, sending every other line every other frame. We only read on every other vertical sync to de-interlace the signal. Our output tends to flicker a little as a result of down-sampling (as opposed to averaging) the NTSC image data. There is currently a little streaking in the output where characters are shown due to noise in the OSD.
sample
Real image, captured image, and interpreted image after applying threshold.

Tracking Demo

object_tracking
An object being tracked, with its interpretation displayed in real-time
To demonstrate our speed and accuracy, we wrote a tracking demo that simply reads the NTSC signal and displays our full resolution output as fast as it can. In object tracking mode, we simply clear the output buffer, load in the input at 39x60 resolution, and display that. This demonstrates the accuracy and speed we were able to achieve.
At 30 frames per second, there is minimal lag on our interpretation of the image. We do not do any filtering in tracking mode. There is a little flicker along the edges due to our down-sampling method. This tracking mode proved very handing for general debugging and especially for getting the timing right for reading in an NTSC frame.

Game Safety and Usability

Anyone capable of movement can play the games in this project, and difficulty can be adjusted by adjusting one's difference from the camera. In this way the game can be adjusted for players of various sizes. The game is also only looking for dark colors, so light colored materials can be used to exclude parts of the image. Brick breaker is a nice alternative to human Tetris for any physically disabled players that might stumble upon our game.

Conclusions


Results vs. Expectations

When we drafted our proposal, our vision of the finished product is very similar to the device we have created. Much of the same hardware devices and software techniques we planned on using ended up in our final design. The main hardware drawback we experienced was that the NTSC decoder we had original planned on using was too fast for our MCU. Instead we had to select and use an ADC which would run independently and we could choose when to sample. In effect, since we only cared about the black-and-white signal, this was all we needed to achieve the same sampling effect we had originally planned on.
We have exceeded our expectations in both spatial and temporal resolution. We originally hoped to just barely have enough resolution for a stick figure and to process the image once every few seconds. We currently have enough resolution to recognize each other in debug images and are processing it all many times a second.
Next time adding sound to the game would make it much more enjoyable (and potentially deepen game play).

Conforming to Standards

Our project uses standard NTSC input and therefore the camera could be swapped. It also produces standard NTSC output, so any device capable of displaying that can be used.
We also use SPI internally. This is not exactly a standard, which probably explains why we only have it working in one direction.

Intellectual Property

We used open source code licensed under GPL v2 used as basis for our OSD SPI driver. The GPLv2 states that any code linking against the GPL v2 code must also be within the GPLv2 license. This probably limits our ability to monetize the project as it stands, since ownership cannot be claimed on GPL v2 code.
Tetris and its artwork are copyrighted and trademarked, so at the least we would have to change the name and some artwork in order to capitalize on our design. Brick Breaker is a new name for Breakout, and there is likely some ownership on the original design but currently many knock-offs exist.

Tetris ® and © 1985~2010 Tetris Holding. Tetris logo, Tetris theme song and Tetriminos are trademarks of Tetris Holding. The Tetris trade dress is owned by Tetris Holding. Licensed to The Tetris Company. Game Design by Alexey Pajitnov. Logo Design by Roger Dean. All Rights Reserved. All other trademarks are the property of their respective owners [Tetris.com].
Breakout is an arcade game developed by Atari, Inc and introduced on May 13, 1976 [Wikipedia].
The games we implemented are someone else's IP. Our driver is GPL-licensed, so no one can make money on our code unless they rip that out first. As Cornell University undergraduate students, we own our original ideas. If this project were to be published, the Tetris aesthetics would have to be replaced.

Ethical Considerations

We have done our best effort to conform to the IEEE Code of Ethics in the design and execution of this project.
Our project is essentially a motion tracking device for the consumer entertainment market. Since it is a class project, it has been created with no intention of profit and in accordance with the beliefs of the GPL. This combination of facts means it was created purely for learning and for fun. Therefore it seeks only to make the world a better place.
The game is based on video output, which means there is a chance it will trigger photosensitive seizures in some users. We have added a warning before the menu screen to alert users to this. We also take that opportunity to warn players about the dangers of motion-based games. Extreme play motions have been known to sometimes cause harm or damage. However, when played safely, our game(s) will improve the health of the user through the physical and mental activity involved.
We have been honest in the reporting of our results, and have strived to write code that does not lie. Our reported resolution is accurate, and our frames per second benchmark is as accurate as our clock will allow.
Because our game is based on video input, a user’s appearance and physical fitness will affect their interaction with the software. For this we recommend users consult with their doctor before playing and wear dark colors to aid the camera in tracking them.

Legal Considerations

Our project is a simple video home entertainment device. It does not release excessive EMF and should not cause any interference with other electronics. We have placed warnings in the game about the dangers involved in playing.

Appendices

A. Source Code

Source files

  • Lab5.c (20KB) – all the ISRs, initialization code, tracking output code, and main state machine
  • human_tetris.c (6KB) – human tetris game logic and data handling
  • brick_breaker.c (8KB) – brick breaker game logic including physics and data handling
  • whack_a_mole.c (5KB) – whack-a-mole game logic and data handling
  • max7456_learn.c (15KB) – contains code for writing to the OSD's progmem
  • max7456_spi.c (9KB) – our OSD driver
  • uart.c (5KB) – uart code from Bruce Land
  • LICENSE.TXT (18KB) – GNU general public license

Header files

  • lab5.h (3KB) – time constants and input and output functions
  • Levels.h (1KB) – progmem array storage of brick breaker levels
  • Shapes.h (9KB) – progmem array storage of human tetris levels
  • macros.h (1KB) – register setting and mathematical macros
  • human_tetris.h (1KB) – exposes game state machine function
  • brick_breaker.h (1KB) – exposes game state machine function
  • whack_a_mole.h (1KB) – exposes game state machine function
  • max7456_characters.h (176KB) – progmem arrays for all our custom characters
  • max7456_learn.h (3KB) – exposes our functions for sending custom characters to the OSD
  • max7456_spi.h (5KB) – exposes useful OSD driver functions
  • uart.h (1KB) – exposes necessary UART functions

MATLAB scripts

  • makeDots.m (2KB) – produces the 64 different 18x12 characters for arrangements of 6x6 dots
  • imgs2progmem.m (2KB) – takes a directory full of images and outputs C code shape arrays for brick breaker
  • cap.m (1KB) – used to grab MCU's image dump from serial interface
Download all files: code.zip (44KB)

. Schematics

schematic
Hardware schematic [full-size image]. Download schematic file: humantetris.sch (36KB).
pcb
Custom printed circuit board layout [full-size image]. Download pcb file: humantetris.pcb (31KB).

C. Parts List

rt Source Unit Price Quantity Total Price
ATmega644PA (8-bit MCU) Empire Technical sampled 1 $0.00
MAX7456 (on-screen display) Maxim-IC sampled 1 $0.00
TLC5540 (flash ADC) Texas Instruments sampled 1 $0.00
CM-26N (CMOS color camera) SparkFun $31.95 1 $31.95
custom PCB ExpressPCB $25.00 1 $25.00
12V power supply owned $5.00 1 $5.00
color TV owned owned 1 $0.00
RCA video cable owned owned 1 $0.00
RCJ-014 (RCA jack) DigiKey $0.66 1 $0.66
HC49US (27MHz crystal) DigiKey $0.63 1 $0.63
header pins lab $0.05 15 $0.75
jumper lab lab 1 $0.00
MP200 (20MHz crystal) lab lab 1 $0.00
2.1mm power jack lab lab 1 $0.00
1N4001 (1A rectifier) lab lab 1 $0.00
LM340T-5 (5V regulator) lab lab 1 $0.00
SPDT slide switch lab lab 1 $0.00
push button (NO) lab lab 3 $0.00
10μF capacitor lab lab 4 $0.00
0.1μF capacitor lab lab 8 $0.00
22pF capacitor lab lab 2 $0.00
100kΩ resistor lab lab 1 $0.00
10kΩ resistor lab lab 2 $0.00
1kΩ resistor lab lab 3 $0.00
300Ω resistor lab lab 1 $0.00
100Ω resistor lab lab 3 $0.00
75Ω resistor lab lab 2 $0.00

Acknowledgements

We would like to thank ECE 4760 Professor Bruce Land and all TA staff (especially our lab TA Jeff Melville), for help and support during the labs and over the course of the project. We thank them for the long lab hours and the parts stocked in the lab.
Additional thanks go to Mary Byatt, for the original idea of doing Human Tetris for our microcontroller project.
We would also like to thank several vendors for parts donations. We sampled several ATmega644PA chips from Empire Technical Associates, MAX7456 chips from Maxim-IC, and TLC5540 chips from Texas Instruments. We also sampled several other parts from Maxim-IC and Texas Instruments (including op-amps, decoders, etc) which did not make it into our final design.

G-Force Meter Project !

Source: http://www.radiolocman.com/

The aim is to build a meter which measures the lateral acceleration force in car, also called g-force or centrifugal force. This is the force which pushes the driver or passenger to the left in a fast right hand turn. The force is normally expressed in g, 1 g (9.8 m/s/s) corresponds to the acceleration due to gravity. A normal car can handle approximately 0.8 g, above this values, the tires cannot handle the sideways force anymore and the car will move sideways. The best sports cars can handle up to approximately 1 g. A very interesting discussion on the forces in a car can be found here.
The g-force will be measured with an accelerometer mounted with its sensitive axis perpendicular to the driving direction. The sensor will be read out using a microcontroller. 30 LEDs are used to indicate the current g-force.

I have chosen the Atmel ATtiny26 microcontroller. It has some interesting features for this project:
  • small and cheap
  • 10 bit ADC
  • sufficient IO pins, which can source and sink 20 mA; LEDs can be driven directly
  • Possibility to use the internal oscillator, no Crystal needed
  • Free development tools (C compiler) available for windows, Linux, OS X etc.
  • Programming can be done using inexpensive hardware and free programming software
  • To measure the G-force, I use the Analog Devices ADXL103. This is a high accuracy accelerometer, which is not really necessary for this project. The ADXL311 seems pin compatible to the ADXL103 and is cheaper. Furthermore, I designed the board such that also a Freescale accelerometer can be used (not tested).
The board
This is version 2 of the board made using Eagle, the first version had the option to use a Freescale accelerometer also, but I needed the space for the logo :-):

The following parts are can be seen:
  • The 30 LED array. Because I do not have 30 IO pins available on the ATtiny26, I decided to create 6 groups of 5 LEDs. 6 pins are needed to indicate the group, and 5 to indicate which LED in the group should be turned on (I hope you get the idea). Extra bonus: only 5 resistors are needed. As a result only 1 LED can be turned on at the same time. This is not a real problem; The impression of multiple burning LEDs can be given by turning them on sequentially quickly.
  • Voltage regulator, needed because I want to run the meter from a car battery.
  • 10 pin header for In System Programming
Of course the board could be improved with a proper ground plane etc., but this is the first board that I ever made. Also a very good accuracy is not needed.

Part list:

  • ADXL103
  • ATtiny26
  • 3 x 10 LED bar
  • 4 x 0.1 uF Ceramic Capcitor
  • 5 x 360 Ohm Resistor (exact value not so important)
  • 10 uF Capacitor.
  • 5 x double male header (for ISP)
  • Voltage regulator 7805, this size is probably an overkill
Building is straightforward. All parts are through hole components except for the accelerometer, but soldering it is not a real problem. Even I could do it with my huge (relatively) iron.

The eagle brd file can be found here

The Software

The software for the ATtiny26 was written in C and is rather straightforward. There is a lookup table which indicate the needed values of P1 and P2 to light one of the 30 LEDs. In the main loop the ADC is read out and the value is converted to a LED number. LED 1 corresponds to 1 g to the left, LED 30 to 1 g to the right. The maximum and minimum LEDs are remembered and also lit.

The hex file can be found here

G-Force Meter Project
G-Force Meter Project

G-Force Meter Project
The result
This is Version 1 of the board (without Hack A Day logo). The middle LED indicates the current G-force, the left and right the maximum values to the left and right.
In the car, the G-force meter functioned well. You do not need to keep an eye on the meter all the time because the maximum values are kept. It is a lot of fun, trying to improve the maximum values.

Possible improvements:
  • Reduction of noise due to vibrations by filtering the ADC output over a longer time (in software).
  • Reset button to reset the maximum values.
  • Non-linear scaling. The first part of the scale is not so important. Maybe it is interesting to let the first 5 LEDs cover the first 0.5 g, the next 10 LEDs from 0.5 till 1 g.

G-Force Meter Project !

Source: http://www.radiolocman.com/

The aim is to build a meter which measures the lateral acceleration force in car, also called g-force or centrifugal force. This is the force which pushes the driver or passenger to the left in a fast right hand turn. The force is normally expressed in g, 1 g (9.8 m/s/s) corresponds to the acceleration due to gravity. A normal car can handle approximately 0.8 g, above this values, the tires cannot handle the sideways force anymore and the car will move sideways. The best sports cars can handle up to approximately 1 g. A very interesting discussion on the forces in a car can be found here.
The g-force will be measured with an accelerometer mounted with its sensitive axis perpendicular to the driving direction. The sensor will be read out using a microcontroller. 30 LEDs are used to indicate the current g-force.

I have chosen the Atmel ATtiny26 microcontroller. It has some interesting features for this project:
  • small and cheap
  • 10 bit ADC
  • sufficient IO pins, which can source and sink 20 mA; LEDs can be driven directly
  • Possibility to use the internal oscillator, no Crystal needed
  • Free development tools (C compiler) available for windows, Linux, OS X etc.
  • Programming can be done using inexpensive hardware and free programming software
  • To measure the G-force, I use the Analog Devices ADXL103. This is a high accuracy accelerometer, which is not really necessary for this project. The ADXL311 seems pin compatible to the ADXL103 and is cheaper. Furthermore, I designed the board such that also a Freescale accelerometer can be used (not tested).
The board
This is version 2 of the board made using Eagle, the first version had the option to use a Freescale accelerometer also, but I needed the space for the logo :-):

The following parts are can be seen:
  • The 30 LED array. Because I do not have 30 IO pins available on the ATtiny26, I decided to create 6 groups of 5 LEDs. 6 pins are needed to indicate the group, and 5 to indicate which LED in the group should be turned on (I hope you get the idea). Extra bonus: only 5 resistors are needed. As a result only 1 LED can be turned on at the same time. This is not a real problem; The impression of multiple burning LEDs can be given by turning them on sequentially quickly.
  • Voltage regulator, needed because I want to run the meter from a car battery.
  • 10 pin header for In System Programming
Of course the board could be improved with a proper ground plane etc., but this is the first board that I ever made. Also a very good accuracy is not needed.

Part list:

  • ADXL103
  • ATtiny26
  • 3 x 10 LED bar
  • 4 x 0.1 uF Ceramic Capcitor
  • 5 x 360 Ohm Resistor (exact value not so important)
  • 10 uF Capacitor.
  • 5 x double male header (for ISP)
  • Voltage regulator 7805, this size is probably an overkill
Building is straightforward. All parts are through hole components except for the accelerometer, but soldering it is not a real problem. Even I could do it with my huge (relatively) iron.

The eagle brd file can be found here

The Software

The software for the ATtiny26 was written in C and is rather straightforward. There is a lookup table which indicate the needed values of P1 and P2 to light one of the 30 LEDs. In the main loop the ADC is read out and the value is converted to a LED number. LED 1 corresponds to 1 g to the left, LED 30 to 1 g to the right. The maximum and minimum LEDs are remembered and also lit.

The hex file can be found here

G-Force Meter Project
G-Force Meter Project

G-Force Meter Project
The result
This is Version 1 of the board (without Hack A Day logo). The middle LED indicates the current G-force, the left and right the maximum values to the left and right.
In the car, the G-force meter functioned well. You do not need to keep an eye on the meter all the time because the maximum values are kept. It is a lot of fun, trying to improve the maximum values.

Possible improvements:
  • Reduction of noise due to vibrations by filtering the ADC output over a longer time (in software).
  • Reset button to reset the maximum values.
  • Non-linear scaling. The first part of the scale is not so important. Maybe it is interesting to let the first 5 LEDs cover the first 0.5 g, the next 10 LEDs from 0.5 till 1 g.

Labels

About Me

My photo
I am an electrical and electronics engineering kathmandu university batch 2007
 
ELECTRICAL AND ELECTRONICS PROJECT COLLECTION. Design by Wpthemedesigner. Converted To Blogger Template By Anshul Tested by Blogger Templates.