Arduino NG and Parallax Servo Controller

Hey all,

I've got a question – I'm trying to interface the Parallax Servo Controller through the Software Serial Library.

The Servo Controller accepts the following syntax: “!SC” C R pw.LOWBYTE, pw.HIGHBYTE, $0D
Where "!SC" is the header, C is a binary number, R is a binary number, PW is a 16bit word, and the $0D is the command terminator (Carriage Return).

I can send the "!SC" with SWprint('!SC);, and the command terminator using SWprint(10), the ASCII value for $0D. My question is, how do I send the binary numbers, and the 16-bit word?

Any insights would be much appreciated!

Serial.print(b, BYTE); will send the byte b

to send a 16 bit integer you need to extract and send the bytes seperatly

int i
byte lsb = i & 0xFF;
byte msb = i >> 8;

Serial.print(lsb, BYTE); // sends the LSB
Serial.print(msb, BYTE); // sends the MSB

edit: I just realised that you are not using the Serial hardware lib.
This page: http://www.arduino.cc/en/Reference/SoftwareSerialPrint says the software library should work the same as the hardware

Thanks for your fast reply! I've tried the following:

int pw = 1250;
byte lsb = pw & 0xFF;
byte msb = pw >> 8;

SWprint(lsb, BYTE);

But when I compile, it displays the following error:

In function 'void setup()':
error: too many arguments to function 'void SWprint(int)

Have you got any idea what might be causing this?

edit:
I've been using code from the following tutorial by the way:

I don't think SWprint takes two arguments so:
SWprint(lsb); //should work?

or you could use the form:
serial.print(lsb, BYTE); // if my interpretation of the refrence linked above is correct

I'll give that a try, thanks again for your help – my only form of debugging until now is seeing if the servo actually moves. Am I correct in sending the binary numbers as follows?:

byte chan = 1;
byte ramp = 7;

SWprint(chan);
SWprint(ramp);

I would expect that to work. You can test what is being sent if you send to the Arduino IDE serial monitor instead of the servo board.

Setup software serial to send on pin1 (the pin that connects the arduino to your pc)

Then try something like this:
byte chan = 1 + '0';
byte ramp = 7 + '0'

SWprint(chan);
SWprint(ramp);

If you see a 1 and 7 on the serial monitor then you have confirmed that SWprint is sending the binary value, this is what you want.

If you see 48 and 55 then it is converting the values into ascii digits before sending, so try the other form: serial.print(chan); serial.print(ramp);

I've tried your code, but if I use the single quotes around the zero, the compiler displays error: stray '' in program

If I use these '0', the code does work and the Serial Monitor displays:
![](colorwash.nl 5.png)

This is not binary or ASCII is it? That was at 2400 baud though, at 9600 baud (set in the software serial), it displays:
![](colorwash.nl 6.png)

With serial.print it does display 1 and 7 in the Serial Monitor, I guess that's the way to go then. Thanks for your help so far!

yes, it should be single quotes:
byte chan = 1 + '0';
byte ramp = 7 + '0';

Not sure what you are seeing on the serial monitor, can you post your sketch that just has this serial test (with any interface code to the servo board removed)

edit, saw your post above after posting this, so ignore my request to post test code.

Good luck

Hello again,

I’ve tried some things but my the servo controller has not been responding yet, the code below gives the following output in the serial monitor:

!SC17â

arduino sketch:

// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>

// #define rxPin 6
// #define txPin 7

#define rxPin 0
#define txPin 1

byte chan = 1 + ‘0’;
byte ramp = 7 + ‘0’;

int pw = 1250;
byte lsb = pw & 0xFF;
byte msb = pw >> 8;

// set up a new serial port
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

void setup() {
// define pin modes for tx, rx:
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
// set the data rate for the SoftwareSerial port
mySerial.begin(2400);
digitalWrite(13, HIGH);

mySerial.print("!SC");

mySerial.print(chan);
mySerial.print(ramp);
mySerial.print(lsb, BYTE);
mySerial.print(msb, BYTE);
mySerial.print(13, BYTE);

}

void loop() {
// …
}

I've got some things working now, thanks for your help!

Good to hear that you have it going.

Just curious to know why you are using software serial on ports 0 and 1 on your ng board. I thought the ng had hardware support for serial on these ports

Well, I’m using the software serial for communicating through port 6 and 7, to the servo controller. But for debugging the output I temporarily used ports 0 and 1 to display the output in the serial monitor, as you suggested in your post yesterday.

Hi, I just got myself an arduino board, and already have the PSC. Would you be able to post your code on how you have got it working? I have tried what has been posted so far but with little luck.

Thanks

How I exactly got it to work, I'm not sure, what I do know is that I noticed there was no servo movement – but I was also sending the same (1250) position over and over again, that sure did not help either in getting it to move. Next to that I still had the jumper on the board, which turned the servo channels in 16-32, instead of 1-15.

Here's the code, that works well for me:

// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>

#define rxPin 6
#define txPin 7

// set up a new serial port
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

void setup() {
// define pin modes for tx, rx:
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
// set the data rate for the SoftwareSerial port
mySerial.begin(2400);
//debug led
digitalWrite(13, HIGH);

}

void loop() {

changeServo(9, 300);
delay(2500);
changeServo(9,1150);
delay(2500);

}

int changeServo(int chan, int posi){

int pw = posi;
byte lsb = pw;
byte msb = pw >> 8;
int ramp = 0;

mySerial.print(33, BYTE); //!
mySerial.print(83, BYTE); //S
mySerial.print(67, BYTE); //C
mySerial.print(chan, BYTE); //channel
mySerial.print(ramp, BYTE); //rampspeed
mySerial.print(lsb, BYTE); //LSB
mySerial.print(msb, BYTE); //MSB
mySerial.print(13, BYTE);

}

I did have some trouble managing to change a global var from within the loop, therefore some variable declarations are within the loop.

So I have answered my own question, and thought you might want to see the code. This is the first time I have written code for an arduino so there may be some unnecessary bits in there. I hope the comments explain it enough.

// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>

#define rxPin 0
#define txPin 7

void SetServoPos(byte chan, int pos, byte ramp);

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
byte BR = 1;

void setup(){

// define pin modes for tx, rx:
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);

// set the data rate for the SoftwareSerial port
// The PSC starts at 2400
mySerial.begin(2400);
digitalWrite(13, HIGH);

// set PSC baud rate to 38400
// makes the PSC go as fast as possible
mySerial.print("!SCSBR");
mySerial.print(BR, BYTE);
mySerial.print(13, BYTE);

mySerial.begin(38400);
}

void loop() {

// SetServoPos Example:
// SetServoPos(Channel, Angle, RampRate)
SetServoPos(5,90,7);
delay(3000);
SetServoPos(5,45,7);
delay(3000);

}

void SetServoPos(byte chan, int pos, byte ramp){

// Converts angel into PWM data
int realpos = int(pos*(1000.0/180.0)+250.0);

byte lsb = realpos & 0xFF;
byte msb = realpos >> 8;
mySerial.print("!SC");
mySerial.print(chan, BYTE);
mySerial.print(ramp, BYTE);
mySerial.print(lsb, BYTE);
mySerial.print(msb, BYTE);
mySerial.print(13, BYTE);

}

I tried your code.
But have you ever tried multiple servos??
I'm trying to make them move at the same time together.
I can't make it! I tried everything BUT...

Also if I change the ramp rate to higher number to make the speed slower, the angle is also changed.
I never can make the motor go to 180 degree.

What can I do?????