Being Driven
/We went out for a drive today. I don’t get to sit behind the wheel just the moment, what with the brain surgery and all. But it was nice to be out in my little car.
Rob Miles on the web. Also available in Real Life (tm)
We went out for a drive today. I don’t get to sit behind the wheel just the moment, what with the brain surgery and all. But it was nice to be out in my little car.
I’ve spent a happy few hours building a Lego Orchid. It looks very realistic. The only slight issue is that the plastic bits waggle in a non-realistic way when you walk past them, but it is very nice to have a Lego Flower build that comes with its own vase.
Yesterday, in preparation for our trip to emf, we went out and bought a tent. Today we had a go at putting it up and it seems to work OK, although putting it back into the bag it came in turned out to be a non-trivial task….
Isn’t this exciting? I’m just on the brink of sending useful messages between my PICO powered controller (which has buttons and a display) and a Pure Data patch running on a Raspberry Pi. Last time I got the comport working now that I can send raw data bytes between the devices. Now I want to see about sending packets of useful data.
The man behind Pure Data (Miller Puckette) has thought of this. He’s invented the FUDI protocol for sending messages. It’s a very simple text based protocol which means that it will be very easy to make the PICO assemble FUDI messages for the Pure Data patch to read.
Lets take a look at the kind of message that I might want to send from the controller to a Pure Data patch:
encoder 97 5;
The controller generates messages like this when an encoder is turned. The word encoder tells the receiver that a new encoder value is coming The first number (97) is the new encoder value. The second number (5) is the number of the encoder. The encoder message is generated by Circuit Python running inside a PICO which is connected to the encoders and sends messages out over the serial port. The Python code that sends these messages is:
b1 = int(self.active_config.serial_channel)
b2 = int(self.active_config.controller_value)
message = "encoder " + str(b1) + " " + str(b2) + ";\n"
send_buffer = bytes(message,"ascii")
print("Sending to serial:", send_buffer)
self.client.serial_port.write(send_buffer)
This code takes the two values and puts them into the variables b1 and b2. Then it creates the message string. Next it makes a byte array containing the message in ASCII. Finally it uses the serial_port_write method provided by the serial port to send the entire string out to the Pure Data patch. Now lets take a look at how this serial data stream is received.
My blog post here shows how to get a Pure Data patch to receive data from a com port. At the bottom of the patch you can see a data flow coming out of the comport object and ending in a rather enigmatic way. The patch decodes the input message and routes it to the required destination. It uses a Pure Data loop to assemble the message (which is a line of text) and then uses FUDI (Fast Universal Digital Interface) to parse the text and extract a message which is then routed to the appropriate destination.
Remember that what is happening is that individual bytes are arriving, one at a time, and need to be assembled into a line of text. The text is terminated by a newline character (10) or a return (13).
The sel object at the top of the patch takes the input stream and feeds it to one of three outputs. If the input value is 10 or 13 (the characters that mark the end of the list) the list is triggered to push its contents into the fudiparse object. If the input value is anything else (this is what the right hand output from sel is for) the newly received character is added to the start of the list, building up the line of text.
The fudiparse block takes the buffer containing the incoming message (in our case “encoder 97 5” and uses it to generate a Pure Data message that contains the values “encoder”, 97 and 5. This message is then sent into a route object. This looks at the first item in the message and then sends the rest of the message (the values 97 and 5) to the output that matches that name. In the case of the patch above, this means that the two encoder value are sent to a message endpoint called “encoderReceived”. Patches in other parts of the of the application can receive these messages and act on them.
You should be able to work out that the decoder above can also respond to an incoming message called button, which tells the Pure Data application when a button was pressed.
I’m building a Raspberry Pi 4 based device that uses a thing called Pure Data to play sounds in response to incoming MIDI messages. The device also has a controller and display which is controlled by a Raspberry Pi PICO. I’ve connected the hardware for a serial connection and discovered how to send serial messages from the Circuit Python program in the PICO. Now I need to get the messages from the PICO into my music making software. This is how to do it.
The above patch fragment (is that even a thing?) shows how it we can surface serial data in a Pure Data patch. However, before we can do this we have to add the comport object to your Pure Data installation. If you re using a Raspberry Pi it turns out that this is very easy:
sudo apt install pd-comport
This console command installs the comport object. Now we can add one to our patches. The patch above shows that we can send it messages to make it do things. The message on the left sets the device name. The second messages sets the baud rate. The third message asks the comport to display all the available comports that Pure Data has found.
When the above patch is triggered by a message on the inlet it will set up a comport and set the baud rate to 19200. Any messages that we send to the comport object will be sent out of the comport. These need to just lists of bytes. If the comport receives any bytes from these are sent out of the bottom of the comport object. In a while we’ll take a look at how we can encode and decode messages that we want to send over the serial connection.
I want the Pure Data patches in my Chocolate Synthbox to be able to display lights that flash in time with the music. The lights in question are a bunch of neopixels connected to a Raspberry Pi PICO which is handing all the inputs and outputs for the device. I’ve done this to keep the design simpler and to remove any chance of issues with the sound code on the Pi interfering with the pixel animations.
However, to make it work I have to connect the Pi and the PICO together. Both devices have plenty of serial ports, so the best way is just to use one of those.
On the Raspberry Pi 4 (note that this only works for the 4) there are four serial ports which are surfaced on the “hat” connector. You have to enable them and they surface as devices you can use.
You enable them by editing the /boot/config.txt file:
sudo nano /boot/config.txt
Then, if you want to enable serial port 2 (which I do) add the following line at the end of the file:
dtoverlay=uart2
Save the file and then restart the Pi. You can now ask it which pins it uses with the command
dtoverlay -h uart2
The important part of this information is the “uart 2 on GPIOS 0-3. This means that the pins will be assigned as follows:
Pin 27 GPIO0 UART2 TX
Pin 28 GPIO1 UART2 RX
The other two pins (GPIO2 and GPIO2) can be used for hardware handshaking, but I’ve not enabled that. The device will appear as /dev/ttyAMA1, I’m going to use it in Pure Data (but that’s a different blog post. For this one, let’s discover how to connect the port to a PICO. I’ve decided to use uart1 in the PICO. This can be used on pins GP8 (TX) and GP9 (RX). So the wiring I need is:
Raspberry PI PICO
Pin 38 GND Pin 13 GND
Pin 27 GP0 UART TX Pin 12 GP9 UART1 RX
Pin 28 GP1 UART RX Pin 11 GP8 UART1 TX
Note that the TX and RX are crossed over. The PIC is running Circuit Python, this is how to connect a program to this port:
serial_port = busio.UART(board.GP8, board.GP9, baudrate=19200,receiver_buffer_size=500)
Now if the Circuit Python program in the PICO sends data to this port it can be picked up in the PI.
Today I needed to find a way to auto start a Pure Data patch when a Raspberry Pi boots up. This is so that the Chocolate Synthbox (patent pending) can play sounds without the owner having to do anything to get it going.
Above you can see how I did it. The /etc/xdg/lxsession/LXDE-pi/autostart file contains commadns that are obeyed once the desktop has loaded. I used this command to start the editor:
sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
I added the line you can see at the bottom:
sudo pd /home/pi/Desktop/Synthbox/ChocSynthboxMain.pd
This works well for me because the file Synthbox on my desktop contains the file ChockSynthMain.pd If you want to use it you change this to the location of your Pure Data patch.
You can use this technique to start any other programs on power up.
I’ve just shipped an article (in time for the deadline - yay!) which means I’ve totally lost interest in doing all the things that I was doing when I should have been writing it. The PICO MIDI Cheesebox settings saving will just have to wait a bit longer.
I hate it when I can’t get things to work. The Lora board I was playing with yesterday has all the hallmarks of a great product. It is excellent value and has some lovely hardware features. But when I try to send a message to a Lora TTN gateway all the addresses end up garbled. Fortunately Brian has also bought the same board and it doesn’t work for him either, so I feel a bit less alone now…
I seem to have a compulsion to do something completely unnecessary whenever faced with a deadline. However, today I had a stern talk with myself about getting things done and as a result I’ve made some good progress on a review of a rather nice Lora board for the PICO. The hardware is lovely, the only problem is that it doesn’t work for me……
Took some time off from my CheeseBox MIDI displacement activity for a walk in the park…
I’ve got lots of things that I need to do today. So I’ve spent all my time trying to store the MIDI cheesebox state in JSON inside the PICO.
As you do.
I’m really looking forward to emfcamp this year. I went to the last one four years ago and it was excellent. Last time I attended lots of splendid sessions and just enjoyed the atmosphere. This time I’m presenting as well. I’m going to be showing off my Chocolate Synthbox synthesizer and describing how you could build one of your own. It’s going to be great fun. Trust me.
There are lots of other great sessions too. You can find the complete list here.
We went out for lunch today. I took a camera along but I think I’d be very hard pushed to create a better picture than the one above that I took with my phone.
I like making things slim and low profile. Yesterday I discovered that I’d overdone this, when it turned out that I couldn’t fit the lid onto a box I’d just spent five hours printing. There were two ways to fix this. One way would be to spend a while finding the right-angled header pins, solder them into a new PICO and then spend another while transferring all the wires from one device to another. The other way would be to just bend all the pins flat on the existing device. Guess which I did? 'm not proud of this solution. But I'm very proud that it works.
Did you know that there are two sizes of 8x8 neopixel panels? I do now, having bought a new one and discovered that it is too small to fit over the pixels in the box I’ve just printed. Wah.
And then I discovered that the box I’d just managed to print was too small to take the PICO and the connections. The lid wouldn’t fit properly. As you can see, I have managed to fix this problem though. I’ll tell you how I did it tomorrow.
I drop in on Hackaday every now and then to see what folks are up to. I’ve just discovered that they have done a write up of the PICO Chord Keyboard which is rather nice. Thanks folks.
One of my golden rules about 3D printing is:
“As soon as you start to think of your 3D printer as an appliance it will go wrong. “
Today I made that mistake. And on Friday 13th too. I was rewarded with the above.
The good news is that all I had to do was adjust the Z offset to make the print nozzle a bit closer to the print surface and all is well.
There should be a special place in hell for people who design booking sites that don’t work properly on mobile devices. I’m talking about you, Hull City Theatre folks. Hull City and Hull New Theatre are both lovely venues. But getting tickets to go to performances is always a fraught business. For a start the booking page is a stinker to use on a phone or tablet. Then it insists that you log in before you can buy anything. And when you get to the final page you discover that you’ve been charged an extra booking fee for using this “service”.
Ugh.
I love working with PureData on the Raspberry Pi. But there are one or two issues. You can see a partiularly irritation one above. When you create a new window in PureData the window is positioned so that the top of the window us underneath the task bar. This means that you can’t click on the top of the window to move it around the screen. I’ve been racking my brains for ages to find a way to get the window into a more useable position. It turns out that the solution is really simple. If you hold down the ALT key and then click anywhere in a window you can then drag that window around the screen.
Wonderful when you know it….
Rob Miles is technology author and educator who spent many years as a lecturer in Computer Science at the University of Hull. He is also a Microsoft Developer Technologies MVP. He is into technology, teaching and photography. He is the author of the World Famous C# Yellow Book and almost as handsome as he thinks he is.