Wednesday, February 24, 2010

4-key-keyboard


note: this video is showing an early prototype, behavior of the final version is slightly modified

Introduction:

A good while back, I made the 1-key-keyboard project. Ever since it has always been in the back of my mind that the ATTiny microcontroller, which I used in this project, had still 3 IO ports which were unused. Only recently I’ve found the time to expand my old project in the most obvious way possible; by adding 3 more buttons to these IO ports and thereby creating a 4-key-keyboard, without having to add any other hardware than these 3 extra buttons.

Although this project can still easily be built on a stripboard, I chose this time to etch my own (single sided) PCB and to use an old USB cable to interface with the computer, instead of the makeshift USB-plug as used in my previous project.

see here the result:

4-key-keyboard_blog_flipwork_nl.jpg

The hardware:

4kk_components.jpg

• 1x Atmel ATTiny45-20PU or ATTiny85-20PU microcontroller
• 1x 8-pin DIL socket (optional but highly recommended)
• 2x Diodes (0.5W) (ordinary 1N4148 will do the job)
• 2x 68 ohm resistors
• 1x 1.5K resistor
• 1x 0.1 uF capacitor (note: can be higher capacity, I also used 1uF and in the example circuit from obdev they use 4u7)
• 4x push-button
• 1x usb cable with the standard usb-A plug
• 1x etched circuit board (or use stripboard as alternative)

And a programmer for the ATTiny45/ATTiny85 microcontroller. For this project a programmer supporting High Voltage Serial Programming (HVSP) is highly recommended, since we enable the ‘reset disable’ fuse. I’ll explain this in more detail later on.

The schematics:

4-key-keyboard-component-layout.gif

The circuit-board:

In the .zip file of this project, there’s a .pdf which can be used for photo-chemical etching of the circuit-board. EAGLE files are also included.

The component layout on the circuit board:
4kk_pcb.png

(The red line in this schematic is a wire. Remapping of the IO ports could possibly remove the need for this wire.. maybe I’ll have a look at optimizing this in a future revision.)

The firmware:

I tried to add useful comments to the sourcecode of this project, so I suggest to have a look at it to see the precise details.

At a high-level, this project implements V-USB (previously called AVR-USB) from Objective Development, which I use to emulate a USB keyboard.

Contrary to my 1-key-keyboard project, I now used the standard report descriptor for a USB keyboard, which has a 8-byte report buffer. This may be a bit of a overkill, since I only use 4 of these bytes in this project (1 for each button) but it does allow for easy expansion of functionality in the future.

Another difference with my old project is the fact the way key-presses are emulated. in the old version, two different keys were emulated on press and release of the button. Now every button simulates just 1 key, but with its individual key-down and key-up event, which is exactly the same as a normal keyboard operates.

In the standard firmware, key presses are emulated for the keyboard-keys 1 to 4. Though this can easily be changed.

Programming the firmware:

OK, I’ll start here with a warning: If you don’t have a programmer that supports High Voltage Serial Programming (HVSP) then you can’t reprogram the ATTiny anymore after enabling the reset-disable fuse. (An Atmel STK500 programmer does support HVSP!)

If you have a programmer that only supports ISP, then you can still successfully program the 4-key-keyboard, as long as you upload the firmware before setting the reset-disable fuse.

If you want to experimenting/test this project without having a HVSP capable programmer, then I suggest to test it without the reset-disable fuse set. This will result in button 3 not working (since it’s connected to the IO pin that doubles as reset pin), but all other 3 will work. Only when you’re sure that you’re happy with the firmware, you can set the reset-disable fuse.

I have personally always used AVR Studio in combination with WinAVR to program my AVR’s (they are available at no cost) But you can use your own favorite AVR programming environment to program your ATTiny. You can find both the sourcecode and a pre-compiled .hex in the .zip file of this project.

Recommended fuse-settings:

EXTENDED: 0xFF
HIGH: 0×5D (use 0xDD to test without reset-disable fuse set, as described above)
LOW: 0xC1

4kk_fuses.png

Testing the project

After you have built the circuit, programmed the firmware and set the fuses correctly, it’s time to test the project.

After plugging in the USB cable, the computer should recognize a new keyboard and automatically install the standard keyboard-drivers. Then it’s time to test! The easiest way is to open a text-editor, e.g. notepad, and push the buttons in the prototype. If everything is successful, keyboard-keys 1-4 are emulated by the 4 buttons on the prototype.

Interfacing with Adobe Flash

By emulating a standard keyboard, this project should be easy to integrate in any software with which you want to interface. But personally I’ve used it often in combination with Adobe Flash. Since I’ve modified the behavior of the buttons to resemble how a normal keyboard operates, there’s a slight change in the code to interface with flash, compared to the 1-key-keyboard project.

Now in flash you can create event-listeners for KeyboardEvent.KEY_DOWN and KeyboardEvent.KEY_UP for keys 1-4, just like one would interface with a normal keyboard to detect when a key is pressed and when it’s released. Flash example code is included in the project file.

Download the project files

Click here to download the complete sourcecode of this project

Tuesday, February 3, 2009

How to display any database table in a Flex 3 Datagrid

The project described in this post is made to display any table from a PostgreSQL or MySQL database in Adobe Flex 3.
(note: only text based database info will work, so it won’t work with e.g. pictures stored in a database)

Here’s an overview of the technologies used in this project:

database2flex.jpg

It works as follows:

1. The Flex 3 application sends out a HttpRequest to a php webpage.
2. The php script queries the database and selects all elements from a table
3. The same php script outputs the table as a XML-formatted page and returns this to the Flex application
4. The Flex application interprets the XML page and creates a table output using a Datagrid.

Download here all the source files. In order to make it work with your site do the following:

Make sure you have a webserver running PHP and MySQL or PostgreSQL

- Copy DataSmart.swf and DataSmart.html to your webdirectory
- Copy either GetDataSmart_MySQL.php or GetDataSmart_PostgreSQL.php to your webdirectory, depending on the database technology you’re using.
- Rename the .php to GetDataSmart.php
- Edit the .php page to connect to your database and to query the table you want to display.

open DataSmart.html in your webbrowser and everything should work (Adobe Flash plugin needed!)

Friday, January 30, 2009

Adobe FLEX 3 .mxml code to display xml data in a datagrid table

This post contains .mxml code which reads in a xml file and outputs a table showing all information.

The xml file should look like this: (see my previous post to see how to dynamically generate such a xml file from a PostgreSQL or MySQL database using PHP)

<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>
<entries>
<entry><column_1_name>column_1_row_1_value</column_1_name><column_2_name>column_2_row_1_value</column_2_name> .......... </entry>
<entry><column_1_name>column_1_row_2_value</column_1_name><column_2_name>column_2_row_2_value</column_2_name> .......... </entry>
........
........
</entries>

Here is the FLEX code:
(the xml data used in this example is dynamically generated by GetDataSmart.php)

<?xml version="1.0" encoding="utf-8"?>
	
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init()" horizontalAlign="left" verticalAlign="top" width="100%" height="100%">
	
<mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.rpc.http.HTTPService;
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;
            import mx.collections.XMLListCollection;
            import mx.controls.dataGridClasses.DataGridColumn;
            import mx.utils.StringUtil;
            import mx.collections.ArrayCollection;
            
            
            private function init():void {
            	data_service.addEventListener("result", httpResult);
            	data_service.addEventListener("fault", httpFault);
            	data_service.send();
            }    
            
            [Bindable]
 			public var datalist:XMLListCollection;      
	
            public function httpResult(event:ResultEvent):void {
            	var x:XML = event.result as XML;
				var xl:XMLList = XMLList(x.children());
				datalist = new XMLListCollection(xl);
	
				list.columns=generateCols(datalist.copy(), false);
               	list.rowCount=datalist.length;
               	list.dataProvider=data_service.lastResult.entry;
              
            }
	
            public function httpFault(event:FaultEvent):void {
                var faultstring:String = event.fault.faultString;
                Alert.show(faultstring);
            }
            
            private function generateCols(input:XMLList, useAttributes:Boolean = false):Array {
 				var e1:XML = input[0];
 				var columns:Array = [];
 				var children:XMLList ;
 				if (useAttributes) {
 					children = e1.attributes();
 				}
 				else {
 					children = e1.children();
 				}
    			for each(var child:XML in children) {
    				var col:DataGridColumn = new DataGridColumn();
    				col.dataField = child.name();
    				columns.push(col);
 				}
 				return columns;
			}
        ]]>
</mx:Script>
	
<mx:HTTPService id="data_service" url="GetDataSmart.php" showBusyCursor="true" resultFormat="e4x"/>
 <mx:Panel width="100%" id="pp" resizeEffect="Resize" height="90%" layout="absolute" title="List of database: DD - Table: short02" horizontalAlign="left" verticalAlign="top">
 <mx:DataGrid id="list" width="100%" enabled="true" editable="false" textAlign="center" variableRowHeight="false" wordWrap="false" y="0" sortableColumns="true" resizableColumns="true" minColumnWidth="150" x="0" rowCount="1">
 </mx:DataGrid>
 <mx:Spacer x="0" y="445"/>
	
</mx:Panel>
 <mx:Spacer/>
 <mx:Button label="Reload Data" id="Reload" click="data_service.send()" width="165" height="35"/>
	
</mx:Application>

Thursday, January 29, 2009

PHP scripts for outputting a complete database table to xml (PostgreSQL and MySQL)

The first php scripts below connects to a postgres database, queries a full table and outputs this table as an XML page.
The second script is similar but implements a MySQL database.

The goal of creating an XML from a table is that XML files are an easy way to communicate data to Adobe Flex (and Flash)

Both PHP scripts will output a xml page that looks like this:

<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>
<entries>
<entry><column_1_name>column_1_row_1_value</column_1_name><column_2_name>column_2_row_1_value</column_2_name> .......... </entry>
<entry><column_1_name>column_1_row_2_value</column_1_name><column_2_name>column_2_row_2_value</column_2_name> .......... </entry>
........
........
</entries>

Here is the php script using PostgreSQL:

<?php
session_start();
header("Cache-control: private");
	
//connect to the database.
$link = pg_connect("dbname=database user=databaseuser password=databasepassword");
	
//Get the data
$Query = "SELECT * from tablename";
$Result = pg_query($Query); //Execute the query
	
$XML = "";
$NumFields = pg_num_fields($Result);
	
$XML .= "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<entries>\n";
$row = true;
while ($row = pg_fetch_row($Result)){
	$XML .= "<entry>";
	for ($i=0; $i < $NumFields; $i++)
    {   
	    $XML .= "<" . pg_field_name($Result, $i) . ">" . $row[$i] . "</" . pg_field_name($Result, $i) . ">";
    }
	$XML .= "</entry>\n";
}
$XML .= "</entries>";
echo ($XML);
	
pg_free_result($Result);
pg_close();
?>

Here is the php script using MySQL:

<?php
session_start();
header("Cache-control: private");
	
define( "DATABASE_SERVER", "localhost" );
define( "DATABASE_USERNAME", "user" );
define( "DATABASE_PASSWORD", "password" );
define( "DATABASE_NAME", "database" );
	
//connect to the database.
$mysql = mysql_connect(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD);
mysql_select_db( DATABASE_NAME );
	
//Get the data
$Query = "SELECT * from table";
$Result = mysql_query( $Query );
	
$XML = "";
$NumFields = mysql_num_fields($Result);
	
$XML .= "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
$XML .= "<entries>\n";
$row = true;
while ($row = mysql_fetch_row($Result)){
	$XML .= "<entry>";
	for ($i=0; $i < $NumFields; $i++)
    {   
	    $XML .= "<" . mysql_field_name($Result, $i) . ">" . $row[$i] . "</" . mysql_field_name($Result, $i) . ">";
    }
	$XML .= "</entry>\n";
}
$XML .= "</entries>";
echo ($XML);
	
mysql_free_result($Result);
mysql_close();
?>

Saturday, January 17, 2009

Adobe Flex 3: How to automatically display the current date in a Datefield component

The following code automatically fills in the current date in a Datafield object in Flex 3.

so you have this: datafield2.jpg instead of this: datafield1.jpg

The full mxml code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="displayDate()">
	<mx:Script>
		<![CDATA[
			 public function displayDate():void {
            	                var now:Date = new Date();
				var day_int:int = now.getDate(); //gets day of the month
				var month_int:int = (now.getMonth()+1); // gets month. Months are given from 0 to 11, so you need to do +1 here
				var year_int:int = now.getFullYear(); // gets year
	
				var day_string:String;
				//display always 2 digits for a month, so '02' instead of just '2' for February
				if (day_int < 10) {
					day_string = "0" + day_int.toString();
				}
				else {
					day_string = day_int.toString();
				}
	
				var month_string:String;
				//display always 2 digits for a day, so '02' instead of just '2'
				if (month_int < 10) { 
					month_string = "0" + month_int.toString();
				}
				else {
					month_string = month_int.toString();
				}
	
				var year_string:String = year_int.toString();
	
				// note: this is displaying the date in the DD/MM/YYYY format, this same format is also set for the Datefield below!
				DateSelect.text = day_string + "/" + month_string + "/" + year_string;
			}
		]]>
	</mx:Script>
	<mx:DateField id="DateSelect" formatString="DD/MM/YYYY"/>
	
</mx:Application>

Thursday, October 9, 2008

the 1-Key-Keyboard project

Update: Please have a look at my 4-key-keyboard project as well!

Click here to download the complete sourcecode of this project (including .hex and Flash demo program)



Introduction:

The idea for a 1-key keyboard comes from the need as an interaction designer to make “cheap, quick and dirty prototypes.” When creating a quick screen-based demo in e.g. Adobe Flash, a common way of quickly prototyping physical actions is to assign actions to certain key presses on a keyboard. In more advanced prototypes, physical hacks to the circuit board from a keyboard are also often used to interface custom buttons and switches with a computer. (see http://wiki.arcadecontrols.com/wiki/Keyboard_Hacks)

What this project does is to create a keyboard hack that is smaller and cheaper and better reproducible than what one would get when hacking a keyboard circuit; a perfect solution for when you only want to use one switch in your prototype. (Note: 3 IO ports from the microprocessor are still unused, so it’s very easy to add 3 more switches. If you want to interface more than 4 switches, I suggest having a look here: http://www.obdev.at/products/vusb/hidkeys.html)

To maximize the functionality of the 1-key keyboard, I implemented having a different key being sent to the computer for a key-down and a key-up event. This can be useful when you create for example a prototype that has to detect whether a physical object is pushing down a switch or not.

This project implements V-USB (previously called AVR-USB) from Objective Development to emulate a standard USB keyboard using an Atmel AVR microcontroller. This project has been heavily inspired by the EasyLogger Reference project.


What does it do?

This 1-Key-Keyboard can be plugged into any computer and will be recognised as a standard USB keyboard.
When closing the switch, the keystroke ‘]’ will be sent.
When opening the switch, the keystoke ‘[’ will be sent.

That’s all.


What do we need:

1x Atmel ATTiny45-20PU or ATTiny85-20PU microcontroller (I used a ATTiny85, which has more memory than the ATTiny45 but the program will fit the ATTiny45 too)
2x Diodes (0.5W) (ordinary 1N4148 are sufficient)
2x 68 ohm resistors
1x 1.5K resistor
1x 0.1 uF capacitor
1x switch
a piece of prototype-board (striped 2.54mm single-sided)

a programmer for the Atmel AVR
the .hex file from the 1-Key-Keyboard project (Download it here)


Instructions:

First program the microcontroller with the .hex file (don’t forget to set the fuses first to 0xFF 0xDF 0xC1)

Link: Instructions for how to set up the Atmel AVR STK500 programmer to program an 8-pin ATTiny

Link: Instructions for setting up AVR studio for using the Atmel STK500 programmer

Link: Instructions for programming a .hex file with AVR Studio


With the programmed ATTiny, build the following circuit:



1_key_keyboard.jpg


To keep the costs low, you can make a usb-plug from strip board (veroboard) see the pictures below




dsc00323.jpg
dsc00328.jpg



Now it’s time to test the 1-Key-Keyboard! you can test it by opening a text editor and press and release the switch a couple of times. If everything went well, you should see a series like this being typed: ][][][][][



Creating a demo-program in Adobe Flash

Here’s the actionscript 3.0 code for a demo-program which detects whether the switch is pressed or not. If the switch is pressed, the movie-clip ‘onSwitch’ is visible. When released, the movie-clip ‘offSwitch’ is visible.

//actionscript 3.0 source file 
stage.addEventListener(KeyboardEvent.KEY_DOWN, reportKeyDown);
offSwitch.visible = true;
onSwitch.visible = false;
function reportKeyDown(event:KeyboardEvent):void {
	switch (String.fromCharCode(event.charCode)) {
	
		case ']' :
			offSwitch.visible = false;
			onSwitch.visible = true;
			break;
	
		case '[' :
			offSwitch.visible = true;
			onSwitch.visible = false;
	
			break;
	
		default :
	
			break;
	
	}
}
// end of source file

Try it out by clicking here and press/release the switch on your 1-Key-Keyboard.

or click here to download a .zip file with the .fla and .swf files




Click here to download the complete sourcecode of this project (including .hex and Flash demo program)



Feedback
Please feel free to leave comments on my 1-key-keyboard project!

Wednesday, October 8, 2008

Programming a .hex file with AVR Studio

If you just want to write an existing program to your Atmel AVR chip, without changing any actual code, you need a precompiled .hex file (a hex file is a compiled version of a program, to work on a specific microcontroller)

If you have a ATTiny45 or ATTiny85 you can Download here a precompiled .hex file for my 1-key-keyboard project. For other microcontrollers you’ll need a .hex file which is compiled for it.

Connect with AVR Studio to your device by pressing the connect button connect.jpg and selecting your programmer from the list and connect.

Before programming the actual firmware, the fuses need to be set on the AVR.
Read more about fuses here

If you’re using my 1-key-keyboard .hex file, the easiest way to get the correct setting is to change the bottom 3 values to:

EXTENDED: 0xFF
HIGH: 0xDF
LOW: 0xC1

Then press “Program” and the fuses are set! (this has to be done only once for every chip, unless you want to change these fuse settings off course)

See the picture below for the correct settings



fuses.jpg



Now you’re ready to program the actual .hex file on the AVR.

Go to the Program tab and under “Flash” select the path of the capslocker.hex file and press “Program”



programming.jpg



If everything goes correct, the ATTiny is programmed and you get the following report (only last 5 lines visible without scrolling)

Getting isp parameter.. SD=0×0a .. OKOK
Reading FLASH input file.. OK
Entering programming mode.. OK!
Erasing device.. OK!
Programming FLASH .. OK!
Reading FLASH .. OK!
FLASH contents is equal to file.. OK
Leaving programming mode.. OK!



Now you have successfully uploaded the code to the AVR!

Setting up AVR studio for ATTiny85 (or ATTiny45 / ATTiny25) using the Atmel STK500 programmer

Software used: AVR studio

(Click here to get AVR Studio)

After starting up AVR studio, press the connect button. connect.jpg

Select the “STK500” option and “Auto” port selection. Then press connect



select.jpg


Then In the “Main” tab, select the ATTiny85 as Device.
Set Programming mode to “ISP mode” and press “Read signature”

If everything is set up OK, then you should see the following output:

Entering programming mode.. OK!
Reading signature .. 0×1E, 0×93, 0×0B .. OK!
Leaving programming mode.. OK!



select2.jpg


Now you’re ready to start programming the ATTiny using the STK500

How to set up the Atmel AVR STK500 programmer for use with ATTiny85-20PU (or ATTiny45 / ATTiny25)

Introduction:

There are 2 ways of programming an ATTiny85 microcontroller using the Atmel AVR STK500 programmer. The first one is In-System Programming (ISP); The most common way of programming AVR’s.
The other way of programming the ATTiny85 is High Voltage Serial Programming (HVSP). This is the only way of programming that can be used after the ‘reset disable’ fuse is set on the ATTiny85.

In-System Programming:

Before being able to program the ATTiny85-20PU with the STK500 you need to add 2 jumper wires on the STK500:

• One wire to connect the PB3 pin (pin 4) on the PORTB header to the XT1 pin (pin 7) on the PORTE / AUX header. This is to connect the clock system to the AVR device.

• The second wire to connect the PB5 pin (pin 6) on the PORTB header to the RST pin (pin 4) on the PORTE / AUX header. This is to connect the reset system to the AVR device.

• Place the 6-pin programmer cable so that it connects ISP6PIN to SPROG1

Jumper settings:

VTAGET: Enabled
AREF: Enabled
RESET: Enabled
XTAL1: Enabled
OSCSEL: pin 1-2 Enabled
BSEL2: Enabled
All other jumpers: Disabled

Place the ATTiny85-20PU in the SCKT3400D1 socket

Connect the (12V) power supply and a (usb-to-)serial cable to connect the programmer to your computer to the RS232 CTRL port and power on the STK500

See the complete setup for ISP in the picture below



isp_stk500.jpg




High Voltage Serial Programming:

source: STK500 user guide

1. Switch power off.
2. Place the ATTiny85 in the SCKT3400D1 socket and make sure all other sockets are empty!
3. Mount jumper OSCSEL on pins 1 and 2 to select software-controlled clock.
4. Mount jumper XTAL1 to route the oscillator signal to the device.
5. Mount jumpers VTARGET and RESET.
6. Use one 2-wire cable to connect the PB3 pin (pin 4) on the PORTB header to the XT1 pin (pin 7) on the PORTE/AUX header. This will connect the clock system to the AVR device.
7. Use another 2-wire cable to connect the PB5 pin (pin 6) on the PORTB header to the RST pin (pin 4) on the PORTE/AUX header. This will connect the reset system to the AVR device.
8. Use a third 2-wire cable to connect the PB0 and PB2 pins (pins 4 and 3) on the SPROG1 header to the DATA0 and DATA2 pins (pins 1 and 3) on the PROG DATA header.
9. Use the last 2-wire cable to connect the PB1 pin (pin 1) on the SPROG1 header to the DATA1 pin (pin 2) on the PROG DATA header.
10. Switch power on and you are ready to program.

See the complete setup for HVSP in the picture below



hvsp_stk500.jpg

Admin area