|
|
@ -14,26 +14,38 @@ const String manual = "\nM034 stepper motor controll\n" |
|
|
|
"protocol structure: command parameter e.g. movl 200\n" |
|
|
|
"commands (in small letters):\n" |
|
|
|
"help: print instruction manual\n" |
|
|
|
"\n" |
|
|
|
|
|
|
|
"Basic Motor Instructions (without encoder):\n" |
|
|
|
"movl (move left): spin x steps counterclockwise\n" |
|
|
|
"movr (move right): spin x steps clockwise\n" |
|
|
|
"\n" |
|
|
|
|
|
|
|
"Other motor Instructions (without encoder):\n" |
|
|
|
"getp (get position): get current motor position\n" |
|
|
|
"movp (move to position): move motor to position uint32_t x\n" |
|
|
|
"gtmp (go to motor position): go to saved motor position x {0-2}\n" |
|
|
|
"gtep (go to encoder position): go to saved encoder position x {0-2}\n" |
|
|
|
"setn (set null): set current position as motor null position (home)\n" |
|
|
|
"smpo (set motor position): save current motor position (moved steps) as position x {0-2}\n" |
|
|
|
"sepo (set encoder position): save current encoder position as position x {0-2}\n" |
|
|
|
"getp (get position): get current position\n" |
|
|
|
"setn (set null): set current position as null (home)\n" |
|
|
|
"gtmp (go to motor position): go to saved motor position x {0-2}\n" |
|
|
|
"\n" |
|
|
|
|
|
|
|
"Motor configuration:\n" |
|
|
|
"setm (set mode): set mode to: 0 - voltage mode; 1 - current mode\n" |
|
|
|
"sets (set microstep size):\n" |
|
|
|
"\tOptions: 1, 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128\n" |
|
|
|
"\tSetS parameter = 1 for 1; 2 for 1/2; ...\n" |
|
|
|
"\tIn current mode the maximum microstepping resolution is 1/16\n" |
|
|
|
"\tIf changed, Null and saved positions get lost\n" |
|
|
|
"\n" |
|
|
|
|
|
|
|
"Encoder Instructions:\n" |
|
|
|
"gete (get encoder position): get current encoder singleturn position (average over x)\n" |
|
|
|
"seep (set EEPROM encoder position): save current encoder singleturn home position to EEPROM\n" |
|
|
|
"sepo (set encoder position): save current encoder position as position x {0-2}\n" |
|
|
|
"gtep (go to encoder position): go to saved encoder position x {0-2}\n" |
|
|
|
"sepe (save encoder positions to EEPROM): backup saved encoder positions in EEPROM\n" |
|
|
|
"reep (reed EEPROM encoder position): reed current encoder singleturn home position from EEPROM\n" |
|
|
|
"init (initialize): move to encoder EEPROM home position and set it to position null\n" |
|
|
|
"\n" |
|
|
|
"init (initialize): load encoder positions from EEPROM, move to encoder 0 position and set it to motor position null\n" |
|
|
|
"\n\n" |
|
|
|
; |
|
|
|
|
|
|
|
|
|
|
@ -50,6 +62,7 @@ const uint32_t MOTORSTEPS = 200; // number of full steps wich the mot |
|
|
|
// EEPROM (test)
|
|
|
|
// const
|
|
|
|
|
|
|
|
// small neutron-switch
|
|
|
|
// motor power settings. Complete explanation in setup. Tested with 16 microsteps
|
|
|
|
const byte CM_RUN_TVAL = 20; // motor power settings for current mode
|
|
|
|
const byte CM_ACC_TVAL = 32; |
|
|
@ -62,22 +75,39 @@ const byte VM_DEC_TVAL = 24; |
|
|
|
const byte VM_HOLD_TVAL = 28; |
|
|
|
const float VM_MAX_SPEED = 1000.0; |
|
|
|
|
|
|
|
// big neutron-switch
|
|
|
|
// motor power settings. Complete explanation in setup. Tested with 16 microsteps
|
|
|
|
/*
|
|
|
|
const byte CM_RUN_TVAL = 30; // motor power settings for current mode
|
|
|
|
const byte CM_ACC_TVAL = 40; |
|
|
|
const byte CM_DEC_TVAL = 40; |
|
|
|
const byte CM_HOLD_TVAL = 24; |
|
|
|
const float CM_MAX_SPEED = 1000.0; |
|
|
|
const byte VM_RUN_TVAL = 16; // motor power settings for voltage mode
|
|
|
|
const byte VM_ACC_TVAL = 24; |
|
|
|
const byte VM_DEC_TVAL = 24; |
|
|
|
const byte VM_HOLD_TVAL = 28; |
|
|
|
const float VM_MAX_SPEED = 1000.0; |
|
|
|
*/ |
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
* global variables * |
|
|
|
**********************************************************************/ |
|
|
|
|
|
|
|
long positionMotor[POSITION_COUNT] = {(long)0, (long)1062, (long)-1067}; // array to save motor positions
|
|
|
|
int32_t positionEncoder[POSITION_COUNT] = {}; // array to save motor positions
|
|
|
|
int32_t positionEncoder[POSITION_COUNT] = {}; // array to save encoder positions
|
|
|
|
uint16_t eeAddress = 0; // Location of next free EEPROM address
|
|
|
|
uint32_t motorMicrosteps = 16; // number of microsteps wich currently used
|
|
|
|
String message; // String for buffering vallidation message
|
|
|
|
String errorMessage; // String for buffering error message
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
* function declaration * |
|
|
|
**********************************************************************/ |
|
|
|
void controlUart(uint8_t port); // check if uart communication is incomming on one of the UART's. If this is the case, read and execute incomming command
|
|
|
|
int32_t averageEncPosition(uint32_t count); // read and build avverage of current encoder position
|
|
|
|
int32_t averageEncPosition(uint32_t count); // read and build avverage of current encoder position
|
|
|
|
void goToEncoderPosition(uint32_t encoderPosition); // gtep (go to encoder position): go to saved encoder position x {0-2}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
@ -116,9 +146,15 @@ void setup() { |
|
|
|
pinMode(PIN_RGB_LED_G, OUTPUT); // Green part of the RGB LED
|
|
|
|
pinMode(PIN_RGB_LED_B, OUTPUT); // Blue part of the RGB LED
|
|
|
|
|
|
|
|
pinMode(PIN_POS1, INPUT_PULLDOWN);// TTL Input for position controll
|
|
|
|
pinMode(PIN_POS2, INPUT_PULLDOWN);// TTL Input for position controll
|
|
|
|
pinMode(PIN_POS3, INPUT_PULLDOWN);// TTL Input for position controll
|
|
|
|
pinMode(PIN_BUTTON_POS1, INPUT_FLOATING);// Push button for position controll
|
|
|
|
pinMode(PIN_BUTTON_POS2, INPUT_FLOATING);// Push button for position controll
|
|
|
|
pinMode(PIN_BUTTON_POS3, INPUT_FLOATING);// Push button for position controll
|
|
|
|
|
|
|
|
pinMode(PIN_LEMO_POS1, INPUT_PULLDOWN);// TTL input on Lemo for position controll
|
|
|
|
pinMode(PIN_LEMO_POS2, INPUT_PULLDOWN);// TTL input on Lemo for position controll
|
|
|
|
pinMode(PIN_LEMO_POS3, INPUT_PULLDOWN);// TTL input on Lemo for position controll
|
|
|
|
|
|
|
|
pinMode(PIN_LEMO_READY, OUTPUT); // TTL output for Ready Signal when Positioning finished
|
|
|
|
|
|
|
|
Serial.begin(SERIAL_BAUD_RATE); // Start serial UART on USB
|
|
|
|
Serial6.begin(SERIAL_BAUD_RATE); // Start serial UART on optical links
|
|
|
@ -210,24 +246,27 @@ void setup() { |
|
|
|
// end of stepper motor shield initialisation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// init
|
|
|
|
EEPROM.get(eeAddress, positionEncoder); // restore encoderpositions from EEPROM
|
|
|
|
|
|
|
|
// led greeting
|
|
|
|
digitalWrite(PIN_RGB_LED_R, LOW); // set all off
|
|
|
|
digitalWrite(PIN_RGB_LED_G, LOW); |
|
|
|
digitalWrite(PIN_RGB_LED_B, LOW); |
|
|
|
digitalWrite(PIN_RGB_LED_R, HIGH);// red on
|
|
|
|
digitalWrite(PIN_RGB_LED_R, HIGH); // set all off (common anode)
|
|
|
|
digitalWrite(PIN_RGB_LED_G, HIGH); |
|
|
|
digitalWrite(PIN_RGB_LED_B, HIGH); |
|
|
|
digitalWrite(PIN_RGB_LED_R, LOW);// red on
|
|
|
|
delay(300); |
|
|
|
digitalWrite(PIN_RGB_LED_R, LOW); // red off
|
|
|
|
digitalWrite(PIN_RGB_LED_G, HIGH);// blue on
|
|
|
|
digitalWrite(PIN_RGB_LED_R, HIGH); // red off
|
|
|
|
digitalWrite(PIN_RGB_LED_G, LOW);// blue on
|
|
|
|
delay(300); |
|
|
|
digitalWrite(PIN_RGB_LED_G, LOW); // blue off
|
|
|
|
digitalWrite(PIN_RGB_LED_B, HIGH);// green on
|
|
|
|
digitalWrite(PIN_RGB_LED_G, HIGH); // blue off
|
|
|
|
digitalWrite(PIN_RGB_LED_B, LOW);// green on
|
|
|
|
delay(300); |
|
|
|
digitalWrite(PIN_RGB_LED_B, LOW); // green off
|
|
|
|
digitalWrite(PIN_RGB_LED_B, HIGH); // green off
|
|
|
|
|
|
|
|
Serial.print(manual); // print instruction manual on USB UART
|
|
|
|
Serial6.print(manual); // print instruction manual on optical UART
|
|
|
|
|
|
|
|
digitalWrite(PIN_RGB_LED_G, LOW); // Turn green LED on (display setup done)
|
|
|
|
} // end of setup()
|
|
|
|
|
|
|
|
|
|
|
@ -244,16 +283,28 @@ void loop() { |
|
|
|
controlUart(6); // If this is the case, execute command
|
|
|
|
} |
|
|
|
|
|
|
|
if(digitalRead(PIN_POS1)==HIGH){ // if TTL position 1 input is HIGH
|
|
|
|
driver.goTo(positionMotor[0]); // drive motor to saved position 1
|
|
|
|
if(digitalRead(PIN_LEMO_POS1)==HIGH){ // if TTL position 1 input is HIGH
|
|
|
|
goToEncoderPosition(0); // drive motor to saved encoder position 1
|
|
|
|
} |
|
|
|
if(digitalRead(PIN_POS2)==HIGH){ // same for position 2
|
|
|
|
driver.goTo(positionMotor[1]); |
|
|
|
if(digitalRead(PIN_LEMO_POS2)==HIGH){ // same for position 2
|
|
|
|
goToEncoderPosition(1); |
|
|
|
} |
|
|
|
if(digitalRead(PIN_POS3)==HIGH){ // and position 3
|
|
|
|
driver.goTo(positionMotor[2]); |
|
|
|
if(digitalRead(PIN_LEMO_POS3)==HIGH){ // and position 3
|
|
|
|
goToEncoderPosition(2); |
|
|
|
} |
|
|
|
|
|
|
|
if(digitalRead(PIN_BUTTON_POS1)==HIGH){ // if button position 1 is HIGH
|
|
|
|
delay(200); // wait, so that reset could be done before motor is moved
|
|
|
|
goToEncoderPosition(0); // drive motor to saved encoder position 1
|
|
|
|
} |
|
|
|
if(digitalRead(PIN_BUTTON_POS2)==HIGH){ // same for position 2
|
|
|
|
delay(200); |
|
|
|
goToEncoderPosition(1); |
|
|
|
} |
|
|
|
if(digitalRead(PIN_BUTTON_POS3)==HIGH){ // same for position 3
|
|
|
|
delay(200); |
|
|
|
goToEncoderPosition(2); |
|
|
|
} |
|
|
|
} // end of loop()
|
|
|
|
|
|
|
|
|
|
|
@ -271,8 +322,7 @@ void controlUart(uint8_t port){ |
|
|
|
String input; // String for buffering read data
|
|
|
|
String parameterStr; // STring for extracted parameter
|
|
|
|
uint32_t parameter = 0; // variable for storing command parameter
|
|
|
|
String message; // String for buffering vallidation message
|
|
|
|
String errorMessage; // String for buffering error message
|
|
|
|
|
|
|
|
|
|
|
|
switch(port){ // Read from the port where the communication is coming from
|
|
|
|
case 3: |
|
|
@ -335,13 +385,16 @@ void controlUart(uint8_t port){ |
|
|
|
// gtep (go to encoder position): go to saved encoder position x {0-2}
|
|
|
|
else if(input.startsWith("gtep")){ |
|
|
|
if(parameter<POSITION_COUNT){ |
|
|
|
goToEncoderPosition(parameter); // Separated so that this can also be called up via the buttons and the TTL inputs.
|
|
|
|
|
|
|
|
/*
|
|
|
|
int32_t currentPosition; |
|
|
|
int32_t steps2Drive = 1; |
|
|
|
uint8_t i = 0; // loop counter
|
|
|
|
message = "Motor is moved to saved position: "; |
|
|
|
message += (String) parameter; |
|
|
|
message += ". Moved steps: "; |
|
|
|
while(steps2Drive != 0){ // move motor to position null till the position is reached, because null is not reached exactly every time
|
|
|
|
while(steps2Drive != 0){ // move motor to position till the position is reached, because it is not reached exactly every time
|
|
|
|
currentPosition = averageEncPosition(ENCODER_AV_COUNT); // read singleturn position
|
|
|
|
steps2Drive = int32_t ((double)(currentPosition - positionEncoder[parameter]) / (131072.0 / (MOTORSTEPS*motorMicrosteps))); // calculate steps to move
|
|
|
|
if(steps2Drive<0){ |
|
|
@ -362,6 +415,7 @@ void controlUart(uint8_t port){ |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
*/ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -389,14 +443,14 @@ void controlUart(uint8_t port){ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// getp (get position): get current position
|
|
|
|
// getp (get position): get current motor position
|
|
|
|
else if(input.startsWith("getp")){ |
|
|
|
long position = driver.getPos(); |
|
|
|
message = "Current position is: "; |
|
|
|
message = (String) position; |
|
|
|
} |
|
|
|
|
|
|
|
// setn (set null): set current position as null (home)
|
|
|
|
// setn (set null): set current position as motor null position (home)
|
|
|
|
else if(input.startsWith("setn")){ |
|
|
|
driver.resetPos(); |
|
|
|
message = "Current position is set to 0"; |
|
|
@ -490,23 +544,28 @@ void controlUart(uint8_t port){ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// seep (set EEPROM encoder position): save current encoder singleturn home position to EEPROM
|
|
|
|
else if(input.startsWith("seep")){ |
|
|
|
int32_t currentPosition; |
|
|
|
currentPosition = averageEncPosition(ENCODER_AV_COUNT); |
|
|
|
EEPROM.put(eeAddress, currentPosition); |
|
|
|
message = "Saved as encoder home position in EEPROM: "; |
|
|
|
message += (String) currentPosition; |
|
|
|
// sepe (save encoder positions to EEPROM): backup saved encoder positions in EEPROM
|
|
|
|
else if(input.startsWith("sepe")){ |
|
|
|
EEPROM.put(eeAddress, positionEncoder); // put data to EEPROM
|
|
|
|
message = "Encoder positions writen to EEPROM: "; // build output string
|
|
|
|
for(int i =0; i<3; i++){ |
|
|
|
message += (String) positionEncoder[i]; |
|
|
|
message += ("; "); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// reep (reed EEPROM encoder position): reed current encoder singleturn home position from EEPROM
|
|
|
|
// reep (reed EEPROM encoder positions): reed encoder singleturn positions from EEPROM
|
|
|
|
else if(input.startsWith("reep")){ |
|
|
|
EEPROM.get(eeAddress, parameter); // reed address from EEPROM and save in parameter
|
|
|
|
message = "Encoder home position in EEPROM is: "; |
|
|
|
message += (String) parameter; |
|
|
|
int32_t positionEncoderEeprom[3] = {0,0,0}; // for read EEPROM data
|
|
|
|
EEPROM.get(eeAddress, positionEncoderEeprom); // reed encoder positions from EEPROM
|
|
|
|
message = "Encoder positions in EEPROM: "; // build output string
|
|
|
|
for(int i =0; i<3; i++){ |
|
|
|
message += (String) positionEncoderEeprom[i]; |
|
|
|
message += ("; "); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// init (initialize): move to encoder EEPROM home position and set it to position null
|
|
|
|
// init (initialize): load encoder positions from EEPROM, move to encoder 0 position and set it to motor position null
|
|
|
|
else if(input.startsWith("init")){ |
|
|
|
int32_t homePosition; |
|
|
|
int32_t currentPosition; |
|
|
@ -521,7 +580,9 @@ void controlUart(uint8_t port){ |
|
|
|
driver.softStop(); // hold motor
|
|
|
|
while(driver.busyCheck()); |
|
|
|
delay(100); // wait till motor stands still
|
|
|
|
EEPROM.get(eeAddress, homePosition); // read home position from EEPROM
|
|
|
|
//EEPROM.get(eeAddress, homePosition); // (old) read home position from EEPROM
|
|
|
|
EEPROM.get(eeAddress, positionEncoder); // restore encoderpositions from EEPROM
|
|
|
|
homePosition = positionEncoder[0]; // copy position 0 to homePosition for manipulation
|
|
|
|
|
|
|
|
|
|
|
|
while(steps2Drive != 0){ // move motor to position null till the position is reached, because null is not reached exactly every time
|
|
|
@ -533,7 +594,7 @@ void controlUart(uint8_t port){ |
|
|
|
driver.softStop(); |
|
|
|
while(driver.busyCheck()); |
|
|
|
delay(10); |
|
|
|
message += (String) steps2Drive; |
|
|
|
message += (String) steps2Drive; // build output string
|
|
|
|
message += ("; "); |
|
|
|
i++; |
|
|
|
if(i==10){ |
|
|
@ -561,29 +622,6 @@ void controlUart(uint8_t port){ |
|
|
|
message = ("hold test done"); |
|
|
|
} |
|
|
|
|
|
|
|
// setb: test set backup register
|
|
|
|
else if(input.startsWith("setb")){ |
|
|
|
uint32_t index = 0; |
|
|
|
uint32_t value = 1000; |
|
|
|
int32_t currentPosition; |
|
|
|
currentPosition = averageEncPosition(ENCODER_AV_COUNT); |
|
|
|
//setBackupRegister(index, value);
|
|
|
|
EEPROM.put(8, currentPosition); |
|
|
|
|
|
|
|
message = ("Backup register written"); |
|
|
|
} |
|
|
|
|
|
|
|
// getb: test set backup register
|
|
|
|
else if(input.startsWith("getb")){ |
|
|
|
Serial6.println(getBackupRegister(0)); |
|
|
|
uint8_t test = 0; |
|
|
|
message = ("Backup register:"); |
|
|
|
for(int8_t i=10; i<20; i++){ |
|
|
|
message += (" "); |
|
|
|
message += EEPROM.get(i, test); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// command unknown
|
|
|
|
else{ |
|
|
|
errorMessage = "Command unknown or parameter is missing. Send 'help' to get the manual again"; |
|
|
@ -630,3 +668,54 @@ int32_t averageEncPosition(uint32_t count){ |
|
|
|
encoderPositionAv = encoderPositionAv / i; // build average
|
|
|
|
return encoderPositionAv; |
|
|
|
} // end of averageEncPosition()
|
|
|
|
|
|
|
|
|
|
|
|
// gtep (go to encoder position): go to saved encoder position x {0-2}
|
|
|
|
// Separated so that this can also be called up via the buttons and the TTL inputs.
|
|
|
|
void goToEncoderPosition(uint32_t encoderPosition){ |
|
|
|
int32_t currentPosition; |
|
|
|
int32_t steps2Drive = 1; |
|
|
|
uint8_t i = 0; // loop counter
|
|
|
|
uint32_t failure = 0; // set if failure happen
|
|
|
|
digitalWrite(PIN_LEMO_READY, HIGH); // Set ready HIGH (display positioning in progress)
|
|
|
|
digitalWrite(PIN_RGB_LED_B, LOW); // Turn blue LED on (display positioning in progress)
|
|
|
|
digitalWrite(PIN_RGB_LED_R, HIGH); // Turn red LED off
|
|
|
|
digitalWrite(PIN_RGB_LED_G, HIGH); // Turn green LED off
|
|
|
|
message = "Motor is moved to saved position: "; |
|
|
|
message += (String) encoderPosition; |
|
|
|
message += ". Moved steps: "; |
|
|
|
while(steps2Drive != 0){ // move motor to position till the position is reached, because it is not reached exactly every time
|
|
|
|
currentPosition = averageEncPosition(ENCODER_AV_COUNT); // read singleturn position
|
|
|
|
steps2Drive = int32_t ((double)(currentPosition - positionEncoder[encoderPosition]) / (131072.0 / (MOTORSTEPS*motorMicrosteps))); // calculate steps to move
|
|
|
|
if(steps2Drive<0){ |
|
|
|
driver.move(REV, ((unsigned long) (steps2Drive * -1))); |
|
|
|
} |
|
|
|
else{ |
|
|
|
driver.move(FWD, (unsigned long) steps2Drive); |
|
|
|
} |
|
|
|
while(driver.busyCheck()); |
|
|
|
driver.softStop(); |
|
|
|
while(driver.busyCheck()); |
|
|
|
delay(10); |
|
|
|
message += (String) steps2Drive; |
|
|
|
message += ("; "); |
|
|
|
i++; |
|
|
|
if(i==10){ |
|
|
|
errorMessage = ("positioning not possible. Check neutron switch. Maybe motor parameter must be updated"); |
|
|
|
failure = 1; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if(failure == 0){ // without failure
|
|
|
|
digitalWrite(PIN_LEMO_READY, LOW); // Set ready LOW (display positioning done)
|
|
|
|
digitalWrite(PIN_RGB_LED_G, LOW); // Turn green LED on (display positioning done)
|
|
|
|
digitalWrite(PIN_RGB_LED_B, HIGH); // Turn blue LED off
|
|
|
|
} |
|
|
|
else{ // with failure
|
|
|
|
//digitalWrite(PIN_LEMO_READY, LOW); // Set ready LOW (display positioning done)
|
|
|
|
digitalWrite(PIN_RGB_LED_R, LOW); // Turn red LED on (display failure)
|
|
|
|
digitalWrite(PIN_RGB_LED_B, HIGH); // Turn blue LED off
|
|
|
|
} |
|
|
|
|
|
|
|
} // end of goToEncoderPosition()
|
|
|
|
|