Created
September 1, 2020 07:17
-
-
Save pingud98/f3c9f4dbcc0d3860f89034f83c4e9702 to your computer and use it in GitHub Desktop.
I2C LCD display scripts for Friendlyelec NanoPi NEO2 based NAS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# Original code found at: | |
# https://gist.github.com/DenisFromHR/cc863375a6e19dce359d | |
""" | |
Compiled, mashed and generally mutilated 2014-2015 by Denis Pleic | |
Made available under GNU GENERAL PUBLIC LICENSE | |
# Modified Python I2C library for Raspberry Pi | |
# as found on http://www.recantha.co.uk/blog/?p=4849 | |
# Joined existing 'i2c_lib.py' and 'lcddriver.py' into a single library | |
# added bits and pieces from various sources | |
# By DenisFromHR (Denis Pleic) | |
# 2015-02-10, ver 0.1 | |
""" | |
# i2c bus (0 -- original Pi, 1 -- Rev 2 Pi) | |
I2CBUS = 0 | |
# LCD Address | |
ADDRESS = 0x27 | |
import smbus | |
from time import sleep | |
class i2c_device: | |
def __init__(self, addr, port=I2CBUS): | |
self.addr = addr | |
self.bus = smbus.SMBus(port) | |
# Write a single command | |
def write_cmd(self, cmd): | |
self.bus.write_byte(self.addr, cmd) | |
sleep(0.0001) | |
# Write a command and argument | |
def write_cmd_arg(self, cmd, data): | |
self.bus.write_byte_data(self.addr, cmd, data) | |
sleep(0.0001) | |
# Write a block of data | |
def write_block_data(self, cmd, data): | |
self.bus.write_block_data(self.addr, cmd, data) | |
sleep(0.0001) | |
# Read a single byte | |
def read(self): | |
return self.bus.read_byte(self.addr) | |
# Read | |
def read_data(self, cmd): | |
return self.bus.read_byte_data(self.addr, cmd) | |
# Read a block of data | |
def read_block_data(self, cmd): | |
return self.bus.read_block_data(self.addr, cmd) | |
# commands | |
LCD_CLEARDISPLAY = 0x01 | |
LCD_RETURNHOME = 0x02 | |
LCD_ENTRYMODESET = 0x04 | |
LCD_DISPLAYCONTROL = 0x08 | |
LCD_CURSORSHIFT = 0x10 | |
LCD_FUNCTIONSET = 0x20 | |
LCD_SETCGRAMADDR = 0x40 | |
LCD_SETDDRAMADDR = 0x80 | |
# flags for display entry mode | |
LCD_ENTRYRIGHT = 0x00 | |
LCD_ENTRYLEFT = 0x02 | |
LCD_ENTRYSHIFTINCREMENT = 0x01 | |
LCD_ENTRYSHIFTDECREMENT = 0x00 | |
# flags for display on/off control | |
LCD_DISPLAYON = 0x04 | |
LCD_DISPLAYOFF = 0x00 | |
LCD_CURSORON = 0x02 | |
LCD_CURSOROFF = 0x00 | |
LCD_BLINKON = 0x01 | |
LCD_BLINKOFF = 0x00 | |
# flags for display/cursor shift | |
LCD_DISPLAYMOVE = 0x08 | |
LCD_CURSORMOVE = 0x00 | |
LCD_MOVERIGHT = 0x04 | |
LCD_MOVELEFT = 0x00 | |
# flags for function set | |
LCD_8BITMODE = 0x10 | |
LCD_4BITMODE = 0x00 | |
LCD_2LINE = 0x08 | |
LCD_1LINE = 0x00 | |
LCD_5x10DOTS = 0x04 | |
LCD_5x8DOTS = 0x00 | |
# flags for backlight control | |
LCD_BACKLIGHT = 0x08 | |
LCD_NOBACKLIGHT = 0x00 | |
En = 0b00000100 # Enable bit | |
Rw = 0b00000010 # Read/Write bit | |
Rs = 0b00000001 # Register select bit | |
class lcd: | |
#initializes objects and lcd | |
def __init__(self): | |
self.lcd_device = i2c_device(ADDRESS) | |
self.lcd_write(0x03) | |
self.lcd_write(0x03) | |
self.lcd_write(0x03) | |
self.lcd_write(0x02) | |
self.lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE) | |
self.lcd_write(LCD_DISPLAYCONTROL | LCD_DISPLAYON) | |
self.lcd_write(LCD_CLEARDISPLAY) | |
self.lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT) | |
sleep(0.2) | |
# clocks EN to latch command | |
def lcd_strobe(self, data): | |
self.lcd_device.write_cmd(data | En | LCD_BACKLIGHT) | |
sleep(.0005) | |
self.lcd_device.write_cmd(((data & ~En) | LCD_BACKLIGHT)) | |
sleep(.0001) | |
def lcd_write_four_bits(self, data): | |
self.lcd_device.write_cmd(data | LCD_BACKLIGHT) | |
self.lcd_strobe(data) | |
# write a command to lcd | |
def lcd_write(self, cmd, mode=0): | |
self.lcd_write_four_bits(mode | (cmd & 0xF0)) | |
self.lcd_write_four_bits(mode | ((cmd << 4) & 0xF0)) | |
# write a character to lcd (or character rom) 0x09: backlight | RS=DR< | |
# works! | |
def lcd_write_char(self, charvalue, mode=1): | |
self.lcd_write_four_bits(mode | (charvalue & 0xF0)) | |
self.lcd_write_four_bits(mode | ((charvalue << 4) & 0xF0)) | |
# put string function with optional char positioning | |
def lcd_display_string(self, string, line=1, pos=0): | |
if line == 1: | |
pos_new = pos | |
elif line == 2: | |
pos_new = 0x40 + pos | |
elif line == 3: | |
pos_new = 0x14 + pos | |
elif line == 4: | |
pos_new = 0x54 + pos | |
self.lcd_write(0x80 + pos_new) | |
for char in string: | |
self.lcd_write(ord(char), Rs) | |
# clear lcd and set to home | |
def lcd_clear(self): | |
self.lcd_write(LCD_CLEARDISPLAY) | |
self.lcd_write(LCD_RETURNHOME) | |
# define backlight on/off (lcd.backlight(1); off= lcd.backlight(0) | |
def backlight(self, state): # for state, 1 = on, 0 = off | |
if state == 1: | |
self.lcd_device.write_cmd(LCD_BACKLIGHT) | |
elif state == 0: | |
self.lcd_device.write_cmd(LCD_NOBACKLIGHT) | |
# add custom characters (0 - 7) | |
def lcd_load_custom_chars(self, fontdata): | |
self.lcd_write(0x40); | |
for char in fontdata: | |
for line in char: | |
self.lcd_write_char(line) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
start on runlevel [2345] | |
stop on runlevel [!2345] | |
exec sh /root/mystartupscript.sh |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Unit] | |
Description=LCDscreen service | |
[Service] | |
Type=simple | |
ExecStart=/usr/bin/python /root/neo2lcdthree.py | |
WorkingDirectory=/root/ | |
Restart=on-failure | |
[Install] | |
WantedBy=multi-user.target | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
import fcntl | |
import struct | |
import psutil | |
import os | |
import sys | |
import time | |
home_dir = os.path.expanduser("~") | |
sys.path.append(home_dir) | |
import I2C_LCD_Driver | |
import SDL_DS1307 | |
mylcd = I2C_LCD_Driver.lcd() | |
ds1307 = SDL_DS1307.SDL_DS1307(0, 0x68) | |
def get_ip_address(ifname): | |
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
return socket.inet_ntoa(fcntl.ioctl( | |
s.fileno(), | |
0x8915, | |
struct.pack('256s', ifname[:15]) | |
)[20:24]) | |
#mylcd.lcd_display_string("hello",1) | |
#mylcd.lcd_display_string("IP Address:", 1) | |
#mylcd.lcd_display_string(get_ip_address('eth0'), 2) | |
# Return RAM information (unit=kb) in a list | |
# Index 0: total RAM | |
# Index 1: used RAM | |
# Index 2: free RAM | |
def getRAMinfo(): | |
p = os.popen('free') | |
i = 0 | |
while 1: | |
i = i + 1 | |
line = p.readline() | |
if i==2: | |
return(line.split()[1:4]) | |
mylcd.lcd_clear() | |
while True: | |
#CPU usage and time | |
CPU_usage = psutil.cpu_percent(interval = .5) | |
mylcd.lcd_display_string("CPU Load %s%% " % (CPU_usage), 1) | |
mylcd.lcd_display_string("%s" % ds1307.read_datetime(), 2) | |
time.sleep(3) | |
mylcd.lcd_clear() | |
#IP ADDRESS | |
mylcd.lcd_display_string("IP Address : ", 1) | |
mylcd.lcd_display_string(get_ip_address('eth0'), 2) | |
time.sleep(3) | |
mylcd.lcd_clear() | |
#RAM USAGE | |
RAM_stats = getRAMinfo() | |
RAM_used = round(int(RAM_stats[1]) / 1000,1) | |
RAM_free = round(int(RAM_stats[2]) / 1000,1) | |
mylcd.lcd_display_string("RAM Used %sMB" % (RAM_used),1) | |
mylcd.lcd_display_string("RAM Free %sMB" % (RAM_free),2) | |
time.sleep(3) | |
mylcd.lcd_clear() | |
mylcd.lcd_display_string("All your base",1) | |
mylcd.lcd_display_string("are belong to us",2) | |
time.sleep(3) | |
mylcd.lcd_clear() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# SDL_DS1307.py Python Driver Code | |
# SwitchDoc Labs 07/10/2014 | |
# Shovic V 1.0 | |
# only works in 24 hour mode | |
# original code from below (DS1307 Code originally - had issues with 24 hour mode. Removed 12 hour mode) | |
#encoding: utf-8 | |
# Copyright (C) 2013 @XiErCh | |
# | |
# Permission is hereby granted, free of charge, to any person obtaining a copy | |
# of this software and associated documentation files (the "Software"), to deal | |
# in the Software without restriction, including without limitation the rights | |
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
# copies of the Software, and to permit persons to whom the Software is | |
# furnished to do so, subject to the following conditions: | |
# | |
# The above copyright notice and this permission notice shall be included in all | |
# copies or substantial portions of the Software. | |
# | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
# SOFTWARE. | |
from datetime import datetime | |
import smbus | |
def _bcd_to_int(bcd): | |
"""Decode a 2x4bit BCD to a integer. | |
""" | |
out = 0 | |
for d in (bcd >> 4, bcd): | |
for p in (1, 2, 4 ,8): | |
if d & 1: | |
out += p | |
d >>= 1 | |
out *= 10 | |
return out / 10 | |
def _int_to_bcd(n): | |
"""Encode a one or two digits number to the BCD. | |
""" | |
bcd = 0 | |
for i in (n // 10, n % 10): | |
for p in (8, 4, 2, 1): | |
if i >= p: | |
bcd += 1 | |
i -= p | |
bcd <<= 1 | |
return bcd >> 1 | |
class SDL_DS1307(): | |
_REG_SECONDS = 0x00 | |
_REG_MINUTES = 0x01 | |
_REG_HOURS = 0x02 | |
_REG_DAY = 0x03 | |
_REG_DATE = 0x04 | |
_REG_MONTH = 0x05 | |
_REG_YEAR = 0x06 | |
_REG_CONTROL = 0x07 | |
def __init__(self, twi=1, addr=0x68): | |
self._bus = smbus.SMBus(twi) | |
self._addr = addr | |
def _write(self, register, data): | |
#print "addr =0x%x register = 0x%x data = 0x%x %i " % (self._addr, register, data,_bcd_to_int(data)) | |
self._bus.write_byte_data(self._addr, register, data) | |
def _read(self, data): | |
returndata = self._bus.read_byte_data(self._addr, data) | |
#print "addr = 0x%x data = 0x%x %i returndata = 0x%x %i " % (self._addr, data, data, returndata, _bcd_to_int(returndata)) | |
return returndata | |
def _read_seconds(self): | |
return _bcd_to_int(self._read(self._REG_SECONDS)) | |
def _read_minutes(self): | |
return _bcd_to_int(self._read(self._REG_MINUTES)) | |
def _read_hours(self): | |
d = self._read(self._REG_HOURS) | |
if (d == 0x64): | |
d = 0x40 | |
return _bcd_to_int(d & 0x3F) | |
def _read_day(self): | |
return _bcd_to_int(self._read(self._REG_DAY)) | |
def _read_date(self): | |
return _bcd_to_int(self._read(self._REG_DATE)) | |
def _read_month(self): | |
return _bcd_to_int(self._read(self._REG_MONTH)) | |
def _read_year(self): | |
return _bcd_to_int(self._read(self._REG_YEAR)) | |
def read_all(self): | |
"""Return a tuple such as (year, month, date, day, hours, minutes, | |
seconds). | |
""" | |
return (self._read_year(), self._read_month(), self._read_date(), | |
self._read_day(), self._read_hours(), self._read_minutes(), | |
self._read_seconds()) | |
def read_str(self): | |
"""Return a string such as 'YY-DD-MMTHH-MM-SS'. | |
""" | |
return '%02d-%02d-%02dT%02d:%02d:%02d' % (self._read_year(), | |
self._read_month(), self._read_date(), self._read_hours(), | |
self._read_minutes(), self._read_seconds()) | |
def read_datetime(self, century=21, tzinfo=None): | |
"""Return the datetime.datetime object. | |
""" | |
return datetime((century - 1) * 100 + self._read_year(), | |
self._read_month(), self._read_date(), self._read_hours(), | |
self._read_minutes(), self._read_seconds(), 0, tzinfo=tzinfo) | |
def write_all(self, seconds=None, minutes=None, hours=None, day=None, | |
date=None, month=None, year=None, save_as_24h=True): | |
"""Direct write un-none value. | |
Range: seconds [0,59], minutes [0,59], hours [0,23], | |
day [0,7], date [1-31], month [1-12], year [0-99]. | |
""" | |
if seconds is not None: | |
if seconds < 0 or seconds > 59: | |
raise ValueError('Seconds is out of range [0,59].') | |
self._write(self._REG_SECONDS, _int_to_bcd(seconds)) | |
if minutes is not None: | |
if minutes < 0 or minutes > 59: | |
raise ValueError('Minutes is out of range [0,59].') | |
self._write(self._REG_MINUTES, _int_to_bcd(minutes)) | |
if hours is not None: | |
if hours < 0 or hours > 23: | |
raise ValueError('Hours is out of range [0,23].') | |
self._write(self._REG_HOURS, _int_to_bcd(hours)) # not | 0x40 as in the orignal code | |
if year is not None: | |
if year < 0 or year > 99: | |
raise ValueError('Years is out of range [0,99].') | |
self._write(self._REG_YEAR, _int_to_bcd(year)) | |
if month is not None: | |
if month < 1 or month > 12: | |
raise ValueError('Month is out of range [1,12].') | |
self._write(self._REG_MONTH, _int_to_bcd(month)) | |
if date is not None: | |
if date < 1 or date > 31: | |
raise ValueError('Date is out of range [1,31].') | |
self._write(self._REG_DATE, _int_to_bcd(date)) | |
if day is not None: | |
if day < 1 or day > 7: | |
raise ValueError('Day is out of range [1,7].') | |
self._write(self._REG_DAY, _int_to_bcd(day)) | |
def write_datetime(self, dt): | |
"""Write from a datetime.datetime object. | |
""" | |
self.write_all(dt.second, dt.minute, dt.hour, | |
dt.isoweekday(), dt.day, dt.month, dt.year % 100) | |
def write_now(self): | |
"""Equal to DS1307.write_datetime(datetime.datetime.now()). | |
""" | |
self.write_datetime(datetime.now()) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment