Showing posts with label game. Show all posts
Showing posts with label game. Show all posts

Tuesday, August 21, 2018

Shakey Shakey - a game using title switches

For the most recent Egham Raspberry Jam @EghamJam we did two workshops.
One was NoPi Blinky, making LEDs blink without any programming. More to come on this as during the workshop we found a few typos.

The other was Shakey Shakey.

For the workshops my goal is to do something slightly different that not only teaches the attendees something new from either a programming or electronics standpoint but also shows them creative options.

Shakey Shakey was based around really simple tilt switches.  They're basically a small tube with a contact inside that moves as you tilt the tube.  Really simple and really cheap. On eBay UK they're about £1.50 for 20. So, ideal when you need a bunch for the Jam
Tilt Switch

The only other things needed then were some female-female jumper wires and some 2 core wire.
I cut the female-female wires in 2 giving me a pair of wires that had the female connectors on one end and bare wire the other.  Cut the 2 core wire into about 150cm lengths and used them to connect the switch to the other wires giving a nice long wire for the kids to shake without (hopefully) unplugging the wires or pulling on the Raspberry Pi.

With the hardware sorted I them did the worksheet which is available to download from GitHub along with other Jam worksheets.

Shakey Shakey worksheet
The worksheet goes through:

  • Connecting a tilt switch
  • Python code to read the switch and display how many times it connects
  • Adding a pause to deal with debouncing
  • Adding a second tilt switch
  • Updating the code so the switches have to be activated alternatively
  • Final update of the code to add a timeline making it into a game

We had a full workshop and the kids who took parts seemed to really enjoy the coding and then playing the new game they created.

At the end I challenged the participants to come back to the next Egham Raspberry Jam (21st October 2018) with their own program that uses the same tilt switch controllers.  The worksheet at the end gives some suggestions.  Here's looking forward to the 21st of October to see what fantastic creative ideas the kids come up with.





Tuesday, June 19, 2018

Cat or Dino- Scratch 2.0 game



I saw a tweet from the @Raspberry_Pi Foundation about a game called Knifey Spoony by @Jonic one of their senior web developers did using pico-8.





The idea of the game is to select if the image is a spoon or a knife as quickly as you can with a timer running getting faster and faster the higher your score, so the pressure is on.

I thought this could be done with Scratch, so I fired up Scratch 2.0 and had a go.

Here is the result.  It uses only built in graphics making it easy for anyone to replicate and extend.
It is done with Scratch 2.0 but there is nothing special so it should work with Scratch 1.4 on the Raspberry Pi as well.

https://scratch.mit.edu/projects/229582133




Thursday, February 8, 2018

More cheap stuff from eBay - Gaming Player Handheld Video Tetris Game Console Kids Children Boy Portable Toy



I'm drawn to the underside of eBay. The placed where strange bits of electronics are sold.  This interest comes from making things and needs odd bits of electronics to realise my (awful) creations.

On one of my regular trawls of ebay I found this.

Gaming Player Handheld Video Tetris Game Console Kids Children Boy Portable Toy


Looked interesting.  OK the display is obviously mono-colour LED and not back lit but for £1.39 I thought it was worth a punt.

From the Listing the dimension are: Product size: 14*8*2cm
Bigger than the Sony PSP Go 12.8*6.9*1.64cm
If Sony can squeeze a 4.3" widescreen display in the PSP Go then this could be a very useful case to work from. A nice sized case with 10 buttons.

For reference a Raspberry Pi Zero is 6.5cm x 3 cm.  An easy fit and with dimensions greater than the PSP Go one of the many 3.2" LCD displays I see running from a Pi should fit nicely.

£1.39 for a case with 10 buttons that should easily take a Raspberry Pi Zero and 3.2 " screen with space for other bits is a bargain.

I see a plan coming together so I ordered one two weeks ago and it arrived today.

The packaging is the same as the listing which is always a good start.



Opened the box and inside was the actual console. OK a bit rough and the sticker isn't straight.  Not a problem as I plan to remove all that anyway.




But there was something else not right.  I checked the listing again and confirmed the dimension Product size: 14*8*2cm

The dimensions on the actual one I received seem a bit off.  Annoyingly I don't have a ruler with me at the moment so I'm using AAA (not AA) as the standard measure.

An AAA battery according to Wikipedia is 4.45cm long.
From the picture below it looks like this may not be 8cm wide or 14 cm in length.



It is more like 9cm in length so a Raspberry Pi Zero may still fit inside and 5cm in width.
There goes the plans for a 3.2" LCD display. Maybe one of the  0.96" OLED displays might fit.


I almost forgot.  What about the 999 games.
It does have Tetris, a variety of Breakout games, a Tank combat game and a Driving game.

The driving game is especially bad as there are only 2 lanes and you just move from left to right as the cars come down the screen.




In summary how does it compare to the listing title.

Gaming Player Handheld Video Tetris Game Console Kids Children Boy Portable Toy
It is a game playing handheld video Tetris Game Console.
No kids, children or boys included, but it definitely is portable and a toy.

As an added bonus you also get the amazing driving game, breakout and tank combat games, so in a way it over delivers on the gaming promise.  I didn't count whether there are 9999 but I suspect we all know the answer to that.

But, if your reason for getting it is to have a 14cm x 8cm x 2cm case with an opening to put a 3.2" display and a Raspberry Pi Zero you will be very disappointed as it's most definitely a lot smaller than the listing.

It is held together with screws so maybe a teardown is needed to see what's inside and if there is anything I can salvage from it.



UPDATE:
I think I may have found an actual correct listing for the one I purchased
http://www.ebay.co.uk/itm/272730431909
Listing states the dimensions are: 10 x 4.5 x 2.4cm

Then there's also this listing for £1.79
https://www.ebay.co.uk/itm/222452404318
With the dimension listed as: 15.5*6.5*2.5cm

If the larger one really is those dimensions then a project may be on to use it as a shell for something more fun.





Thursday, February 16, 2017

Making Games with Scratch and Sense Hat on Raspberry Pi


I'm a big fan of the Raspberry Pi Sense Hat and Scratch for doing interesting things and learning to code.
Previously I made a Sense Hat Cave Game using Python where you tilt the Sense Hat to move around as well as a Crane controller programmed in Scratch.
This time the goal was to create game that uses the Sense Hat as the display while programmed in Scratch.  The best of both world.  The goal for me was to lean to control the pixels a bit better in Scratch.

The result is Collect the Dots a simple game where you're a blue dot collecting red dots.  It's kind of like snake without the tail.



You control your dot using either the small joystick on the Sense Hat or use the keyboard on the computer.  Press Down to start the game.  You'll see in the video it tells you this on the Sense Hat, but if no Sense hat is attached and you're running on screen there is no prompt.


As can be seen in the video the on screen display mirrors on the Sense Hat dots, so either can be used.
Strangely even though the screen display is bigger I found it easier to play if I only looked at the Sense Hat display.
The game can also be played without the Sense Hat. Uploaded to Scratch website https://scratch.mit.edu/projects/144708660/

Embedded from the Scratch Website



You can download the code from GitHub

TIP: As the wonderful Cat Lamin points out in her blog post about using doing an animation on the Sense Hat using Scratch you have to run the code once to enable the sensors and capability of the Sense Hat.  So, the first time you run the program on a Raspberry Pi with a Sense Hat it may not work correctly.  Just stop it and start again and all will be perfect

A thought for an enhancement would be to control your dot by tilting the Sense Hat rather than using the joystick or keys.

Tuesday, August 23, 2016

buttonFlash - game made with Raspberry Pi and Arduino communicating using NRF24L01 modules

IMPORTANT: The code in this blog post is the original code which does work but may not have all the enhancements. If you're building your own I recommend grabbing the code from GitHub.
GitHub link: https://github.com/winkleink/buttonFlash

Update: 19th September:
Took buttonFlash to the Cambridge Raspberry Jam on the 17th of September and it got a proper outing.




UPDATE: 25th August:
Made Raspberry Pi program look prettier
Added sound effects


A few years ago I thought it would be fun to come up with an outdoor game that would get people running around. The Whack-a-Mole/reflexes button game came to mind and this is the result. A game where you have to press buttons as quickly as possible.



Since then a great Raspberry Pi version called Whack-a-Pi was done by +ForToffee
Here are his build instructions and videos. https://fortoffee.org.uk/2016/03/whack-a-pi/

Whack-a-Pi was in constant play at the Raspberry Pi 4th Party.


The concept for buttonFlash is similar to Whack-a-Pi but with the ability for the buttons to be much further apart.  Goal is to get people running around.  With the buttons further apart there was no way I was going to be managing physical wires as it would be a trip hazard and I didn't want to have to manage that many wires.  So, wireless communication between the base and the buttons seemed the obvious choice.

Most fields don't have wifi.  I could bring along my trusty Vocore and create a local WiFi hot spot but again I want this to be simple to set up and use.

VoCore.  Basically guts of a Wifi router

So, I thought the NRF24L01 would do the trick.  They're a really cheap transceiver. They can transmit and receive signals making them ideal for short range two way communication.

NRF24L01

This current UK eBay listing is for five NRF24L01 for £5.99
Also, there are stable libraries for Arduino and Raspberry Pi available.

On the Arduino I used the RF24 library.  If you've the latest version of the Arduino IDE you can install this through the library manager or if you prefer you can go old school and download it from the GitHub repository at the link above. More details on using the NRF24 with Arduino

On the Raspberry Pi I used the following Library https://github.com/BLavery/lib_nrf24

The Arduino side was relatively straightforward to get working while the Raspberry Pi side had me stumped for a while.  Then earlier this year I had a breakthrough when I met +Elliot Pittam.  He had seen the first Wimbledon Raspberry Jam and was interested in coming along.  On email we discussed what we were working on and Elliot said he was using the NRF24L01 with the Pi and Arduino.  We then met at a HackWimbledon event where he showed me his set up and shared his working code. Elliot helped me sort my circuit and pointed me to 2 great videos on using the NRF24L01 with both Arduino and Raspberry Pi.


Tutorial 34 - Part 1

Tutorial 35 - Part 2

With Elliot's assistance I successfully had the Raspberry Pi communicating with the Arduino.


Many of the example I found did not clearly identify which pins on the Arduino or Raspberry Pi were connected to which pins on the NRF24L01. Therefore, below is the wiring I used for the Raspberry Pi and the Arduino with the code provided.  So, it all matches up nicely.

NRF     Pi GPIO  Pin
VCC     3.3V       1
GND     GND        6
CSN     GPIO8     24
CE      CPIO17    11
MOSI    GPIO10    19
MISO    GPIO9     21
SCK     GPIO11    23

NRF           Arduino
VCC     3.3V
GND     GND
CSN     Digital 10
CE      Digital 9
MOSI    Digital 11
MISO    Digital 12
SCK     Digital 13 

For the Arduino to keep it compact I went with Arduino Nano compatible board on a small 170 pin breadboard. Easy build and easy maintenance.

Soldering on the headers to the Arduino Nano
All 5 completed

The Arduino Nano Compatible with a suitable short USB cable are ~£4.50 from the UK but can be ~£2.50 if time isn't an issue and you're happy to order from China/Hong Kong.
It's important to know these compatibles use the CH340G serial chip which is different to the Arduino branded.  You will need additional drivers to get these working with some computers.

To make each of the buttons base I needed a suitable container to hold the button and the rest of the electronics and of course the button.  I'd seen these great 60mm buttons with LEDs built in so I order some.  Again from eBay UK these are about ~£7.00 for five.  

RED 60mm LED button

The ones I ordered are 12V rated which is the power for the LED.  Opening it up these things just have a standard LED and a current limited resistors. The resistor was a 460 Ohm for the 12 volts. Without knowing the specific LEDs and their voltage drop and maximum current I played it safe and replaced the 460 Ohm with 150 Ohm resistors.  The buttons did light very dimly with the 460s but were far brighter with the 150 Ohm.  Below is the button being taken apart.

button in place 

unscrew the button/LED assembly

pull out the LED (like Christmas lights)

remove LED with resistor on Anode (+ side, other goes to GND)

solder on replacement resistor and put it all back together

To test the LED at each stage I ran an Arduino with the blink sketched and wired the LED across pins GND and 13.  Once all reassemble with the wires attached again I tested to make sure I didn't mess things up in putting it back together.

Next, for each Arduino I wired the NRF24L01 as per above.  The LED was wired to Pin 2 and Button was wired to Pin 3. In code I activated the internal pull up resistor so the button is held high until you press it and then it goes low.


it all wired up.

As the Raspberry Pi needed to send a message to the Arduinos to let them know which one is to activate their button and wait for it to be pressed before replying I came up with a simple message that is extendable.  Basically, the number of the Arduino followed by 'P' Examples: 1P, 2P, 3P, 4P, 5P
This would be the message sent out.
All Arduino would receive it and then using a simple IF statement would decide if it means they are to be activated. If not go back to listening. If yes light the button and wait for it to be pressed. Once pressed reply to the Raspberry Pi that the button has been pressed. 
In this way the Arduino are dumb.  They only respond to a request for the button and reply it's been pressed. They don't care if they are the first, second, third,... button to be pressed in the game.  All that is managed at the Raspberry Pi.

To make it easier to setup and to test I included a test mode.
When you press 't' it sends the test message and all the Arduino flash their LEDs 5 time.  Then Arduino 1 (as there will  always be at least 2 Arduino) replies that it is completed.
The Raspberry Pi doesn't do anything with this message as the test is to see if it is sent and replied to which the users sees in the console.
This means Button/Arduino 1 has slightly different code to all the rest of the buttons.

Button/Arduino 1 code with the extra bit for Arduino 1 only highlighted in RED
For each Button/Arduino the text highlighted in BLUE needs to be changed to matched the relevant reference in the Raspberry Pi list. This text is the same in all 3 locations so you can do a Find/Replace to do it in one go.

#include<SPI.h>
#include<RF24.h>

//ce. csn pins
RF24 radio(9, 10);

int buttonPin = 3;
int ledPin = 2;
int x;

void setup(void) {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  while (!Serial);
  Serial.begin(9600);

  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(0x76);
  radio.openWritingPipe(0xF0F0F0F0E1LL);
  const uint64_t pipe = 0xE8E8F0F0E1LL;
  radio.openReadingPipe(1, pipe);

  radio.enableDynamicPayloads();
  radio.powerUp();

}

void loop() {
  radio.startListening();
  Serial.println("Starting Loop, Radio on 1P.");
  char receivedMessage[32] = {0};
  if (radio.available()) {
    radio.read(receivedMessage, sizeof(receivedMessage));
    Serial.print("Received Message: ");
    Serial.println(receivedMessage);
    Serial.println("Turning off the radio.");
    radio.stopListening();

    String stringMessage(receivedMessage);
// Actual action if asked for button press
    if (stringMessage == "1P") {
      digitalWrite(ledPin,HIGH);

      while (digitalRead(buttonPin) == HIGH){
            }
      digitalWrite(ledPin, LOW);      
      Serial.println("looks like they want a string");
      const char text[] = "Node 1P - Hello";
      radio.write(text, sizeof(text));
      Serial.println("We sent our message: " + String(text));
    }

// Test scenario    
    if (stringMessage == "TEST") {
      for(x=0; x < 5; x++){
      digitalWrite(ledPin,HIGH); 
      delay(500);
      digitalWrite(ledPin, LOW);
      delay(500);
      }
      Serial.println("Test completed");
      const char text[] = "Test done";
      radio.write(text, sizeof(text));
      Serial.println("We sent our message: " + String(text));
    
    }

  }

  delay(100);
}

On the Raspberry Pi side the code is a little more interesting as it sets up the NRF24L01 and then creates a graphical window using pygame and finally runs the game.  At this stage it displays Score and High Score.




The steps to get the Raspberry Pi ready are:
Wire up the NRF24L01 as per above
Use the Raspberry Po configuration program to enable SPI (you have to reboot after this)
Then run the following commands.


sudo apt-get update
sudo apt-get upgrade 
sudo apt-get install python-dev python3.dev -y

I'm assuming you're in hour home directory for the rest of this.

mkdir buttonFlash
git clone https://github.com/Gadgetoid/py-spidev
cd py-spidev
sudo python setup.py install
sudo python3 setup.py install

cd ..

git clone https://github.com/BLavery/lib_nrf24
cd lib_nrf24/

cp lib_nrf24.py ~/buttonFlash
cd ..

You should now have SPI working with the python SPI libraries installed for Python 2 and 3 as well as the required lib_nrf24 for working with the NRF24L01 from python.
Finally the library file is copied to the buttonFlash directory.

Copy the Raspberry Pi code into the buttonFlash directory and run it.

All the necessary files and code are available on GitHub https://github.com/winkleink/buttonFlash


sudo python3 buttonFlash.py3

Yeah. Now it all technically works
Here is a short example of it running after the initial build.



With the electronics sorted and the programs functioning the next requirement was a housing for the buttons.  I thought I found the perfect one when I got this spaghetti container from Home Bargains.   It all fit comfortable and the button was really secure.



Only problem was when I went back to get more they were out of stock with no idea when/if more would be coming in.  Then I saw the Pringles can and tried it out and it worked.  Pringles cans for the win.



Oh, and I had to eat another 4 cans of Pringles to get the 5 required.  



As this is designed to be played indoors or outdoors I needed to fina a way to make them stable when placed in a field.  I went super simple and bought 150mm bolts with nuts and passed them through the bottom of the Pringles cans.  You'll notice I numbered each can and there is also a colour listed.  I bought 5 different coloured breadboards so I could tell which Button/Arduino was in each can.  
You can see the bottoms of the tubes are deformed a bit.  Ends up Pringles cans aren't super strong.  Means I have to re-tighten the nuts as they work lose.  Wonder if an application from a glue gun will sort this out.


bottom of each Tube with bolt, number and colour 

all the bits outside the can.

If you watched the video at the top or the video at the bottom you might have noticed the Pringles cans have a bit of a base to keep them stable for indoor use.  In the rush to push the buttons the Pringles cans were falling over.  The solution was some microwave pots that tapered from the bottom to the top turned upside down and with a hole cut int he bottom.  This gives a nice wide base. If further stability is needed these pots could be filled with sand or stones to weigh down the bottom even more.
microwave pot used as base

This was an interesting build as I never used NRF24L01s before.  Finding the information on how to get them to work and wire them up was interesting as most of the guides nearly provided the full details and they all seemed to provide slightly different information. So, I enjoyed solving that riddle and end up with a playable game that scales in the number of buttons and also the space.
This could be set up as 10 buttons on a table with all the cans tied to each other or as 20 buttons around the outside of a field.  You'll hear in the video below that the Raspberry Pi can call out the button numbers. This definitely made it a bit easier as you quickly learn which button is which position.  For outdoor use if it is very sunny I have a feeling the LEDs in the buttons will not be bright enough.  So, next I will be adding more lights and indicators to the buttons so they can be identified outdoors.


Here's another video of the game being played at the Cambridge Raspberry Jam.


If you have any questions or comments let me know.





Friday, January 29, 2016

Zero Ball - a game using Raspberry Pi, GPIO Zero some LDRs and very little building skills


Update: 3rd March 2017.  I resurrected ZeroBall today in preparation for Guildford Innovate on Saturday and did a video.



Trivia: Previously ZeroBall ran from a Raspberry Pi A+.  With the new PiZero W I thought it would be perfect to pair with the NexDock.  The NexDock has Bluetooth keyboard and trackpad and the PiZero W now has Bluetooth, so can be paired to the keyboard easily.  Making a nice compact solution.

On with the actual blog post.

For the recent Egham Raspberry Jam that I organised the theme was Gamification.
I already posted about sensecave a Raspberry Pi Sense Hat game  but I wanted to do something a bit more physical and real world.

That got me thinking about Fairgrounds and the kinds of games you play there.
The final decision was a ball throwing game.  Get the ball in the cups and you get points.  For those who watch US teen movies the principle is similar to beer pong, but without the beer and with points and scores....

Next exercise was to figure out how to detect a ping pong ball going into a cup.
I spent a lovely afternoon trying out PIR (Passive Infrared Sensor) sensors at  HackWimbledon. If you're near Wimbledon in the UK check them out. Great bunch of people and the events are every 2 weeks on a Saturday.

After an enjoyable day I figured out the PIR sensors are great for detecting movement of animals including people, but no use for my requirement as they even  tripped if the ball passed over the cup since the amount of infra-red light changed.  Tweeted when it failed. Luckily there was still a month to the Jam.


I now have six PIR that I can use for a different project. ;-)

With PIR out of the question the alternatives I considered were a switch or an LDR (Light Dependent Resistor) .  Both had their advantages and disadvantages.
Switch digital and easy to read and wire up, but most switches would need more force than a ping pong ball would provide.
LDR would give a great reading but is an analogue device which the Raspberry Pi cannot handled without additional circuitry

In the end despite needing extra circuitry I went with the LDR.
To get a reading from an LDR you have to create a voltage divider circuit so you can get a different voltage depending on the relative resistance values of the 2 resistors used.

Here's a great guide on voltage dividers and using an LDR

The next thing was to get the analogue reading from the voltage divider into a the Raspberry Pi in a format that it could use.  My initial thoughts were to use the analog inputs on an Arduino and then send the data over serial to the Raspberry Pi.  Considered Arduino as I have used them a bunch and knew what to do, but in the end I decided this would be over kill.  Why use a microcontroller to read analogue when there is a nice little chip that can do the same and people way smarter than me have already got it working with the Raspberry Pi.

May I introduce you to the MCP3008. An 8 channel, 10 bit analog to digital converter which communicates with the host over SPI.

Since SPI and the MCP3008 were all new to me I did the Google and found an great article by Raspberry Pi Spy. This guide explains exactly how to wire up the MCP3008/Pi and also RPI.GPIO code.
Using this I tested the LDR and it worked perfectly.  Looks like all systems are go on the project.

Then I saw that gpiozero has built in support for the MCP3008 and decided for the final project to take advantage of the ease of use brought by gpiozero.
A little test and it all worked again.  :-)

So, electronically everything works.  I can use voltage dividers with an LDR and resistor along with an MCP3008 to read the sensors and then using gpiozero read the values over SPI.

So, I began construction.

Firstly, soldering the Raspberry side headers from the MCP3008 on a strip board.

When I did this I made a mistake.  I should have left more room on the Pi wiring side of the MCP3008.  There is no need for the chip to be this close to the edge, with only one hole for the wire to be attached.  This will come back and cause me problems later...

Once this was done I moved on to creating the voltage dividers.  Since there are 6 cups, 6 resistors and LDRs are needed.


In the picture above the left side is VCC (3V3 from the Raspberry Pi), right side is GND.  Each 10k Ohm resistor is soldered to VCC on the left and then to one of the MCP3008 input pins.  The LDRs will then be connected from the MCP3008 input pin to GND to create the divider.

I did a quick test using one LDR to make sure I did this right. Image below shows it wired to the Raspberry Pi.  I used a model A+ as there isn't a requirement for network or more power. Yes, I wired it all up to power and stuff for testing.



After this the need was to add the wiring for the LDRs.  That's 6 connections with 2 wires for each.


This is already starting to look a bit more complicated than the small breadboard projects I've done before.  Looking at the image above you will see 6 black wires from the top edge (GND) and 6 orange wires tied to each MCP3008 input line.

All that was missing for the voltage dividers to be complete was to add the LDR for each line.

Since this is a physical build the LDRs need to be embedded in a plastic cup.  I also needed the LDRs to be flat against the cup to make it register a passing ball without obstructing the path of the ball.



This is the first time the sensor is actually in a cup so I can check if the ping pong ball passing is detected  correctly for the purpose. More testing of a single cup.


It worked and it worked amazing well.  That's 1 cup wired up.  Now just the other 5.


All wired up.  A bit fiddly  keeping the other cups out of the way while soldering and working with all wires the same colours to make sure I wired the correct ones for each LDR.

I had great fun at this time setting the cups up and throwing balls into them.  My kids loved it too. The fact they wanted to keep doing it even when all that happened was the number on a terminal screen updated when it happened made me think the build would actually result in a compelling game.

With the electronics sorted it was onto the bit that was new to me. The physical build.  I heard foam board was easy to work with and sturdy so went with that. Another new thing for me.

I cut holes in the foam board and inserted the cups. Using tape to hold them in place.

top, pretty side
bottom, business side.

As I mentioned the physical build is not something I do regularly, so I didn't have a lot of tools to hand to finesse the build.  My main tools were a sharp knife, glue and tape.

Once built I again did some testing and it all worked.

The top is sloped, so the balls roll back to the player. A layer is underneath, again to have the balls roll back to the player.

In the picture below you can I see a piece on the top to direct the ping pong balls to the bottom right so the returned balls will always be in the same place.  For the layer underneath the same happens. Balls return to the bottom right.


Last requirement of course was the software. I mentioned it used gpiozero for the MCP3008.  For SPI to work you have to run your code as root using sudo.
I wanted the game to feel like a fairground, so music and sound effects were essential as well as a score board.   All coded in Python.  To make this easy (for me) I used Pygame for the display, keyboard input to start a new game and also to play the background music and sound effects when a ball goes in a cup.  If you haven't used Pygame on the Raspberry Pi before then check out their recently released Make Games with Python Essentials book that is available in print, PDF, iOS and Android app.

Electronics sorted, physical build done, programming all completed.  Ready for the Egham Raspberry Jam on the 17th of January. 
As I was packing the night before I thought it best to test my projects as usually for me something goes wrong on the day and since I had the time (rare for me) doing some testing seemed like a good idea.  Ahhhh!!!!.  It didn't work.  I was checking the code and the terminal output.  No readings from any of the sensors. 
On looking at the circuit board a couple of the wires had broken off.  Remember I mentioned my thing about not leaving enough space on the Raspberry Pi side of the stripboard.  

I again went to Twitter an got some some great advise from Alan O'Donohoe and Pete Lomas






You have to love the Raspberry Pi Community. Within a few hours I had exactly the advise I needed to get my project fixed perfectly.  But I had 1 day left and didn't leave enough room to do what they advised so I ignore their advice this time. Soldered the wires back on and crossed my fingers that it would all hold together.


On the day of the Jam the game was very popular.  Great write up from Richard Savill who is well worth following as he does some great Raspberry Pi projects and Kickstarters. With lots of kids and adults playing with it.  When a few kids gathered around the game they would just drop the ball straight in the cups to get the points and hear the sound effects.



Overall, I'm very happy with the final game.  The build is a bit rough around the edges but works great.  The code held up and the kids played it all afternoon which was the desired outcome.   I also had a number of conversations with adults and kids about the code and the electronics involved, so hopefully helped a few of them to learn something new and consider their own Raspberry Pi projects.







Sunday, January 17, 2016

Raspberry Pi SenseHat Game - sensecave

For Christmas I received a lovely Sense HAT from my in-laws. I gave my wife a list of items I would like to have and the Sense HAT was one of them.

The Sense HAT is a great little accessory for the Raspberry Pi.  It includes an 8x8 RGB LED matrix, a joystick and a great range of sensors
Gyroscope
Accelerometer
Magnetometer
Temperature
Barometric pressure
Humidity

With the Sense HAT I gave myself the goal of creating a game and also learning a bit about git/GitHub.  Up until now I have never used git for my projects and just pasted code into the blog posts (if I remembered) otherwise the code is gone forever.

To that here is the link the GitHub page: https://github.com/winkleink/sensecave.git

Thinking on the game I wanted it to be a bit more than an single 8x8 and be a decent challenge.
I was reminded of the old school text cave exploring games where you went from one room to another and decided I liked this idea.

The game is sensecave.
64 rooms in an 8x8 arrangement.  Not because the screen is 8x8, just because it looks like a decent size to play. To make things more interesting instead of all rooms being connected up to 10 entrance/exits are blocked off at random each time you play giving different paths through the maze.

With the cave and the rooms sorted there has to be a quest.
The quest is to find the 7 emeralds hidden in the cave and then get out of the cave.
Just like the walls the 7 emeralds are randomly scattered around the cave making the game different every time.

We now have a location, a challenge and a quest.
Finally we needed a control method.  For the Sense Hat there are two options. Either the small joystick that emulates the cursor keys, with the push button being RETURN or the gyroscope. Realistically there was only one choice it had to be the gyroscope.
Meaning you navigate from room to room and within a room by tilting you Raspberry Pi/Sense Hat.

I love this way of navigating as once you pick up the Pi and the players dot moves the control method is completely intuitive.

In the image below you can see one of the rooms in the cave.
Red dots are the wall with, in this instance exits on all sides.
Green dot is one of the emerald
Blue dot is you.



Each time you find an emerald the screen changes to tell you how many you have found.
After all 7 have been found you're directed to go the exit.  The exit is a white dot.

Once you have exited there is a nice congratulations message and a new maze if created to start all over again.

Some of the fun challenges in programming this game were.
The list for the individual cells/rooms is y,x while the co-ordinates for the players position on the is x,y (as it should be).  This required some mental gymnastics to remember which type I was modifying to get the right result.  A few events were less than productive because of this.

I wanted to store the details for each room in a single number, so I used bitwise data

For the rooms if a side is blocked off then the number included:

top = 128
right = 64
bottom = 32
left = 16

Meaning a room with all exists blocked would equal 240.
If the top and bottom exists were blocked the room would equal 192
Then using Boolean logic the code figured out where the wall were to go.

A diamond = 1, again a room with a diamond had 1 added to it's value.
Diamonds are always drawn in the same place in a room, so that was straightforward.

Finally the exist is always in the bottom right corner and if that room is the current one a white dot is place in the room.

Finally as it can even with 8x8 get a bit disorientating a dot is added to the corners of the corner rooms.  So, you'll know when you've hit a corner and not look for the route to get to the rooms beyond.

One of the goals for this game was to run it headless and the code I found before the Egham Jam on the 17th Jan 2016 used Pygame to access the joystick.  Unfortunately, I could not get Pygame to read the joystick (which is really a keyboard) if no display was attached.  Pygame used SDL and from my reading this expects a display to enable inputs.  So, for now the joystick is not used.  I did see an alternative method for reading the joystick not using Pygame and this will be the next stage...
I really want to add difficulty levels, variable maze sizes and also variable number of emeralds.
This could be a good way for someone the extend the code.

Here's a short video.  Not the best as the lighting was too bright.  It shows the player being controlled by tilting and going from room to room.  When I work out how to do a better video I will update.



Special thanks to the Foundation and specifically Dan Fisher for this game/tutorial that I used to understand how to read the gyroscope and also how to get pixles onto the Sense HAT https://www.raspberrypi.org/learning/sense-hat-marble-maze/




Saturday, July 4, 2015

Flappy Brain - Cambridge Jam Raspberry Pi project

At the last Egham Raspberry Jam I showed the Mindflex game EEG Brainwave reader (CNET article from when it was launched : http://www.cnet.com/uk/news/moving-objects-with-mattels-brainwave-reading-mindflex/) displaying bar graphs for the different brainwave signals.  It was interesting but served no real purpose other than to show the EEG was doing something. Even got a mention on the Linux Luddites Podcast (https://linuxluddites.com/shows/episode-41/)


So, for the Cambridge Raspberry Jam I wanted to get the EEG reader to be used for something.  I decided it had to be a single signal and immediately Flappy Birds came to mind.
Nice simple one button game.
Decision made I went about coding the game in Python on the Raspberry Pi.  I had already done the work to get the EEG

To hack the Mindflex and get it working with an Arduino I used this great guide and the code from the following article: http://frontiernerds.com/brain-hack.
This articles gives a lot of detailed background on the Mindflex and how it as well as lovely clear pictures showing where the TX and GND wires need to be attached.
For strain relief the article uses hot glue.  I wrapped the wires around the already in place knot so the wires could not be pulled no matter what.

The Processing code provided didn't work for me on the Raspberry Pi and that's the main reason I had to code up my own visualisation program.


The example I used to send the data is BrainSerialTest with one small modification. I commented out the following line as it caused the import and breaking out of the variable in Python to fail.  (Limit of my coding ability showing):
        Serial.println(brain.readErrors());

To read this from Python I had to install pyserial as it wasn't installed by default using the following commands.

apt-get update
apt-get install python-serial

You will have to use sudo for this. I left it out from the commands so that  you have to make the decision to run the commands

With the Mindflex hacked, and hooked to the Arduino and then sending it's data over serial I did the code to visualise the data.  Here is the Python code  I used on the Raspberry Pi for the last Egham Raspberry Jam

import serial
import pygame
# initialise pygame
pygame.init()

# Define the colors we will use in RGB format
black = [ 0, 0, 0]
white = [255,255,255]
red = [255, 0, 0]
blue = [0,0,255]
darkBlue = [0,0,128]
pink = [255,200,255]
green = [0,255,0]
orange = [255,102,0]
brown = [153,102,0]
yellow = [255,255,0]
purple = [128,0,128]

# Set the font for the text. Windows computer so usd Ariel

myfont = pygame.font.SysFont("OpenDyslexic", 18)


# Set the height and width of the screen
size=[800,600]
screen=pygame.display.set_mode(size)
# Fill the screen White
screen.fill(white)
# Put something in the application Bar
pygame.display.set_caption("Serial Mind reader")
pygame.display.update()

done = False
div = 2000
fatt = 20
fmed = 20
fdelta = 20
ftheta = 20
flalpha = 20
fhalpha = 20
flbeta = 20
fhbeta = 20
flgamma = 20
fhgamma = 20

ser = serial.Serial('/dev/ttyUSB0',9600)

# Clear the serial input buffer
ser.flushInput()

pygame.draw.rect(screen, white, (0,0,800,600), 0)
pygame.display.update()


while done == False:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done=True

    data = ser.readline()

    signal,att,med,delta,theta,lalpha,halpha,lbeta,hbeta,lgamma,hgamma = data.split(",")

    print signal
    print att
    print data


#  clear screen before putting new square on it 
    pygame.draw.rect(screen, white, (0,0,800,600), 0)
    pygame.display.update()


    fatt = int(att)
    fmed = int(med)
    fdelta = int(delta)
    ftheta = int(theta)
    flalpha = int(lalpha)
    fhalpha = int(halpha)
    flbeta = int(lbeta)
    fhbeta = int(hbeta)
    flgamma = int(lgamma)
    fhgamma = int(hgamma)

    pygame.draw.rect(screen, red, (1,600-(fatt*4),75,fatt*4), 0)
    pygame.draw.rect(screen, blue, (76,600-(fmed*4),75,fmed*4), 0)
    pygame.draw.rect(screen, pink, (152,600-(fdelta/div/2),75,(fdelta/div/2)), 0)
    pygame.draw.rect(screen, green, (227,600-(ftheta/div),75,(ftheta/div)), 0)
    pygame.draw.rect(screen, orange, (303,600-(flalpha/div),75,(flalpha/div)), 0)
    pygame.draw.rect(screen, darkBlue, (379,600-(fhalpha/div),75,(fhalpha/div)), 0)
    pygame.draw.rect(screen, brown, (455,600-(flbeta/div),75,(flbeta/div)), 0)
    pygame.draw.rect(screen, black, (531,600-(fhbeta/div),75,(fhbeta/div)), 0)
    pygame.draw.rect(screen, yellow, (607,600-(flgamma/div),75,(flgamma/div)), 0)
    pygame.draw.rect(screen, purple, (683,600-(fhgamma/div),75,(fhgamma/div)), 0)

    screen.blit(myfont.render("Attention",1,black), (4, 1))
    screen.blit(myfont.render("Mediation",1,black), (79, 1))
    screen.blit(myfont.render("Delta",1,black), (155, 1))
    screen.blit(myfont.render("Theta",1,black), (230, 1))
    screen.blit(myfont.render("Low Alpha",1,black), (306, 1))
    screen.blit(myfont.render("High Alpha",1,black), (382, 1))
    screen.blit(myfont.render("Low Beta",1,black), (458, 1))
    screen.blit(myfont.render("High Beta",1,black), (534, 1))
    screen.blit(myfont.render("Low Gamma",1,black), (610, 1))
    screen.blit(myfont.render("High Gamma",1,black), (686, 1))
# show the whole thing
    pygame.display.update()

pygame.quit ()


As a side note. I did a D&T day at my kids school where I used this code for a Year 1 demonstration. All the kids got to see their brainwaves bouncing around as they moves, did maths and recited poems.  It even went really flat when the kids closed their eyes and calmed down.   Some of the kids had to wait so long that they missed their morning break for the opportunity to see their brains waves bouncing around,

Next onto getting the Flappy Birds inspired game (for the purest you could say helicopter inspired) game working.
I thought myself to code in the 80's on a Commodore 64 and to be honest I haven't updated my skills since, so doing the same in Python was a new challenge for me.
Fortunately, I read an article in Linux Format Issue 112 from December 2008 that made a top down racer using Python and Pygame in 100 lines of code. http://www.linuxformat.com/includes/download.php?PDF=LXF112.tut_code.pdf
Yes, using a tutorial from over 7 years ago.  I may not be great at coding but I do hoard useful bits of knowledge.  I bought the Mindflex from eBay in September 2014 and did nothing with it until January.  Another bit of my electronics stash.

The Racer game if you think about it is the same but more complex than the Flappy Brain game with a few differences.
Racer scrolls vertically, Flappy  Brain scrolls horizontally.  That's just changing the value of the X variable instead of the Y variable
Then it's just change some of the graphics.

Once I figured out the Racer code I worked out the bits I could throw away and then bits I had to keep as well as worked out how to modify the code to do what I needed.

This took me a while to work through again due to a lack of knowledge or practice.

In the end I created the final game that was shown at the Cambridge Raspberry Jam.

Code Below:

from pygame import *
import random
import time
import serial

# set up the serial port
ser = serial.Serial('/dev/ttyUSB0',9600)

# Clear the serial input buffer
ser.flushInput()

# variables for colours 
black = [ 0, 0, 0]
white = [255,255,255]
red = [255, 0, 0]
blue = [0,0,255]
darkBlue = [0,0,128]
pink = [255,200,255]
green = [0,255,0]
orange = [255,102,0]
brown = [153,102,0]
yellow = [255,255,0]
purple = [128,0,128]

# gap in wall
gap  = 200

# width and height of screen 
width = 1000
height = 600
count_gap = int(height/gap)

# 0 = hard, 1 = easier, 2 is easiest
difficulty = 2

# class to create sprites and render them
class Sprite:
    def __init__(self,xpos,ypos,filename):
        self.x = xpos
        self.y = ypos
        self.bitmap = image.load(filename)
    def render(self):
        screen.blit(self.bitmap,(self.x,self.y))

# screen size
size=[width,height]
# initialise pygame
init()

# create the screen (window)
screen = display.set_mode(size)

# Caption to go at the top of the window
display.set_caption("Flappy EEG 2")

# set the music, its volume and start to play. -1 means infinite loop
mixer.music.load("Pinky_and_the_Brain.ogg")
mixer.music.set_volume(0.5)
mixer.music.play(-1)

# crreate sound for crash
crasheffect = mixer.Sound("ouch.ogg")


# fill the screen with blue, update the screen
# not really required but I like it
screen.fill(blue)
display.update()
#time.sleep(1)

# create the sprites for the brain, columns and the background image

playerbrain = Sprite(20,200,"brain_75.png")
column1 = Sprite(1200,100,"column1.png")
column2 = Sprite(1200,100,"column2.png")
background = Sprite(0,0,"background.png")

# set fonts for different purposes
scorefont = font.Font(None,60)
datafont = font.Font(None,20)
overfont = font.Font(None,100)

# set default values for some variables
score = 0
maxscore = 0
quit = 0
gameover = 0

# master loop for the program. If quit == 0 then exit program
while quit == 0:
# flush the serial port of all data to begin fresh
    ser.flushInput()

    gameover = 0

# set the height of top column
    column1.y = (random.randrange(0,(count_gap))*gap)-800

# set the height of the bottom column
    column2.y = column1.y + 800 + gap

# start of loop (using while) to move the columns

# start off screen to the right
    x = width +50

# x>-100 means still valid (yes there is a minus in there)
# gameover when collision
# quit selected. either pressed q or click x on window
    while x >-100 and gameover == 0 and quit == 0:

# increment the score and if higher than maxscore make maxscore = score
        score = score + 1
        if score > maxscore:
            maxscore = score

# update columns location and set x positions
        x = x - 50
        column1.x = x
        column2.x =x  

        data = ser.readline()
#        print data

        signal,att,med,delta,theta,lalpha,halpha,lbeta,hbeta,lgamma,hgamma = data.split(",")

        print "signal: " + signal
        print "attention: " + att
        print "data: " + data
        intatt = int(att)
        if intatt > 90:
            intatt = 90   
        brainpos = intatt * 6
# set brain location based att (attention)

# is intatt near the gap above 
        if brainpos < column1.y +800 and brainpos > column1.y + 800 - (difficulty * 10):
            playerbrain.y = column1.y +800 +70
            print "brain near top and moved down!"
# is intatt near gap bottom
        elif brainpos > column2.y-75 and brainpos < column2.y + (difficulty * 10):
            playerbrain.y = column1.y +800 +70
            print "brain near bottom and moved up!"

        else:
            playerbrain.y = brainpos
            print "brain where is should be"


#        print playerbrain.y
        background.render()
        playerbrain.render()
        column1.render()
        column2.render() 

# display some information on screen
        screen.blit(scorefont.render("Score: "+ str(score),1,white), (100, 5))
        screen.blit(scorefont.render("High Score: "+ str(maxscore),1,white), (400, 5))

        screen.blit(datafont.render("signal: "+ signal,1,white), (5, 570))
        screen.blit(datafont.render("attention: "+ att,1,white), (150, 570))

        screen.blit(datafont.render("playerbrain.y: "+ str(brainpos),1,white), (250, 570))
        screen.blit(datafont.render("column1.y: "+ str(column1.y+800),1,white), (500, 570))
        screen.blit(datafont.render("difficulty: "+ str(difficulty),1,white), (650, 570))

        display.update()

#        print playerbrain.y

# collision dection
        if ((playerbrain.y < column1.y+801 or playerbrain.y > column2.y-74) and (x <150 and x > 20)):
            mixer.music.stop()
            mixer.Sound.play(crasheffect)
            print "BUMP"
            gameover = 1

# check if clicked x on window to exit 
        for ourevent in event.get():
            if ourevent.type == QUIT:
                quit = 1

# has key been pressed. K_q is to quit 
            if ourevent.type == KEYDOWN:
                if ourevent.key == K_DOWN:
                    playerbrain.y = playerbrain.y+10

                if ourevent.key == K_UP:
                    playerbrain.y = playerbrain.y-10

                if ourevent.key == K_q:
                    quit = 1 

# if game over show message
    while gameover == 1 and quit == 0:
        screen.blit(overfont.render("GAME OVER",1,yellow), (380, 260))
        display.update()

# then wait for a key to pressed  before starting again
        for ourevent in event.get():
            if ourevent.type == KEYDOWN:
                if ourevent.key == K_0:
                    difficulty = 0
                    score = 0
                    gameover = 0
                    mixer.music.play(-1)

                if ourevent.key == K_1:
                    difficulty = 1
                    score = 0
                    gameover = 0
                    mixer.music.play(-1)

                if ourevent.key == K_2:
                    difficulty = 2
                    score = 0
                    gameover = 0
                    mixer.music.play(-1)

                if ourevent.key == K_SPACE:
                    score = 0
                    gameover = 0
                    mixer.music.play(-1)

                if ourevent.key == K_q:
                    quit = 1 
                    score = 0
                    gameover = 0


The sharp eyed amongst you will recognise the bits taken from the Racer game and the bits taken from the original visualisation code I create.

I added the ability to Quit the game by pressing 'q' and also 3 difficulty levels. On the Game Over screen press 1, 2, or 3 with the higher number being easier.
It does this by widening the readings that will get you through the gap.

At the Cambridge Raspberry Jam I had the pleasure of meeting Alex Eames who brought us to HDMIPi and also the RasPi IO Duino which was another successful Kickstarter and is now for general sale.  Alex did a great video which you can see below.



Following this the project was picked up by the Raspberry Pi Foundation and featured on their Blog (https://www.raspberrypi.org/flappy-brain/) and most recently was featured as The MagPi Magazine Issue 35 in their Amazing Pi Projects List (https://www.raspberrypi.org/magpi/)
The MagPi magazine is a a resource for everybody with a Raspberry Pi. It includes articles, project details and tutorials in everything from Scratch, to Python and C++ and has software and hardware projects.  Also, they announced recently that it is going to become a physical magazine soon and be available to buy in shops as well as the current PDF download and acces through the Apple App Store and Google Play stores.

It's been a fun few months and to me is an example of what can be done if you take advantage of the resources out there if you have idea.  For this project I used some great code and guide to hack the Mindflex.  Code from a 2008 Linux Format article and some previous work I did to figure out how to read serial data on the Raspberry Pi.

I will be bringing Flappy Brain to the next Egham Raspberry Jam. It is on the 12th of July 2015 and as always is free to attend.  All that's required is to register beforehand on the Eventbrite page.
http://eghamjam8.eventbrite.com

Maybe I'll see you there.