モータードライバーver4.1 角度フィードバック(クーロン摩擦補償) 角速度フィードバック

Dependencies:   mbed QEI PID DBG

Committer:
shundai
Date:
Fri Mar 13 04:51:41 2020 +0000
Revision:
8:d36996d8b4a0
Parent:
5:1155a15f978c
MDP;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shundai 4:40a764acc4ec 1 /************************************************
shundai 1:844acc585d3d 2 MotorDriver ver4.1 farmware
shundai 1:844acc585d3d 3 author : shundai miyawaki
shundai 1:844acc585d3d 4 2019/06/14 ~
shundai 8:d36996d8b4a0 5 Twitter : @WaatH5
shundai 4:40a764acc4ec 6 Copyright shundai miyawaki. All rights reserved.
shundai 4:40a764acc4ec 7
shundai 4:40a764acc4ec 8 ************************************************/
shundai 1:844acc585d3d 9
shundai 5:1155a15f978c 10 /*
shundai 5:1155a15f978c 11
shundai 5:1155a15f978c 12 // target board select checker of stm32f042k6t6
shundai 5:1155a15f978c 13 //未検証
shundai 5:1155a15f978c 14 #if !defined(TARGET_STM32F042K6)
shundai 5:1155a15f978c 15 #error This code is only for NUCLEO-F042K6 or STM32F042K6T6. Reselect a Platform.
shundai 5:1155a15f978c 16 #endif
shundai 5:1155a15f978c 17 */
shundai 5:1155a15f978c 18
shundai 5:1155a15f978c 19 // target board select checker of stm32f303k8t6
shundai 5:1155a15f978c 20 //検証済
shundai 1:844acc585d3d 21 #if !defined(TARGET_STM32F303K8)
shundai 1:844acc585d3d 22 #error This code is only for NUCLEO-F303K8 or STM32F303K8T6. Reselect a Platform.
shundai 1:844acc585d3d 23 #endif
shundai 1:844acc585d3d 24
shundai 5:1155a15f978c 25 // debug switch
shundai 5:1155a15f978c 26 //#define DEBUG //debug ON
shundai 5:1155a15f978c 27 #undef DEBUG //debug OFF
shundai 1:844acc585d3d 28
shundai 5:1155a15f978c 29 // preproseccer
shundai 1:844acc585d3d 30 #include "dbg.h"
shundai 1:844acc585d3d 31 #include "mbed.h"
shundai 5:1155a15f978c 32 #include "PID.h"
shundai 5:1155a15f978c 33 #include "QEI.h"
shundai 1:844acc585d3d 34 //#include <CANformat.h>
shundai 1:844acc585d3d 35
shundai 1:844acc585d3d 36
shundai 5:1155a15f978c 37 // ゲインはモータードライバー固有のパラメータなのでflashに保存する,
shundai 5:1155a15f978c 38 // 初期値としてデフォルトの値をdefineで定義する
shundai 5:1155a15f978c 39 // theta feedback PID gain
shundai 5:1155a15f978c 40 #define theta_Kp 9.0f
shundai 5:1155a15f978c 41 #define theta_Ki 0.0f
shundai 5:1155a15f978c 42 #define theta_Kd 0.00001f
shundai 5:1155a15f978c 43
shundai 5:1155a15f978c 44 // omega feedback PID gain
shundai 5:1155a15f978c 45 #define omega_Kp 0.05f
shundai 5:1155a15f978c 46 #define omega_Ki 0.05f
shundai 5:1155a15f978c 47 #define omega_Kd 0.0f
shundai 5:1155a15f978c 48
shundai 4:40a764acc4ec 49
shundai 4:40a764acc4ec 50 #define ANGLE_THRESHOLD 2.0f //under 2.0 degree is decreaced
shundai 1:844acc585d3d 51
shundai 5:1155a15f978c 52 // CAN PID define
shundai 1:844acc585d3d 53
shundai 5:1155a15f978c 54 #define THETA_FEEDBACK_CCW 10
shundai 5:1155a15f978c 55 #define THETA_FEEDBACK_CW 11
shundai 5:1155a15f978c 56 #define OMEGA_FEEDBACK_CCW 20
shundai 5:1155a15f978c 57 #define OMEGA_FEEDBACK_CW 21
shundai 5:1155a15f978c 58 #define CURRENT_FEEDBACK_CCW 30
shundai 5:1155a15f978c 59 #define CURRENT_FEEDBACK_CW 31
shundai 1:844acc585d3d 60
shundai 5:1155a15f978c 61 #define MOTOR_STOP 0
shundai 5:1155a15f978c 62 #define THETA_FEEDBACK 10
shundai 5:1155a15f978c 63 #define OMEGA_FEEDBACK 20
shundai 5:1155a15f978c 64 #define CURRENT_FEEDBACK 30
shundai 1:844acc585d3d 65
shundai 5:1155a15f978c 66 // math value define
shundai 1:844acc585d3d 67 #define M_PI 3.141593f
shundai 1:844acc585d3d 68
shundai 5:1155a15f978c 69 // constant value
shundai 1:844acc585d3d 70 #define ABLE 0
shundai 1:844acc585d3d 71 #define DISABLE 1
shundai 5:1155a15f978c 72 #define CCW 0
shundai 2:50e50ee8e08a 73 #define CW 1
shundai 1:844acc585d3d 74
shundai 5:1155a15f978c 75 // threshold value define
shundai 1:844acc585d3d 76 #define MOTOR_TARGET_OMEGA_THRESHOLD 0.5f //[deg/s]
shundai 5:1155a15f978c 77 #define MOTOR_TARGET_THETA_THRESHOLD 0.5f //[rpm]
shundai 1:844acc585d3d 78 #define MOTOR_TARGET_CURRENT_THRESHOLD 0.1f //[A]
shundai 1:844acc585d3d 79
shundai 5:1155a15f978c 80 // stm32f303k8t6 unique serial address
shundai 1:844acc585d3d 81 #define uniqueSerialAdd_kl_freescale (unsigned long *)0x40048058
shundai 1:844acc585d3d 82 #define uniqueSerialAddr_stm32 (unsigned long *)0x1FFFF7E8
shundai 1:844acc585d3d 83 #define uniqueSerialAddr uniqueSerialAddr_stm32
shundai 1:844acc585d3d 84
shundai 5:1155a15f978c 85 // controll value define
shundai 5:1155a15f978c 86 #define PID_CONTROLL_PERIOD 8 //[ms]
shundai 1:844acc585d3d 87 #define ENCODER_CONTROLL_PERIOD 8 //[ms]
shundai 5:1155a15f978c 88 #define CAN_SEND_PERIOD 100 //[ms]
shundai 5:1155a15f978c 89 #define MOTOR_FREUENCY 8000 //[Hz]
shundai 5:1155a15f978c 90 #define CAN_FREQUENCY 100 //[kHz]
shundai 5:1155a15f978c 91 #define SERIAL_BAUDLATE 115200 //[bps]
shundai 5:1155a15f978c 92 #define CURRENT_SENSOR_OFFSET_COUNT 1000 // [count]
shundai 1:844acc585d3d 93
shundai 5:1155a15f978c 94 // current sensor define
shundai 1:844acc585d3d 95 #define CURRENT_SENSOR_VCC 3.3 //[V]
shundai 1:844acc585d3d 96 #define CURRENT_SENSOR_RANGE 105 //[mv/A]
shundai 4:40a764acc4ec 97 #define CURRENT_LIMIT 1.5 //[A]
shundai 1:844acc585d3d 98
shundai 5:1155a15f978c 99 // turning by toukai robocon
shundai 4:40a764acc4ec 100 #define MOTOR1_ID 393246
shundai 4:40a764acc4ec 101 #define MOTOR2_ID -2147418100
shundai 4:40a764acc4ec 102 #define MOTOR3_ID 196631
shundai 5:1155a15f978c 103 #define MOTOR4_ID 786469
shundai 5:1155a15f978c 104 #define MOTOR5_ID 1966107
shundai 5:1155a15f978c 105 #define MOTOR6_ID 1638418
shundai 1:844acc585d3d 106
shundai 1:844acc585d3d 107
shundai 1:844acc585d3d 108 //standerd define
shundai 1:844acc585d3d 109 Serial pc(PB_6, PB_7, SERIAL_BAUDLATE);
shundai 1:844acc585d3d 110 DigitalOut myled(LED1); //PB_3
shundai 1:844acc585d3d 111 DigitalIn userSW(PB_5);
shundai 1:844acc585d3d 112
shundai 1:844acc585d3d 113 //motor define
shundai 1:844acc585d3d 114 PwmOut PWM1(PA_4);
shundai 1:844acc585d3d 115 PwmOut PWM2(PA_6);
shundai 1:844acc585d3d 116 PwmOut PHASE(PB_0);
shundai 1:844acc585d3d 117 DigitalOut SR(PA_7);
shundai 5:1155a15f978c 118 PID thetaPID(theta_Kp, theta_Ki, theta_Kd, PID_CONTROLL_PERIOD*0.001f);
shundai 5:1155a15f978c 119 PID omegaPID(omega_Kp, omega_Ki, omega_Kd, PID_CONTROLL_PERIOD*0.001f);
shundai 5:1155a15f978c 120
shundai 5:1155a15f978c 121 //use encoder define
shundai 5:1155a15f978c 122
shundai 5:1155a15f978c 123 /*
shundai 5:1155a15f978c 124 pulse per revolution : 1000
shundai 5:1155a15f978c 125 phase : A, B, Z
shundai 5:1155a15f978c 126 voltage : 10.8V - 20.0V
shundai 5:1155a15f978c 127 */
shundai 5:1155a15f978c 128 //#define ENCODER_TRD_S1000B
shundai 5:1155a15f978c 129 #define ENCODER_E6A2_CW5C
shundai 5:1155a15f978c 130
shundai 5:1155a15f978c 131 #if defined ENCODER_TRD_S1000B
shundai 5:1155a15f978c 132 #define ENCODER_PULSE_PER_REVOLUTION 4000 //(1000*4)
shundai 1:844acc585d3d 133 QEI encoder(PA_3, PA_1, PA_0, ENCODER_PULSE_PER_REVOLUTION, QEI::X4_ENCODING);
shundai 5:1155a15f978c 134 #endif
shundai 5:1155a15f978c 135
shundai 5:1155a15f978c 136 #if defined ENCODER_E6A2_CW5C
shundai 5:1155a15f978c 137 #define ENCODER_PULSE_PER_REVOLUTION 2000 //(500*4)
shundai 5:1155a15f978c 138 QEI encoder(PA_3, PA_1, NC, ENCODER_PULSE_PER_REVOLUTION, QEI::X4_ENCODING);
shundai 5:1155a15f978c 139 #endif
shundai 5:1155a15f978c 140
shundai 5:1155a15f978c 141 //AnalogIn CPUtemp(ADC_TEMP);
shundai 1:844acc585d3d 142 AnalogIn Current(PB_1);
shundai 1:844acc585d3d 143
shundai 1:844acc585d3d 144 //CAN define
shundai 1:844acc585d3d 145 CAN can(PA_11, PA_12); //RD(PA_11,D10),TD(PA_12,D2)
shundai 1:844acc585d3d 146 CANMessage msg;
shundai 1:844acc585d3d 147
shundai 1:844acc585d3d 148 struct CANdata
shundai 1:844acc585d3d 149 {
shundai 1:844acc585d3d 150 //int timeout;
shundai 4:40a764acc4ec 151 int deviceID;
shundai 1:844acc585d3d 152 char recvDATA[8];
shundai 1:844acc585d3d 153 char sendDATA[8];
shundai 1:844acc585d3d 154 };
shundai 1:844acc585d3d 155
shundai 1:844acc585d3d 156 struct CANdata MDCAN;
shundai 1:844acc585d3d 157
shundai 1:844acc585d3d 158
shundai 5:1155a15f978c 159
shundai 1:844acc585d3d 160 //void CANtimeout();
shundai 1:844acc585d3d 161 //void CANtest();
shundai 1:844acc585d3d 162
shundai 4:40a764acc4ec 163 /*
shundai 4:40a764acc4ec 164 int mode : select THETA_FEEDBACK(=1) or OMEGA_FEEDBACK(=2)
shundai 4:40a764acc4ec 165 double target : enter the input value corresponding to the mode
shundai 4:40a764acc4ec 166 */
shundai 2:50e50ee8e08a 167 void MotorDrive(int mode, double target);
shundai 1:844acc585d3d 168
shundai 1:844acc585d3d 169 //void CurrentFunction();
shundai 1:844acc585d3d 170 InterruptIn userButton(PB_5);
shundai 1:844acc585d3d 171 Ticker Encoder;
shundai 5:1155a15f978c 172 Ticker SEND;
shundai 1:844acc585d3d 173 Timer ENCODER_timer;
shundai 1:844acc585d3d 174
shundai 1:844acc585d3d 175 struct state
shundai 1:844acc585d3d 176 {
shundai 5:1155a15f978c 177 int PID;
shundai 4:40a764acc4ec 178 double ThetaTarget;
shundai 4:40a764acc4ec 179 double OmegaTarget;
shundai 4:40a764acc4ec 180 double CurrentTarget;
shundai 1:844acc585d3d 181 double theta;
shundai 1:844acc585d3d 182 double omega;
shundai 1:844acc585d3d 183 double current;
shundai 1:844acc585d3d 184 };
shundai 1:844acc585d3d 185
shundai 1:844acc585d3d 186 struct state Motor;
shundai 1:844acc585d3d 187
shundai 1:844acc585d3d 188 //Current Sensor setup
shundai 1:844acc585d3d 189 double current_bias = 0.0;
shundai 1:844acc585d3d 190
shundai 1:844acc585d3d 191 void Velocity();
shundai 1:844acc585d3d 192 void ButtonFunction();
shundai 1:844acc585d3d 193 void SerialFunction();
shundai 1:844acc585d3d 194 void CANread();
shundai 5:1155a15f978c 195 void CANsend();
shundai 4:40a764acc4ec 196 void CurrentFunction();
shundai 5:1155a15f978c 197 char SerialGet();
shundai 1:844acc585d3d 198
shundai 4:40a764acc4ec 199 // 電流センサーをタイマー割込みにして,規定量を超えたら角速度の目標値を0にする.
shundai 1:844acc585d3d 200
shundai 5:1155a15f978c 201
shundai 5:1155a15f978c 202
shundai 5:1155a15f978c 203 void loadFlash(uint32_t address, uint8_t *data, uint32_t size);
shundai 5:1155a15f978c 204 void writeFlash(uint32_t address, uint8_t *data, uint32_t size);
shundai 5:1155a15f978c 205 void eraseFlash(uint32_t address);
shundai 5:1155a15f978c 206
shundai 5:1155a15f978c 207 float buf = 0.0f;
shundai 5:1155a15f978c 208
shundai 1:844acc585d3d 209 int main()
shundai 1:844acc585d3d 210 {
shundai 1:844acc585d3d 211 // MPU setup
shundai 4:40a764acc4ec 212 DBG("MotorDriver_ver4.1 start! \r\n");
shundai 4:40a764acc4ec 213 DBG("/** MPU INFO **/ \r\n");
shundai 4:40a764acc4ec 214 DBG("Target PlatForm: STM32F303K8T6 \r\n");
shundai 4:40a764acc4ec 215 DBG("System Frequency: %d Hz \r\n", SystemCoreClock);
shundai 4:40a764acc4ec 216 DBG("Program File: %s \r\n", __FILE__);
shundai 4:40a764acc4ec 217 DBG("Compile Date: %s \r\n", __DATE__);
shundai 4:40a764acc4ec 218 DBG("Compile Time: %s \r\n", __TIME__);
shundai 1:844acc585d3d 219
shundai 1:844acc585d3d 220 //Unique ID starting addresses for most of STM32 microcontrollers.
shundai 5:1155a15f978c 221 long *id = (long *)0x1FFFF7AC;
shundai 1:844acc585d3d 222
shundai 4:40a764acc4ec 223 DBG("%d, %d, %d \r\n", id[0], id[1], id[2]);
shundai 4:40a764acc4ec 224
shundai 4:40a764acc4ec 225 switch (id[0])
shundai 4:40a764acc4ec 226 {
shundai 4:40a764acc4ec 227 case MOTOR1_ID:
shundai 4:40a764acc4ec 228 MDCAN.deviceID = 11;
shundai 4:40a764acc4ec 229 DBG("\r\n ==MOTOR1== \r\n\r\n");
shundai 4:40a764acc4ec 230 break;
shundai 4:40a764acc4ec 231
shundai 4:40a764acc4ec 232 case MOTOR2_ID:
shundai 4:40a764acc4ec 233 MDCAN.deviceID = 12;
shundai 4:40a764acc4ec 234 DBG("\r\n ==MOTOR2== \r\n\r\n");
shundai 4:40a764acc4ec 235 break;
shundai 4:40a764acc4ec 236
shundai 4:40a764acc4ec 237 case MOTOR3_ID:
shundai 4:40a764acc4ec 238 MDCAN.deviceID = 13;
shundai 4:40a764acc4ec 239 DBG("\r\n ==MOTOR3== \r\n\r\n");
shundai 4:40a764acc4ec 240 break;
shundai 1:844acc585d3d 241
shundai 4:40a764acc4ec 242 case MOTOR4_ID:
shundai 4:40a764acc4ec 243 MDCAN.deviceID = 14;
shundai 4:40a764acc4ec 244 DBG("\r\n ==MOTOR4== \r\n\r\n");
shundai 4:40a764acc4ec 245 break;
shundai 4:40a764acc4ec 246
shundai 4:40a764acc4ec 247 case MOTOR5_ID:
shundai 4:40a764acc4ec 248 MDCAN.deviceID = 15;
shundai 4:40a764acc4ec 249 DBG("\r\n ==MOTOR5== \r\n\r\n");
shundai 4:40a764acc4ec 250 break;
shundai 4:40a764acc4ec 251
shundai 4:40a764acc4ec 252 case MOTOR6_ID:
shundai 4:40a764acc4ec 253 MDCAN.deviceID = 16;
shundai 4:40a764acc4ec 254 DBG("\r\n ==MOTOR6== \r\n\r\n");
shundai 4:40a764acc4ec 255 break;
shundai 4:40a764acc4ec 256
shundai 4:40a764acc4ec 257 default:
shundai 4:40a764acc4ec 258
shundai 4:40a764acc4ec 259 while(1)
shundai 4:40a764acc4ec 260 {
shundai 5:1155a15f978c 261 DBG("deviceID none define. It does not work!\r\n");
shundai 4:40a764acc4ec 262 }
shundai 4:40a764acc4ec 263 }
shundai 1:844acc585d3d 264
shundai 4:40a764acc4ec 265 DBG("deviceID : %d \r\n", MDCAN.deviceID);
shundai 5:1155a15f978c 266
shundai 5:1155a15f978c 267 // user LED Indicator
shundai 1:844acc585d3d 268 myled = 1;
shundai 1:844acc585d3d 269 wait(1.0);
shundai 1:844acc585d3d 270 myled = 0;
shundai 1:844acc585d3d 271
shundai 1:844acc585d3d 272 // CAN setup
shundai 5:1155a15f978c 273 can.frequency(CAN_FREQUENCY*1000); //ROS default bps:100kbps -> 500kbps
shundai 4:40a764acc4ec 274 can.mode(CAN::Normal);
shundai 4:40a764acc4ec 275 //can.filter(MDCAN.deviceID, 0x0000000F, CANStandard, 14);
shundai 4:40a764acc4ec 276 //can.reset(); //delete receive buffer
shundai 5:1155a15f978c 277
shundai 1:844acc585d3d 278 // motor signal setup
shundai 1:844acc585d3d 279 PWM1.period(1.0f/MOTOR_FREUENCY);
shundai 1:844acc585d3d 280 PWM2.period(1.0f/MOTOR_FREUENCY);
shundai 4:40a764acc4ec 281 PHASE.period(1.0f/MOTOR_FREUENCY);
shundai 1:844acc585d3d 282 PWM1 = 0.0f;
shundai 1:844acc585d3d 283 PWM2 = 0.0f;
shundai 1:844acc585d3d 284 PHASE = 0.0f;
shundai 1:844acc585d3d 285 SR = 0;
shundai 4:40a764acc4ec 286
shundai 4:40a764acc4ec 287 // PID position setup
shundai 5:1155a15f978c 288 thetaPID.setInputLimits(-360.0f*100.0f, 360.0f*100.0f); //[deg]
shundai 5:1155a15f978c 289 thetaPID.setOutputLimits(-240.0f, 240.0f); //[rpm]
shundai 4:40a764acc4ec 290 thetaPID.setBias(0.0);
shundai 4:40a764acc4ec 291 thetaPID.setMode(AUTO_MODE);
shundai 1:844acc585d3d 292
shundai 5:1155a15f978c 293 // PID omega setup
shundai 5:1155a15f978c 294 omegaPID.setInputLimits(0.0, 240.0f*0.9f); //[rpm]
shundai 5:1155a15f978c 295 omegaPID.setOutputLimits(0.0f, 1.0f); //[duty]
shundai 5:1155a15f978c 296 omegaPID.setBias(0.0);
shundai 5:1155a15f978c 297 omegaPID.setMode(AUTO_MODE);
shundai 5:1155a15f978c 298
shundai 1:844acc585d3d 299 // current sensor setup
shundai 1:844acc585d3d 300 for(int i = 0 ; i < CURRENT_SENSOR_OFFSET_COUNT ; i++)
shundai 1:844acc585d3d 301 {
shundai 1:844acc585d3d 302 current_bias += Current.read();
shundai 1:844acc585d3d 303 }
shundai 1:844acc585d3d 304
shundai 1:844acc585d3d 305 current_bias = current_bias/(double)CURRENT_SENSOR_OFFSET_COUNT;
shundai 4:40a764acc4ec 306 DBG("current_bias_average: %f \r\n", current_bias);
shundai 5:1155a15f978c 307
shundai 1:844acc585d3d 308 // interrupt start function
shundai 1:844acc585d3d 309 userButton.mode(PullUp);
shundai 1:844acc585d3d 310 userButton.fall(ButtonFunction);
shundai 1:844acc585d3d 311 pc.attach(SerialFunction, Serial::RxIrq);
shundai 1:844acc585d3d 312 can.attach(CANread, CAN::RxIrq);
shundai 5:1155a15f978c 313 SEND.attach(CANsend, CAN_SEND_PERIOD*0.001f);
shundai 1:844acc585d3d 314 ENCODER_timer.start();
shundai 1:844acc585d3d 315 Encoder.attach(Velocity, ENCODER_CONTROLL_PERIOD*0.001f); //Measure rotation speed every 30ms
shundai 1:844acc585d3d 316 //NVIC_SetPriority(TIMER3_IRQn, 1);
shundai 1:844acc585d3d 317
shundai 4:40a764acc4ec 318 //initial target
shundai 5:1155a15f978c 319 Motor.PID = OMEGA_FEEDBACK; // initial drive mode is stop.
shundai 5:1155a15f978c 320 Motor.ThetaTarget = 0.0f; // initial theta[deg]
shundai 5:1155a15f978c 321 Motor.OmegaTarget = 0.0f; // initial omega[rpm]
shundai 4:40a764acc4ec 322
shundai 1:844acc585d3d 323 while(1)
shundai 1:844acc585d3d 324 {
shundai 5:1155a15f978c 325 pc.printf("%f \r\n", buf);
shundai 5:1155a15f978c 326
shundai 5:1155a15f978c 327 if(buf > 0.0f)
shundai 5:1155a15f978c 328 {
shundai 5:1155a15f978c 329 PWM1 = 0.0f;
shundai 5:1155a15f978c 330 PWM2 = buf;
shundai 5:1155a15f978c 331 }
shundai 5:1155a15f978c 332
shundai 5:1155a15f978c 333 else if(buf <= 0.0f)
shundai 5:1155a15f978c 334 {
shundai 5:1155a15f978c 335 PWM1 = buf;
shundai 5:1155a15f978c 336 PWM2 = 0.0f;
shundai 5:1155a15f978c 337 }
shundai 5:1155a15f978c 338
shundai 2:50e50ee8e08a 339 //Motor.current = ((Current.read()-current_bias)*((float)CURRENT_SENSOR_VCC/2.0f))/(CURRENT_SENSOR_RANGE*0.001f);
shundai 1:844acc585d3d 340
shundai 4:40a764acc4ec 341 //DBG("omegaPID.compute : %6.3f thetaPID.compute : %6.3f theta : %6.3f omega[rps] :%6.3f \r\n", omegaPID.compute(), thetaPID.compute(), Motor.theta, Motor.omega);
shundai 1:844acc585d3d 342
shundai 5:1155a15f978c 343 switch(Motor.PID)
shundai 5:1155a15f978c 344 {
shundai 5:1155a15f978c 345 case THETA_FEEDBACK:
shundai 5:1155a15f978c 346
shundai 5:1155a15f978c 347 //DBG("THETA_FEEDBACK \r\n");
shundai 5:1155a15f978c 348 MotorDrive(THETA_FEEDBACK, Motor.ThetaTarget);
shundai 5:1155a15f978c 349 break;
shundai 5:1155a15f978c 350
shundai 5:1155a15f978c 351 case OMEGA_FEEDBACK:
shundai 5:1155a15f978c 352
shundai 5:1155a15f978c 353 //DBG("OMEGA_FEEDBACK \r\n");
shundai 5:1155a15f978c 354 MotorDrive(OMEGA_FEEDBACK, Motor.OmegaTarget);
shundai 5:1155a15f978c 355 break;
shundai 5:1155a15f978c 356
shundai 5:1155a15f978c 357 case CURRENT_FEEDBACK:
shundai 5:1155a15f978c 358
shundai 5:1155a15f978c 359 //DBG("CURRENT_FEEDBACK \r\n");
shundai 5:1155a15f978c 360 MotorDrive(CURRENT_FEEDBACK, Motor.CurrentTarget);
shundai 5:1155a15f978c 361
shundai 5:1155a15f978c 362 case MOTOR_STOP:
shundai 5:1155a15f978c 363
shundai 5:1155a15f978c 364 //DBG("MOTOR_STOP \r\n");
shundai 5:1155a15f978c 365 MotorDrive(OMEGA_FEEDBACK, 0.0f);
shundai 5:1155a15f978c 366 break;
shundai 5:1155a15f978c 367
shundai 5:1155a15f978c 368 default: // the others PID is stop.
shundai 5:1155a15f978c 369
shundai 5:1155a15f978c 370 MotorDrive(OMEGA_FEEDBACK, 0.0f);
shundai 5:1155a15f978c 371 break;
shundai 5:1155a15f978c 372 }
shundai 5:1155a15f978c 373
shundai 5:1155a15f978c 374 //pc.printf("PID[%d], TT[%6.3f deg], OT[%6.3f rpm], T[%6.3f deg], O[%6.3f rpm] \r\n", Motor.PID, Motor.ThetaTarget, Motor.OmegaTarget, Motor.theta, Motor.omega);
shundai 5:1155a15f978c 375 pc.printf("T[%6.3f deg], O[%6.3f rpm] \r\n", Motor.theta, Motor.omega);
shundai 2:50e50ee8e08a 376
shundai 4:40a764acc4ec 377 //DBG("current:%f omega:%f pwm:%f \r\n",current.read(), omega ,thetaPID.compute());
shundai 1:844acc585d3d 378 //CurrentFunction();
shundai 5:1155a15f978c 379
shundai 1:844acc585d3d 380 }
shundai 1:844acc585d3d 381 }
shundai 1:844acc585d3d 382
shundai 1:844acc585d3d 383 void SerialFunction()
shundai 1:844acc585d3d 384 {
shundai 1:844acc585d3d 385 if(pc.readable() == 1)
shundai 1:844acc585d3d 386 {
shundai 1:844acc585d3d 387 char data = pc.getc();
shundai 4:40a764acc4ec 388 DBG("get data:%c \r\n", data);
shundai 5:1155a15f978c 389
shundai 1:844acc585d3d 390 switch (data)
shundai 1:844acc585d3d 391 {
shundai 2:50e50ee8e08a 392 case 'p':
shundai 5:1155a15f978c 393 //Motor.PID = THETA_FEEDBACK;
shundai 5:1155a15f978c 394 //Motor.ThetaTarget += 30.0f;
shundai 5:1155a15f978c 395 buf += 0.05f;
shundai 4:40a764acc4ec 396 DBG("get 'p' \r\n");
shundai 2:50e50ee8e08a 397
shundai 2:50e50ee8e08a 398 break;
shundai 2:50e50ee8e08a 399
shundai 2:50e50ee8e08a 400 case 'l':
shundai 5:1155a15f978c 401 //Motor.PID = THETA_FEEDBACK;
shundai 5:1155a15f978c 402 //Motor.ThetaTarget -= 30.0f;
shundai 5:1155a15f978c 403 buf -= 0.05f;
shundai 4:40a764acc4ec 404 DBG("get 'l' \r\n");
shundai 2:50e50ee8e08a 405
shundai 2:50e50ee8e08a 406 break;
shundai 5:1155a15f978c 407
shundai 5:1155a15f978c 408 case 'o':
shundai 5:1155a15f978c 409 Motor.PID = OMEGA_FEEDBACK;
shundai 5:1155a15f978c 410 Motor.OmegaTarget += 10.0f;
shundai 5:1155a15f978c 411 DBG("get 'q' \r\n");
shundai 5:1155a15f978c 412
shundai 5:1155a15f978c 413 break;
shundai 2:50e50ee8e08a 414
shundai 5:1155a15f978c 415 case 'k':
shundai 5:1155a15f978c 416 Motor.PID = OMEGA_FEEDBACK;
shundai 5:1155a15f978c 417 Motor.OmegaTarget -= 10.0f;
shundai 5:1155a15f978c 418 DBG("get 'a' \r\n");
shundai 1:844acc585d3d 419
shundai 5:1155a15f978c 420 break;
shundai 5:1155a15f978c 421
shundai 1:844acc585d3d 422 case 'r':
shundai 1:844acc585d3d 423
shundai 4:40a764acc4ec 424 DBG("\r\nSystem Reset! \r\n");
shundai 1:844acc585d3d 425 NVIC_SystemReset();
shundai 1:844acc585d3d 426
shundai 1:844acc585d3d 427 break;
shundai 5:1155a15f978c 428
shundai 5:1155a15f978c 429 case 'f': //PID free (PWM only)
shundai 5:1155a15f978c 430
shundai 5:1155a15f978c 431
shundai 5:1155a15f978c 432 /*
shundai 5:1155a15f978c 433 while(1)
shundai 5:1155a15f978c 434 {
shundai 5:1155a15f978c 435 SR = ABLE;
shundai 5:1155a15f978c 436 PHASE = (float)CW;
shundai 5:1155a15f978c 437 PWM1 = 0.05f;
shundai 5:1155a15f978c 438 PWM2 = 1.0f;
shundai 5:1155a15f978c 439 }
shundai 5:1155a15f978c 440 */
shundai 5:1155a15f978c 441
shundai 1:844acc585d3d 442 default:
shundai 1:844acc585d3d 443
shundai 4:40a764acc4ec 444 DBG("The others key recieve \r\n");
shundai 1:844acc585d3d 445
shundai 1:844acc585d3d 446 break;
shundai 1:844acc585d3d 447 }
shundai 1:844acc585d3d 448 }
shundai 1:844acc585d3d 449 }
shundai 1:844acc585d3d 450
shundai 1:844acc585d3d 451 void ButtonFunction()
shundai 1:844acc585d3d 452 {
shundai 5:1155a15f978c 453 //serial menu printf
shundai 4:40a764acc4ec 454 DBG("setup open \r\n");
shundai 5:1155a15f978c 455 DBG("1: Theta Controll\r\n");
shundai 5:1155a15f978c 456 DBG("2: Omega Controll\r\n");
shundai 5:1155a15f978c 457 DBG("3: Exit setup menu...\r\n");
shundai 5:1155a15f978c 458
shundai 5:1155a15f978c 459 DBG("Send to MD11 test CAN data\r\n");
shundai 5:1155a15f978c 460
shundai 5:1155a15f978c 461 MDCAN.sendDATA[0] = 21; // omega FB CCw
shundai 5:1155a15f978c 462 MDCAN.sendDATA[1] = 60; // 60 rpm
shundai 5:1155a15f978c 463 MDCAN.sendDATA[2] = 0;
shundai 5:1155a15f978c 464 MDCAN.sendDATA[3] = 0;
shundai 5:1155a15f978c 465 MDCAN.sendDATA[4] = 0;
shundai 5:1155a15f978c 466 MDCAN.sendDATA[5] = 0;
shundai 5:1155a15f978c 467 MDCAN.sendDATA[6] = 0;
shundai 5:1155a15f978c 468 MDCAN.sendDATA[7] = 0;
shundai 5:1155a15f978c 469
shundai 5:1155a15f978c 470 if(!can.write(CANMessage(12, MDCAN.sendDATA, 8, CANData, CANStandard)))
shundai 5:1155a15f978c 471 {
shundai 5:1155a15f978c 472 DBG("CAN send error! \r\n");
shundai 5:1155a15f978c 473 }
shundai 1:844acc585d3d 474
shundai 1:844acc585d3d 475 //CANtest(); //CAN通信のテスト信号を簡易的に出す関数(通常は使わない)303K8_sendと同じ機能
shundai 1:844acc585d3d 476
shundai 1:844acc585d3d 477 //ユーザーボタンを押したらモータを台形加速させるプログラムを作る
shundai 1:844acc585d3d 478
shundai 5:1155a15f978c 479 //ボタン情報を割込みで入力させる関数を用意してボタン情報を入力する.
shundai 5:1155a15f978c 480
shundai 5:1155a15f978c 481 //モータが駆動し始める電流を測定する.(パルスが増えるまでPWMを微小増加させる)
shundai 5:1155a15f978c 482 /*
shundai 5:1155a15f978c 483 Motor.OmegaTarget = 60.0f; //[rpm]
shundai 5:1155a15f978c 484
shundai 1:844acc585d3d 485 while(1)
shundai 1:844acc585d3d 486 {
shundai 5:1155a15f978c 487 // motor stop
shundai 5:1155a15f978c 488 PWM1 = 0.0f;
shundai 5:1155a15f978c 489 PWM2 = 0.0f;
shundai 1:844acc585d3d 490 }
shundai 5:1155a15f978c 491 */
shundai 1:844acc585d3d 492 }
shundai 1:844acc585d3d 493
shundai 1:844acc585d3d 494 void CANread()
shundai 1:844acc585d3d 495 {
shundai 5:1155a15f978c 496 // 1. when data received.
shundai 5:1155a15f978c 497 // 2. when CAN data ID equal my ID
shundai 5:1155a15f978c 498 // 3. when CAN data format is Standerd
shundai 5:1155a15f978c 499 // 4. Not the same as the one received in the past
shundai 5:1155a15f978c 500 // 同じものは受信しないプログラムを消したら通信できた446re
shundai 5:1155a15f978c 501 if(can.read(msg) != 0 &&
shundai 5:1155a15f978c 502 MDCAN.deviceID == msg.id &&
shundai 5:1155a15f978c 503 msg.format == 0 )
shundai 1:844acc585d3d 504 {
shundai 4:40a764acc4ec 505 DBG("CAN recieve \r\n");
shundai 1:844acc585d3d 506 myled = !myled;
shundai 4:40a764acc4ec 507
shundai 4:40a764acc4ec 508 DBG("recv ID : %d", msg.id);
shundai 1:844acc585d3d 509
shundai 1:844acc585d3d 510 for(int i = 0 ; i < 8 ; i++)
shundai 1:844acc585d3d 511 {
shundai 1:844acc585d3d 512 MDCAN.recvDATA[i] = msg.data[i];
shundai 4:40a764acc4ec 513 DBG("[%d] ", MDCAN.recvDATA[i]);
shundai 1:844acc585d3d 514 }
shundai 1:844acc585d3d 515
shundai 4:40a764acc4ec 516 DBG("\r\n");
shundai 1:844acc585d3d 517
shundai 4:40a764acc4ec 518 switch(MDCAN.recvDATA[0]) //check PID
shundai 1:844acc585d3d 519 {
shundai 5:1155a15f978c 520 //送られてくるデータはかならず正なので1バイト目のCCW,CWじょうほうを目標値に付け加える.
shundai 5:1155a15f978c 521 case THETA_FEEDBACK_CW: //MD data send
shundai 5:1155a15f978c 522
shundai 5:1155a15f978c 523 Motor.PID = THETA_FEEDBACK;
shundai 5:1155a15f978c 524 Motor.ThetaTarget = (double)MDCAN.recvDATA[1];
shundai 5:1155a15f978c 525 DBG("theta CW FB CAN \r\n");
shundai 5:1155a15f978c 526 break;
shundai 5:1155a15f978c 527
shundai 5:1155a15f978c 528 case THETA_FEEDBACK_CCW: //MD data send
shundai 4:40a764acc4ec 529
shundai 5:1155a15f978c 530 Motor.PID = THETA_FEEDBACK;
shundai 5:1155a15f978c 531 Motor.ThetaTarget = -1.0f*(double)MDCAN.recvDATA[1];
shundai 5:1155a15f978c 532 DBG("theta CCW FB CAN \r\n");
shundai 1:844acc585d3d 533 break;
shundai 1:844acc585d3d 534
shundai 5:1155a15f978c 535 case OMEGA_FEEDBACK_CW:
shundai 1:844acc585d3d 536
shundai 5:1155a15f978c 537 // 1 rpm(0.0166 rps)
shundai 5:1155a15f978c 538 Motor.PID = OMEGA_FEEDBACK;
shundai 4:40a764acc4ec 539 Motor.OmegaTarget = (double)MDCAN.recvDATA[1];
shundai 5:1155a15f978c 540 DBG("omega CW FB CAN \r\n");
shundai 5:1155a15f978c 541 break;
shundai 5:1155a15f978c 542
shundai 5:1155a15f978c 543 case OMEGA_FEEDBACK_CCW:
shundai 5:1155a15f978c 544
shundai 5:1155a15f978c 545 // 1 rpm(0.0166 rps)
shundai 5:1155a15f978c 546 Motor.PID = OMEGA_FEEDBACK;
shundai 5:1155a15f978c 547 Motor.OmegaTarget = -1.0f*(double)MDCAN.recvDATA[1];
shundai 5:1155a15f978c 548 DBG("omega CCW FB CAN \r\n");
shundai 1:844acc585d3d 549 break;
shundai 1:844acc585d3d 550
shundai 1:844acc585d3d 551 default:
shundai 4:40a764acc4ec 552
shundai 4:40a764acc4ec 553 DBG("recv CAN PID error \r\n");
shundai 1:844acc585d3d 554
shundai 1:844acc585d3d 555 break;
shundai 1:844acc585d3d 556 }
shundai 1:844acc585d3d 557 }
shundai 1:844acc585d3d 558 }
shundai 1:844acc585d3d 559
shundai 1:844acc585d3d 560 void Velocity()
shundai 1:844acc585d3d 561 {
shundai 1:844acc585d3d 562 static int pulse; //old pulse
shundai 1:844acc585d3d 563
shundai 5:1155a15f978c 564 Motor.omega = 60.0f*((encoder.getPulses() - pulse)/(double)ENCODER_PULSE_PER_REVOLUTION)/ENCODER_timer.read();
shundai 1:844acc585d3d 565 pulse = encoder.getPulses(); //pulse update
shundai 1:844acc585d3d 566
shundai 1:844acc585d3d 567 Motor.theta = (encoder.getPulses()/(double)ENCODER_PULSE_PER_REVOLUTION)*360.0f;
shundai 1:844acc585d3d 568
shundai 1:844acc585d3d 569 ENCODER_timer.reset(); //timer reset:t=0s
shundai 5:1155a15f978c 570 if(Motor.omega > 0)
shundai 5:1155a15f978c 571 {
shundai 5:1155a15f978c 572 MDCAN.sendDATA[0] = OMEGA_FEEDBACK_CW;
shundai 5:1155a15f978c 573 }
shundai 1:844acc585d3d 574
shundai 5:1155a15f978c 575 else
shundai 5:1155a15f978c 576 {
shundai 5:1155a15f978c 577 MDCAN.sendDATA[0] = OMEGA_FEEDBACK_CCW;
shundai 5:1155a15f978c 578 }
shundai 5:1155a15f978c 579 //pc.printf("%d \r\n", abs(int(Motor.omega)));
shundai 5:1155a15f978c 580 //MDCAN.sendDATA[1] = abs(int(Motor.omega));
shundai 5:1155a15f978c 581 //MDCAN.sendDATA[2] = 0;
shundai 5:1155a15f978c 582 //MDCAN.sendDATA[3] = 0;
shundai 5:1155a15f978c 583 //MDCAN.sendDATA[4] = 0;
shundai 5:1155a15f978c 584 //MDCAN.sendDATA[5] = 0;
shundai 5:1155a15f978c 585 //MDCAN.sendDATA[6] = 0;
shundai 5:1155a15f978c 586 //MDCAN.sendDATA[7] = 0;
shundai 5:1155a15f978c 587
shundai 5:1155a15f978c 588 /*
shundai 5:1155a15f978c 589 if(!can.write(CANMessage(MDCAN.deviceID*10, MDCAN.sendDATA, 8, CANData, CANExtended)))
shundai 5:1155a15f978c 590 {
shundai 5:1155a15f978c 591 DBG("CAN send error! \r\n");
shundai 5:1155a15f978c 592 }
shundai 4:40a764acc4ec 593 */
shundai 5:1155a15f978c 594
shundai 4:40a764acc4ec 595 //DBG("omega[rps]:%lf pulse:%d \r\n", Motor.omega, pulse);
shundai 1:844acc585d3d 596 }
shundai 1:844acc585d3d 597
shundai 5:1155a15f978c 598 void CANsend()
shundai 1:844acc585d3d 599 {
shundai 5:1155a15f978c 600 //CANSendがデータ集めて送信(50mstoka)
shundai 4:40a764acc4ec 601 //__disable_irq();
shundai 4:40a764acc4ec 602 //Encoder.detach();
shundai 1:844acc585d3d 603
shundai 4:40a764acc4ec 604 //data -> Can data
shundai 4:40a764acc4ec 605
shundai 5:1155a15f978c 606 switch (MDCAN.sendDATA[0])
shundai 5:1155a15f978c 607 {
shundai 5:1155a15f978c 608 case THETA_FEEDBACK:
shundai 5:1155a15f978c 609 MDCAN.sendDATA[1] = abs(int(Motor.theta));
shundai 5:1155a15f978c 610 break;
shundai 5:1155a15f978c 611
shundai 5:1155a15f978c 612 case OMEGA_FEEDBACK:
shundai 5:1155a15f978c 613 MDCAN.sendDATA[1] = abs(int(Motor.omega));
shundai 5:1155a15f978c 614 break;
shundai 5:1155a15f978c 615 }
shundai 5:1155a15f978c 616
shundai 5:1155a15f978c 617
shundai 5:1155a15f978c 618 MDCAN.sendDATA[2] = 0;
shundai 5:1155a15f978c 619 MDCAN.sendDATA[3] = 0;
shundai 5:1155a15f978c 620 MDCAN.sendDATA[4] = 0;
shundai 5:1155a15f978c 621 MDCAN.sendDATA[5] = 0;
shundai 5:1155a15f978c 622 MDCAN.sendDATA[6] = 0;
shundai 5:1155a15f978c 623 MDCAN.sendDATA[7] = 0;
shundai 5:1155a15f978c 624
shundai 4:40a764acc4ec 625 //余りを計算して,端数は削除するとCANデータに変換できる
shundai 5:1155a15f978c 626 if(!can.write(CANMessage((char)((int)MDCAN.deviceID-10)*10+100, MDCAN.sendDATA, 8, CANData, CANStandard)))
shundai 1:844acc585d3d 627 {
shundai 4:40a764acc4ec 628 DBG("CAN send error! \r\n");
shundai 1:844acc585d3d 629 }
shundai 5:1155a15f978c 630
shundai 5:1155a15f978c 631 else
shundai 5:1155a15f978c 632 {
shundai 5:1155a15f978c 633 pc.printf("send !!");
shundai 5:1155a15f978c 634 }
shundai 1:844acc585d3d 635
shundai 4:40a764acc4ec 636 //__enable_irq();
shundai 4:40a764acc4ec 637 //Encoder.attach(Velocity, ENCODER_CONTROLL_PERIOD); //Measure rotation speed every 30ms
shundai 4:40a764acc4ec 638 //pc.attach(SerialFunction, Serial::RxIrq);
shundai 4:40a764acc4ec 639 //userButton.fall(ButtonFunction);
shundai 4:40a764acc4ec 640 //can.attach(CANread, CAN::RxIrq);
shundai 1:844acc585d3d 641 }
shundai 1:844acc585d3d 642
shundai 1:844acc585d3d 643 void CurrentFunction()
shundai 1:844acc585d3d 644 {
shundai 4:40a764acc4ec 645
shundai 1:844acc585d3d 646 }
shundai 1:844acc585d3d 647
shundai 2:50e50ee8e08a 648 void MotorDrive(int mode, double target)
shundai 4:40a764acc4ec 649 {
shundai 4:40a764acc4ec 650 //theta feebback(mode 1)
shundai 4:40a764acc4ec 651 //omega feedback(mode 2)
shundai 4:40a764acc4ec 652 //current feedback(mode 3)
shundai 1:844acc585d3d 653
shundai 1:844acc585d3d 654 //static int old_direction;
shundai 5:1155a15f978c 655 //static double old_target;
shundai 1:844acc585d3d 656
shundai 1:844acc585d3d 657 switch (mode)
shundai 1:844acc585d3d 658 {
shundai 1:844acc585d3d 659 case THETA_FEEDBACK:
shundai 1:844acc585d3d 660
shundai 5:1155a15f978c 661 //DBG("THETA_FEEDBACK!! \r\n");
shundai 1:844acc585d3d 662
shundai 5:1155a15f978c 663 thetaPID.setSetPoint(target);
shundai 5:1155a15f978c 664 thetaPID.setProcessValue(Motor.theta);
shundai 1:844acc585d3d 665
shundai 2:50e50ee8e08a 666 if(target >= 0)
shundai 1:844acc585d3d 667 {
shundai 5:1155a15f978c 668 // Friction compensation
shundai 4:40a764acc4ec 669 if(abs(Motor.omega) < 0.01f && abs(Motor.theta - target) > ANGLE_THRESHOLD) //モータの回転が停止中
shundai 1:844acc585d3d 670 {
shundai 5:1155a15f978c 671 //SR = ABLE;
shundai 5:1155a15f978c 672 //PHASE = (float)CW;
shundai 5:1155a15f978c 673 //PWM1 = 0.9f;
shundai 5:1155a15f978c 674 //PWM2 = 1.0f;
shundai 1:844acc585d3d 675 }
shundai 2:50e50ee8e08a 676
shundai 4:40a764acc4ec 677 if(abs(Motor.theta - target) > ANGLE_THRESHOLD)//モータ回転中で誤差が0.1以上
shundai 1:844acc585d3d 678 {
shundai 5:1155a15f978c 679 MotorDrive(OMEGA_FEEDBACK, thetaPID.compute());
shundai 1:844acc585d3d 680 }
shundai 1:844acc585d3d 681
shundai 3:141dc1666df2 682 else //誤差の範囲内ならモータのPWMを停止させる
shundai 3:141dc1666df2 683 {
shundai 3:141dc1666df2 684 MotorDrive(OMEGA_FEEDBACK, 0.0);
shundai 4:40a764acc4ec 685 PWM1 = 0.0f;
shundai 4:40a764acc4ec 686 PWM2 = 1.0f;
shundai 4:40a764acc4ec 687 }
shundai 1:844acc585d3d 688 }
shundai 1:844acc585d3d 689
shundai 1:844acc585d3d 690 else
shundai 5:1155a15f978c 691 {
shundai 5:1155a15f978c 692 // Friction compensation
shundai 4:40a764acc4ec 693 if(abs(Motor.omega) < 0.01f && abs(Motor.theta - target) > ANGLE_THRESHOLD) //モータの回転が停止時
shundai 1:844acc585d3d 694 {
shundai 5:1155a15f978c 695 //SR = ABLE;
shundai 5:1155a15f978c 696 //PHASE = (float)CCW;
shundai 5:1155a15f978c 697 //PWM1 = 0.9f;
shundai 5:1155a15f978c 698 //PWM2 = 1.0f;
shundai 1:844acc585d3d 699 }
shundai 1:844acc585d3d 700
shundai 4:40a764acc4ec 701 if(abs(Motor.theta - target) > ANGLE_THRESHOLD)//モータ回転中で誤差が0.1以上
shundai 1:844acc585d3d 702 {
shundai 5:1155a15f978c 703 MotorDrive(OMEGA_FEEDBACK, thetaPID.compute());
shundai 1:844acc585d3d 704 }
shundai 1:844acc585d3d 705
shundai 3:141dc1666df2 706 else //誤差の範囲内ならモータのPWMを停止させる
shundai 3:141dc1666df2 707 {
shundai 4:40a764acc4ec 708 MotorDrive(OMEGA_FEEDBACK, 0.0);
shundai 3:141dc1666df2 709 PWM1 = 0.0f;
shundai 4:40a764acc4ec 710 PWM2 = 1.0f;
shundai 3:141dc1666df2 711 }
shundai 1:844acc585d3d 712 }
shundai 1:844acc585d3d 713
shundai 1:844acc585d3d 714 break;
shundai 1:844acc585d3d 715
shundai 1:844acc585d3d 716 case OMEGA_FEEDBACK:
shundai 1:844acc585d3d 717
shundai 5:1155a15f978c 718 //DBG("OMEGA_FEEDBACK ");
shundai 2:50e50ee8e08a 719
shundai 2:50e50ee8e08a 720 if(target >= 0.0f)
shundai 2:50e50ee8e08a 721 {
shundai 5:1155a15f978c 722 omegaPID.setSetPoint(abs(target)); //目標値入力
shundai 5:1155a15f978c 723 omegaPID.setProcessValue(abs(Motor.omega));//センサー入力(絶対値いる?)
shundai 1:844acc585d3d 724 //ここにtargetの正負によって回転方向を帰るプログラムを書く
shundai 1:844acc585d3d 725 SR = ABLE;
shundai 2:50e50ee8e08a 726 PHASE = (float)CW;
shundai 5:1155a15f978c 727 PWM1 = omegaPID.compute();
shundai 1:844acc585d3d 728 PWM2 = 1.0f;
shundai 1:844acc585d3d 729
shundai 4:40a764acc4ec 730 //DBG("%f \r\n", (float)direction);
shundai 2:50e50ee8e08a 731 }
shundai 2:50e50ee8e08a 732
shundai 2:50e50ee8e08a 733 else
shundai 2:50e50ee8e08a 734 {
shundai 5:1155a15f978c 735 omegaPID.setSetPoint(abs(target));
shundai 5:1155a15f978c 736 omegaPID.setProcessValue(abs(Motor.omega));
shundai 5:1155a15f978c 737 //ここにtargetの正負によって回転方向を帰るプログラムを書く
shundai 2:50e50ee8e08a 738 SR = ABLE;
shundai 2:50e50ee8e08a 739 PHASE = (float)CCW;
shundai 5:1155a15f978c 740 PWM1 = omegaPID.compute();
shundai 2:50e50ee8e08a 741 PWM2 = 1.0f;
shundai 2:50e50ee8e08a 742 }
shundai 2:50e50ee8e08a 743
shundai 1:844acc585d3d 744 break;
shundai 1:844acc585d3d 745
shundai 1:844acc585d3d 746 case CURRENT_FEEDBACK:
shundai 1:844acc585d3d 747
shundai 4:40a764acc4ec 748 DBG("CURRENT_FEEDBACK UNSELECTABLE!! \r\n");
shundai 1:844acc585d3d 749
shundai 1:844acc585d3d 750 break;
shundai 1:844acc585d3d 751
shundai 1:844acc585d3d 752 default:
shundai 1:844acc585d3d 753
shundai 4:40a764acc4ec 754 DBG("Function:MotorDriver mode error! \r\n");
shundai 1:844acc585d3d 755
shundai 1:844acc585d3d 756 break;
shundai 1:844acc585d3d 757 }
shundai 1:844acc585d3d 758
shundai 1:844acc585d3d 759 //old_direction = direction;
shundai 5:1155a15f978c 760 //old_target = target;
shundai 5:1155a15f978c 761 }
shundai 5:1155a15f978c 762
shundai 5:1155a15f978c 763 void eraseFlash(uint32_t address)
shundai 5:1155a15f978c 764 {
shundai 5:1155a15f978c 765 FLASH_EraseInitTypeDef erase;
shundai 5:1155a15f978c 766 erase.TypeErase = FLASH_TYPEERASE_PAGES; /* ページの消去を選択 */
shundai 5:1155a15f978c 767 erase.PageAddress = address; /* ページの先頭アドレスを指定 */
shundai 5:1155a15f978c 768 erase.NbPages = 1; /* 消すページの数.今回は1つだけ */
shundai 5:1155a15f978c 769
shundai 5:1155a15f978c 770 uint32_t pageError = 0;
shundai 5:1155a15f978c 771
shundai 5:1155a15f978c 772 HAL_FLASHEx_Erase(&erase, &pageError); /* HAL_FLASHExの関数で消去 */
shundai 1:844acc585d3d 773 }
shundai 5:1155a15f978c 774
shundai 5:1155a15f978c 775 void writeFlash(uint32_t address, uint8_t *data, uint32_t size)
shundai 5:1155a15f978c 776 {
shundai 5:1155a15f978c 777 uint32_t *dataWord = (uint32_t*)data; /* 書き込むデータへのポインタ(4Byteごと) */
shundai 5:1155a15f978c 778 uint32_t sizeWord = (size+3)/4; /* データのサイズ(4Byteで1) */
shundai 5:1155a15f978c 779
shundai 5:1155a15f978c 780 HAL_FLASH_Unlock(); /* フラッシュをアンロック */
shundai 5:1155a15f978c 781 eraseFlash(address); /* 指定したアドレスのページを消去 */
shundai 5:1155a15f978c 782 do {
shundai 5:1155a15f978c 783 /* 4Byte(Word)ずつフラッシュに書き込む */
shundai 5:1155a15f978c 784 HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *dataWord);
shundai 5:1155a15f978c 785 } while (address+=4, ++dataWord, --sizeWord);
shundai 5:1155a15f978c 786 HAL_FLASH_Lock(); /* フラッシュをロック */
shundai 5:1155a15f978c 787 }
shundai 5:1155a15f978c 788
shundai 5:1155a15f978c 789 void loadFlash(uint32_t address, uint8_t *data, uint32_t size)
shundai 5:1155a15f978c 790 {
shundai 5:1155a15f978c 791 memcpy(data, (uint8_t*)address, size);
shundai 5:1155a15f978c 792 }