Einleitung

Motivation
Gliederung

Drahtlose Sensornetzwerke



Funkstandards

Derzeit verbreitetete Funkstandards sind:

IEEE 802.11.x (WiFi)
  • 54 … 300 Mbit/s
  • Netzwerkinterface, FileTransfer, Audio, Video
IEEE 802.15.1 (Bluetooth)
  • 732,2 kbit/s … 2,1 MBit/s
  • Nahbereichskommunikation, Sprachübertragung.
IEEE 802.15.4 (ZigBee)
  • 20 bis 250 kbit/s
  • hauptsächlich für Sensoranwendungen geeignet:
    • geringe Datenrate
    • energiesparend
    • niedrige Systemkosten

Drahtloses Datenlogger System

Blockschaltbild
Sensorknoten
  • autark, (Batterie, Energy-Harvesting)
  • sendet kontinuierlich die Werte der Sensoren zum Gateway
Gateway
  • Ausgabe der Sensordaten über serielles Interface
  • permanente Stromversorgung (Netztteil, USB)
Webserver
  • liest und speichert die Daten vom Gatewayknoten
  • Auswertung der Daten mit speziellen Anwendungen.

Boards - Übersicht

Boards - Vorstellung

Zutaten für die Firmware-Entwicklung

Hardware
Software

µracoli - Die AVR-Radio-Library

Library zur einfachen Inbetriebnahme von IEEE-802.15.4-Transceiver-Knoten.

logo

Vergleich von Sensoren

Auswahl von Temperatursensoren

Versuchsaufbau

Umgebung
  • Langzeittests in ruhiger Umgebung
  • Vergleich mit Laborthermometer
  • Tests in wechselnder Umgebung, einschließlich Klimaschrank Vötsch VT4004
Sensorboard
Hardware
  • Montage der Sensoren auf Board
  • SHT-21 2x, TMP141 3x, alle anderen 1x
  • Abfrage über Zigbit-Funkmodul
  • Weiterleitung der Daten über Funk
  • Batteriebetrieb mit 2 x LR03

Messung in ruhiger Umgebung



Messung im Klimaschrank



Schlussfolgerungen

Temperaturmessung
Feuchtigkeitsmessung

Datenauswertung auf dem PC I

System
Sensorlogger

Datenauswertung auf dem PC II

Table-Webserver
Sensorserver

Datenlogger (Prinzip) - sensorlogger.py

import rrdtool
import serial
def rrd_create(tstamp, addr, **kwargs):
  # ... prep to create new .rrd file
  rrdtool.create(r.dbname, *args)

def rrd_update(tstamp, addr, **kwargs):
  # ... prep to update .rrd file with new data
  rrdtool.update(r.dbname, arg)

sport = serial.Serial(SPORT, BAUD)
sport.open()
  while 1:
    try:
      x = sport.readline().strip()
      y = eval("dict(%s)" % x)  # well, it's a demo!
      y["tstamp"] = int(time.time())
      if not SENSORS.has_key(y["addr"]):
        rrd_create(**y)
      rrd_update(**y)
    except:
      print "ERROR:", sys.exc_info()

Web-Server

Webserver
python sensorlogger.py -p /dev/ttyUSB0 -D
python sensorserver.py -v
python tableserver.py -v

Ausblick

Danksagung

Wir möchten uns bei den folgenden Firmen und Personen für die Unterstützung bei diesem Vortrag bedanken.

Herrn Daniel Thiele

für die vielen Freizeitstunden bei Entwicklung und Aufbau der RadioFaro-Module.


sensirion_logo.jpg

für die großzügige Bemusterung mit digitalen Feuchtesensoren vom Typ SHT21.
http://www.sensirion.com


ibdt_logo.png

für die Bereitstellung der Muse231-Prototypen.
http://www.ib-dt.de/

Referenzen

Backup Slides

Das Sensorprogramm (… etwas vereinfacht)

  #include <stdlib.h>
  #include "board.h"
  #include "radio.h"

  volatile app_evnt_t app_evnt;

  int main(void) {
      app_init();
      while (1) {
          app_task();
          do_sleep();
      }
  }

  static void app_init(void) {
      sensor_init();
      timer_init();
      radio_init(NULL, 0);
      app_event = APP_IDLE;
  }

  static void app_task(void) {
      if (app_event == APP_MEASURE) {
          run_measurement();
          radio_set_state(STATE_TXAUTO);
          radio_send_frame(sizeof(TxFrame), (uint8_t *) &TxFrame, 0);
          app_event = APP_IDLE;
      }
  }

  /* radio IRQ callback - startet timer nach senden des Rahmens */
  void usr_radio_tx_done(radio_tx_done_t status) {
      timer_start(tmr_transmit, T_TX_PERIOD, 0);
  }

  /* timer callback */
  time_t tmr_transmit(timer_arg_t t) {
      app_event = APP_MEASURE;
      return 0;
  }

Strombedarf Muse231 Sensorknoten



Table-Server (Prinzip) - tableserver.py

import SimpleHTTPServer
import SocketServer

GLOBDSLIST=[
 [ "vmcu", "Supply", "V"],
 [ "sht_t", "Temperature", "C" ],
 [ "sht_rh", "Humidity", "%" ],
]
# ...
def build_sensor_html_table():
  global RRDFILES
  x = glob.glob("%s/sensor_*.rrd" % WORKDIR)
  for fname in x:
    rdlast=rrdtool.last(fname)
    if time.time() - rdlast > 15:
      # ...
    else:
      rinfo = rrdtool.info(fname)
      for dsi in GLOBDSLIST:
        ik="ds[%s].last_ds" % (ds[0])
        if rinfo.has_key(ik):
          ret += "<td>%.3f</td>" % ( float(rinfo[ik]) )

# Http Server Class
class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
  def do_GET(self):
    self.send_response(200)
    self.send_header('Content-type','text/html')
    self.end_headers()
    txt = build_sensor_html_table()
    self.wfile.write(header() + txt + footer())

if __name__ == "__main__":
  httpd = SocketServer.ThreadingTCPServer(('', PORT),CustomHandler)
  httpd.serve_forever()

Heimautomatisierung - Prinzip

Automatisierungspyramide

Quelle: Wikipedia "Automatisierungspyramide"

Heimautomatisierung - Software

Screenshot Session

sensorserver-hotel.png