Being an Electrical and Electronic Engineering student, I spent a lot of time with Cathode Ray Oscilloscopes (CRO), Bread Board, Ic's ... in the weekly Academic Practical Lab sessions. I have seen a pretty good amount of signals dancing on the CRO's display. This later led my thoughts to make a device which produces signals so as to display a gameplay on CRO.
In my childhood I used to play a frogger like game on my hand video game toy. So I thought I would make one similar thing on CRO. Basically in frogger, we have to make our frog cross a road with some traffic.
I used a pulse of certain amplitude and of certain pulse width to be a vehicle. There were a few of such discrete levels indicating different paths for vehicles. A point was used to display the frog character. The following explanation would be about the making of game using arduino.
I thought I could make the game, first by using a micro controller and then later can build a device from discrete IC's. So, I found Arduino to be pretty comfortable for this. I tried to generate the same pulse on Arduino as thought for the other design shown above using digitalWrite() but, the signal appeared distorted and was ramping down as shown below. Also I had to further used some level shifters to achieve different levels. So, I searched for other better alternatives and found this cool stuff .... http://www.johngineer.com/blog/?p=648
Here, he explained a better way to do this. Analog PWM signal is generated corresponding to required point on screen and is filtered using an RC filter to average the PWM output. Otherwise, the output would not have been at the required level. But the problem for me was to make the animation or characters generated move continuously. So I had to make a scrolling type program to make the characters move on the screen. The co-ordinates required for the obstacles were pre-calculated in the starting position as shown in figure below. Then the co-ordinates were made to move to left (value of x-co-ordinate subtracted by a fixed amount 1 or 2) in the next frame, thus accounting for the motion of obstacles.
Then coming to the frog (a dot here) ... the frog's position was varied using a potentiometer and when the analog value corresponding to pot's position matches the obstacles position at the centre of display, the obstacle hit would be detected. While, the obstacle reaches the top most position (analog value reaches 1024) without hitting any obstacle, the code understands that the frog has crossed the road.
Here's the code explained ....
#define TRACE_DELAY 2500 //Delay which determines the frame rate and output signal clarity
int n = 20;
int ox = 6; //Pins to be connected to x and y channel of CRO after filtering with RC filter
// From pin 6,7 both separate circuits ------/\/\/\-------.------ To CRO - x channel
// R = 10K |
// | | C = 0.1uf
// |
// ---_--- GND
// .
int oy = 7;
// Levels of obstacles
int l1 = 160;
int l2 = 110;
int l3 = 60;
int l4 = 10;
int l5 = 210;
//Analog pin A5 for pot input
int r = 5;
//Pins to indicate win and lose via leds.
int wpin = 8;
int errpin = 9;
int err = 0;
int val = 0;
int hits = 0;
//Arrays containing initial x and y co-ordinates
int x[20] = { 210, 190, 190, 165, 165, 145, 145, 120, 120, 100,
100, 75, 75, 55, 55, 30, 30, 10, 10, 10 };
int y[20] = { l4, l4, l1, l1, l4, l4, l2, l2, l4, l4,
l1, l1, l4, l4, l3, l3, l4, l4, l4, l4 };
void setup()
{
pinMode(ox, OUTPUT);
pinMode(oy, OUTPUT);
pinMode(r, INPUT);
pinMode(wpin, OUTPUT);
pinMode(errpin, OUTPUT);
//Setting clock defaults to use internal oscillator
TCCR0A = ( 1<<COM0A1 | 0<<COM0A0 |
1<<COM0B1 | 0<<COM0B0 |
1<<WGM01 | 1<<WGM00);
TCCR0B = ( 0<<FOC0A | 0<<FOC0B |
0<<WGM02 |
0<<CS02 | 0<<CS01 |
1<<CS00 );
TIMSK0 = ( 0<<OCIE0B | 0<<TOIE0 |
0<<OCIE0A );
}
void loop()
{
int count = 0;
int k = 21;
int ball = l4;
while(1)
{
count = count + 1;
if(count == 1)
{
delay(1000);
}
//Switching between two alternate pulses of widths 25 and 20
if (count != 1)
{
if (k = 21)
{
k = 26;
}
else
{
k = 21;
}
//Loop for scrolling starts
for(int m = 0; m < n-2; m++)
{
x[m] = x[m+2];
y[m] = y[m+2];
}
x[n-2] = 10;
y[n-2] = y[0];
x[n-1] = 10;
y[n-1] = y[1];
}
//Making the scrolling action by x[l] = x[l] + 1
for(int j = 1 ;j < k;j++)
{
for(int l = 1;l < n-1;l++)
{
x[l] = x[l] + 1;
}
for(int i = 0; i < n+1; i++)
{
//Detecting the hit by an obstacle
if((y[i] == ball)&&(ball != 10))
{
if ((x[i]<110)&&(x[i-1]>110))
{
//Making lose indication
digitalWrite(errpin,HIGH);
delay(1000);
digitalWrite(errpin,HIGH);
hits = hits + 1;
}
}
if (ball == l5)
{
//Making win indication
digitalWrite(wpin,HIGH);
}
//Pot input
val = analogRead(r);
//Writing the analog values.. for display (obstacles)
analogWrite(ox, x[i]);
analogWrite(oy, y[i]);
delayMicroseconds(TRACE_DELAY);
//Making the pot's levels discrete
if ((val>0)&&(val<205))
{
ball = l4;
}
if((val>205)&&(val<410))
{
ball = l3;
}
if((val>410)&&(val<615))
{
ball = l2;
}
if((val>615)&&(val<820))
{
ball = l1;
}
if(val>820)
{
ball = l5;
}
if (i==n)
{
//Displaying the ball
analogWrite(ox, 10);
analogWrite(oy, 10);
delayMicroseconds(TRACE_DELAY);
analogWrite(ox, 110);
analogWrite(oy, ball);
delayMicroseconds(TRACE_DELAY);
}
}
}
}
}