BPI-R2/R3 and SSD1306 oled screen

Cannot test on real display and currently disabled icons (to make it easier to run code without icons).i guess furumc and i need smaller icons because we have (i have ordered) 2 color displays. And it looks like yellow is ~16px top and blue 3/4 below

Try here for monochrome icons: flaticon.com. Iā€™ve already selected icons and black-filled filters to aid your process. All you have to do is find the icon(s) you want. They will allow you to select the size of icon you want to download.

is there an easy way to reduce colors (1 bit) and invert them (make black to white)?

you have already white icons, but all iā€™ve found are blackā€¦

icons16.zip (3,0 KB)

i think i got it solved using pillow based on https://note.nkmk.me/en/python-pillow-invert/:

def loadinvert(f):
    iconpath = os.path.dirname(__file__)
    im = Image.open(iconpath+"/"+f).convert('RGB')
    return ImageOps.invert(im).convert('1')

globe = loadinvert('earth16.png')

this works for my earth-icon but not for wifi/phone :frowning:

wifi works if i first convert to 1bit, then to rgb, then invert, but phone still shows only a white square. Seems like i need to change it manually

Maybe this page has an answer: How to invert colors of image with PIL (Python-Imaging)?

Personally, I used GIMP to invert the colors before saving them to PNG. Having that functionality in Python would be greatā€¦ My router image doesnā€™t have the script installed, so I canā€™t test at the moment.

EDIT: I donā€™t think that you should convert to RGB at any point during this processā€¦ I could be mistaken, thoughā€¦

i had problems with the phone-icon also in other editors (e.g. gnome-paint). have now also used gimp (need to redraw the globe completely)

  • colors-invert
  • image-mode-indexed to get it into 1bit

icons-white.zip (7,8 KB)

Btw. Convert to rgb was necessary for the invertā€¦see link above

My new Docker image has been uploadedā€¦

EDIT: Sorry, fixed the link to the repository!

i have uploaded my last version, maybe you can try on your display as i still waiting for it

simply uncomment

use_disp=True

currently working on voip-detection which is a bit tricky because r2 only moves traffic from ppp-interface to a external Voip-adapter. so i need to count sip-packets with an iptables rule, log it every 5 min to a file, read last 2 values from this file and calc differenceā€¦if this (packets in last full 5min block) is >0 (or maybe more) then i expect, the voip-adapter is logged in

i do this check after some basic checks like

ip link sh ppp9 | grep ,UP, >/dev/null;echo $? #check state of voip-interface
ping -c 1 192.168.0.8 >/dev/null;echo $? #check if voip-adapter is reachable
ip rule show | grep voip >/dev/null;echo $? #check if rule is set
ip route show | grep ppp9 >/dev/null;echo $? #check routing table for voip interface

slightly modified:

ip link sh ppp9 | grep ,UP, >/dev/null;u=$?
ping -c 1 192.168.0.8 >/dev/null;p=$?
ip rule show | grep voip >/dev/null;ru=$?
ip route show | grep ppp9 >/dev/null;ro=$?

res=$(($u + $p<<8 + $ru<<16 + $ro<<24)) #shifting each result 8bits (return value can be 255 max)
if [[ $res -eq 0 ]];then echo "all ok";fi

traffic-monitoring (in case anyone will do something similar):

#rules to monitor traffic
${ipt} -N voip1
${ipt} -N voip2
${ipt} -A FORWARD -s 192.168.0.8 -p udp --dport 5160 -j voip1
${ipt} -A FORWARD -d 192.168.0.8 -p udp --dport 5160 -j voip1
${ipt} -A FORWARD -s 192.168.0.8 -p udp --sport 5161 -j voip2
${ipt} -A FORWARD -d 192.168.0.8 -p udp --dport 5161 -j voip2
${ipt} -A voip1 -j ACCEPT
${ipt} -A voip2 -j ACCEPT

#read out (cronjob every 5 min)
iptables-legacy -L voip1 -v -nx  | grep 'ACCEPT' | awk '{print $1}' >>$logdir/voip1.log
iptables-legacy -L voip2 -v -nx  | grep 'ACCEPT' | awk '{print $1}' >>$logdir/voip2.log

#calculate difference (actually i have 40 packets on voip1 and 20packets on voip2, don't know why it is the half...)
bash -c 'str=$(tail -2 /var/log/voip1.log);ar=($str);res=$(( ${ar[1]} - ${ar[0]} ));echo $res'

I tried to rebase my changes on your latest state (i hope i have not break anything) and created pull request.

@furumc can you retest with pr branch in my repo?

I will do it! Which pr branch do you mean?

Strange it is not shown in dropdown on githubā€¦

have ordered a display from germany because the cn one is still not arrivedā€¦the german is now connected. but i donā€™t see i2c-bus in 5.11-mainā€¦any idea?

i2cdetect -y 2
Error: Could not open file `/dev/i2c-2' or `/dev/i2c/2': No such file or directory

and yes i have no /dev/i2c* on my test-device

zgrep 'I2C' /proc/config.gz | grep '=[ym]'                   
CONFIG_REGMAP_I2C=y                                                             
CONFIG_I2C=y                                                                    
CONFIG_I2C_BOARDINFO=y                                                          
CONFIG_I2C_COMPAT=y                                                             
CONFIG_I2C_CHARDEV=m                                                            
CONFIG_I2C_HELPER_AUTO=y                                                        
CONFIG_I2C_ALGOBIT=y                                                            
CONFIG_I2C_MT65XX=y                                                             
CONFIG_VIDEO_V4L2_I2C=y                                                         
CONFIG_VIDEO_IR_I2C=y                                                           
CONFIG_SND_SOC_I2C_AND_SPI=y                                                    
CONFIG_RTC_I2C_AND_SPI=y

see nothing i2c-related on dmesg :frowning:

got itā€¦need to load chardev-module

modprobe i2c-dev

but i do not see the displayā€¦

root@bpi-r2:~# i2cdetect -y 2                                                                                                    
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f                                                                              
00:          -- -- -- -- -- -- -- -- -- -- -- -- --                                                                              
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                                                                              
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                                                                              
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                                                                              
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                                                                              
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                                                                              
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                                                                              
70: -- -- -- -- -- -- -- --

i have connected it to 3V3 (pin 1+9) and use also i2c2 (27+28). should it show anything on only power connected? also tried swapping 27+28

mhm, simply did the echo and it works

echo "ssd1306 0x3C" > /sys/class/i2c-adapter/i2c-2/new_device

add user (which wants to run the script) to i2c-group

adduser frank i2c

and needed to change the iconpath-line a bit

iconpath = os.path.dirname(os.path.abspath(__file__))

and run

python3 stats.py

donā€™t know why i2cdetect donā€™t show the device

Iā€™ve faced exactly with this in the past! Do you remember, on my r2 hdmi collapsed after running i2c-detect? You have figured out, i2c-detect wonā€™t detect it, you have to add it manually as device!

Can I choose pr branch from drop-down menu yet?

no, i guess on github the branch is interpreted as pullrequest because of name pr and filtered out

but you can access it via the link https://github.com/frank-w/bpi-r2-ssd1306-display/tree/pr or by cloning my repo and switching to it by ā€œgit checkout prā€

if i use -r flag of i2cdetect, display is shown

root@bpi-r2:~# i2cdetect -y -r 2                                                                                                 
     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: -- -- -- -- -- -- -- --

i moved some code in functions and added a uptime (currently not displayed)

Pull request has been merged. Thanks!

i hope it does not break anything with your iconsā€¦

btw. is there any larger display which can be used the same way? i saw some larger displays on ebay, but iā€™m unsure they will work like this (which is very small)

e.g. this: https://www.ebay.de/itm/2-4-Serial-UART-I2C-SPI-IPS-Super-TFT-320x240-Display-Module-for-Arduino/371812222044

btw. pip should be installed in debian with

apt install --no-install-recommends python3-pip

else many tools/libs get installed you donā€™t want on a router (gcc,g++,build-essential,cpp,make, *-dev)

Zusammenfassung
Die folgenden zusƤtzlichen Pakete werden installiert:
  binutils binutils-arm-linux-gnueabihf binutils-common build-essential bzip2
  cpp cpp-8 dh-python dpkg-dev fakeroot g++ g++-8 gcc gcc-8 gir1.2-glib-2.0
  libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl
  libasan5 libatomic1 libbinutils libc-dev-bin libc6-dev libcc1-0 libdpkg-perl
  libexpat1-dev libfakeroot libfile-fcntllock-perl libgcc-8-dev
  libgirepository-1.0-1 libgomp1 libisl19 libmpc3 libmpfr6 libpython3-dev
  libpython3.7 libpython3.7-dev libstdc++-8-dev libubsan1 linux-libc-dev make
  manpages manpages-dev patch python-pip-whl python3-asn1crypto
  python3-cffi-backend python3-crypto python3-cryptography python3-dbus
  python3-dev python3-distutils python3-entrypoints python3-gi python3-keyring
  python3-keyrings.alt python3-lib2to3 python3-pkg-resources
  python3-secretstorage python3-setuptools python3-six python3-wheel
  python3-xdg python3.7-dev
Vorgeschlagene Pakete:
  binutils-doc bzip2-doc cpp-doc gcc-8-locales debian-keyring gcc-8-doc
  libstdc++6-8-dbg gcc-multilib autoconf automake libtool flex bison gdb
  gcc-doc libgcc1-dbg libgomp1-dbg libitm1-dbg libatomic1-dbg libasan5-dbg
  liblsan0-dbg libtsan0-dbg libubsan1-dbg libmpx2-dbg libquadmath0-dbg
  glibc-doc bzr libstdc++-8-doc make-doc ed diffutils-doc python-crypto-doc
  python-cryptography-doc python3-cryptography-vectors python-dbus-doc
  python3-dbus-dbg gnome-keyring libkf5wallet-bin gir1.2-gnomekeyring-1.0
  python-secretstorage-doc python-setuptools-doc
Die folgenden NEUEN Pakete werden installiert:
  binutils binutils-arm-linux-gnueabihf binutils-common build-essential bzip2
  cpp cpp-8 dh-python dpkg-dev fakeroot g++ g++-8 gcc gcc-8 gir1.2-glib-2.0
  libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl
  libasan5 libatomic1 libbinutils libc-dev-bin libc6-dev libcc1-0 libdpkg-perl
  libexpat1-dev libfakeroot libfile-fcntllock-perl libgcc-8-dev
  libgirepository-1.0-1 libgomp1 libisl19 libmpc3 libmpfr6 libpython3-dev
  libpython3.7 libpython3.7-dev libstdc++-8-dev libubsan1 linux-libc-dev make
  manpages manpages-dev patch python-pip-whl python3-asn1crypto
  python3-cffi-backend python3-crypto python3-cryptography python3-dbus
  python3-dev python3-distutils python3-entrypoints python3-gi python3-keyring
  python3-keyrings.alt python3-lib2to3 python3-pip python3-pkg-resources
  python3-secretstorage python3-setuptools python3-six python3-wheel
  python3-xdg python3.7-dev

currently facing issues maybe because of thisā€¦python tries to compile some c-filesā€¦maybe i need to setup an chroot to compile these and copy back the built filesā€¦or drop the compile-packages after install

apt install --no-install-recommends binutils binutils-arm-linux-gnueabihf binutils-common build-essential bzip2 cpp cpp-8 dh-python dpkg-dev fakeroot g++ g++-8 gcc gcc-8 python3-dev python3-setuptools python3-wheel

run pip install and then uninstall build-packages

apt remove --purge binutils binutils-arm-linux-gnueabihf binutils-common build-essential cpp cpp-8 dh-python dpkg-dev fakeroot g++ g++-8 gcc gcc-8 python3-dev libexpat1-dev libpython3-dev libpython3.7 libpython3.7-dev python3-dev python3.7-dev
apt autoremove --purge

Maybe compilation can be avoided by using

pip install --only-binary=:all: <pkgname>

by default the i2c-devices have group root till you install i2c-tools, you can create an i2c-group manually (before adding your user to i2c-group) but i2c-utils should be no security problem

seems like there is no binary package of ADAFRUIT-* available for armhf

but my installation on my test-device has created whl-files which can be installed directly

python3 -m pip install --no-index --find-links=~/whl psutil Adafruit-SSD1306 Adafruit-BBIO

i will add the whl-files to my repo soon

Canā€™t say if this python script would work with itā€¦ I bought my SSD1306 cause it was small and fits on the front of the BPI-R2 metal enclosure from China. With a little modification (which I havenā€™t done yet), it looks like it might fit in the IR and lights window. I wouldā€™ve bought a bigger one, but it wanted a front-facing display and that limited my options on purchasing.

Hmmmm, that would be much nicer to have the script running on barebones instead of a docker containerā€¦

started the script now on my routerā€¦seems like the interfaceUp does not work for ppp-interfacesā€¦

$ cat /sys/class/net/ppp8/operstate 
unknown
$ ip link sh ppp8
54: ppp8: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 3
    link/ppp

i changed the condition to throw exception if state is down (instead of !=ā€œupā€)

Have now other wan-ipv4

imho for wifi we need to check hostapd tooā€¦as interface can be up without hostapd running so not functional. It will be tricky to match hostapd processes to interfacesā€¦maybe read config files on start to get filename for specific interface and the read processes with config in cmdline

Something like this: hostapd.py (649 Bytes)

added the code (with prepared debug) to my github repo

after switching from iptables to nftables i do this part now like this:

table ip filter {
	chain FORWARD {
		type filter hook forward priority 0; policy drop;
		...
		ip saddr 192.168.0.8 udp dport 5160 counter name "voip1" comment "counting packets for SIP1"
		ip daddr 192.168.0.8 udp dport 5160 counter name "voip1" comment "counting packets for SIP1"
		ip saddr 192.168.0.8 udp sport 5161 counter name "voip2" comment "counting packets for SIP2"
		ip daddr 192.168.0.8 udp dport 5161 counter name "voip2" comment "counting packets for SIP2"
	}
	counter voip1 {
	}
	counter voip2 {
	}
}

and readout with python-script:

import os
import json

logdir="/var/log/"

def getCounter(countername):
    stream = os.popen('nft list counter filter '+countername+' -j')
    output = stream.read()
    #print(output)
    j=json.loads(output)
    #return j["nftables"][0]["counter"]["bytes"]
    return j["nftables"][0]["counter"]["packets"]

v1=getCounter("voip1")
v2=getCounter("voip2")

with open(logdir+"voip1.log", "a") as f:
    f.write(str(v1)+"\n")
with open(logdir+"voip2.log", "a") as f:
    f.write(str(v2)+"\n")

i know there is a nftables module for python, but i wanted to have less depencies

calculation of last 2 values in both files is same as before

FYI, got display working on r3 working too with module luma-oled

https://luma-oled.readthedocs.io/en/latest/python-usage.html

pip3 install luma-oled

if connected the right way (pins 1=vcc,3=sda,5=scl,6=gnd) it should be visible in i2cdetect at address 0x3c

root@bpi-r3:~# apt install i2c-tools
root@bpi-r3:~# i2cdetect -y -r 2

python-module still needs compile-tools which i try to avoid, but have not yet found a way for this (only install and deinstall after installing python-module)

oled_connection2

photo shows the example from the documentation linked above on my r3

(.venv_display) frank@bpi-r3:~$ python3                                                                                              
Python 3.9.2 (default, Feb 28 2021, 17:03:44)                                                                                        
[GCC 10.2.1 20210110] on linux                                                                                                       
Type "help", "copyright", "credits" or "license" for more information.                                                               
>>> from luma.core.interface.serial import i2c                                                                                       
>>> from luma.core.render import canvas                                                                                              
>>> from luma.oled.device import ssd1306                                                                                             
>>> serial = i2c(port=2, address=0x3C)                                                                                               
>>> device = ssd1306(serial)                                                                                                         
>>> with canvas(device) as draw:                                                                                                     
...     draw.rectangle(device.bounding_box, outline="white", fill="black")                                                           
...     draw.text((30, 40), "Hello World", fill="white")
1 Like