Paso 15: Diseño - escuchar
En esta sección vamos a trabajar en el software del receptor, que hable con un receptor XBee y averiguar los datos de sensor de lo que significa. A se escribe el código en python que es un bastante-fácil de usar lenguaje de scripting. Se ejecuta en todos los OS y tiene toneladas de tutoriales en línea. Además, Google AppEngine utiliza por lo que es un buen momento para aprender!
Esta sección se supone que sólo tiene 1 emisor y 1 receptor, sobre todo para hacer gráficos más fácil para hacer frente a. En la siguiente sección te ATE en sensores más al llegar a la parte de registro de datos!
Crudo entrada analógica
Empezaremos a obtener datos sin procesar de lo XBee y comprobando hacia fuera. Se publica el formato de paquete de XBees pero en vez de enraizamiento en él, sólo usaré la práctica biblioteca de XBee para python. Con él, puedo centrarme en los datos en lugar de bytes de conteo y cálculo de sumas de comprobación.
Para utilizar la biblioteca, primero use el módulo pyserial para abrir un puerto serie (es decir COM4 bajo windows, ttyUSB0 bajo mac, linux, etc.) le puede buscar en la página de proyecto de XBee para obtener información sobre cómo averiguar qué puerto COM está buscando. Nos conectamos a la velocidad en baudios predeterminada estándar de XBees, que es de 9600 y buscar paquetes
de xbee importación xbee
serial de importación
SERIALPORT = "COM4" # el puerto serie com el XBee conectado a
Velocidad en baudios = 9600 # baudios hablamos con el xbee
# abrir el puerto serial FTDI para obtener datos transmitidos al xbee
ser = serial. Serie (SERIALPORT, velocidad en baudios)
ser.Open()
Aunque la verdad:
# Tome un paquete de los xbee, o tiempo de espera
paquete = xbee.find_packet(ser)
Si paquete:
XB = xbee(packet)
imprimir xb
Ejecutar este código, obtendrá el siguiente resultado:
< xbee {app_id: 0x83, address_16: 1, rssi: 85, address_broadcast: False, pan_broadcast: False, total_samples: 19, digital: [[-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1 , -1, -1, -1, -1], [-1, -1 , -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1 , -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1 , -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1 , -1, -1 , -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1 , -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1 , -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1 , -1], [-1 , -1, -1, -1, -1, -1, -1, -1, -1]], analog: [[190, -1, -1, -1, 489, -1], [109, -1, -1, -1, 484, -1], [150, -1, -1, -1, 492, -1], [262, -1, -1, -1, 492 , -1], [423, -1, -1, -1, 492, -1], [589, -1, -1, -1, 492, -1], [740, -1, -1, -1, 492, -1], [843, -1, -1, -1, 492, -1], [870, -1, -1, -1 , 496, -1], [805, -1, -1, -1, 491, -1], [680, -1, -1, -1, 492, -1], [518, -1, -1, -1, 492, -1], [349, -1, -1, -1, 491, -1], [199, -1, -1, -1, 491, -1], [116, -1, -1, -1, 468, -1], [108, -1, -1, -1, 492, -1], [198, -1, -1, -1, 492, -1], [335, -1, -1, -1, 492, -1], [523, -1, -1, -1, 492 -1]]} >
que se vuelva a formatear para hacer un poco más legible
< xbee {}
app_id: 0x83,
address_16: 1,
RSSI: 85,
address_broadcast: False,
pan_broadcast: False,
total_samples: 19,
digital: [[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1]]
analógico: [[190 -1, -1, -1, 489, -1],
[109 -1, -1, -1, 484, -1],
[150 -1, -1, -1, 492, -1],
[262 -1, -1, -1, 492, -1],
[423 -1, -1, -1, 492, -1],
[589, -1, -1, -1, 492, -1],
[740 -1, -1, -1, 492, -1],
[843 -1, -1, -1, 492, -1],
[870, -1, -1, -1, 496, -1],
[805, -1, -1, -1, 491, -1],
[680 -1, -1, -1, 492, -1],
[518 -1, -1, -1, 492, -1],
[349 -1, -1, -1, 491, -1],
[199, -1, -1, -1, 491, -1],
[116, -1, -1, -1, 468, -1],
[108 -1, -1, -1, 492, -1],
[198 -1 -1, -1, 492, -1],
[335 -1, -1, -1, 492, -1],
[523 -1, -1, -1, 492, -1]]
} >
OK ahora su claro lo que está pasando aquí. Para empezar, algunos datos como el identificador de emisor (address_16) y fuerza (RSSI) de señal. El paquete también nos dice cuántos muestra disponible (19). Ahora, las muestras digitales son todos -1 porque no pedimos para ser enviado. La biblioteca aún llena los tho por lo que los datos no están. El segundo pedazo es 19 conjuntos de datos analógicos, que van desde 0 hasta 1023. Como se puede ver, la primera muestra (#0) y quinta muestra (#4) contienen los datos reales, el resto son -1. Corresponde a la sección de hardware donde configuramos AD0 AD4 nuestro voltaje y sensores de corriente.
Nos va modificar nuestro código para que podamos extraer de estos datos sólo e ignorar al resto del paquete.
Este código crea dos matrices, voltagedata y ampdata donde pegamos los datos. Tiramos hacia fuera de la primera muestra porque generalmente ADCs son un poco flojo en la primera muestra y luego son buenos ir después de eso. Puede que no sea necesario tho
#! / usr/bin/env python
serial de importación
de xbee importación xbee
SERIALPORT = "COM4" # el puerto serie com el XBee conectado a
Velocidad en baudios = 9600 # baudios hablamos con el xbee
CURRENTSENSE = # 4 que ADC XBee tiene datos del drenaje actual
VOLTSENSE = 0 # que ADC XBee tiene datos de tensión de red
# abrir el puerto serial FTDI para obtener datos transmitidos al xbee
ser = serial. Serie (SERIALPORT, velocidad en baudios)
ser.Open()
Aunque la verdad:
# Tome un paquete de los xbee, o tiempo de espera
paquete = xbee.find_packet(ser)
Si paquete:
XB = xbee(packet)
#print xb
# sólo almacenaremos n-1 muestras desde el primero de ellos es generalmente desordenado
voltagedata = [-1] * (len(xb.analog_samples) - 1)
ampdata = [-1] * (len (xb.analog_samples) -1)
# Tome 1 n a través de las lecturas de la ADC, haciendo referencia a las constantes de la ADC
# y almacenarlas en arreglos de discos de poco agradables
para que en range(len(voltagedata)):
voltagedata [i] = xb.analog_samples[i+1][VOLTSENSE]
ampdata [i] = xb.analog_samples[i+1][CURRENTSENSE]
imprimir voltagedata
imprimir ampdata
Ahora están más fáciles ver nuestros datos:
Voltaje: [672, 801, 864, 860, 755, 607, 419, 242, 143, 108, 143, 253, 433, 623, 760, 848, 871, 811]
Corriente: [492, 492, 510, 491, 492, 491, 491, 491, 492, 480, 492, 492, 492, 492, 492, 492, 497, 492]
Tenga en cuenta que la tensión oscila de 100 a 900, sinusoidal.
Normalización de los datos
Continuación hasta nosotros se 'normalizar' los datos. La tensión debe ir de -170 a + 170 que es el voltaje real de la línea, en vez de 100 a 900, que es lo que dice el ADC. Para ello, que vamos a obtener el valor medio de la lectura más grande y más pequeño y réstelo de todas las muestras. Después de eso, a normalizar las mediciones actuales, para obtener los números para igualar el consumo de corriente en amperios.
#! / usr/bin/env python
serial de importación
de xbee importación xbee
SERIALPORT = "COM4" # el puerto serie com el XBee conectado a
Velocidad en baudios = 9600 # baudios hablamos con el xbee
CURRENTSENSE = # 4 que ADC XBee tiene datos del drenaje actual
VOLTSENSE = 0 # que ADC XBee tiene datos de tensión de red
# abrir el puerto serial FTDI para obtener datos transmitidos al xbee
ser = serial. Serie (SERIALPORT, velocidad en baudios)
ser.Open()
Aunque la verdad:
# Tome un paquete de los xbee, o tiempo de espera
paquete = xbee.find_packet(ser)
Si paquete:
XB = xbee(packet)
#print xb
# sólo almacenaremos n-1 muestras desde el primero de ellos es generalmente desordenado
voltagedata = [-1] * (len(xb.analog_samples) - 1)
ampdata = [-1] * (len (xb.analog_samples) -1)
# Tome 1 n a través de las lecturas de la ADC, haciendo referencia a las constantes de la ADC
# y almacenarlas en arreglos de discos de poco agradables
para que en range(len(voltagedata)):
voltagedata [i] = xb.analog_samples[i+1][VOLTSENSE]
ampdata [i] = xb.analog_samples[i+1][CURRENTSENSE]
# obtener voltaje max y min y normalizar la curva '0'
# para hacer el gráfico 'AC acoplado' firmado
min_v = 1024 # XBee ADC es 10 bits, por lo que valor máximo es de 1023
max_v = 0
para que en range(len(voltagedata)):
Si (min_v > voltagedata[i]):
min_v = voltagedata [i]
Si (max_v < voltagedata[i]):
max_v = voltagedata [i]
# calcular el promedio de las lecturas de max y min
avgv = (max_v + min_v) / 2
# también calcular las medidas de pico a pico
VPP = max_v-min_v
para que en range(len(voltagedata)):
#remove 'sesgo dc', que llamamos el medio de leer
voltagedata [i] = avgv
# Sabemos que la tensión de red es 120Vrms = +-170Vpp
voltagedata [i] = (voltagedata [i] * MAINSVPP) / vpp
# normalizar las lecturas de corriente de amperes
para que en range(len(ampdata)):
# VREF es el valor de "Sesgo de DC" de codificado, su
# 492 cerca pero sería bueno si podríamos de alguna manera
# obtener estos datos de vez en cuando tal vez con xbeeAPI
ampdata [i]-= VREF
# la CURRENTNORM es la constante de normalización
# que convierte al ADC a amperios
ampdata [i] = CURRENTNORM
Imprimir "voltaje, en voltios:", voltagedata
Imprimir "corriente, en amperios:", ampdata
Se te corre ahora para obtener estos datos, que luce bastante bien, es la tensión sinusoidal estamos esperando y la corriente está sobre todo en 0 y luego los picos arriba y abajo de vez en cuando. Nota que la corriente a veces es negativa pero eso está bien porque lo multiplicamos por el voltaje y si ambos son negativos todavía sale como un consumo de energía positiva
Voltaje, en voltios: [-125,-164, -170, -128, -64, 11, 93, 148, 170, 161, 114, 46, -39, -115, -157, -170, -150, -99]
Corriente, en amperios: [0.064516129032258063,-1.096774193548387, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.096774193548387,]
0.0, 0.0, 0.0,-0.064516129032258063, 0.0, 0.0,-0.70967741935483875, 0.0, 0.0]
Datos básicos de graficación
Por último, voy a añadir un montón de código más que utilizará el numpy gráficas módulos para hacer una buena gráfica de nuestros datos. Tenga en cuenta que necesitará instalar wxpython así como numpyy matplotlib.
En este punto, el código está haciendo waaay a grande para pegar aquí para que "gráfico de red de wattcher.py" de la página de descarga del gancho agarrador!
Ejecutarlo y usted debería ver una ventana de gráfico pop-up con un gráfico de voltaje sinusoidal agradable y varios datos de amperaje. Por ejemplo este primer gráfico es de un ordenador portátil conectado. Verás que es una fuente conmutada y solo tira de energía durante el pico de la curva de tensión.
Ahora vamos a tratar de conectar una lámpara incandescente de 40W. Usted notará que a diferencia de la fuente de conmutación, la corriente sigue la tensión casi a la perfección. Eso es porque una bombilla es una resistencia de sólo!
Por último, permite tratar de pegarse el medidor en un interruptor regulable. Verás que la tensión es 'picada', ya no sinusoidal. Y aunque la corriente sigue la tensión, su todavía bastante bien.
Gráfica potencia!
Bien aseado, su diversión para ver formas de onda pero lo que-quiere - es realmente la potencia utilizada. Recuerda, P = VI, también conocido como Watts = voltaje * corriente. Podemos calcular vatios total utilizado, multiplicando las tensiones y corrientes en cada punto de muestra, Resumen luego de más de un ciclo y un promedio para obtener la potencia utilizada por ciclo. Una vez tengamos vatios, es fácil simplemente multiplicar por 'tiempo' vatios-hora!
Descargar y ejecutar el wattcher.py - script de grapher watt desde la página de descarga
Ahora se puede ver el valor de la última hora de la historia de watt (3600 segundos divididos por 2 segundos por muestra = 1800 muestras) en la imagen de arriba se puede ver como que dim una bombilla de 40 vatios. Los datos son muy 'dispersados' porque no hemos hecho ningún filtrado de paso bajo. Si tuviéramos una mejor muestreo analógico, esto puede no ser tan grande un acuerdo pero con sólo 17 muestras para trabajar con precisión es un poco difícil
Hecho!
OK muy bien! Hemos podido leer los datos, analizar a la carga útil del sensor analógico y procesar de una manera que nos da gráficos significativos. Por supuesto, esto es excelente para el conocimiento instantáneo pero -- sería bueno si pudiéramos tener un almacenaje más largo plazo y también hacer un seguimiento de múltiples sensores. En el siguiente paso haremos aprovechando algunos servicios gratuitos de 'cloud computing'.