Anuncios

Pulsera refigeradora inteligente


Desde  Bangladesh,   un  estudiante de programación   y robótica llamado  Abtahee nos enseña  como construir una pulsera refrigerante  o calefactora basada una vez en una célula Peltier ,y que como aspecto destacable , es controlable desde una app que el propio autor ha creado.
Puede parecer extraño  que desde  una pulsera “normal” se pueda cambiar su sensación térmica y reemplazar el aire acondicionado o calefacción de habitaciones pero ,lo cierto es que es  un hecho científicamente demostrado que     basta  calentar o enfriar sólo la zona de la muñeca   para simular un ambiente térmico  que haga que se sienta más fresco en verano o  se este  caliente en invierno simplemente aplicando frio o calor  solo en  la muñeca

Hablamos  pues de un sistema asequible que teóricamente  podría sustituir  equipos de aire acondicionado destacando el  bajo consumo y su gran portabilidad.

Aunque la pulsera  solo puede enfriar o calentar una pequeña zona del cuerpo, es absolutamente eficaz( incluso según su autor   podría decirse  que  no menos de un aire acondicionado o un calefactor)  consumiendo no más de 2,5 vatios.

Después de usar este sistema  se empieza a sentir fresco dentro de muy poco tiempo ,tanto que incluso si el clima es muy caliente se siente una suave brisa que fluye constantemente hacia el poseedor de la pulsera

El autor ademas comenta que ha probado su diseño de  pulsera en más de 50 personas en condiciones de temperatura diferentes y todos ellos tuvieron respuesta positiva.

 

 

 

 

Hardware

Cambiar la temperatura del cuerpo es muy difícil y se necesita una gran cantidad de energía,por eso  con esta técnica de centrarnos en calentar o enfriar solo un parte del cuerpo (las muñecas  ) sólo necesitamos cambiar la sensación térmica  consumiendo en esa zona consumiendo por tanto  mucho menos energía.

¿Cómo enfriando o calentando una pequeña zona de su cuerpo puede enfriar su cuerpo entero? Pues en realidad no cambia la temperatura de su cuerpo como lo hace un equipo de  aire acondicionado o calefacción pues el trabajo de la pulsera es realmente “engañar” al cerebro con la percepción   

Si se mantiene la mano en agua fría, inmediatamente se siente frío por un tiempo,pero después de que su cerebro procese el cambio de temperatura repentino al rato  ya no sentirá frescor o por lo menos la sensación tan acusada así que en el caso de esta pulsera, si cambiamos  la temperatura cada segundo, su cerebro no puede hacer frente a la sensación de la temperatura y seguirá sintiendo frescor mientras se ponga la pulsera aprovechando  que  los sensores térmicos de la muñeca son más sensibles que otra parte del cuerpo

 

Veamos esto empíricamente mediante un gráfico donde en abscisas indicaremos el tiempo  trascurrido  y  en ordenadas la tasa de cambio de temperatura

grafico.png

 

Puede asumir que  refrescarse o calentar su cuerpo lo hace esta pulsera pero realmente no es así . Algo cambia la temperatura de su muñeca cada segundo como se representa en el gráfico anterior o que hace que su cerebro pare de sentir que la temperatura está cambiando de un ambiente más caliente o más frío. La temperatura aumenta durante 6 segundos y la pulsera se apaga cada segundo de modo  que el cambio continuo de la temperatura en la muñeca obliga a su cerebro a centrarse en la temperatura de su muñeca.

Así que las otras partes de su cuerpo no se sienten  la temperatura del ambiente tan fuertemente como en las muñecas: es por eso que si su muñeca está siendo calentada por la pulsera, usted se sentirá caliente y si la muñeca está siendo enfriada, usted se sentirá fresco por lo que exactamente cuando usted use una pulsera de este tipo, no sentirá la temperatura del ambiente sino la inducida parcialmente por el dispositivo, pero si la temperatura no cambiase, su cerebro se ajustará con la temperatura de la muñeca en un tiempo y nuevamente se comienza a sentir la misma aunque cambie la temperatura de su cuerpo en una tasa pequeña.

 

Bien   veamos ahora los compontes utilizados por este interesante proyecto:

1. Arduino UnoArduino Nano (esta ultima es una mejor opción que uno por ser de tamaño pequeño)                                                                                                        

2. Módulo del controlador Motor L298N/L293D.  pues cada pin en un Arduino puede manejar 40 mA así que conectar directamente la celula  peltier a un pin arduino destruirá la placa arduino.Una opción seria usar un driver basado en relé que consume menos energia y es mas barato pero al requerir refrigerar o enfriar  esto se consigue cambiando los hilos de alimentación  por lo se requiere una electronica mas avanzada como por ejemplo un driver de motor pasos a paso de potencia                                                                                                                   

3.Módulo compatible con Arduino  Bluetooth HC-06/HC-05

4. Sensor LM35 para medir la temperatura exterior                                                                                                                                                                                                                   

5. Módulo peltier (se usa tanto para calefacción y refrigeración.)                                                                                                                                                                 

6.Varios : Disipador de calor, Correas  de relojVelcro/reloj, cables de puente,Bateria  de más  5 voltios,Ledas azul y Led rojo (para indicar si el dispositivo de enfriamiento o calefacción,Pasta térmica y el disipador térmico completo

Montaje  célula  Peltier

Ahora es el turno para hacer la pulsera asi que en primer lugar  tendrá  que adjuntar la célula de  peltier con el disipador de calor así que tome el peltier y el disipador de calor.

Ponga pasta térmica en la parte posterior del disipador de calor y coloque el lado caliente de peltier con el disipador de calor como en la foto

Un aspecto  particularmente es colocar la cara correcta al radiador que como se ve es la zona no seriegrafiada .

Ahora para fijar la célula  peltier puede usar pegamento caliente como se muestra en la imagen.

peltier.PNG

Ahora tocaría fijar el radiador con la célula Peltier a una correa  para lo cual se puede tomar un cable grueso y el disipador de calor  usando un sistema similar al de un cuadro  para que cree dos  ganchos en forma de D en ambos lados del disipador de calor.

Ahora se puede  utilizar pegamento caliente para unir el cable con el disipador de calor más fuertemente y  para que el cable no salga de la pulsera.

Puede  tomar la correa de Aun viejo reloj  o correas de Velcro y fije los ganchos como las imágenes mediante el uso de pegamento caliente.

pulseras.PNG

Ahora la pulsera está lista. Se puede diseñar mediante el uso de pegamento caliente en la parte superior del disipador de calor para que se vea más atractivo.

Diagrama del circuito, código y aplicación

El circuito usado para controlar la célula de Peltier  es relativamente sencillo pues realmente hay un modulo bluetooth   que invierte TX x RX   y Rx xTX    adema de alimentarse de la propia placa

  •  Arduino 3.3V >> módulo Bluetooth VCC
  •  Arduino Tx >> Bluetooth módulo Rx
  •  Arduino Rx >> Bluetooth módulo Tx
  • Arduino GND >> Masa modulo Bluetooth

Ademas tenemos dos leds   conectando el cátodo  del  Led azul al pin  Pin 10  y al  cátodo del led  rojo al pin 11 .

El sensor de temperatura usado  utiliza tres pines  porque se puede alimentar el Peltier  de un modo  y entonces ofrecerá frio por la cara no serigrafiada  y si se invierte la alimentación  también se invierte el efecto térmico

  • Arduino Pin A1 >> Vout del sensor LM35
  • GND >>GND del LM35
  • Vcc>>5v delLM35

Para la placa de potencia  usaremos dos conexiones :

  •  Arduino Pin 3 >> Motor Driver en 1
  •  Arduino Pin 5 >> controlador de Motor en 2
  • Arduino GND >> Masa modulo driver

Lógicamente de la salida de la placa aumentaremos el modulo de Peltier

Por  ultimo concluimos con una batería  y un interruptor general para apagar o encender todo el dispositivo

esqeuma.png

 

Resumidamente las conexiones son pues las siguientes:

  •  Arduino Vin >> Motor Driver VCC y la batería.
  •  Arduino 5V >> Vin del sensor LM35
  •  Arduino 3.3V >> módulo Bluetooth VCC
  •  Arduino Tx >> Bluetooth módulo Rx
  •  Arduino Rx >> Bluetooth módulo Tx
  •  Arduino Pin 3 >> Motor Driver en 1
  •  Arduino Pin 5 >> controlador de Motor en 2
  • Arduino Pin 10 >> Led Blue(+)
  • Arduino Pin 11 >> Led 7.Polarized
  • Arduino Pin A1 >> Vout del sensor LM35
  • Todos los componentes del suelo >> Battery(-)
  • Motor Driver Out1 >> Peltier (cable rojo)
  • Motor Driver Out2 >> Peltier (alambre negro)

El código   usado  los puede  descargar desde Instructables.com

[Nota: pin Tx y Rx del módulo bt no debería conectarse a arduino mientras se cargan el código.]

Ahora es necesario poner todos los componentes en una caja. Utilice una caja que se puede poner fácilmente en su bolsillo.

La caja debe tener suficiente espacio para guardar todos los componentes  y los mas pequeña posible  para contener  el arduino y otros componentes dentro de la caja.  Puede  hacer un área separada para la batería  o ponerla aparte . Es interesante  que el indicador led  y el sensor de temperatura debe estar fuera de la caja. Los cables conectados con la peltier deben ser lo suficientemente largos que pueden mantener la caja en su bolsillo mientras que usa la pulsera en su mano.

 

App movil

pantalla.PNG

Se puede descargar e instalar la aplicación que ha diseñado el autor también desde instructables.com:

Active la conectividad bluetooth en su teléfono inteligente y encienda el dispositivo . Ahora abra la aplicación y pulse el botón conectar y emparejelo  con el módulo bluetooth HC-06/HC-05.

La aplicacion  dispone de tres modos:

  • Auto Control:Si usted activa control automático pulsando el botón de auto control, la pulsera será calentar o enfriar te según la temperatura del ambiente. El dispositivo tiene un sensor de temperatura que mide la temperatura del ambiente. La temperatura se mostrará en su smartphone cuando se conecta el dispositivo con tu smartphone. Si la temperatura es superior a 28° C, enfriará y si la temperatura es inferior a 25° C, calentará. La velocidad de enfriamiento y la tasa de calentamiento depende de la temperatura se muestra en el gráfico anterior.
  • Modo manual :Cuando no se siente satisfecho con el modo automático, se puede ir a través del modo manual usando los controles deslizantes para enfriar o calentar te según tus. Puede utilizar el modo después de trabajo físico o gimnasio para relajarse le para arriba. La temperatura del ambiente no importa si usas el modo manual.
  • Modo de agua e:Si desea bañarse en agua fría o estanques, puede activar el modo de agua caliente te y esperar 4-5 minutos y usted sentirá el agua 1-2 grados más calientes que antes. Pero no funcionará efectivamente cuando el agua es demasiado fría. Pero en caso de enfriamiento o de calefacción, la pulsera funciona como encanto.

Si se utiliza el modo manual, no define la pulsera demasiado caliente o frío así que debe establecer la posición del control deslizante según sus preferencias

Anuncios

Construya su huerto robotico


En efecto   ya es posible  construirse   un huerto robótico ,  donde incluso el sw de gestión es open sw y cuyo cerebro no podía ser otro que una Raspberry Pi 3  .

Evidentemente para llevarlo a  la praxis realmente la barrera no es otra que el exigente hardware para controlar el huerto en si , pues este requiere  de una gran cantidad de elementos  que sin duda hacen mucho mas complejo  su construcción ,pero la buena  noticia  es que   aproximadamente FarmBot (que es la empresa que hay detrás de las idea)  prometen simplificarlo mediante diferentes kits  si esta dispuesto a  realizar una inversión entre 2595$ ( la version standard) o la 3795$ ( la version XL)

Aparte del potente hardware que funciona a modo de un puente grúa  con un cabezal multiherramienta bastante original llama la atención el sw para controlarlo bajo el concepto de arrastrar y soltar donde se puede diseñar gráficamente una granja arrastrando y colocando las plantas en el mapa  desde un interfaz que se  aprende en pocos minutos , por  lo que llevar a la plantación como podemos ver es bastante sencillo ya  que se tendrá todo previsto en todo momento cuando llegue la temporada de cultivo.

Es evidente que unos de los valores mas apreciados en el sw es que permite construir nuevas características,crear  código de propios mods personalizados o soportar  la aplicación web localmente  para ser independiente de la red. Ademas todo el software está bajo la licencia MIT en código abierto (open software)  y este esta compartido en Github , permitiéndole contribuir, copiar, modificar, redistribuir e incluso vender software FarmBot. ¿desea ayudar a crear nuevas funciones o tiene un error que reportar? ¡ Involúcrese en github!

 

En  el sw ademas  se contemplan regímenes de crecimiento  para construir pautas para el cuidado de una planta a lo largo de toda su vida mediante la programación de las secuencias a ejecutar cuando la planta es de una cierta edad. Incluso  los regímenes se pueden reutilizar, haciendo una brisa de replantación. Otro aspecto son las secuencias de construcción donde rápidamente se pude crear secuencias personalizadas para aprovechar al máximo su hardware donde ningún código es requerido. Simplemente arrastrar y soltar las operaciones básicas  ajustar los parámetros y guardar.

Ademas   el control se hace en tiempo real debido a que se pueden  utilizar  las  herramientas en tiempo real con los controles manuales. !Incluso se puede ahuyentar aves en tiempo real ordenándolo desde un smartphone  !

El Hardware ha pasado por grandes esfuerzos al diseño, fabricación y controles de calidad  siendo además, todos los modelos de CAD  públicos así que usted puede construir sus propias piezas.

Respecto  a  los elementos el hw ( que incluyen ambos kits)  estos son los elementos que lo   componen:

  • Extrusiones de aluminio para las pistas, pórtico y eje z
  • Placas de aluminio de 5mm anodizado
  • V-ruedas con rodamientos de bolas de goma sellada de acero inoxidable
  • Moldeado de inyección UV estabilizado componentes de plástico ABS
  • Tornillos de acero inoxidable, tuercas t, separadores y otros hardware
  • Cuatro motores de pasos NEMA 17 con codificadores rotatorios y cables
  • GT2 de correas y poleas de aluminio
  • Portacables de plástico durable
  • Acero inoxidable leadsrew y delrin bloque de 8mm alta tolerancia
  • Fuente de alimentación impermeable IP67 con 110 y 220V CA
  • Raspberry Pi 3 y 8GB de tarjeta microSD
  • Farmduino microcontrolador con montado y probado con controladores paso a paso
  • Caja o impermeable para la electrónica
  • Montaje de la herramienta universal, cubierta y cable de 12 hilos
  • Herramienta de inyector de semilla con bomba de vacío, tubos, compartimiento de la semilla, bandeja de la semilla y agujas de bloqueo luer adaptable (3 dimensiones)
  • Boquilla de  riego con válvula solenoide, tubos y adaptadores para manguera de jardín estándar de Estados Unidos
  • Herramienta de sensor de suelo
  • Herramienta desyerba con implementos personalizables
  • cámara  USB IP67 impermeable
  • Dos toolbays de 3 ranuras

 

En este video podemos ver el equipo en funcionamiento !es impresionante!

 

Software

OpenFarm.CC fue concebido originalmente como un pequeño componente del proyecto FarmBot. A medida que se progresó, se hizo evidente que OpenFarm no tenía ninguna razón para estar atado a FarmBot, sino que podría vivir por sí solo. En septiembre de 2014, 1.605 personas respaldaron a OpenFarm en el pedal. Hoy en día, OpenFarm es una aplicación independiente, sin fines de lucro y comunidad. Puede de hecho involucrarse con OpenFarm uniendo el canal  y  contribuyendo en Github, o yendo a OpenFarm.cc y creando contenido!

Hay muchos sistemas de software que contribuyen a la funcionalidad de FarmBot. El siguiente diagrama muestra los diferentes componentes y la forma en que los datos fluyen entre ellos. Lea las breves descripciones de cada componente en las siguientes secciones para entender el sistema como un todo, y luego Sumérjase en la configuración de los componentes necesarios para su FarmBot.

La aplicación web FarmBot  ,como se pude ver en el video  anterior, permite configurar y controlar fácilmente  FarmBot desde un navegador web en su laptop, Tablet o smartphone. La aplicación cuenta con controles manuales en tiempo real y registro, un generador de secuencias para crear rutinas personalizadas para que se ejecute FarmBot y un diseñador de granjas de arrastrar y soltar para que pueda diseñar y administrar gráficamente su granja.

El broker de mensajes es una aplicación de nube que actúa como intermediario para todos los mensajes entre la aplicación web FarmBot y los dispositivos FarmBot . Maneja conexiones de socket, identificación de dispositivos y autenticación.

FarmBot Raspberry PI utiliza un sistema operativo personalizado llamado FarmBot os para mantener una conexión y sincronizar con la aplicación web a través del intermediario de mensajes. Esto permite a FarmBot descargar y ejecutar eventos programados, ser controlados en tiempo real, y cargar logs y datos de sensores. El SO se comunica con el Arduino sobre USB para enviar comandos de código G y F y también recibir datos recopilados.

FarmBot os tiene una utilidad integrada denominada Configurator que permite introducir fácilmente las credenciales de WiFi y de aplicación web desde un dispositivo habilitado para WiFi (como un ordenador portátil o un smartphone). Esto es útil para la configuración inicial con el fin de obtener su FarmBot conectado a su casa wifi.

Respecto  firmware  Farmbot para Arduino es flasheado en el microcontrolador Arduino mega 2560 de FarmBot y es responsable de operar físicamente el hardware, las herramientas, los sensores  otros componentes electrónicos de FarmBot. Recibe los códigos de G y de F del regulador del PI de la Raspberryde FarmBot vía conexión serial del USB, y después mueve los motores y Lee y escribe los pernos por consiguiente. También envía los datos recogidos de los codificadores rotatorios y el PIN Lee de nuevo a la Raspberry PI.

OpenFarm.cc es una base de datos gratuita y abierta para la agricultura y el conocimiento de jardinería. Este servicio proporciona información de cultivo y crecimiento a la aplicación web para un usuario racionalizado experimentado.

 

Hardware

FarmBot Genesis es  la plataforma de hardware de código abierto de bricolaje optimizada para la producción de alimentos a pequeña escala basada en el suelo .FarmBot Genesis , quee s la version mas económica ,  está diseñado para ser una Fundación FarmBot flexible para la experimentación, prototipado y hacking. Los factores que conducen detrás del diseño son simplicidad, manufacturabilidad, escalabilidad, y hackeabilidad.

FarmBot Genesis es una pequeña escala FarmBot principalmente construida a partir de protuberancias en V-ranura de aluminio y placas de aluminio y soportes. Génesis es conducida por cuatro motores de pasos NEMA 17 con codificadores rotativos, el microcontrolador Farmduino, y un ordenador de frambuesa PI 3. El Génesis puede variar en tamaño desde un área de plantación tan pequeña como 1m2 hasta un máximo de 4,5 m2, mientras que alberga una altura máxima de planta de aproximadamente 1m. Con el hardware y las modificaciones adicionales Anticipamos que el concepto del Génesis podría escalar a aproximadamente 50 m2 y una altura máxima de la planta de 1.5 m.

Como vemos  Farmbot no es su producto típico pues sus creadores  han pasado por grandes esfuerzos para diseñar FarmBot Genesis para ser duraderos, fácilmente ensamblados y modificados con herramientas comunes, construidos a partir de componentes en gran parte fuera de la plataforma, y fabricados con procesos y materiales fácilmente disponibles. Nada sobre FarmBot habla de obsolescencia o de propiedad.

Las pistas son uno de los componentes que realmente diferencian la tecnología de FarmBot de los tractores de ruedas tradicionales de conducción libre. Las pistas son las que permiten al sistema tener una gran precisión de una manera eficiente y sencilla. Hay muchas razones de por qué las pistas son superiores, algunas de las cuales se enumeran a continuación.

  • Las pistas proporcionan una gran precisión y permiten que el FarmBot vuelva a la misma posición repetidamente
  • Cualquier tipo de estructura de empaque de las plantas se puede crear y manejar
  • Las pistas ocupan menos área que las trayectorias para las ruedas del tractor y no compactan el suelo

El pórtico es el componente estructural que puentea las dos pistas y se mueve en la x-dirección vía un sistema de impulsión de la x-dirección. Típicamente, sirve como una guía lineal para el deslizamiento transversal y una base para el sistema de impulsión de la y-dirección que mueve el Cruz-resbale a través del pórtico en la y-dirección. También puede servir como base para el montaje de otras herramientas, electrónica, suministros y/o sensores.

La Cruz se mueve en la Y-dirección a través del pórtico. Este movimiento proporciona el segundo grado mayor de libertad para FarmBots y permite que las operaciones como la plantación se realicen en cualquier lugar del plano XY. El deslizamiento transversal se desplaza utilizando un sistema de impulsión y-dirección y funciona como la base para el montaje de la herramienta y el sistema de la impulsión de la Z-dirección.
Eje Z

El eje z se conecta a la corredera transversal y proporciona el FarmBot con movimiento de dirección z. Sirve como base para la fijación del montaje universal de la herramienta y de otras herramientas. .

Para que los FarmBots crezcan adecuadamente las plantas más altas, el pórtico, la corredera transversal, el eje Z y las herramientas deben tener una separación vertical adecuada de las plantas. Esto generalmente se puede lograr de dos maneras:

  • Usando pistas levantadas y un pórtico Low-Profile
  • Usando pistas bajas con un pórtico alto

En general, el uso de pistas bajas con un pórtico alto es el mejor diseño, especialmente para aplicaciones más grandes, ya que ahorra en costo material, es menos de una monstruosidad, bloquea menos luz del sol, y sería más fácil de mantener. Sin embargo, en el caso de un FarmBot que se está instalando en un invernadero u otra estructura, utilizando las paredes existentes para apoyar las pistas más altas puede ser una mejor solución.

 

El  Soporte universal para herramientas (universal Tool Mount o UTM)  permite a FarmBot Genesis cambiar automáticamente las herramientas para realizar diferentes operaciones. La UTM es necesaria porque no es factible tener todas las herramientas montadas en el eje z al mismo tiempo por varias razones:

  • Esto sería muy pesado y aumentaría las tensiones en todos los componentes, así como requerir un motor más grande del z-axis.
  • La mayoría de las herramientas necesitan ser la cosa “más baja” en el eje z para poder trabajar. Tener múltiples herramientas compitiendo por la posición más baja (ej: una sonda de temperatura y un inyector de semillas) no sería ideal y puede que no funcione en absoluto. El uso de mecanismos de elevación y descenso de herramientas individuales, o un mecanismo de estilo de torreta sería complejo, pesado, voluminoso y limitado en el número de herramientas que podría soportar.
  • El tamaño del eje z debe mantenerse a un mínimo para que tenga un impacto mínimo sobre las plantas, especialmente cuando no hay mucho espacio entre ellos.

La UTM es un componente de plástico que se monta en la extrusión de aluminio del eje z utilizando dos tornillos M5 y tuercas en t.Algunas de sus características:

  • 3 imanes fuertes del anillo del neodimio para sostener magnético las herramientas en el lugar vía otros imanes colocados en la misma configuración en la herramienta.
  • Pasadizos para agua, enmiendas líquidas (ej.: abono), y vacío o aire comprimido para pasar de la UTM (y el resto de FarmBot) a la herramienta.
  • 12 tornillos de resorte que hacen conexiones eléctricas con herramientas.

 

Es como vemos una de las partes cruciales del proyecto pues la que realemnte actua sobe las plantas. Precisamente en este video nos explican en que consiste esta versátil herramienta;

 

Mas información en https://farm.bot/

 

Huerto controlado por raspberry


Carolina Herrero nos propone un sistema de un sistema automatizado para riego  que  ademas  no precisa de conexión a Internet porque todas las medidas se  gestionan de forma interna y por tanto no precisan ningún servicio de IoT  para su  funcionamiento ( como por ejemplo Cayenne.com del que  hemos hablado numerosas ocasiones en este blog)

 

La idea principal de Carolina era construir un sistema de riego automático, controlado por diferentes tipos de sensores, de forma que el sistema tomase decisiones de modo automático  guiándose  en función de las condiciones del ambiente y la necesidad de riego que tiene la tierra según el grado de humedad  de modo que cuando las condiciones fuesen óptimas comenzase el riego(, siempre y cuando exista agua en el depósito)
Además su creadora  también quería que los datos se almacenaran de forma periódica en una base de datos local  mySQL  , y a través de una aplicación Web, con sus  credenciales poder acceder y ver un histórico gráfico de las mediciones de los sensores .
Para conseguir esto básicamente   ha utilizado:
  • Varios  Sensores
  • Una placa  Microcontroladora
  • Un Servidor local

Sensores

El sistema utiliza diferentes tipos de sensores, porque se requiere  controlar diversos valores como son :
  • Valores de la humedad de la tierra para lo que se usa un sensor conocido como YL-69, que consiste en dos picas que se encuentran enterradas en tierra de manera que controlando la resistencia de la tierra se puede conocer la humedad.Esta es una herramienta indispensable para un jardín conectado  pues por si mismo nos puede  recordar que debe regar las plantas de interior o para monitorear la humedad del suelo en su jardín . Se alimenta a: 3.3V-5V   y el modo de módulo de salida dual, salida digital, salida analógica más precisa

  • Para recoger los valores de humedad y temperatura ambiente se utiliza un  simple sensor DHT11 (si bien  un DHT22 hubiese sido  mas recomendable por su mayor precisión , aunque es cierto que su coste es algo mayor)                                                   
  • De la temperatura del suelo se encarga el DS18B20, un sensor sumergible y resistente a la humedad, que se usará para controlar la temperatura de la tierra. 
  • Por seguridad, y para evitar que las bombas funcionen en vacío, y puedan dañarse, es imprescindible controlar el nivel de agua que hay en el depósito, y estos se consigue con un sensor de nivel .Estos sensores pueden medir humedad entre el 10% -90% sin condensación con un consumo de menos de 20mA y ofreciendo una salida analógica con  un área de detección de 40mmx16mm
  •  Por último controlar si hay luz o no, para evitar el riego de noches se ha usado un sensor de luz, también conocido como resistencia LDR.

Arduino

El encargado de recoger todos los  valores  procedentes de los sensores descritos y tomar las acciones necesarias es una placa  sistema Arduino  que ha sido programado para recoger datos, actuar en función de los valores de dichos datos, y en última instancia se encarga de mandarlos a un servidor ( una Raspberry Pi) para su seguimiento estadístico  de modo que en principio si no nos interesa seguir esa traza perfectamente el proyecto quedaría únicamente con esta placa   y sus sensores .

Aquí su autora comparte  una parte del código encargado de recoger los datos, y enviarlos por el puerto serie.

//Función que se encarga de leer datos de todos los sensores
void leer_datos_sensores(){
  valor_ha = dht.readHumidity();             //Se lee la humedad en el ambiente
  valor_ta = dht.readTemperature();          //Se lee la temperatura en el ambiente
  valor_ht1 = analogRead(hum_tierra1);       //Se lee humedad en tierra en la zona1
  valor_na = analogRead(nivel_agua);         //Se mide el nivel de agua existente en el depósito
  valor_luz = analogRead(luz_ldr);           //Se lee la luz
  DS18B20.requestTemperatures();             //Prepara el sensor para la lectura
  valor_tt1 = DS18B20.getTempCByIndex(0);    //Se lee la temperatura en tierra en la zona 1        
}
//Función para enviar valores de los sensores por el puerto serie
void enviar_datos(){
  Serial.print(valor_ha);Serial.print(“,”);
  Serial.print(valor_ta);Serial.print(“,”);
  Serial.print(valor_ht1);Serial.print(“,”);
  Serial.print(valor_na);Serial.print(“,”);
  Serial.print(valor_luz);Serial.print(“,”);
  Serial.print(valor_tt1);Serial.print(“,”);
}

Servidor web y BBDD

Como servidor no podía ser de otra manera que optar  por una Raspberry PI conRaspbian, basada en Debian  y que  hace  de servidor  Base de Datos, y además también de de Servidor Web.
Como servidor web se usa el Servidor Web Apache funcionando junto con MySQL como servidor de BBDD.
Además para que Arduino y Raspberry se comuniquen entre sí, se requiere un script en Python, que se encarga de recibir los datos por el puerto Serie que Arduino está enviando de forma constante .
Básicamente este script recibe los datos de Arduino  , se conecta con la  BBDD MySql  e inserta los datos.
#!/usr/bin/python
#-*- coding: UTF-8 -*-
 
import MySQLdb
import serial
 
# Establecemos la conexión con la base de datos
bd = MySQLdb.connect(“host”,“user”,“pass”,“db” )
# Preparamos el cursor que nos va a ayudar a realizar las operaciones con la base de datos
cursor = bd.cursor()
 
#Inicia la comunicación con el puerto serie
PuertoSerie= serial.Serial(‘/dev/ttyACM0’, 9600)
#Lectura de datos
sArduino = PuertoSerie.readline()
#Separa la cadena en valores, cada valor hasta la coma es almacenado en una variable
sHumAmbiente,sTempAmbiente,sHumTierra1,sNivelAgua,sLuz,sTempTierra1=sArduino.split(“,”)
 
ha = float(sHumAmbiente)
ta = float(sTempAmbiente)
ht1 = int(sHumTierra1)
na = int(sNivelAgua)
luz = int(sLuz)
tt1 = float(sTempTierra1)
zona1 = 1
 
 
#Almacenamos los valores en tabla datos de la base de datos huerto
sql1=“INSERT INTO datos_huerto(hum_ambiente,temp_ambiente,hum_tierra,nivel_agua,luz,temp_tierra,id_zona) VALUES (%f,%f,%d,%d,%d,%f,%d)” % (ha,ta,ht1,na,luz,tt1,zona1)
 
try:
   # Ejecutamos el comando
   cursor.execute(sql1)
   bd.commit()
except:
   print “Error”
   bd.rollback()
 
# Nos desconectamos de la base de datos
bd.close()
Para se hacer esto  de forma periódica pero no constante, puede usarse  la herramienta Cron integrada en Raspbian, de manera que cada “X” minutos se ejecute el script en Python.
Para la parte de  visualización de los datos la autora opto  por o una aplicación Web sencilla, programada n Php, junto con pequeñas funciones en Javascript para controlar y validar ciertos campos. En el aspecto visual uso  el framework Bootstrap, asi como la  librería HighCharts para la creación de gráficas y así conseguir visualización de los datos muy atractiva.
arduino.png
Es muy importante que si le damos salida a internet a La Rasberry PI  nos cercioremos de que está segura. Para ello es interesante :
  • Modificar el archivo de configuración de Apache, para que ante un ataque muestre la mínima información posible sobre el servido
  • Encriptar el tráfico entre cliente y servidor mediante certificados SSL
  • Forzar para que el acceso siempre sea seguro vía peticiones del tipo  HTTPS.
 Finalmente esta es la lista de componentes utilizados para el sistema:
  • Arduino Mega 2560 Rev.3 x1
  • Raspberry Pi x1
  • Sensor de humedad de tierra YL-69 x 2
  • Sensor de temperatura y humedad ambiente DTH-11 x1
  • Sensor de luz LDR x1
  • Sensor de temperatura de tierra  SD18b20 x2
  • Sensor de nivel de agua x1
  • Placa de 4 relés 5V-220Vx1
  • Bombas de agua x2
  • Protoboard x1
  • Resistencias de pull-up de diferentes valoresx 12
  • Cableado y conectores –
  • Leds de diferentes colores x15
  • Bandeja de plástico x1
  • Piezas de policarbonato x2
  • Recipientes para depósito de agua y electrónica x2
  • Tarjeta SD  para Raspberry PI x1
  • Tubos de goteo x2
  • Plantasx 6
  • Fuente de alimentación 220V x1

Le damos nuestra mas sincera enhorabuena a Laura por su sistema que animamos a que siga perfeccionando así como compartiendo con la comunidad todos sus progresos

Sistema de detección de carril con opencv


Kemal Ficici     nos demuestra  con su proyecto escrito en  python,  que por cierto  ha publicado con su código completo en  github,   como es posible usando la librería  OpenCv    construir un detector de carril   que  incluso  maneja carriles con  curvas.

A pesar del gran avance , sin embargo el autor  reconoce  que la salida de su sistema  todavía se ve afectada por sombras y drásticos cambios en la textura de la carretera  lo cual invalida en gran parte su resultado ,  lo cual  le hace  pensar en futuras actualizaciones de su proyecto  haciendo  uso de técnicas de aprendizaje automático para llegar a desarrollar un sistema de detección de vehículo e increíblemente robusto carril.

En el siguiente video podemos ver el resultado de su trabajo:

En cualquier escenario de conducción, las líneas de carril son un componente esencial de lo que indica el flujo de tráfico y donde se debe conducir un vehículo  así  que también es un buen punto de partida en el desarrollo de  niveles de automatismos de ayuda a la conducción ( Sistemas ADAS).
En un proyecto anterior de detección de carril  Kemal  había implementado un sistema de detección de carril  que funcionaba decentemente en perfectas condiciones, sin embargo no detectaba curvas carriles con precisión y no era robusta a obstrucciones y sombras, de modo que  esta nueva versión mejora su   primera propuesta puesto que ha implementado  detección de lineas  curvas en los carriles , de modo que   funciona mucho mejor y es más robusto para entornos exigentes.

El sistema de detección de carril ha sido  escrito en Python usando la librería OpenCV y ha seguido resumidamente las siguientes etapas en el  procesamiento de imagen:

  • Corrección de distorsión
  • Deformación de la perspectiva
  • Filtro de Sobel
  • Detección de picos del histograma
  • Búsqueda de ventana deslizante
  • Ajuste de curvas
  • Superposición de carril detectado
  • Aplicar el resultado a  la salida  al vídeo

Respecto al hardware utililizado :

  • Nvidia Jetson TX2×1
  • Raspberry Pi 3 Model B×1

 

 

Corrección de distorsión

Las  lentes de las cámaras distorsionan la luz entrante al  enfocarla en el sensor de la cámara o CCD . Aunque esto es muy útil porque nos permite capturar imágenes de nuestro entorno, a menudo terminan distorsionando la luz ligeramente de forma imprecisa lo cual  puede ofrecernos medidas inexactas en aplicaciones de visión por ordenador . No obstante  fácilmente podemos corregir esta distorsión calibrando la imagen de un objeto conocido ( por ejemplo  tablero de ajedrez asimétrico,)y generando un modelo de distorsión que represente las distorsiones de la lente.

La cámara utilizada en la prueba video  fue utilizada para tomar 20 imágenes de un tablero de ajedrez, que fueron utilizados para generar el modelo de distorsión.El autor comenzó por convertir la imagen a escala de grises y  entonces aplico la  función cv2.findChessboardCorners .Como sabemos que este tablero de ajedrez es un objeto tridimensional  con líneas rectas exclusivamente podemos aplicar algunas transformaciones a las esquinas detectadas para alinearlos correctamente utilizando cv2.CalibrateCamera()  obteniendo así  los coeficientes de distorsión y la matriz de cámara  de modo que  así  ya estaba calibrada la cámara

Realizado el proceso anterior se puede utilizar  cv2.undistort()  para corregir el resto de sus datos de entrada.

Como demostración en la imagen se puede ver la diferencia entre la imagen original del tablero de ajedrez y la imagen corregida a continuación:

ajedrez

Aquí está el código exacto que usó el autor para esto:

def undistort_img():
    # Prepare object points 0,0,0 ... 8,5,0
    obj_pts = np.zeros((6*9,3), np.float32)
    obj_pts[:,:2] = np.mgrid[0:9, 0:6].T.reshape(-1,2)
    # Stores all object points & img points from all images
    objpoints = []
    imgpoints = []
    # Get directory for all calibration images
    images = glob.glob('camera_cal/*.jpg')
    for indx, fname in enumerate(images):
        img = cv2.imread(fname)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        ret, corners = cv2.findChessboardCorners(gray, (9,6), None)
        if ret == True:
            objpoints.append(obj_pts)
            imgpoints.append(corners)
    # Test undistortion on img
    img_size = (img.shape[1], img.shape[0])
    # Calibrate camera
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img_size, None,None)
    dst = cv2.undistort(img, mtx, dist, None, mtx)
    # Save camera calibration for later use
    dist_pickle = {}
    dist_pickle['mtx'] = mtx
    dist_pickle['dist'] = dist
    pickle.dump( dist_pickle, open('camera_cal/cal_pickle.p', 'wb') )
def undistort(img, cal_dir='camera_cal/cal_pickle.p'):
    #cv2.imwrite('camera_cal/test_cal.jpg', dst)
    with open(cal_dir, mode='rb') as f:
        file = pickle.load(f)    mtx = file['mtx']
    dist = file['dist']
    dst = cv2.undistort(img, mtx, dist, None, mtx)
    return dst
undistort_img()
img = cv2.imread('camera_cal/calibration1.jpg')
dst = undistort(img) # Undistorted image

Y ahora podemos ver  la corrección de distorsión aplicada a una imagen de la carretera.

imagencorregida.png

Solo se puede notar  diferencias leves, pero esto como veremos puede tener un impacto enorme en el tratamiento de la imagen.

Deformación de la perspectiva

La detección de carriles con trazados curvas  en espacios de la cámara espacio no es uan tarea  fácil asi que la idea es  conseguir una vista de pájaro de las pistas , lo cual se e puede hacer aplicando una transformación de perspectiva en la imagen. Aquí es lo que parece:

carril

Como vemos nos es nada espectacular debido a que el carril esta sobre una superficie plana en 2D, asi  que podemos encajar un polinomio que puede representar fielmente el carril en el espacio del carril

Puede aplicar estas transformaciones a cualquier imagen usando la función cv2.getPerspectiveTransform()  para obtener la matriz de transformación, y  aplicar la función cv2.warpPerspective() a una imagen.

Aquí está el código que uso el autor para ello:

def perspective_warp(img,
                     dst_size=(1280,720),
                     src=np.float32([(0.43,0.65),(0.58,0.65),(0.1,1),(1,1)]),
                     dst=np.float32([(0,0), (1, 0), (0,1), (1,1)])):
    img_size = np.float32([(img.shape[1],img.shape[0])])
    src = src* img_size
    # For destination points, I'm arbitrarily choosing some points to be
    # a nice fit for displaying our warped result
    # again, not exact, but close enough for our purposes
    dst = dst * np.float32(dst_size)
    # Given src and dst points, calculate the perspective transform matrix
    M = cv2.getPerspectiveTransform(src, dst)
    # Warp the image using OpenCV warpPerspective()
    warped = cv2.warpPerspective(img, M, dst_size)
    return warped

Filtro de Sobel

En otras versiones una opción era filtrar las líneas de carril con el color peor sin embargo, esto no siempre es la mejor opción. Si el camino utiliza luz de color concreta en lugar de asfalto, el camino pasa fácilmente a través del filtro de color, y esta la percibirá como una línea de carril blanco, pero  eso no es correcto.

En su lugar, podemos utilizar un método similar al detector de borde, esta vez para filtrar hacia fuera de la carretera. Las líneas de carril suelen tienen un alto contraste en  la carretera, por lo que podemos utilizar esta peculiaridad para nuestro beneficio. La funcion detector de borde  Canny utilizado anteriormente  hace uso de Operador de Sobel , para obtener el gradiente de una función de la imagen. La documentación de OpenCV tiene una fantástica explicación sobre cómo funciona asi que utilizaremos esto para detectar zonas de alto contraste para las marcas de carril filtro e ignorar el resto del camino .

Todavía utilizaremos el espacio de color HLS nuevamente, esta vez para detectar cambios en la saturación y la ligereza. Los operadores de sobel se aplican a estos dos canales, y extraemos el gradiente con respecto al eje x y añadiremos los píxeles que pasan nuestro umbral de degradado a una matriz binaria que representa a los píxeles de nuestra imagen. Aquí está como se ve en cámara espacio y lane

blancoynegro.PNG:

Tenga en cuenta que las partes de la imagen que estaban más lejos de la cámara no conserven su calidad muy bien. Debido a las limitaciones de resolución de la cámara, datos de los objetos más lejos son muy borrosos y ruidosos  pero no necesitamos concentrarnos en la imagen, para que podamos utilizar sólo una parte de esta.

Detección de picos del histograma

Ahora aplicaremos un algoritmo especial llamado Sliding Window Algorithm ( algo asi como algoritmo  Desplazamiento de Ventana )para detectar nuestras líneas de carril. Sin embargo, antes de que lo podemos aplicar, debemos determinar un buen punto de partida para el algoritmo pues este funciona bien si comienza en un lugar donde haya píxeles de lineas  presentes, pero ¿cómo podemos detectar la ubicación de estos píxeles de carril en primer lugar?

Estará recibiendo un histograma de la imagen con respecto al eje X. Cada parte del histograma siguiente muestra píxeles blancos en cada columna de la imagen. Entonces tomamos los picos más altos de cada lado de la imagen, uno para cada línea de carril y tendríamos resulto esta parte

Aquí vemos como  el histograma parece, al lado de la imagen binaria:

histograma

Búsqueda de ventana deslizante

Ahora  necesitamos  utilizar el algoritmo de ventana deslizante para distinguir entre los límites del carril de la izquierda y derecha para que podemos caber dos curvas diferentes que representan los límites del carril.

El algoritmo sí mismo es muy simple. A partir de la posición inicial, la primera ventana mide cuántos píxeles se encuentran dentro de la ventana. Si la cantidad de píxeles alcanza un cierto umbral, desplaza la siguiente ventana a la posición lateral media de los píxeles detectados. Si no se detectan los suficientes píxeles, comienza la siguiente ventana en la misma posición lateral.

Esto continúa hasta que las ventanas alcanzan el otro borde de la imagen .Asimismo los píxeles que corresponden a las ventanas reciben un marcador.

En las imágenes de abajo, los píxeles marcados azules representan el carril derecho, y los rojos representan la izquierda:

lineas

Ajuste de curvas

El resto del proyecto es ya mas fácil. Aplicamos la regresión polinomial para los pixeles rojos y azules individualmente usando np.polyfit() , y entonces el detector se hace  sobre todo

Esto es lo que parecen las curvas:

 

Superposición de carril detectado

Ya estamos en la parte final del sistema de detección: la interfaz de usuario. Simplemente creamos una superposición que llena en la parte detectada del carril, y luego  finalmente lo aplicamos al vídeo.

Este es el resultado final

 

 

!Sin duda un resultado  realmente espectacular que puede servir de partida para proyectos  mas ambiciosos!

Mas información en www.hackster.io

 

Actualización de un viejo radiocasete


Esta claramente   de moda la reutilización  de electrónica antigua a nuevos tiempos acoplando   uno de los elementos mas versátiles que existen como son los smartphones

En este caso se trata de  conversión de  viejas pletinas analógica   donde se instala un smartphone que también puede ser reciclado o desuso   en el hueco originalmente destinado a la cinta de casete.

Para  dar mas  realismo ,mientras el reproductor está en funcionamiento sobre la pantalla del smartphone se muestra la imagen animada de una cinta de casete en movimiento sobre la que ademas podemos interactuar.

En realidad puede parecer ingenioso la conversión ,  pero el proceso  no es demasiado complejo sobre todo si  no se tiene nostalgia de mantener la parte mecánica del casete pues esta no sera útil  , pero  haciendo por tanto el proceso irreversible

 

 

Cada pletina actualizada con este sistema  está llena de posibilidades:

  •  Reproductor de MP3 y FLAC con simulación de casete animado
  •  Radio Internet
  • Reproductor  de Spotify, Tidal, Deezer, Pandora etc.
  •  Radio FM
  •  Carga y administración de música inalámbrica
  •  Control táctil
  •  Almacenamiento interno para archivos de música

 

En realidad como se comentaba ,los pasos para la conversión no son demasiado complejos:

Paso 1 :Elección de la pletina

El primer paso es encontrar una pletina grabadora que sea adecuada para la modificación y luego imaginar y planificar con precisión el efecto final.

Debido a la construcción sólida y duradera y la simplicidad, las pletinas  mecánicas vintage  con amplificador HIFI  incorporado son una de las  opciones preferidos   pues le daremos una segunda oportunidad  al menos a  la parte de BF y de paso recordaremos tiempos pasados.

Algunas grabadoras no son adecuadas para el procesamiento debido a su diseño mecánico y eléctrico. Las viejas y simples cubiertas vintage con teclas mecánicas son una opción favorita para la conversión .La cubierta destinada a la conversión debe ser eléctricamente funcional. Los circuitos de audio, las entradas / salidas, los medidores de nivel, las regulaciones, los interruptores, etc. deberían funcionar correctamente.

El motor, las correas y los engranajes no son importantes, pueden estar rotos o dañados.

 

Obviamente para poder partir de algo sobre lo que montar el smartphone al menos la parte de BF ( es decir la etapa de audio ) debería funcionar para poder continuar la conversión , aunque si esta parte  no funciona también podemos optar por reemplazar la vieja etapa de audio por un amplificador clase D ya montado, pues no ocupan nada de espacio y son realmente económicos .

 

 

Paso 2 Software

El corazón del sistema es un teléfono inteligente con pantalla táctil con software dedicado.

El teléfono debe estar equipado con suficiente memoria incorporada   a ser posible con una tarjeta de memoria adicional para almacenar música.

Es ademas necesario  un cargador adecuado  y  cables de audio de jack de 2 1/2″ stereo a dos conectores macho RCA

En cuanto al software  el abanico es inmenso,como pueden ser Casse-o-player, Cassete Tapes, Easy Music Player, etc

Uno de los mas realistas es Delitape   una app nº 1 para iPhone ahora disponible también para Android. Esta app  rememora el sentimiento de los viejos tiempos y convierte cualquier smartphone moderno en un walkman clásico

 

cintas

Esta app vintage de musica le devuelve a los viejos tiempos. Deslízese por las cintas más elegantes, hechas con pasión por los detalles. Durante la reproducción de los temas, la app simula la forma en que se reproducían las cintas de antes.

Esta app ademas tiene  Soporte de radio de Internet con más de 1000 de las mejores estaciones de radio del mundo web!

Otro app necesaria es Airdroid   pues esta app permite acceder y manejar su teléfono o tableta Android desde Windows, Mac o la web, sin cables, y de forma gratuita.

Cada platina sin cinta ofrece muchas posibilidades: reproductor MP3 / FLAC con animación de cassette, radio por Internet y radio FM (algunos modelos). Si lo desea, puede instalar cualquier aplicación de Android, por ejemplo, su servicio favorito de transmisión de música: Tidal, Spotify, Dezeer, Pandora … o lo que sea que necesite.

 

Paso 3 Montaje

Es hora de ensamblar y combinar componentes, incluidos trabajos mecánicos de precisión .

Lo más difícil es poner el teléfono inteligente en el compartimiento del casete  sin romper nada lo cual necesitara grandes dosis de paciencia  e ingenio

Durante el procesamiento, muchas partes mecánicas se eliminan para siempre, por lo que ya no podrá usar las casetes siendo la conversión irreversible.

Respecto a la electrónica , debemos conectar con cable estero apantallado  desde un jack macho stereo de 2 1/2″ hacia la entrada de auxiliar de la pletina ( bien con conectores RCA o bien soldando a la placa de BF).

Obviamente tampoco debemos olvidarnos de alimentar  al smartphone por lo  que situaremos el cargador en el interior de la pletina tomando  la alimentación de ca directamente desde esta (por ejemplo a la salida de interruptor mecánico de power que este tipo de equipos llevan)

La batería se cargara automáticamente cuando se encienda la plataforma. Si no usa la plataforma durante un período prolongado, recuerde apagar el teléfono para evitar descargar la batería por completo. En caso de que la batería esté descargada, simplemente encienda la plataforma y espere un momento hasta que el teléfono muestre signos de vida. Luego encienda el teléfono nuevamente.

Para  operar el teléfono dentro de la plataforma se hará al igual que un teléfono estándar, con una excepción, ya que el teléfono está integrado en la plataforma y el conmutador de encendido / apagado es de difícil acceso, por lo que  lo  “correcto” seria  conectarlo  eléctrica mente a una de las teclas de la plataforma y así funcionaria de la misma manera que el original.

El resultado como se podía  esperar  es bastante impresionante  dependiendo mucho de como seamos capaces de disimular el smartphone dentro de la pletina :

 

Finalmente, el dispositivo se ve y actúa como una platina de cinta real, que incluye una fascinante animación de casete, medidores de nivel de trabajo, señal de salida ajustable, etc. Hermosa pieza de artesanía hecha a mano. Además, cada TapeLess Deck MP3 es un dispositivo único y artesanal, el único en el mundo.

 

Paso 4: Subir y administrar música…

Para preparar  el smartphone , conecte  el  WiFi del smartphone e inicie sesión en su red doméstica. Recuerde que sin cubierta y ordenador  deben trabajar en la misma red.
 
Haga clic en el icono de AirDroid y espere pacientemente a la siguiente pantalla. En el primer uso toma algún tiempo…
Encuentre y haga clic en el icono azul de la AirDroid Web. A veces puede ser cubierto por los anuncios, así que mire con atención…
Espere al respuesta del servidor y escriba dado la dirección exactamente para el navegador de su ordenador.
Vaya a su ordenador  e introduzca  la url citada en un navegador .Ahora verá una página web generada por AirDroid. Contiene algunas informaciones útiles acerca de los teléfonos sin cubierta, como memoria disponible o estado de la batería y mucho mas
 
Haga clic en el icono de archivos y localize la carpeta MUSIC en la tarjeta SD o tarjeta SD externa (dependiendo de la configuración del teléfono). Es el momento para cargar música del ordenador a la memoria del smartphone:Abra la carpeta con la música en su ordenador  seleccione los archivos y sólo tiene que arrastrar a la! Ventana _MUSIC. Espere a que la transferencia hasta el final.

 

 

 

Por cierto esta idea se puede extender no solo a una pletina hifi, también  radiocasete , equipos compactos , etc ¿tiene alguno  de estas viejas leyendas en el trastero  y no sabe que hacer con estas pues con un viejo smartphone le puede dar otra nueva vida?

 

 

Fuente  http://www.mp3tapelessdeck.pl/

Datalogger de posicionamiento con Raspberry Pi y Azure


CÓDIGO

AzureIoTRegistryManagerApp C #
Este es el código de acceso y gestión Azure Registro Hub IO, haciendo uso de la clase RegistryManager.
////The MIT License(MIT)
////Copyright(c) 2016 BardaanA

////Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

////The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

////THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Threading.Tasks;

// These are the Microsoft's recommended libraries to access
// and make changes to Azure IoT Hub's Registry
using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Common.Exceptions;

// This namespace which also dictates the name of the Assembly can be anything you desire.
namespace AzureIoTRegistryManagerApp
{
    class Program
    {
        // RegistryManager object which is going to do most of the work for our application
        static RegistryManager registryManager;
        // This here is the Connection String that you copied from the IoT Hub Shared Access Policies > iothubowner > Shared access keys; remember??
        static string connectionString = "Don't forget to replace this with your own connection string";
        // Keeps track of the registry access status
        static string registryAccessStatus = "";

        static void Main(string[] args)
        {
            try
            {
                // Let's try and create a Registry Manager using our connection string, shall we?
                registryManager = RegistryManager.CreateFromConnectionString(connectionString);
                registryAccessStatus = "Successfuly connected to the IoT Hub registry"; // Yay!
            }
            catch(Exception ex)
            {
                Console.WriteLine("Registry access failed!  {0}",ex.Message);  // Bummer!!
            }
            // Check if RegistryManager was created successfully
            if(registryManager != null)
            {
                Console.WriteLine("*****************************************************");
                Console.WriteLine("===== Welcome to the Azure IoT Registry Manager =====");
                Console.WriteLine();
                Console.WriteLine("++ {0} ++",registryAccessStatus);
                Console.WriteLine();
                int menuSelection = 0;
                while(menuSelection != 3)  // Loop to keep you going...
                {
                    Console.WriteLine("  1) Add device into registry");
                    Console.WriteLine("  2) Remove device from the registry");
                    Console.WriteLine("  3) Close this application");
                    Console.WriteLine("------------------------------------");
                    Console.Write("Enter your selection: ");
                    menuSelection = int.Parse(Console.ReadLine());
                    Console.WriteLine();
                    switch(menuSelection)
                    {
                        case 1:
                            Console.Write("Enter device name that you want to register: ");
                            string deviceName = Console.ReadLine();
                            Console.WriteLine();
                            if(deviceName.Length > 0 && !deviceName.Contains(" "))  // Weak validation :)
                            {
                                // Calling method that actually adds the device into the registry
                                AddDevice(deviceName).Wait();
                            }
                            else
                            {
                                Console.WriteLine("---");
                                Console.WriteLine("Enter valid name!");
                                Console.WriteLine("---");
                            }
                            break;
                        case 2:
                            Console.Write("Enter name of the device to be removed: ");
                            string deviceRemoveName = Console.ReadLine();
                            Console.WriteLine();
                            if(deviceRemoveName.Length > 0 && !deviceRemoveName.Contains(" "))  // Weak validation :(
                            {
                                // Calling method that actually removes the device from the registry
                                RemoveDevice(deviceRemoveName).Wait();
                            }
                            else
                            {
                                Console.WriteLine("---");
                                Console.WriteLine("Enter valid name!");
                                Console.WriteLine("---");
                            }
                            break;
                        case 3:
                            // Breaks out of the loop
                            break;
                        default:
                            Console.WriteLine("---");
                            Console.WriteLine("Choose valid entry!");
                            Console.WriteLine("---");
                            break;
                    }
                }
                // Closes the RegistryManager access right before exiting the application
                registryManager.CloseAsync().Wait();
            }
        }

        // Method used to add device into the Registry, takes in a string as a parameter
        private static async Task AddDevice(string deviceId)
        {
            // A Device object
            Device device;
            try
            {
                // Lets try and create a Device into the Device Registry
                device = await registryManager.AddDeviceAsync(new Device(deviceId));
                if(device != null)
                {
                    Console.WriteLine("Device: {0} added successfully!",deviceId); // Hooray!
                }
            }
            catch(DeviceAlreadyExistsException)  // What?
            {
                Console.WriteLine("---");
                Console.WriteLine("This device has already been registered...");// When did I do that??
                Console.WriteLine("---");
                device = await registryManager.GetDeviceAsync(deviceId);
            }
            Console.WriteLine();
            Console.WriteLine("Generated device key: {0}",device.Authentication.SymmetricKey.PrimaryKey);  // Now you're talking!
            Console.WriteLine();
        }

        // Method used to remove a device from the Device Registry, takes a string as a parameter
        private static async Task RemoveDevice(string deviceId)
        {
            try
            {
                // Lets try and get rid of the Device from our registry, using the device id.
                await registryManager.RemoveDeviceAsync(deviceId);
                Console.WriteLine("Device: {0} removed successfully!",deviceId);  // Yup!
            }
            catch(DeviceNotFoundException)
            {
                Console.WriteLine("---");
                Console.WriteLine("This device has not been registered into this registry!");  // Are you sure??
                Console.WriteLine("---");
            }
        }
    }
}

Fuente aqui

Controle su Roomba con Arduino y Android


 

iRobot Roomba Create2 es una a  plataforma grande y muy asequible para el desarrollo de la robótica, costando alrededor de US$ 200 permitiendo  una variedad de métodos de programación. Como  comienzo mjrovi usó  un Arduino y una aplicación Android para mover el robot  por puerto serie  consiguiendo asi controlar  sus motores, LEDS y sonido.

Como uno de los ganadores de 2016 del concurso de robótica   en Instructables, mjrovi recibió como premio un iRobot Roomba Create2.

 

 

La Roomba es un robot de impulsión diferenciada, con 2 ruedas motrices y una rueda  central  guía. Su velocidad va hasta 500 mm/s y puede ser mandado a ir hacia arriba o hacia atrás.
Para señalización, contamos con cuatro 7 segmentos display y 5 LEDs :

  • Limpiar
  • Punto
  • Muelle
  • ADVERTENCIA/Check
  • Suciedad/escombros

Como sensores internos, tenemos entre otros:

  • Detector de acantilado (4 en el frente)
  • Detectores Bump (frente 2)
  • Codificadores de rueda

Para la programación, el documento: iRobot® Create® 2 abierto interfaz (OI) debe ser utilizado.El Roomba puede ser programado en 3 modos:

  1. Modo pasivo:Al enviar el comando de Start o cualquiera de los comandos de modo de limpieza (por ejemplo, punto limpio, muelle buscar), la OI entra en modo pasivo. Cuando la OI está en modo pasivo, puede solicitar y recibir datos de los sensores usando cualquiera de los comandos del sensor, pero no puede cambiar los parámetros de comando actuales para los actuadores (motores, altavoces, luces, controladores de lado de baja, salidas digitales) a otra cosa.
  2. Modo seguro :Le da un control completo de Roomba, con excepción de las siguientes condiciones relacionadas con la seguridad:
    Cargador conectado y alimentado:detección de una caída de rueda (en cualquier rueda),detección de un acantilado mientras se mueve hacia adelante (o hacia atrás con un pequeño radio de torneado, menos de un radio de robot) o si ocurre una de las condiciones relacionadas con la seguridad mientras que el OI es en modo seguro, Roomba detiene todos los motores y vuelve al modo pasivo.
  3. Modo completo:Le da un control completo sobre Roomba, todos de sus actuadores y todas las condiciones relacionadas con la seguridad que están restringidas cuando la OI en modo seguro, como el modo completo se apaga el acantilado, caída de rueda y características de seguridad cargador interno.

Comunicaciones

Para  programar la Romba  la lista de  materiales  usada es la siguiente:

  • iRobot Create2
  • Arduino UNO
  • Módulo Bluetooth HC-06
  • Pulsador

Para la comunicación entre la Roomba y Arduino, se utilizará el puerto Serial. Por defecto, Roomba comunica a 115.200 baudios, pero para comunicarse con Arduino, se cambiará a 19.200.

Hay 2 formas de establecer la tasa de baudios de Roomba:

  1. Mientras que apagar Roomba, continúan mantenga pulsado el botón de encendido o limpiar después de que la luz se ha apagado. Después de unos 10 segundos, Roomba juega una melodía descendente de las echadas. Roomba se comunicará a 19.200 baudios hasta que el procesador pierde energía de la batería o la tasa de baudios se modifica explícitamente a través de la OI.
  2. Utilizar el pin de cambio de tasa de baudios (pin 5 del conector mini-DIN) para cambiar la velocidad en baudios de Roomba. Después de encender la Roomba, esperar 2 segundos y luego pulso el cambio de la tasa de baudios baja tres veces. Cada impulso debe durar entre 50 y 500 milisegundos. Roomba se comunicará a 19200 baudios hasta que el procesador pierde energía de la batería o la tasa de baudios se modifica explícitamente a través de la OI.

 

El diagrama de arriba muestra cómo la Arduino debe conectarse al conector mini-DIN de Roomba

 

 

Lo primero creo que debe hacerse cuando un Roomba de programación es “Despertar” el robot y  Definir el modo (segura o completa)

Nosotros podemos  hacer  un “wake-up”, enviar un poco de pulso al pin mini-DIN 5 (detección de dispositivo de entrada) como se muestra en la siguiente función:
void wakeUp (void)
{
setWarningLED(ON);
digitalWrite(ddPin, HIGH);
delay(100);
digitalWrite(ddPin, LOW);
delay(500);
digitalWrite(ddPin, HIGH);
delay(2000);
}

Para empezar a Roomba deberán enviarse 2 códigos de siempre: «START» [128] y el modo, en nuestro caso “Modo seguro” [131]. Si usted quiere un “modo completo”, debe enviarse en su lugar el código [132].
void startSafe()
{
Roomba.write(128); //Start
Roomba.write(131); //Safe mode
delay(1000);
}

 

Como se describe en la introducción, el Roomba tiene 5 LEDs:

  • Energía/limpiar (bicolor rojo/verde e intensidad controladas)
  • Punto (verde, intensidad fija)
  • Muelle (verde, intensidad fija)
  • ADVERTENCIA/Check (naranja, intensidad fija)
  • Suciedad/escombros (azul, fija la intensidad)

 

Control de leds

Todos los LEDs pueden ser ordenados mediante código [139]
Para controlar el LED de encendido, debe enviar dos bytes de datos a Roomba: “color” y la “intensidad”.
Color:

  • Verde = 0
  • Naranja = 128
  • rojo = 255

Intensidad:

  • Bajo = 0
  • Max = 255

La función setPowerLED (colores bytes, setIntensity bytes) lo hace:

void setPowerLED(byte setColor, byte setIntensity)
{
color = setColor;
intensity = setIntensity;
Roomba.write(139);
Roomba.write((byte)0x00);
Roomba.write((byte)color);
Roomba.write((byte)intensity);
}

Por ejemplo, para encender el LED de POWER de color naranja en la mitad de su intensidad, usted puede llamar a la función como bramido:setPowerLED (128, 128);

Encender los 4 LEDs restantes, deberán utilizarse las siguientes funciones:
setDebrisLED(ON);
setDockLED(ON);
setSpotLED(ON);
setWarningLED(ON);

Todas las funciones anteriores tiene un código similar a este:
void setDebrisLED(bool enable)
{
debrisLED = enable;
Roomba.write(139);
Roomba.write((debrisLED ? 1 : 0) + (spotLED ? 2 : 0) + (dockLED ? 4 : 0) + (warningLED ? 8 : 0));
Roomba.write((byte)color);
Roomba.write((byte)intensity);
}

Básicamente, la diferencia será la línea: debrisLED = habilitar;  debe modificarse permitiendo a cada uno de los otros LEDs (spotLED, dockLED, warningLED).

 

Envío de mensajes

Roomba tiene cuatro 4 displays de 7 segmentos que puede utilizar para enviar mensajes de dos maneras::
[163] código: Dígitos LED crudo (numérico)
[164] código: Dígitos LED de ASCII (aproximación de letras y códigos especiales)
Para mostrar números  debe enviar el código [163], siguiendo las 4 digitas a mostrar. La función: setDigitLEDs (bytes digit1 digit2 bytes, digit3 bytes, digit4 bytes) lo hace para usted:

void setDigitLEDs(byte digit1, byte digit2, byte digit3, byte digit4)
{
Roomba.write(163);
Roomba.write(digit1);
Roomba.write(digit2);
Roomba.write(digit3);
Roomba.write(digit4);
}

Por ejemplo, para mostrar “1, 2, 3, 4”, debe llamar a la función: setDigitLEDs (1, 2, 3, 4);

Con el código [164], es posible enviar aproximación de ASCII.

La función setDigitLEDFromASCII (dígitos de byte, char letra) hace esto para nosotros:
void setDigitLEDFromASCII(byte digit, char letter)
{
switch (digit){
case 1:
digit1 = letter;
break;
case 2:
digit2 = letter;
break;
case 3:
digit3 = letter;
break;
case 4:
digit4 = letter;
break;
}
Roomba.write(164);
Roomba.write(digit1);
Roomba.write(digit2);
Roomba.write(digit3);
Roomba.write(digit4);
}

Para simplificar, crear una nueva función para enviar los 4 dígitos al mismo tiempo:
void writeLEDs (char a, char b, char c, char d)
{
setDigitLEDFromASCII(1, a);
setDigitLEDFromASCII(2, b);
setDigitLEDFromASCII(3, c);
setDigitLEDFromASCII(4, d);
}

Por ejemplo, para mostrar “STOP”, usted debe llamar a la función: writeLEDs (‘s’, ‘ t ‘, ‘ o ‘, ‘p’);

Mover la  Roomba

Para la movilidad, Roomba tiene 2 motores independientes que pueden programarse para ejecutar 500mm/s. Hay varios comandos que pueden utilizarse para controlar el robot. Los principales son:

  • Código [137]: Unidad == > debe enviar +-velocidad en mm/s y +-radio en mm
  • Codigo [145] de código: Impulsión directa == > debe enviar izquierda velocidad en mm/s (+ para adelante y para atrás)
  • Código [146]: Unidad PWM == > debe enviar +-datos PWM para la izquierda y derecha las ruedas

 

A continuación el código para estas 3 opciones:

void drive(int velocity, int radius)
{
clamp(velocity, -500, 500); //def max and min velocity in mm/s
clamp(radius, -2000, 2000); //def max and min radius in mm

Roomba.write(137);
Roomba.write(velocity >> 8);
Roomba.write(velocity);
Roomba.write(radius >> 8);
Roomba.write(radius);
}

//—————————————————————

void driveWheels(int right, int left)
{
clamp(right, -500, 500);
clamp(left, -500, 500);

Roomba.write(145);
Roomba.write(right >> 8);
Roomba.write(right);
Roomba.write(left >> 8);
Roomba.write(left);
}

//—————————————————————
void driveWheelsPWM(int rightPWM, int leftPWM)
{
clamp(rightPWM, -255, 255);
clamp(leftPWM, -255, 255);

Roomba.write(146);
Roomba.write(rightPWM >> 8);
Roomba.write(rightPWM);
Roomba.write(leftPWM >> 8);
Roomba.write(leftPWM);
}

Tenga en cuenta que la función de “fijar” define los valores máximos y mínimos que se permitieron la entrada. Esta función se define en el archivo rombaDefines.h:

#define abrazadera (valor, min, max) (valor < min? min: valor > max? max: valor)
Utilizando el código anterior, se pueden crear funciones más simples para Roomba alrededor de:
/—————————————————————
void turnCW(unsigned short velocity, unsigned short degrees)
{
drive(velocity, -1);
clamp(velocity, 0, 500);
delay(6600);
drive(0,0);
}

//—————————————————————
void turnCCW(unsigned short velocity, unsigned short degrees)
{
drive(velocity, 1);
clamp(velocity, 0, 500);
delay(6600);
drive(0,0);
}

//—————————————————————
void driveStop(void)
{
drive(0,0);
}

//—————————————————————
void driveLeft(int left)
{
driveWheels(left, 0);
}

//—————————————————————
void driveRight(int right)
{
driveWheels(0, right);
}

Tenga en cuenta que para girar en ángulo, debe calcularse el argumento de “retraso” específicamente para una velocidad dada

A continuación algunos ejemplos que pueden utilizar para probar los motores:

turnCW (40, 180); girar 180 grados hacia la derecha y parada
driveWheels (20, -20); vuelta
driveLeft(20); girar a la izquierda

Para las pruebas de los motores, es bueno añadir un pulsador externo (en mi caso conectado al Arduino pin 12), para que puedan descargar el código de Arduino, a partir de la Roomba, pero parando la ejecución hasta que se pulsa la tecla. Generalmente, para los motores de prueba lo puedes hacer en la parte de configuración del código.

Como ejemplo, consulte el código de Arduino simple abajo (nota que el código usa funciones y definiciones desarrollaron antes):

#include “roombaDefines.h”
#include

// Roomba Create2 connection
int rxPin=10;
int txPin=11;
SoftwareSerial Roomba(rxPin,txPin);

//———————————————
void setup()
{
Roomba.begin(19200);

pinMode(ddPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // connected to Arduino pin 12 and used for “starting”

delay(2000);

wakeUp (); // Wake-up Roomba
startSafe(); // Start Roomba in Safe Mode

while (digitalRead(buttonPin)) { } // wait button to be pressed to continous run code

turnCW (40, 180); //test Roomba spin clock-wise 180 degrees and stop
}

//———————————————
void loop()
{

}

 

Controlar la Roomba a través de Bluetooth

Para controlar  Roomba de modo inalambrico   vamos a instalar un módulo Bluetooth (HC-06) a nuestro Arduino. El diagrama de arriba muestra cómo hacerlo. Suele ser el HC-06 settle up de fábrica con una velocidad de 9.600. Es importante cambiarlo a 19.200 para ser compatible con la velocidad de la comunicación de Arduino-Roomba. Usted puede hacer que el envío un comando AT para el módulo (AT + BAUD5 donde “5” es el código de 19.200).

Para controlar la Roomba, utilizaremos una aplicación genérica que fue desarrollada por jrovai   para el control de robots móviles, con el MIT AppInventor 2: “MJRoBot BT Remote Control”. La aplicación puede descargarse gratuitamente de la tienda de Google a través del enlace: aplicación: MJRoBot BT Remote Control.

La aplicación tiene una interfaz sencilla, lo que le permite enviar comandos al módulo de BT en ambos, modo de texto o directamente a través de botones preprogramados (cada vez que se pulsa un botón, un carácter se envía):

  • w: hacia adeñante
  • S: hacia atras
  • d: derecho
  • a: izquierda
  • f: parada
  • p: ON / OFF (no usado en esta primera parte)
  • m: manual / automático (se utiliza para reiniciar Roomba si un obstáculo como un acantilado se encuentra en modo seguro)
  • +: Velocidad +
  • -: Velocidad –

También puede enviar otros comandos como texto si es necesario. También hay una ventana de texto para los mensajes recibidos desde el módulo de BT. Esta característica es muy importante durante la fase de prueba, puede ser utilizado en la misma forma que el “Serial Monitor”.

El loop() parte del código será “escuchando” el dispositivo bluetooth y dependiendo del comando recibido, tomar una acción:

void loop()
{
checkBTcmd(); // verify if a comand is received from BT remote control
manualCmd ();
}
La función checkBTcmd() se muestra a continuación:

void checkBTcmd() // verify if a command is received from BT remote control
{
if (BT1.available())
{
command = BT1.read();
BT1.flush();
}
}
Una vez que se recibe un comando, la función manualCmd() tomará la acción apropiada:
void manualCmd()
{
switch (command)
{

case ‘m’:
startSafe();
Serial.print(“Roomba in Safe mode”);
BT1.print(“Roomba BT Ctrl OK – Safe mode”);
BT1.println(‘\n’);
command = ‘f’;
playSound (3);
break;

case ‘f’:
driveStop(); //turn off both motors
writeLEDs (‘s’, ‘t’, ‘o’, ‘p’);
state = command;
break;

case ‘w’:
drive (motorSpeed, 0);
writeLEDs (‘ ‘, ‘g’, ‘o’, ‘ ‘);
state = command;
break;

case ‘d’:
driveRight(motorSpeed);
writeLEDs (‘r’, ‘i’, ‘g’, ‘h’);
break;

case ‘a’:
driveLeft(motorSpeed);
writeLEDs (‘l’, ‘e’, ‘f’, ‘t’);
break;

case ‘s’:
drive (-motorSpeed, 0);
writeLEDs (‘b’, ‘a’, ‘c’, ‘k’);
state = command;
break;

case ‘+’:
if (state == ‘w’)
{
motorSpeed = motorSpeed + 10;
if (motorSpeed > MAX_SPEED)
{
motorSpeed = MAX_SPEED;
}
command = ‘w’;
} else {command = state;}
break;

case ‘-‘:

if (state == ‘w’)
{
motorSpeed = motorSpeed – 10;
}
if (motorSpeed < MIN_SPEED )

{ motorSpeed = MIN_SPEED; }

Serial.println(motorSpeed); command = state; break; } }

 

 

 

El código de Arduino completo utilizado en documentos aquí relacionados se puede encontrar en GITHUB en https://github.com/Mjrovai/Roomba_BT_Ctrl

Varias de las funciones que   el autor  ha creado en su  programa se basaron en la biblioteca de crear 2 desarrollada por Dom Amato. Puede descargar la librería completa en‎: https://github.com/brinnLabs/Create2.

A %d blogueros les gusta esto: