Showing posts with label pygame. Show all posts
Showing posts with label pygame. Show all posts

Thursday, November 9, 2017

White Wii Nunchuck shaped Bluetooth Joystick - £1.85/£1.99 on eBay

When I attended PiWars (a great event for people who like to build robots using the Raspberry Pi) earlier this year I saw a whole range of controllers being used for controlling Raspberry Pi based robots. With many using USB dongle ones and others using Bluetooth or even apps on phones.  Expecting to see some BlueDot next year a great Android App for controlling things over Bluetooth.

Since my phone is iPhone (too long to explain) BlueDot isn't an option for me and with my continuing goal of finding cheap solutions to a problem I found a £1.85 Bluetooth controller from eBay - 3D Bluetooth Virtual Reality Glasses VR BOX Game Remote Control Gamepad Handles

What I liked about it is that it uses AAA batteries so if at an event the batteries died I could swap them out. No need to wait for recharging.

It's billed as being for mobile gaming and virtual reality and no mention of working with a regular computer or even Raspberry Pi, so I took a punt for £1.85, well actually £3.70, as I bought two. (walking on the wild side). 

eBay order confirmation

NOTE: The listing I bought from has ended but the same seller has a new listing at £1.99

I've seen some similar listing with switches on the side.  This is not the model I have bought. Mine has no switch.


What it looks like on eBay listing

They arrived and actually look good.  Plastic is definitely cheap, but they don't feel flimsy.
Below are a couple of pictures of the real thing.  A little different to the render but I'm happy..

Top. Joystick, power button, mode change button and 4 facing buttons.

Front has 2 additional buttons for when held straight rather than sideways
Time to start testing.

Setting up a new Raspbian image and using Raspberry Pi ZeroW I added the two AAA batteries and it came on. Blue light flashes to say ready to pair.

Using the Bluetooth Add Device in Raspbian the device VR BOX was found and paired successfully.  The unusal name actuallymakes sense as the listing on eBay is for "3D Bluetooth Virtual Reality Glasses VR BOX Game Remote Control Gamepad Handles"


Bluetooth on Raspbian paired with VR BOX

From the eBay listing and the single sheet of instructions the Gamepad/Nunchuck has 4 modes that you select with a combination of the @ and the relevant button.

A : Function Select (Music Video Mode.)
B : Function Select (game mode)
C : Function Selection (VR video self-timer mode.)
D : Function Select (mouse self-timer mode.)

It starts up in Music mode, so to use as a gamepad you have to change this after it pairs.

As I wanted to test in game mode I did [@]+[B]

I previously created a small python/pygame program to help with the testing.  It's available on GitHub.

I downloaded it to the PiZeroW (one of these days I'll do the proper git clone thing) and ran the program.
I run from the command line as the terminal window prints the details in text while the pygame window gives a graphic representation of the gamepad so I can see if multiple button presses are possible and which button numbers are pressed.  The code includes an analogue joystick so it will show the full range of movement for the gamepad joystick.


python2/pygame gamepad tester

Pressing the buttons the appropriate red square appeared and the terminal window stated which button was pressed or released.  Success! It's being detected as a gamepad and the buttons are working.

I then used the joystick which looks like an analogue stick you see on many projects. Only it's not. The joystick is digital.  Up, Down,Left,Right.  No range in values.  Except for a strange thing.
The positive values are 0.999969482422 and the negative values are -1, so you can't test for 1 for down and right when in gamepad (sideways) mode as 0.999969482422 is not 1. A little gotcha for coding.

The different modes

As listed above there are 4 different modes for the controller.

[@]+[A] for music
Nothing happened on the Pi. I haven't figured out what Bluetooth Music Mode is yet.
I tried this mode with my phone and it does provide volume up/down, mute an play so does what is expected with the target device.

[@]+[B] game mode
This is gamepad in horizontal mode, like a traditional controller with the joystick on the left and the buttons on the right.
For example, if you push up the Up joystick is detected

[@]+[C] VR video self-timer mode
This is a gamepad in Nunchuck mode. So vertical.
For example, if you have the controller held vertically and press up then Up Joystick is detected.

All the buttons are the same as for game mode.

[@]+[D] mouse self-timer mode
Guess what the joystick operates like a mouse held like a Nunchuch (vertical) with the lower front button (trigger) being left click and the higher front button (trigger) being right click.
In mouse mode buttons A and B still get recognised as gamepad buttons so that could be useful.Not sure how or when but extra buttons are always useful. 

Button combinations

In game mode some of the buttons could be pressed at the same time while others could not.

@ and Power are reserved so have no button function.

Bottom trigger and top trigger could not be pressed at the same time. Lower trigger always took priority even if upper was pressed first.

Bottom trigger could be pressed with any of the face bottoms (A,B,C,D). Same for Top Trigger.

A could be pressed with C, but not B or D. A stays active and the others do not show.
If you press B or D first and then press A, A will be activated and the other will be released.

B and C can be pressed at the same time

D is over ridden by all face buttons, so if you have D pressed and then press any of the other their function is activated and D is released.

Also, either trigger and two button face combinations that were noted to work above will also work.
So, if you need 2 buttons at the same time and one is the master and the second one needs to be one of 4 I'd recommend using a trigger as the master and the face buttons as the secondary as this works for all face buttons.
If you need 3 buttons then there are a small number of combinations that will work.
Top button, A and C worked for me.

Future Note: I have a feeling this section may need a chart of some nature. Need to figure out how to represent it.

For Python/Pygame and I expect other system the buttons are numbered:

Gamepad Mode


Face button arrangement
  A 
C   D
  B


Top Trigger: button 7
Bottom Trigger: button 6
A: button 4
B: button 0
C: button 3
D: button 1

VR mode (Nunchuck)

Face button arrangement
  C
B   A
  D

Top Trigger: button 7
Bottom Trigger: button 6
A: button 1
B: button 3
C: button 0
D: button 4

When I saw it changed I thought the button values would have turned clockwise 90 degrees so the buttons were in the same position (top, left, right, bottom) would have the same values but they don't. Top and bottom shift correctly, but left and right are mirrored.

Where did 2 and 5 go.  I wonder if they're on the board and not broken out. Might be a tear down thing


Summary

For £1.85, or £1.99, last time I checked if your need is digital controls then I think this is a hit.  It paired easily. The instructions though really sparse are enough to change modes.
With a phone it does the media things promised from mode A and on the Raspberry Pi and expect and device that supports a Bluetooth Gamepad and Mouse it does exactly what it says on the tin.

For controlling robots it's ideal (except for no analog).
Joystick for direction control and then buttons for other functions. Maybe take a picture, fire a missile, change mode from piloted to auto mode for different challenges at an event like PiWars.
With the advantage of using regular AAA batteries there is no fear that at an even the controller will run out of power and need to be charged.


A little but extra

As each controller having a unique Bluetooth Device ID it's possible to set up a cronjob on Linux to  pair with a specific gamepad when the Raspberry Pi (ZeroW) is booted/rebooted so  at events if you had 5 robots, 5 controllers each controller would be set up to work with a specific controller
It's not too complicated to do.

Get the device ID for the VR Box using the command bluetoothctl
Mine was FF:FF:70:00:76:8B

Run crontab -e
Select your editor if running for the first time. I use Nano

Go to the end and add the line
@reboot echo "connect FF:FF:70:00:76:8B" | bluetoothctl

If using Nano do a [ctrl]-[x] to exist and 'y' to save.
Reboot an you're done.

This will try to auto pair when the Pi boots.

You can also do a cronjob to continuously try to reconnect and not just at boot.
This is useful if the Pi has completed booting before the gampad has been turned on or if the controller hasn't been used for 10 minutes or in pairing mode fails to pair after 3 minutes and so needs to repair when the controller is turned back on


















Thursday, February 16, 2017

Green Screen photo booth using Raspberry Pi

We've seen a number of photo booths herehere and even the All Seeing Pi being done with Raspberry Pi. All of these photo booths are based on taking a picture and maybe putting an overlay to add a banner or something like a funny hat or mustache.

My thoughts were could the Raspberry Pi 3 do Green Screen.  You know that special effect from the movies where the background is removed and a different image put in it's place.

As a kid I think the first time I remember seeing this was Superman.


How cool would that be to make your own version of the special effects used in big budget movies.

So, I started the search for tools under Linux that would permit the green screen to be done.
As a short summary green screen/chroma key is where a a single colour is removed from an image.
Most often it is green as modern cameras are more sensitive to green and a bright green works best as it's less likely to be a colour in a natural scene.  I remember when I was younger hearing it being done with blue screen as well.  


After a bit of looking I found Imagemagick a jack of all trades image processing tool.  It has a function to remove a single colour from an image and as importantly for my use includes a 'fuzzy' search for the colour which gave a bit of tolerance to the lighting.  

In the code the most important line is:
os.system('/usr/bin/convert -limit thread 4 ' + folder +'imagecam.png -fuzz '+fuzzpercent+' -transparent "#'+rgbnum +' " ' + folder + 'imagecamt.png')
I know there is a lot going on in there.  She short version is it takes imagescam.png, makes transparent the colour rgbnum with a tolerance of fuzzpercent and saves it as imagecamt.png

This forum thread was really useful in understanding how to use it.

Once I had my head around this it was then a matter of doing the rest of the code.
Take the picture
Remove the green
Layer a background and the image with the green removed. 
For testing I used some of my kids PlayMobil and a piece of A0 green card.  


All looks like it's working well even with the ability to change the background using the arrow keys

Now for the next level.
Scale it Up to Life Size !!!!

This of course means I needed a green screen background with standard that I bought from eBay.  No idea when I'll use the black or  white backgrounds that came with this kit, but I have them now.

And then Tweet the pictures.
For Tweeting I used tweepy and followed the excellent guide by Alex Eames @RasPiTV 

Finally, wouldn't it be great to have a little remote control and not have to rely on a keyboard.  Since the Raspberry Pi 3 has Bluetooth I thought this might be the ideal solution.  No wires and no messing about.  Since Pygame was already being used for the displaying of the images and I knew Pygame had joystick support built in this looked like the obvious choice.

Again, on eBay I found this small little Bluetooth gamepad and thought it would be perfect.  Super small which means you can have it in your hand but not interfere with your final picture.

Iddy biddy, teeny weeny, black gamepad 

My usual style is before bring a new feature into a project I like to test it standalone to make sure it works.  For the gamepad I created a small Python/Pygame program to test the gamepad 

It paired with the Raspberry Pi first time and worked perfectly with the gamepad test program.  So, 100% sure it will function with the chromaCam setup.

Now all the parts are in place.  PiCamera to take the picture.  Imagemagick to remove the background colour.  Pygame to merge background, foreground picture with green removed and finally an overlay with the background images changed with the keyboard or the super small gamepad.  (Oh yeah, the circular thing at the bottom is an analogue joystick)

The chromaCam set up got it's outing at the last Wimbledon Raspberry Jam.  Here are some pictures.
On the day I used a camera tripod and a lot of tie wraps to hold the Pi Display and the Pi Camera onto the tripod. I would definitely recommend a more secure mounting method 

Getting set up https://twitter.com/MrTomsWorld

Who doesn't love a bit of Harry Potter - https://twitter.com/rdhayler


Those Lions are dangerous

That doesn't look like a sensible thing to do - https://twitter.com/HackHorsham

Final notes.
If you did click the link above that explains Chroma Key/Green Screen then you'll have read that lighting is really important.  The goal is to one specific colour. If your lighting is uneven then due to shadows or folds in the green screen the green will be different giving varying results.
Taking out too much - https://twitter.com/Codepope

I'm sure the top of the Raspberry Pi logo isn't transparent


A few bits of rogue green - https://twitter.com/gowolade

If you want to make your own Green Screen Photo Booth then the code is available on GitHub


Final Thoughts:
Yes, this project worked and was great fun to build and see people using it.
For the project I limited the image size to 640x480 as even at that resolution it took about 2 seconds for the picture to be updated.  This meant it took a little bit of patients to get the picture you wanted before pressing the button to Tweet the image.

I took the set up to Hack Horsham as well but I didn't bring my own lighting and the lighting in the room was perfect for a Jam but didn't give enough contrast for chromaCam to work.  So, it didn't make the final cut and I stuck to Button Flash.

You can see the setup in the mannequin challenge video tweet. 



Again, this was a great learning experience for me and once the computing power for the Raspberry Pi enables it or access to the GPU is supported this will be amazing when the green screen transparency can be done in real time.  
I expect as new devices come out I'll be revisiting this project to see if the performance is improved. 



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.





Wednesday, June 22, 2016

Spider Chart maker using Python and Pygame

16th May 2017 - Updated to make the output an A4 landscape page.
Also, provided Inkscape created SVG file so you can prepare you can add your own School or Club name.  Make sure the final PNG resolution for __spider.png is 3508 x 2481 as the dot locations are hand coded for the spider to be in the location it is on this size of image.

Example of improved chart.



A few days ago a call went on out on Twitter for how to make lots of Spider Charts, also known as Radar charts in a programmatic way.  I decided to take up the challenge.


The code and associated files are available to download from GitHub

Below is a sample completed chart

To do this I started with a blank version of the chart and added the person name top left and the red dots and lines for the individual scores.

The program is written using Python and Pygame and was developed on the Raspberry Pi.
Since it doesn't use any other external libraries I'd expect it to work on other systems with Pygame installed.

To achieve this 2 external CSV files and a large (3508 x 2481) blank chart image are used.

The image file is: __spider.png

spider_data_points.csv is a comma separated variable list of the co-ordinates on the 3508 x 2481 image for the individual points.  By using a separate lookup if this was to be adapted to a different chart then you can just use a new master image and a different set of co-ordinates.

Student_Scores.csv is the file with the individual student (in this case) names and scores for the different skills.  There is no limit to the number of students that can have charts created as the code just goes through the csv line by line and creates a chart for each one.

Rather than creating the csv files manually it is so much easier to use a spreadsheet for data entry and then [Save As] a .csv
To facilitate this I've include .xlsx versions of the files.
These can be open and saved on the Raspberry Pi using OpenOffice.

Meaning if you needed to make 100 of these charts it would be a simple matter of:
Place all the code in a single directory
Enter the data in the spreadsheet.
Save as a .csv
execute spiderchart.py
Watch as all the charts are created automatically with the student name as the filename

Don't worry if the image is mainly off screen it is still being done correctly.

In the code there is a 1 second sleep after each chart is created. If you are doing lots then it might be worth commenting out the sleep.  It's useful for seeing what's going on.

As a complete side note: I was one of the backers of the Indiegogo pi-topCEED an All-in-One form factor for a Raspberry Pi desktop and it was delivered and set up on Monday.  It came with a Raspberry Pi 3.  This was the set up I used to develop and run the code.  I was very impressed by the quality of the 14" screen on the CEED.  This is now set up as the permanent home computer that my kids can use for playing Minecraft and exploring the CEEDuniverse, a game that teaches you about computers, coding and electronics.

Tuesday, March 29, 2016

Testing Gamepad on Raspberry Pi using Pygame

I bought a really small Bluetooth gamepad/media remote on eBay and needed a small program to test the gamepad buttons on the Raspberry Pi 3 once I set up Bluetooth.

So I created a short pyton program using Pygame.
It's available to donwload from GitHub.
https://github.com/winkleink/pygame_test_gamepad




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.