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
- Committer:
- kavhirow
- Date:
- 2018-06-19
- Revision:
- 1:fbed80ea9cf9
- Parent:
- 0:a3c0b8cd6c61
File content as of revision 1:fbed80ea9cf9:
#include "mbed.h"
// Sampling frequency
#define SAMP_FREQ 2000.0
// Motor voltage limit (V_motor = 3.3 * v_out * 4)
#define VLIMIT 0.1
// Motor offset voltage
#define VOFFSET 0.0
// Feedback gains (Arbitrary Unit)
#define KP 1.0
#define KD 0.04
#define KX -0.001
#define KV -0.0007
// Define LEDs
PwmOut led_blink(LED1); // Blink at 1 Hz during operation
PwmOut led_v_over(LED2); // Indicate voltage saturation
PwmOut led_v_forward(LED3); // Indicate voltage for forward motion
PwmOut led_v_backward(LED4); // Indicate voltage for backward motion
// Define motor controls
DigitalOut motor_f(p13); // Motor forward
DigitalOut motor_r(p14); // Motor backward
AnalogOut motor_v(p18); // Motor driving voltage
// Define Photo-diode readings for angle sensor
AnalogIn pd1(p19);
AnalogIn pd2(p20);
// Define Photo-diode readings for encoder
AnalogIn pd3(p15);
AnalogIn pd4(p16);
Serial pc(USBTX, USBRX); // Serial communication
Ticker t_int; // Interrupt ticker
float brightness = 0; // Brightness for blinking led_blink
float br_inc = 1.0/SAMP_FREQ; // For blinkng LED at 1 Hz
float angle, angle_prev = 0; // Angle and Previous angle (for calculating omega)
float v_out; // Output voltage
float v_dir; // Voltage polarity
float omega = 0; // Angluar velocity
float f_omega = 0; // Filtered angluar velocity
int value1 = 0;
int value2 = 0;
int value1_prev = 0;
int value2_prev = 0;
int count = 0;
int count_prev = 0;
float velocity = 0;
float velocity_prev = 0;
float velocity_prev_prev = 0;
float f_velocity = 0;
float f_velocity_prev = 0;
float f_velocity_prev_prev = 0;
float omega_prev = 0;
float f_omega_prev = 0;
float ref = 0;
// Interrupt handler (control loop)
void int0() {
// read difference of photo-diodes
angle = pd1 - pd2;
//binal
if (pd3 > 0.65) {
value1 = 1;
} else {
value1 = 0;
}
if (pd4 > 0.72) {
value2 = 1;
} else {
value2 = 0;
}
//keisoku
if(value1 != value1_prev){
//rising
if(value1 == 1){
if(value2 == 1){
count += 1;
} else {
count -= 1;
}
//falling
} else {
if(value2 ==1){
count -= 1;
} else {
count += 1;
}
}
}
if(value2 != value2_prev){
//rising
if(value2 == 1){
if(value1 == 1){
count -= 1;
} else {
count += 1;
}
//falling
} else {
if(value1 ==1){
count += 1;
} else {
count -= 1;
}
}
}
// calculate omega
omega = (angle - angle_prev) * SAMP_FREQ;
angle_prev = angle;
// filtering omega
f_omega = 0.0155*omega + 0.0155*omega_prev + 0.9691*f_omega_prev;
omega_prev = omega;
f_omega_prev = f_omega;
// calculate velocity
velocity = (count - count_prev) * SAMP_FREQ;
// filtering velocity
f_velocity = 0.0002414*velocity + 0.0004827*velocity_prev + 0.0002414*velocity_prev_prev + 1.9556*f_velocity_prev - 0.9565*f_velocity_prev_prev;
//update value
velocity_prev_prev = velocity_prev;
velocity_prev = velocity;
f_velocity_prev_prev = f_velocity_prev;
f_velocity_prev = f_velocity;
count_prev = count;
value1_prev = value1;
value2_prev = value2;
// output
v_out = angle * KP + f_omega * KD + (count - ref) * KX + f_velocity * KV;
ref += 40.0 / 2000.0;
//v_out = count * KX + f_velocity * KV;
//v_out = angle * KP + f_omega * KD ;
if (v_out > 0) {
motor_f = 1;
motor_r = 0;
v_dir = 1.0;
} else {
motor_f = 0;
motor_r = 1;
v_out *= -1.0;
v_dir = -1.0;
}
if (v_out > VLIMIT) {
v_out = VLIMIT;
led_v_over = 1;
} else {
led_v_over = 0;
}
// Motor output
if (pd1 < 0.02 && pd2 < 0.02) { // if not standing, stop the motor
motor_v = 0;
led_v_forward = 1;
led_v_backward = 1;
} else {
motor_v = v_out + VOFFSET;
led_v_forward = (v_dir > 0 ? v_out*3.3 : 0);
led_v_backward = (v_dir < 0 ? v_out*3.3 : 0);
}
// blink LED
brightness += br_inc;
if (brightness >= 1) brightness = 0;
led_blink = brightness;
// send 6 data to PC (data should be in [0,255]. Data must be casted into (char) type)
//pc.putc((char)(pd1 * 128 + 128));
//pc.putc((char)(pd2 * 128 + 128));
pc.putc((char)(f_velocity + 128));
pc.putc((char)(count + 128));
pc.putc((char)(velocity + 128));
//pc.putc((char)(angle * 128 + 128));
//pc.putc((char)(value1 * 128 + 100));
//pc.putc((char)(value2 * 128 + 120));
//pc.putc((char)(omega * 10 + 128));
//pc.putc((char)(f_omega * 10 + 128));
pc.putc((char)(count + 128));
pc.putc((char)(f_velocity + 128));
pc.putc((char)(v_out * 100 + 128));
}
// Main function is only for initialization
int main() {
// Initializing LED ports and Serial port
led_blink.period(1.0/SAMP_FREQ);
led_v_over.period(1.0/SAMP_FREQ);
led_v_forward.period(1.0/SAMP_FREQ);
led_v_backward.period(1.0/SAMP_FREQ);
pc.baud(230400);
// Wait for 1 second before starting feedback control
wait(1);
pc.printf("12345678"); // For initializing Processing plotter program
// Start Control (to be stopped with any data from serial port)
t_int.attach(&int0, 1.0/SAMP_FREQ); // Start timer-interrupt
while(1) {
if (pc.readable() == 1) { // If any data in serial prot
pc.putc(pc.getc()); // Echo back the data
t_int.detach(); // Stop timer-interrupt
break;
}
}
}