Arduino Programming Tutorials || Collecting multi-digit values using while and Serial.available()

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to this tutorial on collecting multi digit numbers sent from the serial monitor to the Arduino using the while loop command structure and the inbuilt serial available function many people watching this video have probably already figured out how to capture single digit numbers from the serial monitor collect them store them in a variable and then have that variable enter into other parts of the code and trigger various events but maybe all of them haven't so will could take a brief run through with this program what it is is a simple echo program a single digit single digit number or alphanumeric character is sent from the serial monitor to the Arduino the Arduino does a conversion converts it from the ASCII code to an integer and then it prints that particular number back to the screen so it's an echo program so if I enter a 1 and click enter it gives me a 1 back it confirms whatever I enter it echoes and this is the first step in establishing numeric serial communication between the serial monitor and the Arduino and it's a neat little program it's nice it does perfect as as good as one might hope for with single-digit numbers but what happens if we want to send a multi digit number say the number 15 to the Arduino what is this piece of code going to do well let me reset you're doing a creator restart and so let's enter 15 what's going to happen well oh no it printed the one on the line and then it printed 15 on line I want a number equals 15 it would do the same if I sent a big number it strips that number into individual digits and then prints each one on a separate line which is not what we want if we want to collect multi digit numbers and then have the whole value to use somewhere else in the code so this piece of code won't cut it so how could we clean this up and what additions could we make to this little piece of code to achieve the goal of collecting a multi digit numbers say 15 or 2015 and have that sent to the Arduino the Arduino makes sense of it store it in a variable and then be able to use that number late in other parts of the code well the first thing we do is just brief review what's going on in this particular code well there is a number it's of the integer type this or it's a variable name number of the integer type that's assigned the value of zero it doesn't have to be sign the value of zero it could just be initialized here rather than have an assignment the code will still work but it's always kind of nice instead of leaving it hanging here at this point the Arduino has set aside a block of memory that corresponds to the size allotted to the integer type variable and there's a name attached to that block of memory but there's no the value could be anything left in those registers we don't know what that value is so in order to know what it is all we have to do is assign that value zero now wing up and that's just good practice then we move from this global variable to void set up and there's no mystery here it's just a serial connection is established between the Arduino and one's computer and there's a brief delay here this just gives the connection time to stabilize that the Arduino doesn't immediately try to start pitching these strings down the serial line and it's only 50 milliseconds but that's a lifetime in terms of computers and microcontrollers so 10 mils milliseconds would probably be sufficient but the next is there's a serial print line commands all they're doing is this escape character with the end some people may not be familiar with that but all that does is say print an empty line and then print the string and then the print line is going to print another empty line after the strike that's all this does is prints empty line ahead of where you are you can use this escape character at the end too if you want to and print an empty line and another one well the next one and this is just a simple user instruction to set the serial monitor to no line ending sometimes you need to don't know one ending sometimes on new line ending and that's not clear oftentimes just by looking at the code so it's always nice once you figure out which setting you need to go ahead and just send a brief string to the monitor to let you to remind yourself or to remind your user what's happening is there a special condition I need to do before this program is going to behave correctly yes in this case you need your serial monitor on no line ending otherwise you're going to have a newline character that goes through all of this and you'll get errant values so the next thing is just a simple thing enter a number simple user instruction from the setup we move into the void loop where the magic curse number that same number variable that we saw up here is assigned the value of zero well the first time through the loop it's already going to have the value of zero but after it goes through the loop there may be some trash values that have collected especially once we start sending large multi digit numbers there shouldn't be but there may be so it's always nice that the beginning void loop go ahead and establish that yes number we want it to have the value of zero at this point then we have while cereal is available or it is equivalent to zero do nothing well what is this actually saying that it's a while loop structure and this is the while loop test is basically testing see what is the return value of this inbuilt serial available function it has a return value that's what this is capitalizing all the serial available function is inside the Arduino serial receive buffer where anything sent down the serial lines collecting in the Arduino when that buffer has anything in it serial available will return a number higher than zero so what this is basically saying is while that buffer is empty it's and it's returning at which it will be returning a zero this function will at that time do absolutely nothing well that's good and this has the nice advantage that given that it's in void loop and it's sent here that as long as there's nothing in that buffer did void loop is not going to go past this line until we send something through the serial line so now down to the next step is we have this while serial that's available this is slightly ambiguous in the way it's currently set up is that it depends this corner high for me your person is with the way the return values of serial available works that what this is saying is while there is is at least one byte of data in the Arduino serial receive buffer while it's in there execute this cut and if you could make that even more explicit by adding something like greater than zero in there I mean we just saw that it worked without this stroke without this compare comparative operator in here but it's still that's nice well it's still work since it's been added we can upload the code just verify and open the monitor and enter a single digit and it should echo those single digits back yeah it's still functioning nothing is nothing has changed as far as outward behavior goes so this particular addition is not going to change the outward behavior but it is a whole lot more explicit about what is happening here namely whenever that cereal available return value is something besides zero which remember if it's zero that means there's nothing in the Arduino serial receive buffer there are no bytes of data in there well whenever there is a byte of data in there the return value will be greater than zero and then at that point this test will be true which will kick the while loop off and start the rest of the program when you when this was out of here we were just saying well whenever this is true go ahead so it's a matter of preference but I tend to like to be as explicit as possible on the code if it's possible to be well after it gets into the while loop what happens well we have a at least one byte of data in the Arduino serial receive buffer so we want to read that by as soon as it's red it's out of that buffer in it's dumb unless we assign it to some other variable and in this case we've created this one we've initialized it as a byte type variable called incoming namely the incoming buy of data or the incoming data and well you could just as well have used the character type here it would work too by just is the way I think about it there's a byte of data sitting there so you know and it's up to you but it's also kind of helpful sometimes to think about it in terms of a character because it is a particular sort of character that's going to be received and read it's not going to be a it's not going to be just a simple emptor integer and you know you'll mess up every time if you think it is it's actually an actual ASCII version of a character in the ASCII code so what happens is the first bytes read is stored in this variable then we get to this point and this is where that ASCII code we're removing it or converting pulling it off the amount necessary to convert the ASCII type character that we received from the serial monitor to an integer type variable number is an end so it's going to convert the incoming by it'll be a single digit at this point into a true single digit that's of the integer time now how does that work well there's tons of thing tons of discussions of it ultimately ASCII coding is 48 off of integer and that's what the integer value of the zero ASCII character is so if you subtract this character of zero or you subtract 48 it will convert whatever this number is into an integer integer equivalent and then we'll dump it into a true integer variable so that's just something it's kind of it's it can be a little confusing but there's a lot of discussions on it um then we take number and then we basically print it to the screen so once we've once there's a byte of data in the buffer the receive buffer the Arduino that byte is read it's pushed over and assigned to this particular variable this variable drops down we pull up we subtract the necessary value to convert it into an integer store it in number and then we print number its echo so whatever comes in gets echoed back out now as it sits this isn't the best practices way to do this for one thing we could we could add this and make it add things to this piece of code and make it better one thing we could do for sure that doesn't really with a single digit doesn't really make a lot of sense but once we start picking pushing multi digit numbers it's always kind of helpful to make sure that that buffer is completely empty by the time we get to this point because we don't want something to still be hanging out some byte of data in that receive buffer because it will immediately kick it through here and we may you know and we want it to be zero and Pauls long enough for us to enter a multi digit number and then it read that particular number not whatever trash values are in the receipt so the easiest way one easy way to do that there's always many ways to anything with code is we can say while serial available is greater than zero at this point so if there's something about or multiple bytes of data is still in the buffer and after it's been all the way through the loop and roll back around then well what do we want to do well we want to read that so easy enough all you'd have to do is say um let's say yeah as long as it's greater than zero you just serial read and then it's probably helpful to give it a certain amount of delay there I mean you know 100 milliseconds can do a lot less probably and it's still probably work perfectly fine but and what this will do is if there's any trash values collected in the Arduino receive buffer it reads them but it doesn't assign them to any variable so it just throws them away it's basically this is a flush serial flush flushes the transmitted buffer this will flush your receive buffer this these are the lines of code which is really helpful so this is like serial flush for receive buffer and it's really a good little piece of code to know and have on hand so the rest of it's okay this stuff here's perfectly fine we can keep moving but one thing about this piece of code as it currently stands is it doesn't really catch what happens when a user enters like a letter what is it going to do well let's see we can upload it given that we've modified it make sure there's no syntax problems the compiler will definitely it'll catch most of them so now we were supposed to enter a number well what happens if we enter a number it's no problem what if we enter the letter a move 49 what or if we enter the dollar sign look that minus 12 that's not what we expected that's because it's giving an ASCII equivalent to the letter A or something you know in the range but now you got to keep in mind it's also subtracting over there that 48 from that letter A and then 49 is the results so you're not really even getting the ASCII equivalent to the character a you're getting the ASCII equivalent to the character a minus 48 which is that 0 character and in this case this - well well that's just because that dollar sign had a really low ASCII value it was a value that was below 40 a and yet we subtract 48 from it so the result is a minus number so that's not really that great so we can weekend all that up you know make that a little better so where would it matter where would we need to add some some testing to eliminate the possibility that letters would actually be read into this stuff is we can do it right under the serial read that's the best place to do it because we can test this incoming byte with just characters we can say something like if incoming is greater than or equal to the 0 character and it's incoming this will create two boundaries for it is less than or equal to the 9 character remember what's read in and stored there is a type of character that if that's the case then what do we want to do well we'll do some we'll do our conversions but let's go with the else first off what happens if it does if it's not a character digit it's not a single digit character 0 through 9 what are we going to do well maybe we want to tell the user like serial print print line um something like in valid entry try again and that should be clear enough that the user would they receive a message like that they'll be the old well something something not quite right here or something something went wrong so we can throw an escape in there just to make a space we may or may not need it but it'll throw a space above this string and you know I mean you know we can be doubly safe and clear out plenty of space that'll dump two lines underneath it one for the print line and one for the escape in so that should work and so this will execute if someone enters like a the letter A or that dollar sign etc etc it'll catch that and won't let it convert it and print it to the screen so now what do we do so we need to do that conversion here was part of the conversion but at this point we want to collect and an add on to our number we want number to be assigned but what we want is say number of times 10 Plus this incoming character incoming - ASCII character zero and what will this do well since we've added that incoming - zero this we won't need anymore we can get rid of here and what does this do this is kind of confusing to people that come to this for the first time is they're like okay how does this exactly work cause this is the magic this is this is the magic of the multi digits with while loops and serial available it happens right here so what is actually happening well let's think about it so if we go scroll up just a little bit if we go to the top of void loop say that at first numbers at zero then we flush out the serial received buffer on the Arduino then it waits for a character while that's waiting for character then we send it say that we send a war of 15 a multi-digit thing we send a 15 here well what's going to happen is it's going to pick up that first bot that first bite for the one gonna read it assign it to incoming it's still going to be an ASCII format and then but a1 will be between 0 and the 9 our boundaries so it'll pass the f-test then it'll be dropped down here and there will be a 1 here but it won't be 1 it'll be a character 1 and so well what is the equivalent of that and I have a sheet over here it's 49 so if we send a 15 the very first character that's going to come through is a 1 and it's going to be have the ASCII value of 49 here it's gonna be just like this inside these little blue single quotes it'll be 49 so it'll be 49 minus this is a 48 value so it'll be 1 I'll be left over and then this is going to be added onto well whatever this is well the first time through the loop number is 0 so 0 times 10 will be 0 and so they'll just be a 1 left after this calculations performed that'll get assigned a number and then it'll keep on tricular trickling down but we haven't closed this out yet like we would not want it to print right at this particular time if we did it would print the 1 so you won't take that out we'll need to put our print somewhere else you know we'll put our print on after see the while and this is the last price of the while we want to print here serial print line number equals and then serial we'll do a print line here with number and then this will just be a straight-up serial print which that'll be good enough because what it'll do is I mean we could even escape it out put a space ahead of that if we're gonna - doesn't matter um but what will happen is this wild loop will repeat as many times as it needs to and then when it has exhausted its see what's in the serial receive buffer it attacks it come down here because this will turn fall when there's nothing left in the serial received buffer this the serial available will return a zero value that will not be greater than zero so the while loop will exit and then it will kick out our number right here so well what happens so say we're going back to that 15 the first pass through we assigned we sent a 1 we put a 15 through the serial monitor that means serial available is greater than zero one is read the very first by is read it's pitched over here it's in a character format so it's really got the value of 49 and then but either either way it's a one character so it'll pass the if test but it's integer value or what you might want to think of is it's entered your value as a 49 48 will be subtracted from it which leaves one here then that will be added to well 0 number 0 0 times 10 which is 0 so 1 and then number will be 1 and then it'll go all the way with this while loop and it'll get down to the bottom of while loop right here and well the this condition will still be true cuz there will be that 5 float you know sitting right there at the edge of this Arduino serial received buffer and so the serial available will return a value higher than 0 which means the 5 will get read assigned to incoming 5 is between the 0 the 9 but then 5 has its own ASCII value which is 53 so we're going to have 53-48 which just happens to be five and so it's going to be added but keep in mind that number at this point has the value of one so ten times one is one that one value gets shifted over one space which is exactly what we want and then five is added to it which makes fifteen which is assigned a number then it rolls back through hits the bottom of the while loop goes back up well given that we put a fifteen in there it is read both of the bytes as soon as it reads in those bytes are pulled out of the buffer never to return to it again then so this will return a zero value which is less than zero and this while loop will terminate kicking it out to these print statements and that's no the long winded but that's the play-by-play of what is happening here so given that play-by-play this should work we should be able to put a multi digit number into the serial monitor at this point once we upload this code and it should echo a multi digit number by so let's upload it no compiler errors that's a good sign I didn't leave off any parenthesis so yeah just one last look okay so now open the serial monitor and we get the same prompt and it tells us to enter a number but this time let's start with 15 Oh what happened look at this we've got a break here that's not what we wanted we wanted it to be on the same line what is happening here this is one of those gotchas with the Arduino this is this is where and it's not just there do we know that this happens I'm gonna actually take this gal the spice aisle I don't like that but um but this one of the gotchas that what is happening is this is running so fast that serial available gets triggered and that one in the fifteen gets sucked in passes the f-test gets converted stored in number and this is going so fast around that before it may it has a chance to its like before it can pull another serial read pull the five in it actually ejects the while it comes out that serial available returns a zero value it doesn't have enough time to even recognize that there is something still in the buffer and it ejects the one down here so there's so what we need is a brief delay we need to delay this short enough not to hang everything up but long enough to give it enough time to recognize the serial available when it at you know when it kind of pings the serial receipt buffering the Arduino give it enough time to recognize that there's a five setting in the buffer simple to do but something that is frustrating if you don't know to do it so we can do that delay a five should work five milliseconds just think about that five milliseconds that's a lifetime keep in mind for my throat so now will it work let's see all we've done is added to delight everything just have one little fun little thing delay so we need to enter a number let's enter 15 how about that 15 shows up it was just because the reason and we can check this put a larger number in there it doesn't matter just to show that it does work it'll work how many multi digits up to the only limitation is that we are using number is the nth time so we can't enter a number that's beyond 32,767 that's the allotted memory space for however many bytes of data it would take to make that particular number in the Arduino memory that's as many bytes as we have that we can fill up so well what does that mean in practical terms is it if we enter a number over say is 32 767 is the specification so we should enter this and it should show and it does 32 767 well what happens if we go 32 768 which would be 1 over what the nth type is the memory allotted to the nth time well that was not good I'll shut it down sorry so 32 768 enter oh look at that it gives us 32 768 but it's negative it rolled over we rolled because the hint is an unsigned it's signed in this case we haven't said that it is an unsigned integer so that that will determine how large of a multi digit number will be legitimately accepted by a echo program like this or any sort program you could take those one thing to always keep in mind a serial print is just a way to say we've captured a variable from the serial monitor and we're doing something with it you could be sending this number off to all kinds of other special-purpose functions doing all kinds of other things without trying to see rahman irr you could be controlling servo positions you could be controlling the rate of motor speed etc etc so don't think serial prints all this is good for by any means but so but now let's think about that what would happen if we just made this an unsigned int in principle that should double the positive numbers we should be are non-negative numbers we should be able to enter enter into the serial monitor and it echoed by so upload this and let's check it remember before we were only able to enter the 32 767 well what would happen if we go unsigned that she'd be mostly doubled of that so that would be somewhere around 65 35 so that should print to the screen and it does this the unsigned keeps it from going negative you know if it didn't roll over now what happens if we go beyond this which is the limits of an unsigned int well so we could go 65536 enter and it goes to zero see we get a trash value that we exceeded the bounds of an unsigned int which we can go bigger though there's nothing that limits us but that particular whatever we decide to type the number variable so let's make it as big as we can say unsigned long that's the big number in the Arduino microcontroller world so let's upload it and check it I'm with Sara mark so the number that corresponds to like a memory space that's been set aside for the unsigned long should be able to store a number that's this size two nine five that should be as large as our numbers we could enter in dinner so let's see does it bring them successfully yes it does that's the max though if we go one over that so forty two ninety four nine six seven two nine six instead of nine five let's go nine six what's going to happen you know we're gonna get another trash value so that's as large of a number as we could do with this particular program the way it's currently written and we don't have anything else besides that unsigned long it would really be usable for us so that's our limits but think about that that is we could enter a number all the way from zero so let's enter a zero so we can enter the number zero all the way to that gigantic number and so that's a lot of multi digit numbers to work with and to sign into code and that's kind of helpful but most of the time you don't need it that much most people never need more than the end I'm just going to go back to the end just for simplicity but just know that you do have the unsigned int type you have the long and you have unsigned long you can try any of those depending on your application but though you can exceed the unsigned long that'll be the biggest number you can enter into the serial monitor and have this program pull it in and parse it otherwise you'll be exceeding the memory to the time and then you'll be getting trash values so that being said here's the program it works I mean all we have is our slowdown so if you almost fall so screaming and recording you know copy any of this stuff there's all it's happening we've got one global variable that's what's happening in setup and then employed loop there's the code and really the magic to it all occurs from this while down to the F because there's where you're greater than while this is where there's data in the serial buffer serial receipt buffer in there do we know and then this is the processing of it so but what about if we wanted to not have void loop junkie like this all the stuff and void loop can we make just a simple special-purpose function for this sure so that we could call this multiple times if we wanted to so that we want to pull in a multi digit number at one point in the code do some other things and then pull in another one later that would be totally possible granted it's just one multi digit number would be pulling in at a time and processing and assigning which there's other ways that you can in it you know you comma separated values but at this point let's just think simple pulling in one multi digit number of time how can we convert all of this into a special use function that we could call multiple times well the first thing we need to do is decide on what return type do we want that function to have well whatever that it should match whatever the return type of number is because ultimately that's where what we're going to return what comes out of our special function into we're going to give it back to number so numbers an nth type so let's just be can we need to be consistent with whatever if you do unsigned long the the UM return type will need to be on sign long but for our purposes I'm going to do int then let's just make a simple gift multi digit number function we don't need any parameters so we could leave this empty or you can always go void which means nothing here if you put void in front of it like we're void loop it's like it has no return value and if you go void in the parameters it means I it has no parameters you know so now we just close a function down so what do we need to put in there well we could put basically always we won't need this stuff in our prep function but all the rest of it we would so let's just take this stuff cut it from void loop and then paste it into our special-purpose function and now all we would need is we've got this function all we need to do is call it so we can go to void loop and we could call this function so you get multi digit number we want to get the number so call the function and then what do we want to do well this thing returns when we haven't put a return value so where do we need to put the return let's see we just chase our parentheses there's this that's the light that's the while so underneath it right at the very bottom and before we hit the bottom brace of the function will want to return what well number so let's return number and this will take the updated value of number and send it outside of the function so that we can when we call it we can catch that updated value with number and store it in number and then given that numbers of global variable this will work perfectly fine we oh this will run all of the code diff serial - via the serial honor it'll take what's given from the serial monitor process it out pull off the ASCII stuff convert it to an integer and you know and keep adding on until it accumulates that number that's here will eventually empty out the serial receive buffer on the Arduino and whatever the number is by that time we'll get kicked out of the while loop the while loop will go to fall it's here the test will fail it'll kick that number out and that number will be grabbed and returned once it's returned to be handed off the number and then we can go serial print number and we can get feedback again so this should work this should be a simple little special focus function so upload it and check the serum honor everything should still work exactly like it did before as far as outward behavior go so say I enter that number it kicks it back out I could enter others doesn't matter as long as I don't exceed that integer it should be perfectly fine and like I mentioned multiple times if you want it to be able to enter larger multi digit numbers you just need to change the type of the number variable unsigned long will be as big as you can go but if you change this time you'll end up having to change the return type change this to match whatever you change the type of number to the number type variable too and it works it'll continue to work so that's just a way to create a little multi-purpose function so you could do this so say something you could do just to verify let's say the first number entered will be equal and then you could call number again so get or you can call that get multi digit number again and then serial bring up the second number equals number and now we can run this function so let's run this piece of code and when it hits void loop it should grab the first number we enter in the serial monitor assign it to number and then print that to the screen then it'll call they get number of fun multi digit number again assign that back the value we've entered to number basically it'll just overwrite change the value in number and then it should print second number so let's see if that works or if we need anything else so the first number we can enter is like say 1200 first number equals 200 say the second number could be 25 36 second numbers 25 36 now what's going to happen if I enter stuff again well it's employed loops so it'll be the first number again so 362 should be first number it is 78 45 perfectly fine could be 10,000 it'll be back your first number yep can see so you so that's the beauty of having the little multi-purpose function every one of these function calls now takes some where I am and it takes some bytes but at least it gives you the ability to pull in a multi digit number in multiple places in your man in your main void loop and so you may have one set of instructions here like doing doing blah with you know the first number like number one and then here you could have a totally different set of instructions doing something totally different doing la tube with number with the second number I'm just using number two to mean second number and that that is that is the beauty of creating a little special-purpose function and the only tricky part to it is you've got to keep in mind whatever return time you're going to hang out front of your special purpose function it's got to you know it needs to match whatever the type you've assigned to that number variable you know I mean there's ways to work around that too but the matching it is the most consistent way to go so I hope this tutorial has been helpful of how to collect multi-digit numbers one multi digit number at a time granted not the fanciest but still very useful at times to people especially if they're struggling to figure out how to do it at all so I hope this tutorials help with this there is of course more ways than just using while on the serial available inbuilt function to do this particular procedure and then if people are interested in those I'll be more than happy to do some tutorials about it until next time
Info
Channel: philo mech
Views: 17,821
Rating: 4.8392859 out of 5
Keywords: how to use while loop, how to use Serial.available(), collecting multidigit values/numbers, philomech, unsigned long, Arduino serial communication, multidigit values, converting ASCII characters to integers, Arduino serial monitor, philomech tutorials, How-to (Website Category), Tutorial (Media Genre), Serial Communication, Arduino (Brand), programming arduino, Serial.available(), function return value types
Id: tlMbca59Q-M
Channel Id: undefined
Length: 43min 0sec (2580 seconds)
Published: Sun Jul 20 2014
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.