Showing posts with label Sense HAT. Show all posts
Showing posts with label Sense HAT. Show all posts

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, 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









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/