Grasshopper to Arduino

Hi guys, I'm pretty new to the arduino, but I have a project that I'm working on that I was hoping to get some help on. Basically, I'm trying to control the arduino by feeding information from Rhino's Grasshopper plugin. Grasshopper is a parametric modeling program for Rhino, and I've already created a VB.net definition (with some help from Luis Fraguada) that can send data from Grasshopper to Processing via Udp. For this method, I was using a Udp Library written by Stephane Cusot. However, I'm having problems using the same method to send the data to an Arduino compiled file. I did a search on here and found that Björn Hartmann has a library that seems to be what I need to load, however... I'm having some issues getting the library to be recognized, and then how to modify my arduino file to receive the data. As a test project, I just want to send numeric data from Grasshopper (controlling the rotation of an arm) to the arduino file which will rotate a motor in real-time. If you guys have any suggestions, please let me know. Thanks and I look forward to being a part of this community.

Sorry, it wouldn't let me post links in my first post, so here are a few links that wanted to include: Grasshopper Plugin- (http://www.grasshopper3d.com/) Stephane Cusot Udp Library - (http://ubaa.net/shared/processing/udp/) Bjoern's Ethernet Library- (http://bitbucket.org/bjoern/arduino_osc/src/tip/libraries/Ethernet/)

I may have written too soon. I just found the Physical Pixel tutorial on the site which shows how to take info from Processing and turn on an LED light on the Arduino board. Since I already have a VB.net component that sends data to processing, I can just send it from Grasshopper>Processing>Arduino... I'll try this method this weekend and see if this work. Fingers crossed...

Is there a reason for using UDP (like distance) ?

It is pretty straight forward to send data over the serial port directly from vb.NET to Arduino.

No, there isn't a specific reason I was using UDP except that I learned to send data from Grasshopper to Processing via UDP... and I figured if I could get it into Processing, then it shouldn't be too hard to send it to the Arduino. I did try to come up with a method that would send it to GH>Processing>Arduino... but got a little stuck. However, if you think there is a pretty easy way to take the data directly from GH to the Arduino using a VB.net component... I think that would be best. Do you have any information on how to do that? I appreciate the help.

Are there any examples out there that show how to send data to a board using a VB.net script? I would greatly appreciate the help.

Ok, I want to try to re-structure my problem. I’m going to try to re-create the physical pixel example from the Examples page of the forum. In this example, there is the Arduino code that tells the board (in my case, a Decimilla) to turn on an LED pin13 if it receives the letter “H” and to turn the LED off if it receives the letter “L”. I successfully made a Grasshopper VB.net component that will send a message (whatever text string I write) to a processing sketch via UDP. However, I think it would be best to just cut out the middle man and send it directly to the serial port instead of sending it first to a virtual port and then out to the arduino board. So, can anyone help me figure out how to write a VB or C# script that would write either the letter “H” or the letter “L” to the serial port depending on a boolean toggle.

Here’s the arudino code (pasted from the forum)

  http://www.arduino.cc/en/Tutorial/PhysicalPixel
  */

 const int ledPin = 13; // the pin that the LED is attached to
 int incomingByte;      // a variable to read incoming serial data into

 void setup() {
   // initialize serial communication:
   Serial.begin(9600);
   // initialize the LED pin as an output:
   pinMode(ledPin, OUTPUT);
 }

 void loop() {
   // see if there's incoming serial data:
   if (Serial.available() > 0) {
     // read the oldest byte in the serial buffer:
     incomingByte = Serial.read();
     // if it's a capital H (ASCII 72), turn on the LED:
     if (incomingByte == 'H') {
       digitalWrite(ledPin, HIGH);
     } 
     // if it's an L (ASCII 76) turn off the LED:
     if (incomingByte == 'L') {
       digitalWrite(ledPin, LOW);
     }
   }
 }

Ok… I’m a little stuck. And since I don’t know VB or C# extremely well… I figured I would go back to my work around version where I could send information from Grasshopper to Processing and then to the Arduino (I know it’s not very efficient). My VB script in Grasshopper looks like this:

  Sub RunScript(ByVal message As String, ByVal activate As Boolean)
    If activate Then

      Dim udpClient As New System.Net.Sockets.UdpClient()

      Dim sendBytes As [Byte]() = System.Text.Encoding.ASCII.GetBytes(message)

      udpClient.Send(sendBytes, sendBytes.Length, "127.0.0.1", 11000)

    End If
    
  End Sub

So, when I launch my processing sketch, I can at least get a received message in the information bar at the bottom. Here’s what I get when I turn the boolean toggle in Grasshopper to true (which should send an “H” to the processing sketch):

Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
[0] "COM3"
receive: "H" from 127.0.0.1 on port 56688

So, I know I have at least successfully sent the letter “H” to the Processing sketch. So, now I’m trying to use that letter “H” (or “L”) like in the Physical Pixel tutorial to turn on the LED. But, somewhere I’m getting stuck. After I receive my message, I run an If/Else loop to check if the message is an “H” then write the letter “H” to the port… just like in the Physical Pixel example. This should turn the LED on. However, it doesn’t. Here is my hacked code of the physical pixel and UDP sketches. Please let me know if you know what I’m doing wrong. Thanks.

// import UDP library
import hypermedia.net.*;
//import serial library
import processing.serial.*; 
Serial port; //define the serial port

UDP udp;  // define the UDP object

/**
 * init
 */
void setup() {

  // create a new datagram connection on port 11000
  // and wait for incomming message
  udp = new UDP( this, 11000 );
  //udp.log( true );             // <-- printout the connection activity
  udp.listen( true );


  // List all the available serial ports in the output pane. 
  // You will need to choose the port that the Arduino board is 
  // connected to from this list. The first port in the list is 
  // port #0 and the third port in the list is port #2. 
  println(Serial.list()); 

  // Open the port that the Arduino board is connected to (in this case #0) 
  // Make sure to open the port at the same speed Arduino is using (9600bps) 
  port = new Serial(this, Serial.list()[0], 9600); 

}


//process events
void draw() {
  ;
}

/** 
 * on key pressed event:
 * send the current key value over the network
 */
void keyPressed() {

  String message  = str( key );      // the message to send
  String ip       = "localhost";      // the remote IP address
  int port        = 11000;            // the destination port

  // formats the message for Pd
  message = message+";\n";
  // send the message
  udp.send( message, ip, port );

}

/**
 * To perform any action on datagram reception, you need to implement this 
 * handler in your code. This method will be automatically called by the UDP 
 * object each time he receive a nonnull message.
 * By default, this method have just one argument (the received message as 
 * byte[] array), but in addition, two arguments (representing in order the 
 * sender IP address and his port) can be set like below.
 */
// void receive( byte[] data ) {                   // <-- default handler
void receive( byte[] data, String ip, int port ) {      // <-- extended handler


  // get the "real" message =
  // forget the ";\n" at the end <-- !!! only for a communication with Pd !!!
  data = subset(data, 0, data.length);
  String message = new String( data );

  if (message == "H"){
   port.write('H');
  }
  else {
    port.write('L');
  }

  // print the result
  println( "receive: \""+message+"\" from "+ip+" on port "+port );

}

Check out these: support.microsoft.com/kb/904795/ support.microsoft.com/kb/823179/

Hey Andy,
I think i’ve got what you want working. In addition to the processing serial library I had to load cc.arduino. This library is avaliable on the arduino website. What you’ll want to do is follow those instructions to get processing working with your Arduino. Put simply, in Arduino GUI open File>Sketchbook>Examples>Library-Firmata>StandardFirmata. Upload this sketch to your Ardunio Board. Now we can use digitalWrite, pinMode, etc in Processing.
Once i had it in processing I switched your code at if(message == "H")...toif (message.startsWith("H")..I’m still a beginner in both processing and with arduino so i’m not sure why your evaluation did not work. In Grasshopper if you switch the string in the panel to a string with a char != “H” it turns off the LED. Not sure if this is what you were aiming for? Also, I used digital pin 12 for my LED. Anyway, here is the full code let me know how it goes:

// import UDP library
import hypermedia.net.*;
//import serial library
import processing.serial.*;
import cc.arduino.*;

Arduino arduino; //define the serial port
int ledPin = 12; //Connect an LED to digital pin 12
 
UDP udp;  // define the UDP object

/**
 * init
 */
void setup() {

  // create a new datagram connection on port 11000
  // and wait for incomming message
  udp = new UDP( this, 11000 );
  //udp.log( true );             // <-- printout the connection activity
  udp.listen( true );


  // List all the available serial ports in the output pane.
  println(Arduino.list());
  //new arduino make sure you select the right COM port in this case [1] worked for me.
  arduino = new Arduino(this, Arduino.list()[1]);
  //init the pin mode as an output
  arduino.pinMode(ledPin, Arduino.OUTPUT);

}


//process events
void draw() {
  ;
}

/**
 * on key pressed event:
 * send the current key value over the network
 */
void keyPressed() {

  String message  = str( key );      // the message to send
  String ip       = "localhost";      // the remote IP address
  int port        = 11000;            // the destination port

  // formats the message for Pd
  message = message+";\n";
  // send the message
  udp.send( message, ip, port );

}

/**
 * To perform any action on datagram reception, you need to implement this
 * handler in your code. This method will be automatically called by the UDP
 * object each time he receive a nonnull message.
 * By default, this method have just one argument (the received message as
 * byte[] array), but in addition, two arguments (representing in order the
 * sender IP address and his port) can be set like below.
 */
// void receive( byte[] data ) {                   // <-- default handler
void receive( byte[] data, String ip, int port ) {      // <-- extended handler


  // get the "real" message =
  // forget the ";\n" at the end <-- !!! only for a communication with Pd !!!
  data = subset(data, 0, data.length);
  String message = new String( data );

  if (message.startsWith("H")){
   println( "receive: \""+message+"\" from "+ip+" on port "+port+": LED ON" );
    arduino.digitalWrite(ledPin, Arduino.HIGH);
  }
  else {
    println( "String Doesn't Match 'H': LED OFF");
    arduino.digitalWrite(ledPin, Arduino.LOW);
  }

  // print the result
  //println( "receive: \""+message+"\" from "+ip+" on port "+port );

}

BTW, if you wouldn’t mind sharing or explaining your VB.NET to receive UDP in grasshopper that would be awesome.
Cheers! :slight_smile: