lunedì 9 aprile 2012

A 4x5 5mm Red LED Display

If you have at least 20 LED and some wires you can create a very little character display to print some sliding phrases. The idea is extendible: of course if you want to extend the rows/cols of display you can as you desire.
This time I'll use a Digilent Nexys2 Board (with spartan3e 1200k FPGA) in which there is a Leon3 IPCore with GRGPIO controller to drive the expansion port. Nothing forbids you to use Arduino Board: in fact you need only 9 pins in this configuration.
For convenience I'll use a software driver very similar to Arduino (i.e. pinMode, digitalWrite, etc.) plus some useful function that accept mask as parameter (i.e. pinModeMask, digitalWriteMask, etc.): in this way in the "same cycle" it's possible to change the mode or the logical value to some pins. In any case it would be easy to implement a function that accepts input masks on Arduino. Maybe I'll do in next article =P.

How you can use only 9 pins to drive 20 LED? It's very easy, of course! You have to build a LED matrix and link cathodes along the rows (columns) and anodes along the columns (rows); in this way you cannot drive all LEDs in the same time. But our eyes are (very) slow and we have to exploit this feature.
In my case I'll connect the 4x5 LEDs in this way: the 5 rows connect the cathodes (5 cathodes), the 4 columns connect the anodes (4 anodes).

The resistors (100Ω) connect the pins to anodes
You can power up each anode in a loop (powering down the others) and configure the cathodes to light the LEDs you want (this is because the anode is less than the cathode: in this way every cycle has a shorter duration). If the LED has to be power off you have to change the pinMode of cathode pin to input (in this way the pin sets high-impedance, preventing the current passage) else as output with low value (allowing the current passage). In this way only one row (column) is working, the others are switched off; if the loop frequency is at least 30/40Hz our eyes don't perceive that a line is turned on while the others are off, but they see all LEDs lit at the same time.
So the first thing you have to define 4 pin consecutive what will drive anodes: in every loop highAnode = highAnode + 1 mod 4. In each cycle you have to configure the cathodes too.
Animation at 1 Hz of explained concept
Now you have to create a coder that transform ASCII chars into cathodes setting (maybe this requires several minutes and tests). Also, if you want, you can implement a shift mechanism to display some characters. Watch the video below to see a rough draft of the display.


Cya!

domenica 4 marzo 2012

Rock-Paper-Scissors Game for Bash Terminals

Maybe the Rock-Paper-Scissors is the most knew hand game of the world, specially by kids, used to toss up or as pastime. The name goes up from the three gestures used in the game: two players keep a hand closed; they count aloud to three and each time raising one hand in a fist and swinging it down on the count. At the third time (when they say "Scissors!") the players change their hands into one of three gestures:

  • Rock: expressed as a clenched fist
  • Scissors: represented by two fingers separated
  • Paper: expressed ad an open hand with all finger extended
The winner is determined by these simple rules:

  • Rock beats scissors
  • Scissors beats paper
  • Paper beats rock
  • Rock versus rock, scissors versus scissors, paper versus paper results in a draw
You often (or not xD) doesn't have a friend to play with. So, for me, I've write a simple bash/C application to play Rock-Paper-Scissors with your PC. It is so rough, but funny too!
Download the .tar.gz package (by link below) and extract it; after you have to compile the whowins.c file (you can do this simply launching gcc -O3 -o whowins whowins.c on your terminal). Now you can execute rps.sh as script specifying rock (or 1), paper (or 2), scissor (or 3) or random to play versus PC.
Eventually I'll develop a Java porting for all non-unix like platform (maybe with a GUI).



The package contains:

  • align.sh, center.sh and rps.sh: bash scripts  to prepare the environment and align the text
  • whowins.c: a C dummy program that establishes who player wins
  • strings: contains a "raw" configuration strings (be careful to change it, let the lines into the original ordering)


Enjoy

Download Rock-Paper-Scissor Game for Bash terminal

venerdì 30 settembre 2011

Break easily Caesar Crypto-System

When we would guarantee the confidentiality of our data we can use a lot of ciphering methods. The problem dates back to the ancient Romans: when Julius Caesar have to communicate with his generals he wanted to do it without the bearers could read the contents of the message. For this reason he thought up a simple method of encryption that at our days is one of the simplest and most widely known encryption techniques.
Now we're going to how it works. Simply take a integer number in interval [0 to 26]: this is your chiper key (k). The algorithm based on shifting alphabet of k steps and on corresponding between character in original alphabet with character present in same position in transformed alphabet.
I.e. if we choose k = 4 we obtain that corresponding:

normal alphabet: abcdefghijklmnopqrstuvwxyz
shifted alphabet: efghijklmnopqrstuvwxyzabcd

Note that shifting is obtainable considering modulo operation; in fact if you associate a number for each letter in base of position in the alphabet (a --> 0, b-->1, ..., z-->25), to obtain transformed alphabet compute a modulo operation for each letters. I.e. with k = 4:

'a'-->0; (0+4) mod 26 = 4<--'e'
'o'-->14; (14+4) mod 26 = 18<--'s'
'y'-->24; (24+4) mod 26 = 2<--'c'

In this case the world "Caesar" become "Geiwev" because 'C' correspond to 'G', 'a' correspond to 'e', 'e' correspond to 'i', and so on.

If we refers to classical definition of crypto-system, Caesar Encryption uses these characteristics:

  • M = {sequences of letters}
  • K = {i / i is an integer and 0<=i<=25}
  • E = {E(k,m) = (m+k) mod 26}
  • D = {D(k,c) = (26+c-k) mod 26}
  • C = M
The Caesar cipher can be easily broken even attacker knows the ciphertext and that the used algorithm is Caesar Encryption. Since there are only 26 keys is very easy organize a brute-force attack: taking the decrypting function and trying all 26 keys, one of these works properly and give the original text in clear. But if we want to try few keys, there are the most likely, we can use a mathematical (statistical) approach based on correlation. Considering character frequency on English language (or another language) we can calculate the likeness between chars frequency in ciphertext, like decrypted with a generic key, and chars frequency in English language. In mathematical terms, for each key (from 0 to 25) we have to calculate:

f(c): the frequency of character c in English language
p(c): the frequency of character c in ciphertext
a(i): the correlation function calculate in this way



Consider this example to better understand:

Suppose this is cipher text we want decrypt and this is written in English:

dwnzswna ykza ywaown atwilha

First of all we need chars frequency table in English language: with google (or wikipedia) we can find it easily. I use this:

A --> 0.080000
B --> 0.015000
C --> 0.030000
D --> 0.040000
E --> 0.130000
F --> 0.020000
G --> 0.015000
H --> 0.060000
I --> 0.065000
J --> 0.005000
K --> 0.005000
L --> 0.035000
M --> 0.030000
N --> 0.070000
O --> 0.080000
P --> 0.020000
Q --> 0.002000
R --> 0.065000
S --> 0.060000
T --> 0.090000
U --> 0.030000
V --> 0.010000
W --> 0.015000
X --> 0.005000
Y --> 0.020000
Z --> 0.002000

Then obtain a frequency of letters that appear in ciphertext:

A --> 0.200000
B --> 0.000000
C --> 0.000000
D --> 0.040000
E --> 0.000000
F --> 0.000000
G --> 0.000000
H --> 0.040000
I --> 0.040000
J --> 0.000000
K --> 0.040000
L --> 0.040000
M --> 0.000000
N --> 0.120000
O --> 0.040000
P --> 0.000000
Q --> 0.000000
R --> 0.000000
S --> 0.040000
T --> 0.040000
U --> 0.000000
V --> 0.000000
W --> 0.200000
X --> 0.000000
Y --> 0.080000
Z --> 0.080000
It's easy to calculate: named o(i) the occurrence of generic letters i in the ciphertext. The frequency of letter i in ciphertext is: p(c) = o(i)/numbers of letters in ciphertext.
At this step we are ready to calculare 26 correlation function:

0 --> 0.046560
1 --> 0.020400
2 --> 0.024480
3 --> 0.038080
4 --> 0.032880
5 --> 0.043600
6 --> 0.040200
7 --> 0.050000
8 --> 0.044440
9 --> 0.049440
10 --> 0.035600
11 --> 0.039680
12 --> 0.035480
13 --> 0.034480
14 --> 0.038040
15 --> 0.039280
16 --> 0.023200
17 --> 0.027480
18 --> 0.058880
19 --> 0.039280
20 --> 0.042760
21 --> 0.039880
22 --> 0.067600
23 --> 0.024040
24 --> 0.026880
25 --> 0.036360

The best 5 results are in correspond with keys 22, 18, 7, 8 and 0. If you try this 5 keys you can successfully  discover that the right key is 22 and the text in clear:

 hardware code caesar example

For your curiosity, or even to test Caesar encryption, I develop a package of functions that can be used in Matlab environment that you can download from link below.

domenica 1 maggio 2011

[DRAFT] Nintendo Wii Controller Nunchuck as simple Mouse

3D and high definition are the masters at gaming market. The gameplay, thanks to these factors, has become a critical yardstick for players, that require more interactivity. Nintendo Wii firstly made a large piece of ​​history in the seventh generation console with an innovative interface system: I'm talking about Nintendo Wii Remote (nicknamed Wiimote), a free hand controller; the interest of Nintendo was, and it is, to be attractive to a wide public. The real strength of Wii Remote is the low cost, high versatility and availability: a lot of curious people have made crazy applications and strange use (see on youtube).
Wii Remote has to expand, using a proprietary port, with an accessory: the most famous and used is Controller Nunchuck. It's an another free hand controller that allows to have a directional analogic joystick controller plus two buttons (Z and C) and an accelerometer. Ours goal is to use Nunchuck as PC device, so get state information on Nunchuck Controller, i.e.:

  • If Z or C button is pressed
  • The position of analogic in therm of carthesian coordinates
  • The values of accelerometer
Now let's focus on the most interesting thing, that's accelerometer. In the Nunchuck we have a LIS3L02AL, a three-axis linear accelerometer; this device is physically rated to measure accelerations over a range of at least +/- 2g. Here you can find the complete datasheet of LIS3L02AL. With an accelerometer it's possible to take information about direction, sense and magnitude of accelerations in X,Y, Z carthesian coordinates system.






In particular we can get the sigle component on each axis.
Unexpectedly the cost of nunchuck is lower than of the only accelerometer. If you already have a Wii can use the Nunchuck you have; otherwise you can buy it at very cheap price. In fact if you want learn to use a acceleretion sensor you can start with that.
Please note: the LIS3L02AL is a MEMS accelerometer; in this type of accelerometer is possible to approximate the movement made ​​with the acceleration measured.
So before continue be sure to have:
  • Arduino 2009 or Uno board
  • Some wires (minimum 4)
  • Isolator adhesive tape (or common liquid glue)
  • The Nintendo Nunchuck
Also be sure a serial client and a version of Matlab installed on your PC. Matlab can help you to comprehend the best way to acquire and elaborate the value of accelerometer with Plot function.
First we have to create a connector to reach the contact of Nunchuck connector. Take a strip of ordinary paper and fold it to obtain a thicker strip. In this way we can position some wires on the strip as true connector.

The homemade connectors: so you cannot cut the port of Nunchuck to reach wires directly
Put 2 wires upon with 4~4,5 mm between and others 2 in back in same way. We need only 4 wires because 2 of 6 connectors of Nunchuck port are connected:
The standard of communication used by periferical device of Wii Remote is TWI bus, that is the same of I²C, and we are very happy! In fact this standard is supported by a lot of software libraries. On our Arduino Board we can use the library Wire.h, programmated to work on Analog 5 and 6 pins to communicate with a TWI bus device.
So if you want to get more information see the link above. You just know that Vdd of TWI devices is 3,3V or 5V (in our case Nunchuck required 3,3V) and each device has a ID to be addressable. Thus as you can see in pictures SCL (Serial Clock Line) and SDA (Serial DAta) must to be connected respectively with A5 and A4 pins of Arduino Board and are the only two wire (except for the power supply) required from standard (In fact, the acronym is Two Wire Interface).
We have to connect (finally!) Nunchuck to Arduino using the connector you have made.
Please note: in the pictures that you're seeing I'm using a breadboard; it's not required, but I doing only for a comfort.
Nunchuck connected properly to Arduino Uno
Second let's to use Wire.h! Before to proceed define this costant necessary for the communication:


#define KEY 0x17
#define DEVICE 0x52
#define INIT 0x40
#define ACK_PACKET 0

The first value, named Key, is necessary to uncrypt the bits that we received from Nunchuck; I honestly tell you that there is a way to receive unencrypted data directly, but my implementation doesn't use this new way. You can try implement by yourself.
The second is the ID of Nunchuck device on TWI bus; the third rappresent the value of communication startup and last the acknowledgment packet that we have to send to Nunchuck after reading of bytes stream.
Now we have to define some functions that we'll using in our code:

startup(){
  Wire.begin();                     
  Wire.beginTransmission(DEVICE);
  Wire.send(INIT);
  Wire.send(ACK_PACKET);
  Wire.endTransmission();
}

sendAcknoledge(){
  Wire.beginTransmission(DEVICE);     // send a zero to device 0x52
  Wire.send(ACK_PACKET);
  Wire.endTransmission();
}

decode(uint8_t x){
  return (x^KEY)+KEY;
}

On read line of TWI interface we have to read 6 byte once a time; to comprehend the motivation we can discover what's the data structure:

byte[] reading <-- read();
reading[0] contains analog X value
reading[1] contains analog Y value
reading[2] contains the first 8 bits of accelerometer X axis value
reading[3] contains the first 8 bits of accelerometer Y axis value
reading[4] contains the first 8 bits of accelerometer Z axis value
reading[5] contains 5 fields: the bit in first position indicates if the Z button is pressed; the bit in second position indicates if the C button is pressed; third and fourth contains the LSBs of accelerometer X axis value; fiveth and sixth contains the LSBs of accelerometer Y axis value; seventh and eighth contains the LSBs of accelerometer Z axis value;
So we are ready to write a properly function to decode the byte stream:

read(){
  uint8_t buf[6];
  int i=0;
  Wire.requestFrom(DEVICE, 6);        
  while(Wire.available()){
    buf[i++] = decode(Wire.receive());
  }
  if(i>=6){ //check if the whole record is been received
      decode_packet(buf);
 sendAcknoledge(); 
  }
}

decode_packet(uint8_t* packet){
    analog_x = (int)packet[0];//-123;
    analog_y = (int)packet[1];//-123;  
    axis_x = (int)(packet[2]<<2)+((packet[5]>>2)&1);  //Axis X from accelerometer
    axis_y = (int)(packet[3]<<2)+((packet[5]>>4)&2);  //Axis Y from accelerometer
    axis_z = (int)(packet[4]<<2)+((packet[5]>>6)&3);  //Axis Z from accelerometer
    button_z = !(packet[5]&1);
    button_c = !(packet[5]&2);               
}

Now all we need is done and can start with acquisition on ours PC. In my opinion the best and simplest way to excange data between Arduino and PC is the sync communication; in this way you can request data when you want and software application are less critical on acquisition.
If we now try to use this raw data we realize that all is wrong! But don't be afraid: we just need to convert the values. Freely you can choose if do this on Arduino or on Software; I like the second choise. So we can see that the analogical joiystick value are rappresented by 8 bit, 0 to 255; when the joystick is on center the value of X and Y are 125 (in my case; maybe is different to you): if we subtract always this offset obtain correct signal! Similarly we can apply this concept to X, Y, Z axis of accelerometer; in fact this 3 values are rappresented by 10 bit for each, o to 1023: in this case we have to subtract 512.
Please note: the position of accelerometer in Nunchuck permit to read, when you hold the Nunchuck in a hand, the -Z moving it up and down, the Y when you move it farward and back, the X when you move it left or right. When you read Z remember that on this axis there is -g when the board inner Nunchuck is perpendicular respect gravity
Also if you want obtain a range of value [-2g, 2g] is sufficient divide normalized X, Y and Z with 256.

Plot of 1000 X, Y, Z axis values catched from Serial COM transmission; all the axis are plotted normalized to [-2g, 2g]
To comprehend how the accelerometer is positioned you can test with these graphs all movements.


giovedì 21 aprile 2011

NDS Touchscreen can be a cheap touchpad

In this post I show you the best way to get an high performance touchpad with a little fee.

So before continue be sure to have:
  • Arduino Board (In this tutorial I'm using Arduino uno); otherwise you can use a PIC of Microchip
  • NDS touchscreen (I'm using NDS XL touchscreen)
  • A breadboard (no need too big) with some wires
  • 4x10KΩ resistors for pulldown net
Optionally, but recommended:
  • A breakout connector for NDS touchscreen (strongly suggest)
  • Some leds for get hardware feedback
  • A stylus for NDS touchscreen
Also be sure to have a serial client (like PuTTy or serial monitor embedded into Arduino toolchain) and a recent version of Matlab: this last maybe will help you to see completely the signal produced by circuit.
Let's work! First get a circuit like this:
Schematic of connections

Be careful to put correctly NDS touchscreen because in only one side it properly works; in another one touches don't modify resistor property. If you place it as shown in the figure can't go wrong.
Now we are interested in understanding how a resistive touch screen works: it's a two dimensional sensing device constructed by two parallel sheets, kept separate lightly by a spacer dots matrix distributed in the whole area. One of these sheets was made in PET to be flexible (touchable), the other was made by common glass (hard). Both are inner covered by a layer of resistance material, generally a metal oxide. The PET, with a finger pressure that reduce distance between sheets, can push down the resistance coating that meets the other. Our goal is to understand where this contact has happened.


Focus on structure of resistive touchscreen
To catch this information we have to use A/D convertors of our board; in particular we have to measure the voltage drop caused by the contact between two sheets. See the pictures showed below to understand how:

Schematic of circuits and signals need to read X value


Schematic of circuits and signals need to read Y value

The A/D reads the voltage drop and it's as high as x position (or y position). Of course it's required in one cycle we must change the status of pins A0..A4 to get x value and y value.
Now you can understand the role of pull down resistors: in fact the high resistance can stabilize the signal to read; in this way we get two benefits:
  1. We have a range of values around 800
  2. We don't need calibration
However I'm illustrating a simple method to get a great calibration. So let's to see a few code:

#define leftX = A2
#define rightX = A0
#define topY = A1
#define bottomY = A3


void read(int &x, int &y){
pinMode(leftX,OUTPUT); //Set the pin of X as OUTPUT
pinMode(rightX,OUTPUT);
digitalWrite(leftX,LOW); //And feed the circuit properly
digitalWrite(rightX,HIGH);


digitalWrite(bottomY,LOW);
digitalWrite(topY,LOW);
pinMode(bottomY,INPUT); //To read the voltage drop
pinMode(topY,INPUT);


delay(1);


int x=analogRead(bottomY); //Read the value of X


pinMode(bottomY,OUTPUT); //Following dual configuration
pinMode(topY,OUTPUT);
digitalWrite(bottomY,LOW);
digitalWrite(topY,HIGH);


digitalWrite(leftX,LOW);
digitalWrite(rightX,LOW);
pinMode(leftX,INPUT);
pinMode(rightX,INPUT);


delay(1);


int y=analogRead(xLow);
}

So you transmit the coordinates with RS232 protocol over COM with native serial of Arduino: be sure to have in your void setup(){...} function this row:


 Serial.begin(9600);


If you want can increse the Baud Rate, but 9600 enough. After reading x and y put this information over serial in this way:



Serial.print(x);
Serial.print(y);

Open your preferred serial client and connect to right COM port and see the result.
In my example I'm using PuTTy on COM6 (if you want, in devices configuration, can click on Arduino Device and in advance window change the COM port as you wish).


In this implementation you can't see which is x and y, but in this way you don't need a parser to extract information
As extra you can implement a calibration (e.g. if you don't use a pulldown net or to get very precise values) and a test of nds touchscreen limits. See the code below:


#define STRING_TO_CONFIRM "hc" //Change with your string

void calibrate(){
String incoming;
String cmp= String (STRING_TO_CONFIRM);
boolean cond = false;
  int i=0;
Serial.println("Touch it on left border; when finish send \"STRING_TO_CONFIRM \"-->");
   while(!cond){
     readXY();
if(x!=0) xmin=x; //If user touches the screen (x not zero) save the value
    while(Serial.available()>0) incoming[i++]=Serial.read();
      if(i==2){
       Serial.print(xmin);
       if(incoming.equals(cmp)) cond=true;
     }
     i=0;
   }
...//And same for other 3 borders
}

Indeed with calibration you can discover where is the effective range that you can exploit: do it for a few times and get this information to put statically in your code. In this way you can know the X Y min and max, so can try this function:


#define limXMin 8
#define limYMin 9
#define limXMax 10
#define limYMax 11

void check_limits(int x, int y){
    if(x<xmin && x>0)
      digitalWrite(limXMin,HIGH);
    else
      digitalWrite(limXMin,LOW);
    if(x>xmax)
      digitalWrite(limXMax,HIGH);
    else
      digitalWrite(limXMax,LOW);
    if(y<ymin && y>0)
      digitalWrite(limYMin,HIGH);
    else
      digitalWrite(limYMin,LOW);
    if(y>ymax)
      digitalWrite(limYMax,HIGH);
    else
      digitalWrite(limYMax,LOW);
}

When the stylus goes near borderline you can light 4 leds.
At the end you can overwork making a potentiometer to adjust, with PWM mode, brightness of two leds easily:

#define aproxxmin PUT_YOUR_VALUES
#define aproxxmax PUT_YOUR_VALUES
#define aproxymin PUT_YOUR_VALUES
#define aproxymax PUT_YOUR_VALUES
#define pwmX 3 //A right PWM pin has the ~ symbol
#define pwmY 5


int pwmx, pwmy;
...


void setup(){
...


  pwmx = 255/(aproxxmax/10) ;
  pwmy = 255/(aproyxmax/10);
  pinMode(3, OUTPUT);


  pinMode(5, OUTPUT);


...
}


void loop(){
...


  int x_ap=(tc.getx()-aproxxmin )/10;
  int y_ap=(tc.gety()-aproxymin )/10;


  analogWrite(3, x_ap*pwmx);
  analogWrite(5, y_ap*pwmy);


...
}

The methods stretches (compresses) the A/D values in a range [0, 255] that is the PWM range: you considere a generic signal bounded in a range [a, b]; if you wanna stretch it (or compress) in a new range [c, d] you have to do


Surely you're wondering why I did these strange calculations. The only reason is that Arduino operands has only 8/16 bit in ATMega and if you apply directly that formula you can obtain an overflow or underflow; also the term  was constant and can calculate once. To balance calculations you can multiply the difference signal - a by 10 and divide the difference d-c by 10.


In alternative you can analyze completely the quality of touchpad using MatLab. In this environment you can read the values transmitting on COM port like a file.


Use this simple implementation

%Hardware Code
%Serial reader for nds touchpad
%
%Author: DarkIaspis

comnds=serial('COM6');
fopen(comnds);
x=zeros(1,1000);
y=zeros(1,1000);
h=plot(x,y,'b.', 'MarkerSize',16);
axis([0 800 0 800])
for i = 1:1000
    x(i)=fscanf(comnds, '%d');
    y(i)=fscanf(comnds, '%d');
    set(h,'XData', x);
    set(h,'YData', y);
    drawnow;
end
fclose(comnds);
clear comnds;



That's all falks! I hope it was clear and helpful.