Proyecto RPi
Este post es creado como parte del Proyecto Final de Introducción al Raspberry Pi.
Que busca el proyecto:
- Complementar el bot de twitter @Rpi_Twiteando con acciones propias del mundo real. Dando inicio a una serie de proyectos de domotica.
- Twittear y dar alertas pushover de Temperatura y humedad (Oficina y Cuarto 1)
- Encender abanicos en rack cuando la temperatura sea critica 29ºC
- Encender luces de rack cuando la luz sea muy baja
Hardware
- Modulo con sensor de temperatura DTH11
- Sensor de temperatura TMP36
- Kitemisor y receptor de Radiofrecuencia en la banda de 433Mhz(Estándar inalámbrico de banda libre en España)
- Una photo celda como sensor de luz
- Un modulo relay con 2 canales a 5 voltios.
- Raspberry Pi modelo B Rev2
- Arduino UNO
Software
Instalar (indispensable)
Wiring PI
cd ~
sudo apt-get install git-core build-essential
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build
ttytter
cd ~ apt-get install curlwget http://www.floodgap.com/software/ttytter/dist2/2.0.00.txtmv 2.0.00.txt ttytterchmod a+x ttyttermv ttytter /usr/bin/Ejecutar ttytter y seguir los pasos
ttytterFestival
aptitude install festivalwget http://forja.guadalinex.org/frs/download.php/154/festvox-sflpc16k_1.0-1_all.debdpkg -i festvox-sflpc16k_1.0-1_all.debEjemplo
echo Hola, $USERNAME | festival --tts
Conexiones
Sensor de Humedad
WiringPi
|
RPI
|
|
DAT
|
7
|
7
|
VCC 3,3v
|
-
|
1
|
GND
|
-
|
6
|
Para
poder usar el modulo DTH11 con el raspberry pi necesite compilar este script que
encontré en esta web
Creamos el archivo:
nano dth11.c
Y escribimos el siguiente código:
Nota: este código esta el repositorio github que publicaremos adelante.
------------------------------------------
CODIGO DESDE AQUI - Archivo dth11.c
------------------------------------------
//Incluimos librerias necesarias
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//Definimos constantes
#define MAX_TIME 85
#define DHT11PIN 7
#define ATTEMPTS 5
//Definimos un vector global
int dht11_val[5]={0,0,0,0,0};
/////////////////////////////////////////////////////////////
//Funcion principal para leer los valores del sensor.
int dht11_read_val(){
uint8_t lststate=HIGH;
uint8_t counter=0;
uint8_t j=0,i;
for(i=0;i<5;i++){
dht11_val[i]=0;
}
pinMode(DHT11PIN,OUTPUT);
digitalWrite(DHT11PIN,LOW);
delay(18);
digitalWrite(DHT11PIN,HIGH);
delayMicroseconds(40);
pinMode(DHT11PIN,INPUT);
for(i=0;i<MAX_TIME;i++){
counter=0;
while(digitalRead(DHT11PIN)==lststate){
counter++;
delayMicroseconds(1);
if(counter==255){
break;
}
}
lststate=digitalRead(DHT11PIN);
if(counter==255){
break;
}
//Las 3 primeras transiciones son ignoradas
if((i>=4)&&(i%2==0)){
dht11_val[j/8]<<=1;
if(counter>16){
dht11_val[j/8]|=1;
}
j++;
}
}
// Hacemos una suma de comprobacion para ver si el dato es correcto. Si es asi, lo mostramos
if((j>=40)&&(dht11_val[4]==((dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])& 0xFF))){
printf("%d.%d,%d.%d\n",dht11_val[0],dht11_val[1],dht11_val[2],dht11_val[3]);
return 1;
}else{
return 0;
}
}
////////////////////////////////////////////////////////////////
//Empieza nuestro programa principal.
int main(void){
//Establecemos el numero de intentos que vamos a realizar
//la constante ATTEMPTS esta definida arriba
int attempts=ATTEMPTS;
//Si la libreria wiringPi, ve el GPIO no esta listo, salimos de la aplicacion
if(wiringPiSetup()==-1){
exit(1);
}
while(attempts){
//Intentamos leer el valor del gpio, llamando a la funcion
int success = dht11_read_val();
//Si leemos con exito, salimos del while, y se acaba el programa
if (success){
break;
}
//Si no lee con exito, restamos 1, al numero de intentos
attempts--;
//Esperamos medio segundo antes del siguiente intento.
delay(500);
}
return 0;
}
------------------------------------------
CODIGO HASTA AQUI-------- FIN DE ARCHIVO dth11.c
------------------------------------------
Luego compilamos
Nota: ojo que aunque esta en C usa la librebria wiringPI
gcc -o dth11 dth11.c -L /usr/local/lib -l wiringPi
el resultado lo ponemos a disposición de todos los usuarios
cp dth11 /usr/bin
Relay
WiringPi
|
RPI
|
|
VCC 5v
|
-
|
2
|
CH1
|
4
|
16
|
CH2
|
6
|
22
|
GND
|
-
|
9
|
Para el
relay cree fan.sh en la carpeta /opt/ que tiene la siguiente
estructura
Nota: este código esta el repositorio github que publicaremos adelante.
#!/bin/bash
if [ $1 -eq 1 ] ; then
gpio mode 6 out
gpio write 6 1
else
gpio write 6 0
gpio reset
fi
Esto
para controlar cuando se enciende o se apagar el abanico
ej
/opt/fan.sh 1 // enciende del abanico
Foto celda
WiringPi
|
RPI
|
|
VCC 3,3v
|
-
|
17
|
DATA
|
5
|
18
|
GND
|
-
|
25
|
Para poder hacer que
la foto celta funcione bien se necesita un capacitor 1uF que se
coloca en medio del GND y el cable de datos. Y una resistencia de 220Ohm entre el positivo y la foto celda.
Basado en la web de adafruit
El código fuente es el siguiente:
Nota: este código esta el repositorio github que publicaremos adelante.
#!/usr/bin/env python
# Archivo luz.py
import RPi.GPIO as GPIO, time, os
DEBUG = 1
GPIO.setmode(GPIO.BCM)
on = 0
MAX=5200
PIN=23
GPIO.setup(PIN,GPIO.OUT)
def RCtime (RCpin):
reading = 0
GPIO.setup(RCpin, GPIO.OUT)
GPIO.output(RCpin, GPIO.LOW)
time.sleep(0.1)
GPIO.setup(RCpin, GPIO.IN) # This takes about 1 millisecond per loop cycle while (GPIO.input(RCpin) == GPIO.LOW): reading += 1 return reading
while True: print RCtime(24) # Read RC timing using pin #18 luz = RCtime(24) if luz > MAX: GPIO.output(PIN,True) on = 1
if luz < MAX and on == 1: GPIO.output(PIN,False) on = 0
Sensor TMP36, Kit RF 433Mhz y Arduino UNO
TMP36
Arduino
|
RPI
|
|
1
|
5V
|
-
|
2
|
A0
|
-
|
3
|
GND
|
-
|
Transmiter 433Mhz
Arduino
|
RPI
|
|
ATAD
|
D10
|
|
VCC
|
5V
|
-
|
GND
|
GND
|
-
|
Para el arduino Uno se debe descargar e instalar la siguiente librería me base en el blog
para realizar esta parte del proyecto.
El código del
arduino es
Nota: este código esta el repositorio github que publicaremos adelante.
#include <RCSwitch.h>
#include <rcswitch .h="">
RCSwitch mySwitch = RCSwitch();
long envio = 0;
// Declaracion de variables
float tempC;
int tempPin = 0; // Definimos la entrada en pin A0
void setup()
{
// Abre puerto serial y lo configura a 9600 bps
Serial.begin(9600);
mySwitch.enableTransmit(10);
}
void loop()
{
// Lee el valor desde el sensor * 0.00482814
tempC = (analogRead(tempPin)* 5.0) / 1024;
tempC = ((tempC - 0.5) * 100.0) + 4; // mas x es para calibrar mas o menos la temperatura
mySwitch.send(tempC, 8);
// Espera cinco segundo para repetir el loop
delay(5000);
}
Reciver 433Mhz
WiringPi
|
RPI
|
|
VCC 5v
|
-
|
4
|
DATA1
|
0
|
11
|
DATA 2
|
-
|
-
|
GND
|
-
|
6
|
Baje el software c++
y wiringPI basado en este blog
realizando las
siguientes acciones
mkdir -p /usr/src/rasp433/
cd /usr/src/rasp433/
wget https://www.dropbox.com/s/faw6y1lzguhgxvx/rpi.zip
unzip rpi.zip
gcc rfreceive.cpp RCSwitch.cpp -o rfreceive -lwiringPi
gcc rftester.cpp RCSwitch.cpp -o rftester -lwiringPi
y modifique el
código de rfreceive.cpp para que solo devolviera un numer de la
siguiente manera:
Nota: este código esta el repositorio github que publicaremos adelante.
/*
rfreceive.cpp
by Sarrailh Remi
Description : This code receives RF codes and trigger actions
Modificado por @bettocr
*/
#include "RCSwitch.h"
#include <stdlib.h>
#include <stdio.h>
RCSwitch mySwitch;
int pin; //Pin of the RF receiver
int codereceived; // Code received
char buffer[200]; // Buffer for the command
int dato;
int salir;
int main(int argc, char *argv[]) {
if(argc == 2) { //Verify if there is an argument
pin = atoi(argv[1]); //Convert first argument to INT
// printf("PIN SELECTED :%i\n",pin);
}
else {
printf("No PIN Selected\n");
printf("Usage: rfreceive PIN\n");
printf("Example: rfreceive 0\n");
exit(1);
}
if(wiringPiSetup() == -1) { //Initialize WiringPI
printf("Wiring PI is not installed\n"); //If WiringPI is not installed give indications
printf("You can install it with theses command:\n");
printf("apt-get install git-core\n");
printf("git clone git://git.drogon.net/wiringPi\n");
printf("cd wiringPi\n");
printf("git pull origin\n");
printf("./build\n");
exit(1);
}
mySwitch = RCSwitch(); //Settings RCSwitch (with first argument as pin)
mySwitch.enableReceive(pin);
dato = 0;
salir =1;
while(salir) { //Infinite loop
if (mySwitch.available()) { //If Data is detected.
dato = mySwitch.getReceivedValue();
if(dato > 0){
printf("%i", dato );
salir = 0;
}
}
mySwitch.resetAvailable();
}
}
ALERTAS
Para las alertas a
pushover cree un script
/opt/aviso.sh
Que recibe 2 parámetros el titulo del mensaje y el mensajes
Nota: este código esta el repositorio github que publicaremos adelante.
#!/usr/bin/env sh
URL="https://api.pushover.net/1/messages.json"
API_KEY="Su-api-key"
USER_KEY="Su-user-key"
DEVICE="all"
SOUND="magic"
PRIORITY="0"
TITLE="${1}"
MESSAGE="${2}"
curl \
-F "token=${API_KEY}" \
-F "user=${USER_KEY}" \
-F "device=${DEVICE}" \
-F "title=${TITLE}" \
-F "message=${MESSAGE}" \
-F "sound=${SOUND}" \
-F "priority=${PRIORITY}" \
"${URL}" > /dev/null 2>&1
ttytter -status="Send an Alert Message by pushover"
Control de temperatura oficina
Nota: este código esta el repositorio github que publicaremos adelante.
#!/bin/bash
TEMP=`/usr/bin/dth11 | awk -F ",*" '{ print $2}'`
HUME=`/usr/bin/dth11 | awk -F ",*" '{ print $1}'`
TMP=`cat /tmp/dht11.txt` #temperatura anterior
FAN=`cat /tmp/fan` #abanico encendido
FECHA=`date`
DIF1=`echo "$TMP-$TEMP" | bc`
DIF=${DIF1/\.*}
TEMP1=${TEMP/\.*}
TMP1=${TMP/\.*}
DATO=${#TEMP1}
TMAX=28 #temperatura maxiama
logger -i "TEMP "$TEMP" TEMP1 "$TEMP1" TMP "$TMP1" DATO "$DATO" DIF "$DIF" DIF1 "$DIF1" fan "$FAN
if [ $DATO -ne 0 ] && [ $TEMP1 == $TMP1 ] ; then
logger -i "DTH11 funciono"
# echo $FECHA" "$TEMP" "$HUME >> /home/pi/prueba.txt
else
if [ $DATO -ne 0 ] ; then
echo $FECHA" "$TEMP" "$HUME >> /home/pi/prueba.txt
echo $TEMP > /tmp/dht11.txt
echo "Temperatura: "$TEMP" grados centigrados, Humedad: "$HUME"%, Temperatura anterior: "$TMP" grados centigrados " |iconv -f utf-8 -t iso-8859-1| festival --tts
logger -i "DTH11 funciono"
if [ $DIF -le -2 ] || [ $DIF -ge 2 ] ; then
/opt/aviso.sh "Temperatura Oficina" "Aumento de mas de 2 Grados en la oficina. "$TEMP" Grados Centigrados"
ttytter -status="Office temperature "$TEMP"ºC, Humidity "$HUME"%"
logger -i "mensaje"
fi
if [ $TEMP1 -ge $TMAX ] && [ $FAN -eq 0 ] ; then
sudo /opt/fan.sh 1
echo 1 > /tmp/fan
/opt/aviso.sh "Temperatura Oficina" "La Temperatura oficina "$TEMP" Grados he encendio los abanidos del rack"
logger -i "Aabanicos encendidos"
fi
if [ $TEMP1 -lt $TMAX ] ; then
sudo /opt/fan.sh 0
echo 0 > /tmp/fan
logger -i "Abanicos Apagados"
/opt/aviso.sh "Temperatura Oficinia" "apaga los abanicos"
fi
fi
fi
Tweet
Office temperature 24.0ºC, Humidity
— Mi RaspberryPi (@RPi_twiteando) Mayo 21, 2014
temperatura cuarto 1
Nota: este código esta el repositorio github que publicaremos adelante.
#!/bin/bash
TEMP=`cat /tmp/RFtemp0.txt`
TMP=`cat /tmp/cuarto1.txt`
FECHA=`date`
DIF=`echo $TMP-$TEMP | bc`
DATO=${#TEMP}
DATO1=${#TMP}
TMAX=29 #temperatura maxiama
TMIN=15
logger -i "Cuarto 1 TEMP "$TEMP" TMP "$TMP" DATO "$DATO" DIF "$DIF
if [ $DATO -ne 0 ] && [ $DATO1 -ne 0 ] ; then
if [ $TEMP == $TMP ] ; then
logger -i "Cuarto 1 sin cambios"$TEMP" "$TMP
# echo $FECHA" "$TEMP" "$HUME >> /home/pi/prueba.txt
else
echo $FECHA" Cuarto 1 "$TEMP" " >> /home/pi/prueba.txt
echo $TEMP > /tmp/cuarto1.txt
echo "Temperatura Cuarto uno: "$TEMP" grados "" Temperatura anterior: "$TMP" grados " |iconv -f utf-8 -t iso-8859-1| festival --tts
logger -i "Cuarto 1 con cambios"
if [ $DIF -le -2 ] || [ $DIF -ge 2 ] ; then
/opt/aviso.sh "Temperatura Oficina" "Aumento de mas de 2 Grados en la oficina. "$TEMP" Grados Centigrados"
#ttytter -status="Room1 temperature "$TEMP"º"
logger -i "mensaje pushover y twitter"
fi
if [ $TEMP -ge $TMAX ] && [ $FAN -eq 0 ] ; then
/opt/aviso.sh "Temperatura Cuarto 1 "$TEMP" Grados"
logger -i "Esta muy caliente "$TEMP
fi
if [ $TEMP -le $TMIN ] ; then
/opt/aviso.sh "Temperatura Cuarto 1 "$TEMP" Grados"
logger -i "Esta muy frio "$TEMP
fi
fi
Crontab
* * * * * /opt/temp.sh
* * * * * /usr/bin/rfrecivetxt 0 > /tmp/RFtemp0.txt
* * * * * /opt/temp-cuartos.sh
Otros Archivos a crear
touch /tmp/dht11.txt
touch /tmp/fan
touch /tmp/RFtemp0.txt
touch /tmp/cuarto1.txt
Dificultades del proyecto
- La mayor dificultad que encontré fue la parte electrónica ya que no conozco mucho a varios entre ellos la comunidad Arduino Costa Rica que respondieron siempre mis preguntas.
Mejoras al proyecto
- Cambiar el arduino por un attiny85, para reducir tamaño. creando un emisor de temperatura para cada cuarto.
- Colocar cada uno de estos emisores en un cuarto y otro fuera de la casa.
- Probar encendido y apagado de abanicos y luces se pueden hacer con estos mismo dispositivos.
- Actualmente el sistemas mantiene un load de un 4.17, en otros RPi parte de Rpi_twiteando tienen un pico de 5.53 y un minimo de 0.53 de load, por lo que hay que buscar que hace que el load este alto.
- Cuando el Arduino se apaga o pierde conexion la radio frecuencia, el rfreceive sobre carga el sistema.
Costo del Proyecto
Componente
|
Unidades
|
Precio Unitario
|
Precio total
|
Raspberry Pi |
1
|
$42
|
$42
|
Arduino UNO |
1
|
$30
|
$30
|
SD 4Gb |
1
|
$13
|
$13
|
Relay 2Chs 5v |
1
|
$9,95
|
$9,95
|
TMP36 |
1
|
$1,95
|
$1,95
|
DTH11 |
1
|
$3,70
|
$3,70
|
Kit RF 433 |
1
|
$1,90
|
$1,90
|
Total |
$102,5
|
Comentarios
Publicar un comentario