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
Fork of mbed-os-example-mbed5-blinky by
Revision 38:b760c09b311c, committed 2017-06-15
- 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
--- /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
