1D PONG

There are some 1D Pong projects on the interwebs such as monoPong and One dimensional PONG, take two which inspired me making my own. So, here it is. My take on One Dimensional PONG.

DSC 5395

 
The main parts are an ATtiny2313, two tactile push buttons, 12 LEDs, and one buzzer to get some simple sound effects. I have also added a reverse polarity protection 1N4148 diode and a 0.1uF capacitor to stabilize the power supply. 

The PCB

1D PONG was also my very first circuit board designed using CadSoft’s EAGLE. There are many great Eagle tutorials out there. I watched the complete YouTube series of tutorials by rpcelectronics, starting with this one http://www.youtube.com/watch?v=qG0O9LKH-_E

1dpong board

Picking a PCB fab house took quite some time of googling around. I settled for OSH Park. Their prices seem reasonable. The standard deal is that you get three copies of your 2-layer boards at $5 per square inch, $27.75 w/o shipping in my case. They allow you to directly upload your EAGLE files, i.e. no need to create gerber files, and there’s instant rendition of how your board is going to look like.

The downside of ordering it from a fab house instead of etching it yourself, is that you have got to be patient. I ordered mine on Jan 9th, it shipped on Jan 24th, and arrived about a week later.

1dpong oshpark

So, did it work? Yes, it did! There were three little glitches …, First, I inadvertently swapped LED11 and LED12 in the schematic. This was easy to fix in software. Secondly, the strain relief holes for the battery leads were too small. Well, easy to fix with a bigger drill bit.

Lastly, all my traces are 8mils wide which is pretty tiny and not really necessary in this project. I wish I had read Sparkfun’s Better PCBs in Eagle before: “Just because a fab house can handle down to 5mil traces and 6mil space doesn’t mean you should design with those sizes”. Many fab houses including OSH Park provide their own EAGLE design rule check files so you can verify the board. It turned out all fine in my case, but next time I am going to use a wider trace width to be on the safe side.

Pcbtop

It actually works:

[vimeo 65494435 w=600&h=400]

Designed files and AVR code is on github.

Advertisements
Posted in attiny2313, avr | Tagged , , | Leave a comment

PONG on an 8×8 LED Matrix and LoLShield

Being relatively new to electronics in general and microcontrollers in particular, I am still in the “getting excited about blinking lights” phase. So, if a single blinking LED is sort of interesting, how cool are 64 of them? Like Collin Cunningham says in his video “The LED matrix has a bit of a reputation among electronics hobbyists” … and of course, I wanted to play PONG on it.

AS1100 – fully compatible to the MAX7219

I got an 8×8 matrix some time ago, but figured that controlling 64 LEDs from a bare Arduino is a bit painful. Looking for examples, I found projects using current limiting resistors, switching transistors, and 74HC595 shift registers. So in the end, like in Collin’s video, I went for the MAX72xx LED drivers (MAX7219 or MAX7221). Those chips are designed to either drive an 8 digit 7-segment display, or an 8×8 LED matrix. It is a little on the expensive side though. For example, the MAX7219 is EUR 9.15 at Digi-Key. To put this in perspective, the ATmega328P driving the Arduino UNO is EUR 2.71.

But there is an alternative. The AS1100 from austria microsystems is fully compatible to the MAX 7219. Best of all, they do free samples. But otherwise those chips seem to be difficult to get in small quantities. The DIP version for example, is a non-stock item at Digi-Key. If anyone has a source suitable for hobbyists, please leave a comment.

The Build

DSC 6996

Finished:

DSC 7007

The Code

I wrote my PONG game as an Arduino library and put it on github. The library implements the core of the game. Subclasses of the “Pong” base class implement virtual functions to display the ball, paddle, score, intro animations, etc. on the “screen”, see MatrixPong.ino in the examples directory. This way I was able to re-use the same base code for the LoLShield:

Posted in arduino | Tagged , , , | 1 Comment

Working with Arduino sketches on the command line on a Mac

I like using Emacs and the command line, even on a Mac where everything is supposed to be just a few mouse clicks away. The Arduino IDE is great to get started and if you check the “use external editor” box you can also use Emacs or any other editor you prefer.

Compiling and uploading Arduino projects from the command line requires a little more work. I use CrossPack for AVR® Development for pure AVR projects. CrossPack comes with a simple, easy to use Makefile template to run the avr-gcc toolchain and avrdude. So I was looking for something like the CrossPack Makefile template but for the Arduino.

Many people have written Makefiles for Arduino. For example, take a look at the Advanced Arduino Hacking article in PragPub Issue #22, April 2011 by Maik Schmidt. He uses a modified version of Alan Burlison’s A Makefile for Arduino Sketches. Both variants require some tweaks to work with the current Arduino 1.0.1, e.g. the default filename extension is now .ino. However, Alan’s website pointed me to Arduino from the command line by Martin Oldfield, https://github.com/mjoldfield/Arduino-Makefile

This works really well. The package comes with perl scripts to parse the Arduino IDE’s board.txt file and to reset the serial port. I had to install two more Perl packages to make them work:

$ sudo port install p5-YAML
$ sudo port install p5-device-serialport

The Makefile always sets two leonardo specific variables USB_VID and USB_PID even if you use a non-leonardo board such as the uno:

build.vid isn't defined for the uno board, at /Users/ubiyubix/bin/ard-parse-boards line 50.
build.pid isn't defined for the uno board, at /Users/ubiyubix/bin/ard-parse-boards line 50.

This can be safely ignored, but I wrapped setting those variables in an ifeq ($(VARIANT),leonardo) to get rid of it. My github fork https://github.com/alohr/Arduino-Makefile.

Posted in arduino | Tagged , | 1 Comment

Larson Scanner – Remote Controlled

Here is a little hack for Evil Mad Scientists’ Larson Scanner kit. It is possible to add an infrared detector so you can use a TV remote control to play around with the running lights, i.e. toggle the bright mode, skinny eye, and of course the speed. This is possible without any modifications to the original circuit board.

How to assemble

DSC 0394

Additional parts required:

  • ATtiny4313
  • IR detector (e.g. Vishay TSOP 4838)
  • 20 pin IC socket (recommended)
  • Header pins for the programmer (for either J1 or J2 on the circuit board)

Solder the resistors, LEDs, and the capacitor in place normally. I am using a modified version of Ken Shirriff’s Arduino IR library described in my previous post. The ‘2313 does not have enough memory for the original Larson scanner and the IR receiver, but the ‘4313 does. I would also recommend using an IC socket for the ‘4313.

Solder the IR detector in place.

Www vishay com docs 82090 tsop48xx pdf

  • Pin 1 (OUT) connects to S1 (away from the LED D8)
  • Pin 2 (GND) connects to S1 (close to the LED D8)
  • Pin 3 (Vs) connects to Vcc_2

DSC 0018

Program the ‘4313

The code repository is on github.

git clone git://github.com/alohr/avr.git
cd avr/larson_ir
# edit Makefile according to your programmer

# update flash and change AVR fuses:
make install

RC5 protocol only

I use a cheap key fob universal remote control, but any other RC5 remote control should do. While I was putting the Larson scanner and the IR library together I ran into odd problems where the code would simply not work. For example, you’d press any key on the remote control and all LEDs lit up dimly. The only explanation I have is that I ran out of memory (stack overflow or something like that), because there are only 256 bytes of RAM and the IR library already uses 68 of that for the raw buffer to store IR pulses. If I restrict the library to the RC5 protocol only, then I can get away with 24 bytes for this buffer. As soon as I did this, the odd problems went away.

// Length of raw buffer
#if defined(COMPILE_DECODE_NEC)  || \
    defined(COMPILE_DECODE_SONY) || \
    defined(COMPILE_DECODE_RC6)  || \
    defined(COMPILE_DECODE_JCV)
#define RAWBUF 68
#else
// RC5 only
#define RAWBUF 24
#endif

Remote Control Functions

DSC 0398

  • TV/AV = toggle skinny eye
  • Mute = toggle bright mode
  • Volume Up = increase speed
  • Volume Down = decrease speed
  • Channel Up = not used
  • Channel Down = not used
  • On/Off = not used
Posted in attiny4313, infrared | Leave a comment

Porting the Arduino IRremote library to the ATtiny4313

Note: This covers the IR receive and decode part only. I may do the IR send part at some other time.

Ken Shirriff wrote a popular multi-protocol IR library for the Arduino. It’s easy to use and works really well. When I wanted to add an IR receiver to a project based on the ATtiny2313, I turned to this library to see whether it could be ported to run on an ATtiny. It turned out to be next to impossible to squeeze the code into the 2K of flash memory the ATtiny2313 has, but I succeeded using the pin-compatible ATtiny4313. The ‘4313 is more or less identical to the ‘2313, but has twice the amount of ram and flash memory.

Step 1

I started from Ken Shirriff’s code in http://arcfn.com/files/IRremote.zip. The Arduino code is C++, so the very first thing to do was to rename the files and switch from C++ classes to C structs and functions.

IRremote.cpp	-> irrecv.c
IRremote.h	-> irrecv.h
IRremoteInt.h  	-> irrecvint.h

The IR receive code uses a timer interrupt function called every 50 microseconds. The original code used TIMER2 which does not exist in the ‘4313. This chip has an 8-bit TIMER0 and a 16-bit TIMER1. Since I wanted to keep TIMER0 free for other uses, I changed to use TIMER1.

Everything compiled fine and I timed the interrupt function to clock in every 50us using an oscilloscope. A skeleton program using the IR receive library would look something like this:

#include "irrecv.h"

void process(decode_results *r) { /* do cool stuff here */ }

int main(void)
{
    decode_results r;
    setup_irrecv();
    for (;;) {
	if (irrecv_decode(&r)) {
	    process(&r);
	    irrecv_resume();
	}
    }
    return 0;
}

But, there is a problem:

avr-size -t main.o irrecv.o
   text	   data	    bss	    dec	    hex	filename
     64	      0	      0	     64	     40	main.o
   1612	      0	      0	   1612	    64c	irrecv.o
   1676	      0	      0	   1676	    68c	(TOTALS)
avr-size main.elf
   text	   data	    bss	    dec	    hex	filename
   4676	    264	    140	   5080	   13d8	main.elf

The size of the object code of the library and the minimal main program is way less than 2K, but the resulting binary has about 5k. This won’t fit in the 4K available on the ‘4313.

Step 2

The additional code must come from the C library the avr-gcc links to. So, let’s disassemble the .hex file to see what’s in there.

avr-objdump -d main.elf

Whoa! What’s the deal with all those floating point functions? I do not recall seeing any float variables in the IR code.

000006dc <_fpadd_parts>:
0000096c <__addsf3>:
000009ba <__subsf3>:
00000a10 <__mulsf3>:
000006dc <_fpadd_parts>:
[...]

The code allows the timing of the incoming IR signals to be off be a certain percentage. The percentage is first calculated using floating point, but the result will be converted to an integer in the end:

#define TOLERANCE 25  // percent tolerance in measurements
#define LTOL (1.0 - TOLERANCE/100.)
#define UTOL (1.0 + TOLERANCE/100.)
/* ... */
#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))

I changed this to to get rid of the intermediate floating point arithmetic.

#define LTOL (100 - TOLERANCE)
#define UTOL (100 + TOLERANCE)
/* ... */
#define TICKS_LOW(us) (int) (( (long) (us) * LTOL / (USECPERTICK * 100) ))
#define TICKS_HIGH(us) (int) (( (long) (us) * UTOL / (USECPERTICK * 100) + 1))

This results in a much reduced code size:

avr-size main.elf
   text	   data	    bss	    dec	    hex	filename
   1950	      0	    140	   2090	    82a	main.elf

Step 3 – Putting it all together

I tested this using a modified Larson Scanner circuit from Evil Mad Science. The schematics are here and this is what I have changed:

  1. Used ‘4313 instead of ‘2312
  2. Replaced the button at port PB4 with an IR detector. I used a Vishay TSOP 4838.
  3. Added an activity indicator LED at port PB5.

The remote control is a cheap RC5 universal remote from dx.com.

DSC 0412

The code repository is on github.

git clone git://github.com/alohr/avr.git
cd avr/irrecv
# edit Makefile according to your programmer and clock frequency

# update flash *and* change AVR fuses:
make install

# flash only:
make flash

Clock frequencies I tried were 8 Mhz using the avr’s internal oscillator and 16 Mhz with an external crystal.

Some links I found useful during this project

Posted in attiny2313, attiny4313, infrared | 16 Comments