Tech notes: C# serial programming (PC/Arduino)

Just another WordPress site

Tech notes: C# serial programming (PC/Arduino)

now these tech notes present two different techniques that can be used to interface the serial port to a dotnet application in this case I am using a virtual serial port connected to the USB port I am using c-sharp 2010 under windows 7 service pack 1 first I want to discuss a little the testing environment I am using an arduino nano compatible board called the DCC do we know it is basically the same functionally as the arduino nano except that the DCC do we know uses a CH 340 chip to accomplish the interface between the USB and serial protocols the the nano is programmed with a small sketch which basically accepts these commands that are listed here and on this table I which are the asterisk order digit 0 to 6 in it returns back a certain sequence of bytes for example if you send it over an Asterix which I call the high-five command it sends back a plus sign if I send it a 0 command it’s gonna send back one byte if I send it the 3 command is gonna send back 8 bytes and so forth and these bytes were always be starting with 0 such as 0 1 2 3 and so forth I should mention that my application in c-sharp actually gets back the ASCII equivalent so for example if the sketch since pact is 0 and my application is going to read a 48 now I’m gonna bring in the device manager and a small video window here and I am gonna hook up the serial device let me get that ok as you can see it’s just a typical non new board and I’m going to connect it now watch what happens here and once I connected the device manner manager automatically updates and now we have ports so now let’s have a look let’s see what’s inside that port there and then section and as you can see a it clearly it identifies it as comm 5 and it also presents all the information about it specifically on the chip the three-four teacher okay so now that’s that’s looking good so I’m now going to remove these guys here and we’re going to go to the Arduino IDE to test it the first thing we need to do obviously is to set the port that’s very important otherwise there’s no communication as you can see I only have one port here comm 5 so that that’s a no-brainer however if you had more than one port here you have to select the one that matches the one that was listed in device manager when the device was hooked up I should also mention that this device has been hooked up before so that’s why Windows recognized it immediately okay now what I’m doing here is I am sending it the asterisk and the high-five and let’s see if it gives back the plus sign which it did and that’s very nice now I’m just gonna send it a five command and should bring back 31 numbers which it does obviously without the newline carriage carriage return characters so I know that my testing environment is working correctly now I need to have a c-sharp application which will all also do do the same things that you know that we did here in the test environment ok Here I am loading up the source I’m just going to do a quick walk through just to give you an idea what is involved it has the usual set up and loop functions and the set up function I am initializing the serial port and I’m also initializing a pin to be used with an LED I’m setting up my variables and here’s the main loop basically it’s a switch statement and it interprets or whatever the host sends so here I have various options if I am sending a command how 0 through 6 it simply sets up the number of bytes that the sketch is going to send back to the host there’s really nothing complicated here it’s really straightforward Here I am ready to send so what I do is I turn on the LED and I send one byte and every time that this loop is gets executed I’m gonna send a byte in another body until we’re done and now here I’m checking to see whether we’re done if we are I’m returning back to the initial state I’m turning off the LED otherwise I’m gonna send over a character to the host now here I did have the option of using the print or the right I chose to print to send it as a number and not just as a char and was it I send it I increment a counter and finally here’s a different state here’s where it receives the asterisk so what do I do I send back a plus sign and this basically takes care of the sketch next so let’s have a look at what what is necessary for the c-sharp application

alright so let’s start by looking at the user interface this is going to be really quick basically here are the steps that I took to build the user interface I I started a windows form application named that that set a few properties and added a few user interface elements here you can see how the the finished product looks like right now nothing really works it’s just it’s just a visual part of it next comes the code to make the user interface come to life basically in the form load I added this codes so I can have various options from the drop-down list and of course I selected the first item so that when the user runs this program it’s almost ready to go next up was the the button click so in the button click basically what I do is I disable when it starts and Eirene able when I’m done and what I do here is I clear the the items that are in the list in this case this is the list right here so going back here where supposedly the text cursor is that this is where we’re going to add more stuff later right now usually what I do is I first make sure that the user interface is working correctly before I start really adding the real beef of the application so now here we start with the serial communications and as it says here it is the core of the project so what we’re going to do first is that we’re going to do a port scan we’re going to go through all the comforts that are available and we’re gonna try to locate where the Arduino Nano is found and this is as simple as just sending it that high-five asterisk chart and if we get back a plus sign we’re in business so here we’re gonna have a closer look at how I am doing this so here’s the basic algorithm the first thing that I do is that I send an asterisk over to the to the serial port then I wait a full second and then I check whether I have data do I have data if I do then I come this way and I ask myself do I have a plus sign in the data if I do have a plus sign then I go down this way and we have success if there’s no data like for instance here or if the data received is not a plus sign then I come here to a fail state which basically means that the non was not connected to the port and I move on to the next port if available all right so moving on we now go to the first of the code the first code that I added was to using statements so that we could use the ports and we could also make use of the threading functionality available in c-sharp so I added these two statements and you can see still in yellow because I haven’t saved the project at that time next is the actual routine that checks to see whether our serial device is connected to the port so the first thing I do is I declare a new a serial port object now here I check whether the the object is open if the serial port is open then ieave it alone because it’s assumed that it’s busy doing something else and for us it’s not really very good news but then again maybe I’m checking us a report that’s connected to another device ATS is he using it only if it’s not open then I go ahead and I open it before I open it I I said a read timeout so that I’m not waiting forever in case something doesn’t go as well as I had hoped finally after the port is opened I then send an asterisk to it and that’s about it next I make use of the the thread sleep method and I sleep for 1,000 milliseconds which is basically one second when it comes here it’ll be because the one second elapsed so now I’d go at night check do I have anything to read and if I do then I I go ahead and I see what’s up I go ahead and I declare the buffer since I know that Maxim is gonna be three bytes which actually I know it’s only one I hear four three just in case it’s Center asterisks and a newline carriage return character so now I have a buffer three bytes and I go ahead and I used a read method to get the information into the buffer and here this just is telling where I need to start and how how many bytes I’m going to read it doesn’t matter if I receive less bytes than I am trying to read it or just read whatever’s there but what happens here is that not only does the buffer get the data but also here in this variable I

get the number of bytes read now here’s just a conversion because I want to be able to check the message and I need to move the bytes in the buffer into some sort of string variable so I do this this conversion and then I close that’s very important I you must never leave the serial port open after you you’ve used it and you don’t need it anymore and here I return and what I’m returning here if you check it is a boolean function so what I’m returning is a boolean variable and all I need to do here is check to see whether my string contains the plus sign if it does obviously this is going to return true and it’s going to return if it doesn’t have the plus sign it will return false and here we have some else conditions just in case things don’t go as well as planned if the see report was busy and was not able to open it and I just returned false I mean that’s that’s about it and my my catch for my try also here I returned false but I also will send a little message to the to the user to let them know that there’s something weird going on next up is the call that goes into the button click event now here this should look familiar this is what I had already before and actually what I added was this if statement so here I’m just going to do a little quick validation I make sure that the user entered the comport as the OM number if the user hasn’t entered anything or he entered a few spaces to try to trick the program it’s it’s gonna trigger here and it won’t go in so now after that I just called my function to see with the port name and see whether dr do we know not know hardware is connected or in this case I’m keep mentioning Arduino and nano but in this case like I mentioned before it’s a DT DCC do we know and it could be are doing own or to be any kind of Arduino compatible hardware that’s running the little sketch that we looked at at the beginning of this these notes here what I did is I just put a temporary message that tells me that the Arduino was found here I need to do something different but for now I just want to make sure that it what I have in here is working before I put in more stuff and of course I have the else the elseis that will give me the correct message depending what’s going on and here we have the program running in this case my Arduino was that calm v when I ran this program and it found it and I was happy about that but the only thing that’s doing right now it’s just testing to see where they are doing oh it’s found I still need all the logic that will get data inside the list so that is what is coming up next and we’re going to have a closer look at this at this flow chart to explain what’s going on I noticed now that there is actually two flow charts it’s the one here and the other one here so we’re going to look at each one independently and the thing is that with an event-driven system you need two parts first you need the part that’s in the main code that you’re launching and here’s where you open the port and you send whatever command you’re gonna send and you assume success because you really don’t have any kind of evidence to show otherwise now there’s a second procedure and this is a separate piece of code that this is actually the the event what the event does is when the something comes in from the serial port it automatically fires and it starts executing right here that was a terrible error the first thing I’m going to do is I’m going to get the bytes into a buffer and I’m gonna get the number of bytes right next I’m gonna check to see whether I have all the data in if I do then I’m going to close the port and I’m done with it now here it’s not that simple usually when I have all the data in there’s a there’s another step here better change your color here I’m gonna put this down here and it’s more code because that I’m processing the data that I have and I know that I now have all of it if in case the data is not in I still be clear success because well maybe the rest of the data is coming in and the second and the second batch the way this thing works is as the serial port receives data it processes it whatever data is received and then it waits for more and in this event just keeps firing as more data keeps coming in and keeps coming in so usually there is an S to have cold that will know when the relevant data is in there are some cases where you just can’t know that because the stream will be continuous in

our case it’s not in our case I’m going to tell it I want to select a specific command which is the command I’ve sent here then the command is going to tell the little arduino sketch to send back one byte or to send eight bytes or send sixteen bytes so I know exactly how many bytes I’m getting back and I know when I will have all the data I highlighted some text that recaps what I’ve just mentioned this solution that I provided here including the flow chart it’s a very particular to our example needs may vary like for example here I end certain requires may not need to close the port when the data has been received why because maybe it is a continuous stream and there is no such thing as the end of data or having received all the data so the port remains open throughout the lifetime of the application now two different procedures that together form the model needed to send and receive data for the serial device that is something very important there always has to be that first procedure that kicks off the the process and it has to be the second procedure that handles the event when data is received the net another part that is important is this right here I need data structures to be able to handle the incoming data and to handle the serial port in general they like for instance you have the serial port object itself and you have the data structure that’s going to hold the receive data now these data structures need to be declared so that their scope is at the module class or project level if you recall a c-sharp has four different kinds of scopes it is the block the procedure the model class and the project of course the to the two widest reaching scopes are the module class in the project so it could be either one in our case we only have learned form one class form to be precise therefore it doesn’t make much sense to make it at a project level because if if I declare at the module class that will suffice for what we’re doing right now I’m making this object scope to be limited only within that function okay this is really bad it worked perfectly when I checked the the presence of the Arduino so I had that one function that opened the serial port checked and then closed it again and that that was perfectly alright but when you’re trying to do an event-driven model a block or a procedure scope is not going to work so now what is next well we have a various step so we have to add the declarations for the serial port object in the data structure we have to instantiate the the serial the serial port object and most likely will we will also have to instantiate the list we have to do something very important we have to tell the serial port object what procedure to run when it receives data the thing is that right now we are building the procedure that’s going to receive the data but how is the serial port object going to know that that is that procedure that needs to be run whenever data comes in so that takes care of that and of course the last step that we’ll need to do it is to actually get the serial port process started in our case we do it by sending a character to the serial device and the serial device comes back with some data in other cases especially when it’s a continuous stream all that might be necessary to get the serial port process started is just by opening the port let’s summarize that just real quick here’s the here’s the four steps and this is the modification that we need to do to the program as it is right now to get it going and to make sure that it’s going to be able to receive the data that we are going to ask for so now let’s go down here and we’re going to look at some code of course is the first part is the declarations and here I do mention that do you need one more declaration which will be a variable that will hold the number of bytes that I am expecting I’m do I’m using an integer type which is actually a 32 bits so that is more than so here I am declaring the serial port and I’m using the new keyword as I am with the list of bytes a new keyword which basically this means that it not only declares them it also instantiates them and they are ready to use and here is the the integer that I’m going to use to to define the number of bytes that I am expecting and here is the procedure that is going to get a run every time serial data is received basically what I’m doing is I’m declaring an a byte array called buffer

and I am declaring it with 40 now Wi-Fi because I happen to know from the commands that I sent to the serial device that the maximum number of bytes that I’m receiving is 32 so making it 40 is pretty sure bad that I will be covered usually this is not a good idea to put a fixed constant in here but rather to use the the the property called read buffer size from the serial port object and this will declare the array the size of the buffer the default size is a 4k which is kind of huge for our purposes so I just decided to use a very small number here and here is the instruction actually reads the the serial port and it tells you how many bytes were read in the other procedure or function that I have I am not sure if there’s any bytes to be read so this might be zero but here in this event I know I’m going to get something greater than zero because the event itself was run because something was received so I’m almost guaranteed that there’s something there the next time the next thing that I do is I resize the buffer to the number of bytes read this is basically an array resizer so I won’t have anything extra if I’m receiving maybe eight bytes it’s no point having a fortified array especially when I decide to move the contents of the buffer which if you’ll notice it’s a it’s a local and the scope is up at the procedure level so I move it to a data structure that at the module class level and what that does is it basically it guarantees that with this procedure exits I may lose the information in the buffer but it will be safely kept here the thing is that if I leave this at 40 and I receive 8 bytes it’s going to copy all 40 bytes into the list which is basically a waste and this is actually dangerous if you have a continuous stream when where you may receive less bytes than the size of the buffer and so you always have to trim the buffer to make sure that whatever you get in the list is really what came over the wire so to speak here’s where I simply test to see whether I have received all the bytes I’d compare it against the the variable that we just declared to hold the number of bytes expected and at this time I’m just closing the port because I know I am done here I will need to do more work but I will add that later on we now have the code necessary to initiate the the serial port transaction and we have the code that will receive data now we just need to add the write code in the application to make use of all this new functionality so this is what we’re going to do next including setting the the bytes to receive variable if you notice from the from the user interface I wait to to select the number of bytes that we’re going to get back is by selecting the command and if you recall at the beginning if I select command 0 I’m gonna get back one by if I select command one I’m gonna give back two bytes four bytes eight bytes and so forth so we’re going to modify the drop down the combo the combo list in selected index changed event and luckily it’s just one line all I need to do is grab the number of bytes that I’m expected depending on the depending on the commander was selected now here it’s pretty easy because that if the command is 0 its 1 byte if the command is 1 is 2 bytes so basically it’s actually raising the command to the power of 2 and that’s how many bytes I’m I’m getting back so once I have that I don’t need set this again unless I decide to change the command that I’m sending it all right so now we go back to the forum load and we go ahead and we instantiate the serial port object and of course we have to add the name of the procedure that will be receiving the data in our case it was serial port data our X event so you have to be very careful because the serial port object has its own event list which is called data received and we’re going to append to it so that the reason for the plus equal sign and of course we’re here we’re going to create the new the new event handler given the name of the procedure so here here that’s one more step done but as I mentioned here we’re not done yet there is one more step that we need to take in and this is sending the command to the serial device the code needs to be added to the button click event I’ll comment the statement that displays the message and add the code there since

that’s since that message it was just temporary so we’re going to drop down to image 15 and here we go is this image 15 yes it is alright so here we had or had the message which I commented out and I simply added some new code the first thing I’m going to do is I’m going to set the port name given the the port name that the user typed in which is it mentions here is the comm designator and then I go ahead and I open it at this time I assume that the comm designator is correct and once this is open I go ahead and I write the command now here’s an interesting thing you might say well how am I gonna know if this is the correct one and the thing is that when the user clicked up the button had already checked it checked here to see whether this the designator was correct and only if it’s correct will this be true no fault here so I am pretty safe of using the same designator that was here also here because the if it’s if execution is here it means that this is correct so once it’s open then I go ahead and I grab the command from the text that’s inside the selected item in the drop-down list and I send it and that’s it no more need for anything else I don’t need to wait I I just need to finish up here this procedure and let the program do do whatever it has nothing should happen of course we should be receiving the bytes and we are not doing anything with them to verify that the program is working to go to the receive event and put a breakpoint on the line that reads the data so we’re gonna go here and we’re gonna set it int bytes to read the serial port read buffer so this is looking good before we move on I just want to make note of something really quick I’m gonna go back to where I instantiate the serial port object right here this is not really necessary if I go further back to the declarations let’s locate these real quick right here using the new keyword I am instantiating it so actually doing this and doing this is redundant I went ahead and actually comment this this line out and everything worked perfectly okay so let’s give this a run and see how it looks I’m gonna go to the development environment here I already set the break point where the image indicated and I’m just gonna go ahead and run it and I’m gonna move the little window inside the view and I’m gonna type in comm 5 and I’m gonna select that we read 4 bytes that’s good enough so I go ahead and I agreed and it stops where it should so here I’m going to just does a single step it and let’s see how many bytes it right oh yeah I write four bytes yeah so now let’s look at the buffer and just click the plus sign and there it is 48 49 50 51 those are the four bytes that we are expecting and right now I’m just gonna let it run through and there’s the four bytes note is that I thought I ran the fully completed program in the development environment so as you saw the bytes that were coming in were successfully placed in the list if you were to run the program now following the documentation that’s not going to happen because we still don’t have the code to move the bytes from the receive buffer which was the byte array and in the byte list over to the list that’s on screen moving on as you can see I have here more text that basically describes what we did real quick tend to to move to the next statement and here you have a graphical representation of what the and the list looks like in the case of this example I chose to receive 8 bytes so it has a count of 8 and it starts out at 48 it goes to 55 which leads us to the next step to actually move the bytes from the list over to the on screen list box as you can see here I have documented that we’ll be using the the items add method this is pretty typical and here is a snippet of code which basically adds to the code inside the if statement whenever it determines that it

has finished receiving all the bytes before before we didn’t have this we just went straight to close support but now we have a little logic here and then basically it’s very simple it just uses a for each loop to traverse the list and it grabs each item in the list and it adds items to the list box now a the coat is almost complete and we can run it however when we get to the part where the the list of items is being transferred to the list box on screen we’re gonna get this message here and it’s very important to actually understand this here is a cross thread operation the thing is that when when the application is waiting for for something to be received from the serial port and it is received instead of making just a blatant jump to the code to execute the event it starts a new thread and indexing and and it executes that event in the new thread however the threads cannot just be updating a user interface elements just like that now here I should also point out that if for example the application that you need needs to process the bytes or the information the data that’s coming in from the serial port in such a way that it does not affect the user interface which basically means you do not display anything you really don’t need to be thread safe in my case Here I am actually displaying the bytes that are coming in from the serial port and of course there are situations where this is necessary so I need you to bear with me a little bit longer to figure out how we can solve this by making this operation here thread safe to make this work we’re going to employ something that is called a delicate delicate can be seen as a description or a definition of a function that’s going to be passed as a parameter now usually when we talk about parameters we talked about maybe integers lists arrays many many other types but the thing is that with delegates you can actually pass a function named as a parameter now here is the Declaration of the delegate and here I’m doing a few things I’m declaring a void which means that the function that I’m going to pass as a parameter as a parameter does not return anything and I’m also describing its type in this case it’s the update UI which basically means that the function that I’m going to pass is going to do something with the user interface and finally I here I describe the parameter that’s going to be passed to it in this case I want to pass the list of bytes that have been received therefore here in the type I say a list of bytes and then I provide a name for the parameter now we have to get the code to actually do it so here we’re gonna put together a small procedure which I call just GUI update list box and the only thing that it’s going to do is gonna accept a list of bytes it’s gonna grab the bytes in the list and it’s going to use the now well-known items dot dot add method as you can see this code here and this code that generated the error is basically the same one the only difference is its location so now we’re gonna go a little further down if you can see the procedure was simple enough yeah there’s really nothing incredible happening here so now here’s what we’re going to do we’re going to modify the part inside our receive event so that when all the bytes are in now it’s going to execute this code in addition to the serial port closed of course and what it’s going to do is that it’s going to ask the listbox whether an invoke is required if the invoke is not required then this is going to go straight to this procedure and it’s going to execute the the code to update the the list box now I could have just taken this code here and simply attached it here instead of calling the the list box but I just decided to keep it a little bit modular however if it does require an invoke then I’m gonna grab the invoke method of the list box and I’m gonna create a new element the update to UI element and I’m gonna pass it the name of the procedure along with the parameter if you note up here here’s the name of the procedure and of course it accepts one parameter so whenever I make use of this procedure I need to give it this and here it is here is the parameter here’s the name of the procedure and I’m just creating a new object to be able to pass it through the delegate and now all is

well now here I explain a little bit more of what’s going on and after I have this small code in place now we can actually run the the application and it will work fine here I’m just going to remove the the breakpoint so it won’t stop and I’m ready to run the application so here we go and it’s going to appear a little bit off screen but I’ll move it as soon as it comes back okay so there it is I’m going to type in comm five and I am going to select eight bytes and just to follow the documentation and I’m going to read and there they are and no more problems of generating that that error now like for instance if we didn’t want to see the the error in life and not just in our document we can just go ahead and comment out some code like for instance des if I’m gonna do this here comment this out and just run the procedure by itself so here we go again I’ll get the window and view comm five I’m just going to let it return one bite I don’t care it’s gonna error out anyway and here we go okay so now let’s sting a little bit longer than usual and here it comes and there you have it you have the error that that comes up if you try to do something that is not thread safe within your application and now we go back to document and basically that’s it I’ve added a few extra notes okay I guess this is the one of the important ones and our example really just covered something very simple by no means is this and all inclusive and there’s a lot of stuff to learn inside the the serial port object and here is the Arduino code that I added to the end of the document so that and this is actually part of the text so you can actually copy it paste it in the Arduino development environment and create a real quick sketch that you can download so that you can have the the same software that I used to test the serial communications and basically that’s it thank you very much for bearing with me and I really hope that these tech notes are of help to someone else besides myself