Table of Contents

Interruptores inalambricos

Freddy Navarro Umaña B04492

Introducción

Para este proyecto se utilizan ciertos dispositivos abiertos específicos que facilitan el desarrollo del mismo. Para cada interruptor inalámbrico, se utilizara al menos un arduino, un módulo inalámbrico de zigbee (Xbee) y un relay (Led) para lograr lo que se desea. Se usó un raspberry pi donde se diseñó un servidor con acceso mediante wi-fi y que se comunique a su vez por zigbee para controlar los dispositivos inalámbricos.

Objetivos

Objetivo general

Elaborar un sistema capaz de controlar interruptores de manera inalámbrica por medio de una red zigbee, ya sea desde una computadora o un teléfono inteligente.

Objetivos específicos

Herramientas principales

Raspbian

El servidor corre en un raspberry pi, el cual necesita un sistema operativo. Se utiliza Raspbian como sistema operativo y una guia detallada de instalaciòn se obtiene aqui Raspbian

Apache

Es necesario instalar apache en el raspberry para utilizar sus facilidades y poder accesar al servidor, para hacer esto primero se actualizan los paquetes mediante una terminal con los comandos:

sudo apt-get update

Para instalar apache propiamente se escribe:

sudo apt-get install apache2

Serial

Para poder utilizar el puerto serial en el código del servidor, es necesario instalar la librería de Python para soportarlo. Primero se deben descargar los archivos comprimidos respectivos a Source de esta pagina PySerial . Posteriormente se abre una terminal, se cambia el directorio a la ubicacion donde se haya descargado y se ejecuta el siguiente comando para descomprimirlo:

tar -xzf pyserial-2.7.tar.gz 

Seguidamente se instala con el comando:

python setup.py install

Arduino

Para cargar el código al arduino, se utiliza el programa facilitado por los creadores del mismo. La guia oficial de instalacion en Debian se consigue aqui Arduino, con las diferentes opciones para su instalación.

XCTU

Para dar la configuración que se necesita a los dispositivos Xbee, se procede primero a instalar el programa XCTU para interactuar con los mismos de manera sencilla y rápida. Este programa únicamente esta disponible para Windows o MacOS por lo que se necesita acceso a una computadora con alguno de estos sistemas operativos. El programa se puede descargar de la pagina oficial de Digi, desarrolladores del Xbee. Una vez que se cuenta con el programa, es necesario flashear los modulos con el respectivo firmware para el coordinador y el router/end-device.

Programación del arduino

El microcontrolador empleado tiene la función básica de encender o apagar la luz cuando recibe el comando especifico. El arduino tiene un modulo Xbee conectado en sus terminales Tx y Rx para poder enviar y recibir información inalambricamente. Este microcontrolador espera que llegue información por el puerto serial, y cuando esto se cumple y se dan las condiciones definidas en el código, ejecuta un cambio en el estado del pin donde esta conectado el Led(Relay). El código, se compila y se carga por medio del programa Arduino al dispositivo conectado. El codigo elaborado para lograr esto corresponde al siguiente:

int ledPin = 13;
int ledState = -1;
 
 
void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  ledState = LOW;
}
 
void loop() {
  int avail = Serial.available();
  int command = -1;
  if(avail > 0) {
    command = Serial.peek() - '0';
    if(avail == 1 && command == 0) {
      changeLedState();
    }
    for(int i = 0; i < avail; i++) {
      Serial.read();
    }
    Serial.println(ledState);
  }
  delay(50); 
}
 
void changeLedState() {
  ledState = ledState ^ 1;
  digitalWrite(ledPin, ledState);
}

Programación del servidor

El servidor se programó en python y presenta ciertas características a destacar. El servidor utiliza sockets para comunicarse con los clientes, utilizando el protocolo TCP/IP. Actualmente, el servidor únicamente recibe comandos de los clientes pero no esta soportado la respuesta ya que los clientes no están aun diseñados y no se han definido los comandos de respuesta. Para que el servidor pueda manejar múltiples clientes simultáneamente, se implementan “threads” para manejar cada cliente por separado. De esta manera, las peticiones de los clientes no se colocan en espera sino que se procesan inmediatamente. Una vez que se recibe un comando de un cliente, se crea el thread para manejarlo, el servidor los maneja mediante la clase Cliente y el mismo toma el comando y lo envía por medio del puerto serial hacia el modulo Xbee el cual transmite el mensaje inalambricamente por Zigbee. Luego de enviar el mensaje hace limpieza y cierra ambos puertos. El codigo que hace todo esto posible, se guarda en un archivo con extensión *.py y se ejecuta desde una terminal mediante:

python nombredelarchivo.py

Dicho codigo se presenta a continuacion:

#!/usr/bin/env python 
 
import select 
import socket 
import sys 
import threading 
import serial
import time
 
class Server: 
    def __init__(self): 
        self.host = '' 
        self.portIn = 4444
        self.backlog = 5 
        self.size = 1024 
        self.server = None 
        self.threads = [] 
 
    def open_socket(self): 
        try: 
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
            self.server.bind((self.host,self.portIn)) 
            self.server.listen(self.backlog) 
        except socket.error, (value,message): 
            if self.server: 
                self.server.close() 
            print "Could not open socket: " + message 
            sys.exit(1) 
 
    def run(self): 
        self.open_socket() 
        input = [self.server,sys.stdin] 
        running = 1 
        while running: 
            inputready,outputready,exceptready = select.select(input,[],[]) 
 
            for s in inputready: 
 
                if s == self.server: 
                    c = Client(self.server.accept()) 
                    c.start() 
                    self.threads.append(c) 
 
                elif s == sys.stdin: 
                    junk = sys.stdin.readline() 
                    running = 0 
 
        self.server.close() 
        for c in self.threads: 
            c.join() 
 
class Client(threading.Thread): 
    def __init__(self,(client,address)): 
        threading.Thread.__init__(self) 
        self.client = client 
        self.address = address
        self.portOut = "/dev/ttyUSB0"
        self.size = 1024
 
    def getTime(self):
        return int(round(time.time() * 1000))
 
    def sendData(self,data,ser):
        try:
            ser.write(data)
        except:
            return "Could not send data"
        currTime = self.getTime()
        while self.getTime() - currTime < 2000:
            time.sleep(.1)
            if ser.inWaiting() > 0:
                response = ser.read(1)
                ser.flushInput()
                return response
 
    def run(self): 
        running = 1 
        while running: 
            data = self.client.recv(self.size) 
            self.client.close()
            try:
                ser = serial.Serial(self.portOut, 9600)
            except serial.serialutil.SerialException, e: 
                print "Could not connect to serial port"
                exit()
            if data:
                result = self.sendData("0", ser)           
            ser.close()
            running = 0 
 
if __name__ == "__main__": 
    s = Server() 
    s.run()

Referencias


Python
https://docs.python.org/2/library/socket.html
https://docs.python.org/2/howto/sockets.html
http://www.binarytides.com/python-socket-programming-tutorial/
http://pyserial.sourceforge.net/index.html
https://learn.adafruit.com/arduino-lesson-17-email-sending-movement-detector/installing-python-and-pyserial
Xbee
http://www.faludi.com/bwsn/
http://xbee.wikispaces.com/Mesh+with+Xbee