diff --git a/.gitignore b/.gitignore index 5ef86f2..1c566f5 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ report/*.tps report/*.ist test/**/__pycache__ test/player/data/* +report/*.txss +report/**/*.mp4 diff --git a/report/Sumatra.tco b/report/Sumatra.tco deleted file mode 100644 index 330a6c1..0000000 --- a/report/Sumatra.tco +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/report/anexos/acta_pfc.pdf b/report/anexos/acta_pfc.pdf new file mode 100644 index 0000000..0156b10 Binary files /dev/null and b/report/anexos/acta_pfc.pdf differ diff --git a/report/anexos/autorizacion_tutor.pdf b/report/anexos/autorizacion_tutor.pdf new file mode 100644 index 0000000..2508ef4 Binary files /dev/null and b/report/anexos/autorizacion_tutor.pdf differ diff --git a/report/capitulo1/figura12.pdf b/report/capitulo1/cascada.pdf similarity index 100% rename from report/capitulo1/figura12.pdf rename to report/capitulo1/cascada.pdf diff --git a/report/capitulo1/figura11.jpg b/report/capitulo1/figura11.jpg deleted file mode 100644 index e60016f..0000000 Binary files a/report/capitulo1/figura11.jpg and /dev/null differ diff --git a/report/capitulo1/parroquia.jpg b/report/capitulo1/parroquia.jpg new file mode 100644 index 0000000..b782865 Binary files /dev/null and b/report/capitulo1/parroquia.jpg differ diff --git a/report/capitulo2/gantt.pdf b/report/capitulo2/gantt.pdf new file mode 100644 index 0000000..bcdc8d8 Binary files /dev/null and b/report/capitulo2/gantt.pdf differ diff --git a/report/capitulo2/plan_gantt.pdf b/report/capitulo2/plan_gantt.pdf new file mode 100644 index 0000000..d521c74 Binary files /dev/null and b/report/capitulo2/plan_gantt.pdf differ diff --git a/report/capitulo2/planificacion.pdf b/report/capitulo2/planificacion.pdf new file mode 100644 index 0000000..a74113d Binary files /dev/null and b/report/capitulo2/planificacion.pdf differ diff --git a/report/capitulo3/FDCC2004B.png b/report/capitulo3/FDCC2004B.png new file mode 100644 index 0000000..7370667 Binary files /dev/null and b/report/capitulo3/FDCC2004B.png differ diff --git a/report/capitulo3/HIRK-315A-circuits.jpg b/report/capitulo3/HIRK-315A-circuits.jpg new file mode 100644 index 0000000..7116df3 Binary files /dev/null and b/report/capitulo3/HIRK-315A-circuits.jpg differ diff --git a/report/capitulo3/HIRK-433A.jpg b/report/capitulo3/HIRK-433A.jpg new file mode 100644 index 0000000..7c2a5f7 Binary files /dev/null and b/report/capitulo3/HIRK-433A.jpg differ diff --git a/report/capitulo3/SN74HC595.png b/report/capitulo3/SN74HC595.png new file mode 100644 index 0000000..f70bc71 Binary files /dev/null and b/report/capitulo3/SN74HC595.png differ diff --git a/report/capitulo3/arduino.jpg b/report/capitulo3/arduino.jpg new file mode 100644 index 0000000..37112e2 Binary files /dev/null and b/report/capitulo3/arduino.jpg differ diff --git a/report/capitulo3/barroco.jpg b/report/capitulo3/barroco.jpg new file mode 100644 index 0000000..6cd834a Binary files /dev/null and b/report/capitulo3/barroco.jpg differ diff --git a/report/capitulo3/blanca_modelo.PDF b/report/capitulo3/blanca_modelo.PDF new file mode 100644 index 0000000..8cc8faa Binary files /dev/null and b/report/capitulo3/blanca_modelo.PDF differ diff --git a/report/capitulo3/buzzer.jpg b/report/capitulo3/buzzer.jpg new file mode 100644 index 0000000..3d10b53 Binary files /dev/null and b/report/capitulo3/buzzer.jpg differ diff --git a/report/capitulo3/buzzer_freq.pdf b/report/capitulo3/buzzer_freq.pdf new file mode 100644 index 0000000..ec3868a Binary files /dev/null and b/report/capitulo3/buzzer_freq.pdf differ diff --git a/report/capitulo3/consola.jpg b/report/capitulo3/consola.jpg new file mode 100644 index 0000000..37d680b Binary files /dev/null and b/report/capitulo3/consola.jpg differ diff --git a/report/capitulo3/general.pdf b/report/capitulo3/general.pdf new file mode 100644 index 0000000..e6ab66a Binary files /dev/null and b/report/capitulo3/general.pdf differ diff --git a/report/capitulo3/mecanismos.jpg b/report/capitulo3/mecanismos.jpg new file mode 100644 index 0000000..da05ad9 Binary files /dev/null and b/report/capitulo3/mecanismos.jpg differ diff --git a/report/capitulo3/negra_modelo.PDF b/report/capitulo3/negra_modelo.PDF new file mode 100644 index 0000000..fecd533 Binary files /dev/null and b/report/capitulo3/negra_modelo.PDF differ diff --git a/report/capitulo3/pcb_gpio.pdf b/report/capitulo3/pcb_gpio.pdf new file mode 100644 index 0000000..6b361bc Binary files /dev/null and b/report/capitulo3/pcb_gpio.pdf differ diff --git a/report/capitulo3/pcb_pedalier.pdf b/report/capitulo3/pcb_pedalier.pdf new file mode 100644 index 0000000..61d19fe Binary files /dev/null and b/report/capitulo3/pcb_pedalier.pdf differ diff --git a/report/capitulo3/pcb_perifericos.pdf b/report/capitulo3/pcb_perifericos.pdf new file mode 100644 index 0000000..68e36e3 Binary files /dev/null and b/report/capitulo3/pcb_perifericos.pdf differ diff --git a/report/capitulo3/pcb_registros.pdf b/report/capitulo3/pcb_registros.pdf new file mode 100644 index 0000000..401a41c Binary files /dev/null and b/report/capitulo3/pcb_registros.pdf differ diff --git a/report/capitulo3/pcb_teclado.pdf b/report/capitulo3/pcb_teclado.pdf new file mode 100644 index 0000000..cad3907 Binary files /dev/null and b/report/capitulo3/pcb_teclado.pdf differ diff --git a/report/capitulo3/pedalier.jpg b/report/capitulo3/pedalier.jpg new file mode 100644 index 0000000..2c67649 Binary files /dev/null and b/report/capitulo3/pedalier.jpg differ diff --git a/report/capitulo3/pedalier_modelo.PDF b/report/capitulo3/pedalier_modelo.PDF new file mode 100644 index 0000000..a70b7aa Binary files /dev/null and b/report/capitulo3/pedalier_modelo.PDF differ diff --git a/report/capitulo3/raspberry.jpg b/report/capitulo3/raspberry.jpg new file mode 100644 index 0000000..a7ee88c Binary files /dev/null and b/report/capitulo3/raspberry.jpg differ diff --git a/report/capitulo3/rebotes.PNG b/report/capitulo3/rebotes.PNG new file mode 100644 index 0000000..c73a8ad Binary files /dev/null and b/report/capitulo3/rebotes.PNG differ diff --git a/report/capitulo3/registros.jpg b/report/capitulo3/registros.jpg new file mode 100644 index 0000000..c580cd7 Binary files /dev/null and b/report/capitulo3/registros.jpg differ diff --git a/report/capitulo3/romantico.jpg b/report/capitulo3/romantico.jpg new file mode 100644 index 0000000..bca982b Binary files /dev/null and b/report/capitulo3/romantico.jpg differ diff --git a/report/capitulo3/rotary.png b/report/capitulo3/rotary.png new file mode 100644 index 0000000..4bd1067 Binary files /dev/null and b/report/capitulo3/rotary.png differ diff --git a/report/capitulo3/rotary_signal.pdf b/report/capitulo3/rotary_signal.pdf new file mode 100644 index 0000000..aa449c1 Binary files /dev/null and b/report/capitulo3/rotary_signal.pdf differ diff --git a/report/capitulo3/teclado_modelo.PDF b/report/capitulo3/teclado_modelo.PDF new file mode 100644 index 0000000..66b0e04 Binary files /dev/null and b/report/capitulo3/teclado_modelo.PDF differ diff --git a/report/capitulo3/teclados.jpg b/report/capitulo3/teclados.jpg new file mode 100644 index 0000000..a06177b Binary files /dev/null and b/report/capitulo3/teclados.jpg differ diff --git a/report/capitulo4/bd_er.pdf b/report/capitulo4/bd_er.pdf new file mode 100644 index 0000000..30a931a Binary files /dev/null and b/report/capitulo4/bd_er.pdf differ diff --git a/report/capitulo4/bd_fn.png b/report/capitulo4/bd_fn.png new file mode 100644 index 0000000..165f9b6 Binary files /dev/null and b/report/capitulo4/bd_fn.png differ diff --git a/report/capitulo4/bd_rel.pdf b/report/capitulo4/bd_rel.pdf new file mode 100644 index 0000000..c75b629 Binary files /dev/null and b/report/capitulo4/bd_rel.pdf differ diff --git a/report/capitulo4/cap_listas.png b/report/capitulo4/cap_listas.png new file mode 100644 index 0000000..a654006 Binary files /dev/null and b/report/capitulo4/cap_listas.png differ diff --git a/report/capitulo4/cap_mando.png b/report/capitulo4/cap_mando.png new file mode 100644 index 0000000..05c6000 Binary files /dev/null and b/report/capitulo4/cap_mando.png differ diff --git a/report/capitulo4/cap_piezas.png b/report/capitulo4/cap_piezas.png new file mode 100644 index 0000000..79a0978 Binary files /dev/null and b/report/capitulo4/cap_piezas.png differ diff --git a/report/capitulo4/cap_portada.jpg b/report/capitulo4/cap_portada.jpg new file mode 100644 index 0000000..749db46 Binary files /dev/null and b/report/capitulo4/cap_portada.jpg differ diff --git a/report/capitulo4/cap_reproductor.png b/report/capitulo4/cap_reproductor.png new file mode 100644 index 0000000..d83d6aa Binary files /dev/null and b/report/capitulo4/cap_reproductor.png differ diff --git a/report/capitulo4/daemon.pdf b/report/capitulo4/daemon.pdf new file mode 100644 index 0000000..b32d504 Binary files /dev/null and b/report/capitulo4/daemon.pdf differ diff --git a/report/capitulo4/daemon_bd.pdf b/report/capitulo4/daemon_bd.pdf new file mode 100644 index 0000000..618e539 Binary files /dev/null and b/report/capitulo4/daemon_bd.pdf differ diff --git a/report/capitulo4/daemon_critical.pdf b/report/capitulo4/daemon_critical.pdf new file mode 100644 index 0000000..e63093e Binary files /dev/null and b/report/capitulo4/daemon_critical.pdf differ diff --git a/report/capitulo4/daemon_engineer.pdf b/report/capitulo4/daemon_engineer.pdf new file mode 100644 index 0000000..d9a2163 Binary files /dev/null and b/report/capitulo4/daemon_engineer.pdf differ diff --git a/report/capitulo4/daemon_gpio.pdf b/report/capitulo4/daemon_gpio.pdf new file mode 100644 index 0000000..f758256 Binary files /dev/null and b/report/capitulo4/daemon_gpio.pdf differ diff --git a/report/capitulo4/daemon_midi.pdf b/report/capitulo4/daemon_midi.pdf new file mode 100644 index 0000000..89c6740 Binary files /dev/null and b/report/capitulo4/daemon_midi.pdf differ diff --git a/report/capitulo4/daemon_scheduler.pdf b/report/capitulo4/daemon_scheduler.pdf new file mode 100644 index 0000000..08189bd Binary files /dev/null and b/report/capitulo4/daemon_scheduler.pdf differ diff --git a/report/capitulo4/daemon_socket.pdf b/report/capitulo4/daemon_socket.pdf new file mode 100644 index 0000000..a1cea38 Binary files /dev/null and b/report/capitulo4/daemon_socket.pdf differ diff --git a/report/capitulo4/daemon_uart.pdf b/report/capitulo4/daemon_uart.pdf new file mode 100644 index 0000000..7b4cba5 Binary files /dev/null and b/report/capitulo4/daemon_uart.pdf differ diff --git a/report/capitulo4/despliegue.pdf b/report/capitulo4/despliegue.pdf new file mode 100644 index 0000000..11708b6 Binary files /dev/null and b/report/capitulo4/despliegue.pdf differ diff --git a/report/capitulo4/engineer.pdf b/report/capitulo4/engineer.pdf new file mode 100644 index 0000000..d5429b3 Binary files /dev/null and b/report/capitulo4/engineer.pdf differ diff --git a/report/capitulo4/idea.pdf b/report/capitulo4/idea.pdf new file mode 100644 index 0000000..6da6b63 Binary files /dev/null and b/report/capitulo4/idea.pdf differ diff --git a/report/capitulo4/map.pdf b/report/capitulo4/map.pdf new file mode 100644 index 0000000..81d42f9 Binary files /dev/null and b/report/capitulo4/map.pdf differ diff --git a/report/capitulo4/maqueta.pdf b/report/capitulo4/maqueta.pdf new file mode 100644 index 0000000..d111bb6 Binary files /dev/null and b/report/capitulo4/maqueta.pdf differ diff --git a/report/capitulo4/midi_info.pdf b/report/capitulo4/midi_info.pdf new file mode 100644 index 0000000..ee6dfcb Binary files /dev/null and b/report/capitulo4/midi_info.pdf differ diff --git a/report/capitulo4/midi_test.pdf b/report/capitulo4/midi_test.pdf new file mode 100644 index 0000000..d2dcd79 Binary files /dev/null and b/report/capitulo4/midi_test.pdf differ diff --git a/report/capitulo4/mvc.pdf b/report/capitulo4/mvc.pdf new file mode 100644 index 0000000..28c5a95 Binary files /dev/null and b/report/capitulo4/mvc.pdf differ diff --git a/report/capitulo4/mvc_acceso.pdf b/report/capitulo4/mvc_acceso.pdf new file mode 100644 index 0000000..f624254 Binary files /dev/null and b/report/capitulo4/mvc_acceso.pdf differ diff --git a/report/capitulo4/mvc_completo.pdf b/report/capitulo4/mvc_completo.pdf new file mode 100644 index 0000000..f8ff563 Binary files /dev/null and b/report/capitulo4/mvc_completo.pdf differ diff --git a/report/capitulo4/mvc_energia.pdf b/report/capitulo4/mvc_energia.pdf new file mode 100644 index 0000000..d7d3e4c Binary files /dev/null and b/report/capitulo4/mvc_energia.pdf differ diff --git a/report/capitulo4/mvc_idioma.pdf b/report/capitulo4/mvc_idioma.pdf new file mode 100644 index 0000000..857d479 Binary files /dev/null and b/report/capitulo4/mvc_idioma.pdf differ diff --git a/report/capitulo4/mvc_listas.pdf b/report/capitulo4/mvc_listas.pdf new file mode 100644 index 0000000..6c62c4d Binary files /dev/null and b/report/capitulo4/mvc_listas.pdf differ diff --git a/report/capitulo4/mvc_mando.pdf b/report/capitulo4/mvc_mando.pdf new file mode 100644 index 0000000..3bed130 Binary files /dev/null and b/report/capitulo4/mvc_mando.pdf differ diff --git a/report/capitulo4/mvc_piezas.pdf b/report/capitulo4/mvc_piezas.pdf new file mode 100644 index 0000000..9468baf Binary files /dev/null and b/report/capitulo4/mvc_piezas.pdf differ diff --git a/report/capitulo4/mvc_reproductor.pdf b/report/capitulo4/mvc_reproductor.pdf new file mode 100644 index 0000000..fd948b3 Binary files /dev/null and b/report/capitulo4/mvc_reproductor.pdf differ diff --git a/report/capitulo4/navegacion.pdf b/report/capitulo4/navegacion.pdf new file mode 100644 index 0000000..2860b83 Binary files /dev/null and b/report/capitulo4/navegacion.pdf differ diff --git a/report/capitulo4/sched.pdf b/report/capitulo4/sched.pdf new file mode 100644 index 0000000..817cd87 Binary files /dev/null and b/report/capitulo4/sched.pdf differ diff --git a/report/capitulo4/sistema.pdf b/report/capitulo4/sistema.pdf new file mode 100644 index 0000000..8af3b33 Binary files /dev/null and b/report/capitulo4/sistema.pdf differ diff --git a/report/capitulo4/terminal.pdf b/report/capitulo4/terminal.pdf new file mode 100644 index 0000000..3140211 Binary files /dev/null and b/report/capitulo4/terminal.pdf differ diff --git a/report/capitulo4/uml_midi.pdf b/report/capitulo4/uml_midi.pdf new file mode 100644 index 0000000..e59710e Binary files /dev/null and b/report/capitulo4/uml_midi.pdf differ diff --git a/report/capitulo5/ajax.pdf b/report/capitulo5/ajax.pdf new file mode 100644 index 0000000..dc57536 Binary files /dev/null and b/report/capitulo5/ajax.pdf differ diff --git a/report/capitulo5/beethoven_1voz.pdf b/report/capitulo5/beethoven_1voz.pdf new file mode 100644 index 0000000..41e00e3 Binary files /dev/null and b/report/capitulo5/beethoven_1voz.pdf differ diff --git a/report/capitulo5/big_endian.pdf b/report/capitulo5/big_endian.pdf new file mode 100644 index 0000000..8fa67b9 Binary files /dev/null and b/report/capitulo5/big_endian.pdf differ diff --git a/report/capitulo5/cap_elim_lista.png b/report/capitulo5/cap_elim_lista.png new file mode 100644 index 0000000..e10fbf4 Binary files /dev/null and b/report/capitulo5/cap_elim_lista.png differ diff --git a/report/capitulo5/cap_ins_lista.png b/report/capitulo5/cap_ins_lista.png new file mode 100644 index 0000000..8b2ce4e Binary files /dev/null and b/report/capitulo5/cap_ins_lista.png differ diff --git a/report/capitulo5/cap_ins_pieza.png b/report/capitulo5/cap_ins_pieza.png new file mode 100644 index 0000000..6007b22 Binary files /dev/null and b/report/capitulo5/cap_ins_pieza.png differ diff --git a/report/capitulo5/cap_listas.png b/report/capitulo5/cap_listas.png new file mode 100644 index 0000000..082c8d5 Binary files /dev/null and b/report/capitulo5/cap_listas.png differ diff --git a/report/capitulo5/cap_login_error.jpg b/report/capitulo5/cap_login_error.jpg new file mode 100644 index 0000000..9ad0497 Binary files /dev/null and b/report/capitulo5/cap_login_error.jpg differ diff --git a/report/capitulo5/cap_mando.png b/report/capitulo5/cap_mando.png new file mode 100644 index 0000000..3dfd516 Binary files /dev/null and b/report/capitulo5/cap_mando.png differ diff --git a/report/capitulo5/cap_midinfo.png b/report/capitulo5/cap_midinfo.png new file mode 100644 index 0000000..05bd7e7 Binary files /dev/null and b/report/capitulo5/cap_midinfo.png differ diff --git a/report/capitulo5/cap_miditest.png b/report/capitulo5/cap_miditest.png new file mode 100644 index 0000000..b863bdb Binary files /dev/null and b/report/capitulo5/cap_miditest.png differ diff --git a/report/capitulo5/cap_navigation.png b/report/capitulo5/cap_navigation.png new file mode 100644 index 0000000..0cfe0f3 Binary files /dev/null and b/report/capitulo5/cap_navigation.png differ diff --git a/report/capitulo5/cap_parser.png b/report/capitulo5/cap_parser.png new file mode 100644 index 0000000..92dace6 Binary files /dev/null and b/report/capitulo5/cap_parser.png differ diff --git a/report/capitulo5/cap_piezas.png b/report/capitulo5/cap_piezas.png new file mode 100644 index 0000000..fb38a5d Binary files /dev/null and b/report/capitulo5/cap_piezas.png differ diff --git a/report/capitulo5/cap_pytest.png b/report/capitulo5/cap_pytest.png new file mode 100644 index 0000000..d5e3eff Binary files /dev/null and b/report/capitulo5/cap_pytest.png differ diff --git a/report/capitulo5/cap_repr_apagar.png b/report/capitulo5/cap_repr_apagar.png new file mode 100644 index 0000000..b3a20ed Binary files /dev/null and b/report/capitulo5/cap_repr_apagar.png differ diff --git a/report/capitulo5/cap_repr_idiomas.png b/report/capitulo5/cap_repr_idiomas.png new file mode 100644 index 0000000..0d5584b Binary files /dev/null and b/report/capitulo5/cap_repr_idiomas.png differ diff --git a/report/capitulo5/cap_reproductor.png b/report/capitulo5/cap_reproductor.png new file mode 100644 index 0000000..a9ff158 Binary files /dev/null and b/report/capitulo5/cap_reproductor.png differ diff --git a/report/capitulo5/cap_sql.png b/report/capitulo5/cap_sql.png new file mode 100644 index 0000000..e13413e Binary files /dev/null and b/report/capitulo5/cap_sql.png differ diff --git a/report/capitulo5/cap_terminal.png b/report/capitulo5/cap_terminal.png new file mode 100644 index 0000000..d28ace6 Binary files /dev/null and b/report/capitulo5/cap_terminal.png differ diff --git a/report/capitulo5/disaster_girl.jpg b/report/capitulo5/disaster_girl.jpg new file mode 100644 index 0000000..de7a292 Binary files /dev/null and b/report/capitulo5/disaster_girl.jpg differ diff --git a/report/capitulo5/flujo_parser.pdf b/report/capitulo5/flujo_parser.pdf new file mode 100644 index 0000000..2e0def9 Binary files /dev/null and b/report/capitulo5/flujo_parser.pdf differ diff --git a/report/capitulo5/flujo_planificacion.pdf b/report/capitulo5/flujo_planificacion.pdf new file mode 100644 index 0000000..74e0db6 Binary files /dev/null and b/report/capitulo5/flujo_planificacion.pdf differ diff --git a/report/capitulo5/html.pdf b/report/capitulo5/html.pdf new file mode 100644 index 0000000..e609027 Binary files /dev/null and b/report/capitulo5/html.pdf differ diff --git a/report/capitulo5/lineas.pdf b/report/capitulo5/lineas.pdf new file mode 100644 index 0000000..252f808 Binary files /dev/null and b/report/capitulo5/lineas.pdf differ diff --git a/report/capitulo5/lineas_lenguajes.pdf b/report/capitulo5/lineas_lenguajes.pdf new file mode 100644 index 0000000..f2e60bf Binary files /dev/null and b/report/capitulo5/lineas_lenguajes.pdf differ diff --git a/report/capitulo5/lineas_modulos.pdf b/report/capitulo5/lineas_modulos.pdf new file mode 100644 index 0000000..97bcf88 Binary files /dev/null and b/report/capitulo5/lineas_modulos.pdf differ diff --git a/report/capitulo5/little_endian.pdf b/report/capitulo5/little_endian.pdf new file mode 100644 index 0000000..179a53c Binary files /dev/null and b/report/capitulo5/little_endian.pdf differ diff --git a/report/capitulo5/prototipado.pdf b/report/capitulo5/prototipado.pdf new file mode 100644 index 0000000..e8d53cf Binary files /dev/null and b/report/capitulo5/prototipado.pdf differ diff --git a/report/capitulo5/stack.pdf b/report/capitulo5/stack.pdf new file mode 100644 index 0000000..cdb078d Binary files /dev/null and b/report/capitulo5/stack.pdf differ diff --git a/report/capitulo5/varlen.pdf b/report/capitulo5/varlen.pdf new file mode 100644 index 0000000..f582623 Binary files /dev/null and b/report/capitulo5/varlen.pdf differ diff --git a/report/capitulo6/cap_camponulo.png b/report/capitulo6/cap_camponulo.png new file mode 100644 index 0000000..a284956 Binary files /dev/null and b/report/capitulo6/cap_camponulo.png differ diff --git a/report/capitulo6/cap_canyon.png b/report/capitulo6/cap_canyon.png new file mode 100644 index 0000000..fc947db Binary files /dev/null and b/report/capitulo6/cap_canyon.png differ diff --git a/report/capitulo6/cap_errclave.png b/report/capitulo6/cap_errclave.png new file mode 100644 index 0000000..d417a4d Binary files /dev/null and b/report/capitulo6/cap_errclave.png differ diff --git a/report/capitulo6/cap_error.png b/report/capitulo6/cap_error.png new file mode 100644 index 0000000..385a141 Binary files /dev/null and b/report/capitulo6/cap_error.png differ diff --git a/report/capitulo6/cap_hackform.png b/report/capitulo6/cap_hackform.png new file mode 100644 index 0000000..7a5faff Binary files /dev/null and b/report/capitulo6/cap_hackform.png differ diff --git a/report/capitulo6/cap_top.png b/report/capitulo6/cap_top.png new file mode 100644 index 0000000..ca406d5 Binary files /dev/null and b/report/capitulo6/cap_top.png differ diff --git a/report/capitulo6/ejecucion.pdf b/report/capitulo6/ejecucion.pdf new file mode 100644 index 0000000..ab8cbed Binary files /dev/null and b/report/capitulo6/ejecucion.pdf differ diff --git a/report/capitulo6/ejecucion_web.pdf b/report/capitulo6/ejecucion_web.pdf new file mode 100644 index 0000000..ee19420 Binary files /dev/null and b/report/capitulo6/ejecucion_web.pdf differ diff --git a/report/capitulo6/lat_gpio.pdf b/report/capitulo6/lat_gpio.pdf new file mode 100644 index 0000000..174656d Binary files /dev/null and b/report/capitulo6/lat_gpio.pdf differ diff --git a/report/capitulo6/lat_midi.pdf b/report/capitulo6/lat_midi.pdf new file mode 100644 index 0000000..17ba6d6 Binary files /dev/null and b/report/capitulo6/lat_midi.pdf differ diff --git a/report/capitulo6/lat_sched.pdf b/report/capitulo6/lat_sched.pdf new file mode 100644 index 0000000..372a2df Binary files /dev/null and b/report/capitulo6/lat_sched.pdf differ diff --git a/report/capitulo6/network.pdf b/report/capitulo6/network.pdf new file mode 100644 index 0000000..894ee64 Binary files /dev/null and b/report/capitulo6/network.pdf differ diff --git a/report/capitulo6/osc_nota.PNG b/report/capitulo6/osc_nota.PNG new file mode 100644 index 0000000..1f4c213 Binary files /dev/null and b/report/capitulo6/osc_nota.PNG differ diff --git a/report/capitulo6/osc_pulso.PNG b/report/capitulo6/osc_pulso.PNG new file mode 100644 index 0000000..12b5718 Binary files /dev/null and b/report/capitulo6/osc_pulso.PNG differ diff --git a/report/capitulo6/pcb.jpg b/report/capitulo6/pcb.jpg new file mode 100644 index 0000000..30258fd Binary files /dev/null and b/report/capitulo6/pcb.jpg differ diff --git a/report/capitulo6/pcb_ingeniero.jpg b/report/capitulo6/pcb_ingeniero.jpg new file mode 100644 index 0000000..632275b Binary files /dev/null and b/report/capitulo6/pcb_ingeniero.jpg differ diff --git a/report/capitulo6/proto_esquema.pdf b/report/capitulo6/proto_esquema.pdf new file mode 100644 index 0000000..73682e3 Binary files /dev/null and b/report/capitulo6/proto_esquema.pdf differ diff --git a/report/capitulo6/proto_uart.jpg b/report/capitulo6/proto_uart.jpg new file mode 100644 index 0000000..73cae81 Binary files /dev/null and b/report/capitulo6/proto_uart.jpg differ diff --git a/report/estilos/pfc.sty b/report/estilos/pfc.sty index 3012556..05a2c8a 100644 --- a/report/estilos/pfc.sty +++ b/report/estilos/pfc.sty @@ -51,7 +51,7 @@ microcontrolador}, % title % duplicate ignored % http://en.wikibooks.org/wiki/LaTeX/Hyperlinks#Problems_with_Links_and_Pages \usepackage[UTF8]{inputenc} %Formato de caracteres en fichero . -\usepackage[spanish,english]{babel} +\usepackage[spanish]{babel} \usepackage{eurosym} @@ -689,7 +689,7 @@ microcontrolador}, % title \fancyhead[RE]{\rightmark} % Numeros de pagina en las esquinas de los encabezados \fancyhead[RO,LE]{\thepage} -\fancyfoot[RE]{Víctor Manuel Fernández Castro} +\fancyfoot[RE]{Víctor Manuel Fernández Castro.} \renewcommand{\footrulewidth}{0.5pt} \fancyfoot[LO]{Interpretación remota de partituras sobre instrumentos de viento.} diff --git a/report/glosario_acronimos.sty b/report/glosario_acronimos.sty index 78251ce..f87e840 100644 --- a/report/glosario_acronimos.sty +++ b/report/glosario_acronimos.sty @@ -10,7 +10,7 @@ %ACRONIMOS \newacronym{SNR}{SNR}{Signal to noise ratio} -\newacronym{PCB}{PCB}{Printed Circuit Boards} +\newacronym{PCB}{PCB}{Printed Circuit Board} \newacronym{FPGA}{FPGA}{Field Programmable Gate Array} \newacronym{LCD}{LCD}{Liquid Crystal Display} \newacronym{SPI}{SPI}{Serial Peripheral Interface} @@ -20,6 +20,44 @@ \newacronym{PWM}{PWM}{Pulse-Width Modulation} \newacronym{FIR}{FIR}{Finite Impulse Response} +\newacronym{GPIO}{GPIO}{General Purpose Input/Output} +\newacronym{MIDI}{MIDI}{Musical Instrument Digital Interface} +\newacronym{SSH}{SSH}{Secure SHell} +\newacronym{SBC}{SBC}{Musical Instrument Digital Interface} +\newacronym{UART}{UART}{Universal Asynchronous Receiver-Transmitter} +\newacronym{USB}{USB}{Universal Serial Bus} +\newacronym{HDMI}{HDMI}{High Definition Multimedia Interface} +\newacronym{SC}{SC}{Secure Digital} +\newacronym{I2C}{I\textsuperscript{2}C}{Inter-Integrated Circuit} +\newacronym{SD}{SD}{Secure Digital} +\newacronym{CPU}{CPU}{Central Process Unit} +\newacronym{ASCII}{ASCII}{American Standard Code for Information Interchange} +\newacronym{IPC}{IPC}{Inter-Process Communication} +\newacronym{DBMS}{DBMS}{Database Management System} +\newacronym{SGBD}{SGBD}{Sistema de Gestión de Bases de Datos} +\newacronym{XML}{XML}{eXtensible Markup Language} +\newacronym{HTTP}{HTTP}{Hyper-Text Transfer Protocol} +\newacronym{POSIX}{POSIX}{Portable Operating System Interface} +\newacronym{HTML}{HTML}{Hyter-Text Markup Language} +\newacronym{CSS}{CSS}{Cascading Style Sheet} +\newacronym{mutex}{mutex}{Mutual Exclusion} +\newacronym{UID}{UID}{User IDentifier} +\newacronym{GID}{GID}{Group IDentifier} +\newacronym{LSB}{LSB}{Linux Standard Base} +\newacronym{API}{API}{Application Programming Interface} +\newacronym{CGI}{CGI}{Common Gateway Interface} +\newacronym{AJAX}{AJAX}{Asynchronous JavaScript And XML} +\newacronym{DOM}{DOM}{Document Object Model} +\newacronym{URL}{URL}{Uniform Resource Locator} +\newacronym{EIP}{EIP}{Extended Instruction Pointer} +\newacronym{ACID}{ACID}{Atomicity, Consistency, Isolation and Durability} +\newacronym{SQL}{SQL}{Structured Query Language} +\newacronym{CRUD}{CRUD}{Create, Read, Update and Delete} +\newacronym{SHA}{SHA}{Secure Hash Algorithm} +\newacronym{PHP}{PHP}{PHP Hypertext Preprocessor} +\newacronym{TCP}{TCP}{Transmission Control Protocol} +\newacronym{IP}{IP}{Internet Protocol} +\newacronym{DMZ}{DMZ}{DeMilitarized Zone} \newacronym{SMD}{SMD}{Surface Mount Devices} \newacronym{THD}{THD}{Through Hole Devices} @@ -32,7 +70,7 @@ \newacronym{sgt}{SGT}{Surrounding Gate Transistor} \newacronym{EOT}{EOT}{Equivalent Oxide Thickness} \newacronym{BJT}{BJT}{Bipolar Junction Transistor} -\newacronym{led}{LED}{light-emitting diode} +\newacronym{led}{LED}{Light-Emitting Diode} \newacronym{eeprom}{EEPROM}{electrically erasable programmableread-only memory} \newacronym{amd}{AMD}{Advanced Micro Devices} \newacronym{box}{BOX}{Buried OXide. Óxido Enterrado.} @@ -162,7 +200,7 @@ \newglossaryentry{VerilogAMS}{name={Verilog-AMS},description={Lenguaje de modelado derivado del lenguaje de descripción hardware Verilog que incluye extensiones analógicas y mixtas (AMS) para permitir el modelado de estos sistemas. Extiende los simuladores basados en eventos de VHDL en simuladores de tiempo continuo que deben resolver ecuaciones diferenciales en el dominio analógico del tiempo. La simulación analógica y digital quedan acoplados en un mismo simulador.}} \newglossaryentry{fortran}{name=FORTRAN,description={es un lenguaje de programación de alto nivel y procedural, desarrollado para propósitos generales por IBM en 1957 para el equipo IBM 704. Fue el primero desarrollado con estas características. Está fuertemente orientado al cálculo y por ende es uno de los de mayor eficiencia en la ejecución.}} \newglossaryentry{lenguajeC}{name=lenguaje-C,description={Es un lenguaje de programación de propósito general desarrollado por Dennis Ritchie en 1972 en los Bell Telephone Laboratories para usarlo en el sistema operativo UNIX\copyright.}} -\newglossaryentry{API}{name=API,description={Una interfaz de programación de aplicaciones o API (del inglés Application Programming Interface) es el conjunto de funciones y procedimientos (o métodos, en la programación orientada a objetos) que ofrece cierta biblioteca para ser utilizado por otro software como una capa de abstracción. Son usadas generalmente en las bibliotecas (también denominadas comúnmente \textit{librerías}).}} +\newglossaryentry{APII}{name=API,description={Una interfaz de programación de aplicaciones o API (del inglés Application Programming Interface) es el conjunto de funciones y procedimientos (o métodos, en la programación orientada a objetos) que ofrece cierta biblioteca para ser utilizado por otro software como una capa de abstracción. Son usadas generalmente en las bibliotecas (también denominadas comúnmente \textit{librerías}).}} diff --git a/report/logo_ugr.jpg b/report/logo_ugr.jpg new file mode 100644 index 0000000..d7cccc6 Binary files /dev/null and b/report/logo_ugr.jpg differ diff --git a/report/logo_ugr.png b/report/logo_ugr.png deleted file mode 100644 index b46b4cb..0000000 Binary files a/report/logo_ugr.png and /dev/null differ diff --git a/report/makeglossaries.bat b/report/makeglossaries.bat new file mode 100644 index 0000000..5969a37 --- /dev/null +++ b/report/makeglossaries.bat @@ -0,0 +1,11 @@ +set path=%path%;C:\Program Files (x86)\MiKTeX 2.9\miktex\bin + + +makeindex pfc_vmfdez.idx + +makeindex -s "pfc_vmfdez.ist" -t "pfc_vmfdez.alg" -o "pfc_vmfdez.acr" "pfc_vmfdez.acn" + +makeindex -s "pfc_vmfdez.ist" -t "pfc_vmfdez.glg" -o "pfc_vmfdez.sym" "pfc_vmfdez.sbl" + +makeindex -s "pfc_vmfdez.ist" -t "pfc_vmfdez.glg" -o "pfc_vmfdez.gls" "pfc_vmfdez.glo" + diff --git a/report/makeglossaries_amroldan.bat b/report/makeglossaries_amroldan.bat deleted file mode 100644 index 4713f23..0000000 --- a/report/makeglossaries_amroldan.bat +++ /dev/null @@ -1,10 +0,0 @@ -set path=%path%;C:\Program Files (x86)\MiKTeX 2.9\miktex\bin - - -makeindex pfc_amroldan.idx - -makeindex -s "pfc_amroldan.ist" -t "pfc_amroldan.alg" -o "pfc_amroldan.acr" "pfc_amroldan.acn" - -makeindex -s "pfc_amroldan.ist" -t "pfc_amroldan.glg" -o "pfc_amroldan.sym" "pfc_amroldan.sbl" - -makeindex -s "pfc_amroldan.ist" -t "pfc_amroldan.glg" -o "pfc_amroldan.gls" "pfc_amroldan.glo" diff --git a/report/pfc_AMROLDAN.tcp b/report/pfc_AMROLDAN.tcp deleted file mode 100644 index 2ff98c3..0000000 --- a/report/pfc_AMROLDAN.tcp +++ /dev/null @@ -1,12 +0,0 @@ -[FormatInfo] -Type=TeXnicCenterProjectInformation -Version=4 - -[ProjectInfo] -MainFile=pfc_amroldan.tex -UseBibTeX=1 -UseMakeIndex=1 -ActiveProfile=LaTeX ⇨ PDF -ProjectLanguage=es -ProjectDialect=ANY - diff --git a/report/pfc_AMROLDAN.tps b/report/pfc_AMROLDAN.tps deleted file mode 100644 index 8025524..0000000 --- a/report/pfc_AMROLDAN.tps +++ /dev/null @@ -1,30 +0,0 @@ -[FormatInfo] -Type=TeXnicCenterProjectSessionInformation -Version=2 - -[Frame0] -Flags=0 -ShowCmd=1 -MinPos.x=-1 -MinPos.y=-1 -MaxPos.x=-1 -MaxPos.y=-1 -NormalPos.left=4 -NormalPos.top=26 -NormalPos.right=1562 -NormalPos.bottom=591 -Class=LaTeXView -Document=pfc_amroldan.tex - -[Frame0_View0,0] -TopLine=87 -Cursor=3943 - -[SessionInfo] -FrameCount=1 -ActiveFrame=0 - -[Bookmarks] -pfc_amroldan.tex=169 -subdocs\capitulo5.tex=114 113 - diff --git a/report/pfc_amroldan.alg b/report/pfc_amroldan.alg deleted file mode 100644 index ab19a96..0000000 --- a/report/pfc_amroldan.alg +++ /dev/null @@ -1,7 +0,0 @@ -This is makeindex, version 2.15 [MiKTeX 2.9] (kpathsea + Thai support). -Scanning style file D:/Vikman/Dropbox/Universidad/Organo/Memoria/pfc_amroldan.ist.............................done (29 attributes redefined, 0 ignored). -Scanning input file pfc_amroldan.acn....done (69 entries accepted, 0 rejected). -Sorting entries....done (431 comparisons). -Generating output file pfc_amroldan.acr....done (44 lines written, 0 warnings). -Output written in pfc_amroldan.acr. -Transcript written in pfc_amroldan.alg. diff --git a/report/pfc_amroldan.bbl.tex b/report/pfc_amroldan.bbl.tex deleted file mode 100644 index c174952..0000000 --- a/report/pfc_amroldan.bbl.tex +++ /dev/null @@ -1,14 +0,0 @@ -\begin{thebibliography}{1} - -\bibitem{caca1} -{\sc Arian}. -\newblock Contrl pid, conceptos básicos. -\newblock 27. - -\bibitem{caca2} -{\sc Ogata, K.} -\newblock {\em Ingeniería de Control Moderna. Controles PID e introducción al - control robusto, vol. 3}. -\newblock 1999. - -\end{thebibliography} diff --git a/report/pfc_amroldan.ist b/report/pfc_amroldan.ist deleted file mode 100644 index e2db28f..0000000 --- a/report/pfc_amroldan.ist +++ /dev/null @@ -1,31 +0,0 @@ -% makeindex style file created by the glossaries package -% for document 'pfc_amroldan' on 2015-8-9 -actual '?' -encap '|' -level '!' -quote '"' -keyword "\\glossaryentry" -preamble "\\glossarysection[\\glossarytoctitle]{\\glossarytitle}\\glossarypreamble\n\\begin{theglossary}\\glossaryheader\n" -postamble "\%\n\\end{theglossary}\\glossarypostamble\n" -group_skip "\\glsgroupskip\n" -item_0 "\%\n" -item_1 "\%\n" -item_2 "\%\n" -item_01 "\%\n" -item_x1 "\\relax \\glsresetentrylist\n" -item_12 "\%\n" -item_x2 "\\relax \\glsresetentrylist\n" -delim_0 "\{\\glossaryentrynumbers\{\\relax " -delim_1 "\{\\glossaryentrynumbers\{\\relax " -delim_2 "\{\\glossaryentrynumbers\{\\relax " -delim_t "\}\}" -delim_n "\\delimN " -delim_r "\\delimR " -headings_flag 1 -heading_prefix "\\glsgroupheading\{" -heading_suffix "\}\\relax \\glsresetentrylist " -symhead_positive "glssymbols" -numhead_positive "glsnumbers" -page_compositor "." -suffix_2p "" -suffix_3p "" diff --git a/report/pfc_amroldan.lol b/report/pfc_amroldan.lol deleted file mode 100644 index e69de29..0000000 diff --git a/report/pfc_amroldan.tex b/report/pfc_vmfdez.tex similarity index 91% rename from report/pfc_amroldan.tex rename to report/pfc_vmfdez.tex index b5a08bc..fecd2f4 100644 --- a/report/pfc_amroldan.tex +++ b/report/pfc_vmfdez.tex @@ -1,4 +1,4 @@ -\documentclass[titlepage,12pt,a4paper,twoside,openright,svgnames]{report}% +\documentclass[titlepage,12pt,letterpaper,twoside,openright,svgnames]{report}% %Comillas con babel spanish. @@ -67,8 +67,6 @@ %Reconocedor de símbolos: http://detexify.kirelabs.org/classify.html %Cuadradito en Ohmios por cuadro \square - - \usepackage{estilos/pfc} \usepackage{estilos/funciones} @@ -76,20 +74,25 @@ \usepackage{graphicx} \usepackage{subfig} +\usepackage{wasysym} % Simbolos musicales +\usepackage{enumitem} % Para el estilo de las listas de descripcion +\usepackage{algorithmic} % Para describir algoritmos +\usepackage{multirow} % Para combinar celdas de las tablas en vertical +\usepackage{fancyvrb} % Para Verbatim +\usepackage{flashmovie} \usepackage{rotating} - \usepackage{listings} \usepackage{color} \usepackage{eurosym} - - \definecolor{mygreen}{rgb}{0,0.6,0} \definecolor{myyellow}{rgb}{1,1,0.84} \definecolor{mypink}{rgb}{0.7,0.016,0.536} \definecolor{myblue}{rgb}{0,0,1} +\def\code#1{\texttt{#1}} % para usar \code{} + \lstset{ frame=Ltb, framerule=0pt, @@ -248,7 +251,9 @@ \renewcommand{\appendixname}{Apéndice} \renewcommand{\bibname}{Bibliografía} \renewcommand{\figurename}{Figura} -\renewcommand{\listfigurename}{Índice de Figuras} +\renewcommand{\listfigurename}{Índice de Figuras} +\renewcommand{\listtablename}{Índice de tablas} +\renewcommand{\tablename}{Tabla} %Esto funciona normalmente pero en el caso de tener cargado el parquete CAPTION % hay que hacerlo de otra manera @@ -297,28 +302,28 @@ \include{subdocs/ListaFiguras} % %%Lista de FIGURAS - \include{subdocs/ListaListados} +% \include{subdocs/ListaListados} % %%Lista de TABLAS \include{subdocs/ListaTablas} %%%Símbolos: se incluyen en el listado de símbolos - \gls{pi}, \gls{ohm}, \gls{angstrom}, - \gls{QIPrima}, \gls{QBPrima}, \gls{QGPrima} - \gls{QI}, \gls{QB}, \gls{QG} - \gls{qI}, \gls{qB}, \gls{qG} - \gls{Idb}, \gls{gm}, \gls{gmb}, \gls{gsd} - \gls{gbg}, \gls{gbs}, \gls{gbd} +% \gls{pi}, \gls{ohm}, \gls{angstrom}, +% \gls{QIPrima}, \gls{QBPrima}, \gls{QGPrima} +% \gls{QI}, \gls{QB}, \gls{QG} +% \gls{qI}, \gls{qB}, \gls{qG} +% \gls{Idb}, \gls{gm}, \gls{gmb}, \gls{gsd} +% \gls{gbg}, \gls{gbs}, \gls{gbd} % -Acrónimos -\acrshort{SMD} (\acrlong{SMD}) -Enlace al glosario -\glsname{HISIM} (\glstext{HISIM}) +%Acrónimos +%\acrshort{SMD} (\acrlong{SMD}) +%Enlace al glosario +%\glsname{HISIM} (\glstext{HISIM}) % %%%%%% ERROR %%%%%%% -\acrshort{EKV} %(\acrlong{CRA}) -\glsname{EKV} (\glstext{EKV}) +%\acrshort{EKV} %(\acrlong{CRA}) +%\glsname{EKV} (\glstext{EKV}) %%Citas: hace un enlace a la Bibliografía %\cite{rytter1993vibration} @@ -344,7 +349,7 @@ %%H:/pen azul/memoria/V00/ % -%\include{subdocs/capitulo7} +\include{subdocs/capitulo7} %\include{capitulo7} % %\include{subdocs/capitulo8} diff --git a/report/referencias/referencias_BIB.bib b/report/referencias/referencias_BIB.bib index 4b22133..906abf0 100644 --- a/report/referencias/referencias_BIB.bib +++ b/report/referencias/referencias_BIB.bib @@ -1,177 +1,475 @@ % This file was created with JabRef 2.10. -% Encoding: Cp1252 +% Encoding: UTF8 -@Article{PID, - Title = {Contrl PID, conceptos bsicos}, - Author = {Arian}, - Year = {2010}, - Number = {Rev b}, - Pages = {27}, - Volume = {Nota tcnica 10}, +@MastersThesis{mikel, + Title = {Diseño e implementación de un sistema con control remoto para la automatización de un órgano eclesiástico}, + Author = {Mikel Aguayo-Fernández}, + School = {Universidad de Granada}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29} +} + +@Booklet{bdrel, + Title = {Diseño lógico de base de datos relacionales}, + Author = {Fernando Berzal-Galiano}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {http://elvex.ugr.es/idbis/db/docs/design/5-logical.pdf} +} + +@Misc{svg_raspberry, + Title = {Vector illustration of a Raspberry Pi B+}, + + Author = {Cmykey}, + HowPublished = {Wikimedia Commons}, + Month = {July}, + Year = {2014}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://commons.wikimedia.org/wiki/File:Raspberry_Pi_B%2B_illustration.svg} +} + +@Manual{php, + Title = {PHP Manual}, + Author = {Peter Cowburn}, + Organization = {PHP Documentation Group}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {http://php.net/manual/en/language.references.php} +} + +@Manual{wiringpi, + Title = {Wiring Pi Reference}, + Author = {Drogon}, + Year = {2015}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.06} + Owner = {Vikman}, + Timestamp = {2015.08.31}, + Url = {http://wiringpi.com/reference/} } -@Book{Ibrahim, - Title = {Microcontroller Based Temperature Monitoring and Control}, - Author = {Ibrahim, D}, - Publisher = {Elsevier Science Technology Books}, - Year = {2002}, +@Article{vikman_switch, + Title = {Uso de switch en programación}, + Author = {Víctor Manuel Fernández-Castro}, + Journal = {Vikman's Blog}, + Year = {2014}, - Owner = {GermanPortatil}, - Timestamp = {2015.06.08} + Owner = {Vikman}, + Timestamp = {2015.09.01}, + Url = {http://vikman90.blogspot.com.es/2014/02/uso-de-switch-en-programacion.html} } -@Book{Ogata, - Title = {Ingeniera de Control Moderna. Controles PID e introduccin al control -robusto, vol. 3}, - Author = {Ogata, K.}, - Editor = {Editorial Prentice Hall}, - Year = {1999}, +@Article{iglesias_granada, + Title = {Iglesias de la provincia de Granada}, + Author = {Francisco Fervel}, + Journal = {Rincones de Granada}, + Year = {2015}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.05} + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {http://rinconesgranainos.blogspot.com.es/2015/01/iglesias-de-la-provincia-de-granada.html} } -@Article{Jack, - Title = {DETERMINING CIRCUIT BOARD CURRENT CARRYING CAPABILITY}, - Author = {Jack Olson}, +@Book{soii, + Title = {Sistemas Operativos II - Guía didáctica y de trabajo autónomo}, + Author = {José Antonio Gómez-Hernández}, + Publisher = {José Antonio Gómez Hernández}, Year = {2009}, - Pages = {10}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.25}, - Url = {http://frontdoor.biz/PCBportal/HowTo2152.xls} + Owner = {Vikman}, + Timestamp = {2015.08.29} } -@Article{Skogestad, - Title = {Best simple tuning rules}, - Author = {Skogestad, S.}, - Journal = {Journal Of Process Control}, - Year = {2001}, - Pages = {27}, +@Article{shahmir_daemon, + Title = {Beginner's guide to creating a daemon in Linux}, + Author = {Shahmir Javaid}, + Journal = {Shahmir Javaid Blog}, + Year = {2010}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.05} + Owner = {Vikman}, + Timestamp = {2015.09.02}, + Url = {http://shahmirj.com/blog/beginners-guide-to-creating-a-daemon-in-linux} } -@Article{Wescott, - Title = {Pid without a phd}, - Author = {Wescott, T.}, - Year = {2000}, - Pages = {14}, +@Booklet{zanero_cs, + Title = {Computer Security}, + Author = {Stefano Zanero}, + HowPublished = {Politecnico di Milano}, + Year = {2014}, - Editor = {EE Times-India}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.05} + Owner = {Vikman}, + Publisher = {Wiley}, + Timestamp = {2015.09.13} } -@Article{wilson, - Title = {Relay-based pid tunning}, - Author = {Wilson, D. I.}, - Journal = {Automation And Control}, - Year = {2005}, - Pages = {3}, +@Manual{buzzer, + Title = {Piezoelectric Sounders External Drive SMD Type}, + Organization = {muRata}, - Owner = {GermanPortatil}, - Timestamp = {2015.06.09} + Owner = {Vikman}, + Timestamp = {2015.09.15} } -@Article{Arduino, - Title = {Arduino}, +@Manual{imagen_decoder, + Title = {RF Solutions HIRK-433AP RF Receiver Decoder 433mhz}, + Organization = {Rapid Electronics}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.06}, - Url = {www.arduino.cc} + HowPublished = {Rapid Electronics}, + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {http://www.rapidonline.com/Electrical-Power/RF-Solutions-HIRK-433AP-RF-Receiver-Decoder-433mhz-43-0028} } -@Article{Multi9, - Title = {CT modular contactors Multi 9 Merlin Gerin}, - Journal = {Scheneider Electric}, - Pages = {2}, +@Misc{material, + Title = {Material Design}, + HowPublished = {Google Inc.}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.21} + Journal = {Google}, + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://www.google.com/design/spec/material-design/introduction.html} } -@Article{WIKIPED, - Title = {Wikipedia}, - Journal = {The Free Encyclopedia}, +@Manual{mysql, + Title = {MySQL 5.5 Reference Manual}, + Organization = {Oracle Corp.}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.05}, - Url = {www.wikipedia.org} + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {http://dev.mysql.com/doc/refman/5.5/en/} } -@Article{moc, - Title = {MOC306XM datasheet}, - Journal = {Fairchild Semiconductor}, - Year = {2010}, - Pages = {11}, +@Manual{raspberry, + Title = {Raspberry Pi Hardware}, + Organization = {Raspberry Pi Foundation}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.25} + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://www.raspberrypi.org/documentation/hardware/raspberrypi/README.md} } -@Article{ATMega, - Title = {ATMega328}, - Journal = {Atmel}, - Year = {2009}, - Pages = {452}, +@Manual{rotary, + Title = {Encoder EC11J Series}, + Organization = {ALPS}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.06} + Owner = {Vikman}, + Timestamp = {2015.08.29} } -@Article{LCD, - Title = {LCD Module 204A Series}, - Journal = {Displaytech Ltd}, - Year = {2009}, - Pages = {23}, +@Misc{arduino, + Title = {Board Uno}, + HowPublished = {Arduino}, + Year = {2015}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.06} + Owner = {Vikman}, + Timestamp = {2015.09.15}, + Url = {https://www.arduino.cc/en/Main/ArduinoBoardUno} } -@Article{Rotary, - Title = {Rotary Encoder 318-ENC130175F-12PS data sheet}, - Journal = {Alpha}, - Year = {2008}, - Pages = {1}, +@Manual{cplusplus, + Title = {C Library}, + Organization = {cplusplus.com}, + Year = {2015}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.06} + Owner = {Vikman}, + Timestamp = {2015.08.31}, + Url = {http://www.cplusplus.com/reference/clibrary/} } -@Article{7805, - Title = {7805 data sheet}, - Journal = {STMicroelectronics}, - Year = {2003}, - Pages = {30}, +@Manual{gpiofs, + Title = {GPIO Sysfs Interface for Userspace}, + Organization = {Linux Kernel Organization, Inc.}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://www.kernel.org/doc/Documentation/gpio/sysfs.txt} +} + +@Manual{python, + Title = {The Python Standard Library}, + Organization = {Python Software Foundation}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.31}, + Url = {https://docs.python.org/3/library/index.html} +} + +@Manual{w3schools, + Title = {W3Schools Online Web Tutorials}, + Organization = {Refnes Data}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29} +} + +@Article{wiki_1fn, + Title = {Primera forma normal}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://es.wikipedia.org/wiki/Primera_forma_normal} +} + +@Article{wiki_2fn, + Title = {Segunda forma normal}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://es.wikipedia.org/wiki/Segunda_forma_normal} +} + +@Article{wiki_3fn, + Title = {Tercera forma normal}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://es.wikipedia.org/wiki/Tercera_forma_normal} +} + +@Article{wiki_4fn, + Title = {Cuarta forma normal}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://es.wikipedia.org/wiki/Cuarta_forma_normal} +} + +@Article{wiki_5fn, + Title = {Quinta forma normal}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://es.wikipedia.org/wiki/Quinta_forma_normal} +} + +@Article{wiki_acid, + Title = {ACID}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.09.14}, + Url = {https://es.wikipedia.org/wiki/ACID} +} + +@Article{wiki_cascada, + Title = {Desarrollo en cascada}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://es.wikipedia.org/wiki/Desarrollo_en_cascada} +} + +@Article{wiki_endianness, + Title = {Endianness}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.31}, + Url = {https://es.wikipedia.org/wiki/Endianness} +} - Owner = {GermanPortatil}, - Timestamp = {2015.05.05} +@Article{wiki_midi, + Title = {MIDI}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://en.wikipedia.org/wiki/MIDI} +} + +@Article{wiki_normal, + Title = {Normalización de bases de datos}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://es.wikipedia.org/wiki/Normalizaci%C3%B3n_de_bases_de_datos} +} + +@Article{wiki_ohm, + Title = {Ley de Ohm}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.09.16}, + Url = {https://es.wikipedia.org/wiki/Ley_de_Ohm} } -@Article{BC857, - Title = {BC857, PNP general purpose transistor}, - Journal = {PHILIPS}, - Year = {1997}, - Pages = {8}, +@Article{wiki_posix, + Title = {POSIX}, + Journal = {Wikipedia}, + Year = {2015}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.25} + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://en.wikipedia.org/wiki/POSIX} } -@Article{BT139, - Title = {Triac BT139 series data sheet}, - Journal = {Philips Electronics}, - Year = {1997}, - Pages = {6}, +@Article{wiki_runlevel, + Title = {Runlevel}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.09.02}, + Url = {https://en.wikipedia.org/wiki/Runlevel} +} + +@Article{wiki_socket, + Title = {Unix domain socket}, + Journal = {Wikipedia}, + Year = {2015}, + + Owner = {Vikman}, + Timestamp = {2015.09.05}, + Url = {https://en.wikipedia.org/wiki/Unix_domain_socket} +} + +@Article{debian_lsbinit, + Title = {How to LSBize an Init Script}, + Journal = {Debian Wiki}, + Year = {2014}, + + Owner = {Vikman}, + Timestamp = {2015.09.02}, + Url = {https://wiki.debian.org/LSBInitScripts} +} + +@Article{wiki_demonio, + Title = {Daemon (computing)}, + Journal = {Wikipedia}, + Year = {2014}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://en.wikipedia.org/wiki/Daemon_(computing)} +} + +@Article{wiki_divtension, + Title = {Divisor de tensión}, + Journal = {Wikipedia}, + Year = {2014}, + + Owner = {Vikman}, + Timestamp = {2015.09.16} +} + +@Article{wiki_fnbc, + Title = {Forma normal de Boyce-Codd}, + Journal = {Wikipedia}, + Year = {2014}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://es.wikipedia.org/wiki/Forma_normal_de_Boyce-Codd} +} + +@Article{wiki_uart, + Title = {Universal asynchronous receiver/transmitter}, + Journal = {Wikipedia}, + Year = {2014}, + + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter} +} + +@Article{wiki_innodb, + Title = {InnoDB}, + Journal = {Wikipedia}, + Year = {2013}, + + Owner = {Vikman}, + Timestamp = {2015.09.14}, + Url = {https://es.wikipedia.org/wiki/InnoDB} +} + +@Manual{bcm2835, + Title = {BCM 2835 ARM Peripherals}, + Organization = {Broadcom Corp.}, + Year = {2012}, + + Owner = {Vikman}, + Timestamp = {2015.08.29} +} + +@Manual{manpages, + Title = {Linux man-pages}, + Organization = {Linux Kernel Organization, Inc.}, + Year = {2012}, + + Owner = {Vikman}, + Timestamp = {2015.08.31} +} + +@Article{unity_bug, + Title = {Drag and drop not working in Unity (Ubuntu 12.04)}, + Journal = {Launchpad}, + Year = {2012}, + + Owner = {Vikman}, + Timestamp = {2015.09.16} +} + +@Manual{shiftreg, + Title = {SN74HC595 8-bit shift registers with 3-state output registers}, + Organization = {Texas Instruments Inc.}, + Year = {2009}, + + Owner = {Vikman}, + Timestamp = {2015.08.29} +} + +@Manual{datasheet_decoder, + Title = {HIRK-433 RF Receiver Decoder Hybrid}, + Year = {2008}, + + Owner = {Vikman}, + Timestamp = {2015.08.29} +} + +@Manual{datasheet_lcd, + Title = {FDCC2004B Character type dot matrix LCD module specification}, + Organization = {Fordata Electronic Co.}, + Year = {2005}, + + Owner = {Vikman}, + Timestamp = {2015.08.29} +} + +@Manual{midi, + Title = {Standard MIDI-File Format Spec. 1.1}, + Year = {2003}, - Owner = {GermanPortatil}, - Timestamp = {2015.05.06} + Owner = {Vikman}, + Timestamp = {2015.08.29}, + Url = {http://www.cs.cmu.edu/~music/cmsip/readings/Standard-MIDI-file-format-updated.pdf} } diff --git a/report/subdocs/Agradecimientos.tex b/report/subdocs/Agradecimientos.tex index d551aec..bb57b5f 100644 --- a/report/subdocs/Agradecimientos.tex +++ b/report/subdocs/Agradecimientos.tex @@ -17,11 +17,20 @@ \begin{onehalfspace} -Una carrera universitaria es una etapa de la vida, tal vez aquella en la que se tiene la máxima libertad para hacerse a uno mismo, y en ello influyen todas las personas que nos rodean. He tenido la suerte de tener a mi lado a los mejores, y les debo mi eterno agradecimiento a todos. - -A Papá y Mamá, por la vida y el cariño. A Laura, por ser la mejor hermana. A Daniel y Francisco, por las risas. A Paco y José Antonio, por ir un paso por delante. A Manolo y Jesús, por la Alianza. A la Peñita de Milán, por el Erasmus. A los Milestones, por la música. A Mariadel, por enseñarme a tocar el piano. Y a Salva, por explicarme lo que era un ordenador. - -También quiero expresar mi agradecimiento a todos los profesores de la Universidad de Granada por su inestimable esfuerzo por formarnos, así como a todas las personas implicadas en este proyecto: D. Andrés Roldán Aranda, mi tutor, Mikel Aguayo Fernández, ingeriero de la PCB, y el organista Juan Rodríguez Ruiz, nuestro más valioso colaborador. +Una carrera universitaria es una etapa de la vida, tal vez aquella en la que se tiene la máxima libertad para hacerse a uno mismo, y en ello influyen todas las personas que nos rodean. He tenido la suerte de estar con los mejores, y les debo mi eterno agradecimiento a todos. + +\begin{quote} + A mis padres, por la vida y el cariño. \\ + A Laura, por ser la mejor hermana. \\ + A Daniel y Francisco, por las risas. \\ + A Paco y José Antonio, por ir un paso por delante. \\ + A Manolo y Jesús, por la Alianza. \\ + A la Peñita de Milán, por el Erasmus. \\ + A los Milestones, por la música. \\ + Y a mi tío Salva, por meterme en el mundo de la informática. +\end{quote} + +También quiero expresar mi agradecimiento a todos los profesores de la Universidad de Granada por su inestimable esfuerzo por formarnos, así como a todas las personas implicadas en este proyecto: D. Andrés Roldán Aranda y Dª María Isabel García Arenas, mis tutores, Mikel Aguayo Fernández, ingeniero del hardware, y el organista Juan Rodríguez Ruiz, nuestro más valioso colaborador. \end{onehalfspace} diff --git a/report/subdocs/Apendices.tex b/report/subdocs/Apendices.tex index d322c32..2b0ea5f 100644 --- a/report/subdocs/Apendices.tex +++ b/report/subdocs/Apendices.tex @@ -1,10 +1,10 @@ %Begin ---- Para que funcione bien el TOC en PDF -\cleardoublepage +\clearpage{\pagestyle{empty}\cleardoublepage} \phantomsection \addcontentsline{toc}{chapter}{Apéndices} %END ---- Para que funcione bien el TOC en PDF -\chapter*{Apéndices} +%\chapter*{Apéndices} %\newpage %\thispagestyle{empty} %\chapter[Orden INT/316/2011 sobre seguridad privada]{Orden INT/316/2011, de 1 de febrero, sobre funcionamiento de los sistemas de alarma en el ámbito de la seguridad privada.} diff --git a/report/subdocs/ListaFiguras.tex b/report/subdocs/ListaFiguras.tex index ba55e66..723f09d 100644 --- a/report/subdocs/ListaFiguras.tex +++ b/report/subdocs/ListaFiguras.tex @@ -13,9 +13,6 @@ \tableofcontents \end{singlespacing}%onehalfspacing} - - - %Begin ---- Para que funcione bien el TOC en PDF \cleardoublepage \phantomsection \label{listoffig} diff --git a/report/subdocs/capitulo1.tex b/report/subdocs/capitulo1.tex index 0b82193..90eb721 100644 --- a/report/subdocs/capitulo1.tex +++ b/report/subdocs/capitulo1.tex @@ -1,32 +1,89 @@ -\chapter{Introducción.} +\chapter{Introducción y objetivos} \label{cap:capitulo_1} \pagenumbering{arabic} +\begin{quote} + \small \flushright ''\textit{Una partitura también es un lenguaje.}'' \\ + --- Profesor Buenaventura Clares Rodríguez (2013). +\end{quote} + +\vspace{4em} + \section{Contexto} -Llegado el momento de cursar la asignatura "Proyectos Informáticos" de la titulación, iniciamos los preparativos para desarrollar un proyecto propuesto por el Departamento de Electrónica y Tecnología de Computadores de la Universidad de Granada. +Llegado el momento de cursar la asignatura ''Proyectos Informáticos'' de la titulación, iniciamos los preparativos para desarrollar un proyecto propuesto por el Departamento de Electrónica y Tecnología de Computadores de la Universidad de Granada. Para plantearlo, nos hemos fijado en numerosas iglesias de Granada, que incorporan órganos de tubos, instrumentos muy complejos, muchos de ellos formando parte del inmobiliario, y merecedores de un gran reconocimiento por la artesanía y la calidad de su construcción. Lamentablemente, muchos de ellos están en un estado de abandono, debido principalmente a que si no se tocan regularmente, se deterioran y no se reparan, y al no hacerlo, no se pueden tocar, cayendo en un círculo vicioso. Además, creemos interesante la idea de que se pueda hacer sonar un órgano aunque no haya organista, dando la posibilidad tanto de acompañar celebraciones litúrgicas como de tener música de fondo durante el horario de visitas. -Nuestro objetivo es, por tanto, ingeniar un sistema automático capaz de interpretar piezas musicales para órgano, lo que incluye la creación de un sistema mecánico capaz de suplantar las pulsaciones del artista y el desarrollo del software necesario para que el sistema reproduzca partituras electrónicas en formato MIDI. - -\newpage - -Este proyecto atenderá al objetivo global pero se centrará en la parte software, ya que el hardware requiere competencias de Ingeniería Electrónica e Industrial, y será objeto del proyecto de D. Mikel Aguayo Fernández. - -Para abordarlo, hemos contado con la colaboración de Juan Rodríguez Ruiz, responsable del órgano de la Parroquia de la Encarnación de Santa Fe, que nos ha dado acceso tanto al instrumento como a asombrosos datos sobre su historia y su construcción. +\section{Objetivos} + +Nuestro propósito es ingeniar un sistema capaz de \textbf{interpretar partituras musicales en un órgano} suplantando las pulsaciones del artista, lo que incluye los siguientes objetivos: + +\begin{enumerate} + \item Analizar la \textbf{mecánica real} de un órgano. + + \begin{enumerate} + \item Tomar \textbf{medidas completas} de cada uno de los teclados, los pedales y las palancas de registros. + \item \textbf{Diseñar en 3D} los componentes principales del instrumento. + \item Determinar la \textbf{presión} necesaria para mover cada tecla, cada pedal y cada palanca del órgano. + \end{enumerate} + + \item Estudiar la comunicación entre el \textit{software} y el \textit{hardware}, incluyendo todos los \textbf{componentes electrónicos} que habrá de incluir. + + \item Plantear distintas \textbf{alternativas de sistemas empotrados} que sirvan de soporte de programación. + + \item Analizar el \textbf{protocolo \acrshort{MIDI}} como formato de archivo para almacenar partituras. + + \item \textbf{Diseñar} el sistema \textit{software} que cubrirá varias vías de comunicación entre el usuario y la mecánica, lo que comprende: + + \begin{enumerate} + \item Un \textbf{servicio en segundo plano}, que atienda: + + \begin{enumerate} + \item Reproducción de archivos \acrshort{MIDI}. + \item Comunicación inter-proceso. + \item Receptor de un mando a distancia. + \item Menú de control sobre el hardware, con un ''modo Ingeniería''. + \end{enumerate} + + \item Una \textbf{aplicación \textit{web}} para controlar el sistema, con soporte para: + + \begin{enumerate} + \item Reproducir partituras electrónicas. + \item Instalar nuevas piezas y gestionar listas de reproducción. + \item Configurar el mando a distancia. + \end{enumerate} + + \item Una \textbf{base de datos} como soporte de almacenamiento persistente. + \item Un \textbf{protocolo de comunicación} entre la aplicación y el servicio. + \end{enumerate} + + \item \textbf{Implementar} el sistema diseñado, como: + + \begin{enumerate} + \item Un demonio para Linux. + \item Un servicio \textit{web} sobre Apache y \acrshort{PHP}. + \item Una base de datos MySQL. + \end{enumerate} + + \item \textbf{Validar} junto al \textit{hardware} el proyecto desarrollado. +\end{enumerate} + +Este proyecto atenderá al objetivo global pero \textbf{el desarrollo se centrará en la parte \textit{software}}, ya que el \textit{hardware} requiere competencias de Ingeniería Electrónica e Industrial, y será objeto del proyecto de D. Mikel Aguayo Fernández. + +Para abordarlo, hemos contado con la colaboración de \textbf{Juan Rodríguez Ruiz}, responsable del órgano de la \textbf{Parroquia de la Encarnación de Santa Fe}, que nos ha dado acceso tanto al instrumento como a asombrosos datos sobre su historia y su construcción. \smallskip \begin{figure}[H] \noindent \begin{centering} -\includegraphics[width=\linewidth]{capitulo1/figura11} +\includegraphics[width=\linewidth]{capitulo1/parroquia} \par\end{centering} \smallskip -\caption{\label{fig:figura11} Parroquia de la Encarnación de Santa Fe.} -\end{figure} +\caption[Parroquia de la Encarnación de Santa Fe.]{\label{fig:parroquia} Parroquia de la Encarnación de Santa Fe. \cite{iglesias_granada}} +\end{figure} \newpage @@ -40,10 +97,10 @@ \section{Contenido y estructura capitular} \begin{figure}[H] \noindent \begin{centering} - \includegraphics[width=\linewidth/2]{capitulo1/figura12} + \includegraphics[width=\linewidth/2]{capitulo1/cascada} \par\end{centering} \smallskip - \caption{\label{fig:figura12} Modelo de desarrollo en cascada.} + \caption[Modelo de desarrollo en cascada.]{\label{fig:cascada} Modelo de desarrollo en cascada. \cite{wiki_cascada}} \end{figure} \smallskip @@ -54,9 +111,9 @@ \section{Contenido y estructura capitular} \item \textbf{Capítulo 2:} En este capítulo especificaremos los requisitos que supone el diseño del sistema para alcanzar nuestro objetivo, así como indicar las fases del proyecto. -\item \textbf{Capítulo 3:} Vamos a analizar todos los elementos con los que vamos a interactuar, desde el teclado del órgano hasta el computador sobre el que funcionará nuestro software. +\item \textbf{Capítulo 3:} Vamos a analizar todos los elementos con los que vamos a interactuar, desde el teclado del órgano hasta el computador sobre el que funcionará nuestro \textit{software}. -\item \textbf{Capítulo 4:} Plantearemos el diseño de la solución, haciendo Ingeniería el software, que cumpla de la mejor manera posible los requerimientos del \ref{cap:capitulo_2}. +\item \textbf{Capítulo 4:} Plantearemos el diseño de la solución, haciendo Ingeniería el \textit{software}, que cumpla de la mejor manera posible los requerimientos del \ref{cap:capitulo_2}. \item \textbf{Capítulo 5:} En esta parte explicaremos cómo hemos implementado la solución diseñada, y cómo hemos enfrentado los principales problemas que han surgido. diff --git a/report/subdocs/capitulo2.tex b/report/subdocs/capitulo2.tex index 89b4ff6..f60d81e 100644 --- a/report/subdocs/capitulo2.tex +++ b/report/subdocs/capitulo2.tex @@ -1,64 +1,156 @@ -\chapter{Requisitos técnicos del diseño} +\chapter{Requisitos técnicos} \label{cap:capitulo_2} -En este capítulo nos centraremos en detallar los requisitos técnicos de nuestro diseño a nivel tanto -\textit{hardware} como \textit{firmware} +\begin{quote} + \small \flushright ''\textit{Requisito no funcional nº 1: El diseño del sistema debe ser correcto.}'' \\ + --- Profesor José Parets Llorca (2013). +\end{quote} +\vspace{8em} +Como hemos adelantado, pretendemos diseñar un sistema autónomo capaz de hacer sonar un órgano de tubos, tal como lo haría un artista. El uso está enfocado a minimizar la interacción del usuario con el sistema. -\section{Requisitos \textit{hardware}} -A nivel \textit{hardware} se nos pide: -\begin{itemize} -\item[-] Diseñar una \acrshort{PCB} que sea capaz de realizar el control de temperatura de nuestro horno. -\item[-] Dotar a la \acrshort{PCB} de los dispositivos necesarios para la comunicación hombre-máquina. -\item[-] El mecanismo de control de la temperatura ha de ser un controlador PID. -\item[-] Los sensores de temperatura serán PT100 de cuatro hilos. -\end{itemize} +Para especificar el diseño de este proyecto hemos propuesto una serie de requisitos tanto \textit{hardware} como \textit{software}, que enumeramos a continuación. -\section{Requisitos \textit{firmware}} -A nivel \textit{firmware} debemos realizar un programa que contenga todas las rutinas que harán que nuestro horno funcione correctamente y la configuración de todos los dispositivos conectados a la \acrshort{PCB}. Además, deberemos realizar una interfaz gráfica en Matlab que sea capaz de comunicarse con nuestro microcontrolador, de manera que sea capaz de mandar y recibir datos. +\newpage +\section{Requisitos hardware} +\begin{enumerate} + + \item Un juego de mecanismos accionará las \textbf{teclas}, otro moverá los \textbf{pedales} y otro desplazará los \textbf{registros} de timbres. + + \item El sistema no podrá acceder a la mecánica interna del instrumento, ni modificarlo de ninguna forma. + + \item No podrá apoyarse demasiado peso sobre el órgano, ni hacerse contra-apoyo (hacia arriba). + + \item El \textbf{control principal}, la instalación de partituras y la configuración se harán \textbf{remotamente}. + + \item Se proveerá un \textbf{control local reducido} de los accionadores con fines de puesta en marcha y mantenimiento. + + \item Asimismo se facilitará el control remoto desde un \textbf{mando a distancia}. + + \item El diseño debe ser \textbf{flexible y extensible} para distintos órganos. + + \item Se debe de poder instalar y desinstalar fácilmente. + +\end{enumerate} -\section{Fases del proyecto} +\section{Requisitos software} + +Teniendo en cuenta los requisitos \textit{hardware} y el perfil del usuario final, planteamos los siguientes requisitos para el \textit{software} a diseñar: -A continuación expondremos las fases constitutivas del transcurso del proyecto, describiendo su contenido de manera generalizada. +\begin{enumerate} -Una vez expuestas las fases, se considerarán fechas iniciales y finales para cada tarea, a fin de contemplar que alcance temporal que implica el desarrollo del proyecto al completo. Las fechas marcarán el transcurso del trabajo. + \item Se ofrecerá \textbf{control remoto} para todos los casos de uso a nivel de usuario. + + \item La interfaz permitirá controlar la \textbf{reproducción}: iniciar una pieza, pausarla, reanudarla y detenerla. La reproducción por defecto será en modo bucle. + + \item Facilitará la subida y \textbf{gestión de partituras}. En dicho gestor se mostrará la duración de cada pieza. + + \item Los archivos a procesar son de formato \textbf{\acrshort{MIDI} estándar}, sin perjuicio de que una partitura pueda estar adaptada específicamente al sistema. + + \item Las piezas musicales se clasificarán en \textbf{listas de reproducción}. + + \item La interfaz de usuario permitirá \textbf{asignar} dichas listas a ciertos botones del mando arriba mencionado. + + \item El \textbf{mando} tendrá capacidad para reproducir una serie de listas pre-programadas, así como pausar y detener la reproducción. + + \item El \textit{software} dará soporte al \textbf{testeo} de los accionadores de forma local. + + \item El controlador debe ser \textbf{extensible} para órganos con más o menos teclas, distinto número de teclados o diferente configuración de registros. + + \item La aplicación para el usuario debe ser lo más \textbf{sencilla e intuitiva} posible. + + \item Se busca obtener una aplicación de control \textbf{multiplataforma}. + + \item La interfaz de usuario se presentará en varios \textbf{idiomas}. + + \item Ya que el control es remoto, se hará hincapié en la \textbf{seguridad}, tanto autentificación de acceso como aspectos de programación, tales como inyección de código. -\smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.8]{capitulo2/requerimientos_3} -\par\end{centering} -\smallskip -\caption{\label{fig:requerimientos_3} Principales fases de un proyecto \cite{WIKIPED}.} -\end{figure} +\end{enumerate} + +\newpage +\section{Fases del proyecto} -Las diferentes fases son: +Tal como hemos introducido anteriormente, vamos a dividir este proyecto en cuatro fases, cada una de las cuales servirá para obtener los requisitos necesarios para continuar la siguiente. Vamos a trabajar de la siguiente forma: \begin{enumerate} - \item[-] \textbf{FASE I- Especificaciones del sistema:} realizaremos un estudio detallado de los requerimientos del sistema de caracterización. + \item \textbf{FASE I --- Análisis:} Vamos a estudiar todos los componentes a los que tenemos acceso, desde el órgano hasta la placa de circuito y el computador a utilizar, pasando por la especificación del formato \acrshort{MIDI}. + + \item \textbf{FASE II --- Diseño:} En esta fase reunimos las especificaciones del sistema y los requisitos propuestos para definir el sistema que vamos a concebir, desde la interfaz al usuario hasta la interacción con el \textit{hardware}. + + \item \textbf{FASE III --- Implementación:} Es la etapa en la que se programa el \textit{software} a partir del diseño de la fase precedente, y prestaremos atención a los detalles de bajo nivel que se nos presentarán, desde llamadas al sistema y acceso a los periféricos hasta control de concurrencia. + + \item \textbf{FASE IV --- Verificación y validación:} Una vez terminada la fase de implementación, pondremos en funcionamiento el sistema para verificar que tanto el \textit{hardware} como el \textit{software} se integran correctamente y cumplen con los requisitos propuestos. + +\end{enumerate} + +\section{Planificación} + +En base a nuestro objetivo final, este proyecto está estrechamente relacionado con el de Mikel Aguayo Fernández, que abordará la parte relacionada con \textit{hardware}. - \item[-] \textbf{FASE II- Análisis y Diseño:} en esta fase se agrupan todos los requerimientos y especificaciones de la fase anterior y se trata de concebir la composición del sistema. Consideraremos todos aquellos elementos \textit{hardware}, \textit{software} y estructurales necesarios. Analizaremos las funcionalidades de cada equipo electrónico y/o mecánico utilizado, determinando su utilidad dentro del sistema. Diseñaremos y simularemos, mediante un \textit{software} específico. +Nuestro diseño será genérico para cualquier órgano pero \textbf{específico para la plataforma} \textit{hardware}. Por tanto, hay una parte del sistema que no se puede diseñar hasta conocer el proyecto de la \acrshort{PCB}. Para realizar una correcta planificación es necesario tener en cuenta qué parte de nuestro diseño depende del de Mikel Aguayo. - \item[-] \textbf{FASE III- Desarrollo e Implementación:} se fabrica todo el componente hardware diseñado en la fase II y se le incorporan los distintos dispositivos y componentes. Una vez terminado se procede a la programación del algoritmo \glsname{PID} y, ayudándonos de algunas librerías, configuraremos los devices para su correcto funcionamiento. +\subsection{Dependencias entre tareas} - \item[-] \textbf{FASE IV- Testeo y Validación:} una vez se ha concluido el proceso de fabricación e implementación, solo queda validar el funcionamiento global del conjunto, resolviendo defectos y anomalías \textit{hardware} y también depurando fallos \textit{software} y aportando algunas mejoras puntuales. Tras esto, la obtención de datos y resultados. +Esencialmente tenemos los siguientes puntos en común: + +\begin{enumerate} + \item Compartimos inicialmente los \textbf{requisitos}, para entonces clasificarlos entre nuestros proyectos. + \item El otro proyecto necesita el \textbf{análisis} realizado sobre el órgano. + \item El nuestro, a su vez, depende del \textbf{diseño} que se haga de la \acrshort{PCB}. + \item La \textbf{verificación} vuelve a poner en común nuestros trabajos. \end{enumerate} +La siguiente figura descompone a \textit{grosso modo} las tareas e ilustra las \textbf{dependencias} encontradas: -\smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.5]{capitulo2/requerimientos_2} -\par\end{centering} \smallskip -\caption{\label{fig:fases_proy_step} Analogía de fases.} -\end{figure} +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo2/planificacion} + \par\end{centering} + \smallskip + \caption{\label{fig:planificacion} Diagrama de dependencia de tareas.} +\end{figure} -\clearpage{\cleardoublepage} -\clearpage{\pagestyle{empty}\cleardoublepage} +\newpage + +A la vista de este diagrama, esbozaremos la \textbf{planificación temporal} de esta forma: +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo2/plan_gantt} + \par\end{centering} + \smallskip + \caption{\label{fig:plan_gantt} Diagrama de Gantt básico.} +\end{figure} + +\smallskip + +\subsection{Planificación prevista} + +Conocidas las tareas básicas a realizar, proponemos la siguiente planificación para todos los bloques a desarrollar en el sistema. Hemos asignado principalmente las tareas por \textbf{semanas}, aunque algunas de ellas se podrán hacer en común por su simplicidad, y otras deberemos \textbf{descomponerlas} en prototipo e implementación final. + +El primer paso es \textbf{analizar} el funcionamiento y la mecánica del órgano para permitir a Mikel continuar su trabajo. Mientras él diseña la \acrshort{PCB}, nosotros comenzamos el \textbf{diseño} de los módulos que no dependen de ésta. Tan pronto como recibamos su diseño, podremos desarrollar el resto del sistema. + +\newpage + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[height=\textheight]{capitulo2/gantt} + \par\end{centering} + \smallskip + \caption{\label{fig:gantt} Diagrama de Gantt para planificación.} +\end{figure} + +\smallskip + + + +\newpage +\clearpage{\pagestyle{empty}\cleardoublepage} diff --git a/report/subdocs/capitulo3.tex b/report/subdocs/capitulo3.tex index 58175f7..67fb70a 100644 --- a/report/subdocs/capitulo3.tex +++ b/report/subdocs/capitulo3.tex @@ -1,108 +1,939 @@ - -\chapter{Análisis del sistema.} +\chapter{Análisis del sistema} \label{cap:capitulo_3} -En este capítulo se detallará la fase de análisis del proyecto, partiendo de los requisitos técnicos explicados en el capítulo \ref{cap:capitulo_2}. Se detallarán las distintas opciones de diseño y los problemas y soluciones que han ido apareciendo a lo largo del proyecto. -\section{Análisis del horno} -La figura XXXXX muestra el diagrama de nuestro horno con los elementos más importantes. EL horno está controlado principalmente por el termostato que se encargará de encender/apagar el relé que permite el paso de corriente hacia las resistencias que calientan el horno. -A continuación se dará una explicación más detallada de los distintos componentes. +\begin{quote} + \small \flushright ''\textit{Esto es más simple que el mecanismo de un botijo.}'' \\ + --- Profesor Miguel Delgado Calvo-Flores (2011). +\end{quote} + +\vspace{8em} + +Como paso previo al diseño del sistema, deberemos conocer con detalle todos los elementos con los que va a interactuar nuestro sistema, así como plantear diferentes alternativas de cara al desarrollo del \textit{software}. + +En primer lugar estudiaremos el órgano de la Parroquia de la Encarnación, desde los teclados hasta su mecánica. A continuación conoceremos el diseño del \textit{hardware} que nos servirá para controlar el instrumento. Después estudiaremos algunas alternativas disponibles como soporte de programación, y por último analizaremos en profundidad el formato de archivo \acrshort{MIDI}. + +\newpage -\subsection{Termostato} +\section{Órgano de la Parroquia de Santa Fe} -Un termostato es un componente de un sistema de control que comprueba la temperatura de un sistema de manera que mantiene la temperatura de dicho sistema cercana a una consigna. El termostato consigue esto mediante el calentamiento o enfriamiento de dispositivos en on o off. En nuestro caso, mediante el calentamiento de unas resistencias que cederán calor al interior del horno. +El instrumento instalado en la Parroquia de la Encarnación de Santa Fe es en realidad un doble órgano artesanal construido en dos fases: En 1775 se instaló el primer órgano, de estilo \textbf{barroco}, obra del organero Pedro Ghys. Posteriormente, a principios de la década de 1830, el francés Guillermo D'Enoyer lo amplía añadiendo un órgano \textbf{romántico}, con un segundo teclado y nuevos sonidos, pero todo el mecanismo es independiente del primer instrumento. -\smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.1]{capitulo3/termostato} -\par\end{centering} \smallskip -\caption{\label{fig:termostato} Termostato.} -\end{figure} +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo3/consola} + \par\end{centering} + \smallskip + \caption{\label{fig:consola} Consola del órgano.} +\end{figure} -\subsection{Termistor} -Un termistor es un dispositivo que cambia su impedancia dependiendo de la temperatura. +\smallskip -La impedancia del termistor es leída por un sistema de control, usualmente basado en un microcontrolador, que es programado para realizar diferentes operaciones a determinadas temperaturas. -Dicha temperatura la veremos reflejada en un termómetro de mercurio situado en la parte frontal del horno. +Para funcionar, el órgano se alimenta de \textbf{aire}. Antiguamente se utilizaba un fuelle gigante, situado en la antesala, que llevaba el aire a una cámara de almacenamiento, para proporcionar un flujo de entrada constante. Esto requería que hubiese alguien accionándolo mientras el organista tocaba. Hoy día el fuelle ha sido sustituido por una \textbf{bomba eléctrica}. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo3/mecanismos} + \par\end{centering} + \smallskip + \caption{\label{fig:mecanismos} Mecanismos detrás de la consola.} +\end{figure} + +\smallskip + +Los entresijos del órgano barroco, el más grande, está construidos en dos plantas: en la parte más baja, a la altura de la consola, encontramos los juegos de \textbf{palancas}, de las cuales aquellas pertenecientes al órgano barroco suben a la planta superior. A sendos laterales encontramos el corazón del órgano romántico, más pequeño. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo3/romantico} + \par\end{centering} + \smallskip + \caption{\label{fig:romantico} Tubos del órgano romántico.} +\end{figure} + +\smallskip + +En la planta de arriba se encuentra la esencia del instrumento: alrededor de \textbf{600 tubos} de diferentes timbres y alturas sonoras, incluyendo el bajo de \textit{contrast}, que se hace sonar con el \textit{pedalier}. Solo los \textbf{diapasones} ---los flautados de 13' fundamentales y las cornetas--- son visibles desde el exterior. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo3/barroco} + \par\end{centering} + \smallskip + \caption{\label{fig:barroco} Tubos del órgano barroco.} +\end{figure} + +\smallskip + +La parte más importante del órgano es el llamado \textbf{secreto}, una galería a la que entra el aire procedente de la cámara de almacenamiento y se distribuye en cientos de conductos que llevan a las válvulas y los tubos. Siendo éste el corazón de la obra, dentro de él se halla una partitura firmada por el constructor del órgano. En tiempos en los que no existían los manguitos de goma, los conductos están tallados artesanalmente dentro de bloques de madera. + +La primera tarea que llevamos a cabo fue conocer el órgano en profundidad, tomar algunas medidas y \textbf{diseñar el modelo en 3D} con el \textit{software} \textit{SolidWorks}. + +\newpage +\subsection{Teclados} + +Tenemos dos teclados de cuatro octavas notas cada uno, el de arriba, correspondiente al órgano barroco, y otro más abajo, que sobresale del primero, para el órgano romántico, de la misma extensión. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo3/teclados} + \par\end{centering} + \smallskip + \caption{\label{fig:teclados} Teclados del órgano.} +\end{figure} + +\smallskip + +Tanto las \textbf{medidas} de cada tecla como su \textbf{calado} (diferencia entre la posición del borde de una tecla pulsada y sin pulsar) son estándar y coincidentes con las del piano. De la misma forma, la tecla \textit{Do} del centro hace sonar la nota \textit{Do 4} \footnotemark. + +\footnotetext{En España se utilizan dos índices de notación musical: el franco-belga, que asigna el nombre \textit{La 3} a la nota cuya frecuencia fundamental vibra a 440 \textit{Hz}, y el índice científico, que asigna \textit{La 4} a la misma nota. En este proyecto utilizaremos el índice científico, ya que es el utilizado para el sistema \acrshort{MIDI}.} + +Los datos más relevantes son los siguientes: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline Número de teclas & 49 / teclado \\ + \hline Extensión & \textit{Do 2} -- \textit{Do 6} \\ + \hline Profundidad de calado (blancas) & 10 \textit{mm} \\ + \hline Profundidad de calado (negras) & 8 \textit{mm} \\ + \hline Presión máxima & 2,70 \textit{N} \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:teclados} Medidas de los teclados.} +\end{center} + +\newpage + +Cada \textbf{tecla blanca} tiene unas medidas ligeramente diferentes en su parte interna, para permitir que las negras encajen perfectamente. Todas las teclas del mismo nombre son \textbf{idénticas}. Las medidas de una tecla blanca son las siguientes: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo3/blanca_modelo} + \par\end{centering} + \smallskip + \caption{\label{fig:blanca_modelo} Medidas de una tecla blanca.} +\end{figure} + +\newpage + +Las \textbf{teclas negras}, en cambio, son más cortas y más delgadas, sobresaliendo del teclado entre las blancas. Producen las notas cromáticas. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*2/3]{capitulo3/negra_modelo} + \par\end{centering} + \smallskip + \caption{\label{fig:negra_modelo} Medidas de una tecla negra.} +\end{figure} + +\smallskip + +A continuación presentamos las medidas tomadas sobre el teclado en conjunto: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo3/teclado_modelo} + \par\end{centering} + \smallskip + \caption{\label{fig:teclado_modelo} Medidas del teclado.} +\end{figure} + +\smallskip + +Cabe destacar que, a diferencia del piano, la intensidad del sonido no viene dada por la fuerza con la que se pulse una tecla, y no es necesario pulsarla hasta el tope de calado para que suene, basta con hacerla bajar tan solo unos milímetros, lo necesario para \textbf{vencer la válvula}. + +\subsection{Pedales} + +Este órgano cuenta con un \textit{pedalier} con un registro fijo: el \textbf{bajo de \textit{contrast}}. Los pedales están dispuestos en forma de escala diatónica, igual que las teclas. Cada pedal tiene aproximadamente la misma anchura que una tecla aunque, obviamente, están más separados unos de otros. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo3/pedalier} + \par\end{centering} + \smallskip + \caption{\label{fig:pedalier} \textit{Pedalier} del órgano.} +\end{figure} + +\smallskip + +Es importante saber que el \textbf{peso} necesario para mover un pedal es mucho mayor que para una tecla, asimismo, tanto la naturaleza artesanal como el deterioro crean mucha disparidad entre el tacto de cada pedal. + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline Número de pedales & 12 \\ + \hline Extensión & \textit{Do 1} -- \textit{Si 1} \\ + \hline Profundidad de calado (diatónicas) & 14,5 \textit{mm} \\ + \hline Profundidad de calado (cromáticas) & 19,8 \textit{mm} \\ + \hline Presión máxima & 30,54 \textit{N} \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:pedalier} Medidas del \textit{pedalier}.} +\end{center} + +\smallskip + +Por su parte, las cotas que definen el \textit{pedalier} son las siguientes: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo3/pedalier_modelo} + \par\end{centering} + \smallskip + \caption{\label{fig:pedalier_modelo} Medidas de los pedales.} +\end{figure} + +\smallskip + +\subsection{Registros} + +Los registros son las diferentes \textbf{familias de tubos} con el mismo timbre y la misma tesitura. Se pueden abrir o cerrar desde la consola a través de una serie de palancas, de las que se tira para hacer sonar el registro o se empuja para silenciarlo. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*2/3]{capitulo3/registros} + \par\end{centering} + \smallskip + \caption{\label{fig:registros} Registros a la derecha del teclado.} +\end{figure} + +\smallskip + +Estos controles están dispuestos a ambos lados de los teclados y son \textbf{exclusivos} para un teclado u otro. En este órgano existen registros \textbf{parciales}, esto es, se aplican solo a una mitad del teclado, bien de \textit{Do 2} a \textit{Si 3}, o bien de \textit{Do 4} a \textit{Do 6}. + +Dado que el punto interno de equilibro de cada palanca está en lugares diferentes, existe una notable \textbf{disparidad} en la medida en que sobresalen cuando se abren. Además, tenemos una palanca especial, el \textbf{\textit{tremolo}}, que sirve para activar un mecanismo que produce un efecto de fluctuación en el sonido. + +A continuación mostramos las medidas de longitud tomadas durante el análisis. + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline \multicolumn{2}{|c|}{\textbf{A la izquierda}} \\ + \hline & Bajoncillo (142 \textit{mm}) \\ + \hline & Flautado de 13' sordina (160 \textit{mm}) \\ + \hline & Flautado de 13' (175 \textit{mm})\\ + \hline & Octava (161 \textit{mm}) \\ + \hline & Quincena (161 \textit{mm}) \\ + \hline Trémolo (67 \textit{mm}) & Decimonovena (165 \textit{mm}) \\ + \hline Bajón-oboe (103 \textit{mm}) & Lleno (140 \textit{mm}) \\ + \hline Flauta armenia (1106 \textit{mm}) & Clarín (160 \textit{mm}) \\ + \hline Violón (100 \textit{mm}) & Trompeta real (144 \textit{mm}) \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:registros_izquierda} Medidas de los registros (izquierda).} +\end{center} -\hfill -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.3]{capitulo3/termistor} -\par\end{centering} \smallskip -\caption{\label{fig:termistor} Termistor.} -\end{figure} - +\begin{center} + \begin{tabular}{|l|l|} + \hline \multicolumn{2}{|c|}{\textbf{A la derecha}} \\ + \hline Clarín (170 \textit{mm}) & \\ + \hline Corneta (141 \textit{mm}) & \\ + \hline Flautado de 13' sordina (137 \textit{mm}) & \\ + \hline Flautado de 13' (134 \textit{mm}) & \\ + \hline Octava (142 \textit{mm}) & \\ + \hline Docena (142 \textit{mm}) & \\ + \hline Quincena (168 \textit{mm}) & \\ + \hline Lleno (156 \textit{mm}) & Voz humana (110 \textit{mm}) \\ + \hline Clarín (142 \textit{mm}) & Voz celeste (116 \textit{mm}) \\ + \hline Trompeta real (135 \textit{mm}) & Gamba (102 \textit{mm}) \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:registros_derecha} Medidas de los registros (derecha).} +\end{center} + +\smallskip + +\newpage + +\section{PCB de control} + +La placa de circuito impreso es la solución a los requisitos \textit{hardware} aportada por el \textbf{proyecto de Mikel Aguayo Fernández} \cite{mikel}. Incluye una serie de registros de desplazamiento para almacenar el estado del órgano, una interfaz de control local reducido y un medio de control remoto. También alimentará al computador que vamos a utilizar. Actualmente disponemos de un \textbf{prototipo} de la placa con un número limitado de salidas. + +Una de las partes más importantes de este proyecto será desarrollar el \textit{software} controlador para esta \acrshort{PCB}. A continuación detallamos aquellos componentes con los que tendremos que interactuar. + +\subsection{Registros de desplazamiento SN74HC595} +Los registros de desplazamiento son circuitos lógicos que almacenan una serie de bits y permiten desplazarlos de una celda a otra. Este modelo tiene una capacidad de \textbf{8 bits}, soporta entrada en serie y salida en paralelo con registro de almacenamiento \cite{shiftreg}. -\subsection{Relé} -Un relé es un dispositivo electromecánico que mediante una bobina y un electroimán acciona uno o varios contactos que permitirán la apertura o el cierre de otros circuitos eléctricos independientes. En nuestro caso, permitirá el paso de la corriente que calentará por efecto Joule las resistencias que cederán energía en forma de calor al horno. +Así, solo necesitamos un pin para enviar toda la información, y la salida no se ve alterada durante el desplazamiento, sino que damos un \textbf{pulso de reloj} para indicar que hemos terminado de enviar los datos. -\smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.8]{capitulo3/rele} -\par\end{centering} \smallskip -\caption{\label{fig:rele} Relé multi9 CT.} -\end{figure} -Este rele tiene un voltaje de operación de 250 V AC y 25 A. Y su esquemático lo podemos ver a continuación en la figura \ref{fig:esquema_rele}\cite{multi9}. +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/4]{capitulo3/SN74HC595} + \par\end{centering} + \smallskip + \caption{\label{fig:SN74HC595} Pines del SN74HC595. } +\end{figure} -\smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.8]{capitulo3/esquema_rele} -\par\end{centering} \smallskip -\caption{\label{fig:esquema_rele}Esquema relé de dos puertas.} -\end{figure} -\subsection{Fusibles} -Los fusibles son pequeños dispositivos que permiten el paso constante de la corriente eléctrica hasta que ésta supera el valor máximo permitido. Cuando aquello sucede, entonces el fusible, inmediatamente, cortará el paso de la corriente eléctrica a fin de evitar algún tipo de accidente, protegiendo los aparatos eléctricos de "quemarse" o estropearse.. +La información más relevante es la siguiente: -El mecanismo que posee el fusible para cortar el paso de la electricidad consta básicamente en que, una vez superado el valor establecido de corriente permitido, el dispositivo se derrite, abriendo el circuito, lo que permite el corte de la electricidad. De no existir este mecanismo, o debido a su mal funcionamiento, el sistema se recalentaría a tal grado que podría causar, incluso, un incendio. +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline Capacidad & 8 \textit{bits} / canal \\ + \hline Canales & 4 \\ + \hline Ancho de pulso & 100 ns \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:info_regdespl} Características de los registros de desplazamiento.} +\end{center} - -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.2]{capitulo3/fusible} -\par\end{centering} \smallskip -\caption{\label{fig:fusible} Fusible.} -\end{figure} -El fusible incorporado en el horno tiene las siguientes características: +Basándonos en el órgano de la Parroquia de Santa Fe, tendremos cuatro registros de desplazamiento, uno para cada canal: \begin{itemize} -\item Soplado de acción rápida. -\item Capacidad de ruptura de intensidad AC de 100 kA. -\item Intensidad de 6 A. -\item Tensión nominanl de 600V. + \item \textbf{Canal 1}: teclado barroco. + \item \textbf{Canal 2}: teclado romántico. + \item \textbf{Canal 3}: registros. + \item \textbf{Canal 4}: pedalier. \end{itemize} +A pesar de que la capacidad de cada canal es de 8 bits, solo utilizaremos 7 de ellos. +\subsection{Conexión a la mecánica} +\label{subsec:conexion_mecanica} + +Los registros de desplazamiento están diseñados para albergar el \textbf{estado lógico} de cada una de las piezas del órgano con las que vamos a interactuar, y se han dispuesto cuidadosamente para que, clasificados por canales, cada uno se dedique a una zona de la consola del instrumento, manteniendo una interfaz lógica similar con objeto de \textbf{homogeneizar la interfaz} de cara al \textit{software}. + +\subsubsection{Teclados} + +Los dos primeros canales de control están asignados a los teclados. Un \textbf{\textit{driver} de potencia} interno aumentará la \textbf{tensión} a la salida de cada registro para llevarlo a la mecánica que pulsará las teclas. La siguiente figura ilustra este funcionamiento: + +\smallskip -\section{Modificaciones del horno} -En primer lugar empezaremos analizando que módificaciones serán necesarias en el horno. +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo3/pcb_teclado} + \par\end{centering} + \smallskip + \caption{\label{fig:pcb_teclado} Interfaz entre la \acrshort{PCB} y el teclado barroco.} +\end{figure} -Ya hemos visto cómo funciona, y vimos que el control del encendido y apagado para el calentamiento lo lleva a cabo el termostato. Nosotros queremos controlar todo desde una \acrshort{PCB} controlada por un microcontrolador, por lo que tendremos que quitar el termostato de manera que desde la \acrshort{PCB} podamos seguir controlando el horno. La solución que se llevó a cabo fue la de realizar un \textit{bypass} al termostato de manera que no tenga ningún control sobre nuestro horno. +\smallskip + +Los dos teclados se comportan de la misma forma, aunque al de abajo le corresponderá un canal diferente. + +\subsubsection{Pedalier} + +El \textit{pedalier} representa una escala musical, con los pedales bajos similares a las teclas blancas, diatónicas, mientras que los pedales altos emulan a las teclas negras, cromáticas. Por tanto, el esquema de funcionamiento es similar al de los teclados, aunque con menos extensión. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo3/pcb_pedalier} + \par\end{centering} + \smallskip + \caption{\label{fig:pcb_pedalier} Interfaz entre la PCB y el pedalier.} +\end{figure} + +\smallskip -El termostato controla un relé que es el que hace que se circule o no la corriente hacia las resistencias que calientan el horno. Al usar un control \glsname{PID}, controlaremos el horno con una señal \acrshort{PWM}. +\subsubsection{Registros de timbres} -Las señales \acrshort{PWM} cambian de alta a baja en periodos de tiempo muy pequeños. Al ser el relé un elemento de conmutación mecánica, el cambio de estado tan rápido a la larga hara que se rompa. Por lo que se opta por quitarlo y hacer ese cambio de estado ON/OFF mediante un optotriac que irá incorporado en la \acrshort{PCB}. +Como podemos ver, los registros no se corresponden con teclas musicales y no tienen el mismo significado. Sin embargo, sí que tienen la misma \textbf{estructura lógica}, al contemplarse dos posiciones: \underline{abierto} (hacia afuera) y \underline{cerrado} (hacia dentro). -\section{Localización de la \acrshort{PCB}} -Disponemos de varias opciones donde colocar la \acrshort{PCB}, aunque no se tomará ninguna decisión hasta que no tengamos la \acrshort{PCB} fabricada. +La mecánica a utilizar será diferente y, probablemente, algo más compleja, pero la interfaz para manejarlos se asemejará a del resto de controles: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo3/pcb_registros} + \par\end{centering} + \smallskip + \caption{\label{fig:pcb_registros} Interfaz entre la PCB y las palancas de registros.} +\end{figure} + +\smallskip + +\subsection{Receptor de mando a distancia HIRK-433A} +\label{analisis_mando} + +El receptor de mando a distancia es un detector de radio con decodificador a interfaz RS-232. Nos da la información del \textbf{número de serie} del mando y qué \textbf{botones} han disparado el evento. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[clip=true,trim=0 200 0 200, width=\linewidth/2]{capitulo3/HIRK-433A} + \par\end{centering} + \smallskip + \caption[Receptor de radio HIRK-433A.]{\label{fig:HIRK-433A} Receptor de radio HIRK-433A. \cite{imagen_decoder}} +\end{figure} + +\smallskip + +Es flexible para mandos con distinto número de botones y los indica como un campo de bits basados en la letra A. Si el carácter corresponde a una minúscula, nos avisa de que el mando tiene \textbf{poca batería}. Por ejemplo: \begin{itemize} -\item Parte superior del horno. -\item Lateral del horno. -\item Interior del horno abriendo agujeros para que sean accesibles los dispositivos de comunicación hombre-máquina. + \item \textbf{A}: Botón 1. + \item \textbf{B}: Botón 2. + \item \textbf{C}: Botones 1 y 2. + \item \textbf{d}: Botón 3 (batería baja). + \item \textbf{H}: Botón 4. \end{itemize} +La siguiente tabla muestra los datos de nuestro interés: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline Interfaz & RS-232 \\ + \hline Velocidad & 9600 \textit{baudios} \\ + \hline Longitud de trama & 10 \textit{bytes} \\ + \hline Sintaxis & \\ + \hline + \end{tabular} + \smallskip + \captionof{table}[Características del receptor de mando.]{\label{tab:info_recv} Características del receptor de mando. \cite{datasheet_decoder}} +\end{center} + +\smallskip + +\subsection{Pantalla LCD FDCC2004B} + +Esta pantalla es un \acrshort{LCD} (\textit{\acrlong{LCD}}) genérico basado en el Hitachi HD44780, considerado un estándar \textit{de facto} para este tipo de dispositivos. Tiene una pequeña \textbf{memoria} para almacenar el estado (no hay que enviar continuamente la información), tiene los caracteres \acrshort{ASCII} predefinidos y tiene capacidad para configurar hasta 8 caracteres especiales. + +Esta pieza presenta el siguiente aspecto: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo3/FDCC2004B} + \par\end{centering} + \smallskip + \caption{\label{fig:FDCC2004B} LCD FDCC2004B.} +\end{figure} + +\smallskip + +La siguiente tabla muestra sus características principales \cite{datasheet_lcd}: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline Tipo & \acrshort{LCD} retroiluminado \\ + \hline Filas & 4 \\ + \hline Columnas & 20 \\ + \hline Dimensión de celda & 5 x 8 \textit{pixels} \\ + \hline Caracteres especiales & 8 \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:info_lcd} Características de la pantalla LCD.} +\end{center} + +\smallskip + +\subsection{Codificador rotatorio EC11J} +\label{subsec:rotary} + +Un codificador rotatorio es un componente electrónico consistente en un \textbf{botón giratorio}, y emite una señal cuyas características dependen del sentido en que el usuario ha girado el botón. El modelo que vamos a utilizar contiene un botón \textbf{giratorio y pulsable}. \cite{rotary} + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/4]{capitulo3/rotary} + \par\end{centering} + \smallskip + \caption{\label{fig:rotary} Codificador rotatorio EC11J.} +\end{figure} + +\smallskip + +La información nos viene dada por tres canales: uno para el pulsador y dos para la rotación. A medida que rotamos el botón, A y B oscilan produciendo una \textbf{señal cuadrada} que viene desfasada 90\textdegree, como la que aparece en la siguiente imagen: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/3]{capitulo3/rotary_signal} + \par\end{centering} + \smallskip + \caption{\label{fig:rotary_signal} Código de señales utilizado por el codificador rotatorio.} +\end{figure} + +\smallskip + +Los \textbf{puntos de equilibro} ---\textit{detent stability points}--- coinciden con los saltos del canal B, de forma que a la mitad del recorrido de un giro cambiará el canal A. Todo lo que tenemos que hacer entonces es detectar un cambio en A y comparar el valor de A y B: si son iguales, significa que se ha rotado en sentido antihorario; si son distintos, entendemos que se ha girado en sentido horario. + +De la parte del \textbf{pulsador}, los botones pueden presentar problemas de \textbf{rebotes}. Para diseñar una solución en caso de ser necesario, analizamos con un \textbf{osciloscopio} la señal que produce una pulsación: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*2/3]{capitulo3/rebotes} + \par\end{centering} + \smallskip + \caption{\label{fig:rebotes} Señal producida por una pulsación.} +\end{figure} + +\smallskip + +En resumen, condensamos la información que nos será útil en la siguiente tabla: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline Giro & Canales A y B \\ + \hline Pulsación & Canal C \\ + \hline Punto de equilibro & Saltos del canal B \\ + \hline Giro a derecha & $A\neq B$ \\ + \hline Giro a izquierda & $A=B$ \\ + \hline Tiempo de incertidumbre & $118 \; \mu s$\\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:info_rotary} Características del codificador rotatorio.} +\end{center} + +\smallskip + +\subsection{Zumbador PKLCS1212E4001-R1} + +Este componente es un dispositivo piezoeléctrico que produce un sonido agudo continuado. A diferencia de un altavoz, está diseñado para producir \textbf{ondas cuadradas}. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/3]{capitulo3/buzzer} + \par\end{centering} + \smallskip + \caption[Zumbador PKLCS1212E4001-R1.]{\label{fig:buzzer} Zumbador PKLCS1212E4001-R1. \cite{buzzer}} +\end{figure} + +\smallskip + +El siguiente gráfico muestra la \textbf{frecuencia de respuesta} de este zumbador: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo3/buzzer_freq} + \par\end{centering} + \smallskip + \caption{\label{fig:buzzer_freq} Frecuencia de respuesta del zumbador.} +\end{figure} + +\smallskip + +\subsection{Conexión entre la PCB y los periféricos} + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo3/pcb_perifericos} + \par\end{centering} + \smallskip + \caption{\label{fig:pcb_perifericos} Interfaz entre la PCB y los periféricos.} +\end{figure} + +\smallskip + +\newpage + +\section{Plataforma Arduino} + +\textit{Arduino} es una placa basada en un \textbf{microcontrolador}: el \textit{ATmega328}. Con unas características básicas, es una opción muy interesante a la hora de utilizar un sistema informático para programar \textit{hardware}. + +Sus especificaciones son las siguientes: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline Modelo & Arduino Uno rev. 3 \\ + \hline Microcontrolador & Atmel ATmega328 @ 16 \textit{MHz}\\ + \hline Memoria SRAM & 2 \textit{KB} \\ + \hline Memoria Flash & 32 \textit{KB} \\ + \hline Memoria EPROM & 1 \textit{KB} \\ + \hline Pines digitales & 14 (6 con salida \acrshort{PWM}) \\ + \hline Pines analógicos & 6 \\ + \hline Alimentación & 7 - 12 \textit{V} \\ + \hline + \end{tabular} + \smallskip + \captionof{table}[Especificaciones del Arduino Uno]{\label{tab:rapberry} Especificaciones del Arduino Uno. \cite{arduino}} + +\end{center} + +\smallskip + +Esta placa tiene, entre muchas otras ventajas, la posibilidad de recibir \textbf{entradas analógicas} y generar \textbf{modulación por ancho de pulso} (\acrshort{PWM}) desde el propio controlador, una característica poco común en ordenadores. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo3/arduino} + \par\end{centering} + \smallskip + \caption{\label{fig:arduino} Placa Arduino Uno.} +\end{figure} + +\smallskip + +El hecho de utilizar un microcontrolador nos permite desarrollar \textit{software} sencillo y trabajar a bajo nivel sin dificultades. Además, al no disponer de sistema operativo su funcionamiento es determinista, siendo más fácil desarrollar \textit{software} en \textbf{tiempo-real}. + +\newpage + +\section{SBC Rasberry Pi} + +El \textit{Raspberry Pi} es un \textbf{ordenador} de placa única ---\acrshort{PCB} (\textit{\acrlong{SBC}})---, más potente que un microcontrolador y con \textbf{sistema operativo} basado en Linux. Se alimenta por \textit{USB} y se puede controlar con teclado y ratón, o bien desde red mediante \acrshort{SSH}. + +El corazón de este computador es un \textbf{\acrshort{SOCA}} (\textit{\acrlong{SOCA}}), que integra microprocesador, memoria y periféricos principales. El modelo escogido, \textit{B+}, posee numerosos pines de entrada y salida de propósito general (\textbf{\acrshort{GPIO}}), que utilizaremos para interactuar con la \acrshort{PCB} y para ser \textbf{alimentado} por ésta. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo3/raspberry} + \par\end{centering} + \smallskip + \caption{\label{fig:raspberry} Placa computadora Raspberry Pi.} +\end{figure} + +\smallskip + +\subsection{Especificaciones técnicas} + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline Modelo & Raspberry Pi B+ v1.2 \\ + \hline \acrshort{SOCA} & Broadcom BCM2835 \\ + \hline Procesador & 1176JZF-S @ 700 \textit{MHz} \\ + \hline Repertorio de instrucciones & ARMv6 (\textit{RISC} 32-\textit{bit}) \\ + \hline Memoria & 512 \textit{MB} @ 400 \textit{MHz} \\ + \hline Procesador gráfico & Broadcom VideoCore IV \\ + \hline Almacenamiento & Micro-\acrshort{SD} 8 \textit{GB} \textit{class 10} \\ + \hline Salida de vídeo & \acrshort{HDMI} \\ + \hline Salida de audio & \textit{Jack} 3.5 \textit{mm}, \acrshort{HDMI} \\ + \hline Conectividad USB & 4 x \acrshort{USB} 2.0 \\ + \hline Conectividad de red & \textit{Ethernet} 100 \textit{Mbit/s} \\ + \hline Periféricos & 28xGPIO, \acrshort{UART}, \acrshort{I2C}, \acrshort{SPI} \\ + \hline Alimentación & 5V Micro-\acrshort{USB} o \acrshort{GPIO} \\ + \hline Consumo máximo & 1.8 \textit{A} (9 \textit{W}) \\ + \hline Sistema operativo & Raspbian (Linux 3.8) \\ + \hline + \end{tabular} + \smallskip + \captionof{table}[Especificaciones del Raspberry Pi.]{\label{tab:rapberry} Especificaciones del Raspberry Pi. \cite{raspberry}} + +\end{center} + +\smallskip + +\subsection{Sistema operativo} + +A pesar de su reducido tamaño, \textit{Raspberry Pi} no es un microcontrolador, sino un \textbf{microcomputador}, con una cantidad notable de recursos \textit{hardware} y potencia de cálculo suficiente para albergar \textbf{múltiples procesos} funcionando concurrentemente. Esto hace necesario el uso de un sistema operativo. + +Podemos encontrar varios sistemas operativos compatibles con este computador, pero nosotros vamos a utilizar el sistema oficial: \textbf{\textit{Raspbian}}, una distribución basada en \textit{Debian}, que incorpora el núcleo \textbf{GNU/Linux} para la plataforma \textit{ARMv6}. + +La introducción de un sistema operativo flexibiliza enormemente la gestión de los recursos \textit{hardware} de un ordenador y garantiza la \textbf{convivencia} equitativa de todos los procesos. Por contra, esto significa que ninguna aplicación podrá utilizar la \acrshort{CPU} a tiempo completo, ni se garantiza tiempo-real. + +El \textit{BCM2835} posee un \textbf{temporizador} de 1 \textit{MHz}. A pesar de esta velocidad, cada vez que se agote el tiempo de espera de un proceso, éste no es llamado inmediatamente, sino que se lleva a la cola de procesos. Esto garantiza un uso adecuado de los recursos \textit{software} al tiempo que hace imposible realizar comunicaciones síncronas a alta velocidad mediante programación. + +Además, la versión utilizada del núcleo Linux es \textbf{apropiativa} ---\textit{preemptive}---, lo que significa que una rutina en modo \textit{kernel} puede bloquearse para dar paso a un servicio de interrupción, incluso que una interrupción puede verse bloqueada por otra de mayor prioridad (interrupciones anidadas). + +En conclusión, el uso de un sistema operativo de este tipo, a pesar de ser de gran utilidad, no garantiza sincronismo ni que una espera solicitada sea tan exacta como se pide. + +\subsection{Pines de E/S} + +Como hemos adelantado, la \acrshort{PCB} se conectará al \textit{Raspberry Pi} a través de los conectores \acrshort{GPIO} (\textit{\acrlong{GPIO}}). Todos ellos se utilizarán de forma \textbf{genérica}, excepto el receptor del mando a distancia, que se comunica con la interfaz \textit{RS-232} y debe conectarse al \textbf{\acrshort{UART}} mediante el pin dedicado a tal periférico. + +El siguiente esquema ilustra las conexiones entre la \acrshort{PCB} y el \textit{Raspberry Pi}: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo3/pcb_gpio} + \par\end{centering} + \smallskip + \caption{\label{fig:pcb_gpio} Pines de conexión de la PCB con el Raspberry Pi.} +\end{figure} + +\smallskip + +La asignación de pines es la que sigue: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline \multicolumn{2}{|c|}{\textbf{Registros de desplazamiento}} \\ + \hline S1 (teclado barroco) & \acrshort{GPIO} 02 \\ + \hline S2 (teclado romántico) & \acrshort{GPIO} 03 \\ + \hline S3 (registros) & \acrshort{GPIO} 04 \\ + \hline S4 (\textit{pedalier}) & \acrshort{GPIO} 17 \\ + \hline RCLK (almacenamiento) & \acrshort{GPIO} 27 \\ + \hline SRCLK (desplazamiento) & \acrshort{GPIO} 22 \\ + \hline \multicolumn{2}{|c|}{\textbf{Receptor de radio}} \\ + \hline O/P-AF (datos) & \acrshort{GPIO} 15 (RDX) \\ + \hline \multicolumn{2}{|c|}{\textbf{Pantalla \acrshort{LCD}}} \\ + \hline DB4 (línea 4 del bus) & \acrshort{GPIO} 12 \\ + \hline DB5 (línea 5 del bus) & \acrshort{GPIO} 07 \\ + \hline DB6 (línea 6 del bus) & \acrshort{GPIO} 08 \\ + \hline DB7 (línea 7 del bus) & \acrshort{GPIO} 25 \\ + \hline RS (selección de registro) & \acrshort{GPIO} 20 \\ + \hline ES (habilitación de señal) & \acrshort{GPIO} 16 \\ + \hline \multicolumn{2}{|c|}{\textbf{Codificador rotatorio}} \\ + \hline Canal A (rotación) & \acrshort{GPIO} 18 \\ + \hline Canal B (rotación) & \acrshort{GPIO} 24 \\ + \hline Pulsación & \acrshort{GPIO} 23 \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:gpio} Asignaciones de los pines del GPIO.} +\end{center} + +\smallskip + +\newpage + +\section{Formato de archivo MIDI} +\label{sec:fmto_midi} + +El estándar \acrshort{MIDI} (\acrlong{MIDI}) es una interfaz que permite conectar \textbf{instrumentos musicales} electrónicos y computadoras. Comprende desde un protocolo electrónico hasta un formato de archivos, que se basa en una serie de \textbf{eventos de control} de parámetros musicales. \cite{wiki_midi} + +Los datos de entrada a nuestro sistema consisten en archivos \acrshort{MIDI}, tal como se menciona en los requisitos. Este tipo de ficheros se presenta como un conjunto de \textbf{bloques} ---\textit{chunks}--- que contienen los eventos clasificados por pistas. Todos los valores numéricos están en formato \textbf{\textit{big-endian}}, detalle a tener en cuenta, ya que tanto la arquitectura x86 como ARM trabajan en \textit{little-endian}. \cite{midi} + +\subsection{Bloque de cabecera} + +El bloque de cabecera es siempre el \textbf{primero}, empieza por la firma ''MThd'' e incluye la siguiente información: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|l|} + \hline \multicolumn{1}{|c|}{\textbf{Longitud}} & \multicolumn{1}{c|}{\textbf{Descripción}} & \multicolumn{1}{c|}{\textbf{Valor}} \\ + \hline 4 bytes & Firma & ''MThd'' \\ + \hline 4 bytes & Tamaño & 6 \\ + \hline 2 bytes & Formato & 0--2 \\ + \hline 2 bytes & Número de pistas & 1--65535 \\ + \hline 2 bytes & División de tiempo & \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:midi_header} Contenido de la cabecera MIDI.} +\end{center} + +\smallskip + +\begin{description} + \item[Formato] Es la forma en que se organizan las pistas. Puede ser: + \begin{description} + \item[0] Una sola pista. + \item[1] Varias pistas, simultáneas. + \item[2] Varias pistas, independientes. + \end{description} + + \item[Número de pistas] Indica de cuántas pistas se compone el archivo. Obviamente, si el formato es 0, el valor de este campo será 1. + + \item[División de tiempo] Nos indica el significado de cada \textit{tick} de reloj del protocolo como divisiones de una negra (\quarternote). Valores típicos son 96, 120, 180, 192, 240, 360, 384, 480, 640, 720, 768 y 960 \textit{ticks}/\quarternote. Si el \textit{bit} más significativo es 1, el valor indica en su lugar el número de \textit{ticks/fotograma}, habitualmente utilizado en realización de vídeo. +\end{description} + +\subsection{Bloque de pista} + +Una pista consta de una cabecera y de una lista de eventos, que termina con el meta-evento \textit{fin de pista}. + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|l|} + \hline \multicolumn{1}{|c|}{\textbf{Longitud}} & \multicolumn{1}{c|}{\textbf{Descripción}} & \multicolumn{1}{c|}{\textbf{Valor}} \\ + \hline 4 bytes & Firma & ''MTrk'' \\ + \hline 4 bytes & Tamaño & 0-65535 \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:midi_track} Contenido de la cabecera de una pista MIDI.} +\end{center} + +\smallskip + +\subsection{Eventos MIDI} + +Cada evento está formado por los siguientes campos: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline \multicolumn{1}{|c|}{\textbf{Longitud}} & \multicolumn{1}{c|}{\textbf{Descripción}} \\ + \hline Variable & $\Delta$ \\ + \hline 1 byte & Tipo de evento y canal \\ + \hline 1 byte & Parámetro 1 \\ + \hline 1 byte & Parámetro 2 \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:midi_evento} Especificación de un evento MIDI.} +\end{center} + +\smallskip + +\begin{description} + \item[$\Delta$] Indica el número de \textit{ticks} que separan al evento actual del precedente. + \item[Tipo de evento y canal] Los cuatro \textit{bits} más significativos corresponden al tipo de evento. Los otros cuatro marcan el canal \acrshort{MIDI}. +\end{description} + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|l|l|} + \hline \multicolumn{4}{|c|}{\textbf{Tipos de evento}} \\ + \hline \multicolumn{1}{|c|}{\textbf{Valor}} & \multicolumn{1}{c|}{\textbf{Nombre}} & \multicolumn{1}{c|}{\textbf{Parámero 1}} & \multicolumn{1}{c|}{\textbf{Parámetro 2}} \\ + \hline 0x80 & NOTE-OFF & Nota & Velocidad \\ + \hline 0x90 & NOTE-ON & Nota & Velocidad \\ + \hline 0xA0 & NOTE-AFTERTOUCH & Nota & Velocidad \\ + \hline 0xB0 & CONTROLLER & Controlador & Valor \\ + \hline 0xC0 & PROGRAM-CHANGE & Programa & \\ + \hline 0xD0 & CHANNEL-AFTERTOUCH & Velocidad & \\ + \hline 0xE0 & PITCH-BEND & \multicolumn{2}{c|}{Valor} \\ + \hline 0xF0 & SYSTEM-EXCLUSIVE & \multicolumn{2}{c|}{} \\ + \hline 0xFF & Meta-evento & \multicolumn{2}{c|}{} \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:midi_eventos} Eventos MIDI.} +\end{center} + +\smallskip + +\subsubsection{Meta-eventos} + +Los metaeventos son mensajes de control que extienden la semántica de los eventos normales. Tienen la siguiente estructura: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline \multicolumn{1}{|c|}{\textbf{Longitud}} & \multicolumn{1}{c|}{\textbf{Descripción}} \\ + \hline Variable & $\Delta$ \\ + \hline 1 byte & 0xFF \\ + \hline 1 byte & Tipo de metaevento \\ + \hline Variable & Longitud del argumento \\ + \hline (Longitud) & Valor del argumento \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:midi_mevaevento} Especificación de un meta-evento MIDI.} +\end{center} + +\smallskip + +Los tipos de meta-evento estándar son los siguientes: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline \multicolumn{2}{|c|}{\textbf{Tipos de meta-evento}} \\ + \hline \multicolumn{1}{|c|}{\textbf{Valor}} & \multicolumn{1}{c|}{\textbf{Nombre}} \\ + \hline 0x00 & Número de secuencia \\ + \hline 0x01 & Texto \\ + \hline 0x02 & Noticia de \textit{copyright} \\ + \hline 0x03 & Nombre de la secuencia \\ + \hline 0x04 & Nombre del instrumento \\ + \hline 0x05 & Letra de la canción \\ + \hline 0x06 & Marca \\ + \hline 0x07 & Punto de corte \\ + \hline 0x08 & Nombre del programa \\ + \hline 0x09 & Nombre del dispositivo \\ + \hline 0x20 & Canal por defecto (obsoleto) \\ + \hline 0x21 & Puerto por defecto (obsoleto) \\ + \hline 0x2F & Fin de pista \\ + \hline 0x51 & \textit{Tempo} ($\mu s/\quarternote$) \\ + \hline 0x54 & Desplazamiento temporal \\ + \hline 0x58 & Indicación de compás \\ + \hline 0x59 & Indicación de tonalidad \\ + \hline 0x7F & Reservado para el secuenciador \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:midi_metaeventos} Meta-eventos MIDI.} +\end{center} + +\smallskip + +\subsubsection{Notas} + +Las notas en \acrshort{MIDI} se indican numéricamente, en base 0, asignando valores a las notas cromáticas a partir de \textit{Do -1}. Por ejemplo, al \textit{Do central (Do 4)} le corresponde el valor 60. + +\newpage + +\section{Esquema de interconexión general} + +Todos los elementos que hemos descrito conformarán la parte \textit{hardware} del sistema y establecerán una conexión cuyos extremos son el \textbf{computador} \textit{Raspberry Pi} y los \textbf{mecanismos} que interactuarán con la consola del órgano. + +A continuación presentamos un diagrama que describe a \textit{grosso modo} la \textbf{conexión lógica} entre todos los elementos contemplados: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo3/general} + \par\end{centering} + \smallskip + \caption{\label{fig:general} Conexión lógica entre los elementos hardware.} +\end{figure} + +\smallskip + +La \acrshort{PCB} está conectada mediante la interfaz \acrshort{GPIO}. Las conexiones harán funcionar los mecanismos del órgano, pasando por los registros de desplazamiento, que retendrán el estado. + +El resto de \textbf{periféricos} de la placa nos serán de utilidad para desarrollar un sistema que cumplirá todos los requisitos contemplados en el capítulo \ref{cap:capitulo_2}. +\newpage +\clearpage{\pagestyle{empty}\cleardoublepage} \ No newline at end of file diff --git a/report/subdocs/capitulo4.tex b/report/subdocs/capitulo4.tex index 5cccc90..e44209b 100644 --- a/report/subdocs/capitulo4.tex +++ b/report/subdocs/capitulo4.tex @@ -1,405 +1,2061 @@ -\chapter{Diseño del sistema.} +\chapter{Diseño del sistema} \label{cap: capitulo_4} -Durante el presente capítulo se expondrán los procedimientos de diseño \textit{hardware} e implementación \textit{software} la PCB que controlará nuestro horno. +\begin{quote} + \small \flushright ''\textit{Esa es la diferencia entre un ingeniero pata negra y otro papa frita.}'' \\ + --- Profesor Andrés María Roldán Aranda (2009). +\end{quote} -En esta sección se analizaran las soluciones tomadas para cumplir los requisitos propuestos en el capítulo \ref{cap:capitulo_2}. +\vspace{8em} +En este capítulo vamos a detallar cómo hemos concebido la solución a los requisitos \textit{software}, teniendo en cuenta los correspondientes al \textit{hardware} y a partir de los elementos que hemos descrito en el capítulo anterior. -\section{Implementación \textit{Hardware}} +\newpage -A la hora de diseñar la parte \textit{hardware} hemos de tener en cuenta las distintas partes de las que constará nuestro sistema para su correcto funcionamiento. +\section{Planteamiento} -\begin{itemize} - \item Control y procesamiento: Hay que seleccionar la solución óptima en el control y -procesamiento de forma que tenga la capacidad de llevar a cabo toda la funcionalidad, -y que sea una solución robusta y del menor coste posible. - \item Sistemas de medida de temperatura: Se precisa buscar la manera de medir la temperatura de la manera más precisa posible y teniendo en cuenta los rangos de temperatura en los que trabaja el horno(0-300$^{\circ}C$). - \item Elección de los componentes: Se tomarán las decisiones para elegir la solución más adecuada entre las posibilidades planteadas anteriormente. +Como idea más abstracta, el \textit{software} que tenemos que diseñar consiste en un \textbf{reproductor de archivos \acrshort{MIDI}}, que recibe el fichero y lo envía a la \acrshort{PCB} a través del \acrshort{GPIO}. Por supuesto, la reproducción estará controlada por el usuario. + +Este esquema representa la idea de funcionamiento general: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo4/idea} + \par\end{centering} + \smallskip + \caption{\label{fig:idea} Planteamiento inicial.} +\end{figure} + +\smallskip + +Luego, dividiremos el sistema en cuatro grandes bloques. Respecto al de \textbf{control}, se requiere varias formas de acceder al sistema: + +\begin{enumerate} + \item Un \textit{software} controlador principal, que cubra todos los casos de uso, y sea fácil de instalar y utilizar, con preferencia de que sea multiplataforma. -\end{itemize} + \item Un mando a distancia, que altere la reproducción. + + \item Un control reducido empotrado en la \acrshort{PCB}. +\end{enumerate} +Atendiendo a los requisitos del primer controlador, decidimos enfocar la solución como una \textbf{interfaz \textit{web}} con un servidor. De esta forma podemos llegar fácilmente a cualquier sistema operativo de escritorio, incluso es fácilmente adaptable a \textbf{dispositivos móviles}. +Además de atender peticiones de control remoto, hay que atender las señales del mando a distancia y manejar los controles de la \acrshort{PCB}. Un microcontrolador como \textit{Arduino} difícilmente será capaz de realizar tantas funciones simultáneas. Este motivo, sumado a la idea de la interfaz \textit{web} nos hacen \textbf{decantarnos por el \textit{Raspberry Pi}}. -\subsection{Control y procesamiento} -El control y procesamiento es la parte más importante a nivel \textit{hardware}. Es por ello que debemos empezar por aquí. El resto de apartados dependerán de nuestra elección. +Sin embargo, el reproductor no puede funcionar dentro de un servidor \textit{web}, ya que éstos atienden peticiones sin estado, y se cierran automáticamente después de devolver la información. Por ello, vamos a diseñar el reproductor como un \textbf{demonio} de Linux, junto con sus módulos auxiliares. -Para este proyecto se precisa un dispositivo fácil de programar, lo más barato posible, compatible con distintos componentes externos y con un módulo de conversores A/D. +Este programa, además de gestionar la reproducción de archivos \acrshort{MIDI}, proporcionará la interfaz de \textbf{control reducido}, para manejar la mecánica desde la \acrshort{PCB}. Además, despachará las órdenes del \textbf{mando a distancia}. -Aunque la mejor opción hubiera sido el uso de un PIC, porque nos permite diseñar un sistema a la medida de nuestras necesidades. Debido al poco tiempo del que disponía, se opto por usar un Arduino UNO. -\begin{itemize} - \item Open Source: Arduino es una plataforma de código y hardware abierto, es decir, puedes acceder a todo aspecto del funcionamiento circuital y algorítmico de las placas, y mucho mejor que eso, te dan todos los archivos Eagle, diagramas y componentes para que tu mismo crees tu versión de Arduino. - \item Fácil de programar: Arduino te ofrece un entorno de desarrollo integrado (IDE) con funciones preestablecidas que reducen la lógica a lectura de entradas, control de tiempos y salidas de una manera semántica e intuitiva. - \item Documentación y tutoriales en exceso: Internet esta plagado literalmente de documentación sobre esta plataforma. - \item Librerías: Una de las ventajas mas grandes que tiene Arduino es que poseen librerías para prácticamente cualquier componente externo que se le quiera acoplar. - \item Precio: Las placas de Arduino tienen un precio de entre 21\$ y 71\$, dependiendo del modelo que elijamos. -\end{itemize} +En último lugar, necesitamos \textbf{almacenar información} sobre los archivos \acrshort{MIDI}, listas de reproducción y asignaciones del mando en memoria persistente. Una \textbf{base de datos} nos permitiría guardar toda esa información de manera estructurada y coherente, además de ser fácilmente accesible por todos los componentes del sistema. + +\bigskip +\section{Demonio del reproductor} -\subsection{Sistema de medida de temperatura} -Para la obtención de la temperatura se ha optado por el uso de sensores PT100. Consiste en un alambre de -platino que a 0 °C tiene 100 ohms y que al aumentar la temperatura aumenta su resistencia eléctrica. El incremento de la resistencia no es lineal pero si creciente y característico del platino de tal forma que mediante tablas(figura \ref{fig:tablaPT100}) es posible encontrar la temperatura exacta a la que corresponde. +Un demonio ---\textit{daemon}--- es un proceso que se ejecuta en \textbf{segundo plano} en la fase de arranque del sistema operativo, y no interactúa directamente con el usuario, sino que se comunica con \textbf{otros procesos} a través de herramientas proporcionadas por el sistema operativo. \cite{wiki_demonio} + +Este programa será el \textbf{núcleo} de nuestro sistema, y ofrecerá las siguientes \textbf{vías} para comunicarse: + +\begin{enumerate} + \item Un \textbf{\textit{socket} local} de Linux. Será usado principalmente por la interfaz \textit{web}, pero es una forma flexible y eficiente para que lo hagan más aplicaciones. + + \item El \textbf{puerto en serie} (\acrshort{UART}) del \textit{Raspberry Pi}, para recibir órdenes del mando. + + \item Los \textbf{pines del \acrshort{GPIO}} correspondientes al codificador rotatorio y el \acrshort{LCD}, para la interfaz reducida. +\end{enumerate} + +Así, el esquema de uso de los distintos componentes queda así: -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=1.1]{capitulo4/tablaPT100} -\par\end{centering} -\caption{\label{fig:tablaPT100} Tabla de resistencias de una PT100.} \smallskip -\end{figure} -Un Pt100 es un tipo particular de RTD (Dispositivo Termo Resistivo). Normálmente las Pt100 industriales se consiguen encapsuladas en la misma forma que las termocuplas, es decir dentro de un tubo de acero inoxidable ú otro material (vaina) , en un extremo está el elemento sensible (alambre de platino) y en el otro está el terminal eléctrico de los cables protejido dentro de una caja redonda de aluminio (cabezal). -Las Pt100 siendo lévemente más costosos y mecánicamente no tán rígidos como las termocuplas, las superan -especiálmente en aplicaciones de bajas temperaturas (-100 a 200 $^{\circ}C$). -Los Pt100 pueden fácilmente entregar precisiones de una décima de grado con la ventaja que la Pt100 no se descompone graduálmente entregando lecturas erroneas, si no que normálmente se abre, con lo cual el dispositivo medidor detecta inmediátamente la falla del sensor y da aviso. -Existen 3 modos de conexión para las Pt100, cada uno de ellos requiere un instrumento lector distinto. -El objetivo es determinar exactamente la resistencia electrica R(t) del elemento sensor de platino sín que influya en la lectura la resistencia de los cables Rc. En nuestro caso usaremos una PT100 de 4 hilos. +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/daemon} + \par\end{centering} + \smallskip + \caption{\label{fig:daemon} Diagrama de uso entre los componentes del reproductor.} +\end{figure} -El método de 4 hilos es el más preciso de todos, los 4 cables pueden ser distintos (distinta resistencia) pero el instrumento lector es más costoso. +\smallskip + +\subsection{Descodificador de MIDI} +\label{subsec:daemon_midi} + +Como hemos detallado más arriba, el formato \acrshort{MIDI} expone los eventos de control en \textbf{orden temporal}, clasificados por pistas, habitualmente simultáneas. Debemos proporcionar una estructura de datos que permita mantener cada archivo a reproducir en memoria y facilitar el acceso individual a cada pista. + +Concebimos la estructura de datos principal como un \textbf{conjunto de pistas}, compuestas a su vez de \textbf{eventos}. El tamaño de los eventos normales es constante, sin embargo, los \textbf{meta-eventos} extienden la semántica con una cadena de datos. + +El siguiente diagrama de clases ilustra la \textbf{estructura de datos} completa: -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.6]{capitulo4/PT100_4hilos} -\par\end{centering} -\caption{\label{fig:PT100_4hilos} Conexión de una PT100 de 4 hilos.} \smallskip -\end{figure} -Por los cables 1 y 4 se hace circular una corriente I conocida a traves de R(t) provocando una diferencia de potencial V en los extremos de R(t). Los cables 2 y 4 están conectados a la entrada de un voltímetro de alta impedancia luego por estos cables no circula corriente y por lo tanto la caida de potencial en los cables Rc2 y Rc3 será cero (dV=Ic*Rc=0*Rc=0) y el voltímetro medirá exáctamente el voltaje V en los extremos del elemento R(t). Finalmente el instrumento obtiene R(t) al dividir V medido entre la corriente I conocida. +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo4/uml_midi} + \par\end{centering} + \smallskip + \caption{\label{fig:uml_midi} Diagrama de clases para el módulo MIDI.} +\end{figure} + +\smallskip + +\subsubsection{Clase MidiFile} + +Define un archivo \acrshort{MIDI}. Sus atributos son: + +\begin{description} + \item[format : \textit{enum}] Formato del archivo. Puede tener los siguientes valores enumerados: + + \begin{description} + \item[SINGLE\_TRACK] Una sola pista. + \item[MULTIPLE\_SIMULTANEOUS] Varias pistas, simultáneas. + \item[MULTIPLE\_INDEPENDENT] Varias pistas, independientes. + \end{description} + + \item[division : \textit{enum}] Unidad de medida de la división de tiempo: + + \begin{description} + \item[TICKS\ PER\ BEAT] La división se especifica en \textit{ticks}/\quarternote. + \item[FRAMES\_PER\_SECOND] La división se especifica en \textit{ticks/fotograma}. + \end{description} + +\end{description} + +La clase declara los siguientes métodos: -La corriente I conocida se consigue mediante una fuente de corriente constante que se detellará en el apartado \ref{sec:BC} +\begin{description}[style=nextline] + \item[MidiFile (path)] + Constructor, lee un archivo \acrshort{MIDI}. + + \begin{description} + \item[path : \textit{string}] Ruta del fichero a leer. + \end{description} + + \item[duration () : \textit{float}] + Obtener la duración de una pieza en segundos. + + \item[length : \textit{integer}] + Devuelve el número de pistas contenidas en el archivo. + + \item[get (n) : \textit{MidiFile}] + Devuelve la pista indicada. + + \begin{description} + \item[n : \textit{integer}] Índice de pista. + \end{description} +\end{description} -\subsection{Elección de componentes} +\subsubsection{Clase MidiTrack} -En este apartado se seleccionarán los dispositivos que usaremos para el correcto funcionamiento de nuestra PCB y así conseguir cumplir los requisitos propuestos. +Esta clase se modela como una colección de los eventos pertenecientes a cada pista de un archivo \acrshort{MIDI}. -Se intentaran buscar los dispositivos más baratos, de menor consumo posible y a ser posible con montaje superficial \acrshort{SMD} (\acrlong{SMD}). +Solo contiene un atributo intrínseco y un constructor: -Los distintos dispositivos y componentes seleccionados son los siguientes: +\begin{description} + \item[size : \textit{integer}] Tamaño en \textit{bytes} que ocupa la pista en el fichero. +\end{description} -\begin{itemize} - \item Arduino UNO - \item Display \glsname{LCD} 4x20A - \item Regulador de voltaje LM7805 - \item Transistor PNP BC857 - \item Rotary Encoder - \item Optotriac MOC3061M - \item Triac BT139 -\end{itemize} +\begin{description} + \item[MidiTrack (file)] + Construye una pista a partir de un fichero abierto. + + \begin{description} + \item[file : \textit{MidiFile}] Archivo \acrshort{MIDI} abierto. Su tipo depende del sistema subyacente. + \end{description} +\end{description} + +\subsubsection{Clase MidiEvent} + +Define un evento \acrshort{MIDI}. + +\begin{description} + \item[delta : \textit{integer}] Separación temporal respecto al evento anterior. + \item[type : \textit{enum}] Tipo de evento. Se enumeran en la tabla \ref{tab:midi_eventos}. + \item[param1 : \textit{byte}] Valor del primer parámetro, dependiendo del tipo de evento. + \item[param2 : \textit{byte}] Valor del segundo parámetro, dependiendo del tipo de evento. +\end{description} + +Los parámetros se consideran privados, ya que su semántica depende del tipo de evento. Por tanto, estableceremos los siguientes métodos para obtener la información adecuada: + +\begin{description}[style=nextline] + \item[MidiEvent (delta, type, p1, p2)] + Crea un nuevo evento. + + \begin{description} + \item[delta : \textit{integer}] Separación temporal respecto al evento precedente. + \item[type : \textit{enum}] Tipo de evento. + \item[p1 : \textit{byte}] Valor del primer parámetro. + \item[p2 : \textit{byte}] Valor del segundo parámetro. + \end{description} + + \item[parse (file) : \textit{list(MidiEvent)}] + Analiza un archivo \acrshort{MIDI} en el punto en que estaba abierto, hasta encontrar un evento de final de pista. + + \begin{description} + \item[file : \textit{MidiFile}] Archivo \acrshort{MIDI} abierto. Su tipo depende del sistema subyacente. + \end{description} + + Devuelve una lista de eventos. + + \item[note () : \textit{byte}] + Código de nota musical. + + \item[velocity () : \textit{byte}] + Velocidad de pulsación (intensidad del sonido). + + \item[aftertouch () : \textit{byte}] + Variación de intensidad. + + \item[controller () : \textit{byte}] + Número de controlador. + + \item[value () : \textit{byte}] + Valor del controlador. + + \item[program () : \textit{byte}] + Número de programa. + + \item[pitch () : \textit{byte}] + Valor del \textit{pitch-bend}. +\end{description} -\subsubsection{Arduinio UNO} -Se optó por usar un Arduino UNO \cite{Arduino}, ya que cubría todas nuestras necesidades y era uno de los modelos más baratos. +\subsubsection{Clase MetaEvent} -Arduino es una placa con un microcontrolador de la marca Atmel, el ATMega328 \cite{ATMega}, y con toda la circuitería de soporte, que incluye, reguladores de tensión, un puerto USB (En los últimos modelos, aunque el original utilizaba un puerto serie) conectado a un módulo adaptador USB-Serie que permite programar el microcontrolador desde cualquier PC de manera cómoda y también hacer pruebas de comunicación con el propio chip. -Un arduino dispone de 14 pines que pueden configurarse como entrada o salida y a los que puede conectarse cualquier dispositivo que sea capaz de transmitir o recibir señales digitales de 0 y 5 V. -También dispone de entradas y salidas analógicas. Mediante las entradas analógicas podemos obtener datos de sensores en forma de variaciones continuas de un voltaje. Las salidas analógicas suelen utilizarse para enviar señales de control en forma de señales \acrshort{PWM}. +Define un meta-evento. Extiende la clase \textit{MidiEvent} y presenta un atributo privado: + +\begin{description} + \item[data : \textit{string}] Cadena de datos correspondientes al meta-evento. +\end{description} + +Podemos interactuar con el meta-evento mediante los siguientes métodos, cada uno será válido para el tipo de meta-evento que corresponda. + +\begin{description}[style=nextline] + \item[MetaEvent (delta, type, data)] + Crea un nuevo meta-evento. + + \begin{description} + \item[delta : \textit{integer}] Separación temporal respecto al evento precedente. + \item[type : \textit{enum}] Tipo de evento. + \item[data : string] Cadena de datos correspondientes al meta-evento. + \end{description} + + \item[number () : \textit{integer}] + Número de secuencia. + + \item[text () : \textit{string}] + Texto del meta-evento. + + \item[channel () : \textit{byte}] + Devuelve el canal por defecto. + + \item[tempo () : \textit{float}] + Velocidad de ejecución del pasaje musical, en \textit{$\mu s / \quarternote$}. + + \item[offset () : \textit{array(integer)}] + Desplazamiento temporal. Devuelve una tupla con el siguiente contenido: + + \begin{enumerate} + \item Velocidad en \textit{cuadros / s}. + \item Hora. + \item Minuto. + \item Segundo. + \item Cuadro (\textit{frame}). + \end{enumerate} + + \item[time () : \textit{array(integer)}] + Devuelve la marca de compás mediante una tupla de la siguiente manera: + + \begin{enumerate} + \item Numerador. + \item Denominador como fracción de redonda. (\fullnote =1, \halfnote = 2, \quarternote =4, \eighthnote =8 ...) + \item Número de \textit{ticks} entre cada marca del metrónomo. + \item Subdivisión, en \textit{fusas / click}. + \end{enumerate} + + \item[key () : \textit{array(integer)}] + Devuelve la tonalidad de la pieza, mediante una tupla con el siguiente significado: + + \begin{enumerate} + \item Número de $\sharp$ si es positivo, o número de $\flat$ si es negativo. + \item Modo, de forma enumerada: + + \begin{description} + \item[MAJOR] Modo mayor. + \item[MINOR] Modo menor. + \end{description} + \end{enumerate} +\end{description} + +\subsubsection{Diagrama de uso} + +El módulo \acrshort{MIDI} solo se usa directamente a través del planificador. Éste se encarga de gestionar las partituras, y ordenar su eliminación cuando sea necesario. \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.2]{capitulo4/ArduinoUno} -\par\end{centering} -\caption{\label{fig:ArduinoUno} Vista frontal de Arduino UNO .} -\end{figure} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/daemon_midi} + \par\end{centering} + \smallskip + \caption{\label{fig:daemon_midi} Diagrama de uso del módulo MIDI.} +\end{figure} + \smallskip -A continuación expondremos el mapeado de pines del Arduino UNO, disponible en la página web de Arduino \cite{Arduino}. +\subsection{Control por socket} +\label{subsec:daemon} + +Un \textit{socket} un mecanismo de \textbf{comunicación inter-proceso} ---\acrshort{IPC} (\textit{\acrlong{IPC}})--- que proporciona Linux y enviar y recibir datagramas en modo \textit{duplex}, bien dentro de la misma máquina (\textit{socket} local) o en una red (\textit{socket} de Internet). + +Vamos a crear un \textbf{\textit{socket} local}, accesible desde el sistema de archivos de Linux, que escuche peticiones de los clientes que se conecten, utilizando una interfaz basada en \textbf{lenguaje natural}, que explicaremos en la sección \ref{sec:protocolo}. + +\subsubsection{Funciones públicas} + +Las funciones diseñadas para el uso externo son las siguientes: + +\begin{description}[style=nextline] + \item[socket\_init (uid, gid) : \textit{integer}] + Inicializar el \textit{socket} con el ID de usuario y grupo indicados. + + \begin{description} + \item[uid : \textit{integer}] ID de usuario en Linux. + \item[gid : \textit{integer}] ID de grupo en Linux. + \end{description} + + Devuelve 0 en caso de éxito y -1 en caso de error. + + \item[socket\_destroy ()] + Cierra el \textit{socket}. + + \item[socket\_loop ()] + Despliega una hebra con un bucle de escucha y atiende las peticiones. + +\end{description} + +\subsubsection{Funciones privadas} + +\begin{description}[style=nextline] + \item[socket\_play (arg, loop) : \textit{integer}] + Reestructura la lista de reroducción (del protocolo de comunicación a una lista de cadenas de caracteres) e inicia la ejecución. + + \begin{description} + \item[arg : \textit{string}] Cadena de caracteres recibida, conteniendo la lista de archivos. + \item[loop : \textit{integer}] 1 para reproducir en bucle o 0 para hacerlo secuencialmente. + \end{description} + + Devuelve 0 en caso de éxito o -1 en caso de error. + +\end{description} + +\subsubsection{Diagrama de uso} +El módulo correspondiente al \textit{socket} solamente interacciona internamente con el planificador, al que transmite adecuadamente las órdenes recibidas. \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=1]{capitulo4/ARDUINOPINMAP} -\par\end{centering} -\caption{\label{fig:ARDUINOPINMAP} Arduino UNO pin mapping.} -\end{figure} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/daemon_socket} + \par\end{centering} + \smallskip + \caption{\label{fig:daemon_socket} Diagrama de uso del servidor socket.} +\end{figure} + \smallskip +\subsection{Control del mando} +\label{subsec:daemon_mando} +Como hemos indicado en el capítulo anterior, el receptor del mando a distancia está conectado al \textit{Raspberry Pi} a través de los pines correspondientes al dispositivo \textbf{\acrshort{UART}} ---\textit{\acrlong{UART}}---, que controla los puertos serie. \cite{wiki_uart} -\subsubsection{Display \glsname{LCD} 4x20A} +Este módulo tiene una topología análoga al control por \textit{socket}, tan solo cambia el origen y la forma de entrada de los datos. Establecerá una comunicación con el puerto serie e iniciará un \textbf{bucle de escucha}. La sintaxis del mensaje, como ya sabemos, es: -Este pantalla \glsname{LCD} funciona basándose en el estándar de display 4x20 caracteres, y será configurado, su funcionamiento, por software. El único hardware adicional de adaptación que requiere es únicamente un potenciómetro que establezca el nivel de contraste de la pantalla. +\begin{center} + +\end{center} -\hfill -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.5]{capitulo4/LCD} -\par\end{centering} -\caption{\label{fig:LCD} Display LCD 4x20 204A.} -\end{figure} -\hfill +De esta forma, el servicio tan solo debe \textbf{verificar el nº de serie} y \textbf{ejecutar} la orden correspondiente. + +Además de reconocer la pulsación del mando, es necesario consultar en la \textbf{base de datos}, que detallaremos en la sección \ref{sec:database}, la lista que corresponde al botón pulsado y los archivos contenidos, que serán transmitidos al planificador. + +\subsubsection{Funciones públicas} + +Las funciones correspondientes a la interfaz de este módulo son las siguientes: + +\begin{description}[style=nextline] + \item[uart\_init () : \textit{integer}] + Establece comunicación con el puerto serie. + + Devuelve 0 en caso de éxito y -1 en caso de error. + + \item[uart\_destroy ()] + Cierra la comunicación. + + \item[uart\_loop ()] + Despliega una hebra con un bucle de escucha y ejecuta las órdenes. + +\end{description} + +\subsubsection{Funciones privadas} -Las principales características de nuestra \glsname{LCD} \cite{LCD} son: +\begin{description}[style=nextline] + \item[uart\_run ()] + Ejecuta el bucle de escucha en una hebra aparte. + + \item[uart\_playlist (list) : \textit{integer}] + Consulta a la base de datos los nombres de archivos asociados a la lista asignada al botón pulsado e inicia la reproducción. + + \begin{description} + \item[list : \textit{integer}] Código del botón que se ha pulsado. + \end{description} + + Devuelve 0 en caso de éxito o -1 en caso de error. + + \item[uart\_pause () : \textit{integer}] + Pausa o reanuda la reproducción, dependiendo de si estaba o no pausada. + + Devuelve 0 en caso de éxito, o -1 si el reproductor estaba detenido. +\end{description} + +\subsubsection{Diagrama de uso} + +Este bloque interacciona con el planificador en unos términos similares al \textit{socket}, y utiliza la interfaz de la base de datos. \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.9]{capitulo4/caracteristicas_lcd} -\par\end{centering} -\caption{\label{fig:caracteristicas_lcd} Principales características del Display LCD 4x20 204A.} -\end{figure} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/daemon_uart} + \par\end{centering} + \smallskip + \caption{\label{fig:daemon_uart} Diagrama de uso del receptor de radio.} +\end{figure} + \smallskip -Para el correcto funcionamiento del BackLight se tuvo que introduciendo una resistencia en la parte trasera de nuestra \glsname{LCD}. Para el cálculo de esta resistencia se tienen en cuenta los siguientes datos: alimentamos nuestra \glsname{LCD} con 5V, el Forward Voltage es de 3.2V y la corriente máxima es de 30mA. Por lo que nuestra resistencia se calcula de la siguiente manera: +\subsection{Comunicación con la base de datos} -\begin{equation} -R\geq(\frac{(5-3.2)V}{30mA})=60 \Omega -\end{equation} +La información relativa a la lista de reproducción asignada a un botón, así como la lista de partituras correspondientes, residirán en una base de datos, que definiremos en la sección \ref{sec:database}. Así, enmarcaremos un nuevo módulo dedicado a \textbf{consultar} la información requerida, ofreciendo una \textbf{interfaz independiente} del sistema de gestión de bases de datos que utilicemos, y de la propia base de datos. -Finalmente cogimos una resistencia de 100 \Omega para nuestra \glsname{LCD}. +\subsubsection{Funciones} +El sistema se comunicará con la base de datos mediante las siguientes funciones: -\subsubsection{Regulador de voltaje LM7805} -El regulador de voltaje LM7805 \cite{7805} entrega 5V de tensión continua. La tensión de alimentación debe ser un poco más de 2 voltios superior a la tensión que entrega el regulador y menor a 35V. Usualmente, el modelo estándar soporta corrientes de hasta 1 A aunque hay diversos modelos en el mercado con corrientes que van desde los 0,1A. El dispositivo posee como protección un limitador de corriente por cortocircuito, y además, otro limitador por temperatura que puede reducir el nivel de corriente. -El regulador de voltaje LM7805 lo usaremos para alimentar el Arduino con 5V. +\begin{description}[style=nextline] + \item[db\_init () : \textit{integer}] + Inicia la comunicación con el gestor de bases de datos. Devuelve 0 en caso de éxito y -1 en caso de error. + + \item[db\_destroy ()] + Cierra la comunicación. + + \item[db\_query (scores, idshortcut) : \textit{integer}] + Realiza la consulta mencionada, asignando a \textit{scores} la lista de piezas a reproducir. + + \begin{description} + \item[scores : \textit{array(string)}] Lista de rutas a las piezas. + \item[idshortcut : \textit{integer}] ID del botón que se ha pulsado en el mando. + \end{description} + + Devuelve el número de piezas asignadas (pudiendo ser 0), o -1 en caso de error. + +\end{description} -Ya que lo usamos para regular tensión proveniente de una una fuente de alimentación(en nuestro caso con un adaptador AC de una PSP), tendremos que hacer un filtrado para eliminar cualquier fluctuación de voltaje que pueda ocurrir. Para dicho filtrado colocaremos un condensador a la salida del regulador y dos a la entrada. Tal y como se muestra en la siguiente imagen: +\subsubsection{Diagrama de uso} -\smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo4/regulador} -\par\end{centering} -\caption{\label{fig:regulador} Configuración del regulador de voltaje 7805.} -\end{figure} -\hfill +La interfaz de la base de datos es utilizada exclusivamente por el servidor del receptor de radio, sin perjuicio de que en un futuro podamos extender su funcionalidad, por lo que la hemos separado lógicamente del módulo \acrshort{UART}. El diagrama de uso es el siguiente: -Los condensadores C2 y C3 seran no polarizados. Mientras que el condensador C1 será polarizado de al menos 16V para soportar los 12V. +\smallskip -Con esta configuración ya podemos alimentar nuestro Arduino UNO con 5V. +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/daemon_bd} + \par\end{centering} + \smallskip + \caption{\label{fig:daemon_bd} Diagrama de uso de la interfaz de base de datos.} +\end{figure} -\subsubsection{Transistor PNP BC857} -\label{sec:BC} -A la hora de diseñar una fuente de corriente constante necesité de dos transistores \glsname{PNP}. Se buscó un transistor pequeño y barato. Los transistores PNP BC857 son la versión \acrshort{SMD} (\acrlong{SMD}) de los BC557 y su precio está entre 0.03\textup{\euro} y 0.1\textup{\euro} lal unidad según la cantidad que compremos. +\smallskip -\hfill -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.2]{capitulo4/BC857} -\par\end{centering} -\caption{\label{fig:BC857} Transistor \glsname{PNP} BC857.} -\end{figure} -\hfill +\subsection{Planificador} +\label{subsec:planificador} -Las principales características de este transistor \cite{BC857} son: +El planificador es la \textbf{pieza principal} del reproductor. Recibe las \textbf{órdenes} de los controladores y la lista de \textbf{partituras} a ejecutar. Una a una las lee con ayuda del módulo \acrshort{MIDI} y \textbf{planifica los eventos} de todas las pistas para lanzarlos a la salida en el momento necesario. -\hfill -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.9]{capitulo4/tabla_BC} -\par\end{centering} -\caption{\label{tabla_BC} Características del BC857\cite{BC857}.} -\end{figure} -\hfill +Al igual que otros módulos, utiliza una hebra para reproducir los archivos, pero en este caso es una \textbf{hebra dinámica}, que podrá ser iniciada, pausada y detenida por el resto de procesos, por lo que hay que tener en cuenta los \textbf{problemas de concurrencia} para garantizar la \textbf{consistencia} del sistema. +\subsubsection{Funciones} -La curva de ganancia de DC es la siguiente, figura \ref{fig:curva_BC}. +La interfaz que el planificador ofrece es la que sigue: -\hfill -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo4/curva_BC} -\par\end{centering} -\caption{\label{fig:curva_BC} Curva de ganancia de corriente en DC.} -\end{figure} -\hfill +\begin{description}[style=nextline] + \item[player\_init () : \textit{integer}] + Inicializa las estructuras de datos. Devuelve 0 en caso de éxito o -1 en caso de error. + + \item[player\_destroy () : \textit{integer}] + Detiene el reproductor y elimina las estructuras de datos. + + \item[player\_start (playlist, n, loop) : \textit{integer}] + Inicia la reproducción de una lista de archivos. Si ya estaba reproduciendo una lista, primero detiene la reproducción y elimina la lista antigua. + + \begin{description} + \item[playlist : \textit{array(string)}] Lista de rutas absolutas a los archivos que queremos reproducir. + \item[n : \textit{integer}] Número de piezas que se han transmitido en el parámetro anterior. + \item[loop : \textit{bool}] Utilizar (1) o no (0) reproducción en bucle. + \end{description} + + Devuelve 0 en caso de éxito o -1 en caso de error. + + \item[player\_pause () : \textit{integer}] + Pausa la reproducción, si estaba activa. Devuelve 0 en caso de éxito o -1 en caso de error. + + \item[player\_resume () : \textit{integer}] + Reanuda la reproducción, si estaba pausada. Devuelve 0 en caso de éxito o -1 en caso de error. + + \item[player\_stop () : \textit{integer}] + Detiene completamente la reproducción, si estaba activa o pausada. Si estaba parado, no hace nada. Devuelve 0 en caso de éxito o -1 en caso de error. + + \item[player\_wait () : \textit{integer}] + Espera a que el reproductor se detenga. Solo tiene sentido llamarla en caso de no estar reproduciendo en bucle. Devuelve 0 en caso de éxito o -1 en caso de error. + + \item[player\_state (file) : \textit{enum}] + Indica el estado actual del planificador. Tales estados se detallan en el apartado siguiente. + + \begin{description} + \item[file : \textit{string}] Es un parámetro de salida, sobre él se escribe el nombre del archivo que se estaba reproduciendo. Solo es válido si el reproductor está activo o en pausa. + \end{description} + + Devuelve el estado actual del reproductor, a saber entre los estados contemplados en la máquina. + + \item[player\_engineer\_enter () : \textit{integer}] + Detiene el reproductor, bloquea el planificador y entra en modo Ingeniería. Devuelve 0 en caso de éxito o -1 en caso de error, como estar ya dentro del modo Ingeniería. + + \item[player\_engineer\_exit () : \textit{integer}] + Sale del modo Ingeniería y debloquea el planificador. Devuelve 0 en caso de éxito o -1 en caso de error, como no estar dentro del modo Ingeniería. + +\end{description} +\subsubsection{Máquina de estados} -Este transistor lo usaremos para crear una fuente de corriente constante. El esquema del circuito es el siguiente: +Para gestionar su funcionamiento, el planificador utiliza una pequeña cantidad de estados, que mostramos a continuación: \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo4/fuente} -\par\end{centering} -\caption{\label{fuente} Esquema de una fuente de corriente constante.} -\end{figure} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo4/sched} + \par\end{centering} + \smallskip + \caption{\label{fig:sched} Diagrama de estados del planificador.} +\end{figure} + \smallskip +\begin{description} + \item[Activo] En funcionamiento, reproduciendo activamente una partitura. + \item[Pausado] No reproduce, mantiene el estado del órgano en el módulo de salida. + \item[Detenido] En espera. Es el estado inicial. + \item[Ingeniero] Bloqueado, en modo Ingeniería. Ha cedido el control del módulo de salida. +\end{description} +\subsubsection{Algoritmo básico} -\subsubsection{Rotary Encoder} -Los Rotary Encoder son dispositivos para medir ángulos. Se usan para medir de manera precisa la rotación de motores o para crear un controlador tipo rueda(knobs) que pueden girar indefinidamente. Algunos están equipados con un pulsador. Los Rotary cuentan con tres patillas: dos de salida y una que va a masa. +El procedimiento para reproducir \textbf{una sola pista} es trivial: recorrerla ordenadamente, y para cada evento, esperar el tiempo indicado y ejecutarlo. Sin embargo, un archivo \acrshort{MIDI} suele estar compuesto ---y de hecho así lo esperamos--- por varias pistas \textbf{simultáneas}. +Para que todas las pistas se ejecuten simultáneamente, debemos diseñar un algoritmo que atienda a todas y decida qué evento debe ejecutarse en cada momento. Lo hemos realizado inspirándonos en el algoritmo de ordenación \textbf{\textit{merge sort}}: + +El planificador recorre en cada ciclo todas las pistas, avanzando mientras sea el momento de ejecutar el evento correspondiente ($\Delta=0$). Cuando se ha llegado a un evento con $\Delta > 0$ en todas las pistas, se busca el \textbf{menor} de ellos y se resta al \textit{delta} de todos los eventos. A continuación, se solicita al sistema operativo la \textbf{espera} correspondiente al tiempo restado, y se repite el ciclo. El algoritmo \textbf{termina} cuando todas las pistas han llegado al final. -\hfill -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.3]{capitulo4/rotary} -\par\end{centering} -\caption{\label{fig:rotary} Rotary Encoder.} -\end{figure} \smallskip - -El funcionamiento del Rotary Encoder se basa en que tenemos dos señales de salida cuadradas(A y B) que están desfasadas 90º. El número de pasos por vuelta variará según el modelo, en nuestro caso son 24. El siguiente diagrama muestra como las fases de A y B se relacionan según giremos el Rotary Encoder en el sentido de las agujas del reloj o en sentido contrario. +\begin{algorithmic} + \LOOP + \STATE $mindelta \gets \infty$ + \STATE $i\gets 0$ + \WHILE {$i < n_{tracks}$} + \WHILE {$event_i.delta = 0$ \AND \NOT ($event_i.type = METAEVENT$ \AND \\ $event_i.metaevent.type = END\_OF\_TRACK$)} + \IF {$event_i.type = NOTE\_ON$} + \STATE $output\_noteon(i, event_i.param1)$ + \ELSE + \IF {$event_i.type = NOTE\_OFF$} + \STATE $output\_noteoff (i, event_i.param1)$ + \ENDIF + \ENDIF + \STATE $event_i \gets event_i.next$ + \ENDWHILE + \IF {$event_i.delta > 0$ \AND $event_i.delta < mindelta$} + \STATE $mindelta \gets event_i.delta$ + \ENDIF + \ENDWHILE + \STATE $i \gets 0$ + + \WHILE {$i < n_{tracks}$} + \STATE $event_i.delta \gets event_i.delta - min$ + \ENDWHILE + \STATE $sleep (mindelta)$ + \ENDLOOP +\end{algorithmic} \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.8]{capitulo4/rotary_encoder_phase} -\par\end{centering} -\caption{\label{fig:rotary_encoder_phase} Relación de las señales A y B según el sentido del giro.} -\end{figure} + +\subsubsection{Diagrama de uso} + +Como parte central del programa, y al contrario que el resto de componentes, el planificador está conectado con la mayoría de módulos, actuando como mediador y coordinador entre aquellos que reciben órdenes y los que facilitan la salida de información. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/daemon_scheduler} + \par\end{centering} + \smallskip + \caption{\label{fig:daemon_scheduler} Diagrama de uso del planificador.} +\end{figure} + \smallskip -Cada vez que el pulso de la señal A va de positivo a cero, leemos el valor del pulso B. Podemos observar que cuando el Rotary Encoder se gira en el sentido de las agujas del reloj, B es siempre positivo. Mientras que si lo giramos en sentido contrario, B siempre es cero. +\begin{itemize} + \item Los servidores de \textit{socket} y de \acrshort{UART}, y el control de interfaz reducida, envían las órdenes de control. + \item El módulo \acrshort{MIDI} es utilizado para descodificar los archivos de entrada. + \item La información extraída se dirige al módulo de salida (\acrshort{GPIO}) para llegar a la \acrshort{PCB}. +\end{itemize} + +\subsection{Modo Ingeniería} +\label{subsec:ingenieria} -En nuestro proyecto hemos elegido uno tipo knob sin pulsador. Su conexión es muy simple, unicamente hay que conectar la patilla central a tierra y las otras dos a los pines 2 y 3 del Arduino, ya que son las habilitadas para interrupciones externas. -La función del Rotary Encoder será la de permitirnos movernos por el menú y también poder establecer la temperatura de consigna que queramos. +El sistema requiere un modo de mantenimiento para regular la \textbf{mecánica}, al que se accederá localmente, a través de una interfaz reducida que controlaremos con el codificador rotatorio y el \acrshort{LCD}. Este sistema permitirá controlar las siguientes acciones: +\begin{enumerate} + \item Entrar en modo Ingeniería. + \item Activar y desactivar el metrónomo. + \item Apagar y reiniciar el sistema. +\end{enumerate} -\subsubsection{Optotriac MOC3061M} -Los triacs acoplados ópticamente combinan un diodo emisor de luz (\acrshort{led}) con un triac foto-detector (foto-triac) dentro de un mismo encapsulado con un esquema que es mostrado en la figura \ref{fig:optotriacs}. Al no existir conexión eléctrica entre la entrada y la salida, el acoplo es unidireccional (\acrshort{led} al foto-TRIAC) y permite un aislamiento eléctrico entre ambos dispositivos de hasta 7500 V (typ). Además, algunos foto-TRIAC incluyen un circuito de detección de paso por cero que permite sincronizar señales de la red eléctrica con señales de control del \acrshort{led} para ajustar el ángulo de conducción. +El codificador permitirá acceder al \textbf{modo Ingeniería}, que detendrá la reproducción ---si estaba en funcionamiento--- y aislará el planificador, ganando acceso directo a la salida \acrshort{GPIO}. Funcionará en una hebra independiente. -\hfill -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.8]{capitulo4/optotriacs} -\par\end{centering} -\caption{\label{fig:optotriacs} Esquema de un Optotriac.} -\end{figure} -\hfill +Vamos a diseñar la interfaz como una \textbf{máquina de estados}: Inicialmente el modo Ingeniería está desactivado, girando el botón se nos dará la opción de activarlo, y al pulsarlo entraremos en él. Se activará la nota más baja de la primera pista, al girar el botón podremos movernos cíclicamente por todas las notas de esa pista. Pulsando el botón cambiamos a la segunda pista, luego a la tercera, y así hasta la última. Si apretamos nuevamente el botón, volvemos al menú que nos permitirá salir del modo Ingeniería. -A continuación podemos ver las diferentes características de cada uno de los componentes del MOC3061M \cite{moc}. +También vamos a insertar en el menú opciones para habilitar el \textbf{metrónomo} y para \textbf{desactivar el sistema}. -\hfill -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=1]{capitulo4/moc} -\par\end{centering} -\caption{\label{fig:moc} Características individuales de los componentes de un MOC306XM.} -\end{figure} -\hfill +Este diagrama muestra las \textbf{transiciones} entre los estados: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo4/engineer} + \par\end{centering} + \smallskip + \caption{\label{fig:engineer} Máquina de estados de la interfaz reducida.} +\end{figure} + +\smallskip + +\begin{description} + \item[Reproductor] Estado inicial, muestra el estado del reproductor. + \item[Menú ingeniería] Ofrece la opción de entrar en el modo Ingeniería. + \item[Modo Ingeniería] Modo Ingeniería activado, los subestados dependen de la pista y la nota actuales. + \item[Menú metrónomo] Muestra y permite alterar el estado del metrónomo. + \item[Menú energía] Deja entrar al menú de control de energía. + \item[Reiniciar] Da la opción de reiniciar el sistema al pulsar el botón. + \item[Apagar] Apaga el equipo si se pulsa el botón. + \item[Volver] Permite retornar al menú anterior. +\end{description} + +\subsubsection{Funciones públicas} + +Este bloque solo incluye una función: -En nuestro caso usamos el optotriac para aislar la etapa de control(circuitería de baja tensión) con la de potencia(la red y la carga) y de esta forma, evitar posibles daños en el Arduino UNO. Utilizamos un Optotriac MOC3061M, un optotriac con conmutación en el paso por cero y aislamiento entre entrada y salida. +\begin{description}[style=nextline] + \item[periph\_init () : integer] + Inicia el módulo y prepara la escucha de los controles. + + Devuelve 0 en caso de éxito, o -1 si encuentra algún error. +\end{description} + +\subsubsection{Funciones privadas} -A continuación podemos ver las diferentes características de cada uno de los componentes +\begin{description}[style=nextline] + \item[rot\_change ()] + Se llama cuando se gira el botón del \textit{rotary}. Envía una señal a la hebra de control. + + \item[rot\_push ()] + Se llama cuando se aprieta el botón del \textit{rotary}. De manera análoga, envía una señal a la hebra que controla el modo Ingeniería. + + \item[periph\_run ()] + Ejecuta el bucle de actualización de la máquina de estados, en función del estado actual y cualquier eventual entrada, además de actualizar la salida al \acrshort{LCD}. +\end{description} -A continuación, la figura \ref{fig:circuito_potencia} muestra la configuración usada en la etapa de potencia que controlara el encendido y apagado de nuestro horno. Donde la resistencia de 39 ohmios y el condensador de 0.1 microfaradios se usan para desairar el triac y a menudo, pero no siempre, necesario dependiendo del triac y de la carga. +\subsubsection{Diagrama de uso} +El módulo que controla el modo Ingeniería interacciona con el planificador, para detenerlo y aislarlo del \acrshort{GPIO}, y con el módulo de salida, que maneja el propio \acrshort{GPIO}, para manipular el estado. \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=1]{capitulo4/circuito_potencia} -\par\end{centering} -\caption{\label{fig:circuito_potencia} Esquema de un Optotriac.} -\end{figure} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/daemon_engineer} + \par\end{centering} + \smallskip + \caption{\label{fig:daemon_engineer} Diagrama de uso del modo Ingeniería.} +\end{figure} + \smallskip +\subsection{Salida hacia la PCB} +\label{subsec:output} + +El reproductor delega en el módulo de salida las siguientes funciones: +\begin{enumerate} + \item Dirigir las pistas de \acrshort{MIDI} al canal de salida correspondiente. + \item Almacenar el estado de salida (notas pulsadas y no pulsadas). + \item Volcar la información en el \acrshort{GPIO}. + \item Hacer sonar el metrónomo. +\end{enumerate} + +Éste será el único módulo que tendremos que cambiar a la hora de pasar de un órgano a otro. El hecho de \textbf{aislar la salida} también nos da flexibilidad para sustituir la interfaz \acrshort{GPIO} por otro tipo de salida, como la consola, con fines de mantenimiento y depuración. + +\subsubsection{Funciones} + +Las siguientes funciones conforman la interfaz del módulo: + +\begin{description}[style=nextline] + \item[output\_init () : \textit{integer}] + Inicializa los componentes de la salida. Devuelve 0 en caso de éxito o -1 en caso de error. + + \item[output\_destroy ()] + Cierra el módulo de salida y libera la memoria ocupada. + + \item[output\_noteon (track, note)] + Marcar una nota para activar en el sistema. + + \begin{description} + \item[track : \textit{integer}] Índice de la pista \acrshort{MIDI}. + \item[note : \textit{integer}] Número de nota \acrshort{MIDI}. + \end{description} + + \item[output\_noteon (track, note)] + Marcar una nota para apagarla en el sistema. + + \begin{description} + \item[track : \textit{integer}] Índice de la pista \acrshort{MIDI}. + \item[note : \textit{integer}] Número de nota \acrshort{MIDI}. + \end{description} + + \item[output\_update ()] + Vuelca el estado en la salida. + + \item[output\_panic ()] + Vuelve al estado inicial (silenciar todas las notas), y lo vuelca en la salida. + + \item[output\_silence ()] + Silencia todas las notas en la salida, pero mantiene el estado. Útil para pausar la reproducción. + + \item[output\_metronome ()] + Emite un pulso del metrónomo. + + \item[output\_metronome\_enable (enabled)] + Habilita o deshabilita el metrónomo. + + \begin{description} + \item[enabled : \textit{bool}] \textit{true} para habilitar, \textit{false} para deshabilitar. + \end{description} + + \item[output\_metronome\_enabled () : \textit{bool}] + Devuelve \textit{true} si el metrónomo está habilitado, o \textit{false} en caso contrario. + +\end{description} +\subsubsection{Mapeo de pistas y canales} +Nuestra especificación deja abierta la estructura que pueda tener un archivo \acrshort{MIDI}. A pesar de que el sistema podrá descodificar \acrshort{MIDI} estándar, para lograr una óptima ejecución, la pieza deberá \textbf{adaptarse} a cada órgano concreto. -\subsubsection{Triac BT139} -El triac es un semiconductor, de la familia de los transistores. La diferencia con el tiristor convencional es que éste es unidireccional, es decir, funciona con corriente alterna en el sentido de polarización con medio semiciclo, y el triac es bidireccional, funciona en los semiciclos positivos y negativos. Cuando el triac conduce, hay una trayectoria de flujo de la polaridad del voltaje externo aplicado. Cuando el voltaje es más positivo en T2, la corriente fluye de T2 a T1 en caso contrario fluye de T1 a T2. En ambos casos el triac se comporta como un interruptor cerrado. Cuando el triac deja de conducir no puede fluir corriente por los terminales sin importar la polaridad del voltaje externo aplicado, por tanto actua como un interruptor abierto. +El módulo de salida permitirá asignar cada pista \acrshort{MIDI}, que normalmente corresponde a un \textbf{pentagrama} de la partitura, a un canal de salida diferente. La asignación por defecto, para el órgano estudiado, será la siguiente: \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.8]{capitulo4/triac} -\par\end{centering} -\caption{\label{fig:triac} Esquema de un triac \cite{BT139}.} -\end{figure} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/3]{capitulo4/map} + \par\end{centering} + \smallskip + \caption{\label{fig:map} Asignación de pistas MIDI y canales de salida.} +\end{figure} + \smallskip +\subsubsection{Diagrama de uso} -Las características del triac BT139 las podemos encontrar en su datasheet \cite{BT139}. Las más importantes son: +La interfaz de salida es utilizada principalmente por el \textbf{planificador} y, solo cuando éste entra en \textbf{modo Ingeniería}, es accedida por el módulo del mismo nombre, para poner a prueba la mecánica del sistema. \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo4/resistencia_termica} -\par\end{centering} -\caption{\label{fig:resistencia_termica} Resistencia termica.} -\end{figure} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/daemon_gpio} + \par\end{centering} + \smallskip + \caption{\label{fig:daemon_gpio} Diagrama de uso del módulo de salida.} +\end{figure} + \smallskip +\subsection{Seguridad} + +A pesar de que el acceso al sistema se hará siempre con autentificación de usuario, nos interesa controlar que no todos los usuarios, o no todas las aplicaciones, se conecten al \textit{socket}. La seguridad de Linux recae en gran parte sobre su \textbf{sistema de archivos} y permisos. Se creará un \textbf{nombre de usuario} de sistema para ser utilizado \textbf{exclusivamente} por el \textit{socket}, que tendrá permisos de lectura y escritura para dicho usuario y su grupo. + +Para \textbf{autorizar} a un usuario a acceder al \textit{socket}, simplemente hay que añadirlo al grupo del usuario propietario. + +Por otro lado, el demonio se ejecuta con permisos de \textit{superusuario}, y es \textbf{inseguro} mantenerse durante toda la ejecución con tales privilegios. A pesar de que introduciremos medidas de seguridad en los clientes que desarrollemos para el sistema, \textbf{reduciremos los permisos} después de inicializar el proceso, como medida adicional para evitar problemas. + +\newpage + +\section{Base de datos} +\label{sec:database} + +La información que queremos almacenar funciona de la siguiente forma: + +\begin{enumerate} + \item Las \textbf{partituras} se guardan en un archivo, cuyo nombre no tiene que coincidir con el título de la partitura. + \item De una partitura podremos conocer su \textbf{duración}. + \item Una \textbf{lista de reproducción} es una colección de partituras, y le asignaremos un nombre. + \item Cada partitura pertenecerá a una lista de reproducción, y solo a una. + \item Un \textbf{botón} se distingue por su código, y se le asigna a una lista de reproducción, sin perjuicio de que una lista esté asignada a varios botones. Naturalmente, puede haber listas que no estén asignadas a ningún botón. +\end{enumerate} + +\subsection{Modelo entidad-relación} + +Atendiendo a los requisitos propuestos, modelamos nuestros datos según el siguiente diagrama: \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo4/caracteristicas_estaticas} -\par\end{centering} -\caption{\label{fig:caracteristicas_estaticas} Caracteristicas estaticas.} -\end{figure} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo4/bd_er} + \par\end{centering} + \smallskip + \caption{\label{fig:bd_er} Modelo entidad-relación.} +\end{figure} + \smallskip +\subsection{Modelo relacional} + +Una vez hemos considerado las entidades, sus atributos y las relaciones, diseñamos el \textbf{modelo de datos}, que depende del tipo de sistema de gestión de bases de datos ---\acrshort{DBMS} (\textit{\acrlong{DBMS}})--- que vayamos a utilizar. En nuestro caso, utilizaremos un \textbf{\acrshort{DBMS} relacional} \cite{bdrel}. + +\begin{enumerate} + \item Convertimos en relaciones (\textbf{tablas}) todas las entidades y las relaciones del modelo entidad-relación. + \item Los atributos de las entidades pasan a ser \textbf{atributos} de las relaciones correspondientes. + \item Buscamos \textbf{llaves candidatas} y escogemos una como llave primaria. En el caso de Pieza y Lista, no tenemos llave candidata, así que añadimos un ID a cada relación. + \item Las relaciones Contiene y Asigna tienen cardinalidad N-1, de forma que comparten la clave primaria. \textbf{Fusionamos} Contiene en Pieza y Asigna en Botón. +\end{enumerate} + +Una vez hecho esto, el modelo resultante es el siguiente: + \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo4/caracteristicas_dinamicas} -\par\end{centering} -\caption{\label{fig:caracteristicas_dinamicas} Caracteristicas dinamicas.} -\end{figure} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo4/bd_rel} + \par\end{centering} + \smallskip + \caption{\label{fig:bd_rel} Modelo relacional.} +\end{figure} + \smallskip +\subsection{Consistencia} +Para garantizar que la base de datos mantendrá la información coherente y sin anomalías, estudiamos las relaciones para \textbf{normalizarlas}. Podemos verificar que nuestro modelo relacional está en \textbf{5ª forma normal}, atendiendo a las siguientes condiciones: +\begin{description} + \item[1FN] El \acrshort{SGBD} relacional se encarga de que se cumpla la forma normal más básica: las columnas son regulares, no habrá filas duplicadas (por la llave primaria) ni orden alguno entre filas o columnas. \cite{wiki_1fn} + \item[2FN] Todos los atributos secundarios de cada tabla dependen de la \textbf{llave primaria}, por tanto, está en segunda forma normal. \cite{wiki_2fn} + \item[3FN] No existen atributos secundarios que dependan \textbf{transitivamente} de la llave primaria, entonces, está en tercera forma normal. \cite{wiki_3fn} + \item[FNBC] La forma normal de Boyce-Codd establece que los únicos determinantes sean las \textbf{claves candidatas}. Como el modelo está en 3FN y no existen llaves candidatas compuestas, podemos decir que está también en 3FN. \cite{wiki_fnbc} + \item[4FN] La cuarta forma normal extiende la FNBC exigiendo que no existan \textbf{dependencias multivaluadas} no triviales. Este modelo no tiene dependencias multivaluadas, de forma que está en 4FN. \cite{wiki_4fn} + \item[5FN] Por último, la quinta forma normal especifica que, además de todo lo anterior, cada \textbf{dependencia de unión} sea implicada por claves candidatas. Esto se cumple en nuestro modelo, ya que toda llave externa se vincula a la llave primaria de otra relación. \cite{wiki_5fn} +\end{description} +Nuestro modelo relacional cumple todas las exigencias de las formas normales tenidas en cuenta, con lo que podemos garantizar que el modelo es \textbf{consistente}. +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/bd_fn} + \par\end{centering} + \smallskip + \caption[Relación entre las formas normales.]{\label{fig:bd_fn} Relación entre las formas normales. \cite{wiki_normal}} +\end{figure} -\subsection{Esquemático Altium} -En este apartado expondremos el diseño esquemático en el que juntaremos los distintos módulos ya interconectados. Se divide en dos: uno en el que se muestra los periféricos de control(LCD, pulsador, rotary y leds de control) y otro en el que se muestra la circuitería de control. +\smallskip -\subsection{Esquemático Altium} +\newpage -\includepdf[pages=1,link=true,landscape,linkname=schematic,addtotoc={1,section,1,Esquemático Altium,letter}]{capitulo4/esquematico1} +\section{Control remoto} -\subsection{Esquemático Altium} -\includepdf[pages=1,link=true,landscape,linkname=schematic,addtotoc={1,section,1,Esquemático Altium,letter}]{capitulo4/esquematico2} +Hasta ahora hemos diseñado el \textit{back-end} del sistema, con todas las características que darán funcionalidad a nuestra solución. Pero aún no tenemos una interfaz que permita al usuario interactuar con el sistema, más que el control del mando a distancia o desde la \acrshort{PCB}. +El próximo paso es \textbf{concebir el \textit{front-end}} que, a tenor de los requisitos que propusimos al inicio, ofrezca al usuario la interfaz más completa posible. Frecuentemente la \textbf{funcionalidad} viene contrapuesta a la \textbf{facilidad} de uso; es nuestra tarea encontrar el mejor \textbf{equilibrio} posible. +Vamos a diseñar una solución enfocada al uso remoto con ayuda de un \textbf{explorador} de Internet, como \textit{Chrome}, \textit{Firefox} o \textit{Safari}, con lo que crearemos un servidor \textit{web}. El control del órgano queda pues estructurado de la siguiente forma: -\section{Implementación \textit{Firmware}} -\label{sec:ImpFirm} +\smallskip +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo4/despliegue} + \par\end{centering} + \smallskip + \caption[Comunicación entre el cliente y el software del sistema]{\label{fig:despliegue} Comunicación entre el cliente y el software del sistema. \cite{svg_raspberry}} +\end{figure} -En este apartado se expondrán los distintos programas usados a lo largo del poryecto y su uso. +\smallskip -Principalmente se han usado tres programas: +Lo primero que haremos será especificar los casos de uso que nos enfrentarán al usuario. Después, concebiremos el aspecto de la interfaz y por último esbozaremos la estructura del diseño. +\subsection{Casos de uso} +A continuación enumeramos una relación de casos de uso que deberá cubrir la interfaz de usuario: \begin{enumerate} - \item ALTIUM \textit{Designer} versión 14.1: Con este \textit{software}, a partir del circuito esquemático se obtendrá la correspondencia en circuito \acrshort{PCB}. - \item Arduino IDE versión 1.0.6: Este \textit{software} lo podemos encontrar en la página de arduino. Es un \textit{software} libre y muy sencillo de usar. Con él programaremos la rutina principal para el control de nuestro horno. - \item MATLAB R2013a: Gracias a su gran procesamiento de datos, podremos representar los datos obtenidos de la temperatura dentro del horno y representarlos para poder obtener conclusiones sobre el comportamiento de nuestro horno. + \item \textbf{Identificarse} en el sistema como usuario autorizado. + \item \textbf{Salir} del sistema, en el sentido de que al entrar de nuevo haya que identificarse. + \item Controlar la \textbf{reproducción} directamente, a saber: + + \begin{enumerate} + \item Ver el nombre de la pieza que se está reproduciendo. + \item Ejecutar una lista de reproducción en bucle. + \item Escoger una pieza de la lista para reproducirla. + \item Pausar la reproducción de una pieza. + \item Reanudar la ejecución de una pieza, si estaba pausada. + \item Detener completamente la reproducción. + \item Avanzar en la lista y reproducir la siguiente pieza. + \item Retroceder en la lista y reproducir la partitura anterior. + \end{enumerate} + + \item Gestionar \textbf{listas de reproducción}: + + \begin{enumerate} + \item Crear una nueva lista, dándole un nombre. + \item Visualizar todas las listas existentes. + \item Modificar el nombre de la lista. + \item Eliminar una lista. + \end{enumerate} + + \item Gestionar \textbf{piezas musicales}: + + \begin{enumerate} + \item Cargar una nueva partitura en el sistema, dentro de una lista de reproducción. + \item Ver una relación de las piezas contenidas en una lista, y su duración. + \item Cambiar el nombre de una pieza. + \item Borrar una pieza del sistema. + \end{enumerate} + + \item Gestionar \textbf{asignaciones} de botones del mando: + + \begin{enumerate} + \item Ver las asignaciones actuales. + \item Cambiar la lista a reproducir cuando se pulsa un botón, escogiéndola entre todas las listas. + \end{enumerate} + + \item Controlar básicamente la \textbf{energía} del sistema: + + \begin{enumerate} + \item Apagar el sistema. + \item Reiniciar el sistema. + \end{enumerate} + + \item Escoger el \textbf{idioma} en que se muestra el texto, entre una lista de lenguas disponibles. \end{enumerate} -\subsection{ALTIUM \textit{Designer}} -Altium Designer es una solución integrada de hardware y software para cubrir todas las etapas de un desarrollo que van desde después de la idea hasta el prototipo final. +\subsection{Modelo-vista-controlador} + +Para estructurar los elementos que conformarán la interfaz, utilizaremos el patrón de modelo-vista-controlador, que divide la funcionalidad de un sistema en tres bloques, con el siguiente criterio: -Altium Designer es un recurso para el diseño electrónico en todas sus fases y para todas las disciplinas, ya sean esquemas, simulación, diseño de circuitos impresos, imple¬mentación de FPGA o desarrollo de código para microprocesadores. +\smallskip - Detrás de lo que encierra el nombre Altium Designer existe una plataforma de integración de software que reúne todas las herramientas necesarias para crear un entorno completo para el desarrollo de productos electrónicos, en una sola aplicación. Altium Designer incluye herramientas para todas las tareas de diseño: desde la captura de diseño esquemático y HDL, simulación de circuitos, análisis de integridad de señales, diseño de \acrshort{PCB}, hasta el diseño de sistemas embebidos. Características de Altium Designer: +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/mvc} + \par\end{centering} + \smallskip + \caption{\label{fig:mvc} Relación entre la vista, el modelo y el controlador.} +\end{figure} -\begin{itemize} - \item Diseño de \acrshort{PCB}: -Altium Designer ha unificado el diseño de la plataforma física con el diseño de tarjeta de circuito impreso, con soporte para lógica programable. Esto proporciona un sistema de desarrollo totalmente unificado que puede desplegarse a través de todos los elementos del proceso de diseño de productos electrónicos. - \item Gestión de librerías: -Elegir un componente obsoleto o fuera de stock de puede dar lugar a la producción de largos retrasos y sobrecostos. Altium Designer ofrece una amplia gama de herramientas de gestión de datos y recursos de información que le permiten mantener el control sobre el uso de partes. - \item Diseño para fabricación: -Altium Designer ayuda a reducir la brecha entre el diseño y la fabricación, ademas le permite administrar de forma activa la generación y verificación de todos los datos de fabricación, ahorrando tiempo y minimizando los costosos, errores durante el flujo de diseño. - \item Dispositivos programables: -Altium Designer es la única herramienta que permite explotar plenamente el potencial que ofrecen hoy los dispositivos programables, al unificar el diseño de \acrshort{FPGA}s, el desarrollo de software y el diseño de \acrshort{PCB}s, en una sola plataforma. - \item Diseño Unificado de \acrshort{FPGA}/\acrshort{PCB}: -Los dispositivos programables son cada vez más usados en desarrollo electrónico. Este tipo de dispositivos abren nuevas posibilidades de diseño y aportan beneficios significativos para el proceso de diseño, lo que permite que la complejidad funcional se traslade de dispositivos discretos cableados al ámbito de dispositivos programables. - \item Gestión de todo el proceso de desarrollo: -Altium Designer unifica todo el proceso de diseño y permite gestionar todos los aspectos del desarrollo dentro de un único entorno de diseño, y ofrece una infraestructura de administración de proyectos y documentos unificada que soporta la convergencia de diseños de tradicionalmente disciplinas separadas. - -\end{itemize} +\smallskip + +\begin{description} + \item[Vista] Reúne los elementos que van a proporcionar al usuario la \textbf{información} que requiere. + \item[Controlador] Comprende los módulos a los que el usuario acudirá para \textbf{manipular} el sistema. Eventualmente, después de realizar una operación, puede llamar a la vista para realimentar de información al usuario. + \item[Modelo] Contiene los componentes más internos, abstrayendo a la vista y al controlador de la \textbf{representación} de los datos o la interacción con el sistema. +\end{description} -\subsection{Arduino IDE} +Considerando los casos de uso y los requisitos, hemos enmarcado en el esquema modelo-vista-controlador los siguientes elementos: -Para programar la placa es necesario descargarse de la página web de Arduino el entorno de desarrollo (IDE). Se dispone de versiones para Windows y para MAC, así como las fuentes para compilarlas en LINUX. -Estructura básica de un programa +\smallskip -La estructura básica de programación de Arduino es bastante simple y divide la ejecución en dos partes: setup y loop. Setup() constituye la preparación del programa y loop() es la ejecución. En la función Setup() se incluye la declaración de variables y se trata de la primera función que se ejecuta en el programa. Esta función se ejecuta una única vez y es empleada para configurar el pinMode (p. ej. si un determinado pin digital es de entrada o salida) e inicializar la comunicación serie. La función loop() incluye el código a ser ejecutado continuamente (leyendo las entradas de la placa, salidas, etc.). +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*2/3]{capitulo4/mvc_completo} + \par\end{centering} + \smallskip + \caption{\label{fig:mvc_completo} Módulos que componen el sistema.} +\end{figure} -\subsection{MATLAB} -MATLAB (abreviatura de MATrix LABoratory, "laboratorio de matrices") es una herramienta de software matemático que ofrece un entorno de desarrollo integrado (IDE) con un lenguaje de programación propio (lenguaje M) y servicio de especie. Está disponible para las plataformas Unix, Windows, Mac OS X y GNU/Linux . +\smallskip + +A lo largo de esta sección detallaremos el comportamiento de todos los componentes. + +\subsection{Estilo de la interfaz} + +La \textbf{visualidad} es un punto importante en el diseño de interfaces gráficas, es la encargada de proporcionar una \textbf{experiencia de usuario} y hacer asequible la utilización del sistema. Pretendemos entregar la información requerida de forma clara y concisa, disponer fácilmente de los controles que puedan ser necesarios en cada vista, y que el estilo sea \textbf{agradable} y acorde a la solución que se está diseñando. + +Por ello, vamos a fijarnos en la guía de estilo \textbf{\textit{Material Design}} de Google \cite{material} para inspirar el diseño. La idea es sencilla: cada elemento de la interfaz se entiende como una \textbf{hoja de papel}. El diseñador maquetará la interfaz en base a hojas que se solapan, produciendo una sutil sombra cuando esto ocurre. + +\textit{Material design} provee una gran cantidad de \textbf{componentes} de control y \textbf{paletas} de colores. De todos ellos, escogeremos listas, menús desplegables y botones flotantes. Nos decantamos por un color \textbf{marrón}, que evoca tranquilidad y \textbf{estabilidad}, dando idea de un \textit{software} intuitivo y robusto. + +Una vez dibujados los primeros trazos, no es necesario maquetar completamente la interfaz con una aplicación para manipular imágenes, pudiendo diseñar las vistas en \textbf{\acrshort{HTML} y \acrshort{CSS}}, aún sin código de programación. Pero es muy útil dibujar al menos una página que nos sirva de \textbf{modelo}. La siguiente imagen es una primera versión de la maqueta, diseñada con \textbf{\textit{Adobe Photoshop}}: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo4/maqueta} + \par\end{centering} + \smallskip + \caption{\label{fig:maqueta} Maquetación de las capas.} +\end{figure} + +\smallskip + +\subsection{Portada} +\label{subsec:portada} + +La portada es la vista principal y va a cumplir estas funciones: + +\begin{enumerate} + \item Presentar la aplicación y dar la bienvenida. + \item Introducir una contraseña para acceder al sistema. + \item Informar de un apagado o un reinicio. + \item Alertar de que la contraseña no es válida. +\end{enumerate} + +Para modelar la página adecuadamente, la consulta admitirá los siguientes parámetros: + +\begin{description} + \item[error=1] La contraseña no es correcta. + \item[view=shutdown|reboot] Se ha ordenado apagar o reiniciar el sistema. +\end{description} + +\subsubsection{Autentificación} + +El módulo de autentificación recibe la \textbf{contraseña} introducida por el usuario, y utiliza la interfaz del modelo para validarla. + +La contraseña será la de un usuario (a especificar) del sistema \textbf{Linux}, que provee una forma segura de almacenar contraseñas cifradas y gestionar usuarios. La verificación no se hará directamente, sino que llamaremos a un \textbf{programa externo}, que describiremos más abajo, en la sección \ref{subsec:applogin}, para que haga tal trabajo. + +El resto de vistas y controladores de la interfaz deberán consultar si se ha iniciado sesión antes de proceder a realizar la petición correspondiente. Cuando un usuario accede al sistema con una contraseña válida, se guardará una \textbf{marca} en su sesión para no tener que introducirla en cada vista. + + +\subsubsection{Maqueta} + +La vista proporcionará un fondo dinámico, con varias \textbf{imágenes temáticas}, y un cuadro para introducir la contraseña. Al hacerlo, se enviará al controlador, que se ocupará de \textbf{verificar} que la clave es correcta y concederá el acceso al reproductor. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo4/cap_portada} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_portada} Maqueta de la portada.} +\end{figure} + +\smallskip + +\subsubsection{Funciones} + +Definiremos las siguientes funciones: + +\begin{description}[style=nextline] + \item[login (password)] + Comprueba la contraseña llamando a una aplicación que diseñaremos específicamente. + + \begin{description} + \item[password] Clave introducida por el usuario. + \end{description} + + Si la contraseña es correcta, marca la autorización en la sesión y redirige a la vista del Reproductor. Si no, redirige a la portada y muestra un mensaje de error. + + \item[logout ()] + Cierra la sesión retirando la marca de autorización de la sesión. Redirige a la portada. + +\end{description} + +\subsubsection{Diagrama de uso} + +A continuación mostramos el diagrama de uso de la vista de portada y el módulo de acceso: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/mvc_acceso} + \par\end{centering} + \smallskip + \caption{\label{fig:mvc_acceso} Módulos implicados en el acceso al sistema.} +\end{figure} + +\smallskip + +\subsection{Reproductor} + +El reproductor es la parte fundamental de la interfaz. Mostrará los siguientes elementos: + +\begin{enumerate} + \item Estado del demonio (reproduciendo, pausado o detenido). + \item Nombre de la pieza que se está ejecutando (si procede). + \item Lista de reproducción activa (si procede). + \item Controles de reproducción: + + \begin{enumerate} + \item Pausar. + \item Reanudar. + \item Detener. + \item Siguiente pieza. + \item Pieza anterior. + \end{enumerate} +\end{enumerate} + +Hay que tener en cuenta que el protocolo de comunicación establece que el reproductor del demonio no es consciente de la lista de reproducción en la base de datos. Al ordenar una reproducción se le envía los \textbf{nombres de archivo}. De igual forma, al consultar el estado, devuelve el nombre de la pieza que se está ejecutando, cuya lista se puede conocer por \textbf{reunión natural} en la base de datos, y si no se encuentra, es porque se está reproduciendo un archivo externo, o tal vez otro usuario la ha eliminado. + +Esto se hace así para evitar mantener un \textbf{estado común} entre el demonio y la interfaz, que podría provocar \textbf{incoherencias} si el cliente se desconecta repentinamente o si hay varios usuarios conectados al mismo tiempo. + +\subsubsection{Maqueta} + +Guiados por la lista de controles requeridos y la filosofía de \textit{Material Design}, proponemos la siguiente interfaz visual: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo4/cap_reproductor} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_reproductor} Maqueta del reproductor.} +\end{figure} + +\smallskip + +\subsubsection{Funciones} + +Se definirán las siguientes funciones: + +\begin{description}[style=nextline] + \item[play (idplaylist, idscore)] + Reproduce en bucle la lista indicada, empezando por la pieza especificada. + + \begin{description} + \item[idplaylist] ID de la lista en la base de datos. + \item[idscore] (opcional) ID de la primera pieza a reproducir. + \end{description} + + Redirige a la vista del Reproductor. + + \item[pause ()] + Pausa la reproducción de la partitura. + + \item[resume ()] + Reanuda la ejecución de la pieza. + + \item[stop ()] + Detiene completamente la reproducción en el demonio. + +\end{description} + +\subsubsection{Diagrama de uso} + +El reproductor interacciona con el resto de la interfaz según este esquema: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/mvc_reproductor} + \par\end{centering} + \smallskip + \caption{\label{fig:mvc_reproductor} Módulos implicados en el reproductor.} +\end{figure} + +\smallskip + +\subsection{Gestión de listas de reproducción} +\label{subsec:listas} + +Una parte importante de la interfaz es facilitar la \textbf{organización} de la información. Las piezas musicales se clasificarán en \textbf{listas de reproducción}. Este módulo agrega la funcionalidad necesaria para gestionar listas. + +El gestor se presentará con los siguientes controles: + +\begin{enumerate} + \item Lista de listas de reproducción, con el siguiente contenido: + + \begin{enumerate} + \item Nombre de la lista. + \item Número de piezas contenidas. + \item Vínculo para acceder a la lista. + \item Vínculo para ejecutar la lista en el reproductor. + \end{enumerate} + + \item Botón para crear una nueva lista. Al dispararlo, abrirá un cuadro de diálogo para introducir el nombre de la lista. + +\end{enumerate} + +\subsubsection{Maqueta} + +Hemos diseñado la vista de este módulo con el siguiente aspecto: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo4/cap_listas} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_listas} Maqueta del gestor de listas de reproducción.} +\end{figure} + +\smallskip + +\subsubsection{Funciones} + +El controlador tendrá las siguientes funciones: + +\begin{description}[style=nextline] + \item[new\_playlist (name)] + Genera una lista nueva, con el nombre que se recibe. + + \begin{description} + \item[name] Nombre que identificará a la nueva lista. + \end{description} + + Redirige al administrador de la nueva lista. + + \item[rename\_playlist (idplaylist, name)] + Cambia el nombre de una lista existente. + + \begin{description} + \item[idplaylist] ID de la lista en la base de datos. + \item[name] Nuevo nombre a asignar a la lista. + \end{description} + + Redirige al administrador de la lista. + + \item[delete\_playlist (idplaylist)] + Elimina una lista de reproducción y todas las partituras que contenga. + + \begin{description} + \item[idplaylist] ID de la lista en la base de datos. + \end{description} + + Redirige al gestor de listas de reproducción. + +\end{description} + +\subsubsection{Diagrama de uso} + +Los componentes implicados en la gestión de listas se relacionan de la siguiente forma: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/mvc_listas} + \par\end{centering} + \smallskip + \caption{\label{fig:mvc_listas} Módulos implicados en el gestor de listas.} +\end{figure} + +\smallskip + +\subsection{Gestión de partituras} +\label{subsec:piezas} + +El gestor de partituras está estrechamente relacionado con el de listas de reproducción, en tanto que realmente es el \textbf{gestor de una lista} concreta. Desde aquí podremos conocer el contenido de cada lista, así como renombrarla y eliminarla. Al mismo tiempo, servirá para añadir \textbf{partituras}, cambiar su título y borrarlas, de una forma similar a las propias listas. + +Los controles de la interfaz serán los siguientes: + +\begin{enumerate} + \item Editar el nombre de la lista que se está mostrando. + \item Eliminar completamente la lista. + \item Añadir una pieza a la lista. + \item Control oculto para añadir una pieza arrastrando un fichero sobre la vista (\textit{drag \& drop}). + \item Lista de partituras que contiene la lista, con el siguiente contenido: + + \begin{enumerate} + \item Nombre de la pieza. + \item Duración de la obra. + \item Vínculo para reproducirla. + \item Vínculo para descargarla en el cliente. + \item Control para renombrar la partitura. + \item Control para eliminar la pieza. + \end{enumerate} +\end{enumerate} + +\subsubsection{Maqueta} + +Todos los controles se dispondrán de la siguiente forma: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo4/cap_piezas} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_piezas} Maqueta del gestor de piezas musicales.} +\end{figure} + +\smallskip + +\subsubsection{Funciones} + +Para hacer funcionar este módulo son necesarios los siguientes procedimientos: + +\begin{description}[style=nextline] + \item[new\_score (idplaylist, name, score)] + Inserta una pieza en la lista de reproducción y guarda el archivo en el almacenamiento interno. Para conocer la duración de una partitura, hace una llamada a lun aplicación que diseñaremos para extraer información de archivos \acrshort{MIDI} (véase la sección \ref{subsec:midinfo}). + + \begin{description} + \item[idplaylist] ID de la lista de reproducción que contendrá la partitura. + \item[name] Nombre que identificará a la nueva obra. + \item[score] Fichero de formato \acrshort{MIDI} que contiene la pieza. + \end{description} + + Redirige al administrador de la lista contenedora. + + \item[rename\_score (idscore, name)] + Cambia el nombre de una pieza existente. + + \begin{description} + \item[idscore] ID de la partitura en la base de datos. + \item[name] Nuevo nombre a asignar a la pieza. + \end{description} + + Redirige al administrador de la lista que contiene la partitura. + + \item[delete\_score (idscore)] + Elimina una partitura de la base de datos y del almacenamiento. + + \begin{description} + \item[idscore] ID de la pieza en la base de datos. + \end{description} + + Redirige al gestor partituras que contenía a la pieza eliminada. + +\end{description} + +\subsubsection{Diagrama de uso} + +La interacción entre los componentes implicados es la siguiente: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/mvc_piezas} + \par\end{centering} + \smallskip + \caption{\label{fig:mvc_piezas} Módulos implicados en el gestor de partituras.} +\end{figure} + +\smallskip + +\subsection{Asignación del mando a listas} +\label{subsec:mando} + +Como ya sabemos, en base al diseño general, dispondremos de un mando a distancia que permitirá iniciar la reproducción de listas de partituras según una asignación que podrá realizar el usuario. + +La adición o sustracción de botones compete al \textbf{administrador} del sistema, pero la asignación puede ser modificada por cualquier usuario. La interfaz es sencilla: se mostrará una lista de todos los botones disponibles, junto a un \textbf{menú desplegable} que presentará todas las listas existente, dando opción a escoger una de ellas, o ninguna. + +Recordar que esta interfaz normalmente mostrará \textbf{menos botones} de los que tiene el mando, ya que se debe \textbf{reservar} al menos dos para pausar y detener la reproducción. + +\subsubsection{Maqueta} + +Esta es la vista de este componente: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo4/cap_mando} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_mando} Maqueta del gestor de botones del mando.} +\end{figure} + +\smallskip + +\subsubsection{Funciones} + +El controlador utilizará la siguiente función: + +\begin{description}[style=nextline] + \item[set\_shortcut (idshortcut, idplaylist)] + Asignar una lista de reproducción a un botón del mando. + + \begin{description} + \item[idshortcut] ID del botón del mando en la base de datos. + \item[idplaylist] ID de la lista de partituras escogida. Puede ser un valor nulo. + \end{description} + + Redirige a la vista del asignaciones del mando. +\end{description} + +\subsubsection{Diagrama de uso} + +El gestor de botones del mando relaciona sus componentes de la siguiente manera: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/mvc_mando} + \par\end{centering} + \smallskip + \caption{\label{fig:mvc_mando} Módulos implicados en el gestor del mando.} +\end{figure} + +\smallskip + +\subsection{Control de energía} + +Hemos contemplado proveer la posibilidad de apagar o reiniciar el sistema remotamente. Para ello, ofreceremos un menú en la cabecera de la pantalla, que será común a todas las vistas, excepto la portada, con el siguiente contenido: + +\begin{enumerate} + \item Apagar el sistema. + \item Reiniciar el sistema. +\end{enumerate} + +El control de energía es una operación de control, no de vista. El menú presentado se muestra en la figura \ref{fig:maqueta}. + +\subsubsection{Funciones} + +Tendremos dos funciones de control, que ejecutarán la orden correspondiente a la gestión de energía en el sistema operativo subyacente. + +\begin{description}[style=nextline] + \item[shutdown ()] + Solicita el apagado del sistema. Muestra un mensaje de confirmación. + + \item[reboot ()] + Solicita el reinicio del sistema. Muestra un mensaje de confirmación y programa una recarga de página. +\end{description} + +\subsubsection{Diagrama de uso} + +El diagrama de uso es más sencillo que en los casos anteriores, porque en este caso no tenemos una vista, solamente el controlador que ejecuta una orden en el sistema operativo. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/mvc_energia} + \par\end{centering} + \smallskip + \caption{\label{fig:mvc_energia} Módulos implicados en el control de energía.} +\end{figure} + +\smallskip + +\subsection{Soporte de idiomas} +\label{subsec:idiomas} + +Uno de los requisitos especificados es que la interfaz soporte varios idiomas. Modelaremos la solución para que sea fácil tanto escoger un idioma como \textbf{agregar} nuevas lenguas. + +Para ello, utilizaremos \textbf{archivos de traducción} independientes que el sistema detectará automáticamente, permitiendo que añadir un idioma sea tan sencillo como agregar un fichero nuevo. + +Al igual que el control de energía, el selector de idioma aparecerá como un menú desplegable en la \textbf{cabecera} de la aplicación, pero a diferencia de aquél, también se mostrará en la portada. + +\subsubsection{Formato del archivo de traducción} + +El sistema de traducción estará basado en pares \textbf{clave-contenido}. El lenguaje de los ficheros derivará del \acrshort{XML} ---\textit{\acrlong{XML}}--- y tendrá la siguiente estructura: + +\begin{description}[style=nextline] + \item[translation] + Elemento raíz. Define la traducción completa a un idioma. Sus atributos son: + + \begin{description} + \item[code] Código estándar del idioma, como ''es'' (español) o ''en'' (inglés). + \item[language] Nombre de la lengua, escrito en el propio idioma. + \end{description} + + Contendrá como hijos tantos elementos \textit{string} como sea necesario. + + \item[string] + Significado de una cadena clave. Tiene un atributo: + + \begin{description} + \item[name] Clave de traducción. + \end{description} + + Su nodo hijo será la cadena de texto que se mostrará en la interfaz. +\end{description} + +\subsubsection{Diagrama de uso} + +De la misma forma que ocurría con el gestor de energía, no existe una vista propia de este componente. Con lo cual solo tenemos elementos de modelo y de controlador: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/mvc_idioma} + \par\end{centering} + \smallskip + \caption{\label{fig:mvc_idioma} Módulos implicados en el control de energía.} +\end{figure} + +\smallskip + +\subsubsection{Funciones} + +El módulo de traducción consta de los siguientes elementos: + +\begin{description}[style=nextline] + \item[Estructura \textit{Translator}] + Representa un traductor, con los siguientes campos: + + \begin{description} + \item[code] Código estándar del idioma. + \item[language] Nombre de la lengua. + \item[strings : \textit{array(string)}] Lista de cadenas de traducción. + \end{description} + + \item[language (code)] + Selecciona una lengua para la interfaz y almacena el código en la sesión. + + \begin{description} + \item[code] Código del lenguaje, tal como aparece en el archivo de traducción. + \end{description} + + Redirige a la vista que ha llamado al controlador. + + \item[translator ()] + Pertenece al modelo. Busca y carga todos los archivos de traducción. + + \item[get\_translator (code)] + Pertenece al modelo. Busca y obtiene un objeto traductor. + + \begin{description} + \item[code] Código estándar del idioma. + \end{description} + + Devuelve el objeto traductor indicado por el código. +\end{description} + +\subsection{Navegación} + +Como hemos visto en las maquetas, tendremos un \textbf{menú lateral} que nos permitirá acceder a las vistas principales de la interfaz. Aparte quedan la portada, a la que no se podrá volver ---a menos que se cierre la sesión, lo que reiniciaría la navegación--- y el gestor de piezas de una lista, al que se accederá a través del gestor general de listas. + +El siguiente diagrama ilustra las principales posibilidades de navegación: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/navegacion} + \par\end{centering} + \smallskip + \caption{\label{fig:navegacion} Diagrama de navegabilidad entre vistas.} +\end{figure} + +\smallskip + +\subsection{Sesión} +\label{subsec:session} + +La comunicación entre servidor y cliente en un entorno \textit{web} utiliza el protocolo \acrshort{HTTP} (\textit{\acrlong{HTTP}}), un modelo de conexión \textbf{sin estado} ---\textit{stateless}---, una característica positiva en balance para este tipo de sistemas, pero nos limita a la hora de pretender una comunicación efectiva. + +Para solventar este problema, \textbf{almacenaremos} en el servidor una pequeña cantidad de información relativa al cliente, tal como la que sigue: + +\begin{enumerate} + \item Marca de autentificación. + \item Lenguaje que ha seleccionado para la interfaz. + \item Última vista ejecutada, útil para ciertos controladores. +\end{enumerate} + +En aras de promover un diseño limpio y extensible, aislaremos esta pequeña funcionalidad en un \textbf{módulo aparte} en el modelo, y que sea independiente del lenguaje de implementación. + +\subsubsection{Funciones} + +Las funciones del modelo dedicadas a manipular la sesión son las siguientes: + +\begin{description}[style=nextline] + \item[test\_auth ()] + Comprueba si existe marca de autentificación. Si no la hay, redirige a la portada. + + \item[get\_auth () : \textit{boolean}] + Devuelve si existe (\textit{true}) o no (\textit{false}) la marca de autentificación. + + \item[set\_auth ()] + Establece la marca de autentificación. El usuario se acaba de identificar. + + \item[unset\_auth ()] + Quita la marca de autentificación. El usuario acaba de cerrar la sesión. + + \item[set\_page (file)] + Guarda el nombre de una página como la última vista ejecutada. + + \begin{description} + \item[file] Nombre de la página. + \end{description} + + \item[last\_page ()] + Devuelve el nombre de la última página almacenada. + + \item[set\_language (code)] + Establece el código de idioma como seleccionado por el usuario. + + \begin{description} + \item[code] Código estándar del idioma escogido. + \end{description} + + \item[get\_language ()] + Devuelve el código de lengua escogido por el usuario o, en su defecto, el código del idioma por defecto. + +\end{description} + +\subsection{Comunicación con el demonio} +\label{subsec:web_demonio} + +Especificamos ahora el módulo que hará de modelo del s\textbf{ervicio de reproducción}, ofreciendo procedimientos para realizar las operaciones elementales sobre el reproductor. Se comunicará con el demonio a través del \textbf{\textit{socket} local} que implementa para tal efecto (véase el apartado \ref{subsec:daemon}), y utilizando el protocolo que describiremos en la sección \ref{sec:protocolo}. + +\subsubsection{Funciones} + +Como podremos ver, la interfaz de este componente actúa como tocón hacia las funciones que implementa el planificador, descrito en la sección \ref{subsec:planificador}. + +\begin{description}[style=nextline] + \item[driver ()] + Establece la comunicación con el \textit{socket}. En caso de error, muestra un mensaje. + + \item[driver\_play (playlist, ifirst) : \textit{boolean}] + Reproduce una lista de piezas en bucle. + + \begin{description} + \item[playlist : \textit{array(string)}] Lista de nombres de archivo \acrshort{MIDI} a reproducir. + \item[ifirst : \textit{integer}] Índice del primer archivo a ejecutar, que se pondrá a la cabeza de la lista. + \end{description} + + Devuelve \textit{true} en caso de éxito o \textit{false} en caso de error. + + \item[driver\_pause () : \textit{boolean}] + Pausa la reproducción, si estaba activa. Devuelve \textit{true} en caso de éxito o \textit{false} en caso de error. + + \item[driver\_resume () : \textit{boolean}] + Reanuda la ejecución, si estaba pausada. Devuelve \textit{true} en caso de éxito o \textit{false} en caso de error. + + \item[driver\_stop () : \textit{boolean}] + Detiene completamente la reproducción. Devuelve \textit{true} en caso de éxito o \textit{false} en caso de error. + + \item[driver\_status () : \textit{array}] + Consulta el estado de reproducción, y si corresponde, el nombre de archivo que se está reproduciendo. Devuelve un \textit{array} de uno o dos elementos, dependiendo del estado: + + \begin{description} + \item[PLAYING, ] Reproduciendo el archivo que indica (ruta absoluta). + \item[PAUSED, ] Pausado sobre el archivo espeficicado (ruta absoluta). + \item[STOPPED] Detenido. + \item[ENGINEER] En modo Ingeniería. Cualquier orden será rechazada mientras se mantenga en este estado. + \end{description} + +\end{description} + +\subsection{Comunicación con la base de datos} +\label{subsec:web_database} + +La base de datos, diseñada en la sección \ref{sec:database}, es el principal \textbf{nexo} de unión entre el controlador y la vista. Aparte de las operaciones obvias, como insertar, modificar y eliminar partituras y listas, será utilizada al recibir el nombre de archivo que se está reproduciendo para \textbf{inferir} el título de la obra y la lista a la que pertenece. + +Por otro lado, el controlador del mando realiza \textbf{asignaciones} de botones a listas, y esta información es recogida por el demonio, en el componente descrito en la sección \ref{subsec:daemon_mando}. + +\subsubsection{Funciones} + +La interfaz del modelo de la base de datos es la que sigue: + +\begin{description}[style=nextline] + \item[Estructura \textit{playlist}] + Representa una lista de reproducción. Sus campos son: + + \begin{description} + \item[id] Identificador único. + \item[name] Nombre de la lista. + \item[scores : \textit{array(score)}] Lista de partituras incluidas. + \end{description} + + \item[Estructura \textit{score}] + Representa una partitura musical. Incluye los siguientes atributos: + + \begin{description} + \item[id] Identificador único. + \item[name] Nombre de la lista. + \item[duration] Duración de la pieza, en segundos. + \item[source] Ruta del archivo asociado. + \item[playlist] ID de la lista contenedora. + \end{description} + + \item[Estructura \textit{shortcut}] + Representa una asignación de botón a una lista. Sus campos son: + + \begin{description} + \item[id] Identificador único del botón. + \item[playlist] Identificador de la lista de reproducción. + \end{description} + + \item[database ()] + Inicializa el módulo, se debe llamar a esta función antes que cualquier otra de esta interfaz. En caso de error, emite un mensaje. + + \item[db\_get\_playlists () : \textit{array(playlist)}] + Devuelve una lista de todas las listas existentes en la base de datos. + + \item[db\_insert\_playlist (name) : \textit{integer}] + Inserta una nueva lista de reproducción. + + \begin{description} + \item[name] Nombre asignado a la lista. + \end{description} + + Devuelve el ID de la nueva lista. + + \item[db\_get\_playlist (idplaylist) : \textit{playlist}] + Busca una lista por ID. + + \begin{description} + \item[idplaylist] Identificador único de lista. + \end{description} + + Devuelve la lista de reproducción, o un valor nulo si no se encuentra. + + \item[db\_rename\_playlist (idplaylist, name)] + Cambia el nombre de una lista. + + \begin{description} + \item[idplaylist] Identificador único de lista. + \item[name] Nuevo nombre de la lista. + \end{description} + + \item[db\_delete\_playlist (idplaylist)] + Borra una lista de la base de datos. + + \begin{description} + \item[idplaylist] Identificador único de lista. + \end{description} + + \item[db\_insert\_score (idplaylist, name, duration) : \textit{integer}] + Inserta una nueva partitura en la base de datos, dentro de una lista de reproducción + + \begin{description} + \item[idplaylist] Identificador único de la lista que contendrá a la pieza. + \item[name] Título de la obra insertada. + \item[duration] Duración de la partitura, en segundos. + \end{description} + + Devuelve la pieza insertada en una estructura \textit{score}. + + \item[db\_get\_score (idscore) : \textit{score}] + Obtiene una partitura por ID. + + \begin{description} + \item[idscore] Identificador único de pieza. + \end{description} + + Devuelve la estructura \textit{score} correspondiente, o un valor nulo si no se encuentra. + + \item[db\_find\_score (source) ] + Busca una partitura por el nombre de archivo. + + \begin{description} + \item[source] Nombre del archivo \acrshort{MIDI} como criterio de búsqueda. + \end{description} + + Devuelve el objeto \textit{score} de la partitura, o un valor nulo si no se encuentra. + + \item[db\_rename\_score (idscore, name)] + Cambia el nombre de una partitura. + + \begin{description} + \item[idscore] Identificador único de pieza. + \item[name] Nuevo título de la obra. + \end{description} + + \item[db\_delete\_score (idscore)] + Elimina la tupla correspondiente a una pieza. + + \begin{description} + \item[idscore] Identificador único de partitura. + \end{description} + + \item[db\_get\_shortcuts () : \textit{array(shortcut)}] + Obtiene una lista con todas las asignaciones del mando a distancia. + + \item[db\_set\_shortcut (idshortcut, idplaylist)] + Establece una asignación de un botón del mando a una lista de reproducción. + + \begin{description} + \item[idshortcut] Identificador único del botón. + \item[idplaylist] Identificador único de la lista. + \end{description} +\end{description} + +\newpage + +\section{Protocolo entre el control y el demonio} +\label{sec:protocolo} + +Como hemos visto, la interfaz de usuario y el servicio en segundo plano se comunican a través de un \textit{socket} que hace de puente entre el reproductor de la interfaz y el planificador del demonio. + +La interfaz estará basada en \textbf{lenguaje natural}, su diseño debe ser sencillo y debe maximizar la \textbf{coherencia} entre ambos subsistemas, evitando inconsistencias en supuestos como los siguientes: + +\begin{enumerate} + \item El usuario hace una petición de reproducción e \textbf{inmediatamente} después se desconecta. + \item Se \textbf{elimina} la lista de reproducción que se está ejecutando. + \item Varios usuarios controlan \textbf{simultáneamente} la interfaz. +\end{enumerate} + +Para obtener una comunicación consistente, el demonio no guardará más estado que el del \textbf{planificador}, y no será consciente de la organización en listas de reproducción de la base de datos. Por su parte, la interfaz gráfica se referirá a las partituras con \textbf{rutas absolutas} a los archivos correspondientes a las partituras. + +Las peticiones que describen el protocolo resultante, así como las posibles respuestas, se enumeran de la siguiente forma: + +\begin{description} + \item[PLAY [ *]] Reproducir una lista de archivos \acrshort{MIDI}, indicando las rutas completa, separadas por espacios. Respuesta: + + \begin{description} + \item[OK] en caso de éxito. + \item[ERROR] en caso de error o estar en modo Ingeniería. + \end{description} + + \item[PLAYLOOP [ * ]] Reproducir en bucle una lista de archivos \acrshort{MIDI}, indicando las rutas completa, separadas por espacios. Respuesta: + + \begin{description} + \item[OK] en caso de éxito. + \item[ERROR] en caso de error o estar en modo Ingeniería. + \end{description} + + \item[PAUSE] Pausar la reproducción. Silencia las notas pero manteniendo el estado. Respuesta: + + \begin{description} + \item[OK] en caso de éxito. + \item[ERROR] en caso de error, como estar detenido, o en modo Ingeniería. + \end{description} + + \item[RESUME] Reanuda la reproducción en el punto en que se pausó. Respuesta: + + \begin{description} + \item[OK] en caso de éxito. + \item[ERROR] en caso de error, como no estar pausado, o en modo Ingeniería. + \end{description} + + \item[STOP] Detiene completamente la reproducción y libera la lista de reproducción. Respuesta: + + \begin{description} + \item[OK] en caso de éxito. + \item[ERROR] en caso de error o estar en modo Ingeniería. + \end{description} + + \item[STATUS] Consulta el estado del reproductor. Respuesta: + + \begin{description} + \item[PLAYING ] Reproduciendo el archivo cuya ruta absoluta se especifica. + \item[PAUSED ] Pausado en un punto del archivo cuya ruta se indica. + \item[STOPPED] Detenido. Es el estado inicial. + \item[ENGINEER] En modo Ingeniería. No se podrá reproducir nada hasta desbloquearse. + \end{description} + +\end{description} + +\newpage + +\section{Aplicaciones auxiliares} + +De acuerdo con los requisitos, hemos concebido el sistema como la conjunción de tres grandes bloques: + +\begin{enumerate} + \item La base de datos, como almacenamiento persistente. + \item El demonio, como \textit{back-end}. + \item La interfaz, como \textit{frond-end}. +\end{enumerate} + +Sin embargo, tal como están diseñados, existe una \textbf{dependencia mutua} total, contraproducente para la fase de implementación, donde será necesario realizar \textbf{pequeñas pruebas} sobre el código que vayamos construyendo. + +Para \textbf{verificar el desarrollo}, vamos a prever la necesidad de probar los módulos críticos del diseño, a saber: + +\begin{enumerate} + \item Descodificador de archivos \acrshort{MIDI}. + \item Planificador. + \item Interfaz de salida. + \item Servidor \textit{socket}. +\end{enumerate} + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/daemon_critical} + \par\end{centering} + \smallskip + \caption{\label{fig:daemon_critical} Módulos críticos del back-end.} +\end{figure} + +\smallskip + +En las secciones siguientes describiremos las soluciones que nos servirán para probar estos componentes. + +Por otro lado, el \textit{front-end} necesita dos aplicaciones externas para distintos fines: + +\begin{enumerate} + \item El gestor de piezas (sección \ref{subsec:piezas}) requiere \textbf{validar} y conocer la \textbf{duración} de una partitura mediante un programa que analice archivos \acrshort{MIDI}. + \item El componente de autentificación (dentro de la sección \ref{subsec:portada}) necesita comprobar externamente la \textbf{contraseña} introducida por el usuario. +\end{enumerate} + +\subsection{Información de archivo MIDI} +\label{subsec:midinfo} + +Esta aplicación cumplirá dos fines: + +\begin{enumerate} + \item Validar el analizador de archivos \acrshort{MIDI}. + \item Servir al \textit{front-end} la duración de una partitura. +\end{enumerate} + +Sencillamente, utilizará la interfaz creada por el descodificador \acrshort{MIDI} (visto en la sección \ref{subsec:daemon_midi}) para enviar el nombre de un fichero \acrshort{MIDI}, \textbf{descodificarlo} y mostrar en la salida estándar la información básica de una partitura: + +\begin{enumerate} + \item Organización de las pistas. + \item Número de pistas. + \item División de tiempo. + \item Duración de la obra. +\end{enumerate} + +Esta información podrá ser aprovechada tanto desde el terminal como desde la interfaz gráfica. + +\subsubsection{Diagrama de uso} + +Al utilizar simplemente la interfaz del componente \acrshort{MIDI}, éste es el único elemento que habrá que implementar para validarlo. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/3]{capitulo4/midi_info} + \par\end{centering} + \smallskip + \caption{\label{fig:midi_info} Interacción del programa con el back-end.} +\end{figure} + +\smallskip + +\subsection{Simulador de reproducción} + +El siguiente bloque a construir será el \textbf{planificador} (véase la sección \ref{subsec:planificador}) y la interfaz de \textbf{salida} (explicada en la sección \ref{subsec:output}). Ésta es una parte fundamental del planificador pero, como ya explicamos, la colocamos en un componente aparte para permitir implementar la interfaz según nuestras necesidades, bien para movernos de un órgano a otro, o bien para definir otro tipo de salida. + +Vamos a hacer una pequeña aplicación que nos permita verificar el funcionamiento del planificador y la interfaz de salida, de la siguiente manera: + +\begin{enumerate} + \item Interactuará directamente con el planificador, de la misma forma que hará el \textit{socket} o el \acrshort{UART}. + \item Implementará la salida (diseñada para el \acrshort{GPIO}) sobre la salida estándar, suplantando a la \acrshort{PCB}. +\end{enumerate} + +\subsubsection{Diagrama de uso} + +Este programa utilizará el planificador e implementará la interfaz de salida: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/midi_test} + \par\end{centering} + \smallskip + \caption{\label{fig:midi_test} Interacción del programa con el back-end.} +\end{figure} + +\smallskip + +\subsection{Terminal del reproductor} +\label{subsec:terminal} + +Una vez implementados los componentes críticos del demonio, crearemos un sencillo programa que haga las \textbf{llamadas básicas} del protocolo a través del \textit{socket}, como lo hará la interfaz gráfica. Esto nos permitirá comprobar que la estructura principal funciona correctamente, y \textbf{manejar el reproductor} sin la interfaz gráfica. + +La aplicación admitirá los siguientes argumentos: + +\begin{description} + \item[play ] Ejecutar un fichero \acrshort{MIDI}. + \item[playloop ] Reproducir en bucle un archivo.. + \item[pause] Pausar la reproducción, si estaba funcionando. + \item[resume] Reanudar la ejecución, si estaba pausada. + \item[stop] Detener completamente la reproducción. + \item[status] Mostrar información del planificador. +\end{description} + +\subsubsection{Diagrama de uso} + +Contando con una etapa madura del desarrollo, el terminal se comunicará con el \textit{back-end} a través del socket. Esto requerirá que ya esté funcionando como proceso demonio, y permitirá detectar posibles errores de implementación. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo4/terminal} + \par\end{centering} + \smallskip + \caption{\label{fig:terminal} Interacción del programa con el back-end.} +\end{figure} + +\smallskip + +\subsection{Comprobación de contraseña} +\label{subsec:applogin} + +Por último, concebiremos una aplicación minimalista para comprobar la contraseña del usuario. Dependiendo del grado de seguridad que implantemos, crearemos o no un usuario dedicado con permiso para utilizar la interfaz gráfica. + +La aplicación recibe los siguientes argumentos por consola: + +\begin{enumerate} + \item Nombre de usuario. + \item Contraseña introducida. +\end{enumerate} + +Se verificará que la contraseña introducida corresponda a la del \textbf{usuario en Linux} con el nombre indicado, y el resultado se indicará como código de salida del proceso: + +\begin{description} + \item[0] Usuario y contraseña válidos. + \item[1] El nombre de usuario no existe, o bien la contraseña es incorrecta. +\end{description} + +\newpage + +\section{Resultado del diseño} + +El desarrollo de este capítulo nos ha permitido afinar con un alto nivel de detalle el esbozo inicial (figura \ref{fig:idea}), hasta obtener los tres grandes bloques del diseño: + +\begin{enumerate} + \item Un demonio de Linux, como \textit{back-end}. + \item Una base de datos, como sistema de almacenamiento persistente. + \item Una interfaz \textit{web}, como \textit{front-end}. +\end{enumerate} + +En definitiva, hemos concebido un completo sistema de control para la \acrshort{PCB}, cuyo funcionamiento se resume en el siguiente diagrama: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo4/sistema} + \par\end{centering} + \smallskip + \caption{\label{fig:sistema} Resumen del diseño del sistema.} +\end{figure} + +\smallskip -Entre sus prestaciones básicas se hallan: la manipulación de matrices, la representación de datos y funciones, la implementación de algoritmos, la creación de interfaces de usuario (GUI) y la comunicación con programas en otros lenguajes y con otros dispositivos hardware. El paquete MATLAB dispone de dos herramientas adicionales que expanden sus prestaciones, a saber, Simulink (plataforma de simulación multidominio) y GUIDE (editor de interfaces de usuario - GUI). Además, se pueden ampliar las capacidades de MATLAB con las cajas de herramientas (toolboxes); y las de Simulink con los paquetes de bloques (blocksets). +\newpage +\clearpage{\pagestyle{empty}\cleardoublepage} \ No newline at end of file diff --git a/report/subdocs/capitulo5.tex b/report/subdocs/capitulo5.tex index 8e32b11..8907003 100644 --- a/report/subdocs/capitulo5.tex +++ b/report/subdocs/capitulo5.tex @@ -1,359 +1,2066 @@ -\chapter{Implementación del sistema.} +\chapter{Implementación} \label{cap: capitulo_5} +\begin{quote} + \small \flushright ''\textit{Hay varias formas de hacer las cosas, y una de ellas es hacerlas bien.}'' \\ + --- Profesora Mª Amparo Vila Miranda (2010). +\end{quote} -En la fase de implementación es donde se sintetiza todo el análisis realizado anteriormente, -y se procede a formalizar el producto resultante. Como solución \textit{hardware} se plantea el -diseño del circuito en placa impresa (\acrshort{PCB}), llevándose al proceso de -fabricación y soldado de componentes. Por otro lado, en el aspecto \textit{software} se explicará el -método de programación seguido para la rutina de control, y se perfilará el firmware final. - -\section{Implementación \textit{Hardware}} -\label{sec:ImpHard} -Tal y como se introdujo en el la sección \ref{sec:ImpFirm}, el software ALTIUM Designer -versión 14.1 ha sido empleado para el diseño del circuito, tanto para el apartado esquemático -como para el diseño de la placa PCB. Este segundo punto consiste en posicionar los elementos -del circuito de manera que queden interconectados entre ellos siguiendo el patrón designado -en el esquemático. Esta interconexión consiste en pistas grabadas sobre una placa de cobre, -que será las encargadas de transportar corriente y permitir al circuito su funcionamiento. - -\subsection{Diseño y fabricación de \acrshort{PCB}} -\label{sec:Diseño} - -Partiendo del circuito esquemático de los diseños se genera el \textit{layout} que constituye, junto -con los componentes, el circuito electrónico del dispositivo. Para ello, ALTIUM Designer -ofrece multitud de funcionalidades que facilitan el trabajo y permiten alcanzar magníficos -resultados. Demasiadas para ser expuestas en estas líneas, aunque podemos resaltar la comodidad -para gestionar distintos proyectos y librerías, la creación de componentes en todos -sus niveles, y asistencia continua durante el diseño del layout que posibilitan un diseño de -calidad óptimo y minimizan los posibles errores -Realizado el conexionado lógico entre los distintos terminales (definido en el esquemático), -se procede a plantear la disposición física de los elementos, incluidas las pistas que interconectan -dichos terminales. Para realizar el \textit{layout}, no solo se necesita conocer la información -de los elementos a nivel funcional y eléctrico, sino también las especificaciones mecánicas del -encapsulado y del sustrato que soporta los componentes. - -La PCB la fabricaremos mediante el uso de una LPKF ProMat S62. Con la cual obtendremos una pracisión de 0.01 mils. - -\hfill -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.6]{capitulo5/maquina} -\par\end{centering} -\caption{\label{fig:maquina} LPKF ProMat S62.} -\end{figure} -\smallskip +\vspace{8em} +A lo largo de este capítulo vamos a explicar cómo hemos llevado a cabo el proceso de implementación del sistema, partiendo del diseño especificado en las páginas anteriores. -\subsection{Consideraciones previas} -Las siguientes consideraciones se tuvieron muy en cuenta ya que tienen un gran impacto en el resultado final de la \acrshort{PCB}. Ignorarlas haría que el funcionamiento no fuera el deseado. +Todos los bloques se han implantado con una filosofía similar, teniendo en cuenta que nos dirigimos a un \textbf{sistema empotrado}, de prestaciones limitadas, y donde la \textbf{seguridad} y el \textbf{tiempo de respuesta} son cruciales. -\begin{itemize} - \item \textbf{Anchura de las pistas y distancia entre las mismas:}Para el dimensionamiento de las pistas existen un gran número de parámetros que influyen en su tamaño final. En este proyecto se han tenido en cuenta la corriente que circula por la pista, el incremento de temperatura que experimentará ésta durante su funcionamiento, la distancia a la que está la pista más próxima, las propiedades del material sobre el que se imprime la \acrshort{PCB}, sus dimensiones y por último se añadió un margen de seguridad. Con el fin de obtener unos cálculos más precisos, se hizo uso del documento de Excel creado por Jack Olson \cite{Jack}, un diseñador de \acrshort{PCB}s que lleva mas de veinte años trabajando en este campo y que ha obtenido un certificado avanzado del IPC en Diseño de Interconexiones(CID). - -El dimensionamiento final fue 20 mils para las pistas de conexión entre los pins del Arduino UNO y los distintos devices, 50 mils para las pistas que van a 5V y entre 250 y 322 mils para las pistas de potencia. - - \item \textbf{Espaciado de componentes.}Debido a que la soldadura se realiza de forma manual, -con un soldador de estaño, es necesario tener acceso a patillas y pads de contacto, -junto con sus superficies de soldado. Cada montaje sugiere un espaciado concreto, pero -distancias de unos pocos milímetros suelen ser válidas. - - \item \textbf{Dimensiones de las huellas.}Con el componente colocado sobre la huella, es deseable -que se pueda tener acceso a dicha huella, facilitando así las labores de soldado. Para -estas dimensiones suele ser suficiente con unas décimas de milímetro. Un dimensionado -de huellas pensado para soldado con pasta en horno de \textit{reflow} o similar, puede complicar -notablemente la tarea. - - \item \textbf{Alineamiento de doble cara y dimensiones de vías y taladros.}Las placas -de doble cara llevan asociado el uso de vías y pads para componentes de agujero -pasante, y constituyen orificios que conectan el \textit{layout} de ambas capas. Por tanto, -cualquier elemento del diseño de una capa que constituya un orificio deberá estar -perfectamente alineado con la otra capa. Puesto que el alineamiento se realiza de forma -manual, las dimensiones vías y orificios están limitadas por dos cuestiones: la destreza -visual (incluso con el posible uso de microscopio o aparatos de aumento ópticos) y de -alineamiento manual, y la exactitud y diámetro de las herramientas de taladrado. Con -las herramientas disponibles, se pueden conseguir orificios de hasta 0.8 mm con un -alineamiento adecuado. - - \item \textbf{Metalización de vías y localización.}Otra de las restricciones de las vías (además -de sus dimensiones mínimas) se trata de la carencia de herramientas adecuadas para -la metalización. Mediante este proceso, estas vías son simplemente taladros, que -no ofrecen conexión eléctrica alguna entre ambas capas. Esa conexión se logra introduciendo -un pequeño cable, o elemento conductor, que se suelda por ambas caras, y -posteriormente se elimina el excedente. En cualquier caso, siempre supone un relieve -en el orificio de dicha vía, frente a las vías planas de fabricación industrial. Esto implica -que las vías no pueden localizarse debajo de componentes \acrshort{SMD} cuyo encapsulado -no disponga de espacio con la superficie de la placa. Así mismo, los componentes de -agujero pasante solo estarán conectados eléctricamente con la cara opuesta al componente, -ya que habitualmente no se podrá soldar la patilla por ambas caras del pad. -Este detalle ha de tenerse muy en cuenta para evitar errores indeseados en el diseño. -\end{itemize} +Debemos tener también en cuenta que el servicio podrá ser utilizado por \textbf{varios usuarios} a la vez ---incluso varios componentes--- y el planificador, si bien no requiere características de tiempo-real estricto, es necesario que responda adecuadamente a los tiempos marcados por la partitura. + +En el demonio, nuestra máxima prioridad será la \textbf{eficiencia}, mientras que en la interfaz \textit{web} nos centraremos en la \textbf{accesibilidad}. + +\newpage + +\section{Servicio del reproductor} + +Este bloque compone el \textit{back-end} del sistema. Comprende una gran cantidad de elementos técnicos y hace uso de numerosas funciones del sistema operativo. Vamos a escribirlo casi por completo en \textbf{lenguaje C}, por las siguientes razones: -\subsection{Modelo en 2D y 3D} -En esta sección se mostrará el resultado obtenido, tanto en 2D como en 3D. En la figura \ref{fig:noNet_net} podemos observar en la imagen de la izquierda la disposición de los distintos componentes que contendrá nuestra \acrshort{PCB} sin incluir las \textit{nets} que conectarán unos con otros. La \textit{rats net} nos indicará qué va conectado con que. En la imagen de la derecha, se muestra el resultado final del ruteo. +\begin{enumerate} + \item Alta calidad y \textbf{eficiencia}. + \item Cercanía al \textbf{\textit{hardware}}. + \item Capacidad para hacer \textbf{llamadas al sistema} Linux. + \item Posibilidad de acceder al código ensamblador para hacer \textbf{optimizaciones}. +\end{enumerate} +Aunque todos los ejecutables se van a compilar desde código \textit{C}, haremos uso de \textit{shell-scripts} y un \textit{Makefile} que nos permitirá compilar fácilmente las fuentes e instalar los ejecutables. +En ciertos componentes, necesitaremos hacer \textbf{prototipos} para estudiar su funcionamiento y realizar pruebas de concepto, antes de implantarlos definitivamente. Esto lo haremos en \textbf{Python}, un lenguaje interpretado y de programación más ágil que C. +En resumen, utilizaremos el siguiente procedimiento con los componentes más complejos, que así lo requieran: -El último paso es colocar los planos de masa. Para ello hacemos uso de la herramienta \textit{Polygon pour} de Altium. Hay que tener presente que hay que colocar un plano de masa tanto en la capa \textit{Bottom} como en la \textit{Top}. +\smallskip +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo5/prototipado} + \par\end{centering} + \smallskip + \caption{\label{fig:prototipado} Esquema de prototipado.} +\end{figure} -Una vez terminado la colocación de componentes, ruteo y planos de masa, podemos ver como quedará nuestro producto en 3D. A continuación, se presentarán imágenes del modelo en 3D desde distintas perspectivas. +\smallskip -Una vez terminados los modelos 2D y 3D procederemos a la fabricación. Como ya dijimos en la sección \ref{sec:Diseño}, usaremos una LPKF ProMat S62. Podemos dividir el proceso en dos fases: +El código hace uso de los siguientes componentes externos: \begin{enumerate} -\item Preparación archivos GERBER y NCdrills: Mediante el programa CircuitCAM preparamos el archivo de extensión .LMD que será el que contenga toda la información de por dónde debe trazar la fresadora las pistas y realizar los agujeros. -\item Procesado del archivo .LMD: Mediante el software BoardMaster calibramos el plotter PROTOMAT S62, preparamos la placa FR4, e importamos el archivo .LMD, desde el cual se fabricará finalmente la PCB. + \item Biblioteca estándar de C \cite{cplusplus}. + \item Interfaz \acrshort{POSIX} \cite{wiki_posix}. + \item Llamadas al sistema Linux \cite{manpages}. + \item Sistema de archivos especial \textit{GPIOFS} \cite{gpiofs}. + \item \acrshort{API} para C del cliente MySQL (para el módulo de base de datos) \cite{mysql}. + \item Biblioteca \textit{WiringPi} (solo para el modo Ingeniería) \cite{wiringpi}. + \item Biblioteca estándar de Python (para los prototipos) \cite{python}. \end{enumerate} -\subsection{Resultado final} -Una vez impresa la PCB y colocados todos los componentes, el resultado es el siguiente: +\subsection{Descodificador de MIDI} -IMAGENES DE LA PCB FINAL POR LA PARTE DE ARRIBA Y ABAJO - -Ya solo falta ver donde la colocaremos en el horno. De las distintas posibilidades que había se opta por colocarla en un lateral. Para ello se perfora el horno para que, una vez colocada, solo se vean el \glsname{LCD}, el rotary, el pulsador y los leds. El resultado se puede ver en la figura \ref{fig:corte}. +Este fue el primer módulo a implementar. Estudiado el análisis, el diseño es sencillo por la independencia entre eventos. Sin embargo, la implementación presentaba una \textbf{complejidad} notable, sobre todo porque no hay un carácter separador entre eventos, y tanto los meta-eventos como las marcas de duración tienen \textbf{longitud variable}. +Como ya indicamos en la sección \ref{sec:fmto_midi}, el protocolo \acrshort{MIDI} especifica que los valores numéricos se indican en \textit{big-endian}. Como el procesador del \textit{Raspberry Pi} funciona en \textit{little-endian}, hay que \textbf{intercambiar los \textit{bytes}} de los números que ocupen más de un \textit{byte}. La figuras siguientes ilustran este problema: \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.08]{capitulo5/corte} -\par\end{centering} -\caption{\label{fig:corte} NO SE QUÉ PONER.} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/3]{capitulo5/big_endian} + \includegraphics[width=\linewidth/3]{capitulo5/little_endian} + \par\end{centering} + \smallskip + \caption[Big-endian y little-endian]{\label{fig:endianness} Big-endian (izquierda) y little-endian (derecha). \cite{wiki_endianness}} \end{figure} + \smallskip -Finalmente, colocamos la \acrshort{PCB}. +Por otro lado, también sabemos que ciertos valores, como el \textit{delta} de cada evento o el tamaño de datos de los meta-eventos, son de \textbf{longitud variable}: cada \textit{byte} tiene un significando de 7 \textit{bits}, los menos significativos. Mientras el último \textit{bit} sea 1, entonces el \textit{byte} siguiente del archivo corresponde, de igual forma, a otros 7 \textit{bits}, que se colocarían a la derecha (menos significativos). \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.1]{capitulo5/fin} -\par\end{centering} -\caption{\label{fig:fin} NO SE QUÉ PONER.} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo5/varlen} + \par\end{centering} + \smallskip + \caption{\label{fig:varlen} Campo de longitud variable.} \end{figure} -\smallskip -\section{Implementacion \textit{Software}} +\smallskip -En los siguientes apartados se detallarán las distintas funciones de las que consta el código fuente. +Además, podemos ver que todos los tipos de evento se numeran a partir de $80_{16}$, o sea, su \textit{bit} más significativo es 1. Si el analizador buscara un tipo de evento y encontrara un valor por debajo de este número, significa que el archivo está \textbf{obviando el tipo} de evento, y está indicando los parámetros ---cuyo tope es 127---. -\subsection{Configuración del \glsname{LCD}} -La configuración del \glsname{LCD} es bastante simple. Lo único que necesitamos son las librerias \glsname{SPI}.h y LiquidCrystal.h. -La librería \glsname{SPI}.h la usamos para la conexión serie entre Arduino UNO y nuestro \glsname{LCD}. Siendo el Arduino UNO el maestro y el \glsname{LCD} el esclavo. Con esta librería controlamos las líneas \glsname{MISO}, \glsname{MOSI} y \glsname{SCK}. Estas líneas nos permitirán mandar datos entre el Arduino UNO y el \glsname{LCD}. -La librería LiquidCrystal.h nos permite controlar el \glsname{LCD} desde el Arduino UNO. Incluye una gran variedad de funciones entre las que destacaremos: +El \textbf{algoritmo de análisis} consiste, pues en recorrer el archivo por \textbf{pistas}, y clasificar cada evento según su tipo. El \textbf{flujo de trabajo} es el siguiente: -\begin{itemize} -\item \textbf{begin(columnas,filas).} Inicia la pantalla del \glsname{LCD} y especifica las dimensiones. -\item \textbf{setCursor(columna,fila).} Fija el cursor en una posición determinada. -\item \textbf{clear().} Limpia el \glsname{LCD} y sitúa el cursor en la esquina superior izquierda. -\end{itemize} +\smallskip -\subsection{Rotary encoder} -NI IDEA DE LO QUE HACE LA RUTINA +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo5/flujo_parser} + \par\end{centering} + \smallskip + \caption{\label{fig:flujo_parser} Diagrama de flujo del analizador.} +\end{figure} +\smallskip -\subsection{Lectura de temperatura} -Para la lectura de la temperatura haremos uso de la función analogRead. AnalogRead lee la tensión que tenemos en un pin y la divide en 1024 niveles, del modo que 0 Voltios equivaldría al nivel, o step, 0, y 5 Voltios a 1023, por lo que podemos decir que: +\subsubsection{Prototipo} -\begin{equation} -V=\left(\frac{analogRead(PT100)*5}{1024}\right) V -\end{equation} +En primer lugar hacemos una implementación sencilla en Python, que nos permita comprobar que hemos aplicado correctamente los conceptos. -Sabiendo el valor de la corriente que circula por la PT100, podemos calcular el valor de la resistencia mediante: +Todos los valores de los tipos enumerados se hacen mediante constantes. Tal como dicta el diseño, la clase principal es \code{MidiFile}, que recibe un nombre de archivo. Los métodos se han implementado de la siguiente forma: -\begin{equation} -R=\left(\frac{V}{I_{PT100}}\right) \Omega -\end{equation} +\begin{description}[style=nextline] + \item[\code{\_\_init\_\_(self, pathname)}] + Constructor: crea un archivo \acrshort{MIDI} completo desde un nombre de archivo (\code{pathname}). Abre el archivo, desempaqueta la cabecera y escribe los atributos del objeto en consecuencia. A continuación, inicializa la lista de pistas llamando al constructor de \code{MidiTrack} tantas veces como pistas indica el archivo. + + \item[\code{\_\_len\_\_(self)}] + Devuelve el tamaño de la lista de pistas. + + \item[\code{\_\_getitem\_\_(self, key)}] + Devuelve la pista indicada (\code{key}). + +\end{description} -Una vez sabemos el valor de la resistencia podemos calcular el valor de la temperatura. Partiendo que el valor de la resistencia es, +De esta forma, un archivo es sustancialmente una lista de pistas, y define los siguientes métodos: -\begin{equation} -R(t)=R(0)[1+A*t+B*t^{2}] \Omega -\end{equation} +\begin{description}[style=nextline] + \item[\code{\_\_init\_\_(self, file)}] + Constructor: crea una pista a partir de un fichero abierto (\code{file}), cuyo puntero debe estar al inicio de una nueva pista. Análogamente al constructor de \code{MidiFile}, analiza la cabecera, comprueba que sea válida y genera una lista de eventos utilizando para ello \code{MidiEvent.parseEvent()} + + \item[\code{\_\_iter\_\_(self)}] + Permite iterar sobre los eventos la pista, devolviendo un iterador de la lista de eventos. +\end{description} -podemos despejar t en función de los parámetros A, B, R(t) y R(0). Donde: -\newline -\newline - R_0 = 100 \Omega -\newline -A=3,908 * 10^{-3} -\newline -B=-5,775 * 10^{-7} +Otra de las clases a implementar es \code{MidiEvent}, que representa cada uno de los eventos contenidos en un archivo, y contiene los siguientes métodos: -Despejando queda: +\begin{description}[style=nextline] + \item[\code{\_\_init\_\_(self, delta, value, param1, param2)}] + Constructor: crea un evento \acrshort{MIDI}, copiando en el sujeto (\code{self}) el retardo temporal (\code{delta}), el tipo de evento, junto al canal (\code{value}) y los parámetros (\code{param1} y \code{param2}). + + \item[\code{\_\_repr\_\_(self)}] + Devuelve una cadena que expresa la representación del objeto, de la siguiente forma: + + \begin{center} + : Event @ ( , ) + \end{center} + + \item[\code{note(self)}] + Devuelve el código de nota (primer parámetro). + + \item[\code{velocity(self)}] + Devuelve la intensidad sonora (primer parámetro). + + \item[\code{aftertouch(self)}] + Devuelve la variación de intensidad, sita en el segundo parámetro si el tipo es \code{NOTE\_AFTERTOUCH} o en el primero en otro caso. + + \item[\code{controller(self)}] + Devuelve el número de controlador (primer parámetro). + + \item[value\code{(self)}] + Devuelve el valor del controlador (segundo parámetro). + + \item[program\code{(self)}] + Devuelve el código de programa (primer parámetro). + + \item[pitch\code{(self)}] + Devuelve el valor del \textit{pitch-bend} uniendo los parámetros: + + \begin{equation} + pitch = p_1 \; | \; (p_2 << 7) + \end{equation} + + \item[parseEvents(file)] + Método de clase. Analiza todos los eventos de la pista actual en el archivo (\code{file}), de acuerdo al diagrama de la figura \ref{fig:flujo_parser} hasta encontrar el meta-evento \code{END\_OF\_TRACK}. + + \item[\code{varlen(file)}] + Es una función auxiliar privada que recibe el archivo (\code{file}) apuntando a un campo de longitud variable (véase la figura \ref{fig:varlen}) y devuelve su valor. + +\end{description} -\begin{equation} -T=\left(\frac{-100*A*\sqrt{100^2*A^2-4*100*B*(100-R(t))}}{2*100*B}\right) ^{\circ}C -\end{equation} +Por último, la clase \code{MetaEvent} hereda de \code{MidiEvent} y, de acuerdo al diseño, tiene los siguientes métodos: +\begin{description}[style=nextline] + \item[\code{\_\_init\_\_(self, delta, evtype, data)}] + Constructor. Crea un metaevento copiando en el sujeto (\code{self}) el retardo temporal (\code{delta}), el tipo de meta-evento (\code{evtype}) y la cadena de datos (\code{data}). + + \item[\code{\_\_repr\_\_(self)}] + Devuelve una cadena que expresa la representación del objeto, de la siguiente forma: + + \begin{center} + : Meta-event @ ( , ) + \end{center} + + \item[\code{number(self)}] + Devuelve el número de secuencia (primer \textit{byte} de la cadena). + + \item[\code{text(self)}] + Devuelve la propia cadena de texto. + + \item[\code{channel(self)}] + Devuelve el canal por defecto (primer \textit{byte} de la cadena). + + \item[\code{tempo(self)}] + Calcula el \textit{tempo} en \textit{$\mu s / \quarternote$}. Este valor ocupa 3 \textit{bytes}, que se acuñan así: + + \begin{equation} + (d_0 << 16) \; | \; (d_1 << 8) \; | \; d_2 + \end{equation} + + \item[\code{offset(self)}] + Devuelve el desplazamiento temporal en una lista con el siguiente contenido: + + \begin{enumerate} + \item Velocidad, según los 2 \textit{bits} más significativos del primer \textit{byte} de la cadena: + + \begin{itemize} + \item $d_0[7:6] = 0 \Rightarrow 24 \; fps$ + \item $d_0[7:6] = 1 \Rightarrow 25 \; fps$ + \item $d_0[7:6] = 2 \Rightarrow 30 \; fps$ + \end{itemize} + + \item Número de horas ($d_0[5:0]$). + \item Número de minutos ($d_1$). + \item Número de segundos ($d_2$). + \item Número de cuadros ($d_3$). + \end{enumerate} + + \item[\code{time(self)}] + Devuelve la marca de compás en una lista, de la siguiente forma: + + \begin{enumerate} + \item Numerador: $d_0$. + \item Denominador: $2^{d_1}$. + \item Número de \textit{ticks} entre cada marca del metrónomo: $d_2$. + \item Subdivisión, en \textit{fusas / click}: $d_3$. + \end{enumerate} + + \item[\code{key(self)}] + Devuelve la tonalidad en una lista, con los siguientes valores: + + \begin{enumerate} + \item Número de $\sharp$ si es positivo, o número de $\flat$ si es negativo: $d_0$. + \item Modo: $d_1$ + \end{enumerate} +\end{description} -Una vez implementado esto, tras varias pruebas, observamos que obtenemos mucho ruido en nuestros resultados, tal y como muestra la figura \ref{fig:prueba1}. +Ya que es una prueba de concepto, el analizador emitirá un \textit{log} con todos los datos extraídos de un archivo. Un ejemplo de salida es el siguiente: \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.55]{capitulo5/prueba1} -\par\end{centering} -\caption{\label{fig:prueba1} Datos obtenidos en la primera lectura de temperatura.} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*2/3]{capitulo5/cap_parser} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_parser} Salida del prototipo del analizador.} \end{figure} + \smallskip -Ya que estas medidas no son fiables, aplico un filtro de media para suavizar el ruido. Pero no es suficiente, los datos siguen teniendo mucho ruido. +\subsubsection{Implementación final} + +Una vez puesto a prueba el analizador de \acrshort{MIDI} en Python, lo pasamos a C. Al ser un lenguaje no orientado a objetos, hay que introducir algunos cambios, pero el algoritmo es el mismo que el del prototipo. + +Sin embargo, las funciones no diferirán mucho del lenguaje anterior, porque en Python hay que poner el \textbf{sujeto} del método como primer parámetro, y en la nueva implementación haremos lo mismo. La diferencia más significativa es que tendremos que insertar un \textbf{destructor}. -Es por esto que implemento un filtro \glsname{FIR} paso bajo para intentar eliminar el ruido. Para el cálculo del orden y coeficientes del filtro \glsname{FIR} hago uso de la aplicación de Matlab \textit{Filter Design & Analysis Tool}. -Los datos que necesitamos para este filtro son el tiempo de muestreo y entre que frecuencias queremos nuestra banda de paso bajo. Por defecto, el orden que nos da Matlab es el optimo para el filtro. Pero es demasiado grande y al tener que realizar tantas operaciones el Arduino, se queda sin memoria. Es por esto que seleccionamos un orden acorde a nuestra memoria. La frecuencia de muestreo la obtenemos calculando cada cuanto tiempo tomamos una muestra de temperatura. Para ello nos ayudamos del osciloscopio para tener una exactitud mayor. Obtenemos que cada 9ms(337micro segundos) tenemos una muestra, por lo que la frecuencia de muestreo será de 111Hz. +En primer lugar, definimos los \textbf{tipos enumerados}: -AQUI SIGO CON LOS DATOS OBTENIDOS DE MATLAB, ESPERAR A TENER EL HORNO MONTADO Y VER HASTA CUANTO PUEDO LLEGAR DE ORDEN DEL FILTRO. +\begin{description} + \item[\code{enum format\_t}] Formato del archivo: + + \begin{description} + \item[\code{SINGLE\_TRACK}] Una sola pista. + \item[\code{MULTIPLE\_INDEPENDENT}] Varias pistas, simultáneas. + \item[\code{MULTIPLE\_SIMULTANEOUS}] Varias pistas, independientes. + \end{description} + + \item[\code{enum division\_t}] Unidad de medida de la división de tiempo: + + \begin{description} + \item[TICKS\ PER\ BEAT] La división se especifica en \textit{ticks}/\quarternote. + \item[FRAMES\_PER\_SECOND] La división se especifica en \textit{ticks/fotograma}. + \end{description} + + \item[\code{enum midievent\_type\_t}] Tipo de evento \acrshort{MIDI}. Se enumeran en la tabla \ref{tab:midi_eventos}. + \item[\code{enum metaevent\_type\_t}] Tipo de meta-evento. Se enumeran en la tabla \ref{tab:midi_metaeventos}. + + \item[\code{enum midimode\_t}] Modo tonal: + + \begin{description} + \item[MAJOR] Modo mayor. + \item[MINOR] Modo menor. + \end{description} +\end{description} -Una vez implementado el filtro \glsname{FIR} podemos observar como mejora nuestras lecturas de temperatura y no tenemos tanto ruido como al principio. +Aparte del resto de transformaciones obvias, en pro de la velocidad de ejecución, hacemos los siguientes cambios: +\begin{enumerate} + \item Anteponemos un \textbf{prefijo} a las funciones propias de cada estructura. El primer parámetro de todas ellas será un puntero a la misma. + + \item Eliminamos las funciones de consula que acceden llanamente a los parámetros, y a cambio sustituimos los parámetros simples por \textbf{uniones} con los nombres de las funciones. + + \item Ya que no podemos conocer a \textit{priori} el número de eventos que contendrá una pista, vamos a interpretar la composición propuesta por el diagrama \ref{fig:uml_midi} como una \textbf{lista enlazada} de eventos. Ya que la inserción y la lectura van a ser secuenciales, garantizamos una eficiencia algorítmica $O(1)$ en cada acceso. +\end{enumerate} +\subsection{Planificador} +\label{subsec:impl_planificador} +El planificador es la parte más crítica del sistema: debe cronometrar y ejecutar los eventos del archivo que está abierto, y atender a las llamadas declaradas en la interfaz. +El procedimiento básico es sencillo: cada evento tiene una marca de tiempo respecto al evento anterior. El sistema debe ''dormir'' el tiempo indicado ejecutar el evento, y avanzar al siguiente, hasta la marca de fin de pista. +Solo vamos a atender cuatro tipos de evento: -\subsection{Lectura del pulsador} -La lectura del pulsador se hace comprobando el estado del boton ha cambiado. Para evitar el efecto rebote introducimos un tiempo de debounce para que no nos lea dos pulsaciones al pulsar una sola vez el pulsador. +\begin{enumerate} + \item Evento NOTE\_ON, para activar una nota. + \item Evento NOTE\_OFF, para desactivar una nota. + \item Metaevento TEMPO, para establecer la velocidad. + \item Metaevento END\_OF\_TRACK, para terminar. +\end{enumerate} -\section{Implementación del algoritmo \glsname{PID}} -En este apartado se explicará los pasos seguidos para el ajuste del algoritmo \glsname{PID}. Empezaremos estudiando cada uno de los distintos métodos de ajuste de parámetros \glsname{PID}. -Los métodos que estudiaremos en los siguientes apartados son: +\subsubsection{Prototipo} -\begin{itemize} -\item Sintonía Zieger-Nichols. \cite{Ibrahim} -\item Método del relé. \cite{wilson} -\item Ajuste manual del sistema.\cite{Skogestad} -\end{itemize} +De la misma forma que hicimos con el descodificador de archivos \acrshort{MIDI}, vamos a escribir un prototipo sencillo en Python. Recibirá un objeto de la clase \code{MidiFile} e interpretará una de sus pistas, a fin de estudiar la salida y hacer ajustes si es necesario. -\subsection{Sintonía Zieger-Nichols} -Busca valores para los parámetros \glsname{PID} de la planta basado en la respuesta del sistema en -lazo abierto o cerrado. Para poder emplear el método ZN en lazo abierto es necesario que la -respuesta del sistema ante un escalón de potencia sea de tipo S, figura \ref{fig:ZN1}: +El algoritmo se estructurará según el siguiente diagrama: \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo5/ZN1} -\par\end{centering} -\caption{\label{fig:ZN1} Lazo abierto con respuesta tipo S\cite{Ibrahim}.} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo5/flujo_planificacion} + \par\end{centering} + \smallskip + \caption{\label{fig:flujo_planificacion} Diagrama de flujo del planificador (simple).} \end{figure} + \smallskip -Los parámetros \glsname{PID} se obtienen empleando la siguiente tabla: +En este caso, implementamos la clase \code{Instrument} para abstraernos de la configuración del instrumento, que tendrá que definir mínimamente algunas funciones de la interfaz de salida: + +\begin{description}[style=nextline] + \item[\code{state}] + Estado del instrumento. Almacena qué notas están activas y cuáles inactivas. En lugar de una lista de \textit{booleanos}, será un simple número entero que trataremos como un campo de \textit{bits}, correspondiendo el más significativo a la nota más aguda, y el \textit{bit} menos significativo a la tecla más grave. + + \item[\code{length}] + Especifica el número de notas que admite nuestro instrumento. Será el ancho del campo de \textit{bits}. + + \item[\code{offset}] + Indica la primera nota del instrumento como el desplazamiento respecto a la primera nota \acrshort{MIDI}. + + \item[\code{\_\_init\_\_(self, length, offset}] + Constructor. Crea las estructuras de datos en \code{self} conociendo la longitud del teclado (\code{length}) y la primera nota (\code{offset}). + + \item[\code{note\_on(self, note)}] + Activa la nota indicada (\code{note}), comprobando antes si está dentro del rango cubierto por el teclado. + + \item[\code{note\_off(self, note)}] + Apaga la nota indicada (\code{note}) si ésta pertenece al teclado. + + \item[\code{play(self, midi, track)}] + Método del planificador. Cronometra y ejecuta la pista indicada (\code{track}) del archivo de la clase \code{MidiFile}. Esta función implementa el algoritmo que queremos prototipar. + +\end{description} + +La salida es muy simple: muestra para cada evento el cambio producido y el estado actual: \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo5/ZN2} -\par\end{centering} -\caption{\label{fig:ZN2} Parámetros \glsname{PID} para Zieger-Nichols\cite{Ibrahim}.} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*2/3]{capitulo5/cap_pytest} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_pytest} Captura de pantalla del prototipo.} \end{figure} + \smallskip -Para la sintonización en lazo cerrado, se realiza el siguiente procedimiento manual: +El prototipo nos sirvió para extraer dos objeciones: + +\begin{enumerate} + \item El \textbf{retraso} ($\Delta$) del evento es \textbf{inversamente proporcional} al \textit{tempo} y a la división de tiempo, indicada en la cabecera del archivo. Así pues, como el \textit{tempo} se expresa invertido, la espera se calcula de la siguiente forma: + + \begin{equation} + retraso \; (\mu s) = \frac{\Delta \; (ticks) \; \times \; tempo \; (\mu s / \quarternote)}{division \; (ticks / \quarternote)} + \end{equation} + + \item La semántica para \textbf{desactivar una nota} no solo se hace con un evento NOTE\_OFF, sino que algunas piezas lo especifican con un evento NOTE\_ON con velocidad 0. Esto resulta útil para ahorrar espacio de almacenamiento, repitiendo el mismo tipo de evento. +\end{enumerate} + +Una vez corregidos estos detalles, el prototipo cumple su objetivo correctamente. + +\subsubsection{Implementación final} + +El paso siguiente es implantar el algoritmo en C con los correspondientes añadidos. El más importante es que, en realidad, no debemos ejecutar una pista, sino tantas como tenga el archivo. Tenemos dos alternativas: \begin{enumerate} -\item Se activa únicamente el control proporcional, y se ajusta la respuesta a un determinado \textit{set point}. -\item Se modifica el valor de $K_{p}$ hasta conseguir ver una oscilación estable en la salida. Este -valor de ganancia será la ganancia crítica, $K_{u}$. -\item Se obtiene el período crítico $K_{p}$ de la señal oscilatoria, figura \ref{fig:ZN3}: + \item A \textbf{cada pista} se le asigna una \textbf{hebra} de ejecución. Se inician todas a la vez y se esperan al final. + \item Ampliamos el algoritmo para que una sola hebra ejecute \textbf{todas las pistas} de forma \textbf{síncrona}. +\end{enumerate} + +Como hemos podido deducir del diseño, nos decantamos por la \textbf{segunda opción}, considerando que todas las hebras tendrían que sincronizarse con la interfaz de salida, haciendo más llamadas de las necesarias. Además, las llamadas al sistema para retrasar la ejecución, así como las dedicadas a sincronizar la exclusión mutua, \textbf{desfasarían las pistas}, provocando una interpretación musical incorrecta. + +Ya que el procesador del \textit{Raspberry Pi} solo tiene un \textbf{núcleo}, no vamos a ganar tiempo dividiendo el proceso en hebras, si sabemos manejar correctamente las pistas. Para ello, diseñamos el algoritmo descrito en la sección \ref{subsec:planificador}, que requerirá una sola hebra, que llamaremos \textbf{hebra de reproducción}. + +El planificador define su interfaz de la siguiente manera: + +\begin{description}[style=nextline] + \item[enum player\_state\_t] + + Estado interno del reproductor. + + \begin{description} + \item[\code{PAUSED}] En pausa. + \item[\code{PLAYING}] Reproduciendo. + \item[\code{STOPPED}] Detenido completamente. + \item[\code{ENGINEER}] En modo Ingeniería. No se puede reproducir. + \end{description} + + El orden de los tipos debe hacerse cuidadosamente para permitir al compilador generar un código óptimo \cite{vikman_switch}: Si las funciones utilizan la sentencia \code{switch} con etiquetas que comparten instrucciones (no todas acaban en \code{break}), es buena práctica que las etiquetas sigan el orden en que se ha declarado la enumeración. + + \item[\code{int player\_start(char **playlist, int n, int loop)}] + Inicia la hebra de reproducción. Si ésta estaba en funcionamiento, primero la detiene. En primer lugar almacena la lista de rutas de archivo (\code{playlist}), el índice de la primera pieza a ejecutar (\code{n}) y la especificación de reproducir o no en bucle (\code{loop}). + + Ya que la terminación de la hebra anterior pudo ser natural o forzada, esta función es la encargada de eliminar la lista de reproducción precedente, si la hubiera. Una vez hecho esto, lanza la hebra de reproducción y devuelve el código de error (normalmente 0). + + \item[\code{int player\_wait()}] + + Bloquea a la hebra llamante hasta que la hebra de reproducción termine, y devuelve siempre \code{NULL}. + + \item[\code{int player\_pause()}] + + Comprueba que la hebra está funcionando y la pausa, cambiando el estado a \code{PAUSED}. A fin de evitar la espera activa de la hebra de reproducción, utilizaremos un semáforo de sincronización, que explicaremos más abajo. + + Devuelve 0 si ha pausado correctamente, o -1 si no estaba en ejecución. + + \item[\code{int player\_resume()}] + + Al contrario que la función anterior, comprueba que estaba en pausa, cambia el estado a \code{PLAYING} y señala el semáforo para despertar a la hebra de reproducción. Si estaba en reproducción, no hace nada. + + Devuelve 0 si se ha reanudado la reproducción (o ya estaba funcionando), o -1 si estaba detenido. + + \item[\code{int player\_stop()}] + + Provoca la detención de la hebra de reproducción cambiando el estado a \code{STOPPED}, y espera a que la hebra termine efectivamente. Si estaba en pausa, primero despierta a la hebra para que termine por sí sola. + + Devuelve 0 si se ha detenido correctamente. Solo devuelve -1 si estaba en modo Ingeniería. + + \item[\code{player\_state\_t player\_state(char *file)}] + + Esta función devuelve el estado actual del reproductor. En caso de que estuviera en funcionamiento o pausado, copia en el parámetro \code{file} la ruta del archivo que está reproduciendo la hebra. + + \item[\code{int player\_engineer\_enter()}] + + Entra en el modo Ingeniería cambiando el estado a \code{ENGINEER}. Si la hebra estaba iniciada, previamente la detiene completamente. Si ya está en modo Ingeniería, no hace nada. + + Siempre devuelve 0. + + \item[\code{int player\_engineer\_exit()}] + + Sale del modo Ingeniería, si estaba dentro de él. El estado a la salida de \code{STOPPED}. Devuelve 0 si ha salido correctamente, o -1 si no estaba dentro. +\end{description} + +Además, el módulo implementa los siguientes elementos de forma \textbf{estática}. Esto, en el ámbito del lenguaje C, significa que los símbolos no se exportan y, en consecuencia, solo las funciones dentro del módulo pueden llamarlas. Es el equivalente a los métodos privados en los lenguajes orientados a objetos. Son las siguientes: + +\begin{description}[style=nextline] + \item[\code{void* player\_run(void *arg)}] + Punto de inicio de la hebra de reproducción. Consiste sencillamente en un bucle que recorre la lista de reproducción. En cada ciclo, abre el archivo correspondiente con ayuda del módulo \acrshort{MIDI} y lo ejecuta llamando a \code{playscore()}. Si la lectura falla, se ignora el archivo. En cualquier caso, después del uso, se destruye. + + Si se ha marcado la ejecución en bucle, al terminar de reproducir la lista, se vuelve al principio, indefinidamente. Si se diera el (improbable) caso de que todos los archivos de la lista fallen, la hebra termina. + + Devuelve siempre \code{NULL} como código de retorno del subproceso. + + \item[\code{int playscore(midifile\_t *file)}] + + Implementa el algoritmo de planificación para reproducir el archivo (\code{file}). Aplica el procedimiento descrito, al que añade una comprobación de estado en cada ciclo del bucle principal: + + \begin{description} + \item[\code{PLAYING}] Continúa la ejecución normalmente. + + \item[\code{PAUSED}] Silencia la salida (manteniendo el estado) y pausa la reproducción. Como hemos adelantado, utiliza un semáforo para evitar la espera activa. El subproceso se bloquea hasta que otra hebra llame a \code{player\_pause()}, que es la que señala dicho semáforo. + + \item[\code{STOPPED}] Restablece la salida (borra el estado) y sale del bucle principal. + \end{description} + + Para un rendimiento óptimo, el bucle que ejecuta inmediatamente los eventos llama a \code{output\_noteon()} y \code{output\_noteoff()}, que cambian el estado del módulo de salida pero no la exportan efectivamente al instrumento. Cuando la racha termina, se sincroniza con la salida ---\code{output\_update()}--- y realiza la espera mediante una llamada a \code{nanosleep()}. + + El método de salida queda patente por el código de retorno: + + \begin{description} + \item[0] Finalización natural. + \item[1] Finalización forzada por una llamada a \code{player\_stop()}. + \end{description} + +\end{description} + +\subsubsection{Metrónomo y velocidad} + +Todas las partituras tienen una \textbf{marca de \textit{tempo}}, es decir, la velocidad a la que se reproducen. Esto se indica mediante el \textbf{meta-evento} correspondiente, habitualmente en la primera pista. + +El planificador debe tener en cuenta este dato para reproducir correctamente la pieza. Si no se especificase el \textit{tempo}, se toma \textbf{por defecto} $\quarternote=120$, o $\quarternote=0.5 \;s$. + +La interfaz de salida permite marcar \textbf{pulsos de metrónomo} para marcar el \textit{tempo} mediante un \acrshort{led} o un zumbador. Para controlar el tiempo, el planificador incorpora una \textbf{pista extra} compuesta por negras (\quarternote). Cuando se agota su \textit{delta}, en lugar de volcarlas a en la salida mediante \code{output\_noteon()}, las indica llamando a \code{output\_metronome()}. + +\subsubsection{Concurrencia} + +El planificador puede ser llamado por el servidor de \textit{socket}, el controlador del mando o el gestor del modo Ingeniería en cualquier momento, y en cualquier punto del reproductor. Esto puede llegar a generar \textbf{condiciones de carrera}, o incluso bloquear el sistema si dos módulos pretenden llevar a cabo acciones al mismo tiempo. + +Además, debemos tener en cuenta posibles \textbf{usos ilegales} de la hebra de reproducción, como iniciarla, pausarla o detenerla varias veces consecutivas. Para evitar esto, como hemos descrito, las funciones públicas de control comprueban el estado antes de actuar. + +A fin de no provocar una condición de carrera entre la hebra de reproducción y el resto, la primera nunca cambiará el estado, incluso si la partitura ha acabado. En su lugar activa una \textbf{variable ''bandera''} volátil (no afectada por optimizaciones del compilador) para ser leída por las funciones de control. Si está marcada, cambiarán automáticamente el estado a \code{STOPPED}. + +Para evitar inconsistencias entre funciones públicas, todas ellas utilizarán un \textbf{\acrshort{mutex}} que monitoriza las llamadas, haciendo que toda función deba esperar a que termine cualquier otra que estuviera funcionando. + +Por último, la \textbf{espera activa} se evita con un semáforo que se comporta como un \acrshort{mutex}: La función \code{player\_pause()} en primer lugar decrementa el semáforo y luego pone el estado a \code{PAUSED} para que, en la próxima vuelta, el planificador lo detecte y se bloquee esperando al semáforo. Cuando cualquier función quiera despertar al planificador, lo hace al revés: primero pone el estado a \code{PLAYING} y después desbloquea el semáforo, así el planificador no cae dos veces por error en el código de espera. Una vez el reproductor consigue el semáforo, lo vuelve a incrementar. + +Hacemos esto así para que el valor ''por defecto'' sea 1, evitando problemas si se diera el caso de solicitar una pausa justo cuando el planificador ha salido del bucle y no va a esperar al semáforo. La alternativa era utilizar un \acrshort{mutex}, pero no tenemos garantía de que lo vaya a desbloquear la misma hebra (e.g. si pausamos desde la interfaz gráfica, en una hebra, y reanudamos desde el mando, en otra). Un \acrshort{mutex} caería en una \textbf{condición indefinida}, mientras que un semáforo responde correctamente. + +\subsection{Salida GPIO} + +Esta parte del programa supone el \textbf{puente} entre el planificador y la \acrshort{PCB}, transformará instrucciones de activación y desactivación de notas en señales lógicas que emitiremos por el \acrshort{GPIO}. + +Este módulo se diseñó de forma muy flexible para que se pudiera adaptar fácilmente a cualquier órgano, o incluso se pudiera dirigir a otra interfaz, como tal vez la salida estándar ---de hecho, en el simulador de reproducción (sección \ref{subsec:simulador_reproduccion}) redefiniremos el funcionamiento para que así sea---. + +Todas las implementaciones deben tener en común el hecho de almacenar el estado de todas las notas del instrumento. Las llamadas a \code{output\_noteon()} y \code{output\_noteoff()} cambiarán ese estado, y \code{output\_update()} volcará efectivamente esta información en la salida. + +\subsubsection{Prototipo} + +Inicialmente hicimos una \textbf{prueba de concepto} en Python para entender el funcionamiento de los registros de desplazamiento. Como ya explicamos en la sección de análisis (\ref{subsec:conexion_mecanica}), cada registro está dedicado a un componente del órgano, pero todos funcionan igual. + +La idea es conseguir ver en los \acrshort{led}s la interpretación de una pieza conocida y fácilmente reconocible. Hemos tomado como \textbf{ejemplo} el famoso fragmento de la \textit{Oda a la Alegría} de Ludwig van Beethoven: \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo5/ZN3} -\par\end{centering} -\caption{\label{fig:ZN3} Lazo cerrado con ganancia crítica\cite{Ibrahim}.} + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/beethoven_1voz} + \par\end{centering} + \smallskip + \caption{\label{fig:beethoven_1voz} Fragmento de la Oda a la Alegría de Beethoven.} \end{figure} + \smallskip -\item Finalmente se ajustan los parámetros con la siguiente relación: +Ya que no tenemos notas cromáticas, y disponemos de solo 7 \textit{bits} en la \acrshort{PCB}, vamos a establecer la siguiente equivalencia: \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo5/ZN4} -\par\end{centering} -\caption{\label{fig:ZN4} Parámetros \glsname{PID} para ZN en lazo cerrado\cite{Ibrahim}.} -\end{figure} + +\begin{center} + \begin{tabular}{|l|l|} + \hline Do & \code{1000000} \\ + \hline Re & \code{0100000} \\ + \hline Mi & \code{0010000} \\ + \hline Fa & \code{0001000} \\ + \hline Sol & \code{0000100} \\ + \hline La & \code{0000010} \\ + \hline Si & \code{0000001} \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:equiv_notas_prot} Equivalencia de notas en el prototipo.} +\end{center} + \smallskip +Cualquier \textbf{acorde} no sería más que una combinación de bits. Todo lo que tenemos que hacer es \textbf{volcar} cada nota por separado, \textbf{esperar} el tiempo que hagamos corresponder a una negra (\quarternote) y \textbf{silenciarlo} todo (volcar solo ceros). El procedimiento es muy sencillo: + +\begin{enumerate} + \item \textbf{Escribir} el valor de una celda del vector en el puerto \acrshort{GPIO} correspondiente. + \item Emitir un \textbf{pulso} en el puerto conectado a SRCLK para \textbf{desplazar} y almacenar. + \item Repetir los pasos 1 y 2 con el resto de \textit{bits}. + \item Emitir un pulso en el puerto conectado a RCLK para \textbf{copiar} del registro de desplazamiento al registro de almacenamiento. +\end{enumerate} + +Para emitir un pulso en el registro, actuamos de la siguiente forma, de acuerdo al manual técnico de los registros: + +\begin{enumerate} + \item Escribir ''1'' en el puerto llamando a \code{output()}. + \item Esperar 100 \textit{ns} con una llamada a \code{sleep()}. + \item Escribir ''0'' en el puerto. +\end{enumerate} + +\subsubsection{Implementación final} + +Este módulo va a ser llamado síncronamente por el planificador, por lo que todas las funciones que implementemos deben de ser tan rápidas como sea posible. El primer detalle importante es escoger una \textbf{estructura de datos} eficiente para almacenar el estado. + +En este caso, todos los registros tienen el mismo tamaño, y conocemos de antemano las dimensiones, con lo cual, tenemos dos opciones. Teniendo en cuenta que hay que \textbf{indizar} por (nota, pista), vamos a deducir el número de operaciones necesarias para la escritura (aleatoria) y la lectura (secuencial): + +\begin{enumerate} + \item Una variable entera \textbf{como campo de \textit{bits}}. + \begin{itemize} + \item Cada \underline{escritura} requiere: indirección + multiplicación + suma + desplazamiento + conjunción + escritura. + \item Cada \underline{lectura} requiere: desplazamiento. + \end{itemize} + + \item Una \textbf{matriz de \textit{bytes}}. + + \begin{itemize} + \item Cada \underline{escritura} requiere: multiplicación + suma + escritura. + \item Cada \underline{lectura} requiere: suma + indirección. + \end{itemize} \end{enumerate} -\subsection{Método del relé} -Es una variante del método ZN de lazo cerrado, y consiste en la incorporación de un -relé en la salida del bloque \glsname{PID} que realmente actúa como si fuese un bloque ON/OFF. Se -obtiene el período crítico $P_{u}$ y con él la ganancia crítica $K_{u}=\frac{4d}{\pi a}$, figura \ref{fig:rele1}. +La matriz de \textit{bytes} está mejor \textbf{equilibrada}, sobre todo teniendo en cuenta que se va a hacer más escrituras que lecturas. El campo de \textit{bits}, además, nos limita a 32 \textit{bits} en total, lo que nos obligaría a hacer modificaciones cuando extendamos los registros. + +Crearemos la matriz de esta manera: \smallskip -\begin{figure}[H]%here -\noindent \begin{centering} -\includegraphics[scale=0.7]{capitulo5/rele1} -\par\end{centering} -\caption{\label{fig:rele1} Sintonización con método del relé\cite{Wilson}.} -\end{figure} + +\begin{center} + \begin{tabular}{|c|cccc|} + \hline & \multicolumn{4}{c|}{N pistas} \\ + \hline \multirow{7}{*}{\rotatebox[]{90}{M notas}} & $s_{0,0}$ & $s_{0,1}$ & $s_{0,2}$ & $s_{0,3}$ \\ + & $s_{1,0}$ & $s_{1,1}$ & $s_{1,2}$ & $s_{1,3}$ \\ + & $s_{2,0}$ & $s_{2,1}$ & $s_{2,2}$ & $s_{2,3}$ \\ + & $s_{3,0}$ & $s_{3,1}$ & $s_{3,2}$ & $s_{3,3}$ \\ + & $s_{4,0}$ & $s_{4,1}$ & $s_{4,2}$ & $s_{4,3}$ \\ + & $s_{5,0}$ & $s_{5,1}$ & $s_{5,2}$ & $s_{5,3}$ \\ + & $s_{6,0}$ & $s_{6,1}$ & $s_{6,2}$ & $s_{6,3}$ \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:matriz_estatica} Configuración de las notas en el estado.} +\end{center} + +\smallskip + +El compilador, conociendo las dimensiones, convertirá la matriz estática en un \textit{array} de la siguiente forma: + +\smallskip + +\begin{center} + \begin{tabular}{|c|} + \hline $M\times N$ \textit{bytes} \\ + \hline $s_{0,0}$ $s_{0,1}$ $s_{0,2}$ $s_{0,3}$ $s_{1,0}$ $s_{1,1}$ ... $s_{6,2}$ $s_{6,3}$ \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:matriz_fisica} Disposición física de la matriz en memoria.} +\end{center} + +\smallskip + +Con esta estructura, el acceso aleatorio para escribir un valor en el estado se hará con la siguiente fórmula: + +\begin{center} + $s_{nota,pista} = v_{nota \times N + pista}$ +\end{center} + +Para \textbf{volcar} la información en los registros, seguiremos los mismos pasos que en el prototipo, pero en lugar de transmitir a un puerto \acrshort{GPIO}, transmitiremos a tantos como pistas tengamos, antes de enviar el pulso a SRCLK, que desplaza las notas de todos los registros a la vez. + +Hemos organizado la matriz para que la lectura se hagan en el \textbf{orden estricto} en que están los datos en memoria, con lo cual, en lugar de acceder a la matriz directamente y obligar al compilador a hacer una multiplicación y una suma, utilizaremos \textbf{aritmética de punteros} para movernos por ella. + +\subsection{Metrónomo} + +A diferencia de las notas musicales, el metrónomo \textbf{no se almacena} en el estado ni se retrasa su ejecución hasta llamar a \code{output\_update()}, sino que debe marcarse tan rápido como se ejecute la función \code{output\_metronome()}. + +Para hacer sonar los pulsos de metrónomo, la \acrshort{PCB} cuenta con un zumbador, tal como se definió en la fase de análisis. A pesar de que está diseñado para emitir sonidos agudos continuados, vamos a generar un \textbf{pulso de 1 \textit{ms}}. + +Para obtener la mayor velocidad de respuesta sin retrasar al planificador, la función \code{output\_init()} crea una \textbf{hebra} que espera un \textbf{semáforo}. \code{output\_init()} se limita a enviar una señal a dicho semáforo para despertar a la hebra y hacerla enviar un pulso al zumbador. + +\subsubsection{Acceso directo al GPIO} + +La siguiente cuestión es cómo acceder al \acrshort{GPIO}. Conocemos bien el \textbf{sistema de archivos} especial que nos brinda Linux, pero el hecho de actuar por medio de llamadas al sistema y acceso a ficheros para algo tan elemental podría resultar \textbf{ineficiente}. + +Los puertos \acrshort{GPIO} son \textbf{pines físicos} del \acrshort{SOCA}, y se puede acceder a ellos mediante el periférico correspondiente mediante \textbf{acceso a memoria}. Estudiando el manual del BCM2835, obtenemos la siguiente información: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline 0x20200000 & Dirección base \\ + \hline + \hline Base + 0 & \multirow{6}{*}{Selección de función} \\ + \cline{1-1} Base + 4 & \\ + \cline{1-1} Base + 8 & \\ + \cline{1-1} Base + 12 & \\ + \cline{1-1} Base + 16 & \\ + \cline{1-1} Base + 20 & \\ + \hline Base + 24 & Reservado \\ + \hline Base + 28 & \multirow{2}{*}{Poner a ''1''} \\ + \cline{1-1} Base + 32 & \\ + \hline Base + 36 & Reservado \\ + \hline Base + 40 & \multirow{2}{*}{Poner a ''0''} \\ + \cline{1-1} Base + 44 & \\ + \hline \multicolumn{2}{|c|}{...} \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:gpio_struct} Direcciones físicas del GPIO.} +\end{center} + +\smallskip + +El controlador de \acrshort{GPIO} utiiza registros de 32-\textit{bit}. Para obtener un puntero a una dirección de memoria física, tan solo necesitamos hacer una llamada a \code{mmap(file = ''dev/mem'', offset = 0x20200000)} \cite{soii}. + +A partir de ahí, podemos acceder a cada registro con los \textbf{desplazamientos} adecuados. Hay un \textbf{banco} de registros para poner a ''1'', escribiendo un 1 lógico en el \textit{bit} correspondiente al número de puerto, y otro para poner a ''0'', escribiendo un 1 lógico en el \textit{bit} adecuado. + +De esta forma logramos la mayor \textbf{eficiencia}, tanto por el acceso directo a memoria como la posibilidad de escribir en todas las pistas más el reloj en \textbf{una sola operación} de escritura. + +\subsubsection{Mapeo y tolerancia} + +Huelga decir que para logar una óptima reproducción, será necesario adaptar las partituras al órgano en cuestión, ya que cada ejemplar tendrá una rango de notas y un conjunto de registros distintos. Nuestra aplicación será lo más \textbf{estándar} posible a la hora de leer un archivo \acrshort{MIDI}, por ello, y para \textbf{evitar errores} por incompatibilidad, debemos contemplar que podemos recibir un archivo \acrshort{MIDI} cualquiera. + +El número de pistas y el tamaño de cada una es conocido en tiempo de \textbf{compilación}, como ya sabemos. Las funciones \code{output\_noteon()} y \code{output\_noteoff()} reciben el código de nota y el índice de pista, que se escribirá en el estado. Un detalle simple, pero importante, será \textbf{descartar} cualquier nota fuera del rango, y cualquier pista no declarada. + +Por otro lado, no es estrictamente necesario que el orden de las pistas en el archivo (pentagramas) coincida con el orden de los registros en la \acrshort{PCB}. Para modelar esto, tendremos un \textbf{\textit{array}} con los números de puerto \acrshort{GPIO} asociados a cada pista del archivo \acrshort{MIDI}: + +La \textbf{asignación por defecto}, para el órgano de prueba, será la siguiente: + +\smallskip + +\begin{center} + \begin{tabular}{|l|c|c|c|c|} + \hline \textbf{Pista} & 1 & 2 & 3 & 4 \\ + \hline \textbf{Puerto GPIO} & 02 & 03 & 17 & 04 \\ + \hline \textbf{Canal PCB} & S1 & S2 & S4 & S3 \\ + \hline \textbf{Componente} & Teclado 1 & Teclado 2 & Registros & Pedalier \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:asig_canales} Asignación de pistas al GPIO.} +\end{center} + \smallskip +\subsection{Servidor socket} -\subsection{Ajuste manual} -Este método se emplea cuando los diferentes algoritmos de sintonización no terminan de -ajustarse correctamente, o para mejorar ciertas características como el sobredisparo, tiempo -de respuesta, etc... Requiere un conocimiento avanzado del comportamiento de la planta. El -procedimiento es el siguiente: +Esta parte del programa es la vía de acceso al servicio, se dedica a atender las peticiones de otras aplicaciones, como la interfaz web, según el protocolo de comunicación diseñado. Para ello utiliza un \textit{socket} de Unix \cite{wiki_socket}, similar a los \textit{sockets} de Internet, pero dedicado a la comunicación inter-proceso dentro de la misma máquina, a través de memoria compartida. +El \textbf{código de inicialización}, en la función \code{socket\_init(uid, gid)}, hace lo siguiente: \begin{enumerate} -\item Se activa únicamente el control proporcional para un determinado set point. Se intenta -que el sobredisparo no sea demasiado alto y que la señal quede cercana a la consigna -seleccionada. -\item Se añade el control integral y se modifica su valor observando el cambio en las siguientes -características: + \item Crea la estructura de archivos de programación. + \item Asigna un archivo \textit{socket} en el sistema de archivos. Por defecto será \code{/run/organd.sock}. + \item Prepara el zócalo para escucha (modo servidor). + \item Establece como propietario el \acrshort{UID} y el \acrshort{GID} que recibe como parámetros, correspondientes a un usuario especial. + \item Solicita ignorar la señal \code{SIGPIPE}, que colgaría el programa si un cliente se desconecta repentinamente. +\end{enumerate} + +Por otro lado, el procedimiento \code{socket\_loop()} inicia el \textbf{bucle de escucha}: se bloquea hasta recibir una nueva petición y, a partir de ahí, actúa siguiendo el protocolo establecido en la sección \ref{sec:protocolo}, transmitiendo las órdenes al planificador. + +Recordemos que el planificador recibe una lista de nombres de archivo, como una \textbf{matriz de caracteres}, de cuya destrucción se ocupa él mismo. La función \code{socket\_play()} pues, \textbf{clasifica} la lista de archivos recibidas en la cadena a una lista de cadenas, antes de pasarla al planificador (\code{player\_start()}). + +\subsection{Servidor UART} + +El módulo de servicio del \acrshort{UART} tiene una estructura similar al del \textit{socket}, solo que atiende a las peticiones del mando a distancia que llegan por el \textbf{puerto en serie}. Por un lado el protocolo de comunicación es más sencillo, por otro, no conocemos la información de las listas asociadas a un botón, por lo que hay que hacer consultas a la \textbf{base de datos}. + +En primer lugar, \code{uart\_init()} abre la comunicación con el puerto en serie y establece los \textbf{parámetros de configuración} adecuados al receptor del mando (9600 \textit{baudios}) y bloqueo hasta recibir 10 caracteres, que es la longitud de la cadena que esperamos recibir. + +Para iniciar el \textbf{bucle de recepción} implementamos \code{uart\_loop()}, que simplemente crea una hebra y la inicia en \code{uart\_run()}. Como adelantamos en la fase de análisis (sección \ref{analisis_mando}), el descodificador envía en primer lugar el \textbf{número de serie} del mando, que comparamos con el número de serie registrado en tiempo de compilación. + +A continuación leemos el \textbf{código del botón}, codificado como ya describimos, y seguimos adelante según este esquema para un mando de dos botones: + +\begin{description} + \item[Botón 1] Inicia la lista de reproducción asignada al botón 1. + \item[Botón 2] Reproduce la lista asignada al botón 2. + \item[Ambos] Pausa la reproducción, o la reanuda. +\end{description} + +Para reproducir una lista, escribimos el código en una función auxiliar, \code{uart\_playlist()}, que se comunica con la \textbf{base de datos} en busca de una lista de reproducción asignada, y los nombres de archivo correspondientes, para generar un \textit{array} de rutas de fichero y llamar a \code{player\_start()}. + +Por otro lado, la función de \textbf{pausa/reanudar} llama a la función \code{uart\_pause()}, encargada de consultar el estado del planificador y actuar en consecuencia: si estaba funcionando llama a \code{player\_pause()}, y si estaba pausado ejecuta \code{player\_resume()}; en otro caso no realiza ninguna acción. + +La función para \textbf{detener} está implementada aunque actualmente no se utiliza. Simplemente hace llamar a \code{player\_stop()}, cuyo funcionamiento es inocuo si el reproductor ya estaba parado. + +\subsection{Comunicación con la base de datos} + +El módulo receptor del mando necesita conocer la asignación de botones a listas, y las rutas de archivo de las partituras pertenecientes a las listas. Esta información está almacenada en una base de datos, y el acceso se hace a través de un módulo aparte, con objeto de presentar una interfaz independiente del \acrshort{SGBD} que utilicemos. + +Como explicaremos más adelante, utilizaremos \textbf{MySQL}, de forma que nuestro módulo utilizará la biblioteca cliente de MySQL para C. Así, la implementación de las funciones de inicio y cierre, \code{db\_init()} y \code{db\_destroy()}, respectivamente, simplemente abren la comunicación con MySQL mediante \code{mysql\_real\_connect()} y la terminan con \code{mysql\_close()}. + +Para conectarse a la base de datos hay que conocer el \textbf{nombre de usuario} y la \textbf{contraseña} asignados a dicha base, que conocemos de antemano y están guardados en tiempo de compilación. + +La última función diseñada, \code{db\_query()}, es la encargada de \textbf{consultar} la lista de archivos en la base de datos, conocido el número de botón pulsado. La información recibida es devuelta como un puntero a una matriz de caracteres, a tratar por el módulo llamador. + +\subsection{Modo Ingeniería} + +El diseño ha contemplado un control de la mecánica del sistema, a través del \acrshort{LCD} y el codificador rotatorio, que consiste en un menú que permite entrar en modo Ingeniería para \textbf{activar y desactivar las notas} a placer, de una en una. De la misma forma, tendremos la opción para activar y desactivar el \textbf{metrónomo}, así como \textbf{apagar y reiniciar} el sistema. + +Como especificamos en la sección \ref{subsec:ingenieria}, la gestión de esta interfaz está diseñada como una \textbf{máquina de estados}. La función \code{periph\_init()} se encarga de preparar los puertos \acrshort{GPIO} asignados al codificador, e inicializa el \acrshort{LCD}. Por seguridad, activaremos la polarización de los puertos \acrshort{GPIO} de acuerdo a la utilizada por el codificador: \begin{itemize} -\item Sobredisparo. -\item Error en set point. -\item Tiempo de establecimiento. -\item Grado de oscilación. -\item Estabilidad en la potencia de salida. + \item \textit{Pull-up} para los canales A y B (giro). + \item \textit{Pull-down} para el pulsador. \end{itemize} -Cada modificación realizada en el parámetro integral $T_{I}$ se hace aumentando o disminuyendo -el valor al doble o mitad del valor anterior respectivamente. +Por último, esta función crea una \textbf{hebra independiente} para gestionar la máquina de estados. + +\subsubsection{Control de entrada} + +El codificador rotatorio producirá los eventos de entrada. De acuerdo con el análisis de este dispositivo (sección \ref{subsec:rotary}), entre dos puntos de equilibrio cambia el canal A, y entonces, dependiendo del valor de los canales A y B ---si coinciden o difieren--- interpretaremos un giro a la izquierda y otro a la derecha. -\item Si persisten oscilaciones de alta amplitud en el bloque PI se reajustan los parámetros -siguiendo la siguiente relación: $K'_{P}T'_{I}=fK_{P}T_{I}$ , con $f=0.1\frac{P_{0}}{T_{Io}}$, siendo P_{0} y T_{Io} el período de oscilación y la constante de tiempo integral anterior, respectivamente. -\item Para controlar oscilaciones de baja amplitud y mejorar la respuesta del sistema, se -agrega el bloque derivativo y se modifica el valor de $T_{D}$ observando los cambios para -las mismas características vistas en el bloque integral. Este parámetro es muy sensible -y puede conducir fácilmente a una inestabilidad en la potencia de salida, por lo que se -debe incluir únicamente en los casos en los que se aprecie una mejora significativa. +De esta forma, tenemos que esperar dos eventos: + +\begin{enumerate} + \item Cambio en el canal A. + \item Subida en el pulsador. \end{enumerate} + +A fin de evitar la \textbf{espera activa}, se crearán dos hebras que se bloquearán hasta recibir la señal correspondiente, cuando llamarán a dos funciones asignadas como \textit{callbacks}: + +\begin{description}[style=nextline] + \item[rot\_change()] Ha cambiado el canal A. Lee A y B, los compara y activa la bandera correspondiente. + \item[rot\_push()] Se ha pulsado el botón. Solicita una espera de 1 \textit{ms} y activa la bandera de pulsación. +\end{description} + +Ambas funciones utilizan un \textit{array} de banderas (\textit{flags}) para indicar qué evento está pendiente de atender, y señalan un \textbf{semáforo} para el control de la máquina de estados. + +La pulsación está sujeta a problemas de \textbf{rebotes}, que podrían disparar la función varias veces aun pulsando el botón una vez. Como vimos en la figura \ref{fig:rebotes}, existe una \textbf{incertidumbre} de $118 \; \mu s$ desde que comienza a subir la señal hasta que se queda estable. Por seguridad, estableceremos un tiempo de 1 \textit{ms} antes de hacer una \textbf{segunda lectura}, si sigue siendo positiva, aceptamos la pulsación. + +\subsubsection{Máquina de estados} + +La función principal de la hebra de control es \code{periph\_run()}, que implementa un bucle para atender los eventos y definir el \textbf{estado siguiente}. La implementación de esta función sigue la especificación del diagrama de la figura \ref{fig:engineer}. + +Cuando entra en modo Ingeniería, llama a la función \code{player\_engineer\_enter()} del planificador, que lo \textbf{aísla de la salida} del \acrshort{GPIO}, dejándolo libre para actuar sobre él con las llamadas a bajo nivel \code{output\_noteon()} y \code{output\_noteoff()}. + +Por otro lado, el menú ofrece la opción de activar y desactivar el \textbf{metrónomo}, para ello hace uso de las función \code{output\_metronome\_enable()}. Además, existe otro menú para \textbf{controlar la energía} del sistema, esto se hace llamando a la orden \code{shutdown} con la función \code{system()}. + +Al final del bucle, el subproceso se bloquea esperando que el usuario actúe y el \textit{callback} correspondiente señale el semáforo. + +\subsubsection{Control de salida} -\subsection{Sintonización \glsname{PID} del horno} -Empezamos empleando el método de sintonía de Zieger-Nichols fijando un \textit{setpoint} de $T=50^{\circ}C$. Tras varias pruebas obtenemos que para $a=K_{P}=3$ la respuesta queda cercana al punto de consigna. +La salida de este módulo se hace sobre el \acrshort{LCD}, que realimentará las acciones del usuario en modo Ingniería. Sin embargo, mientras no se use este modo, se mostrará el \textbf{estado del planificador} y, en su caso, la ruta del \textbf{archivo} que se está reproduciendo. +Para ello, cuando el bucle de la máquina de estados ha calculado el estado siguiente, se refresca la pantalla en función del nuevo estado, ya sea: -Podemos observar oscilaciones que presentan un periodo crítico de $P_{u}= 3800s$. Si aplicamos las reglas de sintonización de Zieger-Nichols para lazo cerrado: +\begin{enumerate} + \item Navegar por el menú. + \item Mostrar el estado del reproductor. + \item En modo Ingeniería, indicar la pista actual y la nota que está activa. +\end{enumerate} -$$K_{u}=0.45K_{P}=1.35$$ -$$T_{I}=\frac{P_{u}}{1.2}=3166$$ -Por lo que finalmente los parámetros de sintonización son: +Para mostrar el estado del reproductor, hay que tener en cuenta que la información va a cambiar aunque el usuario no interactúe con los mandos. Por ello, la espera del semáforo será \textbf{temporizada}: si tras un tiempo determinado el usuario no toca el control, la hebra se despierta sola y refresca la pantalla. -$$a=K_{u}=1.35$$ -$$b=\frac{K_{u}T}{T_{I}}=0.0042$$ +\subsection{Inicio del demonio} +Ahora vamos a crear el punto de inicio de nuestro servicio, para que se inicie durante el arranque del sistema operativo del \textit{Raspberry Pi}. Lo que este módulo hará será muy sencillo: iniciar todos los módulos y llamar a los bucles de escucha que incorporan en hebras diferentes. +\subsubsection{Características} +Un demonio ---en nomenclatura de la familia Unix--- es un programa que se ejecuta en segundo plano, es iniciado por el \textbf{\textit{boostrap}} del sistema operativo y no interactúa directamente con el usuario. Está diseñado para dar servicio a otras aplicaciones. Ni siquiera utiliza la entrada y salida estándar, en su lugar usa el registro del sistema. -$$K_{u}=0.6K_{P}=1.5$$ -$$T_{I}=\frac{P_{u}}{2}=1900$$ -$$T_{I}=\frac{P_{u}}{8}=475$$ +Al mismo tiempo, y paradójicamente, debe \textbf{terminar} lo antes posible para permitir que continúe el arranque del sistema. Para iniciar correctamente el demonio, la función principal del programa hará lo siguiente: \cite{shahmir_daemon} + +\begin{enumerate} + \item Crea una copia de sí mismo mediante una bifurcación, llamando a \code{fork()}. Como ya sabemos, esta función devuelve el ID del hijo al proceso padre y 0 al proceso hijo. En este punto, el padre termina. + + \item Crea una nueva sesión mediante \code{setsid()}, convirtiendo al proceso hijo en líder de su grupo de procesos. + + \item Cambia la carpeta de trabajo por la raíz del sistema, llamando a \code{chdir(''/'')}. + + \item Cierra mediante \code{close()} los descriptores de archivo de la entrada y salida estándar: \textit{stdin}, \textit{stdout} y \textit{stderr}. + + \item Abre el \textit{log} del sistema con \code{openlog()}. + + \item Inicia el módulo del \textit{socket}. + + \item Arranca el módulo del mando a distancia. + + \item Inicia el módulo del modo Ingeniería. + + \item Rebaja sus permisos a los del \acrshort{UID} y el \acrshort{GID} recibidos. + + \item Inicia el bucle de escucha del servidor del puerto en serie (en otra hebra). + + \item Llama al bucle de servicio del \textit{socket}. + +\end{enumerate} -Por lo que finalmente los parámetros de sintonización son: +Otra acción importante es \textbf{programar el cierre} controlado mediante una sencilla función que detenga la reproducción y llame a las funciones de limpieza ---las que terminan en \code{\_destroy()}---: + +\begin{enumerate} + \item Planificar dicha llamada cuando se termine el programa, haciendo uso de \code{atexit}. + \item Programar una salida normal ---\code{exit(0)}--- cuando se reciba la señal SIGTERM, que es la que envía por defecto \code{kill} y la que corresponde a pulsar Ctrl+C. +\end{enumerate} + +\subsubsection{Script de arranque} + +Conforme a la base estándar de Linux ---\acrshort{LSB}, \textit{\acrlong{LSB}}---, el arranque del sistema buscará un \textit{script} para iniciar el demonio en una ubicación dependiente del nivel de ejecución, y lo llamará con el argumento \code{''start''}. \cite{debian_lsbinit} + +Con objeto de arrancar los distintos servicios en el orden correcto para preservar dependencias, debemos escribir una \textbf{cabecera} en el código, que utilizará la orden \code{insserv} para registrar el servicio. En ella especificaremos la siguiente información: + +\begin{enumerate} + \item Requiere el servicio \code{syslog}, para el \textit{log} del sistema. + \item Se iniciará en los niveles de ejecución 2, 3, 4, 5 (multiusuario). \cite{wiki_runlevel} + \item Se parará en los niveles 0, 1 y 6 (monousuario, apagar y reiniciar). +\end{enumerate} + +De acuerdo al estándar, el \textit{script} atenderá a las siguientes órdenes: + +\begin{description} + \item[start] Arranca el demonio. Busca el proceso con \code{ps -e | grep}, si no lo encuentra, consulta el \acrshort{UID} y \acrshort{GID} del usuario dedicado, y llama al servicio pasando ambos argumentos. + + \item[stop] Busca el proceso y, si lo encuentra, lo detiene con \code{kill} y espera a que haya finalizado. + + \item[restart] Detiene el servicio y lo vuelve a iniciar. + + \item[force-reload] Esta orden sirve para recargar la información. Nuestro programa no tiene nada que hacer al respecto. + + \item[status] Informa de si el proceso está iniciado o no. Si está funcionando muestra el estado del planificador (reproduciendo, detenido, pausado o en modo Ingeniería). +\end{description} + +\subsubsection{Permisos de usuario} + +El demonio es llamado por el proceso \code{init} (que está empezando a ser reemplazado por \code{systemd}), por supuesto con permisos de \textbf{superusuario} (\textit{root}). Mantener al proceso con tales privilegios es \textbf{inseguro}. El servicio debe cambiar de usuario y de grupo con \code{setuid()} y \code{setgid()} cuando haya terminado de iniciar los dispositivos que requieren permisos especiales, especialmente el \acrshort{GPIO}, que mapea un puntero en memoria física. + +Para manejar los permisos adecuadamente, crearemos un usuario de sistema, de uso exclusivo para el demonio. Su \acrshort{UID} y su \acrshort{GID} se obtendrán mediante la \textbf{\acrshort{API} de criptografía} de Linux. + +\subsection{Seguridad} +\label{subsec:seg_demonio} + +Un servicio es un programa que funcionará en segundo plano sin interacción directa con el usuario. Incluso, a menos que éste sea un administrador del sistema, su existencia suele pasar inadvertida al resto de usuarios. + +Es muy importante que se mantenga en funcionamiento y con \textbf{capacidad de respuesta}, pues en caso de bloquearse no basta con cerrar una ventana y volver a abrirla, es más, podría bloquear a otras aplicaciones. + +Cualquier detalle de diseño o implementación puede ser decisivo a la hora de obtener un resultado \textbf{seguro y fiable}. Para ello, puliremos toda la programación relativa a la \textbf{entrada de datos}. Otra parte importante es la seguridad respecto a la concurrencia, ya abordada en la construcción del planificador, y que afinaremos a continuación. + +\subsubsection{Desbordamiento de la memoria de entrada} + +En este caso, dado que la recepción de órdenes viene dada por una aplicación, además, de implementación propia, no será necesario filtrarla tanto como haremos en el \textit{front-end}. Sin embargo, es necesario \textbf{acotar el riesgo} de que, bien por intrusión, bien por un error de programación, recibamos una cantidad inesperada de datos. + +El desbordamiento de memoria de entrada ---\textit{buffer overflow}--- se produce cuando una función de lectura acepta una cadena \textbf{mayor que la memoria} que tenía reservada. Esto puede dar si, por ejemplo, la única condición de parada es recibir el carácter de \textbf{fin de cadena} (0). + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo5/stack} + \par\end{centering} + \smallskip + \caption[Pila de aplicación en Linux]{\label{fig:stack} Pila de aplicación en Linux. \cite{zanero_cs}} +\end{figure} + +\smallskip + +Linux administra la pila en orden \textbf{descendente} (hacia direcciones de memoria menores). En cada llamada a función, se almacena el puntero de instrucción actual ---\acrshort{EIP}, \textit{\acrlong{EIP}}--- Si el \textit{buffer} de recepción está emplazado en la pila y se intenta escribir más allá de su longitud declarada, se sobrescribirá cualquier variable antes declarada. En el peor caso se modificará el puntero de instrucción guardado, causando una \textbf{violación de segmento} a la hora de retornar a la función anterior. + +Más aún, este riesgo podría ser aprovechado por un \textbf{intruso} para modificar las instrucciones del programa, accediendo ilegalmente al sistema. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo5/disaster_girl} + \par\end{centering} + \smallskip + \caption{\label{fig:disaster_girl} ¿Y si cambiamos el puntero de instrucción?} +\end{figure} + +\smallskip + +La \textbf{solución} adoptada es utilizar una cantidad razonable de memoria y limitar la cadena de entrada acotando tanto la \textbf{recepción} en la llamada al sistema \code{recv()} como la \textbf{comparación} de cadenas, usando \code{strncmp()} en lugar de \code{strcmp()}. Nuestro sistema utiliza \textit{buffers} de \textbf{4 \textit{KiB}}, memoria más que suficiente para recibir una lista de reproducción de tamaño considerable. + +\subsubsection{Permisos de usuario} + +Otra capa de seguridad se implanta utilizando permisos de usuario en el sistema de archivos de Linux, sobre el que descansa gran parte de la seguridad de este sistema operativo. Creamos el usuario \textbf{\code{organ}} y su grupo correspondiente, que serán \textbf{dueños} del proceso demonio y del \textit{socket}, con dos objetivos: + +\begin{enumerate} + \item Solo los usuarios autorizados (pertenecientes al grupo \code{organ}) podrán utilizar el \textit{socket}. + + \item En caso de intrusión, el servicio no podrá hacer en el sistema más cambios que los autorizados. +\end{enumerate} + +Hay una excepción a tener en cuenta: el modo Ingeniería requiere\textbf{ apagar y reiniciar} el sistema. El programa \code{shutdown} requiere permisos de \textbf{superusuario}, pero es muy inseguro mantener el proceso con tales privilegios para tener esa capacidad. + +Este problema se corrige modificando el archivo \code{/etc/sudoers}, que almacena la lista de usuarios que tienen permiso para utilizar la orden \code{sudo}. En él añadiremos al grupo \code{organ}, pero solo con capacidad de ejecutar \code{shutdown}, ningún otro programa. + +\subsubsection{Conexiones simultáneas} + +El núcleo de control del demonio es el planificador, que tiene una hebra independiente para reproducir piezas musicales. Los problemas de seguridad concurrente encontrados fueron descritos más arriba (sección \ref{subsec:impl_planificador}). + +Sin embargo, surge un nuevo problema: sus funciones públicas pueden ser llamadas desde cualquier otro módulo, y cada uno de ellos funciona en una hebra distinta. Si dos funciones del planificador son ejecutadas \textbf{simultáneamente} se puede producir una inconsistencia o una \textbf{condición de carrera}. + +Por ello, toda función pública está protegida por un \textbf{cerrojo} de exclusión mutua, a modo de monitor del módulo, que hace que cualquier subproceso que intente acceder deba esperar a que termine cualquier otra función que se esté ejecutando. + +\subsection{Pre-instalación} + +Para facilitar la compilación y la puesta en marcha del demonio, vamos a construir un \textit{script} que prepare el sistema para el funcionamiento del servicio, instalando los paquetes necesario y haciendo las configuraciones pertinentes. + +El \textit{script} es muy sencillo y hace lo siguiente: + +\begin{enumerate} + \item Instala la biblioteca cliente de \textbf{MySQL} para C, incluyendo las cabeceras. + \item Crea un usuario y grupo de sistema, llamados \code{organ}, que poseerán el proceso del demonio y el \textit{socket}. + \item Agrega al usuario por defecto del \textit{Raspberry Pi} al grupo \code{organ}. + \item Declara en el archivo \code{/etc/sudoers} permiso del grupo \code{organ} para ejecutar \code{shutdown}. + \item Descarga la biblitoeca \textbf{WiringPi} del repositorio de su desarrollador, y la compila. + \item Crea las carpetas \textbf{bin} y \textbf{obj}, para alojar los archivos compilados. +\end{enumerate} + +\subsection{Compilación e instalación} + +La compilación y la instalación del servicio está gestionada \textbf{\textit{Makefile}}, que trabaja sobre la siguiente estructura de directorios: + +\begin{description} + \item[bin] Archivos ejecutables finales. + \item[include] Ficheros de cabecera de C. + \item[obj] Código objeto, ensamblado pero no vinculado. + \item[scripts] Código de pre-instalación y arranque del demonio. + \item[src] Ficheros de código fuente en C. +\end{description} + +El \textit{Makefile} contiene las siguientes reglas: + +\begin{description} + \item[all] Por defecto. Compila todos los ejecutables. + \item[install] Instala los archivos compilados en el sistema operativo. + \item[uninstall] Deshace la instalación. + \item[preinstall] Ejecuta los pasos de pre-instalación. + \item[clean] Elimina todos los archivos compilados. + \item[objclean] Limpia los ficheros de código objeto. +\end{description} + +Las carpetas utilizadas como destino de instalación son las siguientes: + +\begin{description} + \item[/usr/local/bin] Programas auxiliares. + \item[/usr/local/sbin] Ejecutable del demonio (binarios de superusuario). + \item[/etc/init.d] \textit{Script} de inicio del servicio. +\end{description} + +\newpage + +\section{Interfaz web} + +Es ahora el momento de abordar la construcción del \textit{back-end} del sistema. Como ya sabemos, será un servidor \acrshort{HTTP}. Hemos tenido en cuenta las siguientes \textbf{alternativas} como lenguajes de programación para el servidor: + +\begin{itemize} + \item \textbf{C/C++ con \acrshort{CGI}}. Sería la solución más rápida en tiempo de ejecución, por ser lenguajes compilados. A cambio, la programación sería mucho más lenta, porque trabajamos a más bajo nivel. + + \item \textbf{\acrshort{PHP} 5}. Es quizás la opción más popular, es un lenguaje interpretado y diseñado para entornos \textit{web}. + + \item \textbf{Python 3 con la biblioteca Django}. También es un lenguaje interpretado, la biblioteca Django tiene una estructura más complicada, diseñada para sitios complejos. +\end{itemize} + +Estudiadas las tres opciones, consideramos que la mejor es \textbf{\acrshort{PHP}}, por equilibrar rendimiento y comodidad de programación. En el capítulo posterior probaremos el tiempo de ejecución de las páginas, que es más que aceptable. + +El servidor generará una página \textbf{\acrshort{HTML} 5}, la última versión del estándar. La estética se escribirá en \textbf{\acrshort{CSS} 3}. En el lado del cliente, siempre es necesario actuar sobre una página generada, donde utilizaremos \textbf{JavaScript} para acceder a ella a través de \acrshort{DOM} ---\textit{\acrlong{DOM}}---. + +Además, debemos almacenar las cadenas constantes en archivos, dependiendo del idioma del usuario; para esto usaremos archivos \textbf{\acrshort{XML}}. Otra tecnología que nos resultará útil es \textbf{\acrshort{AJAX}} ---\textit{\acrlong{AJAX}}---, para que JavaScript haga consultas al servidor sin recargar la página completa. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo5/ajax} + \par\end{centering} + \smallskip + \caption{\label{fig:ajax} Funcionamiento de AJAX.} +\end{figure} + +\newpage + +En resumen usaremos las siguientes tecnologías: + +\begin{enumerate} + \item \acrshort{PHP} 5.4, como lenguaje de programación. + \item \acrshort{HTML} 5, como lenguaje de marcado. + \item \acrshort{CSS} 3, para las hojas de estilos. + \item \acrshort{XML}, para almacenar información estática. + \item JavaScript, \acrshort{AJAX} y \acrshort{DOM}, para interactuar dinámicamente con la página. +\end{enumerate} + +\subsection{Estructura principal} + +Vamos a organizar los archivos de una forma limpia y fácil de acceder. Para ello, en la carpeta raíz tendremos los archivos \acrshort{PHP} correspondientes a las vistas, y otro para el control. Cada \textbf{vista} se implementará en un archivo diferente, para facilitar la consulta. Ya que el \textbf{controlador} recibirá datos privados, se implementará en un solo archivo. + +El resto de ficheros se clasificarán de las siguientes carpetas: + +\begin{description} + \item[ajax] Páginas \acrshort{PHP} de uso exclusivo para \acrshort{AJAX}. + \item[images] Imágenes para la página. + \item[lib] Bibliotecas \acrshort{PHP}, para el modelo y para la vista. + \item[scripts] Código JavaScript a cargar por las páginas. + \item[styles] Hojas de estilos en cascada, en \acrshort{CSS}. + \item[translations] Ficheros de traducción, en \acrshort{XML}. +\end{description} + +\subsubsection{Plantillas} + +A medida que construimos la maqueta en \acrshort{HTML} y \acrshort{CSS}, fuimos conscientes de qué trozos de código se repetían, totalmente o con un ligero cambio, lo que nos ayudó a crear una \textbf{biblioteca de plantillas}, que podríamos denominar ''rutinas de vista''. + +Para conseguir un resultado acorde al diseño estético, vamos a maquetar las páginas \acrshort{HTML} de forma homogénea, siguiento esta estructura: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/html} + \par\end{centering} + \smallskip + \caption{\label{fig:htnl} Maquetación de la página HTML.} +\end{figure} + +\smallskip + +En este módulo hemos escrito las siguientes funciones: + +\begin{description}[style=nextline] + \item[\code{html\_open(id, refresh)}] + Genera la cabecera \acrshort{HTML}. Establece el \code{id} del documento, y opcionalmente, una \acrshort{URL} de redirección (\code{refresh}). + + \item[\code{html\_close()}] + De manera contraria, escribe el final del documento \acrshort{HTML}. + + \item[\code{html\_header(full)}] + Modela la barra de cabecera. Si se indica \code{full} se hace completa, incluyendo los controles de energía (apagar y reiniciar). Si se pasa el valor \code{false}, entonces solo se muestra el cambio de idioma. + + \item[\code{html\_navigation (selected)}] + Escribe la barra de navegación, marcando como seleccionado aquel elemento de la lista cuyo ID coincida con el valor de \code{selected}. + + \item[\code{html\_footer}] + Muestra el pie de página de la vista. + + \item[\code{html\_error (type)}] + Genera una página completa con un mensaje de error, y cuyo texto depende del parámetro \code{type}. A continuación termina el programa. + + \item[\code{html\_redirect (target)}] + Crea una página sin contenido, dedicada a redireccionar a otra, cuya \acrshort{URL} se indica en \code{target}. + + \item[\code{html\_script (src)}] + Escribe el texto \acrshort{HTML} necesario para incluir el archivo JavaScript especificado en \code{src}. +\end{description} + +\subsubsection{Controlador} + +Este archivo implementará todas las funciones de control del sistema, como iremos describiendo más adelante. Tan solo especificar que la ejecución de este módulo se lleva a cabo con una mezcla de parámetros \textit{GET} y \textit{POST}: + +\begin{description} + \item[GET] Solo se envía el nombre de la acción a ejecutar, como \code{control.php?action=login}. + \item[POST] Transmite el resto de la información, cuyos parámetros dependen de la acción. +\end{description} + +De esta forma se evita que el explorador o eventualmente un motor de búsqueda cacheen una instancia. Si la orden se ejecuta correctamente, se devuelve una página en blanco con \textbf{redirección} a la vista adecuada (se pierde la dirección y no se relanza la orden si actualizamos la página). En caso de \textbf{error}, se muestra pero se mantiene la dirección en el explorador para poder volver a intentarlo. + +\subsubsection{Sesión} + +Este módulo implementa el modelo de la sesión para permitir que todos los parámetros a almacenar sean accedidos por el resto de archivos a través de funciones, evitando errores lógicos. La interfaz está descrita en la sección \ref{subsec:session}, del capítulo de diseño. + +La sesión de usuario es una \textbf{\textit{cookie}} gestionada por el intérprete de \acrshort{PHP}, que se incluye en la cabecera \acrshort{HTTP} al principio del programa, llamando a \code{session\_start()}. A partir de ahí, tenemos acceso a la variable global \code{\_SESSION}, un \textit{array} del que utilizaremos tres claves: + +\begin{description} + \item[auth] Tiene el valor 1 si el usuario se ha autentificado. Se escribe con \code{set\_auth()} y \code{unset\_auth()} y se consulta con \code{get\_auth()}. + + \item[last] Hace referencia a la consulta de la última vista ejecutada, por si el controlador debe volver a ella. Se escribe con \code{set\_page()} y se lee con \code{last\_page()}. + + \item[lang] Almacena el código de lenguaje seleccionado por el usuario o, en su defecto, el idioma preestablecido. Se escribe con \code{set\_language()} y se consulta con \code{get\_language()}. +\end{description} + +\subsubsection{Hoja de estilos} + +El modelo estándar de implementación de páginas \acrshort{HTML} separa contenido y forma en distintos archivos, así, todo el estilo de la interfaz se escribe en hojas de estilos en cascada. + +Nuestra interfaz será \textbf{homogénea}, de manera que todos los estilos se definirán en un solo archivo \acrshort{CSS}. El objetivo es obtener un resultado lo más cercano posible al diseño, donde tenemos un ejemplo en la figura \ref{fig:maqueta}. + +Sin adentrarnos en el código, existen tres zonas bien distinguidas en el fichero: + +\begin{enumerate} + \item Reglas \textbf{generales}, como el margen, la tipografía o el color de la fuente. + \item Opciones para los \textbf{elementos}, dependiendo de su etiqueta \acrshort{HTML}. + \item Reglas \textbf{específicas}, sobre todo a determinadas páginas. Esta es la razón por la que cada vista tiene un ID diferente. +\end{enumerate} + +Como podemos ver en las siguientes figuras, hemos conseguido una estética en \acrshort{CSS} prácticamente similar a la diseñada con Photoshop. + +\subsection{Traductor} + +El traductor es el módulo en el que delegamos todo el texto que aparecerá en las \textbf{vistas} y será dependiente del idioma que escoja el usuario. Como especificamos en la sección \ref{subsec:idiomas} del capítulo de diseño, cada archivo de traducción implementará un elemento \code{} como raíz, dedicado a un solo lenguaje. + +Un ejemplo para un ''Hola Mundo'' en dos idiomas sería el siguiente: + +\begin{Verbatim}[commandchars=\\\{\}] + \color{blue} + \color{blue}\color{black}¡Hola Mundo!\color{blue} + \color{blue} + + \color{blue} + \color{blue}\color{black}Ciao Mondo!\color{blue} + \color{blue} +\end{Verbatim} + +El programa en \acrshort{PHP} busca todos los archivos existentes en la carpeta de traducciones con \code{glob()} y los interpreta con ayuda de la función \code{simplexml\_load\_file()}. A continuación los guarda en una lista global, denominada \code{translators}, a acceder por todas las funciones que la requieran. + +El hecho de leer todos los archivos de lenguaje se explica en el \textbf{menú desplegable} que se mostrará en la barra de cabecera, y presenta todos los idiomas disponibles, con el siguiente aspecto: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_repr_idiomas} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_repr_idiomas} Vista del menú desplegable de idiomas.} +\end{figure} + +\smallskip + +Cada opción está vinculada al \textbf{controlador}, que lanza la orden \code{language} con el código de idioma como parámetro. + +\subsection{Control de energía} + +Una de las funciones de la interfaz sería controlar el reinicio y el apagado del \textit{Raspberry Pi}. Esta acción solo se puede llevar a cabo con la orden correspondiente de Linux, y con permiso de superusuario. + +La implementación es tan sencilla como mostrar en la cabecera un \textbf{menú desplegable} con ambas opciones: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_repr_apagar} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_repr_apagar} Vista del menú desplegable de control de energía.} +\end{figure} + +\smallskip + +Cada uno de estos elementos llama a controlador con una acción diferente: + +\begin{description} + \item[shutdown] Hace ejecutar la función \code{shutdown()}, que solo llama a \code{sudo shutdown now}. + + \item[reboot] Ejecuta la función \code{reboot()}, que llama a \code{sudo shutdown -r now}. +\end{description} + +Ambas llamadas devuelven un \textbf{código de retorno} (0 en caso de éxito o 1 en caso de error). El controlador filtra dicho código para \textbf{redirigir a la portada}, o bien mostrar un mensaje de error. + +Recordar que el usuario del servidor Apache (www-data) no posee por defecto privilegios para realizar cambios que afecten al equipo. Por ello modificaremos el sistema para concederle tales permisos, como explicaremos más adelante, en la sección \ref{subsec:web_seguridad}. + +\subsection{Portada} +\label{subsec:impl_portada} + +La portada constituye la primera página que se muestra al acceder al sistema. La \textbf{vista} incluye un fondo de pantalla dinámico, que cambia a intervalos de tiempo regulares. + +Para esto hemos implementado una función en JavaScript llamada \code{toggle()}, que guarda una lista de imágenes y altera el estilo del fondo de la página. + +Otro elemento importante es un \textbf{formulario} que permite introducir la contraseña de usuario y nos lleva al \textbf{controlador}, con la acción \code{login}. + +\subsubsection{Autentificación} + +El \textbf{controlador} recibe la contraseña por el método \textit{POST}, para ocultarla de la vista de la dirección y evitar que sea cacheada. Todo lo que hará será llamar a una \textbf{aplicación auxiliar} de la que hablaremos más tarde, en la sección \ref{subsec:aux_login}. A esta aplicación le pasamos el nombre de usuario (predefinido por nosotros) y la contraseña introducida como parámetros de llamada, y nos devuelve 0 (correcto) o 1 (error). + +Si se aprueba el acceso, llamamos a \code{set\_auth()} para registrarlo en la sesión y redirigimos al \textbf{reproductor}. En caso contrario, volvemos a la pantalla con parámetro \code{error=1}, de forma que se mostrará un pequeño mensaje de error: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_login_error} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_login_error} Formulario de entrada con mensaje de error.} +\end{figure} + +\smallskip + +Por razones de seguridad, la utilidad de autentificación \textbf{retrasa} la ejecución 2 segundos en caso de recibir una contraseña incorrecta, atenuando la efectividad de un \textbf{ataque por fuerza bruta}. + +\subsection{Navegación} + +Para movernos cómodamente entre las páginas de la interfaz, hemos diseñado una barra lateral de navegación. Consiste en una lista de vínculos, adornados con iconos mediante estilos. + +La función de la plantilla que la crea, \code{html\_navigation()}, utiliza el ID de la página para indicar la clase \code{selected} al vínculo correspondiente. La hoja de estilos se encarga de que dicho elemento se dibuje de otro color para remarcar la página actual. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_navigation} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_navigation} Barra lateral de navegación.} +\end{figure} + +\smallskip + +\subsection{Conexión a la base de datos} + +De manera análoga a como hicimos en el demonio para comunicarnos con la base de datos independientemente del motor utilizado, en la interfaz dedicaremos un módulo a conectarnos a la base de datos MySQL. + +La estructura de datos que más utilizaremos serán \textbf{mapas asociativos} (\textit{arrays} con claves), ya que son la estructura subyacente en los objetos de \acrshort{PHP} y, por consiguiente, más eficientes. + +Nuestro módulo establecerá una conexión con la base de datos, creando un objeto \code{mysqli}, la nueva versión del cliente MySQL para \acrshort{PHP}. Las credenciales y el nombre de esquema quedan predefinidos mediante constantes. En caso de \textbf{error}, se mostrará un mensaje con \code{html\_error()}, y no podremos continuar hasta que solucionemos el problema. + +Todas las funciones definidas están descritas en la sección \ref{subsec:web_database} de diseño. El \textbf{procedimiento habitual} para ejecutar una sentencia es el siguiente: + +\begin{enumerate} + \item Creamos una sentencia preparada con \code{prepare()}, a partir del código SQL correspondiente, marcando con una interrogación ('?') los valores que irán parametrizados. + \item Utilizamos el método \code{bind\_param()} para enlazar cada parámetro con su argumento correspondiente, que recibiremos en la llamada a la función. + \item Ejecutamos la sentencia con el método \code{execute()}. + \item Recibimos la información requerida con \code{get\_result()}. + \item Clasificamos los datos según sea necesario, y los devolvemos. +\end{enumerate} + +\subsection{Conexión al demonio} + +Si el demonio implantaba un servidor de \textit{socket}, nosotros vamos a escribir un \textbf{cliente} que se conecte a él. El código de inicio utiliza las funciones \code{socket\_create()} y \code{socket\_connect()} para establecer una conexión con el \textit{socket} del demonio, sito en \code{/run/organ.sock}. + +El resto de funciones simplemente adaptan la llamada correspondiente a una orden que siga el \textbf{protocolo} descrito en la sección \ref{sec:protocolo}. Las interfaz de las funciones se desglosó en la sección \ref{subsec:web_demonio}, donde diseñamos este módulo. + +\code{driver\_play()} recibe una lista de reproducción (obtenida de la base de datos) y el índice de la primera pieza. Entonces \textbf{genera la cadena} de nombres de archivo, empezando por la partitura indicada, y la envía al demonio. + +\code{driver\_pause()}, \code{driver\_resume()} y \code{driver\_stop()} simplemente \textbf{transmiten la orden} procedente y reciben el mensaje de retorno, que indica si se ha realizado correctamente la operación. Los casos típicos de fallo son: + +\begin{enumerate} + \item Tener un estado incompatible con la llamada (e.g. pausar si estaba detenido). + \item Estar en modo Ingeniería. +\end{enumerate} + +Por último, \code{driver\_status()} lanza una consulta y devuelve los datos recibidos tal cual en un array con el siguiente contenido: + +\begin{enumerate} + \item Palabra de estado, en mayúscula ---como dicta el protocolo---. + \item Ruta absoluta de la pieza que se está reproduciendo (si procede). +\end{enumerate} + +\subsection{Reproductor} + +Ésta es la página principal del administrador, desde la que podremos controlar la reproducción del órgano. Tendrá la funcionalidad básica de cualquier reproductor. + +\subsubsection{Vista} + +La página se genera en función de una consulta hacia el \textbf{demonio} para conocer su estado, mediante \code{driver\_status()}. En caso de estar reproduciendo o en pausa, también recibimos la ruta absoluta del archivo MIDI en curso. Probablemente sea una pieza almacenada en la base de datos y, por consiguiente, perteneciente a una lista. O bien sea un archivo puntualmente ejecutado por consola. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_reproductor} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_reproductor} Vista del reproductor.} +\end{figure} + +\smallskip + +Si el reproductor recibe un nombre de archivo, lo busca en la base de datos e infiere inferir la lista que se está reproduciendo. Pueden ocurrir dos cosas: + +\begin{enumerate} + \item Si el archivo está registrado, muestra el título y la lista de reproducción correpondiente. + \item Si no es encuentra el fichero, aparece el nombre de archivo y no se muestra ninguna lista. +\end{enumerate} + +El resto de controles aparecen a razón del estado. Para cambiar la partitura a reproducir, podemos desplazar con los botones adelante/atrás, o bien \textbf{seleccionar} un elemento de la lista. + +\subsubsection{Controlador} + +El grueso del controlador de este módulo está compuesto por llamadas a funciones escritas en JavaScript que se comunican dinámicamente con el servidor utilizando \textbf{\acrshort{AJAX}}, para obtener una respuesta eficiente y evitar recargar la página. Cada botón está asignado a una función diferente: + +\begin{description} + \item[\code{resume()}] Reanudar la reproducción. + \item[\code{pause()}] Pasar programa. + \item[\code{stop()}] Detener completamente. + \item[\code{previous()}] Siguiente pista, circularmente. + \item[\code{next()}] Pista anterior, circularmente. +\end{description} + +\code{pause()}, \code{resume()} y \code{stop()} hacen una petición de tipo \acrshort{AJAX} a pequeñas aplicaciones \acrshort{PHP} específicas a tal efecto, que simplemente transmiten la orden al demonio mediante el \textit{socket}. Después, modifican los controles según corresponda ---ocultar un botón, mostrar otro, etc.--- + +\code{previous()} y \code{next()}, para los botones adelante/atrás, realizan \textbf{peticiones completas} para reproducir una lista, empezando por una pista distinta. La reproducción se hace en ciclo, por tanto, la pieza que sucede a la última es la primera. + +Este mismo mecanismo se utiliza cuando se pulsa sobre un elemento de la lista, que llama a la función de JavaScript \code{play()}. Todas ellas hacen al servidor una petición del tipo: + +\begin{center} + \code{control.php ? action=play \& idplaylist=\$X \& idscore=\$Y} +\end{center} + +La parte del control en \acrshort{PHP} recibe la orden, consulta en la base de datos la lista de archivos y la envía al demonio a través del \textit{socket}. + +\subsection{Gestión de listas y piezas} +\label{subsec:impl_gestor} + +Esta parte de la aplicación nos permite administrar las piezas almacenadas en el sistema, crear y modificar listas de reproducción, y gestionar las partituras que contienen. + +\subsubsection{Vista} + +El módulo consta de \textbf{dos vistas}: una para ver las \textbf{listas} existente y crear nuevas, y otra para gestionar las \textbf{piezas} contenidas en cada lista, a la que accedemos desde la primera página. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_listas} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_listas} Vista del gestor de listas.} +\end{figure} + +\smallskip + +El gestor de listas consiste esencialmente en una \textbf{tabla} que muestra las listas que hemos creado, nos da a conocer el nombre y el número de piezas contenidas. Además proporciona un botón para \textbf{reproducir} directamente la lista. La página muestra también un botón para \textbf{insertar} una lista nueva. + +Para generar esta página, la aplicación hace una consulta a la \textbf{base de datos} llamando a \code{db\_get\_playlists()}, que devuelve un \textit{array} con todas las listas almacenadas. Hacer clic en cualquier lista nos lleva a la vista siguiente, para gestionarla. + +Para \textbf{crear una lista}, el botón correspondiente llama a una función JavaScript, \code{add()}, que hace aparecer una \textbf{ventana modal} con un pequeño formulario para que introduzcamos el nombre de la nueva lista. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_ins_lista} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_ins_lista} Diálogo para crear una lista.} +\end{figure} + +\smallskip + +Por \textbf{seguridad}, el campo es obligatorio y está limitado a 255 caracteres, la misma longitud que la columna de la base de datos que almacenará esta información. Aún así, el \textbf{controlador} realizará una segunda comprobación cuando reciba los datos. + +El \textbf{administrador de piezas} es una vista similar al gestor de listas, pero en cambio muestra el contenido de cada lista. Se accede de forma normal haciendo clic en una lista de reproducción, que llama a esta vista con esta sintaxis: + +\begin{center} + \code{playlist.php ? idplaylist=\$X} +\end{center} + +Esta página busca la lista indicada por ID en la base de datos y extrae su contenido mediante la función \code{db\_get\_playlist()}. A partir de esta información genera una tabla en la que a cada partitura le corresponde una fila, y nos da a conocer el título y la duración, también aparece un vínculo para descargar la pieza en formato \acrshort{MIDI}, un botón para cambiar el título y otro para eliminarla. + +La cabecera de la sección provee controles que permiten renombrar y borrar la lista, así como añadir una nueva pieza. Esta zona soporta ''\textbf{arrastrar y soltar}'' para añadir piezas fácilmente. La vista tiene el siguiente aspecto: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_piezas} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_piezas} Vista del administrador de piezas.} +\end{figure} + +\smallskip + +Para \textbf{añadir una partitura} tenemos un botón de tipo \code{}, que tiene un comportamiento aislado por el navegador por razones de seguridad, y ni siquiera se puede cambiar su estilo. Por ello, este control está oculto y en su lugar aparece un botón estándar, programado para transmitir la función \code{click()} cuando el usuario pulse sobre él. Al hacerlo, aparece un pequeño explorador para seleccionar un archivo, filtrado por formato \acrshort{MIDI}. + +El vínculo para \textbf{descargar} enlaza al archivo correspondiente en el servidor, pero éste guarda el archivo con un nombre numérico para evitar colisiones. Por esta razón, se indica en el vínculo el \textbf{nombre de la pieza} para guardar el archivo descargado. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_elim_lista} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_elim_lista} Diálogo para eliminar una lista.} +\end{figure} + +\smallskip + +Por último, existen varias \textbf{ventanas modales}, cada una correspondiente a un diálogo que se hará aparecer cuando el usuario haga clic en el botón correspondiente, mediante sencillas funciones JavaScript. En el caso de renombrar, el cuadro de texto adquiere el \textbf{título actual} de la pieza o de la lista, y adquiere el \textbf{foco} del teclado para agilizar la operación. + +\subsubsection{Controlador} + +La mayor parte del controlador para este módulo consiste en pequeñas funciones de acceso a la base de datos. Su sintaxis está descrita en en las secciones \ref{subsec:listas} y \ref{subsec:piezas}: + +\code{new\_playlist()}, \code{rename\_playlist()} y \code{rename\_score()} alteran la base de datos llamando a la función del modelo del mismo nombre. En todos los casos, se verifica que el título exista, si es mayor que el campo de la base de datos que lo almacena, será truncado. + +\code{delete\_score()} borra una pieza de la base de datos y del almacenamiento. La función \code{delete\_playlist()} elimina una lista de la base de datos, pero antes debe obtener los nombres de archivos contenidos y eliminarlos. Ya que las listas están enlazadas a las piezas por \textbf{llave externa}, las tuplas correspondientes a las piezas contenidas en la lista se eliminarán automáticamente. + +\code{new\_score()} inserta una pieza en una lista. Recibe el parámetro \code{idplaylist} y el archivo \acrshort{MIDI}. En primer lugar comprueba el formato del archivo y su tamaño ---se descartan archivos mayores de 1 \textit{MiB}--- y utiliza la aplicación \textit{Midinfo} (descrita en la sección \ref{subsec:midinfo}) para conocer su duración y verificar su formato. Para \textbf{evitar colisiones} de nombres, el archivo se guardará con un nombre igual a su identificador en la base de datos. La inserción se hace en dos pasos: + +\begin{enumerate} + \item Se inserta la tupla mediante \code{db\_insert\_score()}, que crea el elemento asignando como título el nombre original de archivo, pero establece otro nombre de almacenamiento único. + + \item Se mueve el archivo recibido a la carpeta específica para contener partituras, con el nombre de archivo que indica la base de datos. +\end{enumerate} + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_ins_pieza} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_ins_pieza} Progreso de inserción de piezas.} +\end{figure} + +\smallskip + +Como hemos explicado en la vista, hay \textbf{dos métodos} para subir archivos, aunque ambos llaman a la misma función del controlador: + +\begin{enumerate} + \item Seleccionando un archivo \acrshort{MIDI} en el explorador que aparece al pulsar el\textbf{ botón para añadir} una pieza. El archivo se envía en el formulario de manera normal. Solo se permite seleccionar un fichero y, de fallar, recibiremos un mensaje de error indicando los motivos. + + \item \textbf{Arrastrando} uno o varios archivos a la sección central de la vista. Esto activa la función \code{ondrop()} de JavaScript, que no puede acceder al elemento \code{} del formulario mediante \acrshort{DOM} y añadir el archivo recibido, por motivos de seguridad. En cambio, utiliza \acrshort{AJAX} para hacer dinámicamente un envío por cada archivo. Ya que \acrshort{AJAX} es, por definición, \textbf{asíncrono}, enviaría todos los archivos simultáneamente. Para evitarlo, establecemos un \textit{callback} al recibir la respuesta, que haga transmitir el archivo siguiente. La implementación es similar a una \textbf{función recursiva}. Si un archivo falla, es descartado silenciosamente. +\end{enumerate} + +Este segundo método permite enviar muchos archivos y puede tardar algún tiempo, aunque la interfaz siga respondiendo. Mientras se están subiendo archivos aparece una ventana emergente que muestra qué fichero está en curso. + +\subsection{Asignación del mando} + +Una vez creadas las listas, tendremos la posibilidad de asignarlas a un botón del mando a distancia. La \textbf{base de datos} almacena esta información y permite que sea consultada directamente por el demonio, que será el que reciba las pulsaciones del mando. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_mando} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_mando} Vista del gestor del mando.} +\end{figure} + +\smallskip + +\subsubsection{Vista} + +Esta página muestra una \textbf{tabla} con todos los botones contemplados en el mando, y la lista que tiene asignada cada uno. Este dato viene dado en un \textbf{menú desplegable} que da a escoger entre todas las listas recogidas en la base de datos, o dejar el botón \textbf{sin asignar}. + +\subsubsection{Controlador} + +Para establecer un vínculo entre un botón y una lista, el controlador ejecuta la función \code{set\_shortcut()}. Como se describió en la sección \ref{subsec:mando} de diseño, recibe el identificador de botón y de lista. + +El controlador hace patente la asignación en la base de datos llamando a la función del modelo, \code{db\_set\_shortcut()}, dejando automáticamente la información compartible hacia el servicio de reproducción. + +\subsection{Seguridad} +\label{subsec:web_seguridad} + +Si en el \textit{back-end} los detalles de seguridad que nos preocupaban son esencialmente los relacionados con incompatibilidades del formato \acrshort{MIDI}, permisos de usuario y gestión de la concurrencia, ahora debemos atender escrupulosamente la \textbf{entrada de datos} provenientes del usuario que, de forma intencional o no, podría causar un error en el sistema. + +En el \textit{front-end} implantaremos dos capas de seguridad: + +\begin{enumerate} + \item Una primera capa en la \textbf{vista}, para informar inmediatamente de un error en un formulario. + \item Otra capa en el \textbf{controlador}, para evitar errores más complejos o un conjunto de datos forzado. +\end{enumerate} + +\subsubsection{Cadenas de entrada} + +Los formularios de la aplicación proveen \textbf{campos de texto} para introducir ciertos datos, como el nombre de una partitura. La información llega a la base de datos, cuyos campos están limitados, generalmente a 255 \textit{bytes}, y son obligatorios. + +Para conseguir la mayor efectividad, los campos \code{} tienen marcadas estas condiciones, para alertar al usuario. Sin embargo, pueden ser forzados fácilmente con las \textbf{funciones de depuración} del explorador. Dichas condiciones son comprobadas de nuevo en el \textbf{controlador}; en caso de no cumplirse, se muestra un error. + +\subsubsection{Formato de archivo MIDI} + +El único tipo de archivo aceptado para guardar partituras en el sistema es el formato \acrshort{MIDI}. De manera similar al caso anterior, el explorador desplegado a la hora de añadir partituras filtra los archivos por extensión, pero esta medida es fácilmente sorteable. + +Como especificamos más arriba (sección \ref{subsec:impl_gestor}), el controlador del gestor de piezas llama al \textbf{analizador} de archivos \acrshort{MIDI} antes de insertar el fichero. Si la aplicación no reconoce el archivo \textbf{completamente}, devuelve un error y se descarta. + +\subsubsection{Inyección de código SQL} + +Un error de programación muy común al comunicar el controlador con el modelo es \textbf{concatenar} una orden con la entrada del usuario. Por ejemplo, para buscar un usuario en la base de datos para autentificar: + +\begin{center} + \code{SELECT id FROM user WHERE nick = '\$X' AND password = '\$Y'} +\end{center} + +Si el usuario escribe en el campo de contraseña el siguiente texto: + +\begin{center} + \framebox[\textwidth/4][c]{\code{' OR 1=1;}} +\end{center} + +Entonces el gestor de bases de datos recibirá la siguiente cadena: + +\begin{center} + \code{SELECT id FROM user WHERE nick = 'foo' AND password = '' OR 1=1;'} +\end{center} + +Teniendo en cuenta que todo lo que sucede al punto y coma es descartado, la base de datos devolverá el usuario \textbf{independientemente} de la contraseña. De igual forma, un usuario malintencionado podría eliminar tuplas o tablas enteras de la base de datos. + +Esto se evita \textbf{filtrando} todas las cadenas de entrada del usuario, descartando caracteres especiales que puedan producir efectos nocivos. La implementación del modelo de la base de datos se ha hecho con \textbf{sentencias preparadas}, que realizan esta acción automáticamente. + +Como medida adicional, las \textbf{credenciales} de usuario cedidas a la aplicación \acrshort{PHP} solo tienen permisos para alterar el \textbf{contenido} de las tablas, no para modificar las propias tablas. + +\subsubsection{Inyección de código shell} + +En nuestro caso particular de \textbf{autentificación}, el controlador recibe la contraseña del usuario y llama a la aplicación externa para verificarla. El método para transmitir la clave es como argumento de llamada: + +\begin{center} + \code{/usr/local/bin/organ-login ''pi'' ''\$pass''} +\end{center} + +Un ejemplo de inyección de código podría ser escribir la siguiente ''contraseña'': + +\begin{center} + \framebox[\textwidth/2][c]{\code{'' || sudo shutdown now || ''}} +\end{center} + +Dando como resultado la siguiente instrucción de consola: + +\begin{center} + \code{/usr/local/bin/organ-login ''pi'' '''' || sudo shutdown now || ''''} +\end{center} + +Este riesgo es real en nuestra aplicación, pues tenemos permiso de \textit{root} para apagar el sistema. La solución a este problema es similar a la del caso anterior: \textbf{filtrar la entrada} del usuario, en este caso usaremos la función \code{escapeshellargs()} de \acrshort{PHP}. + +\subsubsection{Permisos de usuario} + +Para que nuestra aplicación funcione correctamente, el servidor \textit{web} necesita acceder a los siguientes recursos externos del sistema: + +\begin{enumerate} + \item \textit{Socket} de comunicación hacia el \textit{back-end}. + \item \textit{Socket} para acceder a la base de datos. + \item Directorio de almacenamiento de archivos \acrshort{MIDI}. + \item Aplicación \code{organ-login} (como root) para autentificar al usuario. + \item Orden \code{shutdown} (como \textit{root})para apagar el sistema +\end{enumerate} + +El primer y el quinto caso se comparten con el demonio, es por esto que el usuario del servidor Apache, \code{www-data}, pertenece al grupo \code{organ}, al que pertenece el \textit{socket}. Además, como explicamos en la sección de seguridad del demonio (\ref{subsec:seg_demonio}), este grupo tiene permiso para ejecutar \code{sudo shutdown}, por lo que la aplicación \textit{web} hereda este permiso. + +El directorio donde se guardarán las partituras (\code{/home/pi/midis}) se considera una carpeta \textbf{pública}, de forma que tiene \textbf{permisos de escritura} para todos los usuarios. Por supuesto, el acceso a cualquier usuario del sistema está \textbf{acotado} por otras medidas de seguridad. + +La utilidad de \textbf{autentificación} requiere permisos de administrador. Aún así, no será necesario solicitar elevación explícitamente porque utiliza la característica \textbf{\textit{setuid}}, que hace que se ejecute siempre con permisos de \textit{root}. + +Por último, el acceso al \textit{socket} de la \textbf{base de datos} es público, siempre que se conecte de forma \textbf{local}. El resto de la seguridad de MySQL descansa sobre la gestión de usuarios y contraseñas, para la cual tenemos un usuario dedicado, como describiremos a continuación. + +\newpage + +\section{Base de datos} + +Como hemos adelantado, utilizaremos una base de datos para organizar la información persistente del sistema, con el objetivo de mantener la información consistente y estructurada. Hemos debatido entre dos motores muy interesantes: + +\begin{description} + \item[MySQL] Es un gestor muy popular, multiusuario, con arquitectura cliente-servidor. Su motor de tablas \textbf{InnoDB} soporta transacciones \acrshort{ACID} e integridad referencial. \cite{wiki_innodb} + + \item[SQLite] Se implementa como una biblioteca de programación y también es compatible con \acrshort{ACID}. Es mucho más rápida que MySQL en lectura y escritura pero más ineficiente en acceso multiusuario. +\end{description} + +El hecho de que un gestor de bases de datos sea compatible con \acrshort{ACID} ---\acrlong{ACID}--- garantiza que las transacciones son \underline{atómicas} (o todas o ninguna), \underline{consistentes} (mantienen la integridad del sistema), \underline{aisladas} (frente a accesos concurrentes) y \underline{persistentes} (los cambios se mantienen. \cite{wiki_acid} + +SQLite es una opción muy buena en aplicaciones sencillas y mono-usuario, al ser una biblioteca se integra directamente en el programa y, si bien su implementación del lenguaje \acrshort{SQL} es \textbf{limitada} ---no provee integridad referencial ni soporta chequeo de datos---, es muy veloz gestionando información. + +Sin embargo, SQLite gestiona el acceso concurrente bloqueando completamente la base de datos. En cambio, MySQL modela esta característica de una forma más compleja, bloqueando solo la tupla necesaria. Ya que el servidor \textit{web} soporta multi-usuario, y el uso será compartido con el demonio, mientras que el volumen de datos a tratar es muy pequeño, decidimos que \textbf{MySQL es la mejor opción} en este caso. + +\subsection{Tablas} + +Para diseñar la base de datos, tal como mostramos en la figura \ref{fig:bd_rel} del capítulo anterior, hemos utilizado \textbf{MySQL Workbench}, una aplicación especialmente diseñada para trabajar con el motor MySQL. Una vez descrito el esquema, genera el código \acrshort{SQL} que define nuestra base de datos. + +Este archivo se incluye en el \textbf{instalador} y se ejecuta después de instalarse previamente el servidor de bases de datos MySQL. Las tablas contenidas, de acuerdo al diseño, son las siguientes: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|l|l|} + \hline \multicolumn{1}{|c|}{\textbf{Campo}} & \multicolumn{1}{c|}{\textbf{Tipo}} & \multicolumn{1}{c|}{\textbf{Restricciones}} & \multicolumn{1}{c|}{\textbf{Descripción}} \\ + \hline idplaylist & INTEGER & Llave primaria & Identificador de lista \\ + \hline name & VARCHAR(255) & & Nombre de la lista \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:db_playlist} Tabla playlist.} +\end{center} + +\smallskip + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|l|l|} + \hline \multicolumn{1}{|c|}{\textbf{Campo}} & \multicolumn{1}{c|}{\textbf{Tipo}} & \multicolumn{1}{c|}{\textbf{Restricciones}} & \multicolumn{1}{c|}{\textbf{Descripción}} \\ + \hline idscore & INTEGER & Llave primaria & Identificador de partitura \\ + \hline \multirow{2}{*}{playlist} & \multirow{2}{*}{INTEGER} & Obligatorio & \multirow{2}{*}{Lista contenedora} \\ + \cline{3-3} & & Referencia a Playlist & \\ + \hline source & VARCHAR(255) & & Nombre de archivo MIDI \\ + \hline name & VARCHAR(255) & & Título de la pieza \\ + \hline duration & INTEGER & & Duración en segundos \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:db_score} Tabla Score.} +\end{center} + +\smallskip + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|l|l|} + \hline \multicolumn{1}{|c|}{\textbf{Campo}} & \multicolumn{1}{c|}{\textbf{Tipo}} & \multicolumn{1}{c|}{\textbf{Restricciones}} & \multicolumn{1}{c|}{\textbf{Descripción}} \\ + \hline idshortcut & INTEGER & Llave primaria & Identificador de botón \\ + \hline playlist & INTEGER & & Referencia a Playlist \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:db_playlist} Tabla Shortcut.} +\end{center} + +\smallskip + +\subsection{Privilegios} + +El acceso al \acrshort{SGBD} está limitado por defecto al \textbf{sistema local} (\textit{localhost}). No es un problema, ya que las dos aplicaciones que accederán a la base de datos conviven en la misma máquina. Esto, además, es una capa extra de \textbf{seguridad}. + +El servicio MySQL se instala con un usuario llamado \textbf{\code{root}} que, como su nombre sugiere, posee permisos totales sobre todo el sistema, una opción poco recomendable. Por ello, aunque será \code{root} quien cree la base de datos, insertará además un usuario con permisos de \textbf{manipulación} de datos (\acrshort{CRUD}: \textit{\acrlong{CRUD}}) sobre la base de datos concreta para gestionar el sistema. + +En conclusión, existirán dos usuarios: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|l|l|} + \hline \textbf{Usuario} & \textbf{Origen} & \textbf{Permisos} & \textbf{Esquema} \\ + \hline root & localhost & Totales & Todos \\ + \hline organo & localhost & \acrshort{CRUD} & Organo \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:db_permisos} Permisos sobre la base de datos.} +\end{center} + +\smallskip + +Solo el segundo de ellos se dará a conocer al demonio y a la interfaz, con la contraseña correspondiente. + +\subsection{Datos iniciales} + +A \textit{priori}, la base de datos estará prácticamente en blanco, a excepción de la tabla cuya inserción no está contemplada en el diseño de la interfaz: la \textbf{asignación de botones} a listas. Un usuario podrá modificar los vínculos, pero solo un administrador podrá añadir botones si, por ejemplo, adquirimos un nuevo mando con más controles. + +Tal como previmos en el \textit{back-end}, utilizaremos un mando con dos botones, cada uno podrá asignarse a una lista. Por tanto, inicialmente se insertarán dos tuplas: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline \textbf{idshortcut} & \textbf{playlist} \\ + \hline 1 & NULL \\ + \hline 2 & NULL \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:db_shorcut_tuplas} Datos iniciales de la tabla Shortcut.} +\end{center} + +\smallskip + +Después de crear listas de ejemplo y agregar algunas piezas, hacemos una consulta para comprobar si los datos coinciden con la información introducida: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth]{capitulo5/cap_sql} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_sql} Consulta de las piezas contenidas en la base de datos.} +\end{figure} + +\smallskip + +\newpage + +\section{Aplicaciones auxiliares} + +He aquí la implementación de los programas diseñados para fines de verificación y soporte a módulos. Se trata en su mayoría de aplicaciones muy sencillas que cubrirán las funciones mínimas que no se han implantado en los subsistemas principales. + +\subsection{Información de archivo MIDI} + +Como se describió en la sección \ref{subsec:midinfo} de diseño, este programa tiene dos objetivos: + +\begin{enumerate} + \item Comprobar el funcionamiento del analizador \acrshort{MIDI}. + \item Enviar la duración de una pieza a la interfaz \textit{web}. +\end{enumerate} + +El programa recibe como argumento un \textbf{nombre de archivo}, que presuntamente corresponde a una partitura compatible, y utiliza la biblioteca implementada para analizar el archivo. + +La naturaleza de la función en cuestión, \code{midi\_init()}, hace que el fichero sea analizado completamente, y recibamos una \textbf{estructura de datos} con toda la información extraída, a excepción de los mensajes exclusivos, no utilizados en este proyecto. + +La aplicación devuelve al usuario una serie de datos tales como éstos: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo5/cap_midinfo} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_midinfo} Captura del visor de archivos MIDI.} +\end{figure} + +\smallskip + +Existe una opción, \code{--duration}, que hace mostrar solamente la duración de la pieza, y la emite como un número \textbf{entero}, redondeando a la unidad. Ésta será la opción utilizada por la \textbf{interfaz \textit{web}} cuando insertemos un nuevo archivo. + +En caso de \textbf{error de lectura}, se imprime un mensaje de error y se finaliza con ''\textbf{código 1}''. Esto además es útil al \textit{front-end} para garantizar que todo archivo subido corresponde efectivamente a una partitura \acrshort{MIDI}. + +\subsection{Simulador de reproducción} +\label{subsec:simulador_reproduccion} + +Este programa se diseñó para probar el planificador y la estructura de la salida, dos módulos que van de la mano y conforman el núcleo del demonio. En realidad es una \textbf{reimplementación} del prototipo del planificador que escribimos en Python, pero ahora trabaja con el planificador final. + +La salida de datos, diseñada en la sección \ref{subsec:output} es una \textbf{interfaz} utilizada por el planificador, que evita la necesidad de modificarlo de manera alguna cuando nos movamos de un órgano a otro. Sus funciones públicas coinciden en su mayor parte con las instrucciones del \textbf{protocolo \acrshort{MIDI}}. + +En este caso vamos a simular más exactamente el órgano de la Parroquia de la Encarnación de Santa Fe que el prototipo de la \acrshort{PCB}, en tanto que éste solo abordará 7 notas en cada canal. En resumen tendremos esta estructura: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|l|l|} + \hline \textbf{Pista} & \textbf{Extensión} & \textbf{Comienzo} & \textbf{Descripción} \\ + \hline 1 & 49 notas & 36 (\textit{Do-2}) & Teclado barroco \\ + \hline 2 & 49 notas & 36 (\textit{Do-2}) & Teclado romántico \\ + \hline 2 & 12 notas & 36 (\textit{Do-1}) & Pedalier \\ + \hline 2 & 49 notas & 36 (\textit{Do-4}) & Registros \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:miditest_map} Asignación de notas en el simulador de reproducción.} +\end{center} + +\smallskip + +El simulador funcionará en consola, de forma que, en lugar de volcar la información en los puertos \acrshort{GPIO}, lo haremos hacia la \textbf{salida estándar}. A continuación mostramos una captura del programa: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_miditest} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_miditest} Captura del visor de archivos MIDI.} +\end{figure} + +\smallskip + +Como podemos comprobar, el planificador comienza realizando una función de limpieza (\textit{Panic}), escribiendo ceros en todas las notas. A continuación, de acuerdo a la partitura, se activan \textit{Mi-4} en la pista 0, \textit{Do-3} en la pista 1 y \textit{Do-1} en la pista 2 (pedal). + +Después del tiempo correspondiente a una \textbf{negra}, se apagan las notas de las pistas 0 y 1 (teclados), manteniéndose la del pedal, para repetirse un instante después. En efecto, las dos primeras notas de la \textit{Oda a la Alegría} de Beethoven son \textbf{unísonas}. + +Este es el único de los programas escritos en C que, por su naturaleza, \textbf{no se instalará} en el sistema de archivos, ya que no tiene más finalidad que depurar el sistema. + +\subsection{Terminal del reproductor}. + +De acuerdo a la sección \ref{subsec:terminal}, se implementaría un programa que nos permita comunicarnos con el demonio a través de la \textbf{consola}. + +Esta aplicación abre un \textit{socket} cliente para comunicarse con el demonio, al que transmite las órdenes recibidas desde la consola, utilizando las mismas órdenes que especificamos en el protocolo. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/cap_terminal} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_terminal} Captura del controlador por terminal.} +\end{figure} + +\smallskip + +\subsection{Comprobación de contraseña} +\label{subsec:aux_login} + +Para autorizar la entrada a la interfaz gráfica, se ha decidido utilizar la seguridad de Linux, ya que utiliza la función de resumen (\textit{hash}) junto a una serie de \textit{bits} aleatorios (\textit{salt}) para almacenarla. + +Nuestro programa utilizará la \textbf{\acrshort{API} de criptografía} de Linux para comprobar si una contraseña es válida. Ya que la clave no está almacenada como tal, sino solo un \textit{hash}, procederemos de la forma que sigue: + +\begin{enumerate} + \item La aplicación recibe un nombre de usuario y una contraseña. + \item Buscamos en el sistema el usuario indicado, y obtenemos el \textit{hash} de su clave. + \item Encriptamos la contraseña recibida con el mismo algoritmo y la misma sal. + \item Comparamos ambos resúmenes: si coinciden, autentificamos al usuario. +\end{enumerate} + +El programa devuelve un \textbf{código de error} si el usuario no existe o la clave no es válida. En este último caso, retrasa la ejecución 2 segundos, para dificultar un \textbf{ataque por fuerza bruta}. + +El acceso al fichero de usuarios (\code{/etc/shadow}), utilizado por la utilidad de \textbf{autentificación}, requiere permisos de administrador. Aún así, tenemos la seguridad de que este programa no hará cambios en el sistema, y produce un \textbf{retraso} si recibe una contraseña que no coincide con el usuario. Con estas premisas instalamos la aplicación con la característica \textbf{\textit{setuid}}, que hace que se ejecute siempre con permisos de \textit{root}. + +\subsection{Instalador del servidor} + +El demonio incluye un \textit{Makefile} y un \textit{script} de preinstalación para ser compilado e instalado sin dificultad. La puesta en marcha de la interfaz y la base de datos requiere de una serie de pasos que, por simplicidad, reuniremos en un \textit{script} que lo haga automáticamente. + +Las acciones que realiza son las siguientes: + +\begin{enumerate} + \item Instala el sistema MySQL, el servidor Apache y el lenguaje \acrshort{PHP}. + \item Añade el usuario de Apache, \code{www-data}, al grupo \code{organ}. + \item Genera el archivo de configuración del sitio \textit{web} desde una plantilla: + + \begin{enumerate} + \item Establece un nombre del sitio ---que puede ser \textit{localhost}---. + \item Selecciona el directorio raíz del sitio, y sus permisos. + \item Crea un vínculo para la carpeta contenedora de archivos \acrshort{MIDI}. + \end{enumerate} + + \item Ejecuta el archivo \acrshort{SQL} para crear la base de datos. + \item Crea la carpeta raíz de la interfaz y el directorio de ficheros \acrshort{MIDI}. +\end{enumerate} + +\newpage + +\section{Resultado de la implementación} + +Al término de la fase de implementación hemos obtenido todo el sistema \textit{software} en distintos módulos y aplicaciones, que darán a la \acrshort{PCB} todo el soporte especificado en los requisitos. + +\subsection{Módulos} + +Si bien el diseño del sistema ha distinguido entre \textit{front-end}, \textit{back-end} y base de datos, a la hora de implementarlo hemos separado el código en tres bloques: + +\begin{description} + \item[Controlador] Incluye el demonio y las aplicaciones auxiliares. En definitiva, todo aquello implementado en código para compilar. + \item[Administrador] Comprende la interfaz \textit{web} y la base de datos. + \item[Prototipos] Programas escritos para realizar pruebas sobre los módulos anteriores. +\end{description} + +\subsubsection{Controlador} + +Este bloque, que se encuentra en la rama \textbf{\textit{driver}} del desarrollo, contiene todo el código a compilar del demonio y los programas auxiliares. Se clasifican de la siguiente manera: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|l|l|} + \hline \multicolumn{1}{|c|}{\textbf{Aplicación}} & \multicolumn{1}{c|}{\textbf{Módulo}} & \multicolumn{1}{c|}{\textbf{Declaración}} & \multicolumn{1}{c|}{\textbf{Definición}} \\ + \hline \multirow{9}{*}{\textbf{Demonio}} & Base de datos & database.h & database.c \\ + \cline{2-4} & Salida & output.h & gpio.c \\ + \cline{2-4} & MIDI & midi.h & midi.c \\ + \cline{2-4} & Principal & & organd.c \\ + \cline{2-4} & Ingeniería & peripherals.h & peripherals.c \\ + \cline{2-4} & Planificador & player.h & player.c \\ + \cline{2-4} & Socket & socket.h & socket.c \\ + \cline{2-4} & UART & uart.h & uart.c \\ + \cline{2-4} & Constantes & values.h & \\ + \hline \textbf{Autentificación} & Principal & & login.c \\ + \hline \textbf{Información MIDI} & Principal & & midinfo.c \\ + \hline \multirow{2}{*}{\textbf{Simulador}} & Salida & (output.h) & monitor.c \\ + \cline{2-4} & Principal & & test.c \\ + \hline \textbf{Terminal} & Principal & & organ.c \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:archivos_driver} Relación de módulos en el controlador.} +\end{center} + +\smallskip + +\subsubsection{Administrador} + +El administrador incluye esencialmente todos los módulos relacionados con la programación \textit{web}, además de la base de datos. Los bloques de programación son los siguientes: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|l|l|} + \hline \multicolumn{1}{|c|}{\textbf{Módulo}} & \multicolumn{1}{c|}{\textbf{Vista}} & \multicolumn{1}{c|}{\textbf{Controlador}} & \multicolumn{1}{c|}{\textbf{Modelo}} \\ + \hline \multirow{2}{*}{\textbf{Portada}} & index.php & control.php & \\ + & index.js & & \\ + \hline \multirow{4}{*}{\textbf{Reproductor}} & player.php & control.php & \\ + & player.js & pause.php & \\ + & & resume.php & \\ + & & stop.php & \\ + \hline \multirow{2}{*}{\textbf{Listas}} & playlists.php & control.php & \\ + & playlists.js & & \\ + \hline \multirow{2}{*}{\textbf{Piezas}} & playlist.php & control.php & \\ + & playlist.js & & \\ + \hline \multirow{2}{*}{\textbf{Mando}} & remote.php & control.php & \\ + & remote.js & & \\ + \hline \textbf{Energía} & & control.php & \\ + \hline \textbf{Base de datos} & & & database.php \\ + \hline \textbf{Demonio} & & & driver.php \\ + \hline \textbf{Sesión} & & & session.php \\ + \hline \textbf{Traducción} & & & translator.php \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:archivos_manager} Relación de módulos en el administrador.} +\end{center} + +\smallskip + +Además hemos añadido los siguientes archivos de soporte: + +\smallskip + +\begin{center} + \begin{tabular}{|l|l|} + \hline \multicolumn{1}{|c|}{\textbf{Recurso}} & \multicolumn{1}{c|}{\textbf{Archivos}} \\ + \hline Plantillas HTML & templates.php \\ + \hline Constantes & values.php \\ + \hline Hoja de estilos & styles.css \\ + \hline \multirow{3}{*}{Traducciones} & english.xml \\ + & italian.xml \\ + & spanish.xml \\ + \hline Base de datos & organo.sql \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:archivos_manager} Archivos de soporte al administrador.} +\end{center} + +\smallskip + +\subsection{Líneas de código} + +Agrupamos todos los módulos y contamos las líneas de código para conocer la relación entre los 10 lenguajes utilizados y el grosor de cada uno de los tres bloques principales. Del código fuente no hemos tenido en cuenta las líneas vacías: + +\smallskip + +\begin{center} + \begin{tabular}{|l|r|r|r|r|} + \hline & \textbf{Controlador} & \textbf{Administrador} & \textbf{Prototipos} & \textbf{Total} \\ + \hline \textbf{C} & 2116 & & 498 & 2614 \\ + \hline \textbf{\acrshort{PHP}} & & 1057 & & 1057 \\ + \hline \textbf{Python} & & & 543 & 543 \\ + \hline \textbf{CSS} & & 460 & & 460 \\ + \hline \textbf{JavaScript} & & 263 & & 263 \\ + \hline \textbf{XML} & & 189 & & 189 \\ + \hline \textbf{Shell} & 122 & 36 & & 158 \\ + \hline \textbf{Makefile} & 86 & & 10 & 96 \\ + \hline \textbf{SQL} & & 68 & & 68 \\ + \hline \textbf{Processing} & & & 25 & 25 \\ + \hline \textbf{Total} & 2324 & 2073 & 1076 & \textbf{5473} \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:lineas} Recuento de líneas de código.} +\end{center} + +\smallskip + +Esta información se representa gráficamente de la siguiente manera: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/lineas} + \par\end{centering} + \smallskip + \caption{\label{fig:lineas} Distribución del código fuente.} +\end{figure} + +\smallskip + +Podemos ver que la mayor parte del código está en \textbf{lenguaje C} y pertenece al \textbf{controlador}, existiendo una cantidad menor de código para los prototipos. Le sigue \acrshort{PHP} en el administrador, mientras que Python ha sido el lenguaje más utilizado para prototipos. + +Si agrupamos los datos en función de los bloques, obtenemos la siguiente gráfica: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/lineas_modulos} + \par\end{centering} + \smallskip + \caption{\label{fig:lineas_modulos} Distribución del código fuente por módulos.} +\end{figure} + +\smallskip + +El mayor coste en lo que a código se refiere ha sido el \textbf{controlador}, al que sigue de cerca el administrador. + +Por último, mostramos la gráfica que agrupa las líneas de código en función del lenguaje: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo5/lineas_lenguajes} + \par\end{centering} + \smallskip + \caption{\label{fig:lineas_lenguajes} Distribución del código fuente por lenguaje.} +\end{figure} + +\smallskip -$$a=K_{u}=1.5$$ -$$b=\frac{K_{u}T}{T_{I}}=0.007$$ -$$c=\frac{K_{u}T_{D}}{T}=712.5$$ +El \textbf{lenguaje más utilizado} en este proyecto ha sido C con amplia diferencia. A pesar de que es un lenguaje de bajo nivel, con mayor coste de implementación y es fácil cometer errores con él, sobre todo utilizando aritmética de punteros, podremos ver en el capítulo que sigue que ha merecido la pena, tanto por su \textbf{eficiencia} como su capacidad de \textbf{modularización}. +\newpage +\clearpage{\pagestyle{empty}\cleardoublepage} \ No newline at end of file diff --git a/report/subdocs/capitulo6.tex b/report/subdocs/capitulo6.tex index dda4da9..18dad1c 100644 --- a/report/subdocs/capitulo6.tex +++ b/report/subdocs/capitulo6.tex @@ -1,3 +1,642 @@ -\chapter{Conclusión y líneas futuras.} +\chapter{Validación y verificación} \label{cap:capitulo6} +\begin{quote} + \begin{flushright} + \small ''\textit{Pon el programa a funcionar, y que Dios nos pille confesados.}'' \\ + --- Profesor Salvador Villena Morales (2013). + \end{flushright} +\end{quote} + +\vspace{8em} + +Como fase final de cualquier proyecto, una vez terminada la implementación, es el momento de ejecutar las pruebas de validación sobre el sistema desarrollado. + +En primer lugar debemos \textbf{verificar} que el proyecto cumple los requisitos propuestos. Otro paso importante será comprobar que el sistema es \textbf{válido} para solucionar nuestro problema, donde entran componentes relacionados con el rendimiento. + +\newpage + +\section{Servicio de reproducción} + +El servicio de reproducción es el \textbf{demonio} desarrollado para reproducir las partituras y despachar peticiones del \textit{socket} y del mando (a través del \acrshort{UART}). Ya que funcionará en segundo plano será muy importante que la implementación controle adecuadamente todos los errores posibles para evitar cierres inesperados. + +Algunos de los problemas más comunes son los \textbf{errores de memoria}, sobre todo en un lenguaje que no la gestiona automáticamente. Para validar la gestión de memoria, hemos utilizado la herramienta \textbf{Valgrind}, que nos muestra todos los posibles errores relativos a memoria, tales como: + +\begin{itemize} + \item Acceder a una dirección ilegal. + \item No liberar la memoria reservada. +\end{itemize} + +Esta aplicación no funciona correctamente en \textit{Raspbian}, por tanto hicimos la prueba en un sistema con \textbf{\textit{Ubuntu}}. La gestión de memoria es similar, aunque difieren algunas longitudes de variables, sin embargo, eso lo gestiona el \textbf{compilador} y no depende de la programación. + +Solo hubo un módulo que no se pudo comprobar: la salida \acrshort{GPIO}, ya que es dependiente de la plataforma \textit{hardware}. A pesar de ello, solo hace una llamada a \code{mmap()} al inicio y otra a \code{munmap()} al final, de forma que los errores serían visibles nada más arrancar el programa. + +\subsection{Requisitos} + +Para validar los distintos módulos se realizó una \textbf{batería de pruebas} sobre ellos, respectivas a la entrada de datos que esperan, y estudiamos la salida para verificar que coincide con lo requerido. + +\subsubsection{Entrada de archivos MIDI} + +El principal requisito del analizador de \acrshort{MIDI} es que debe aceptar cualquier fichero de formato válido, no solo aquellos adaptados a nuestro proyecto. Hemos analizado hasta \textbf{46 archivos} \acrshort{MIDI} de diferentes orígenes: + +\begin{enumerate} + \item 42 piezas estándar, con varias pistas y diferentes instrumentos ---incluyendo batería---. + \item 4 de formato específico, con 2 a 4 pistas. +\end{enumerate} + +De acuerdo a lo especificado, el \textit{software} analiza correctamente archivos \acrshort{MIDI} con varias \textbf{pistas simultáneas}, y de cualquier \textbf{división de tiempo}, en formato $ticks / \quarternote$, descartando los \textbf{eventos específicos} del sistema. + +\subsubsection{Planificador y control} + +El planificador debe ser capaz de atender ágilmente cualquier archivo \acrshort{MIDI} con varias pistas. Para probarlo, utilizamos el \textbf{simulador} de reproducción, construido para este propósito (véase la sección \ref{subsec:simulador_reproduccion}). Esta aplicación fue muy útil para pulir cualquier detalle de programación, y probó que el \textbf{diseño} del algoritmo de planificación es correcto desde el primer momento. + +El concepto de la \textbf{interfaz de salida} también fue comprobado, a pesar de que la verificación de la implementación requiere la \acrshort{PCB}, de la que dispondremos más adelante. + +Por otro lado, la aplicación del \textbf{terminal} nos sirvió para dos cosas: + +\begin{enumerate} + \item Verificar el \textbf{protocolo} de comunicación. + \item Validar la gestión \textbf{concurrente} entre la hebra de reproducción y la del \textit{socket}. +\end{enumerate} + +En base a las pruebas realizadas, el funcionamiento coincide con lo esperado, y controla adecuadamente los siguientes problemas en la entrada: + +\begin{enumerate} + \item Sin argumentos. + \item Parámetros incorrectos. + \item Argumentos muy largos, con un nombre de archivo ficticio de 40 \textit{KiB} (el \textit{buffer} está limitado a 4 \textit{KiB}). +\end{enumerate} + +\subsubsection{Mando y metrónomo} + +La validación de esta parte del sistema requería disponer de la \acrshort{PCB}, pero tenía una complejidad considerable y era necesario realizar incluso prototipos de \textit{software} para el \acrshort{UART}. + +La solución a este problema fue utilizar un \textbf{\textit{Arduino}} para simular el mando a distancia, y un \acrshort{led} para comprobar el funcionamiento del metrónomo. Esto supuso una serie de cuestiones: + +\begin{enumerate} + \item \textit{Arduino} funciona a 5 \textit{V}, mientras que \textit{Raspberry Pi} trabaja a 3,3 \textit{V}. + \item La corriente del \acrshort{GPIO} del \textit{Raspberry Pi} está limitado a 50 \textit{mA}, a cargo del usuario. +\end{enumerate} + +La solución a estos problemas fue \textbf{diseñar} un pequeño circuito electrónico con un \textbf{divisor de tensión} y una resistencia para el \acrshort{led}. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/2]{capitulo6/proto_esquema} + \par\end{centering} + \smallskip + \caption{\label{fig:proto_esquema} Esquema de la placa de prueba.} +\end{figure} + +\smallskip + +De acuerdo a la fórmula de un divisor de tensión resistivo \cite{wiki_divtension}, a la salida en el pin RX de \textit{Raspberry Pi} tendremos: + + +\begin{equation} + V_{out} = V_{in} \times \frac{R_2}{R_1 + R_2} = 5 \; V \times \frac{2 \; K\Omega}{3 \; K\Omega} = 3,\stackrel{\frown}{3} \; V +\end{equation} + + +Por otro lado, con la resistencia junto al \acrshort{led}, la corriente está muy por debajo del límite de 50 \textit{mA}, según la \textbf{ley de Ohm} \cite{wiki_ohm}: + +\begin{equation} + I = \frac{V}{R} = \frac{3.3 \; V}{100 \; \Omega} = 33 \; mA +\end{equation} + +El resultado fue el siguiente: \textit{Raspberry Pi} alimenta a Arduino, y se comunica mediante el \acrshort{UART} con un circuito de seguridad para asegurar el voltaje de la señal. Además, tenemos un indicador luminoso para verificar el metrónomo. + +Por simplicidad, programamos una batería de pruebas para que Arduino suplantara al mando generando distintas cadenas aleatorias, variando los siguientes parámetros: + +\begin{enumerate} + \item Número de serie del mando. + \item Botones pulsados. + \item Señal de batería baja. + \item Longitud de la cadena (generar errores). +\end{enumerate} + +El despachador de \acrshort{UART} del servicio atiende correctamente las señales transmitidas. Si el nº de serie no coincide con el registrado o recibe un aviso de batería baja, \textbf{emite un mensaje en el \textit{log}} del sistema y descarta el resto del mensaje. + +Si eventualmente llegan menos \textit{bytes} de los 10 previstos, el programa sigue esperando el resto (otra pulsación), entonces detecta una \textbf{corrupción} de datos y vacía el \textit{buffer}. Es importante tener este improbable supuesto en cuenta para no bloquear indefinidamente el receptor. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/proto_uart} + \par\end{centering} + \smallskip + \caption{\label{fig:proto_uart} Placa de prueba entre Arduino y Raspberry Pi.} +\end{figure} + +\smallskip + +\subsubsection{Funcionamiento continuado} + +Es importante comprobar que el demonio es estable y se mantiene activo durante un tiempo considerable. Para ello, hemos dejado el sistema reproduciendo una lista repetidamente durante casi 40 horas, manteniendo el funcionamiento y el uso de memoria. + +A continuación, mostramos una captura de pantalla de la aplicación \code{top}, que detalla el \textbf{uso de recursos} del servicio en segundo plano: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/cap_top} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_top} Uso de recursos del sistema.} +\end{figure} + +\smallskip + +El programa muestra que el demonio en funcionamiento consume un \textbf{1,3\% de \acrshort{CPU}} y \textbf{5,27 \textit{MiB} de memoria} RAM, entre privada y compartida. + +\subsection{Rendimiento} + +En las líneas siguientes estudiaremos la eficiencia de los módulos más importantes del sistema, a través de distintos procedimientos. + +Para cronometrar el tiempo utilizaremos la función \code{clock\_gettime()} de la \textbf{biblioteca de tiempo-real} de \acrshort{POSIX}. Emplearemos el \textbf{reloj monotónico} del sistema, que tiene una resolución del orden de 1 \textit{ns}. + +\subsubsection{Analizador MIDI} + +En primer lugar, vamos a medir el tiempo que tarda el módulo \acrshort{MIDI} en analizar un archivo completo. Para ello, insertamos en la función \code{midi\_init()} el código necesario para cronometrar, según hemos descrito anteriormente. + +Hemos medido 5 veces el tiempo de análisis de \textbf{10 partituras}, con el siguiente resultado: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/lat_midi} + \par\end{centering} + \smallskip + \caption{\label{fig:lat_midi} Tiempo de ejecución del analizador MIDI.} +\end{figure} + +\smallskip + +Podemos comprobar que el tiempo de análisis es bastante aceptable, manteniendo tiempos del orden de 100 \textit{ms}. Las cuatro primeras partituras son de \textbf{creación propia}, el peor caso es ''Super Mario (1)'', que tarda 27 \textit{ms}. La \textbf{ejecución más veloz} ha sido la de ''Beethoven'', con 4,62 \textit{ms}. + +El resto de piezas forman parte de la batería de pruebas y no se utilizarán finalmente. El archivo ''Canyon'' representa un \textbf{valor atípico} con un tiempo de 700 \textit{ms}. Se trata de una antigua demostración de \acrshort{MIDI} para \textit{Windows 98}, contiene 7 pistas y una serie de \textbf{complejas instrucciones} que no utilizaremos en un funcionamiento normal. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/cap_canyon} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_canyon} Edición de canyon.mid con Magix Music Maker 2015.} +\end{figure} + +\smallskip + +\subsubsection{Planificador} + +Para analizar el rendimiento del planificador, medimos el \textbf{tiempo de cada iteración} del bucle principal. Para obtener los datos más adecuados al funcionamiento real, utilizaremos dos partituras específicas: la \textit{Oda a la Alegría} de Beethoven y el \textit{Preludio nº 4} de Bach: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/lat_sched} + \par\end{centering} + \smallskip + \caption{\label{fig:lat_sched} Tiempo de ejecución del planificador.} +\end{figure} + +\smallskip + +Los datos indican que el \textbf{ciclo medio} tarda $738 \; \mu s$. Ya que el algoritmo está diseñado para avanzar tantos eventos como pueda dentro de cada pista, era previsible encontrar tiempos \textbf{ligeramente superiores} en algunos casos. Aún así, el peor tiempo es de 1,94 \textit{ms}, un lapso imperceptible por el usuario. + +\subsubsection{Salida GPIO} + +Es ahora el momento de medir el tiempo que tarda el programa en enviar los datos a la \acrshort{PCB} a través del \acrshort{GPIO}. En este caso, vamos a contrastar los datos de dos implementaciones: + +\begin{enumerate} + \item Volcado de notas del prototipo en Python. + \item Función \code{output\_update()} de la implementación final en C. +\end{enumerate} + +La siguiente imagen ilustra los datos obtenidos: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/lat_gpio} + \par\end{centering} + \smallskip + \caption{\label{fig:lat_gpio} Tiempo de ejecución de la salida a GPIO.} +\end{figure} + +\smallskip + +Los datos más relevantes son los siguientes: + +\smallskip + +\begin{center} + \begin{tabular}{|l|r|r|} + \hline & \textbf{Prototipo} & \textbf{Final} \\ + \hline \textbf{Peor caso} & $1401 \; \mu s$ & $977 \; \mu s$ \\ + \hline \textbf{Media} & $973 \; \mu s$ & $738 \; \mu s$ \\ + \hline + \end{tabular} + \smallskip + \captionof{table}{\label{tab:lat_gpio} Latencia de la salida al GPIO.} +\end{center} + +\smallskip + +El hecho de que el peor caso esté claramente en las \textbf{primeras llamadas} a la función se explica por la implementación del acceso al \acrshort{GPIO} como un \textbf{periférico mapeado} en memoria. Inicialmente el acceso es notablemente superior, hasta que la \textbf{memoria caché} almacena la dirección, acelerando los accesos posteriores. + +A pesar de que Python es un lenguaje \textbf{interpretado}, la biblioteca para acceder al \acrshort{GPIO} está implementada en C, lo que nos proporciona un buen \textbf{rendimiento}. + +\newpage + +\section{Interfaz web} + +La interfaz principal está implementada como un servicio \textit{web} sito en el propio \textit{Raspberry Pi}. Como cualquier servidor estándar, escucha el \textbf{puerto 80} del protocolo \acrshort{TCP} a través de la interfaz de red. + +Uno de los pasos previos a las pruebas de validación es configurar el módulo \acrshort{PHP} en \textbf{modo \textit{development}} (desarrollo), para recibir información y alertas que nos permitirán detectar errores eficazmente. + +\subsection{Red de área local} + +El sistema no está ideado para ser utilizado desde Internet, pero sí en una red de área local sencilla, bien a través de cable o bien conectando un adaptador WiFi por \acrshort{USB}. + +Sin embargo, nuestro \textit{Raspberry Pi} va a estar \textbf{conectado a Internet} durante la fase de desarrollo, tanto para descargar los paquetes necesarios y recibir actualizaciones como para facilitar la verificación. Conectaremos el dispositivo a nuestro \textit{router} mediante un cable \textit{Ethernet} directo. + +Para \textbf{recibir conexiones} \acrshort{HTTP} desde Internet, es necesario configurar el router y \textbf{desviar el puerto \acrshort{TCP} 80} hacia la dirección \acrshort{IP} que hayamos asignado al \textit{Raspberry Pi}. + +En lugar de hacer esto, vamos a crear una \textbf{segunda red local} a la que dirigiremos todos los puertos de entrada, convirtiéndola en una \textbf{zona desmilitarizada} (\acrshort{DMZ}, \textit{\acrlong{DMZ}}). La \textbf{red doméstica} quedará al otro lado del \textit{firewall} del \textit{router}. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/network} + \par\end{centering} + \smallskip + \caption{\label{fig:network} Diagrama de red conectada al Raspberry Pi.} +\end{figure} + +\smallskip + +\subsection{Requisitos} + +Ya que ésta es una aplicación de usuario, desplegaremos las pruebas típicas de entradas de datos en formularios. Una regla importante de la \textbf{programación defensiva} es no permitir al usuario utilizar incorrectamente el sistema. + +\bigskip + +\begin{quote} + \small \flushright ''\textit{Haced los programas como si el usuario tratara el teclado a patadas.}'' \\ + --- Profesor Joaquín Fernández Valdivia (2009). +\end{quote} + +\bigskip + +Además, podremos conectarnos desde \textbf{varios clientes} para comprobar que el sistema responde correctamente ante peticiones simultáneas. + +\subsubsection{Vista y controlador} + +La implementación de las interfaces de entrada y salida sigue este principio: + +\begin{itemize} + \item Si un error proviene del \textbf{usuario}, se comporta asertivamente (muestra un error). + \item Si procede de un \textbf{error interno}, actúa pasivamente o muestra un error genérico. +\end{itemize} + +Hemos contemplado los siguientes supuestos: + +\begin{description} + \item[Errores externos] Producidos por el usuario. Se muestra un error. + + \begin{enumerate} + \item Se intenta poner un nombre nulo a una lista o una obra. + \item Se consulta por \acrshort{URL} una lista que no existe. + \item Se llama al controlador sin un argumento válido. + \end{enumerate} + + \item[Errores internos] Se pueden producir por una incoherencia entre la interfaz y el demonio. La interfaz los intenta recuperar. + + \begin{enumerate} + \item Si desde un terminal se ejecuta la reproducción de una pieza que \textbf{no está registrada} en la base de datos, se muestra el nombre del archivo y se oculta la lista de reproducción. + + \item Si se \textbf{elimina} la pieza o la lista de reproducción en curso, el sistema se comporta como en el caso anterior. Cuando la pieza acaba y el servicio intenta cargar un archivo que no existe, pasa al siguiente. A pesar de que la reproducción se haga \textbf{en bucle}, si todos los archivos fallan, \textbf{el sistema se detiene} (de forma similar a pulsar \textit{Stop}). + \end{enumerate} +\end{description} + +\subsubsection{Formularios} + +Como describimos en la sección \ref{subsec:web_seguridad} del capítulo de implementación, los formularios tienen una \textbf{doble capa} de seguridad: + +\begin{enumerate} + \item La \textbf{vista} en \acrshort{HTML} configura los campos para alertar al usuario si deja alguno en blanco o se excede del límite. El formulario \textbf{no se acepta} hasta que todas las entradas cumplan las condiciones. + + \item El \textbf{controlador} vuelve a comprobar las longitudes de cadena, filtra los mensajes para evitar inyección de código, y muestra un error si algún dato no está conforme. +\end{enumerate} + +Realizaremos las siguientes pruebas en formularios: + +\begin{enumerate} + \item Dejar un campo \textbf{en blanco}. El navegador nos impide continuar. + + \smallskip + + \begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/3]{capitulo6/cap_camponulo} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_camponulo} Alerta al dejar un campo nulo.} + \end{figure} + + \smallskip + + Sin embargo, es muy sencillo \textbf{eliminar la restricción} del formulario en el navegador: + + \smallskip + + \begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/cap_hackform} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_hackform} Herramientas de desarrollo en Chrome.} + \end{figure} + + \smallskip + + Al hacer esto, podemos dejar efectivamente el campo en blanco, pero entonces el \textbf{controlador} detectará este hecho y emitirá igualmente un error: + + \smallskip + + \begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/cap_error} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_error} Mensaje de error en la interfaz.} + \end{figure} + + \smallskip + + \item Alcanzar el \textbf{límite} de tamaño permitido. La aplicación se comporta de la misma forma que en el caso anterior, a excepción de que, si \textbf{forzamos} la entrada de texto, el controlador \textbf{descartará} el texto más allá del límite especificado. + + \item \textbf{Inyectar código \acrshort{SQL}} en el formulario. El controlador filtra la cadena e introduce los \textbf{caracteres de escape} adecuados para evitar la inyección. La pieza o la lista quedan nombradas con el código tal como se escribe. + + \item Introducir una \textbf{contraseña incorrecta}. De acuerdo a lo descrito en la sección \ref{subsec:impl_portada} de implementación, el programa se bloquea 2 segundos y retorna con un aviso: + + \smallskip + + \begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth/3]{capitulo6/cap_errclave} + \par\end{centering} + \smallskip + \caption{\label{fig:cap_errclave} Mensaje de error en la contraseña.} + \end{figure} + + \smallskip + + \item Inyectar \textbf{código shell}. El controlador evita la inyección de la misma manera, escapando la cadena de entrada, y se intenta acceder al sistema con la cadena introducida como clave. + +\end{enumerate} + +\subsubsection{Carga de partituras} + +Como interfaz de cara al usuario, la subida de partituras al servidor solo permite almacenar archivos \acrshort{MIDI} de hasta 1 \textit{MiB}. La batería de pruebas ha sido la siguiente: + +\begin{enumerate} + \item Subir una partitura válida. Se almacena sin mayor problema y aparece en la lista. + \item Subir una partitura compuesta solo por \textbf{silencios} musicales. Se almacena y se muestra. + \item Subir un archivo de \textbf{formato incorrecto} con extensión \code{.mid} de más de 1 \textit{MiB}. Aparece un error, explicando el tamaño como motivo. + \item Subir un archivo de formato incorrecto con extensión \code{.mid} de menor tamaño. Muestra el mensaje de error de formato. + \item Arrastrar y soltar varios archivos sobre la lista, algunos válidos y otros no. Se envían todos al servidor pero solo se aceptan los correctos. +\end{enumerate} + +\subsection{Rendimiento} + +La eficiencia del servidor \textit{web} no es tan crítica como la del reproductor, pero es importante acotarla para lograr una \textbf{experiencia de usuario} cómoda. La interfaz ha sido ágil en todo momento durante la fase de prueba. + +A continuación mostramos una gráfica que relaciona el tiempo de ejecución de las \textbf{vistas}: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/ejecucion_web} + \par\end{centering} + \smallskip + \caption{\label{fig:ejecucion_web} Tiempo de ejecución de las vistas.} +\end{figure} + +\smallskip + +Todas ellas están \textbf{por debajo de 100 \textit{ms}}. La más \textbf{rápida} es la portada, ya que no tiene que consultar información en la base de datos, mientras que el \textbf{reproductor} supera al resto, ya que tiene que comunicarse, además, con el demonio, aunque el tiempo extra es aceptable. + +\subsection{Compatibilidad} + +La interfaz se ha implementado en \acrshort{HTML}5 y \acrshort{CSS} 3.0. Cualquier navegador que los soporte debería funcionar sin problemas. Por nuestra parte, hemos probado la \textit{web} con las siguientes aplicaciones: + +\begin{enumerate} + \item Google Chrome 45 en Windows 8.1. + \item Mozilla Firefox 40 en Windows 8.1. + \item Microsoft Internt Explorer 11 en Windows 8.1. + \item Microsoft Edge 20 en Windows 10. + \item Firefox 40 en Ubuntu 15.04. + \item Firefox 40 en Fedora 22. + \item Google Chrome 45 en Mac OS Yosemite. + \item Safari 8 en Mac OS Yosemite. + \item Google Chrome 45 en Android 4.0.2 y 5.1.1. +\end{enumerate} + +A continuación presentamos las \textbf{incidencias} que hemos encontrado: + +\begin{enumerate} + \item La página \textbf{no es compatible} con Internet Explorer, por su escaso soporte de \acrshort{CSS}. + \item En Edge, sin embargo, funciona todo excepto ''arrastrar y soltar''. + \item En Ubuntu tampoco funciona la función ''arrastrar y soltar'', por un \textbf{\textit{bug} en Unity} \cite{unity_bug}. + \item Safari no soporta la \textbf{validación de formulario} (permite introducir campos en blanco), aunque sigue apareciendo el error del controlador. + \item Safari tampoco permite \textbf{descargar} un \acrshort{MIDI} haciendo clic directamente, si no hay un reproductor compatible. En cambio, se puede hacer seleccionando ''Guardar enlace como...'' + \item No hemos podido verificar la función ''arrastrar y soltar'' en Android. +\end{enumerate} + +A pesar de los problemas encontrados, exceptuando Internet Explorer, en el resto de sistemas la aplicación es totalmente \textbf{funcional y estética}. + +\subsection{Aplicaciones auxiliares} + +Estas aplicaciones han servido de soporte a los bloques anteriormente descritos, de forma que podemos decir que \textbf{cumplen los requisitos}, pues de otra forma, habríamos descubierto los problemas en las pruebas anteriores. + +No obstante, la \textbf{interfaz} utiliza el analizador de \acrshort{MIDI} y la aplicación de autentificación, y es interesante conocer el tiempo que emplea en usarlos. + +Hemos realizado con la herramienta \code{time} una \textbf{medición superficial} del tiempo de ejecución desde consola de las siguientes órdenes: + +\begin{enumerate} + \item \code{organ status} + \item \code{organ-midinfo --duration beethoven.mid} + \item \code{organ-login pi} +\end{enumerate} + +A continuación mostramos el resultado de \textbf{10 ejecuciones}: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/ejecucion} + \par\end{centering} + \smallskip + \caption{\label{fig:ejecucion} Tiempo de ejecución de los programas auxiliares.} +\end{figure} + +\smallskip + +El resultado más sorprendente es el del \textbf{analizador}, cuya ejecución total es de 207 \textit{ms} de media, cuando la propia función de análisis solo tarda una media de 5,41 \textit{ms}. + +\newpage + +\section{Prueba sobre la PCB} + +En último lugar, volvemos a reunirnos con Mikel Aguayo para validar nuestros \textbf{proyectos en conjunto}, tal como teníamos previsto. Actualmente solo disponemos de un \textbf{prototipo} del circuito impreso diseñado, más que suficiente para comprobar que el sistema funciona y se comporta como esperábamos. + +De acuerdo a la especificación, la \acrshort{PCB} alimenta al \textit{Raspberry Pi} y se conecta, mediante unos conectores situados en la parte inferior, al banco de puertos \acrshort{GPIO} del computador. + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/pcb} + \par\end{centering} + \smallskip + \caption{\label{fig:pcb} Prototipo hardware.} +\end{figure} + +\smallskip + +Cuando conectamos la fuente de alimentación, el \textit{Raspberry Pi} arranca automáticamente hasta que aparece ''DETENIDO'' en el \acrshort{LCD} del prototipo, que indica que la carga ha finalizado y el dispositivo está listo para funcionar. + +El módulo receptor del mando responde a todos los mandos sin necesidad de \textbf{registrarlos}, ya que envía el nº de serie al \textit{software}, y éste se encarga de gestionar la pulsación. + +\subsection{Entrada de datos} + +Sobre la placa hemos probado dos \textbf{versiones} del software: + +\begin{enumerate} + \item \textbf{Prototipo} en Python con una combinación fija de notas, como prueba de concepto. + \item Implementación \textbf{final} del módulo \textit{software} de salida por \acrshort{GPIO}. +\end{enumerate} + +En el prototipo establecimos un \textbf{ancho de pulso} muy grande, del orden de 1 \textit{ms}, para descartarlo de antemano de cualquier otro problema que pudiera surgir. La primera prueba fue satisfactoria como \textbf{prueba de concepto}, sin embargo, producía errores en la salida, debido a desfases producidos por el intérprete Python, pues sucedía casi determinísticamente en el 4º canal, independientemente del que escogiéramos. + +Utilizamos un \textbf{osciloscopio} para realizar medidas sobre las señales que el \textit{software} envía a la \acrshort{PCB}. Aquí podemos ver el \textbf{ancho de pulso} de reloj: + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*2/3]{capitulo6/osc_pulso} + \par\end{centering} + \smallskip + \caption{\label{fig:osc_pulso} Ancho de pulso.} +\end{figure} + +\smallskip + +Tal como vemos, el lapso es de $114 \; \mu s$, que se ajusta aceptablemente a la espera requerida. + +La \textbf{segunda implementación}, ya en lenguaje C, elimina por completo este problema. Entonces ajustamos más finamente los parámetros según las especificaciones. Algunos de los \textbf{cambios} que realizamos fueron: + +\begin{enumerate} + \item Establecer el ancho de pulso del \textbf{reloj} a 100 \textit{ms}. + \item Almacenar el nº de serie del \textbf{mando} a distancia. +\end{enumerate} + +%También observamos el tiempo total en \textbf{volcar una nota}, desde que se desplaza el primer \textit{bit} hasta que se se copian los valores a la salida del registro de desplazamiento: + +%\smallskip + +%\begin{figure}[H] +% \noindent \begin{centering} +% \includegraphics[width=\linewidth*2/3]{capitulo6/osc_nota} +% \par\end{centering} +% \smallskip +% \caption{\label{fig:osc_nota} Tiempo de transmisión de una nota.} +%\end{figure} + +%\smallskip + +%El aparato nos marca 1,16 \textit{ms}. + +\subsection{Modo Ingeniería} + +Éste es el nombre que hemos acuñado para el \textbf{control reducido}, que facilita un menú con cuatro funciones: + +\begin{enumerate} + \item Informar del estado del \textbf{reproductor}. + \item Controlar el \textbf{modo Ingeniería} propiamente dicho. + \item Activar y desactivar el \textbf{metrónomo}. + \item \textbf{Apagar} y reiniciar el sistema. +\end{enumerate} + +\smallskip + +\begin{figure}[H] + \noindent \begin{centering} + \includegraphics[width=\linewidth*3/4]{capitulo6/pcb_ingeniero} + \par\end{centering} + \smallskip + \caption{\label{fig:pcb_ingeniero} PCB en modo Ingeniería.} +\end{figure} + +\smallskip + +Las pruebas de validación de este módulo han sido tres: + +\begin{enumerate} + \item Comprobar que el \textit{software} recibe correctamente las señales de giro y pulsación del codificador rotatorio. + + \item Verificar que el menú realiza las funciones indicadas, de acuerdo a la máquina de estados diseñada en la figura \ref{fig:engineer}. + + \item Probar que el metrónomo funciona correctamente y que se puede apagar y reiniciar el sistema. +\end{enumerate} + +Durante la prueba del control remoto pudimos detectar tres pequeños problemas: + +\begin{enumerate} + \item El \textit{software} reconocía los giros del codificador \textbf{al revés}, discrepando de la especificación de la tabla \ref{tab:info_rotary}. + \item Se producían algunos \textbf{rebotes} en el pulsador. + \item Apenas se escuchaba el \textbf{metrónomo}, por tener un ancho de pulso muy pequeño. +\end{enumerate} + +Por tanto, se realizaron las siguientes \textbf{medidas correctoras}: + +\begin{enumerate} + \item Reajustar el sentido de giro. + \item Aumentar la tolerancia de rebote. + \item Regular el ancho de pulso del metrónomo para maximizar la acústica, bastante tenue. +\end{enumerate} + +Aplicados estos pequeños cambios, la \acrshort{PCB} y el \textit{software} fueron capaces de comunicarse perfectamente, haciendo funcionar la reproducción de partituras tanto desde la interfaz \textit{web} como desde el mando a distancia, y manejando eficazmente el control remoto. + +Hecho todo esto, podemos dar por \textbf{completada} la fase de verificación de los objetivos propuestos en este proyecto. + +\subsection{Vídeo del funcionamiento de la PCB} + +\smallskip + +\begin{center} + Para reproducir este vídeo, es necesario utilizar Adobe Reader 9 o superior. + \smallskip + \flashmovie[engine=flv-player,width=11cm,height=6cm,auto=1,controlbar=0]{capitulo6/video_pcb.mp4} + \smallskip + \captionof{figure}{\label{fig:video_pcb} Vídeo del funcionamiento de la PCB.} +\end{center} + +\smallskip + +\newpage +\clearpage{\pagestyle{empty}\cleardoublepage} \ No newline at end of file diff --git a/report/subdocs/capitulo7.tex b/report/subdocs/capitulo7.tex index 110551e..f4630a9 100644 --- a/report/subdocs/capitulo7.tex +++ b/report/subdocs/capitulo7.tex @@ -1,529 +1,50 @@ +\chapter{Conclusión y líneas futuras} +\label{cap:capitulo7} -\chapter{Control remoto de la instrumentación electrónica.} +\begin{quote} + \begin{flushright} + \small ''\textit{Pensad que lo malo ya ha pasado, y lo bueno está por llegar.}'' \\ + --- Profesor Juan Manuel López Soler (2013). + \end{flushright} +\end{quote} -Como ya se comentó inicialmente, se pretende dotar al sistema de un control automático y centralizado de todos los equipos electrónicos necesarios vistos en el capítulo 6, de modo que su configuración se realice por medio del software que implementaremos, evitando la necesidad de manipular cada instrumento individualmente sobre su propio panel frontal de configuración o \textit{setup}. +\newpage -%Para este objetivo, y aprovechándonos de que la mayoría de equipos que utilizaremos tienen conexión GPIB, crearemos unas librerías de control para cada instrumento, que utilizarán comandos virtuales de configuración remota a través del bus GPIB 488.2 de IEEE. El gaussímetro, que es imprescindible para medir el valor del campo magnético generado por las bobinas y poder así establecer una calibración de las mismas, se controla por medio del puerto serie, por tanto necesitará una librería diferente. -% -%A continuación explicaremos las principales características del bus GPIB de comunicación así como el protocolo empleado con el gaussímetro sobre el puerto serie. -% -%\section{El bus GPIB.} -% -%Es un sistema de inteconexión de instrumentos programables consistente en un bus simple formado por 24 líneas a las que elementos del sistema se conectan en paralelo-serie. La comunicación se realiza mediante el paso de mensajes que transportan datos y mensajes de control. Inicialmente el bus fue desarrollado por \textit{Hewlett-Packard} en 1969 y lo llamo HP-IB (Hewlett-Packard Instrumentation Bus). -% -%En 1978 el IEEE estandarizó el bus en la norma que denominó IEEE-488, para proporcionar u n interfaz estándar para la comunicación entre los instrumentos de diversas fuentes. Originalmente, el objetivo era permitir que sus equipos pudieran conectarse con los de otros fabricantes y con ordenadores funcionando como \textit{hosts}. El interfaz ganó rápidamente renombre en la industria del ordenador debido a su gran versatilidad y entonces el comité del IEE lo rebautizó como GPIB (\textit{General Purpose Interface Bus}). -% -%Dado que esa primera norma no incluía indicaciones sobre la sintaxis o el formato de los comandos a usar, apareció la norma 488.2 que incluía un mínimo de mensajes que debía entender un instrumento o el tipo de formato de datos y comandos. -% -%\subsection{La norma IEEE 488.2 (GPIB).} -% -%A la hora de definir las características de un bus hay que pensar en que éste se puede definir bajo dos conceptos: uno físico y otro lógico. Físicamente consiste en un cierto número de conductores que transportan señales eléctricas en paralelo entre diferentes sistemas que contienen circuitos electrónicos. El concepto lógico de refleja en las normas y formatos de intercambio de datos, en la sincronización y en la temporización. -% -%El bus transportará información en todas direcciones y todos los instrumentos recibirán instrucciones similares y deberán reconocer de forma automática que han sido direccionados. Los parámetros más importantes que describen a un bus son: -% -%\begin{itemize} -% -%\item[-] Datos mecánicos y eléctricos (conector y tecnología empleada). -% -%\item[-] Procesadores compatibles. -% -%\item[-] Espacio de memoria direccionable y cantidad de instrumentos direccionables. -% -%\item[-] transferencia síncrona o asíncrona. -% -%\item[-] Multipleaxión de datos. -% -%\item[-] Frecuencia de operación. -% -%\item[-] Velocidad de transferencia. -% -%\item[-] Protocolo. -% -%\item[-] Numéro de unidades masters. -% -%\end{itemize} -% -% -%De esta manera, los objetivos principales de la norma IEEE 488.1, incorporados por la norma 488.2 fueron: -% -%\begin{itemize} -% -%\item[-] Crear un sistema de control de instrumentación donde dichos instrumentos se encuentran relativamente próximos. -% -%\item[-] Permitir la comunicación directa entre elementos sin necesidad de que los datos pasen por el controlador. -% -%\item[-] Compatibilidad entre equipos de diferente fabricante, funcionalidad y velocidad. -% -%\item[-] No disminuir la funcionalidad de los equipos. -% -%\end{itemize} -% -% -% -%\subsection{Especificaciones físicas y mecánicas del bus.} -% -% -%Finalmente la norma publicó una serie de especificaciones físicas y mecánicas, entre las que podemos destacar: -% -%\begin{itemize} -% -%\item[-] El número máximo de dispositivos conectados es 15, y necesariamente uno de ellos ha de ser el controlador. -% -%\item[-] La longitud del cable de interconexión total de los elementos está restringido a un máximo de 20 metros. -% -%\item[-] Hay 16 líneas de señales, 8 para control y 8 para datos. -% -%\item[-] La transferencia es asíncrona, controlada mediante líneas de \textit{handshaking}. -% -%\item[-] La velocidad máxima de transferencia es de 1MB/s, para distancias muy cortas (<50 cm). -% -%\item[-] Se pueden direccionar hasta un total de 31 direcciones primarias aunque solo se puedan emplear 15 instrumentos. Además de las 31 direcciones primarias, existen otras 31 secundarias. -% -%\item[-] Entre los 15 intrumentos puede haber más de un intrumento de control, sin embargo, solo puede haber uno activo al mismo tiempo. -% -%\end{itemize} -% -%El conector está formado por 24 pines y funciona simultáneamente como conector macho y hembra, facilitando la interconexion de instrumentos entre sí. -% -%Respecto a las especificaciones eléctricas, solo mencionar que tanto los emisores como receptores deben ser compatibles con TTL y que además se utiliza lógica negativa. Actualmente existen gran variedad de integrados especializados en realizar esa función de conexión con el GPIB por lo que dichas especificaciones no deben suponer problema alguno. -% -%En la Figura \ref{fig:pines_conectorGPIB}, podemos ver una representación del conector de 24 pines utilizado para comunicaciones GPIB. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.8]{capitulo7/busGPIB/ieee488_connector_pines} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:pines_conectorGPIB} Conector de 24 pines para bus GPIB \cite{WIKIPED}.} -%\end{figure} -% -% -%\subsection{Especificaciones funcionales.} -% -%En toda comunicación con intercambio de datos dentro del bus se necesitarán al menos tres elementos funcionales de carácter básico: -% -%\begin{itemize} -% -%\item Un dispositivo actuando \textit{controller}, es decir dirigiendo el flujo de datos de forma adecuada y controlando el sentido de la comunicación. Normalmente la mayoría de los sistemas GPIB consisten en un ordenador y varios instrumentos. Si hay varios ordenadores conectados entre si solo puede haber un \textit{controler} en un mismo instante de tiempo, que se denomina CIC (\textit{Controller In Charge}). -% -%\item Un dispositivo actuando como \textit{listener}, es decir escuchando instrucciones o datos provenientes de bus. Se permite que haya varios \textit{listeners} a la vez. -% -%\item Un dispositivo actuando como \textit{talker}, es decir enviando información al bus. Solo puede haber un \textit{talker} a la vez. -% -%\end{itemize} -% -% -%\subsubsection{Líneas de datos.} -% -%Las líneas de datos son bidireccionales y están destinadas a transportar mensajes usualmente en código ASCII de 7 bits. La información transferida va desde direcciones a órdenes de programación, información sobre el dispositivo o medidas tomadas por un cierto instrumento. Estas líneas de datos van desde el pin DIO7 al DIO0. -% -%\subsubsection{Líneas de control de transferencia de datos o \textit{handshaking}.} -% -%Obviamente, al ser un bus asíncrono, se necesitan ciertas líneas para coordinar la transferencia de datos y asegurar que nada se emita si todos los receptores no están debidamente preparados para recibir o que la transmisión dure lo suficiente para que el dispositivo más lento reciba la información. -% -%En las líneas de handshaking se utiliza lógica negativa con cierto colector abierto, lo que aporta una serie de ventajas como la reducción del margen de ruido o la realización de operaciones AND entre líneas mediante el WIRED-OR. -% -%Éstas líneas de control son: -% -%\begin{itemize} -% -%\item \textbf{DAV:} (\textit{Data Valid}). Controlada por el emisor, indica que en el bus hay un dato correcto y estable que puede ser aceptado sin errores. -% -%\item \textbf{NRFD:} (\textit{Not Ready for Data}). Los receptores controlan esta línea de indicándole al emisor que están o no preparados para la recepción de datos por el bus. -% -%\item \textbf{NDAC:} (\textit{Not Data Accepted}). \textit{Flag} o bandera para que los receptores indiquen si han aceptado o no el dato enviado por el bus. -% -%\end{itemize} -% -%Mediante el cronograma de señales mostrado en la siguiente Figura \ref{fig:senal_cronogramasig}, podemos entender rápidamente el funcionamiento de estas líneas. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.5]{capitulo7/busGPIB/ch_gpib2} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:senal_cronogramasig} Cronograma de señales de interfaz para handshaking \cite{WIKIPED}.} -%\end{figure} -% -% -%\subsubsection{Líneas de control general del bus.} -% -%Las siguientes líneas son las encargadas de gestionar el flujo de información a través del bus GPIB: -% -% -%\begin{itemize} -% -%\item \textbf{IFC:} (\textit{Interface Clear}). Inicializa el bus a un estado conocido. -% -%\item \textbf{ATN:} (\textit{Attention}). Según el nivel lógico de esta línea los valores que circulen por el bus de datos serán considerados mensajes de interfaz o bien mensajes de datos ASCII correspondientes a comandos del instrumento. -% -%\item \textbf{REN:} (\textit{Remote Enable}). El controlador informa de que dispositivos deben situarse en estado remoto y atender al bus. -% -%\item \textbf{EOI:} (\textit{End Or Identify}). Esta línea tiene una doble función. Por una parte cuando un dispositivo actúa como transmisor de hacia el bus y quiere finalizar la transmisión, y por otro lado también se usa en los pollings paralelos para identificación. -% -%\item \textbf{SRQ:} (\textit{Request of Service}). Esta será la línea que utiliza un determinado instrumento para notificar al controlador del bus que necesita de sus servicios. -% -%\end{itemize} -% -% -%En cuanto un determinado instrumento emite un \textit{Service Request}, el controlador debe realizar un \textit{polling} serie o paralelo para detectar el instrumento demandando servicio y poder enlazarlo. -% -% -%Los mensaje que se transmiten a lo largo del bus pueden ser de dos tipos, atendiendo a su finalidad: -% -%\begin{itemize} -% -%\item \textbf{Mensajes de interfaz:} son los mensajes dirigidos a la interfaz del GPIB y que no interactúan con el instrumento propiamente dicho, sino solo con la interfaz de comunicación. Estos mensajes serán los que mantengan el protocolo en el estado adecuado que permita enviar y/o recibir mensajes de dispositivo en cada momento. -% -%\item \textbf{Mensajes de dispositivo:} son los mensajes que no interaccionan con la interfaz lógica del bus, por tanto no afectan al estado actual en el que se encuentre el bus, sino que actúan sobre el propio instrumento al que van dirigidos, configurando cualquier funcionalidad que ofrezca dicho dispositivo. De esta manera, si nos encontramos como \textit{listeners} (atentos a la información que se envía por el bus), nos encontramos en un estado lógico de la interfaz; si además recibimos un mensaje para efectuar una medida d corriente a través de uno de los terminales del dispositivo, el estado \textit{listener} no se habrá modificado, sin darse cambio alguno en ese sentido. -% -%\end{itemize} -% -%A continuación, en la Figura \ref{fig:tot_mens_interfaz}, se muestra el conjunto total de mensajes de interfaz, también llamados remotos. Estos mensajes se enviarán codificados en las líneas del bus. Por ejemplo, si se quisiese indicar al instrumento cuya dirección es la 10, que actúe como \textit{listener}, haría que activar la línea ATN (indicadora de transmisión de mensajes de interfaz) y enviar por las lineas DIO7-DIO0 el símbolo * codificado en ASCII, que corresponde a la instrucción MLA10 (\textit{MLA - My Listener Address}). -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.6]{capitulo7/busGPIB/mensajes_interfaz_gpib} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:tot_mens_interfaz} Totalidad de mensajes de interfaz GPIB \cite{WIKIPED}.} -%\end{figure} -% -%De todos modos, no es necesario que utilicemos directamente estos comandos desde el punto de vista del programador, ya que dentro de Matlab y como se comentara en las siguientes secciones, todos estos comandos de interfaz se ejecutarán de forma automática dentro del driver del fabricante Agilent que utilizamos, por tanto no deben preocuparnos excesivamente. -% -% -%\subsubsection{Protocolo de direccionamiento.} -% -%Conviene destacar el protocolo de direccionamiento, el cual utilizan dispositivos \textit{controllers}, \textit{talkers} y \textit{listeners} para referenciarse entre ellos. -% -%Antes de que tenga lugar cualquier transferencia de datos en el bus, es necesario que algún dispositivo sea direccionado como \textit{talker} y algún otro como \textit{listener}. El controlador es el encargado de nombrar a quién habla y quién escucha, disponiendo un mensaje de interfaz con las direcciones específicas, tal y como los mostrados anteriormente. -% -%El formato del byte de mensaje de direccionamiento es el indicado en la Figura \ref{fig:direc_mens_interfaz}. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.95]{capitulo7/busGPIB/direcciones_gpib_formato} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:direc_mens_interfaz} Formato del mensaje de direccionamiento GPIB \cite{WIKIPED}.} -%\end{figure} -% -%El contenido de los bits de la posición 0-4 se utiliza para indicar la dirección del dispositivo. Los bits 5 y 6 informan de si es una dirección \textit{listener} o \textit{talker} respectivamente. -% -%Además de estos comandos existen también el comando \textit{Untalk} y \textit{Unlisten}, empleados para desdireccionar a los posibles \textit{listeners} y al posible \textit{talker} de un momento determinado. -% -% -%\subsubsection{Protocolo de \textit{Polling}.} -% -%Como se ha visto anteriormente, en el bus GPIB existe una línea de control, la SRQ, que activada informa al \textit{controller} sobr la necesidad de atención por parte de uno de los instrumentos conectados al bus. Para descubrir quién ha activado esta línea, existen dos métodos: el \textit{serial-polling} y el \textit{parallel-polling}. -% -%Al generarse un \textit{serial poll}, el \textit{controller} envía un mensaje de comando SPE (\textit{Serial Poll Enable}) a cada dispositivo de forma serializada y especificando su dirección. De esta forma cuando dicho dispositivo se direcciona como \textit{talker}, éste contesta al \textit{controller} indicando si ha sido él o no el que ha realizado un SRQ. Al recibir el \textit{controller} este byte, el controller devuelve a este mismo instrumento un SPD (\textit{Serial Poll Disable}) con el que el instrumento regresa a su estado normal de \textit{talker} o \textit{listener}. En caso de ser un \textit{parallel poll}, el envío del SPE se realiza en paralelo, pudiendo el \textit{controller} identificar al instrumento demandando servicio de forma más rápida y eficiente. - % -%\newpage -%\subsection{Conexión de interfaces IEEE 488.}\label{gpib_scheme} -% -%En la presente sección, se indicará al lector los pasos de instalación y estructura de conexionado que se ha empleado para habilitar un control centralizado de los 4 dispositivos dotados con este tipo de interfaz en un único ordenador personal con una \textit{GPIB 82350A PCI Interface Card} de Agilent Technologies (Figura \ref{fig:tarj_gpib}) basada en IEEE 488. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.65]{capitulo7/busGPIB/agilent82350A} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:tarj_gpib} GPIB 82350A PCI Interface Card de Agilent \cite{AGILGPIB}.} -%\end{figure} -% -%Lo primero que debemos de realizar antes de montar la interfaz PCI o conectar algún dispositivo, es instalar la suite de librerías Agilent para el control de los puertos de entrada/salida del ordenador personal. Concretamente la suite se llama \textit{IO Agilent Libraries Suite v16.3}. Estas librerías habilitan la comunicación con instrumentos para una gran variedad de entornos de desarrollo compatibles con puertos GPIB, USB, LAN, RS-232, PXI, AXIe y VXI de diferentes fabricantes. Una vez instalado el software en el PC (Figura \ref{fig:iosuite_pic1}), podemos realizar el montaje de la \textit{PCI interface card} y ejecutar el software para activar la interfaz y comprobar la funcionalidad de la misma. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.8]{capitulo7/busGPIB/capture_iosuite0} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:iosuite_pic1} Icono IO Suite 16.3 en el taskbar de Windows.} -%\end{figure} -% -%La conexión de la tarjeta GPIB PCIIA al PC se realiza mediante un zócalo de 80 conexiones presente en la gran mayoría de ordenadores. El bus de la tarjeta funciona a 16 bits, si bien, puede conectarse con un equipo cuyo bus sea de 32 bits si se dispone de un equipo en tal disposición, mediante el controlador gpib-32.dll incluido en las mencionadas librerías. -% -%Una vez ejecutado el software de librerías I/O, nos aparecerá una pantalla en la que se detallan los diferentes puertos detectados en el PC, el GPIB entre ellos (Figura \ref{fig:gpib_suiteinterface}(a)). Si seleccionamos la interfaz GPIB y hacemos click en el botón \textit{Properties} accedemos al panel de configuración de la interfaz GPIB 82350A, donde podemos modificar su dirección GPIB, los identificadores VISA y SICL, además de la unidad lógica (permite diferenciar entre varias tarjetas de interfaz GPIB PCI instaladas en el mismo equipo) (Figura \ref{fig:gpib_suiteinterface}(b)). En nuestro caso hemos dejado los valores por defecto, que asignan a esta interfaz la dirección 21 y la unidad lógica 8. -% -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\subfloat[]{\includegraphics[scale=0.35]{capitulo7/busGPIB/capture_suite1}} -%\hspace{0.1cm} -%\subfloat[]{\includegraphics[scale=0.5]{capitulo7/busGPIB/prop}} -%\vspace{0.5cm} -%\smallskip -%\caption{\label{fig:gpib_suiteinterface} Interfaz GPIB detectada y configurada.} -%\par\end{centering} -%\end{figure} -% -%El siguiente paso es determinar una dirección GPIB para cada instrumento que vamos a conectar por medio de este bus. Generalmente, cada instrumento posee un conmutador DIP de 7 interruptores en el panel trasero, por medio del cual se fija la dirección con un binario equivalente a un decimal en el rango 0-30, ya que el máximo número de dispositivos conectados a la misma tarjeta es 31. Cada dirección tiene una dirección primaria y otra secundaria, aunque en este caso solo emplearemos la dirección primaria. A continuación incluimos las direcciones de los dispositivos utilizados en este proyecto (Tabla \ref{tab:devices_addr}). -% -%\begin{table}[H] -%\begin{center} -%\bigskip -%\includegraphics[scale=0.9]{capitulo7/busGPIB/gpibdirec} -%\smallskip -%\caption{Direcciones GPIB de los dispositivos utilizados.} -%\label{tab:devices_addr} -%\end{center} -%\end{table} -% -%Para la conexión de los dispositivos se ha utilizado cables 10833A y 10833D de Agilent, de 1 metro y 0.5 metros respectivamente, acoplados según la forma indicada en la Figura \ref{fig:conex_pic}, que es la recomendada por el fabricante para la conexión de más de un instrumento. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=1]{capitulo7/busGPIB/conex4_gpib} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:conex_pic} Esquema del conexionado de dispositivos mediante cables GPIB de 24-pines.} -%\end{figure} -% -%Agilent recomienda determinadas restricciones en cuanto a la longitud del cable y número de elementos conectados para alcanzar determinadas tasas de datos en la comunicación por el bus. Para minimizar el riesgo de sobrecarga, no se deben acoplar más de tres tomas de 24-pines una encima de otra. Si queremos alcanzar tasas de transferencia superiores a 500 Kbytes/sec la longitud total de cable utilizado debe ser menor que 1 metro por el número de instrumentos conectados juntos. -% -%Una vez conectados los dispositivos, al encenderlo y pulsar el botón \textit{Refresh} del software, deberían aparecernos detallados bajo la interfaz a la que han sido conectados, en nuestro caso a la GPIB1, como muestra la Figura \ref{fig:gpib_suitedevices}. Podemos ver las propiedades de cada dispositivo en la parte derecha de la ventana. Notar que algunos dispositivos no son reconocidos mediante su nombre comercial, sino que algunos son nombrados con la primera cadena de caracteres que devuelven al mandarles un comando de petición de identificación (IDN?), y este en algunos casos es el nombre o una fecha de fabricación, etc, por lo que es conveniente determinar cuál es cada uno por medio de su dirección GPIB. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.35]{capitulo7/busGPIB/capture_suite2} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:gpib_suitedevices} Dispositivos GPIB reconocidos.} -%\end{figure} -% -%Además de la tarjeta GPIB 82350A PCI de Agilent, disponemos de un conector GPIB/USB modelo 82357A (Figura \ref{fig:gpib_usbdevice}) de Agilent que permite la comunicación de hasta 14 dispositivos interconectados mediante conexiones GPIB de 24-pines a un PC por medio de un puerto USB. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.65]{capitulo7/busGPIB/usb_gpibpic} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:gpib_usbdevice} Conector GPIB/USB 82357A de Agilent \cite{AGILGPIB}.} -%\end{figure} -% -%Para tal utilización, la conexión debe realizarse siguiente el esquema propuesto en la Figura \ref{fig:usbgpib_esquema}. Notar también que para esta interfaz, la dirección GPIB de la interfaz es también 21, pero la unidad lógica es 7, para diferenciarse de la otra en caso de que se usen simultáneamente. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=1.2]{capitulo7/busGPIB/conexion_usbgpib} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:usbgpib_esquema} Esquema de conexión GPIB/USB con el modelo 82357A \cite{AGILGPIB}.} -%\end{figure} -% -% -%\section{Matlab Instrument Control Toolbox.} -% -%Como el software será definitivamente implementado en Matlab, se ha hecho uso de la funciones ofrecidas por la herramienta \textit{Instrument Control Toolbox} para conectar con los equipos que vamos a utilizar de forma remota a través de nuestra estación de trabajo. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.3]{capitulo7/busGPIB/logo_mictg} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:dibujo_mict} Instrument Control Toolbox \cite{ICTGPIB}.} -%\end{figure} -% -%Instrument Control Toolbox nos permite por tanto controlar y comunicarnos con dispositivos externos a través de los protocolos de comunicación GPIB y VXI directamente desde Matlab. En nuestro caso, hemos utilizado este toolbox para poder llevar a cabo el control de instrumentos a través de la programación directa del bus GPIB, Figura \ref{fig:tbmh_esquema}. - % -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=1.2]{capitulo7/busGPIB/matlab_control_toolbox} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:tbmh_esquema} Esquema de control de instrumentos vía GPIB con Matlab \cite{ICTGPIB}.} -%\end{figure} -% -%\newpage -% -%Para realizar una comunicación con un instrumento podemos utilizar diferentes buses de comunicación siempre y cuando el instrumento disponga de ellos. Para acceder al bus desde un PC, es necesaria una tarjeta controlador del bus, ya sea GPIB, VXI o cualquiera de ellos. Para acceder a cada una de estas tarjetas podemos utilizar las funciones propias del bus, como por ejemplo los comandos SCPI para el bus GPIB. Pero la utilización de éstas, fuerza que las aplicaciones que desarrollamos para un determinado instrumento sirven únicamente para ese bus y ese instrumento. Por ejemplo, si utilizamos comandos SCPI para controlar un multímetro vía bus GPIB, no podremos utilizar dicho programa para controlar el mismo instrumento utilizando un bus diferente. Para solucionar este y otros problemas semejantes, en 1993 National Instruments junto con GenRad, Racal Instruments, Tektronix y Wavetek formaron un consorcio llamado VXI plug and play Systems Aliance. Uno de los estándares más desarrollados por este grupo fue VISA (Virtual Instrument Software Architecture), que es un conjunto de funciones de alto nivel que se encarga de hacer transparente los recursos software que estemos utilizando. -% -%\subsection{Funciones GPIB.} -% -%La herramienta Matlab Instrument Control Toolbox ofrece una amplia variedad de funciones para llevar a cabo la comunicación con el instrumento por medio de diferentes tipos de interfaces. En nuestro caso nos centraremos en aquellas destinadas a la interfaz GPIB y a la creación de objetos de este tipo. -% -%Entre todas ellas destacamos las siguientes: -% -%\begin{itemize} -% -%\item \textbf{\textit{gpib}:} permite crear objetos de tipo gpib indicándole el fabricante del instrumento, el número de tarjeta GPIB y la dirección del instrumento en cuestión. -% -%\item \textbf{\textit{fopen}:} una vez se ha creado el objeto de tipo gpib, se crea la conexión entre el objeto de la interfaz GPIB y el instrumento. -% -%\item \textbf{\textit{fclose}:} cierra la conexión entre el objeto de la interfaz GPIB creado y el instrumento en cuestión. -% -%\item \textbf{\textit{fprintf}:} escribe cadenas de texto ASCII en el instrumento. -% -%\item \textbf{\textit{fscanf}:} permite escanear el buffer del instrumento, obteniendo datos en formato texto ASCII. -% -%\item \textbf{\textit{clrdevice}:} borra el buffer del instrumento. -% -%\item \textbf{\textit{disp}:} muestra un resumen detallado del objeto creado. -% -%\end{itemize} -% -% -%\subsubsection{SCPI.} -% -%Una gran ventaja a la hora de mandar los comandos de instrucción a cada dispositivo enlazado vía GPIB por medio de las funciones Matlab Instrument Control Toolbox, es que la totalidad de los instrumentos utiliza cadenas de caracteres en formato ASCII para definir los códigos de instrucciones. -% -%La norma SCPI (Standard Commands for Programmable Instruments) aparece en 1991 para conseguir una estandarización de los comandos de control y el formato de los datos de los instrumentos. El objetivo es que, independientemente del fabricante, equipos que tienen la misma funcionalidad respondan de igual forma a un conjunto estándar de comandos. La norma SCPI es el escalón más alto dentro de la jerarquía normativa para el control de sistemas de instrumentación. Tal como se puede ver en la figura I.14, la norma SCPI se asienta sobre la IEEE-488.2 y esta, a su vez, en la IEEE-488.1, Figura \ref{fig:ieee488strc_esquema}. -% -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.9]{capitulo7/busGPIB/estructura_ieee488} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:ieee488strc_esquema} Esquema de control de instrumentos vía GPIB con Matlab.} -%\end{figure} -% -%A pesar de esta jerarquía los comandos y la estructura de datos basados en la norma SCPI pueden usarse, y se usan, en sistemas de instrumentación que no estén basados en IEEE-488, por ejemplo en sistemas basados en VXI, RS-232 o LAN. -% -%La norma SCPI reduce los costes de desarrollo y mantenimiento de programas de control de sistemas de instrumentación para pruebas automáticas. Esto se consigue ya que: -% -%\begin{itemize} -% -%\item Facilita el aprendizaje y uso de los comandos y los datos. -% -%\item Facilita el desarrollo y mantenimiento de los programas. -% -%\item Posibilita la sustitución de equipos con los mínimos cambios de software. -% -%\end{itemize} -% - % -%Los manuales de programación de las instrucciones SCPI, para controlar las funcionalidades de los cuatro instrumentos a través del bus GPIB, se encuentran referenciados en el apéndice. -% -%\begin{itemize} -% -%\item HP 4145B $[$\hyperlink{codesHP4145B.1}{ref}$]$. -% -%\item HP 3478A $[$\hyperlink{codesHP3478A.1}{ref}$]$. -% -%\item KEPCO BOP 50-8 $[$\hyperlink{codesKTH220.1}{ref}$]$. -% -%\item Keithley 220 $[$\hyperlink{codesKEPCO508.1}{ref}$]$. -% -%\end{itemize} -% -% -%\newpage -% -%\section{Puerto serie RS-232.} -% -%Se trata de un antiguo estándar de comunicación serie que se diseñó para la comunicación entre un equipo terminal de datos (DTE), como un computador y un equipo de comunicaciones de datos (DCE), como un módem. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.55]{capitulo7/busRS232/rs_232_logo} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:rs232bus_logo} Estandar RS-232 \cite{WIKIPED}.} -%\end{figure} -% -%Es un enlace de tipo full dúplex y punto a punto. La distancia máxima que abarca sin ningún circuito de ampliación es de aproximadamente 15 m (en la práctica puede llegar a funcionar hasta con distancias de 100 m) y su velocidad típica ronda los 19000 baudios aunque puede ser superior. Este tipo de enlace dispone de unas líneas de datos y unas líneas de control sobre las que se implementa el protocolo de comunicación (ciertas señales presentes en el conector que permiten el bloqueo de la transmisión o la recepción). -% -%La norma básica se ocupa de las especificaciones físicas del conector, los niveles de tensión de las señales y las señales de protocolo. Se suele utilizar un conector de 25 pines. Cuando no son necesarias todas las señales se puede adoptar un conector de 9 pines. Los niveles lógicos 0 y 1 se representan por los niveles físicos de tensión que muestra la Figura \ref{fig:rs232bus_crono}. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.9]{capitulo7/busRS232/rs232_cronogram} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:rs232bus_crono} Cronograma de señales durante comunicación RS-232 \cite{WIKIPED}.} -%\end{figure} -% -%Cualquiera que sea el tipo de transmisión es necesario que el receptor se sincronice para saber en todo momento donde comienza la transmisión de un bit, un carácter o un bloque. Cada carácter va precedido de un bit de inicio (bit de Start) y finaliza con 1 ó 2 bits de parada (bits de Stop), que garantizan la sincronización del receptor y permiten el reconocimiento del comienzo y el final del carácter. -% -%Para el caso del gaussímetro GM08 de Hirst Magnetic, utilizamos una conexión vía este tipo de puerto para comunicarnos. Las especificaciones de configuración del puerto están recogidas en el manual de configuración del instrumento \cite{GM08FIELD}. -% -%\subsection{Protocolo de comunicación con Gaussímetro GM08 vía RS-232.} -% -%En esta sección se pretende dar una idea sobre el protocolo de comunicación empleado con el gaussímetro para configurarlo y obtener valores de campo magnético medidos por su sonda axial o transversal. -% -%Lo primero que hicimos fue conectarlo al PC, siguiendo las indicaciones del fabricante (Figura \ref{fig:datos_para_conex_gm}). -% -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\subfloat[]{\includegraphics[scale=0.8]{capitulo7/busRS232/pines_frabrica_gmo8}} -%\hspace{0.1cm} -%\subfloat[]{\includegraphics[scale=0.8]{capitulo7/busRS232/espec_frabrica_gmo8}} -%\vspace{0.5cm} -%\smallskip -%\caption{\label{fig:datos_para_conex_gm} a) Líneas del bus. b) Especificaciones del puerto.} -%\par\end{centering} -%\end{figure} -% -%Una vez conectado, utilizamos un rastreador de puerto serie para tratar de entender la comunicación controlando el gaussímetro manualmente, en primera instancia. El rastreador de puerto puede verse configurado y listo para iniciar una conexión en la Figura \ref{fig:rastreator_dpuerto}. -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.4]{capitulo7/busRS232/rastreador_puerto} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:rastreator_dpuerto} Rastreador de puerto serie RS-232.} -%\end{figure} -% -%A partir de un estudio analítico de la transferencia de datos por medio del puerto serie y ayudándonos de la librería GM0.dll escrita en C, pudimos realizar un proceso de ingeniería inversa para extraer el protocolo empleado por el dispositivo y el host durante la comunicación. Una breve introducción sobre dicho mecanismo de intercambio de datos se muestra en las siguientes líneas. -% -%El gaussímetro tiene dos modos de funcionamiento bien diferenciados: -% -%\begin{itemize} -% -%\item \textbf{Data Mode:} donde, si la sonda del gaussímetro está conectada, este realiza medidas del campo magnético constantemente, y las manda por el puerto serie, en nuestro caso hasta el PC. Este es en el modo en el que debemos dejar funcionando al instrumento, al terminar de configurar alguna de sus opciones. -% -%\item \textbf{Command Mode:} donde el gaussímetro deja de mandar medidas y espera a que el host le mande un comando para configurar alguna función de medida. Una vez se le manda dicho comando, es necesario devolverlo al \textit{Data Mode}. -% -%\end{itemize} -% -%\smallskip -%\begin{figure}[H]%here -%\noindent \begin{centering} -%\includegraphics[scale=0.9]{capitulo7/busRS232/diagrama_sec_gmo8} -%\par\end{centering} -%\smallskip -%\caption{\label{fig:diagram_mensajes_gausim} Diagrama de flujo de mensajes PC-GM08.} -%\end{figure} -% -%El dispositivo GM08 posee un byte de estado o \textit{Status Byte} que suele utilizarse para describir en qué situación se encuentra el dispositivo o para detectar errores en la comunicación. El gaussímetro siempre contesta con su \textit{Status Byte} después de recibir cualquier dato proveniente del host, de tal manera que no se le puede enviar ningún comando sin haber recibido previamente su \textit{Status Byte}. -% -%En la Figura \ref{fig:diagram_mensajes_gausim}, hemos incluimos un diagrama de flujo de mensajes entre el PC y el gaussímetro donde se ejemplifican las transiciones entre ambos modos de funcionamiento. -% -%A través de la librería GM0.dll extrajimos la totalidad de comandos admitidos por el gaussímetro, a fin de elaborar nuestra propia librería empleando funciones propias de matlab para el control de comunicación sobre este puerto. -% -%Para finalizar este tema, hacemos un breve nombramiento del conjunto de funciones más representativas utilizadas en matlab para configurar la librería de control de comunicación del GM08: -% -%\begin{itemize} -% -%\item \textbf{\textit{serial}:} permite crear objetos de tipo \textit{serial port object} indicándole las propiedades como los baudios de conexión, bits de datos, bits de paridad, etc. -% -%\item \textbf{\textit{fopen}:} una vez se ha creado el objeto de tipo \textit{serial port object}, se crea la conexión entre el objeto de la interfaz RS-232 y el instrumento. -% -%\item \textbf{\textit{fclose}:} cierra la conexión entre el objeto de la interfaz RS-232 creado y el instrumento en cuestión. -% -%\item \textbf{\textit{fwrite}:} escribe datos de tipo binario en el instrumento. -% -%\item \textbf{\textit{fread}:} permite leer datos binarios del buffer del instrumento, pudiéndose especificar la cantidad de valores a leer. -% -%\end{itemize} -% +\section{Conclusión} -%\newpage -%\cleardoublepage \ No newline at end of file +Es curioso darse cuenta de cómo las cosas llegan cuando menos te lo esperas. Y así ocurrió, en mi primer año de universidad (curso 2008-2009), durante una clase de prácticas de Fundamentos Tecnológicos de los Computadores, cuando el profesor D. Andrés Roldán me propuso un proyecto basado en su idea original de que una máquina tocara el órgano. Un proyecto que no podría encajar mejor con mis dos mayores pasiones: la Informática y la Música, ya que estudié Piano en el conservatorio y formé un grupo musical hace algunos años. + +Siempre resulta emocionante partir de una idea y un papel en blanco, y ser consciente de cómo evoluciona hasta hacerse realidad. Por fortuna, esta carrera es una de las en que el propio ingeniero puede avanzar más allá del diseño y darse la satisfacción de verlo funcionando. + +Hemos conseguido, no solo diseñar el sistema, sino también llegar a hacer funcionar un \textbf{prototipo}, que demuestra que el diseño es válido. Por parte de Mikel, la \textbf{mecánica} ha sido diseñada, pero no ha sido posible llevarla a cabo debido a los altos \textbf{costes} que conlleva. + +Ha sido, además, un proyecto que ha abarcado \textbf{un poco de cada rama} de la informática: electrónica, bases de datos, sistemas operativos, ingeniería del software, programación concurrente, lenguajes informáticos, algorítmica, seguridad informática, redes y sistemas empotrados. Esto me ha permitido \textbf{desplegar al máximo} mis habilidades y desarrollar \textbf{nuevas capacidades}, como diseño en 3D o programación para la \textit{web}. + +La \textbf{interfaz de usuario} obtenida es simple pero cubre completamente las necesidades básicas. Queda pendiente un estudio de mercado y una entrevista con el usuario final para poder ofrecer una \textbf{aplicación completa}. Con la esperanza de que esto suceda, el diseño ha sido \textbf{modular} y la implementación es limpia y está lo suficientemente bien \textbf{documentada} como para poder ampliarla sin problemas. + +No ha sido un trabajo sencillo, pero cada minuto que hemos dedicado ha merecido la pena, máxime al fusionar los dos proyectos hermanos y lograr dar vida al \textit{hardware} de la \acrshort{PCB}. Me siento honestamente satisfecho del trabajo realizado, y tanto mi compañero Mikel como yo estamos animados a continuar esta línea de desarrollo. + +Reitero mi agradecimiento a mi compañero, a mis tutores, y a todos los que nos han ayudado a llevar este proyecto adelante. + +\newpage + +\section{Vistas al futuro} + +Refiriéndonos al objetivo completo, como hicimos en un principio, hemos alcanzado un alto nivel de desarrollo en cuanto al \textit{software} y la \textit{electrónica} del sistema, dejando pendiente la implantación de la \textbf{mecánica}. + +Como músico y como ingeniero puedo asegurar que este invento \textbf{no pretende sustituir} a ningún organista. Estamos convencidos de que el proyecto puede resultar interesante en iglesias con horarios amplios de visitas, o aquellas en las que no suela haber un organista. + +Como todo proyecto vivo, siempre surgen tareas e \textbf{ideas nuevas}, algunas de ellas se pueden aplicar inmediatamente, otras deben esperar un tiempo, tal vez a una \textbf{nueva iteración} del desarrollo. Los \textbf{pasos siguientes} para una nueva versión podrían ser: + +\begin{enumerate} + \item Crear una interfaz específica para \textbf{dispositivos móviles}. + \item Dar al usuario \textbf{mayor control sobre el mando}, contemplar que tengamos varios transmisores, con distinto número de botones, y permitir asignar tanto listas como acciones sobre el reproductor. + \item Añadir el control de \textbf{energía del órgano} al sistema, permitiendo encenderlo y apagarlo remotamente. + \item Especificar la \textbf{correspondencia} entre notas musicales y \textbf{registros}, para obtener nuestra propia asignación. + \item Replantear la compatibilidad con \acrshort{MIDI} y estudiar la posibilidad de producir \textbf{partituras exclusivas}, abriendo una posible vía de \textbf{ingresos económicos}. +\end{enumerate} + +Como paso previo, es necesario \textbf{presupuestar} el desarrollo, hacer un \textbf{estudio de mercado} para conocer la viabilidad comercial del proyecto y \textbf{rentabilizar} todo el proceso, pues las próximas tareas que tenemos que llevar a cabo suponen un \textbf{alto coste} económico. + +\newpage +\clearpage{\pagestyle{empty}\cleardoublepage} \ No newline at end of file diff --git a/report/subdocs/glosario.tex b/report/subdocs/glosario.tex index a1d0b2b..07c5a00 100644 --- a/report/subdocs/glosario.tex +++ b/report/subdocs/glosario.tex @@ -1,10 +1,10 @@ -\chapter*{Abreviaturas y siglas}% +%\chapter*{Abreviaturas y siglas}% \fancyhead{} \fancyhead[RO]{\small{\nouppercase{Abreviaturas y siglas}}} \fancyhead[LE]{\small{\nouppercase{Abreviaturas y siglas}}}% %\printglossary[type=acronym,title=Acrónimos y siglas,toctitle=Acrónimos y siglas] \printglossary[style=long3col,type=\acronymtype,title=Acrónimos,toctitle=Acrónimos] -\clearpage{\pagestyle{plain}\cleardoublepage}% +\clearpage{\pagestyle{empty}\cleardoublepage}% @@ -31,7 +31,7 @@ \chapter*{Abreviaturas y siglas}% \phantomsection \label{ListadoSimbolos} %END ---- Para que funcione bien el TOC en PDF -\printglossary[style=long3col,type=symbols,title=Listado de Símbolos,toctitle=Listado de Símbolos] +\printglossary[style=long3col,type=symbols,title=Listado de Sí­mbolos,toctitle=Listado de Símbolos] %\addcontentsline{toc}{chapter}{Símbolos} %Índice Alfabético de apariciones diff --git a/report/subdocs/portada.tex b/report/subdocs/portada.tex index a843d5e..337a68f 100644 --- a/report/subdocs/portada.tex +++ b/report/subdocs/portada.tex @@ -15,7 +15,7 @@ \thispagestyle{empty} \begin{center} -\textbf{\huge \includegraphics[scale=0.8]{logo_ugr.png}} +\textbf{\huge \includegraphics[scale=0.2]{logo_ugr}} \par\end{center}{\huge \par} \begin{center} @@ -60,7 +60,7 @@ \thispagestyle{empty} \begin{center} -\includegraphics[scale=0.8]{logo_ugr.png} +\includegraphics[scale=0.2]{logo_ugr} \par\end{center} \begin{center} @@ -92,15 +92,18 @@ \par\end{center} \begin{center} -\textbf{Andrés María Roldán Aranda} +\textbf{Andrés María Roldán Aranda} \\ +Y \\ +\textbf{María Isabel García Arenas} \par\end{center} \begin{center} -DEPARTAMENTO: +DEPARTAMENTOS: \par\end{center} \begin{center} -\textbf{Electrónica y Tecnología de los Computadores} +\textbf{Electrónica y Tecnología de Computadores} \\ +\textbf{Arquitectura y Tecnología de Computadores} \par\end{center} \begin{center} @@ -178,56 +181,13 @@ %\newpage %\thispagestyle{empty} -\begin{itemize} - \item [] -\end{itemize} - - -\newpage -\includepdf[pages=-,link=true,linkname=hojaEvaluacionesUGR]{anexoIV_actaPFC} - \newpage \thispagestyle{empty} -%Begin ---- Para que funcione bien el TOC en PDF -\cleardoublepage -\thispagestyle{empty} \phantomsection \addcontentsline{toc}{chapter}{Autorización Lectura} -\noindent D. Andrés María Roldán Aranda, Profesor del departamento -de Electrónica y Tecnología de los Computadores de la Universidad -de Granada, como director del Proyecto Fin de Carrera de D. Víctor Manuel Fernández Castro, - -\vspace*{1cm} - -Informa: - -\begin{doublespace} -que el presente trabajo, titulado: -\end{doublespace} - -\begin{doublespace} -\begin{center} -\textbf{\emph{\large {}``Interpretación remota de partituras sobre instrumentos de viento''}} -\par\end{center}{\large \par} -\end{doublespace} - -\noindent ha sido realizado y redactado por el mencionado alumno bajo -nuestra dirección, y con esta fecha autorizo a su presentación. - -\vspace*{1cm} - -\begin{center} -%Granada, a 06 de Julio de 2012 -Granada, a ~~~~~~ de Junio de 2015 -\par\end{center} - -\bigskip%%%%%%%o -\bigskip%%%%%%%o -\begin{doublespace} -\hspace{4cm}Fdo. -\end{doublespace} +\includepdf[pages=-]{anexos/autorizacion_tutor} \newpage \thispagestyle{empty} @@ -253,8 +213,7 @@ \vspace*{1cm} \begin{center} -%Granada, a 06 de Julio de 2012 -Granada, a ~~~~~~ de Agosto de 2015 +Granada, a ~~~~~~ de septiembre de 2015. \par\end{center} \bigskip%%%%%%%o @@ -348,6 +307,7 @@ \textbf{\emph{\large Mi familia y mis amigos. Por estar siempre ahí.}} \par\end{center}{\large \par} \end{quotation} + \newpage \thispagestyle{empty}