diff options
| author | Daniel Friesel <derf@finalrewind.org> | 2020-07-05 21:43:08 +0200 | 
|---|---|---|
| committer | Daniel Friesel <derf@finalrewind.org> | 2020-07-05 21:43:08 +0200 | 
| commit | ce0cd4bdafacbaee74eba78f15acccf5488a5a36 (patch) | |
| tree | 6f132917ed056d9ebcd7f9d5f73fa1c387f03204 /src/app | |
| parent | 9942173a2b46d5eb28fc41faf1627afc9929902d (diff) | |
add anemometer app
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/wetterstation/Makefile.inc | 1 | ||||
| -rwxr-xr-x | src/app/wetterstation/client.py | 108 | ||||
| -rw-r--r-- | src/app/wetterstation/main.cc | 44 | 
3 files changed, 153 insertions, 0 deletions
| diff --git a/src/app/wetterstation/Makefile.inc b/src/app/wetterstation/Makefile.inc new file mode 100644 index 0000000..2cb8a42 --- /dev/null +++ b/src/app/wetterstation/Makefile.inc @@ -0,0 +1 @@ +loop ?= 1 diff --git a/src/app/wetterstation/client.py b/src/app/wetterstation/client.py new file mode 100755 index 0000000..5bc2afc --- /dev/null +++ b/src/app/wetterstation/client.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 + +import numpy as np +import re +import requests +import serial +import serial.threaded +import sys +import time + +class SerialReader(serial.threaded.Protocol): +    """ +    Character- to line-wise data buffer for serial interfaces. + +    Reads in new data whenever it becomes available and exposes a line-based +    interface to applications. +    """ +    def __init__(self, callback): +        """Create a new SerialReader object.""" +        self.callback = callback +        self.recv_buf = '' + +    def __call__(self): +        return self + +    def data_received(self, data): +        """Append newly received serial data to the line buffer.""" +        try: +            str_data = data.decode('UTF-8') +            self.recv_buf += str_data + +            # We may get anything between \r\n, \n\r and simple \n newlines. +            # We assume that \n is always present and use str.strip to remove leading/trailing \r symbols +            # Note: Do not call str.strip on lines[-1]! Otherwise, lines may be mangled +            lines = self.recv_buf.split('\n') +            if len(lines) > 1: +                self.recv_buf = lines[-1] +                for line in lines[:-1]: +                    self.callback(str.strip(line)) + +        except UnicodeDecodeError: +            pass +            #sys.stderr.write('UART output contains garbage: {data}\n'.format(data = data)) + +class SerialMonitor: +    """SerialMonitor captures serial output for a specific amount of time.""" + +    def __init__(self, port: str, baud: int, callback): +        """ +        Create a new SerialMonitor connected to port at the specified baud rate. + +        Communication uses no parity, no flow control, and one stop bit. +        Data collection starts immediately. +        """ +        self.ser = serial.serial_for_url(port, do_not_open=True) +        self.ser.baudrate = baud +        self.ser.parity = 'N' +        self.ser.rtscts = False +        self.ser.xonxoff = False + +        try: +            self.ser.open() +        except serial.SerialException as e: +            sys.stderr.write('Could not open serial port {}: {}\n'.format(self.ser.name, e)) +            sys.exit(1) + +        self.reader = SerialReader(callback = callback) +        self.worker = serial.threaded.ReaderThread(self.ser, self.reader) +        self.worker.start() + +    def close(self): +        """Close serial connection.""" +        self.worker.stop() +        self.ser.close() + +if __name__ == '__main__': + +    got_data = False +    step = 0 + +    def parse_line(line): + +        global got_data + +        match = re.match('Anemometer Count = ([^ ]+)', line) +        if match: +            got_data = True +            wind_clicks = float(match.group(1)) +            windspeed_kmh = wind_clicks * 2.4 / 10 +            requests.post('http://influxdb:8086/write?db=sensors', data='anemometer,area=hm17_,location=balkon windspeed_kmh={}'.format(windspeed_kmh)) + +    monitor = SerialMonitor('/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.1:1.0-port0', 57600, parse_line) + +    try: +        while True: +            time.sleep(5) + +            step += 1 + +            if step == 4: +                if not got_data: +                    print('Error: received no data for 20 seconds', file=sys.stderr) +                    sys.exit(1) +                got_data = False +                step = 0 + +    except KeyboardInterrupt: +        monitor.close() diff --git a/src/app/wetterstation/main.cc b/src/app/wetterstation/main.cc new file mode 100644 index 0000000..2c47d78 --- /dev/null +++ b/src/app/wetterstation/main.cc @@ -0,0 +1,44 @@ +#include "arch.h" +#include "driver/gpio.h" +#include "driver/stdout.h" + +#include <avr/interrupt.h> + +volatile uint16_t anemometer_count = 0; + +void loop(void) +{ +	static uint8_t loop_count = 0; +	static uint16_t anemometer_copy; +	if (++loop_count == 10) { + +		cli(); +		anemometer_copy = anemometer_count; +		anemometer_count = 0; +		sei(); + +		kout << "Anemometer Count = " << anemometer_copy << endl; +		loop_count = 0; +	} +} + +int main(void) +{ +	arch.setup(); +	gpio.setup(); +	kout.setup(); + +	gpio.output(GPIO::pd2, 0); +	gpio.input(GPIO::pd3, 1); + +	EICRA = _BV(ISC11); +	EIMSK = _BV(INT1); + +	arch.idle_loop(); + +	return 0; +} + +ISR(INT1_vect) { +	anemometer_count++; +} | 
