June 09, 2013

Playing Tetris in engineer style

Introduction

Month ago my girlfriend showed me a 9gag post and asked, if I could build something like that. So I ordered 2 led matrices and buttons from ebay, and built it, so here it is:
Sorry for the quality, I recorded it with my cellphone yesterday evening, but I hope you see the point of it.
It was a complicated project, so writing a step-by-step tutorial would take too many time, so I just summarize the main steps of the project and some advises.

First step: wiring of the led-matrix and functional for driving it

I checked the ebay site where I ordered the matrices and found this:
It's very similar in the inner working as the 7 segment display, see below. I wrote a custom functional for driving it, see at the code.

Second step: connect the buttons

I used very simple buttons from dx:
If you press it, it connects the 2 wire. It was the first time I've ever used a button with arduino, so I was a little bit confused about it, but Google helped me out again.

Third step: writing the tetris program

As I said in the title, and as you can see in the video, this version is only beta. There are bugs in the code, sometimes it makes weird things, and I can't figure out why. I'm going to fix it sometimes, but until then, here is the code:
(if link's broken, here: http://codepad.org/gY3fLXXx)
But during the programming I've learned something useful. There is a a 2D int array, called fix[16][8], which store the fix dots, the fix pixels. It has a 5 in every pixel, where led lights and a 0 where led's dark. So I wanted to check if there is a full line, so I wrote this code:
//full line
for(int i=0; i<16; i++){
  int ch=1;
  for(int j=0; j<8; j++) ch=ch*fix[i][j];
  if(ch>0){
    for(int k=i; k<15; k++)
      {for(int l=0; l<8; l++)
        fix[k][l]=fix[k+1][l];
      }
     for(int k=0; k<8; k++) fix[15][k]=0;
    }
     
}
It multiply every number in a line and if it's bigger than 0 at the end, ie there was no 0 in the line, so it's a full line, the program deletes it. And it didn't work. Why? After a long time I figured it out: 5^8=390625. And it's too big for an int, so it overflows and gives back a negative number! So finally I changed ch to long int and so it works now. I could change if(ch>0) to if(ch!=0)or ch=ch*fix[i][j]; to ch=ch*fix[i][j]/5; but long int was my first tough and it works so I leave it so.

Summary

It was, and it's still a big project, I hope, someday I'll finish it. Maybe I will add a demultiplexer to use less output of the arduino, and use better buttons, maybe even a use a keypad. But first I have to make the program better.

Best regards, hope you enjoy:

Mark

March 29, 2013

4-digit-7-segment display

Introducion


In this tutorial I'm going to show you the basics of the working of a 7 segment display, and how to use, when you have 4 in a row. So lets take look:

So that"s it. I ordered it from dx.com half years ago, because it was only $2, and I was interested in it. But in the beginning it was too hard for me, I just can't make it work. It has 6+6 so 12 pins in the back, and has no sign about them, as here:
So I took it away, and didn't even touch it till this month. We learned about 7 segment displays, and I was wondering, what if I could make my work. So I looked up on the internet, and find, that this display has its own library, here: https://github.com/sparkfun/SevSeg First I just downloaded and tried it, and it worked. So I looked into the code, and started to understand the inner working. So basically this display has 4*8 leds ( because each the number has 7, and there are 4 dots also). How is it possible then to control them only with 12 pins? Don't we need 4*8=32 pins for that? Yes, theoretically we would need 32 pins. But then, how does it works? The trick is, that we don't need to light up all lightning led constantly. If they blink very fast, we will see as if they're lighting. So there is 4 pin for specifying the number, and then whit the rest 8 pins we can control the 8 leds of the number. And if we change between the numbers very fast, nobody will be able to see the blinking. And changing it very fast is not a problem, when we are using arduino.

Inner working

Okay, you can say, but how is it possible? I mean, how does it work? It's quiet simple, using the special attribution of the led, that it's a diod, so the current can flow only in one direction. So here is  how to show a 5 in the 3. place:
(Red lines are HIGH, blues are LOW, because my display is common anode type. If yours is common cathode, just change every HIGH to LOW and )So as you can see 8 of the 12 pins is connected to each led, but in every number. The other 4 pins are connected to the other side of the leds but one by every number. The led will show up, if it get a red line (HIGH) from the top and a blue line (LOW) from the button. Otherwise it stays dark. Try to understand this part, because many-many things works in this principle like led cubes, and matrix displays

Using it

The pins are numbered this way:
And connect these pins of the display to those pins of the arduino:

   //Declare what pins are connected to the digits
   int digit1 = 2; //Pin 12 on my 4 digit display
   int digit2 = 3; //Pin 9 on my 4 digit display
   int digit3 = 4; //Pin 8 on my 4 digit display
   int digit4 = 5; //Pin 6 on my 4 digit display
   
   //Declare what pins are connected to the segments
   int segA = 6; //Pin 11 on my 4 digit display
   int segB = 7; //Pin 7 on my 4 digit display
   int segC = 8; //Pin 4 on my 4 digit display
   int segD = 9; //Pin 2 on my 4 digit display
   int segE = 10; //Pin 1 on my 4 digit display
   int segF = 11; //Pin 10 on my 4 digit display
   int segG = 12; //Pin 5 on my 4 digit display
   int segH= 13; //Pin 3 on my 4 digit display

After that we can control the display from the arduino. For this here is my code:
(NOTE: I've used Arduino MEGA for this tutorial and connected the display to pins 22-33, so if you use an UNO, change it as shown under)

boolean show[4][8];

void setup()
{
  //actually we don't need this part, but it's always good to know the wiring 
   //Declare what pins are connected to the digits
   int digit1 = 22; //Pin 12 on my 4 digit display
   int digit2 = 23; //Pin 9 on my 4 digit display
   int digit3 = 24; //Pin 8 on my 4 digit display
   int digit4 = 25; //Pin 6 on my 4 digit display
   
   //Declare what pins are connected to the segments
   int segA = 26; //Pin 11 on my 4 digit display
   int segB = 27; //Pin 7 on my 4 digit display
   int segC = 28; //Pin 4 on my 4 digit display
   int segD = 29; //Pin 2 on my 4 digit display
   int segE = 30; //Pin 1 on my 4 digit display
   int segF = 31; //Pin 10 on my 4 digit display
   int segG = 32; //Pin 5 on my 4 digit display
   int segDP= 33; //Pin 3 on my 4 digit display


   for(int i=22; i < 34; i++) pinMode(i, OUTPUT);
   
   //adding the text or numbers
   for(int i=0; i < 4; i++){for(int j=0; j < 8; j++) show[i][j]=true;} //if true: the led is dark, if false the led shows up
   //A
   show[0][0]=false;
   show[0][1]=false;
   show[0][2]=false;
   show[0][4]=false;
   show[0][5]=false;
   show[0][6]=false;
   //n
   show[1][2]=false;
   show[1][4]=false;
   show[1][6]=false;
   //n
   show[2][2]=false;
   show[2][4]=false;
   show[2][6]=false;
   //a
   show[3][2]=false;
   show[3][3]=false;
   show[3][4]=false;
   show[3][6]=false;
   show[3][7]=false;

}



void loop()
{
for(int i=0; i < 4; i++) //run on the digits
{
 for(int j=0; j < 8; j++) digitalWrite(j+26, true); //turn off every segment
digitalWrite(22+i, true); //turn the actual number on
digitalWrite(22+(i+1)%4, false); //and 
digitalWrite(22+(i+2)%4, false); //fade
digitalWrite(22+(i+3)%4, false); //the rest

for(int j=0; j < 8; j++)
{
digitalWrite(j+26, show[i][j]); //turn the specified segments on as defined in the array show
}
delay(1);
}

}

And the same code for arduino UNO:

boolean show[4][8];

void setup()
{
   //I've deleted the unnecessary part from here
   for(int i=2; i < 14; i++) pinMode(i, OUTPUT);
   
   //adding the text or numbers
   for(int i=0; i < 4; i++){for(int j=0; j < 8; j++) show[i][j]=true;} //if true: the led is dark, if false the led shows up
   //A
   show[0][0]=false;
   show[0][1]=false;
   show[0][2]=false;
   show[0][4]=false;
   show[0][5]=false;
   show[0][6]=false;
   //n
   show[1][2]=false;
   show[1][4]=false;
   show[1][6]=false;
   //n
   show[2][2]=false;
   show[2][4]=false;
   show[2][6]=false;
   //a
   show[3][2]=false;
   show[3][3]=false;
   show[3][4]=false;
   show[3][6]=false;
   show[3][7]=false;

}



void loop()
{
for(int i=0; i < 4; i++) //run on the digits
{
 for(int j=0; j < 8; j++) digitalWrite(j+26, true); //turn off every segment
digitalWrite(2+i, true); //turn the actual number on
digitalWrite(2+(i+1)%4, false); //and 
digitalWrite(2+(i+2)%4, false); //fade
digitalWrite(2+(i+3)%4, false); //the rest

for(int j=0; j < 8; j++)
{
digitalWrite(j+6, show[i][j]); //turn the specified segments on as defined in the array show
}
delay(1);
}

}

If it runs perfectly you should see "Anna" on the screen, like shown here:

You can control the text with changing the array show. For example for the first character "A" we need 6 segment from the first display: a,b,c,e,f,g. So because it's the first number, we change show[0][*] and because a=0, b=1, c=2, e=4, f=5, g=6, so

   //A
   show[0][0]=false;
   show[0][1]=false;
   show[0][2]=false;
   show[0][4]=false;
   show[0][5]=false;
   show[0][6]=false;
I think it's not so complicated :)

Deeply into the case

As you see, it use 12 pins, which actually all of the digital pin of a normal arduino UNO. So what can we do? If you think about it, there is a redundant information in the system, because every time only one of the 4 digit-pin is HIGH, so it can be controlled with a demultiplexer (aka demux). It works so:
So I0 is connected to Vcc, and F0-F3 to the 4 digit pin of the display. So now if you want a HIGH on F0, you only have to give LOW and LOW on S1 and S0, for F1 LOW and HIGH, for F2 HIGH and LOW and for F3 HIGH and HIGH. So in the end you save 2 pins, which are not the word, but sometimes can be very helpful.

I hope this tutorial was helpful, if you have any question, please feel free to write or comment

Best regards:

Mark

March 14, 2013

Homemade Shooting Gallery 1.0 (LabVIEW Image Processing)

Introduction:

Several years ago I've seen a shooting gallery in the Palace of Miracles. They've solved it with a laser gun (laser with invisible frequency) and a photosensitive target. I wanted to do the same, but much cheaper, without a photosensitive target. So I thought about visible laser dots and image processing with a webcam watching the target. That sounded much cheaper and easier and I also wanted to learn the basics of image processing for other projects, so I've started.

Purpose of the project:

So my project has basically 3 parts: a gun, that emit a red laser dot for a 0.1-0.2 seconds, a target made of paper and a software part with a webcam, that monitors the target, recognizes the laser-dot and calculates your score.

What you need:

for the gun:

  • a laser-diode, like this or these
  • a battery
  • button
  • some kind of timing IC with capacitors and resistor, more about it later
  • bunch of wires
  • some kind of base. Mine was made out of wood.
for the target:
  • just design and print something like this in A3 paper (or bigger) (mine's here)
for the software part:
  • webcam
  • for the image processing LabVIEW with NI-IMAQ and NI Vision Acquisition. I've used LabVIEW 2009, but I suppose other versions work too.

First step: the gun

It's not so hard to build a gun with a button and a laser diode and if you press the button, the diode will show up. But I needed something more. I wanted the laser dot only showed up for 0.1-0.2 second, because you know, that would be more realistic and otherwise people can just move the dot to the middle of the target. Of course it wouldn't be so hard with arduino, but I wanted to do it simpler with only IC(s), resistor and capacitors.
First I looked around on the internet, and found, that almost every timing problem has a solution, called IC 555. I've made very nicely blinking leds and I can even make a led, that shows up when you press the button and after a controllable time it turns off. The only problem was that this time had to be longer than the button-pressing-time. So I asked about it on a mailing list, and got several answers. They recommended a site where is a description about this, but it just didn't want to work. So I asked my digital-electronics-teacher, and he recommended the 74122 IC (actually he recommended 74121, but I could buy only 74122, but it's almost the same). With this I have solved, that if you pressed and release the button, then it shows up for a changeable time. So here is the wiring:

For debugging I connected an other button, which is a simple press-light wiring. After testing on breadboard, I built it and soldered together:



It looks good, but the laser dot was just too dim, and from 5 m I can't even see it, so I've used the debugging-button for the test and I'm still trying to find a good solution.
That is also a problem, that I forgot to unplug it for the night, and till morning the battery discharged, and I had to buy a new one. So I'll integrate a new switch between the battery and the others.

Second step: the LabVIEW programming

As I mentioned one of my previous post I've found a youtube tutorial for image processing. I've edit it a little bit to pattern the middle of the target and the laser dot:
When the program starts to process the image of the webcam, first it makes the picture black-and-white, after that starts looking for the patterns. If it finds these, it gives back the coordinates of the en-frame rectangle. After that it count the coordinate of the middle-point of the target and the dot (for this we only need the top-left and down-right corner of the rectangle. It also shows these coordinates as an array). Sometimes the processing algorithm loses the match for a second and give back 0, so I've made a subVI for filter it and give back the previous value:
So it knows the coordinates of the 2 middle-points. Then it counts the distance between these points, subtracts it from 100 and this is your score. I store it as unsigned int, so if it is less than 0, it's going to be 0.

But I got a strange error. If I cover the camera, => there isn't any pattern, all of the coordinates will be the same, the previous version of the first coordinate. After 10 minute of google, I found all my subVIs are using the same memory, so I have to clone them to solve the problem. Open the subVI, File > VI Properties and change it so:
After that, it worked fine, here is the result:

Summary

As you can see on the video, sometimes it doesn't recognize the dot. It can be because the target's lines are too thick and the dot gets lost between them. I've showed it to my teacher, and he recommended to mark the edge of the target and only looking for the dot inside of the target. He said, that will make the program run faster and smoother. I also have to rethink the gun, so version 2.0 coming soon.

Best regards:
Mark

February 24, 2013

Siren light, or controlling 6 LEDs with a potentiometer

Introduction

Yesterday I've got a variable resistance (aka potentiometer) from an old car radio, and today morning my brother (age 5) asked me to build a robot with him. So we built a controllable siren:

As you can see there is much more wire than necessary. Well, that was my brother's part of the project :D

Purpose of the project

As seen above, if you turn the potentiometer the lights will "run" slower or faster.

What you need:

6 LEDs, if possible reds and blues
a potentiometer
an Ardunio microcontroller and a breadboard with wires

First step: wiring

Connect the 6 LEDs to the ground and to the pin 2,4,6,8,10,12.
Connect the middle pin of the potmeter to the pin A2 (analog input) and the other 2 to 5V and GND. (More info about potmeter in this tutorial: http://www.arduino.cc/en/Tutorial/Potentiometer)

Second step: programming

Here is the code:

int val = 0;       // variable to store the value coming from the sensor

void setup() {
  pinMode(2,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(6,OUTPUT); 
  pinMode(8,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(12,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  val = analogRead(2)+1000;    // read the value from the sensor, and add 1000, because if it's too small, we can't see anything
  Serial.println(val);        //write it on serial monitor

for(int i=1; i < 7; i++)
  {
   digitalWrite(i*2,HIGH);
   delay(val/15);
   digitalWrite(i*2,LOW);  
  }
for(int i=6; i > 0; i--)
  {
   digitalWrite(i*2,HIGH);
   delay(val/15);
   digitalWrite(i*2,LOW);  
  }
}

Best regards:
Mark

February 23, 2013

Scrapyard, or how to get cool stuff for free

Today I just realized, I've slept over a goldmine for years :D Because every time we bought a new car radio, or a new printer we didn't throw away the old one, just put it under my bed. So today I took out and disassembled 3 radios, and found many useful stuff. 
First of all I got 3 DC(?) motors, which used to spin the tape. I googled one of those and found that it's operating on 13.5 V. But it's working on 5 V too, so I can use them for my arduino projects.
I've also got several capacitors (2200 μF, 3300  μF, 220 μF) from the IC, and variable capacitors  variable resistor from the volume adjustments and some buttons from the front cover. I have to test them before use, but I'm sure, they're worth the effort.
So look under your bed or on your attic or basement, maybe you can find some broken devices which has useful stuff inside.

Best regards:
Mark

PS.: Here's some picture about the disassemble and the stuff I found:


LabVIEW - ardunio interface and image processing

LabVIEW Interface for Arduino Toolkit

I have started learning about LabVIEW at the uni. I made some search on it, and find some interesting stuff. First of all, it has an add-on for arduino and it isn't so hard to use it, thanks to that video:
So now I have a nice interface for my arduino, but it's still a little bit new and complicated for me to program in LabVIEW, so I'm going to stay with the original C++ coding. But it's going to be a cool example, when I'll make a presentation with my friend about serial communication in LabVIEW.

Image processing with LabVIEW

I have a big project about a shooting gallery, and for this project I need an image processing method with webcam and computer. First I thought about MATLAB, and found some very interesting videos, but afterwards I wondered, what if LabVIEW can also do this for me. And I found a video, which make my project a lot simpler:
With this tutorial I've made the half of my project in one day. There was only 2 problems during the process: first I can't find a VI, what he had used, so I googled on that and find out, it's part of an add-on  so I downloaded it. The other problem comes out, when I start to configure the Vision Assistant. It complained about my screen size/resolution. I've tried to change the resolution, but it didn't help. Finally I had to change the taskbar  to autohide to make it work. At the end I finished up here:
As you can see it sees and marks the middle of the target and the laser dot.
Now I only have to make the gun. It's a little bit complicated, because when you press the button the light should show up only for 0.1-0.2 second, and I'd like to solve it without an arduino, only with simple circuit elements. I'm going to see, what I can do.

Best regards:
Mark

February 22, 2013

First project, ardunio and distance sensor with LEDs

Introduction

This is my first project here, so be patient with me. I'm also sorry for my English, as you probably already noticed, I'm not a native speaker :D But I hope, you will find something helpfully here. If anything is not 100% clear, or need help, just ask. I will do my best, but it's impossible to make no mistakes, so if you find one, let me know.

The purpose of the project

So arduino. This project is basically for the beginners about how to control LED-s and use an ultrasonic distance meter sensor without an additional library. If there is nothing before the sensor, shows 0 led. When something is coming closer and closer at 30 cm the first led shows up, at 20 cm the second and at 10 cm the third. As you can see here:

What you need:

3 LED-s
3 220 ohm resistors (recommended, but not absolutely necessary)
1 HC-SR04 ultrasonic distance sensor
an Ardunio microcontroller and a breadboard with wires

First step: Wiring

The wiring is very simple. First you need 3 LEDs and 3 resistors. (I've used 220 ohm resistors, but you have some with other parameter, or you don't have resistance at all, it's not a so big problem. Theoretically you always have to use resistance before LED, because otherwise too many current is going to flow through the LED and it will kill it. But I tried this without any resistance, and it worked fine and none of my LEDs died.)  So connect the resistors to the arduino ground (GND) pin, then connect each resistance to a LED lastly connect the LED-s to 2, 4, 6 pin. Now the LED-s are ready, you need to wire the ultrasonic sensor. I've used a HC-SR04 module, because it's cheap and more than enough for this function.  Here it is:

As you can see, it has 4 pin. Connect the Vcc to 5V and GND to the ground pin. Connect the trig pin to 12 and echo  pin to 13. (Of course you can change these numbers in the code)
And here is the breadboard:


Second step: programming the microcontroller

If you are ready with wiring, you have only one job left: just copy and upload the code to your ardunio. The code also available here: http://codepad.org/TvZQ2v7O

//3 leds on pin 2, 4, 6
int a = 2;
int b = 4;
int c = 6;

//the ultrasonic sensors trig and echo are connected to pin 12 and 13
#define trigPin 12 
#define echoPin 13

//run only once at the beginning. Define pinMode-s depending on we gonna send or recive data from that
void setup() {
  //LEDs
    pinMode(a, OUTPUT);    
    pinMode(b, OUTPUT);  
    pinMode(c, OUTPUT);  
   //distance sensor
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT); 
}

// the loop routine runs over and over again forever:
void loop() {
  int duration, distance;
  //send the sound
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(1000); //wait a little bit
  digitalWrite(trigPin, LOW); //turn off the sound
  //perceive when it come back
  duration = pulseIn(echoPin, HIGH);
  //convert from time to distance (in cm)
  distance = (duration/2) / 29.1;
  //first turn off all the leds
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
 if(distance < 10) //if very close: 3 leds on
  {
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
  }
  else if(distance < 20) //if close: 2 leds on
  {
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
  }
  else if(distance < 30) //if not so far: only 1 led on
  {
     digitalWrite(a, HIGH); 
  }

}

Summary

It was one of my first project, and I recommend it for absolute beginners too. If you get stuck, just let me know, and I'm going to try to help you. More complicated projects are coming soon :P

Best regards:
Mark