Arduino y Matlab V – Leer una IMU por Serial Posted on November on November 4, 2014 by 2014 by Tr4nsduc7or Tr4nsduc7or
¡Hola humanos! Continuando con nuestra nu estra sección de tutoriales de Matlab y Arduino, hoy voy a enseñaros cómo controlar un Servomotor con Matlab a través de Arduino. Si eres nuevo deberás coniurar "rimero tu Arduino "ara Arduino "ara #ue "ueda comunicarse con Matlab, y #ui$ás #uieras hacer el "rimer tutorial de e%em"lo, un sim"le &lin'.(o &lin'.(o coniurar tu Arduino es cómo ir a la uerra sin esco"eta. Hoy sim"lemente vamos a mover el servomotor de ) a *+) rados. Sé #ue no es el tutorial más emocionante #ue he "osteado, "ero si alun da hay una catástroe mundial aradecerás saber cómo coniurar los cierres automáticos d e tu reuio nuclear. &ien, el tutorial de hoy ho y va a ser muy sencillo, y sólo vamos a necesitar-
o
o
Placa Arduino. ste tutorial está testeado con Arduino UNO, Duemilanove y Nano Servomotor , a ser "osible #ue uncione con /0, as va a "oder ser alimentado a través de Arduino.
o
Cable 1recomiendo conectores Macho2Macho3
o
Cable US!
l es#uema a seuir será este.
•
"o#o 1"ositivo3 4 /0 Arduino
•
Ne$ro%Marr&n 1neativo3 4 5nd Arduino
•
Naran#a%Amarillo%!lanco 1datos3 4 6in 7iital 8 Arduino
9na ve$ cableado, conectamo el US! con el ordenador . Si estamos en :inu;, "robablemente tenemo 'ue crear de nuevo el enlace imb&lico del "uerto 9S& de Arduino a través de la
9na ve$ creado, abrimos Matlab. Como siem"re, em"e$amos creando la clae (arduino) "ara "oder enviarle instrucciones a nuestra "laca. arduino = arduino('/dev/ttyS101') 9na ve$ conectado, etableceremo el Pin n*mero + como alida de dato para ervomotor . 6ara ello, utili$aremos un comando "ro"io de la librera Servo.h , la cual ya viene citada "or deecto en el s'etch #ue le caramos a Arduino.
1
arduino.servoAttach(3) 6ara cambiar la "osición de nuestro servomotor escribimos-
1
arduino.servoWrite(3, 30) l "rimer valor es el "in del servomotor #ue #ueremos mover. l seundo valor es la "osición, y accepta entero de , a -,. (ada de decimales.
1
Ahora vamos a crear un sim"le bucle "ara mover el servomotor de ) a *+) rados y al revés. =ecuerda #ue "uedes "arar el "rorama con Ctrl>C en cual#uier momento, aun#ue si #uieres "uedes es"erar a #ue el "rorama termine. so s, es"era sentado #ue hay "ara rato?
1 2 3 4
x = 0; %vara!e "ara a!#acenar "osiciones #ax = $a!se; %varia!e oo!eana "ara decidir si hay ue su#ar o restar "osicione &hi!e true %esto va a au#entar considera!e#ente !a duracion de nuestro "rora#a. arduino.servoWrite(3,x) i$ #ax
5 6 7 8 9 10 11 12 13 14 15 16
x = x1 e!se x = x1 end i$ x == 1*0 #ax = true e!sei$ x == 0 #ax = $a!se end "ause(0.003) end
@ con esto ya sabemos cómo coniurar nuestro servomotor y controlarlo a través de Matlab. Sencillo, verdadB n el "ró;imo tutorial intentaremos enviar datos desde Arduino a Matlab. Hasta entonces, "uedes intentar crear un "rorama tal #ue entrando una unción cual#uiera en Matlab 1"or e%em"lo, y ;DE>/3, el servomotor cambie de "osición en unción del valor de las y. @ debe uncionar con cual#uier ti"o de unción, incluso si tiene valores neativos o el valor de las y va más allá de *+) 1recuerda #ue el comando servoFrite sólo acce"ta valores enteros de ) a *+)3.
Placa Arduino, "or ra$ones obvias. Como siem"re voy a utili$ar mi Arduino 9(P
•
r8. •
Ordenador con Matlab intalado. @o utili$o :inu;, as #ue los comandos de la
•
!ot&n%pulador.
•
"eitencia de -/,0 o un valor seme%ante. Sin ella, es "osible #ue haya intererencias en la lectura de los "ines.
•
Conductor el1ctrico, recomiendo #ue tena conectores MIM.
•
Protoboard. s o"cional, "ero te acilitará mucho la vida al montar el circuito.
•
Cable US! de impreora.
•
Diodo L2D. s o"cional, "uesto #ue se "uede utili$ar el #ue lleva incor"orado Arduino en el "in *8.
•
Potenci&metro, uno de *QR debera bastar
9na ve$ hayas sa#ueado tu ca%a de com"onentes "ara encontrar todo el material, deberás em"e$ar "or crear una ve3 m4 el enlace imb&lico para el puerto US!. n tutoriales anteriores se e;"lica con detalle "or#ué es necesario.
Ahora abrimos Matlab y escribimosarduino = arduino('/dev/ttyS101') Con esto ya estamos "re"arados "ara em"e$ar.
1
Pine Di$itale n "rimer luar vamos a a"render a leer pine di$itale. m"e$amos montando ete circuito-
9na ve$ construido, "roseuimos a abrir Matlab. Habrá #ue etablecer el pin di$ital como entrada y el -+ como alida .
1 2
arduino."in+ode(*, 'in"ut') arduino."in+ode(13, 'out"ut')
Ahora escribiremos un "e#ueño códio #ue encender4 el L2D i el uuario pula el bot&n. Se trata de un bucle ininito, recordemos #ue con Ctrl>C "odemos detener el "roceso.
1 2 3 4 5 6
&hi!e true &hi!e a.diita!ead(*) == 1 a.diita!Write(13,1) end a.diita!Write(13,0) end
%0- W 1- 2
5ambi1n podemo ai$nar la entrada a variable. 0oy a "ro"oner dos códios- en el "rimero, el valor del "in diital se uarda en la variable ;, y a su ve$ el :7 coe el valor de la variable. n el seundo códio, cada ve$ #ue se "ulsa el botón, se suma * a la variable ;, y al llear a 8 enciende el :7.
1 2 3 4 1 2 3 4 5 6 7 8 9 10 11
&hi!e true x = a.diita!ead(*) a.diita!Write(13,x) end a.diita!Write(13,0) x = 0 &hi!e true i$ a.diita!ead(*) == 1 x = x1 "ause(1) end i$ x - a.diita!Write(13,1) end end
Pine anal&$ico :a lectura de los "ines analóicos es muy similar a la de los diitales, "ero con la dierencia de #ue no hay #ue declararlos como entradas o salidas. 0amos a montar ete circuito con el potenci&metro-
0amos a recrear el e%em"lo t"ico del comando analo$"ead de Arduino. Sim"lemente vamos a leer el valor del "otenciómetro 1#ue se encuentra entre ) y *)E83 y vamos a encender y a a"aar el :7 en intervalos de tiem"o #ue variarán en unción de la entrada analóica.
1 2 3 4 5 6 7 8 9
a.diita!Write(13,0) &hi!e true x = a.ana!oead() a.diita!Write(13,1) "ause(x/1000) %Si no dividi#os, vas a tener ue es"erarte 1000 seundos... x = a.ana!oead() a.diita!Write(13,0) "ause(x/1000) end
Con esto deberas ver #ue el :7 se a"aa y se enciende constantemente, y "uedes cambiar la velocidad irando el "otenciómetro. Si te surió alOn "roblema, "uedes comentar aba%o y te res"onderé en breves ciclos. Asimismo, si te ustó mi manico y elocuente tutorial también "uedes dar tu o"inión. @ no dudes en Suscribirte yIo darle Me 5ustaT a nuestra recién creada "áina de Kaceboo'. :os editores de =obolos te? #uerremos mucho? incluso yo. 9n "oco.
&uenos das, lectores humanos. Al habla
9na "laca Arduino, cual#uier modelo vale. 0oy a utili$ar una 9(P
•
Cable 9S& de im"resora
•
Prdenador con Matlab instalado y uncionando
l códio de Arduino es básico.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
int i = 0; int 4 = 1; void setu"() 5 Seria!.ein(6700); 8 void !oo"() 5 Seria!."rint!n(i); Seria!."rint!n(4); i; i$(i - 30) 5 i = 0; 8 8
9na ve$ el códio está carado en Arduino, hay #ue abrir Matlab. :o "rimero será decirle al pro$rama cu4l e el puerto de Arduino mediante el comando-
1
arduino = seria!('/dev/tty9S:0')
Sutituyendo %dev%ttyUS!, por la direcci&n de tu placa, como "or e%em"lo IdevIttyACM) o CPMG si estás en FindoJs. Si tienes dudas mira en la 7 de Arduino en el menO Herramientas2U6uerto de Série. Ahora hay #ue abrir el Serial para empe3ar a leerlo. 6ara ello tendrás #ue utili$ar el comando o"en1arduino3.
1
1 2 3 4
$or c= 1100 x(c) = $scan$(arduino, '%d') y(c) = $scan$(arduino, '%d') end
:a instrucción scan sirve "ara leer un ichero, en este caso el "uerto Serial. =ecibe dos "arámetros- el primero e el arc8ivo #ue debe leer 1en este caso el "uerto Serial3. 2l e$undo e el :ormato- VWdX siniica #ue debe leer un entero. Ahora hay #ue motrar lo valore de ;< y en un ráico mOlti"le. Con el comando iure se crea un $r4:ico m*ltiple, y con sub"lot se es"eciica cuántas ráicas van a caber. Mostramos ;, y y los titulamos.
1
$iure su"!ot(,1,1)
2 3 4 5 6 7
"!ot(x) tit!e('
@ el resultado será un ráico "arecido a éste, en el #ue se muestra el recorrido de la variable k e i .
@ es as de sencillo. A "artir de este e%em"lo "uedes leer y "rocesar con Matlab "rácticamente cual#uier lectura "roviniente de Arduino u otro sensorImicrocontrolador #ue tena cone;ión "or Serial. Kinal de lnea.
&uenos das, lectores humanos. Al habla
9na "laca Arduino, cual#uier modelo vale. 0oy a utili$ar una 9(P
•
Cable 9S& de im"resora
•
Prdenador con Matlab instalado y uncionando
l códio de Arduino es básico.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
int i = 0; int 4 = 1; void setu"() 5 Seria!.ein(6700); 8 void !oo"() 5 Seria!."rint!n(i); Seria!."rint!n(4); i; i$(i - 30) 5 i = 0; 8 8
9na ve$ el códio está carado en Arduino, hay #ue abrir Matlab. :o "rimero será decirle al pro$rama cu4l e el puerto de Arduino mediante el comando-
1
arduino = seria!('/dev/tty9S:0')
Sutituyendo %dev%ttyUS!, por la direcci&n de tu placa, como "or e%em"lo IdevIttyACM) o CPMG si estás en FindoJs. Si tienes dudas mira en la 7 de Arduino en el menO Herramientas2U6uerto de Série. Ahora hay #ue abrir el Serial para empe3ar a leerlo. 6ara ello tendrás #ue utili$ar el comando o"en1arduino3.
1
1 2 3 4
$or c= 1100 x(c) = $scan$(arduino, '%d') y(c) = $scan$(arduino, '%d') end
:a instrucción scan sirve "ara leer un ichero, en este caso el "uerto Serial. =ecibe dos "arámetros- el primero e el arc8ivo #ue debe leer 1en este caso el "uerto Serial3. 2l e$undo e el :ormato- VWdX siniica #ue debe leer un entero. Ahora hay #ue motrar lo valore de ;< y en un ráico mOlti"le. Con el comando iure se crea un $r4:ico m*ltiple, y con sub"lot se es"eciica cuántas ráicas van a caber. Mostramos ;, y y los titulamos.
1 2 3 4 5 6 7
$iure su"!ot(,1,1) "!ot(x) tit!e('
@ el resultado será un ráico "arecido a éste, en el #ue se muestra el recorrido de la variable k e i .
@ es as de sencillo. A "artir de este e%em"lo "uedes leer y "rocesar con Matlab "rácticamente cual#uier lectura "roviniente de Arduino u otro sensorImicrocontrolador #ue tena cone;ión "or Serial.
Saludos, humano. Al habla
El cubo. También conocido por: hexaedro, hexaedro regular, dado, bloque… Antes de seuir éste tutorial, deber7a mirarte Arduino y Matlab 0 4 :eer Comandos "or Serial, "ara entender cómo enviar comandos "or Serial a Matlab.
Material neceario •
Arduino. sta ve$ utili$o la versión (ano, "ero cual#uiera vale.
•
MPU=>,/, conectada a Arduino. nsisto, si no sabes cómo unciona y no #uieres undirla echa un vista$o a mi tutorial.
•
Ordenador con Matlab instalado
•
Cable US! de ti"o im"resora
2l c&di$o para Arduino l códio "ara Arduino será una variante del 'ue ecriv7 para el tutorial del MPU=>,/, . Sim"lemente he cambiado la lnea #ue enva "or Serial los out"uts, a in de #ue sea más ácil traba%ar con los valores en Matlab-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
inc!ude >Wire.h//?ireccion @ de !a +9 de$ine +9 0x7* //atios de conversion de$ine AB 173*C.0 de$ine 2B 131.0 //@onversion de radianes a rados 1*0/ de$ine A?BAB?D2 = EF.6EFF6 //+970E0 da !os va!ores en enteros de 17 its //>*NWire.read(); //@ada va!or ocu"a reistros AcH=Wire.read()>>*NWire.read(); AcI=Wire.read()>>*NWire.read();
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
//Se ca!cu!an !os anu!os H, G res"ectiva#ente. AccJ1K = atan(1O(AcG/AB)/srt("o&((AcH/AB),) "o&((AcI/AB),)))OA?BL AccJ0K = atan((AcH/AB)/srt("o&((AcG/AB),) "o&((AcI/AB),)))OA?BLB?D //eer !os va!ores de! 2irosco"io Wire.einLrans#ission(+9); Wire.&rite(0xC3); Wire.endLrans#ission($a!se); Wire.reuestMro#(+9,C,true); //A di$erencia de! Ace!ero#etro, so!o se "iden 2yG=Wire.read()>>*NWire.read(); 2yH=Wire.read()>>*NWire.read(); //@a!cu!o de! anu!o de! 2irosco"io 2yJ0K = 2yG/2B; 2yJ1K = 2yH/2B; //Seria!."rint(2yJ0K); Seria!."rint(PNNP); Seria!."rint(2yJ1K); Seria!." //A"!icar e! Mi!tro @o#"!e#entario An!eJ0K = 0.6* O(An!eJ0K2yJ0KO0.010) 0.0OAccJ0K; An!eJ1K = 0.6* O(An!eJ1K2yJ1KO0.010) 0.0OAccJ1K; //+ostrar !os va!ores "or conso!a //Seria!."rint(PAn!e G P); Seria!."rint(An!eJ0K); Seria!."rint(PnP); //Seria!."rint(PAn!e H P); Seria!."rint(An!eJ1K); Seria!."rint(Pn Seria!."rint!n(An!eJ0K); Seria!."rint!n(An!eJ1K); de!ay(10); //Questra dt sera, "ues, 0.010, ue es e! interva!o de tie#"o en 8
Compila y car$a el pro$rama. 9na ve$ hecho, es hora de abrir Matlab.
Crear una :unci&n6 plotCube?@ n ve$ de escribir un "rorama "ara visuali$ar cómo cambian los nOmeros #ue enva Arduino "or Serial, hoy me siento ins"irado "ara hacer alo me%or. l siuiente "aso será crear una unción #ue dibu#e un cubo y lo vaya rotando a medida #ue cambie el ánulo de la M9. @ la unción se llamará plotCube?@. Si tienes alo de e;"eriencia en Matlab, sabrás #ue no e poible declarar la :uncione en la Ventana de Comando. 7eben escribirse en el 2ditor de uncione. Hay #ue "ulsar NeB = unction , y a"arecerá otra ventana similar a un editor de te;to dónde "roramar la unción.
plotCube?@ recibir4 do par4metro llamados roll y pitc8, #ue van a corres"onderse a los ánulos Z e @ res"ectivamente. :a unción también dibu#ar4 un cubo y lo "intará de color ro%o. 7es"ués lo $irar4 en :unci&n de lo par4metro de entrada.
m"e$amos "or iniciali$ar la unción y sus arumentos-
1
$unction "!ot@ue(ro!!, "itch)
Para crear el cubo e neceitan do array. l "rimero, llamado verte;[matri;, almacena las coordenada EF de todo lo v1rtice del cubo, mientras #ue aces[matri; almacenará las cara. stos dos arrays son de manual.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vertexB#atrix = J0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1K0.E; $acesB#atrix = J1 7 E 3 F 7 3 C * F C 1 E * 1 3 C E 7 F *K;
l siuiente "aso es motrar el cubo en pantalla.
1 2 3
axis(J1 1 1 1 1 1K); axis eua! o$$; cue = "atch('
:os "arámetros de a;i sirven "ara establecer cómo va a mostrarse el cubo. :a listaaxis([-1 1 -1 1 -1 1]);
Sirve "ara limitar el valor m4;imo y m7nimo de lo e#e Z, @, \. Sin ella, "odra haber "artes del cubo #ue #uedaran uera de la cámara. n cuánto a los "arámetros axis eual o!;
e'ual sirve "ara evitar 'ue Matlab de:orme la ima$en "ara a%ustarla a la ventana. o:: sirve "ara econder la re#illa con las medidas de los e%es. 6or Oltimo, el comando patc8 creará una :i$ura +d llamada cube a "artir del verte;[matri;, el aces[matri; y de color ro%o. Ahora rotamos a cube-
1 2 3 4 5
rotate(cue, J1,0,0K, ro!!); rotate(cue,J0,1,0K, "itch); vie&(0,0); end
:a instrucción rotate recibe tre par4metro. l "rimero es el ob#eto 'ue debe rotare, en este caso cube. l seundo es la direcci&n de rotaci&n G;
vieB?@ recibe dos "arámetros, a$imuth y elevación. vieJ1),)3 coloca la cámara totalmente 8ori3ontal. @ lóicamente #ueremos la cámara hori$ontal "ara no distorsionar la "ers"ectiva. @ end cerrará la unción. l códio com"leto será-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
$unction "!ot@ue(ro!!, "itch) vertexB#atrix = J0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1K0.E; $acesB#atrix = J1 7 E 3 F 7 3 C * F C 1 E * 1 3 C E 7 F *K; su"!ot(1,3,1) axis(J1 1 1 1 1 1K); axis eua! o$$; cue = "atch('
uarda eta :unci&n en el directorio bin de Matlab y sal del editor. AC5UALIFACIJN6 =ecordaos de uardar la unción con el nombre plotCube.m . 7e lo contrario habrá "roblemas.
Intruccione para la Ventana de Comando6 n la Command KindoB hay #ue crear un bucle in:inito #ue vaya leyendo y mostrando las lecturas de la M9. M6P=C. Si no, vas a tener cubo "ara rato.
1 2 3 4 5 6 7 8
arduino = seria!('/dev/tty9S:0') $o"en(arduino) &hi!e 1 x = $scan$(arduino, '%e') y = $scan$(arduino, '%e') "!ot@ue(x, y) dra&no&
9 10 11
c!$ end
(o debera tener mucho secreto. while 1 es un bucle ininito, fscanf lee un ichero, en éste caso arduino, y la notación e siniica #ue debe leer un :loat .
plotCube?;
cl: borra el dibu#o a cada iteraci&n.Sin el comando de borrar, a cada iteración Matlab dibu#ar7a un nuevo cubo encima del anterior. Si ahora "ulsas enter, verás #ue aparece una pantalla con un cubo ro#i3o en el centro. Si mueves la M9, el cubo irará, "ero &lo en lo e#e < E. =ecuerda #ue desactivamos la rotación del e%e \ 1llamada yaJ3 en el tutorial del M692Y)/).
E a8ora 'u1 (5ranductorQ RSe mueve< pero va con retrao). s normal. n un "rimer momento, el movimiento va con alo de retraso. s"era un momento y si no unciona, vuelve a iniciar el bucle.
(5ranductorQ R2to no e mueve) . (o es normal. l códio #ue he "ublicado a#u es e;actamente el #ue yo he utili$ado. =evisa tu "rorama, lnea " or lnea.
(5ranductorQ me $ira< RPero va al rev1) s "osible #ue te el cubo te ire bien, "ero al revés de como debera. Si es tu caso, abre el editor de unciones y cambia el sino de las variables roll eIo yaJ.
(5ranductorQ Ser7a poible crear otro do cubo< uno para la lectura del aceler&metro y otro para la del $irocopio) n eecto. :a idea es la misma. 7eberás crear dos cubos más en la unción, llamados cubeE y cube8. 7eberás utili$ar el comando sub"lot13 "ara mostrar los tres cubos en un solo ráico. Además necesitarás más arumentos, dos "ara el acelerómetro y dos "ara el irosco"io. s decir-
1 2 3 4 5 6 7
su"!ot(1,3,x) axis(J1 1 1 1 1 1K); axis eua! o$$; cueG = "atch('
Sustituyendo la ; de sub"lot13 "or el nOmero de cubo, y cubeZ "or cubeE o cube8. arumento[; y arumento[y serán los arumentos ;, y del irosco"ioIacelerómetro.
(5ranductorQ puedo ecribir mi duda en lo comentario) ¡6or upueto, lector! @o o aluno de mis com"añeros te res"onderemos lo más rá"ido "osible. Kinal de lnea.