Translate

sábado, 8 de noviembre de 2014

Sistema Solar.


Como nació el proyecto.

El día lunes mi hijo de 7 años nos pidió a mi esposa y a mi que le ayudáramos con su proyecto del sistema solar, como calificarían la creatividad nos pidió que llevará luces la verdad en lo primero que pensé fue en usar un PICMicro de Microchip; pero como el proyecto era a entregar en 2 días y con mis horarios de trabajo no me iba a alcanzar el tiempo. Por esa razón voltee a ver una de mis Raspberry Pi, sabía que me iban a sacar a flote con esto.


Materiales:


  • 9 esferas de unicel para los planetas.
  • 1 pelota de plástico transparente para el Sol.
  • Celofan para amarillo para las llamas del Sol.
  • 1 Raspberry Pi con soporte para python-gpio.
  • 1 caja para transportar la maqueta.
  • 1 Resistencia de 10K.
  • 10 LEDS de diferentes colores.
  • Varios palillos de madera.
  • Cable y cinta de asilar.


Pasos a Seguir:

Pintar las esferas con los colores deseados de los planetas.

Una vez que las esferas de unicel estén secas, un adulto deberá cortar las esferas por la mitad y rascar el unicel para que las mismas queden huecas. como se muestra en la siguiente imagen(repetir el proceso con todas las esferas).



Una vez que la esfera este hueca se deberá insertar el LED deseado para cada planeta.






Soldar un par de cables al LED(asegurarse de diferenciar el ánodo del cátodo con los cables, la patilla larga es el positivo y la patilla corta es el negativo). Con cuidado pegar la otra parte de la esfera con silicon.

Para el Sol pegar el celofan sobre la pelota transparente y posteriormente insertar un LED dentro de la pelota.

Construir una base para el sistema con los palillos de madera. mi esposa ha creado una similar a esta imagen.



Dando como resultado:



Conexión a la Raspberry Pi.

La distribución de los planetas con respecto a las entradas de la tarjeta quedó así:

Planeta BCM GPIO LED COLOR
Mercurio GPIO4 Blanco
Venus GPIO17 Amarillo
Tierra GPIO21 Azul
Marte GPIO22 Rojo
Jupiter GPIO18 Amarillo
Saturno GPIO23 Amarillo
Urano GPIO24 Azul
Neptuno GPIO25 Azul
Switch GPIO0



La conexión de los leds respetando el GPIO asignado es similar a:



El Switch será conectado en el GPIO0 que es usado como SDA de modo que tendremos que disparar el evento con un 0 lógico, ya que SDA tiene un Pull-Up desde el hardware.




Teniendo como resultado:



El Programa.

Para crear el programa he usado Python junto con la librería python-rpi.gpio. Realmente el programa no está optimizado pero tomando en cuenta que lo hicimos en una tarde no me puedo quejar mucho.


#!/usr/bin/env python

#importing libraries
from time import sleep
import os
import RPi.GPIO as GPIO

#setting mode to BCM GPIO
GPIO.setmode(GPIO.BCM)

#SDA as INPUT
GPIO.setup(0,GPIO.IN)

#ALL GPIO as OUTPUT
GPIO.setup(4, GPIO.OUT)
GPIO.setup(17, GPIO.OUT)
GPIO.setup(21, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)
GPIO.setup(18, GPIO.OUT)
GPIO.setup(23, GPIO.OUT)
GPIO.setup(24, GPIO.OUT)
GPIO.setup(25, GPIO.OUT)

#Cleanning all OUTPUTS
GPIO.output(4, GPIO.LOW)
GPIO.output(17, GPIO.LOW)
GPIO.output(21, GPIO.LOW)
GPIO.output(22, GPIO.LOW)
GPIO.output(18, GPIO.LOW)
GPIO.output(23, GPIO.LOW)
GPIO.output(24, GPIO.LOW)
GPIO.output(25, GPIO.LOW)

#A blink for saying a live ah-ah staying a live
GPIO.output(4, GPIO.HIGH)
sleep(1)
GPIO.output(4, GPIO.LOW)
sleep(1)
GPIO.output(4, GPIO.HIGH)
sleep(1)
GPIO.output(4, GPIO.LOW)
sleep(1)

#creating the pwm handlers for each planet
mercurio = GPIO.PWM(4, 50)
venus    = GPIO.PWM(17, 50)
tierra   = GPIO.PWM(21, 50)
marte    = GPIO.PWM(22, 50)
jupiter  = GPIO.PWM(18, 50)
saturno  = GPIO.PWM(23, 50)
urano    = GPIO.PWM(24, 50)
neptuno  = GPIO.PWM(25, 50)

#Looping
while True:
        #Start the loop when press the button
        if ( GPIO.input(0) == False ):
         for i in range(0 ,2):
                mercurio.start(10)
                sleep(.5)
                mercurio.ChangeDutyCycle(10)
                sleep(.5)
                mercurio.ChangeDutyCycle(30)
                sleep(.5)
                mercurio.ChangeDutyCycle(40)
                sleep(.5)
                mercurio.ChangeDutyCycle(50)
                sleep(.5)
                mercurio.ChangeDutyCycle(70)
                sleep(.5)
                mercurio.ChangeDutyCycle(100)
                sleep(3)
                mercurio.stop()


                venus.start(10)
                sleep(.5)
                venus.ChangeDutyCycle(20)
                sleep(.5)
                venus.ChangeDutyCycle(30)
                sleep(.5)
                venus.ChangeDutyCycle(40)
                sleep(.5)
                venus.ChangeDutyCycle(50)
                sleep(.5)
                venus.ChangeDutyCycle(70)
                sleep(.5)
                venus.ChangeDutyCycle(100)
                sleep(3)
                venus.stop()

                tierra.start(10)
                sleep(.5)
                tierra.ChangeDutyCycle(20)
                sleep(.5)
                tierra.ChangeDutyCycle(30)
                sleep(.5)
                tierra.ChangeDutyCycle(40)
                sleep(.5)
                tierra.ChangeDutyCycle(50)
                sleep(.5)
                tierra.ChangeDutyCycle(70)
                sleep(.5)
                tierra.ChangeDutyCycle(100)
                sleep(3)
                tierra.stop()

                marte.start(10)
                sleep(.5)
                marte.ChangeDutyCycle(20)
                sleep(.5)
                marte.ChangeDutyCycle(30)
                sleep(.5)
                marte.ChangeDutyCycle(40)
                sleep(.5)
                marte.ChangeDutyCycle(50)
                sleep(.5)
                marte.ChangeDutyCycle(70)
                sleep(.5)
                marte.ChangeDutyCycle(100)
                sleep(3)
                marte.stop()

                jupiter.start(10)
                sleep(.5)
                jupiter.ChangeDutyCycle(20)
                sleep(.5)
                jupiter.ChangeDutyCycle(30)
                sleep(.5)
                jupiter.ChangeDutyCycle(40)
                sleep(.5)
                jupiter.ChangeDutyCycle(50)
                sleep(.5)
                jupiter.ChangeDutyCycle(70)
                sleep(.5)
                jupiter.ChangeDutyCycle(100)
                sleep(3)
                jupiter.stop()

                saturno.start(10)
                sleep(.5)
                saturno.ChangeDutyCycle(20)
                sleep(.5)
                saturno.ChangeDutyCycle(30)
                sleep(.5)
                saturno.ChangeDutyCycle(40)
                sleep(.5)
                saturno.ChangeDutyCycle(50)
                sleep(.5)
                saturno.ChangeDutyCycle(70)
                sleep(.5)
                saturno.ChangeDutyCycle(100)
                sleep(3)
                saturno.stop()

                urano.start(10)
                sleep(.5)
                urano.ChangeDutyCycle(20)
                sleep(.5)
                urano.ChangeDutyCycle(30)
                sleep(.5)
                urano.ChangeDutyCycle(40)
                sleep(.5)
                urano.ChangeDutyCycle(50)
                sleep(.5)
                urano.ChangeDutyCycle(70)
                sleep(.5)
                urano.ChangeDutyCycle(100)
                sleep(3)
                urano.stop()

                neptuno.start(10)
                sleep(.5)
                neptuno.ChangeDutyCycle(20)
                sleep(.5)
                neptuno.ChangeDutyCycle(30)
                sleep(.5)
                neptuno.ChangeDutyCycle(40)
                sleep(.5)
                neptuno.ChangeDutyCycle(50)
                sleep(.5)
                neptuno.ChangeDutyCycle(70)
                sleep(.5)
                neptuno.ChangeDutyCycle(100)
                sleep(3)
                neptuno.stop()


                GPIO.output(4, GPIO.HIGH)
                GPIO.output(17, GPIO.HIGH)
                GPIO.output(21, GPIO.HIGH)
                GPIO.output(22, GPIO.HIGH)
                GPIO.output(18, GPIO.HIGH)
                GPIO.output(23, GPIO.HIGH)
                GPIO.output(24, GPIO.HIGH)
                GPIO.output(25, GPIO.HIGH)

                sleep(3)

                GPIO.output(4, GPIO.LOW)
                GPIO.output(17, GPIO.LOW)
                GPIO.output(21, GPIO.LOW)
                GPIO.output(22, GPIO.LOW)
                GPIO.output(18, GPIO.LOW)
                GPIO.output(23, GPIO.LOW)
                GPIO.output(24, GPIO.LOW)
                GPIO.output(25, GPIO.LOW)

#GPIO.cleanup()



Para ejecutar el script al arranque de la Raspberry añadí el script anterior a /etc/rc.local y después de que mercurio hace blink se entra en el loop que espera a que el boton envíe la rutina de PWM a los planetas.

Siendo sincero el programa se puede optimizar mucho creando funciones pero quedará para la próxima.


Mejoras:

  • Optimizar el código para usar funciones y no taanto código.
  • Si se fijan en el código se cuenta con la línea import os. La idea original era añadir audio al sistema pero como no alcanzó el tiempo no pude hacerlo funcionar pero la idea es agregar un sonido a cada planeta con un comando similar a: os.system('mpg321 intro-planet &')
  • Hacerlo Rotar, se'ria genial crear una base giratoria para que todo se mueva.
  • Finalmente la idea es que mi Hijo comience a usar Scratch GPIO para que él pueda hacerlo solo.


El Vídeo.


video








domingo, 2 de marzo de 2014

Añadiendo un ADC a la Raspberry Pi

Se me encargó medir voltaje con la Raspberry Pi, así que como todo en san google uno encuentra mucha información así que dí con está página que muestra como usar un conversor analogo-digital SPI con la RPi de la tienda http://www.abelectronics.co.uk/

En el enlace anterior usan el integrado MCP3002 y en la web encontrarán miles de ejemplos para el MCP3008 como vivo en pueblo quieto lo único que pude conseguir en la ciudad fue un MCP3202 la única diferencia es que solo tiene 2 canales y que este sensor tiene una resolución de 12Bits, es decir, los valores obtenidos en decimal iràn de 0 a 4095.

Y bueno aquí les dejo los pasos para habilitar el soporte SPI en la Raspberry Pi, el programa(obtenido del enlace anterior) el circuito y unas capturas de prueba.

Background.

Este ADC para la Raspberry Pi esta basado en el chip MCP3202 de Microchip. Es un ADC de 12 bits
de resolución y se comunica vía SPI.

Como la Raspberry Pi usa 3.3v se usa un divisor de tensión para bajar 10V a 3.3V de modo que los
pasos del ADC van de 0 para 0V y 4095 para 3.3V.

REQUERIMIENTOS:

  1. Raspbian Wheezy
  2. Python
  3. Python-dev
  4. spidev
  5. Habilitar el soporte para SPI de la Raspberry Pi.

Instalación de Dependencias:

  • Para instalar python python-dev realizar:
 $ sudo apt-get install python-dev python
  • Para instalar spidev:
$ git clone git://github.com/doceme/py-spidev
$ cd py-spidev/
$ sudo python setup.py install
  • Habilitar el soporte de spi en la raspberry-pi:
$ sudo sed -i 's/blacklist spi\-bcm2708/\#blacklist spi-bcm2708/g' /etc/modprobe.d/raspi-blacklist.conf
$ sudo reboot


Diagrama:



El Programa
#!/usr/bin/python
import spidev
import time
DEBUG = 0

spi = spidev.SpiDev()
spi.open(0,0)

# read SPI data from MCP3202 chip
def get_adc(channel):
        # Only 2 channels 0 and 1 else return -1
        if ((channel > 1) or (channel < 0)):
                return -1
        r = spi.xfer2([1,(2+channel)<<6,0])

        ret = ((r[1]&0x0F) << 8) + (r[2])
        return ret

tempval = 0
#Take 5 reads on the adc
for x in range(0, 9):
 tempval += get_adc(0)

#Get the prom
promval = tempval/10

#Get the volts
V1 = (get_adc(0)*3.3)/4096
V2 = (V1*10)/3.3 


#Print results

print "Valor Decimal: ", promval
print ""
print "Divisor de Voltaje: %0.2f" % (V1)
print ""
print "Voltaje de Entrada: %0.2f" % (V2)
print ""


Y unas capturas del circuito y capturando el voltaje.


Primer captura de Voltaje:




Segunda Captura de Voltaje: