LEGO WeDo 2.0 – playing sound

This post is part 4 of 6 of  WeDo 2.0 - reverse engineering

Great news – LEGO Eduction released the WeDo 2.0 SDK today!

After digging into it, I found the information needed to control the Piezo: as expected, it’s controlled by the same handle that is used for controlling the motor and the RGB LED (0x003d). The “port” is “05” and the “command” to activate the Piezo is “02”, followed by a payload of “04” bytes containing:

  • the Frequency in Hz (2 bytes, reversed)
  • the duration in ms (2 bytes, reversed)

So to play a “C” (or “Do”, 261 Hz) during 1/8 of a second (125 ms) we use this command:

[A0:E6:F8:1E:58:57][LE]> char-write-cmd 003d 050204B801E803

So let’s hear the very first music played by a WeDo 2.0 from a linux shell script:

#!/usr/bin/env bash

# In Ubuntu run this script with sudo
# "Imperial March on a WeDo 2.0" was inspired by https://gist.github.com/tagliati/1804108

# command: gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204

# beep(a, 500) 
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B801F401
sleep 0.5

# beep(a, 500) 
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B801F401
sleep 0.5

# beep(a, 500) 
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B801F401
sleep 0.5

# beep(f, 350)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502045D015E01
sleep 0.35

# beep(cH, 150)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B029600
sleep 0.15

# beep(a, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B801F401
sleep 0.5

# beep(f, 350)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502045D015E01
sleep 0.35

# beep(cH, 150)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B029600
sleep 0.15

# beep(a, 1000)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B801E803
sleep 1.0

# beep(eH, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502049302F401
sleep 0.5
    
# beep(eH, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502049302F401
sleep 0.5

# beep(eH, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502049302F401
sleep 0.5

# beep(fH, 350) 
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204BA025E01
sleep 0.35

# beep(cH, 150)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B029600
sleep 0.15

# beep(gS, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502049F01F401
sleep 0.5    

# beep(f, 350)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502045D015E01
sleep 0.35

# beep(cH, 150)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B029600
sleep 0.15

# beep(a, 1000)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B801E803
sleep 1.0
 
# beep(aH, 500)   
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502047003F401
sleep 0.5

# beep(a, 350) 
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B8015E01
sleep 0.35

# beep(a, 150)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B8019600
sleep 0.15

# beep(aH, 500)   
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502047003F401
sleep 0.5

# beep(gSH, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502043E03FA00
sleep 0.25

# beep(gH, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502041003FA00
sleep 0.25

# beep(fSH, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204E4027D00
sleep 0.125

# beep(fH, 125) 
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204BA027D00
sleep 0.125  
   
# beep(fSH, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204E402FA00
sleep 0.25

# delay(250)
sleep 0.25

# beep(aS, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204C701FA00
sleep 0.25

# beep(dSH, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502046E02F401
sleep 0.5

# beep(dH, 250)  
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502044B02FA00
sleep 0.25

# beep(cSH, 250)  
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502042A02FA00
sleep 0.25

# beep(cH, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B027D00
sleep 0.125

# beep(b, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204D2017D00
sleep 0.125

# beep(cH, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B02FA00
sleep 0.25
      
# delay(250)
sleep 0.25

# beep(f, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502045D017D00
sleep 0.125

# beep(gS, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502049F01F401
sleep 0.5

# beep(f, 375) 
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502045D017701
sleep 0.375

# beep(a, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B8017D00
sleep 0.125
  
# beep(cH, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B02F401
sleep 0.5

# beep(a, 375)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B8017701
sleep 0.375

# beep(cH, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B027D00
sleep 0.125

# beep(eH, 1000)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502049302E803
sleep 1.0

# beep(aH, 500)   
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502047003F401
sleep 0.5

# beep(a, 350) 
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B8015E01
sleep 0.35

# beep(a, 150)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B8019600
sleep 0.15

# beep(aH, 500)   
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502047003F401
sleep 0.5

# beep(gSH, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502043E03FA00
sleep 0.25

# beep(gH, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502041003FA00
sleep 0.25

# beep(fSH, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204E4027D00
sleep 0.125
    
# beep(fH, 125) 
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204BA027D00
sleep 0.125

# beep(fSH, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204E402FA00
sleep 0.25

# delay(250)
sleep 0.25

# beep(aS, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204C701FA00
sleep 0.25

# beep(dSH, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502046E02F401
sleep 0.5

# beep(dH, 250)  
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502044B02FA00
sleep 0.25

# beep(cSH, 250)  
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502042A02FA00
sleep 0.25

# beep(cH, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B027D00
sleep 0.125

# beep(b, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204D2017D00
sleep 0.125

# beep(cH, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B02FA00
sleep 0.25

# delay(250)
sleep 0.25

# beep(f, 250)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502045D01FA00
sleep 0.25

# beep(gS, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502049F01F401
sleep 0.5 
  
# beep(f, 375)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502045D017701
sleep 0.375

# beep(cH, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502040B027D00
sleep 0.125
           
# beep(a, 500)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B801F401
sleep 0.5

# beep(f, 375)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 0502045D017701
sleep 0.375

# beep(c, 125)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 05020405017D00
sleep 0.125

# beep(a, 1000)
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write-req -a 0x003d -n 050204B801E803
sleep 1.0