Visual Basic And Arduino (Serial) : Reading

So I'm trying to use my Arduino Nano (from Gravitec) and one of these:

To create a custom game controller (any game) and right now I'm focused on getting it to simulate the key-press of W,S,A or D.

The only way that It looks like I can do this is sensing the position of the joystick -> turning that position into a line of serial -> reading that value in visual basic -> using the "SendKeys" function in VB (2010).

I've dabbled in visual basic before but that was only with sending lines of serial to the arduino, not receiving them. :~

So where should I start? I mean I've kind of done my homework by looking around in the forum and it looks like I should be using the Readline().ToString() in visual basic. It also seems as though I'm going to have to loop to read the constant input of the arduino inside of visual basic.

Or If there's some library that I'm unaware of that lets me use my arduino (either uno or nano I've got both) as a USB HID. Or maybe just bypass visual basic with some cleverness.

Thanks in advance!

Or maybe just bypass visual basic with some cleverness.

Not really sure what you are trying to accomplish, but have you considered just directly wiring the pots in the joystick directly to your nano as analog inputs?

It's better to use the datarecieved event in VB, but it requires you to use a delegate, because the serial comm stuff and the rest of your program are running in two differen threads.

I have a small example of how to do it here:

http://mikmo.dk/misc/vbarduino.zip

The program was used to recieve a string of values read from 16 pots hooked up to an Arduino.

If you never used delegates in VB it can be a little hard to understand.

The code is based on a small "serial chat program" i found somewhere on Microsofts sample code site a long time ago.

Not really sure what you are trying to accomplish, but have you considered just directly wiring the pots in the joystick directly to your nano as analog inputs?

The Joystick is wired to the arduino, and since it uses two pots, it is wired to the analog inputs (atucally a multiplexer but that's because I know I'm eventually going to need much more that 7 Inputs XD ) So all it is doing is sending those values to the serial COM port which is eventually and hopefully read by visual basic, which then visual basic simulates a key-press.

You're going to want to fully emulate keydown and keyup events as opposed to just Sendkeys.

Issue a W keydown event when your joystick vertical analog value > some preset.
Issue a W keydown event when your joystick vertical analog value < some preset (may want some hysteresis to avoid stuttering around the preset).
Same with S.

Similar with A and D on the horizontal axis. You'll want a deadzone around the center of the joystick where no keys are pressed.

Similar with A and D on the horizontal axis. You'll want a deadzone around the center of the joystick where no keys are pressed.

I probably should have posted my code :confused: Here it is :

/* 

Verison 1 Changelog:

    Evening of 24 June 2011 | The Crystal LCD was setup
    Aft of July 3rd | Worked On Displaying Joystick Value

*/

#include <LiquidCrystal.h> //LCD Library

//Mux control pins
int s0 = 5;
int s1 = 4;
int s2 = 3;
int s3 = 2;

//Mux in "SIG" pin
int SIG_pin = 0;

int Button1 = 1; //Pressing this will show the raw serial values of the joysticks  Top : (Horz,Vert) Bottom: (Horz,Vert)
int Button2 = 2; //This will label the two # coords Top: Left: (Horz,Vert) Bottom: Right: (Horz,Vert)
int Button3 = 3; //This will show the actual direction Top: (Up ect...,Right ect...) The bottom is still the same
int Button4 = 4; //This will show a 1 sentance description of the combo of both joysticks.

/* 
  Buttons 1-4 above will mostly handle the actions on the on-board lcd for example the different modes of the lcd
  
  The output to the serial console will never change however, only the outputs to the lcd. 
  
  By default the LCD will display the physical directions of the joystick  The left on top and the right on the buttom
  
*/

int Left_X_ZPad = 0;
int Left_Y_ZPad = 0;

int Right_X_ZPad = 0;
int Right_Y_ZPad = 0;

 
/*

The above code will do with zero padding

zero padding is adding 0's before an integer to make it more managable

*/


int delaypot = 5;

//LiquidCrystal lcd(7, 8, 9, 10, 11, 12);


void setup() {
  
  //Mux Setup
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT); 

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  
  pinMode(12, OUTPUT);  
   
  Serial.begin(9600); //Serial baud rate. If using with the BlueSMiRF set to 115200
 
  //LCD Setup
 // lcd.begin(16, 2);
  
}

void loop() {
  
 
  
if (analogRead(2) < 10 && analogRead(3) < 10 && analogRead(4) > 0){ //1st switch
   TextOut();      
}                           
  
if (analogRead(2) < 10 && analogRead(3) > 0 && analogRead(4) < 10){ // 2nd Switch
  ValsOut();
}

if (analogRead(2) > 0 && analogRead(3)< 10 && analogRead(4) < 10){ //3rd switch
  BothOut();
}
/*
if (analogRead(1) > 0){
  Serial.println("                 ==|==");
}

else if (analogRead(1) < 10){
  Serial.println("");
}

*/
  digitalWrite(12, LOW);
  delay(analogRead(delaypot));
  digitalWrite(12, HIGH);



}
int readMux(int channel){
  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };

  //loop through the 4 sig
  for(int i = 0; i < 4; i ++){
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }

  //read the value at the SIG pin
  int val = analogRead(SIG_pin);
   
  //return the value
  return val;

}

void TextOut(){
     
      Serial.print("(");
      
      if ((readMux(0)) > 510){
          Serial.print("A");
      }
      else if ((readMux(0)) < 505){ 
          Serial.print("D");
      }
      if(readMux(0) >= 505 && readMux(0) <= 510){
          Serial.print("#");
      }
       
      Serial.print(",");
  
      if ((readMux(1)) > 498){
          Serial.print("W");
      }
      else if ((readMux(1)) < 495){ 
          Serial.print("S");
      }
      if(readMux(1) >= 495 && readMux(1) <= 498){
          Serial.print("#");
      }
      
      Serial.println(")");  
  }

void ValsOut(){

      Serial.print("(");
    
     if ((readMux(0)) == 0){ 
         Serial.print("000"); 
     }
     else if ((readMux(0)) < 10){  
          Serial.print("000");    
     }
     else if ((readMux(0)) < 100){  
          Serial.print("00");     
     }
     else if ((readMux(0)) < 1000){
          Serial.print("0");       
     }
   
     Serial.print((readMux(0)));
     Serial.print(",");
   
     if ((readMux(1)) == 0){ 
         Serial.print("000"); 
     }
     else if ((readMux(1)) < 10){  
          Serial.print("000");    
     }
     else if ((readMux(1)) < 100){  
          Serial.print("00");     
     }
     else if ((readMux(1)) < 1000){
          Serial.print("0");       
     }
     
     Serial.print((readMux(1)));  
     Serial.println(")");
}

void BothOut(){
  
      Serial.print("(");
      
      if ((readMux(0)) > 510){
          Serial.print("A");
      }
      else if ((readMux(0)) < 505){ 
          Serial.print("D");
      }
      if(readMux(0) >= 505 && readMux(0) <= 510){
          Serial.print("#");
      }
       
      Serial.print(",");
  
      if ((readMux(1)) > 498){
          Serial.print("W");
      }
      else if ((readMux(1)) < 495){ 
          Serial.print("S");
      }
      if(readMux(1) >= 495 && readMux(1) <= 498){
          Serial.print("#");
      }
  
       Serial.print(")");
       Serial.print(" | ");
       Serial.print("(");
     
     if ((readMux(0)) == 0){ 
         Serial.print("000"); 
     }
     else if ((readMux(0)) < 10){  
          Serial.print("000");    
     }
     else if ((readMux(0)) < 100){  
          Serial.print("00");     
     }
     else if ((readMux(0)) < 1000){
          Serial.print("0");       
     }     
     
     Serial.print((readMux(0)));
     Serial.print(",");
   
     if ((readMux(1)) == 0){ 
         Serial.print("000"); 
     }
     else if ((readMux(1)) < 10){  
          Serial.print("000");    
     }
     else if ((readMux(1)) < 100){  
          Serial.print("00");     
     }
     else if ((readMux(1)) < 1000){
          Serial.print("0");       
     }
     
     Serial.print((readMux(1)));  
     Serial.println(")");
  
}

So there are a couple of switches that change what it sends out but that was for debugging purposes at the time. I'm mainly concerned with this part:

void TextOut(){
     
      Serial.print("(");
      
      if ((readMux(0)) > 510){
          Serial.print("A");
      }
      else if ((readMux(0)) < 505){ 
          Serial.print("D");
      }
      if(readMux(0) >= 505 && readMux(0) <= 510){
          Serial.print("#");
      }
       
      Serial.print(",");
  
      if ((readMux(1)) > 498){
          Serial.print("W");
      }
      else if ((readMux(1)) < 495){ 
          Serial.print("S");
      }
      if(readMux(1) >= 495 && readMux(1) <= 498){
          Serial.print("#");
      }
      
      Serial.println(")");  
  }

Because that has all of the deadzone stuff included and its a nicer-looking string IMO.

This is the arduino side of my program and I don't have any VB stuff as of yet besides MikMo's

Thanks guys!