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.
Fork of mbed-os-example-mbed5-blinky by
main.cpp
- Committer:
- gunarthon
- Date:
- 2017-07-05
- Revision:
- 42:b69538bba4f9
- Parent:
- 41:3bc2a3885b9d
- Child:
- 43:5123f24e0b2c
File content as of revision 42:b69538bba4f9:
#include "mbed.h" #include "Queue.h" #include "TextLCD.h" #include "pid.h" #include <Serial.h> #include "EthernetInterface.h" //definitions typedef struct { double input; } message_t; bool useUDP = false; const int heightResolution = 1000; const int BAUDRATE = 115200; const char* host_address = "10.1.1.101"; const int host_port = 7; const int cameraFPS = 60; const int displayRefreshTime = 200; const double setPoint = 0.5; const double Kp = 0.02; const double Ki = 0; const double Kd = 0; const double configStep = 0.001; const double configFastStep = configStep*10; const int simulationSeconds = 10; enum {btnRIGHT, btnUP, btnDOWN, btnLEFT, btnSELECT, btnNONE, btnSIZE}; enum {menuSETPOINT, menuPID, menuSIMULATE, menuSIZE}; enum {parameterKP, parameterKI, parameterKD, parameterSIZE}; enum {simulSTEP, simulRAMP, simulNONE, simulSIZE}; //Pins PwmOut outPin(D3); //DigitalOut led2(LED2); DigitalOut led3(LED3); AnalogIn buttons(A0); //Threads Thread lcdThread; Thread pidThread; Thread serialThread; Thread hmiThread; Thread setPointThread; Thread udpThread; //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; //Menu settings int menu = menuSETPOINT; int parameter = parameterKP; int simul = simulNONE; bool setPointSimul = false; // Network interface EthernetInterface net; //=============================Thread Methodes================================== void setPointMethode(void) { while(1) //toggle every 20 seconds between 2 setPoint values { while(!setPointSimul) Thread::wait(2000); if(setPointSimul) { pidController->setSetPoint(0.2); Thread::wait(20000); if(setPointSimul) { pidController->setSetPoint(0.8); Thread::wait(20000); } } } } void LcdMethode(void) { while(true) { led3 = !led3; double lastPwm = pidController->getLastPwm(); double lastInput = pidController->getLastInput(); if(menu == menuSETPOINT) { 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*lastInput)); lcd.locate(12,1); lcd.printf("%d", int(1000*lastPwm)); } else if(menu == menuPID) { lcd.cls(); lcd.printf(" Kp Ki Kd"); lcd.locate(6*parameter, 0); lcd.printf("*"); lcd.locate(0,1); lcd.printf("%d", int(1000*pidController->getKp())); lcd.locate(6,1); lcd.printf("%d", int(1000*pidController->getKi())); lcd.locate(12,1); lcd.printf("%d", int(1000*pidController->getKd())); } else if(menu == menuSIMULATE) { lcd.cls(); if(simul == simulNONE) { if(setPointSimul) lcd.printf("u:STEP * d:RAMP"); else lcd.printf("u:STEP _ d:RAMP"); } else 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*lastInput)); lcd.locate(12,1); lcd.printf("%d", int(1000*lastPwm)); } Thread::wait(displayRefreshTime); } } //------------------------------------------------------------------------------ void PidMethode(void) { while(true) { osEvent ev = messageQueue.get(osWaitForever); if (ev.status == osEventMessage) { message_t *message = (message_t*)ev.value.p; double input = message->input; double newPwm = pidController->getPwm(input); outPin.write(newPwm); mpool.free(message); } } } //------------------------------------------------------------------------------ void SerialMethode(void) { Serial serial(USBTX, USBRX); serial.baud(BAUDRATE); serial.format(8, SerialBase::None, 1); double input = 0; while(true) { input = double(serial.getc()+(serial.getc()<<8)) / heightResolution; message_t *message = mpool.alloc(); message->input = input; messageQueue.put(message); } } //------------------------------------------------------------------------------ void UdpMethode(void) { UDPSocket socket(&net); socket.bind(host_port); SocketAddress socketAddress; socket.set_blocking(true); uint16_t packet = 0; double input = 0; while(true) { //socket.sendto(host_address, host_port, (const void*)input, sizeof(input)); //input += 1; socket.recvfrom(&socketAddress, &packet, sizeof(packet)); input = double(packet) / heightResolution; message_t *message = mpool.alloc(); message->input = input; messageQueue.put(message); Thread::wait(300); } } //------------------------------------------------------------------------------ unsigned readButtons() { 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; return button; } //------------------------------------------------------------------------------ //human-machine interface void hmiMethode(void) { unsigned button = btnNONE; bool fastChange = false; while(true) { button = readButtons(); while(button == btnNONE) { button = readButtons(); Thread::wait(10); fastChange = false; } double prevSetPoint = pidController->getSetPoint(); double newSetPoint = prevSetPoint; if(button == btnSELECT) { menu = (menu+1) % menuSIZE; simul = simulNONE; } else if(menu == menuSETPOINT) { if(button == btnUP) newSetPoint += fastChange ? configFastStep : configStep; else if(button == btnDOWN) newSetPoint -= fastChange ? configFastStep : configStep; else if(button == btnLEFT) newSetPoint -= fastChange ? 10*configFastStep : 10*configStep; else if(button == btnRIGHT) newSetPoint += fastChange ? 10*configFastStep : 10*configStep; pidController->setSetPoint(newSetPoint); } else if(menu == menuPID) { if(button == btnUP) { if(parameter == parameterKP) pidController->addKp(fastChange ? configFastStep : configStep); else if(parameter == parameterKI) pidController->addKi(fastChange ? configFastStep : configStep); else if(parameter == parameterKD) pidController->addKd(fastChange ? configFastStep : configStep); } else if(button == btnDOWN) { if(parameter == parameterKP) pidController->addKp(fastChange ? -configFastStep : -configStep); else if(parameter == parameterKI) pidController->addKi(fastChange ? -configFastStep : -configStep); else if(parameter == parameterKD) pidController->addKd(fastChange ? -configFastStep : -configStep); } else if(button == btnLEFT) parameter = (parameter+1) % parameterSIZE; else if(button == btnRIGHT) pidController->setParameters(Kp, Ki, Kd); } else if(menu == menuSIMULATE) { if(button == btnUP) //step { simul = simulSTEP; for(unsigned i = 0; i < cameraFPS * simulationSeconds; i++) { double input = i < cameraFPS * simulationSeconds / 2 ? 0 : 1; message_t *message = mpool.alloc(); message->input = input; messageQueue.put(message); Thread::wait(1000/cameraFPS); } simul = simulNONE; } else if(button == btnDOWN) //ramp { simul = simulRAMP; for(unsigned i = 0; i < cameraFPS * simulationSeconds; i++) { double input = double(i) / ((cameraFPS * simulationSeconds)-1); message_t *message = mpool.alloc(); message->input = input; messageQueue.put(message); Thread::wait(1000/cameraFPS); } simul = simulNONE; } else if(button == btnLEFT) setPointSimul = true; else if(button == btnRIGHT) setPointSimul = false; } unsigned repeatCount = 0; while(button != btnNONE && !fastChange) { repeatCount++; button = readButtons(); Thread::wait(10); if(repeatCount > 50) fastChange = true; } 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"); Thread::wait(2000); if(readButtons() == btnDOWN) useUDP = true; if(useUDP) { lcd.cls(); lcd.printf("Connecting..."); net.connect(); // Show the network address const char *ip = net.get_ip_address(); lcd.cls(); lcd.printf("%s", ip ? ip : "No IP"); if(!ip) while(1); //terminate program Thread::wait(5000); udpThread.start(UdpMethode); } else serialThread.start(SerialMethode); pidController = new Pid(Kp, Ki, Kd); pidController->setSetPoint(setPoint); lcdThread.start(LcdMethode); pidThread.start(PidMethode); hmiThread.start(hmiMethode); setPointThread.start(setPointMethode); while (true) { Thread::wait(1100); } } //==============================================================================