Skip to content

Instantly share code, notes, and snippets.

Last active Jul 1, 2018
What would you like to do?
Sonic Pi controls Raspberry Pi GPIO and vice versa. See my article at and video at
#Demo program gpiocontrol.rb to control GPIO devices from Sonic Pi
#and to receive data to play from a GPIO button being pressed
#written by Robin Newman, July 2017
SPoschandler_server = "" #adjust for your own setup
use_osc SPoschandler_server,8000 #SPoschandler_Server on port 8000
define :all_off do
osc "/led/control",0,0
define :do_testprint do
osc "/testprint","This is a test message with data",1,2,"The end"
##| all_off #uncomment these two lines to turn all leds off and stop
##| stop
live_loop :testprinting do
do_testprint # try out the testprint OSC message. Should print on the Pi terminal screen
sleep 2
live_loop :test do
n= sync "/osc/play"
puts n
use_synth :tri
play n,sustain: 0.05,release: 0.2
live_loop :m do
s=scale(:c4,:minor,num_octaves: 2).tick
play s,release: 0.1
#uncomment ONE of the next two lines to alter the response of the LEDS
if s >note(:c4)+12
#if look%2==0
osc "/led/control",1,0
osc "/led/control",0,1
sleep 0.2
#!/usr/bin/env python3 written by Robin Newman, July 2017
#Provides the "glue" to enable the GPIO on Raspberry Pi
#to communicate with Sonic Pi. Sonic Pi can control LEDs etc,and receive
#input from devices like push buttons connected to GPIO pins
#Sonic Pi can be running either on the Raspberry Pi,
#or on an external networked computer
#The program requires gpiod daemon to be running. Yu can install this with
#sudo apt-get update followed by sudo apt-get install pigpio if you don't have it
#best to set it up to auto start on boot using
#sudo systemctl enable pigpiod.service (followed by a reboot)
#The program also requires gpiozero to be installed and python-osc
from gpiozero import LED, Button
from pythonosc import osc_message_builder
from pythonosc import udp_client
from pythonosc import dispatcher
from pythonosc import osc_server
from time import sleep
import argparse
import sys
#These are representative buttons and leds used in initial tests
#You can specify your own pin numbers if differnt
button = Button(10)
blue = LED(14)
white = LED(19)
red = LED(20)
#This function is called when the button connected to the GPIO is pushed
def msg():
blue.on() #turn blue led on
for x in range(15): #send data for playing some notes to Sonic Pi via OSC
#sender client set up in __main__ below
sender.send_message('/play', 48 + [0,2,4,5,7,9,11,12,11,9,7,5,4,2,0][x])
sleep(0.1) #Turn blue led off to indicate that data transfer is completed
button.when_pressed = msg #this is where the msg routing is activated
#This is activated when /led/control OSC message is received by the server.
#two arguments r and b contain 0 or 1 and are used to control the red and blue leds
def handle_leds(unused_addr,args, r,b):
print("Sent from Sonic Pi",r,b)
if r==1:
if w==1:
#The main routine called when the program starts up follows
if __name__ == "__main__":
try: #use try...except to handle possible errors
#first set up and deal with input args when program starts
parser = argparse.ArgumentParser()
#This arg gets the server IP address to use. or
#The local IP address of the PI, required when using external Sonic Pi
default="", help="The ip to listen on")
#This is the port on which the server listens. Usually 8000 is OK
#but you can specify a different one
type=int, default=8000, help="The port to listen on")
#This is the IP address of the machine running Sonic Pi if remote
#or you can omit if using Sonic Pi on the local Pi.
default="", help="The ip Sonic Pi is on")
args = parser.parse_args()
if args.ip=="" and args.sp !="":
#You must specify the local IP address of the Pi if trying to use
#the program with a remote Sonic Pi aon an external computer
raise AttributeError("--ip arg must specify actual local machine ip if using remote SP, not")
#Provide feed back to the user on the setup being used
if args.sp == "":
print("local machine used for SP",spip)
print("remote_host for SP is",args.sp)
#setup a sender udp-client to send out OSC messages to Sonic Pi
#Sonic Pi listens on port 4559 for incoming OSC messages
sender=udp_client.SimpleUDPClient(spip,4559) #sender set up for specified IP
#dispatcher reacts to incoming OSC messages and then allocates
#different handler routines to deal with them
dispatcher = dispatcher.Dispatcher()
#A specimen handler routine handle_leds is specified
#which deals with the OSC message .led.control being received"/led/control",handle_leds,"r","b")
#The following handler responds to the OSC message /testprint
#and prints it plus any arguments (data) sent with the message"/testprint",print)
#Now set up and run the OSC server
server = osc_server.ThreadingOSCUDPServer(
(args.ip, args.port), dispatcher)
print("Serving on {}".format(server.server_address))
#run the server "forever" (till stopped by pressing ctrl-C)
#deal with some error events
except KeyboardInterrupt:
print("\nServer stopped") #stop program with ctrl+C
#Used the AttributeError to specify problems with the local ip address
except AttributeError as err:
#handle errors generated by the server
except OSError as err:
print("OSC server error",err.args)
#anything else falls through
#Script to check the correct operation of the three leds and single pushbutton
#used in the demonstration of controlling Sonic Pi from the GPIO and vice versa
#You are strongly advised to use this before trying to use the script
from gpiozero import LED,Button
from time import sleep
from signal import pause
r=LED(20) #amend if you use leds connected to different GPIO pins
button=Button(24) #amend if using a differnt pin for input.
button.when_pressed= b.on
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment