How to make a Bluetooth remote using a Raspberry Pi Pico W and MicroPython

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey robot makers do you want to know how to  use Bluetooth on the Raspberry Pi Pico using   micropython then this is the show for you let's  get started so back in the middle of June this   year Raspberry Pi announced that the Bluetooth  functionality is now available for Pico W to   get this new functionality all we need to do is  update the firmware on our Pico w we can do that   either using thony or just by downloading the file  from micropython.org and dragging that onto our   pcorw from the Explorer R finder window okay so  let's have a look at some of the Bluetooth basics   so what is Bluetooth Bluetooth is a wireless  communication technology used to exchange data   over short distances it was invented by Erickson  in 1989 it doesn't sound a long time ago to me   but it's uh quite a while ago now there's over  34 years ago as of the recording of this video   and it was intended to replace rs232 data cables  to create Wireless communication between devices   it operates between 2.4 and 2.485 gigahertz in  the ism band and it typically has a range of up   to 100 meters it's ideal for creating personal  area networks for devices such as smartphones   PCS and peripherals and also controlling robots  this piece of trivia there the logo for Bluetooth   is actually made up of two runic symbols because  it's named after Harold Bluetooth it was called   Bluetooth because he had a dead tooth and uh  it was a bluish in color so Harold Bluetooth   H and B are two Nordic runes and added  them together you get the Bluetooth logo   so let's have a look at Bluetooth profile the  first thing people think when they hear about   Bluetooth is how do I get my remote control to  work with some Pi Pico devices for example well   there's actually two different types of Technology  there's the sort of classic Bluetooth Bluetooth   head or human interface devices and this is for  things like keyboards mice and game controllers   and it allows users to control functionality of  their device from another device over Bluetooth   when coding you're essentially transferring those  keystrokes mouth movements over Bluetooth and then   the focus of today's session which is Bluetooth  low energy which is a newer version of Bluetooth   it's a power efficient version as compared with a  classic Bluetooth it's designed for shot bursts of   long range radio connections ideal for internet  things applications where power consumption   needs and need to be kept to a minimum which is  exactly what we're looking at when we look at   battery powered robots it operates in a different  way compared to Classic Bluetooth even though   it shares the same spectrum and when coding we  typically work with services and characteristics   that allow for reading and writing of a short  pieces of data so services and characteristics   we'll be laughing a look at in a minute so let's  have a look at the connection stages of Bluetooth   so our Bluetooth goes through a series of  different stages first of all we have advertising   so on the server so in this case I'm going to use  a little Raspberry Pi Pico which has a display   pack from pimroni on the front I'm using this  because it's got some nice little buttons so what   this is going to do this is going to be the server  and then the robot is going to be the client so   that's going to receive all these communications  and then act upon them so on the server we need to   advertise that we have a service available and on  the client we want to scan for that for any remote   control nearby and then once it's found one we  can then establish a connection now you don't have   to pair these but you do have to find a device  that you're looking for and then connect to it   so pairing is a bit more of a extended handshake  connection is more of a lightweight kind of link   and on the Raspberry Pi pcores implementation of  Bluetooth in micropython can have one connection   at a time so you can't connect one remote to  several robots for example you'd need to have   more devices to do that after we've established  a connection we can then do data transfer we can   send our up down left right type commands to our  robot and then at the very end after we've done   with this we can then disconnect or if there's an  issue say you walk too far away from your robot so   there's a larger distance between the transmitter  and the receiver the client in the server it'll   automatically disconnect and we need to handle  that in our code next up is gats generic attribute   profiles Bluetooth can be a bit of a complicated  beat underneath but we don't need to worry too   much about this but I'm just going to tell you  what these are just so that you understand so a   Bluetooth generic attribute profiles also known  as gats are one of these foundational design   requirements of how two devices talk to each  other that's quite a wordy way of saying we need   to establish some way of communicating between  these two devices in a way that they both expect   and the profiles allow us to do that so gas is  only used once we've established the communication   so it's not used at the advertising and scanning  stage so we're gonna have to use some different   styles of programming that we've typically  done on our projects to date and this is the   difference between synchronize and asynchronous  code so synchronous code I think I just called it   synchronize synchronous code is kind of regular  programming so when you think about your python   programs your micro python programs they are  synchronous what that means is they're simple   predictable easy to write and understand and  ideal for beginners a short tasks that don't   require multitasking the sequential in execution  sometimes called procedural programming and that   means it's very easy to debug because we we can  look through what the next line of code is what   the previous line of code is and understand what's  going on there and task completion is completed   by moving from one task to another waiting for one  to finish before we move to the next that's called   synchronous programming asynchronous programming  is a bit more complicated than that this is to do   with non-blocking operations we allow a program  to do more than one thing at once so it's a   multitasking doesn't necessarily use different  cores in the processor micro python kernel can   look at a synchronous code and essentially  start and stop tasks or carry on with tasks   depending on what their status is so it's more of  a Cooperative multitasking than true multitasking   so it doesn't wait for a task to complete before  moving moving on to the next one which can improve   efficiency particularly when you're waiting for  some input output to complete it's also designed   for event-driven execution so when you think about  when we press a button on a keypad what we want to   do there is wait until that event occurs and  once that event occurs act on a piece of code   so we want to handle that in some way so ideal for  handling interrupts for handling events especially   in embedded systems where code can run and respond  to a specific trigger so in our case I'm going to   have a piece of code that when you press a button  it will fire off that code to send that signal   over Bluetooth to our robot and our robot can  then interpret that in a way that we wish it to   like moving forward and this means that it can  be a lot more responsive it has this enhanced   responsiveness it's ideal for applications that  require that high responsiveness such as user   interfaces since it can continue to process other  tasks in the background while waiting for that to   happen so rather than having to go around in a  loop and test for each different button being   pressed we can simply just say if this is pressed  then fire off that task so choosing between the   two asynchronous and synchronous depends on  what you your task is and for ble we need to   use asynchronous programming we don't know when  a signal is going to be received from our server   to move the robot forward left or right and so on  and therefore we need to use a synchronous code to   handle that to catch that as it comes in to use  asynchronous coding in our program what we need   to do is have three different commands it was in a  sync a weight and run command so the async command   is used to declare a function as a co-routine so  rather than just being a regular function it's   called a CO routine because it's a Cooperative  multitasking so a keyword that's put in front of   the usual def when we're defining a function so  the example there is a sync def my function and   it enables the await command so you can only use  a weight within a call routine task and you have   to have one at the end otherwise it will never  complete so a weight is kind of a way of saying   wait for this to complete so wait is used to pause  the program and essentially hand back control to   another code core routine task to carry on doing  what it wants to do a weight is used to pause the   execution of the core routine until the task is  completed and this allows all the tasks to run   in the meantime so calling call routines where you  simply just use the weight like await my function   a waitable object means that you can only use the  await in an awaitable object which is a co-routine   and task that has that async def my function for  example we'll have a look at this in the examples   a bit later on so if you like what I do please  give this video a like drop me a comment let me   know if you're going to build any projects with  Bluetooth and specifically what kind of projects   you're going to build with Bluetooth I'd really  love to know and if you've not already subscribed   to this Channel please hit the Subscribe button  hit the little bell in the notification most of   the people that watch this video aren't subscribed  don't be one of those leave one of the people that   subscribe and help me grow my channel it  really does help I do go live every single   Sunday at seven o'clock Greenwich Mean Time  or British summer time which is just GMT plus   one depending what time of year it is so I'll be  going live this Sunday seven o'clock UK local time   okay so once we've done our sync and our  weight at the very bottom of our program we   need to have some kind of way of starting up  that whole asynchronous programming Loop and   the way that we do that is we have a special  event Loop that's called run the Run function   starts the event Loop which is necessary for  that asynchronous call to run in micropython   you'll use a library like micro a sync IO to  provide that functionality and that's what   we'll be using in our robot code today so running  tasks we have to do things like usync io.run and   we can also create tasks and that's what we're  going to do in our code we're going to create   a series of about two or three different tasks  and then we're going to pass those tasks lists   to the Run function and then the Run Loop will  handle all those uh those called routines run is   essential because top level await statements are  not allowed you can't use a weight outside of the   async function so they all have to be within it  again makes sense when we can show you some code   so writing a synchronous code remember the goal  of a sync weight is to write non-blocking code   what we mean by blocking code say we had something  that takes five minutes to go on process I'll do   that's going to block any other piece of code  from running we don't want that to happen so   non-blocking code means that the operations that  block things like input output are ideally coded   with a sync and a weight so we can handle them and  have their tasks although elsewhere carry on doing   things kind of using my hands to demonstrate this  and you can't see it nested code routines you can   have code routines that have other code routines  or remember to use the await keyword when calling   a call routine from another call routine an  exception handling you can use regular try   accept blocks to handle exceptions within a sync  functions but remember that exceptions may affect   all the tasks running in the event Loop we do use  the try accept blocks in our code as well because   there's quite a few different things that we need  to handle such as the disconnect we talked about   earlier okay ble characteristics and services so  a service is kind of the collection of related and   Associated behaviors that accomplish a particular  a function or feature of a device it's a way to   group together pieces of information together  so for example the heart rate monitor that we   say here there's a heart rate service that runs  on our fitness tracker and that groups together   all the data and behaviors related to measuring  heart rate heartbeat Apple pressure that kind of   thing from a barely characteristics perspective  characteristics are the individual data points   within that service so the heart rate for example  the location on where on the body where the center   is all those are individual data points and we can  have those as specific characteristics there's a   whole bunch of standards that are defined by the  Bluetooth group for what each one of these is now   if you wanted to create something commercially  you probably have to look up what's the closest   characteristic code for what you've designed in  however you don't have to stick with these if   you don't want to if it's just for a robotics  project you can kind of as long as you use a   characteristic number doesn't matter what that  number is we can reuse any of the different types   so we're going to use one today that's roughly  a remote control type and these are hierarchy   call so we can have our Bluetooth device that has  several services in it we're going to build two   Services into our remote control we're going  to have some device information that's got   things like the firmware version the unique ID  of this particular Pico and then we're going to   have another service which does all the control  stuff so together services and characteristics   form a hierarchical structure a ble device  can have multiple services and each can have   multiple characteristics and this organized  structure allows for other devices to discover   and understand the data being offered by this  ble device facilitating seamless and meaningful   communication remember both of the services and  characteristics are identified by a uuid which   is a universally unique ID allowing them the  devices to recognize and interact with them and   this is what these codes are that the Bluetooth  organization have put together in Endless tables   honestly it's a three or four hundred page  document that lists out all the individual   uuids and some uuids are standard as defined by  this Bluetooth special interest group for common   services and characteristics while custom ones  can be defined for Unique applications like ours   so how do we actually send the data using these  characteristics so individual data points have a   characteristic type such as button temperature  center Etc and they can also have an encoded   payload which is just data that you want to  send and receive and it's just represented in   bytes so we can encode and decode that if it's  more complicated I'm simply going to send single   characters like up down sub U and D L and R for  left and right and that's all I'm going to send   so I don't really need to encode and decode that  we can send that quite simply and then the data   is decoded on the receiving device so let's  go over to our demo build some code and make   some robots work with Bluetooth so over here  on the bench I've got a couple of components   I'm going to use to build this robot so this is  a virgobot as I call it burgerbots are round in   shape they have a Raspberry Pi Pico they also  have a pimarroni motor shim on board and also   a Pico lipo to connect to a lipo battery as well  so on this one I can show you on the overhead here   you can see that the LiPo battery sits at the back  there connects into either a lipo shim or I've got   one of these lipo Amigo Pros here this just means  I can charge it while I'm also using it and you   can see though that we've got the the Raspberry Pi  Pico that's got the motor shim on there the motor   shims a bit easier to see if I show you on this  one here because it's sat right on the top and it   simply allows two Motors sort of a left and right  motor one motor two and the motor is in there   are Simply Connected there's another one I made  earlier using these motor shims so it's a motor   that's got a little connector on and then you can  just connect a wire between that and the motor   shim and Away you go so if you want to know how to  build your own Burger bot I have done some videos   on this previously so I'll put a link up in the  description up there so you can get a link to how   to build your own burgerbot and what we're simply  going to do is write some code that will enable   us to control this robot using this Raspberry Pi  Pico so this Raspberry Pi Pico is using a pimra   only display pack 2. this is a display pack too  so it's got some headers there and we just push   the picot onto the the header and away we go so  here's one I prepared earlier I'm simply going to   use the a b X and Y buttons as a forward backwards  left and right and we might even write some code   to display something on this nice screen as well  and that's all we're going to do okay so over here   I'm going to write the code using visual studio  I find it's a lot easier to write code in Visual   Studio I'm also using the the functionality such  as this co-pilot down here and copilot helps you   write code it will suggest code for you that's an  extra paid service book I quite like that right so   what I'm going to do I'm going to create a new  file let's call this one remote control.pi and   let's get started so the first thing I'm going  to do is input CIS sys and I'll also to access   some of the hardware and system information of  our micropython device I'm going to use this   to grab a unique ID of this particular board we  also need to import aible which is asynchronous   ble and we're going to import Bluetooth so let's  import Bluetooth now if you try and use Bluetooth   and you haven't got this available it says  module not found you're not using the updated   firmware you need to go to micropython.org to  grab the latest version or if you want to use   thunder you can use that instead and just install  the latest version so next we need to import a   machine because we're going to use some pins  on the machine we're also going to import UA   sync IO as a sync IO we're also going to use some  constants as well and we're also going to import   from pimroni the button function because we want  to be able to capture those a b up down left right   kind of buttons now I want to be able to provide  a unique ID and just have a little help function   to do this so I'm going to say Define uid and then  what I'm going to do next is Type in this code so   this is what I've got GitHub co-pilots helping me  type out some of this so this is going to return   a unique ID of the device as a string and what are  these squiggly colon or 2x all these things these   are formatting options and it's essentially  saying just provide this as a unique string   so it's going to format that and then return that  value as a string next we're going to set up some   constants so the first one is the manual Factor ID  these are going to be characteristics that we're   going to provide as part of one of the services  the device info service so that's value there O2   a29 that's one of the Bluetooth organizations  predefined characteristic types the Gat types   for manufacturer ID so I'm going to type in  a couple more of these we've got model number   we have serial number we have Hardware revision  number and we also have the ble version as well   next up I'm going to create some variables four  variables one for each of the buttons and this   is using the pimeronis the batteries included  button function for the display pack 2. these   numbers here 12 13 14 15 they're the gpio pins  on the Pico each button corresponds to next we   want to have a nice little LED that can Flash so  the onboard LED which it used to be pin 25 on the   Pico and on the Pico W you can actually just say  pin and then in speech Max quote marks capitals   LED and set that to machine.pin out because we  want it to be an output and we're going to use   this to flash on and off our LED onboard our  micropython board and we're going to flash it   quickly if nothing's connected and then slowly if  something's connected so just by looking at it we   can see what state the board is in okay next up  we're going to create some more variables these   are going to be the the various uuids that we  need to use so let's create one let's call it   generic generic I should say and this one is going  to equal Bluetooth Dot uuid and then we need to   pass in this uuid so 1848 so the 0x means that  this is a hexadecimal value and we're going to   have another one which is the button so let's do  button uuid and that's again equal to Bluetooth   I've got to make sure these are correct because  on the other code which we're going to create for   the the actual robot these need to to match  okay and then the other thing we're going to   do is we're going to create a ble appearance so  next up we need to have an advertising frequently   this is how long we wait before we time out on  our advertising stage so let's say interval in   milliseconds it is going to be 250 000 and then  let's set the device info to equal and this is   where we create the actual service so so I'm going  to change that number up there actually to be okay   and then we're going to say connection of course  none so to begin with we've got no connection   let's create the characteristics for the device  info and then a i o b l e dot characteristic   now let's create one so device info is what is  the name of the service that we've created and   then we want to create another Bluetooth uuid  manufacturer ID we then say we can read this   value so that's true and then the initial value  is what we want to call our device so this is we   can create what manufacture our devices so I can  say kev's robots Okay next up we want to create a   couple of other things we need the model number so  we can have that there let me just close that out   so we've got a bit more space to work with I'm  going to say that this is the model number so   let's set up the initial value to be 1.0 0 we're  then going to have the serial number and this is   where we use that uuid function helper function  that we created up here we can actually pass in   that as the initial value so whatever that unique  ID is for our specific board and that means it's   Unique across every board that there could be  and then let's also include in here the system   version so let's do Hardware revision so instead  of saying initial zero let's say sys dot version   and then finally let's have one more which is  the Bluetooth ble version that we're using so   let's just have an initial 1.0 for that as well so  these aren't real values that are being used by a   commercial device this is just us playing with it  to show you how you can actually investigate this   okay so let's create the remote service now  so remote service equals service generic and   let's then create a button characteristic and we  can do that by creating the characteristic let's   just uh make our code a bit better there so we're  passing them remote service that we created there   the button ID that we've created further up we're  saying notify is true and we're also going to say   read equals true as well so at this point I like  to create a little print statement so that we can   see that this code is working so I'm going to say  registering services and then what we're going to   then do is do a i b l e dot register services and  we can register both of them we can register the   remote Service as well as the device service so  we just passed in both of those two Services we've   created so now we'll say connected equals false  we can use this connected to drive our blinking   rate later on we can use that as a flag so we're  going to create our first async function now so   we're going to create a task for handling the  button presses so let's say a sync Def and then   let's call this remote task so to handle the  remote control so what we're going to do on   here is we're going to have a while true Loop  so we'll say while true which means run forever   so if not connected then print not connected  we'll get it to wait for one second and then   continue means at this point in the loop stop and  then go back to the very beginning of this while   true Loop so this piece of code will keep going  round in a circle until connected is true and   that extra second weight there just means carry  on doing everything else in the background but   just wait a second right now what we can do is we  can say button a which we created further up dot   read so if button a has been red we can say print  button a pressed connection is and then we can say   connection and if we've got that little F at the  very beginning of that we can actually embed that   variable within our string which is quite a nice  healthy thing to do next we can say button dot   characteristic and then we can write this this is  the part where we actually send the command over   Bluetooth to whatever device is listening to us  and what we're going to do is we're going to say   characteristic dot right and then we need to pass  in a byte so we use the B to indicate that this   string that follows is actually a byte and I'm  simply going to pass in the character a because   it's the a button that's been pressed the next  thing I'm going to do is I'm also going to notify   we can notify using the connection and again we're  going to say byte and a so this we have to pass   in the connection that we're using which is the  connection is a variable that stores all the state   of the connection and the the A's basically just  a replica of that okay so that's everything that   we need for the first button we just need to now  do this for the other button so instead of doing   another if statement I'll do an elif so this is  an else if and the benefit of using else if rather   than just having four if statements one for each  button is if the first statement isn't true it   immediately tests for the second immediately test  for the third as long as you've got this uh this   alif so if we do that button a button B has been  read we can then say button B has been pressed we   can write button B and we can notify button b as  well and then we just need to do that for the x   button and I'm just going to let call pal help  me write this code out here it's a little bit   quicker to do that and then finally we'll have an  else so after all these elifs have been tested if   everything else if none of the button's been  pressed we can have a final state so let's say   button a characteristic and let's have a kind of  a default value that gets passed even if nobody's   pressed anything now this isn't the best way of  handling key presses a better more responsive way   would be when you press the button down that fires  an event when you let go of the button that also   fires an event and that you can fire those off to  your robot and it can handle both the key being   pressed and the key being released and it just  makes the whole motion smoother but for Simplicity   this is the simplest way to do it and we have got  a loop where it has to test each of the button   States as well so we're not really using that  notify particularly well in this current piece   of code but conceptually it's like easy for you  to understand that right so that's going to send   off just an exclamation mark and what we're going  to do now is just await so if we say await sync IO   sleep and we're going to sleep for 10 milliseconds  so it's a really quick sleep but it just means our   Loop has got some kind of pause in if we don't  have an await in here of any time at all we're   actually not allowing any time for any of  the other background tasks to occur so we   do need to have some kind of weight in here but  if the weight's too long on this one it'll wait   an entire say if you put as a thousand a thousand  milliseconds being a second when you press a key   it would only be responsive one second at a time  so a 10 is 10 milliseconds is pretty responsive   there okay so that's the first task the next  one is going to be our peripheral task so let's   say diff find the peripheral task and what this is  going to do this is going to handle the connection   itself so let me just get rid of all that for a  second so what we want to bring in so we do want   to bring in connected and also connection and  while true we can say connection to the first   state we want this to be in connection is false  sorry connected is false connected is our flag   for our blink thing later on and then we're gonna  have another sink so this is kind of a within the   sink we can have another a sink with a weight and  this then says a i o b l e dot advertise let's get   rid of that and what we want to advertise now  is the we want the wait time which we defined   before the interval time we want to pass in the  name so let's say that this is a kev's robots   it's cool when you see this using another tool  that's actually scanning your Bluetooth Network   and then we're going to say the appearances that  appearance that we defined and then we need to see   what the service is okay and then we can Define  that as connection so a connection contains all   that connectivity information so once that's  done we can then say connected or connection   from and then we can say connection dot device and  that will give us the information of which device   is actually connected to it connected is true  that's the flag that's going to make our blinking   change the rate and then we can then say print  again this is just for debug connected and then   and that'll just give us the connected State  as being true or false we can then say await   connection dot disconnected and then we can print  at the end disconnect it so it'll wait for that to   occur and then it'll print out the disconnected  message so that's our peripheral task that will   handle all the connectivity and then we can now do  our blink task so let's do a sync def blink task   this one really brings it to life when the you've  just got a single Peak or not doing very much so   what we're going to say on here is this is going  to Blink task to Blink and we're going to create   a variable that's just called toggle we're going  to set that to true to begin with and then we'll   say while true so this Loop is going to also run  forever and what we're going to do on here we're   going to say LED dot value that's going to equal  to toggle we're going to then going to say toggle   not toggle so that will toggle the toggle also  if it's true it'll become false if it's false   it become true we're then going to set the blink  rate to initially 1000 so that'll be one second   and I'm going to say if connected is true then we  want to change the the blink rate to once every   second else we want the blink rate to be I'm going  to put a quarter of a second so it flashes pretty   quickly it'll turn on and off pretty quickly  and then finally we can then blink whatever the   blink rate is that we've just defined there so  it'll wait depending on whether it's connected   or not at different times and that's it that's our  blink task All That Remains now is to create our   main function and then the Run function so let's  create our sync Main and we're going to create a   tasks list here and this is going to Simply have a  sync create a task which is the remote task create   another one for the peripheral and then the last  one for the blink task then what we're going to   do is want to say await gather and tasks and that  will gather all those tasks together start each   one in the background and then wait until those  tasks complete but because they're all running   in a while true Loop they will run forever and  then finally we can just say a sync IO run main   which is this main function here and that's it  that's our program for the remote control so we   can upload this now what I like to do is I like  to upload this using thony so if I flick over to   thony here I load up the the code that we've just  created so ble remote and I call this one remote   control so there's the code that we just created  fine I'll plug in our remote control I'm going   to plug this in on the moment of truth will our  code actually work so let me just hit the stop   start button on there and then let's hit run  with our code so if I go back over here I'm   just going to hit run let's see if you've got any  problems so I just need to update that typo that   I had there which is on line 54 so I think it's  register services like so let's try that again   um generic isn't defined and it's because it's  underscore generic not just generic so let me   just go and fix that one let's try that again  there we go so so far it says not connected and   it's registered the service and if I go back over  to here and I flick this over you can see that   the LED is blinking and it's blinking quite fast  because nothing is connected so I'm just checking   my reference code here I'm just going to create an  extra a couple of things here so I can do this in   Thon it will update both visual studio and funny  at the same time so that's fine so let's create   another one in here and let's call this one and  it's going to simulate a uuid and I'm just going   to change the number on that one to be 4 8 and  what I think I need to do on that is just check   which device info we are updating so the device  info that one should be robot and then the other   one which is the remote service should be generic  so generic should be 448 and robot okay let me   just stop that Rerun it so to help troubleshoot  I've downloaded an application that which is   called Blue utility now you can see a blue utility  here it has a list of all the different devices   and the signal strength for them and if I run  our code in the background let me just go over   here and run this so that it's actually saying  registered service not connected if I get this   blutility code up let's get this sort of side by  side with the other code so now if I go and find   kev's robots on here can you see we have robots I  click on kev's robots we can see their connection   from device public address connected connected and  then if I click on the 1848 which is the name of   the service ID we can click on the characteristic  and this exclamation mark means that I'm currently   not pressing any buttons so if I hold down I'm  going to hold down the a button on here you can   see that it says button a is pressed and if I  click on read we might be able to capture there   we go that there was a an a being pressed okay so  we know that it's sending out bluetooth data we're   actually receiving it on this Mac and therefore we  know that where things are actually working we now   need to write some code for our robot to receive  that the other thing I just wanted to point out as   well was when we actually connect to this using  this blue utility let me get this down here so   we can see it if we just disconnect for a second  on our code it says not connect to the moment it   will register the disconnect you can see the the  blinking rates near my thumb there is flashing now   watch this when I actually connect to it down here  if I click to connect to to catch robots can you   see now that the connection the light is flicking  at a different rate because it's using that   connected variable to govern that and then as soon  as I disconnect and do something else it'll go   back to flashing about different speed so we can  see there that we've got that nice indication just   from the LED so the other thing I need to do to  make this run in the background we need to save in   thony this to the Pico so if we go to file save as  click on Raspberry Pi picot we can then save it as   main.pi a main.pi is a special name that's given  to the code that will run when you first boot   up your pico so if I now just connect this into  some power you can now see that that's uh waiting   to connect and if I go to some test code that  we're going to write in a second just run this   I can now see that this actually does connect  right so let's write this code in the robot   so like before we need to import a couple of  things before we start so we need to import   the Bluetooth library for low energy we need to  import the Bluetooth itself let's import machine   because we're going to connect to some Hardware  let's import UA sync IO as sync IO and then I've   created a special library for burgerbot which  is simply called burgerbot and that contains   all the different interactions with those motors  from the motor shim from pimarroni and that means   that we're able to sort of utilize that without  having to worry about how to make our robot work   behind the scenes right so now we need to create  a couple of those unique IDs so what I'm going to   do is create an extra one and that's going to be  1800 and let's now do LED equals machine dot pin   and that's going to be the the blink function  that's going to help us with our blink function   we then need to do connected is false a live is  false we're going to use a live to help handle the   connects and disconnects and we're actually going  to create our robot here our burgerbot as the   variable bot and we're going to say bot dot stop  just to make sure it doesn't roll off the desk   when we very first initialize it okay we need to  create something called find remote find remote is   going to be another background task at the first  background task and this is going to scan every   five seconds to see is there anything available  that we're looking for so we say sync with Iowa   DOT scan we then set the number of milliseconds  5000 the interval is 30 000. the window is 30   000 and active is true I'm going to save this as  a scanner and then we say wait for the results so   a sync for resulting scanner so that's going to  loop around for any results it finds and that's   essentially going to build out the list very  similar to this list here of everything that's   available in our personal area network and what we  want to do is look for the result name of anything   that's called kev's robots because that's the name  that we gave our device once we've found that we   can then say so if result.name brackets equals  equals kev's robots then print found casual Bots   and then for the items because we've got more  than one service in there we have the device   info Service as well as the actual control of  the robot service so we can save item in result   Services print item and if generic which we've  created up there is found in resource.service   then we can then say print found the robot service  and then we can return that result dot device to   the thing that's going to be calling it otherwise  if you don't find anything we just say return none   that's the first task the next task is going to  be our blink one which we created before so we're   going to turn our blink off on on every couple of  seconds our blink task has started we're going to   say blink while true and alive so link equals 250  the LED value is going to be equal to whatever   we toggle and we need to toggle that value after  we've done it so toggle equals not toggle we then   say if connected blink is every second otherwise  blink every quarter of a second and then we can   then say print blink task is stopped because if we  exit that while true Loop because it's no longer   alive then we can say the blink task has stopped  so we need some way in our the very bottom of our   code of having a wild true Loop to start all those  tasks back up again so this can help us in a kind   of Fail-Safe point of view so next we need to have  a function to move our robot so let's call it move   robot and pass in a command and we're going to  test for if command equals byte a so that's our   up we can say move the robot forward so bot dot  forward and then this 0.1 is how long we're going   to do this for so one being a second so 0.1 is  0.1 of a second a tenth of a second else if B   is been pressed then move the robot backwards  if x has been pressed then turn the robot left   if y has been pressed then turn the robot right  and that's it that's all we need to do for our   move robot okay so we need the peripheral task  again this is going to handle the connection and   disconnection so peripheral task and let's just  say starting up peripheral task we're going to   bring in connected and alive so we use this Global  to bring in any Global variable that we want   change the value of we can leave it out we didn't  include that for example in our blink thing   because we're not changing the value of a lie but  if we want to change the value of a live to say   false or true then because it's a global variable  we have to bring that one in using the global   keyword okay next we're going to say connected  equals false so we start off with a no connection   at all we're going to say device equals and then  await find remote so if device if not device so if   the device is false then print no remote found  we want to return return will exit out of this   function so we need some way of starting that task  back up which we'll look at later on and then we   need a try accept block so try accept his way  of catching errors without the program crashing   so the first thing I'm going to do is say print  connecting to and then we can pass in the device   and that will give us all the details of that and  we can then say connection equals await device dot   connect okay so if there's an error we can then  catch that error by using the accept a sync AOL   we can specify exactly what kind of error we want  to catch so we want to capture timeout error so   we can just say something like that and then  we return we're going to exit out the function   let's now do so in the case everything's worked  okay let's say a sync with connection and then   we can say print connected so we're connected  to our bluetooth remote we can then say alive   is true because we've connected and we can say  connected is also true and then down here we can   say robot service equals awaitconnection dot  service and then we can pass in that remote   uuid that we created use that one and then we  also want to create the control characteristic   as well so once we've got the characteristics and  the Service established we can then say while true   and we can say try if remote service is none so if  there's been some kind of problem it's probably a   disconnect error we can say remote disconnected  alive equals false and then we can say break so   break is different than return break will just  break out of this while true Loop so it'll go to   whatever's beneath this while true Loop but  it won't actually exit out this particular   function so that's another way of breaking out of  a loop so let's have another timeout error so time   out during Discovery service characteristics  and again we can just say alive equals false   it's going to be a robot service nut remote  service there we go because it has to be the same   as that and then once that's been captured we can  then say so everything at this point is still good   we can then say if control characteristic is none  so if there's a problem with that then there's   no control so we can say no control um alive is  false and break and if all that's worked okay so   there's been no errors we can then say data equals  await control characteristics dot read and we can   provide a timeout value in there for a sec for a  whole second await control characteristics read   what that is going to do is going to read from  our bluetooth remote control what the value is   and it's going to store it in data so we can now  say await control characteristics and let's do a   subscribe then notify equals true and then while  true command equals await control characteristics   multiplied and we can then move our robot using  our move robot task and passing the command that's   been up down left right commands that we've been  passed in there we can even print out what that   command is if you want to see it and then we can  do bot stop as well okay we can now capture any   other exceptions so if we want to just say all  exceptions we can say exceptions as e and then   we can say something went wrong and then we  can just pass in that e let's just make that   an F string so that we can embed the variable  in it and we can then just say connection sorry   connected equals false alive equals false and  we can break out of that Loop otherwise so at   this point what we want to be able to do is just  handle any kind of disconnection gracefully so   await connection dot disconnected and we want  to just print disconnected set alive to equal   false and then we're done on that one so now we  just need to create our our main function and   our sync main function and we just need to create  some tasks so tasks I'm going to create an empty   list there we're then going to say tasks equal  and let's do a sync I'll create task link task   and also our prayerful task and then after this  we just say await asyncio.gather our tasks and   then at the very bottom we just have a while true  Loop which will just run our sync IO dot main dot   run main Hoops sync IO dot run main okay that's  it that's our code for the robot itself so let's   go back over to thony and let's just troubleshoot  any issues that are in there so first of all no   module named ink I also I need to rename that  sync IO let's try again okay so we can see that   it's flashing and let me just try and change that  to be 1848 see if that makes it work there we go   so my remote control if I go over to over  here you can see on the remote control   that's now flashing steadily which means it's  connected now it says here something went wrong   with the characteristic isn't defined so  what we need to do is just switch around   so I've just spotted a typo that's need to  correct that I put an extra underscore in   there which I didn't need to do so let me  just fix that okay just one more character   that I need to change there so it's timeout  underscore Ms let's try running that again okay so it's now receiving all those controls  let's just stop that so I've just been checking   the codes I think we just need to go through  this just to make sure that they are aligned   so the robot code which is running on our robot we  need to make sure we have the remote uuid As 1848   and the generic as 1800 these are the codes that  are used to sort of pair the things together and   then on the other side so if we just go to the  remote control similarly they have to have I've   created a new one called device ID device info  uid that's a 180 a generic is 1848 and robot is   1800. this 1808 is kind of a separate one for the  machine info in fact if we go over here and we go   to Let's refresh that we find kev's robots on here  there it is we get two Services one for the device   info and if we click on device info we can see  the manufacturer string which is Cash robots.com   we can see the model number we can see the serial  number which is the uid that we found and we can   see the firmware version 3.4 micro Python and  the software version version one which we've   defined and then in the 1848 we have that 246e  characteristic and that's currently receiving   that exclamation character which means our raw is  sending data to us now we do have to remember to   disconnect from this blue utility to make sure  that we're not hogging that connection and then   if we go back and run our remote code let's run  this remote code we can see it's not connected   let's restart our remote control running the wrong  code there let's run the robot code on the robot   there we go so it says robot found connecting  to the uh to the device and it's connected now   the big test if I press a will it launch the  robot forward so let's put the robot there I think I might have got my controls slightly  the wrong way around there we go I'm going to   disconnect this cable up before I disconnect the  cable I'm going to just stop that code I'm going   to save it as on the Pico main.pi so main.pi  will mean that it will run indefinitely on   the Pico robot we call main.pi overwrite it yes  upload it so now I can actually disconnect this   robot from there I can Power It Up by pressing  this little little button just inside there and   now let's get our remote control I can see now  it's doing a slow pulse on there which means   if I now start pressing some of these buttons  we now have a remote control Bluetooth robot there we go spin it round and so on so now it's  time for a quick word from our sponsors which   is PCB way this video is sponsored by PCB way  your ultimate destination for all things PCB   manufacturing and assembly whether you're a  hobbyist a startup or a seasoned professional   PCB way has got you covered PCB way offers an  impressive range of services they provide high   quality custom designed printed circuit boards  for any application you can imagine from single   layer to multi-layer flexible and even rigid Flex  pcbs they have the expertise to bring your designs   to life PCB way ensures fast turnaround times  and affordable prices without compromising on   quality with their state-of-the-art facilities and  advanced manufacturing techniques they can handle   small prototype orders up to large-scale  production runs with equal precision and   efficiency PCB way offers additional value-added  services such as PCB assembly component sourcing   and even functional testing you can trust them  to deliver the fully assembled and tested boards   ready for integration into your projects one of  the best parts of PCB way is their user-friendly   online platform allows you to easily upload  your designs get instant quotes and track   the progress of your orders in real time plus  their dedicated customer support team are ready   to assist you with any questions or concerns  so whether you're working on an Innovative   Internet of Things device a robotics project or  anything in between PCB ways your go-to partner   for Reliable and affordable PCB manufacturing  and assembly head over to pcbway.com today and   turn your ideas into reality with PCB way your  trusted PCB manufacturing and assembly partner   thank you for that message we have merch on  our store now so if you want to get one of   these funky hats you want to get the kids robot  mug or one of the t-shirts or hoodies then head   over to kids robots.com merch and you can help  support the show there if you haven't already   joined us on Discord we have a growing community  on Discord head over to casualbox.com Discord to   get the sign up link there completely free as well  no problems there and if you want to help me grow   on social media you can do this in a number of  different ways if you go to tick tock I'm a kid   mackley A6 on there on Instagram I'm Kev McAleer  on Twitter I am at kev's Mark and on mustard on   social I'm at kevsmack mastodon.social and if  you want to support the show in some other ways   there's a couple of other ways you can do that too  you can do a super thanks if you're watching this   um on replay and you want to press the button  underneath the main player and YouTube there's   a thanks button and that's price of a coffee  is a one-off thing if you want to buy me a   physical coffee and I do like coffee then you can  go to cash robots.com and there's the information   there for that and course you can always join  the YouTube membership program by clicking the   join button at the bottom of the player as well  just next to the Subscribe buttons hint press   that too and we have a number of supporters as  well I want to give a shout out to so here that   the supporters who've been supporting the show  so far so we have buy me a coffee they actually   bought the 10 coffees a couple of weeks ago we've  got uh day in court we have Marlene Brent John   rank Tom shammy Steve Phillips and then on the  membership side on YouTube we have Johnny Bates   Bill Hoy auxrad39 Jose Skipper Banks Jeff Ford  hands from chair lights Michael and of course Tom   so thank you to everybody who's been supporting  the show I really appreciate that so I hope you   enjoyed this video I want to say short video this  video and I shall see you next time bye for now
Info
Channel: Kevin McAleer
Views: 20,397
Rating: undefined out of 5
Keywords: Kevin McAleer, Small Robots, raspberry pi, raspberry pi projects, small robots, pico w, bluetooth, pico, raspberry pi pico w bluetooth, pico bluetooth, micropython bluetooth, pico w bluetooth, raspberry pi bluetooth, bluetooth remote, raspberry pi pico, robotics, robot, micropython, robots, raspberry pi pico projects, python, raspberry pi pico w, raspberry pi robot, kevin mcaleer raspberry pi
Id: -0wCtKz1l78
Channel Id: undefined
Length: 47min 32sec (2852 seconds)
Published: Sun Jul 02 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.