onilink_

firmware

Aug 22nd, 2021
1,149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.43 KB | None | 0 0
  1.  
  2. #define LED_PIN            13
  3.  
  4. #define X_STEP_PIN         54
  5. #define X_DIR_PIN          55
  6. #define X_ENABLE_PIN       38
  7.  
  8. #define Y_STEP_PIN         60
  9. #define Y_DIR_PIN          61
  10. #define Y_ENABLE_PIN       56
  11.  
  12. #define Z_STEP_PIN         46
  13. #define Z_DIR_PIN          48
  14. #define Z_ENABLE_PIN       62
  15.  
  16. #define INPUT_SIZE 30
  17.  
  18. // todo: command to get state of motors (enabled or not)
  19. // todo: command to get microstep value
  20.  
  21. enum {
  22.   CMD_NOP,
  23.   // Start / Stop motor
  24.   CMD_MOTOR_X_START, // SX
  25.   CMD_MOTOR_Y_START, // SY
  26.   CMD_MOTOR_X_STOP,  // EX
  27.   CMD_MOTOR_Y_STOP,  // EY
  28.   CMD_MOVE_RELATIVE_X, // MX relative_pos
  29.   CMD_MOVE_RELATIVE_Y, // MY relative_pos
  30.   CMD_MOVE_TO_X, // PX pos
  31.   CMD_MOVE_TO_Y, // PY pos
  32.   CMD_GET_POS, // POS
  33. };
  34.  
  35. //const int stepsPerRevolution = 200;
  36.  
  37. int microsteps = 2;
  38. int pulse_width = 10;
  39.  
  40. int max_speed = 50;
  41. int default_speed = 10;
  42. int motor_speed = default_speed;
  43.  
  44. // 5: se coince, perte de pas
  45. int millis_between_steps = 100.0 / motor_speed;
  46.  
  47. char input[INPUT_SIZE + 1];
  48.  
  49. // assuming the stage is centered
  50. int xpos = 0;
  51. int ypos = 0;
  52.  
  53. const int X_MIN =-400;
  54. const int X_MAX = 400;
  55. const int Y_MIN =-400;
  56. const int Y_MAX = 400;
  57.  
  58. bool motor_x_is_on = false;
  59. bool motor_y_is_on = false;
  60.  
  61. // MX, MY: pos
  62. int arg0 = 0;
  63. // MX, MY: speed
  64. int arg1 = 0;
  65.  
  66. void enableMotorX(bool enabled) {
  67.   if(motor_x_is_on != enabled) {
  68.     digitalWrite(X_ENABLE_PIN, enabled? LOW: HIGH);
  69.     motor_x_is_on = enabled;
  70.  
  71.     if(enabled) {
  72.       Serial.println("Start Motor X");
  73.     } else {
  74.       Serial.println("Stop Motor X");
  75.     }
  76.   }
  77. }
  78. void enableMotorY(bool enabled) {
  79.   if(motor_y_is_on != enabled) {
  80.     digitalWrite(Y_ENABLE_PIN, enabled? LOW: HIGH);
  81.     motor_y_is_on = enabled;
  82.    
  83.     if(enabled) {
  84.       Serial.println("Start Motor Y");
  85.     } else {
  86.       Serial.println("Stop Motor Y");
  87.     }
  88.   }
  89. }
  90.  
  91. void setup()
  92. {
  93.   // 9600 bits per seconds
  94.   Serial.begin(9600);
  95.  
  96.   pinMode(X_STEP_PIN, OUTPUT);
  97.   pinMode(X_DIR_PIN, OUTPUT);
  98.   pinMode(X_ENABLE_PIN, OUTPUT);
  99.  
  100.   pinMode(Y_STEP_PIN, OUTPUT);
  101.   pinMode(Y_DIR_PIN, OUTPUT);
  102.   pinMode(Y_ENABLE_PIN, OUTPUT);
  103.  
  104.   // disable motors
  105.   enableMotorX(false);
  106.   enableMotorY(false);
  107. }
  108.  
  109.  
  110. byte parseCommand(const char* input)
  111. {
  112.   byte command = CMD_NOP;
  113.  
  114.   // Move relative
  115.   if(input[0] == 'M' && input[2] == ' ') {
  116.     if(input[1] == 'X') {
  117.       command = CMD_MOVE_RELATIVE_X;
  118.     }
  119.     else if(input[1] == 'Y') {
  120.       command = CMD_MOVE_RELATIVE_Y;
  121.     }
  122.   }
  123.  
  124.   // Move absolute
  125.   else if(input[0] == 'P' && input[2] == ' ') {
  126.     if(input[1] == 'X') {
  127.       command = CMD_MOVE_TO_X;
  128.     }
  129.     else if(input[1] == 'Y') {
  130.       command = CMD_MOVE_TO_Y;
  131.     }
  132.   }
  133.  
  134.   // Start motor
  135.   else if(input[0] == 'S') {
  136.     if(input[1] == 'X') {
  137.       command = CMD_MOTOR_X_START;
  138.     }
  139.     else if(input[1] == 'Y') {
  140.       command = CMD_MOTOR_Y_START;
  141.     }
  142.   }
  143.  
  144.   // Stop motor
  145.   else if(input[0] == 'E') {
  146.     if(input[1] == 'X') {
  147.       command = CMD_MOTOR_X_STOP;
  148.     }
  149.     else if(input[1] == 'Y') {
  150.       command = CMD_MOTOR_Y_STOP;
  151.     }
  152.   }
  153.  
  154.   else if(input[0] == 'P' && input[1] == 'O' && input[2] == 'S') {
  155.     command = CMD_GET_POS;
  156.   }
  157.  
  158.   return command;
  159. }
  160.  
  161. bool execCommandWithoutArguments(byte command)
  162. {
  163.   if(command == CMD_MOTOR_X_START) {
  164.     enableMotorX(true);
  165.   }
  166.   else if(command == CMD_MOTOR_Y_START) {
  167.     enableMotorY(true);
  168.   }
  169.   else if(command == CMD_MOTOR_X_STOP) {
  170.     enableMotorX(false);
  171.   }
  172.   else if(command == CMD_MOTOR_Y_STOP) {
  173.     enableMotorY(false);
  174.   }
  175.   else if(command == CMD_GET_POS) {
  176.     char str[10];
  177.     snprintf(str, 9, "%d", xpos);
  178.     Serial.print(str);
  179.     Serial.print(",");
  180.     snprintf(str, 9, "%d", ypos);
  181.     Serial.println(str);
  182.   }
  183.   else {
  184.     return false;
  185.   }
  186.   return true;
  187. }
  188.  
  189. void parseCommandArguments()
  190. {
  191.   char* token = strtok(input, " ");
  192.  
  193.   int index = 0;
  194.   while(token != NULL)
  195.   {
  196.     if(index == 1) {
  197.       arg0 = atoi(token);
  198.     }
  199.     else if(index == 2) {
  200.       arg1 = atoi(token);
  201.     }
  202.    
  203.     //Serial.println(token);
  204.     token = strtok(NULL, " ");
  205.     ++index;
  206.   }
  207. }
  208.  
  209. void setMotorDirFromArg0_relative(int dir_pin)
  210. {
  211.   if(arg0 < 0) {
  212.     arg0 = -arg0;
  213.     digitalWrite(dir_pin, LOW);
  214.   } else {
  215.     digitalWrite(dir_pin, HIGH);
  216.   }
  217. }
  218.  
  219. void setMotorDir(int dir_pin, bool reverse)
  220. {
  221.   if(reverse) {
  222.     digitalWrite(dir_pin, LOW);
  223.   } else {
  224.     digitalWrite(dir_pin, HIGH);
  225.   }
  226. }
  227.  
  228. void setMotorSpeedFromArg1()
  229. {
  230.   int motor_speed = arg1;
  231.   if(motor_speed <= 0) {
  232.     motor_speed = default_speed;
  233.   }
  234.   if(motor_speed > max_speed) {
  235.     motor_speed = max_speed;
  236.   }
  237.   millis_between_steps = 100.0 / motor_speed;
  238. }
  239.  
  240. void rotate(int step_pin, int distance)
  241. {
  242.   for(int x=0; x<distance; x++)
  243.   {
  244.     digitalWrite(step_pin, HIGH);
  245.     delayMicroseconds(pulse_width);
  246.     digitalWrite(step_pin, LOW);
  247.     delay(millis_between_steps);
  248.   }
  249. }
  250.  
  251. void execCommandWithArguments(byte command)
  252. {
  253.   if(command == CMD_MOVE_RELATIVE_X) {
  254.     // check bounds
  255.     if(arg0 > 0) {
  256.       if(xpos == X_MAX) {
  257.         return;
  258.       }
  259.       if(xpos + arg0 > X_MAX) {
  260.         arg0 = X_MAX - xpos;
  261.       }
  262.     }
  263.     else if(arg0 < 0) {
  264.       if(xpos == X_MIN) {
  265.         return;
  266.       }
  267.       if(xpos + arg0 < X_MIN) {
  268.         arg0 = X_MIN - xpos;
  269.       }
  270.     }
  271.    
  272.     if(arg0 == 0) {
  273.       return;
  274.     }
  275.    
  276.     enableMotorX(true);
  277.     xpos += arg0;
  278.     setMotorDirFromArg0_relative(X_DIR_PIN);
  279.     setMotorSpeedFromArg1();
  280.    
  281.     int distance = arg0 * microsteps;
  282.     rotate(X_STEP_PIN, distance);
  283.   }
  284.  
  285.   else if(command == CMD_MOVE_RELATIVE_Y) {
  286.     // check bounds
  287.     if(arg0 > 0) {
  288.       if(ypos == Y_MAX) {
  289.         return;
  290.       }
  291.       if(ypos + arg0 > Y_MAX) {
  292.         arg0 = Y_MAX - ypos;
  293.       }
  294.     }
  295.     else if(arg0 < 0) {
  296.       if(ypos == Y_MIN) {
  297.         return;
  298.       }
  299.       if(ypos + arg0 < Y_MIN) {
  300.         arg0 = Y_MIN - ypos;
  301.       }
  302.     }
  303.    
  304.     if(arg0 == 0) {
  305.       return;
  306.     }
  307.    
  308.     enableMotorY(true);
  309.     ypos += arg0;
  310.     setMotorDirFromArg0_relative(Y_DIR_PIN);
  311.     setMotorSpeedFromArg1();
  312.    
  313.     int distance = arg0 * microsteps;
  314.     rotate(Y_STEP_PIN, distance);
  315.   }
  316.   else if(command == CMD_MOVE_TO_X)
  317.   {
  318.     arg0 = constrain(arg0, X_MIN, X_MAX);
  319.     if(xpos == arg0) {
  320.       return;
  321.     }
  322.    
  323.     enableMotorX(true);
  324.     setMotorDir(X_DIR_PIN, arg0 < xpos);
  325.     setMotorSpeedFromArg1();
  326.    
  327.     int distance;
  328.     if(arg0 < xpos) {
  329.       distance = (xpos - arg0) * microsteps;
  330.     } else {
  331.       distance = (arg0 - xpos) * microsteps;
  332.     }
  333.     xpos = arg0;
  334.    
  335.     rotate(X_STEP_PIN, distance);
  336.   }
  337.   else if(command == CMD_MOVE_TO_Y)
  338.   {
  339.     arg0 = constrain(arg0, Y_MIN, Y_MAX);
  340.     if(ypos == arg0) {
  341.       return;
  342.     }
  343.    
  344.     enableMotorY(true);
  345.     setMotorDir(Y_DIR_PIN, arg0 < ypos);
  346.     setMotorSpeedFromArg1();
  347.    
  348.     int distance;
  349.     if(arg0 < ypos) {
  350.       distance = (ypos - arg0) * microsteps;
  351.     } else {
  352.       distance = (arg0 - ypos) * microsteps;
  353.     }
  354.     ypos = arg0;
  355.    
  356.     rotate(Y_STEP_PIN, distance);
  357.   }
  358. }
  359.  
  360. void loop()
  361. {
  362.   if(Serial.available()) {
  363.     byte size = Serial.readBytes(input, INPUT_SIZE);
  364.     input[size] = 0;
  365.  
  366.     byte command = parseCommand(input);
  367.     if(!execCommandWithoutArguments(command))
  368.     {
  369.       arg0 = 0;
  370.       arg1 = 0;
  371.       parseCommandArguments();
  372.       execCommandWithArguments(command);
  373.     }
  374.   }
  375. }
  376.  
Advertisement
Add Comment
Please, Sign In to add comment