PURE DATA to ARDUINO_2 servos

hello everybody,
I’d like to control several servos with pure data. For the moment I’m able to control one servo with this simple arduino sketch:

#include <Servo.h>

Servo myservo1;
int incomingByte = 0; // for incoming serial data

void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
myservo1.attach(3);

}

void loop() {

// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
myservo1.write(incomingByte);

}
}

in PD, the patch is a simple HSLIDER 0–>180 linked to the object comport 4 9600

I read on the net that to control multiple servos I need to write a communication protocol, … I’m a noob and don’t know how to do this, does anybody know how to?
thank you
manu

I read on the net that to control multiple servos I need to write a communication protocol

A protocol is an agreed upon method for ordering data that is to be communicated.
You could have a command like <Servo1 54> to move servo 1 to 54 degrees.
Or, you could have a command like <S:54, 78> to set two servos to 54 degrees and 78 degrees.

So, what you need to do is to determine (or control) how PureData is able to output to the serial port, and figure out how to make use of that data on the Arduino.

thank you, but I knew it was the way to make it work but I don't know how and where to write this... :-/ is it a new object or a new message in PD? or do I have to add something in the object comport 4 9600 ... I told you I was a noob ;) thanx manu

This is not a PureData forum. The PureData forum is over there. Somewhere.

okay, I go there

okay,...I really searched the net, but I'm not able to find the solution..I know it's not a pure data forum, but this is the interfacing part of the forum so I retry here... I found something to control two servos on pins 9 and 10, but I'd like to control 4 servos and I'd like to use the command myservo2.write(120); I think I'm close to the solution...I understand I have to send a suite of integers from PD like 20 120 50 80 to control the 4 servos, but I don't know how to build the message in PD and how to decompose it in arduino to give each different value to each different servo. I hope there is a pure data arduino master who could tell me the solution or send me in the good way.. thanx and sorry again if it's not exactly the good place to ask this.. manu

Below is a simple servo test application I made using the WString.h library, which makes string handling easier for me. You should be able to expand it for more servos. As to testing your PD programming, you can get a piece of wire and jumper the RX/TX on the arduino board to echo back what ever you send. This way you should be able to see what you are actually sending using PD (assuming your PD program can also read input to the PC serial port).

//zoomkat 7-30-10 serial servo test
//type servo position 0 to 180 in serial monitor

#include <WString.h>
String readString = String(100);
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
      Serial.begin(9600);
        myservo.attach(9);
        }

void loop() {

        while (Serial.available()) {
        delay(10);  
          if (Serial.available() >0) {
        char c = Serial.read();
        readString.append(c); }
        }
        
      if (readString.length() >0) {
      Serial.println(readString);
      int n;
      n = atoi(readString); //convert string to number
      myservo.write(n);
      readString="";
      } 
   }

hi, thank you for the response, but I found a simplest way to do what I want with the Simple Message System library. I use this arduino sketch:

/* 
 ---- SimpleMessageSystem Example 1 ----
 Control Arduino board functions with the following messages:
 
 r a -> read analog pins
 r d -> read digital pins
 w d [pin] [value] -> write digital pin
 w a [pin] [value] -> write analog pin
 
 
 Base: Thomas Ouellet Fredericks 
 Additions: Alexandre Quessy 
 
 */

// Include de SimpleMessageSystem library
// REMOVE THE FOLLOWING LINE IF USING WIRING
#include <SimpleMessageSystem.h> 
#include <Servo.h> 
Servo myservo1;  // create servo object to control a servo 
Servo myservo2;
void setup()

{
  
  // The following command initiates the serial port at 9600 baud. Please note this is VERY SLOW!!!!!! 
  // I suggest you use higher speeds in your own code. You can go up to 115200 with the USB version, that's 12x faster
  Serial.begin(9600); //Baud set at 9600 for compatibility, CHANGE!
 myservo1.attach(4);
  myservo2.attach(5);

}

void loop()
{

  if (messageBuild() > 0) { // Checks to see if the message is complete and erases any previous messages
    switch (messageGetChar()) { // Gets the first word as a character
    case 'r': // Read pins (analog or digital)
      readpins(); // Call the readpins function
      break; // Break from the switch
    case 'w': // Write pin
      writepin(); // Call the writepin function
    }

  }

}

void readpins(){ // Read pins (analog or digital)

  switch (messageGetChar()) { // Gets the next word as a character

    case 'd': // READ digital pins

    messageSendChar('d');  // Echo what is being read
    for (char i=2;i<14;i++) {
      messageSendInt(digitalRead(i)); // Read pins 2 to 13
    }
    messageEnd(); // Terminate the message being sent
    break; // Break from the switch

  case 'a': // READ analog pins

    messageSendChar('a');  // Echo what is being read
    for (char i=0;i<6;i++) {
      messageSendInt(analogRead(i)); // Read pins 0 to 5
    }
    messageEnd(); // Terminate the message being sent

  }

}

void writepin() { // Write pin

  int pin;
  int state;

  switch (messageGetChar()) { // Gets the next word as a character

    case 'a' : // WRITE an analog pin

    pin = messageGetInt(); // Gets the next word as an integer
    state = messageGetInt(); // Gets the next word as an integer
    pinMode(pin, OUTPUT); //Sets the state of the pin to an output
    analogWrite(pin, state); //Sets the PWM of the pin 
    break;  // Break from the switch


    // WRITE a digital pin
  case 'd' : 

    pin = messageGetInt();  // Gets the next word as an integer
    state = messageGetInt();  // Gets the next word as an integer
    pinMode(pin,OUTPUT);  //Sets the state of the pin to an output
    digitalWrite(pin,state);  //Sets the state of the pin HIGH (1) or LOW (0)
    

  }

}

so, with this code and a patch in pure data, I can control each pin separately, but it remains a problem… In pure data, I send for example te message “list w d 4 130”, which indicates to my servo connected to the digital pin 4 to write 130°, I can connect a number box or a slider (0–>180) to move the servo, but when I move the slider in PD from 0 to 180, the servo moves from 0 to 180 but when I don’t move the slider, the servo goes back to 0°. I hope that my description is clear… :-?
I think there is something to add in the arduino sketch…I don’t know what…Does somebody know??
thank you
manu

You have several problems. You are using digitalWrite() to write arbitrary values to the servo pins.

The digitalWrite function expects to write HIGH or LOW to the digital pin, not values like 130.

Servos typically are controlled using PPM, not PWM. With PWM, the duty cycle is on the specified amount of time (out of 255), but the width of a pulse is not controllable. A servo is moved by sending a specific length pulse.

That specific length pulse is sent using Servo.write().

Once you get these issues squared away, if the servo moves back to 0, the reason must be that the servo was commanded to move. That command is coming from PureData, so you need to fix the problem in the PureData code.