Arduino and Faulhaber Command execution help

Hello,

I have a faulhaber motion controller: Motion Controllers MCDC 3006 S
I have the RS232 port connected to the Rx and Tx of the arduino through a MAX232. I would like to send commands from the arduino to the faulhaber motion controller.

General Overview: Faulhaber motion controllers are controlled by set of commands, such as:
-V1000 = Starts clockwise rotation of motor at 1000rpm.
-POS = Gets actual numerical position of motor.
-SP5000 = Sets maximum speed to 5000rpm
-EN = enables motor
-SOR0/CONTMOD = behavior settings of motor. not too important for the question.
-M = Starts movement, but only needed for position control, not velocity control. Doesn’t affect behavior though.

Currently, I am trying to send the faulhaber motion controller a “V5000” command through an arduino script. This is the following script I have for this. not too complicated I think.

int once = 0;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600,SERIAL_8N1);
}

void loop() {
  // put your main code here, to run repeatedly:
while(once ==0){
Serial.println("EN");
Serial.println("SOR0");
Serial.println("CONTMOD");
Serial.println("SP5000");
Serial.println("V-5000");
Serial.println("M");
once = 1;
}
while(Serial.available()){
  Serial.write(Serial.read());
}
}

This does not get the motor moving. this is what appears in the Serial Monitor:
FAULHABER MCDC3006S-RS
EN
SOR0
CONTMOD
SP5000
V-5000
M

I know that the two devices are recognizing each other because of the first line:“FAULHABER MCDC3006S-RS” Which is the product code of the motion controller.

However, when I manually type in “V5000” into the command box of the serial monitor and hit send, the motor moves at 5000rpm in clockwise direction.

I am confused as to how to perform the same task of manually typing into command prompt in a standalone script. I have some more information regarding the format of commands sent through the RS232 line attached to this post.

I have also tried numerous other methods to send command lines but with no luck. I’ll post those down in the attachments as well.

byte rx_byte = 0;
byte EN[] = {0x45,0x4E,0x0D};
byte SOR0[] = {0x53,0x4F,0x52,0x30,0x0D};
byte CONTMOD[] = {0x43,0x4f,0x4e,0x54,0x4d,0x4f,0x44,0x0a,0x0D};
byte SP1000[] = {0x53,0x50,0x35,0x30,0x30,0x30,0x0a,0x0D};
byte V1000[] = {0x56,0x35,0x30,0x30,0x30,0x0D,0x0A};
byte  Vneg1000[] = {0x56,0x2d,0x35,0x30,0x30,0x30,0x0D};
byte M[] = {0x4d,0x0a,0x0D};
byte V0[] = {0x56,0x30,0x0D};
byte POS[] = {80,79,83,13,10};
int starter = 0;
void setup(){
 Serial.begin(9600);

}
void loop(){
  int incomingByte = 0; // for incoming serial data


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

    // say what you got:
    Serial.print("I received: ");
    Serial.println(incomingByte, HEX);
    Serial.write(Serial.read());
  }
while(starter == 0){
  Serial.write(Vneg1000,sizeof(Vneg1000));

starter = 1;
delay(1000);
}

serial_communication_2.ino (428 Bytes)

AN121_RS232_ASCII_protocol.pdf (728 KB)

serial_communication_1.ino (1.38 KB)

serial_practice_2.ino (326 Bytes)

If typing in the serial monitor allows you to control the motor, it indicates that your wiring is wrong and that you need to swap pins 0 and 1.

This provides another challenge as now the connection might interfere with the uploads; disconnect pins 0 and 1 during upload will solve that issue.

If you have a need for both connectivity to the PC and the faulhaber controller, consider using software serial for the latter.

Hello, and thank you for the quick replies!

I changed the wiring, and yes although I can't input any commands through serial monitor anymore, the motor does move with the following code.

int once = 0;
int starter =0;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600,SERIAL_8N1);
}

void loop() {
  // put your main code here, to run repeatedly:
delay(10000);
while(starter ==0){
if(once ==0){
Serial.println("EN");
Serial.println("SOR0");
Serial.println("CONTMOD");
Serial.println("SP5000");
Serial.println("V-5000");

once = 1;
delay(5000);
Serial.println("POS");
while(Serial.available()){
int pos = Serial.read();
Serial.print(pos);
}
}
if(once ==1){
  Serial.println("EN");
Serial.println("SOR0");
Serial.println("CONTMOD");
Serial.println("SP5000");
Serial.println("V5000");

once = 0;
delay(5000);
Serial.println("POS");

while(Serial.available()){
int pos = Serial.read();
Serial.print(pos);
}

}



}
}

The output on my serial monitor looks like the following.
23:03:40.858 -> 45505654525151131079751310797513107975131079751310EN
23:03:40.892 -> SOR0
23:03:40.925 -> CONTMOD
23:03:40.925 -> SP5000
23:03:40.925 -> V-5000
23:03:45.863 -> POS
23:03:45.863 -> 505654525548131079751310797513107975131079751310EN
23:03:45.931 -> SOR0
23:03:45.931 -> CONTMOD
23:03:45.965 -> SP5000
23:03:45.965 -> V5000

and the motor moves in opposite directions as it runs through the conditional statements. Now my concern is how to get a sensible value from the "POS" command. I am guessing that I need to make an array and store each hex value being returned from the motion controller, until I detect the carriage return and line feed ASCII command(0x0D,0x0A) but I am not too sure how to get started on this. any help would be appreciated. :slight_smile:

This is what I have up so far, and last step is just to get a sensible value from the POS command. any help would be appreciated. Here is the document discussing the nature of the return values.

int once = 0;
int starter =0;
byte pos_byte[20];
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600,SERIAL_8N1);
}

void loop() {
  // put your main code here, to run repeatedly:
delay(10000);
while(starter ==0){
  int i=0;
  int out = 0;
if(once ==0){
Serial.println("EN");
Serial.println("SOR0");
Serial.println("CONTMOD");
Serial.println("SP5000");
Serial.println("V-5000");

once = 1;
delay(5000);
Serial.println("POS");
//while(Serial.read()!=0x0a){
int pos = Serial.read();
Serial.print(pos);
//}
}
if(once ==1){
  Serial.println("EN");
Serial.println("SOR0");
Serial.println("CONTMOD");
Serial.println("SP5000");
Serial.println("V5000");

once = 0;
delay(5000);
Serial.println("POS");
int pos = Serial.read();
Serial.print(pos);

}



}
}

gives me:
23:40:45.617 -> 10EN
23:40:45.617 -> SOR0
23:40:45.617 -> CONTMOD
23:40:45.617 -> SP5000
23:40:45.650 -> V5000
23:40:50.622 -> POS
23:40:50.622 -> EN
23:40:50.622 -> SOR0
23:40:50.622 -> CONTMOD
23:40:50.622 -> SP5000
23:40:50.656 -> V-5000
23:40:55.614 -> POS
23:40:55.614 -> 79EN
23:40:55.614 -> SOR0
23:40:55.648 -> CONTMOD
23:40:55.648 -> SP5000
23:40:55.648 -> V5000

Serial.read() only returns one character; a quick solution (possibly not the best) will be to use Serial.readBytesUntil() and use '\n' for the character to wait for.