pid control android
Dependencies: QEI TextLCD mbed
Revision 0:5a12b85e8aa4, committed 2016-10-07
- Comitter:
- deiwidricaurte
- Date:
- Fri Oct 07 16:28:53 2016 +0000
- Commit message:
- control pid con encoder y arduino;
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DebouncedIn.cpp Fri Oct 07 16:28:53 2016 +0000
@@ -0,0 +1,93 @@
+#include "DebouncedIn.h"
+#include "mbed.h"
+
+/*
+ * Constructor
+ */
+DebouncedIn::DebouncedIn(PinName in)
+ : _in(in) {
+
+ // reset all the flags and counters
+ _samples = 0;
+ _output = 0;
+ _output_last = 0;
+ _rising_flag = 0;
+ _falling_flag = 0;
+ _state_counter = 0;
+
+ // Attach ticker
+ _ticker.attach(this, &DebouncedIn::_sample, 0.005);
+}
+
+void DebouncedIn::_sample() {
+
+ // take a sample
+ _samples = _samples >> 1; // shift left
+
+ if (_in) {
+ _samples |= 0x80;
+ }
+
+ // examine the sample window, look for steady state
+ if (_samples == 0x00) {
+ _output = 0;
+ }
+ else if (_samples == 0xFF) {
+ _output = 1;
+ }
+
+
+ // Rising edge detection
+ if ((_output == 1) && (_output_last == 0)) {
+ _rising_flag++;
+ _state_counter = 0;
+ }
+
+ // Falling edge detection
+ else if ((_output == 0) && (_output_last == 1)) {
+ _falling_flag++;
+ _state_counter = 0;
+ }
+
+ // steady state
+ else {
+ _state_counter++;
+ }
+
+ // update the output
+ _output_last = _output;
+
+}
+
+
+
+// return number of rising edges
+int DebouncedIn::rising(void) {
+ int return_value = _rising_flag;
+ _rising_flag = 0;
+ return(return_value);
+}
+
+// return number of falling edges
+int DebouncedIn::falling(void) {
+ int return_value = _falling_flag;
+ _falling_flag = 0;
+ return(return_value);
+}
+
+// return number of ticsk we've bene steady for
+int DebouncedIn::steady(void) {
+return(_state_counter);
+}
+
+// return the debounced status
+int DebouncedIn::read(void) {
+ return(_output);
+}
+
+// shorthand for read()
+DebouncedIn::operator int() {
+ return read();
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DebouncedIn.h Fri Oct 07 16:28:53 2016 +0000
@@ -0,0 +1,31 @@
+#include "mbed.h"
+
+ class DebouncedIn {
+ public:
+ DebouncedIn(PinName in);
+
+ int read (void);
+ operator int();
+
+ int rising(void);
+ int falling(void);
+ int steady(void);
+
+ private :
+ // objects
+ DigitalIn _in;
+ Ticker _ticker;
+
+ // function to take a sample, and update flags
+ void _sample(void);
+
+ // counters and flags
+ int _samples;
+ int _output;
+ int _output_last;
+ int _rising_flag;
+ int _falling_flag;
+ int _state_counter;
+
+ };
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QEI.lib Fri Oct 07 16:28:53 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/aberk/code/QEI/#5c2ad81551aa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Fri Oct 07 16:28:53 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/avallejopo/code/TextLCD/#aba8ab3dde9d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Fri Oct 07 16:28:53 2016 +0000
@@ -0,0 +1,502 @@
+#include "mbed.h"
+#include <stdio.h>
+#include "QEI.h"
+#include "TextLCD.h"
+#include "string.h"
+
+
+TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7
+QEI encoder (PTA13, PTD5, NC, 624);
+AnalogIn y(PTB3);//entrada analoga
+AnalogOut u(PTE30);//salida analoga OJO solo se le pueden drenar 1.5mA en circuitos use un Buffer
+
+Serial usart(PTE0,PTE1); //puertos del FRDM para el modem
+Serial pc(USBTX,USBRX); //puertos del PC
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+
+DigitalIn button3(PTC16);//cambia ingreso de los 4 parametros
+DigitalIn button4(PTC17);//termina y consolida valores de 4 parametros y sale del loop
+
+//codigos movimiento del curzor
+
+//int C1=0x0E; // solo muestra el curzor
+int C2=0x18; // desplaza izquierda
+int C3=0x1A; // desplaza derecha
+int C4=0x0C; // quito cursor bajo
+
+int C1=0x0F;
+float pid,o,ai,ad,ap,med,err;
+float err_v,med_v;
+int sp=0,ki=0,kp=0,kd=0;
+int j,k;
+char buffer[4];// TAMAÑO DEL BUFER
+Timer t; //VALOR DEL TIEMPO
+int count;
+int contador;
+int i = 0;
+int c=0;
+char cc;
+char caux[]="0000";
+int readBuffer(char *buffer,int count) //esta funcion lee un bufer de datos
+{
+ int ij=0;
+ t.start(); //CUENTA EL TIEMPO DE CONEXION E INICIA
+ while(1) {
+ while (usart.readable()) {
+ //char
+ cc = usart.getc();
+ if (cc == '\r' || cc == '\n') cc = '$';//si se envia fin de linea o de caracxter inserta $
+ buffer[ij++] = cc;//mete al bufer el caracter leido
+ if(ij > count)break;//sale del loop si ya detecto terminacion
+ }
+ if(ij > count)break;
+ if(t.read() > 1) { //MAS DE UN SEGUNDO DE ESPERA SE SALE Y REINICA EL RELOJ Y SE SALE
+ t.stop();
+ t.reset();
+ break;
+ }
+ }
+ return 0;
+}
+
+void cleanBuffer(char *buffer, int count) //esta funcion limpia el bufer
+{
+ for(int i=0; i < count; i++) {
+ buffer[i] = '\0';
+ }
+}
+void encoderdatos()
+{
+
+ int pos=1;
+ int cambio=0, diferencia=0;
+
+ while(1)
+ {
+
+ diferencia=encoder.getPulses()-cambio;
+ cambio=encoder.getPulses();
+ if (diferencia==0)
+ {
+ //nada
+ }
+ else if(diferencia>0)
+ {
+ if(pos==1)
+ {
+
+ if(sp+diferencia>=999)
+ {
+ sp=999;
+ lcd.locate(3,0);
+ lcd.printf(" ");
+ lcd.locate(3,0);
+ lcd.printf("%d", sp);
+ }
+ else
+ {
+ sp+=diferencia;
+ lcd.locate(3,0);
+ lcd.printf("%d", sp);
+
+
+ }
+ }
+ else if(pos==2)
+ {
+ if(kp+diferencia>=999)
+ {
+ kp=999;
+ lcd.locate(11,0);
+ lcd.printf(" ");
+ lcd.locate(11,0);
+ lcd.printf("%d", kp);
+ }
+ else
+ {
+ kp+=diferencia;
+ lcd.locate(11,0);
+ lcd.printf("%d", kp);
+ }
+ }
+ else if(pos==3)
+ {
+ if(ki+diferencia>=999)
+ {
+ ki=999;
+ lcd.locate(3,1);
+ lcd.printf(" ");
+ lcd.locate(3,1);
+ lcd.printf("%d", ki);
+ }
+ else
+ {
+ ki+=diferencia;
+ lcd.locate(3,1);
+ lcd.printf("%d", ki);
+ }
+ }
+ else if(pos==4)
+ {
+ if(kd+diferencia>=999)
+ {
+ kd=999;
+ lcd.locate(11,1);
+ lcd.printf(" ");
+ lcd.locate(11,1);
+ lcd.printf("%d", kd);
+ }
+ else
+ {
+ kd+=diferencia;
+ lcd.locate(11,1);
+ lcd.printf("%d", kd);
+ }
+ }
+ }
+ else if(diferencia<0)
+ {
+ if(pos==1)
+ {
+ if(sp+diferencia<0)
+ {
+ //No ocurre nada
+ }
+ else
+ {
+ sp+=diferencia;
+ lcd.locate(3,0);
+ lcd.printf(" ");
+ lcd.locate(3,0);
+ lcd.printf("%d", sp);
+ }
+ }
+ else if(pos==2)
+ {
+ if(kp+diferencia<0)
+ {
+ //No ocurre nada
+ }
+ else
+ {
+ kp+=diferencia;
+ lcd.locate(11,0);
+ lcd.printf(" ");
+ lcd.locate(11,0);
+ lcd.printf("%d", kp);
+ }
+ }
+ else if(pos==3)
+ {
+ if(ki+diferencia<0)
+ {
+ //No ocurre nada
+ }
+ else
+ {
+ ki+=diferencia;
+ lcd.locate(3,1);
+ lcd.printf(" ");
+ lcd.locate(3,1);
+ lcd.printf("%d", ki);
+ }
+ }
+ else if(pos==4)
+ {
+ if(kd+diferencia<0)
+ {
+ //No ocurre nada
+ }
+ else
+ {
+ kd+=diferencia;
+ lcd.locate(11,1);
+ lcd.printf(" ");
+ lcd.locate(11,1);
+ lcd.printf("%d", kd);
+ }
+ }
+ }
+ if (!button3) //cambia la posicion de ingreso de parametros
+ {
+ led3 =!led3;
+ if(pos==4)
+ {
+ pos=1;
+ lcd.locate(3,0);
+ lcd.printf("%d", sp);
+ }
+ else if (pos==1)
+ {
+ pos++;
+ lcd.locate(11,0);
+ lcd.printf("%d", kp);
+ }
+ else if(pos==2)
+ {
+ pos++;
+ lcd.locate(3,1);
+ lcd.printf("%d", ki);
+ }
+ else if(pos==3)
+ {
+ pos++;
+ lcd.locate(11,1);
+ lcd.printf("%d", kd);
+ }
+ wait(0.25);
+
+ }
+
+
+ if (!button4)
+ {
+ break; //sale del bucle si pisan suiche4
+ }
+
+ wait(0.01);
+ }
+ //return spnum,kinum,kpnum,kdnum;
+
+}
+
+int main()
+ {
+
+
+ lcd.locate(0,1);
+ lcd.printf("**Control PID**");
+ wait(2);
+ lcd.cls(); // Borrar Pantalla
+ lcd.writeCommand(C1);//escribimos un comando segun el manual del modulo LCD
+
+ lcd.locate(8,0);
+ lcd.printf("Kp=%d",kp);
+ lcd.locate(0,1);
+ lcd.printf("Ki=%d",ki);
+ lcd.locate(8,1);
+ lcd.printf("Kd=%d",kd);
+ lcd.locate(0,0);
+ lcd.printf("Sp=%d",sp);
+ wait(0.2);
+ encoderdatos();
+ wait(0.1);
+
+ usart.baud(9600); // asigno baudios y configuro puerto serie de la usart
+ usart.format(8,Serial::None,1);
+ //
+
+
+ //
+ //sp=valores[0];
+
+ wait(0.001);
+ if(sp<256)
+ {
+ usart.putc(sp);
+ usart.putc(0);
+
+ }
+ if(sp>255)
+ {
+ j=sp/256;
+ k=sp-j*256;
+ usart.putc(k);
+ usart.putc(j);
+
+ }
+ wait(0.001);
+ if(kp<256)
+ {
+ usart.putc(kp);
+ usart.putc(0);
+
+ }
+ if(kp>255)
+ {
+ j=kp/256;
+ k=kp-j*256;
+ usart.putc(k);
+ usart.putc(j);
+
+ }
+ wait(0.001);
+ if(ki<256)
+ {
+
+ usart.putc(ki);
+ usart.putc(0);
+
+ }
+ if(ki>255)
+ {
+ j=ki/256;
+ k=ki-j*256;
+ usart.putc(k);
+ usart.putc(j);
+
+ }
+ wait(0.001);
+ if(kd<256)
+ {
+ usart.putc(kd);
+ usart.putc(0);
+
+ }
+ if(sp>255)
+ {
+ j=kd/256;
+ k=kd-j*256;
+ usart.putc(k);
+ usart.putc(j);
+
+ }
+
+ //Transicion
+ lcd.writeCommand(C4);//escribimos un comando segun el manual del modulo LCD para quitar cursor bajo
+ lcd.cls(); //borra la pantalla
+ lcd.printf(" GUARDADOS!");
+ wait(1);
+ lcd.cls();
+ lcd.printf(" INICIA EL PID");
+ wait(1);
+ // se imprimen los parches del control *****************************************
+ lcd.cls();
+ lcd.printf("Er=%3.0f",err);
+ lcd.locate(8,0);
+ lcd.printf("Me=%3.0f",med);
+ lcd.locate(0,1);
+ lcd.printf("Sp=%3.0f",sp);
+ lcd.locate(8,1);
+ lcd.printf("Co=%3.0f",pid);
+ wait(1);
+
+ //ciclo control
+
+ while(1)
+ {
+ //
+ if (usart.readable())
+ {
+ cleanBuffer(buffer,4);
+ readBuffer(buffer,4);
+ pc.printf("buffer= %s\n\r ",buffer); //imprime el bufer
+
+ if ('h' == buffer[0])
+ {
+ lcd.cls();
+ lcd.locate(3,1);
+ lcd.printf("hola: %s",buffer);
+ wait(1);
+ lcd.cls();
+ //cleanBuffer(buffer,4);
+ //sp=88;
+ for(int ii=1; ii < 4; ii++){
+ caux[ii-1]=buffer[ii];
+
+ }
+ //sp=caux[2];
+
+ }
+ //sp=strtol(caux,null,2);
+
+ }
+
+
+ //
+ med = y.read()*999;
+ err = (sp-med); //se calcula el error
+ ap = kp*err*0.01f; //se calcula la accion proporcinal
+ ai =(ki*err*0.01f)+ai; //calculo de la integral del error
+ ad = kd*(err-err_v)*0.01f; //calculo de la accion derivativa
+ pid = (ap+ai+ad);
+ // se verifica que pid sea positivo **************************************
+ if(pid<=0)
+ {
+ pid=0;
+ }
+
+ // se verifica que pid sea menor o igual la valor maximo *****************
+ if (pid > 999)
+ {
+ pid=999;
+ }
+
+
+ //se muestran las variables******************************************
+ lcd.locate(3,0);
+ lcd.printf(" ");
+ lcd.locate(3,0);
+ lcd.printf("%3.0f",err);
+ lcd.locate(11,0);
+ lcd.printf(" ");
+ lcd.locate(11,0);
+ lcd.printf("%3.0f",med);
+ lcd.locate(3,1);
+ lcd.printf(" ");
+ lcd.locate(3,1);
+ lcd.printf("%d",sp);
+ lcd.locate(11,1);
+ lcd.printf(" ");
+ lcd.locate(11,1);
+ lcd.printf("%3.0f",pid);
+
+
+
+
+ //Normalizacion de la salida
+ // se actualizan las variables *******************************************
+ err_v = err;
+ if(err_v<0)
+ {
+ err_v=err_v*(-1);
+ }
+
+ if(err_v<256)
+ {
+ usart.putc(err_v);
+ usart.putc(0);
+
+ }
+
+ if(err_v>255)
+ {
+ j=err_v/256;
+ k=err_v-j*256;
+ usart.putc(k);
+ usart.putc(j);
+
+ }
+ //wait(0.1);
+
+ med_v = med;
+ //wait(0.1);
+ if(med_v<256)
+ {
+ usart.putc(med_v);
+ usart.putc(0);
+
+ }
+
+ if(med_v>255)
+ {
+ j=med_v/256;
+ k=med_v-j*256;
+ usart.putc(k);
+ usart.putc(j);
+
+ }
+ //GSM.putc(err_v);
+ o = pid/999;
+ u.write(o);
+ // se envia el valor pid a puerto analogico de salida (D/A) **************
+
+ // se repite el ciclo
+ wait_ms(300);
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Oct 07 16:28:53 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/abea610beb85 \ No newline at end of file