Telescope motorised focuser based on the moonlite protocol, indilib's indi_monlite_focuser compliant. WIP

Revision:
4:2235d6d01ca5
Parent:
3:20b077586e4e
Child:
5:8965c2919afb
--- a/main.cpp	Mon Jul 02 19:15:17 2018 +0000
+++ b/main.cpp	Mon Jul 30 17:42:39 2018 +0000
@@ -11,6 +11,8 @@
 bool is_moving, move = false;
 
 uint16_t step_delay = 256;
+uint8_t step_delay_multiplier = 40; //less delay is more speed, a delay of 40 is about 48 pps on the slowest setting and about 770 steps per second on the fastest!!! dont go under 39 ... //TODO
+
 
 char ml_in[256];
 uint8_t idx = 0;
@@ -26,14 +28,37 @@
 }
 
 
-//TODO motor control with MP6500 https://www.pololu.com/product/2968
-//DigitalOut step(A0);
-//DigitalOut dir(A1);
-//DigitalOut MS1; //only use MS1, set low for FULL or high for HALF only to be moonlite compliant ?
+//IN PROGRESS: TODO motor control with MP6500 https://www.pololu.com/product/2968
+//D2,D3,D4,D5,D6,D7,D8,D9 - DIR, STEP, SLP, I2, I1, MS2, MS1, EN
+
+DigitalOut dir(D2);
+DigitalOut step(D3);
+DigitalOut slp(D4); //pull high to enable operation
+DigitalOut i2(D5); //set low to enable pwm power controll
+PwmOut i1(D6); //MP6500 power limit control
+DigitalOut ms2(D7); 
+DigitalOut ms1(D8); //set low for FULL or high for HALF, only use MS1 to be moonlite compliant ?
+DigitalOut en(D9); //pulled low by the motor driver, default enables operation
+
+
 //PwmOut I1; //TODO try to set optimal motor current, if you don't use this it will be set at 500ma with the MP6500 (in full step that is about 70.71% on both phases, half step is 100% on one phase or 70 on both)
-//try to set 3.3v 80% duty cycle for a safe value, 100% duty cycle is minimum https://www.pololu.com/product/2968#lightbox-picture0J8398;main-pictures , 1 kHz or greater, I2 set to low (tied to ground?)
+//try to set 3.3v 90% duty cycle for a safe value, 100% duty cycle is minimum https://www.pololu.com/product/2968#lightbox-picture0J8398;main-pictures , 1 kHz or greater, I2 set to low (tied to ground?)
 //learn to block comment
 
+void mp6500() //TODO enable/disable motor
+{
+    dir = 0;
+    step = 0;
+    slp = 1;
+    i2 = 0;
+    i1.period(0.001f); //1kHz period
+    i1.write(0.90f); //90% duty cycle
+    ms2 = 0;
+    ms1 = 0;
+    en = 0;
+}
+
+
 void motor()
 {
 
@@ -45,22 +70,36 @@
 
             if(gp > gn) {
 
+                dir = 0;
+//__disable_irq();    // Disable Interrupts
+// 
+//// do something that can't be interrupted
+// 
+//__enable_irq();     // Enable Interrupts
                 led = !led;
-                wait_ms(step_delay/2);
+                step = !step;
+                wait_us(step_delay * step_delay_multiplier); //TODO rewrite more accurate stepping delay
                 led = !led;
-                wait_ms(step_delay/2);
+                step = !step;
+                wait_us(step_delay * step_delay_multiplier);
                 gp--;
 
             } else if (gp < gn) {
 
+                dir = 1;
+
                 led = !led;
-                wait_ms(step_delay/2);
+                step = !step;
+                wait_us(step_delay * step_delay_multiplier);
                 led = !led;
-                wait_ms(step_delay/2);
+                step = !step;
+                wait_us(step_delay * step_delay_multiplier);
                 gp++;
 
             } else {
 
+                step = dir = 0;
+
                 is_moving = false;
                 move = false;
 
@@ -90,12 +129,10 @@
                     case 'F':
                         switch (ml_in[1]) {
                             case 'G': //N/A Go to the new position as set by the ":SNYYYY#" command.
-                                move = true;
-                                //gp = gn; //TODO move motor to new position
+                                move = true; //runs motor();
                                 break;
                             case 'Q': //N/A Immediately stop any focus motor movement.
                                 move = false;
-                                //TODO
                                 break;
                             default:
                                 break;
@@ -111,17 +148,13 @@
                                 pc.printf("02#");
                                 break;
                             case 'D': //XX# Returns the current stepping delay where XX is a two-digit unsigned hex number. Valid values 02, 04, 08, 10, 20 -> stepping delay 250, 125, 63, 32, 16 pps
-                                pc.printf("%02X#", 512 / step_delay); //TODO
+                                pc.printf("%02X#", 512 / step_delay); //TODO? we sleep for step_delay*step_delay_multiplier microseconds between steps
                                 break;
                             case 'H': //00# OR FF# Returns "FF#" if the focus motor is half-stepped otherwise return "00#"
-                                pc.printf("00#"); //TODO
+                                //pc.printf("00#"); //TODO
+                                pc.printf("%02X#", ms1 * 255);
                                 break;
                             case 'I': //00# OR 01# Returns "00#" if the focus motor is not moving, otherwise return "01#"
-//                                if(is_moving) {
-//                                    pc.printf("01#"); //TODO
-//                                } else {
-//                                    pc.printf("00#"); //TODO
-//                                }
                                 pc.printf("%02X#", is_moving);
                                 break;
                             case 'N': //YYYY# Returns the new position previously set by a ":SNYYYY#" command where YYYY is a four-digit unsigned hex number
@@ -132,7 +165,7 @@
                                 break;
                             case 'T': //YYYY# Returns the current temperature where YYYY is a four-digit signed (2’s complement) hex number.
                                 pc.printf("%04X#", temperature * 2); //indi_moonlite_focuser returns the temp/2, dunno why, dont care
-                                //pc.printf("0019#"); //25c, 12.5c in indi_moonlite control panel
+                                //pc.printf("0019#"); //should be 25c but is 12.5c in indi_moonlite control panel
                                 break;
                             case 'V': //DD# Get the version of the firmware as a two-digit decimal number where the first digit is the major version number, and the second digit is the minor version number.
                                 pc.printf("01#");
@@ -147,28 +180,22 @@
                             case 'C': //N/A Set the new temperature coefficient where XX is a two-digit, signed (2’s complement) hex number.
                                 break; //TODO
                             case 'D': //N/A Set the new stepping delay where XX is a two-digit, unsigned hex number. Valid values to send are 02, 04, 08, 10 and 20, which correspond to a stepping delay of 250, 125, 63, 32 and 16 steps per second respectively.
-                                //strncpy(str, cmd + 2, 2);
-                                //g_motor1.set_speed(util::hexstr2long(str));
                                 step_delay = 512 / strtol(ml_in + 2, NULL, 16);
                                 break;
 
                             case 'F': //N/A Set full-step mode.
-                                //g_motor1.set_full_step();
+                                ms1 = 0;
                                 break;
 
                             case 'H': //N/A Set half-step mode.
-                                //g_motor1.set_half_step();
+                                ms1 = 1;
                                 break;
 
                             case 'N': //N/A Set the new position where YYYY is a four-digit unsigned hex number.
-                                //strncpy(str, cmd + 2, 4);
-                                //g_motor1.set_target_position(util::hexstr2long(str));
                                 gn = strtol(ml_in + 2, NULL, 16); //read ml_in, discard 2 chars, convert to long, set gn
                                 break;
 
                             case 'P': //Set the current position where YYYY is a four-digit unsigned hex number.
-                                //strncpy(str, cmd + 2, 4);
-                                //g_motor1.set_current_position(util::hexstr2long(str));
                                 gp = strtol(ml_in + 2, NULL, 16);
                                 break;
 
@@ -207,14 +234,22 @@
 
 
     }
+
 }
 
 
 int main()
 {
+    mp6500();
 
     //led_thread.start(led_blink);
+    pc.attach(read_serial, Serial::RxIrq);
+
     motor_thread.start(motor);
-    pc.attach(&read_serial, Serial::RxIrq);
+
+    while(true) {
+        Thread::wait(100);
+        //read_serial();
+    }
 
 }