I wanted to be able to send messages (instructions) from my desktop PC to my Arduino ... I'd like to have my Arduino send instructions as a consequence to other connected devices via I2C, but that's another issue for later.
For now, let's just get our PC and Arduino have a meaningful dialog. Who knows what may blossom from there?
The goal is fairly simple, I will use System.IO.Ports.SerialPort from the .NET side to communicate with the Arduino with Serial on the other side.
This is based on some other resources on the interweb that I found (and since lost) where this is done.
In this instructable, I've changed the code slightly to better suit my requirements on both the .NET and Arduino side of the fence.
Here we go.
Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.
Step 1: VB.NET Side
We start with a Windows Forms application and dive right into Form1.vb code (all of this is in the attached Form1.vb)
As I want the application to use the IO subsystem, we want to reference System.IO
This will be events driven, so we instantiate that
Dim WithEvents SerialPort As New IO.Ports.SerialPort
The interface is designed with a combo box (txtPort) which is populated by the RefreshPorts method. This method simply writes the serial port names into the combo box from the list of available ports in Windows. If there are more than 0 ports, select the first one. Whenever you change the selection, the selected COM port is shown in the application title.
The refresh button is intended to refresh the combo box (in case you want to plug another device in, or disconnect one).
When the application attempts to send a serial message, it makes sure that the COM port is open and configured correctly. If the port is already open, the application closes it and opens it with the currently selected configuration (so that you don't have the problem of trying to open a port that is already open or try to open a different port when one is already open ...
When you click on the send button, the application sends the string to the Serial Port.
When data is returned (by the Arduino) the received data is sent to the txtSerialText field.
The Clear button, simply clears the txtSerialText field.
The Exit button closes the application.
Step 2: The Arduino Side
The attached sketch is the one that I've used for this instructable.
First, I've set up a char variable to receive the incoming data
The setup() function simply sets up the Arduino Serial connection (9600 baud)
The loop() function "listens" for an available Serial communication
When it executes, the loop sets the incomingByte value to the Serial.read() ... that is, whatever the incoming byte of data is.
The loop() then writes the incomingByte value back to the Serial connection. This is then picked up by the VB.NET application.
Step 3: Interface Stuff
The first image is of the populated COM combo box where I have two boards attached to the computer. COM8 is an Arduino UNO that is running the Arduino As ISP sketch, while COM7 is a Freetronics Eleven running the ArduinoSerial sketch (our responder).
The second image shows the response from the Arduino.
The original version of this application that I derived this application from had the incomingByte variable (in the Arduino sketch) as an integer and the Serial.println method in the loop function sending back incomingByte as a DEC value.
I modified the sketch so that it receives a char and sends one back too.
Where to from here?
Next, I'll extend the Arduino sketch so that it performs various tasks based on the input. For instance a switch function that sends data/instruction to an attached ATTiny via I2C.
I'll need to change the sketch so that it receives whole instruction strings rather than just a letter, as I'll want to be able to direct the instruction to one of multiple connected devices with parameters.
Anyway ... that's it for now. Have Fun!
Step 4: Moving on ... a Char Array in Arduino
As I mentioned previously, I want to be able to send a line of text, an instruction and parameters from the PC to the Arduino.
I added the integer variable lf with a value of 10 and then changed the variable incomingBytes from a char to a char array and then changed from incomingBytes = Serial.read() to Serial.readBytesUntil(lf, incomingBytes, 80);, this means that the sketch will read the inbound serial data into an array of 80 elements (my buffer) and then write the result out through the Serial.println(incomingBytes) method.
Interestingly, I noticed that when the input value is 100 characters in length, the sketch will output the initial array of 80 elements, then read the next serial block, and then print that ... that could be a useful piece of functionality.
Finally, I need to clear the array using:
memset(incomingBytes, 0, sizeof(incomingBytes));
This clears the incomingBytes array. Without this function the array didn't seem to clear when new data was received ... anyway, that seems to have fixed the problem that I was seeing ... maybe I have mistaken the result, but the new result is what I want.
Again, the entire sketch is included for your entertainment.
Nothing needed to be changed in the VB.NET application, so no updates there.
What I'm thinking of here is to receive a line of text such as:
and then for the Arduino to split it into three instructions (X, Y and Z) sending these instructions to three ATTiny84 chips to move a step motor to those coordinates. There's a LOT missing in that simple statement, such as timing etc., but I'm considering implementing this in the VB.NET code ... maybe chasing fairies ... maybe not. I won't know until I've gone further with this design.
Participated in the