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.
Dependencies: mbed QEI MPU6050_2 BLE_API nRF51822 MCP4725 eMPL_MPU6050
Diff: main.cpp
- Revision:
- 13:41edfb8e3b3c
- Parent:
- 12:ba4ce3fa4f53
- Child:
- 14:fe003a27018d
--- a/main.cpp Thu May 28 16:39:03 2020 +0000
+++ b/main.cpp Thu May 28 18:14:34 2020 +0000
@@ -1,21 +1,48 @@
/*
Boulus Abu Joudom
- Version: May 21, 2020. 17:00
+ Cube Mini - Prototype 1 V1
+ Mbed Version: May 28, 2020. 18:00
ZHAW - IMS
- Cubiod (Cube Mini) Balancing Experiment - Control Lab
- Using Seeed Tiny Microcontroller
+ Cubiod Balancing Experiment - Control Lab
+ Template Version: 1.0
+ Seeed Tiny Microcontroller on Cuboid 1.0
+*/
+
+/*
+ Settings for Maxon ESCON controller (upload via ESCON Studio)
+ Escon Studio file Location: ...
+
+ Hardware Connections
+ Serial PC Communication
+ UART_TX p9
+ UART_RX p11
+ IMU SDA and SCL
+ MPU6050_SDA p12
+ MPU6050_SCL p13
+ Velocity Input as Analogue Signal from Escon
+ Pin 5
+ Current output to Escon occurs through I2C connection to a DAC (Digital to Analogue Converter). DAC outputs Analogue voltage to Escon
+ Pin SDA p3
+ Pin SCL P4
+
+ Notes
+ The Maximum output Current allowed is 13A and the Minimum is -13A !!!
+ All needed Libraries for the IMU (Accelerometer and Gyroscope), DAC are included.
+ The PID is to be written by students. Use PID_Cntrl.cpp and PID_Cntrl.h as templates
+ ...
+
+
*/
// Libraries
+#include <stdbool.h>
#include "mbed.h"
-#include "math.h"
-#include "MPU6050.h"
-#include "IIR_filter.h"
-#include "mcp4725.h"
-#include <stdbool.h>
-#include "LinearCharacteristics.h"
-#include "PID_Cntrl_Old.h"
-#include "PID_Cntrl_2.h"
+#include "MPU6050.h" // IMU Library
+#include "mcp4725.h" // DAC Library
+#include "IIR_filter.h" // Filter Library (Please go to the Filter Library and add in your Code)
+#include "LinearCharacteristics.h" // Linear Scaling Library
+#include "PID_Cntrl.h" // PID Library (Please go to PID Library and add in your PID Code)
+
// Serial PC Communication
#define UART_TX p9
@@ -29,121 +56,104 @@
#define PI 3.1415927f
#define pi 3.1415927f
-// PC Serial
-Serial pc(UART_TX, UART_RX);
+// PC Serial Connection
+Serial pc(UART_TX, UART_RX); // serial connection via USB - programmer
// -------------------------------
// Analog/Digitsl I/O Definitions
// -------------------------------
-AnalogIn Velocity_Voltage_Input(p5);
-DigitalOut Pin_3V3(p30);
+AnalogIn Velocity_Voltage_Input(p5); // Velocity Input as Analogue Signal from Escon
+DigitalOut Pin_3V3(p30); // Defining P30 as 3V3 Pin for internal use. Please do not modify.
-// ------------------------------------
-// USER INPUT ( Desired Values)
-// ------------------------------------
-// User Input
-float Desired_input = 0.0f;
-// Initial System input in Amperes
-float Sys_input_Amps = 0.0f;
-
-// ------------------------------------
-// Variables
-// ------------------------------------
+// -------------------------------
+// Initialization of Values and Variables
+// -------------------------------
// Sample time of main loops
-float Ts = 0.005;
+float Ts = 0.007; // Around 143 Hz. Do not change. THis is the lowest value possible if printing to a serial connection is needed.
// MPU 6050 Variables - Acceleration and Gyroscope Raw and Converted Data Variables
int16_t AccX_Raw, AccY_Raw, AccZ_Raw;
int16_t GyroX_Raw, GyroY_Raw, GyroZ_Raw;
-
double AccX_g, AccY_g, AccZ_g;
double GyroX_Degrees, GyroY_Degrees, GyroZ_Degrees, GyroZ_RadiansPerSecond;
-// ------------------------------------
-
-// Angle Variables
-double Cuboid_Angle_Radians, Cuboid_Angle_Degrees;
-double Cuboid_Angle_Speed_Degrees = 0.0;
-
-// Low pass filter variables
-float t = 0.5f;
-
// printf Variable
int k = 0;
-int Case1_Counter = 0;
+
+
+// -------------------------------
+// Variables: Here define variables such as gains etc.
+// -------------------------------
+
+
+// Accelerometer and Gyroscope
+
+
+// Cube Angle and Speed Variables
+
+
+// Low pass filter variables
+
// Flywheel Position and Velocity variables
-double Velocity_Input_Voltage = 0.0f;
-double Velocity, Velocity_Voltage, Velocity_rpm, Velocity_Voltage_Read;
+
-// --------------------------------------
-
-//----------------- Controller VARIABLES------------------
-// Variables concerning the Controller, the Design is in reference to the Matlab Simulink .............. and Variables are in reference to the ............. File
+// -------------------------------
+// Controller Variables: Such as SS Controller Values and Saturation Limits
+// -------------------------------
+// Variables concerning the Controller Design is in reference to the Matlab and Simulink Files ..............
// Sate Space Controller Values
-float K_SS_Controller [2] = {-57.1176*0.3, -2.6398}; // From Matlab
+
// Controller Variables
-float Loop1_output; // Loop 1 controller output
-float Loop2_output; // Loop 2 controller output
-float PID_Input, PID_Output;
+
+
+// PID (PI Parameters)
+
// Saturation Parameters
-// PI Controller Limits
-const float uMin1 = -5.0f;
-const float uMax1= 5.0f;
-// Cuboid Driver Input Limits
-const float uMin2 = -13.0f;
-const float uMax2= 13.0f;
-// Controller Loop 2 (PI-Part)
-float Kp_1 = -0.09;
-float Ki_1 = -0.09;
-float Kd_1 = 0; // No D-Part
-float Tf_1 = 1; // No D-Part
+// Cuboid Escon Input Limits in Amps
+const float uMin = -13.0f; // Minimum Current Allowed
+const float uMax = 13.0f; // Maximum Current Allowe
-// Controller Loop (PI-Part) in Case 2 (breaking case)
-float Kp_2 = 4;
-float Ki_2 = 80;
-float Kd_2 = 0; // No D-Part
-float Tf_2 = 1; // No D-Part
-// User Button
-int Button_Status = 0;
-
-// ---------- Functions -------------
+// -------------------------------
+// User-Defined Functions
+// -------------------------------
// Interrupts
Ticker ControllerLoopTimer; // Interrupt for control loop
-// DAC
+
+// -------------------------------
+// Functions
+// -------------------------------
+
+// DAC - For Current output
MCP4725 VoltageOut(p3, p4, MCP4725::Fast400kHz, 0);
// IMU - MPU6050 Functions and I2C Functions
I2C i2c(MPU6050_SDA, MPU6050_SCL);
MPU6050 mpu(i2c);
-// Accelerometer and Gyroscope Filters
-IIR_filter FilterAccX(t, Ts, 1.0f);
-IIR_filter FilterAccY(t, Ts, 1.0f);
-IIR_filter FilterGyro(t, Ts, t);
-
-// Linear Scaler
-LinearCharacteristics CurrentToVoltage(-15.0f, 15.0f, 0.0f, 5.0f);
-LinearCharacteristics VoltageToVelocity(0.0f, 3.0f, -4000.0f, 4000.0f);
-
-// PID Controllers
-PID_Cntrl_Old C1(Kp_1,Ki_1,Kd_1,Tf_1,Ts,uMin1,uMax1); // Defining the 1st Loop Controller (PI-Part)
-PID_Cntrl_Old C2(Kp_2,Ki_2,Kd_2,Tf_2,Ts,uMin1,uMax1); // Defining the PI Controller for Chase (State 2) to keep motor velocity at zero
-
// Timers
Timer Loop;
+// Accelerometer and Gyroscope Filters
+
+// PID (PI) Controller
+
+
// ----- User defined functions -----------
-void updateControllers(void); // speed controller loop (via interrupt)
+
+// Controller loop (via interrupt)
+void updateControllers(void);
+
+// Linear Scaler - Follow the mapping mentioned in the Notes above
//******************************************************************************
//---------- Main Loop -------------
@@ -151,121 +161,65 @@
int main()
{
// Microcontroller initialization
- pc.baud(115200);
- VoltageOut.write(CurrentToVoltage(0));
Pin_3V3.write(1);
*((unsigned int *)0x40007504) = 0x400A; // Configure the ADC to the internel reference of 1.2V.
- // IMU - MPU6050 initialization
+ // IMU - MPU6050 initialization - Do NOT Modify
mpu.initialize();
- mpu.setDLPFMode(MPU6050_DLPF_BW_20); // Sets Low Pass Filter Bandwidth to 21Hz (8.5ms) for the Acc and 20Hz (8.3ms) for the Gyroscope
+ mpu.setDLPFMode(MPU6050_DLPF_BW_42); // Set Low Pass Filter Bandwidth to 44Hz (4.9ms) for the Acc and 42Hz (4.8ms) for the Gyroscope
mpu.setFullScaleGyroRange(2u); // Change the scale of the Gyroscope to +/- 1000 degrees/sec
mpu.setFullScaleAccelRange(MPU6050_ACCEL_FS_4); // Change the scale of the Accelerometer to +/- 4g - Sensitivity: 4096 LSB/mg
+
+ // Serial Communication
+ pc.baud(115200);
+
+ VoltageOut.write(2.5); // Output Zero Current to the Motor
- // Reset Filters
- FilterAccX.reset(0.0f);
- FilterAccY.reset(0.0f);
- FilterGyro.reset(0.0f);
-
- // Reset PID
- C1.reset(0.0f);
+ // Reset Filters and PID Controller
// Control Loop Interrupt at Ts, 200Hz Rate
ControllerLoopTimer.attach(&updateControllers, Ts);
}
//******************************************************************************
-//---------- control loop (called via interrupt) -------------
+//---------- Control Loop (called via interrupt) -------------
//******************************************************************************
void updateControllers(void)
{
+
+ // Acquire Velocity
+ Velocity_Voltage = 3.0*1.1978917*(Velocity_Voltage_Input.read()); // *1.2V because the Vref is 1.2V // *3 because the prescaling is 1/3 // *1.1978917 is for Calibration purposes instead of 1.2
+ // Velocity = .... Refer to mapping
+
// Aquire Raw Acceleration and Gyro Data form the IMU
mpu.getMotion6(&AccX_Raw, &AccY_Raw, &AccZ_Raw, &GyroX_Raw, &GyroY_Raw, &GyroZ_Raw);
- // Acquire Velocity
- Velocity_Voltage_Read = Velocity_Voltage_Input.read();
- Velocity_Voltage = 3.0*1.1978917*(Velocity_Voltage_Read); // *1.2V because the Vref is 1.2V // *3 because the prescaling is 1/3 // *1.1978917 is for Calibration purposes instead of 1.2
- Velocity_rpm = VoltageToVelocity(Velocity_Voltage);
- Velocity = Velocity_rpm*2.0*pi/60.0;
-
// -------------- Convert Raw data to SI Units --------------------
//Convert Acceleration Raw Data to (ms^-2) - (Settings of +/- 4g)
- AccX_g = AccX_Raw / 8192.0f;
- AccY_g = AccY_Raw / 8192.0f;
- AccZ_g = AccZ_Raw / 8192.0f;
+ AccX_g = AccX_Raw / 8192.0f; AccY_g = AccY_Raw / 8192.0f; AccZ_g = AccZ_Raw / 8192.0f;
- //Convert Gyroscope Raw Data to Degrees per second
- GyroX_Degrees = GyroX_Raw / 32.768f; // (2^15/1000 = 32.768)
- GyroY_Degrees = GyroY_Raw / 32.768f; // (2^15/1000 = 32.768)
- GyroZ_Degrees = GyroZ_Raw / 32.768f; // (2^15/1000 = 32.768)
+ //Convert Gyroscope Raw Data to Degrees per second - (2^15/1000 = 32.768)
+ GyroX_Degrees = GyroX_Raw / 32.768f; GyroY_Degrees = GyroY_Raw / 32.768f; GyroZ_Degrees = GyroZ_Raw / 32.768f;
//Convert Gyroscope Raw Data to Degrees per second
GyroZ_RadiansPerSecond = (GyroZ_Raw / 32.768f)* pi/180.0f;
// ----- Combine Accelerometer Data and Gyro Data to Get Angle ------
- Cuboid_Angle_Radians = -1*atan2(-FilterAccX(AccX_g), FilterAccY(AccY_g)) + 0.7854f + FilterGyro(GyroZ_RadiansPerSecond); // Check later if fast enough!!
- Cuboid_Angle_Degrees = Cuboid_Angle_Radians*180.0f/pi;
+
// ------------------------- Controller -----------------------------
- switch(Button_Status) {
-
- case 0:
-
- // PI Controller
- PID_Input = Desired_input - Velocity;
- PID_Output = C1.update(PID_Input);
-
- // System input
- Sys_input_Amps = PID_Output;
- VoltageOut.write(CurrentToVoltage(Sys_input_Amps));
-
- // Counter of 10 seconds then go to Case 1
- Case1_Counter++;
- if (Case1_Counter > 2000) {
- Button_Status = 1;
- }
-
- case 1:
-
- // Current Input Updater - Amperes
- // Loop 1
- Loop1_output = Cuboid_Angle_Radians*K_SS_Controller[0];
- // Loop 2
- Loop2_output = GyroZ_RadiansPerSecond*K_SS_Controller[1];
- // PI Controller
- //PID_Input = Desired_input - Velocity;
- //PID_Output = C1.update(PID_Input);
-
- // Constant Speed Control
- //PID_Input = 52.36f - Velocity;
- //PID_Output = C1.update(-1*PID_Input);
-
- // System input
- Sys_input_Amps = 0.5f; //PID_Output; //- Loop1_output - Loop2_output;
- //VoltageOut.write(0.5f);
-
- if (Sys_input_Amps > uMax2) {
- Sys_input_Amps = uMax2;
- }
- if (Sys_input_Amps < uMin2) {
- Sys_input_Amps = uMin2;
- }
-
- // Scaling the controller output from -15 A --> 15 A to 0 V --> 5 V
- VoltageOut.write(CurrentToVoltage(Sys_input_Amps));
-
- }
+ // ......
// Print Data
- if(++k >= 10) {
+ if(++k >= 100) {
k = 0;
pc.printf("Some Outputs: %0.6f, %0.6f\n\r", Sys_input_Amps, Velocity);
}
- pc.printf("%0.6f, %0.6f\n\r", Sys_input_Amps, Velocity);
+
}