commit f2c2210bfb56702f5f972002eff729d1158be649 Author: James Devine Date: Tue Sep 1 09:17:17 2020 +0200 diff --git a/I2C_LCD_Driver.py b/I2C_LCD_Driver.py new file mode 100644 index 0000000..a8a67f3 --- /dev/null +++ b/I2C_LCD_Driver.py @@ -0,0 +1,180 @@ +# -*- 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) + + diff --git a/SDL_DS1307.py b/SDL_DS1307.py new file mode 100644 index 0000000..91e4fdc --- /dev/null +++ b/SDL_DS1307.py @@ -0,0 +1,201 @@ +#!/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()) + diff --git a/mystartupscript.conf b/mystartupscript.conf new file mode 100644 index 0000000..dd84cfc --- /dev/null +++ b/mystartupscript.conf @@ -0,0 +1,4 @@ +start on runlevel [2345] +stop on runlevel [!2345] + +exec sh /root/mystartupscript.sh diff --git a/mystartupscript.service b/mystartupscript.service new file mode 100644 index 0000000..da587fc --- /dev/null +++ b/mystartupscript.service @@ -0,0 +1,12 @@ +[Unit] +Description=LCDscreen service + +[Service] +Type=simple +ExecStart=/usr/bin/python /root/neo2lcdthree.py +WorkingDirectory=/root/ +Restart=on-failure + +[Install] +WantedBy=multi-user.target + diff --git a/neo2lcdthree.py b/neo2lcdthree.py new file mode 100644 index 0000000..b1095a2 --- /dev/null +++ b/neo2lcdthree.py @@ -0,0 +1,71 @@ +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()