Obsah

Raspberry PI

Mini počítač Raspberry PI lze jednoduše využít k logování naměřených hodnot na cloud Tmep.cz. Následující příklady počítají s nainstalovaným systémem RASPBIAN JESSIE (Release date: 2017-01-11).

Raspberry PI + DS18B20

Čidlo má celkem tři vývody (GND, DQ, VDD). Mezi napájení (VDD) a DQ je nutné připojit pull-up odpor o hodnotě 4k7. Komunikace s čidlem probíhá datově, délka vodičů tedy neovlivňuje naměřenou hodnotu. Reálně lze dosáhnout vzdálenosti 50m až 100m s použitím vhodné kabeláže. Na jedné sběrnici může být připojeno více čidel. Nejprve je nutné zprovoznit podporu 1-Wire sběrnice. V souboru /boot/config.txt zrušíme poznámku či doplníme následující nastavení:

dtoverlay=w1-gpio,gpiopin=4

Po restartu zařízení již bude funkční 1-wire sběrnice na GPIO 4. Pokud máme připojeno čidlo můžeme provést kontrolu:

ls /sys/bus/w1/devices/

V našem příkladu máme připojeno čidlo s unikátní výrobní adresou 0000070aeea3, 28 značí čidlo 18B20.

pi@raspberrypi:~ $ ls /sys/bus/w1/devices/
28-0000070aeea3  w1_bus_master1

Pro periodické ukládání hodnot na cloud Tmep.cz můžeme využít skript.

Nezapomeňte upravit proměnné GUID a SERVER dle aktuálního nastavení Tmep.cz

#!/bin/bash
 
# This script reads the temperature from all connected 1-wire temperature
# sensors of the DS1820 family.
# The script will answer nothing if it can't find any sensors.
#
# Author: San Bergmans
#         www.sbprojects.com
#
# Modified for Tmep.cz Petr Domorazek
#
 
GUID="1234567890"
 
SERVER="tst.tmep.cz"
 
W1DIR="/sys/bus/w1/devices"
 
# Exit if 1-wire directory does not exist
if [ ! -d $W1DIR ]
then
    echo "Can't find 1-wire device directory"
    exit 1
fi
 
# Get a list of all devices
DEVICES=$(ls $W1DIR)
 
# Loop through all devices
for DEVICE in $DEVICES
do
    # Ignore the bus master device
    if [ $DEVICE != "w1_bus_master1" ]
    then
        # Get an answer from this device
        ANSWER=$(cat $W1DIR/$DEVICE/w1_slave)
 
        # See if device really answered
        # When a previously existing device is removed it will
        # read 00 00 00 00 00 00 00 00 00, which results in a
        # valid CRC. That's why we need this extra test.
        echo -e "$ANSWER" | grep -q "00 00 00 00 00 00 00 00 00"
 
        if [ $? -ne 0 ]
        then
            # The temperature is only valid if the CRC matches
            echo -e "$ANSWER" | grep -q "YES"
            if [ $? -eq 0 ]
            then
                # Isolate the temprature from the second line
                TEMPERATURE=$(echo -e "$ANSWER" | grep "t=" | cut -f 2 -d "=")
                let TEMPE=$TEMPERATURE/100
                TEMPERATURE=$TEMPE
                # Isolate integer and fraction parts so we know where 
                # the decimal point should go
                INTEGER=${TEMPERATURE:0:(-1)}
                FRACTION=${TEMPERATURE:(-1)}
 
                # Restore the leading 0 for positive and negative numbers
                if [ -z $INTEGER ]
                then
                    INTEGER="0"
                fi
                if [ "$INTEGER" == "-" ]
                then
                    INTEGER="-0"
                fi
 
                # Write result of this sensor
                echo "$DEVICE=$INTEGER.$FRACTION"
                curl -s -H "Cache-Control: no-cache" $SERVER/?$GUID=$INTEGER.$FRACTION > /dev/null
            else
                # A CRC was found, show error message instead
                echo "$DEVICE=CRC error"
            fi
        fi
    fi
done

Pravidelným spouštěním každou minutu prostřednictvím plánovače zajistíte automatické ukládání hodnot.

crontab –e
# m h  dom mon dow   command
  * *   *   *   *    /home/pi/tmep.sh > /dev/null 2>&1


Raspberry PI s více DS18B20 na jedné sběrnici

Nezapomeňte upravit proměnou SERVER dle aktuálního nastavení Tmep.cz. GUID odpovídá unikátní adrese každého čidla.

#!/bin/bash
 
# This script reads the temperature from all connected 1-wire temperature
# sensors of the DS1820 family.
# The script will answer nothing if it can't find any sensors.
#
# Author: San Bergmans
#         www.sbprojects.com
#
# Modified for Tmep.cz Petr Domorazek
#
 
SERVER="tst.tmep.cz"
NAZEVCIDLA="cidlo"
NAZEVMERENI="&mojemereni"
 
W1DIR="/sys/bus/w1/devices"
 
# Exit if 1-wire directory does not exist
if [ ! -d $W1DIR ]
then
    echo "Can't find 1-wire device directory"
    exit 1
fi
 
# Get a list of all devices
DEVICES=$(ls $W1DIR)
 
# Loop through all devices
for DEVICE in $DEVICES
do
    # Ignore the bus master device
    if [ $DEVICE != "w1_bus_master1" ]
    then
        # Get an answer from this device
        ANSWER=$(cat $W1DIR/$DEVICE/w1_slave)
 
        # See if device really answered
        # When a previously existing device is removed it will
        # read 00 00 00 00 00 00 00 00 00, which results in a
        # valid CRC. That's why we need this extra test.
        echo -e "$ANSWER" | grep -q "00 00 00 00 00 00 00 00 00"
 
        if [ $? -ne 0 ]
        then
            # The temperature is only valid if the CRC matches
            echo -e "$ANSWER" | grep -q "YES"
            if [ $? -eq 0 ]
            then
                # Isolate the temprature from the second line
                TEMPERATURE=$(echo -e "$ANSWER" | grep "t=" | cut -f 2 -d "=")
                let TEMPE=$TEMPERATURE/100
                TEMPERATURE=$TEMPE
                # Isolate integer and fraction parts so we know where 
                # the decimal point should go
                INTEGER=${TEMPERATURE:0:(-1)}
                FRACTION=${TEMPERATURE:(-1)}
 
                # Restore the leading 0 for positive and negative numbers
                if [ -z $INTEGER ]
                then
                    INTEGER="0"
                fi
                if [ "$INTEGER" == "-" ]
                then
                    INTEGER="-0"
                fi
 
                # Write result of this sensor
                echo "$DEVICE=$INTEGER.$FRACTION"
                curl -s -H "Cache-Control: no-cache" $SERVER/?$NAZEVCIDLA=$DEVICE$NAZEVMERENI=$INTEGER.$FRACTION > /dev/null
            else
                # A CRC was found, show error message instead
                echo "$DEVICE=CRC error"
            fi
        fi
    fi
done


Raspberry PI + DHT22

Čidlo DHT22 též zakoupíte pod označením AM2302, či v jiném provedení pouzdra jako AM2301, AM2305 nebo AM2306. Z hlediska komunikace jsou tato čidla kompatibilní. Pouze DHT11 používá jiný formát dat a nelze ho s následujícím příkladem použít. DHT22 má celkem čtyři vývody (Vcc, DATA, NC, GND). Mezi napájení (Vcc) a DATA je nutné připojit pull-up odpor o hodnotě 4k7 až 10k. Komunikace s čidlem probíhá datově, délka vodičů tedy neovlivňuje naměřenou hodnotu. Reálně lze dosáhnout vzdálenosti až 30m s použitím vhodné kabeláže. Na rozdíl od teplotních čidel DS18B20 návrh komunikačního protokolu DHT22 nepočítá s více čidly na jedné datové sběrnici. Při potřebě připojení více čidel, připojte každé čidlo na samostatný GPIO. Následující návod počítá s čidlem DHT22 připojeným na GPIO22. Prostřednictvím následujících příkazů stáhněte a nainstalujte knihovnu Adafruit Python DHT Sensor Library:

sudo apt-get install git
cd ~
git clone https://github.com/adafruit/Adafruit_Python_DHT.git
cd Adafruit_Python_DHT
sudo apt-get update
sudo apt-get install build-essential python-dev
sudo python setup.py install

Komunikaci s čidlem vyzkoušíme pomocí následujících příkazů:

cd examples
sudo ./AdafruitDHT.py 22 22

Prostřednictvím editoru vytvořte skript v jazyku Python:

cd ~
nano ./tmep_DHT.py

Nezapomeňte upravit proměnné GUID a SERVER dle aktuálního nastavení Tmep.cz

#!/usr/bin/python
import Adafruit_DHT, socket, urllib2, sys
 
GUID = '1234567890'
SERVER = 'tst.tmep.cz'
 
# sensor 22 = DHT22, pin 22 = GPIO 22
humidity, temperature = Adafruit_DHT.read_retry(22, 22)
 
if humidity is not None and temperature is not None:
    temperature = round(temperature, 1)
    humidity = round(humidity, 1)
    url = 'http://' + SERVER + '?' + GUID + '=' + str(temperature) + '&humV=' + str(humidity)
    print(url)
    urllib2.urlopen(url)
else:
    print('Failed to get reading. Try again!')
    sys.exit(1)

Přidejte souboru právo spuštění a můžete ho vyzkoušet:

chmod +x ./tmep_DHT.py
./tmep_DHT.py

Pravidelným spouštěním každou minutu prostřednictvím plánovače zajistíte automatické ukládání hodnot:

crontab -e
*   *   *   *   *      ./tmep_DHT.py > /dev/null 2>&1


Raspberry PI + SHT21

SHT21 je teplotní a vlhkostní čidlo o velikosti 3x3mm, které se obvykle prodává na osazené PCB. Komunikační rozhraní je sběrnice I2C. Čidlo vykazuje přesnější měření (především vlhkosti) než DHT22. Datová sběrnice I2C není vhodná pro delší vzdálenosti. Nejprve je nutné zprovoznit podporu I2C sběrnice. V souboru /boot/config.txt zrušíme poznámku či doplníme následující nastavení:

dtparam=i2c_arm=on

Přidáme i2c-dev do zaváděných modulů a doinstalujeme i2c-tools:

sudo echo 'i2c-dev' >> /etc/modules
sudo apt-get install i2c-tools

Po restartu zařízení již bude funkční I2C sběrnice na pinech 2 a 3. Pokud máme připojeno čidlo, můžeme provést kontrolu:

sudo i2cdetect -y 1

Při přítomnosti čidla se zobrazí adresa 0x40:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Prostřednictví těchto příkazů stáhněte knihovnu sht21_python a vytvořte soubor tmep_sht21.py:

sudo apt-get install git
cd ~
git clone https://github.com/jaques/sht21_python.git
cd sht21_python
nano ./tmep_sht21.py

Skript tmep_sht21.py:

Nezapomeňte upravit proměnné GUID a SERVER dle aktuálního nastavení Tmep.cz

#!/usr/bin/python
 
import sht21, socket, urllib2, sys
 
GUID = '1234567890'
SERVER = 'tst.tmep.cz'
 
try:
    with sht21.SHT21(1) as sht21:
	temperature = sht21.read_temperature()
	humidity = sht21.read_humidity()
 
    temperature = round(temperature, 1)
    humidity = round(humidity, 1)
    url = 'http://' + SERVER + '?' + GUID + '=' + str(temperature) + '&humV=' + str(humidity)
    print(url)
    urllib2.urlopen(url)
 
except IOError, e:
    print e
    print "Error creating connection to i2c.  This must be run as root"
    sys.exit(1)

Přidejte práva pro spouštění a můžete skript otestovat:

chmod +x ./tmep_sht21.py
./tmep_sht21.py

Pravidelným spouštěním každou minutu prostřednictvím plánovače zajistíte automatické ukládání hodnot:

sudo crontab -e
*   *   *   *   *      /home/pi/sht21_python/tmep_sht21.py > /dev/null 2>&1

Raspberry s HTU21DF a OLED displejem

Příklad od mikroma.

Web autora příkladu: http://mikrom.cz/
Kontakt na autora: mikrom@mikrom.cz

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
# Author: mikrom, 2018
#
# Based on:
# https://github.com/rm-hull/luma.oled
# https://github.com/dalexgray/RaspberryPI_HTU21DF
# https://github.com/al45tair/netifaces
# https://github.com/httplib2/httplib2
#
# HTU21DF needs to run $sudo pigpiod
# tmep.sh added to $sudo nano /etc/rc.local
 
from oled.serial import i2c
from oled.device import sh1106
from oled.render import canvas
from PIL import ImageFont, ImageDraw
import time #from time import sleep <- do not use this
import HTU21DF
import netifaces as ni
import httplib2
 
# Settings
sleep = 5                                    # Time between two measuring cycles (seconds)
url = "http://tmep.server.url/?"             # Server url (ending with question mark)
guid = "guid"                                # Secret guid
rotation = 0                                 # Display rotation 0=no, 1=90, 2=180, 3=270
fontname = "BRBELRT0.ttf"                    # Font name
fontsize = 18                                # Font size
serial = i2c(port=1, address=0x3C)           # Do not touch
device = sh1106(serial, rotate=rotation)     # Change it to ssd1306 if you have more common display
ni.ifaddresses('eth0')                       # Probably no need to change it (maybe to wlan0)
font = ImageFont.truetype("/home/pi/fonts/" + fontname, fontsize) # specify where your fonts are stored
 
# Run infinitely
while True:
  # Get temperature and humidity from HTU21D
  HTU21DF.htu_reset                          # Reset sensor first
  temp = "%.1f" % HTU21DF.read_temperature() # Round float to 1 decimal and convert to string
  time.sleep(1)                              # Sensor is slow, so add some delay
  hum = "%.0f" % HTU21DF.read_humidity()     # Round float to 0 decimal and convert to string
  print("Temp=" + temp + "C")
  print("Hum=" + hum + "%")
 
  # Get IP address from netifaces
  ip = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
  print("IP=" + ip)
 
  # Display data on OLED
  with canvas(device) as draw:
    temperature = "Temp: " + temp + u"\N{DEGREE SIGN}C"        # Prepare string to display. Degree sign is little bit challenging to add :)
    w, h = font.getsize(temperature)                           # Get dimensions of the string
    draw.text(((128-w)/2,0), temperature, font=font, fill=255) # Just some positioning, it is centered by x and y=0
    humidity = "Hum: " + hum + "%"                             # Prepare string to display. 
    w, h = font.getsize(humidity)                              # Get dimensions of the string
    draw.text(((128-w)/2,20), humidity, font=font, fill=255)   # Just some positioning, it is centered by x and y=20
    w, h = font.getsize(ip)                                    # Get dimensions of the string
    draw.text(((128-w)/2,40), ip, font=font, fill=255)         # Just some positioning, it is centered by x and y=40
 
  # Send data to tmep server
  requesturl = url + guid + "=" + temp + "&humV=" + hum
  print("Send to: " + requesturl)
  resp, content = httplib2.Http().request(requesturl)
  if resp.status == 200:
    print("Send OK")
  else:
    print("Send Error")
 
  # Take a nap
  print("Go to sleep for %d s..." % sleep)
  time.sleep(sleep)