Cube_Mini_Solution

Dependencies:   mbed QEI MPU6050 BLE_API nRF51822 MCP4725 eMPL_MPU6050

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);
+
 }