Go Down

Topic: Major help with VB -> Arduino (Read 3223 times) previous topic - next topic

Du-z

hey guys i have been working on a project for around six months (yes i was/still am a newbie in electrical engineering)

heres the log of my progress, the first two entries have all the info you should need to know.

http://www.overclock.net/case-mod-work-logs/502116-project-case-fan-led-controller.html

basically i have built my own arduino and i have manage to make the LEDs turn off and on using processing. so the hardware is OK.

I have moved onto VB 2008 now to try and do a similar thing but it is not working, could one of you guys make a simple program for me.

basically 2 buttons one button sends a instruction to turn on the LEDs and another turns them off.

Du-z

bump to the top, please help or point me in the right direction.

Robert Lee

Asking people to write a program for you won't get much of a response here (or on most development support forums).

You said that you got this working in Processing, why would you want to redo it in .NET. Nothing wrong with wanting to redo it, just wondering why.

What's not working in .NET, or what are you stuck on? While the code would be different, the concepts would be the same.

From the post on the other forum, I couldn't even begin to guess at what to write, since I don't know what your Arduino code looks like, or how you were doing it in Processing.

In short, you're going to have to post a lot more info to get some help with this.

Andrew Craigie

Hi Du-z,

You might want to have a look at the sample applications on this site:
http://www.acraigie.com/programming/firmatavb/

Especially the ArduinoFirmataVBExtended.zip on the Downloads page. This is a Visual Basic.NET application that communicates to the Arduino which is running Standard Firmata. Firmata is a ready-made protocol for communicating with the Arduino.

Regards,

Andrew
Put together FirmataVB - http://www.acraigie.com/programming/firmatavb/default.html

Du-z

#4
Aug 26, 2009, 09:04 am Last Edit: Aug 26, 2009, 03:11 pm by Du-z Reason: 1
yeah ive been eyeing this, so the idea behind this is so i can modify it to my use?

what if i wanted to use my own protocol?

0 = off
1 = white
2 = green
ect....

Sorry about my ignorance Robert.

Andrew Craigie

Hi Du-z,

Yes you can modify the Firmata protocol if you want to and you can certainly modify the FirmataVB code for your own needs (you're encouraged to do so)

To turn on/off some LEDs you can use the Standard Firmata sketch as it is. Load this onto your board. Connect LEDs to as many digital pins as you like (pins 2 - 13).

You would then send messages to the board from your software using the Firmata protocol. This is where the FirmataVB code comes in. You would adapt it to do what you want. You can either set up buttons in your VB project to turn on/off LEDs or have the user type in values that the software then sends to the board.

Not sure from you're reply whether you intend trying to control RGB LEDs but if you did you could use the PWM pins to 'mix' the colours.

Anyway, the best way to find out how it all works is to try it out

I'd suggest you...
  • Upload the Standard Firmata sketch to your board
  • Download and extract the ArduinoFirmataVBExtended zip file from the download page at http://www.acraigie.com/programming/firmatavb/firmatavb_downloads.html
  • Navigate to the following folder in the download ArduinoFirmataVBExtended\ArduinoFirmataVBExtended\ArduinoFirmataVBExtended\bin\Release
  • Double click the ArduinoFirmataVBExtended.exe file and try this out with a few LEDs connected to your board.


Regards,

Andrew Craigie
Put together FirmataVB - http://www.acraigie.com/programming/firmatavb/default.html

Du-z

sweet I will give this a go!

yes I am using RGB LEDs on the PWM pins.

Du-z

#7
Aug 26, 2009, 12:17 pm Last Edit: Aug 26, 2009, 12:18 pm by Du-z Reason: 1
Unfortunately Firmata is not working it is not working, and it is not as streamline as i would like later on as i might be making a few of these for friends.

However i have made a sketch for the Arduino. How will i be able to make this work with VB?

From what i can see this code will work.

Code: [Select]

   By Du-z

Notes:

EEPROM Addresses:
1 = Red LED Colour
2 = Green LED Colour
3 = Blue LED Colour



*/

#include <EEPROM.h>
#include <LED.h>

LED ledboot_ok = LED(13);//declare digital pin 13 as the boot ok LED.
LED ledr = LED(11);//declare digital pin 11 as a Red LED's.
LED ledb = LED(10);//declare digital pin 10 as a Blue LED's.
LED ledg = LED(9); //declare digital pin 9 as a Green LED's.
int com;




void setup()
{
 Serial.begin(9600); // opens the com port and sets it at 9600 baud
 ledr.setValue(EEPROM.read(1)), ledg.setValue(EEPROM.read(2)), ledb.setValue(EEPROM.read(3)); // sets LEDs and fans to previous settings before reset.
 ledboot_ok.setValue(255); // Turns boot_ok LED on
}

void loop()
{
 if (Serial.available())
 {
   com = Serial.read();

   // This is for the red LEDs
   if (com >= 1000 && com <= 1225) {
     ledr.setValue( com - 1000);
     EEPROM.write(1, com - 1000);
   }
   // This is for the green LEDs
   if (com >= 2000 && com <= 2255) {
     ledg.setValue(com - 2000);
     EEPROM.write(2, com - 2000);
   }
   // This is for the blue LEDs
   if (com >= 3000 && com <= 3255) {
     ledg.setValue(com - 3000);
     EEPROM.write(3, com - 3000);
   }
 }
}



How can i make this a reality?

Edit: Sorry for the double post.  :-[

Andrew Craigie

Hi again,

Not sure what you mean by 'Firmata is not working'!?! I'm assuming you mean it is not working for you and as your post suggests it is not working for you in the way you would like it to. With Firmata running on your Arduino and using the FirmataVB component you could easily implement a small program in VB.NET or C#.NET to send PWM to any/all of the 6 PWM pins on the Arduino. The issue is then one of knowing how to write the .NET application. Forgive me if i'm wrong on this but it seems that is where you're looking for support.

To 'simply' control your LEDs you don't, of course, need to use Firmata. You do however need to create your own protocol and write not only the Arduino sketch to receive it but to write the VB.NET application as well. You've made a start with the Arduino sketch.

A few comments on your Arduino sketch first:

You appear to be trying to set the value of Pin 13 to 255. Pin 13 is not a PWM pin so to turn it on you'd use digitalWrite(ledboot_ok, HIGH) and to turn it off you'd use digitalWrite(ledboot_ok, LOW).

It looks like you want to send values of 1000 - 1225, 2000 - 2225, 3000 - 3255 to the Arduino from your computer. Any of these values would require you to send 2 bytes. Nothing wrong with that but using com = Serial.read() will only read the first byte you send and as your code stands all of the if statements would be false all of the time.

If you're going to write your own sketch (rather than using Firmata) you will need to write it to accept at least 2 bytes at a time.

Something like the following might work:

Code: [Select]
if (Serial.available())
 {
   // read the first byte (1, 2 or 3)
   LEDtoSet = Serial.read();
   delay(100);  // this line may not be necessary
   // read the next byte (0 - 255)
   PWMvalue = Serial.read();

   // code here to then set the LED PWM value
   analogWrite(LEDtoSET, PWMvalue);

 }


Doing it that way you'd have to send 3 seperate 2 byte messages from your computer to set the LEDs. An alternative approach would be to have the Arduino sketch accept a 4 byte message. The first byte would be the RGB 'cluster' number then the next 3 bytes would be the R, G & B values. Slightly more complex Arduino sketch but would cut down on data sent and be easier to implement in VB.

In Visual Basic (or C#) a simple program that does the following would work:

  • Configure a serial port with the name of the port your using and the baud rate your using
  • Open the serial port
  • Send the bytes you want to send


I'd include a some VB code for you but work beckons.

Cheers,

Andrew Craigie
Put together FirmataVB - http://www.acraigie.com/programming/firmatavb/default.html

Du-z

#9
Aug 26, 2009, 02:35 pm Last Edit: Aug 27, 2009, 10:12 am by Du-z Reason: 1
ill get that PWM on LED 13 fixed and yes the VB stuff is were i need the help really, the tutorials for Arduino are great.

i like that cluster idea i was actually tried that with processing when i was trying to figure out what was best as far as the protocol goes. i needed to have a 50ms delay in there to wait for the next value.

so basically the first if thing that is sent over the serial is the 'colour' and the next will be the actally LED PWM value

thanks mate  :)

Du-z

Heres the new sketch, but its not working both the 'on' and 'off' buttons turns all of the LEDs on. (i have comented out the EEPROM stuff to make it simpler)

Arduino Sketch:
Code: [Select]
/*
  /*
   By Du-z

Notes:

EEPROM Addresses:
1 = Red LED Colour
2 = Green LED Colour
3 = Blue LED Colour

To Do:

Add Fan Controler.
Serial/Program Active LED ???

*/

#include <EEPROM.h> //  http://www.arduino.cc/en/Reference/EEPROM
#include <LED.h>    //  http://www.arduino.cc/playground/Code/LED

LED ledboot_ok = LED(13);//declare digital pin 13 as the boot ok LED.
LED ledr = LED(11);//declare digital pin 11 as a Red LED's.
LED ledb = LED(10);//declare digital pin 10 as a Blue LED's.
LED ledg = LED(9); //declare digital pin 9 as a Green LED's.
int com;
int colour;

void setup()
{
 Serial.begin(9600); // opens the com port and sets it at 9600 baud
 //ledr.setValue(EEPROM.read(1)), ledg.setValue(EEPROM.read(2)), ledb.setValue(EEPROM.read(3)); // sets LEDs and fans to previous settings before it was reset/turned off.
 ledboot_ok.on(); // Turns boot_ok LED on
}

void loop()
{
 if (Serial.available())
 {
   com = Serial.read();

   // This is for the red LEDs
   if (com = 1) {
     colour = Serial.read();
     ledr.setValue(colour);
     //EEPROM.write(1, colour);
   }
   // This is for the green LEDs
   if (com = 2) {
     colour = Serial.read();
     ledg.setValue(colour);
     //EEPROM.write(2, colour);
   }
   // This is for the blue LEDs
   if (com = 3) {
     colour = Serial.read();
     ledb.setValue(colour);
     //EEPROM.write(3, colour);
   }
 }
}


VB Code:
Code: [Select]

Public Class frmMain

   Dim oCOM As New System.IO.Ports.SerialPort


   Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

       '//use the settings in the config file to set up the com port object

       Try
           oCOM.BaudRate = CInt(My.Settings.baudrate)
           oCOM.DataBits = CInt(My.Settings.databits)
           oCOM.Parity = CType(My.Settings.parity, IO.Ports.Parity)
           oCOM.StopBits = CType(My.Settings.stopbit, IO.Ports.StopBits)

           '//added her for always open
           oCOM.Open()

       Catch ex As Exception
           MessageBox.Show(ex.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
       End Try

   End Sub

   Private Sub btnSend0_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend0.Click
       '//button click event calls the routine below named SendComPortValue, and passes the string value to it
       SendComPortValue("1")
       SendComPortValue("0")
       SendComPortValue("2")
       SendComPortValue("0")
       SendComPortValue("3")
       SendComPortValue("0")

   End Sub

   Private Sub btnSend1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend1.Click
       '//button click event calls the routine below named SendComPortValue, and passes the string value to it
       SendComPortValue("1")
       SendComPortValue("255")
       SendComPortValue("2")
       SendComPortValue("255")
       SendComPortValue("3")
       SendComPortValue("255")
   End Sub

   '...add button events here



   Private Sub SendComPortValue(ByVal sValueToSend As String)

       '// reusable code for sending values over the com port

       Try
           'oCOM.Open()

           oCOM.Write(sValueToSend)

           'oCOM.Close()

       Catch ex As Exception
           MessageBox.Show(ex.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
       End Try

   End Sub


   Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
       '//make sure we close the com port when the app is closing
       If oCOM.IsOpen = True Then
           oCOM.Close()
       End If

       oCOM.Dispose()
   End Sub


End Class

Andrew Craigie

Hi again,

There are two main things that are causing the problem:

1) Timing issues in the Arduino sketch. Adding a delay between reading the serial bytes fixes this
2) You are sending Strings from your VB code. Sending bytes will fix this

A few other minor things that you should be aware of:

  • When using if (Serial.available()) in an Arduino sketch you should use if(Serial.available() > 0) to account for no serial available actually returning a value of -1 which could cause a 'true' even when no serial data is available
  • In the Arduino sketch its a good idea to create variables of the type that the code expects. Using the LED.h library and the led.setvalue() command you should use a byte variable between the brackets. It would probably work with an integer but best to be on the safe side. So it'd be a good idea to use byte colour instead of int colour
  • Read your serial data outside any conditional statements. If for any reason none of the conditions were met the serial buffer would still have the 'colour' data in it the next time through the loop
  • In VB code to send byte values (which is what you want to do) you use an array of bytes (in the code below i've called this sendBuffer but you could call it anything you like.


Anyway... I've included some code below that does work...

Arduino Sketch

Code: [Select]
#include <EEPROM.h> //  http://www.arduino.cc/en/Reference/EEPROM
#include <LED.h>    //  http://www.arduino.cc/playground/Code/LED

LED ledboot_ok = LED(13);//declare digital pin 13 as the boot ok LED.
LED ledr = LED(11);//declare digital pin 11 as a Red LED's.
LED ledb = LED(10);//declare digital pin 10 as a Blue LED's.
LED ledg = LED(9); //declare digital pin 9 as a Green LED's.
// Changed these two variables to bytes instead of integers
byte com;
byte colour;

void setup()
{
 Serial.begin(9600); // opens the com port and sets it at 9600 baud
 //ledr.setValue(EEPROM.read(1)), ledg.setValue(EEPROM.read(2)), ledb.setValue(EEPROM.read(3)); // sets LEDs and fans to previous settings before it was reset/turned off.
 ledboot_ok.on(); // Turns boot_ok LED on
}

void loop()
{
 // changed (Serial.available()) to (Serial.available() > 0)
 if (Serial.available() > 0)
 {
   com = Serial.read();
   delay(50);
   colour = Serial.read();

   // This is for the red LEDs
   if (com = 1) {
     ledr.setValue(colour);
     //EEPROM.write(1, colour);
   }
   // This is for the green LEDs
   if (com = 2) {
     ledg.setValue(colour);
     //EEPROM.write(2, colour);
   }
   // This is for the blue LEDs
   if (com = 3) {
     ledb.setValue(colour);
     //EEPROM.write(3, colour);
   }
 }
}


Visual Basic code
Code: [Select]
Public Class Form1

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       With SerialPort1
           .PortName = "COM2"
           .BaudRate = 9600
       End With

       Try
           SerialPort1.Open()
       Catch ex As Exception
           MessageBox.Show(ex.ToString)
       End Try
   End Sub

   Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
       Try
           If (SerialPort1.IsOpen()) Then
               SerialPort1.Close()
           End If
       Catch ex As Exception

       End Try
   End Sub

   Private Sub btnAllOff_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAllOff.Click
       SendComPortValue(1, 0)
       SendComPortValue(2, 0)
       SendComPortValue(3, 0)
   End Sub

   Private Sub btnAllOnFull_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAllOnFull.Click
       SendComPortValue(1, 255)
       SendComPortValue(2, 255)
       SendComPortValue(3, 255)
   End Sub

   Private Sub SendComPortValue(ByVal colour As Byte, ByVal PWMvalue As Byte)
       Dim sendBuffer() As Byte = {0, 0}
       sendBuffer(0) = colour
       sendBuffer(1) = PWMvalue

       Try
           SerialPort1.Write(sendBuffer, 0, 2)
       Catch ex As Exception

       End Try
   End Sub

End Class


Hope this helps. Good luck with the rest of it.

Andrew Craigie
Put together FirmataVB - http://www.acraigie.com/programming/firmatavb/default.html

Du-z

Would you be able to send the VB stuff in a zip folder via email? i cant get it to debug :(

Andrew Craigie

Hi,

Did you create buttons on your form with the same names I used?

You can download the Visual Basic 2008 project I tested the code in here:

http://www.acraigie.com/programming/firmatavb/downloads/Du_z.zip

I'm not sure what version of Visual Basic you are using but you may not be able to open it in an Express version.

If you can't then work your way systematically through the debug errors and you should get it to work (check the button names first).

Cheers.

Andrew Craigie.
Put together FirmataVB - http://www.acraigie.com/programming/firmatavb/default.html

uberdum05

I got mine working like this :
VB code
Code: [Select]
Public Class Form1
   Dim counter As Integer
   Dim read As Byte

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       SerialPort1.Open()
       SerialPort1.DtrEnable = True
       SerialPort1.DtrEnable = False
       Threading.Thread.Sleep(10)
       SerialPort1.DtrEnable = True
       Timer1.Start()
   End Sub

   Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
       counter = counter + 1
       read = SerialPort1.ReadByte
       '# 0'
       If read = 48 Then
           Button1.BackColor = Color.Red
       End If
       '# 1'
       If read = 49 Then
           Button1.BackColor = Color.Yellow
       End If
       '# 2'
       If read = 50 Then
           Button1.BackColor = Color.Lime
       End If
       If read = 48 Then
           TextBox1.Text = "0"
       End If
       If read = 49 Then
           TextBox1.Text = "1"
       End If
       If read = 50 Then
           TextBox1.Text = "2"
       End If
       If counter = 3 Then
           Call reset_arduino()
       End If
   End Sub

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Timer1.Stop()
       SerialPort1.DtrEnable = True
       SerialPort1.DtrEnable = False
       Threading.Thread.Sleep(10)
       SerialPort1.DtrEnable = True
       SerialPort1.DiscardInBuffer()
       Timer1.Start()
   End Sub
   Private Sub reset_arduino()
       Timer1.Stop()
       SerialPort1.DtrEnable = True
       SerialPort1.DtrEnable = False
       Threading.Thread.Sleep(10)
       SerialPort1.DtrEnable = True
       SerialPort1.Close()
       Threading.Thread.Sleep(10)
       SerialPort1.Open()
       SerialPort1.DiscardInBuffer()
       Timer1.Start()
   End Sub

Arduino code :
Code: [Select]
void setup(){
 Serial.begin(9600);
}

void loop(){
 Serial.println("0");
 delay(100);
 Serial.println("1");
 delay(100);
 Serial.println("2");
 delay(100);
}


That will change the colour of the button on form1 by the arduino sending out 0,1,2.
Hope that helped :)
uberdum05

Go Up