Tuesday, August 23, 2016

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

UPDATE: 25th August:
Made Raspberry Pi program look prettier
Added sound effects
Use the GitHub link to get the latest code: https://github.com/winkleink/buttonFlash

A few years ago I thought it would be fun to come up with an outdoor game that would get the kids running around and the 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 has been done by +ForToffee on a big Raspberry Pi.
Here are the build instructions and videos. https://fortoffee.org.uk/2016/03/whack-a-pi/

Here's a video of it being played at the Raspberry Pi 4th Party.


The concept for Button Flash is similar to Whack a Pi but with the ability for the buttons to be much further apart.  Goal is to get the kids 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 would really mess with the high score if people were falling.  So, it needed to be wireless.  

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

VoCore.  Basically guts of a Wifi router

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

NRF24L01

As I mentioned these things are super cheap.  This current UK eBay listing is for five NRF24L01 for £5.99
Also, they 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, shared his working code. 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 has the Raspberry Pi communicating with the Arduinos.
Below are the steps I took to get it all working.

Depending on which example you look at the pins used can be a bit different but they rarely give details on which pin is which making it difficult to figure out how to adapt one example to your needed.  Therefore, below is the wiring I used for the Raspberry Pi and the Arduino with the code provided. 

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 used 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 based 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 buts 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 a 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 is always be at least 2 Arduino) replies that it is completed.
In fairness 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 no 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.

Final thing is to copy the Raspberry Pi code into the buttonFlash directory and run it with

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.



I mentioned above for the Button/Arduino I needed a tube to put them in.  I thought I found the perfect one when I got this 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 more would be coming in.  Then I saw these tubes and tried it out and it worked.  Pringles tubes for the win.



Oh, and I had to eat another 4 tubes of Pringles to get the 5 needed.  



The last need was to stake them to the ground.  I went super simple and bout 150mm bolts with nuts and passed them through the bottom of the Pringles tins.  You'll noticed I numbered each tube and there is also a colour listed.  I bought 5 different coloured breadboards so I could tell which was Button/Arduino was in each tube.  
You can see the bottoms of the tubes are deformed.  Ends up Pringles tubes 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 tube
 The next time I have it out I will get a video of some actually playing the game.

If you have any questions or comments let me know.





Monday, August 22, 2016

eBay USB soldering iron in use


Sometimes I've to do a little bit of soldering.  Usually only a few wires and since at present I have no place to leave an iron set up permanently this requires for me to either unpack my rework station or even just a simple mains powered soldering iron.
Even doing this has resulted in me pushing back soldering jobs as the extra time for setup
 as a ratio against actual build time doesn't feel like time well spent.

Then on eBay UK I came across a listing for USB soldering iron for £3.39


Since my electronics is usually tied to an Arduino or Raspberry Pi project I will have a computer up and running and I thought for less than £4.00 including shipped from Hong Kong it was worth a punt.
Well, it arrived this week and as per the picture it includes the soldering iron with a plastic cover for the top.  A USB to 3.5mm jack for power.  A really small stand made from a folded piece of metal with a bit taken out and just enough solder to know it's working.  Actually I soldered about 30 wires using the solder provided and have a bit left over.  Still you'll need to get some solder.

First impressions were positive.  Packed in a proper retail packaging box and not just a jiffy bag like many cheap things on eBay from Hong Kong.

The iron heated up quickly and has a red LED to let you know it's on.
It was definitely hot enough to melt the solder and do the job I required.
Since the original outing I have used it again to replace some current limiting resistors for 5 LEDs in a project I'm working on.  Again all worked great.

As I've only used it twice I can't speak for the long term reliability but from first impressions it is well worth the £3.39 it cost me.

The only things I would change are:
I would have liked the power to be microUSB and not 3.5mm jack.  I've loads of microUSB cables but this is my only USB-3.5mm cable.  If I lose it I'll have to get a new kit. Probably not a disaster at £3.39 and then I'd have a backup.

The tip on the iron is a needle tip. My personal preference is a bevel tip. The ones where it's like they cut a diagonal slice off a flat tip.
Here is a nice instructable explaining the different tips. My preference is called a C series tip in the guide.   Rarely do really fine work and even then a bevel can still be used quite well for most things.

Saying all this for less than £4.00 it feels nice to use and means I can set up, do the rework and pack away in minutes. Which is ideal when only soldering a few wires at any one time.

UPDATE: after posting this I was sent a link to a great video by bigclivedotcom where he tests, tearsdown  reverse engineers the circuit diagram.  Let's just say his review is way better than mine.
Here's the video.



Tuesday, July 19, 2016

Toy crane controlled from Raspberry Pi Zero with SenseHat using Scratch


Since the micro:bit was launched one of the demos that I kept seeing was the toy crane controlled using the motion sensing in the micro:bit.  The kids loved it and was very interactive.

Since the SenseHat on the Raspberry Pi has the motion sensors built in I thought this would a good project for a Raspberry Jam.

So, off I went to Home Bargains and bought a crane. From the picture, definitely the right age for me.  This crane is normally controlled using two levers on the hand controller. It can rotate and raise/lower the bucket.

Didn't come with the hard hat
First order of business was to figure out the wiring and cut the cable as the final build would be battery powered to work the same as the micro:bit version.


Cut the red wire

From above the wiring is:
VCC - Red wire
GND - Brown wire (not black)

Rotate motor 
Orange and Yellow

Crane lift motor
Blue and Green.

For turning and crane the direction it goes depends on how you wire it up and how your code works so some adjusting may be needed later.

To make sure I had this right I tested by touching Red to Orange and Brown to Yellow. Crane rotated one way. Swapped wires around and crane rotated the other way.
Red to Blue and Brown to Green, Bucket went down. Swapped wires around and bucket went up.

Wiring confirmed and tested.

As the Raspberry Pi isn't designed to control motors directly I needed a small motor controller.
The L9110s looked perfect for the job. Smaller than the L298N that I usually use so would be easier to accommodate in the final box.

L9110s motor controller
The 2 terminal blocks on the left in the image are for the motors.
On the right are the control pins and power.
Top 2 connections are control for Motor A
Bottom 2 connections are control for Motor B
Then in the middle are VCC and GND

NOTE: A really important thing is to make sure when using multiple boards that all the GND lines are tied together so that all the voltages have the same base reference.  Otherwise strange things can happen.

I wired up the motors. Turning uses GPIO 5 and GPIO 6 on the Raspberry Pi and Motor B on the L9110s while lifting uses GPIO 27 and GPIO 17 and Motor A.

Again did some simple code to see if it would work from Scratch. Initially manually moving with the keyboard.  It worked great and I brought it along to the Egham Jam in April 2016.  As the organiser of the Jam I was a bit delinquent in taking pictures so the only one I have is of the crane, bottom left in the booth of the car before I went to the event. I promise the kids loved it and it was a massive hit, really. Actually, I had a different project called ZeroBall that was finished so it took most of my time.

Bottom leftis the crane
There were two technical reason I didn't have it all set up with motion sensing and coded in Scratch for the Jam.

  1. The SenseHat covers all the GPIO pins meaning I couldn't get at the pins to attach the wires for the motor controller.  So, I could get the readings from the SenseHat but couldn't control the motors.
  2. The Scratch at the time had a problem whereby it didn't support AddOn board. 


The first problem was solved with Stacking Headers and great tutorial from Keith's Pi Tutorials even has a video.
Also, a great reference site for Raspberry Pi board pin usage is pinout.xyz.  They have loads of boards listed and this is where I got the details for the pins used on the SenseHat

Stackable Headers. Note the high tech blutac for holding it all in the tub


The second problem of Scratch not working at all with AddOn boards was reported and fixed in the May 2016 Raspbian update.

With the purchase of Stackable Headers from The Pi Hut and a freshly imaged SD card both of these technical problems were overcome and the way forward was sorted for the SenseHat to be used to control the crane.

Since I wanted it to be battery powered the Raspberry Pi Zero was the obvious choice as it is low power. Only thing is Scratch is a GUI program and so I needed a desktop environment to run it (If you can run Scratch code without a GUI I'd love to know, but I suspect it kind of defeats the purpose of a drag and drop interface if you run it from the command line)

To overcome this I used a USB wifi dongle to connect over the network to the PiZero and then on a laptop used RealVNC to get a desktop. Since this was going to be shown at the first Wimbledon Raspberry Jam I didn't know if I would have a wifi network to connect to so I brought my own in the shape of a VoCore. A one inch cubed wireless router running openWRT.  I backed this as a crowdfunding thing a while back and all I've used it for it to create a local wifi hotspot.  At the Jams I can even power it from a powered Raspberry Pi USB port.

Side Notes:
I think the number is the manufacturing order of the original batch and I've never seen one with a number lower than 26.
The VoCore is only the top layer. The rest is an add-on that gives you USB, Ethernet, microUSB power socket and a microSD slot.  IT also has it's own GPIO pins so can be used for embedded projects.

Vocore. Basically, the guts of a wifi router
Obviously, as this was going to be standalone it had to be battery powered. I'd been picking up these 18650 Lithium Ion batteries in Poundworld and thought 4 of these in a case would make a decent power supply for the day.  No idea why when I cracked them open one was pink.  The battery case was from eBay and it all snapped together really easily.
The case has 2 USB ports for power so could power the Raspberry Pi and the VoCore at the same time.

Batteries in their original cases

Batteries in their new case


I mentioned above that all the Grounds need to be tied together.  In this instance I have 3 circuits that need to all have the same GND. Crane, L9110s and Raspberry Pi Zero (The SenseHat is take care of through the Pi Zero)
I tied the Crane GND (Brown wire directly to Pin 39 on the Raspberry Pi, then the GND pin on the L9110s was tied to Pin 6 on the Raspberry Pi.  In this way all 3 had a common GND.

It's good to be aware that in a circuit all GND can usually be treated as the same point. Especially for such low power and low frequency signals.  If this was a high power high frequency circuit then the trace length between the different GND points could case harmonics.  I cannot think of a project using the Pi that I would do where the length of the trace between GND pins would be a problem


So, now I have power, local network, a way to run Scratch so people can see the code and all the bits wired up. Last of all was the actual Scratch code.

From the image you'll see the code isn't very complex.  The main thing I'd to figure out was which one of the sensors I needed to read. It's the Accelerometer.
I believe the range is -4095 to + 4095 on each axis.
When the program is run a base "flat' reading for Lifter and Turning is taken so any movement in the sensor doesn't carry from one person to the next.  This is what the middle block of code does.
The block of code on the right is there if it all goes wrong and I can just press [space] to turn off the motors.

Th middle block is where the magic happens.  It checks if Accelerometer X is 1000 less or 1000 more than the flat reading for Lifter and/or Turning and then activates the appropriate motor to either turn the crane or raise/lower the bucket.

Not shown below is a second costume for the crane that just says "Put Pi on a flat surface" at the start of the calibration.


If you're not up for trying to copy the code from the image you can download the Scratch code from GitHub.

To make it hand held I stuffed all the bits in to a plastic Chinese takeaway box.  You can see the L9110s on the left, wifi dongle on a short microUSD to USB cable and the SenseHat with the Stackable Headers so the wires for the motor controller can could be added.

Finally, here is a boy totally engrossed in playing with the crane at the Wimbledon Jam.  It all ended really well.

Hours of fun transporting monkey from one place to another