Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 #include "mbed.h" //uses https://github.com/ARMmbed/mbed-os/ 00002 00003 DigitalOut led(LED1); //board led, just for fun 00004 00005 Serial pc(USBTX, USBRX); // tx, rx pc control over usb 00006 00007 uint16_t gn = 0; //position to move to 00008 uint16_t gp = 0; //current position 00009 uint16_t temperature = 255; //hardcoded for now //TODO 00010 00011 bool move = false; 00012 00013 uint16_t step_delay = 256; 00014 00015 //minimum motor speed that will get doubled 5 times to result maximum motor speed 00016 //eg: for a value of 16 there will be 5 speeds as follows 16*1,16*2,16*4,16*8,16*16 00017 //eg: for a value of 16 there will be 5 speeds as follows 16,32,64,128,256 00018 uint8_t min_motor_pps = 16; //TODO use max pps since it might be more intuitive? 00019 00020 00021 char ml_in[256]; 00022 uint8_t idx = 0; 00023 00024 Thread serial_thread, motor_thread; 00025 Ticker m_speed; 00026 00027 void led_blink() 00028 { 00029 while (true) { 00030 led = !led; 00031 wait(1); 00032 } 00033 } 00034 00035 00036 //motor control with MP6500 https://www.pololu.com/product/2968 00037 //aproximate formula for motor current control pwm.pulsewidth% = (motor_rated_current_in_amps-2.2)/-2.079, so for our 330ma motor we use pw = (0.330-2.2)/-2.079 00038 // https://www.pololu.com/product/2968#lightbox-picture0J8398;main-pictures , 1 kHz or greater, I2 set to low 00039 //D2,D3,D4,D5,D6,D7,D8,D9 - DIR, STEP, SLP, I2, I1, MS2, MS1, EN 00040 00041 DigitalOut dir(D2); 00042 DigitalOut step(D3); 00043 DigitalOut slp(D4); //pull high to enable operation 00044 DigitalOut i2(D5); //set low to enable pwm power control 00045 PwmOut i1(D6); //MP6500 power limit control 00046 DigitalOut ms2(D7); //D7 and D8 are PC_14 and PC_15 N/C oscillator pins, hence this is full step only //TODO 00047 DigitalOut ms1(D8); //set low for FULL or high for HALF, only use MS1 to be moonlite compliant ? 00048 DigitalOut en(D9); //pulled low by the motor driver, default enables operation 00049 00050 float motor_max_amps = 0.33f; 00051 00052 float pw = (motor_max_amps-2.2f)/-2.079f; //https://www.pololu.com/product/2968#lightbox-picture0J8398;main-pictures 00053 00054 void mp6500() //TODO enable/disable motor 00055 { 00056 dir = 0; 00057 step = 0; 00058 slp = 1; 00059 i2 = 0; 00060 i1.period(0.001f); //1kHz period 00061 i1.write(1.0f); //start with lowest power since we're idle 00062 ms2 = 0; 00063 ms1 = 1; 00064 en = 0; 00065 } 00066 00067 00068 void m_step() 00069 { 00070 00071 //while (true) { 00072 00073 if(move) { 00074 00075 i1.write(pw); //set defined current motor while moving 00076 00077 if(gp > gn) { 00078 00079 dir = 0; 00080 wait_us(1); 00081 //led = !led; 00082 step = !step; 00083 wait_us(1); //mp6500 00084 //led = !led; 00085 step = !step; 00086 wait_us(1); 00087 //https://os.mbed.com/docs/v5.9/mbed-os-api-doxy/mbed__wait__api_8h_source.html use Thread::wait()? 00088 //wait((step_delay/1.024)/min_motor_pps/250); 00089 gp--; 00090 00091 } else if (gp < gn) { 00092 00093 dir = 1; 00094 wait_us(1); 00095 //led = !led; 00096 step = !step; 00097 wait_us(1); 00098 //led = !led; 00099 step = !step; 00100 wait_us(1); 00101 //wait((step_delay/1.024)/min_motor_pps/250); 00102 gp++; 00103 00104 } else { 00105 00106 step = dir = 0; 00107 wait_us(1); 00108 00109 i1.write(1.0f); //set minimum controller power while holding, keeps motor cool and still provides a nice holding torque, ~120ma 00110 00111 move = false; 00112 00113 } 00114 00115 } 00116 00117 //} 00118 00119 } 00120 00121 00122 00123 //http://indilib.org/media/kunena/attachments/1/HighResSteppermotor107.pdf 00124 void read_serial() 00125 { 00126 while(true){ 00127 if(pc.readable()) { 00128 char c = pc.getc(); 00129 00130 switch (c) { 00131 case '#': 00132 00133 switch (ml_in[0]) { 00134 case 'C': //N/A Initiate a temperature conversion; the conversion process takes a maximum of 750 milliseconds. The value returned by the :GT# command will not be valid until the conversion process completes. 00135 break; //TODO 00136 case 'F': 00137 switch (ml_in[1]) { 00138 case 'G': //N/A Go to the new position as set by the ":SNYYYY#" command. 00139 move = true; //runs motor(); 00140 break; 00141 case 'Q': //N/A Immediately stop any focus motor movement. 00142 move = false; 00143 break; 00144 default: 00145 break; 00146 } 00147 break; 00148 00149 case 'G': 00150 switch (ml_in[1]) { 00151 case 'B': // Get the backlight value 00152 pc.printf("00#"); 00153 break; 00154 case 'C': //XX# Returns the temperature coefficient where XX is a two-digit signed (2’s complement) hex number. 00155 pc.printf("02#"); 00156 break; 00157 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 00158 pc.printf("%02X#", 512 / step_delay); //TODO? we sleep for step_delay*step_delay_multiplier microseconds between steps 00159 break; 00160 case 'H': //00# OR FF# Returns "FF#" if the focus motor is half-stepped otherwise return "00#" 00161 //pc.printf("00#"); //TODO 00162 pc.printf("%02X#", ms1 * 255); 00163 break; 00164 case 'I': //00# OR 01# Returns "00#" if the focus motor is not moving, otherwise return "01#" 00165 pc.printf("%02X#", move); 00166 break; 00167 case 'N': //YYYY# Returns the new position previously set by a ":SNYYYY#" command where YYYY is a four-digit unsigned hex number 00168 pc.printf("%04X#", gn); //TODO use this to move the motor 00169 break; 00170 case 'P': //YYYY# Returns the current position where YYYY is a four-digit unsigned hex number. 00171 pc.printf("%04X#", gp); //TODO update gp with actual motor data 00172 break; 00173 case 'T': //YYYY# Returns the current temperature where YYYY is a four-digit signed (2’s complement) hex number. 00174 pc.printf("%04X#", temperature * 2); //indi_moonlite_focuser returns the temp/2, dunno why, dont care 00175 //pc.printf("0019#"); //should be 25c but is 12.5c in indi_moonlite control panel 00176 break; 00177 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. 00178 pc.printf("01#"); 00179 break; 00180 default: 00181 break; 00182 } 00183 break; 00184 00185 case 'S': 00186 switch(ml_in[1]) { 00187 case 'C': //N/A Set the new temperature coefficient where XX is a two-digit, signed (2’s complement) hex number. 00188 break; //TODO 00189 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. 00190 step_delay = 512 / strtol(ml_in + 2, NULL, 16); 00191 m_speed.attach(&m_step, (step_delay/1.024)/min_motor_pps/250); 00192 break; 00193 00194 case 'F': //N/A Set full-step mode. 00195 ms1 = 0; 00196 break; 00197 00198 case 'H': //N/A Set half-step mode. 00199 ms1 = 1; 00200 break; 00201 00202 case 'N': //N/A Set the new position where YYYY is a four-digit unsigned hex number. 00203 gn = strtol(ml_in + 2, NULL, 16); //read ml_in, discard 2 chars, convert to long, set gn 00204 break; 00205 00206 case 'P': //Set the current position where YYYY is a four-digit unsigned hex number. 00207 gp = strtol(ml_in + 2, NULL, 16); 00208 break; 00209 00210 default: 00211 break; 00212 } 00213 break; 00214 00215 case '+': //N/A Activate temperature compensation focusing. 00216 break; //TODO 00217 case '-': //N/A Disable temperature compensation focusing. 00218 break; //TODO 00219 00220 case 'P': 00221 break; 00222 00223 // case ':POXX#': //N/A Temperature calibration offset, XX is a two-digit signed hex number, in half degree increments. Example 1: :PO02# offset of +1°C Example 2: :POFB# offset of -2.5° 00224 // break; //TODO 00225 00226 default: 00227 break; 00228 } 00229 break; 00230 00231 case ':': 00232 idx=0; 00233 memset(ml_in, 0, 8); 00234 break; 00235 00236 default: 00237 ml_in[idx++] = c; 00238 idx %= 8; 00239 break; 00240 } 00241 00242 00243 00244 } 00245 }//while true 00246 } 00247 00248 00249 int main() 00250 { 00251 mp6500(); 00252 00253 //pc.attach(read_serial, Serial::RxIrq); 00254 serial_thread.start(&read_serial); 00255 00256 //motor_thread.start(motor); 00257 m_speed.attach(&m_step, (step_delay/1.024)/min_motor_pps/250); 00258 00259 00260 while(true) { 00261 Thread::wait(1); 00262 } 00263 00264 }
Generated on Wed Aug 10 2022 05:48:42 by
1.7.2