This is my setup to control a robotic arm comprised of 9 servos. I need to send a 3 byte command to a servo controller over a serial connection. They must be sent as individual byte values, not as text representations of numbers. This is what the manual states:
For example, to run servo 3 at a speed of 4 units per frame to position 100, your instruction would be as follows. [255, (128+3), 100]
The code I have been playing with and failing is this:
#include <SoftwareSerial.h>
const byte rxPin = 10;
const byte txPin = 9;
byte sync = 255;
byte pos = 127;
byte servo = 0;
// Set up a new SoftwareSerial object
SoftwareSerial mySerial (rxPin, txPin);
void setup() {
// put your setup code here, to run once:
mySerial .begin(9600); // set up Serial library at 9600 bps
}
void loop() {
// put your main code here, to run repeatedly:
mySerial .write(sync);
mySerial .write(servo);
mySerial .write(pos);
delay(10000);
pos = 184;
mySerial .write(sync);
mySerial .write(servo);
mySerial .write(pos);
pos = 127;
delay(10000);
}
Ultimately I want to be able to create movements that would consist of numerous commands strung together to create a full function such as picking something up, etc. But I cant seem to figure out how to get the command to the servo controller to even begin. Currently my code does not move the servos at all and I never see the LED flash on the servo controller indicating it has received a command. Using the same code on the hardware serial and printing it I get:
�255
0
127
�255
0
127�255
0
127
�255
0
127
so it seems to be sending the numbers but I guess not correctly?
I tried this code, and the other coding examples presented by others, but got no response from the servo controller. It should have its LED light go off after receiving its first command then blink on any further commands. This puzzled me so much that I reinstalled the old mini-ABB board using a BS2 chip to make sure the servo controller still worked. It did. The ABB board has 3 buttons and they are currently programmed to pickup a ping pong ball, insert it in a holder, which then throws it. This was programmed with Basic Stamp, but not by me obviously. The basic stamp 2 program example to send a command looks like this:
serout 8,n96n, [sync, svo + speed, pos1]
It seems like my softwareserial port isn't working? How can I test to see if anything is actually being transmitted? I know I can serial.println on the hardware serial port. Is there a way to forward that output to the hardware serial port so I can see what is being sent, if anything?
This is all good stuff that I hope to incorporate, but I've tried the various code given to me and cant get any response from the servo controller. I put back my old mini-ABB board and confirmed that the servo controller board is still working. I'm wondering if my software serial is even transmitting anything. I can see the numbers being transmitted on the hardware serial when testing, but I'm not sure how to confirm if the softwareserial port is even sending anything. Is there a way to echo the transmitted variables on a software serial?
The serial is wired with the serial TX on the arduino, pin9, going to the serial-in port on the servo controller board, and then a ground from the servo controller board going to GND on the arduino. Its pretty much just like how the mini-ABB board is wired .
That is from the manuals section on programming for the SSC-12 or mini SSC III which is what the servo controller is called. This is old stuff, but still just uses the simple mini SSC-II protocol. They are sent as 3 individual bytes like:
so... First, let me say that despite the various suggestions on how to do it better, the code that you have in the original post SHOULD WORK FINE. I do not see anything wrong with the code, or with your translation of what you say you're trying to do to what you've actually done. Serial.write() is the function you want for writing raw bytes.
If this is the Servo Controller you are using: https://www.seetron.com/docs/ssc2mnl.pdf then there are a couple of worrying aspects:
It mentioned a bitrate jumper, which if omitted will cause the board to operate at 2400bps rather than 9600bps. I'll assume that this is present, since it works with your stamp...
More seriously, the manual implies that the board is designed to connect directly to the DB9 serial port of a PC. This would mean "rs232 levels", which are INVERTED compared to the signals put out on Arduino's "TTL level" pins. (They're a different voltage, too, but that shouldn't matter in this case.) A quick glance at a BASIC stamp manual implies that it also will typically output "rs232-like" signals, rather than "ttl-like.
If (2) is your problem, you'll be happy to know that there's an option in the softwareSerial library to output inverted signals.
SoftwareSerial(rxPin, txPin, inverse_logic);
// used like:
SoftwareSerial mySerial(9, 10, true);
Ahh. It may be a symbol defined deep in the Stamp IDE, but the SEROUT documentation does rather imply that "baud codes" starting with N are "inverted."
In the Basic Stamp 2 program n96n is a variable name with a value of $4054 which sets a baudmode of 9600, if I understand it correctly. I actually was searching to find what it stood for and then went back and realized it was just a variable name they used to set the 9600 baud rate on. This is a Basic Stamp II program that the manual uses to demonstrate sending commands to the servo controller:
First, this servo controller is the mini SCC III or SCC-12 which was made by seetron for Lynxmotion specifically for use in one of their hexapod models. It doesn't have the jumpers to change baudrate. It is hard coded at 9600. It does have a serial in pin and also an RJ11 connection for serial. I'm using the serial in pin.
Second, I had wondered if the serial connection was actually being established and just started looking at the whole inverted thing based on some info I found elsewhere, but didn't know enough about anything to actually try to implement it. Having said that.....it worked! I'm not sure why the manual didn't mention anything about needing to be inverted but it also could just be my inexperience. Thanks again!
Could this code be somehow used to take a long string of these 3 byte commands and send them all so as to make a function out of the entirety which could then be set to execute using a button? Or would I need something different?
Maybe? At some point you may run into problems with how many commands the SSC can accept an process without "pauses." The Arduino can write the data very fast; probably significantly faster than any loop on a Basic Stamp.
From a technical perspective, if you had a 100 bytes array filled with instructions then the same line of code would work
byte command[100] ;
… // code to fill in the array
mySerial.write(command, sizeof command); // send the 100 bytes
You need to double check what are the capabilities on the other side to buffer this data though, the arduino won’t pause and at 9600 bauds the 100 bytes will be out in roughly 100ms