Programming a Wireless Robotic Arm

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello for this video I wanted to do something a little bit different and that's been made possible by the very generous support for my patreon or patreon is depending on where you're from for a while I've wanted to tackle embedded systems as a topic but I've looked for a suitable entry point that's simply enough to make into a nice video but also lays the foundations for future video work so let's get to it let's make an program a robotic arm the aim of this video is to control a robot arm wirelessly via my computer here I've got my computer and on the screen I want to have some sliders which allow me to set the joint positions of the robots moveable parts on my computer I have a USB port and into that I have a bluetooth dongle the bluetooth dongle is going to transmit to a Bluetooth receiver this receiver is going to then communicate with a microcontroller micro C in this case it's an embed LPC 1768 and it's going to do that communication via what's known as a UART and I will go through all of these terms as part of this video robot arm consists of six degrees of freedom so that means it's got six moveable components these are known as servos and the servos require a pulse width modulation signal pwm from the microcontroller to set their positions so from the microcontroller phones have six lots of PWM we also need to think about power it's a power my system from a small supply connected into the mains which is going to convert it to six volts I then want to power my microcontroller by this six volts but then I also want to power all of my servos by the same six volts I'm going to use the pixel game engine to draw some sliders on the screen and I want to communicate with the bluetooth dongle via a virtual comm port and so the ultimate aim is that when we move a slider we see a joint move in real-time this is the robot arm I intend to build it's the DIY more wrought through you six degrees of freedom al robot arm with a claw and this specific purchase from Amazon you can upgrade to also include the six servos and I did just that so thank you to my patrons for funding this project but there is no doubt it is the cheapest and nastiest robot arm on Amazon but I think that's okay because if we can get this to work and get it to work well then you know it just goes to show you don't have to pay a fortune for some really cool stuff the microcontroller I'm going to use is the EM bed LPC 1768 and this is a really nice microcontroller I know a lot of you will be familiar with things like Arduino I don't tend to use those very much I prefer using this instead mainly because it's also quite applicable to use in industry I like the fact that it's so small and it's so modular and it's so easy to program and we'll see just how easy to program it is later on they're not the cheapest microcontroller modules available however it is entirely open-source both from a firmware and hardware perspective and it has lots of ready-to-go peripherals just simple and easy to use it also has a form factor which makes it very easy to plug into prototyping board and a quick look at some of the specifications here it's an arm cortex-m 3 which is a low aspect arm processor but it's a tremendously capable processor it can clock at about 96 megahertz it's got 32 K Bram and 512 K of flash it's got a whole bunch of i/o for us to exploit but the bits I love about it the most of these programming is drag and drop it pops up like a flash drive and you just drag the programmed file onto it very nice and all of the coding that can be done via the browser and you might be thinking oh dear me that sounds dreadful actually it's not that bad and experience at all it's quite a sophisticated web interface you can use offline tools if you want to but that does require a bit of setting up I like embeds I've been using them for quite a number of years even in industry as we can see it's quite a small device so it measures here about 53 millimeters by 25 millimetres and it's designed to fit into standard 2.5 4 millimeter pitch headers now on the back here you can see there's all sorts of things going on and this is what makes it easy to use this is the user interface circuitry they´ll allows you to just plug it into your computer and program it quite simply but on the on the top is where the real stuff happens and there's not that many features really we have a big button in the middle this is to reset the module this is the arm cortex m3 processor itself and we have four little LEDs which are under user control the other two big components on here are just power regulation because we can provide power to this via the pins or via the USB and there's an advantage to being able to power it by the pins so up here we've got ground and voltage in but because that accepts a voltage range between four and a half to 14 volts whereas from USB we just get five it's more convenient sometimes to just power your system from one place particularly in this case because the servo motors that I'm going to use I'm going to power those at 6 volts they would work at 5 volts but I don't have the current capacity from the USB hub in order to drive all of them so I'm having to drive these servos from a separate power supply every time you buy an embed and I must have bought about 50 of them by now you gets a little card like this so I quite a stack of these things but it's a really convenient thing to show you where all the pins up so we can see we've got power pins here labeled in red and all of the other pins are music and figural IO in one way or another so we've got two lots of SPI buses and we've got two lots of UART on this side we've also got a UART on this side too we'll look at you at for communicating between the computer and the controller module we've also got some analog in pins so there's a built in analog to digital converter on here and that will accept up to six inputs it's it's okay it's not the fastest and it's not the most noise free but for most applications it's fine and with some twiddly of the hard work this sort of assembly level on them I can control you can actually tidy that up quite a bit there's a single analog out employment obviously there is a digital to analog converter on here we've also got two eye squad sea buses they're usually quite popular I don't like them as much as SPI but it depends on the application but most importantly for today we've got six PWM out pins so these are hard work configured so that PWM is handled by the hard work meaning we don't have to maintain that in software there's also USB so if you doing USB on-the-go applications these are the pigeon use for that and finally there's Ethernet and at best it's a functional level Ethernet it's not for any high-speed streaming the whole device is really only clock able at 96 megahertz which doesn't sound like a lot but it's enough to do a lot of interesting things for sure the embed also really conveniently provides a regulated 3.3 volts output and we'll be using that to power the Bluetooth module this is the Bluetooth module I'm intending to use the DSD tech hc-05 bluetooth serial pass-through module with wireless serial communication with button it says for Arduino but doesn't matter it's just a Bluetooth module that gives us access to a UART and I've chosen this because I'm literally just going to plug it straight into the breadboard and hope that it works I have a little USB dongle on my main computer and this is my Bluetooth module and I chose this just because of its simplicity it's entirely contained so here you can see we've got the Bluetooth antenna and we've got some interface chips to handle the air the radio I guess and on the back it very conveniently labels what the pins are and we're not interested in all of them what we're interested in is VCC which we're going to power it from now we're going to power it from 3.3 volts not to the recommended three point six volts you can see here exactly it's okay it works and we've got the t XD and r XD lives there the UART lines that's where our communication is going to be happening so the computer is going to transmit via bluetooth to this module and this module will convert it into 3 12 3 level you are which the M bed can understand quite naturally the other pins I'm not too interested in what they do when you enter the world of embedded systems development one of the first things you'll come across is the need to have things vary over time in a kind of analog e type way but all you've got is a bunch of digital pins well one way to satisfy this is to use pulse width modulation which sounds very complicated but is in fact quite a simple thing if I create an axis which represents time and I take two points along that axis this is more commonly known as the period because what I'm going to assume is that we're going to have some repeating signal between these two points digital signals of course can only really be 0 and 1 just to make this clear I'm going to add in another timeline so I've got two sections of time here a digital clock is a signal that oscillates between 1 and 0 so for example it may look something like this the time that the clock is high is the same as the time that the clock is low and this repeats for a PWM perspective a clock is PWM at 50% let's consider a PWM at 25% well in this case it's high for 25% of the period but low for 75% of it and it repeats I'm sure you've already worked out by now but if we wanted something like 75% PWM it's highly for 75% of the period and low for the remaining 25% so to specify a PWM signal we need two pieces of information we need the period which is this duration of time and we need the duty cycle there are variations of this depending on the polarity of your signals but I'm not going to look into that today so let's program the microcontroller now now firstly I must apologize unlike Visual Studio I don't have as much graphical control over how the browser integrated development environment looks for embed so I can't really change the font and zoom in quite as easily as I can in Visual Studio so we'll just have to make do but all of the source code for this will be available in the github and is linkable from the description below a blank embed program looks like this and this is the environment I've put on the dark theme so I don't blind myself and it looks just like a C++ programming environment I've got some files and projects down here on the Left I've got a coding window here and I've got some output window at the bottom and this is the skeleton stub program you include embedded and he give int main and says well have at it you can press ctrl + B or click build from the menu up here and it builds it and gives you the syntax error and this is all happening in the browser now since we've just been looking at PWM I think the first thing to implement is a simple PWM exercise so I'm just going to specify a pin called PWM out so this is an object which will facilitate the coordination of the PWM peripherals for a specific pin and I'm going to give that pin the name LED LED one actually will go so we're going to blink one of the LEDs on the board according to the PWM signal and I can specify which particular piece of hardware I want when I'm constructing this pin and on the EM bed conveniently its LED one now thinking back to PWM if you remember there are two bits of information you need to specify the first is the period so on my pin object LED one I'm going to specify the period I'm going to set the period to be one second I'm now going to specify the duty cycle by writing to that pwm pin the duty cycle is a percentage so if I set this as not 0.5 what we should expect to see is the LED blinking on and off at a half second interval and because I'm old-fashioned and I don't want main to exit just in case it resets the EM bed controller I'm just going to sit in a loop let's compile it so compiling it was very simple well actually all I've done was build it but if I click compile it'll run through the build process and gives me a file to download which we've just seen here and this file is called robot arm LPC one seven six eight dot bin which means it's a binary file and that's the file that I'm going to drag and drop onto the EM bed when it appears like a flash drive so I'm just going to plug the embed in and take my embed and I'm going to insert the USB connector directly to my computer and we can see it's powered up the embed and that this led here tells you that the embed has power be embed itself pops up just like a regular flash drive so I'm going to take the binary file that just been given to me be the Chrome browser and I'm going to drag it on to the flash drive and as you just saw on the camera the LED blinked that's telling us that the file has been flashed on to the memory of the EM bed I now need to press the button on the amber to reset it and we can see now LED one flashing with a 50% duty cycle on a period of one and that's just been done via pwn this does mean we can flash the other LEDs too so I'm going to duplicate this code for the four LEDs on the board but I'm going to set the duty cycles to be different so we'll have led to moving at 75% LED three moving at 25% and LED for moving at I don't know let's pick something like 10% click the compile button and straightaway there's an error of course simply because I've not defined what the pins are welcome to embedded try that again there we go success and it's giving me the file so I'm going to drag that file onto the embed and program it now you can see there's multiple files now on the embed that's ok the most recently written thing to it is the thing that flashes so going back to our device I'm going to reset it by pressing the button on the top and we can see we've now got LEDs with different duty cycles a bit tricky to tell which one was which but we can see that LED for here is a very brief pulse that was our 10 percent whereas led to was 75 percent LED 1 was 50 percent and we see that's extinguished before the 75 percent one but we see the 25 percent one extinguished before the 50 percent one so it is working and the periods for the PWM are all in sync I'm going to remove the other LEDs and to show one last thing regarding PWM we've set the period here to be one second which is actually quite slow so I'm going to set that to be 10 milliseconds instead and I'll introduce an additional variable at time and in my while loop I'm going to set the duty cycle for that particular pin to be a function of time in fact specifically I'm going to set it to be sign of time but sign will of course give me a value between minus 1 and plus 1 so I'm going to add 1 to that and divide the whole thing by 2 I want time to increase so I'm just going to add a little tiny bit to it let's take a look so I've just reprogrammed the N bit and I've reset it and what we see now is a nice gently pulsing LED 1 and so PWM is really used for whenever you want something to look analog II in a digital domain the LED is flashing on and off so quickly and we're in control of how quickly it is flashing enough that we can make it look like different intensities a very common technique on anything where you see LEDs with this sort of behavior pulse width modulation is also used to regulate power efficiency in battery-powered circuits because most of the time you don't want your LED on all the time it's quite sufficient to have it pulsing at perhaps a 50 percent duty cycle to the human eye it's still just as bright it's still a usable tool but it's only using 50% of the power UART stands for Universal asynchronous received transmit and it's a mechanism for sending and receiving data between two devices so here I have device a and it's going to have an rx pin and a TX pin so it receives data from its rx pin and will transmit data to its TX pin this could be talking to another device let's call it B which also has an rx pin and a TX pin and again transmits via TX and receives via rx if it is agreed beforehand how a and B should communicate with each other creating a UART is very simple we simply take our X and connect it to TX because this is a high-level video I won't go into too much detail the nature of the signals that are being transmitted but this mechanism has been around for decades and I don't think it's going anywhere anytime soon simply because it's so easy to use but it does require that both devices are talking the same language so one of the properties that we'll need to set is known as the baud rate or bowel rate depending on where you're from and this is a good agreement beforehand that specifies how many bits per second are going to be transmitted along the Rx and TX lines once we've specified the speed that which our UART will use for transmission we also need to specify the protocol and a very common protocol is known as 8n1 and this tells the UART it's expecting a package of eight bits with one stop bit and no parity checks and so for transmitting a single byte across the UART we may assume that there is a packet that looks a bit like this we have the first thing that comes along is what's known as the start bit then we have our 8 data bits 1 2 3 4 5 6 7 & 8 then we have a stop bit before we go back to rest this implies of course that for every 8 bits of data we want to send or 1 byte of data we actually send 10 bits via the UART and the hardware will look after that for us we don't need to do that in software we just send the byte we're interested in and rely on the peripheral hardware to apply the start and stop bits for us which means we can't simply divide the baud rate by the number of bits that we want to send to give us a bytes per second value in this particular instance it's ten bits per byte so we can realistically send about 960 bytes per second and that might seem horribly slow to those of you on Menem Ultra if fiber megabit internet there are other baud rates you can choose there are standard board rates and basically they follow the old modem speeds and there's a reason for that but a typically high-end baud rate may have looked something like 1 1 5 2 zero-zero he can go a bit higher than this but real world starts to play an effect on your protocol at the length of the cables need to get shorter the nature of your circuit need to be able to handle high-speed digital signals but also the system processing the packet at either end also needs to be much faster because even though here we've got a very slow clock speed compared to the microcontroller that peripheral that's handling the UART has to have lots of individual clocks per bit in order to work out what they are so very quickly you can see that we do need fast clocks even to handle low speed you arts but thankfully for today the EM bed is going to take care of all of that for us in fact and how do we know what do to the take-home message from this is you arts are very simple to use and it's such a ubiquitous mechanism of communication nearly every device you buy will have the capability to talk to something very UART even that super flashy new PC you've just bought if it's got a comm port or it's got headers on the motherboard for a Khambhat it can talk very UART in my robot arm application I'm facilitating the UART via bluetooth the actual data transmitted via bluetooth doesn't look really anything like the UART signal but the Bluetooth module will reconstruct it into a UART signal that my embed module can understand I could on the imbed also use the USB interface directly this is the one that's plugged into the computer to make it appear like a flash drive you need to download an additional driver to do that but it will make the USB port appear like a virtual comm pot now I think it's time to look at building the robotic arm and did a full video about this but there's a live stream in Q&A session but I've condensed it now into a couple of minutes for you to have a look at [Music] [Music] [Music] [Music] the servo motors provided with my robot arm where the mg 996 are all metal gear servo motors and it looks like this it came with a load of peripherals I didn't actually need but the servo itself is this chunky box in the middle with a connector for power ground and signal the datasheet itself is dreadful but it does have some useful information so the operating voltage is 4.8 volts to 7 point 2 volts that's okay I'm intending to use 6 volts but more worryingly is the running current is 500 milliamps and it can stall at 2.5 amps this is a problem because I've got 6 servo motors so let's assume that's all 6 running at 500 milliamps I need a 3 amp power supply I don't have one I only have a two and a half amp supply so I'm gonna have to cross my fingers and hope that that works servos work using a PWM signal and we can see here that the period of the PWM is 20 milliseconds or 50 Hertz and you'd expect the point of the signal would be a zero percent duty cycle would be one extreme of the range of the servo and a hundred percent duty cycle would be the other but that's not the case and in fact the entire range of the servo is crushed down into a small range of the duty cycle as alluded to by this wonderful sentence position zero 1.5 millisecond pulse is middle 92 millisecond pulse is middle is all the way to the right - 91 millisecond pulse is all the way to the left I think there's been some translation going on here however what this is saying is that one extreme is one millisecond and the other extreme is two milliseconds and of course the middle the zero position of the servo is in between the two so looking at our PWM signals again let's assume they start somewhere here or the start of the period is here Android - here we know that the period was 50 milliseconds what it tells us is that 90 degrees so that's the server all the way to the left let's say had a duty cycle where the pulse was one millisecond high zero degrees at a pulse that was one point five milliseconds and the full plus 90 degrees all the way to the right was two milliseconds and so the active range of our servo motors is quite narrow relative to the period and this means we're going to need to do some maths to do this scaling for us so let's say we have a target angle and we'll call that 45 degrees we're also given a duty cycle min as being 0.001 a duty Max of zero point zero zero two so the range of the duty cycle is just one millisecond I also have an angle min of being minus 90 so that's to physically stop the motor from trying to damage itself and an angle max of plus 90 so with this information we can develop the relationship between the requested angle and the requested duty cycle and so bringing all that together we can work out an equation to give us the duty cycle for a given angle first we'll normalize the angle according to its range that's angle divided by angle max take angle min given that angle can be positive and negative this could give us a value between minus 0.5 and plus 0.5 so I'm going to offset it by 0.5 to bring it between 0 and 1 I now want to scale that to the applicable duty cycle range which is simply duty Max - duty min but the minimum value we can give it is Duty min so I need to offset all of that by dou T minimum going back to a blank embed program I'm going to start writing the code for the robot arm I'm going to set up the hardware first so I know I need all six PWM pins at labeled pin 21 through 226 to be configured as PWM out and in int main the first thing I'm going to do is specify the period of the PWM for each of those pins in this case 20 milliseconds 50 Hertz in my main function I'm going to want a loop that doesn't end but this time I'm going to want to do things inside the loop and the two main things I want to do are going to be read from the UART and write duty cycle 2 pins I appreciate not all of these are that visible I do apologize again but because I see this as being the start of several robotic arm projects I want to create a class that represents the joint and given that this is a C++ environment I can do just that now all of my servo motors have the same physical restraints on the duty cycles regarding the PWM so I'm going to store those as constants in this class and you may notice if you're eagle-eyed enough that these values don't reflect what we've just seen on the datasheet don't forget these are percentages of the period not times directly and so our period was 20 milliseconds this is 11 percent of 20 milliseconds which is about 2.2 milliseconds and that implies that this one is indeed 3% of 20 milliseconds which is about point 6 milliseconds for our servos I worked out these values by driving a servo to his extremes and just backing yourself a little bit and I think that's a good lesson for any embedded systems design don't ever assume anything if you need to do an experiment do it in my joint class I also want to store some values that represent the status of the joint so I want a target position where is the joint moving to the actual position where is to join currently and some maybe some constraints on the minimum and maximum angles that that joint can be set to the first method I'm going to add to the class is set target which takes a floating point angle in degrees and clamps it according to the joint min and joint max variables and just for kicks and because I like the abuse in the comments I'm going to add a get target to next I'm going to add a function that returns the duty cycle for a given angle given the constraints that we have and I showed you the mass for this a minute ago this means I can now add a constructor and I'm going to add a constructor that takes some default values in this case a minimum angle a maximum angle and a default position and also oddly for now going to add an update position function and all this is going to do for this video is take the position and set it from the target so the user will use this joint class by setting the target updating the position and then calculating the duty cycle based on that position the reason I've added this in is I think in the future I want to play with slightly more complicated trajectory planning based upon what is requested of the servo and I'd like the microcontroller to handle that rather than the house needing to calculate it all but since this is a very simple video I'm just going to set the position directly to the target in our main function I'm now going to create an array of six joints and again via experimentation I've determined that actually you don't want them all at zero when the robot starts up it starts up in a rather strange pose instead and I've determined that these values are quite useful for making the robot straight vertically upright and this is where the physical dynamics of the robot are coming into play not everything is ideal in the real world and so sometimes there are bits of noise and there are some offset particularly offsets with how I assemble the servos because I had no realistic way of lining up where the servers were without them being powered so once I've read the commands via the UART I want to update all of the positions of my joints and ultimately I want to write those to the PWM pins so just exactly how are we going to communicate with our robot are given the simplicity and low speed connection of our UART I want communication to be as simple as possible and use as few bytes as possible but I also want it to be self synchronizing and that's quite an important thing when you're a hobbyist developer things crash things go wrong power supplies explode components burn out which means very quickly a system becomes out of sync and as you can tell I'm speaking from experience there's nothing more infuriating than needing to start up your experiment or your build in a particular order in order to get things to talk so one of the things I always try to do is make sure that communication is a asynchronous in a way so it doesn't really matter what order things are powered up and we should also be sure that any data that is left in any buffers anywhere isn't going to causes any problems we could have a sequence of bytes that represents an instruction so perhaps we specify a joint number followed by a command followed by a value this is a valid option why not so we specify we want to open the claw and we want to in this case move because we may have different move options later down in the line and we want to specify a particular angle all of which represented as three bytes on paper this is excellent but in practice does suffer from some problems let's assume one of the bytes didn't make his across the communication perhaps because a device has been powered up at just the wrong time if our program on the microcontroller is always expecting three bytes to occur in a particular order it will now adjust assume that those bytes are correct even if they actually started here with the move command there's two scenarios here that can play out firstly this third byte might never be received so the micro controller simply stalls secondly and perhaps even worse is this move command could be interpreted as a joint number and the value could be interpreted as whatever symbol was used to represent the move command so suddenly we've got a situation which is quite unsafe we could either stall the microcontroller by starving it of data or send it commands that interprets but the quite dangerous commands to actually execute so it's worth spending the time to think about what is it that your application actually requires so for my robot arm I've devised a 2 byte protocol the first byte that gets sent is going to represent the joint number and the second byte that gets sent is going to represent the angle for the target of that joint I'll call that joint theta but I'm going to explore the nature of what the data in these bytes is going to represent I know that my joint angle can only sensibly represent it by minus 90 to plus 90 I'm going to do something a bit strange here having a negative number means I might have to worry about sign bits and stuff like that so I'm going to offset all of this by 128 so that really means I have an effect of range of 218 as a maximum and 38 as a minimum it's very easy for me to subtract 1 to 8 from this to get back to the original 90 to plus 90 but this also gives me something interesting it means I've got space either side of this range with nothing in it bear with me I've only got six joints in the system and so my zero to six value never overlaps with the range required by the joint theta this means I can do a check for every point that comes in I can check if the bite value is less than ten for example then I know that I'm representing a joint number but if it is greater than ten then I know I'm representing a joint theta this way it doesn't matter really what bytes the system receives first because it let's say it receives a joint angle that's going to be greater than ten it's just going to reject it so just by examining the data we've come up with a way to make it robust against startup order yes bites might go missing but ultimately it's not going to damage your stall our system win-win the embed has access to the UART pins directly but you really want to use them directly you probably always want to run them through a buffer first just in case um bed is doing something else and can't respond to the pins being activated for UART transfer so I'm going to use a library that's provided by some other person in the embed community and that's one of the brilliant things about the embed community but to handle that buffer for me so I'm going to go to my robot arm project import library and go from import wizard which pulls up this window and in here at the library that I'm after particularly I'm just going to type in UART and click search and we'll see what it comes up with and the first one that comes up is buffered cereal so I'm going to use that and to select it and click import now the nice thing about the embed environment is that it's basically also get in the background so all of the libraries and things can be updated automatically and if somebody else in the community changes their library I get a little notification in here that says this is ready for update but the buffered serial library has given me two files dot H and CPP so I'm going to include the dot H file at the top and I'm going to specify a buffered serial object I'm simply going to call it UART and I'm going to pass to that the two pins I'm using for receive and transmit I could also specify to use the USB connection too but you need to download a driver for that but in this case I'm going for two regular pins because I'm just going to connect those pins directly to the Bluetooth module by default this UART is already configured with a baud rate of nine thousand six hundred and an a-10 one protocol as is the Bluetooth module so I need to do nothing else in order to use it so I'm going to go down to my int main and start filling in how we read from the UART firstly I'm going to create a temporary variable called target joint and I'm going to interrogate are any bytes available in the buffer for my UART and that's done with the readable function if there is a byte available to read then read it please answer get see if the value of C is less than ten that we know that that's our target joint and if it's not less than ten we know it represents a joint theta so I'm going to take the joint object for the target joint we've just temporarily stored and set its angle remembering to offset by minus 128 to bring it back down to a minus 90 to plus 90 range and that's really it that's how simple our imbed program is going to be obviously having a microcontroller unit and Bluetooth module on their own is not going to do anything very useful we need to somehow connect them together and to do that I'm going to use prototyping breadboard this heap of spaghetti is the breadboard but I've pre-wired ready for our arm now if you're not familiar with breadboard the way that it works is all of the dots along a particular row section are connected so these these are all connected and these are all connected and these are all connected but as she go down the columns they're not connected and this allows you to conveniently create quite complicated circuits where multiple wires are connected to single locations now the Bluetooth module lives over here so I'm just going to make sure that this red wire which is my VCC ie the power for the Bluetooth module it's connected to the same row as that power in on the Bluetooth module so I'm just going to push that in there and the big empty space in the middle here is where the embed is going to sit it's it's this way around and if you remember from the card all of the people we went but I'll show the card all of the PWM signals are along the bottom right of the module the little pink box there if it's not visible on the camera and they correspond to these six cables here so I'm just going to make sure that that's pushed in properly and aligned up there we go almost click so the people um is now coming out of the module and going to this header here this is an angled 2.5 4 mil pitch header or 0.1 inch - you Yanks and I'm using this to connect to the individual servo connections I have six servos and each servo has a three pin connector so here I've got eighteen pins and they correspond in order to the repeating sequence of signal followed by power followed by ground signal power ground signal power ground etc etc all the way to the end and I'm taking the power ground directly from the input so I'm going to power this board with a six volt power supply and that gets split from here so the power on the grounds go straight to the servos and then it's also split to the embed module so the N bit modules being powered off six volts - but it's okay with that the module itself will provide a 3 volt 3 output for me to power the Bluetooth module because I don't want to overpower the Bluetooth module even though it says it is parable by 6 volts if I have any problems with it perhaps I can power the Bluetooth module directly off the supply - however the servo supply is likely to be quite noisy and unstable simply because it's got motors attached to it and given that I know nothing about the quality of these servos for the motor aficionados out there I don't really know if they have any capacity for handling back drive so if something some inertial load drives the servo I could quite easily see my power supply railspike quite highly here and I don't want that spike to propagate onto the Bluetooth module because I know that that's got a maximum of 6 volts so I'm using the regulated supply off the EM bed to provide 3 bot 3 nice nice and isolated from the rest of the system here is one of the connections from the servo and orange was signal red is power Brown is ground so they're just going to connect directly onto these three pins like so so here you can see I've fastened the circuit board to the side of the robot arm because the cables aren't quite long enough and it's still got the USB attached to it at the moment but I'm also now just going to switch on the power now keep my head out of the way because if you remember the first thing that our embed is going to do is set all the target positions to somewhere near zero of the range for each of the servos there we go that's quite exciting wasn't it let's start work on making the host application and we're back in familiar territory now this is a pixel game engine instance were constructed to 400 by 400 pixels where each pixel is to screen pixels wide so it's only going to be a small window but I've got overrides fully on user create function and on user update and I've also added 1/4 on user destroy which if you didn't know already exists it's there for closing up when you click the close button and I'm not going to dwell on this too long I really I'm going to be quite quick going through the code what I want to do is present a series of sliders that control each joint and to do that I'm going to do a first for the channel I'm going to use some third-party code and this is a GUI library extension created for pixel game engine by a member of the disco community called sleeping bear he also has a YouTube channel and I'll put links to both this code and his channel in the description below and this just allows me to quickly throw some familiar GUI components on the screen so I'm going to add an instance of his gooey container object and they might on use a create function I'm going to add six sliders one for each of the joint so I'm specifying the X&Y location of the slider and its length and I'm also going to specify some default values now the sliders in this naive implementation go from 0 to 100 regardless the length is the physical length on the screen so I'm going to take the 0 to 100 and convert that to minus 90 to plus 90 so the numbers on the screen aren't accurately going to reflect what angles the joints are at but all I'm really after here is a quick slider in on user update I need to tell the GUI components to update themselves and then I'm going to clear the screen to Walgreen in this instance and I'm going to tell the GUI to go and draw itself so the GUI extension is really quite nice and encapsulated like that I don't have to do anything else it's all going to look after itself but it's in on user update I also want to do some interesting things so the first thing I want to do is get the angles from all the sliders well I've got 6 sliders so I'm going to create an array of 6 floats which represents the angles I'm interested in and once the GUI has been updated I'm going to iterate through all 6 sliders get its value and scale it to between minus 90 and plus 90 but what we're really interested in doing here is transmitting this value to our embedded system and this is where things are going to get a bit Windows II I'm afraid it is a similar process on Linux so the syntax is a bit different given that I've included as part of the pixel game engine windows dot H in this instance I've got access to various operating system file routines and opening a comport is really simple in fact to your program it's just going to look like a regular file stream so I've created a handle H comm and set it to null pointer and in on user create I'm going to open the comport now on my system the compost is comm 3 it will be different on different systems you'll have to look at device manager or similar to work it out but creating the compost is actually quite simple it's done in a single line of code and I'll talk you through it so it's the create file function-- and you pass - it's the address of the file in this case we want is comm 3 and we tell it we want to be able to read and write to it we're not actually going to read from it in this particular application though if we wanted the embedded system to return information to us to display we would want to read to it so I'm going to leave that there and then we specify typical file attributes and parameters particularly we want to open existing we don't wanted to try and create a new comm 3 port if that fails it doesn't manage to create it we just want to return false at this point and the application will exit so that is it that is all this required to open the comport we just treat it like a file specifying the properties of aur requires the use of the rather curious DCB structure I'm not sure what that stands for if you know please enlighten me but I'm going to assume it's something like device control buffer or device control block but anyway this structure contains the properties that we need to set to specify the UART now the comm port will already have some properties associated with it so I'm going to grab those using the H comm handle that we created earlier and I'm going to overwrite the properties that I'm interested in setting from my system namely the baud rate at 9600 the number of bits in our bytes a stop bit and the fact there's no parity this is the 8 n1 specification and then I'm going to rewrite this structure back out to define how that comport should communicate when you're done using a comm pot you probably do want to close it this is very simple it's just a call to the closed handle function there'll be an equivalent set to all of these functions on Linux writing the command via the comm port is quite simple we've got six joints and we know that our protocol is going to be two bytes per joint so I'll create a character buffer 12 bytes long and I'm going to populate that buffer with all of the information required so the first byte or all of the even bytes including 0 are the joint number the odd bytes starting from one of the joint angle offset by 128 because remember that's what our protocol requires so this will give us a buffer of joint number joint angle joint number joint angle joint number joint angle all the way for all six joints I then want to periodically right this buffer to the system now on user update is going to run very very quickly far faster than the rate our UART can communicate at so I want to do something on a particular tick I don't want to do it every frame and I like to do this by accumulating every elapsed time so I'll create a variable called F accumulated time and only when that accumulated time variable is over a fixed amount do I want to write anything to the hardware remember at this point to also subtract your weight amount from accumulated time so this gives you a very precise tick regardless of the frame rate of the application writing to the device is very simple I need a temporary value called BW which is going to represent the number of bytes that have been successfully written by the following command which is write file so this is a standard file write command on Windows it takes the handle of the comport it takes the buffer how many bytes we want to write and it will return to us how many bytes it's successfully written now if I was doing this with the professionalism of somebody that works in industry I would check to make sure that the number of bytes written is actually how many I think it is and if it hasn't been let's say it's only written 5 bytes out of the 12 I would then try and call this again starting from the fifth position and working my way through the buffer however I'm reasonably confident it's going to successfully write all 12 bytes this is not a particularly large demand so in the name of clarity I've not put in any buffer checking here and that's fundamentally our program we get values from sliders that are going to be on the screen we create a command string from the values of those sliders and the angle of our joints and then periodically in this case every 50 milliseconds I'm going to write that command string to the hardware so I've just powered up the robot and you may hear a faint buzzing noise in the background that's the servos and I'm now going to run the application that we've just created and we can see sort of jolted into position that's okay that's all of our slider values being centralized so I'm going to start at the top with the claw so I can't remove the slider and I get an instant response from the cloth the next joint down rotates the claw the joint after that is like a wrist joint so that can move the core backwards forwards the joint after that is like an elbow joint and the joint at the bottom is a shoulder joint to make sure this stays in the video feed I think it's okay the shoulder joint and the final servo is sort of shoulder rotation joint so I've overlaid these sliders with the actual application or I think we can see it's very responsive system and so that's sliders from an external pixel game engine extension library opening a comm port talking through virtual kompot via bluetooth the Bluetooth is talking very UART to the embed controller the embed controller is running C++ code to set the PWM values for the servo motors and the servo motors are actuating the individual parts of the robot I'll just try and position that devil wave it around with as you can see driving the robot is not as simple as it should be but also notice the robot is wobbling all over the place and it's quite jerky mainly that's because it is quite a cheap robot but secondly we have no trapezoidal acceleration curves and that might be the topic of the next video in this series is how do we actually create proper smooth motion curves rather than just slamming PWM values around quite an important thing to do when working with robotics systems so if you've enjoyed this video a big thumbs up please and have a think about subscribing of course I'll put all the source code on the github and link to it below I'll also put the embed source code as part of the pixel game engine file we've just created on the github to a big thanks again to all of the patrons that have made this particular project possible I've had lots of fun with it and so I think for this video that's it take care and I'll see you next time
Info
Channel: javidx9
Views: 52,759
Rating: undefined out of 5
Keywords: one lone coder, onelonecoder, learning, programming, tutorial, c++, beginner, olcconsolegameengine, command prompt, ascii, game, game engine, pixelgameengine, olc::pixelgameengine, micro controller, robotic arm, robots, embedded, arduino, mbed, arm cortex m3, lpc1768, UART, pulse width modulation, pwm
Id: ekdQ-aAB36Y
Channel Id: undefined
Length: 53min 15sec (3195 seconds)
Published: Thu Apr 18 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.