Advertisement
Guest User

Untitled

a guest
Mar 24th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.84 KB | None | 0 0
  1. #include "mbed.h"
  2. #include "rtos.h"
  3. #include "PID.h"
  4. #include "QEI.h"
  5.  
  6. //**********************************************
  7. //* Constants Definitions *
  8. //**********************************************
  9. //Photointerrupter input pins
  10. #define I1pin D2
  11. #define I2pin D11
  12. #define I3pin D12
  13.  
  14. //Incremental encoder input pins
  15. #define CHA D7
  16. #define CHB D8
  17.  
  18. //Motor Drive output pins //Mask in output byte
  19. #define L1Lpin D4 //0x01
  20. #define L1Hpin D5 //0x02
  21. #define L2Lpin D3 //0x04
  22. #define L2Hpin D6 //0x08
  23. #define L3Lpin D9 //0x10
  24. #define L3Hpin D10 //0x20
  25.  
  26. DigitalIn I1(I1pin);
  27. DigitalIn I2(I2pin);
  28. DigitalIn I3(I3pin);
  29.  
  30. DigitalIn CHAInput(CHA);
  31. DigitalIn CHBInput(CHB);
  32.  
  33. //**********************************************
  34. //* New Constants *
  35. //**********************************************
  36.  
  37. //Motor Drive outputs
  38. DigitalOut *L1Ldigi = new DigitalOut(L1Lpin);
  39. DigitalOut *L1Hdigi = new DigitalOut(L1Hpin);
  40. DigitalOut *L2Ldigi = new DigitalOut(L2Lpin);
  41. DigitalOut *L2Hdigi = new DigitalOut(L2Hpin);
  42. DigitalOut *L3Ldigi = new DigitalOut(L3Lpin);
  43. DigitalOut *L3Hdigi = new DigitalOut(L3Hpin);
  44.  
  45. PwmOut *L1Lpwm = new PwmOut(L1Lpin);
  46. PwmOut *L1Hpwm = new PwmOut(L1Hpin);
  47. PwmOut *L2Lpwm = new PwmOut(L2Lpin);
  48. PwmOut *L2Hpwm = new PwmOut(L2Hpin);
  49. PwmOut *L3Lpwm = new PwmOut(L3Lpin);
  50. PwmOut *L3Hpwm = new PwmOut(L3Hpin);
  51.  
  52. DigitalOut led1(LED1);
  53. RawSerial pc(SERIAL_TX, SERIAL_RX);
  54. QEI wheel(CHA, CHB, NC, 117);
  55.  
  56. int8_t intState = 0;
  57. int8_t intStateOld = 0;
  58. int8_t orState = 0;
  59.  
  60. //Drive state to output table | Mapping from interrupter inputs to sequential rotor states. 0x00 and 0x07 are not valid
  61. const int8_t driveTable[] = {0x12, 0x18, 0x09, 0x21, 0x24, 0x06, 0x00, 0x00};
  62. const int8_t stateMap[] = {0x07, 0x05, 0x03, 0x04, 0x01, 0x00, 0x02, 0x07}; // Used for +ve velocity (CW)
  63. //const int8_t stateMap2[] = {0x07, 0x01, 0x03, 0x02, 0x05, 0x00, 0x04, 0x07}; // Used for -ve velocity (ACW)
  64. const int8_t lead = 1; //2 for forwards, -2 for backwards
  65.  
  66. const float Vref = 20;
  67. const float Rref = 1000;
  68. const float thresholdRPS = 38; //Used to toggle between PWM and DigitalOut
  69.  
  70. const float RPS_SAMPLING_RATE = 0.1; // rate at which interrupt is called, also the time difference(t) since the last interrupt call
  71. float lastPosition = 0;
  72. float currentPosition = 0;
  73. float currentRPSValue = 0; // global angular velocity/RPS value
  74.  
  75. float targetPosition=117*Rref;
  76. float PIDrate = 0.2;
  77. float Kc = 5.0;
  78. float Ti = 0.0;
  79. float Td = 0.0;
  80. bool AUTO = 1;
  81. float dutyCycle = 0; //global duty cycle to be passed to motorOut
  82. float oriDutyCycle = 0;
  83. float tmpdutycycle = 0;
  84. PID controller(Kc, Ti, Td, PIDrate);
  85. Thread PIDthread;
  86.  
  87. Ticker sampleRPS;
  88. Ticker PrintRPS;
  89. Ticker PrintKpara;
  90.  
  91. //**********************************************
  92. //* Function Definitions *
  93. //**********************************************
  94. //------- Convert photointerrupter inputs to a rotor state -------
  95. inline int8_t readRotorState()
  96. {
  97. return stateMap[I1 + 2 * I2 + 4 * I3];
  98. }
  99.  
  100. //------- Modulus Function -------
  101. float modulus(float n) {
  102. if(n<0) {
  103. n=-n;
  104. return n;
  105. } else {
  106. return n;
  107. }
  108. }
  109.  
  110. //------- Run the motor with speed limitation -------
  111. void motorOut(int8_t driveState){
  112.  
  113. int8_t driveOut = driveTable[driveState & 0x07];
  114.  
  115. if (currentRPSValue <= thresholdRPS) { //Use PWM at low speeds
  116. if(L1Lpwm == NULL){ // if PWM pointers point to nothing, create new PwmOut Pins
  117. L1Lpwm = new PwmOut(L1Lpin);
  118. L1Hpwm = new PwmOut(L1Hpin);
  119. L2Lpwm = new PwmOut(L2Lpin);
  120. L2Hpwm = new PwmOut(L2Hpin);
  121. L3Lpwm = new PwmOut(L3Lpin);
  122. L3Hpwm = new PwmOut(L3Hpin);
  123. }
  124.  
  125. if(L1Ldigi != NULL){ // if digital pin pointers point to something, delete them
  126. delete L1Ldigi;
  127. delete L1Hdigi;
  128. delete L2Ldigi;
  129. delete L2Hdigi;
  130. delete L3Ldigi;
  131. delete L3Hdigi;
  132. L1Ldigi = NULL;
  133. L1Hdigi = NULL;
  134. L2Ldigi = NULL;
  135. L2Hdigi = NULL;
  136. L3Ldigi = NULL;
  137. L3Hdigi = NULL;
  138. }
  139.  
  140. if (~driveOut & 0x01) *L1Lpwm = 0;
  141. if (~driveOut & 0x02) *L1Hpwm = 1;
  142. if (~driveOut & 0x04) *L2Lpwm = 0;
  143. if (~driveOut & 0x08) *L2Hpwm = 1;
  144. if (~driveOut & 0x10) *L3Lpwm = 0;
  145. if (~driveOut & 0x20) *L3Hpwm = 1;
  146.  
  147. if (currentRPSValue < Vref) {
  148. if (driveOut & 0x01) L1Lpwm->write(dutyCycle);
  149. if (driveOut & 0x02) L1Hpwm->write(1-dutyCycle);
  150. if (driveOut & 0x04) L2Lpwm->write(dutyCycle);
  151. if (driveOut & 0x08) L2Hpwm->write(1-dutyCycle);
  152. if (driveOut & 0x10) L3Lpwm->write(dutyCycle);
  153. if (driveOut & 0x20) L3Hpwm->write(1-dutyCycle);
  154. }
  155. }
  156.  
  157. else { //High Speed use digitalpin
  158. if(L1Ldigi == NULL){
  159. L1Ldigi = new DigitalOut(L1Lpin);
  160. L1Hdigi = new DigitalOut(L1Hpin);
  161. L2Ldigi = new DigitalOut(L2Lpin);
  162. L2Hdigi = new DigitalOut(L2Hpin);
  163. L3Ldigi = new DigitalOut(L3Lpin);
  164. L3Hdigi = new DigitalOut(L3Hpin);
  165. }
  166. if(L1Lpwm != NULL){
  167. delete L1Lpwm;
  168. delete L1Hpwm;
  169. delete L2Lpwm;
  170. delete L2Hpwm;
  171. delete L3Lpwm;
  172. delete L3Hpwm;
  173. L1Lpwm = NULL;
  174. L1Hpwm = NULL;
  175. L2Lpwm = NULL;
  176. L2Hpwm = NULL;
  177. L3Lpwm = NULL;
  178. L3Hpwm = NULL;
  179. }
  180.  
  181. if (~driveOut & 0x01) *L1Ldigi = 0;
  182. if (~driveOut & 0x02) *L1Hdigi = 1;
  183. if (~driveOut & 0x04) *L2Ldigi = 0;
  184. if (~driveOut & 0x08) *L1Hdigi = 1;
  185. if (~driveOut & 0x10) *L3Ldigi = 0;
  186. if (~driveOut & 0x20) *L1Hdigi = 1;
  187.  
  188. if(currentRPSValue < Vref) {
  189. if (driveOut & 0x01) *L1Ldigi = 1;
  190. if (driveOut & 0x02) *L1Hdigi = 0;
  191. if (driveOut & 0x04) *L2Ldigi = 1;
  192. if (driveOut & 0x08) *L2Hdigi = 0;
  193. if (driveOut & 0x10) *L3Ldigi = 1;
  194. if (driveOut & 0x20) *L3Hdigi = 0;
  195. }
  196. }
  197. }
  198.  
  199. //------- Basic synchronisation routine -------
  200. int8_t motorHome()
  201. {
  202. motorOut(0);
  203. wait(1.0);
  204. return readRotorState();
  205. }
  206.  
  207. //------- Map duty cycle -------
  208. void dutyMap() {
  209. if(oriDutyCycle<0) {
  210. tmpdutycycle = oriDutyCycle;
  211. tmpdutycycle=-tmpdutycycle;
  212. }
  213. else {
  214. tmpdutycycle = oriDutyCycle;
  215. }
  216. dutyCycle = tmpdutycycle*0.275 + 0.725;
  217.  
  218. }
  219.  
  220. //------- Drive motor using position sensed by PI -------
  221. //+ve lead = forward | -ve lead = acw
  222. inline void readPIrunMotor(){
  223. // pc.printf("QEI rps: %f \t", currentRPSValue);
  224. // pc.printf("QEI count: %f \n\r", currentPosition);
  225. intState = readRotorState();
  226. if (intState != intStateOld) {
  227. intStateOld = intState;
  228. if (oriDutyCycle > 0) {
  229. dutyMap();
  230. motorOut((intState - orState + lead + 6 ) % 6); //Forwards
  231. }
  232. if (oriDutyCycle < 0) {
  233. dutyMap();
  234. motorOut((intState - orState - lead + 6 ) % 6); //backwards
  235. }
  236. }
  237. }
  238.  
  239. //------- Speed from QEI and PI -------
  240. void getRPSfromQEI(){
  241. lastPosition = currentPosition;
  242. currentPosition = wheel.getPulses(); //getPulses gets accumulated no. of pulses recorded
  243. float numberOfRevolutions = (currentPosition - lastPosition) / 117;
  244. currentRPSValue = modulus((numberOfRevolutions / RPS_SAMPLING_RATE));
  245. }
  246.  
  247. //------- Controller -------
  248. void controlInit() {
  249. controller.setInputLimits(0.0,targetPosition);
  250. controller.setOutputLimits(-1.0, 1.0);
  251. controller.setBias(0.0);
  252. controller.setMode(AUTO);
  253. controller.setSetPoint(targetPosition);
  254. // pc.printf("Kc: %f\n",controller.getPParam());
  255. // pc.printf("Ki: %f\n",controller.getIParam());
  256. // pc.printf("Kd: %f\n",controller.getDParam());
  257. }
  258.  
  259. void controlR() {
  260. while(1) {
  261. controller.setProcessValue(modulus(currentPosition));
  262. oriDutyCycle = controller.compute();
  263. Thread::wait(PIDrate);
  264. }
  265. }
  266.  
  267. void printRPSfromQEI(){
  268. pc.printf("QEI rps: %f \t", currentRPSValue);
  269. pc.printf("QEI count: %f \n\r", currentPosition);
  270. pc.printf("duty cycle: %f \n\r", oriDutyCycle);
  271. }
  272.  
  273. // void PrintK(){
  274. // pc.printf ("Current Kc: %f \t", controller.getPParam());
  275. // }
  276.  
  277.  
  278. //**********************************************
  279. // Main Function *
  280. //**********************************************
  281. int main()
  282. {
  283. pc.printf("Hello\n\r");
  284. orState = motorHome();
  285. pc.printf("Rotor origin: %x\n\r", orState);
  286.  
  287. sampleRPS.attach(&getRPSfromQEI, RPS_SAMPLING_RATE);
  288. PrintRPS.attach(&printRPSfromQEI, 3);
  289. //PrintKpara.attach(&PrintK,2);
  290.  
  291. //******* Setup threads for controller *******
  292. controlInit();
  293. PIDthread.start(controlR);
  294.  
  295. while (1)
  296. {
  297. readPIrunMotor();
  298. }
  299. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement