Page 1 of 1

WiringCB-python + OLED + BMP180

Posted: 22 August 2015, 19:41 - Sat
by pancio
Dzisiejszy tutorial dotyczy obsługi I2C (TWI) w CB/CT. Przykładowo obsłużymy wyświetlacz OLED ze sterownikiem SSD1306 (koszt 3$ z transportem) oraz czujnik ciśnienia i temperatury BMP180 ( 2$ ).
096_oled.jpg
096_oled.jpg (25.85 KiB) Viewed 28976 times
BMP180.jpg
BMP180.jpg (59.62 KiB) Viewed 28976 times
Zaczynamy

Przestroga 1.
Wszystkie operacje wykonuję jako uprzywilejowany użytkownik root . Nie jest to dobra praktyka więc proponuję używać sudo i wykonywać wszystkie komendy z poziomu normalnego użytkownika...


Uwaga.
Dystrybucja, której używam to kompilacja ze źródeł CTDebian Igora Pecovnik-a: http://www.igorpecovnik.com/2013/12/24/ ... ard-image/. Możesz pobrać najnowszą wersję ze strony Igora lub skorzystać z mojej kompilacji: files/img/Cubietruck_Debian_4.1_jessie_3.4.108.zip


Przestroga 2
Wszystko co robisz - robisz na własną odpowiedzialność. W trakcie tutoriala wykonywane są czynności, które mogą uszkodzić twoje urządzenie...




Identyfikacja urządzeń I2C

Cubietruck posiada 3 magistrale I2C, jednak ich obsługa musi być uaktywniona w konfiguracji (script.bin). Ja używam płytki developerskiej DVK570 i tu magistrala I2C jest skonfigurowana jako twi1 (odpowiednio: scl = port:PB18 i sda = port:PB19). Jeśli korzystasz z innej dystrybucji i/lub modułu developerskiego, musisz sprawdzić jak i gdzie twój CB/CT obsługuje magistrale...

Aby sprawdzić jakie urządzenia są wykrywane na magistrali:

Code: Select all

root@cubietruck:~# i2cdetect -y 1
root@cubietruck:~# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@cubietruck:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@cubietruck:~# 
W powyższym przypadku nie wykryliśmy żadnych urządzeń na magistrali... powód? Jak wspomniałem powyżej - domyślna konfiguracja script.bin brandu Igora nie obsługuje twi1. Zmieńmy konfigurację:

Code: Select all

root@cubietruck:~# bin2fex /boot/script.bin > /boot/script.fex
root@cubietruck:~# cd /boot/
root@cubietruck:/boot# ls
boot.axf  boot.ini  linux  magic.bin  script.bin  script.fex  uEnv.txt	uImage

root@cubietruck:/boot# vim script.fex 
Teraz odnajdujemy:

Code: Select all

[twi0_para]
twi0_used = 1
twi0_scl = port:PB00<2><default><default><default>
twi0_sda = port:PB01<2><default><default><default>

[twi1_para]
twi1_used = 0
twi1_scl = port:PB18<2><default><default><default>
twi1_sda = port:PB19<2><default><default><default>

[twi2_para]
twi2_used = 0
twi2_scl = port:PB20<2><default><default><default>
twi2_sda = port:PB21<2><default><default><default>
i zamieniamy na:

Code: Select all

[twi0_para]
twi0_used = 1
twi0_scl = port:PB00<2><default><default><default>
twi0_sda = port:PB01<2><default><default><default>

[twi1_para]
twi1_used = 1
twi1_scl = port:PB18<2><default><default><default>
twi1_sda = port:PB19<2><default><default><default>

[twi2_para]
twi2_used = 0
twi2_scl = port:PB20<2><default><default><default>
twi2_sda = port:PB21<2><default><default><default>
Zapisujemy binarną formę konfiguracji i reboot:

Code: Select all

root@cubietruck:/boot# fex2bin script.fex script.bin 
root@cubietruck:/boot# reboot

Po restarcie ponownie sprawdzamy dostępne urządzenia I2c:

Code: Select all

pancio@plapik ~ $ ssh root@192.168.3.15
root@192.168.3.15's password: 

  ____      _     _      _                   _    
 / ___|   _| |__ (_) ___| |_ _ __ _   _  ___| | __
| |  | | | | '_ \| |/ _ \ __| '__| | | |/ __| |/ /
| |__| |_| | |_) | |  __/ |_| |  | |_| | (__|   < 
 \____\__,_|_.__/|_|\___|\__|_|   \__,_|\___|_|\_\
                                                  

Last login: Sat Aug 22 16:44:43 2015 from plapik

Load: 0.93, 0.25, 0.08 - Board: 23.4°C - Drive: 30°C - Memory: 1963Mb

root@cubietruck:~# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@cubietruck:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- 77                         
root@cubietruck:~#
Wykryliśmy 2 urządznia:

adres 0x3c - wyświetlacz OLED
adres 0x77 - czujnik ciśnienia BMP180



WiringCB-python

Na początku update systemu:

Code: Select all

aptitude update;aptitude upgrade
... i wszystko co jest wymagane...:

Code: Select all

aptitude install python-dev python-setuptools swig
aptitude install python-smbus python-pip
Właściwy pakiet pobierzemy i zainstalujemy z repo GitHub-a:

Code: Select all

git clone https://github.com/gootoomoon/WiringCB-python.git
cd WiringCB-python

python setup.py install
Na tym etapie powinniśmy już móc używać WiringCB, działanie można sprawdzić wykonując po drobnej modyfikacji pliki z katalogu examples.



BMP180

Pobieramy paczke (kopia w dziale: Dowload) i rozpakowujemy:

Code: Select all

root@cubietruck:~# mkdir BMP180
root@cubietruck:~# cd BMP180
root@ctdev:~/BMP180# wget https://dl.dropboxusercontent.com/u/2379893/blogspot/blogspot-bmp085.tar
root@ctdev:~/BMP180# tar -xf blogspot-bmp085.tar 

root@ctdev:~/BMP180# ls -al
total 6
drwx------  7 root root  4096 Aug 22 17:47 .
drwxr-xr-x 21 root root  4096 Jan  1  2010 ..
-rwxrwxrwx  1 root root  8231 May 21  2014 Adafruit_BMP085.py
-rwxrwxrwx  1 root root  4586 May 21  2014 Adafruit_I2C.py
-rwxrwxrwx  1 root root  1654 May 21  2014 barometer.py
-rw-r--r--  1 root root 17920 Aug 22 17:46 blogspot-bmp085.tar
root@ctdev:~/BMP180#
czas na pierwszy test:

Code: Select all

root@ctdev:~/BMP180# ./barometer.py 
2015-08-22 20:39:20	Temperature 26.10C	Pressure: 98616Pa	AltPressure: 100388Pa	Altitude: 228.109271m
root@ctdev:~/BMP180# 
SUKCES! Czas na wyświetlacz...



Obsługa OLED ze sterownikiem SSD1306

Pobieramy i instalujemy paczke z GitHub-a:

Code: Select all

root@cubietruck:~# git clone https://github.com/rm-hull/ssd1306.git
root@cubietruck:~# cd ssd1306
root@cubietruck:~/ssd1306# ls
	doc  examples  fonts  LICENSE.md  oled	README.md  setup.py
	
root@cubietruck:~/ssd1306# python setup.py install
Instalujemy wymagane paczki:

Code: Select all

root@cubietruck:~/ssd1306# pip install pillow
root@cubietruck:~/ssd1306# pip install psutil
ten ostatni moduł (psutil) wymagany jest do odczytu pewnych systemowych zmiennych inie jest wymagany jako taki...

odpalamy i sprawdzamy działanie wyświetlacza:

Code: Select all

root@cubietruck:~/ssd1306# python examples/demo.py
IMG_20150822_213155_mini.jpg
IMG_20150822_213155_mini.jpg (138.88 KiB) Viewed 28976 times


Łączymy wszystko razem

Code: Select all

root@ctdev:~# cp BMP180/Adafruit_BMP085.py ssd1306/examples/.
root@ctdev:~# cp BMP180/Adafruit_I2C.py ssd1306/examples/.
root@ctdev:~# cd ssd1306/examples/
Tworzymy nowy plik:

Code: Select all

root@ctdev:~/ssd1306/examples# vim temp_press.py
i wklejamy:

Code: Select all

#!/usr/bin/env python

import os
import sys
import string

if os.name != 'posix':
    sys.exit('platform not supported')
import psutil

import datetime
from oled.device import ssd1306, sh1106
from oled.render import canvas
from PIL import ImageDraw, ImageFont

from Adafruit_BMP085 import BMP085

# Initialise the BMP085 and use STANDARD mode (default value)
# bmp = BMP085(0x77, debug=True)
bmp = BMP085(0x77)

# To specify a different operating mode, uncomment one of the following:
# bmp = BMP085(0x77, 0)  # ULTRALOWPOWER Mode
# bmp = BMP085(0x77, 1)  # STANDARD Mode
# bmp = BMP085(0x77, 2)  # HIRES Mode
bmp = BMP085(0x77, 3)  # ULTRAHIRES Mode

temp = bmp.readTemperature()

# Read the current barometric pressure level
pressure = bmp.readPressure()

# To calculate altitude based on an estimated mean sea level pressure
# (1013.25 hPa) call the function as follows, but this won't be very accurate
altitude = bmp.readAltitude()

# To specify a more accurate altitude, enter the correct mean sea level
# pressure level.  For example, if the current pressure level is 1023.50 hPa
# enter 102350 since we include two decimal places in the integer value
# altitude = bmp.readAltitude(102350)

altitute_in_cm = 15000  # 150 m in cm
altPressure = pressure / pow((1 - altitute_in_cm / float(4433000)), 5.255)

#print "Temperature: %.2f C" % temp
#print "Pressure:    %.2f hPa" % (pressure / 100.0)
#print "AltPressure: %.2f hPa" % (altPressure / 100.0)
#print "Altitude:    %.2f" % altitude

#temp_tmp1 = str(temp) 

print "Temperature %.2fC\t" % temp
print temp
print "Pressure: %dPa\t" % pressure, 
print "AltPressure: %dPa\t" % altPressure
print "Altitude: %fm" % altitude


# TODO: custom font bitmaps for up/down arrows
# TODO: Load histogram



def bytes2human(n):
    """
    >>> bytes2human(10000)
    '9K'
    >>> bytes2human(100001221)
    '95M'
    """
    symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
    prefix = {}
    for i, s in enumerate(symbols):
        prefix[s] = 1 << (i+1)*10
    for s in reversed(symbols):
        if n >= prefix[s]:
            value = int(float(n) / prefix[s])
            return '%s%s' % (value, s)
    return "%sB" % n

def temp2oled(temp):
	temp_msg = "Temp: " +str(temp) +str(" C")
	return temp_msg

def stats(oled):
    font = ImageFont.load_default()
    with canvas(oled) as draw:
        draw.text((0, 0), "Temp:", font=font, fill=255)
        draw.text((0, 8), str("     ") +str(temp) +str(" C"), font=font,fill=255)
        draw.text((0, 16), "Press:", font=font, fill=255)
        draw.text((0, 24), str("     ") +str(pressure) +str(" Pa"), font=font,fill=255)
        draw.text((0, 32), "Altitude:", font=font, fill=255)
        draw.text((0, 40), str("     ") +str(altitude) +str(" m"), font=font,fill=255)
def main():
    oled = ssd1306(port=1, address=0x3C)
    stats(oled)

if __name__ == "__main__":
    main()
a na koniec uruchamiamy....

Code: Select all

root@ctdev:~/ssd1306/examples# python temp_press.py
BMP180_OLED.jpg
BMP180_OLED.jpg (111.39 KiB) Viewed 28976 times
... dodajemy kolejne sensory etc.. etc...