Receives a measured height of a ping-pong ball from a PC, and uses it to control the PWM of a fan to keep the height as set with the keypad. Information is shown on the LCD

Dependencies:   TextLCD

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

Files at this revision

API Documentation at this revision

Comitter:
gunarthon
Date:
Thu Jun 15 23:19:38 2017 +0000
Parent:
37:8f3f0b8835f8
Child:
39:e4f5710b2f31
Commit message:
initial commit

Changed in this revision

TextLCD.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
pid.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD.lib	Thu Jun 15 23:19:38 2017 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/simon/code/TextLCD/#308d188a2d3a
--- a/main.cpp	Thu Jun 08 11:15:02 2017 +0100
+++ b/main.cpp	Thu Jun 15 23:19:38 2017 +0000
@@ -1,12 +1,162 @@
 #include "mbed.h"
+#include "Queue.h"
+#include "TextLCD.h"
+#include "pid.h"
 
-DigitalOut led1(LED1);
+//definitions
+typedef struct {
+    uint32_t input;
+} message_t;
+
+const int heightResolution = 1024;
+const double setPoint = 0.5;
+const double Kp = 1;
+const double Ki = 0.2;
+const double Kd = 0.3;
+
+enum {btnRIGHT, btnUP, btnDOWN, btnLEFT, btnSELECT, btnNONE};
 
-// main() runs in its own thread in the OS
-int main() {
-    while (true) {
-        led1 = !led1;
-        wait(0.5);
+//Pins
+PwmOut          outPin(D3);
+DigitalOut      led2(LED2);
+DigitalOut      led3(LED3);
+AnalogIn        buttons(A0);
+
+//Threads
+Thread blueThread;
+Thread pidThread;
+Thread communicationThread;
+Thread hmiThread;
+
+//Global variables
+TextLCD lcd(D8, D9, D4, D5, D6, D7); // rs, e, d4-d7
+Pid* pidController;
+MemoryPool<message_t, 16> mpool;
+Queue<message_t,16> messageQueue;
+
+//=============================Thread Methodes==================================
+
+void BlueMethode(void)
+{
+    while(true)
+    {
+        led3 = !led3;
+        Thread::wait(500);
     }
 }
 
+//------------------------------------------------------------------------------
+
+void PidMethode(void)
+{
+    while(true)
+    {
+        osEvent ev = messageQueue.get(osWaitForever); 
+        if (ev.status == osEventMessage)
+        {
+            message_t *message = (message_t*)ev.value.p;
+            
+            double input = double(message->input) / heightResolution;
+            
+            double newPwm = pidController->getPwm(input);
+            
+            outPin.write(newPwm);
+            
+            mpool.free(message);
+            
+            lcd.cls();
+            lcd.printf("set   in    out");
+            lcd.locate(0,1);
+            lcd.printf("%d", int(1000*pidController->getSetPoint()));
+            lcd.locate(6,1);
+            lcd.printf("%d", int(1000*input));
+            lcd.locate(12,1);
+            lcd.printf("%d", int(1000*newPwm));
+        }
+    }   
+}
+//------------------------------------------------------------------------------
+
+void CommunicationMethode(void)
+{
+    uint32_t input = 0;
+    while(true)
+    {
+        input = input>=1000 ? 0 : input+1;
+        message_t *message = mpool.alloc();
+        message->input = input;
+        messageQueue.put(message);
+        Thread::wait(100);
+    }   
+}
+
+//------------------------------------------------------------------------------
+//human-machine interface
+void hmiMethode(void)
+{
+    while(true)
+    {
+        double buttonsValue = buttons.read();
+        
+        unsigned button = btnNONE;
+        if(buttonsValue < 0.08) //0.000
+            button = btnRIGHT;
+        else if(buttonsValue < 0.28) //0.170
+            button = btnUP;
+        else if(buttonsValue < 0.51) //0.397
+            button = btnDOWN;
+        else if(buttonsValue < 0.78) //0.621
+            button = btnLEFT;
+        else if(buttonsValue < 0.97) //0.936
+            button = btnSELECT;
+        else                         //1.000
+            button = btnNONE;
+            
+        
+        double prevSetPoint = pidController->getSetPoint();
+        double newSetPoint = prevSetPoint;
+        if(button == btnUP)
+            newSetPoint += 0.001;
+        else if(button == btnDOWN)
+            newSetPoint -= 0.001;
+        else if(button == btnLEFT)
+            newSetPoint -= 0.01;
+        else if(button == btnRIGHT)
+            newSetPoint += 0.01;
+        else if(button == btnSELECT)
+            newSetPoint = 0.5;
+            
+        pidController->setSetPoint(newSetPoint);
+        
+        Thread::wait(100);
+    }   
+}
+
+//=============================Main Thread======================================
+// main() runs in its own thread in the OS
+
+int main() {
+    
+    //led1.period(4.0f);      // 4 second period
+    
+    lcd.cls();
+    lcd.printf("HELLO");
+    
+    pidController = new Pid(Kp, Ki, Kd);
+    pidController->setSetPoint(setPoint);
+    
+    blueThread.start(BlueMethode);
+    pidThread.start(PidMethode);
+    communicationThread.start(CommunicationMethode);
+    hmiThread.start(hmiMethode);
+    
+    while (true) {
+        led2 = !led2;
+        Thread::wait(1100);
+    }
+}
+
+//==============================================================================
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pid.h	Thu Jun 15 23:19:38 2017 +0000
@@ -0,0 +1,72 @@
+#ifndef _PID_H_
+#define _PID_H_
+
+//http://coder-tronics.com/pid-tutorial-c-code-example-pt2/
+
+class Pid
+{
+    private:
+        double setPoint;
+        double Kp, Ki, Kd;
+        
+        double integrator, derivator;
+        double maxInteg, minInteg;
+        double maxPwm, minPwm;
+        
+    public:
+        Pid(double Kp, double Ki, double Kd)
+        {
+            this->Kp = Kp;
+            this->Ki = Ki;
+            this->Kd = Kd;
+            
+            integrator = 0;
+            derivator = 0;
+            
+            maxInteg = 3;
+            minInteg = -3;
+            
+            maxPwm = 1;
+            minPwm = 0.05;
+        }
+        
+        //desired value
+        void setSetPoint(double setPoint)
+        {
+            this->setPoint = setPoint;
+        }
+        double getSetPoint()
+        {
+            return setPoint;
+        }
+        
+        //values from 0-1
+        double getPwm(double input)
+        {
+            double errorValue = setPoint - input;
+            
+            //P term
+            double P = Kp * errorValue;
+            
+            //I term
+            integrator += errorValue;
+            
+            integrator = integrator>maxInteg? maxInteg : integrator;
+            integrator = integrator<minInteg? minInteg : integrator;
+            
+            double I = Ki * integrator;
+            
+            //D term
+            double D = Kd * (derivator - errorValue);
+            derivator = errorValue;
+            
+            //output
+            double pwm = P + I + D;
+            pwm = pwm>maxPwm? maxPwm : pwm;
+            pwm = pwm<minPwm? minPwm : pwm;
+            
+            return pwm;
+        }
+       
+};
+#endif
\ No newline at end of file