Go Down

Topic: Batsocks TellyMate Shield (Read 1 time) previous topic - next topic

Mike Mc

Thought you might like to see some pics of the Batsocks TellyMate Shield hooked up to my 47" LCD TV:-








florinc

The quality is really impressive.
I am wondering if somebody already started implementing some old fashioned apps, like tennis, or even come up with a ZX Spectrum "replacement".


Mike Mc

I'm going to give 'Pong' a go for starters :)

mem

#3
May 20, 2009, 09:34 am Last Edit: May 20, 2009, 09:35 am by mem Reason: 1
Hi Mike, I starting working on that as well, how far along is yours?

Mike Mc


mem

#5
May 20, 2009, 04:34 pm Last Edit: May 20, 2009, 04:35 pm by mem Reason: 1
Here is a version of pong for the TellyMate. The gameplay is  based on some code Tom Igoe posted here: http://www.tigoe.net/pcomp/code/category/Processing/454#more-454
Code: [Select]
/*
 TellyPong
 pong for the TellyMate shield
 based on gameplay created by Tom Igoe http://www.tigoe.net/pcomp/code/category/Processing/454#more-454
 modified by mem 20 May 2009

 This example uses the TellyMate shield http://www.batsocks.co.uk/products/Other/TellyMate%20Shield.htm
*/

#define RIGHT_PIN 0  // pins connected to pots (2 and 0 are sliders 1 and 3 on dangershield)
#define LEFT_PIN  2

// define the edges of the screen:
#define HEIGHT 25
#define WIDTH  38
#define LEFT    0
#define RIGHT  (WIDTH -1)
#define TOP     0
#define BOTTOM (HEIGHT-1)

#define PADDLESIZE  1      // this how many pixels the paddle extends top and bottom  
#define SPEED    4000      // how many milliseconds it takes the ball to move across the screen

#define BALL      'o'      // character code for ball
#define PADDLE    219      // character for paddle (see http://en.wikipedia.org/wiki/Code_page_437)

#define CHAR_ESC "\x1B"    // escape character used in TellyMate commands

int ballX = WIDTH/2;          // X position of the ball
int ballY = HEIGHT/2;         // Y position of the ball
int ballDirectionY = 1;       // X direction of the ball
int ballDirectionX = 1;       // Y direction of the ball

int rightPaddleY = 0;         // X position of the center of the right paddle
int leftPaddleY = 0;          // Y position of the center of the right paddle

int prevRight = -1;           // holds previous paddle position
int prevLeft  = -1;           // set to -1 to force display on startup

long timeStamp = 0;           // time stamp to control the pauses between ball moves
long interval = SPEED/WIDTH ; // interval in milliseconds between ball moves
boolean gamePaused = false;   // state of the game

void setup() {
 Serial.begin(57600); //57k6 baud
 screen_clear();
 Serial.println("TellyPong!");
 cursor_show(false); // turn cursor off
 delay(1000);
 screen_clear();
}

void loop() {
 // read input:
 readSensors();
 // move the ball:
 if (gamePaused) {
   if (millis() - timeStamp > interval*10) {
     // if enough time has passed, start the game again:
     gamePaused = false;
   }
 }
 // if the game isn't paused, and enough time between ball moves
 // has passed, move the ball and update the timestamp:
 else {
   if (millis() - timeStamp > interval) {
     moveBall();
     timeStamp = millis();
   }
 }
}

void readSensors() {
 // read the sensors for X and Y values:
 leftPaddleY = map(analogRead(LEFT_PIN), 0, 1023, 0, BOTTOM);
 if( leftPaddleY != prevLeft){
    drawPaddle(' ',0, prevLeft); // erase old paddle
    drawPaddle(PADDLE,0, leftPaddleY);
    prevLeft = leftPaddleY;
 }
 rightPaddleY = map(analogRead(RIGHT_PIN), 0, 1023, 0, BOTTOM);
 if( rightPaddleY != prevRight){
    drawPaddle(' ',RIGHT, prevRight); // erase old paddle
    drawPaddle(PADDLE,RIGHT, rightPaddleY);
    prevRight = rightPaddleY;
 }
}

void moveBall() {
 // check to see if the ball is in the horizontal range
 // of the paddles:

 // right:
 if (ballX >= RIGHT - 1) {
   // if the ball's next Y position is between
   // the top and bottom of the paddle, reverse its  X direction:
   if ((ballY + ballDirectionY >= rightPaddleY - PADDLESIZE)
     && (ballY + ballDirectionY <= rightPaddleY + PADDLESIZE)) {
     // reverse the ball horizontal direction:
     ballDirectionX = -ballDirectionX;
   }
 }

 // left:
 if (ballX <= LEFT + 1) {
   // if the ball's next Y position is between
   // the top and bottom of the paddle, reverse its  X direction:
   if ((ballY + ballDirectionY >= leftPaddleY - PADDLESIZE )
     && (ballY + ballDirectionY <= leftPaddleY + PADDLESIZE )) {
     // reverse the ball horizontal direction:
     ballDirectionX = -ballDirectionX;  
   }
 }

 // if the ball goes off the screen bottom,
 // reverse its Y direction:
 if (ballY == BOTTOM) {
   ballDirectionY = -ballDirectionY;
 }
 // if the ball goes off the screen top,
 // reverse its X direction:
 if (ballY == TOP) {
   ballDirectionY = -ballDirectionY;
 }

 // clear the ball's previous position:
   screenShowXY(' ', ballX, ballY);

 // if the ball goes off the screen left or right:
 if ((ballX == LEFT) || (ballX == RIGHT)) {
   // reset the ball:
   ballX = WIDTH/2;
   ;
   ballY = HEIGHT/2;
   // pause  and note the time you paused:
   gamePaused = true;
   timeStamp = millis();
 }
 // increment the ball's position in both directions:
 ballX = ballX + ballDirectionX;
 ballY = ballY + ballDirectionY;
 
 // if the game isn't paused, set the ball
 // in its new position:
 if (!gamePaused) {
   // set the new position:
    screenShowXY(BALL, ballX, ballY);
 }
}

void drawPaddle(char paddleChar, int x, int y)
{
 for(int i =-PADDLESIZE; i <= PADDLESIZE; i++)
 {
   screenShowXY(paddleChar, x, y + i);
 }
}

// TellyMate helper functions

void screenShowXY( char ch, int x, int y){
 // display the given character at the screen x and y location  
 cursor_move(y,x);
 Serial.print(ch);
}
void screen_clear( void )
{ // <ESC>E
 Serial.print( CHAR_ESC "E" );
}

void cursor_move( uint8_t row , uint8_t col )
{ // <ESC>Yrc
 Serial.print( CHAR_ESC "Y" ) ;
 Serial.print((unsigned char)(32 + row)) ;
 Serial.print((unsigned char)(32 + col)) ;
}

void cursor_show( bool show )
{ // <ESC>e or <ESC>f
 Serial.print( CHAR_ESC ) ;
 Serial.print( show?'e':'f' ) ;
}

Mike Mc

Nice one. I haven't got that shield but will modify it for my kit. Thanks!

mem

Quote
I haven't got that shield but will modify it for my kit

what modificaitons ? it looks like we use the same shield.

Mike Mc

The 'dangershield' mentioned in your code.

mem

You only need to set the analog pin assignments for your pots. I am not using any of the other features of the DangerShield - but it would be cool to use the piezo to add sound for ball contacts, and perhaps use the swtiches to start and pause the game. hmmm


mem

#10
May 21, 2009, 03:41 pm Last Edit: May 21, 2009, 06:16 pm by mem Reason: 1
here a version that uses a speaker or piezo on pin 3 for sound.

Code: [Select]
/*
 TellyPong
 pong for the TellyMate shield
 based on gameplay created by Tom Igoe http://www.tigoe.net/pcomp/code/category/Processing/454#more-454
 modified by mem 20 May 2009

 This example uses the TellyMate shield http://www.batsocks.co.uk/products/Other/TellyMate%20Shield.htm
*/

#define RIGHT_PIN 0  // pins connected to pots (2 and 0 are sliders 1 and 3 on dangershield)
#define LEFT_PIN  2

#define BUZZER_PIN 3 // digital pin connected to a piezo buzzer or speaker
#define PADDLE_SOUND 2000
#define EDGE_SOUND   500

// define the edges of the screen:
#define HEIGHT 25
#define WIDTH  38
#define LEFT    0
#define RIGHT  (WIDTH -1)
#define TOP     0
#define BOTTOM (HEIGHT-1)

#define PADDLESIZE  1      // this how many pixels the paddle extends top and bottom  
#define SPEED    4000      // how many milliseconds it takes the ball to move across the screen

#define BALL      'o'      // character code for ball
#define PADDLE    219      // character for paddle (see http://en.wikipedia.org/wiki/Code_page_437)

#define CHAR_ESC "\x1B"    // escape character used in TellyMate commands

int ballX = WIDTH/2;          // X position of the ball
int ballY = HEIGHT/2;         // Y position of the ball
int ballDirectionY = 1;       // X direction of the ball
int ballDirectionX = 1;       // Y direction of the ball

int rightPaddleY = 0;         // X position of the center of the right paddle
int leftPaddleY = 0;          // Y position of the center of the right paddle

int prevRight = -1;           // holds previous paddle position
int prevLeft  = -1;           // set to -1 to force display on startup

long timeStamp = 0;           // time stamp to control the pauses between ball moves
long interval = SPEED/WIDTH ; // interval in milliseconds between ball moves
boolean gamePaused = false;   // state of the game

void setup() {
 pinMode(BUZZER_PIN, OUTPUT); // if using speaker
 Serial.begin(57600); //57k6 baud
 screen_clear();
 Serial.println("TellyPong!");
 cursor_show(false); // turn cursor off
 delay(1000);
 screen_clear();
}

void loop() {
 // read input:
 readSensors();
 // move the ball:
 if (gamePaused) {
   if (millis() - timeStamp > interval*10) {
     // if enough time has passed, start the game again:
     gamePaused = false;
   }
 }
 // if the game isn't paused, and enough time between ball moves
 // has passed, move the ball and update the timestamp:
 else {
   if (millis() - timeStamp > interval) {
     moveBall();
     timeStamp = millis();
   }
 }
}

void readSensors() {
 // read the sensors for X and Y values:
 leftPaddleY = map(analogRead(LEFT_PIN), 0, 1023, 0, BOTTOM);
 if( leftPaddleY != prevLeft){
    drawPaddle(' ',0, prevLeft); // erase old paddle
    drawPaddle(PADDLE,0, leftPaddleY);
    prevLeft = leftPaddleY;
 }
 rightPaddleY = map(analogRead(RIGHT_PIN), 0, 1023, 0, BOTTOM);
 if( rightPaddleY != prevRight){
    drawPaddle(' ',RIGHT, prevRight); // erase old paddle
    drawPaddle(PADDLE,RIGHT, rightPaddleY);
    prevRight = rightPaddleY;
 }
}

void moveBall() {
 // check to see if the ball is in the horizontal range
 // of the paddles:

 // right:
 if (ballX >= RIGHT - 1) {
   // if the ball's next Y position is between
   // the top and bottom of the paddle, reverse its  X direction:
   if ((ballY + ballDirectionY >= rightPaddleY - PADDLESIZE)
     && (ballY + ballDirectionY <= rightPaddleY + PADDLESIZE)) {
     // reverse the ball horizontal direction:
     ballDirectionX = -ballDirectionX;
     playSound(PADDLE_SOUND);
   }
 }

 // left:
 if (ballX <= LEFT + 1) {
   // if the ball's next Y position is between
   // the top and bottom of the paddle, reverse its  X direction:
   if ((ballY + ballDirectionY >= leftPaddleY - PADDLESIZE )
     && (ballY + ballDirectionY <= leftPaddleY + PADDLESIZE )) {
     // reverse the ball horizontal direction:
     ballDirectionX = -ballDirectionX;  
     playSound(PADDLE_SOUND);
   }
 }

 // if the ball goes off the screen bottom,
 // reverse its Y direction:
 if (ballY == BOTTOM) {
   ballDirectionY = -ballDirectionY;
 }
 // if the ball goes off the screen top,
 // reverse its X direction:
 if (ballY == TOP) {
   ballDirectionY = -ballDirectionY;
 }

 // clear the ball's previous position:
   screenShowXY(' ', ballX, ballY);

 // if the ball goes off the screen left or right:
 if ((ballX == LEFT) || (ballX == RIGHT)) {
   playMiss();
   // reset the ball:
   ballX = WIDTH/2;
   ;
   ballY = HEIGHT/2;
   // pause  and note the time you paused:
   gamePaused = true;
   timeStamp = millis();
 }
 // increment the ball's position in both directions:
 ballX = ballX + ballDirectionX;
 ballY = ballY + ballDirectionY;
 
 // if the game isn't paused, set the ball
 // in its new position:
 if (!gamePaused) {
   // set the new position:
    screenShowXY(BALL, ballX, ballY);
 }
}

void drawPaddle(char paddleChar, int x, int y)
{
 for(int i =-PADDLESIZE; i <= PADDLESIZE; i++)
 {
   screenShowXY(paddleChar, x, y + i);
 }
}

void playSound(int period ){
 digitalWrite(BUZZER_PIN,HIGH);
 delayMicroseconds(period);
 digitalWrite(BUZZER_PIN, LOW);
 delayMicroseconds(period);
}

void playMiss(){
 for(int i=0; i < 100; i++)
    playSound(400);  
 for(int i=0; i < 100; i++)
    playSound(3000 + i);  
}

// TellyMate helper functions

void screenShowXY( char ch, int x, int y){
 // display the given character at the screen x and y location  
 cursor_move(y,x);
 Serial.print(ch);
}
void screen_clear( void )
{ // <ESC>E
 Serial.print( CHAR_ESC "E" );
}

void cursor_move( uint8_t row , uint8_t col )
{ // <ESC>Yrc
 Serial.print( CHAR_ESC "Y" ) ;
 Serial.print((unsigned char)(32 + row)) ;
 Serial.print((unsigned char)(32 + col)) ;
}

void cursor_show( bool show )
{ // <ESC>e or <ESC>f
 Serial.print( CHAR_ESC ) ;
 Serial.print( show?'e':'f' ) ;
}



Mike Mc

Nice. I'll give that a try some time this week when I get a chance.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy