Arduino y Pure Data. Ondas: Color y Sonido - V1 MÓDULO 1: INTRODUCCIÓN Unos conceptos básicos para comenzar Programación en general: el mundo de los algoritmos ¿Qué es un Algoritmo? Un algoritmo es un conjunto de instrucciones estructuradas que tienen como objetivo resolver un problema. Los algoritmos están presentes en nuestra vida cotidiana en multiples campos, desde una receta de cocina que nos indica que ingredientes necesitamos, en que orden y como debemos prepararlos para obtener el plato deseado; pasando por las instrucciones de montage de un LEGO o un mueble de IKEA; una partitura musical, que indica que notas tocar para reproducir una determinada pieza o una guía de color, que nos dice, que tenemos que mezclar azul y amarillo para obtener verde. Estas instrucciones o algoritmos pueden representarse/implementarse utilizando diferentes lenguajes y estructuras (códigos de representación). Por ejemplo: - Mezclando azul y amarillo obtendremos verde. Si a ese verde le añadimos blanco sera verde claro, pero si le añadimos negro sera verde oscuro.                                                +blanco = verde claro - Azul + Amarillo = Verde  <                                                +negro = verde oscuro                               + [  ] = [  ] - [  ] + [  ] = [  ]  <                               + [  ] = [  ] En computación, los programas son algoritmos escritos en un lenguaje especifico y comprensible para la máquina, ya que, es la maquina la que tiene que realizar esas acciones. Al igual que en el ejemplo anterior, en el que hemos escrito con tres códigos de representación diferentes el algoritmo que resuelve el problema '¿cómo crear color verde?', en la programación pasa igual, y existen múltiples estructuras, lenguajes y entornos, que nos permitirán implementar el algoritmo que solucione nuestro problema. Es muy importante tener siempre en mente que EN PROGRAMACIÓN NO HAY UN SOLO CAMINO CORRECTO :) Programar es un proceso creativo y constructivo, en el que, de diferentes formas, se pueden obtener resultados equivalentes. Aunque siempre podrá haber diferencias en los costes, tanto de tiempo como de memoria. Existen muchos lenguajes de programación diferentes y aunque unos y otros frecuentemente tienen elementos en común, cada lenguaje se rige por sus reglas específicas. Esto implica que un comando o elemento que funciona en un lenguaje puede no funcionar en otro, o funcionar de otra manera; por lo que tendremos que conocer y tener en cuenta, en cada caso, los códigos de representación del lenguaje y el entorno en el que estemos programando. Ejemplo de cómo imprimir en 4 lenguajes diferentes la misma frase "Hello World": Figura 1. "Hello World" en cuatro lenguajes diferentes (C, C++, Java, Python) Ejercicio 1 : Busca 2 ejemplos de algoritmos en tu vida cotidiana y represéntalos con dos códigos diferentes. ¿Qué es la programación? La programación informática, se refiere al proceso de construcción de estos grupos de instrucciones, para que sean procesadas por un ordenador o microcontrolador. La programación, se basa en flujos de datos que se almacenan, comprueban y transforman de manera estructurada. En un sistema computacional vamos a tener elementos de dos tipos: el software, que es la parte inmaterial, y el hardware, que es la parte material.  El software, son los componentes lógicos ("Software", 2022), las instrucciones o algoritmos, es decir, los programas que serán seguidos por el hardware. El hardware, son los componentes físicos que constituyen el ordenador/computadora (disco duro, tarjeta gráfica, pantalla, ratón, altavoz, cámara ...). El software, le dice al ordenador lo que tiene que hacer, para lograr el resultado deseado. El software es el ADN de la máquina. No obstante, pese a que esta distinción está ampliamente extendida, en realidad, no está tan claro dónde debe situarse la línea que establece la diferencia entre hardware y software. Lo que sí está claro es que esta combinación de hardware y software constituye el sistema, es decir, la infraestructura que permitirá que los datos introducidos en un programa, a los que se conocen como inputs/inlets/entrada, sean procesados, es decir, que sean comprobados, leídos, almacenados, modificados. El resultado que este programa proporciona se conoce como output/outlet/salida. Esta terminología y estructura (entrada -> proceso -> salida), se aplica también, a los procesos internos de los programas, ya que, un programa está constituido por otros programas, que son, multiples procesos conectados e interrelacionados. Esta idea de entrada y salida de datos, nos va a acompañar durante todo el curso, ya que, en nuestros proyectos vamos a trabajar con un conjunto de datos de entrada, que nos permitirán obtener un resultado o salida. Generalmente, todo proceso tiene una entrada de datos (input), un procesamiento, durante el cual se realizan acciones con esos datos, y una salida de datos(output) que es el resultado del proceso. Programar es la acción de construir esos programas para ordenador (Scratch, 2022). Para explicar y hacer más comprensible cómo funcionan los algoritmos, suelen emplearse metáforas. Así, es posible establecer similitudes entre algo tan abstracto, como es la programación, con procesos que nos resultan más familiares. Vamos a tomar como metáfora los sistemas hidrográficos: ríos, arroyos, pozos, lagos, meandros, y las infraestructuras que el ser humano introduce en estos sistemas fluviales para modificar el curso y estado del agua: presas, centrales hidroeléctricas, sistemas de canalización para el riego, acueductos o simples marcas en la pared de un canal, para medir el nivel del agua y obtener información acerca del crecimiento de los ríos. Figura 2. Mapa de embalses de la cuenca del Ebro. Por ejemplo: En Zaragoza el nivel del agua del rio se mide una vez (Proceso 0: contar) todos los días (Proceso 1: comparar) y se apunta en una libreta (Proceso 2: almacenar). Este nivel, ha de ser siempre superior a 50 (Proceso 3: comparar). Cuando el nivel de agua en Zaragoza, desciende por debajo de 50, se avisará al embalse (Proceso 4.1.1: enviar información) para que deje salir más agua (Proceso 4.1.2: cambiar), si el nivel de agua no ha bajado por debajo de 50, no se avisara al embalse y el agua que deja salir este, seguirá siendo la misma (Proceso 4.2: no cambiar). Nombre descriptivo de este programa: Comprobación del estado del agua en Zaragoza, y estado del embalse en función de esa comprobación. El agua de este sistema hidrográfico va a ser los datos. Y las infraestructuras introducidas por el ser humano para controlar estas aguas van a ser los programas que procesaran estos datos. De esta manera, iremos encadenando procesos por los que los datos pasan para conseguir nuestro objetivo. Ejercicio 2: Identifica y etiqueta los diferentes procesos que conforman los algoritmos que has elegido para el ejercicio 1. Por etiqueta, nos referimos a que clasifiques estos procesos como en el ejemplo anterior, en función del tipo de acción que se realiza en cada proceso, utilizando categorías como comparar, almacenar o cualquier otra que se te ocurra. Figura 3. Un gráfico de un lenguaje de programación visual llamado "Bolt" en funcionamiento. En la Figura 3. podemos ver un ejemplo animado de programación gráfica, que visualmente, se asemeja al mapa de la cuenca hidrográfica del Ebro de la Figura 2. Vemos cajitas conectadas por unas líneas, a través de las cuales, unas bolitas se desplazan de una caja a otra. Cada una de las cajitas representa un proceso, y las bolitas son los datos que entran por la parte izquierda de una cajita, en la cajita son procesados, y salen por la parte derecha en dirección a otra cajita. La dirección del desplazamiento de las bolitas, indica la dirección de los datos a través de estos procesos, que en este caso fluyen de izquierda a derecha, y es en este orden en el que se procesan. Figura 4. Detalle de la figura 3. que muestra un mismo outlet puede alimentar los inlets de varios procesos (el mismo outlet de Time hace de input para Select, Add y Add) y un proceso puede tener varios inlets (Select tiene 3 inlets). Vemos que la salida de una sola cajita, puede estar conectada con las entradas de varias cajitas, ya que, el mismo resultado de un proceso puede alimentar varios procesos (Cajita Time). Y que, un proceso puede tener varios datos de entrada diferentes, que proceden de diferentes procesos previos (Cajita Select). Figura 5. Detalle de la figura 3. que muestra que un proceso puede tener varios outlets. Y aunque en la Figura 5, no haya ninguna cajita con más de una de sus salidas conectadas a otras cajitas, vemos que una cajita o un proceso, pueden tener varias salidas diferentes (Cajitas "Expose Color" y "Material Set Color"). Cada salida, sera el resultado de un proceso distinto, llevado a cabo con los mismos datos de entrada. Recordar, que cada lenguaje y entorno, tienen sus normas y por lo tanto el ejemplo de las Figuras 3, 4 y 5 también. Diferencia entre datos e información Un dato es una representación simbólica (numérica, alfabética, algorítmica, espacial, etc.) de un atributo o variable cuantitativa o cualitativa ("Dato", 2022), o sea: la descripción codificada de un hecho empírico, un suceso, una entidad (Equipo editorial, Etecé, 2021). Para que los datos tengan sentido para nosotros, han de ser puestos en contexto, por si solos no significan nada. Ejemplo de datos: (19,25), (2022), (54.3, 56.2, 54.1, 49.6, 52.9, 53.2, 52.6), (L, M, X, J, V, S, D), (septiembre) (20,26), (2021), (56.1, 58.3, 59.2, 55.8, 54.7, 54.6, 55.5), (L, M, X, J, V, S, D), (septiembre) Arriba vemos varias listas de números y caracteres, son un conjunto de datos, pero somos incapaces de saber qué representan. Poner estos datos en contexto con otros datos: relacionarlos, compararlos, en definitiva, procesarlos; nos permite entender, que relación existe entre los datos y los hechos, sucesos o entidades que representan. Al resultado comprensible del procesamiento y contextualización de datos es a lo que llamamos información. Ejemplo de información: Nivel del agua del río Ebro en Zaragoza en la semana del 19 al 25 de septiembre de 2022 fue: lunes 19: 54.3 cm; martes 20: 56.2 cm; miércoles 21: 54.1 cm; jueves 22: 49.6 cm; viernes 23: 52.9 cm; sábado 24: 53.2 cm; domingo 25: 52.6 cm Nivel del agua del río Ebro en Zaragoza en la semana del 20 al 26 de septiembre de 2021 fue: lunes 20: 56.1 cm; martes 21: 58.3 cm; miércoles 22: 59.2 cm; jueves 23: 55.8 cm; viernes 24: 54.7 cm; sábado 25: 54.6 dm; domingo 26: 55.5 cm Tipos de datos Numérico Entero: Tipo de dato formado por una variable numérica que no cuenta con parte decimal ("Dato", 2020). En programación, vamos a conocer este tipo de dato como int (integer) Ejemplo int: dia del mes = 22 Real: Tipo de dato formado por una variable numérica que puede contar con parte decimal ("Dato", 2020). En programación, vamos a conocer este tipo de dato como float Ejemplo float: altura del agua = 49.6 Una variable de tipo float, siempre va a poder representar números enteros y decimales, sin embargo, una variable de tipo int, solo podrá representar números enteros. Texto Caracter: Tipo de dato formado por una unidad o símbolo que puede ser una letra, un número, una mayúscula o un signo de puntuación. En programación, vamos a conocer este tipo de dato como char (character). Ejemplo char:  dia de la semana = J Cadena: Tipo de dato formado por un conjunto de caracteres dispuestos de forma consecutiva que se representa entre comillas. En programación, vamos a conocer este tipo de dato como string. Ejemplo string:  nombre del mes del año = "septiembre" Una variable de tipo texto, tanto carácter como cadena, también puede representar números enteros y decimales, sin embargo estos serán entendidos por el programa como datos textuales, no como datos numéricos. Lógico Boolean: Tipo de dato que puede representar dos valores: verdadero o falso. Ejemplo boolean:  El jueves 22 de 2022 el nivel del agua del rio Ebro en Zaragoza supera los 50 cm = Falso Ejercicio 3: Identifica y separa los datos de la información que has incluido en los algoritmos que has elegido para el ejercicio 1. Una vez tengas los datos separados, indica que tipo de datos son en tu algoritmo. Figuras: Figura 1: Tomada de "Hello World in Python | Python Program to Print Hello World" por FACE prep https://dev.faceprep.in/python/hello-world-in-python/ Figura 2: Tomada de "Mapas Temáticos" por Confederación Hidrográfica del Ebro https://www.chebro.es/ca/mapas-tematicos Figura 3: Tomada de "Visualize that! Behind the scenes with Bolt for Visual Scripting" por Unity bloghttps://blog.unity.com/games/visualize-that-behind-the-scenes-with-bolt-for-visual-scripting Figura 4: Tomada y recortada de "Visualize that! Behind the scenes with Bolt for Visual Scripting" por Unity bloghttps://blog.unity.com/games/visualize-that-behind-the-scenes-with-bolt-for-visual-scripting Figura 5: Tomada y recortada de "Visualize that! Behind the scenes with Bolt for Visual Scripting" por Unity bloghttps://blog.unity.com/games/visualize-that-behind-the-scenes-with-bolt-for-visual-scripting Referencias: Dato. (2020, octubre 1). Equipo editorial, Etecé (Ed.),  En Enciclopedia Concepto. Consultado el 19 septiembre 2022 en https://concepto.de/dato/ Dato. (2022, Septienbre 2) En Wikipedia. https://es.wikipedia.org/wiki/Dato Dato en informática. (2021, agosto 5). Equipo editorial, Etecé (Ed.), En Enciclopedia Concepto. Consultado el 19 septiembre 2022 en https://concepto.de/dato-en-informatica/ Pure Data (2022). Pure Data home. [Website/Pagina web] Pure Data. Consultado el 16 Agosto 2022 en http://puredata.info/ Scratch (n.d). Programming. Scratch wiki. Retrieved August 17, 2022 https://en.scratch-wiki.info/wiki/Programming Software. (2022, Agosto 15). In Wikipedia. https://es.wikipedia.org/wiki/Software Práctica 0: Programación Textual y Programación Visual En este curso está claro que vamos a tener que programar, pero primero vamos a ver qué dos tipos distintos de programación emplearemos: la programación textual y la programación visual. Algo común a ambas tipologías es que la estructura de estos programas suele representarse con lo que se conoce como diagrama de flujo. Con él, es posible representar los diferentes caminos que puede tomar nuestro algoritmo dependiendo de que se cumplan o no las condiciones que incluyamos. Cuando queramos crear un programa, nos va ser muy útil para definir su estructura, realizar un diagrama de flujo antes de empezar a programar en el ordenador. Podemos hacerlo con papel y boli. En él vamos representar con el lenguaje que queramos, ya que somos nosotros quienes lo vamos a leer, todos los pasos  necesarios para resolver nuestro problema y cómo los resultados de estos pasos se conectan con otros procesos. Figura 1. Estructura de un diagrama de flujo. Elementos del diagrama de flujo Un diagrama de flujo está formado fundamentalmente por los siguientes elementos: Línea o flechas del flujo: Indica la instrucción que se va a realizar, o la dirección del flujo del proceso. Muestra el carácter secuencial del programa. Terminal o inicio y final: Es la forma en la cual se indica el “inicio del proceso” y “final del proceso”. Su icono suele ser un rectángulo con las esquinas redondeadas. Asignación/ definición: Permite asignar un valor o definir una variable, donde se almacenan los datos que se necesitan para resolver el problema. Suele representarse con un rectángulo. Datos de entrada: Indica la recepción de datos en la entrada. Se representa con un recuadro con las esquinas inclinadas y una flecha hacia dentro. Datos de salida: Indica la impresión de datos en la salida. Se representa con un recuadro con las esquinas inclinadas y una flecha hacia fuera. Decisión: Indica que desde el punto en que nos encontramos, puede haber más de un camino para seguir, según la condición dada. En este caso se usa un rombo. Otros: Como algunos tipos de bucles, los iremos viendo más adelante. Vamos a hacer un diagrama de flujo del ejemplo que vimos en Programación en genera... | Librería CATEDU en el que había que controlar el nivel del agua del Ebro en Zaragoza: Figura 2. Diagrama de flujo del control del nivel del agua del río Ebro en Zaragoza. Práctica 0: Diagramas de flujo de nuestros algoritmos Ejercicio 4: Crea los diagramas de flujo correspondientes a los algoritmos que has hecho en los ejercicios del capítulo anterior. Utiliza una cajita para representar cada proceso. Incluye un proceso condicional en al menos uno de los diagramas. Si no queréis utilizar papel y boli podéis utilizar esta herramienta para crear tus diagramas: diagrams.net¿Qué tenemos que entregar? ¿Qué tenemos que entregar? El ejercicio 4. Sube a la carpeta del Moodle de la Practica 0 una captura de pantalla o foto de los diagramas que has creado. Los archivos deberán llamarse: Practica0_nombre_apellido_1 , Practica0_nombre_apellido_2 Si utilizáis PseInt para crear los diagramas incluir junto con el diagrama una captura del código. Programación textual Una definición sencilla de este tipo de programación nos viene dada en el propio concepto que queremos definir: programación basada en texto. Para programar de esta manera es necesario que escribamos las palabras, como si componemos un texto literario, solo que la sintaxis y la gramática van a ser distintas... bastante distintas en algunos casos. Para empezar, casi todos los lenguajes de programación están basado en el inglés. Así que, tener unas nociones de inglés nos va a venir de maravilla si queremos tener las cosas algo más fáciles cuando empezamos a programar. Si no, siempre podemos buscar el significado de esas palabras y las iremos aprendiendo. Muchos de los ejemplos y de la información que nos encontraremos en internet también estarán en inglés, aunque existen hispanohablantes que también comparten sus proyectos en español. Volviendo a la programación textual en sí, hay que mencionar que esta surgió antes que la visual, pero no vamos a entrar aquí a trazar una historia de los lenguajes de programación... Vamos a pasar a citar algunos ejemplos de programación textual dentro del mundo del arte y la educación. Arduino Este lenguaje de programación está basado en C++, que a su vez está basado en C. Y es que, aunque existen miles de lenguajes de programación, muchos de ellos están en lenguajes preexistentes, con algunas modificaciones que los mejoran para determinados usos. Sobre todo aquellos creados en el área de la educación y el arte, ya que tratan de simplificar estructuras y procesos. Processing Basado en Java, este lenguaje de programación se creó originalmente para facilitar que los artistas y diseñadores pudiesen crear con facilidad imágenes bastante potentes visualmente generadas por ordenador y en movimiento, e incluso añadirles interactividad. Desde hace más de 20 años la comunidad de Processing ha ido creciendo y se mantiene como un lenguaje de referencia a la hora de enseñar a programar dentro del mundo del arte y el diseño. Aquí puedes ver algunos ejemplos. p5.js Este lenguaje es el que más recientemente ha surgido de los tres. Está basado en Javascript y la diferencia que presenta frente a los tres es que se diseñó para ser ejecutado directamente en el navegador, de ahí que está basado en Javascript. Como puedes leer en su página web, surgió como una adaptación de Processing para la web, por lo que su propósito principal es facilitar la creación de elementos visuales interactivos a artistas, diseñadores, educadores, etc.  En la siguiente captura puedes ver el área de trabajo y si conoces Processing te darás cuanta de que ambas son muy similares: Figura 3. Imagen de un programa de p5. Programación visual ¿Qué es? Figura 4. Programa en un lenguaje de programación visual llamado "Bolt" en funcionamiento. La programación grafica (VPL Visual programing languages) nos permite crear estas estructuras para comprobar y transformar datos de manera visual en 2D (dos dimensiones) o incluso 3D (tres dimensiones). Frecuentemente en este lenguaje de programación nos vamos a encontrar con cajitas o formas que vamos a poder conectar unas con otras. Cada cajita o forma va a realizar una función muy específica. Por ejemplo una cajita que detecta cuando pulsamos la tecla "A". Es la combinación de estas cajitas sencillas lo que nos va a permitir crear estructuras que realicen tareas más complejas, por ejemplo, enviar un mensaje cuando el ratón hace click en un elemento determinado. Las cajitas por lo general van a tener entradas y salidas. Por esas entradas, llamadas también inlets o inputs, llegarán datos a la cajita, en la cajita se procesarán esos datos y a traves de sus salidas, llamadas también outlets u outputs, se enviarán los datos resultantes del proceso que ha realizado la cajita. Por ejemplo, la cajita exprimidor saca por su salida zumo de limon cuando entran 4 limones, si en vez de limones entran 3 naranjas sacara por su salida zumo de naranja. ¿Cuál es el proceso que realiza la cajita exprimidor? Exprimir. ¿Cuál es el inlet? Cítricos. ¿Cuál es el outlet? Zumo. Figura 5. La cajita exprimidor. Vamos a ver algunos ejemplos de lenguajes de programación visual de diferentes épocas (Nakashima, 2018): Pygmalion (1975) Uno de los primeros intentos de mejorar los procesos de programación. Fijándose en cómo se comunicaban y como pensaban las personas, se desarrolla con el objetivo de construir un entorno que facilitara la comunicación y estimulara el pensamiento creativo (Instadeq Blog, 2022). Figura 6. Imagen del programa Pygmalion. ¿Algunos de estos lenguajes de programación visual se parecen un poco a los diagramas de flujo, ¿no? Agentsheets (1983) Si, la programación visual puede parecer el mapa de un videojuego, y utilizar representaciones puramente visuales como veis en la figura X. Figura 7. Imagen del programa Agentsheets. Scratch Es un lenguaje desarrollado por el MIT Media Lab en 2002 creado para niños. https://scratch.mit.edu/ Figura 8. Hello world (Hola Mundo) en el lenguaje de programación visual "Scratch". vvvv Creado para facilitar el desarrollo en grandes entornos multimedia, destaca su capacidad para generar gráficos en tiempo real. https://vvvv.org/ Cuando decimos que un programa trabaja en tiempo real quiere decir que el resultado que ofrece el programa se está procesando en este mismo instante. A medida que se van procesando los datos se va emitiendo el resultado de ese proceso. Figura 9. patch en vvvv (izquierda) y el resultado visual de ese patch (derecha). Blender En Blender, que es uno de los programas de 3D más potentes, podemos por ejemplo crear materiales utilizando un sistema de nodos, que es programación visual. https://www.blender.org/ Figura 10. Edición de materiales en Blender utilizando programación visual. Pure Data Pd es un entorno de código abierto de programación gráfica en tiempo real para audio, video y procesamiento gráfico (imágenes) (Pure Data, 2022). ¡Este va a ser el programa que aprenderemos en este taller! https://puredata.info/ Figura 11. Imagen de un programa en Pure Data. Referencias: Instadeq Blog: No-code Data Analysis & Interactive Visualizations (2022, febrero 21) No-code History: Pygmalion (1975). https://instadeq.com/blog/posts/no-code-history-pygmalion-1975/ Nakashima, E. (2018, May 12-13) Whoa, pictures! A visual history of visual programming languages! [Conference session] !!Con 2018, New York, United States. https://www.youtube.com/watch?v=mU1aPvvQbqk Pure Data (2022). Pure Data home. Pure Data. Consultado el 16 Agosto 2022 de http://puredata.info/ Programación textual: https://formacion.intef.es/catalogo/mod/book/view.php?id=69&chapterid=330p5.js: https://p5js.org/es/Processing: https://processing.org/Elementos del diagrama de flujo: https://libros.catedu.es/books/fundamentos-de-programacion-estructurada-con-pseint-y-scratch/page/diagramas-de-flujo Figuras: Figura 1. Estructura de un diagrama de flujo. https://c.pxhere.com/photos/cc/97/mark_marker_hand_leave_production_planning_control_organizational_structure_work_process-774947.jpg!d Figura 2. Diagrama de flujo del control del nivel del agua del río Ebro en Zaragoza. Figura 3. Imagen de un programa de p5.js.: https://editor.p5js.org/ Figura 4. Programa en un lenguaje de programación visual llamado "Bolt" en funcionamiento. bloghttps://blog.unity.com/games/visualize-that-behind-the-scenes-with-bolt-for-visual-scripting Figura 5. La cajita exprimidor. https://giphy.com/gifs/hulu-snl-saturday-night-live-nbc-3o7TKPdUkkbCAVqWk0 Figura 6. Imagen del programa Pygmalion. https://danhalbert.org/pbe-html.htm Figura 7. Imagen del programa Agentsheets. https://www.researchgate.net/figure/AgentSheets-Graphical-Rewrite-Rule-Double-clicking-an-agent-would-create-a-local-copy-of_fig13_320445800 Figura 8. Hello world (Hola Mundo) en el lenguaje de programación visual "Scratch". https://anthsperanza.com/2018/05/01/scratch-educator-guide/ Figura 9. patch en vvvv (izquierda) y el resultado visual de ese patch (derecha). https://i.ytimg.com/vi/XTVBdWnsxk0/maxresdefault.jpg Figura 10. Edición de materiales en Blender utilizando programación visual. https://forum.sketchfab.com/uploads/db4890/original/3X/c/e/ceda7cef9f1de189fc38901b360916dd8ae182f4.gif Figura 11. Imagen de un programa en Pure Data. https://blog.bela.io/images/mct-masters-part-1/hyperguitar_pitch.gif Elementos que debemos conocer Antes de comenzar a programar, es importante que conozcamos una serie de elementos que nos van a acompañar durante este curso. Ahora puede abrumarnos y parecernos mucha información, pero este apartado y el siguiente que trata sobre estructuras está pensado para que puedas volver a consultarlo a lo largo del curso. 1. Comentarios... En algunos de nuestros algoritmos/programas, puede que se vea muy claro qué hace cada parte, pero en otras ocasiones no es tan fácil saberlo. Por ello, los comentarios van a ayudar a que otros programadores que tengan acceso a nuestro código puedan comprenderlo más fácilmente, e incluso nosotros mismos. Imagina que has escrito un algoritmo en 2007, te olvidas de él y lo vuelves a abrir en 2032. Probablemente, en un primer momento no sepas de qué va, ni para qué lo escribiste, pero si en 2007 escribiste comentarios, te habrá ahorrado mucho tiempo al abrirlo 25 años después. Estos comentarios contienen información dirigida a las personas, son notas que tomaréis para vosotros mismos relacionadas con el funcionamiento del programa que estéis construyendo, o notas para facilitar a otras personas la comprensión del algoritmo que habéis creado. Son muy útiles para escribir recordatorios o explicaciones durante el proceso de trabajo y para etiquetar las diferentes partes de las estructuras que hagáis. ...en Arduino Vamos a echarle un vistazo a la siguiente imagen: Figura 1. Imagen de un sketch de Arduino Esto es lo primero que veremos cuando tengamos instalado Arduino. Por defecto, al abrir la aplicación aparecen ciertas palabras escritas. En azul y verde vemos void setup() y void loop(). De ambas nos ocuparemos en el siguiente apartado sobre funciones. Ahora, lo que nos interesa son las líneas que aparecen // entre los corchetes de ambas funciones. ¿Qué es importante aquí? Que esas indicaciones no van destinadas a nuestro ordenador, sino al programador. Se trata de comentarios. Cuando nuestros comentarios solamente ocupen una línea los escribiremos tras //. Como puedes comprobar, su color es gris claro, eso nos indica que Arduino hará caso omiso de ellos. Habrá momentos en los que necesitemos escribir comentarios más extensos y para ellos los escribiremos entre  /**/. Ejemplo: /*Esto es un comentarioque ocupa más de una línea. */ ...en Pure Data En Pure data vamos a tener cajitas para las distintas funciones con entradas y salidas para los datos. Los comentarios visualmente no aparecen en ninguna cajita ni tienen entradas/inputs ni salidas/outputs. El texto introducido en los comentarios es información que no sera interpretada por la maquina como elementos transformadores del programa/patch que estamos construyendo. Figura 2. Un comentario en Pure data cuando esta recién creado. 2. Funciones... Una función es un fragmento de código, un subalgoritmo dentro de nuestro algoritmo, que tiene como propósito resolver una tarea determinada. Por ejemplo, si nuestro algoritmo es hacer un bizcocho, que consta de una serie de pasos como: comprar los ingredientes, batir los huevos, añadir el azucar, etc. Una función podría ser la que se encarga del paso 'batir los huevos' y la descompondríamos en : 1. coger los huevos, 2.romperlos y echarlos en un plato, 3. coger un tenedor, 4. batirlos. ... en Arduino Como hemos visto en el apartado anterior, a parte de los comentarios había unas palabras a color: void setup() y void loop() Bueno, la estructura sería esta. void setup() {// aquí escribimos los comandos a ejecutar} Es muy importante que no olvidemos ningún paréntesis ni corchete, o el programa no funcionará. Ambas son funciones. Y, ¿qué es una función dentro del mundo de Arduino? Como ya hemos dicho, una función es un fragmento de código, un subalgoritmo dentro de nuestro algoritmo, que tiene como propósito resolver una tarea específica. La palabra void, significa que esta función no nos devuelve ningún valor (sea un número, un caracter, un string, etc.) y la palabra reservada setup indica que el código que escribamos entre las llaves {} se ejecutará una sola vez al inicio del programa. Tanto setup como loop son palabras reservadas, pero eso lo veremos un poco más abajo. En Arduino existen muchas funciones ya programadas, pero a parte de eso, podemos programar nuestras propias funciones. Tienes una lista completa con las funciones que podemos encontrar en Arduino, aquí. ... en Pure Data En pure data las funciones serán los objetos, que son cajitas en las que escribiremos el nombre de la función. Cada objeto va a realizar una función específica. Una metáfora de una función que ya hemos visto en la Práctica 0: Programaci... | Librería CATEDU sería la cajita exprimidor. Figura 3. La cajita exprimidor. 3. Variables y palabras reservadas ... en Arduino No podemos avanzar mucho más sin hablar de ellas, las variables. Ellas nos van a permitir almacenar valores en nuestros programas, para ello debemos que saber que podemos almacenar datos de distintos tipos. Palabras como int, for, void loop() o if se consideran palabras reservadas porque poseen un significado especial dentro del lenguaje de programación que estamos empleando. Una manera de identificar a estas palabras especiales es porque aparecen con un color diferente. Palabras reservadas para tipos de datos Estas palabras tienen diferentes objetivos. Uno de ellos es para denotar los tipos de datos que podemos usar en nuestros programas. A estas palabras se les conoce como tipos predefinidos,  las escribimos delante de aquellas variables que vamos a emplear en nuestro programa y algunas de ellas son: int: almacena un número entero de un tamaño máximo de 16 bits.float: almacena un número decimal de 32 bits.char: almacena un caracter.boolean: almacena el valor verdadero (TRUE) o falso (FALSE).long: almacena el valor de un número entero de 32 bits. Por ejemplo podemos crear una variable que almacene el valor numérico que obtengamos con un sensor. Podríamos crearla así: int valorSensorTemperatura = 0; Lo que haría que el valor de esa variable inicialmente sea cero, siendo modificado cuando lo asignemos al pin de nuestro Arduino al que hemos conectado el sensor. Como vemos, la palabra reservada sería int, mientras que valorSensorTemperatura es el nombre de la variable. Ese nombre lo usaremos en nuestro programa cada vez que queramos usar o modificar su valor. Palabras reservadas para funciones Como ya hemos visto, existe una serie de funciones que ya vienen preprogramadas y que podemos utilizar directamente. Las dos fundamentales son void setup() y void loop(), pero existen muchas otras. Algunas de ellas son:delay(): detiene el programa durante el tiempo indicado (en milisegundos).random(): genera números pseudoaleatorios.float(): convierte un número, por ejemplo del tipo int, a un número decimal. 4. Consola La consola nos va a permitir saber el estado de nuestro algoritmo. En ella vamos a poder leer información referente a los diferentes pasos que nuestro algoritmo siga mientras es procesado. Es muy útil para detectar errores (bugs). ... en Arduino En este caso, la consola nos va a permitir saber el estado de las conexiones con nuestro Arduino. Nos informará de si nuestro programa contiene algún error, si ha sido subido correctamente a nuestro Arduino o si ha habido algún problema.  La podemos ver rodeada en color rojo en la siguiente imagen: Figura 4. Sketch de Arduino con la zona correspondiente a la consola marcada en rojo ...en Pure Data La ventana principal se abre cuando ejecutamos Pd y tiene esta apariencia: Figura 5. Ventana principal de Pure Data. En la parte inferior tenemos un espacio para la impresión de contenido desde patches de Pd y/o mensajes del propio Pd. Para imprimir desde un patch utilizaremos principalmente el objeto "print".Este objeto es útil para visualizar el estado de los datos en diferentes partes de la estructura/programa que creemos, nos va a ayudar a encontrar errores y a entender mejor cómo funciona nuestro programa. Los mensajes que Pd envíe aparecen en el mismo espacio y nos dan información acerca de errores y procesos que realiza el programa. El botón de "Log" nos permite filtrar la cantidad de mensajes enviados por Pd que queremos ver en ese espacio. Siendo "0 fatal" la mínima cantidad de información mostrada y "4 todo" la máxima. Inicialmente vamos a tener el Log en "2 normal" y ampliaremos la información mostrada en función de nuestras necesidades a la hora de resolver posibles problemas. Figura 6. Ventana principal de Pure data (izquierda) y un patch/programa de Pure data (derecha). REFERENCIAS: Cerrada Somolinos, J. A., & Collado Machuca, M. E. (2015). Fundamentos de programación. Editorial Universitaria Ramón Areces : UNED. Figuras: Figura 1. Captura de pantalla de la IDE de Arduino Figura 2. Un comentario en Pure data cuando esta recién creado. Figura 3. La cajita exprimidor. https://giphy.com/gifs/hulu-snl-saturday-night-live-nbc-3o7TKPdUkkbCAVqWk0 Figura 4. Captura de pantalla de la IDE de Arduino Figura 5. Ventana principal de Pure Data. Figura 6. Ventana principal de Pure data (izquierda) y un patch/programa de Pure data (derecha).Estructuras que debemos conocer 0. Contadores Esta sencilla estructura nos va a permitir contar eventos o sucesos. Esto nos permitirá, con ayuda de los condicionales e iteradores, tomar decisiones en función de cuántas veces haya sucedido un evento. Importante: en el mundo de la informática normalmente se empieza a contar por el numero 0. Luego en una lista de 8 elementos, el primer elemento ocupara la posición 0 y el octavo elemento la posición 7. El ejemplo más sencillo y básico de contador consiste en crear una variable dentro del proceso a contar y sumarle a esta variable 1 cada vez que se ejecute el proceso. Asignaremos como valor de partida el número 0. Y cada vez que el proceso se ejecute, se sumará 1 a esa variable. Una variable es un objeto que almacenará un valor, ese valor podrá modificarse a lo largo del programa. Por ejemplo, int i = 0 traducido a nuestro idioma sería: 'la variable "i" pertenece al tipo número entero y tiene el valor 0'. Por lo general en un contador, la variable que creemos será del tipo integer, abreviado int –ya habíamos hablado de tipos de datos en este apartado–, ya que para contar nos conviene utilizar números enteros. En los lenguajes de programación textual, tradicionalmente, se utiliza la letra "i" para nombrar las variables contador, pero se puede utilizar la letra o nombre que queráis y si tenéis varias variables tendréis que utilizar nombres diferentes para cada una de ellas. int i=0; int i = i+1; Que significa: "El entero i va a tomar el valor de si mismo más uno."Eso se traduce en que i pasará a valer 0 + 1 = 1. Vamos a ver ahora un ejemplo de que pasaría en cada repetición de un programa en el que la variable contador se incrementa 1 unidad: Antes del Arranque del programa: Variable contador = 0 Arranque del programa: Inicio del proceso: (Incrementar en 1 unidad el valor de la variable contador: Variable contador = Variable contador + 1) Variable contador = 0 + 1 Fin del proceso. Si lo repetimos una segunda vez, tenemos: Inicio del proceso: (Incrementar en 1 unidad el valor de la variable contador: Variable contador = Variable contador + 1) Variable contador = 1 + 1 Fin del proceso. Si lo repetimos una tercera vez, tenemos: Inicio del proceso: (Incrementar en 1 unidad el valor de la variable contador: Variable contador = Variable contador + 1) Variable contador = 2 + 1 Fin del proceso. Cuarta repetición: Inicio del proceso: (Incrementar en 1 unidad el valor de la variable contador: Variable contador = Variable contador + 1) Variable contador = 3 + 1 Fin del proceso. ... Cada vez que se ejecuta el proceso se le suma 1 al resultado del proceso anterior. Si el proceso se ejecuta 8 veces el valor de la Variable contador tra esas repeticiones sera 8. Ejercicio 5: ¿Qué valor tendría la variable contador después de que el proceso se ejecute 8 veces si en cada proceso sumamos 2 en lugar de uno. Variable contador = Variable contador +2? Ejercicio 6: Y, ¿si el proceso se realiza 15 veces y la cantidad sumada en cada proceso es 3? Variable contador= Variable contador + 3? 1. Condicionales (if-else-else if)... Estas estructuras se encargan de controlar qué acciones de nuestro algoritmo van a ejecutarse y cuáles no. Solo hay dos opciones, o bien se cumplirán las condiciones, o no. En ejemplo del control del nivel del agua en Zaragoza tenemos un claro condicional: Condición, acción si la condición se cumple, acción si la condición no se cumple En Zaragoza el nivel del agua del rio se mide una vez (Proceso 0: contar) todos los días (Proceso 1: comparar) y se apunta en una libreta (Proceso 2: almacenar). Este nivel, ha de ser siempre superior a 50 (Proceso 3: comparar). Cuando el nivel de agua en Zaragoza desciende por debajo de 50, se avisará al embalse (Proceso 4.1.1: enviar información) para que deje salir más agua (Proceso 4.1.2: cambiar), si el nivel de agua no ha bajado por debajo de 50, no se avisara al embalse y el agua que deja salir este, seguirá siendo la misma (Proceso 4.2: no cambiar). Figura 1. Condicionales marcados en el diagrama de flujo del control del nivel del agua del río Ebro en Zaragoza. En los lenguajes de programación visual esta estructura se va a construir de manera diferente a en los lenguajes de programación textual. En Arduino ... Las palabras clave de esta estructura son: IF - ELSE IF: A esta palabra le seguirá la condición que deberá cumplirse para ejecutar una serie de acciones.ELSE: irá seguida de las acciones que se ejecutarán en caso de que la condición no se cumpla. Un ejemplo para verlo en acción No hay mejor manera para entender algo que ver una demostración de su uso. Para ello, vamos a recurrir a uno de los ejemplos que nos brinda la IDE (Integrated Development Environment, el lugar en el que vamos a escribir nuestros programas) de Arduino. Este ejemplo podemos encontrarlo dentro de: Archivo > Ejemplos > 01. Basics > Fade Aunque, como de momento no hemos instalado Arduino en nuestro ordenador, simplemente échale un vistazo al código de la siguiente imagen: Figura 2. Imagen de la IDE de Arduino En este ejemplo, lo que hacemos es aumentar y disminuir la luminosidad de un LED de manera progresiva. De este ejemplo, por el momento, vamos a ver concretamente la parte relacionada con el condicional. En este algoritmo, el condicional aparece en las siguientes líneas. if (brightness <= 0 || brightness >= 255) { fadeAmount = -fadeAmount; } En estas líneas encontramos la palabra reservada if seguida de dos condiciones encerradas entre paréntesis. Lo que traducido a español significaría: "Si el brillo es menor o igual que cero o el brillo es mayor o igual que 255". La disyunción nos viene dada por el operador lógico OR que para Arduino se traduce como ||. Otros operadores lógicos muy comunes son AND, que se traduce por && y NOT, que se escribe !. Entre corchetes { } encontramos la acción a realizar. En este caso, revertir la cantidad de brillo que emitirá nuestro LED: si lo hemos apagado, lo comenzaremos a encender y al revés, si lo hemos encendido completamente, comenzaremos a apagarlo.En este caso, no existe una acción que deba ejecutarse en caso de que no se de alguna de las dos circunstancias encerradas en el condicional, pero si la hubiese aparecería detrás de la palabra else. Por tanto, un esquema de la estructura de los condicionales sería: if (Condición) { Acción A} else { Acción B} Siendo posible también: if (Condición) { Acción} Una última palabra sobre los condicionales: else if Existe también la posibilidad de que tengamos que realizar selecciones que den lugar a más de dos posibilidades, como por ejemplo en el caso que estemos leyendo ciertos valores de un sensor y queramos que un actuador realice diferentes acciones dependiendo de ellos. Si el sensor recibe valores entre 0 y 255 --> Acción ASi el sensor recibe valores entre 256 y 511 --> Acción BSi el sensor recibe valores entre 512 y 1024 --> Acción C Para ello necesitaremos las palabras else if, las cuales indican una segunda condición, o sucesivas. La estructura sería la siguiente: if (Condición 1) { Acción A} else if (Condición 2) { Acción B} else{ Acción C} Puede parecer algo lioso en un primer momento, pero conforme avancemos y veamos ejemplos, te familiarizarás con estas estructuras. En Pure Data ... En Pure Data que es el lenguaje visual que vamos a aprender en este curso se pueden crear estructuras condicionales utilizando diferentes objetos, por ejemplo algunos objetos operadores o el objeto "select" o el objeto "spigot" que es una puerta que se abre y deja pasar datos o se cierra y no los deja pasar. Veremos más adelante como construir estas estructuras de momento es importante que comprendáis la lógica del condicional. Figura 3. operadores de pure data que nos van a permitir comparar valores o caracteres. Cuando la comparación se cumpla enviaran un 1 por su salida, si no se cumple, enviaran un 0. Figura 4. objeto "select" de pure data que nos va a permitir clasificar en base a una comparación. En la imagen se comparan si el valor que llegue al objeto es igual que 0, igual que 1  ... igual que 7 o no es igual a ninguno de los números anteriores. Figura 5. Cuando la cajita de control envíe un 1 la puerta se abrirá y el mensaje "0.5 1000" llegara al objeto "print". En la imagen el control está cerrado y ha enviado un 0, por lo que la puerta esta cerrada y el mensaje no llega al objeto "print". 2. Bucles o Iteraciones (for/while)... Definiremos como iteración a la ejecución sistemática, repetida, de una serie de acciones mientras se dé una condición. Existe una condición que se analiza, normalmente, cada vez que se repite dicha iteración. Si esta condición se sigue cumpliendo, volveremos a repetir el proceso; si, por el contrario, ya no se cumple, pasaremos al siguiente proceso y ejecutaremos la acción correspondiente. En Arduino ... Las dos iteraciones más comunes son for y while. En la sentencia for, existe un índice cuyo valor va aumentando o disminuyendo conforme se ejecuta el algoritmo y la condición de la iteración va comprobando si se ha alcanzado el límite o no. Un esquema de esta estructura sería: for (int indice= inicial; indice<= final; indice ++){ Acción} Para entenderlo con un ejemplo, imagina que tienes una caja en la que caben solamente 10 cubos. Al principio, la caja estaría vacía, por lo que el valor de indice = 0. La caja se llena cuando hay 10 cubos, por lo que indice<=10. Y lo que queremos hacer es añadir cajas de una en una, por lo que tenemos que escribir que el valor de indice aumente utilizando la expresión indice ++.  En acción es donde iríamos añadiendo una caja de bombones cada vez. Así que, nuestro for añadirá bombones hasta que nuestro índice sea menor o igual al valor de final, que en este caso es 10. Es importante no olvidar colocar los paréntesis, puntos y comas y los corchetes donde corresponda, o Arduino se quejará y no nos hará caso... A parte del bucle for existe el bucle while, cuyo esquema general sería: while (condición){ Acción} Un ejemplo, para verlo en funcionamiento aunque no tengo mucha utilidad real, sería: int var = 0; while (var < 200) { // haz algo 200 veces var=var+1; //también podría escribirse como var++. } En él, hemos creado una variable con el valor 0, la cuál es aumentada dentro del bucle while con la operación var = var+1. Antes de aumentar este valor, en la línea superior deberíamos escribir la acción que querríamos ejecutar 200 veces. REFERENCIAS:Sentencia for en Arduino y ejemplo: https://www.arduino.cc/reference/en/language/structure/control-structure/for/Sentencia while en Arduino y ejemplo: https://www.arduino.cc/reference/en/language/structure/control-structure/while/Cerrada Somolinos, J. A., & Collado Machuca, M. E. (2015). Fundamentos de programación. Editorial Universitaria Ramón Areces : UNED.Puerto serie: https://www.luisllamas.es/arduino-puerto-serie/ Figuras: Figura 1. Condicionales marcados en el diagrama de flujo del control del nivel del agua del río Ebro en Zaragoza. Figura 2. Captura de pantalla de la IDE de Arduino Figura 3. operadores de pure data que nos van a permitir comparar valores o caracteres. Cuando la comparación se cumpla enviaran un 1 por su salida, si no se cumple, enviaran un 0. Figura 4. objeto "select" de pure data que nos va a permitir clasificar en base a una comparación. En la imagen se comparan si el valor que llegue al objeto es igual que 0, igual que 1  ... igual que 7 o no es igual a ninguno de los números anteriores. Figura 5. Cuando la cajita de control envíe un 1 la puerta se abrirá y el mensaje "0.5 1000" llegara al objeto "print". En la imagen el control está cerrado y ha enviado un 0, por lo que la puerta esta cerrada y el mensaje no llega al objeto "print". Algo de teoría sobre las ondas Vibraciones y Ondas Las vibraciones y ondas están muy presentes en todos los aspectos de nuestra vida, desde el movimiento que realizamos para bailar el hula hoop, hasta los mecanismos de percepción que hemos desarrollado en torno a la vibración, como son la vista y el oído (Crowell, 2000). Las ondas de luz, que nos permiten ver y percibir colores, implican vibración. Podemos escuchar y hablar porque nuestros tímpanos y cuerdas vocales vibran, nuestros corazones laten de manera periódica y nuestros pulmones inhalan y exhalan aire repetidamente.  (French, 1971). Figura.1 Niñx vibrando con un aro. Las Vibraciones son movimientos que se repiten una y otra vez en torno a una posición de equilibrio ("Vibración", 2022), un movimiento repetitivo que también se conoce como movimiento oscilatorio (French, 1971).                     Figura 2. Representación de dos modos de vibración periódica Periodo, frecuencia y amplitud Un movimiento que se repite una y otra vez se conoce como movimiento periódico, y el tiempo necesario para llevar a cabo una repetición se denomina periodo, T.  El número de repeticiones por segundo es la frecuencia, f (Crowell, 2000). La frecuencia y el periodo son magnitudes que dependen de la fuente que origina la vibración. f = 1/T Como podéis observar la frecuencia (f) es la inversa del periodo (T). Luego T y f son dos unidades que permiten medir la relación entre tiempo y repetición de movimientos oscilatorios. El periodo se mide en segundos, y la frecuencia en Hercios, Hz. Figura 3. Persona bailando el hula hoop Por ejemplo, una persona bailando un aro alrededor de su cintura, realiza un movimiento periódico, un movimiento que se repite. Vamos a fijarnos ahora en el aro, cada vez que el aro toca su ombligo contaremos una vuelta o una repetición. El tiempo que tarda el aro en volver a pasar por el ombligo sera el periodo (T), y la frecuencia (f) es cuantas veces por segundo pasa el aro por el ombligo. Podemos intuir que la velocidad con la que el aro gira va a estar relacionada con el periodo (T) y la frecuencia (f), cuanto más rápido gire el aro menor sera el tiempo que tarda en pasar por el ombligo, luego menor sera el periodo (T). Sin embargo, cuanto más rápido gire el aro, mayor sera la frecuencia (f), ya que el aro pasará más veces por el ombligo, en el mismo periodo de tiempo. El tamaño de las vibraciones se refleja en la amplitud A, que se relaciona con el valor máximo alcanzado en cada repetición y se define en física de forma general, como la distancia desde el centro a uno de los extremos del movimiento (Crowell, 2000). Las unidades de la amplitud dependerán de la escala y tipo de movimiento. Figura 4. Amplitud del movimiento del aro en una persona bailando un hula hoop. Cualquier vibración contiene energía, y el valor de esa energía es proporcional a la amplitud. Sin embargo, el periodo y la frecuencia son independientes de la amplitud (Crowell, 2000). ¿Qué son las ondas? Figura 5. Niñx vibrando. La vibración no se transmite al aro. En la imagen superior vemos como la niña vibra, pero no consigue que el movimiento de su vibración se traslade al aro, que cae inmóvil al suelo mientras el niño continúa vibrando. La intención de la niña es la de mover el aro con su vibración, transmitir el movimiento que realiza con su cuerpo a otro objeto, pero, no lo consigue. Por otro lado, en la figura 2, la persona sí logra transmitir el movimiento de su cuerpo al aro que se mueve alrededor de ella de manera periódica. Una vez tenemos claro qué es una vibración, es el momento de pasar a hablar sobre las ondas. Estas se producen como consecuencia de oscilaciones y vibraciones de la materia ("Onda", 2021). En física, una onda (del latín unda) consiste en la propagación de una perturbación de alguna propiedad del espacio, por ejemplo, densidad, presión, campo eléctrico o campo magnético, implicando un transporte de energía sin transporte de materia. ("Onda", 2022). Figura 6. Fila de personas cayendo por el empuje de la última. Para entenderlo mejor, vamos a utilizar una metáfora que si queréis podéis utilizar para explicárselo a vuestros alumnos. Imagina que tenemos una fila de 5 niños esperando para entrar en clase. El ultimo niño, al que asignaremos la posición 5, empuja al que tiene delante: niño número 4. El niño 4 sin poder evitarlo se precipita sobre el 3, que a su vez se precipita sobre el 2 que inevitablemente empuja al 1, que choca contra la puerta. Sin que los niños se desplacen, el empujón del niño 5 ha llegado hasta la puerta, lo mismo sucede con las ondas, sin que la materia se desplace, una perturbación se propaga a través del espacio. Este movimiento, iniciado por el niño 5, se ha transmitido de niño en niño en una reacción en cadena, como en el ejemplo clásico de la fila de fichas de dominó cayendo. La perturbación en la fila causada por el niño 5 ha llegado hasta la puerta pasando de niño en niño. Vemos, por tanto, que la fila es el medio y que los niños son las partículas del medio. Las magnitudes que hemos visto relacionadas con las vibraciones: periodo (T), frecuencia (f) y aptitud (A); se aplican también a las ondas. Figura 7. Amplitud (A) y periodo (T) en una onda representada en función del tiempo. Las ondas y su clasificación Las propiedades físicas de las ondas dependen y varían en función del origen y medio a través del cual se propagan (Onda, 2021). Las clasificamos de la siguiente manera: 1. Según el MEDIO en que se propagan: Ondas MECÁNICAS. Precisan de un medio elástico (líquido, gaseoso o sólido) y de condiciones determinadas de temperatura y presión, para propagarse efectivamente. Por ejemplo: las ondas sonoras que se propagan por el aire o por el agua y que veremos en el proximo capitulo. Ondas ELECTROMAGNÉTICAS. No requieren de un medio porque se pueden propagar en el vacío. Por ejemplo: la luz. De la que volveremos a hablar en la página siguiente. Ondas GRAVITACIONALES. Alteraciones del espacio-tiempo (recién confirmadas por la ciencia). 2. Según su PERIODICIDAD: Ondas PERIÓDICAS. Presentan ciclos repetitivos o regulares. Ondas NO PERIÓDICAS. Presentan ciclos irregulares. Figura 8. Representación de una onda periódica (izquierda) y de una onda no periódica (derecha) 3. Según su DIRECCIÓN: Ondas UNIDIMENSIONALES. Se propagan a través de una sola dimensión en el espacio.         Figura 9. Onda unidimensional. Ondas BIDIMENSIONALES. Se propagan a través de dos dimensiones y se suelen llamar también superficiales.   Figura 10. Onda bidimensional. Ondas TRIDIMENSIONALES. Se propagan en tres dimensiones y suelen llamarse esféricas. Figura 11. Onda tridimensional. Según el MOVIMIENTO DEL MEDIO respecto a la dirección en que se propague la onda: Ondas LONGITUDINALES. Las partículas del medio se mueven en la misma dirección en que se propaga la onda. Ondas TRANSVERSALES. Las partículas vibran perpendicularmente a la dirección de propagación de la onda. Figura 12. Movimiento de una onda longitudinal (arriba) y de una onda transversal (abajo). La marca roja en ambos casos indica una partícula del medio y como esta se mueve. Aquí tienes algunos ejemplos de tipos de ondas: Sonido de una flauta tocando la nota Do: Onda mecánica, periódica, tridimensional y longitudinal. Sonido ruido blanco: Onda mecánica, no periódica, tridimensional y longitudinal. Perturbación de una gota en el agua que cae en un lago: Onda mecánica, periódica, bidimensional y transversal. La luz visible: Onda electromagnética, periódica, tridimensional y transversal. Partes de una onda. En la siguiente imagen vemos las partes de una onda que se propaga en el espacio: Figura 13. Partes de una onda: Cresta, valle, amplitud (A), longitud de onda (λ) y el eje de equilibrio. Longitud de onda La longitud de onda, representada por la letra λ, hace referencia al espacio que avanza el movimiento en cada repetición, y se puede definir como el espacio que abarca cada una de esas repeticiones. Para medirla tomaremos como punto de referencia una cresta, por lo tanto, la longitud de onda sera la distancia entre dos crestas consecutivas. Debemos tener cuidado, porque la longitud de onda guarda ciertas similitudes con el periodo. Ambas nos hablan de la repetición del movimiento, pero existe una diferencia fudnamental entre ambas, ya que la longitud de onda (λ) registra espacio, y el periodo (T) registra tiempo. Cuando veamos gráficas debemos tener en cuenta el sistema de representación que se utiliza, y fijarnos no solo en qué variables representan los ejes vertical y horizontal, sino también en qué unidades se presentan estas variables. Figura 14. Representación de una onda en función del espacio (arriba) y una onda en función del tiempo (abajo) En la figura 14, el eje horizontal del gráfico superior representa el espacio, por eso, la magnitud entre crestas medida en metros, es la longitud de onda (λ). En el gráfico inferior, el eje horizontal representa el tiempo, por lo que la magnitud definida por la distancia entre crestas es el periodo (T) y se mide en segundos. Debemos fijarnos en que aunque en esta imagen la longitud de onda y el periodo se representen de forma equivalente, sus valores no lo son. T y λ son variables diferentes y relacionándolas podemos obtener la velocidad de la onda (v), ya que la velocidad es el espacio recorrido en un tiempo determinado. v = λ / T = λ f Sobre la velocidad volveremos a hablar más adelante cuando aparezcan los conceptos de reflexión y refracción. Frente de onda El frente de onda es el lugar geométrico de los puntos del medio que se encuentran afectados por la perturbación en un instante determinado. Tomaremos las crestas como referencia, por lo que la distancia entre frentes de onda es igual a la longitud de onda. La dirección de propagación de un frente de onda es perpendicular al mismo. Figura 15. Frente de onda en una onda circular(arriba) y en una onda plana (abajo). Principio de Fresnel - Huygens Este método plantea un modelo que nos va a permitir analizar y comprender cómo se propagan las ondas y nos sera útil para entender los fenómenos que con ellas ocurren. "Todo punto de un frente de onda inicial puede considerarse como una fuente de ondas esféricas secundarias que se extienden en todas las direcciones con la misma velocidad, frecuencia y longitud de onda que el frente de onda del que proceden." ("Principio de Fresnel", 2020) Figura 16. Representación del principio de Fresnel-Huygens en una onda plana (izquierda) y en una onda circular (derecha) Retomando nuestro ejemplo de la fila de niños, vemos como cada niño que recibe un empujón, genera a su vez otro empujón sobre el siguiente niño, en la misma dirección que el empujón recibido. Digamos que cada niño se convierte en un origen secundario de un nuevo empujón. Relación entre ondas Superposición Algo muy interesante sobre las ondas es que, a diferencia del movimiento de objetos, que al entrar en contacto generan fuerzas de repulsión entre ellos, las ondas se superponen en una misma región del espacio sin repulsión, y en el punto en el que coinciden se suman (Crowell, 2000. p.40). Figura 17. Dos ondas con diferente dirección de desplazamiento. Figura 18. Resultado de la superposición de las ondas de la figura 17. Video 1.  Superposición de ondas superficiales en el agua. Fase Otro concepto importante a la hora de trabajar con ondas, sobre todo lo podremos aplicar en el sonido, es el de la fase. La fase de una onda φ, es la posición relativa de un punto a lo largo de la onda (Polyakov, 2022). Es decir, en que posición de la repetición se encuentra un punto, en un momento determinado. La mediremos en función del ángulo descrito por su representación circular, en la que una repetición representa el circulo completo: Figura 19. Representación de la fase de una onda. (Phase=fase, Wave=onda) Esta magnitud cobra importancia al comparar las fases de varias ondas. A esta comparación la llamaremos diferencia de fase. Y la mediremos en grados o radianes. Figura 20. Representación de la diferencia de fase entre dos ondas con la misma frecuencia. (Phase=fase, Wave=onda) La diferencia de fase va a influir en el resultado de la superposición de ondas. Podemos comprobar, que cuando la diferencia de fase es 180º las ondas se anulan, en este caso decimos que la fase de una, es la inversa de la otra y que se encuentran en oposición de fase. Figura 21. Resultado de la suma de dos ondas sinusoidales de la misma frecuencia, pero diferencia de fase variable. Para entenderlo un poco mejor vamos a volver al símil del hula hop pero con 2 aros en lugar de 1.  Cuando la persona comienza, sujeta los aros en la misma tocando su espalda, en ese momento los aros estarían en fase. Tras varias vueltas, en el mismo instante un aro toca el ombligo, sin embargo, el otro aro que gira más rápido está tocando la espalda de la persona, en ese momento los aros no están en fase, están desfasados, hay una diferencia de fase entre ellos. Para ilustrarlo en la siguiente imagen podéis ver muchos aros girando en distintas fases: Figura 22. Muchos aros girando con diferentes fases unos de otros. Fenómenos/Propiedades de las ondas Absorción y Atenuación Tanto en la absorción como en la atenuación, la amplitud (A) de la onda disminuye, pero por diferentes motivos. Recordemos que la amplitud es la distancia máxima alcanzada por una partícula del medio en cada repetición. En el caso de la absorción, se produce una disminución de la intensidad y, por lo tanto, de la amplitud de una onda al perder energía mientras se propaga (Giménez Valentín, 2019). Esta perdida se debe a las interacciones con el medio (Giménez Valentín, 2019), como el rozamiento o pérdida en forma de calor. Figura 23. atenuación de una onda superficial y representación de la disminución de su amplitud a medida que se propaga. Si hablamos de atenuación esa disminución en la amplitud se produce al repartirse su energía en frentes cada vez más amplios (Giménez Valentín, 2019). Este fenómeno lo encontraremos en ondas bidimensionales y tridimensionales, como en el ejemplo de la figura 23, porque al propagarse en dos y tres direcciones respectivamente ocupan progresivamente mayor espacio. En una onda unidimensional el espacio ocupado, cuando esta se propaga, no varía. Para entenderlo un poco mejor tomaremos la metáfora económica que nos presentan en el siguiente video el profesor de la UPV, Marcos Herminio Giménez Valentín, y su amigo "Jota", que es una cabeza. En el ejemplifican primero la absorción y luego la atenuación: Video 2. Ejemplo de atenuación y absorción de una onda. Reflexión y Refracción Cuando una onda, que se propaga en un medio, llega a otro medio, se produce un cambio de dirección de la onda incidente y por lo general tendremos dos ondas resultantes, una onda que se refleja y otra onda que se refracta (Rubio Michavila, 2019a). La onda que se refleja vuelve al mismo medio y la onda que se refracta se propaga en un medio distinto. La reflexión consiste en un cambio de dirección, cuando incide una onda en la superficie limítrofe entre dos medios. La onda reflejada se continúa propagando a través del mismo medio por el que a incidido (Rubio Michavila, 2019a). La velocidad (v) de la onda reflejada y la onda incidente es la misma ya que la velocidad (v) depende del medio y al no cambiar de medio esta se mantiene. Figura 24. Diagrama de la reflexión y refracción de una onda al llegar al límite entre dos medios. En la imagen superior (figura 24), la onda que pasa al medio gris (verde), y que en el dibujo se denomina "Onda Transmitida", es el resultado de la refracción de la onda incidente (roja). En la refracción se da un cambio de dirección y de medio cuando, una onda incide en la superficie limítrofe entre dos medios. La onda refractada se propagará por el nuevo medio con una velocidad (v) diferente, ya que como habíamos dicho antes, esta depende del medio en que se propaga la onda. Con esta variación de velocidad (v), el periodo (T) y la frecuencia (f) se conservan sin embargo la longitud de onda (λ) varía, aumentando cuando la velocidad aumente y disminuyendo cuando la velocidad disminuya (Rubio Michavila, 2019b). Figura 25. Persona en una fila rebotando entre otras dos. Retomemos la metáfora de la fila de niñxs para comprender un poco mejor estos conceptos. El ultimo niño, al que asignamos la posición 5, empuja al que tiene delante: niño número 4. El niño 4 sin poder evitarlo se precipita sobre el 3, que a su vez se precipita sobre el 2 que inevitablemente empuja al 1, que choca contra la puerta. Tras golpearse con la puerta El niño 1 rebota y sin poder evitarlo empuja al niñx 2 que ha su vez empuja al niño tres. Tras golpear la puerta los niños pasan a empujarse en la dirección opuesta a la que lo hacían antes de chocar con la puerta, pero manteniéndose fuera de la clase, esto sería la reflexión del movimiento al llegar a la puerta. Sin embargo, del golpe del niño 1 en la puerta se cae un gorro que está colgado detrás. Parte de la energía con la que el niño 1 ha impactado en la puerta se transmite a esta, la atraviesa y llega al gorro que esta al otro lado. Esto sería el equivalente de la refracción ya que el movimiento ha continuado propagándose por un nuevo medio. Difracción Acabamos de ver qué les pasa a las ondas cuando al propagarse cambian de un medio a otro, y ahora veremos lo que sucede cuando una onda se desvía al atravesar un orificio o encontrar un obstáculo. El objeto difractante o la rendija, se convierte en una fuente secundaria de la propagación de la onda ("Difracción", 2022). Veremos con más detalle el ejemplo de la rendija, para ello, vamos a recordar que según el principio de Fresnel - Huygens, todo punto de un frente de onda inicial puede considerarse como una fuente de ondas esféricas secundarias. También, debemos de tener en cuenta que la relación entre la longitud de onda y el tamaño de la rendija van a condicionar la difracción, por eso es necesario que el tamaño de la abertura sea del mismo orden que la longitud de la onda incidente (Rubio Michavila, 2019c). Cuando un frente de ondas llega a una superficie con una rendija del mismo tamaño que su longitud de onda, el punto medio de la rendija se convierte en una fuente puntual de ondas esféricas que se propagan con la misma velocidad, frecuencia y longitud de onda: Figura 26. Difracción de una onda plana cuando el ancho de la ranura es igual a la longitud de onda. Si aumentamos el tamaño de la rendija, aparecerán más puntos como fuentes puntuales de ondas esféricas: Figura 27. Difracción de una onda plana cuando el ancho de la ranura es varias veces la longitud de onda. Extra: Si el mundo de las ondas os ha apasionado y queréis saber más en el siguiente link podéis encontrar un curso detallado de la UPV sobre oscilaciones y ondas. Figuras: Figura 1. Niñx vibrando con un aro. https://giphy.com/gifs/fail-kid-hula-hoop-cIhzInb5BWjXJhREXk Figura 2. Representación de dos modos de vibración periódica. https://massbateria.com/modos-de-vibracion-2/ Figura 3. Persona bailando el hula hoop https://giphy.com/gifs/thisgirlcan-hula-hoop-hooping-this-girl-can-JTbqfw3dydAg6d8axU Figura 4. Amplitud del movimiento del aro en una persona bailando un hula hoop. Imagen editada. https://www.kindpng.com/imgv/ihmTThR_person-using-hula-hoop-hd-png-download/ Figura 5. Niñx vibrando. La vibracion no se transmite al aro.  https://giphy.com/gifs/fail-kid-hula-hoop-fSdPI1jp98tlg6xpZS?utm_source=media-link&utm_medium=landing&utm_campaign=Media%20Links&utm_term=https://giphy.com/ Figura 6. Fila de personas calends por el empuje de la última. https://giphy.com/gifs/peterbjornandjohn-peter-bjorn-and-john-3o6gE57nEDKeoCxsrK Figura 7. Amplitud (A) y periodo (T) en una onda representada en función del tiempo. https://es.wikipedia.org/wiki/Per%C3%ADodo_(f%C3%ADsica) Figura 8. Representación de una onda periódica (izquierda) y de una onda no periódica (derecha). http://ondassonorasfaviotorrealba.blogspot.com/2015/11/segun-el-medio-en-que-se-propagan.html Figura 9. Onda unidimensional. https://intothecontinuum.tumblr.com/post/29160638835/is-it-possible-to-visualize-3-dimensional-standing Figura 10. Onda bidimensional. https://intothecontinuum.tumblr.com/post/29165448842/the-end-of-this-post-concludes-with-a Figura 11. Onda tridimensional. https://intothecontinuum.tumblr.com/post/29165448842/the-end-of-this-post-concludes-with-a Figura 12. Movimiento de una onda longitudinal (arriba) y de una onda transversal (abajo). https://www.physicslens.com/wp-content/uploads/2022/03/longitudinal-transverse-waves.gif Figura 13. Partes de una onda. https://www.lifeder.com/onda-transversal/ Figura 14. Representación de una onda en función del espacio (arriba) y una onda en función del tiempo (abajo). https://www.google.com/url?sa=i&url=http%3A%2F%2Fhyperphysics.phy-astr.gsu.edu%2Fhbasees%2FSound%2Fwavplt.html&psig=AOvVaw022BZbBkeoNNzkiuTa9JBV&ust=1665140039984000&source=images&cd=vfe&ved=0CAwQjRxqFwoTCKD91pe4y_oCFQAAAAAdAAAAABAD Figura 15. Frente de onda en una onda circular(arriba) y en una onda plana (abajo). https://www.aplustopper.com/what-is-wave/ Figura 16. Representación del principio de Fresnel-Huygens en una onda plana (izquierda) y en una onda circular (derecha). https://tfgonline.es/principio-de-huygens/ Figura 17. Dos ondas con diferente dirección de desplazamiento. http://ondassonorasfaviotorrealba.blogspot.com/2015/11/segun-el-medio-en-que-se-propagan.html Figura 18. Resultado de la superposición de las ondas de la figura 17. http://ondassonorasfaviotorrealba.blogspot.com/2015/11/segun-el-medio-en-que-se-propagan.html Figura 19. Representación de la fase de una onda. (Phase=fase, Wave=onda). https://www.nist.gov/image/phasegif Figura 20. Representación de la diferencia de fase entre dos ondas con la misma frecuencia. (Phase=fase, Wave=onda). https://www.nist.gov/image/phase-differencegif Figura 21. Resultado de la suma de dos ondas sinusoidales de la misma frecuencia, pero diferencia de fase variable. https://mriquestions.com/what-is-phase-encoding.html Figura 22. Muchos aros girando con diferentes fases unos de otros. https://giphy.com/gifs/hooping-hula-perth-MwC8t7MaaR7kCr3FaN Figura 23. atenuación de una onda superficial y representación de la disminución de su amplitud a medida que se propaga. http://newton.cnice.mec.es/materiales_didacticos/ondas2/ondas-conclusion4.html?3&2 Figura 24. Diagrama de la reflexión y refracción de una onda al llegar al límite entre dos medios. https://www.prored.es/la-reflexion-en-las-ondas-y-radioenlaces/ Figura 25. Persona en una fila rebotando entre otras dos. https://giphy.com/gifs/bully-harold-lloyd-waiting-in-line-26AHRsTEXSMgl3rXi Figura 26. Difracción de una onda plana cuando el ancho de la ranura es igual a la longitud de onda. https://es.wikipedia.org/wiki/Principio_de_Fresnel_-_Huygens Figura 27. Difracción de una onda plana cuando el ancho de la ranura es varias veces la longitud de onda. https://es.wikipedia.org/wiki/Principio_de_Fresnel_-_Huygens Videos: Video 1. Superposición de ondas superficiales en el agua. https://www.youtube.com/watch?v=1mPYQ5DVPxQ&t=7s Video 2. Ejemplo de atenuación y absorción de una onda. https://www.youtube.com/watch?t=114&v=I4tCNpnR-b4&feature=emb_imp_woyt Referencias: Crowell, B. (2000). Vibrations and waves (Vol. 3). Light and Matter. Difracción. (2022, abril 23).  En Wikipedia. https://es.wikipedia.org/wiki/Difracci%C3%B3n French, A. P. (1971). Vibrations and Waves. CRC Press. Gimenez Valentin, M. H. [Universitat Politècnica de València UPV]. (2019, 30 abril). Atenuación y absorción de una onda | 15/25 | UPV. [Video]. YouTube. https://www.youtube.com/watch?v=I4tCNpnR-b4&t=114s Onda. (2021, julio 15). Estefania Coluccio Leskow, En Enciclopedia Concepto. Consultado el 1 octubre 2022 en https://concepto.de/onda-2/ Onda. (2022, septiembre 21).  En Wikipedia. https://es.wikipedia.org/wiki/Onda#:~:text=La%20teor%C3%ADa%20de%20ondas%20se,Ostrovsky%20y%20Potapov%2C%201999) Polyakov, S. (2022, Enero 25). New Telecom Receiver System Checks Reliability of Message Components in Real Time. National Institute of Standards and Technology. https://www.nist.gov/news-events/news/2022/01/new-telecom-receiver-system-checks-reliability-message-components-real-time Principio de Fresnel - Huygens. (2020, agosto 20) En Wikipedia. https://es.wikipedia.org/wiki/Principio_de_Fresnel_-_Huygens Rubio Michavila, C. [Universitat Politècnica de València UPV].  (2019a, 30 abril). Reflexión de las ondas | 18/25 | UPV. [Video]. https://www.youtube.com/watch?v=m32o8WTXy-g&list=PL6kQim6ljTJudzpws0ggAtF0RQsIPwgGr&index=18 Rubio Michavila, C. [Universitat Politècnica de València UPV].  (2019b, 30 abril b). Refracción de ondas. | 19/25 | UPV. [Video]. https://youtu.be/mXoVi8mv15Y Rubio Michavila, C. [Universitat Politècnica de València UPV].  (2019b, 30 abril c). Difracción de ondas. Lección 19 | 20/25 | UPV [Video]. https://youtu.be/vivFGdGVItQ Vibración. (2022, septiembre 16). En Wikipedia. https://es.wikipedia.org/wiki/Vibraci%C3%B3n Las ondas y el color La idea inicial de la que vamos a partir es que los objetos no tienen color en sí mismos, sino que su color proviene de la luz que incide sobre ellos. Este es el concepto nº 1 cuando se habla de las propiedades físicas del color. Los objetos no son de colores en sí mismos. Si somos capaces de percibir algo de color rojo, por ejemplo, es porque ese objeto absorbe la luz de todas las longitudes de onda del espectro visible excepto la longitud correspondiente al color rojo. De la misma manera, un objeto negro absorbe todas las longitudes de onda y uno blanco las rechaza a todas. La luz visible, que es la que nos permite ver los colores es una onda electromagnética, periódica, tridimensional y transversal, como ya hemos visto en el apartado anterior. La visión humana es bastante limitada y el espectro que abarca la luz visible solamente va de los 400 a los 700 nm: La imagen superior nos muestra que el ojo humano no es capaz de percibir la mayoría de la luz que nos rodea, sino solamente los colores que asociamos al arco iris. Lo que miden los 400 a 700 nm que podemos ver es la longitud de onda (λ) . Este concepto ya lo hemos explicado en la página anterior, así que aquí solamente recordaremos que la longitud de onda se refiere a la distancia entre dos puntos máximos consecutivos: Para poder visualizar los colores de las diferentes longitudes de onda que componen la luz visible, es conocido el experimento realizado con un prisma, gracias al que la luz es refractada, reflejada y descompuesta. Síntesis aditiva y superposición de ondas Hablar de la luz visible y de su descomposición con un prisma nos conduce a la síntesís aditiva. En la página anterior hemos visto que cuando superponemos dos ondas, se suman. ¿Y esto qué consecuencias tiene en el mundo del color? Todos hemos oído hablar del sistema RGB (Red Green Blue) que es el que se utiliza en las pantallas de los ordenadores y televisores. y en esos tres colores es en los que se basa la generación de diferentes colores empleando la luz. Este tipo de síntesis aparece en contraposición a la síntesis sustractiva, que es la que emplean las impresoras o nosotros cuando queremos pintar algo empleando pigmentos. Esta síntesis está basada en otros tres colores: CMY (Cyan Magenta Yellow y también el Key que equivale al negro): En la imagen superior podemos ver los colores primarios y los secundarios de la síntesis aditiva a la izquierda y sustractiva a la derecha. Te aconsejo que en este punto experimentes con linternas y papel de celofán. Solo necesitarías dos linternas (una de ellas puede ser la de tu móvil) y papeles de celofán con los colores rojo, verde y azul. Si tapas una de la linterna con celofán rojo y la otra con verde, veras que la luz resultante al proyectarlas sobre el mismo punto es amarilla. ¿Cómo percibimos el color? Hablar de luz y colores luz nos conduce a hablar sobre cómo percibimos nosotros esos colores y con ello a unos tipos de células denominados bastones y conos. A estas células se les conoce como fotorreceptores y son las encargadas de absorber la luz y transformarla en señales eléctricas. No vamos a entrar a hablar en detalle sobre ellas, pero mencionaremos simplemente que los bastones son los que cuentan con una fotosensibilidad alta y poca agudeza visual, siendo incapaces de distinguir entre los diferentes colores; mientras que los conos son los verdaderamente responsables de la percepción de los colores. Más adelante, cuando usemos Arduino, probaremos dos sensores que funcionan de una manera similar a los bastones y conos; una fotorresistencia y el sensor TCS3200 respectivamente. REFERENCIAS: Percepción del color: https://es.wikipedia.org/wiki/Percepci%C3%B3n_del_colorImagen espectro luz visible: https://es.wikipedia.org/wiki/Espectro_visible#/media/Archivo:Electromagnetic_spectrum-es.svgLongitud de onda: https://es.wikipedia.org/wiki/Longitud_de_ondaImagen longitud de onda: https://es.wikipedia.org/wiki/Longitud_de_onda#/media/Archivo:Sine_wavelength.svgImagen prisma descomponiendo luz: https://es.wikipedia.org/wiki/Prisma_(%C3%B3ptica)#/media/Archivo:Light_dispersion_conceptual_waves.gifImagen síntesis aditiva y sustractiva: https://1.bp.blogspot.com/-b5-zMiCiRbg/XJ0E963BwLI/AAAAAAAAAbM/dvg_z4d8hlYPJHKghKNRpIL2ojXShrBzgCLcBGAs/s1600/mezcla_aditiva_sustractiva.pngFotorreceptores: https://www.kenhub.com/es/library/anatomia-es/fotorreceptores Las ondas y el sonido El sonido es una onda mecánica, tridimensional y longitudinal. Es mecánica porque necesita de un medio elástico para propagarse, por ejemplo, en el espacio exterior, más allá de la atmósfera, no hay ondas sonoras ya que el sonido no se propaga en el vacío. Es tridimensional porque se propaga en tres dimensiones, y es longitudinal porque el movimiento de las partículas del medio sigue la misma dirección en que se propaga la onda. Recordamos que una onda es la propagación de una perturbación de alguna propiedad del espacio, implicando un transporte de engería sin transporte de materia. En el caso de sonido una de las propiedades perturbadas es la presión, que se define como fuerza por unidad de superficie. La propagación de estas variaciones de presión es lo que conocemos como onda sonora y esa variación de presión es lo que percibimos y denominamos sonido. Para ilustrar esto vamos a ver un gif de cómo genera un altavoz ondas sonoras. En el gif vemos como la membrana del altavoz se mueve, vibra, este movimiento genera cambios de presión y densidad en el aire. Estos cambios son lo que nuestro oido va a captar. Figura 1. Membrana de un altavoz vibrando. ¿Como percibimos el sonido? Percibimos el sonido a traves del oído, que nos permite captar los cambios de presión en el aire generados por las ondas sonoras. Estas ondas mecánicas son captadas y transformadas en impulsos eléctricos que el cerebro puede interpretar. Video 1. Funcionamiento del oído. Pero no solo el oído nos va a permitir percibir estos cambios de presión, nuestro cuerpo también va a notar las vibraciones, sobre todo aquellas causadas por frecuencias bajas. Frecuencias que va a hacer vibrar diferentes tejidos y cavidades de nuestros cuerpos. Asi que recordar que, si tenéis algún alumno con una pérdida parcial o total de audición, aun va a poder percibir sonido, percibir música a traves de su cuerpo y por supuesto también crearla. Para conseguir ondas sonoras con frecuencias bajas podéis probar con instrumentos de percusión como un bombo y para reproducir frecuencias bajas con un altavoz necesitareis un subwoofer. Intensidad, volumen y amplitud Cuando hablamos del volumen de un sonido nos referimos a la intensidad con la que percibimos ese sonido. Esta intensidad está relacionada con la amplitud de la onda sonora, de forma que, si la amplitud aumenta, también lo hara la intensidad con la que percibimos ese sonido. Como vimos en el capítulo anterior, la amplitud es el valor máximo alcanzado por un punto del medio en cada repetición. A mayor amplitud de onda, percibiremos un sonido como más fuerte, mayor sera su volumen. Nuestro oído adapta su sensibilidad a la intensidad que percibe, o digámoslo de una forma más precisa, la sensibilidad de nuestro oído en función de la intensidad de la onda no tiene una progresión lineal si no logarítmica. Esto nos permite distinguir pequeñas variaciones de intensidad en sonidos muy suaves, pero no en sonidos muy fuertes, en los que solo percibiremos grandes cambios de intensidad (Cabrera, n.d.). Este comportamiento de nuestra percepción acústica nos lleva a diferenciar entre intensidad de una onda y la intensidad con la que percibimos esa onda. Para medir cada una de ellas utilizaremos diferentes escalas y magnitudes. La intensidad de una onda sonora la mediremos en W/m^2 y la intensidad con la que percibimos una onda la mediremos en decibelios (dB). Umbral de audición y umbral de dolor En lo que a intensidad se refiere nuestro oído también tiene sus limites. Podremos escuchar sonidos desde el umbral de audición: 10 ^-12 W/m^2 o 0dB, hasta el umbral de dolor: 1W/m^2 o 120dB. Por debajo del umbral de audición no escucharemos nada, por encima del umbral de dolor podemos dañar nuestros oídos (Gimenez Valentin, 2019). Figura 2. Rango de intensidad sonora percibida por el ser humano en dB. Es muy importante no someter al oído a intensidades por encima del umbral de dolor, ni cercanas a este, especialmente durante un largo periodo de tiempo, ya que se pueden generar daños y perdidas de audición irreversibles. Cuando trabajemos con nuestros alumnos va a ser de vital importancia el control del volumen y debemos enseñarles a cuidar de sus oídos. Cuando trabajemos con sonido en Pure data, vamos a regular el volumen modificando la amplitud (A). Estas modificaciones de amplitud también nos van a ser útiles a la hora se sumar ondas para crear sonidos más complejos, digamos que nos permitirá regular cuanta cantidad de una onda mezclamos con otra, como si de una receta de cocina se tratara, cuanta sal y cuanta vinagre le echamos al gazpacho para potenciar su sabor, la cantidad de sal va a sera una amplitud de una onda y la cantidad de vinagre sera la amplitud de otra onda. Como veíamos anteriormente y ya que el sonido es una onda tridimensional, experimenta atenuación al propagarse. Por eso cuanto más nos alejamos de una fuente sonora menor es el volumen que percibiremos. Frecuencia y tono, resonancia y timbre Cuando hablamos del tono de un sonido nos referimos a la frecuencia. Esta frecuencia viene determinada por el número de repeticiones por unidad de tiempo y la medimos es Hercios (Hz). La frecuencia guarda cierta relación con la longitud de onda. Veamos qué relación: recordemos que la velocidad de propagación de una onda depende del medio por el que se propaga, y en un mismo medio se mantiene constante. Por ejemplo, la velocidad de propagación del sonido en el aire, a una temperatura de 20º es siempre 343 m/s. Tambien veíamos que la velocidad de propagación es igual a la longitud de onda por la frecuencia, que distancia recorre cada repetición en función del tiempo. v = λ f = λ / T En un mismo medio una onda con una mayor frecuencia tendrá menores longitudes de onda, y una onda con menor frecuencia tendrá una longitud de onda mayor. Ejemplo: La longitud de onda (λ) de un sonido que se propaga en el aire con una frecuencia de 50 Hz y de 10.000 Hz: frecuencia de 50 Hz (λ = v/f) frecuencia de 10.000 Hz (λ = v/f) λ=343/50  λ=6,86 m λ=343/10.000 λ=0,0343 m Tabla 1. Relación entre frecuencia y longitud de onda para dos ondas que se propagan en el aire. Como bien sabemos la frecuencia es una magnitud que depende de la fuente que origina la onda, por lo que cuando una onda cambia de medio la frecuencia se mantiene constante, luego, lo que va a variar con la velocidad de propagación de la onda es la longitud de onda. Para nuestros oídos la frecuencia es lo que determina como de grave o agudo es un sonido, también determina las notas de la escala musical. Cada nota de la escala musical corresponde a una vibración con una frecuencia especifica, por ejemplo, un Re que tiene una frecuencia de 293,6 Hz. Sonidos graves 20-256 Hz Sonidos medios 256 Hz - 2 KHz Sonidos agudos 2 KHz - 20KHz Tabla 2. Clasificación de los sonidos según su frecuencia en graves, medios y agudos. ¿Pero porque la misma nota tocada en un violin suena diferente que en un piano? Para responder a esta pregunta vamos a introducir primero el concepto de resonancia, que es el fenómeno que permite a una cantante de ópera romper una copa con su voz. Pero como sucede esto? Toda vibración requiere de una fuerza que la genere y como vimos en la definición de onda, una onda implica un transporte de energía sin transporte de materia. Tambien vimos que esta energía es proporcional a la amplitud de la onda, amplitud que disminuye con los fenómenos de absorción y atenuación. En el caso de la resonancia la amplitud va a aumentar considerablemente para frecuencias especificas que dependerán del objeto afectado por una vibración. La copa de cristal tiene una frecuencia natural de vibración, que es a la que tendera a vibrar esta copa después de ser golpeada ("Frecuencia Natural", 2022). Cuando esta copa es afectada por una onda cuya frecuencia coincide con su frecuencia natural de vibración, se genera el fenómeno de la resonancia y la amplitud de la vibración en la copa para esa frecuencia aumentara considerablemente. Este fenómeno indica la tendencia de un sistema a vibrar con mayores amplitudes de onda al ser afectado por una vibración cuya frecuencia coincide con las frecuencias naturales de vibración del sistema (Crowell, 2000). En una situación en la que tenemos un cuerpo vibrando en resonancia se consigue la mayor amplitud en relación a la cantidad de energía transportada por la onda. En el siguiente video vemos el experimento de la copa que podéis, (con mucho cuidado), realizar con vuestros alumnos. Video 2. Rotura de una copa haciéndola vibrar a su frecuencia de resonancia. En la naturaleza rara vez vamos a encontrar ondas compuestas por una sola frecuencia, ondas puras. Tampoco vamos a encontrar sistemas con una unica frecuencia de resonancia. Los objetos vibrantes que generan y a traves de los cuales se propagan las ondas sonoras van a tener varias frecuencias naturales de vibración. Este grupo de frecuencias resonantes es lo que nos permite diferenciar un violin y un piano cuando tocan la misma nota, esta diferencia o característica de cada instrumento es lo que conocemos como timbre. Aunque un violin toque la nota Re correspondiente a la frecuencia 293,6 Hz, la onda que produce el instrumento no está formada únicamente por la frecuencia 293,6 Hz, no es una onda pura. Esa onda también contiene un grupo de frecuencias en su mayoría superiores a 293,6 Hz. Este grupo de frecuencias resonantes son múltiplos de la frecuencia fundamental 293,6 Hz, y es lo que conocemos como armónicos. Vamos a ver que frecuencias acompañan a la fundamental de la nota "Re" tocada por varios instrumentos: Figura 3. Tres graficas del rango de frecuencias que se generan al tocar la nota Re=296,6 Hz con tres instrumentos diferentes. Como vemos en las gráficas anteriores los armónicos creados por diferentes instrumentos al tocar la misma nota tienen diferentes intensidades. La cantidad e intensidad de cada uno de los armónicos que acompañan al sonido fundamental es lo que va a determinar el timbre de un sonido. El espectro audible "El espectro audible,​ también denominado campo tonal, se encuentra conformado por las audiofrecuencias, es decir, toda la gama de frecuencias que pueden ser percibidas por el oído humano. Un oído sano y joven es sensible a las frecuencias comprendidas entre los 20 Hz y los 20 kHz." ("Espectro audible", 2022) Figura 4. Espectro audible humano en naranja, y de diferentes animales. Por debajo del espectro audible humano, 20Hz se encuentran los infrasonidos que nuestros oídos no pueden percibir, sin embargo, son absorbidos por nuestro cuerpo y perceptibles para los oídos de algunos animales. Por encima de 20 kHz se encuentran los ultrasonidos que tampoco percibe nuestro oído, pero si el de algunos animales como los gatos o los delfines. Los ultrasonidos se utilizan comúnmente en medicina para realizar imágenes del interior del cuerpo, ya que a traves de los tejidos de nuestros órganos se propagan estos ultrasonidos. Como vimos anteriormente cuando una onda llega a límite entre dos medios se producen los fenómenos de reflexion y refracción, esto sucede dentro de nuestros cuerpos con las ondas ultrasónicas de una ecografía, y el registro de esas reflexiones es lo que nos permite crear una imagen del interior de nuestros cuerpos (Diplomado en Ultrasonografía Médica, 2017). Si nos fijamos, los principios básicos de gran parte del desarrollo de herramientas tecnológicas son los mismos que encontramos en el desarrollo de los sentidos del mundo animal, y en general en los fenómenos que constituyen el mundo que nos rodea. Es interesante, revelador e inspirador comparar o tomar como referencia estos fenómenos a la hora de observar y trabajar en el campo de la ciencia y la tecnología. Nuestro oído es un sensor que capta un determinado rango de ondas sonoras, es nuestro micrófono y nuestras cuerdas vocales por ejemplo son nuestro altavoz. En el capítulo anterior veíamos la vista y las ondas electromagnéticas, el ojo es el sensor que nos permite percibir una parte de esta radiación electromagnética. Al igual que nuestros ojos y oídos que tiene un rango de valores perceptibles, cuando trabajemos en Arduino con sensores nos pasara lo mismo, y cada sensor registrara un rango especifico de una variable del espacio. Es importante pues, elegir el sensor adecuado en el rango adecuado para lo que queramos medir. La ficha técnica de estos componentes os dará información acerca de ese rango, también conocido como sensibilidad, y de las condiciones de trabajo del componente. Eco y Reverberación. Ambos fenómenos son consecuencia de la reflexión de las ondas sonoras y se diferencian principalmente por el tiempo que tarda la onda reflejada en volver al lugar donde se ha originado, también por el número de reflexiones, ya que en la reverberación las ondas rebotan varias veces sobre diferentes superficies. En el ámbito acústico, se diferencian comúnmente por como percibe el oyente estas ondas, en el caso de la reverberación el tiempo entre que el oyente percibe la onda originaria o sonido directo, y las reflexiones de esta, o sonido reflejado, es lo suficientemente corto para que la onda originaria y las ondas reflejadas se perciban como una sola. En el caso del eco este tiempo, es mayor, y el número de ondas reflejadas menor, de manera que el oyente puede percibir como varios sonidos la onda originaria y cada una de las reflexiones de esta (Espuma acústica, 2021). Video 3. Ejemplo sonoro de eco y reverberación. Por lo general la reverberación la encontraremos es espacios cerrados, no muy grandes y con materiales que absorban muy poco sonido. El eco sera más frecuente en espacios abiertos y/o con largas distancias entre la fuente que genera las ondas y el medio en el que estas se reflejan. Figuras: Figura 1. Membrana de un altavoz vibrando. https://fromvinyltoplastic.com/wp-content/uploads/2019/09/sub-animation.gif Figura 2. Rango de intensidad sonora percibida por el ser humano en dB. https://www.fisic.ch/contenidos/ondas-y-sonido/caracter%C3%ADsticas-del-sonido/ Figura 3. Tres graficas del rango de frecuencias que se generan al tocar la nota Re=296,6 Hz con tres instrumentos diferentes. http://www.fqsaja.com/?p=8537 Figura 4. Espectro audible humano en naranja, y de diferentes animales. https://www.fisic.ch/contenidos/ondas-y-sonido/caracter%C3%ADsticas-del-sonido/ Tablas: Tabla 1. Relación entre frecuencia y longitud de onda para dos ondas que se propagan en el aire. Tabla 2. Clasificación de los sonidos según su frecuencia en graves, medios y agudos. Videos: Video 1. Funcionamiento del oído. https://www.youtube.com/watch?v=PuC1BDFUq2I Video 2. Rotura de una copa haciéndola vibrar a su frecuencia de resonancia. https://www.youtube.com/watch?v=Ory4XB9SmkY Video 3. Ejemplo sonoro de eco y reverberación. https://www.youtube.com/watch?v=VK6LAgmllRU Referencias: Cabrera, R. (n.d.) Intensidad y nivel de intensidad sonora Escala de decibeles (dB). Ricardo Cabrera https://ricuti.com.ar/no_me_salen/ondas/Ap_ond_16.html Crowell, B. (2000). Vibrations and waves (Vol. 3). Light and Matter. Diplomado en Ultrasonografía Médica. (2017, julio 11). Principios físicos del ultrasonido. Diplomado en Ultrasonografia. https://diplomadomedico.com/principios-fisicos-del-ultrasonido-2/ Espectro audible. (2022, septiembre 24).  En Wikipedia. https://es.wikipedia.org/wiki/Espectro_audible Espuma acústica. (2021, diciembre 15). ¿Qué es la reverberación, cuál es la diferencia con el eco y qué problemas te afectan? Espuma acústica. https://www.espumaacustica.online/reverberacion-eco/ Frecuencia Natural. (2022, septiembre 26) . En Wikipedia. https://es.wikipedia.org/wiki/Frecuencia_natural Gimenez Valentin, M. H. [Universitat Politècnica de València UPV]. (2019, 30 abril). Intensidad asociada a una onda | 13/25 | UPV. [Video]. YouTube. https://youtu.be/EqArgDzU3Bc MATERIALES KIT MÓDULO 2: PURE DATA Vamos a ver qué es Pure Data, instalarlo y haremos la primera práctica ¿Qué es Pure Data (Pd)? Pure Data o Pd Pd es un entorno de código abierto de programación gráfica en tiempo real para audio, video y procesamiento gráfico (imágenes) (Pure Data, 2022). Este lenguaje de programación permite a músicos, artistas visuales, performers, investigadores y desarrolladores (programadores) crear software/programas de manera grafica sin tener que escribir una sola línea de código (Pure Data, 2022). Ejemplos de artistas/proyectos hechos con Pure Data: Patricia Cadavid - Tawa Patricia Cadavid Hinojosa es una inmigrante, artista e investigadora nacida en Colombia. En su trabajo, aborda las relaciones y efectos de la colonialidad en los nuevos medios desde la experiencia migratoria y el pensamiento decolonial y anticolonial. Su investigación reciente se centra en la reivindicación de la memoria contenida en las interfaces ancestrales de los Andes de Abya Yala, invisibilizadas por la colonización y sus conexiones con el arte y la ciencia, reutilizándolas en nuevos procesos artísticos relacionados con el video, las interfaces sonoras, tangible live coding y la performance multimedia. Ha recibido un Master en Artes en el programa Interface Cultures (Kunstuniversität Linz), el grado en Bellas Artes por la Universidad de Castilla-La Mancha y un máster en Artes Visuales y multimedia por la Universitat Politècnica de València, Su trabajo ha sido expuesto en festivales como Ars Electronica (Austria), ADAF (Grecia), la conferencia NIME, y varios espacios en Estados Unidos, Chile, México, España, Alemania y Colombia. Tawa - por Patricia Cadavid from Plataforma Bogotá AV on Vimeo. Video editado por Juliana Ortigoza Para conseguir la armonía ha de existir el equilibrio, en la cosmología andina Tawa (cuatro) simboliza los dos equilibrios opuestos que se complementan. En el año especial que suma 4, el khipu se anudará por primera vez con Pure Data, con sonidos que celebran los encuentros, y la memoria de experiencias vividas en este periodo excepcional donde seguimos aprendiendo a tejer el equilibrio desde la incertidumbre y la esperanza. Un Khipu es un dispositivo que se usaba en el antiguo Imperio Inca para el procesamiento y transmisión de información estadística y narrativa. En esta performance, la interfaz se reutiliza en un nuevo khipu electrónico como instrumento para la interacción y generación de sonido experimental en vivo, donde a través del tejido de nudos, se busca codificar el legado interrumpido de esta práctica ancestral. (Cadavid, 2022) Nerea Tascón Ruiz - Moog Analog Synthesizer Component Characterization and Implementation of their Digital Model in Pure Data. Nerea desarrolla una version simplificada en Pure Data del sintetizador analógico Moog Slim Phatty. Este modelo está disponible en el siguiente link: https://github.com/nereatruiz/Moog-Analog-Synthesizer-ComponentsCharacterization-and-Implementation-oftheir-Digital-Model-in-Pure- IOhannes m zmölnig - Pointillism Tanto el código de representación (los visuales) como el audio generado, utilizan puntos como blokes de construcción: la música se genera utilizando patrones de código morse, y el código está escrito en "Braille". La performance es un statement que ironiza sobre el típico "enséñanos tu pantalla". Mostrando al público un código en una forma que ni siquiera pretende ser legible. (m zmölnig ,n.d.) Pointillism from IOhannes m zmölnig on Vimeo. Referencias: Cadavid, P. (2020). Tawa. Pure Data & electronic Khipu knotted. [Artwork]. Patricia Cadavid. https://www.patriciacadavid.net/2020/08/tawa-pure-data-electronic-khipu-knotted.html#/page/1 m zmölnig, I. (n.d.). Pointillism. [Artwork]. forum::für::umläute. https://umlaeute.mur.at/Members/zmoelnig/projects/pointillism/ m zmölnig, I. (2016). IOhannes M Zmölnig - pointillism. [Video]. YouTube. https://www.youtube.com/watch?v=zfH7H5Xht_U Pure Data (2022). Pure Data home. Pure Data. Consultado el 16 Agosto 2022 de http://puredata.info/Instalar Pd Descargar Pure Data https://puredata.info/ Figura 1. Página web principal de Pure data con las secciones de descarga indicadas. https://puredata.info/downloads Figura 2. Página web de descargas de Pure data con el link a Pure data Vanilla indicado. https://puredata.info/downloads/pure-data Figura 3. Página web de descargas de Pure data Vanilla con los links de diferentes sistemas operativos marcados. Instalar Pure Data WINDOWS Una vez hemos descargado el archivo de instalación lo ejecutaremos permitiendo que realice cambios en el equipo. Tras ser descargado lo más probable es que el archivo este en la carpeta de descargas. Figura 4. Instalando Pure data en Windows. Figura 5. Ventanas que se abrirán tras la instalación de Pure data. El manual está en Ingles. Si alguien quiere consultarlo y necesita la ayuda de un traductor, os recomiendo este: https://www.deepl.com/translator ¡PURE DATA YA ESTA INSTALADO EN NUESTRO EQUIPO WINDOWS! Figura 6. Usuarios de Windows tras instalar Pure Data en su ordenador sin ningún problema. MAC OS Para descargar la versión de Mac iremos también a la sección de Downloads y descargaremos el archivo para nuestro Mac. Se nos descargará un archivo del tipo .zip. Lo abriremos y nos encontraremos un archivo del tipo .dmg. ¿Qué hacemos con él? Simplemente lo arrastraremos a nuestra carpeta de Aplicaciones y desde allí lo abriremos. Figura 7. Instalación de Pure data en MAC OS. ¡PURE DATA YA ESTA INSTALADO EN NUESTRO EQUIPO MAC! Figura 8. Usuarios de MAC OS tras instalar Pure Data en su ordenador sin ningún problema. LINUX Si tu centro dispone de equipos con Vitalinux, la instalación no puede ser más fácil. Vas a la aplicación Vitalinux Play, localizas el software en el filtro buscador y le das a la flecha de arriba a la derecha para instalar Figura 9. Instalando Pure data en Vitalinux. Por unos instantes la flecha parpadeará hasta que la aplicación nos informe de que ya está instalado. En ese momento solo tendremos que usar la combinación de teclas Control+Espacio y teclear Pure Data y ya lo tendremos accesible. Figura 10. Como acceder a Pure data en Vitalinux una vez está instalado. ¡PURE DATA YA ESTA INSTALADO EN NUESTRO LINUX! Figura 11. Usuarios de Linux tras instalar Pure Data en su ordenador sin ningún problema. Figuras: Figura 1. Página web principal de Pure data con las secciones de descarga indicadas. Figura 2. Página web de descargas de Pure data con el link a Pure data Vanilla indicado. Figura 3. Página web de descargas de Pure data Vanilla con los links de diferentes sistemas operativos marcados. Figura 4. Instalando Pure data en Windows. Figura 5. Ventanas que se abrirán tras la instalación de Pure data. Figura 6. Usuarios de Windows tras instalar Pure Data en su ordenador sin ningún problema. https://hollywoodunlocked.com/bill-gates-steps-down-microsoft-berkshire-hathaway-boards/ Figura 7. Instalación de Pure data en IOS. Figura 8. Usuarios de MAC OS tras instalar Pure Data en su ordenador sin ningún problema. http://edition.cnn.com/2011/TECH/gaming.gadgets/01/17/steve.jobs.life/index.html Figura 9. Instalando Pure data en Vitalinux. Figura 10. Como acceder a Pure data en Vitalinux una vez está instalado. Figura 11. Usuarios de Linux tras instalar Pure Data en su ordenador sin ningún problema. https://i.pinimg.com/originals/0a/c3/a7/0ac3a7cc84525b75238fde131dcb6af4.gif Entorno Cuando trabajemos con Pd, veremos la Ventana principal de Pd y posiblemente uno o mas "patches", también conocidos como "canvases" o "lienzos". Los "patches" serán los espacios en los que vamos a construir nuestros programas. Ventana principal La ventana principal se abre cuando ejecutamos Pd y tiene esta apariencia: Figura 1. Ventana principal de Pure data. En la parte superior encontramos un menú horizontal que aparecerá también en los patches de Pd. Este es el menú principal que utilizaremos para configurar Pd, realizar acciones y que nos permite interactuar don Pd. En la parte inferior tenemos un espacio para la impresión de contenido desde patches de Pd y/o mensajes del propio Pd. Para imprimir desde un patch utilizaremos principalmente el objeto "print". Este objeto es útil para visualizar el estado de los datos en diferentes partes de la estructura/programa que creemos, nos va a ayudar a encontrar errores y a entender mejor cómo funciona nuestro programa. Los mensajes que Pd envíe aparecen en el mismo espacio y nos dan información acerca de errores y procesos que realiza el programa. El botón de "Log" nos permite filtrar la cantidad de mensajes enviados por Pd que queremos ver en ese espacio. Siendo "0 fatal" la mínima cantidad de información mostrada y "4 todo" la máxima. Inicialmente vamos a tener el Log en "2 normal" y ampliaremos la información mostrada en función de nuestras necesidades a la hora de resolver posibles problemas. Figura 2. Ventana principal de Pure data (izquierda) y un patch/programa de Pure data (derecha). La casilla de "DSP" (Digital Signal Processor) nos permite encender y apagar el sistema de audio/señales del programa. Si el audio esta apagado las señales de audio de nuestros patches no se procesarán, luego siempre que trabajemos con audio debemos de tener el DSP encendido. El DSP también lo podemos encender y apagar desde el menú superior en Medios>Encender DSP o Medios>Apagar DSP; o utilizando los comandos "Ctrl+/" para encenderlo y "Ctrl + ." para apagarlo. Patches Los "patches" son las ventanas en las que construiremos nuestros programas y tienen este aspecto: Figura 3. Un patch de Pure data llamado Untitled-1 en el modo edición. La ventana de patch tiene en la parte superior el mismo menú horizontal que la ventana principal de Pd. Encima del menú veremos el nombre del patch y en qué directorio esta guardado. Cuando estemos en el modo edición entre el nombre del patch y el directorio veremos "[edit]". El modo edición de un patch es el estado de construcción en el que podemos añadir objetos y modificar conexiones o mensajes. Para activar y desactivar el modo edición utilizaremos el comando "Ctrl+E" o en el menu horizontal Editar>Modo edición. Cuando el modo edición este desactivado el programa se estará ejecutando y el puntero del ratón tendrá forma de flecha, estará en el modo de funcionamiento y no podremos modificarlo. Cuando el modo edición este activado el programa seguirá ejecutándose, pero podremos modificarlo y el puntero del ratón tendrá forma de manita. Para crear un patch iremos al menú horizontal Archivo>Nuevo o utilizando el Shortcut/abreviatura "Ctrl+N", y para guardar un patch "Ctrl+S" o en Archivo>Guardar. Vamos a crear nuestro primer patch! ¿Ya lo tenéis? aparecerá una ventanita nueva llamada Untitled, se llama así porque aún no habéis guardado y nombrado el patch. Cuando lo guardéis podréis nombrarlo como queráis. Os recomiendo elegir nombres que os permitan identificar fácilmente que hay dentro. Es conveniente guardar el patch en el que este estemos trabajando para no perder nuestros progresos en caso de que haya un error grave. Ahora vamos a crear nuestro primer mensaje en nuestro patch de Pure Data: en menu horizontal>Poner>Mensaje o utilizando en comando "Ctrl+2". Dentro del mensaje podréis escribir lo que queráis. ¿Funciona? Es posible que el mensaje os parezca muy pequeño y difícil de visualizar cómodamente. Si queremos aumentar el tamaño de los objetos que vamos a colocar en un patch, podemos hacerlo desde el menú horizontal en Editar>Fuente En lugar de editar fuente también podéis modificar el tamaño en Editar>Acercar o con "Ctrl" + "+" y Editar>Alejar o con "Ctrl" + "-". Os recomiendo utilizar acercar, alejar en lugar de modificar el tamaño de la fuente. Figura 4. Opción de acercar en un patch de Pure data llamado Untitled-1 en el modo edición. Figura 5. Opción de alejar en un patch de Pure data llamado Untitled-1 en el modo edición. La opción ordenar ayuda a mantener el patch organizado a nivel visual. Editar>Ordenar o con "Ctrl" + "Shift/Mayus" + "R". Figura 6. Opción de ordenar en un patch de Pure data llamado Untitled-1 en el modo edición. Dentro de un patch podremos crear sub-patches que son ventanitas dentro de nuestra ventana principal del patch, o procesos dentro de nuestro programa principal/algoritmo principal. Los sub-patches nos permitirán agrupar, estructurar y organizar las diferentes partes de un programa con muchos elementos, de manera que la estructura principal de nuestro programa sea visible y comprensible. Cuando el programa se esté ejecutando, aunque la ventana de un sub-patch esté cerrada, está siempre en funcionamiento (Pure Data, 2022). Como ejemplo, una receta de cocina Por ejemplo, estamos siguiendo una receta de un libro de repostería para hacer una tarta. La receta de la tarta sería nuestro algoritmo principal=ventana de patch principal. Esta receta nos pide montar las claras de 5 huevos pero no nos explica como hacerlo, nos indica que en la pagina 6 del libro de cocina están las instrucciones de como montar claras. También, nos pide hacer hojaldre pero tampoco nos explica como hacerlo en la receta de la tarta, nos indica que las instrucciones parar hacer hojaldre se encuentran en la pagina 8. Nuestro algoritmo principal es la receta de la tarta y las instrucciones de la página 6 y la pagina 8 son subalgoritmos necesarios para el algoritmo principal que es nuestra receta. El subpatch sera un subalgoritmo en nuestro programa. Si toda la información de cómo hacer esta tarta, incluyendo cómo montar las claras y hacer hojaldre, se encontrara toda junta en la misma página, nos sería más complicado comprender y visualizar rápidamente el proceso general que debemos seguir para hacerla.    Veremos cómo crear sub patches en el capítulo "Subpatch" pero no os adelantéis. Referencias: Este capitulo ha sido redactado tomando como guía el Capitulo 2 del Manual de Pd. Pure Data (2022). Pd Manual chapter 2: theory of operation. In Pure Data (Version 0.52.2). [Computer software]. Pure Data. https://puredata.info/downloads/pure-data Figuras: Figura 1. Ventana principal de Pure data. Figura 2. Ventana principal de Pure data (izquierda) y un patch/programa de Pure data (derecha). Figura 3. Un patch de Pure data llamado Untitled-1 en el modo edición. Figura 4. Opción de acercar en un patch de Pure data llamado Untitled-1 en el modo edición. Figura 5. Opción de alejar en un patch de Pure data llamado Untitled-1 en el modo edición. Figura 6. Opción de ordenar en un patch de Pure data llamado Untitled-1 en el modo edición. Práctica 1: Hello Pd World (Hola Mundo Pd) Este va a ser vuestro primer programa con Pd y vamos a imprimir en la zona de impresión de la Ventana principal un mensaje que enviemos desde un patch de Pd.  Figura 1. Hello World en Pure Data Enviamos mensajes con Pure Data Lo primero que haremos será crear un patch nuevo. Para ello, iremos al menú horizontal Archivo>Nuevo o utilizando el Shortcut/abreviatura "Ctrl+N". Vamos a crear un mensaje en Pure Data: en menu horizontal>Poner>Mensaje o utilizando en comando "Ctrl+2". En este mensaje vamos a escribir "hola mundo" Ahora necesitamos al mensajero que envíe este mensaje al espacio de impresión, para ello utilizaremos un objeto "print". Creamos un objeto (menu horizontal>Poner>Objeto o utilizando en comando "Ctrl+1) y escribimos print dentro de él. Tras escribir "print" en el objeto, clicaremos fuera de él, veréis como la caja de línea discontinua que lo contiene se convierte en una caja de línea continua, esto os indica que el objeto se ha creado correctamente. Para que este mensaje llegue al objeto "print" tenemos que conectar el outlet/la salida de nuestro mensaje con el inlet/entrada del objeto "print". Una vez conectado, salimos del modo edición ("Ctrl+E" o en el menu horizontal Editar>Modo edición), nuestro programa ya esta marcha. ¿Funciona? Los mensajes no se envían de manera constante, solo cuando una acción o evento activan este envío. Por ejemplo, cuando clicamos sobre el mensaje, su contenido es enviado; cuando un mensaje recibe cualquier otro mensaje (sin importar el contenido del mensaje recibido), el mensaje receptor envía su contenido. Vamos a comprobar esto separando en dos mensajes el "hola mundo". Vamos a editar el mensaje que habíamos creado y borrar la palabra "hola". Crearemos otro mensaje en el que escribiremos la palabra hola y lo conectaremos a nuestro mensaje con la palabra mundo: Cuando hacemos clic en el primer mensaje "hola", este mensaje se envía y llega a la entrada del mensaje "mundo". El mensaje que contiene la palabra mundo se activa, e interpreta el mensaje recibido como una orden de activarse sin importar ni preservar el contenido de este y envía su contenido: la palabra mundo que llega al objeto "print" y se imprime en la zona de impresión de la ventana principal. Por eso el "hola" del primer mensaje no se imprime, el segundo mensaje no guarda ni reenvía el hola recibido, solo envía el contenido que ya tiene, en este caso, mundo. El objeto print también nos va a permitir visualizar valores numéricos. Entramos en el modo edición, creamos una cajita de número variable (menu horizontal>Poner>Numero o utilizando en comando "Ctrl+3") y la conectamos con el objeto print. Salimos del modo edición ("Ctrl+E" o en el menu horizontal Editar>Modo edición) y manteniendo el clic izquierdo sobre la cajita arrastramos el ratón para cambiar el número. Cada vez que el número de esta cajita cambia, es enviado por el outlet o salida. Este elemento NO nos va a permitir enviar su contenido clicando sobre el. Para que envíe su contenido tendremos que hacerle llegar un mensaje de bang, y si queremos cambiar su contenido a traves de su entrada, tendremos que hacerle llegar un valor numérico válido, por ejemplo con un mensaje que contenga dicho valor. Un mensaje con símbolos que no puedan ser interpretados como valores numéricos validos no sera aceptado por la cajita de numero variable y nos mostrara un error en el espacio de impresión, ya que este objeto solo acepta como entradas mensajes de bang o valores numéricos. Ejercicio 1: Después de ver el video y construir el patch de hola mundo. Crea otro patch con tres mensajes que modifiquen el contenido de una cajita de numero variable, e imprime el contenido de la cajita de numero variable en la zona de impresión. ¿Qué tenemos que entregar? El ejercicio 1. Sube a la carpeta del Moodle de la Practica 1 una captura de pantalla y el patch que has creado. El patch debera llamarse: Practica1_nombre_apellido.pd y la imagen Practica1-imagen_nombre_apellido. Figuras: Figura 1: Tomada de "Pure Data Start Here" by Pure Data https://puredata.info/docs/StartHere Referencias: Pure Data (2022). Pure Data Start Here. Pure Data. Consultado el 14 Septiembre 2022 de https://puredata.info/docs/StartHere ¿Qué vamos a hacer en este curso?: Presentación y Cronograma MÓDULO 3: ARDUINO Vamos a aprender qué es Arduino, lo instalaremos y realizaremos nuestras dos primeras prácticas con él ¿Qué es Arduino? ¿Qué es un microcontrolador? Un microcontrolador es un "microordenador" en un chip. Tiene una CPU, RAM (memoria de acceso aleatorio), registros de funciones especiales, memoria ROM de programa, memoria ROM de datos, de uno a varios puertos paralelos de E/S (entrada/salida), y puede tener una gran cantidad de periféricos en el chip que incluyen, pero no se limitan, a un convertidor analógico-digital (ADC), un convertidor digital-analógico (DAC), una UART serie, uno o varios temporizadores, comparadores/referencia de tensión en el chip, módulo de captura/comparación/PWM (Pulse Width Modulation), puerto serie síncrono maestro para comunicaciones SPI (Serial Peripheral Interface)/I2C (Inter Integrated Circuit), puerto USB, puerto ethernet, osciladores en el chip, junto con una serie de otros periféricos. Todo esto nos puede parecer farragoso en un primer momento, pero si lo vemos con imágenes, aplicado a un ejemplo de Arduino en concreto y os lo voy comentando, lo vamos a acabar entendiendo perfectamente. Espera un segundo, pero ¿Arduino es un microcontrolador? Aunque utilicemos Arduino y microcontrolador como sinónimos, un Arduino en realidad es una plataforma de desarrollo que entre otros componentes, contiene un microcontrolador. Junto a este microcontrolador encontraremos una serie de entradas y salidas que nos permitirán añadir interactividad a nuestros proyectos, empleando los sensores y actuadores que hemos mencionado en la página anterior. El nacimiento y propósito de los Arduinos Aquí no vamos a hablar de quiénes o cuándo crearon Arduino, ya que eso lo podemos encontrar fácilmente en este enlace (el cual os aconsejo leer); en cambio, sí que vamos a hablar del propósito inicial con el que fue creado: facilitar la comunicación entre un microcontrolador y otros dispositivos. De esta manera, es sencillo incentivar el desarrollo de procesos creativos y el diseño de proyectos tanto a  personas de una edad temprana, como a aquellas que sin tener conocimientos amplios de informática o electrónica quieran embarcarse a experimentar con proyectos interactivos. El formato de Arduino hace posible que podamos adentrarnos en la electrónica sin sentirnos abrumados con información demasiado técnica. Bueno, a continuación, paso a mostraros la imagen de un Arduino: Como podemos ver, un Arduino cuenta con muchos componentes dentro de su tarjeta, algunos de los cuales ya hemos mencionado en la cita que abre esta página. No voy a entrar a explicar cada uno de ellos, pero sí los más importantes, los que nos ayudarán a entender cómo funciona un microcontrolador y para qué (y para qué no) lo podemos utilizar. Un buen símil para un Arduino es el de una caja negra. ¿Por qué? Porque no vamos a necesitar conocer el funcionamiento de cada parte para poder utilizarlo. Lo que es importante conocer es que cuenta con componentes que son de entrada, otros procesan la información y otros son de salida. ____________     ____________ __________| ENTRADA |-->| PROCESO |-->| SALIDA | A continuación, veremos cuáles son los componentes de entrada, procesamiento y salida sin perder de vista la definición del comienzo de la página. Arduino UNO: partes que debemos conocer Uno de los primeros componentes mencionados es el propio microcontrolador. Y es que, el Arduino en sí ya hemos dicho que no es un microcontrolador, sino una placa de desarrollo. El microcontrolador del Arduino es este: Se llama ATMEGA 328P y es el que tiene el Arduino que vamos emplear en este curso: el Arduino UNO. Pero claro, existen otros tipos de Arduinos, los cuales cuentan con otros microcontroladores. Para profundizar sobre el ATMEGA328P podéis encontrar más información aquí. Bien, este microcontrolador, como podéis ver, cuenta con una serie de 'patitas' a la cuales vamos a llamar pines. (Esta palabra es una de las importantes y la cual vamos a leer en bastantes ocasiones a lo largo de estas páginas). Estos pines son los que nos van a permitir programar, recibir y enviar la información. Para poder acceder a ellos, Arduino nos facilita las cosas con una serie de pines de entrada que encontramos en la imagen siguiente: Como podéis comprobar, esos pines se encuentran a ambos lados del ATMEGA 328P, aunque visualmente no parezcan directamente en contacto. Ya veremos, qué cables y cómo los tenemos que conectar más adelante... Por el momento, nos quedaremos con que esos pines serán los que tendremos que utilizar para conectar los sensores y actuadores. También veremos que algunas de estas entradas son digitales y otras analógicas, pero de eso nos ocuparemos más adelante... Por tanto, nuestro ATMEGA 328P cuenta con una CPU, RAM (memoria de acceso aleatorio), registros de funciones especiales, memoria ROM de programa, memoria ROM de datos, puertos paralelos de E/S (entrada/salida), etc. Para el tipo de proyecto que vamos a construir, no es necesario preocuparse de sobre la ROM ni sobre la RAM, ya que no vamos a escribir programas excesivamente extensos (quizás en el futuro... ). Los componentes que se mencionan en la definición que abre esta página y que sí vamos a necesitar conocer son otros como por ejemplo el puerto USB. En el Arduino UNO, el puerto USB se encuentra aquí: Y el cable que necesitaremos es este, se llama AB USB: Con él, conectaremos nuestro Arduino al ordenador y seremos capaces de programarlo y también de proporcionarle el voltaje necesario para alimentarlo a él y a los sensores que conectemos a él. Tendremos que tener cuidado con qué sensores conectamos, porque algunos de ellos necesitarán más alimentación que la que proporcionamos a nuestro Arduino a través del USB, que son 5V. Algunos sensores y actuadores funcionan a 12V o a voltajes mayores. Para este curso no será una preocupación, porque ninguno de los sensores empleados necesita alimentación extra. No obstante, tendremos que tenerlo en cuenta si en el futuro queremos emplear unos sensores diferentes. Aparte de mediante el USB, es posible alimentar nuestro Arduino UNO utilizando una pila de 9V y un adaptador o un cargador conectado a la corriente con un voltaje de 7 a 12V como máximo. Para saber más sobre las maneras de alimentar nuestro Arduino, puede ser útil este artículo. El lugar al que conectaremos nuestra pila o adaptador es este: Como puedes comprobar, no se han explicado todas las partes que conforman el Arduino UNO. Esto es, porque para los propósitos de este curso no va a ser necesario conocer esta placa en profundidad, sino entender qué función realizan las partes que vamos a utilizar y hacernos una idea general sobre las partes que comparten la mayoría de los Arduinos. FUENTES: Contenido obtenido de: https://libros.catedu.es/books/microcontroladores-vestibles-y-conectados-a-internet/page/comenzamos-microcontroladores Instalar la IDE de Arduino Lo primero que tenemos que hacer es instalar la IDE (Entorno de Desarrollo Integrado) de Arduino en nuestro ordenador. Dependiendo del sistema operativo que empleemos, tendremos que suguir unas instrucciones u otras. A continuación te dejo los enlaces para instalarlo tanto en Windows, Linux o Mac. Arduino IDE LinuxArduino IDE macOSArduino IDE Windows La descarga e instalación nos puede llevar de 5 a 20 minutos, dependiendo de la velocidad de nuestra conexión a internet y del sistema operativo que tengamos, ya que el procedimiento varía notablemente de uno a otro. En este taller, instalamos la IDE de Arduino en nuestro ordenador, aunque si durante la instalación tuviéseis muchos problemas (que no suele ser común, aunque puede suceder si, por ejemplo el ordenador que utilizáis tiene un sistema operativo muy antiguo) podrías utilizar la versión online. Para ello es necesario crear una cuenta en la web de Arduino y seguir los siguientes pasos. Abrimos la aplicación Una vez hayamos instalado la IDE, estaremos listos para abrirla y nos encontraremos con algo muy similar a esto: A través de esta aplicación programaremos nuestro Arduino. Lo primero que vamos a hacer es ver qué podemos hacer con algunos de los botones que utilizaremos con más frecuencia. Comenzaremos de arriba a abajo y de izquierda a derecha. Se recomienda abrir la aplicación para poder ir viendo cada botón conforme se explica su función. Símbolo tick (Verificar): con él, comprobaremos que el código que queremos subir a nuestro Arduino no contiene fallos. ¿Dónde nos comunicará la aplicación si nuestro código tiene fallos o no? Lo veremos en el rectángulo negro de la parte inferior. Esa parte se denomina consola. ¿Siempre que nuestro código pase satisfactoriamente el paso de verifiación nos aseguramos de que funcione correctamente? Pues, desafortunadamente no. Esta verificación nos asegura que no existen fallos sintácticos: palabras mal escritas, expresiones incorrectas... pero no nos asegura que la lógica de nuestro programa sea la correcta. Flecha a la derecha (Cargar): una vez nos hayamos asegurado de que nuestro código es correcto sintácticamente, al darle a la flecha, comenzaremos a subirlo a nuestro Arduino. Hoja de papel (Nuevo): este botón abre una pestaña nueva para que podamos escribir código. No la utilizaremos en este taller. Flecha arriba (Abrir): nos permite abrir un archivo (sketch) existente. Flecha abajo (Guardar): permite guardar el archivo en el que estamos trabajando actualmente. Lupa (monitor serial): abre una ventana que nos permite ver la información serie que la placa transmite. Es muy útil para encontrar fallos en el código y ver si el programa y el Arduino funcionan correctamente. Lo veremos con más detalle en las partes prácticas del taller. Nombre del sketch: en esta pestaña encontraremos el nombre de nuestro sketch. Por defecto será algo similar a sketch_fecha Área de escritura: en esta zona escribiremos nuestro programa. Área de mensajes: en esta parte, el IDE nos indicará si existen errores en el código. Consola de texto: la consola nos mostrará los mensajes de error completos, es muy útil a la hora de depurar nuestro código. Placa y puerto serie: se muestra el nombre de la placa (Arduino) que tenemos conectada (o la última que hemos conectado, si no hay ninguna conectada) y el puerto al que está conectada. Aparte de estas herramientas, contamos con una barra de herramientas en la parte superior (Arduino, Archivo, Editar...). El aspecto de esta barra de herramientas puede variar ligeramente de un sistema operativo a otro, pero las funciones serán las mismas. Algunas de ellas las veremos a continuación. REFERENCIAS:Instalar la IDE de Arduino: https://libros.catedu.es/books/microcontroladores-vestibles-y-conectados-a-internet/page/practica-11-descargar-la-ide-de-arduino-y-encender-un-ledEl puerto serie de nuestro UNO Una parte fundamental de nuestro Arduino es el puerto serie. Gracias a él se comunicará con nuestro ordenador y seremos capaces de enviar y recibir información con nuestro Arduino. ¿Existen otras maneras? Sí, pero esta es la que emplearemos a lo largo de este curso para ver qué valores reciben nuestros sensores a través de la pantalla de nuestro ordenador. Para abrir nuestro puerto serie en Arduino necesitaremos hacer click en la lupa que se encuentra en la parte superior derecha de nuestro sketch: Una vez hayas instalado Arduino, puedes venir a esta sección a probarlo, si no, lo probaremos en las prácticas, no te preocupes. Si tenemos nuestra placa de Arduino conectada, al hacer clic sobre la lupa se nos abrirá esta ventana: Pero si no tenemos nuestro Arduino conectado, nos dará un error similar a este: Existen ciertos parámetros que podemos modificar en la ventana de nuestro puerto serie, dependiendo de a qué velocidad o baudios nos tengamos que comunicar con nuestro Arduino. En la mayoría de los proyectos de este curso no será necesario modificar nada, porque emplearemos los 9600 baudios que aparecen por defecto, solamente en una de las prácticas, necesitaremos cambiar ese valor a 115200 baudios.Práctica 2: Arduino UNO + LED Llegadas a este punto, estamos listas para conectar nuestro Arduino al ordenador. Para ello, necesitaremos nuestro cable USB-AB. Una vez hayamos conectado un extremo a nuestro Arduino y el otro al puerto USB de nuestro ordenador, tendremos que ayudar a la IDE a que reconozca a nuestro Arduino. Lo primero que veremos será un LED VERDE que se enciende y junto al que pone ON. Eso nos indica que la placa está recibiendo corriente desde nuestro ordenador. Los usuarios de Windows (seguramente) tendrán que instalar una serie de drivers una vez se conecte el Arduino al ordenador. Lo siguiente que tendremos que hacer es ir a la barra de herramientas superior y precisamente en Herramientas tendremos que configurar dos cosas, la placa y el puerto. Configuramos la placa En Herramientas > Placa nos aparecerá nuestro Arduino UNO, tendremos que seleccionarlo Al seleccionarla, le estamos diciendo a nuestro Arduino "¡Hey! Prepárate, voy a conectarte un Arduino UNO", por lo que si al final conectásemos otro tipo de Arduino, la IDE no la reconocería y no podríamos programarlo. Si utilizamos otro tipo de Arduino, lo primero que tenemos que hacer es decírselo a Arduino seleccionando la placa correcta en Placa, como acabamos de hacer. Configuramos el puerto Una vez le hemos dicho la placa que vamos a conectar, nuestro IDE necesita saber en qué puerto USB la hemos conectado. Para ello, tendremos que ir a Herramientas > Puerto Para los usuarios de Windows podría tener esta apariencia: (Arduino UNO) Para los de  MAC o Linux, la apariencia puede ser parecida a esta: /dev/cu.usbmodem14112 (Arduino UNO) Una vez hayamos seleccionado nuestra placa y puerto, pasaremos a encender el LED. Y se hizo la luz Para encender nuestro LED, vamos a utilizar un ejemplo de los que se nos proporcionan desde la propia IDE de Arduino. Estos ejemplos nos pueden ser útiles para descubrir lo que podemos hacer con estas placas, por lo que os recomiendo que les echéis un vistazo. El ejemplo que vamos a utilizar se llama Blink y nos va a venir bien para asegurarnos de que la instalación y toda la configuración se han realizado correctamente. Para abrir y subir este ejemplo a nuestro Arduino tenemos que navegar a: Archivo > Ejemplos > 01.Basics > Blink. Una vez hagamos click, se abrirá una nueva ventana de Arduino con el código que permitirá que nuestro LED comience a parpadear. El código que veremos será el siguiente: /* Blink Turns an LED on for one second, then off for one second, repeatedly. Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to the correct LED pin independent of which board is used. If you want to know what pin the on-board LED is connected to on your Arduino model, check the Technical Specs of your board at: https://www.arduino.cc/en/Main/Products modified 8 May 2014 by Scott Fitzgerald modified 2 Sep 2016 by Arturo Guadalupi modified 8 Sep 2016 by Colby Newman This example code is in the public domain. https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink */ // the setup function runs once when you press reset or power the board void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); } // the loop function runs over and over again forever void loop() { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second } Ahora, no vamos a entrar a explicar qué significa este código, eso lo haremos en la página siguiente. Lo que sí vamos a hacer es darle a la flecha a la derecha para subir ese código a nuestro UNO: Y si todo ha ido bien, lo que veremos será un LED naranja, cerca del conector USB, que permanecerá un segundo encendido, un segundo apagado. ¡Y ya lo tenemos! Es posible que nos de algún error y que no funcione. Eso no significa que algo esté roto.Como ya avisé en la primera página del taller, no siempre funciona todo a la primera. Si en la consola vemos algún error, tendremos que asegurarnos de que hemos seleccionado el puerto y la placa correctas y que hemos seguido todos los pasos correctamente, sin olvidar ninguno. ¿Qué tenemos que entregar? Tendrás que subir un video o .gif en el que se vea tu Arduino conectado al ordenador con el LED parpadeando y luego la pantalla de tu ordenador con el sketch abierto. FUENTES:Basado en: https://libros.catedu.es/books/microcontroladores-vestibles-y-conectados-a-internet/page/practica-11-descargar-la-ide-de-arduino-y-encender-un-ledEntender el código para encender un LED Como ya te comenté en la página anterior, lo que vamos a hacer ahora es entender el código que hemos utilizado para programar nuestro Arduino. El lenguaje de programación que empleamos para programar nuestro UNO (o cualquier otro Arduino o placa basada en Arduino que programemos con la IDE que acabamos de descargar) se llama también Arduino y está basado en el lenguaje de programación C++. Diremos que es una versión simplificada de C++. Es importante tener ciertas nociones de inglés para poder programar Arduino, ya que al ser un lenguaje basado en C++, C++ tiene como lenguaje natural de referencia el inglés. Para entender el código que ha iluminado nuestro LED, lo que vamos a hacer es ir viéndolo párrafo a párrafo y así, explicaremos diferentes características que necesitaremos conocer para trabajar en nuestros propios proyectos. ¿Y por qué copiamos código en lugar de escribir el nuestro? Esta pregunta puede venirnos a la cabeza y es normal. A la hora de comenzar a trabajar con Arduino, suelen seguirse los siguientes pasos: 1. Buscar ejemplos similares a lo que queremos hacer2. Entender lo que hace el código y copiarlo 3. Realizar las modificaciones necesarias para adaptarlo a nuestro proyecto ¿Y por qué se suele hacer eso en lugar de escribir código desde cero? Arduino se creó con la finalidad de que gente que no pertenece al mundo de la electrónica y la programación fuese capaz de programar y de realizar proyectos interactivos. Por ello, existe una amplia comunidad de creadores que comparten sus proyectos (tanto el hardware como el software) de manera libre, para que la gente pueda reutilizarlo y adaptarlo a sus necesidades. Muchos de los proyectos que queramos realizar, ya habrán sido realizados antes y además la gente que los comparte suele explicar detalladamente cómo replicarlos y por qué los han realizado de una manera determinada. Aparte de facilitarnos el trabajo, reutilizar código nos puede enseñar funciones y características de Arduino que desconocíamos. Y por supuesto, siempre podremos decidir hacer las cosas de otra manera cuando tengamos los conocimientos suficientes. En algunas ocasiones es bueno intentar crear algo desde cero, pero en muchas ocasiones no es necesario tratar de reinventar la rueda. ¿No estamos plagiando/robando otros proyectos? - No, los proyectos de Arduino que se comparten son de código abierto (open source) y eso significa que podemos reutilizarlos y adaptarlos a nuestras necesidades sin ningún problema. Comencemos a entender el idioma de Arduino Cuando programemos nuestro Arduino, tenemos que tener en mente que el código que escribamos, aparte de ser procesado por nuestro Arduino, es leído por nosotros y por cualquier otra persona que colabore en nuestro proyecto. Como ya se ha comentado, Arduino nació con la finalidad de aproximar la electrónica y la programación a cualquier persona que le interesase sin que sea necesario que tenga amplios conocimientos de programación. Por ello, el trabajo colaborativo y compartir el código es algo muy común. Para que eso se realice correctamente es necesario que nuestro código sea comprensible por nosotros y por cualquiera que pueda trabajar con nosotros en el proyecto. Una manera de explicar y clarificar la finalidad de nuestro código es el uso de comentarios. Los comentarios son aquellas oraciones que no van destinadas a que las procese nuestro Arduino, sino que el destinatario somos nosotros mismos u otras personas. ¿Nosotros mismos? Sí. Imagina que estás trabajando en un proyecto de Arduino, pero que por alguna circunstancia tienes que dejar de trabajar en él y lo retomas un año después. Quizá después de tanto tiempo no recuerdas bien para qué habías escrito ese código... Los comentarios pueden ayudarte en esa tarea. Échale un vistazo a este fragmento de código: /* Blink Turns an LED on for one second, then off for one second, repeatedly. Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to the correct LED pin independent of which board is used. If you want to know what pin the on-board LED is connected to on your Arduino model, check the Technical Specs of your board at: https://www.arduino.cc/en/Main/Products modified 8 May 2014 by Scott Fitzgerald modified 2 Sep 2016 by Arturo Guadalupi modified 8 Sep 2016 by Colby Newman This example code is in the public domain. https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink */ Como puedes ver, se trata de un código separado en párrafos: Blink: Lo primero que nos encontramos es el título del proyecto.Descripción del proyecto: Breve descripción de la finalidad del código y explicación.Modificaciones y autores: Fechas de modificación y los autores que lo han editado. Arduino se basa en compartir y reutilizar código, por ello es necesario indicar quién ha creado ese código y quién lo ha modificado. No debemos apropiarnos del código de otra persona sin mencionarlo. Dominio público: cualquiera puede utilizar este código con los fines que prefiera, comerciales o no.Web: Tutorial en el que se explica el proyecto. Cuando nosotras creemos un proyecto, será necesario que escribamos algo parecido a esto al principio de nuestro código. Y si te has fijado bien, al principio y al final encontramos /* y */ eso nos indica que lo que escribamos entre ambos símbolos es un comentario, sin importar que nos ocupe una línea o varias. Normalmente se utiliza para comentar párrafos.Su función es evitar que Arduino lo lea y que cuando el código sea compilado, se obvie. Si Arduino intentase procesar ese texto escrito en inglés (los comentarios también podríamos hacerlos en español) daría error porque no está escrito en el lenguaje que comprende Arduino. Otra manera de escribir comentarios cuando solamente ocupan una línea es empleando // únicamente al principio. Os invito a que abráis Arduino con el sketch Blink, lo guardéis con otro nombre y hagáis pruebas con el texto de los comentarios. Guardar un archivo preexistente de Arduino Para guardar una copia del sketch Blink, lo que haremos será ir a Archivo > Guardar como...  y ahí se nos abrirá una ventana en la que podremos escribir un nuevo nombre y elegir la ubicación para guardarlo. Yo os recomiendo que para guardar los sketches que escribamos en este taller os creéis una carpeta, por ejemplo en Documentos o en el Escritorio, y ahí Arduino os creará una subcarpeta para cada archivo nuevo que guardemos. Al guardar un archivo por primera vez, se genera el archivo con la extensión .ino y una carpeta que lo contiene. Cada sketch necesita estar dentro de una carpeta con su mismo nombre. ¿Por qué? Nosotros en este taller no vamos a emplear archivos externos aparte del sketch en nuestro proyecto, pero podría darse el caso que para funcionar, los necesitásemos; estos archivos deben estar dentro de la carpeta, sino, el programa no funcionaría correctamente. void setup() Una vez hemos entendido qué son los comentarios y cómo guardar nuestros archivos, vamos a continuar leyendo el código: // the setup function runs once when you press reset or power the board void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); } Lo próximo que nos encontramos (tras el comentario // que ya hemos comentado en el párrafo anterior) son las palabras void setup(). Bueno, la estructura correcta sería esta: void setup() {// aquí escribimos los comandos a ejecutar} Es muy importante que no olvidemos ningún paréntesis ni corchete, o el programa no funcionará. Eso es una función. Y, ¿qué es una función dentro del mundo de Arduino? Una función es un fragmento de código, un subalgoritmo dentro de nuestro algoritmo, que tiene como propósito resolver una tarea determinada. La palabra void, significa que esta función no nos devuelve ningún valor (sea un número, un caracter, un string, etc.) y la palabra reservada setup indica que el código que escribamos entre las llaves {} se ejecutará una sola vez al inicio del programa. Una palabra reservada es aquella que dentro de un lenguaje de programación tiene un significado determinado. Lo iremos entendiendo a lo largo del taller. Más ejemplos. Tienes una lista completa con las funciones que podemos encontrar en Arduino, aquí. En este caso, el código escrito dentro de la función setup() es:   pinMode(LED_BUILTIN, OUTPUT); Esta línea está compuesta por una función y dos palabras reservadas. pinMode(pin, modo) : es una función que nos ayuda a configurar los pines digitales de nuestro Arduino para que funcionen, o bien como entrada, o como salida de la información. El primer parámetro de esta función recibe el número (o en este caso nombre, porque es un pin especial) del pin que vamos a utilizar. El segundo parámetro recibe el modo: INPUT o OUTPUT, si lo vamos a utilizar como pin de entrada o de salida respectivamente. La palabra LED_BUILTIN es una palabra reservada y se refiere al LED que viene dentro de nuestra placa, como se ha comentado en la página anterior. Por tanto en esta línea le estamos diciendo a Arduino: "Oye, coge el pin al que llamas LED_BUILTIN y configúramelo como pin de salida, por favor." Para finalizar, añadimos un ;. Esto es importante, porque sin él tendríamos un error al verificar el código. void loop() // the loop function runs over and over again forever void loop() { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second } Ahora que ya hemos visto qué es una función, nos va a resultar más fácil ver qué es esto de void loop(). Si la función void setup() ejecutaba el código que contenía solamente  una única vez  al arrancar el programa, la función loop lo hace en bucle (como su propio nombre indica), ejecutando indefinidamente el código que escribimos {} entre las llaves. En este caso encontramos dos funciones, la primera es digitalWrite() y la segunda es delay(). digitalWrite(): recibe dos parámetros, el primero es el led que utilizaremos, y que previamente habremos configurado como pin de salida (como hemos hecho con pinMode()), y el segundo es lo que haremos con ese pin. Al ser digital solo existen dos acciones, activar o desactivar el pin (HIGH o LOW). Si la acción es HIGH, el pin tendrá un voltaje de salida de 3.3V si la acción es LOW, el voltaje será 0V. delay(): esta función hace que el arduino se detenga una determinada cantidad de tiempo, medido en milisegundos. Solamente cuenta con un parámetro. Por tanto, a nuestro Arduino, dentro de void loop() le estamos diciendo: "Hey, enciéndeme el LED un segundo y apágalo otro segundo, por favor. Al principio, puede parecer un poco farragoso, pero poco a poco iremos familiarizándonos con el lenguaje de Arduino y nos iremos entendiendo mejor. Para practicar, te aconsejo que modifiques los valores dentro de delay (sin que sean menores a 500ms) y subas esas modificaciones a Arduino, para que veas cómo cambia la frecuencia con la que parpadea el LED. FUENTES:Extraído de: https://libros.catedu.es/books/microcontroladores-vestibles-y-conectados-a-internet/page/entender-el-codigo-para-encender-el-ledPráctica 3: Hello Arduino World (Hola Mundo Arduino) En Arduino, al igual que en Pure Data, tenemos la opción de escribir un programa del tipo 'Hello, World!'. Para ello, solamente necesitaremos nuestro Arduino y el cable USB AB. Lo primero que haremos será conectar nuestro UNO al ordenador. Una vez lo hayamos conectado, abriremos la IDE de Arduino. Si justo has realizado la práctica anterior, no será necesario que selecciones la placa, ya que seguirá figurando tu UNO. Si lo has conectado a otro puerto USB, tendrás que seleccionarlo en Herramientas > Puerto, como hemos hecho en la práctica anterior. Escribimos nuestro código Para esta práctica no vamos a tener que escribir mucho. Lo primero que haremos, en la función setup(), para poder ver escritas nuestras palabras de saludo al mundo, será iniciar la comunicación con el puerto serie en 9600 baudios. Después imprimiremos por el puerto serie las palabras "Hello, World!". Para ello, es necesario que usemos comillas, así la IDE sabe que lo que queremos imprimir es una cadena de caracteres (String). En la función loop() no será necesario que escribamos nada. El código tendrá el siguiente aspecto: void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println("Hello, World!"); } void loop() { // put your main code here, to run repeatedly: Este será el aspecto de nuestro programa en la IDE de Arduino. Cuando lo tengamos, le daremos al botón circular con el símbolo del tick, para verificar y a continuación al botón circular con la flecha hacia la derecha, para subirlo a nuestro UNO: Una vez lo hayamos subido, tendremos que hacer click sobre la lupa de la esquina superior derecha, para abrir el puerto serie: Una vez hayamos hecho click, se abrirá una ventana emergente en la que aparecerán escritas las palabras "Hello, World!": ¿Qué tenemos que entregar? Tendrás que subir un video o .gif en el que se vea tu Arduino conectado al ordenador y luego el puerto serie abierto con las palabras Hello, World! impresas como se ve en la imagen superior. FUENTES:Hello World con Arduino: https://arduinogetstarted.com/tutorials/arduino-hello-world MÓDULO 4: PURE DATA Veremos los elementos básicos, cómo configurar el programa, crearemos nuestro primer patch y experimentaremos con el micrófono Elementos básicos ELEMENTOS En Pure Data trabajaremos con 4 tipos/clase de elementos o cajitas: objetos, mensajes, GUI, y comentarios. Estas cajitas pueden tener 0 o más entradas y/o salidas (Pure Data, 2022). Estas cajitas van a ser contenedores de procesos o datos y las conectaremos unas a otras para crear la estructura que nos permita obtener el resultado deseado. Figura 1. patch que imprime un numero <--- en este patch hay cuatro cajitas de texto: una cajita de numero (que contiene un cero), una caja de objeto que contiene la palabra "print" y dos comentarios que indican la función de las otras dos cajas. Un clic derecho sobre cualquier elemento nos abre un menu con tres opciones: Propiedades, Abrir y Ayuda. Figura 2. Ventana de opciones que aparece al hacer click derecho sobre cualquier elemento de Pure data. Ayuda nos va a abrir un patch sobre ese elemento con una explicación sobre su funcionamiento y ejemplos. Esta explicación está en inglés, si no la entendéis podéis utilizar deeple para traducirla: Figura 3. Patch de ayuda de la interfaz gráfica de cajita de numero variable Mensaje La cajita de Mensaje se representa por un polígono irregular, un rectángulo con dos piquitos en los vertices derechos. El contenido que introduzcamos en una cajita de mensaje en el modo edición no se puede cambiar mientras el programa está fuera del modo de edición, para modificar el contenido de un mensaje tenemos que hacerlo en el modo edición del patch y este contenido se conserva cuando guardamos, cerramos y volvemos a abrir el patch. Los mensajes envían su contenido cuando son activados (generalmente utilizaremos un Bang para activar un mensaje, si queremos que un mensaje se envié dos veces tendremos que activar el bang dos veces). Tambien podemos enviarlo clicando sobre él, esto hace que el mensaje sea considerado también una interfaz gráfica de usuario (GUI). Conectaremos la salida de un mensaje con la entrada de un objeto que sera el destinatario del mensaje. Las salidas de cualquier elemento de pure data se encuentran en la parte inferior de la cajita, y las entradas en la parte superior. Por defecto los caracteres numéricos, por ejemplo, el numero 5, en un mensaje serán considerados float. La palabra "perros" sera considerada symbols, y cuando un mensaje contenga varios elementos separados por un espacio tendremos una lista. Las listas pueden contener elementos de diferentes clases por ejemplo "5 perros" Para colocar un mensaje en nuestro patch: menu horizontal>Poner>Mensaje o utilizando en comando "Ctrl+2" Objeto Los objetos se crean escribiendo texto en una cajita de objeto, y es ese texto el que va a crear un objeto determinado con una función específica. Este texto se divide en atoms separados por un espacio. El primer atom indica que tipo de objeto sera creado, los atoms siguientes, llamados argumentos de creación, indican a Pd como inicializar el objeto, por ejemplo que valor/valores o en qué estado comienza el objeto (Pure Data, 2022).  Hacerlo mas claro, añadir imagen con explicacion La cajita de objeto se representa por un rectángulo, en la parte superior del rectángulo se encuentran las entradas, también llamadas inputs o inlets, marcadas con una pequeña línea gruesa. En la parte inferior se encuentran las salidas, outputs o outlets, marcadas cada una de ellas también con una pequeña línea gruesa. Dependiendo del objeto el número de entradas y salidas variara, y hay objetos que no tienen salida, solo tienen entrada como el "print". Para referirnos a las entradas o salidas empezaremos a contar por la parte izquierda, por ejemplo, el objeto suma que veis a continuación tiene dos entradas, la primera entrada es la que se encuentra a la izquierda y la segunda entrada es la que se encuentra a la derecha. el "+" especifica el tipo de objeto que sera esta cajita, indica que es un objeto de suma y su función sera esa, sumar. Este objeto tiene un argumento que es el "13" indica que cantidad se va a sumar al número que llegue por la entrada izquierda del objeto (Pure Data, 2022): Entrada/input izquierda + 13 = output/salida La cantidad a sumar sera el argumento inicial del objeto ,13, a no ser que introduzcamos otro número por la entrada derecha del objeto. El numero introducido remplazara al 13 y quedara almacenado en el objeto suma. Aunque visualmente en el objeto sigamos viendo "+ 13", su contenido es "+ Ultima Entrada/inlet derecha" Entrada/input izquierda + Ultima Entrada/input derecha  = output/salida Figura 4. patch Suma.pd ¿Hay alguna diferencia entre la entrada izquierda del objeto suma y la entrada derecha? Si las hay, y es importante que las conozcamos. Como regla general el primer inlet de un objeto sera un "hot" inlet o entrada caliente y el resto de inlets serán "cold" inlets o entradas frías. Un valor enviado a una entrada fría sera almacenado por el objeto, pero no activará el proceso de ejecución del objeto y este no emitirá ningún valor por su outlet hasta que la entrada caliente reciba un bang o un valor/mensaje. Los atoms son números o símbolos. Todo aquello que no sea considerado un numero valido sera interpretado por el programa como símbolo. Los números validos pueden contener decimales (12, 15.6, -783) o estar escritos con notación exponencial (7.8e3 = quiere decir 78 multiplicado por 10 tres veces = 7800) (Pure Data, 2022). Los exponenciales negativos dividen entre 10 (69.3e-4= 0,00693) (Pure Data, 2022). Entre números no validos que son leídos como símbolos podemos encontrar expresiones como "+5" "0..6" "casa" y el programa reconoce como símbolos diferentes "hola" , "Hola" y "HOLA" luego diferencia entre mayúsculas y minúsculas (Pure Data, 2022). Los números validos pueden ser de dos tipos: Integer o int = números enteros, sin decimales. Como el numero 5 o el 22. Float = números con decimales. Como el numero 10,85 o el 22,6. Para colocar un objeto en nuestro patch: menu horizontal>Poner>Objeto o utilizando en comando "Ctrl+1" Utilizando un objeto podemos crear una variable que nos permita almacenar datos. ¿Os acordáis de lo que era una variable? Lo vimos en la página "Elementos que debemos de conocer" Tendremos que saber qué tipo se variable queremos almacenar, ya que crearemos un objeto para ese tipo de variable. Si queremos almacenar un numero entero crearemos un objeto "int" o "i", son el mismo objeto, pero podemos escribirlo de estas dos maneras, una de ellas ocupa mucho menos espacio y nos va ser mucho más cómoda cuando tengamos muchos objetos en nuestro patch. Si queremos almacenar un numero decimal crearemos un objeto "float" o "f". En la carpeta de Elementos básicos que os he dejado encontrareis el patch Variables-Integer-Float.pd donde podréis probar estos objetos: Figura 5. patch Variables-Integer-Float.pd Los objetos de variables int y float funcionan siguiendo el esquema de entrada caliente y entrada fría que explicábamos antes. Los valores que lleguen al inlet derechos serán almacenados, pero no serán enviados hasta que el inlet izquierdo reciba un bang. Los valores recibidos en el inlet izquierdo serán almacenados y enviados inmediatamente al ser recibidos. Podéis comprobarlo en el patch Variables-Integer-Float.pd. Para más información de cualquier elemento de Pure Data accederemos a el patch de ayuda que encontraremos clicando sobre el elemento con el botón derecho y seleccionando Ayuda. Este patch en ingles explica la funcionalidad y posibilidades del elemento. Cuando trabajemos con señales de audio utilizaremos objetos específicos de audio. Estos objetos siempre contienen el símbolo de virgulilla : "~" y a diferencia de los objetos de control/Data flow que realizan su función únicamente cuando sucede un evento y los activa (ejemplo: un el clic sobre un mensaje, la llegada de un símbolo a un print), los objetos de audio procesan y envian señal constantemente sin necesidad de eventos que los activen. La señal de audio sera un flujo constante de datos y visualmente la podremos diferenciar como una línea más gruesa que une distintas cajitas. Figura 6. patch Senial.pd Cada objeto dependiendo de su función va a esperar un tipo de inlets, y si intentamos conectar un envió con un inlet cuyo tipo no corresponde, la conexión no se hara, veremos que la línea no queda conectada, o veremos un error marcado en rojo en la zona de impresión de la ventanita de pd: Figura 7. Ventana principal de Pd con mensajes en la consola. En la ventana superior el mensaje en rojo dice que no podemos conectar una salida de una señal de audio a una entrada que no es de señal. Este mensaje ha aparecido al intentar conectar la salida del objeto "osc~" con un bang. Si no sabéis el tipo que inlets que espera un objeto podéis entrar en su patch de ayuda y ahi abrir el subpatch "pd reference": Figura 8. patch de ayuda y subpatch "pd reference" del objeto "osc~" Lista de objetos: Lista de objetos de Pure Data Vanilla + librerías externas: https://puredata.info/docs/ListOfPdExternals/ Aqui os dejo una lista con objetos de Pure Data y su función. Tambien podréis ver si pertenecen a Pure Data Vanilla, que es el programa base sobre el que trabajamos o si forman parte de alguna librería, si forman parte de alguna librería los llamaremos objetos extended y tendremos que instalar esa librería para poder utilizar esos objetos. A utilizar librerías aprenderemos más adelante. GUI (Graphical User Interface/ Interfaz Gráfica de Usuario) Las interfaces graficas de usuario (GUI) son elementos cuya apariencia puede variar cuando el programa está en funcionamiento, a diferencia de los objetos y mensajes que por lo general tienen una apariencia estática. Alguno de estos elementos es interactivo y nos van a permitir modificar parámetros desde el ratón y/o visualizar cambios o estados cuando el programa este en funcionando. Tienen diferentes formas y funciones. Estas son algunas de las más utilizadas: Cajita de número La cajita de número se representa por un rectángulo truncado en su esquina superior derecha. Este elemento nos permite almacenar y visualizar el número que llegue por el inlet a través de un mensaje u objeto. Podremos modificar el numero almacenado con el ratón clicando y arrastrando arriba o abajo cuando el programa este en ejecución. Este elemento enviara el número que contiene cuando este varíe o cuando reciba un evento ej. (bang). Si el número no varía y no recibe ningún bang, la cajita de número no envía nada y a diferencia del mensaje que con un clic hacemos que se envíe, sobre este, el click de ratón no hará que la cajita de numero envíe su contenido. Figura 9. patch Suma.pd Clic derecho en el objeto>Propiedades = nos permite modificar tamaño, limites, etiquetas ... Para colocar una caja de numero en nuestro patch: menu horizontal>Poner>Numero o utilizando en comando "Ctrl+3" Ejercicio 1: Realizar una suma de dos números contenidos en dos mensajes e imprimir el resultado en la ventana principal. Ejercicio 2: Realizar una suma utilizando dos cajitas de numero variable. Ves alguna diferencia entre el inlet derecho de la suma y el inlet izquierdo? Si la hubiere como afecta esta diferencia al output del objeto suma? Bang Este elemento es un botón que nos permite enviar un "impulso" o "mensaje de bang" cuando es activado: bien clicando sobre él, o cuando recibe cualquier mensaje en su entrada, da igual el contenido del mensaje. Frecuentemente utilizaremos el bang para activar otros elementos y nos va permitir visualizar cuando hay flujo de datos entre otros objetos. El mensaje de bang le dice a otros objetos: actúa! para que realicen su función. Y a nosotros nos dice que algo ha llegado. Su forma GUI se representa con un cuadrado con un circulo circunscrito, cuando el bang se activa el circulo cambia momentaneamente de color, nos indica que ha recibido cualquier mensaje y enviado un mensaje de bang. En la parte superior izquierda tiene una entrada y en la parte inferior izquierda una salida. Clic derecho en el objeto>Propiedades = nos permite modificar tamaño, color, etiquetas ... Para colocar un bang en nuestro patch: menu horizontal>Poner>Bang o utilizando en comando "Shift+Ctrl+B" El bang se puede crear también como objeto: "bang" o "b" y realiza la misma función que su version GUI pero no permite al usuario activarlo desde el ratón ni visualiza su actividad. Podremos encontrarlo también en forma de mensaje con el texto "bang" Figura 10. Posible formas que tiene el bang en Pd. (Interfaz grafica, Objetos y Mensaje) Ejercicio 3: Abrir el patch de ayuda del objeto suma (binops-help.pd). Dentro del patch de ayuda del objeto suma, abrir el subpatch "pd reference" para obtener más información acerca del funcionamiento de los objetos "operadores aritméticos". Utiliza deeple para traducir el texto en ingles del patch de ayuda que no comprendas. Responde las siguientes preguntas: 3.1 - Que sale del output derecho del objeto trigger ([t b f]) en el primer ejemplo del patch? ¿Y del output izquierdo? Utiliza el objeto print para comprobarlo. Figura 11. primer ejemplo del patch de ayuda del objeto "+" 3.2 - Que utilidad tiene el objeto trigger ([t b f])? Abre el patch de ayuda de este objeto para descubrilo. 3.3 - Qué pasaría si prescindiéramos del objeto trigger en este ejemplo y conectáramos la cajita de numero variable del lado derecho directamente al inlet derecho de los operadores? Ejercicio 4: En el caso anterior sustituye el objeto trigger ([t b f]) por un bang y reconecta las cajitas para obtener la misma funcionalidad que con el objeto trigger ([t b f]). Ejercicio 5: ¡Reto! Construye un programa en Pd que imprima el resultado de la siguiente ecuación: (2X + 4) x (3Y -20). Pista: X e Y serán cajitas de numero variable. Cuando queramos que un bang se envíe automáticamente al abrir un patch utilizaremos el objeto "loadbang": Figura 12. Objeto "loadbang" Toggle Este objeto GUI tiene dos estados: apagado y encendido. Podemos cambiar el estado del objeto clicando sobre él o enviando un valor o mensaje a su inlet. Cuando recibe un valor igual a 0 en su entrada, el estado del toggle cambiara a apagado y emitira por su la salida el valor 0. Visualmente reconoceremos el estado de apagado como un cuadrado blanco vacío. Al cambiar el estado a encendido, clicando sobre el o cuando recibe en su entrada un numero distinto de 0, la salida del toggle emitirá ese numero distinto de cero y reconoceremos este estado por una cruz dentro del cuadrado. Un toggle encendido, por defecto emitirá un 1, a no ser que reciba otro valor numérico. Un clic de ratón sobre el objeto o un mensaje de bang cambian el estado del objeto, si este está encendido cambiara a apagado y emitirá un 0, y si esta apagado cambiara a encendido y emitirá un 1. Un input numérico distinto de zero posiciona siempre el toggle en estado de encendido y un input igual a cero lo cambia o mantiene en estado apagado. El toggle emite un valor por su salida cada vez que el valor de entrada cambie aunque este valor no haga que cambie su estado. Frecuentemente utilizaremos el toggle para activar o cambiar de estado otros elementos y nos va permitir visualizar el estado de esos elementos. Figura 13. patch Toggle.pd. Toggle apagado y su output, Toggle encendido y su output predeterminado. Si el input del toggle es un numero distinto de 0 y distinto de 1, por ejemplo, el 5, el toggle estará en el estado de encendido y emitirá un 5 por su output, si después de ese 5 enviamos un 6 al input del toggle el estado de este no cambiará y permanecerá encendido, pero emitirá el numero 6. Figura 14. patch Toggle.pd. Estado de Toggle y que outlet proporciona en función de su inlet. Para cambiar el estado del toggle sin que emita ningún valor a su salida se utiliza el mensaje "set 0" para apagarlo y "set (valor distinto de 0)" para encenderlo. (hacer un gif de esto) Figura 15. patch Toggle.pd. Mensaje "set" para cambiar el estado del toggle sin que emita ningún valor. Para colocar un toggle en nuestro patch desde el menu horizontal en Poner>Toggle o utilizando en comando "Shift+Ctrl+T" Clic derecho en el objeto>Propiedades = nos permite modificar tamaño, color, etiquetas ... Figura 16. Ventana de propiedades de Toggle. En el patch de Lista de objetos (help-intro.pd) que se encuentra en menu horizontal>Ayuda>Lista de objetos hay un sub-patch llamado "all_guis" que nos muestra todas las interfaces graficas de Pd Vanilla. Comentarios Los comentarios visualmente no aparecen en ninguna cajita ni tienen entradas/inputs ni salidas/outputs. El texto introducido en los comentarios es información que no sera interpretada por la maquina como elementos transformadores del programa/patch que estamos construyendo. Estos comentarios contienen información dirigida a las personas, notas que tomareis para vosotros mismos relacionadas con el funcionamiento del patch que estéis construyendo o notas para facilitar a otras personas la comprensión del patch que habéis creado. Son muy útiles para escribir recordatorios o explicaciones durante el proceso de trabajo y para etiquetar las diferentes partes de las estructuras que hagáis. Para colocar un comentario en nuestro patch desde el menu horizontal en Poner>Comentario o utilizando en comando "Ctrl+5". Para editar un comentario clicamos sobre el cuando estemos en el modo edición. Este capítulo ha sido redactado tomando como guía el Capitulo 2 del Manual de Pd. Referencias: Pure Data (2022). Pd Manual chapter 2: theory of operation. In Pure Data (Version 0.52.2). [Computer software]. Pure Data. https://puredata.info/downloads/pure-data http://puredata.info/docs/manuals/pd/ Figuras: Figura 1. patch que imprime un numero. Figura 2. Ventana de opciones que aparece al hacer click derecho sobre cualquier elemento de Pure data. Figura 3. Patch de ayuda de la interfaz gráfica de cajita de numero variable Figura 4. patch Suma.pd Figura 5. patch Variables-Integer-Float.pd Figura 6. patch Senial.pd Figura 7. Ventana principal de Pd con mensajes en la consola. Figura 8. patch de ayuda y subpatch "pd reference" del objeto "osc~" Figura 9. patch Suma.pd Figura 10. Posible formas que tiene el bang en Pd. (Interfaz grafica, Objetos y Mensaje) Figura 11. primer ejemplo del patch de ayuda del objeto "+" Figura 12. Objeto "loadbang" Figura 13. patch Toggle.pd. Toggle apagado y su output, Toggle encendido y su output predeterminado. Figura 14. patch Toggle.pd. Estado de Toggle y que outlet proporciona en función de su inlet. Figura 15. patch Toggle.pd. Mensaje "set" para cambiar el estado del toggle sin que emita ningún valor. Figura 16. Ventana de propiedades de Toggle.Configuración de Audio en Pure Data y notación MIDI RECOMENDACIÓN: os aconsejo trabajar con altavoces, no con cascos. El sonido puede hacer daño a los oídos si no controláis el volumen. Cuando hablemos de sonido en el ámbito digital, por ejemplo, dentro de un programa, nos referimos a una representación del sonido dentro de este entorno. Se trata de una representación que podemos manipular. De esta manera, podemos diseñar sonidos desde un ordenador, pero sonido como tal solo sera lo que el altavoz produce. Para diferenciarlo llamaremos a esta representación señal de audio, ya que es una señal cuyo ultimo propósito será hacer vibrar la membrana de un altavoz para generar esa onda mecánica que conocemos como sonido.  ¿Qué es una tarjeta de sonido? Es la parte del hardware de vuestro ordenador que se encarga de gestionar el procesamiento de audio y, sobre todo, de convertir datos en señales eléctricas que permitan controlar el movimiento de un altavoz, o de traducir a datos digitales las señales eléctricas generadas por un micrófono que registra el sonido de una voz. Cuando hablamos de señal, nos estamos refiriendo a una onda, que en el programa se representa como una rápida secuencia de números. Digamos que estos valores indican la posición de un punto de la onda en el momento en que se generan. Vuestros ordenadores tienen una tarjeta de audio integrada, pero existen también tarjetas de audio externas que se pueden conectar al ordenador. Si no sabéis si tenéis una tarjeta de audio interna o externa, quiere decir que tenéis una tarjeta de audio interna, que está dentro del ordenador. Configuración del audio en Pure Data Vamos a ver dónde está la configuración de Audio de Pure Data y si tenéis que cambiar algo. La ventana de configuración de audio está en Menu horizontal>Archivo>Preferencias>Audio... Sample rate o frecuencia de sampleo Es el número de valores por segundo que definen una onda. La mayoría de las tarjetas de sonido funcionan a 44.000 Hz, que es la frecuencia que viene predeterminada en la configuración de Pure data, o a 48.000 Hz. Tendréis que configurar este parámetro para que coincida con el de vuestra tarjeta de sonido. En mi caso utilizo una tarjeta de sonido externa que actualmente tengo configurada a 48 kHz, por lo que utilizaré la misma frecuencia en mi configuración de Pure Data. Figura 1. Configuración de audio de Pure Data (izquierda), configuración de tarjeta de sonido externa (derecha) Latencia, Retardo o delay Es el tiempo que tarda desde el momento en que se ejecuta una acción hasta que percibimos su resultado, por ejemplo; desde que apretamos el botón de play hasta que el sonido sale por los altavoces y podemos escucharlo. Las latencias cortas transmiten la sensación de mayor responsive, ya que el resultado de una acción es percibido inmediatamente. Sin embargo, una latencia demasiado corta puede provocar interrupciones o errores en el sonido (clics, pums, craks ...), ya que el ordenador no tiene tiempo suficiente para terminar de procesar los datos antes de enviarlos. Así que, si os encontráis con este problema, probad a aumentar la latencia. En mi caso configuraré la latencia en 80 milisegundos. Tamaño de Bloque o Buffer Size. Este parámetro está relacionado con la latencia y vamos a dejarlo en 64. Dispositivos de Entrada Aquí, podemos configurar qué entradas y a través de qué tarjeta vamos a recibir señal de audio en Pure Data, por ejemplo, el micrófono interno de vuestro ordenador. En mi caso, es la entrada que aparece configurada en la Figura 2. Fijaros que la cajita de la izquierda este activada. Figura 2. Dispositivos de entrada y salida en la configuración de audio de Pure Data. Dispositivos de Salida Este apartado nos permitir configurar a través de qué salidas se enviará el audio que creemos en Pure Data. En mi caso como tengo una tarjeta de audio externa a la que tengo conectados mis altavoces, la salida que selecciono será la de mi tarjeta de sonido: OUT 1-2 (MOTU M Series) Los dispositivos de salida y entrada en vuestros ordenadores van a tener diferentes nombres dependiendo del ordenador o tarjeta que tengáis, así que, no esperéis encontrar los mismos que aparecen en las imágenes que os pongo. Cuando empecemos a trabajar con sonido, si algo no va bien, volveremos a esta página para revisar nuestra configuración de audio MIDI " MIDI (siglas de Musical Instrument Digital Interface) es un estándar tecnológico que describe un protocolo, una interfaz digital y conectores que permiten que varios instrumentos musicales electrónicos, ordenadores y otros dispositivos relacionados se conecten y comuniquen entre sí.​" (Wikipedia) "El sistema MIDI transporta mensajes de eventos que especifican notación musical, tono y velocidad (intensidad); señales de control para parámetros musicales como lo son la dinámica, el vibrato, panoramización en dos dimensiones, cues y señales de reloj que establecen y sincronizan el tempo entre varios dispositivos." (Wikipedia) A nosotros, del MIDI nos interesa la codificación de la frecuencia que utiliza para las notas musicales, para trabajar con la escala musical diatónica (Do, Re, Mi ...). En MIDI a cada nota de la escala musical se le asigna un número del 0 al 127. Siendo el 0 igual al DO de la octava -1, que a su vez es una onda de 8,175799 Hz. La nota MIDI 127 corresponde con un Sol de la octava 9, y la frecuencia de esta onda es de 12.543,853516 Hz. Tabla de equivalencia MIDI: Figura 3. Tabla de equivalencia MIDI (Nota | Valor MIDI | Frecuencia en Hz) Como habíamos visto en la página "Las Ondas y el Sonido", la frecuencia es lo que determina qué tan agudo o grave suena un sonido. Determina el tono, la nota. Cuando trabajemos con osciladores en Pure Data tendremos que introducir la frecuencia de la onda que queramos generar en Hz, por lo que si queremos trabajar con la notación MIDI necesitaremos un objeto que traduzca de MIDI a Hz. El objeto "mtof" (midi to frequency) convierte valores de MIDI a Hz. Y si queremos pasar de Hz a MIDI utilizaremos el objeto "ftom" que convierte valores de Hz a MIDI. Estos objetos reciben valores numéricos y devuelven valores numéricos. Inlet (float), outlet (float). Abrir el patch MIDI-Hz-Tono-Frecuencia.pd para probar estos objetos. Figura 4. patch MIDI-Hz-Tono-Frecuencia.pd. Los que tengáis un controlador MIDI podéis conectarlo a Pure Data, pero en este curso no lo vamos a explicar. Podéis buscar información en internet de cómo hacerlo o preguntar en una tutoría. Figuras: Figura 1. Configuración de audio de Pure Data (izquierda), configuración de tarjeta de sonido externa (derecha). Figura 2. Dispositivos de entrada y salida en la configuración de audio de Pure Data. Figura 3. Tabla de equivalencia MIDI (Nota | Valor MIDI | Frecuencia en Hz). https://cmtext.indiana.edu/appendices/appendix_B.php Figura 4. patch MIDI-Hz-Tono-Frecuencia.pd. Referencias: https://es.wikipedia.org/wiki/MIDI https://archive.flossmanuals.net/pure-data/getting-started/configuring.html Práctica 4: Nuestro primer patch sonoro ¿Qué elementos nuevos introduciremos en esta práctica? Figura 1. Gatos con un metrónomo. metro Este objeto va a ser nuestro metrónomo en Pure Data y nos va a permitir enviar un bang cada tantos milisegundos. Por ejemplo, un metro con un argumento de 10.000 enviara un bang cada 10.000 milisegundos, que es lo mismo que cada 10 segundos. Este objeto nos va a permitir por ejemplo crear ritmos o secuenciar acciones. Para que el metro funcione y comience a enviar bangs, tendremos que configurar sus parámetros y activarlo con un número distinto de 0. Para activarlo podemos enviar al inlet izquierdo un bang, un toggle encendido, o un mensaje con un valor numérico. Si queremos que deje de enviar bangs, tendremos que pararlo con un mensaje de stop o un valor igual a 0. En este caso, el toggle estará apagado y el mensaje contendrá el numero 0. El primer argumento del metro (float) indica el tiempo entre bangs que por defecto está en milisegundos. El segundo argumento (float) nos permite modificar el tempo de la velocidad que ha configurado el primer argumento. El tercer argumento (symbol) nos permite configurar las unidades, por ejemplo, en segundos con la palabra "second". También podremos modificar el tempo a través de un mensaje con los siguientes datos: la palabra "tempo", el valor del tempo y la unidad del tiempo. Figura 2. patch metro-demo.pd. Cuatro formas diferentes de configurar el objeto metro para que emita un bang por segundo. A través del inlet de la derecha también podremos configurar el tiempo entre bangs una vez el metro esté corriendo. Para ello, utilizaremos una cajita de numero variable o un mensaje. Si en la figura x enviamos el mensaje "stop" al metro, la emisión de bangs se detendrá. Si enviamos 294 a traves del inlet derecho, en lugar de emir bangs cada 1000 milisegundos el metro, emitirá bangs cada 294 milisegundos. Figura 3. patch metro-demo.pd. Objeto metro que emite bangs cada 294 milisegundos. line~ Figura 4. Tortuga deslizándose por una rampa. El objeto "line~" genera rampas lineales entre dos valores en un tiempo determinado. Su outlet está en formato de señal. (Tambien podremos encontrar el objeto "line" que hace lo mismo, pero emitiendo una sucesión de números en lugar de una señal.) Los parámetros de la rampa se determinan en los argumentos del objeto o por los mensajes recibidos en los inlets de line. Por ejemplo, generar una secuencia de valores entre 2 y 5 en 100 milisegundos. Enviando un mensaje al inlet izquierdo podremos configurar los valores de partida, destino y el tiempo de nuestra rampa. Abre el patch line-snapshot-demo.pd para probar este objeto. Figura 5. patch line-snapshot-demo.pd. Veamos cómo tenemos que construir los mensajes para controlar nuestra rampa: El tiempo también podremos configurarlo con el inlet derecho. Un mensaje con único valor indicará el valor del destino. El line de la imagen ira al valor 5 en 64 milisegundos. Figura 6. patch line-snapshot-demo.pd. objeto line~ que recibe un mensaje con la configuración: destino=5. Y el tiempo de la rampa se configura a traves del inlet derecho. Cuando enviemos un mensaje con dos valores separados por un espacio, el primer valor del mensaje indicara el valor del destino y el segundo valor el tiempo que se tomara en llegar a ese valor de destino. El line de la imagen siguiente ira al valor 5 en 100 milisegundos. Figura 7. patch line-snapshot-demo.pd. objeto line~ que recibe un mensaje con la configuración: destino=5, tiempo=100. Enviamos un mensaje con tres valores, los dos primeros separados por "coma" "espacio" y el segundo y el tercero por un "espacio"; el primer valor indicara el valor de partida, el segundo el valor de destino y el tercero el tiempo requerido para ir desde el valor de partida al valor de destino. El line de la imagen siguiente ira desde el valor 2 al valor 5 en 100 milisegundos. Figura 8. patch line-snapshot-demo.pd. objeto line~ que recibe un mensaje con la configuración: Inicio=2, destino=5, tiempo=100. Si no especificamos el tiempo, saltará directamente al valor de destino. Si queremos detener la progresión de la rampa enviaremos un mensaje con la palabra "stop". El ultimo valor generado antes de parar la progresión, o el valor de destino de la rampa en caso de que la progresión no se detenga y llegue al final, quedará almacenado. Cuando no especifiquemos un valor de partida, tomará como valor de partida ese valor almacenado en la interacción anterior. Cuando no haya habido una interacción anterior el valor de partida por defecto sera 0. El line de la imagen siguiente irá desde el valor 2 al valor 5 en 100 milisegundos. Si recibe el mensaje stop, detendrá la progresión. Figura 9. patch line-snapshot-demo.pd. objeto line~ que recibe un mensaje con la palabra "stop" snapshot~ Figura 10. El "snapshot~" haciendo una foto de la señal cada vez que le llega un bang. El snapshot~ permite convertir una señal en valores numéricos. Esto nos será muy útil cuando queramos enviar valores procedentes de una señal de audio a un objeto que no sea de audio. Recordad que los objetos que no son de audio no tienen la "~" y no aceptan señales de audio como input. Este objeto nos será útil para visualizar qué sucede con nuestras señales de audio. Cada vez que recibe un bang registra el valor que tiene la señal que llega la inlet en ese momento, sería el equivalente a la posición de una partícula afectada por una onda en un momento determinado. Figura 11. ejemplo del objeto "snapshot~" Ejercicio 6: Abre los patches de ejemplo: line-snapshot-demo.pd y metro-demo.pd y prueba el funcionamiento de los objetos que acabamos de ver. Encontrarás los patches en el material de este apartado ¿Tienes alguna duda? env~ Similar al "snapshot~", el envelope follower: "env~" recibe una señal y saca por su salida la amplitud de esta señal, pero en dB, con una equivalencia de 1 igual a 100 dB. Este objeto recibe una señal y devuelve valores numéricos. Nos será muy útil para conocer el volumen de nuestra señal en dB y también para visualizar ese volumen en el VU meter que vamos a presentar a continuación. Recordad que en el apartado "Las ondas y el sonido",  habíamos visto que el volumen es la intensidad con la que percibimos un sonido. Es una magnitud que relaciona la amplitud de una onda sonora y la percepción humana de esta onda. VU meter Podremos crear este objeto desde el menu>poner>VU Meter o escribiendo "vu" en un objeto. Este objeto es una interfaz gráfica que representa el nivel de señal como el que podemos encontrar en el master de una mesa de mezclas, o de un canal en programas como Ableton Live. Nos va a indicar el volumen de la señal. Figura 12. Representación de un VU meter. El rango un VU meter va de valores negativos a valores positivos. Los valores mínimo y máximo varían en cada aparato o programa, sin embargo, el 0 sera el valor de referencia en todos ellos. Y un código de colores nos ayudara a leer esa escala. El verde nos indica un nivel de señal adecuado, el amarillo nos indica un nivel de señal próximo al límite entre un nivel adecuado y un nivel excesivo, y el rojo nos indica un nivel de señal excesivo que debemos evitar y a partir del cual consideraremos que nuestra señal esta "picando" y se va a distorsionar. En Pure data el VU-meter tiene un rango visible de -100 a 12, y el 0 va a ser nuestro límite de pico entre señal adecuada y señal excesiva. Ya que el envelope nos proporcionará valores con una igualdad de 100 dB a 1 unidad de amplitud, tendremos que restar 100 a la salida del envelope para enviar un valor adecuado al VU meter. Figura 13. patch Envelope-Vumeter-demo.pd Slider Figura 14. Slider en funcionamiento. (no es Pure Data) El slider es una interfaz gráfica que nos permite enviar valores repartidos en un rango determinado, colocando y moviendo un indicador en cualquier posición de la representación de ese rango. Para mover el indicador, clicaremos sobre el elemento y manteniendo el click pulsado moveremos el ratón. En caso de necesitar mas precisión a la hora de ajustar la posición del indicador, realizaremos la acción anteriormente mencionada mientras pulsamos la tecla SHIFT o MAYUS. Tambien podremos modificar la posición del indicador enviado un mensaje con el valor que queramos al inlet del slide. Esta representación podrá ser vertical u horizontal y configuraremos los valores mínimo y máximo de su rango, haciendo click derecho sobre el slider>Propiedades>Rango de Salida. En propiedades también podremos configurar los colores, etiqueta o tamaño del slider. Figura 15. patch Slider-demo.pd. Slider vertical a la izquierda y Slider horizontal a la derecha con sus ventanas de propiedades. El slider por defecto tiene un rango de 0 a 127, rango que tendremos que ajustar a nuestras necesidades. Este objeto nos va a ser extremadamente útil para regular el volumen. Ajustaremos su rango de 0 a 0.5 o, como máximo, de 0 a 1. Oscilador y *~ Figura 16. Personita generando una onda de 293.6 Hz. El objeto osc~ es un generador de ondas sinusoidales, también conocidas como ondas puras. Debe recibir en su inlet izquierdo la frecuencia de la onda que queramos generar en valores en Hz. Este objeto va a generar una onda con una amplitud de 1, lo que quiere decir que generara valores correspondientes a esa onda sinusoidal de -1 a 1. Figura 17. La onda Sinusoidal que genera el "osc~". En Pure Data se parte de la equivalencia de 1 unidad de amplitud igual a 100 dB. Recordad que los dB median la intensidad sonora percibida y que esta tiene una relación logarítmica a la amplitud, no lineal. Por lo tanto, aunque 1 unidad de amplitud equivalga a 100dB, 0,5 unidades de amplitud NO equivalen a 50 dB, 0,5 unidades de amplitud equivalen a unos 90 dB. El objeto "*~" nos va a permitir controlar/modular la amplitud de una señal multiplicándola por un valor numérico o por otra señal.  En el ejemplo del patch osc-demo.pd la multiplicamos por un valor numérico del tipo float. Cuando multipliquemos por valores situados entre 0 y 1 estaremos disminuyendo la amplitud de la señal. Valores mayores de 1 estarán aumentando la amplitud de la señal. Para el control de volumen siempre multiplicaremos por valores ente 0 y 1. Más adelante también utilizaremos este objeto para mezclar señales. Sus inlets esperan una señal o un valor numérico, y su outlet es una señal. Abrid el patch osc-demo.pd que encontraré deis en el material que os damos para la Practica 2. Vamos a ver esto con un ejemplo en el que utilizaremos algunos de los objetos que hemos visto anteriormente. el snapshot~: para ver el valor de la señal en un momento determinado el env~: para transformar la amplitud de la señal en dB. el VU: visualizar el volumen en dB. el metro para hacer la foto de la señal con el "snapshot~" la slider para controlar el volumen. Figura 18. patch osc-demo.pd. El "osc~" de la figura 17, genera una onda sinusoidal de 293,6 Hz de frecuencia. La amplitud de esa onda se reduce multiplicándola por 0,1333 en el objeto "*~". El "env~" registra la amplitud de la señal que le llega y la convierte a dB, con una equivalencia de 100 dB a 1 unidad de amplitud. Restamos 100 al volumen que proporciona el "env~" para poder visualizar el volumen en el VU meter. ¿Alguna duda de cómo funciona el patch osc-demo.pd? MIDI to frequency: mtof Esto ya lo hemos visto en "Configuración de Audio en Pure Data y notación MIDI". Como bien sabemos, el oscilador habla el idioma de los Hz y en este idioma interpretará los valores que reciba. El objeto "mtof" convierte valores numéricos de MIDI a valores numéricos de Hz. Nos será muy útil para trabajar con los valores de la escala musical diatónica (Do, Re, Mi ...). Este objeto recibe valores numéricos y devuelve valores numéricos. Inlet (float), outlet (float) Figura 19. patch mtof-ftom-demo.pd. Conversion de MIDI a Hz con el objeto mtof. Figura 20. Transformer civil pasando de Hz a MIDI Frequency to MIDI: ftom El objeto "ftom" objeto realiza el proceso inverso a "mtof", convierte valores numéricos de Hz a valores numéricos de MIDI. Inlet (float), outlet (float). Figura 21. patch mtof-ftom-demo.pd. Conversion de MIDI a Hz con el objeto mtof, y de Hz a MIDI con el objeto ftom. Tabwrite~ y Array (GUI) El objeto "tabwrite~" nos permite almacenar los valores de una señal de manera secuencial en un vector. Podremos visualizar este vector con la interfaz gráfica "Array", que es una especie de lienzo. Para colocar un array en nuestro patch: menu horizontal>Poner>Array o utilizando en comando "Mayus/Shift+Ctrl+A" ¿Pero qué es un vector en programación? Es una lista de valores almacenados de manera secuencial. Figura 22. Diagrama de un vector. El argumento del "tabwrite~" indicará el nombre del vector y para que empiece a registrar los valores que le llegan tendremos que enviar un bang. Cuando el vector se llene dejará de registrar valores y si queremos que vuelva a registrar tendremos que enviar otro bang. El vector almacenará 100 valores por defecto. Si queremos modificar su tamaño, haremos click derecho sobre Lienzo>Propiedades>Propiedades del array>Tamaño. En propiedades del array también podremos ver la lista de valores almacenados clicando en "Ver Lista ...". Para modificar parámetros del lienzo utilizaremos la ventana "Propiedades de Canvas" que se ha abierto justo con la ventana de "Propiedades del array" La interfaz gráfica array nos va a permitir visualizar el valor almacenado en cada posición de un vector. Tendremos que indicar en la configuración del array el nombre del vector que queramos visualizar. La posición en el vector, el índice, se representa en el eje x y el valor almacenado, el contenido, en el eje y. Podéis estos elementos en el patch tabwrite-array-demo.pd que encontrareis en el material de la Practica 2. Figura 23. patch tabwrite-array-demo.pd. Todo esto puede parecer un poco complicado, así que, para entender mejor cómo funciona, utilizaremos la representación de este vector a lo largo del tiempo. Vamos a utilizar la metáfora de una fotografía: Figura 24. Una imagen de la animación en la figura 25. Cada vez que el "tabwrite~" recibe un bang, toma una foto de los valores de la señal en un corto periodo de tiempo que medimos con un cronómetro. Cuando el cronómetro comienza a contar, el primer valor registrado ocupará la primera posición del vector y cuando el cronometro termina el último valor registrado, tomará la última posición del vector. Para ver cómo una señal evoluciona en el tiempo, tendremos que tomar muchas fotos. Es lo mismo que sucede con un video o una película de dibujos animados, en la que por lo general vemos 24 imagen por segundo. Para que tome todas estas fotos utilizaremos el objeto metro que hemos visto anteriormente. Figura 25. Animación que veremos en el array del patch tabwrite-array-demo.pd si activamos el metro. Tamaño del array: Cuando queráis visualizar una señal utilizando el array, cambiar el tamaño del array os va a ayudar a ajustar la escala de lo que queráis visualizar, de forma que esta visualización os proporcione información comprensible. Podéis cambiar el tamaño del array en propiedades. Os dejo dos imágenes para que veáis la diferencia representando la misma señal con un array de tamaño 100 y otro de tamaño 2000: Figura 26. Misma señal representada con un array de tamaño de 100 (izquierda) y con un array de tamaño de 2000 (derecha). send~ y receive~ Estos dos objetos nos van a permitir enviar y recibir señales sin necesidad de unir cajitas con cables. Son como un emisor y un receptor inalámbricos y nos van a ser muy útiles para mantener la claridad y comprensión de nuestros programas cuando tengamos muchos elementos y conexiones. Figura 27. Criatura enviando datos. Cuando queramos enviar datos que no tienen el formato de señal, utilizaremos los mismos objetos, pero sin la virgulilla "~". Esto nos va a permitir enviar mensajes (int, float y symbols) sin necesidad de conectar las cajitas con líneas. Figura 28. patch send-receive-demo.pd dac~ ¡¡Finalmente vamos a conectarnos a los altavoces!! Figura 29. Altavoces recibiendo sonido desde Pure Data cuando no controlamos el volumen. dac~ = "digital to analog converter" Este objeto representa la puerta de conversión entre los números que componen señales de audio y el movimiento de la membrana del altavoz que va a generar el sonido. Nuestra tarjeta de sonido va a convertir estos datos en variaciones de corriente eléctrica que van a hacer que nuestro altavoz se mueva. Vemos que el objeto tiene dos inlets, cada uno corresponde a un canal de estéreo: derecha e izquierda. Figura 30. patch dac-demo.pd. Como veis en el ejemplo del patch dac-demo.pd, puedo tener varios receptores del mismo envío y ambos reciben la misma señal. ¡Comencemos con la practica! Figura 31. Gato haciendo la Practica 2 de Pure Data. Ahora vamos a crear un patch con los elementos que acabamos de ver. Podéis copiar y pegar elementos de un patch a otro, y recordad que tenéis acceso a todos los patches con todos los ejemplos que hemos visto en esta lección. Para ello os voy a dar el algoritmo escrito de cómo ha de ser nuestro programa y vosotros lo construiréis en Pure Data. Recordad que hay diferentes formas de llegar al mismo resultado así que sentíos con libertad de combinar los objetos que acabamos de introducir de diferentes maneras para probar y conseguir resolver el problema de la manera que más cómoda os resulte. Ejercicio 7:  Crear un patch que nos permita reproducir las notas de la escala de una octava con nuestros altavoces. En mi caso he elegido la octava tercera. A parte de reproducir las notas, nos gustaría elegir la nota de la octava que se reproduce a través del ratón. Podéis consultar el numero MIDI de cada nota en la tabla que vimos en "Configuración de Audio en Pure Data y notación MIDI" Solo enviaremos sonido a los altavoces una vez estemos seguros de que el nivel de volumen es adecuado. Algoritmo: Voy a crear un nuevo patch. Necesito tener el DSP encendido para que el programa trabaje con señales. Necesito hacer llegar a un oscilador los valores en Hz de las frecuencias correspondientes a la octava. Necesito controlar el volumen. Voy a regular la amplitud de la señal que sale del oscilador y voy a utilizar un rango de 0 a 0.5 para modularla. Me aseguro de que el volumen es adecuado. Voy a visualizar el nivel de volumen con el VU-meter antes de enviar la señal al dac~. Una vez el volumen en Pure Data está bajo control y con el volumen de mis altavoces bajado enviare la señal al dac~ y poco a poco subo el volumen de los altavoces. El volumen de mis altavoces esta fuera de Pure Data, por ejemplo, en mi caso es un knob, una rueda que giro en mi tarjeta de sonido. Si no tenéis tarjeta de sonido externa sera el volumen de vuestro ordenador. Una vez escucho una de las notas de la octava probare a reproducir el resto de las notas. Subo y bajo el volumen desde Pure data. ¿Escuchas algo raro? clics y pums? Utiliza el objeto line~ para suavizar los cambios de volumen. Si quiero visualizar la señal utilizaré un vector y la interfaz gráfica que me permite visualizarlo. Si tras intentarlo no habéis logrado finalizar la práctica, podéis mirar la página de pistas de la Practica 4 ¿Qué tenemos que entregar? El ejercicio 7. Sube a la carpeta del Moodle de la Practica 4 una captura de pantalla det patch y el patch que habéis creado. El patch deberá llamarse: practica4_vuestronombre_vuestroapellido.pd y la imagen practica4-imagen_vuestronombre_vuestroapellido. Figuras: Figura 1. Gatos con un metrónomo. https://gifer.com/en/AFH7 Figura 2. patch metro-demo.pd. Cuatro formas diferentes de configurar el objeto metro para que emita un bang por segundo. Figura 3. patch metro-demo.pd. Objeto metro que emite bangs cada 294 milisegundos. Figura 4. Tortuga deslizándose por una rampa. https://gifer.com/en/cih Figura 5. patch line-snapshot-demo.pd. Figura 6. patch line-snapshot-demo.pd. objeto line~ que recibe un mensaje con la configuración: destino=5. Y el tiempo de la rampa se configura a traves del inlet derecho. Figura 7. patch line-snapshot-demo.pd. objeto line~ que recibe un mensaje con la configuración: destino=5, tiempo=100. Figura 8. patch line-snapshot-demo.pd. objeto line~ que recibe un mensaje con la configuración: Inicio=2, destino=5, tiempo=100. Figura 9. patch line-snapshot-demo.pd. objeto line~ que recibe un mensaje con la palabra "stop". Figura 10. El "snapshot~" haciendo una foto de la señal cada vez que le llega un bang. https://gifer.com/en/73QW Figura 11. ejemplo del objeto "snapshot~" Figura 12. Representación de un VU meter.https://www.freeimages.com/nl/photo/vu-meter-1242056 Figura 13. patch Envelope-Vumeter-demo.pd Figura 14. Slider en funcionamiento. (no es Pure Data). https://www.pinterest.com.mx/pin/751186412851747700/ Figura 15. patch Slider-demo.pd. Slider vertical a la izquierda y Slider horizontal a la derecha con sus ventanas de propiedades. Figura 16. Personita generando una onda de 293.6 Hz. https://gfycat.com/concretebetterbilby Figura 17. La onda Sinusoidal que genera el "osc~". https://www.hsa.org.uk/electricidad/onda-y-frecuencia Figura 18. patch osc-demo.pd. Figura 19. patch mtof-ftom-demo.pd. Conversion de MIDI a Hz con el objeto mtof. Figura 20. Transformer civil pasando de Hz a MIDI. https://gifer.com/en/8pIY Figura 21. patch mtof-ftom-demo.pd. Conversion de MIDI a Hz con el objeto mtof, y de Hz a MIDI con el objeto ftom. Figura 22. Diagrama de un vector. https://montealegreluis.com/logica-programacion/docs/arreglos.html Figura 23. patch tabwrite-array-demo.pd. Figura 24. Una imagen de la animación en la figura 25. https://tenor.com/view/human-wave-formation-soliders-gif-12353118 Figura 25. Animación que veremos en el array del patch tabwrite-array-demo.pd si activamos el metro. https://tenor.com/view/human-wave-formation-soliders-gif-12353118 Figura 26. Misma señal representada con un array de tamaño de 100 (izquierda) y con un array de tamaño de 2000 (derecha). Figura 27. Criatura enviando datos. https://gifer.com/en/HvQG Figura 28. patch send-receive-demo.pd Figura 29. Altavoces recibiendo sonido desde Pure Data cuando no controlamos el volumen. https://gifer.com/en/763H Figura 30. patch dac-demo.pd. Figura 31. Gato haciendo la Practica 2 de Pure Data. https://gifer.com/en/2GU Clip y distorsion En el capítulo anterior hemos hecho referencia a la importancia de tener el volumen bajo control. Vamos a ver un objeto de seguridad que nos va a permitir limitarlo y con el podríamos trabajar con cascos de manera segura en caso de necesidad. Es el objeto "clip~" Este objeto va a controlar la amplitud de la señal que entre por su inlet izquierdo y la limitará en un rango determinado. Indicaremos ese rango en los argumentos del objeto, siendo el primero el valor mínimo y el segundo el valor máximo. Por lo general el rango de nuestras señales no ha de salirse del intervalo [-1 ,1]. El valor mínimo en la configuración del clip nunca ha de ser menos que -1, ya que el objeto no estaría realizando su función, ni el máximo más que 1. También podremos configurar este intervalo a través de los inlets segundo(mínimo) y tercero(máximo). Abre el patch Clip-demo.pd. Vamos a ver como limita la señal: Figura 1. patch Clip-demo.pd. Visualización de una onda limitada por el objeto clip~. Su amplitud se limita a la mitad de la onda que genera el osc~. La amplitud de esta onda es de 0.5. Sin el clip la señal tendría la siguiente forma: Figura 2. patch Clip-demo.pd. Visualización de una onda NO limitada por el objeto clip~. Su amplitud es igual a 1. Como podemos ver un "clip~ -0.5 0.5" corta todos los valores que superen en 0.5 por arriba y que sean menores de -0.5 por abajo. Esto disminuirá el volumen, pero también modifica la forma de la onda, la distorsiona y sonará diferente que si hubiéramos reducido la amplitud con un multiplicador: Figura 3. patch Clip-demo.pd. Visualización de una onda cuya amplitud se reduce multiplicando la onda que emite el osc~ por 0.5. La amplitud de esta onda es de 0.5. Esa distorsión que crea el clip al cortar la onda la podemos utilizar como un efecto estético o como un elemento semántico en nuestras creaciones. Amplificaremos excesivamente y luego cortaremos. Veremos este otro uso del clip en el próximo capitulo, pero: el uso esencial del objeto "clip~" será de seguridad e irá justo antes del "dac~" con un rango de -1 a 1, nunca un rango más amplio. A partir de ahora lo colocareis siempre en los patches sonoros que creéis. Figuras: Figura 1. patch Clip-demo.pd. Visualización de una onda limitada por el objeto clip~. Su amplitud se limita a la mitad de la onda que genera el osc~. La amplitud de esta onda es de 0.5. Figura 2. patch Clip-demo.pd. Visualización de una onda NO limitada por el objeto clip~. Su amplitud es igual a 1. Figura 3. patch Clip-demo.pd. Visualización de una onda cuya amplitud se reduce multiplicando la onda que emite el osc~ por 0.5. La amplitud de esta onda es de 0.5. Micrófono: Grabar y reproducir archivos En este capítulo vamos a ver cómo utilizar entradas, podéis utilizar el micrófono del ordenador. Veremos como grabar el sonido que generamos en pd y como reproducir archivos de audio externos. Abrir la carpeta de material correspondiente a este capitulo. En ella encontrareis todo lo necesario para seguir la lección. Entrada/Micrófono. adc~ Una entrada de audio nos va a permitir meter sonidos en tiempo real al ordenador, como el sonido que capta un micrófono o el sonido que produce una guitarra eléctrica. Vamos a poder grabar, reproducir o transformar estos sonidos. Actualmente casi todos los ordenadores tienen un micrófono integrado, que es el que, por ejemplo, en una video llamada capta el sonido de vuestra voz. Para acceder a este micrófono o cualquier otra entrada que tengáis, en Pure Data utilizaremos el objeto "adc~" (analog digital converter). Las entradas en Pure Data las podéis configurar en la sección "Dispositivos de Entrada" que se encuentra en "Configuración de Audio", hemos visto cómo hacerlo en la lección "Configuración de Audio en Pure Data y notación MIDI", pero antes de tocar la configuración de audio vamos a probar si el micro funciona, ya que Pure Data configurara una de las entradas de vuestro ordenador por defecto, así que si recibimos señal del micrófono no tendremos que modificar la configuración. Figura 1. Persona probando un micrófono. Para comprobar si recibimos señal vamos a utilizar el VU meter y el objeto "*~" para regular el nivel de la señal: Figura 2. patch Micro-tengo-senial.pd Recordar que para que Pure Data procese señal de audio tenéis que tener encendido el DSP y que para visualizar correctamente el nivel de volumen en el VU meter, al outlet del objeto "env~" tenéis que restarle 100 antes de enviar ese valor al VU meter. Si vemos nivel verde en el VU meter y cambia cuando damos palmadas es que tenemos señal de nuestro micrófono. ¡¡¡Ya estamos listos para transformar esa señal!!! Distorsión La distorsión a parte de un fenómeno que en algunos casos intentamos evitar se utiliza comúnmente como un efecto sonoro por ejemplo en las guitarras eléctricas.  ¿Percibís la gran diferencia entre la guitarra distorsionada y la guitarra sin distorsionar? Hemos visto en la lección anterior que el objeto "clip~" aparte de como elemento de seguridad nos va a servir para distorsionar señales de audio. Vamos a probar a distorsionar nuestra voz, para ello vamos a aumentar excesivamente el volumen se la señal que capta nuestro micrófono, para luego cortarla de forma brusca con el "clip~". Podremos regular el nivel de distorsión variando cuanto aumentamos la señal y cuanto cortamos con el "clip~". Cuanto más aumentemos y más cortemos, más distorsionada estará la señal. Vamos a probarlo: Figura 3. patch Micro-distorsion.pd En la figura 3 podéis ver como el clip situado en la parte de arriba limita la señal de -0,5 a 0,5. Abrir el patch Micro-distorsion.pd, ¿podéis escuchar vuestra voz distorsionada? Figura 4. Persona escuchando su voz distorsionada con Pure Data Feedback loop ¿Habéis oído alguna vez ese sonido constante e intenso que aumenta de volumen rápidamente cuando alguien con un micrófono se acerca a los altavoces por los que sale el sonido que recoge ese micrófono? Es algo así: En este evento del cole diríamos que el micrófono se está acoplando con los altavoces. Esto quiere decir que la voz de los niños o cualquier sonido que capte el micrófono se amplifica y envía a los altavoces. Los altavoces devuelven ese sonido amplificado al espacio y el micrófono vuelve a captar ese sonido que ya ha sido amplificado, lo amplifica otra vez y lo envía a los altavoces que devuelven ese sonido cada vez más amplificado. Es un ciclo en el que cada vez se aumenta más el nivel de una señal hasta generar esos tonos constantes que podéis escuchar en el video y que tanto molestan a los niños. Si os sucede esto tendréis que bajar el volumen de los altavoces y/o amplificar menos la señal que captáis con el micro, alejar el micro de ellos o colocarlo en una posición donde no este afectado. Este fenómeno se conoce como "feedback loop" que en español sería algo así como bucle de retroalimentación. Es un fenómeno que por lo general se intenta evitar, especialmente cuando el objetivo de utilizar un micrófono y unos altavoces es comunicar un mensaje a una gran audiencia, ya que la voz de quien habla tiene que entenderse y ser lo más clara posible. Al igual que la distorsión se puede, y se utiliza, como un elemento estético y creativo en la producción sonora, pero puede ser difícil de controlar. Para este curso solo necesitamos saber lo que es y cómo evitarlo en caso de que vuestro micrófono se acople con vuestros altavoces. Grabar. writesf~ Este objeto nos va a permitir grabar señales de audio que se encuentren en Pure Data. De esa grabación vamos a obtener un archivo que podremos reproducir con casi cualquier lector de Audio. Va a ser un archivo como el de una cancion que descarguéis de internet. ¿Como funciona este objeto? Para realizar una grabación con "writest~" vamos a utilizar 3 mensajes. El primero que le enviaremos va a crear el archivo en el que se guardara la grabación y dentro escribiremos "open" "espacio" "nombre-de-nuestro-archivo.wav". Sería como meter una cinta dentro de un caset. Figura 5. Meter la cinta = Abrir el archivo. El archivo se creará en la misma carpeta en la que tengamos guardado el patch. Cuando creamos el archivo aun no estamos grabando, para comenzar a grabar enviaremos el mensaje "start". Si no habéis creado el archivo antes, el mensaje "start" no va a funcionar. Sería como poner a grabar un caset sin meter ninguna cinta. Figura 6. patch Grabar-micro.pd Una vez hemos comenzado a grabar, pararemos la grabación enviando el mensaje "stop" Ya está, ¡¡ya tenemos nuestra primera grabación con hecha con Pure Data!! Ir a la carpeta donde está el patch guardado. ¿Veis el archivo? hacer doble click sobre el para abrirlo. ¿Escucháis vuestra voz? Cuando queráis realizar una nueva grabación acordaros de cambiar en el mensaje open el nombre del archivo para no sobre escribir y perder grabaciones anteriores. Esto sería como sacar la cinta en la que ya habéis grabado del caset y preparar una nueva. En la carpeta de material de esta lección os dejado la grabación que he hecho yo con este patch. Reproducir. readsf~ Este objeto nos va a permitir introducir en Pure Data señales de audio que se encuentran en archivos externos. Por ejemplo, la grabación que acabamos de hacer, o la grabación del golpe de una baqueta en un tambor. Figura 7. Meter la cinta y apretar al play = Abrir el archivo y enviar un "1". "readsf~" funciona de una manera muy similar a "writesf~". Tendremos primero que abrir el archivo que se encuentra alojado en la carpeta de nuestro patch utilizando el mensaje "open nombre-del-archivo.wav" (meter la cinta en el reproductor de casetes). Una vez el archivo está abierto comenzamos la reproducción enviando un "1" al objeto (apretar al botón play). Para parar la reproducción enviaremos un "0" (apretar al botón de parar). Los archivos que grabemos y reproduzcamos en pure data van a esta en formato WAV Figura 8. patch Reproducir-Grabar-Micro.pd Hay que volver a abrir el archivo cada vez que queramos reproducirlo. Si queremos que un archivo que está siendo reproducido vuela a empezar, habrá que pararlo, volver a abrirlo y comenzar de nuevo su reproducción cada vez que queramos reproducirlo de nuevo. Recordar que el orden en el que conectáis las cajitas va a influir en el orden en el que se realizan los envíos. Para controlar ese orden de manera más precisa y visible en caso de necesidad podéis utilizar un delay con un tiempo muy pequeño. Y como ya os podéis imaginar, para escucharlo por los altavoces tendréis que hacer llegar la señal que acabáis de introducir el Pure Data al "dac~" En la carpeta de material de esta lección os dejado la carpeta "musicradar-drum-samples" con grabaciones de sonidos de percusión que podéis utilizar. Ejercicio 8: Explicar la función que tiene el delay de la figura 8. Añadir otro delay para aseguraros que el orden de los mensajes permite volver a reproducir un archivo cada vez que activemos el bang, aunque este archivo se esté reproduciendo. Figuras: Figura 1. Persona probando un micrófono. https://giphy.com/gifs/polyvinylrecords-is-this-thing-on-anna-burch-tell-me-whats-true-QWYFDsf7qOxlS7FrHn Figura 2. patch Micro-tengo-senial.pd Figura 3. patch Micro-distorsion.pd Figura 4. Persona escuchando su voz distorsionada con Pure Data. Figura 5. Meter la cinta = Abrir el archivo. https://giphy.com/gifs/vhs-vaporwave-retrowave-VHktKwkD9OEVaX4kq2 Figura 6. patch Grabar-micro.pd Figura 7. Meter la cinta y apretar al play = Abrir el archivo y enviar un "1". https://giphy.com/gifs/XxHVJxuogNP32 Figura 8. patch Reproducir-Grabar-Micro.pdOsciladores, expr, if En esta lección vamos a ver varios tipos de ondas, que, por ejemplo, se utilizan para generar sonido en sintetizadores. Tambien vamos a ver el objeto "expr" y el condicional "if". Encontrareis todos los patches de demostración en la carpeta de material correspondiente a esta lección. Onda sinusoidal. osc~ Figura 1. Persona oscilando y generando un movimiento periódico. El objeto "osc~" es un generador de ondas sinusoidales, también conocidas como ondas puras. Hemos visto este objeto en la Practica 2: nuestro pr... | Librería CATEDU, pero vamos a recordarlo un poco. Debe recibir en su inlet izquierdo la frecuencia de la onda que queramos generar en Hz. Este objeto va a generar una onda pura, esto quiere decir una onda sin armónicos, constituida por una sola frecuencia y con una amplitud de 1, por lo que generara valores de -1 a 1. Figura 2. patch Onda-Sinusoidal.pd Onda de sierra: phasor Estas ondas suenan más agresivas y estridentes que las ondas sinusoidales. La forma de esta onda son una sucesión de rampas iguales que van de 0 a 1 en un tiempo determinado. Estas rampas están generadas por el objeto "phasor~". Al llegar a 1 los valores caen inmediatamente a 0 desde donde comienza de nuevo la rampa. Cada rampa será una repetición y la frecuencia de esta onda vendrá determinada por el número de rampas sucedido en una unidad de tiempo. Tenemos una onda de sierra que va de 0 a 1, luego su amplitud sera de 0.5, por lo que vamos a normalizarla, que quiere decir ajustar el centro del desplazamiento transversal de una partícula en 0 con una amplitud de 1. Para ello la multiplicaremos por dos para obtener una amplitud de 1 y para colocar su centro en 0 le restaremos 1. Figura 3. patch Onda-Sierra.pd Los toggles verdes activan y desactivan la onda sin normalizar y la onda normalizada para que podáis compararlas en el patch Onda-Sierra.pd. Si encendéis los dos a la vez tendréis una combinación de ambas ondas. Onda rectangular: phasor + filtro Su forma se tiene que alternar entre -1 y 1, generando una onda rectangular. Para conseguir esta onda vamos a partir de una onda de sierra que vamos a transformar con el objeto "expr". Abre el patch Expr-explicacion.pd y vamos a ver un poco cómo funciona el objeto expr: expr Este objeto nos va a permitir evaluar expresiones o realizar operaciones utilizando operadores matemáticos (<, ==, +, ...) o estructuras condicionales (si esta condición se cumple, entonces envía en valor A, si esta condición no se cumple envía el valor B. En programación por defecto las situaciones ciertas se representan con un 1, y las falsas con un 0. En las expresiones cuando utilicemos el $ vamos a especificar el tipo de variable que es (int, float o symbol). Cuando sea un int colocaremos una i entre el símbolo $ y el número que representas la posición ocupa la variable en la expresión. ej $i2 Cuando sea un float colocaremos un f y para symbol una s. $Tipo-de-variablePosicion-variable Figura 4. patch Expr-explicacion.pd [expr~] es el objeto expr que nos va a permitir tratar con señales, tiene una variable input específica para señales '$v#'. En este caso colocamos una v entre el símbolo $ y el valor que indica la posición. Abre el patch Expr-explicacion.pd para probar el objeto "expr" Figura 5. patch Expr-explicacion.pd Como sabemos la onda de sierra es una rampa lineal que va de 0 a 1 en un tiempo determinado. Esta rampa pasa por valores intermedios entre 0 y 1, a la mitad de la rampa en concreto se encontrará en 0.5. La onda rectangular que queremos crear ahora no pasa por ningún valor intermedio, va de 0 a 1 inmediatamente. Para convertir esta rampa lineal en un salto vamos a decirle al objeto expr~ que la condición se cumple cuando los valores son superiores a 0.5. por lo tanto, todos los valores de 0 a 0.5 pasaran a ser un 0 y que todos los valores de 0.5 a 1 pasaran a ser un 1, ya que,  verdadero es igual a 1 y falso es igual a 0: Figura 6. El objeto "phasor~" envía una señal que sera filtrada por el objeto "expr~ $v1 > 0.5" $v1 sera la señal que el "phasor~" en via al inlet de "expr~". Cuando los valores generados por el phasor sean mayores que 0.5 la expresión devolverá por su output un 1, cuando los valores sean menores que 0.5 devolverá por su output un 0. Figura 7. Representación de como el objeto "expr~ $v1 > 0.5" transforma una onda de sierra en una onda cuadrada. ¿Os acordáis de la metáfora del rio Ebro que utilizábamos en la lección Programación en genera... | Librería CATEDU? El objeto "expr" y el operador ">" realizarían la acción de evaluar la altura del agua y cuando desciende por debajo de 50 abrirían la compuerta del embalse. Ahora tenemos una onda rectangular que va de 0 a 1, luego su amplitud sera de 0.5, por lo que vamos a normalizarla como hicimos anteriormente con la onda de sierra. La multiplicaremos por 2 para obtener una amplitud de 1 y para colocar su centro en 0 le restaremos 1. Figura 8. patch Onda-Rectangular.pd Onda triangular Su forma se compone de rampas ascendentes y descendentes que van de -1 a 1 y de 1 a -1. Para construirla vamos a partir de nuevo de una onda de sierra. A mitad de la progresión de esta onda de sierra vamos a invertir la pendiente de la progresión, de manera que al llegar a 0.5 en lugar de seguir subiendo hasta 1, comience a bajar hasta 0 con la misma pendiente pero invertida.  Para ello vamos a utilizar dentro del objeto expr~ el condicional if, que nos va a permitir configurar los outputs en función de si la condición se cumple o no. su estructura es la siguiente: if(condicion, verdadero, falso). Nuestra condición va a se que la señal sea mayor que 0.5, cuando la condición se cumpla la expresión va a devolver la inversa de la señal (1-señal) y cuando la condición no se cumpla devolverá la señal que ha entrado sin ninguna modificación. La expresión sera la siguiente: Figura 9. El objeto "phasor~" envía una señal que sera filtrada por el objeto "expr~ if($v1 > 0.5, 1 - $v1, $v1)". $v1 sera la señal que el "phasor~" en via al inlet de "expr~". Cuando los valores generados por el phasor sean mayores que 0.5 la expresión devolverá la inversa de la señal (1-señal), cuando los valores sean menores que 0.5 devolverá la señal. "expr~ if($v1 > 0.5, 1 - $v1, $v1)" Figura 10. Representación de como el objeto "expr~ if($v1 > 0.5, 1 - $v1, $v1)" transforma una onda de sierra en una onda cuadrada. Ahora tenemos una onda triangular que va de 0 a 0.5, luego su amplitud sera de 0.25, por lo que vamos a normalizarla como hicimos anteriormente con la onda de sierra y la onda rectangular. La multiplicaremos por 4 para obtener una amplitud de 1 y para colocar su centro en 0 le restaremos 1. Figura 11. patch Onda-Triangular.pd ¿Alguna duda de las ondas que acabamos de ver? ¿Preparados para oscilar? Figura 12. Perro oscilando. En la carpeta de material de esta lección tenéis todos los patches que hemos visto y también un patch con todas las ondas (Osciladores.pd) para que comparéis y experimentéis un poco con ellas. Figuras: https://giphy.com/clips/storyful-lady-gaga-poker-face-coach-beard-pS8uMLP7sgXmK8d3Mr Figura 2. patch Onda-Sinusoidal.pd Figura 3. patch Onda-Sierra.pd Figura 4. patch Expr-explicacion.pd Figura 5. patch Expr-explicacion.pd Figura 6. El objeto "phasor~" envía una señal que sera filtrada por el objeto "expr~ $v1 > 0.5" Figura 7. Representación de como el objeto "expr~ $v1 > 0.5" transforma una onda de sierra en una onda cuadrada. Figura 8. patch Onda-Rectangular.pd Figura 9. El objeto "phasor~" envía una señal que sera filtrada por el objeto "expr~ if($v1 > 0.5, 1 - $v1, $v1)". Figura 10. Representación de como el objeto "expr~ if($v1 > 0.5, 1 - $v1, $v1)" transforma una onda de sierra en una onda cuadrada. Figura 11. patch Onda-Triangular.pdPráctica 5: Contador y Secuenciador Un secuenciador nos va a permitir repetir series de acciones de manera estructurada. Con esta estructura, por ejemplo, vamos a poder crear ritmos o melodías que se repiten. ¿Qué elementos de Pure data necesitaremos conocer? Variables int y float En Pure data una variable numérica va a ser una cajita en la que podamos almacenar un valor numérico. Podremos enviar ese valor por su outlet y también podremos sustituir ese valor por otro, esto nos va a ayudar a crear una estructura que nos permita contar. Esta cajita puede ser de tipo integer, objeto"int" o "i", o de tipo float, objeto "float" o "f". Las variables de tipo int solo aceptan números enteros y si reciben un numero decimal ignoraran su parte decimal y solo almacenaran la entera. Sin embargo, las variables de tipo float aceptan números enteros y decimales. Ya habíamos visto los tipos de datos y de variables en las lecciones "Programación en general: el mundo de los algoritmos" y en "Elementos que debemos conocer". Figura 1. patch variables-demo.pd Contador Una vez que conocemos la variable, vamos a utilizarla para realizar un contador. Anteriormente, introdujimos este concepto si tienes alguna duda vuelve a la página "Estructuras que debemos conocer". Figura 2. Epi contando hasta 6 y volviendo a empezar. Un contador nos va a permitir contar el número de veces que sucede un evento y en función de ese número tomaremos decisiones, de momento vamos a dejar lo de tomar decisiones más adelante y ahora aprenderemos a contar con Pure data. En este caso, utilizaremos una variable de tipo int, al contenido de esa variable le sumaremos 1 cada vez que llegue un evento. Figura 3. patch contador-demo.pd Como podéis apreciar en el patch, el outlet de la cajita de la variable i se envía a la entrada de otra cajita cuya función es sumar una unidad al valor que entre y devolver el resultado por su salida. El resultado de esta suma se envía al inlet derecho de la variable i que lo almacenara. Los valores que entran por el inlet derecho de la variable i sustituyen el valor que almacena la variable sin sacarlo de nuevo por el outlet de la cajita con la variable i. El cofre rojo seria nuestra variable "i" y el pajarito el objeto "+ 1" que cada vez añade una moneda más al cofre. Figura 4. Pajarito contando. En nuestro patch de Pure Data, para obtener el valor almacenado en la variable i a traves de su outlet utilizaremos un bang en su inlet izquierdo. Recordar lo que vimos en la lección "Elementos básicos" sobre la entra caliente de un objeto y las entradas frias. El mensaje con el valor 0 en el inlet derecho nos permitirá inicializar el contador a 0. Tomaremos como valor de cuenta el resultante de la suma, luego el outlet del objeto "+1". módulo, % El objeto % es un operador matemático conocido como módulo, que devuelve por su outlet el resto de una division. El argumento de objeto (en la figura 5, el argumento del objeto "%" seria 8), indica el divisor de la operación, que también se puede configurar a traves del inlet derecho. El dividendo es el valor introducido por el inlet izquierdo y el resto de esta division es el outlet del objeto %. Figura 5. patch variable-resto-demo.pd Radio El Radio es una interfaz gráfica que nos permite enviar valores correspondientes con una secuencia de celdas, esos valores se envían activando las diferentes celdas desde el ratón o a traves del inlet. Figura 6. patch radio.pd y ventana de propiedades del Radio Horizontal Para seleccionar cada celda, clicaremos sobre ella o enviaremos al inlet del radio un numero correspondiente a la posición de la celda. La numeración de las celdas comienza en 0, luego la primera celda corresponderá con el numero 0. Esta interfaz podrá ser vertical u horizontal y configuraremos el número de celdas, haciendo click derecho sobre el radio>Propiedades>Número de Celdas. En propiedades también podremos configurar los colores, etiqueta o tamaño del radio. Figura 7. patch radio-demo.pd El radio por defecto tiene 8 celdas que tendremos que ajustar a nuestras necesidades. Este objeto nos va a ser extremadamente útil para visualizar secuencias o activar distintos eventos. Contador cíclico Figura 8. Epi contando hasta 6 y volviendo a empezar. Ahora vamos a crear un contador que llegue a un número determinado y vuelva a empezar, para ello vamos a utilizar el objeto "%", que nos proporciona el resto de una división. Dividiremos por el numero al que queremos que llegue la cuenta teniendo en cuenta que el primero de esos números sera 0. Por ejemplo, si queremos que cuente hasta 8, nuestro divisor será 8 y el argumento de % también sera 8. El resto de esta división tendrá valores entre 0-7. De esta forma obtendremos una cuenta cíclica de 8 pasos. Figura 9. patch contador-ciclico-demo.pd Select. sel Este objeto nos va a permitir clasificar valores, comparando el valor que recibe en su inlet izquierdo con el o los argumentos que contiene. Si en esa comparación hay una coincidencia emitirá un bang por el outlet correspondiente a ese argumento, el primer argumento corresponderá con el primer outlet empezando a contar por la izquierda, el segundo argumento al segundo outlet, ... Cuando no haya una coincidencia emitirá el valor recibido y no coincidente por el outlet derecho, el ultimo outlet si empezamos a contar por la izquierda. Figura 10. patch select-demo.pd. Objeto select con 1 argumento. Digamos que, si el objeto select tiene 5 argumentos, va a tener 6 puertas de salida. Para salir por cada una de las puertas hay que cumplir un requisito. En el caso de la figura 11, para salir por la primera puerta (primera-izquierda) el valor recibido tiene que ser un dos, para salir por la segunda puerta un 4, por la tercera un 6, por la cuarta puerta el valor deberá de ser igual a 8 y por la quinta igual a 10. Lo que sale por todas las puertas excepto por la última es un bang. Figura 11. patch select-demo.pd. Objeto select con 5 argumentos. ¿Y quién sale por la ultima puerta? Por la ultima puerta salen todos los valores que no puedan salir por las puertas anteriores y es la unica que enviara un valor número, el resto de las puertas envían un mensaje de bang. Ejercicio 9: Utilizando el contador que acabamos de ver y el objeto selector crea una melodía de 8 tiempos. Pista: Utiliza el objeto select para enviar las diferentes notas en el momento deseado a un "osc~". Puedes hacer que la melodía vaya más rápido o más despacio? ¿Y hacer que vaya para atrás? ¿Qué tenemos que entregar? El ejercicio 9. Sube a la carpeta del Moodle de la Practica 5 una captura de pantalla del patch y el patch que has creado. El patch deberá llamarse: practica5_vuestronombre_vuestroapellido.pd y la imagen practica5-imagen_vuestronombre_vuestroapellido. Figuras: Figura 1. patch variables-demo.pd Figura 2. Epi contando hasta 6 y volviendo a empezar. https://giphy.com/gifs/APMTV3-apm-apmtv3-Y3LuJcBQFsqQTglmJF Figura 4. Pajarito contando. https://giphy.com/gifs/bird-gold-saving-money-YNE2DIwH8K1aUirbwz Figura 5. patch variable-resto-demo.pd Figura 6. patch radio.pd y ventana de propiedades del Radio Horizontal Figura 7. patch radio-demo.pd Figura 8. Epi contando hasta 6 y volviendo a empezar. https://giphy.com/gifs/APMTV3-apm-apmtv3-Y3LuJcBQFsqQTglmJF Figura 9. patch contador-ciclico-demo.pd Figura 10. patch select-demo.pd. Objeto select con 1 argumento. Figura 11. patch select-demo.pd. Objeto select con 5 argumentos. MÓDULO 5: ARDUINO Haremos una práctica en la que nuestro Arduino será capaz de detectar sonido Práctica 6: Arduino y micrófono Para esta práctica, vamos a necesitar el micrófono que venía en nuestro kit: Lo que haremos será detectar el sonido de una palmada y encender el LED que viene integrado en nuestro Arduino UNO. El propósito de esta práctica es poder activar diferentes sonidos en Pure Data cuando, más adelante, veamos cómo conectar este programa a nuestro Arduino. El micrófono El módulo que vamos a utilizar detecta el sonido con la ayuda de un micrófono conectado a un amplificador. También consta de un potenciómetro que se utiliza para ajustar el nivel de sonido de salida y la sensibilidad del micrófono. Hay dos tipos de salidas accesibles desde este sensor y son la salida digital y la salida analógica. La salida digital se obtiene cuando el sonido está en un umbral determinado. El potenciómetro se utiliza para ajustar la sensibilidad del pin de salida digital. Cuando un determinado sonido sea mayor/menor que el nivel de umbral, la salida digital será baja/alta. La salida analógica representa la señal directa del micrófono como un nivel de tensión que cambia con la intensidad del sonido y será la que utilicemos en este proyecto. Los pines Este módulo consta de cuatro pines AO, G, + y DO: El pin AO se utiliza para la salida analógica.El pin G lo conectaremos al pin GND (Ground o masa) de nuestro Arduino. El + se utiliza para alimentar a nuestro sensor conectándolo al pin de 5V de nuestro Arduino. El pin D0 se utiliza para la salida digital. Las conexiones En la siguiente imagen puedes ver un esquema de las conexiones que tendrás que realizar: Como puedes ver, el pin D0 no vamos a utilizarlo para esta práctica. En nuestro caso, para realizar las conexiones vamos a usar la protoboard, pero tendremos que tener cuidado con cómo realizamos la conexiones, ya que todos los puntitos están conectados entre sí de la siguiente manera: Por tanto, tendremos que colocar nuestro sensor paralelo a las líneas azul y roja, como en la siguiente imagen: Una vez tengamos las conexiones preparadas, pasaremos a ver el código que hará funcionar nuestro sensor. El código Como vas a ver, no consta de muchas líneas. Lo primero que haremos será crear la variable que almacenará el valor que leamos con nuestro micrófono, este valor será un entero y la variable se llamará soundPin: int soundPin = A0; A continuación, encontramos la función void setup() que se ejecutará una sola vez y lo que en ella haremos es comenzar la comunicación con el puerto serie a una velocidad de 9600 baudios: void setup() { Serial.begin(9600); } En la función void loop() vamos a encontrar una variable de un tamaño mayor que el número entero anterior, por eso la almacenamos en un long. Esta variable sum va a ir almacenando los valores que se lean desde nuestro sensor agrupados en grupos de 100 y calcularemos la media dividiendo el valor obtenido en 100 (sum=sum/100). Esa agrupación viene dada por el bucle for, que ya mencionamos en este apartado, en el que decimos que en la variable sum se vayan almacenando los valores que se detecten en nuestro soundPin. ¿Recuerdas los contadores que explicamos en este capítulo? Pues la sentencia sum += analogRead(soundPin); funciona como un contador que va almacenando valores gracias a +=. Si escribiésemos sum = sum + analogRead(soundPin) obtendríamos el mismo resultado. Lo siguiente es imprimir por el puerto serie el valor obtenido (Serial.println(sum);)y pedirle a nuestro Arduino que espere 10 milisegundos a detectar un nuevo valor (delay(10);). void loop() {   long sum = 0;   for(int i=0; i<100; i++)   {       sum += analogRead(soundPin);   }   sum = sum/100;   Serial.println(sum);   delay(10); } Ver el sonido Para ver cómo varía el sonido, tendremos que abrir nuestro Monitor Serie en modo Serial Plotter. Para ello, tendremos que pulsar la tecla SHIFT (o flecha hacia arriba) en nuestro teclado mientras nuestro ratón está colocado sobre la imagen de la lupa: El resultado será algo así: ¿Qué tenemos que presentar? Será necesario que presentéis un video o un .gif en el que se vea el sensor de sonido y en el puerto serie abierto, veamos cómo cambia la onda al tocarlo, similar al .gif que puedes ver encima de esta sección. REFERENCIAS: Tutorial Arduino y micrófono: https://microcontrollerslab.com/ky-038-microphone-sound-sensor-module-arduino-tutorial/Tutorial Arduino y micrófono 2: https://kolwidi.com/blogs/blog-kolwidi/como-usar-un-microfono-con-arduinoImagen Arduino y micrófono http://arduinolearning.com/wp-content/uploads/2018/07/ky038-example_bb.jpg MÓDULO 6: PURE DATA Utilizaremos el objeto envelope y OSC para enviar información desde otro dispositivo a Pure Data Envelope ¿Qué conceptos nuevos necesitaremos conocer? ¿Qué es un envelope o envolvente? El envelope va a determinar la variación de los niveles de una señal a lo largo del tiempo. Para nosotros, va a ser una herramienta que nos permitirá dar forma/esculpir el sonido con el que estemos trabajando, desde su volumen a su frecuencia. En lo que a síntesis de sonido se refiere, el envelope es una curva que nos va a permitir controlar algún parámetro de una señal (Wilczek, 2022). Ya lo hemos utilizado anteriormente, pero de una manera muy sencilla cuando utilizamos el "line~" para suavizar los cambios de volumen en la "Practica 2: nuestro primer patch sonoro". En este caso utilizamos una sola rampa. ¿Os acordáis? Figura 1. Tortuga deslizándose por una rampa. Los envelopes se componen por varios segmentos y en cada segmento encontraremos una rampa diferente. Vamos ver el envelope ADSR, que es uno de los mas utilizados. Este envelope consiste en cuatro segmentos: A=attack, D=decay, S=sustain y R=release. Figura 2. ADSR envelope El Attack es el segmento en el que el valor aumenta desde el mínimo hasta el máximo que va a alcanzar el envelope. El Decay es el segmento en el que el envelope cae desde el pico máximo que se alcanza en el Attack, hasta un valor que se mantendrá constante en el segmento conocido como Sustain. El Realease es el último segmento del envelope en el cual el valor desciende a 0. Por ejemplo, utilizaremos el ADSR para controlar la amplitud de una señal, en este caso estaremos dando forma al volumen de esta señal. Aqui teneis un ejemplo de ADSR modulando la amplitud: En el video anterior podéis escuchar cómo cambia el sonido al modificar el tiempo de duración de cada segmento. Ahora vamos a aprender como hacer envelopes en Pure Data ¿Qué elementos nuevos de Pure data necesitaremos conocer? Delay Este objeto nos va a permitir enviar un bang después de un tiempo de espera determinado. Digamos que nos va a permitir retener y retrasar el envío de un bang. El tiempo que se retrase el bang lo configuraremos en el argumento del objeto o a traves del inlet derecho. A traves del inlet izquierdo también podemos configurar el tiempo e iniciar el delay, sin embargo cuando configuremos un tiempo a traves del inlet derecho el delay no empezara hasta recibir un bang en el inlet izquierdo Recordar lo que vimos en la lección "Elementos básicos" sobre la entra caliente de un objeto y las entradas frías. Por defecto la unidades son milisegundos, si queremos trabajar con otra unidad como por ejemplo segundos, tendremos que especificarlo en el mensaje que configura el tempo del delay. Si queremos detener el delay enviaremos un mensaje de stop. Figura 3. patch delay-demo.pd En la figura 3, el primer delay retrasara el bang medio segundo y el segundo delay 1 segundo. Tras mandar el mensaje configurando el tempo en segundos el tercer delay retrasará el bang medio segundo, si no enviamos ese mensaje configurando el tempo, el delay se retrasará medio milisegundo. Delay + line Como vimos anteriormente el objeto "line~" nos permite crear rampas. Crear una progresión lineal desde un valor a otro en un tiempo determinado. ¿Os acordáis? lo vimos en la "Practica 2: nuestro primer patch sonoro". Figura 4. Tortuga deslizándose por una rampa. Combinando "delay" y "line" vamos a poder combinar rampas para crear progresiones mas complejas, con diferentes direcciones. Por ejemplo ir de 1 a 0.5 en 500 milisegundos y al llegar a 0.5, ir a 0 en 800 milisegundos. Figura 5. Combinación de varias rampas. Vamos a ver cómo crear ahora un envelope ADSR con Attack, Decay, Sustain y Release en pure data, podéis abrir el patch line-ADSR.pd para probar su funcionamiento: Figura 6. patch line-ADSR.pd En la figura 4. vemos el patch line-ADSR.pd. Para comenzar el envelope activaremos el bang que se encuentra arriba. Este bang envía el primer mensaje y activa los dos delays. Cuando termina la primera rampa (el ataque) después de medio segundo (500 milisegundos) comienza la segunda rampa, como podéis ver el tiempo que dura la primera rampa y el tiempo del primer delay es el mismo para que justo en el momento en que termine la primera rampa comience la siguiente rampa, la segunda rampa que durara 700 milisegundos. Cuando termine la segunda rampa, habrán pasado 500+700=1200 milisegundos desde el comienzo del envelope. Si quisiéramos que la tercera rampa comenzara inmediatamente después de terminar la segunda configuraríamos el segundo delay con un tiempo de 1200 milisegundos, pero queremos que la señal se mantenga constante durante 3800 milisegundos, asi crearemos la sección de Sustain. Para esto configuraremos el segundo delay con un tiempo superior a 1200 en nuestro caso 1200+3800=5000 ya que 3800 es el tiempo que queremos que dure el sustain. Tras 5000 milisegundos el segundo delay envía el bang que enviará el mensaje con la tercera rampa al line~, comienza el release que en nuestro caso durara 1000 milisegundos. Ejercicio 1: ¿Cuál es la duración total del envelope en el ejemplo anterior? Ejercicio 2: crea un patch que genere un envelope con un ataque que vaya de 0.5 a 1 en 300 milisegundos, un decay que baje a 0.7 en 900 milisegundos. Un sustain de 2000 milisegundos y un decay que baje a 0 en 1100 milisegundos. ¿Cuál es la duración total del envelope que acabáis de construir? Como habéis visto en el video de arriba, el tiempo que dura cada segmento es un parámetro clave para darle forma al sonido. Ahora, vamos a modificar el patch anterior para poder controlar el tiempo de cada segmento, y para ello vamos a introducir una utilidad de Pure data que nos va a permitir modificar el valor o los valores de un mensaje u objeto. Es el símbolo del dólar $. $ Utilizaremos el símbolo $ para remplazar un valor numérico o un símbolo en un mensaje u objeto. Es una forma de crear una variable que podamos modificar dentro de un mensaje u objeto. Acompañaremos $ con el número que indica la posición del valor en el mensaje u objeto, en ente caso comenzamos a contar en el 1. Si tenemos un mensaje con dos valores, el primero será $1 y el segundo $2. El $1 y el $2 van a ser remplazados por los valores recibidos. Vamos a ver un ejemplo en el patch "variable-dollar-demo.pd": Figura 7. patch variable-dollar-demo.pd Si os acordáis habíamos visto que en programación se empieza a contar en el 0, entonces, ¿porque el primer valor variable cuando utilizamos $ lo nombramos con 1? Es poque el $0 tiene otra función, y lo utilizaremos para indicar que un objeto al cual le asignamos nosotros un nombre, como por ejemplo "tabwrite~", array, "send", "receive", ... funcionan e interaccionan solo con objetos del patch en el que se encuentra, es decir tiene un alcance local. Esto que quiere decir y por qué nos va a ser util? Por ejemplo, teniendo dos patches abiertos con objetos "send" y "receive" nombrados con la misma etiqueta, "send go" y "receive go", lo que envíe el send del patch 1 va a llegar también al receive del patch 2, para evitar esto, colocaremos el $0 al comenzar el nombre de nuestra etiqueta: "send $0-go" y "receive $0-go", así, lo que envíe el "send $0-go" del patch 1 solo llegara al "receive $0-go"del patch 1. Como os podéis imaginar utilizaremos esto para objetos que no están conectados a traves de líneas, como el "tabwrite~" y la interfaz grafica array. En el siguiente capitulo veréis como esta utilizado en los patches. Ahora que ya sabemos cómo introducir valores variables en mensaje, vamos a modificar el patch anterior para poder controlar el tiempo que dura el attack, el decay, el sustain y el release: La duración del primer delay va a ser la misma que la duración de la primera rampa (Attack). La duración del Decay sera la duración de la segunda rampa. La duración del segundo delay sera la suma de la duración del Attack más la duración del Decay más el tiempo de duración del Sustain. La duración del Release sera la duración de la tercera rampa Recordar que en el objeto suma el inlet derecho actualiza el valor de uno de los sumandos, pero al actualizar ese valor no se emite el resultado por la salida. El objeto + va a enviar el resultado solo cuando reciba un valor o bang en el inlet izquierdo, por eso cuando actualizamos el valor del inlet derecho enviamos también un bang en el inlet izquierdo. Figura 8. patch line-ADSR-tiempos-variables.pd Vamos a ver ahora otra manera de construir estos envelopes en pure data utilizando el objeto "vline~". vline~ Este objeto nos va a permitir construir envelopes combinando rampas de la misma forma que la combinación de delay y line~. De momento utilizaremos solo el inlet izquierdo para configurar los parámetros del vline~, que espera un mensaje con la información de las rampas que ha de realizar y cuando. La información de cada rampa estará separada por una coma, detrás de cada coma indicaremos el valor de destino, el tiempo que tardará en llegar al valor de destino y el tiempo que tardará esa rampa en comenzar desde que empieza el envelope. Si queremos configurar un valor inicial pondremos dicho valor al principio separado de una coma. El mensaje tendría la siguiente forma: valor-inicial, valordestino-rampa1 tiempo-rampa1 delay-rampa1, valordestino-rampa-2 tiempo-rampa2 delay-rampa2 0, 1 500, 0.8 700 500 Rampa 1, Rampa 2 Para la primera rampa generalmente no pondremos delay porque al ser la primera comienza a la vez que se inicia el envelope. Y el delay de cada rampa es el tiempo desde que empieza el envelope hasta el momento en que queremos que commence esa rampa. Vamos a ver ahora en el patch xxx como construir el mismo envelope que hicimos en el ejemplo de la figura 5, pero utilizando el objeto "vline~". Figura 9. patch line-vline-ADSR.pd Ejercicio 3: Construye el mismo envelope que hiciste en el ejercicio 1 utilizando el objeto vline~ Ejercicio 4: Modifica el patch en la Práctica 2, para ello, utiliza un envelope ADSR con el tiempo de decay variable que regule el volumen cada vez que se reproduzca una nota. Figuras: Figura 1. Tortuga deslizándose por una rampa. https://gifer.com/en/cih Figura 2. ADSR envelope. https://thewolfsound.com/envelopes/ Figura 3. patch delay-demo.pd Figura 4. Tortuga deslizándose por una rampa. https://gifer.com/en/cih Figura 5. Combinación de varias rampas. https://giphy.com/gifs/southparkgifs-l0HluCIeReFkeWAQ8 Figura 5. patch line-ADSR.pd Figura 6. patch variable-dollar-demo.pd Figura 7. patch line-ADSR-tiempos-variables.pd Figura 8. patch line-vline-ADSR.pd Referencias: Wilczek, J. (2022, Julio 3) Envelopes in Sound Synthesis: The Ultimate Guide. WolfSound. https://thewolfsound.com/envelopes/ Práctica 7: Kick drum y random Una vez sabemos qué es y cómo utilizar un envelope, vamos a crear un sonido que imita el kick drum de una batería. Crearemos una version sencilla con los elementos de Pure data que hemos aprendido hasta el momento. Vamos a utilizar dos envelopes, uno para el volumen y otro para la frecuencia. Recordar que hemos visto que era un envelope en la lección anterior. Envelope que controla el volumen Figura 1. patch Kick-drum-sencillo-paso-1.pd Vamos a utilizar un oscilador y vamos a regular su volumen con un envelope utilizando el objeto "vline~". Los parámetros del "vline~" son los que nos van a permitir conseguir el efecto del kick-drum. En este caso nuestro envelope parte de 0.5 lo que va a generar un pequeño golpe, el Attack es muy rápido, va de 0.5 a 0.8 en 5 milisegundos. El Decay mucho más largo que en el attack baja de nuevo a 0.5 en 60 milisegundos. No tendremos Sustain e inmediatamente después del Decay comenzaremos con el Release, que sera la parte más larga de nuestro envelope, bajando a 0 en 400 milisegundos. A continuación veremos el contenido del mensaje que recibirá el "vline~" con los parámetros que configuran cada rampa de nuestro envelope, y una tabla en la que desgranaremos esos parámetros: 0.5, 0.8 5, 0.5 60 5, 0 400 65 Rampas Valor inicial Valor Final Duración (milisegundos) Delay. Tiempo desde el inicio del envelope, hasta el comienzo de esta Rampa (milisegundos) Attack 0,5 0.8 5 0 Decay 0.8 0.5 60 5 Sustain - - - - Release 0.5 0 400 65 = 60 + 5 Ejercicio 5: Abrir el patch Kick-drum-sencillo-paso-1.pd y completar siguiendo las instrucciones que encontrareis a lo largo de la lección para crear un Kick drum. Al archivo que modifiquéis lo llamareis Kick-drum-sencillo-vuestronombre_vuestroapellido.pd Cuando abráis el patch Kick-drum-sencillo-paso-1.pd, subir un poco el volumen, aseguraros de que el "osc~" está recibiendo un valor con el que vibrar (con activar el "osc~" os he ayudado un poquitito con el objeto "loadbang" que envía automáticamente un bang al abrir el patch). Ahora hacer click en el bang azul del patch. ¿Escucháis algo? ¿Veis cómo se dibuja la onda cada vez que enviáis el bang? Recordar que, si no tenéis encendido el DSP, Pure Data no procesara señales y ni oiréis ni veréis nada Cuando enviamos el bang para activar el envelope que controla el volumen, habréis podido comprobar que cada vez suena un poco diferente, al igual que el dibujo de la onda que veis en el array "$0-scope3", que cada vez se empieza a dibujar en un punto distinto. Esto pasa por que la fase de la onda cada vez que activamos el envelope es distinta. Figura 2. Muchos aros girando con diferentes fases unos de otros. ¿Os acordáis de lo que es la fase? Lo vimos en la lección "Algo de teoría sobre las ondas". Para que suene siempre igual tendremos que inicializar la fase del oscilador cada vez que activemos el Kick drum, haremos esto a través del inlet derecho del oscilador. Podéis probar diferentes valores para la fase buscando el sonido que más os guste: Figura 3. Añadimos un control de fase al oscilador del patch Kick-drum-sencillo-paso-1.pd Envelope que controla la frecuencia Hasta el momento la frecuencia del kick drum se mantiene constante desde el inicio al final del sonido del kick drum, en la figura 3 es de 71 Hz. Para continuar dándole forma al kick drum vamos a introducir un envelope que modifique la frecuencia, siendo mas aguda al principio que al final. En este caso nuestro envelope tendrá tres secciones, la primera un Attack que va de 6 a 2 en 2 milisegundos. La segunda un Sustain que dura 3 milisegundos y la ultima un Release que va de 2 a 0 en 460 milisegundos. En este caso nuestro envelope no tiene Decay. 6, 2 2, 0 460 5 Rampas Valor inicial Valor Final Duración (milisegundos) Delay. Tiempo desde el inicio del envelope, hasta el comienzo de esta Rampa (milisegundos) Attack 6 2 2 0 Decay - - - Sustain 2 2 3 = 5 - 2 Release 2 0 460 5 Vemos que la duración del Sustain viene determinada por la duración de la rampa anterior y el delay de la rampa siguiente. Figura 4. Envelope que utilizaremos para controlar la frecuencia del "osc~" en el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd En el envelope de la figura 4, tenemos una variación de valores que va de 6 a 0 en 465 milisegundos. Una frecuencia de 6 Hz es muy muy baja y ni la escucharemos ni nuestros altavoces serán capaces de reproducirla. Lo que vamos a hacer es elegir una frecuencia central en torno a la cual se produzca la variación que nuestro envelope controla. Vamos a mezclar esa frecuencia y la señal que genera nuestro envelope utilizando el objeto "*~". Si os fijáis también multiplicamos el resultado del envelope por sí mismo con otro objeto "*~" esto hara los cambios del envelope más pronunciados: Figura 5. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos añadido el envelope que controla la frecuencia. Como podéis comprobar, hemos hecho coincidir el tiempo de duración total del envelope que regula la frecuencia y el del envelope que regula el volumen, 465 milisegundos, si estos tiempos fueran distintos, la duración del kick drum vendría determinada por el envelop que controla el volumen. Como podéis ver, multiplicamos nuestro envelope por el valor de la frecuencia central de nuestro kick drum. En el ejemplo de la figura 5, la frecuencia inicial del kick drum es de 6x45= 270, tras 2 milisegundos esa frecuencia baja y se mantiene 3 milisegundos en 2x45= 90 Hz y de ahí descenderá a 0 en 460 milisegundos. ¿Veis cómo como varia la frecuencia de nuestra onda con respecto al paso anterior en el cual la frecuencia era constante? Figura 6. Comparación entre la onda con frecuencia de 71 Hz constante (izquierda) y la onda con frecuencia variable (derecha) regulada por un envelope. Envelopes regulables Ahora, vamos a hacer regulable una parte del envelope que controla la frecuencia, en concreto el valor inicial del envelope utilizando el símbolo $, esto va a afectar al golpe inicial del kick drum. Hemos visto el uso del símbolo $ en Envelope | Librería CATEDU ¿Qué notáis al variar ese valor? Figura 7. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos hecho modificable el envelope que controla la frecuencia. Vamos a introducir ahora un nuevo elemento para controlar la escala de la frecuencia inicial de manera aleatoria. El objeto random. random Este objeto va a generar valores aleatorios en un rango determinado que comienza en 0. El número de valores desde el 0 que va a generar lo configuraremos en el argumento del random. Por ejemplo, si el argumento es 4, cada vez que reciba un bang enviara por su out put un 0, un 1, un 2 o un 3. Figura 8. patch random-demo.pd primera parte Si queremos que el rango comience en otro valor por ejemplo 17, sumaremos ese valor al resultado del random. De esta forma obtendremos valores aleatorios entre 17 y 20, 17 y 20 incluidos. Figura 9. patch random-demo.pd segunda parte Ejercicio 6: crea un patch utilizando el objeto random que genere valores pares entre 20 y 30. [20, 22, 24, 26, 28, 30]. A este patch lo llamareis random-ejercicio2_vuestronombre_vuestroapellido.pd Ejercicio 7: Observa los valores impresos en la ventana de Pd procedentes del random de la figura 9. ¿Qué sucede cada vez que envías el mensaje de "seed 50" al random? Para visualizar mejor lo que sucede imprime también el mensaje de "seed 50" cada vez que lo envies al objeto random. ¿Y si mandas en mensaje "seed 4962"? Observa la secuencia de números que se genera. En un documento al que llamareis random-ejercicio3_vuestronombre_vuestroapellido colocar una captura de pantalla de lo que sucede y responder a las preguntas. Ahora que ya conocemos el random, incluyámoslo en el control del envelope que regula la frecuencia de nuestro kick drum. El random va a controlar el valor de partida de ese envelope: Figura 10. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos hecho que un objeto random modifique el envelope que controla la frecuencia. Ejercicio 8: Una vez lograste un patch como el de la figura 10, os toca experimentar, probar lo queráis con lo que hemos a prendido hasta ahora, buscar sonido que os parezcan interesantes, lo que queráis. El archivo que creéis para este ejercicio lo llamareis kick-drum-lab_vuestronombre_vuestroapellido.pd ¿Qué tenemos que entregar? Los 4 ejercicios de la lección. Sube a la carpeta del Moodle de la Practica 7 los siguientes archivos: Ejercicio 5: patch practica7_Kick-drum-sencillo-vuestronombre_vuestroapellido.pd Ejercicio 6: patch practica7_random-ejercicio2_vuestronombre_vuestroapellido.pd Ejercicio 7: documento practica7_random-ejercicio3_vuestronombre_vuestroapellido Ejercicio 8: patch practica7_kick-drum-lab_vuestronombre_vuestroapellido.pd Figuras: Figura 1. patch Kick-drum-sencillo-paso-1.pd Figura 2. Muchos aros girando con diferentes fases unos de otros. https://giphy.com/gifs/hooping-hula-perth-MwC8t7MaaR7kCr3FaN Figura 3. Añadimos un control de fase al oscilador del patch Kick-drum-sencillo-paso-1.pd Figura 4. Envelope que utilizaremos para controlar la frecuencia del "osc~" en el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd Figura 5. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos añadido el envelope que controla la frecuencia. Figura 6. Comparación entre la onda con frecuencia constante (izquierda) y la onda con frecuencia variable (derecha) regulada por un envelope. Figura 7. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos hecho modificable el envelope que controla la frecuencia. Figura 8. patch random-demo.pd primera parte Figura 9. patch random-demo.pd segunda parte Figura 10. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos hecho que un objeto random modifique el envelope que controla la frecuencia.Práctica 8: OSC. Open Sound Control  ¿Qué es OSC? Open Sound Control, abreviado OSC, es un protocolo de comunicación entre dispositivos (ordenadores, sintetizadores ...) que está optimizado para tecnologías conectadas en red (Hutchinson, 2022). ¿Y qué es un protocolo? Un protocolo es un lenguaje, un código que tanto emisor como receptor comprenden y nos va a servir para enviar datos estructurados que una vez recibidos podamos descifrar. En este curso vamos a utilizar este protocolo para comunicar Pure data con otros programas y/o dispositivos. Esto nos va a permitir, por ejemplo, controlar Pure data desde el móvil. Para entender cómo funciona, primero vamos a utilizar un ejemplo muy sencillo que nos va a permitir controlar desde un móvil, tablet u otro programa del ordenador el Kick drum que hemos hecho en Práctica 7: Kick drum ... | Librería CATEDU . Vamos a utilizar una aplicación o app para ello. El ordenador y el movil que queramos utilizar para este ejercicio deberán de estar conectados a la misma red, por ejemplo ambos deben de estar conectados a la wifi de casa. Para asegurarnos de esto podemos apagar los datos de nuestro movil y solamente conectarlo a traves de la wifi. Etiquetas y datos ¿Os acordáis de la diferencia entre datos e información que veíamos en Programación en genera... | Librería CATEDU? Vamos a ver como toma relevancia a la hora de enviar datos. Para que los datos que recibimos puedan ser interpretados como información tendremos que ponerlos en contexto y para ello vamos a utilizar etiquetas que nos indiquen el origen y contexto de cada dato. Figura 1. El programa emisor poniéndole una etiqueta a un mensaje osc, para saber que contiene. Los datos van a llegar por el mismo sitio y pueden ser diferentes como, por ejemplo, la hora de llagada y la hora de salida de un tren. Si solo recibimos la hora: "16:45" y nada mas no podremos saber si es la hora de salida o de llegada necesitaremos recibir un mensaje con otro dato que nos proporcione esa información: "salida 16:45". Ahora ya sabemos que la hora que hemos recibido es la de salida. ¡Vamos a ello! Comencemos por instalar y configurar la app en nuestro móvil o tablet: Si no tienes un dispositivo Android más abajo te damos una alternativa para el ordenador y otros dispositivos. Movil-Tablet Android Vamos a instalar la aplicación "OSCcontroller", podéis encontrarla en el siguiente enlace. Una vez instalada, la abrimos y configuramos la IP de la red a través de la cual queremos enviar datos. ¿Qué es la IP? Una IP es la dirección que utilizan los dispositivos conectados a red para identificarse. En nuestro caso, vamos a tomar la IP local o privada. ¿Y cómo sabemos cual es nuestra IP? Podremos consultarlo en nuestro ordenador, accediendo a la configuración de red: Figura 2. Consultar la IP local en Windows 10. Esta IP es la que vamos a introducir en la app "OSCcontroller". Tambien vamos a configurar el puerto a través del cual nos vamos a comunicar, que sera el mismo que configuraremos en Pure data. El puerto es el canal especifico en el que vamos a enviar los datos. Para este ejemplo utilizaremos el 8000, pero podéis utilizar otro puerto que tengáis libre. Nuestra IP puede cambiar así que, si vemos que no funciona, nos aseguraremos de que la IP de nuestra red coincide con la que configuramos en la app. Figura 3. Configuración de IP, puerto, inicio de la conexión y acceso a los controles que enviaran los mensajes osc en la app OSCcontroller. Una vez tengamos IP y puerto configurados pulsaremos Start para iniciar la conexión. El botón azul de control nos llevara a una ventana en la que encontraremos sliders, botones e interruptores y son los valores de estos controles los que se enviaran por osc. ¡Nuestro móvil o tablet ya está listo para enviar datos! Ahora vamos a configurar Pure data: Configuremos Pure data Para recibir esta comunicación a través de la red, vamos a utilizar el objeto "netreceive" de la siguiente manera: Vamos a configurar el puerto de escucha en Pure data enviando un mensaje con el texto "listen" y el numero del puerto. Pondremos dos argumentos en el objeto "netreceive" para asegurar su correcto funcionamiento: "-u" y  "-b". Los datos recibidos por "netreceive" serán traducidos por el objeto "oscparse" a un language legible. Tras la traducción vamos a imprimir lo que estamos recibiendo. ¡Comencemos a enviar datos! Vamos a tocar los botones y sliders que vemos en la ventana de control del móvil: Figura 4. ventana de los controles en la app OSCcontroller. Figura 5. Pure data imprime los datos recibidos por osc y que se han enviado desde la app OSCcontroller. Vamos a fijarnos en la interfaz del móvil en la figura 4. Tenemos 4 sliders en la parte izquierda, en la parte derecha superior tenemos tres interruptores y debajo de estos tres pulsadores. Cada uno de estos sliders, botones y pulsadores van a tener un código identificativo, una etiqueta que nos permitirá saber desde que objeto de control proviene la información recibida. Vamos a fijarnos ahora en las líneas impresas en la ventanita de Pd. En las primeras líneas podemos leer lo siguiente: print: list oscControl slider4 0.16 Encontramos palabras y números separados por un espacio. Vamos a ver qué indican cada uno de estos grupos. Como bien sabeis el "print:" nos indica que esta linea que aparece en la ventanita son datos impresos desde un patch de pd utilizando el objeto print. La palabra "list" nos indica que lo que se está imprimiendo es una lista de elementos. La palabra "oscControl" es una etiqueta que identifica el emisor de estos datos, en nuestro caso es la app OSCcontrol. Podemos configurar el nombre de esta etiqueta en la app: Figura 6. Marcado en rojo se muestra donde cambiar la etiqueta del emisor en la app "OSCcontroller". La siguiente palabra es una etiqueta que nos va a indicar desde elemento de control se envían los datos. Que botón, interruptor o slider envía esos datos: slider1, slider2, slider3, slider4, toggle1 toggle2 toggle3, button1, button2 o button3. print: list oscControl slider4 0.16 Tras esta etiqueta que indica desde que botón, interruptor o slider se envían esos datos, encontraremos un valor numérico que corresponde con el estado del botón, interruptor o slider. Este envío se va a realizar cuando cambie el estado del botón, interruptor o slider, por ejemplo, cuando pulsemos un botón o movamos un slider. Como podéis ver en la figura 5, en la consola de Pd recibimos información de varios actuadores/elementos de control. El slider4 en la posición 0.16, el button1 y el button2 han sido pulsados, el toggle3 ha encendido y apagado, el toggle2 ha sido encendido y permanece encendido y finalmente el button3 y el button1 han sido pulsados. Ejercico 9: Montad el sistema que acabamos de ver y haced pruebas con los actuadores y el print. ¿Funciona? Figura 7. El paquete del slider4 de camino a Pure data cuando no enviamos el mensaje "listen 8000" al objeto "netreceive". Una vez recibimos los datos en Pd tendremos que procesarlos un poco para poder utilizarlos para modificar parámetros en nuestro patch. Como hemos visto estamos recibiendo una lista con etiquetas y un valor numérico, vamos a desgranar y clasificar esa lista. Vamos a empezar por quitar la palabra "list" de nuestra lista de datos, utilizando el objeto "list trim" Figura 8. Uso del objeto "list trim" para eliminar la palabra "list" de la lista en Pure data. Ahora, vamos a ver cómo clasificar los datos en base a sus etiquetas con el objeto "route". Al tener solo datos enviados de desde el mismo origen, todas las listas contienen la palabra oscControl que hace referencia al origen de los datos. Si recibiéramos datos de dos fuentes distintas tendríamos una etiqueta diferente para identificar cada fuente, como en el siguiente ejemplo: Figura 9. mensajes osc recibidos de dos emisores distintos en Pure data. Para separar los datos de cada emisor, utilizaremos el objeto route cuyos argumentos serán el nombre de la etiqueta de cada emisor. En el ejemplo de las figuras 9 y 10, he utilizado dos aplicaciones distintas para enviar mensajes osc y mostraros como seria, pero vosotros de momento solo utilizareis OSCcontrol. Figura 10. Uso del objeto "route" para clasificar los mensajes osc procedentes de dos emisores en Pure data. Fuente 1=oscControl, Fuente 2=multisense. Por la primera salida del route, saldran las listas con la etiqueta oscControl, que es el primer argumento del "route"; por la segunda salida, las listas con la etiqueta multisense; y por la tercera salida, las listas que no contengan ninguna de las etiquetas anteriores. Como podéis observar, tras clasificar estas listas el route elimina la etiqueta de la lista, que era el primer elemento de la lista. La figura 10 era un ejemplo con dos fuentes, aunque en el ejercicio que estamos haciendo solo vamos a trabajar con una fuente, vamos a utilizar el route para quitar la etiqueta oscCcontrol. Ahora vamos a clasificar los datos que vienen de cada botón utilizando el objeto route. Para los botones podemos ver en la lista que hemos impreso previamente que las etiquetas que utilizan son button1, button2 y button3. Utilizaremos esas etiquetas en el route. Figura 11. Clasificación de los datos recibidos por osc en Pure data. Vemos que al pulsar el botón 1 se envía un 1 a traves de la primera salida del route y al pulsar el botón 3 se envía un 1 a traves de la tercera salida del route. Al encender un toggle se envía un 1 y al apagarlo un 0. Los sliders envían un valor correspondiente a la posición del indicador en un rango de 0 a 1. Ejercicio 10 : Una vez hemos conseguido enviar valores desde nuestro móvil a nuestro patch estamos listos para incluir estos controles en el kick drum que hemos hecho en la Práctica 7: Kick drum ... | Librería CATEDU. Vamos a utilizar los tres botones para controlar cada uno de los valores iniciales del envelope que regula la frecuencia del kick drum. Si os fijáis, en el patch que hicimos era un random el que controlaba los valores iniciales del envelope, ahora van a ser los botones de la app oscControl. Ejercicio 11: Ahora que ya controlas el envelope de la frecuencia con los botones, intenta controlar la frecuencia general con el slider1 y el volumen con el slider2. ¿Y qué pasa con los que no tenéis un dispositivo Android? Os vamos a dar una alternativa que es la aplicación TouchOSC. Esta aplicación está disponible para iphone y android pero en estos dispositivos es una aplicación de pago. La version de prueba de ordenador de esta aplicación es gratuita y podréis utilizarla para aprender a enviar mensajes osc desde otro programa a Pure Data. Aunque utilicemos una aplicación distinta para enviar los mensajes de osc, estos funcionaran de la misma manera que en el ejemplo con Android.  Pure Data nos llegaran listas con etiquetas y valores que tendremos que procesar. Movil-Tablet-Ordenador MacOSX Vamos a descargar e instalar la última version para nuestro sistema operativo desde este link: https://hexler.net/touchosc/bridge-releases TouchOSC: Abrimos el ejemplo BeatMachine Mk2, en Help > Examples. Salimos del modo de edición con Cmd + EConfiguración: En TouchOSC > Connections Figura 12. programa "Touch OSC" En la pestaña OSC configuramos en Host nuestra ipv4 y en Send Port: 8000 Figura 13. Configuración de IP y puerto en "Touch OSC". Abrimos nuestro patch de Pure Data y hacemos click sobre listen 8000. Si no lo hacemos, Pure Data no recibirá información.Una vez hayamos hecho click, podemos comenzar a girar los botones en TouchOSC y veremos cómo los valores se imprimen en la consola de Pure Data, como puedes ver en el siguiente .gif: Figura 14. "Touch OSC" enviando mensajes osc a Pure data. Aqui encontrareis un video de como configurar el programa si tenéis alguna duda. La parte de la aplicación Protokol no es necesaria ya que solo visualiza esos mensajes: https://hexler.net/touchosc/manual/getting-started-osc ¿Qué tenemos que entregar? El ejercicio 10 y 11. Sube a la carpeta del Moodle de la Practica 8: Ejercicio 10: Un video en el que se vea y escuche como desde otra aplicación se controla el kick drum en Pd. El video deberá llamarse: practica8-video_vuestronombre_vuestroapellido. Ejercicio 11: una captura de pantalla del patch y el patch que has creado. El patch deberá llamarse: practica8_vuestronombre_vuestroapellido.pd y la imagen practica8-imagen_vuestronombre_vuestroapellido. Referencias: Hutchinson, S. [Simon Hutchinson].  (2022, 7 febrero). Open Sound Control (OSC) in Pure Data Vanilla | Simon Hutchinson. [Video]. https://youtu.be/tJ2Kocl-2m4 Figuras: Figura 1. El emisor poniéndole una etiqueta a un mensaje osc, para saber que contiene. https://giphy.com/gifs/GLSSpain-box-parcel-paquete-OKPtqN7dlflYcw8gPu Figura 2. Consultar la IP local en Windows 10. Figura 3. Configuración de IP, puerto, inicio de la conexión y acceso a los controles que enviaran los mensajes osc. Figura 4. ventana de los controles en la app OSCcontroller. Figura 5. Pure data imprime los datos recibidos por osc y que se han enviado desde la app OSCcontroller. Figura 6. Marcado en rojo se muestra donde cambiar la etiqueta del emisor en la app "OSCcontroller". Figura 7. El paquete del slider4 de camino a Pure data cuando no enviamos el mensaje "listen 8000" al objeto "netreceive". https://giphy.com/gifs/page-usps-XoPxquIwsYXpC Figura 8. Uso del objeto "list trim" para eliminar la palabra "list" de la lista en Pure data. Figura 9. mensajes osc recibidos de dos emisores distintos en Pure data. Figura 10. Uso del objeto "route" para clasificar los mensajes osc procedentes de dos emisores en Pure data. Fuente 1=oscControl, Fuente 2=multisense. Figura 11. Clasificación de los datos recibidos por osc en Pure data. Figura 12. programa "Touch OSC" Figura 13. Configuración de IP y puerto en "Touch OSC". Figura 14. "Touch OSC" enviando mensajes osc a Pure data.Subpatch A medida que vamos conociendo más elementos de Pure data y creando programas más complejos, nuestros patches se llenan más y más de cajitas y líneas que cruzan de un lado a otro, dificultando la legibilidad de nuestro algoritmos. Figura 1. Patch de Pure data, poco legible para el ojo humano. Vamos a intentar evitar situaciones como la de la imagen anterior. Existen algunos objetos que nos van a ayudar a mantener orden y claridad en nuestros patches, algunos de ellos ya los conocemos. Son el send y el receive que vimos en la Practica 2: nuestro pr... | Librería CATEDU. El nuevo elemento que vamos a introducir hoy es el subpatch. ¿Y que es un subpatch? Un subpatch es un patch que vamos a crear dentro de nuestro patch principal de pure data y que nos va a permitir agrupar partes del programa para que nuestro algoritmo principal sea fácilmente visible y comprensible, para que nosotros o cualquier persona que lea nuestro programa pueda entender qué es lo que estamos haciendo rápidamente. Recordemos la metáfora de la receta del libro de cocina que veíamos en la página de Entorno | Librería CATEDU. En el siguiente video veremos cómo crear un subpatch utilizando el objeto "pd" Ejercicio 12: Tras crear el subpatch que ves en el video. añade dos subpatches más uno para el volumen y otro para la comunicación osc. Figuras: Figura 1. Patch de Pure data, poco legible para el ojo humano. https://patchstorage.com/shedding-hydrogen/ MÓDULO 7: ARDUINO Realizaremos tres prácticas con el pulsómetro de nuestro kit Práctica 9.1 Medimos nuestras pulsaciones El pulsómetro Uno de los sensores que vienen con nuestro kit es este: Este sensor se va a encargar de detectar nuestras pulsaciones. Aunque no vamos a entrar a explicar su funcionamiento. Si quieres saber más, puedes hacer click en este enlace. Para detectar nuestras pulsaciones, tendremos que colocar nuestro dedo pulgar sobre la imagen del corazón blanco, sin presionar muy fuerte. Conectarlo a nuestro Arduino no puede ser más sencillo. Si miras en el lado contrario en el que está dibujado el corazón, te encontrarás esto: Verás que, probablemente, el color de los cables de tu pulsómetro es distinto al mío, pero eso no importa. Te tienes que fijar en las letras que hay escritas al lado de cada cable. La letra S es la que e encarga de transportar la señal desde nuestro sensor hasta Arduino y para esta práctica irá conectada a nuestro UNO en el pin A0. El símbolo + es el que se encarga de alimentar a nuestro Arduino e irá en el pin 5V. Por último, el signo - es el que va a masa (ground) y en nuestro UNO irá conectado a uno de los dos pines GND. Las conexiones nos quedarán como las de esta imagen: Una vez hemos conectado nuestro sensor a Arduino, pasaremos a ver qué tenemos que hacer en la IDE de Arduino para hacerlo funcionar. La librería Pulse Sensor Playground Como ya sabes, una librería (también te la puedes encontrar denominada como biblioteca) de Arduino es una colección de código y ejemplos sobre un tema o dispositivo específico. Por ejemplo, para controlar el sensor que vamos a utilizar en esta práctica, un pulsómetro, vamos a emplear la biblioteca/librería PulseSensor Playground. En ella, vamos a encontrar una colección de código y proyectos creados exclusivamente para facilitar el uso de este sensor junto con Arduino. Lo primero que haremos será instalar esta librería. Para ello, iremos a Programa > Incluir Librería > Administrar Bibliotecas... : Una vez ahí, haremos click y nos aparecerá una ventana emergente en la que podremos buscar la librería, que en este caso se llama PulseSensor Playground, cuando aparezca, pondremos el ratón sobre ella y nos aparecerá el botón Instalar. La instalaremos: Cerraremos la ventana emergente y veremos que si vamos a Archivo > Ejemplos nos aparecerán los ejemplos de la librería PulseSensor Playground: Una vez la hayamos instalado, abriremos el ejemplo GettingStartedProject. Y pasaré a explicarte lo que hace cada línea de código. ¡Pulsación detectada ♥! Lo primero que voy a hacer es poner aquí el código, aunque imagino que ya lo tienes abierto en tu IDE de Arduino: /* PulseSensor Starter Project and Signal Tester * The Best Way to Get Started With, or See the Raw Signal of, your PulseSensor.com™ & Arduino. * * Here is a link to the tutorial * https://pulsesensor.com/pages/code-and-guide * * WATCH ME (Tutorial Video): * https://www.youtube.com/watch?v=RbB8NSRa5X4 * * ------------------------------------------------------------- 1) This shows a live human Heartbeat Pulse. 2) Live visualization in Arduino's Cool "Serial Plotter". 3) Blink an LED on each Heartbeat. 4) This is the direct Pulse Sensor's Signal. 5) A great first-step in troubleshooting your circuit and connections. 6) "Human-readable" code that is newbie friendly." */ // Variables int PulseSensorPurplePin = 0; // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 0 int LED13 = 13; // The on-board Arduion LED int Signal; // holds the incoming raw data. Signal value can range from 0-1024 int Threshold = 550; // Determine which Signal to "count as a beat", and which to ingore. // The SetUp Function: void setup() { pinMode(LED13,OUTPUT); // pin that will blink to your heartbeat! Serial.begin(9600); // Set's up Serial Communication at certain speed. } // The Main Loop Function void loop() { Signal = analogRead(PulseSensorPurplePin); // Read the PulseSensor's value. // Assign this value to the "Signal" variable. Serial.println(Signal); // Send the Signal value to Serial Plotter. if(Signal > Threshold){ // If the signal is above "550", then "turn-on" Arduino's on-Board LED. digitalWrite(LED13,HIGH); } else { digitalWrite(LED13,LOW); // Else, the sigal must be below "550", so "turn-off" this LED. } delay(10); } Ahora, vamos a ir desmenuzando qué es lo que hace el código: Todo el primer bloque, recogido entre los símbolos /* */ es un comentario. No volveremos a explicar su función porque ya lo vimos en este apartado. Pasaremos directamente a los párrafos que contienen las variables: // Variables int PulseSensorPurplePin = 0; // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 0 int LED13 = 13; // The on-board Arduion LED int Signal; // holds the incoming raw data. Signal value can range from 0-1024 int Threshold = 550; // Determine which Signal to "count as a beat", and which to ingore. Para hacer funcionar nuestro proyecto, necesitaremos crear 4 variables de números enteros (int). La primera de ellas PulseSensorPurplePin tiene el valor 0, ya que va conectado el pin analógico A0. Aparece el color purple, porque en el sensor para el que en origen se creó este ejemplo, el cable que se conecta a A0 era morado. La variable LED13 tiene el valor 13, ya que es el pin al que va conectado el pin que va integrado en la placa de nuestro UNO. Signal almacenará el valor que nuestro sensor produce cuando está intentando detectar una pulsación. Como se trata de un sensor analógico, la señal se corresponderá a valores discretos, dentro del rango 0 hasta 1024.Por último, Threshold será el umbral a partir del cual podremos afirmar que se ha producido un latido, una pulsación, en este caso será 550. Ya habíamos dicho que el umbral de nuestra señal iba de 0 a 1024, por lo que utilizar 550 es una buena referencia. A continuación, vamos a pasar a ver la función setup(): // The SetUp Function: void setup() { pinMode(LED13,OUTPUT); // pin that will blink to your heartbeat! Serial.begin(9600); // Set's up Serial Communication at certain speed. } Es bastante breve y en ella lo único que necesitamos incluir es el modo del pin que vamos a utilizar gracias a la función pinmode(). En ella indicaremos el pin y si va a ser de entrada (INPUT) o de salida (OUTPUT). Como en este caso es un LED, le diremos que es de salida. También le diremos a nuestro UNO a que velocidad tiene que enviar la información a través del puerto serial, que en este caso será 9600 baudios. Recuerda que todo lo incluido en la función setup() solamente se ejecutará una vez. La última parte de nuestro sketch se corresponde con la función loop(). // The Main Loop Function void loop() { Signal = analogRead(PulseSensorPurplePin); // Read the PulseSensor's value. // Assign this value to the "Signal" variable. Serial.println(Signal); // Send the Signal value to Serial Plotter. if(Signal > Threshold){ // If the signal is above "550", then "turn-on" Arduino's on-Board LED. digitalWrite(LED13,HIGH); } else { digitalWrite(LED13,LOW); // Else, the sigal must be below "550", so "turn-off" this LED. } delay(10); } En ella, lo primero que vamos a hacer es almacenar en la variable Signal los valores que lea nuestro sensor. Para leer esos valores, usaremos la función analogRead(). Indicaremos que la señal analógica que ha de ser leída es la que recibamos con la variable PulseSensor PurplePin.A continuación, imprimiremos por nuestro puerto serial el valor obtenido, aunque para visualizar las pulsaciones no nos va a servir de mucho, porque los números aparecen a gran velocidad. Para visualizar las posiciones usaremos el LED. ¿Cómo? Pues usaremos un condicional: "Oye, Arduino, si (if) la señal que lees es mayor que el umbral (Signal > Threshold), enciende el LED (digitalWrite(LED13,HIGH)), si no (else), apágalo (digitalWrite(LED13,LOW))". Para finalizar, usamos un delay de 10 milisegundos, para darle a nuestro Arduino un pequeño respiro entre lectura y lectura. Ahora, conectaremos nuestro UNO al ordenador y subiremos el código. En este GIF puedes ver cómo la luz naranja situada más a la derecha, comienza a parpadear cuando coloco mi dedo encima del pulsómetro: Cuando no está el dedo colocado, la luz también parpadeará aleatoriamente. Eso no sucede porque el sensor esté roto o no funcione bien, sino porque el sensor realizará lecturas erróneas. Intentará detectar pulsaciones, aunque nuestro dedo no esté colocado sobre él. Es importante colocar el dedo sin apretar mucho y sin moverlo y esperaremos uno 3 o 4 segundos hasta que el sensor sea capaz de leer correctamente nuestras pulsaciones. ¿Qué tenemos que presentar? En este caso será suficiente con que me envíes un .gif o video en el que se vea el pulsómetro sin tu dedo y luego con tu dedo sobre él, iluminándose el LED naranja, similar al video que aparece justo encima de este apartado. FUENTES Librería de Pulse Sensor: https://pulsesensor.com/pages/installing-our-playground-for-pulsesensor-arduinoSobre Pulse Sensor: https://pulsesensor.com/pages/code-and-guidePráctica 9.2: Calculamos nuestras pulsaciones por minuto Ahora, vamos a pasar a hacer algo más interesante. Está bien poder detectar nuestras pulsaciones, pero ¿por qué no contar el número de pulsaciones que tenemos por minuto o BPM? Lo haremos con el siguiente código: /* Getting_BPM_to_Monitor prints the BPM to the Serial Monitor, using the least lines of code and PulseSensor Library. * Tutorial Webpage: https://pulsesensor.com/pages/getting-advanced * --------Use This Sketch To------------------------------------------ 1) Displays user's live and changing BPM, Beats Per Minute, in Arduino's native Serial Monitor. 2) Print: "♥ A HeartBeat Happened !" when a beat is detected, live. 2) Learn about using a PulseSensor Library "Object". 4) Blinks LED on PIN 13 with user's Heartbeat. --------------------------------------------------------------------*/ #define USE_ARDUINO_INTERRUPTS true // Set-up low-level interrupts for most acurate BPM math. #include // Includes the PulseSensorPlayground Library. // Variables const int PulseWire = 0; // PulseSensor PURPLE WIRE connected to ANALOG PIN 0 const int LED13 = 13; // The on-board Arduino LED, close to PIN 13. int Threshold = 550; // Determine which Signal to "count as a beat" and which to ignore. // Use the "Gettting Started Project" to fine-tune Threshold Value beyond default setting. // Otherwise leave the default "550" value. PulseSensorPlayground pulseSensor; // Creates an instance of the PulseSensorPlayground object called "pulseSensor" void setup() { Serial.begin(9600); // For Serial Monitor // Configure the PulseSensor object, by assigning our variables to it. pulseSensor.analogInput(PulseWire); pulseSensor.blinkOnPulse(LED13); //auto-magically blink Arduino's LED with heartbeat. pulseSensor.setThreshold(Threshold); // Double-check the "pulseSensor" object was created and "began" seeing a signal. if (pulseSensor.begin()) { Serial.println("We created a pulseSensor Object !"); //This prints one time at Arduino power-up, or on Arduino reset. } } void loop() { int myBPM = pulseSensor.getBeatsPerMinute(); // Calls function on our pulseSensor object that returns BPM as an "int". // "myBPM" hold this BPM value now. if (pulseSensor.sawStartOfBeat()) { // Constantly test to see if "a beat happened". Serial.println("♥ A HeartBeat Happened ! "); // If test is "true", print a message "a heartbeat happened". Serial.print("BPM: "); // Print phrase "BPM: " Serial.println(myBPM); // Print the value inside of myBPM. } delay(20); // considered best practice in a simple sketch. } Como puedes ver, no tiene muchas líneas, ¿por qué? Pues porque la mayor parte de procesos los realizan funciones que nos vienen preprogramadas en la librería PulseSensor Playground. Así, nosotras no tenemos que preocuparnos demasiado de esa parte y nos resultará más sencillo integrar nuestro pulsómetro con otros sensores o actuadores, haciendo que no sean necesarias tantas líneas de código. Desmenuzando el código Como ya he hecho en anteriores páginas, no voy a volver a explicarte la parte de los comentarios, aunque te invito a leerlos, porque de esta manera entenderás mejor el propósito del código y las partes de este. En esta práctica, vamos a ver un concepto nuevo en el que no vamos a ahondar demasiado: las interrupciones. #define USE_ARDUINO_INTERRUPTS true // Set-up low-level interrupts for most acurate BPM math. #include // Includes the PulseSensorPlayground Library. Las interrupciones Las interrupciones se encargan de indicarle a nuestro Arduino que cierto proceso ha de ser atendido con una prioridad mayor a cualquier otro. De esta manera se interrumpe cualquier actividad del Arduino para atender la información recibida a través de alguno de los pines. En nuestro ejemplo concreto, para asegurar una correcta lectura de nuestras pulsaciones, usamos la orden  #define USE_ARDUINO_INTERRUPTS true. Todo el manejo de las interrupciones permanece oculto, pero es necesario para la correcta lectura de nuestras pulsaciones. Si quieres saber más sobre interrupciones, puedes echarle un vistazo a este enlace. Las librerías La siguiente línea que encontramos importa la librería PulseSensorPlayground.h. A Arduino necesitaremos indicárselo usando la palabra reservada #include seguida de la librería que queramos incluir, entre < >. Las librerías, son archivos con la terminación .h. Estos documentos pueden ser abiertos en un editor de texto y podemos ver su contenido y modificarlos, aunque esto último no te lo aconsejo... ya que si no estamos seguros de qué estamos modificando y borramos o editamos algo que no deberíamos, esta librería dejaría de funcionar y tendríamos que reinstalarla. Las variables y constantes Si avanzamos, encontramos las siguientes líneas, las cuales aparecen explicadas en los comentarios que las acompañan a la derecha: const int PulseWire = 0; // PulseSensor PURPLE WIRE connected to ANALOG PIN 0 const int LED13 = 13; // The on-board Arduino LED, close to PIN 13. int Threshold = 550; // Determine which Signal to "count as a beat" and which to ignore. // Use the "Gettting Started Project" to fine-tune Threshold Value beyond default setting. // Otherwise leave the default "550" value. En Arduino, habíamos visto que existen distintos tipos de datos para almacenar información. Por ejemplo, si estamos trabajando con números, podíamos usar, entre otros, números enteros o decimales, int o float respectivamente. A parte de elegir el tipo de datos, podemos indicarle a nuestro Arduino si el valor que vamos a almacenar va a variar o siempre va a ser el mismo. Si el valor puede ser modificado a lo largo del código, escribiremos las variables como hemos hecho hasta ahora, pero si no queremos que ese valor cambia, si queremos que sean constantes, tendremos que escribir delante la palabra const. El objeto pulseSensor Para hacer uso de las funciones preprogramadas en la librería que queremos utilizar, tenemos que crear "una instancia del objeto PulseSensorPlayground". Eso es lo que nos pone en el comentario que acompaña a la siguiente línea de código. Pero, ¿qué significa eso? PulseSensorPlayground pulseSensor; // Creates an instance of the PulseSensorPlayground object called "pulseSensor" Bueno, si te suena raro, voy a explicártelo con coches. Por un lado existe la idea abstracta de coche y, por otro, los coches reales que podemos conducir con unas características que los diferencian según la marca, el año, etc. Bueno, hasta aquí todo bien. Pues nuestra librería es como la idea de coche, también tiene una serie de características y para usarlas, tendremos que crear un objeto que funcione como un pulsómetro. En el caso de los coches, una instancia de la idea de coche podría ser un ALFA ROMEO Giulietta 1.6 JTD 120CV. En el caso de nuestra librería, podemos crear una instancia de un pulsómetro con la línea de código: PulseSensorPlayground pulseSensor; Ahí, lo que estamos diciendo es que a partir de la idea de coche/librería PulseSensorPlayground, vamos a obtener un coche/pulsómetro que se va a llamar pulseSensor. Una vez hayamos creado este objeto, podremos utilizar las funciones que en la librería han sido programadas. void setup(): lo que se ejecuta una sola vez Una vez tenemos  todo preparado, será necesario comenzar la comunicación a través del puerto serie y configurar nuestro objeto pulseSensor. Para ello, usaremos funciones vinculadas a él. Estas funciones tendremos que escribirlas a continuación de nuestro objeto y separadas de este por un '.' Una de ellas es pulseSensor.analogInput(PulseWire). Ahí, lo que estamos diciendo es que para nuestro pulsómetro, el pin de entrada va a ser el pin A0. Si recuerdas, la constante pulseWire ya la hemos definido antes. Las otras dos funciones que la siguen, lo que dicen es que el LED que parpadeará será el 13 (pulseSensor.blinkOnPulse(LED13)) y que el umbral para detectar la pulsación sea el que hemos definido antes con la constante Threshold (pulseSensor.setThreshold(Threshold)) . void setup() { Serial.begin(9600); // For Serial Monitor // Configure the PulseSensor object, by assigning our variables to it. pulseSensor.analogInput(PulseWire); pulseSensor.blinkOnPulse(LED13); //auto-magically blink Arduino's LED with heartbeat. pulseSensor.setThreshold(Threshold); // Double-check the "pulseSensor" object was created and "began" seeing a signal. if (pulseSensor.begin()) { Serial.println("We created a pulseSensor Object !"); //This prints one time at Arduino power-up, or on Arduino reset. } } A continuación, encontramos un condicional en el que, si hemos comenzado la comunicación por el puerto serie, imprimiremos: We created a pulseSensor object!. void loop(): lo que se ejecuta todo el rato A continuación, vamos a guardar en una variable las pulsaciones por minuto que va a calcular la función .getBeatsPerMinute(). Esto lo va a calcular la función directamente, así que no tendremos que preocuparnos de cómo se hace. En el siguiente condicional, lo que vamos a hacer es que cada vez que se detecte una pulsación, con la función .sawStartOfBeat(), se va a imprimir por el puerto serie un aviso de que ha ocurrido una pulsación e imprimirá las pulsaciones por minuto actuales. Para finalizar, se añade un pequeño delay para que la lectura de pulsaciones se realice correctamente. void loop() { int myBPM = pulseSensor.getBeatsPerMinute(); // Calls function on our pulseSensor object that returns BPM as an "int". // "myBPM" hold this BPM value now. if (pulseSensor.sawStartOfBeat()) { // Constantly test to see if "a beat happened". Serial.println("♥ A HeartBeat Happened ! "); // If test is "true", print a message "a heartbeat happened". Serial.print("BPM: "); // Print phrase "BPM: " Serial.println(myBPM); // Print the value inside of myBPM. } delay(20); // considered best practice in a simple sketch. } Ahora que ya entendemos el código, conectamos nuestro Arduino al ordenador y subimos el código. En este .gif podemos verlo en acción: ¿Qué tenemos que presentar? En este caso, al igual que con la práctica anterior, será suficiente con que me envíes un .gif o video en el que se vea el pulsómetro sin tu dedo, luego con tu dedo sobre él, y que posteriormente la cámara enfoque al monitor y con el puerto serial abierto, sea posible ver las pulsaciones. Similar al video que aparece justo encima de este apartado. Práctica 9.3: Visualizamos cada pulsación en el serial plotter Como ya hemos visto, al abrir el puerto serial, comenzamos a transmitir información entre nuestro Arduino y nuestro ordenador. Lo que vamos a ver ahora son las dos maneras en que podemos visualizar esa transmisión de información. Hasta ahora, hemos utilizado el monitor serial, pero en esta práctica vamos a emplear el plotter. Habíamos visto que para abrir el puerto serie, había que hacer click sobre el icono de lupa en la esquina superior derecha. Para visualizarlo como plotter no será necesario hacer click en ningún otro sitio, pero cuando nuestro ratón este sobre el icono de la lupa, tendremos que pulsar la tecla shift (flecha hacia arriba). De esta manera, en lugar de aparecer las palabras Monitor Serie, cuando nuestro ratón esté sobre la lupa pondrá Serial Plotter. ¿Para qué necesitamos el Serial Plotter? Es otra manera de visualizar la información. A través del monitor serie, podemos visualizarla en forma de números y caracteres; mientras que el plotter nos permite visualizar esa información gráficamente, como en el caso que nos ocupa de las pulsaciones. En el anterior ejemplo veíamos el número de pulsaciones por minuto y ahora lo que vamos a hacer es visualizar cada pulsación como una línea, al igual que en un electrocardiograma. El código Este es el código que pasaremos a comentar: /* Code to detect pulses from the PulseSensor, using an interrupt service routine. Here is a link to the tutorial\ https://pulsesensor.com/pages/getting-advanced Copyright World Famous Electronics LLC - see LICENSE Contributors: Joel Murphy, https://pulsesensor.com Yury Gitman, https://pulsesensor.com Bradford Needham, @bneedhamia, https://bluepapertech.com Licensed under the MIT License, a copy of which should have been included with this software. This software is not intended for medical use. */ /* Every Sketch that uses the PulseSensor Playground must define USE_ARDUINO_INTERRUPTS before including PulseSensorPlayground.h. Here, #define USE_ARDUINO_INTERRUPTS true tells the library to use interrupts to automatically read and process PulseSensor data. See ProcessEverySample.ino for an example of not using interrupts. */ #define USE_ARDUINO_INTERRUPTS true #include /* The format of our output. Set this to PROCESSING_VISUALIZER if you're going to run the Processing Visualizer Sketch. See https://github.com/WorldFamousElectronics/PulseSensor_Amped_Processing_Visualizer Set this to SERIAL_PLOTTER if you're going to run the Arduino IDE's Serial Plotter. */ const int OUTPUT_TYPE = SERIAL_PLOTTER; /* Pinout: PULSE_INPUT = Analog Input. Connected to the pulse sensor purple (signal) wire. PULSE_BLINK = digital Output. Connected to an LED (and 220 ohm resistor) that will flash on each detected pulse. PULSE_FADE = digital Output. PWM pin onnected to an LED (and resistor) that will smoothly fade with each pulse. NOTE: PULSE_FADE must be a pin that supports PWM. Do not use pin 9 or 10, because those pins' PWM interferes with the sample timer. */ const int PULSE_INPUT = A0; const int PULSE_BLINK = 13; // Pin 13 is the on-board LED const int PULSE_FADE = 5; const int THRESHOLD = 550; // Adjust this number to avoid noise when idle /* All the PulseSensor Playground functions. */ PulseSensorPlayground pulseSensor; void setup() { /* Use 115200 baud because that's what the Processing Sketch expects to read, and because that speed provides about 11 bytes per millisecond. If we used a slower baud rate, we'd likely write bytes faster than they can be transmitted, which would mess up the timing of readSensor() calls, which would make the pulse measurement not work properly. */ Serial.begin(115200); // Configure the PulseSensor manager. pulseSensor.analogInput(PULSE_INPUT); pulseSensor.blinkOnPulse(PULSE_BLINK); pulseSensor.fadeOnPulse(PULSE_FADE); pulseSensor.setSerial(Serial); pulseSensor.setOutputType(OUTPUT_TYPE); pulseSensor.setThreshold(THRESHOLD); // Now that everything is ready, start reading the PulseSensor signal. if (!pulseSensor.begin()) { /* PulseSensor initialization failed, likely because our particular Arduino platform interrupts aren't supported yet. If your Sketch hangs here, try PulseSensor_BPM_Alternative.ino, which doesn't use interrupts. */ for(;;) { // Flash the led to show things didn't work. digitalWrite(PULSE_BLINK, LOW); delay(50); digitalWrite(PULSE_BLINK, HIGH); delay(50); } } } void loop() { /* Wait a bit. We don't output every sample, because our baud rate won't support that much I/O. */ delay(20); // write the latest sample to Serial. pulseSensor.outputSample(); /* If a beat has happened since we last checked, write the per-beat information to Serial. */ if (pulseSensor.sawStartOfBeat()) { pulseSensor.outputBeat(); } } La primera parte, el comentario en el que se explica el propósito del código, no la comentaremos. Y en este caso, tampoco las dos líneas siguientes en las que incluimos el uso de interrupciones y de la librería PulseSensorPlayground.h, porque acabamos de explicarlo en la práctica anterior. La siguiente línea de código que encontramos es una en la que definimos una constante llamada OUTPUT_TYPE. Ahí estamos obligando a nuestro Arduino a establecer su salida de información en el SERIAL_PLOTTER. Al ser una constante, ese valor no cambiará a lo largo del sketch. Es decir, que la información tendremos que visualizarla necesariamente a través del Serial Plotter: const int OUTPUT_TYPE = SERIAL_PLOTTER; Más constantes Aparte del tipo de salida, vamos a definir cuatro constantes más: const int PULSE_INPUT = A0; const int PULSE_BLINK = 13; // Pin 13 is the on-board LED const int PULSE_FADE = 5; const int THRESHOLD = 550; // Adjust this number to avoid noise when idle Como pone en el comentario que aparece en el sketch sobre estas líneas, lo primero que estamos definiendo es desde que pin estamos recibiendo la información de nuestro pulsómetro (A0). La siguiente línea nos dice que con cada pulsación encenderemos el LED 13, que es el LED que nuestro Arduino lleva integrado. En el caso de que quisiéramos que la intensidad de un LED variase de la misma manera que varía la intensidad en cada pulsación, deberíamos conectar un LED y una resistencia al pin digital 5. Pero no lo haremos en esta práctica. En la última línea estamos diciéndole a nuestro Arduino que todo lo que no llegue a 550 no debe considerarlo como una pulsación, para evitar la mayor cantidad de ruido posible. El objeto pulseSensor Como ya hemos visto en la práctica anterior, para hacer uso de las funciones de la librería es necesario crear una instancia de nuestra librería, un pulsómetro: PulseSensorPlayground pulseSensor; void setup(): lo que se ejecuta una sola vez A continuación, pasaremos a ver lo que solamente ha de ejecutarse un vez y que por tanto aparece dentro de la función setup(). Obviando los comentarios, la primera línea de código que nos encontramos es el comienzo de la comunicación a través del puerto serie, en este caso a una mayor velocidad que en prácticas anteriores, a 115200 baudios. Esto nos permitirá enviar y recibir información de una manera más rápida y hará que funcione bien nuestro pulsómetro, como se nos indica en el comentario: void setup() { /* Use 115200 baud because that's what the Processing Sketch expects to read, and because that speed provides about 11 bytes per millisecond. If we used a slower baud rate, we'd likely write bytes faster than they can be transmitted, which would mess up the timing of readSensor() calls, which would make the pulse measurement not work properly. */ Serial.begin(115200); Después, cuando abras tu Serial Monitor, en la esquina inferior derecha de tu Serial monitor seguramente pondrá 9600 baudios, así que tendrás que abrir la pestaña y cambiarlo a 115200 baudios. Lo siguiente que vamos a hacer es preparar nuestro objeto pulsómetro. Al igual que en la práctica anterior, tendremos que decirle cuál es el pin de entrada (pulseSensor.analogInput(PULSE_INPUT)), el pin que parpadeará (pulseSensor.blinkOnPulse(PULSE_BLINK)) y el pin que variará su intensidad (pulseSensor.fadeOnPulse(PULSE_FADE)), aunque nosotras no vamos a conectar nada en este tercero. // Configure the PulseSensor manager. pulseSensor.analogInput(PULSE_INPUT); pulseSensor.blinkOnPulse(PULSE_BLINK); pulseSensor.fadeOnPulse(PULSE_FADE); pulseSensor.setSerial(Serial); pulseSensor.setOutputType(OUTPUT_TYPE); pulseSensor.setThreshold(THRESHOLD); Los tres siguientes se encargan de decirle a nuestro Arduino que vamos a usar el puerto serie, que nuestra salida va a ser el SERIAL_PLOTTER (esa constante la hemos definido al principio de nuestro código) y la última línea configura como umbral, el que ya hemos definido en la constante THRESHOLD. Lo siguiente que haremos es comenzar la comunicación con el puerto serie. Para ello, utilizaremos un condicional que detectará si la comunicación serie ha comenzado o no: if (!pulseSensor.begin()) { for(;;) { // Flash the led to show things didn't work. digitalWrite(PULSE_BLINK, LOW); delay(50); digitalWrite(PULSE_BLINK, HIGH); delay(50); } } Dentro de este condicional solamente entraremos si la comunicación no funciona (cosa que con nuestro Arduino UNO no ocurrirá), y ahí encontraremos un bucle sin fin creado gracias a la expresión for ( ; ; ) Lo que hace el código encerrado dentro de ese bucle es encender y apagar constantemente el LED que hemos definido anteriormente como el que marcará nuestras pulsaciones: for(;;) { digitalWrite(PULSE_BLINK, LOW); delay(50); digitalWrite(PULSE_BLINK, HIGH); delay(50); } void loop(): lo que se ejecuta todo el rato Y por último, encontramos la función loop() con el código que ha de ejecutarse continuamente. A continuación te escribo el código sin comentarios, para que te resulte más fácil verlo: void loop() { delay(20); pulseSensor.outputSample(); if (pulseSensor.sawStartOfBeat()) { pulseSensor.outputBeat(); } } Lo primero que encontramos es un delay para mantener las lecturas en orden y sin problemas. Lo siguiente, es utilizar la función .outputSample() que es la que escribe los valores recibidos por el puerto serie. El condicional que lo sigue, dice que si hemos detectado una pulsación, tendremos que dibujar esa información en nuestro plotter. Con el Arduino conectado al ordenador, subimos el código y podremos visualizar en nuestro Serial Plotter algo similar a esto: ¿Qué tenemos que presentar? En este caso, al igual que con la práctica anterior, será suficiente con que me envíes un .gif o video en el que se vea el pulsómetro sin tu dedo, luego con tu dedo sobre él, y que posteriormente la cámara enfoque al monitor y con el puerto serial abierto, sea posible ver tus pulsaciones en el plotter. Similar al video que aparece justo encima de este apartado. MÓDULO 8: PURE DATA ¡Por fin vamos a conectar Pure Data con Arduino! Práctica 10: Primera conexión con Arduino Por fin vamos a conectar Arduino con Pure data y vamos a utilizar nuestro ritmo cardiaco para controlar el kick drum. Habéis visto en la lección de Arduino Práctica 4.1 Medimos n... | Librería CATEDU como medir vuestras pulsaciones y detectar un latido. Esta vez a parte de encender un led cuando se produzca un latido, vamos a mandar un mensaje a traves del puerto Serial. ¿Qué es un puerto Serial? Es una interfaz de comunicación a través de la cual se envían datos de manera secuencial. Digamos que los datos van en una sola fila uno detrás de otro. Si has seguido el orden propuesto, ya habrás visto este apartado sobre el puerto serie. Ahora en lugar de ser la app oscControl la que nos envíe datos a través de osc, será Arduino el que envíe esos datos a través del puerto Serial. En Arduino vamos a recoger y procesar los valores que el sensor de latidos nos dé. Tras procesar esos valores vamos a identificar cuándo se produce un latido, y cuando ese latido se produzca vamos a enviar un mensaje a Pure data gracias al puerto serie para activar el kick drum que hicimos en la Práctica 4: Kick drum ... | Librería CATEDU. El ritmo de nuestro corazón se va escuchar en nuestros altavoces y sonará como un kick drum. Con este ritmo podríamos controlar cualquier evento de Pure Data; es un juego de números. En Arduino cuando detectamos una pulsación aparte de encender el LED vamos a imprimir en el puerto Serial un 1. El código en Arduino A continuación, te dejamos el código que necesitará tu Arduino para reconocer cuándo se ha producido un latido. En los comentarios, puedes leer qué función tiene cada línea. int leer = 0; //esta variable almacenará los valores leídos por nuestro sensor void setup() { Serial.begin(9600); //iniciamos la comunicación con el puerto serie a 9600 baudios } void loop() { leer = analogRead(A0); // almacenamos en la variable 'leer' los valores que detecta nuestro sensor if(leer > 550){ // consideraremos que un valor >550 es un latido. Si se produce uno... Serial.println("1"); //enviaremos un '1' a Pure Data gracias al puerto serie. } Serial.println(); // enviamos una línea en blanco delay(200); // esperamos 200 ms para realizar una nueva lectura } Conexiones en Arduino Las conexiones que tienes que realizar entre el pulsómetro y tu Arduino, son las mismas que en esta práctica. Recibir Serial en Pd Como ya hemos visto, cada vez que Arduino detecte un latido enviará un '1' a Pure Data. Cuando recibamos ese '1' vamos a activar el kick drum. ¿Cómo vamos a recibir ese mensaje? Utilizando el objeto "comport". En él tendremos que configurar qué puerto serie va a escuchar y la velocidad de comunicación. Tanto el puerto como la velocidad tienen que coincidir con las utiliza nuestro Arduino. En mi caso es el COM 5 y la velocidad son 9600 baudios: Figura 1. Arduino utilizando el puerto serial: "COM5" Figura 2. Velocidad del puerto serial en Arduino configurada a 9600 baudios. El objeto "comport" no está incluido en Pure Data Vanilla, Forma parte de una librería externa que tendremos que instalar. Os dejo un video de como instalar librerías. No tenéis que instalar la librería que instalo yo en el video. Para esta práctica vamos a instalar dos librerías:  "comport" y "cyclone" Figura 3. Proceso de instalación de librería comport. Figura 4. Proceso de instalación de librería cyclone. ¿Ya tenéis las dos librerías instaladas y registradas en inicio para que se carguen al abrir Pd? Al objeto "comport" le indicaremos el puerto en el primer argumento y la velocidad en el segundo. Recordar que el puerto va a ser la dirección donde Arduino enviara los datos, y sera en esa dirección donde Pure data tiene que ir a buscarlos. El mensaje device imprimirá en la ventanita de Pd la lista de puertos serial disponibles, tendréis que escoger aquel que coincida con el que utiliza vuestro Arduino. Para abrir el puerto enviaremos el mensaje open, en ese mensaje también podemos especificar el identificador del puerto que vamos a abrir, en mi caso es el 5. Para cerrar la comunicación enviaremos un mensaje con la palabra "close". Figura 5. objeto "comport" Cerrar la ventana de Serial en Arduino para abrir la comunicación de pure data, si no, no os dejara. Para cargar el programa en Arduino también necesitaremos cerrar el puerto en pure data, de lo contrario nos dará error. No podemos tener dos elementos conectados a la vez al mismo puerto serial Una vez recibido el mensaje en Pure Data tendremos que decodificarlo, para ello vamos a utilizar el siguiente grupo de objetos. Ahora no vamos a entrar a explicarlo. Simplemente lo utilizaremos tal cual se muestra en la imagen. Figura 6. Grupo de decodificación para los datos que llegan a traves de serial a Pure Data. A este grupo (figura 6) le llegará el outlet del objeto "comport", Y de su ultimo objeto "cyclone/fromsymbol" obtendremos la información que Arduino envió por el puerto serie, en nuestro caso es el número 1. Con ese número activaremos un bang que activará nuestro kick drum. Lo haremos de la misma forma que en la práctica de osc pero esta vez utilizaremos un random para que con cada latido se active un uno de los 3 valores iniciales del envelope que regula la frecuencia del kick drum. Figura 7. patch de Pd como el que tenéis que construir en esta práctica 10. Recordad que tenéis que tener encendido el DSP de pure data para procesar sonido. ¿Qué tenemos que entregar? Sube a la carpeta del Moodle de la Práctica 10 los archivos de Arduino y Pure Data que has utilizado para convertir tu latido en un kick drum y escucharlo en tus altavoces. Sube un video en el que se vea tu dedo en el sensor, el led encendiéndose con tus latidos y que se escuche el kickdrum también al ritmo de tus latidos. Archivos que tenéis que subir: patch Pd Practica10_Pd-vuestronombre_vuestroapellido.pd. patch Arduino Practica10_Ardu-vuestronombre_vuestroapellido.ino. video Practica10_Video-vuestronombre_vuestroapellido Figuras: Figura 1. Arduino utilizando el puerto serial: "COM5" Figura 2. Velocidad del puerto serial en Arduino configurada a 9600 baudios. Figura 3. Proceso de instalación de librería comport. Figura 4. Proceso de instalación de librería cyclone. Figura 5. objeto "comport" Figura 6. Grupo de decodificación para los datos que llegan a traves de serial a Pure Data. Figura 7. patch de Pd como el que tenéis que construir en esta práctica 10. MÓDULO 9: ARDUINO Mediremos la cantidad de luz con nuestro Arduino Práctica 11: Arduino y sensor lumínico ¿Te acuerdas de los bastones, aquellas células fotorreceptoras de las que hablabamos en este apartado? Pues el funcionamiento del sensor que vamos a utilizar aquí es bastante similar... Ha llegado el momento de que veamos un nuevo sensor, el cual resulta interesante tanto por la facilidad de su uso como por su reducido coste. Existen diferentes versiones, pero para esta práctica, vamos a utilizar la versión sencilla, directamente la fotorresistencia. Antes de empezar, ¿qué es un divisor de voltaje? Ya hemos visto que para trabajar con Arduino, son necesarias una serie de estructuras de programación. Aparte de eso, a veces vamos a necesitar ciertos componentes que permitan leer los valores de nuestros sensores. La mayor parte de los sensores que utilizamos con Arduino son plug-and-play, es decir, no necesitan nada extra para funcionar, pero, en ocasiones, necesitaremos alguna cosilla extra. Ese es el caso de nuestra fotorresistencia. Para poder leer esa variación en la fotorresistencia que se produce cuando aumenta o disminuye la luz, necesitaremos conectar una resistencia extra que funcionará como divisor de voltaje. Esta resistencia también podría ser un potenciómetro, o lo que es lo mismo, una resistencia con un valor variable que podemos ajustar. Con un divisor de voltaje, seremos capaces de obtener a partir de la variación en la resistencia, una variación en el voltaje que será lo que lea nuestro Arduino a través del pin que configuremos como entrada. Para saber más sobre divisores de voltaje puedes visitar esta página. Materiales Para realizar esta práctica necesitaremos: 1. Nuestro Arduino UNO2. 3 Cables macho-macho. ¿Por qué se llaman así? pues porque ambos extremos se insertan en alguna parte. Existen también cables macho-hembra y hembra-hembra, los cuales son útiles dependiendo del tipo de pines que tengan tanto el microcontrolador como los sensores y actuadores que usemos.3. 1 resistencia de 10KOhm que funcionará como divisor de voltaje.4. Cable AB USB para conectar nuestro Arduino.5. La fotorresistencia. Estableciendo la conexión Las conexiones que tenemos que realizar son las siguientes: Para realizar este circuito se ha utilizado Tinkercad, el cual nos permite diseñar circuitos de una manera visual. Recuerda cómo debes colocar los componentes en la protoboard, ya lo vimos en este apartado. ¡No realices cortocircuitos! Ahí vemos que estamos empleando 3 pines: A0: va desde ahí hasta una pata de nuestra resistencia, la cual está conectada a una pata de la fotorresistencia. 3.3V: va desde ahí hasta la pata de la fotorresistencia que no está conectada a la resistencia. GND: va desde ahí hasta la pata de la resistencia que no está conectada a nada. Tenemos que tener cuidado con varios aspectos a la hora de realizar las conexiones en nuestra protoboard. El más importante es que todos esos puntitos están conectados unos con otros en línea. Es decir, en la posición en la que está colocada la protoboard de la imagen superior, los puntos están conectados en líneas verticales, de arriba a abajo, pero no de forma horizontal. Exceptuando las líneas roja y negra señalizadas con el símbolo + y - respectivamente, las cuales están conectadas de izquierda a derecha, si mantenemos la posición de la protoboard de la imagen de arriba. Por tanto, vemos que nuestro cable negro está conectado a uno de los extremos de nuestra resistencia, mientras que el otro extremo se conecta a un extremo de la fotorresistencia y al pin A0 de nuestro Arduino. Una vez hemos terminado nuestro circuito va a llegar el momento de ver el código que necesitaremos para que funcione: * * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-light-sensor * Modificado por Marta Pérez */ void setup() { // comienza la comunicación del puerto serie en 9600 bits por segundo: Serial.begin(9600); } void loop() { // Lee el valor de A0 (entre 0 y 1023) int analogValue = analogRead(A0); Serial.print("Lectura analógica: "); Serial.print(analogValue); // the raw analog reading // Definiremos los umbrales dependiendo de la cantidad de luz recibida if (analogValue < 10) { Serial.println(" - Oscuro"); } else if (analogValue < 200) { Serial.println(" - Tenue"); } else if (analogValue < 500) { Serial.println(" - Iluminado"); } else if (analogValue < 800) { Serial.println(" - Bastante iluminado"); } else { Serial.println(" - Mucha luz"); } delay(500); Anteriormente, en la práctica anterior, se ha explicado línea a línea; un código compuesto por condicionales en su mayoría, por lo que no se ha considerado necesario explicar este código línea a línea. Ahora conectamos nuestro Arduino al ordenador y subimos el código. El resultado que obtenemos una vez hayamos subido el código es: Como puedes ver, al tapar el sensor parcialmente, se reduce la cantidad de luz que recibe y eso se refleja en la consola del puerto serie de nuestro Arduino. ¿Qué tenemos que presentar? En este caso será suficiente con que me envíes un .gif o video con el circuito hecho en la protoboard en el que se vea también la medición del sensor en el puerto serie, similar al video que aparece justo encima de este apartado. FUENTES: Arduino y sensor lumínico: https://arduinogetstarted.com/tutorials/arduino-light-sensor MÓDULO 10: PURE DATA Aprenderemos qué son las rampas potenciales, filtros y crearemos nuestra primera caja de ritmos Rampas potenciales: pow y sqrt ¿Os acordáis de las rampas que hemos visto para suavizar los cambios de volumen y los envelopes en las lecciones. Practica 2: nuestro pr... | Librería CATEDU y Envelope | Librería CATEDU? Vamos a ver dos objetos que nos permitirán transformar esas rampas lineales en progresiones potenciales. Abrir el patch pow-sqrt.pd El objeto "pow~" elevara la señal recibida en el inlet izquierdo a el valor o valores recibidos en el inlet derecho o indicados en su argumento. El objeto "sqrt~" devolverá por su outlet la raíz cuadra de la señal recibida en su único inlet. Este objeto no tiene argumento. Figura 1. patch pow-sqrt.pd Figuras: Figura 1. patch pow-sqrt.pdNoise o Ruido "Los estudiosos de la música definen “ruido” como ondas irregulares sin un tono definido; en ingeniería se define como una señal que interfiere con la detección o calidad de otra señal (ASHA, 2012). En acústica, se entiende por ruido aquel sonido no deseado (Jaramillo, 2007) y comúnmente el ruido, en inglés noise, se utiliza para referirse a un sonido desagradable. Este término aparece también frecuentemente asociado a ideas de comunicación como distorsionador de aquello que se quiere transmitir." (del Río, 2019) Ruido en el ámbito del Arte Sonoro "Una de las primeras aproximaciones al concepto de ruido en el contexto artístico es la que da Luigi Russolo (1913), que fecha el nacimiento del ruido en el siglo XIX con la llegada de la revolución industrial y la aparición de las máquinas. Russolo queda fascinado por esos nuevos sonidos extraños, disonantes e intensos que tornan exhausta y monótona la tradición musical clásica (Russolo, 1913). El oído quiere más y más extremo, y en este autor se aprecia el anhelo de una experiencia sonora abrumadora." (del Río, 2019) Luigi Russolo, 1913-1914 "Si en el siglo XIX el avance tecnológico que revolucionó la economía, sociedad y el modo de producción fue la máquina, en el siglo XXI los avances tecnológicos correspondientes serían la tecnología digital, la computación, Internet, etc. En el S XIX las máquinas mecánicas reemplazaban las funciones motoras de un cuerpo humano, y en el S XXI las máquinas digitales reemplazan funciones de a la mente humana. Las máquinas del siglo XIX reemplazaron nuestros cuerpos y las del SXXI remplazan también nuestras mentes y nos ofrecen un nuevo espacio virtual en el que habitar. Las tecnologías digitales son para nosotros lo que las máquinas fueron para Luigi Russolo, el más reciente estado de los avances tecnológicos que transformó la sociedad del siglo XIX. Las máquinas de nuestro tiempo son eléctricas, digitales, dispositivos e interfaces omnipresentes conectadas unas con otras a través de la mega estructura de telecomunicaciones (Andersen, Pold, 2018). Las máquinas del siglo XXI se han vuelto más silenciosas e invisibles." (del Río, 2019) "Salome Voegelin (2010) apunta que el ruido de las máquinas de Luigi reflejaba el movimiento de masas y el progreso, y que el ruido de hoy refleja una privada y aislada quietud. La principal noción de ruido que trabaja esta autora es la de aquel sonido que atrapa al cuerpo que escucha y lo aísla incluso de sí mismo, “Sound is noisy when it deafens my ears to anything but itself” [El sonido es ruidoso cuando ensordece mis oídos de todo excepto de sí mismo] (Voegelin, 2010, p.44)." (del Río, 2019) "Para Salome Voegelin (2010) existen diferentes tipos de ruido (formas y razones), como “el ruido de lo indeseado” que ejemplifica con la música desagradable de sus vecinos a la que reacciona poniendo música en su casa con la intención de crear una barrera sonora que neutralice el sonido indeseado; “el ruido en el contexto del arte sonoro”; “el ruido de una rave que toma el control del cuerpo” o “el ruido de una voz que renuncia a la comunicación semántica”, entre otros." (del Río, 2019) "Contextualizando el ruido en la era postmoderna, Voegelin (2010, pp. 62-63) lo presenta como lo que la postmodernidad es a la modernidad, el ruido de la heterogeneidad, trabajando fuera y a través de disciplinas. Una postmodernidad que rechaza las ideas de totalidad y unidad legado de la modernidad, la postmodernidad abraza la fragmentación, la diversidad, la subjetividad del individuo, al cuerpo y su experiencia, integrándolo en el juego artístico." (del Río, 2019) Noise breaks with the language base… Noise can only find its way to language in the acknowledgment that it can't. The thing discussed is the body that heard not the work that played. Noise forces the listening subject into the critical ring and turns the work into moments of experience. And that is the true criticality of noise. [El ruido rompe con la base lingüística… El ruido solo puede encontrar su camino en el lenguaje en el reconocimiento de que no puede. Lo que se discute es el cuerpo que escucha no la pieza que suena. El ruido fuerza al sujeto que escucha dentro de un anillo crítico y convierte la pieza en momentos de experiencia. Y esta es la verdadera crítica del ruido.] (Voegelin, 2010, p.65). Por tanto, ¿podríamos considerar el noise, el ruido, la banda sonora ideal de la era internet, conectividad constante y saturación aislante? Merzbow, 2014 El ruido en pure data El ruido del que ahora vamos a hablar se ajustaría a la definición de ondas irregulares sin un tono definido. Vamos a ver con que objeto podemos generar ese tipo de señal en Pure data. En Pd vamos a generar ruido con el objeto "noise~". El ruido que nos proporciona este objeto es ruido blanco, esto quiere decir, que es un ruido que incluye de manera aleatoria todas las frecuencias por igual. La señal contiene todas las frecuencias y todas ellas muestran la misma potencia. Existen otros tipos de ruidos en los que determinados rangos de frecuencias tienen más probabilidad de estar presentes ya que la generación de ruido es un proceso aleatorio que tienen una componente estadística. Vamos a ver un ejemplo para entender mejor esto: Si mi prima la del pueblo compra 10 décimos de lotería para el sorteo del niño va a tener más probabilidades de que le toque algún premio que yo, que solo he comprado 1 décimo. En el ruido blanco todas las frecuencias han comprado 10 décimos de lotería y tienen la misma probabilidad de formar parte de la señal generada. En el marron, por ejemplo, cuanto más alta es una frecuencia, aparecerá representada con menor intensidad. Aqui podéis escuchar varios colores de ruidos: Volvamos al objeto "noise~" que como hemos dicho antes va a generar una señal de ruido blanco que saldrá por su único outlet. El inlet de este objeto nos va a permitir configurar la semilla, en inglés "seed", ¿Y qué es eso de la semilla? En computación no existe ningún proceso puramente aleatorio y estos objetos que generan patrones aleatorios son en realidad algoritmos que toman un valor inicial a partir del cual calculan una serie de números pseudoaleatorios. La semilla o seed es el valor inicial a partir del cual se calcularán esos valores. Cada vez que enviemos al objeto "noise~" o al objeto "random" la misma semilla, el cálculo comenzara de nuevo, generando la misma secuencia de valores. Habíamos comenzado a ver este concepto en la Práctica 7: Kick drum ... | Librería CATEDU. Podéis probarlo en este patch: Figura 1. patch Noise.pd Cuando creemos sonidos sintéticos el uso del ruido nos va a permitir crear sonidos más próximos a los sonidos que existen en el mundo acústico/material, como por ejemplo el sonido de los platillos de una batería. Recordar que las ondas sinusoidales puras prácticamente no existen en la naturaleza (Las ondas y el sonido | Librería CATEDU). Figuras: Figura 1. patch Noise.pd Referencias: Andersen, C. U., & Pold, S. B. (2018). The metainterface: The art of platforms, cities, and clouds. MIT Press. ASHA (2012). Serie informativa de audiología. El Ruido. Recuperado de https://www.asha.org/uploadedFiles/AIS-El-Ruido.pdf del Río, J. (2019) El ruido como elemento expresivo en la interfaz mediante el coil o inductor como meta-interfaz en el móvil y en el ratón informático. Aplicación práctica performativa (2016-2019) [Trabajo Final de Máster, Universitat Politècnica de València]. RiuNet.  https://riunet.upv.es/handle/10251/129810 Jaramillo, A. M. J. (2007). Acústica: la ciencia del sonido. ITM. Peters, J. D. (1999). Speaking into the Air: A History of the Idea of Communication. Chicago: University of Chicago Press. Russolo, L. (2004). The art of noises: Futurist manifesto. Audio culture: Readings in modern music, 10-14. Voegelin, S. (2010). Listening to noise and silence: Towards a philosophy of sound art. USA: Bloomsbury Publishing.Filtros básicos: low pass, high pass, band pass Low pass Este filtro solo deja pasar frecuencias bajas a partir de un valor determinado. Este valor se denomina frecuencia cutoff, o frecuencia de corte. Las frecuencias superiores al valor del cutoff serán reducidas o eliminadas. En Pure data, es el objeto "lop~". Podemos configurar la frecuencia de corte el el argumento o a traves del inlet derecho. En el inlet izquierdo recibiremos la señal que vamos a filtrar. Figura 1. patch Filtro-Low-pass.pd High pass Este filtro deja frecuencias altas a partir de un valor determinado. Al igual que en el low pass, este valor se denomina frecuencia cutoff, o frecuencia de corte. Las frecuencias inferiores al valor del cutoff serán reducidas o eliminadas. En pure data es el objeto "hip~". Podemos configurar la frecuencia de corte en el argumento o a traves del inlet derecho. En el inlet izquierdo recibiremos la señal que vamos a filtrar. Figura 2. patch Filtros-High-pass.pd Band pass Podemos describir este filtro como una combinación de un low pass y un high pass. Dejará pasar las frecuencias comprendidas en un rango determinado, reduciendo o eliminando las frecuencias inferiores al valor inferior del rango y las superiores al valor superior del rango. Este rango va a venir determinado por una frecuencia central y la longitud del rango de frecuencias que alrededor de esa frecuencia central el filtro dejara pasar, a este rango lo denominaremos resonancia. La frecuencia central pasara intacta, las frecuencias alrededor de esta frecuencia central se irán reduciendo progresivamente a medida que nos alejemos de la frecuencia central, hasta ser eliminadas. Este objeto tiene 3 inlets, el primero recibirá la señal de audio a filtrar. El segundo la frecuencia central y el tercero controlara la resonancia (en este objeto de pure data se recomienda utilizar unos valores para la de resonancia de entre 0 y 10, pero probar todos los valores que queráis) Figura 3. patch Filtros-Band-pass.pd Combinar Filtros En la carpeta de material, os dejo un patch con todos los filtros para que los probéis, comparéis y mezcléis: Figura 4. patch Filtros.pd Figuras: Figura 1. patch Filtro-Low-pass.pd Figura 2. patch Filtros-High-pass.pd Figura 3. patch Filtros-Band-pass.pd Figura 4. patch Filtros.pdSnare drum y Hi hat Batería Es un conjunto de instrumentos musicales de percusión. Vamos a ver tres de sus elementos más característicos y recrear su sonido en Pure Data. Los elementos que vamos a ver son el kick drum, que vimos anteriormente en la Práctica 4: Kick drum ... | Librería CATEDU, el hi hat y el snare drum: Kick drum: Es lo que conocemos como bombo y produce el sonido más grave y potente de la batería, se percute con una maza que se activa con el pie utilizando un pedal. Hi-hats: Son los platillos metálicos. Frecuentemente un sistema que consta de 2 platillos instalados en un soporte con pedal que permite que uno caiga sobre el otro haciéndolos sonar. Snare drum: En español se conoce como caja y es un tambor. Como vais a ver a continuación lo que vamos a hacer el pure data es emular las ondas generadas por estos instrumentos acústicos y cómo se comportan en el espacio y el tiempo. Kick drum o bombo Ahora que conocemos los filtros vamos a añadir un filtro low pass "lop~" al Kick drum que va a cortar todas las frecuencias por encima de 1000, esto mejorar su sonido. Y vamos a hacer en el envelope que controla el volumen, que el decay sea regulable utilizando "$1": Figura 1. patch Kick-drum.pd Hi hat De forma similar a como hemos creado el kick drum, vamos a crea un Hi hat. Para ello utilizaremos las frecuencias más agudas del ruido blanco que crearemos con el objeto "noise" y les daremos forma con un envelope muy sencillo con una progresión exponencial que controle el volumen. Vamos a modificar la rampa que controla el volumen con el objeto "pow~" que hemos visto en Rampas potenciales: po... | Librería CATEDU. Tambien haremos que el Decay del volumen sea regulable utilizando $1. Figura 2. patch Hi-hat.pd Ejercicio 1: Porque utilizamos una variable integer para las variaciones de la rampa de volumen en los dos ejemplos anteriores? ¿Qué pasaría si omitiéramos el objeto "i" y variáramos el valor que llega a la rampa del line? Snare drum Vamos a crea un snare drum muy sencillo en Pure data. Para ello utilizaremos un oscilador cuyo volumen controlaremos con un envelope; las frecuencias más agudas del ruido blanco que volveremos a filtrar con un bandpass y cuyo volumen regularemos con una rampa que dure más que el sonido del oscilador. Probar a cambiar los valores de los envelopes para ver que efecto tiene en el sonido. Probar a cambiar todos los números de los filtros. Experimentar para conocer cómo funciona el patch Snare-Drum.pd Figura 3. patch Snare-Drum.pd Ejercicio 2: Crear un subpatch para el kick drum, otro para el hi hat y otro para el snare drum. Coloca esos tres subpatches en el mismo patch de pure data. El kickdrum tendrá 3 inlets y 1 outlet. El hi hat 3 inlets y 1 outlet y el snare drum 4 inlets y 1 outlet. Figuras: Figura 1. patch Kick-drum.pd Figura 2. patch Hi-hat.pd Figura 3. patch Snare-Drum.pdPráctica 12: Caja de ritmos Ahora que tenemos los instrumentos de una batería y sabemos hacer un secuenciador vamos a juntarlo todos para crear una caja de ritmos de 8 pasos/tiempos. Os dejo un video de una caja de ritmos de 16 tiempos para que os hagáis una idea de lo que permite: ¿Qué necesitamos y que estructura va a tener este programa? Este será nuestro algoritmo general: 1- Necesitamos un contador de 8 pasos. 2- Necesitaremos enviar esos pasos a cada uno de nuestros instrumentos. 3- Necesitaremos indicar en cada instrumento en cual o cuales de los 8 pasos queremos que se activen. 4- Necesitaremos que los instrumentos generen una señal. 5- Necesitaremos poder regular el volumen de cada instrumento para ajustar la mezcla. 6- Necesitaremos mezclar la señal de los tres instrumentos y regular el volumen de ma mezcla (master). Vamos a ver que tenemos que hacer en cada paso de nuestro algoritmo para conseguir nuestro objetivo: 1- Contador de 8 pasos. Esto ya lo hemos hecho anteriormente en la página Práctica 3: Contador y... | Librería CATEDU. Y sería algo asi: Figura 1. Contador de 8 tiempos. 2- Enviar esos pasos a cada uno de nuestros instrumentos. Para facilitar el orden y la legibilidad de nuestro patch utilizaremos los objetos "send" and "receive" para enviar el resultado de nuestro contador (que serán valores del 0 al 7) a cada uno de nuestros instrumentos. Utilizaremos un "receive" para cada instrumento 3- Indicar en cada instrumento en cual o cuales de los 8 pasos queremos que se activen. Este paso va a ser el más novedoso para nostros ya que aún no hemos construido un patch así. ¿Como podemos hacer esto y que necesitamos? escribamos un algoritmo para plantear la solución a nuestro problema. 3.1- Necesitamos saber en qué paso está el contador. 3.2- Necesitaremos una configuración que indique en que pasos queremos que se active el instrumento. 3.3 - Necesitamos saber si el paso en que se encuentra el contador está activado en un instrumento. 3.4 - Si el paso en el que se encuentra el contador esta activado enviaremos un bang para activar el instrumento  3.5 - Si el paso en el que se encuentra el contador no está activado no enviaremos un bang para activar el instrumento Vamos a incluir el sub-algoritmo 3 en un subpatch que tendrá 8 inlets y 1 outlets. 3.1- Necesitamos saber en qué paso está el contador. Habíamos dicho en el punto dos que enviaríamos el resultado del contador con un objeto "send", asique crearemos un objeto "receive" para que a cada uno de nuestros instrumentos les llegue la información de en qué paso está el contador. 3.2- Necesitaremos una configuración que indique en que pasos queremos que se active el instrumento. En nuestro caso vamos a utilizar 8 objetos toggle para cada instrumento, habíamos visto su funcionamiento en la página tal. los colocaremos en fila y cada uno de ellos controlara el estado de un paso del contador. Cuando el toggle este abierto enviara un 1 por su salida y cuando esté cerrado un 0. Figura 2. Ocho toggles en fila. 3.3 - Necesitamos saber si el paso en que se encuentra el contador está activado en un instrumento. Para ello vamos a comparar la posición en la que se encuentra el contador con el estado de un instrumento para esa posición. Los valores que genera el contador van de 0 a 7 y los valores que genera el toggle que nos indica el estado de cada posición son 0 o 1. Vamos a buscar una manera de comparar estos dos valores. Primero vamos a utilizar el objeto "select" o "sel" para separar cada uno de los pasos del contador. ¿Cómo funciona este objeto? En el objeto "sel" podremos introducir tantos argumentos como elementos queramos evaluar, cuando un elemento recibido por el sel coincida con alguno de su argumento enviara un bang a traves del outlet correspondiente con la posición del argumento. Figura 3. Objeto select. Esto quiere decir si coincide con el segundo argumento, enviara un bang por el outlet segundo. "select" se puede utilizar también con símbolos, pero no se pueden mezclar símbolos y numero. En nuestro caso vamos a utilizar números. Pero vemos que para tres argumentos tenemos 4 outlets. Esto es porque por el ultimo outlet se enviarán aquellos valores que no coincidan con ninguno de los argumentos. Abre el patch select.pd para probar el objeto. Figura 4. Patch select.pd. Ahora que ya conocemos el objeto select vamos a utilizarlo para separar cada uno de los pasos del contador. Como el contador genera números de 0 a 7 vamos a crear un "select" con 8 argumentos, que coinciden con los valores que genera nuestro contador: Figura 5. Objeto "select" que vamos a utilizar en esta práctica. Cada vez que llegue al inlet del "select" de la figura 5, un 6, se enviara un bang por la séptima salida. El objeto "r $0-tempo" recibe los valores que genera el contador. Figura 6. Objeto "sel" que acaba de recibir un 6 en su inlet y envía un bang por el séptimo outlet. (el 6 es el séptimo argumento). Ahora vamos a crear una estructura que compare cada paso del contador con el estado del instrumento en ese paso. Empezamos por el primer paso, que en los valores que nos proporciona el contador corresponde con el numero 0, y que es el primer argumento de nuestro "select". Cada vez que el contador se encuentre en la posición 0 nuestro select enviara un bang por su primer outlet. Habíamos dicho que utilizamos 8 objetos toggle para marcar los pasos en los que queremos que este activado el instrumento. Como el toggle activado envía un 1 vamos a utilizar ese valor como parámetro de comparación. Vamos a utilizar el objeto "==" para comparar el estado de un instrumento en un paso determinado. Cada vez que el contador este en el paso que estamos evaluando queremos que se realice una comparación con el estado del instrumento en ese paso. Es algo así como responder a la pregunta. Estamos en el paso 1, en qué estado está el instrumento en el paso 1? Si esta activado activa el instrumento. Recordar que el los operadores matemáticos el inlet izquierdo introduce valor y da la orden de realizar la operación, por el contrario, el inlet derecho solo introduce valor. Como queremos que la comparación se realice cuando el contador este en el paso que estamos evaluando vamos a enviar un 1 a traves del inlet izquierdo de "==" cada vez que el contador se encuentre en el paso que estamos evaluando. Figura 7. Cuando el objeto "select" reciba un 0 por su inlet, un bang saldrá por su primer outlet y enviara el mensaje que contiene "1" al inlet izquierdo del objeto "==". Por el inlet derecho de "==" vamos a recibir el estado del instrumento en ese paso. Como es el primer paso vamos a enviar el estado del primer toggle, que cuando este activado sera un 1 y cuando este desactivado sera un 0. Figura 8. El primer paso del control de este instrumento esta activado. Cuando el primer toggle este activado se enviará un "1" al inlet derecho del objeto "==", cuando el toggle este desactivado enviará un "0". Cuando el primer toggle este activado se enviará un "1" al inlet derecho del objeto "==", cuando el primer toggle este desactivado enviará un "0". Cuando el objeto "select" reciba un 0 por su inlet, un bang saldrá por su primer outlet y se enviara un "1" al inlet izquierdo del objeto "==". Cuando los valores que recibe el objeto "==" sean iguales, enviara un 1 por su outlet, si los valores procedentes del contador y del estado del instrumento no coinciden, enviara un 0. La operación de comparación en el objeto "==" se realizará cada vez que llegue algo al inlet izquierdo. En nuestro caso al inlet izquierdo llega siempre un 1 y sera el estado del instrumento recibido en el inlet derecho el valor que alterne entre 0 y 1, dependiendo de si este activado ese paso o no. 3.4 - Si el paso en el que se encuentra el contador esta activado enviaremos un bang para activar el instrumento + 3.5 - Si el paso en el que se encuentra el contador no está activado no enviaremos un bang para activar el instrumento Cuando el toggle este activado y el objeto "==" se realize la comparación "1 ==1" el objeto "==" emitirá por su outlet un 1, ya que sus dos inlets cumple la condición de igualad que establece el operador matemático. Cuando el toggle este desactivado y el objeto "==" se realize la comparación "1 ==0" el objeto "==" emitirá por su outlet un 0, ya que la condición de igualdad no se cumple. Para activar el instrumento nos interesa tener un bang cada vez que esta condición de cumpla por lo que volveremos a utilizar el objeto "select" para emitir un bang cada vez que el objeto "==" envíe un 1 por su outlet y este bang sera el que active el instrumento. Figura 9. Comprobación del estado del instrumento en el paso en el que se encuentra el contador (primer paso). En ese paso el instrumento esta activado por lo que tras comparar con el "==" y clasificar con el "sel 0 1" obtenemos un bang por el segundo outlet de objeto "sel 0 1". Lo que hemos hecho hasta el momento evalúa solo el estado del instrumento en el primer paso, tendremos que repetir lo mismo para cada paso: Figura 10. Patch que compara el estado del instrumento en cada uno de los 8 pasos que genera el contador. Cada vez que un paso del instrumento este activado se enviara un bang para activar el sonido. Una vez lo tengamos hecho para cada paso tendremos completado el control de 1 instrumento, para controlar el resto de los instrumentos, tendremos que repetir la misma estructura y lo haremos creando un subpatch donde meteremos toda esta estructura de control. Figura 11. Subpatch que contine gran parte de la estructura de la figura 10. Este subpatch tendra 9 inlets y 1 outlet. 8 de los inlets enviaran el estado del instrumento en cada paso que controlan los toggles y 1 de los inlets enviara el valor del contador. En el outlet tendremos el bang que controla el instrumento. Figura 12. Estructura de control de la figura 10 metida en un el subpatch "pd step-state" de la figura 11. Ya tenemos nuestro sistema de control para los instrumentos. ¡Traigamos ahora los instrumentos! Figura 13. La orquesta de camino a vuestro patch de pd. 4- Instrumentos generen una señal, o que la reproduzcan. Los hemos hecho en lecciones anteriores: Snare drum y Hi hat | Librería CATEDU y Micrófono: Grabar y re... | Librería CATEDU Podemos utilizar los instrumentos que hemos hecho en la lección anterior o también reproducir sonidos grabados, vamos a combinar estos. Vamos a meter los instrumentos en subpatches y dejar fuera del subpatch solo los parámetros que queramos o necesitemos. En previos capítulos hemos creado el kick drum, snare drum y hi hats. Una vez hayamos creado los subpatches en el patch de cada instrumento, vamos a coger esos subpatches y traerlos al patch en el que estamos creando nuestra caja de ritmos. Figura 14. Subpatch para el kick drum o bombo. Figura 15. Subpatch para snare drum o caja. Figura 16. Subpatch para hi hats o platillos. Copiamos los subpatches de nuestros instrumentos, seleccionándolos en el modo edición, clicamos y sin soltar movemos el rato cubriendo el area donde se encuentren los objetos que queremos seleccionar, una vez seleccionados se pondrán en azul). Los copiámos (Ctrl + C) y los pegamos (Ctrl + V) en el patch que queramos: Figura 17. El subpatch del kick drum seleccionado. Una vez tengamos los instrumentos, conectamos cada uno con un subpatch de control. Vamos a añadir también un instrumento utilizando un sample, hemos visto cómo hacerlo en Micrófono: Grabar y re... | Librería CATEDU: Figura 18. patch Sample-subpatch.pd. Subpatch para el sonido procedente de un archivo. En el mensaje de open hemos sustituido el nombre del archivo por $1 para poder cargar diferentes archivos enviado un mensaje con el nombre del archivo que queremos reproducir. Hemos añadido al mensaje la palabra symbol para que se identifique como tal. Recordar que los archivos tienen que estar en la misma carpeta que el patch. Recordar que el orden en el que conectáis los objetos importa. El orden en que el bang activa en 0 y el delay importan. Para controlar el orden también podéis utilizar un delay muy rápido para aseguraros de que el orden en que se ejecutan los comandos es el que queréis. 5- Regular el volumen de cada instrumento para ajustar la mezcla. Como podréis observar en las figuras 14, 15, 16, 17 y 18, he añadido un control de volumen que se puede modificar desde fuera del subpatch a todos los instrumentos. Estos nos va a permitir ajustar la mezcla. Figura 19. Subpatch para snare drum o caja con el control de volumen general del instrumento marcado en rojo. 6- Mezclar la señal de los tres instrumentos y regular el volumen de la mezcla (master). Una vez tengamos todos los instrumentos que queramos vamos a mezclarlos utilizando el objeto "*~" . Enviaremos las señales al inlet izquierdo y a traves del inlet derecho controlaremos el volumen. El master es lo que enviamos a nuestros altavoces "dac~". Figura 20. El patch que habéis construido para vuestra caja de ritmos. Ejercicio 1: Construye la caja de ritmos como se acabamos de ver. Ha de tener un mínimo de cuatro instrumentos. Puedes incluir más instrumentos o sonidos grabados, incluso una melodía. Explora, experimenta y diviértete. Una vez tengas tu caja de ritmos graba tres audios utilizando el objeto "writesf~" con diferentes patrones de ritmo. Recuerda vimos el objeto "writesf~" en Micrófono: Grabar y re... | Librería CATEDU. Sube tu patch y esas tres grabaciones. Ejemplos: caja de ritmos de grabaciones de estornudos, de pedos, de palabras grabadas... Explora, experimenta y diviértete ¿Qué tenemos que entregar? El ejercicio 1 de la lección. Sube a la carpeta del Moodle de la Practica 12 los siguientes archivos: patch caja_de_ritmos-vuestronombre_vuestroapellido.pd. grabacion grabacion_caja_de_ritmos-vuestronombre_vuestroapellido-1 grabacion grabacion_caja_de_ritmos-vuestronombre_vuestroapellido-2 grabacion grabacion_caja_de_ritmos-vuestronombre_vuestroapellido-3 Si has hecho varios patches diferentes o alguna grabación mas también puedes subirlo. Máximo 3 patches y 6 grabaciones. Figuras: Figura 1. Contador de 8 tiempos. Figura 2. Ocho toggles en fila. Figura 3. Objeto select. Figura 4. Patch select.pd. Figura 5. Objeto "select" que vamos a utilizar en esta práctica. Figura 6. Objeto "sel" que acaba de recibir un 6 en su inlet y envía un bang por el séptimo outlet. (el 6 es el séptimo argumento). Figura 7. Cuando el objeto "select" reciba un 0 por su inlet, un bang saldrá por su primer outlet y enviara el mensaje que contiene "1" al inlet izquierdo del objeto "==". Figura 8. El primer paso del control de este instrumento esta activado. Cuando el primer toggle este activado se enviará un "1" al inlet derecho del objeto "==", cuando el toggle este desactivado enviará un "0". Figura 9. Comprobación del estado del instrumento en el paso en el que se encuentra el contador (primer paso). En ese paso el instrumento esta activado por lo que tras comparar con el "==" y clasificar con el "sel 0 1" obtenemos un bang por el segundo outlet de objeto "sel 0 1". Figura 10. Patch que compara el estado del instrumento en cada uno de los 8 pasos que genera el contador. Cada vez que un paso del instrumento este activado se enviara un bang para activar el sonido. Figura 11. Subpatch que contine gran parte de la estructura de la figura 10. Figura 12. Estructura de control de la figura 10 metida en un el subpatch "pd step-state" de la figura 11. Figura 13. La orquesta de camino a vuestro patch de pd. https://giphy.com/gifs/perfect-band-member-11MS2pksWxB8SA Figura 14. Subpatch para el kick drum o bombo. Figura 15. Subpatch para snare drum o caja. Figura 16. Subpatch para hi hats o platillos. Figura 17. El subpatch del kick drum seleccionado. Figura 18. Subpatch para el sonido procedente de un archivo. Figura 19. Subpatch para snare drum o caja con el control de volumen general del instrumento marcado en rojo. Figura 20. El patch que habéis construido para vuestra caja de ritmos.Efectos MÓDULO 11: ARDUINO Mediremos el color de los objetos con nuestro Arduino Práctica 13: Cómo percibir el color con Arduino Para percibir un determinado color, vamos a utilizar uno de los sensores que vienen en nuestro kit, el TCS34725, al que por comodidad denominaremos 'sensor de color'. En uno de sus lados, como ves en la primera foto, puedes ver 4 pines, que son los que conectaremos a nuestra protoboard y de esta a nuestro Arduino. En el otro lado, como se muestra en la segunda foto, puedes ver el sensor que, rodeado de cuatro LED blancos se encarga de determinar la cantidad de rojo, verde y azul que contiene el objeto que le coloquemos delante. ¿Cómo funciona? Este sensor óptico consta de una matriz de 3x4 fotodiodos filtrados para rojo, verde, azul, y sin filtro (clear). También cuenta con 4 conversores analógico digital de 16bits (ADC) que realizan la medición de los fotodiodos: Fuente: https://www.luisllamas.es/arduino-sensor-color-rgb-tcs34725/ Los conversores ADC integran la medición de los fotodiodos, que es transferida a los registros internos del TCS34725. La conexión de los módulos que integran el TCS34725 es sencilla, ya que la comunicación se realiza a través de I2C. Comunicación I2C Aunque no vamos a entrar a explicar cómo funciona la comunicación I2C (inter integrated circuits), debemos saber que se trata de un protocolo basado en la existencia de dos líneas de comunicación, una de ellas lleva la señal de reloj y es conocida como (SCL), y la otra linea lleva los datos y es conocida como (SDA). Los Pines SDA y SLC se encuentran especificados en todos los componentes que usan este tipo de protocolo de comunicación, como podemos ver si volvemos a la primera foto de arriba. Por tanto, para hacer funcionar nuestro sensor, alimentamos nuestro sensor de color desde Arduino mediante los pines G y 5V y conectamos el pin SDA y SCL del sensor a los 2 pines de nuestro UNO SCL y SDA: ¿Cómo conectamos el sensor a nuestro Arduino? Para conectarlo, necesitaremos la protoboard, como ya hemos dicho al principio. Es muy importante realizar las conexiones como te indico en la imagen de abajo: Nuestro sensor ha de estar paralelo a las líneas azul y rojo, no perpendicular. ¿Por qué? Porque la protoboard internamente está conectada de la siguiente forma: Si conectamos nuestro sensor con sus pines perpendiculare a las líneas azuly rojo, lo que estamos haciendo es cortociruitar el sensor y conectar todos los pines entre sí, lo que provocará que lo rompamos y probablemente salga humo... cosa que, obviamente, queremos evitar. Colocaremos nuestro sensor de la manera correcta y posteriormente usaremos 4 cables para conectar cada uno de los pines de la protoboard con nuestro Arduino UNO: El pin SCL con SCLEl pin SDA con SDAEl pin G con el GNDEl pin 5V con el 5V Quedando de la siguiente manera: Ahora, pasaremos a ver el código necesario para identificar colores dependiendo de la cantidad de rojo, verde y azul que detecta el sensor. Identificamos colores Lo primero que haremos será descargar una librería, siguiendo el procedimiento que ya realizamos cuando instalamos la librería PulseSensor Playground. En este caso, buscaremos en el gestor de librerías de nuestro Arduino una llamada Adafruit TCS34725: Cuando la instalemos, probablemente nos aparecerá el siguiente aviso: Haremos clic sobre el botón Install All y así ya tendremos instaladas todas las librerías necesarias para que funcione el código siguiente: #include #include "Adafruit_TCS34725.h" /* Initialise with default values (int time = 2.4ms, gain = 1x) */ Adafruit_TCS34725 tcs = Adafruit_TCS34725(); void setup(void) { Serial.begin(9600); if (!tcs.begin()) { Serial.println("Error al iniciar TCS34725"); while (1); } } void loop(void) { uint16_t r, g, b, c, colorTemp, lux; tcs.getRawData(&r, &g, &b, &c); colorTemp = tcs.calculateColorTemperature(r, g, b); lux = tcs.calculateLux(r, g, b); Serial.print("Temperatura color: "); Serial.print(colorTemp, DEC); Serial.println(" K"); Serial.print("Lux : "); Serial.println(lux, DEC); Serial.print("Rojo: "); Serial.println(r, DEC); Serial.print("Verde: "); Serial.println(g, DEC); Serial.print("Azul: "); Serial.println(b, DEC); Serial.print("Clear: "); Serial.println(c, DEC); Serial.println(" "); delay(1000); } Este código está basado en el ejemplo TCS34725, con algunas modificaciones. El original puedes encontrarlo en la IDE de Arduino en Archivo > Ejemplos > Adafruit TCS34725 > tcs34725. Desmenuzando el código Lo primero que nos encontramos es dos sentencias que comienzan con # seguido de la palabra include. Como ya hemos visto en prácticas anteriores, esto se utiliza para importar librerías. En este caso importaremos las dos librerías que acabamos de instalar. #include #include "Adafruit_TCS34725.h" A continuación, lo que hacemos es crear un objeto sensor de color, de la misma manera que hicimos cuando creamos un objeto para nuestro pulsómetro. /* Initialise with default values (int time = 2.4ms, gain = 1x) */ Adafruit_TCS34725 tcs = Adafruit_TCS34725(); A continuación, encontramos la función void setup: void setup() { Serial.begin(9600); if (!tcs.begin()) { Serial.println("Error al iniciar TCS34725"); while (1); } } En ella comenzamos la comunicación con el puerto serial. Lo siguiente que haremos es comprobar si nuestro Arduino reconoce al sensor. Si no lo reconoce, entraremos en un bucle con la línea while (1) delay (1000); y pasado 1 segundo, volveremos a comprobar si nuestro Arduino ha reconocido al sensor. Si hemos realizado las conexiones correctamente esta línea no llegará a ejecutarse. Lo próximo que nos encontramos es la función void loop, que también la hemos visto en las anteriores prácticas. En ella, vamos a crear las variables que almacenarán la cantidad de rojo (r), verde (g), azul (b), el valor que reciban los fotodiodos sin filtro (c), la temperatura de la luz (colorTemp) y la cantidad de luz (lux). Serán variables cuyo tamaño sea 16 bits y eso lo sabemos porque se utiliza la palabra uint16_t. Seguidamente, encontramos tres funciones que se encargarán de recibir y procesar la información sobre el color que coloquemos delante del sensor. Con la primera tcs.getRawData(&r, &g, &b, &c);, recibimos los datos en bruto y con las dos sentencias siguientes, calculamos la temperatura del color colorTemp = tcs.calculateColorTemperature(r, g, b) haciendo uso de los valores RGB; y también la luz lux = tcs.calculateLux(r, g, b);. Los siguientes 7 Serial.print imprimen por el puerto serial los valores obtenidos. Al final encontramos un delay de 1 segundo (1000 ms) que nos facilitará la lectura del sensor al darle tiempo para procesar la información. void loop(void) { uint16_t r, g, b, c, colorTemp, lux; tcs.getRawData(&r, &g, &b, &c); colorTemp = tcs.calculateColorTemperature(r, g, b); lux = tcs.calculateLux(r, g, b); Serial.print("Temperatura color: "); Serial.print(colorTemp, DEC); Serial.println(" K"); Serial.print("Lux : "); Serial.println(lux, DEC); Serial.print("Rojo: "); Serial.println(r, DEC); Serial.print("Verde: "); Serial.println(g, DEC); Serial.print("Azul: "); Serial.println(b, DEC); Serial.print("Clear: "); Serial.println(c, DEC); Serial.println(" "); delay(1000); } Si ahora copiamos y pegamos este código en la IDE de nuestro Arduino y abrimos el puerto serial: Cuando acerquemos un objeto de color y abramos el puerto serial nos encontraremos con algo parecido a esto: Para ver qué color recibe nuestro Arduino, podemos introducir los valores RGB obtenidos en la siguiente página we: https://www.rapidtables.com/web/color/RGB_Color.html En el .gif superior, los valores obtenidos son: R=66G=62B=101 Si los introducimos en la página web, obtenemos un color similar al que hemos puesto delante del sensor: Tendremos que tener cuidado porque dependiendo de la superficie de los materiales que acerquemos al sensor, detectará los colores mejor o peor. Por ejemplo, las superficies brillantes dificultan reconocer el color. ¿Qué tenemos que presentar? Tendremos que presentar un .gif similar al que aparece en el apartado anterior. Tendrá que verse el sensor, un objeto de un color acercarse a él y con el monitor serial abierto, tendrán que verse los valores leídos por el sensor. REFERENCIAS: Imagen protoboard conexiones: https://2.bp.blogspot.com/-VL06n9GES1w/U3wniqqJoJI/AAAAAAAAACA/rbZNM-qF9lE/s1600/protoboard+(2).jpg Sensor TCS34725: https://www.luisllamas.es/arduino-sensor-color-rgb-tcs34725/ PROYECTO FINAL Práctica Final: Arduino + Pure Data: convertimos el color en sonido Este último proyecto va a consistir en que conecteis el sensor de color TCS34725 que vimos en la Práctica 13: Cómo perc... | Librería CATEDU con Pure Data para poder generar diferentes sonidos dependiendo de los valores que lea el sensor. Vamos a proporcionaros alguna herramienta más para que podáis trabajar con más comodidad y versatilidad con los datos que envies desde Arduino a Pure data, datos que vais a utilizar para controlar parámetros de vuestro patch: Etiquetas en el Serial: Anteriormente en la Práctica 10: Primera c... | Librería CATEDU enviamos valores desde Arduino a Pure data utilizando el puerto serial. En aquel caso Arduino detectaba cuando se producía un latido y enviaba un mensaje a Pure data para que con cada latido se produjera un sonido. Lo que hacíamos era controlar el sonido con los latidos de nuestro corazón. En aquel ejercicio en Arduino trabajábamos con un solo parámetro y todos los valores que Arduino enviaba Pure data procedían de ese único parámetro, por lo tanto, sabíamos sin necesidad de más información que aquellos datos que llegaban a Pure data correspondían con la detección de un latido. ¿Pero y si quisiéramos enviar datos de varios parámetros, como por ejemplo cuándo se produce un latido y las pulsaciones por minuto? Cuando estos datos llegan a Pure data, ¿cómo sabemos que datos corresponden al latido y cuáles, a las pulsaciones por minuto? Utilizando etiquetas. ¿Os acordáis de que en la Práctica 8: OSC. Open ... | Librería CATEDU recibíamos valores desde varios actuadores diferentes: (botón1, botón2, slider1, pulsador3 ...) y que cada uno de ellos tenía su etiqueta para que supiéramos su procedencia? En Arduino si queremos enviar a Pure data, a través del Serial, los valores de diferentes parámetros, como, por ejemplo, el rojo, azul y verde que lee el sensor de color, tendremos que enviar junto con cada valor una etiqueta que nos permita identificarlos. ¿Y cómo vamos a hacer esto? Empaquetando en una línea cada etiqueta con su valor. Crearemos este formato de paquete en Arduino, utilizando dos funciones para imprimir datos en el Serial. Cada línea sera un paquetito que va a contener una etiqueta y un valor. Por ejemplo, un paquete: "rojo: 140" En Arduino vamos a utilizar dos funciones para imprimir en el serial: Serial.print() y Serial.println() La diferencia entre Serial.print() y Serial.println() es que Serial.println() realiza un salto de línea tras imprimir su contenido en el puerto serial, este salto de línea es lo que vamos a utilizar para "cerrar" nuestros paquetes y que tengan una forma que podamos decodificar fácilmente en Pude data utilizando objeto "route", si os acordáis vimos este objeto en la Práctica 8: OSC. Open ... | Librería CATEDU y nos permite clasificar valores en función de etiquetas. Vamos a ver ahora con ejemplos que hacen en Arduino las funciones Serial.print() y Serial.println(): // The SetUp Function: void setup() { Serial.begin(9600); // Set's up Serial Communication at certain speed. } // The Main Loop Function void loop() { Serial.print("Mira "); // Send the "Mira" to Serial Plotter. Serial.print("por "); // Send the "por" to Serial Plotter. Serial.print("la "); // Send the "la" to Serial Plotter. Serial.print("ventana "); // Send the "ventana" to Serial Plotter. delay(10); } El código de la ventana superior imprimirá los valores en el serial de la siguiente manera: La función Serial.print() imprime y se mantiene en la misma línea en la que ha impreso. La función Serial.println() realizará un salto de línea tras imprimir: // The SetUp Function: void setup() { Serial.begin(9600); // Set's up Serial Communication at certain speed. } // The Main Loop Function void loop() { Serial.print("Mira "); // Send the "Mira" to Serial Plotter. Serial.println("por "); // Send the "por" to Serial Plotter. Serial.println("la "); // Send the "la" to Serial Plotter. Serial.print("ventana "); // Send the "ventana" to Serial Plotter. delay(10); } El código de la ventana superior realizará un salto de línea tras imprimir "por " y tras imprimir "la ": Si queremos que cada frase "Mira por la ventana" se imprima en una sola línea tendremos que colocar la función Serial.println() al final de la frase, imprimiendo la última palabra de esta frase: // The SetUp Function: void setup() { Serial.begin(9600); // Set's up Serial Communication at certain speed. } // The Main Loop Function void loop() { Serial.print("Mira "); // Send the "Mira" to Serial Plotter. Serial.print("por "); // Send the "por" to Serial Plotter. Serial.print("la "); // Send the "la" to Serial Plotter. Serial.println("ventana "); // Send the "ventana" to Serial Plotter. delay(10); } Ahora que ya sabemos manejar Serial.print() y Serial.println() vamos a preparar los paquetitos en Arduino para enviarlos a Pure data: Vamos a crear las etiquetas en Arduino que imprimiremos por el serial junto con los valores correspondientes. Cada etiqueta con su valor se imprimirá en la misma línea y antes que el valor, tras la impresión del valor habrá un salto de línea que cierre el paquete: Serial.print("Etiqueta1:"); Serial.println(valor1); Figura 1. Lectura de valores del sensor TCS34725 e impresión de esos valores junto con una etiqueta en el puerto serial. (¡Esta imagen solo es una parte del programa!) Cuando lleguen estos datos a través del serial a Pure data utilizaremos el objeto "route" para clasificar los datos recibidos. Los argumentos de este objeto serán las etiquetas que hemos creado en Arduino (figura 1): Figura 2. Clasificación en Pure data de los datos enviados por Arduino en la figura X. Ya sabemos preparar paquetes de datos en Arduino para enviar a traves de Serial! Figura 3. Nosotros poniéndole etiquetas en Arduino a un valor para saber qué contiene. Mapear valores: ¿Qué es mapear? Para nostros mapear valores va a ser ajustar la escala de un rango de datos a otra escala diferente. Vamos a ver un ejemplo: El sensor TCS34725 con el que estáis trabajando, registra el color utilizando parámetros RGB. En la codificación RGB encontraremos tres valores que nos permitirán definir un color: rojo (r), verde (g), azul (b). El rango de cada uno de estos tres valores es de 0-255. Supongamos que queremos regular el volumen de uno de nuestros instrumentos en función de la cantidad de rojo que tenga un objeto. Como bien sabéis, en Pure data controlamos el volumen modificando la amplitud de las ondas y nuestro rango de volumen ha de estar siempre entre 0 y 1. Para poder controlar el volumen (0-1) con el parámetro que mide el color rojo (0-255) vamos a tener que adaptar los valores del rojo a los valores del volumen, siendo 0=0 y 255=1. Con esta conversión si el valor del parámetro rojo fuera 127,5 el valor de nuestro volumen sera 0,5. Para realizar esta conversión vamos a utilizar el objeto "scale". Abrid el patch mapear-scale.pd para ver cómo funciona. En su primer inlet recibirá los valores a mapear, en nuestro caso los valores del color rojo del objeto que se está evaluando. En el segundo inlet enviaremos el valor menor del rango de los valores de entrada, que en nuestro caso es el 0. En el tercer inlet enviaremos el valor mayor del rango de los valores de entrada, que en nuestro caso es el 255. En el cuarto inlet enviaremos el valor menor del rango de los valores de salida, que en nuestro caso es el 0. En el quinto inlet enviaremos el valor mayor del rango de los valores de salida, que en nuestro caso es el 1. Figura 4. patch mapear-scale.pd Ahora que conocéis el objeto "scale" podréis controlar cualquier parámetro de vuestro patch con los valores que capten los sensores Arduino!!! Nos os olvidéis de enviar los mensajes al objeto "scale". Que los mensajes no se envían ellos solos. Práctica Final Como os hemos dicho anteriormente este último proyecto va a consistir en que conectéis el sensor de color que vimos en la Práctica 13: Cómo perc... | Librería CATEDU con Pure Data para poder generar diferentes sonidos dependiendo de los valores que lea el sensor. Como ves, el enunciado es bastante sencillo, pero para poder hacerlo, es necesario que hayas seguido todos los pasos y actividades que hemos realizado a lo largo del curso, si no, no va a ser muy fácil... El resultado final tendrá que ser algo parecido a esto: ¿Qué tendremos que entregar? La entrega tendrá dos partes. PARTE 1: ARCHIVOSEsto será una carpeta comprimida en .zip que contenga:1. Documento de texto con: Nombre completo, explicación de los valores del sensor utilizados, dificultades encontradas.2. Sketch de Arduino3. Patch de Pure Data El nombre de la carpeta será vuestro ProyectoFinal_Nombre_PrimerApellido_SegundoApellido PARTE 2: VIDEO CON AUDIOSerá necesario un video con audio de menos de 1 minuto en el que se vea el funcionamiento. El video se llamará: ProyectoFinalVideo_Nombre_PrimerApellido_SegundoApellido Figura 1. Lectura de valores del sensor X e impresión de esos valores junto con una etiqueta en el puerto serial. (¡Esta imagen solo es una parte del programa!) Figura 2. Clasificación en Pure data de los datos enviados por Arduino en la figura X. Figura 3. Nosotros poniéndole etiquetas en Arduino a un valor para saber que contiene.  https://giphy.com/gifs/GLSSpain-box-parcel-paquete-OKPtqN7dlflYcw8gPu Figura 4. patch mapear-scale.pd Pure Data a.k.a Pd Ayuda Pd El menu de ayuda nos proporciona documentación e información muy util acerca de Pure Data. Ayuda>puredata.info nos lleva a la pagina web de Pure Data.  Ayuda>Manual.HTML... abre la pagina web del Manual de Pure Data. Es el manual que vimos después de la instalación. Ayuda>Lista de objetos... abre Ayuda>Navegador abre Ayuda>Buscar Externos abrePistas para las practicas Pistas: Práctica 4 Ahora, vamos a crear un patch con los elementos que acabamos de ver. Para ello os voy a dar el algoritmo escrito de cómo ha de ser nuestro programa y vosotros lo construiréis en Pure data. Recordad que hay diferentes formas de llegar al mismo resultado así que sentíos con libertad de combinar los objetos que acabamos de introducir de diferentes maneras para probar y conseguir resolver el problema de la manera que más cómoda os resulte: Nuestro objetivo es reproducir las notas de la escala de una octava con nuestros altavoces, en mi caso he elegido la octava tercera y nos gustaría elegir la nota de la octava que se reproduce a traves del ratón. Importante solo enviaremos sonido a los altavoces una vez estemos seguros de que el nivel de volumen es adecuado. 1. Voy a crear un nuevo patch. 2. Necesito tener el DSP encendido para que el programa trabaje con señales. 3. Necesito hacer llegar a un oscilador los valores en Hz de las frecuencias correspondientes a la octava. Utilizar el código Midi para las notas de la octava y transformar esos valores a Hz antes de enviarlas al oscilador: 4. Necesito controlar el volumen. Voy a regular la amplitud de la señal que sale del oscilador y voy a utilizar un rango de 0-0.5 para modularla. Voy a utilizar el objeto "*~" para modular la amplitud y también puedo utilizar una slider con un rango de (0-0.5) 5. Me aseguro de que el volumen es adecuado. Voy a visualizar el nivel de volumen con el VU-meter antes de enviar la señal al dac~. 6. Una vez el volumen está bajo control y con el volumen de mis altavoces bajado enviare la señal al dac~. El volumen de mis altavoces esta fuera de pure data, por ejemplo, en mi caso es un knob, una rueda que giro en mi tarjeta de sonido. 7. Una vez escucho una de las notas de la octava probare a reproducir el resto de las notas. Enviare distintas frecuencias al oscilador. 8. Subo y bajo el volumen desde Pure data. ¿Escuchas algo raro? ¿clics y pums? Utiliza el objeto line~ para suavizar los cambios de volumen. 9. Si quiero visualizar la señal utilizare un vector y la interfaz gráfica que me permite visualizarlo. Créditos Relación de los contenidos del curso con la LOMLOE Asignaturas para trabajar interdisciplinarmente los contenidos de este curso Los principios metodológicos en los que se apoya esta formación son el fomento de la creatividad, preparación para la resolución de problemas en contextos reales y la inclusión  de tecnologías digitales como medio para que explorar las posibilidades para aprender, comunicarse y realizar creaciones propias. Para Música: En el nuevo currículo tenemos una competencia específica de la materia de Música CE.MU.4 que habla de crear propuestas artístico-musicales utilizando medios analógicos y herramientas tecnológicas con el fin de potenciar la creatividad. Dentro de las propuestas a las que se hace referencia en esta competencia se habla de instalaciones sonoras y  espectáculos multimedia, articulando lo sonoro con otras formas de arte  y organizándolo de proyectos pluridisciplinares compartidos con otras materias. La capacidad de formular propuestas artísticas contribuye al desarrollo de la creatividad y a la capacidad de trabajar en equipo. La reflexión final sobre su propio aprendizaje desarrolla el espíritu crítico así como la valoración de las manifestaciones artísticas desde el siglo XX en adelante. Esta competencia específica de música conecta con el  descriptor del perfil de salida STEM3  queso desarrolla  a través proyectos en lo que se diseña, fabrica y evalúa diferentes prototipos o modelos para generar o utilizar productos que den solución a una necesidad o problema de forma creativa y en equipo, atendiendo a la resolución pacífica de conflictos y valorando la importancia de la sostenibilidad. Si unimos el perfil de salida STEM e incluimos la competencia específica de en materia de música, que es Arte, tenemos STEAM A nivel de contenidos específicos de la asignatura música este curso se vincula con:1º, 3º y 4º de ESO : Planificar y desarrollar, con creatividad, propuestas artísticas musicales1º, 3º de ESO: Sonido silencio y ruido3º de ESO: El sonido y la música en los medios audiovisuales y las tecnologías digitales4º de ESO Del sonido, del ruido y del silencio en la era digital.1º, 3º de ESO: Herramientas digitales para la creación musical4º de ESO  Planificación y ejecución de proyectos musicales y audiovisuales4º de ESO Recursos para la creación de productos musicales y audiovisuales Para Educación Plástica Visual y Audiovisual: En el nuevo currículo tenemos dos competencias específicas de la materia de Educación Plástica, Visual y Audiovisual relacionadas con este curso CE.EPVA.5 y CE.EPVA.7. Por un lado, CE.EPVA.5 habla de realizar producciones artísticas con creatividad seleccionando y  aplicando herramientas, técnicas y soportes en función de la intencionalidad. Llevar a cabo una producción artística es un proceso complejo que implica proyección de los propios pensamientos y el conocimiento de los materiales, las herramientas, las técnicas  escogidas. Esta competencia  tiene relación directa con la CE.MU.4, ambas tratan la producción artística como una forma de potenciar la creatividad y  de ampliar las oportunidades de desarrollo personal, social, académico y profesional. En Tecnología y Digitalización el vínculo se da con la CE.TD.2 y la CE.TD.4. La CE.TD.2 involucra la autonomía y la creatividad, así como la capacidad de hacer uso de contenidos interdisciplinares para resolver problemas de forma eficaz. Por otro lado, CE.EPVA.7 consiste  en  aplicar técnicas, recursos de los lenguajes artísticos, e incorporar de forma creativa, las posibilidades que ofrecen las diversas tecnologías, para integrarlos y enriquecer el diseño y la realización de un proyecto artístico. En la actualidad  contamos con lenguajes como el audiovisual, la instalación o la performance que deben ser identificados y valorados. Para ello es importante que experimente con los diferentes medios, tecnologías e instrumentos de creación, haciendo especial hincapié en los digitales, definitorios de nuestro presente buscando un resultado que sea fruto de una expresión actual y contemporánea.  Esta competencia se relaciona con CE.MU.4 y con Tecnología y Digitalización se relaciona con  CE.T.2, y CE.T.5  en cuanto a la aplicación de técnicas y conocimientos interdisciplinares y por otro las herramientas digitales. Ésta competencia conecta con el  descriptor del perfil de salida STEM3  que al unirlo a la competencia específica de plástica visual y audiovisual, que es Arte, tenemos STEAM A nivel de contenidos específicos de la asignatura música este curso se vincula con:1º ESO: Elementos visuales, conceptos y posibilidades expresivas: forma, color y textura. 2º ESO: Elementos visuales, conceptos y posibilidades expresivas: forma, color y textura. 2º ESO: La percepción visual. Introducción a los principios perceptivos, elementos y factores Para Expresión Artística: Al igual que en las anteriores asignaturas la de expresión artística tiene una competencia CE.EA.4 que consiste en la creación de  producciones artísticas, realizadas con diferentes técnicas y herramientas. Esta competencia tiene vinculación con CE.MU.4, CE.EPVA.5 y CE.EPVA.7 y perfil de salida STEM3. A nivel de contenidos específicos de la asignatura música este curso se vincula con:4º ESO: Elementos y principios básicos del lenguaje visual y de la percepción. Color y composición. 4º ESO: Recursos digitales para la creación de proyectos de vídeo-arte. Para Tecnología y Digitalización: La nueva normativa educativa impulsa de forma decisiva la enseñanza de contenidos relacionados con la programación. Por un lado, la competencia específica CE.TD.2  plantea abordar problemas tecnológicos con autonomía y actitud creativa, aplicando conocimientos interdisciplinares y trabajando de forma cooperativa y colaborativa, para diseñar y planificar soluciones a un problema o necesidad de forma eficaz, innovadora y sostenible.  Uno de sus perfiles de salida también es  STEM3 Y la competencia CE.TD.5.  habla de desarrollar algoritmos y aplicaciones informáticas en distintos entornos, aplicando los principios del pensamiento computacional e incorporando las tecnologías emergentes, para crear soluciones a problemas concretos, automatizar procesos y aplicarlos en sistemas de control o en robótica.   De nuevo uno de los perfiles de salida es STEM3 Específicamente en los criterios de evaluación de dicha competencia, para el curso de 2º de ESO, se habla de: 5.1. Describir, interpretar y diseñar soluciones a problemas informáticos a través de algoritmos básicos y diagramas de flujo sencillos, aplicando los elementos y técnicas de programación de manera creativa.5.2. Programar aplicaciones sencillas, de forma guiada con una finalidad concreta y definida, para distintos dispositivos (ordenadores, dispositivos móviles y otros) aplicando herramientas de edición y empleando los elementos de programación de manera apropiada. Para Programación y Robótica: La Competencia CE.TD.5 también se encuentra en el Currículo de la materia optativa de 3º de ESO de Programación y Robótica como Competencia Específica nº 4 de esa materia, pudiendo aplicarse todo lo dicho anteriormente también en el desarrollo de dicha materia. Para Física y Química: El planteamiento del curso Arduino y Pure data permite desarrollar las siguientes competencias específicas del área de Física y Química (ESO): CE.FQ.1. Comprender y relacionar los motivos por los que ocurren los principales fenómenos fisicoquímicos del entorno, explicándolos en términos de las leyes y teorías científicas adecuadas, para resolver problemas con el fin de aplicarlas para mejorar la realidad cercana y la calidad de vida humana. CE.FQ.2. Expresar las observaciones realizadas por el alumnado en forma de preguntas, formulando hipótesis para explicarlas y demostrando dichas hipótesis a través de la experimentación científica, la indagación y la búsqueda de evidencias, para desarrollar los razonamientos propios del pensamiento científico y mejorar las destrezas en el uso de las metodologías científicas. CE.FQ.5. Utilizar las estrategias propias del trabajo colaborativo, potenciando el crecimiento entre iguales como base emprendedora de una comunidad científica crítica, ética y eficiente, para comprender la importancia de la ciencia en la mejora de la sociedad, las aplicaciones y repercusiones de los avances científicos, la preservación de la salud y la conservación sostenible del medio ambiente. Estas Competencias específicas se vinculan a los Perfiles de salida STEM1, STEM2, STEM3 y STEM5 Los contenidos de este curso trasladados convenientemente al alumnado de 4º ESO resultan especialmente adecuados a los criterios de evaluación 1.1, 1.3, 2.1, 2.3 y 5.1 y 5.2.  (1.1. Comprender y explicar con rigor los fenómenos fisicoquímicos cotidianos a partir de los principios, teorías y leyes científicas adecuadas, expresándolos de manera argumentada, utilizando diversidad de soportes y medios de comunicación; 1.3. Reconocer y describir situaciones problemáticas reales de índole científica y emprender iniciativas colaborativas en las que la ciencia, y en particular la física y la química, pueden contribuir a su solución, analizando críticamente su impacto en la sociedad y el medio ambiente; 2.1. Emplear las metodologías propias de la ciencia en la identificación y descripción de fenómenos científicos a partir de situaciones tanto observadas en el mundo natural como planteadas a través de enunciados con información textual, gráfica o numérica. 2.3. Aplicar las leyes y teorías científicas más importantes para validar hipótesis de manera informada y coherente con el conocimiento científico existente, diseñando los procedimientos experimentales o deductivos necesarios para resolverlas y analizar los resultados críticamente; 5.1. Establecer interacciones constructivas y coeducativas, emprendiendo actividades de cooperación e iniciando el uso de las estrategias propias del trabajo colaborativo, como forma de construir un medio de trabajo eficiente en la ciencia;  5.2. Emprender, de forma autónoma y de acuerdo a la metodología adecuada, proyectos científicos que involucren al alumnado en la mejora de la sociedad y que creen valor para el individuo y para la comunidad.) El epígrafe La luz y el sonido como ondas que transfieren energía se encuentra de forma explícita en el currículo de 4º ESO, en el Bloque D, La Energía (Concreción de los saberes básicos, III.2.3. Física y Química 4º ESO).Hacemos un proyecto STEAM Herramientas para hacer un proyecto STEAM Como hemos visto en el apartado anterior,  los contenidos que se enseñan en este curso pertenecen a varias asignaturas, esto nos permite hacer un proyecto STEAM en nuestro centro educativo. No tienes por qué incluir todas las asignaturas si hay alguna persona o departamento didáctico que no está interesado o no se atreve en un primer momento, se pueden ir incorporando en los próximos años ya que es un proyecto que se puede repetir. ¿Qué es STEAM? Para el proyecto STEAM Lab Aragón  STEAM  no es una metodología, sino un enfoque interdisciplinario que sirve para desarrollar los procesos de enseñanza y aprendizaje a través de la ciencia,  la tecnología y la creatividad (creatividad entendida como ideas nuevas que dan solución a problemas o como maneras novedosas de comunicar).  Por lo tanto, las áreas académicas tradicionales, como son la ciencia, la tecnología, la ingeniería, las artes y las matemáticas se estructuran e integran en un mismo currículum. Otro punto importante es tener claro para qué hacemos STEAM y aquí seguimos al equipo de Digna Couso;  lo que se quiere es capacitar y alfabetizar en STEAM a toda la ciudadanía para empoderar en la construcción de un mundo más sostenible, equitativo e inclusivo. ¿Cómo diseñamos un proyecto STEAM a partir de los contenidos de este curso? En el STEAMLAB Aragón tenemos herramientas de diseño basadas en la metodología Design Thinking que os ayudarán a hacerlo. En este enlace  encontrarás las herramientas y en este otro tienes un ejemplo Cualquier duda: steam@catedu.es