A Spark of Life: More DigiSpark fun

WP_20151019_22_42_59_Pro__highresI recently wrote about the cool little DigiSpark ATTiny 85 controller board. This little USB wonder, like the AdaFruit Trinket, is based on the ATTiny85 Microcontroller and has limited I/O, memory and is cheap, very cheap.

One thing it is not short on, however, is uses. This little thing can be used for a variety of things, including games and control applications.  For any use, though, you will need some kind of input and some kind of output.  In a previous post, I postulated about porting my ‘Battlestar Galactica’ game to the DigiSpark from the Trinket.  So, here are the results of that endeavor and some other things as well.

For the backstory of the game and why I wrote it, check out this post. I’ll wait.

Read it?  Cool.WP_20151019_22_44_34_Pro__highres

Ok, so there are few differences between the Trinket and the DigiSpark, other than size.  The way you program it is very similar and the pins are nearly identical.  The way you talk to things, is, however, a little different.

The Trinket needed SoftwareSerial. We don’t here, we just use DigitalRead and DigitalWrite and Serial.write to read the button and write to the screen.

The display is a 16×2 Serial LCD from Parallax.  The button is actually a ‘controller’ I built a couple of years ago for my game console. I did not use it for that, opting for the Wii Nunchuck instead.  So, the controller has three buttons that would be used for left, right and ‘fire’ or action.  Here, they just return a 0 if pressed and a 1 when ‘open’.  The code periodically polls the controller for a press and then acts on the press to evaluate a hit or miss.

WP_20151019_22_44_06_Pro__highres

Now, one of the problems I had was the lack of GROUND pins. So, I made a ground bus, a four pin strip with a wire connecting all four pins. I then connected this to ground on the DS and the button and the LCD as well are connected to this bus. I have one free ground pin.  Well, what I did not realize was that you can use any pin for ground.  While I did not change my connections, I find this pretty cool.

TIP! To use a free pin as ground:

(From the wiki)

You can use an I/O pin as a ground/+5V if you have some left and the current that flow in it is low (a few milliamps if you want the pin to stay around 0V/+5V. If you don’t care about the exact voltage you can go up to 40mA per pin according to the datasheet but it’s good to keep a safety margin).

Configure the pin as an output and set its value to either LOW or HIGH (for ground or +5V

#define button 0
#define gnd 2
 
void setup() {                
  pinMode (button, INPUT);
  digitalWrite (button, HIGH); // enable pullup
  pinMode(gnd, OUTPUT);
  digitalWrite (gnd, LOW); // use this pin as a ground
}

For much more information and tips, go to the wiki, located here.

The game code is below.

Come back for more on this cool little device.  Since it is capable of serial i/o, I’m thinking of using the Bluetooth Serial module and connecting the DS to one of my HalfByte Consoles running the graphical serial software for video display from the DS.

WP_20151019_22_45_35_Pro__highresWP_20151019_22_43_27_Pro__highres

Game Code:

#include <TinyPinChange.h>

 // globals
 int  cylonpos;
 int  oldcylonpos;
 int  cyDirection;
 int  button;
 int  posStart;
 int  lin2Start;
 int  bsgpos;
 
 // special characters
 int  bsg;
 int  cylon;
 
 // total number of torpedos the ship has left
 int  tShots=10;
 
 // the setup routine runs once when you press reset:
 void waitforbutton();
 void moveCylon();
 
 void setup() {  // initialize the digital pin as an output.  
   Serial.begin(9600); 
   Serial.write(12);
   Serial.write(17);
   
   //define the ship character
   Serial.write(249);
   Serial.write(0x4);
   Serial.write(0xE);
   Serial.write(0xE);
   Serial.write(0x15);
   Serial.write(0x1F);
   Serial.write(0x15);
   Serial.write(0xE);
   Serial.write(0xE);
   
   // baddies
   Serial.write(251);

   Serial.write(uint8_t(0x0));//to handle a goofy issue with '0'
   Serial.write(uint8_t(0x0));
   Serial.write(0xE);
   Serial.write(0x15);
   Serial.write(0x1F);
   Serial.write(uint8_t(0x0));
   Serial.write(uint8_t(0x0));
   Serial.write(uint8_t(0x0));
 
 // the button is on pin 0  
   pinMode(0,INPUT);
   
 // the initial direction is right
   cyDirection=1;
   
 } // the loop routine runs over and over again forever:
 void loop() {
  int score;
  score=0;
  
  Serial.write(12); // clear the screen and show the instructions
  Serial.println("Shoot the Cylon\n");
  Serial.println("press btn strt");
  
  // wait for the button
  waitforbutton();
  
  // define somethings before we start the game loop
  tShots=10;
  cylon=3;
  bsg=1;
  lin2Start=148; // the baddies appear on line 1
  posStart=128;  // the good guys on line 2
  randomSeed(analogRead(0)); // gen a random seed
  
  bsgpos = 8;  // our ship starts in the middle of the sector
  cylonpos=random(0,15); // baddies warp in at a random spot
  oldcylonpos=cylonpos;
  
  Serial.write(12);  // clear screen
  Serial.write(17);  // turn on backlight so we can see
  Serial.write(posStart + cylonpos);  // uh oh...the Cylon appeared!
 
  Serial.write(cylon);
  Serial.write(lin2Start+bsgpos);
  Serial.write(bsg); // and here we are
  
  // begin the game 
  while(1){
    /* Game loop */
    int button;
    Serial.write(22); // kill the cursor
    moveCylon();
    delay(200);
    button=digitalRead(0);  // check the button
    
    if(button==0){ // torpedo fired?
      if(cylonpos==bsgpos){ // Hit?
        Serial.write(132); // center 'Hit' on screen
        Serial.print("** HIT **");
        score ++;  // update score
        Serial.write(213); // noise (C at half note, 3rd scale)
        Serial.write(215); // play the note
        Serial.write(224);
        Serial.write(225);
        if(score==10){  // did we win?
           Serial.write(12); // clear screen
           Serial.write(128);// start at beginning
           Serial.print("You have saved\nthe Galactica.");
           delay(2000);
           loop();  // start game again
        }
        delay(3000); // did not win yet
        Serial.write(12); // clear screen
        Serial.write(lin2Start); // move cursor to beginning of line
        Serial.write("Score:");  // put up score
        Serial.print(score);
        Serial.write(lin2Start+bsgpos); // Since we shot the Cylon, we have to leave the sector, so...
        Serial.write(0x20); // go into hyperdrive and erase the BSG
        bsgpos=random(9,15);  // calculate new position
        Serial.write(lin2Start+bsgpos); //...and, we are here
        Serial.write(bsg);
        Serial.write(posStart+cylonpos);
        Serial.write(0x20);
        cylonpos=random(0,15); // Damn, they found us!
        oldcylonpos=cylonpos;
        moveCylon();
      } 
      
      tShots --; // decrement our torpedo inventory
      if(tShots<1){ // out of ammo?
        Serial.write(12);  // clear screen
        Serial.write(posStart); // start at beginning of line
        Serial.print("The Cylons win.\n");
        int count=1;
        // show animation of our ship exploding
        while (count<10){
          Serial.write(lin2Start+bsgpos);
          Serial.write(bsg);
          delay(500);
          Serial.write(lin2Start+bsgpos);
          Serial.write('*');
          delay(500);
          count++;
        }        
        loop(); // Play again
      }
    }  
  }
}
void moveCylon(){
  // sneaky Cylons...they show up anywhere!
  Serial.write(posStart+oldcylonpos);
  Serial.write(0x20);
  if (random(0,6)>3){
      //Cylon warped
      cylonpos=random(0,15);
      oldcylonpos=cylonpos;
  }
  
  cylonpos += cyDirection; // figure out which way to move
  if (cylonpos>15){
   cylonpos=15;
   cyDirection=-1;
  }
  
  if (cylonpos<0){
    cylonpos=0;
    cyDirection=1;
  }
  // erase from old spot
  Serial.write(posStart+oldcylonpos);
  Serial.write(0x20);
  Serial.write(posStart+cylonpos);
  Serial.write(cylon);
  oldcylonpos=cylonpos;
} 

void waitforbutton(){
   
  int button;
  button=digitalRead(0);
  while(button==1){     //wait for button press
    button=digitalRead(0);
    delay(1000);
  }  
  Serial.write(1);  
  delay(1000);
  Serial.write(12); 
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s