Para el desarrollo de la práctica, se tiene que cumplir con los siguientes puntos:
- Controlar dos servomotores con el acelerómetro (Uno con el eje x; el otro con y).
- Encender un Led con un tapsimple.
- Encender dos Leds con un doble tap.
- Parpadeo de un led después de caída libre
Para el desarrollo de la práctica, se utilizó:
- Acelerómetro ADXL345
- 2 servomotores
- 3 Leds
- Microcontrolador de 8-bits PSoC 1
- Raspberry Pi modelo B+
- Bluetooth HC05
Acelerómetro ADXL345
El dispositivo ADXL345 es un acelerómetro de tres ejes (X, Y, Z) que utiliza las interfaces de comunicación I2C y SPI . Posee un regulador de 3.3V lo que permite elegir el voltaje lógico de interfaz, ya sea 3V o 5V.
Utilizando las interfaces se puede definir la sensibilidad del sensor, el cual ofrece los niveles de sensibilidad de +-2g, +-4g, +-8g, +-16g. El menor rango de medición, por lo regular, es utilizado para medir movimientos lentos, mientras que el mayor rango ofrece cambios a movimientos rápidos.
La resolución del acelerómetro ADXL345 es de 10 a 13 bits, por lo que se requiere dos bytes para alojar el resultado completo de cada eje. Esto quiere decir que en total recibiremos 6 bytes, que será necesario convertir a solo 1 byte por eje. El primer byte de cada eje contiene el valor menos significativo.
Entre sus aplicaciones podemos encontrar:
- Telefonía móvil
- Instrumentación médica
- Juegos y dispositivos señaladores
- Instrumentación industrial
- Dispositivos de navegación personal
- Protección de discos duros
- Equipo para ejercitarse
Características
- 2.0-3.6VDC de voltaje de alimentación
- Ultra Bajo Consumo: 40uA tiempo de medición, 0.1uA en standby @ 2.5V
- Detección de Tap/Doble Tap
- Detección de caída libre
- Interfaces I2C y SPI
Acelerómetro ADXL345 |
Servomotores
Los servomotores son motores especiales que incluyen circuitería interna para poder controlarse con mucha precisión. Son utilizados para controlar posición (ángulo) de giro. Normalmente pueden girar dentro de un rango de 0-180° y se controlan por PWM.
Servomotor |
Comúnmente, el tiempo del pulso en estado alto debe ser entre 1-2ms y la posición cero queda en 1.5ms, mientras que 0°y 180°corresponden a 1ms y 2ms, respectivamente, lo que significa que el movimiento del servomotor no tiene que ser estrictamente lineal. La relación del ancho de pulso respecto al ángulo del eje es lineal. Para mantener la posición del motor es necesario seguir enviando los pulsos continuamente por lo tanto si se deja de enviar pulsos o se excede el tiempo de estado bajo, el motor puede perder fuerza y cambiar su posición.
Desarrollo del programa
El programa se desarrollo en 2 partes, para dar solución al problema de que el microcontrolador tenga que estar conectado mediante cables a la alimentación.
Pseudocódigo de PSoC1
Proceso ProgramaPSoC
Definir Registros Como Caracter
Dimension BytesEscritura[2]
ConfiguracionInicial()
BytesEscritura[0] <- DireccionRegistro
BytesEscritura[1] <- ConfiguracionRegistro
EscribirRegistro(BytesEscritura)
Mientras Verdadero es Verdadero
Dimension Lecturas[9]
Lecturas[0] <- DireccionRegistro
EscribirRegistro(Lecturas[0])
LeerRegistro(Lecturas)
EscribirEnLCD(Lecturas)
MandarPorUART(Lecturas)
FinMientras
FinProceso
Interrupciones TAP - DOBLE TAP - CAIDA LIBRE
SubProceso GPIO_ISR()
Dimension ISR[2]
Definir TAP_ISR como Entero
Definir DOBLE_TAP_ISR como Entero
Definir CAIDA_ISR como Entero
ISR[0] <- DireccionRegistro
EscribirRegistro(ISR[0])
LeerRegistro(ISR[1])
Si ISR[1] = TAP_ISR Entonces
Encender_1_LED()
FinSi
Si ISR[1] = DOBLE_TAP_ISR Entonces
Encender_2_LEDs()
FinSi
Si ISR[1] = CAIDA_ISR Entonces
Parpadear_LED()
FinSi
FinSubProceso
Imágenes de los dispositivos funcionando independientemente |
Código de control de servomotores en Python (Raspberry)
try:
import serial
import RPi.GPIO as GPIO
port = "/dev/ttyAMA0"
serie = serial.Serial(port,9600)
serie.flushInput()
serie.flush()
GPIO.setmode(GPIO.BCM)
GPIO.setup(13, GPIO.OUT)
p = GPIO.PWM(13, 1000)
p.start(0)
while True:
if (serie.inWaiting() > 0):
input = serie.read(5)
lect = bytearray(input)
x = (lect[1] << 8) | lect[0]
y = (lect[3] << 8) | lect[2]
if(x & (1 << 16) - 1):
x = x - (1 << 16)
if(y & (1 << 16) - 1):
y = y - (1 << 16)
strX = str(x)
strY = str(y)
strISR = str(lect[4])
print(strX, strY, strISR)
except KeyboardInterrupt:
GPIO.cleanup()
Finalmente se muestra en video el funcionamiento de los dos dispositivos independientes, sin cables y utilizando un bluetooth para comunicación.