Pages: [1]   Go Down
Author Topic: Batsocks TellyMate Shield  (Read 966 times)
0 Members and 1 Guest are viewing this topic.
London, England
Offline Offline
Edison Member
*
Karma: 4
Posts: 1026
Go! Go! Arduinoooo !!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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







Logged

0
Offline Offline
Edison Member
*
Karma: 8
Posts: 1411
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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".

Logged

London, England
Offline Offline
Edison Member
*
Karma: 4
Posts: 1026
Go! Go! Arduinoooo !!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm going to give 'Pong' a go for starters smiley
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Mike, I starting working on that as well, how far along is yours?
« Last Edit: May 20, 2009, 02:35:10 am by mem » Logged

London, England
Offline Offline
Edison Member
*
Karma: 4
Posts: 1026
Go! Go! Arduinoooo !!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Not even started yet   :smiley
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*
  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' ) ;
}
« Last Edit: May 20, 2009, 09:35:29 am by mem » Logged

London, England
Offline Offline
Edison Member
*
Karma: 4
Posts: 1026
Go! Go! Arduinoooo !!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I haven't got that shield but will modify it for my kit
what modificaitons ? it looks like we use the same shield.
Logged

London, England
Offline Offline
Edison Member
*
Karma: 4
Posts: 1026
Go! Go! Arduinoooo !!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The 'dangershield' mentioned in your code.
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

here a version that uses a speaker or piezo on pin 3 for sound.

Code:
/*
  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' ) ;
}

« Last Edit: May 21, 2009, 11:16:30 am by mem » Logged

London, England
Offline Offline
Edison Member
*
Karma: 4
Posts: 1026
Go! Go! Arduinoooo !!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to: