Society of Robots - Robot Forum

Software => Software => Topic started by: Doug83 on August 16, 2017, 12:28:41 PM

Title: Dweeno Link: Visual Basic robot control
Post by: Doug83 on August 16, 2017, 12:28:41 PM
I'm not sure how much interest there will be in this. Most of the VB posts are rather old it seems but the Arduino Android App topic got a lot of interest, so here goes nuthin'.

This is a how-to for writing a Visual Basic program and an Arduino sketch, to allow both of them to communicate with each other using Serial over a USB cable.

I have named it Dweeno Link to clarify it from other similar efforts.
In the online world, everything needs a unique name to identify it.
The name Dweeno Link currently has no results in Google, so I'm using that.

The Dweeno Link Visual Basic program doesn't do anything that requires an Arduino specifically, it is just a program that allows two-way communication over the USB/serial port. You could use it with PICs or stamps or propellers or whatever else microcontroller board you wanted to, as long as you can make them do serial over USB.

The only hardware that you need to try this example is a Windows PC, an Arduino Uno/Nano/Mega and the USB cable to connect the Arduino board to your PC. Hooking up a couple normally-open push buttons and a couple LEDs + resistors to the Arduino helps too if you have them, but isn't necessary to see that the example provided works.

The only software you need is the Arduino IDE and Microsoft Visual Studio Community Edition, both of which are free downloads.

The VB program and Arduino sketch I wrote is tested with Arduino Unos, Nanos and Megas.

The Visual Basic program is called Dweeno Link, and the Arduino sketch is called Dweeno Slave.

When checked for an Uno, Dweeno Slave uses 12% of program storage space and 15% of dynamic memory.
You would probably want to add some more functions to it--but even on an Uno or Nano, you still have a lot of space left to do that.

When built, the version-1 of Dweeno Link (the VB program) is about 20kb.

The Dweeno Slave sketch has some functions already written in.
Two of them send a message to the PC when either of the two buttons is pressed.
Two of them are for blinking the pin-13 LED slow and fast, as many times as you tell it.
Four are for reading and writing to Arduino pins (the functions for reading pins report the result back to the PC).
The last one is one that uses the Arduino to intentionally cause a time delay in the Visual Basic program.
And from those you can see how to add more functions of your own.

I wrote this because there's a lot of other programs that can communicate with an Arduino over serial/USB, but many of them are pre-constructed products that limit what you can do with them.
Also, most of them cost money....
Visual Studio Community is free for hobbyists to use, and Visual Basic is a 'real' programming language that doesn't limit how you use it.

There is a lot of attempts online to do this in VB already, but most of those are not 2-way messaging, and when I searched I found that many of them were so old that they wouldn't even work in the current version of Visual Studio. Dweeno Link was written in the current version of Visual Studio 2017.

I also could have done this in C#, but VB is still a little easier to use I think.

I looked into writing a cross-platform version in Eclipse/Java, but ran into problems with finding a suitable Java cross-platform serial port library.

I may write a Linux version eventually, but I don't have a Linux computer around so I currently have no way to do that now... And most people still use Windows, so (I think) a Linux version wouldn't have nearly as wide of an appeal as something that can run on Windows.

A lot of other pages online show you how to make simple programs in various programming languages (many even in VB) to send individual characters to the Arduino, but they skip explaining how to do anything useful with it. They don't provide any way for the Arduino to respond back to the PC at all, and because of this, they are only good for human ?remote control? use. They aren't really suitable for using the PC to control the Arduino on its own. You can use Dweeno Link just as a human-operated remote control if you want, but it also allows you to have the PC control the Arduino all on its own.

In order for the computer to automatically control the Arduino, the PC has to be prevented from sending commands faster than the Arduino can carry them out. That requires a messaging setup that works both ways. The Arduino gets a command sent to it, and when it is done performing that command, it has to reply back to the PC to ask for another command. The Arduino also needs the ability to send data back to the PC as well. Providing two-way communication requires writing a multi-threaded program, and most amateur Arduino users aren't familiar enough with PC/OS programming to do that.
So I'm going to show how to do that part.

Visual Studio Community is the free version of Microsoft's Visual Studio programming IDE, available on Microsoft's own website. To download that, you need to register an MSN or a Microsoft account (and for that you need an email address) but it doesn't cost any money to do. They just want the email address so they can send you developer spam now and then.
!!!WARNING!!!
Every few months the Visual Studio program makes you verify the email address that you used to register your Microsoft account. If you don't do that when it asks, then Visual Studio STOPS WORKING. So you MUST use a real email address that you have access to. Don't use a throwaway email address for your Microsoft account!

Also another warning:
The Microsoft program that you need here is Visual Studio Community, that is for programming with Visual Basic and C#. It is a BIG download of several hundred megabytes.

Microsoft also has a free coding text editor now called ?Visual Studio Code?, but that is the wrong thing. It is just a small download of only a few megabytes, but it won't work for this.

Another thing the other pages don't explain real well is how to do anything useful with the single characters that the Arduino receives. As is typical with most other microprocessors, the Atmel chips used in the Arduino boards can only retrieve one byte at a time from their serial input buffer. You need a way to reconstruct the individual characters into -some- kind of useful data.
I'm going to show an Arduino sketch that does that too.
Title: Re: Dweeno Link: Visual Basic robot control
Post by: Doug83 on August 16, 2017, 12:33:53 PM
The message system that I use here has a particular format.

For the messages that you sent TO the Arduino, each SINGLE message is limited to sending a maximum of twelve positive integer numbers, and each of those numbers can be up to 4 digits long.

Each number is followed by a colon, and at the end of each line you must have an asterisk because the asterisk is used as the end-of-line marker. The asterisk is a printing character and so it's much less confusing to use than the typical invisible cr/lf. 

So a message of twelve values would look sort-of like this:
XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:*
--where each of the XXXX parts could be any number up to four digits long.

If you don't need to send twelve values, you don't have to.
You just need the colon after every number, and the asterisk at the very end.
Below is shown an example that only has five numbers (but with XXXX where the numbers would be):
XXXX:XXXX:XXXX:XXXX:XXXX:*

Also you don't need to send numbers that are four digits long, if you don't need such big numbers.
You do not need to insert leading zeros into the unused number places, since these fields get converted back to real-actual-integer-numbers in the Arduino and any leading zeroes would get dropped anyway.
One of the real actual example commands is as follows:
101:30:*
Where {101} is the command for [blink fast], and {30} means [thirty times]. But we'll get to that later below...

What if you want to do something that needs more than 11 different values? Say, 20 values?
Then you just send the values in two different messages of two different function numbers, with no more than 11 values in each (the first value would be the function number).
For transferring 20 pieces of data to the Arduino, the first and second messages could have 10 values each.
The first message could be numbered 138, and the Arduino just stores the data from the first message.
The second message could be numbered 139, and the Arduino stores the data from the second message, and then begins performing the command.
Since the two messages are numbered different, the Arduino will know which one is which. You only need to send the commands in the proper order.
--Also those functions don't exist yet.
You would need to write those functions yourself, but you can do that.

Why is there a 12-number limit?
Because the default Arduino serial input buffer is only 64 bytes. If you add up those characters-- 4 digits + a colon is 5 characters per [number]. 5 characters per number x 12 numbers = 60 characters, and adding the asterisk on the end makes 61 characters. Keeping the Arduino's message length under 64 bytes and making the PC wait for an Arduino response means the PC won't ever cause the issue of running over the Arduino's default-size serial input buffer.

(The serial buffer size is just a software setting that can be changed--but it's a bit in-depth, it isn't without side effects and it really isn't necessary anyway since you can just use multiple commands to send more than 11 data values)

Why only allow sending numbers?
Because mostly that's what you would want to send, and it simplifies converting the message on the Arduino side. You only need one coded routine to convert every field to a useful piece of data.


So that is the restriction on what messages to send to the Arduino.
What restrictions are there on messages that the Arduino sends to the PC?
Well... technically... not much really.

The default incoming serial buffer size is 4Kb in VB.net. Sending that much data back to the PC in one message (from an Arduino!) isn't very likely IMO, and the PC can empty its input buffer WAY faster than the Arduino can send stuff anyway.
Also you can send strings back in the message to the PC if you want, if there was any reason. A PC can handle juggling strings way better than an Arduino can.
.......
The main suggestion I would make (and what I use here) is to use the same format as the messages to the Arduino: values separated by colons, and ended with an asterisk. This way in the PC you can split the message into another String array at the colons, and deal with each field data type separately as you need to.

Lastly before proceeding: I will say right now that the messaging system I've written here is NOT made to be as compact & fast as possible.
Right off--I could have used the bitwise values of bytes and crammed more data into the 64-byte Arduino buffer limit, but doing that would make the code a lot harder to understand (as well as harder to type by hand) so I didn't do it.
You can re-write it like that if you want.
Title: Re: Dweeno Link: Visual Basic robot control
Post by: Doug83 on August 16, 2017, 12:37:16 PM
First off, we shall deal with the Arduino sketch.
See this pastebin page:
https://pastebin.com/JU2Rsd28

With each message sent, the Arduino gets a series of numbers + colons + one asterisk.
What do all those numbers in the messages stand for?
Well, whatever you want them to. There is no default definition. You get to write that part. :)

How I do it is like this:
The FIRST numeric field of the message sent to the Arduino is a number that indicates what function to call.
All the other fields are the data that this function needs to work.

Using the first field to indicate the function means that you can *only* have 10,000 possible different functions, but that's probably enough.

This sketch has a number of functions already written.
They appear at the bottom of the sketch, so you can skip all the way down to see them and how they are called.
I began numbering them from 100, but you could start from zero if you wanted to:

button1_pressed() ----- this function reports from the Arduino whenever button 1 on the Arduino is pressed.
There is no way to call this function from the PC; the button #1 pin on the Arduino must be shorted to ground to trigger this message.
This function sends the below message to the PC:
btn:1:*

button2_pressed() ----- this function is just like above, but is for button #2 on the Arduino.
This function sends the below message to the PC:
btn:2:*

The two button messages above are the only two that send back any string values. All the rest below just send back numbers.

blink_slow(int) ----- this function blinks pin 13, 1-second-on/1-second-off, as many times as you tell it (the int value)
to call this function you send:
100:X:*
 --- where X is the number of times you want it to blink.
It reports back to the PC after it has completed:
100:*

blink_quick(int) ----- this function blinks pin 13, four times on and off per second, as many times as you tell it (the int value)
to call this function you send:
101:X:*
------where X is the number of times you want it to blink.
It reports back to the PC after it has completed:
101:*

digitalRead_pin_D3() ----- this function digitalReads pin 3 and reports the value to the PC.
you call it by sending the command:
103:*
and it answers with the reply:
103:X:*
------where X is the value of the pin, either zero or 1.

analogRead_pin_A3() ----- this function analogReads pin A3 and reports the value to the PC.
you call it by sending the command:
104:*
and it answers with the reply:
104:X:*
------where X is the value of the pin, an integer from zero to 1023.

digitalWrite_pin_D4(int) ----- this function digitalWrites pin 4.
you call it by sending the command:
105:X:*
------where X is either zero or 1, that you want the pin set to.
and it answers with the reply:
105:*
------to confirm that it has completed.

analogWrite_pin_D5(int) ----- this function analogWrites pin D5 (which is a PWM pin).
106:X:*
------where X is a number from zero to 255.
and it answers with the reply:
106:*
------to confirm that it has completed.

arduinoTimeDelay(int t_Minutes, int t_Seconds)] ----- This function causes a time delay.
107:X:Y:*
------where X is the time in minutes to wait.
------Y is the time in seconds to wait.
After the specified time interval has passed, the Arduino replies:
107:*

More info about the arduinoTimeDelay() function:
When a lot of people start using Visual Basic, they ask if there is a way to make it slow down or pause while doing something. There are different ways to do that, but--just like the Arduino's delay() function--the simplest and easiest ways have some serious drawbacks overall and so they are hardly ever used in the professional world.

This function allows the Arduino to perform a pause instead, that also causes the PC to pause. And the way that this function is written, it doesn't use the delay() function at all, so it does not interfere with any other tasks that the Arduino is supposed to be doing at the same time. For example: if you press one of the Arduino buttons when a the arduinoTimeDelay() function is running, the Arduino will still send the button message back to the PC.


commandNotFound() ----- if a function number that you send cannot be matched with a function in the Arduino, this function is called and sends back the following message:
???:*
You can verify this by entering a non-existent command, such as 999:*


WARNING: other than identifying non-existent commands, none of these functions currently has any error-catching code in them. You must send the correct data they require.


You can use this sketch with the usual Arduino IDE serial monitor, to verify that the sketch is working as it should.
The Arduino sketch is set to a serial speed of 115200, so the serial monitor must also be set to the same speed.
Type the commands and send them, or press the Arduino buttons 1/2, and you should see the responses in the serial monitor's reply window.
Also the pin 13 LED should blink, if you try those two commands.

Note that if you send the LED-blink commands or the arduinoTimeDelay command, the end message will not appear until the function has completed.
That is a very important detail that will get used later on.

The Arduino response messages do not send line feeds, so in the Arduino IDE serial monitor they end up all printing on one line. That isn't a mistake; the line feeds are of no use to the Dweeno Link PC program, so I left them out on purpose.
Title: Re: Dweeno Link: Visual Basic robot control
Post by: Doug83 on August 16, 2017, 12:44:24 PM
On to the Visual Basic program.

Microsoft Visual Studio projects are not easily transportable, because they contain a lot of files that have absolute file path references in them. If you make one in one place and then cut and paste it into some other folder on your PC, it isn't going to work anymore. So we aren't doing that.

This program doesn't need a lot of controls so it is easier to just add them manually.

First we need a new Forms project: open Visual Studio, and start a new project.
If the Start page is showing, there is a link there to ?Create new project?. Or-
Go to the top menu bar and click on [File] and then [New Project...].

A New Project dialog window will pop up, with 3 sections. On the left side there is a treeview menu.
1) In the treeview, select [Installed], and then [Templates], and then [Visual Basic].
2) Then in the center pane of the dialog window, select the choice that says ?Windows Forms App (.NET Framework)?. Further to the right it should say ?Visual Basic?.

See image below:

(http://beevilletrainwreck.com/assorted/dweeno/00_how_to_begin.png)

(Mine is black because I set it to that theme. Yours may look gray, but it should still be the same dialog)

3) At the bottom of the center pane of the window, is a long textbox that says ?Name?. Enter a suitable name for the project (such as Dweeno_slave_01). There may be something already in there, but you can delete that first.
4) press the [OK] button in the bottom of the right pane, and after a few moments, you should see a ?blank? window on the main area of the screen.

It should look like the image below, but maybe with a couple differences:
...Again, yours may not be black, but that doesn't matter.
...Mine has a bunch of toolbars and windows showing, that yours may not have showing. That doesn't matter either, right now.
...You just need to have that center area, with the ?blank window? form showing.

(http://beevilletrainwreck.com/assorted/dweeno/01_newVBproject.png)

Next, you will want to open two more windows: the Properties window and the Toolbox window.
These may be already open. They may also not be in the same place as mine because you can move them around, but that doesn't matter. You just need them open.
If they're not both open, then go to the menu bar and click on [View].
The Properties window option is near the bottom, and the Toolbar window option is about halfway down.
(see the below image)

(http://beevilletrainwreck.com/assorted/dweeno/02_properties_toolbox.png)

In the Properties window, there is five little icons along the top.
If the second and third ones are not highlighted, then they need to be.
Click on the THIRD one first, and then click on the second one.
(See the picture below; the two selected icons are in blue squares. This will list the selected object's properties in alphabetical order.)

(http://beevilletrainwreck.com/assorted/dweeno/03_properties_select.png)
Title: Re: Dweeno Link: Visual Basic robot control
Post by: Doug83 on August 16, 2017, 12:47:28 PM
Next we will create the controls needed.
The picture below (04_form_layout) shows what I made mine look like. You want it to look like this but the exact sizing of anything isn't critical.

(http://beevilletrainwreck.com/assorted/dweeno/04_form_layout.png)

Below is the steps to create and name these things properly.
Some of them must be renamed because you will copy & paste the page code in, and your control names must match what is in the pasted code.

(http://beevilletrainwreck.com/assorted/dweeno/05_form_parts.png)

Whenever you highlight an object, the Properties window changes to show the Properties of that object, and you can change the individual property settings.

1) Click on the blank form and then in the Properties window, find the property in the left column named Text. To the right it will say Form1. This is the text that will appear in the Window's title bar. You don't NEED to change it, but I changed mine to say Dweeno Link 2017 v1.0. Edit it if you want and hit the [enter] key or mouse-click into any other property value, and the changes will appear on the Form1 [Design] tab. Note that this ONLY changes the window's title bar text; it doesn't change anything else about the program or project.

Non-numbered step: click on the blank form and then click down on the lower-right corner, and drag it down and right to make the form area bigger. This is just to make it easier to place controls on, you can make it smaller again later.

To add controls onto the form in a particular place, you drag the control you want from the Toolbox and then drop it on the form where you want it.

2) Find the GroupBox control (in the Containers sub-section) and drag it onto the form. With the GroupBox still highlighted, go to the property that says Text and change its value to Select port. Arrange this on the left side of the form. You don't need to change the name.

3) Drag another GroupBox onto the right side of the form. Change the Text property of this one to say Serial connection.  You don't need to change the name.

Note: GroupBoxes usually don't really do anything, they are just a way to group related controls visually.

4) Drag and drop the Button tool from the toolbox into the left Select port groupbox. Change the button's Name property to RSP_Button , and then change the button's Text property to Refresh serial ports.

5) Drag and drop the ListBox tool into the left Select Port groupbox, under the button. The ListBox Name property should be ListBox1 and you should leave it as that. Check that the SelectionMode property says One.

6) Drag and drop the Label tool into the left Select Port groupbox. Change the Label's Text property to Selected port: . The Label's name does not need to be changed.

7) In the Toolbox, find the TextBox tool and drag it into the left Select Port groupbox. Change its Name property to SelectedPort_TextBox , and set its ReadOnly property to True.

8) Drag and drop another Label into the right Serial connection groupbox. Change its Text property to Data to send: . The label's name does not need to be changed.

9) Drag and drop another TextBox below the label you just made in the right Serial connection groupbox. Change the textbox's Name property to Sending_TextBox .

10) Drag another Button onto the form, and drop it in the right Serial connection groupbox. Change its Name property to Send_Button , and change its Text property to Send button .

11) Drag and drop another Label into the right Serial connection groupbox. Change its Text property to Data received: . The Label's name does not need to be changed.

12) Drag and drop another TextBox into the right Serial connection groupbox. Change its Name property to Receiving_TextBox , and set its ReadOnly property to True.

Whenever you click on a control, its drag handles appear and you can use them to resize the control.
It may be helpful to drag the Form1 and the groupboxes out bigger to get all the controls in, and then reduce them afterwards.
Drag them around until you get something similar to what I showed in the first image above.
Title: Re: Dweeno Link: Visual Basic robot control
Post by: Doug83 on August 16, 2017, 12:53:42 PM
Now we need to put in the code to make the form work.
To do that, we need to get to the coding view of Form1.
The easy way to do that is to double-click on the title bar of the Form1 window in the designer view currently open.

Another tab will open, showing the same form but in its coding view.

It will look basically like this:

Code: [Select]
Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
       
    End Sub

End Class

There is another pastebin link below.
Everything in that pastebin paste, you must copy and past *over* everything that is currently on that tab page.
https://pastebin.com/3uUN48Pn

Save the project, and check that there are no errors indicated (there should be no underlined code, or anything showing on the warnings list or error list).

If there is no errors or warnings, then you can run the program.
If the program needs to be rebuilt, Visual Studio will do that automatically.

In one of the toolbars along the top, there is a [Start] button with a green triangle pointing right; that will build the program and then start the program running in the debugger.

Alternately, go to the menu bar and click on [Debug], and then click on the [Start Debugging] option.

Either way, the program should pop up running in a few moments. It can take 30+ seconds to finish building the first time.

The Dweeno Link program window should pop up, on top of the Visual Studio window.
Visual Studio also starts up some performance-monitoring stuff at the same time--little moving charts to show memory usage and so on.

You can stop the Dweeno Link program by either clicking on it's own [close] button in the top-right corner, or by clicking on the [Start] button again in Visual Studio, which will have now changed to a [Stop] button with a red square on it.
Title: Re: Dweeno Link: Visual Basic robot control
Post by: Doug83 on August 16, 2017, 12:57:36 PM
Okay, so your Dweeno Slave program has no errors and runs now.
Here is the instructions for how to use it.

1) Start the Dweeno Link program again, in the debugger (-for now).
2) Click the upper-left button that says ?Refresh serial ports?. This will cause all the available serial ports to be listed in the textbox immediately below.

Note: you may prefer to disconnect your Arduino when first pressing the ?Refresh serial ports? button, and then connect the Arduino and wait a couple seconds for it to be recognized, and then press the ?Refresh serial ports? button again. The new COM port will probably be the one that the Arduino is using.
...Or...
-you can just try sending Arduino messages to all the COM ports that show up.
I don't know for a fact that it is safe to do, or that it might harm anything.
I've tried it with my PC and nothing bad seemed to happen, but you are acting on your own there.

3) Then in the listbox, you click on the COM port that you want to use (the one that the Arduino is connected to). That same COM port will then appear in the textbox below, titled ?Selected port:?. This means that the selected COM port is the one that the SerialPortObject in the Dweeno Link program is set to use.

Sometimes when starting the PC program you also have to hit the [reset] button on the Arduino. I have not been able to pin down why this happens yet.

4) When you start Dweeno Link, the [Send Button] starts out disabled because there's no serial port set to send on. When you clicked into the listbox on a COM port, that also should have enabled the [Send Button]. Type your command in the ?Data to send? textbox, and press the [Send Button]. The [Send button] will turn gray, as it is disabled until a response from the Arduino comes.

5) If something goes wrong and you want to re-enable the Send button, then just click again on the selected COM port in the Listbox. That will enable the Send button again.

What commands you can send are shown below.

The blink-slow command:
100:7:*
 --- where 7 is the number of times you want it to blink. Blink time is 1 second on, 1 second off.
It will send the following message when it is finished:
100:*

The blink-fast command:
101:25:*
------where 25 is the number of times you want it to blink. Blink time is on-off, four times per second.
It will send the following message when it is finished:
101:*

To read the digital value of pin 3:
103:*
and it answers with the reply:
103:X:*
------where X is the value of the #3 pin, either zero or 1.

To read the analog value of pin A3:
104:*
and it answers with the reply:
104:X:*
------where X is the value of the pin, an integer from zero to 1023.

,,,,Of course, if you got nothing connected to either of those pins, then the result you will get is random.
But you could hook something suitable onto them to test, if you wanted to.

To digitalWrite to pin 4:
105:X:*
------where X is either zero or 1, that you want the pin set to.
and it answers with the reply:
105:*
------to confirm that it has completed setting the pin.

To analogWrite (PWM) to pin 5:
106:X:*
------where X is a number from zero to 255.
and it answers with the reply:
106:*
------to confirm that it has completed setting the pin.

,,,for the pin-writing commands, you could connect a LED and a 200 ohm resistor to show the pin's states.

arduinoTimeDelay(int t_Minutes, int t_Seconds)] ----- This function causes a time delay.
107:X:Y:*
------where X is the time in minutes to wait.
------Y is the time in seconds to wait.
The total time ends up being (minutes * 60) + seconds.
After the specified time interval has passed, the Arduino replies:
107:*

More info about the arduinoTimeDelay() function:
When a lot of people start using Visual Basic, they ask if there is a way to make it slow down or pause while doing something. There are different ways to do that, but--just like the Arduino's delay() function--the simplest and easiest ways have some serious drawbacks overall and are hardly ever used in the professional world.

This function allows the PC to pause sending more commands, by telling Arduino to pause instead. And the way that this function is written, it doesn't use the delay() function at all, so it does not interfere with any other tasks that the Arduino is supposed to be doing at the same time. For example: if you press one of the Arduino buttons when a the arduinoTimeDelay() function is running, the Arduino will still send the button message back to the PC.

Also there is the buttons:

Any time that button #1 is pressed, the Arduino will send the following message:
btn:1:*

Any time that button #2 is pressed, the Arduino will send the following message:
btn:2:*

Neither of the button commands can be called from the PC, they can only originate from the Arduino.
Both buttons share a one-second de-bounce timer. If you press either button, neither will work until 1 second of time has passed.

There is also a general error message.
If a function number that was sent cannot be matched with a function in the Arduino's sketch, then the commandNotFound() function is called and sends back the following message:
???:*
You can verify that this works by entering a non-existent command, such as 999:*

[EDIT]
This is the same list of commands given a couple posts above. Oh well.
Also a lot of my quotes changed to question marks. --So if you see question marks, those maybe are supposed to be quotes.
[EDIT END]

So now you may begin to see how this code can be modified into an automatic controller for the Arduino.
It doesn't do that right now, but it has the basic event handling in place to do that.
There is even some comments in the Visual Basic code, hinting where things need to be added.

All you need to add at this point is a way to store a list of desired Arduino commands, and then every time the [Send command] button gets re-enabled, that means you can process any data sent back from the Arduino and then send the next Arduino command.
Title: Re: Dweeno Link: Visual Basic robot control
Post by: Doug83 on August 16, 2017, 01:09:27 PM
If you run the program from within the Visual Studio program, then what you are really doing is running the source code files inside the Visual Studio debugger. It should work like that, but running the executable file will often work a bit faster and most people probably don't want to open Visual Studio every time just to use the Dweeno Link program anyway.

To get to the executable file, find the project folder that the project was saved into.
For Visual Studio it will be in your Documents folder in [Visual Studio 2017]--[Projects]--[(project name)]--[(project name)]--[bin]--[Debug]
The file has the project filename, and the .exe extension.
If you edited a project that you began in a previous version of Visual Studio, then it will be in the same place, but in the folder for that Visual Studio version instead (such as [Visual Studio 2016] or [Visual Studio 2015]).

When you run the program in the debugger it may work fine and not show any errors, but when you run the executable, the operating system may stop and say it has various errors.
This isn't greatly unusual.
Debuggers don't catch everything; Visual Studio works pretty well but debuggers are programs themselves, and they have bugs too.
The operating system will often catch run-time technical errors that the IDE ignored or missed.

Lastly: if you attempt to run this executable on another computer that does not have Visual Studio installed and it will not run, then you may need to also install a .NET Framework redistributable package from Microsoft. This was the case in past years but MS may have just included it into the normal Windows Updates nowadays.

------

At this point I'm going to wait a few days and see if anyone tries this, and if they have any problems.

The automatic control part can be added on to the Dweeno Link program with the existing controls in place.
I haven't done that yet myself, but it isn't difficult.
Title: Re: Dweeno Link: Visual Basic robot control
Post by: Doug83 on August 17, 2017, 10:18:33 PM
Before moving on to other more complicated things, I will add a couple more little features to what is done so far.

1. Add a combobox control to allow changing the connection speed.
2. Add a checkbox control to allow or prevent the [Send button] from disabling automatically until a response is received.

See the image below:

(http://beevilletrainwreck.com/assorted/dweeno/11_added_controls.png)

Drag the form's border and the two groupboxes out so you have more room, and arrange the existing controls like you see above.

Then:
1) Drag a new Label from the Toolbox onto the form, and change its Text property value to say Speed . Leave its Name as it is.

2) Drag a ComboBox from the Toolbox onto the form. Leave its Name as it is (ComboBox1). Change the DropDownStyle property to DropDownList.

3) Now, drag a CheckBox control onto the form, below the [Send button]. Change the Text property to say ?Keep send button enabled?. Leave its name as it is (CheckBox1).

Now you need to add some code, so switch to the code-view tab.

Near the top, there is a subroutine that begins with this line:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

Create a new line inside that sub and add the lines below:
Code: [Select]
ComboBox1.Items.Add(115200)
ComboBox1.Items.Add(57600)
ComboBox1.Items.Add(38400)
ComboBox1.Items.Add(28800)
ComboBox1.Items.Add(19200)
ComboBox1.Items.Add(14400)
ComboBox1.Items.Add(9600)
ComboBox1.SelectedIndex = 0

Next, go back to the designer tab and double-click on the Listbox1 control. It will switch back to the code-view tab and put the cursor inside the sub that begins with the line:
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged

In that sub there is a line that says MySerialPort.Open() .
Make an empty line ABOVE that statement, and then add the line below:
Code: [Select]
MySerialPort.BaudRate = Convert.ToInt32(ComboBox1.SelectedItem.ToString)

Next, go back to the form design tab, and double-click on the checkbox you made earlier.
Visual Studio will create a subroutine as below, but without any lines inside it (just the first and last lines).
You need to copy all inside lines below, and put them into your own sub.

Code: [Select]
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
        If ListBox1.SelectedIndex <> -1 Then
            If CheckBox1.CheckState = CheckState.Checked Then
                Send_Button.Enabled = True
            End If
        End If
    End Sub

Next, go back to the form design tab again, and double-click on the [Send button].
Visual Studio will switch to the code view tab and put the cursor into the sub for that button.
You need to change your code so that it looks like what is below.

Code: [Select]
Private Sub Send_Button_Click(sender As Object, e As EventArgs) Handles Send_Button.Click
        If MySerialPort.IsOpen() Then
            incomingData = ""
            outgoingData = Sending_TextBox.Text
            'If you wanted the ability to automatically progress through a list of commands,
            'then this is where you would start the process by sending the first command in the list of commands to send.
            SendOutgoingData()
            Receiving_TextBox.Text = ""
            If CheckBox1.CheckState = CheckState.Unchecked Then
                Send_Button.Enabled = False
            End If
        End If
    End Sub

NOW,,,, if there is no errors, try to build/run the program again.

The connection speed combobox will default to the highest speed of 115200, but now you should be able to set it to slower speeds if you want.
The speed change does not take effect until you click into the listbox below however, on the COM port you want to use.

If you check the "Keep send button enabled" checkbox, then the Send button won't be disabled while waiting for an Arduino response.
And if the Send button is already disabled, checking the checkbox should re-enable it again--even if it was disabled because the PC was already waiting for an Arduino reponse.
Title: Re: Dweeno Link: Visual Basic robot control
Post by: Doug83 on August 26, 2017, 11:51:20 AM
In this stage we will add 20 user-editable buttons.
They can be customized by typing the desired settings directly, or by loading (or saving) already-existing settings from a text file. This way you can have as many different button config files as you want, and you can still use any of them easily.

Step 1: drag a TabControl control onto the form, and drag it out big as shown below. (I have moved the "Serial connection" groupbox to make more room).

(http://beevilletrainwreck.com/assorted/dweeno/user_buttons/ucfb_01.png)

Step 2: with the new TabControl highlighted, open the property that says TabPages.

Step 3: a dialog box that is titled "TabPage Collection Editor" should open. On the left side, highlight "TabPage1". On the right, find the property "Text" and change it to say "Buttons".

(http://beevilletrainwreck.com/assorted/dweeno/user_buttons/ucfb_02.png)

Step 4: On the left side again, highlight "TabPage2". On the right, find the property "Text" and change it to say "Button settings". Press the [OK] button to close that dialog. If you did it correctly, the two TabControl tabs on-screen should now say "Buttons" and "Button settings".

Step 5: Click on the Buttons tab on the TabControl, drag twenty buttons onto it and arrange them as shown below. Change each button's Name property by adding the letters "UP" onto the front--so that Button1 is renamed to UPButton1, and so on. Do that for all twenty buttons. You want them to be named UPButton_1 through UPButton_20 when you are done.

(-the Text properties of the buttons will still say Button1 through Button20, but that isn't important right now. You don't need to change that. Just rename the buttons-)

(http://beevilletrainwreck.com/assorted/dweeno/user_buttons/ucfb_04.png)

Step 6: drag twenty labels onto the form as shown above, placing each one at the upper-left corner of each button. Change each label's Text property to the same ending number as the button has (-the reason we are adding these labels is because the text on these buttons is going to be editable by changing text boxes on the other tab, and so you need some way other than the button's text to identify which button is which-).

Note: the buttons don't need to be in straight columns and rows, it was just easier to show the example that way. You can move them around later if you want. You just need to make sure you keep the correct text label next to its button.

Step 7: Now change to the Settings tab on the TabControl. Create a button on the Settings tab, and change its name to LoadUBF_Button. Change its text to say "Load user-set button file". ------- (For these next steps, see the next image further below)

Step 8: create another button and change its name to UPButtons_UseEdits_Button. Change its text to say "Post edits without saving file".

Step 9: Create another button and change its name to SaveUBF_Button. Change its text to say "Save user-set button file".

Step 10: Create a textbox under the left-side button and change its name to UBFpath_TextBox. Change the ReadOnly property to true.

Step 11: Next you need to create a series of textboxes and labels as shown below. The green overlaid text tells what the names of the textboxes must be changed to. When you are done you will have one series of textboxes named UBText_TextBox1 through UBText_TextBox20 and anther series named UBCom_TextBox1 through UBCom_TextBox20, arranged in two groups of two separate columns. The labels only need their text properties changed as you see, none of the labels needs to be renamed.

(http://beevilletrainwreck.com/assorted/dweeno/user_buttons/ucfb_05a.png)

Step 12: In the ToolBox, open the Dialogs section and drag an OpenFileDialog control onto your form (drop it anywhere) and then drag a CloseFileDialog onto the form (also drop it anywhere). A new panel under the form display will appear, and these two controls will be displayed in there. By default their names will be OpenFileDialog1 and CloseFileDialog1, and just leave their names like that.

Step 13: copy everything from the PasteBin link below, and paste that over everything on the code-view tab of the Dweeno Link project.

https://pastebin.com/rsbZycia

There should be no errors showing at this point.
You can try running it now if you want, just to see that it does,,, but there's no button config file to use yet.

Step 14: the OpenFileDialog will be set to open in the My Documents folder.
Go into your My Documents folder and create another folder named dweeno_link. Then inside that folder, make another folder named button_configs. Inside that folder create a plain text file named user_set_buttons_01.txt
Copy the text from the pastebin link below into that text file and save it.

https://pastebin.com/c6j6EmxS

Each line of this file has three dividing vertical bars (|||, ASCII#124) that separate the file line into four sections.
The first part (button) and the second part (a number) is just indicating what button that line refers to.
The third section is the text that will be used on the button. (Note: no vertical bars allowed)
The fourth section is the actual command that the button will send out over the USB/serial port.

The last line of the text file is just the letters EOF, for an end-of-file marker.

In my example file, only the first three buttons have button text and commands assigned to them. The rest of them don't at the moment. If you don't need to use a button then you can just leave the last line section blank. The Dweeno Link program is set to skip sending it, and pop up a message box that says the button has no command to send.

You can edit the button configuration files directly if you want and then just re-load the button configuration file in Dweeno Link, but you can also edit and save them while in the Dweeno Link program.

HOW TO USE IT:

Now try running the Dweeno Link program again.

On the Settings tab, the left upper button [Load user-set button file] is for loading a button configuration file. Open the file in dweeno_link\button_configs\user_set_buttons_01.txt

The first three button textboxes should show text and a command in them, that sends to the Arduino when they are clicked on. The rest of the buttons aren't set, so they won't do anything yet.

The right upper button [Save user-set button file] does two things. Whatever button text and commands are in all those text boxes gets saved as the named button file, and the button text get re-copied to the actual command buttons so that the command buttons say what they're supposed to.

The center button  [Post edits without saving file] is for using changes without saving a file: if you want to edit any buttons but don't want to save those edits as a file, then clicking on [Post edits without saving file] copies the button text from the Settings tab into the command buttons themselves--but DOES NOT save the file.

Whenever you click on a button on the first tab, it will send whatever serial message is in its corresponding Button command textbox on the second tab.