Sand Bucket, Pokitto join micro:bit

Some time ago I purchase a micro:bit for about 15€.

It’s a fun little device packed with sensors and a 5x5 led matrix. You can program it in many ways, the fastest is using a web ide MakeCode where you can choose between JavaScript, Python and “Block” programming. The first time you access the online IDE it is stored in the browser cache, so you can compile and download even without internet connection. The library provided is clear and allow direct to access all resources in a easy way. Lot of examples and well documented.

I start thinking on a nice project or demo and so I took inspiration from that Falling-sand game like The Powder Toy or many others of the genre:

image

The idea is quite simple: micro:bit will send the accelerometer trough serial interface and Pokitto will take care of drawing and simulate the grains of sand.
Both device run at 3.3V DC and soon it came the idea to feed power to the micro:bit via the PEX.
As reported here Pokitto can deliver up to 200mA @ 3.3V safety while micro:bit, which can be feed in various way, require 30mA. The more direct way is trough the edge connector even if is the less safe as it is not protected by over voltage or reverse polarity. It’s risky but with some precaution it works!
Beware to not connect the micro:bit usb connector to a power source when power is already provided by Pokitto. Is never a good thing connect two voltage regulator in parallel.

As a side note the IO connection of the micro:bit is the worst aspect I’ve found in the product. The edge connector is designed to be used with crocodile clips for only 3 pins (plus power supply), all the others need some kind of adapter to a more canonical pin headers.

My actual wiring is an homemade solution that just work. The project require only 3 connection 0V, 3.3V and Tx from micro:bit to Rx on Pokitto. All PEX connection are accessible here on Pokitto web site.

Theory


Practice
|

Code on micro:bit is quite minimal:

Same as JS

serial.redirect(
SerialPin.P0,
SerialPin.P1,
BaudRate.BaudRate115200
)
basic.forever(function () {
    led.toggle(2, 2)
    serial.writeLine("x" + ("" + input.acceleration(Dimension.X)) +
     "y" + ("" + input.acceleration(Dimension.Y)) +
      "z" + ("" + input.acceleration(Dimension.Z)) + "#")
})

Or if you feel more Pythonic ( :wink: @Hanski)


serial.redirect(SerialPin.P0, SerialPin.P1, BaudRate.BAUD_RATE115200)

def on_forever():
    led.toggle(2, 2)
    serial.write_line("x" + ("" + str(input.acceleration(Dimension.X))) +
     "y" + ("" + str(input.acceleration(Dimension.Y))) +
      "z" + ("" + str(input.acceleration(Dimension.Z))) + "#")
basic.forever(on_forever)

So simply read the sensor and stream to the serial port, with serial pins redirected to P0 and P1 instead of USB. You can see the output and simulate the inclination of the board from the IDE:

Our output will be something like: x240y-277z-956# with carriage return and line feed appended at the end. So far so good.

Let’s move to the Pokitto!
Here I choose to use C/C++ and FemtoIde as IDE. We have two task to complete:

  1. Read and parse the string coming from micro:bit
  2. Simulate the sand grains according to gravity acceleration

Serial read is embedded in mbed framework (pun intended) so we can use the Serial API present on OS2 (the vintage mbed release we are using).
Basically we monitor when the serial have some character(byte) to read, then we read it and put into a buffer (at least as big as our full string). When terminating char is read (’\n’ = Line Feed = 10 (decimal) = 0x0A (hexadecimal) ) we terminate out string with a ‘\0’ and try to parse the whole line using sscanf that I didn’t know but seems to be the perfect match to parse strings in C. Serial allow to be attached to an hardware interrupt, that mean every time something arrive in the input pin a specific portion of code is called. That way we can ensure any incoming data is managed regardless the actual load on the CPU.

void Rx_interrupt() {
    while (ser.readable()) {
        char byteIn = ser.getc();
        serialInBuffer[serialCount] = byteIn; // store the character
        if (serialCount < MAX_SERIAL_BUFFER) // increase the counter.
            serialCount++;
        if ((byteIn == '\n')) { // if an end of line is found
            serialInBuffer[serialCount] == '\0'; // null terminate the input
            int x, y, z;
            if (sscanf(serialInBuffer, "x%dy%dz%d#\r\n", & x, & y, & z) == 3) { // managed to read all 3 values
                //Shift array to the right
                for (int i = AVARAGES - 2; i >= 0; i--) {
                    accelerometer[0][i + 1] = accelerometer[0][i];
                    accelerometer[1][i + 1] = accelerometer[1][i];
                    accelerometer[2][i + 1] = accelerometer[2][i];
                }
                accelerometer[0][0] = x;
                accelerometer[1][0] = y;
                accelerometer[2][0] = z;
            }
            serialCount = 0; // reset the buffer
        }
    }
}

We are storing the accelerometers values in an array to calculate an average later and so reduce some spikes reading from the sensor.

While looking for some examples on dust simulation I found that Adafuit have a nice library for exactly the things I need. They call it Pixel Dust and it’s tailored to work with both Arduino micro controllers and more powerfull device like RPI. At the same time is quite generic and written in C++ with practically no external dependencies.
But instead of use a ready made product I spent my time re-implementing the wheel in my way, and after some failed attempt I can say even my solution works.
Adafruit use more memory but is much faster with many particles and richer in functionality. My approach is slower in some case but use less memory and was cleaner for me to understand, as it is not using some optimization.

The core of both approaches is to keep track of particle position and speed, at every iteration collision for the particle is checked against other particles regardless of inducted motion. In case of collision with actual speed we try to use only one component of the motion (X or Y) and check if in that case the position would be free. When position is occupied the speed vector is bounced with an attenuation factor (so X,Y or both speeds are reversed in sign and multiply for a value < 1) while previous position (X,Y or both) is restored at previous value.

On top of this we simply apply the acceleration read from the micro:bit, and correctly scaled to all particles.

Both library use fixed point math to perform calculation in a fast and efficient way. While Adafruit manage calculus by multiply or dividing by 256 when going from screen coordinates to simulated and viceversa, I’ve preferred to use @Pharap FixedPointsArduino library that really works well even with Pokitto (despite the name :grin:) just by adding #define FIXED_POINTS_NO_RANDOM

Here a short video of the resulting simulation:

And copy of the source code, both with Adafruit library:
SandBucketAdafruit.zip (368.1 KB)
and without
SandBucket.zip (105.3 KB)

These are FemtoIde project library, so simply download and unzip in your FemtoIde projects installation folder to compile and simulate the code even without hardware. Pressing C button toggle a virtual vector force that you can move with DPAD.

This experience let me think about how many different knowledge are required to manage even a simple project like this. But lucky for us, most of the time you can just use some already made brick and glue it together step after step
It was also an opportunity to use another platform for STEAM study. I’ve been very impressed by the quality of BBC product, especially in the simple yet powerful IDE (makecode), the rich documentation tailored for beginners and abundance of sensors (there’s a radio module that’s itching me) in this little device. I don’t think any comparison can be made with Pokitto, as the target price, form factor and founding are just too different. Both live their own life and both can work well togheter :grin:

And for last I’d like to quack @FManga to have been my Rubber duck debugging device once again.

9 Likes

An amazing project!

What kind of sensors are there in MicroBit?
Would it be possible to make a PEX hat and use BM also as a points showing device in games :wink:

1 Like

Thanks @Hanski putting some hardware together took inspiration from your amazing car project.

About sensors and PEX adapter, we discuss something here with @torbuntu , that seems really enjoying this crossover.

Basically:

  • Radio + Bluetooth
  • Temperature sensor
  • Compass
  • Accelerometer
  • 2 More buttons
  • An LED matrix display
  • Light sensor
3 Likes

I love this and am still completely obsessed with the idea ever since I saw your video on it. Since I have a few Microbits just in a box :eyes: unused…

Enjoying is an understatement, I’m overwhelmingly obsessed >_<… But that’s easy for me I think.

I must ask, @HomineLudens, would it be possible to use this as an article for the next Pokitto Magazine? (Issue 3) ? Since it is already written up, it would only take some editing to make it suitable I think.

I have been looking online now for some adapters and such in order to more easily fit the M:B and Pokitto together, because I see some ridiculously high levels of potential with this :eyes:

2 Likes

Honestly while writing it It came to my mind the idea to postpone the release for the magazine, but simply I wanted to move on something else and flush my cache :smiley:.
Anyway I’ll be more than happy to see this on the next issue.

Please keep me updated :wink:

1 Like

I am SO glad you shared now, because this has some great info for when I get started. I can get it edited (in the event of spelling, no changes as far as content) and put up in the repo for mag3, because I really think this is amazing, and I’m sure there has got to be others that would benefit from seeing this :smiley:

will do!

1 Like