pioneer600

Pioneer600 sample for headless raspberry pi servers
git clone git://git.ckyln.com/pioneer600.git
Log | Files | Refs | README

commit 1748ecb119c0c529f780f128684db4a12248e05e
parent 4584d69cf1e28945a0272deb053c81c30a36337f
Author: cemkeylan <32103268+cemkeylan@users.noreply.github.com>
Date:   Thu,  5 Jul 2018 15:22:34 +0300

Version 1.0 Released

Diffstat:
AKeepCalm-Medium.ttf | 0
APioneer600.py | 260+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MREADME.md | 4++++
ASSD1306.py | 172+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aadd_module.py | 40++++++++++++++++++++++++++++++++++++++++
5 files changed, 476 insertions(+), 0 deletions(-)

diff --git a/KeepCalm-Medium.ttf b/KeepCalm-Medium.ttf Binary files differ. diff --git a/Pioneer600.py b/Pioneer600.py @@ -0,0 +1,260 @@ +#!/usr/bin/python +# -*- coding:utf-8 -*- +# Cem KEYLAN +# 2018 +# Version 1.0 + + +import RPi.GPIO as GPIO +import smbus +import spidev as SPI +import SSD1306 +import time +import Image +import ImageDraw +import ImageFont +import os +import add_module + +KEY = 20 +address = 0x20 +main_menu = 1 +submenus = 1 + + +def beep_on(): + bus.write_byte(address,0x7F&bus.read_byte(address)) +def beep_off(): + bus.write_byte(address,0x80|bus.read_byte(address)) +def led_off(): + bus.write_byte(address,0x10|bus.read_byte(address)) +def led_on(): + bus.write_byte(address,0xEF&bus.read_byte(address)) + + +def oled(Line1, Line2, Line3=""): + # Draw a black filled box to clear the image. + draw.rectangle((0,0,width,height), outline=0, fill=0) + draw.text((x, top), str(Line1), font=font1, fill=255) + draw.text((x, top+20), str(Line2), font=font2, fill=255) + draw.text((x, top+40), str(Line3), font=font2, fill=255) + disp.image(image) + disp.display() + +def MyInterrupt(KEY): + print("KEY PRESS") + +def menu (): + global values + global submenus + global main_menu + + if values == "up" : + submenus = submenus - 1 + elif values == 'down' : + submenus = submenus + 1 + elif values == "right" : + main_menu = main_menu + 1 + submenus = 1 + elif values == "left" : + main_menu = main_menu - 1 + submenus = 1 + + if main_menu == 5: + main_menu = 1 + if main_menu == 0: + main_menu = 4 + + # Main Information delivering up status + if main_menu == 1 : + + if submenus == 4: + submenus = 1 + if submenus ==0: + submenus =3 + + if submenus == 1: + if len(os.popen("hostname -I").read()) == 1 : + upstatus = "Down" + else: + upstatus = "UP" + oled("Status = " + upstatus,os.popen("hostname -I").read(),"by Cem Keylan") + elif submenus == 3 : + if "active" in os.popen("sudo service ssh status").read(): + upssh = "UP" + else: + upssh = "DOWN" + oled("SSH Server", upssh) + elif submenus == 2 : + if len(os.popen("hostname -I").read()) is not 1: + if "unreachable" in os.popen("nc 8.8.8.8 53 -zv").read(): + oled("Connection", "could NOT be","established.") + else: + oled("Connection","could be","established.") + + + # Device Info + elif main_menu == 2: + + if submenus == 5: + submenus = 1 + if submenus ==0: + submenus =4 + + if submenus == 4 : + oled("Device Info","CPU Temperature=",(add_module.getCPUtemperature()+" C")) + elif submenus == 2 : + oled("Device Info","Free RAM",(str(int(add_module.getRAMinfo()[2])/1024)+" MB")) + elif submenus == 3 : + oled("Device Info","CPU Usage",(str(add_module.getCPUuse())+" %")) + elif submenus == 1 : + oled("Device Info","Disk Usage",add_module.getDiskSpace()[3]) + + #aƧ kapa + elif main_menu == 3 : + + if submenus == 4: + submenus = 1 + if submenus == 0: + submenus = 3 + + elif submenus == 1 : + oled("System","Close App","Press Button") + if GPIO.input(KEY) == 0: + if len(os.popen("hostname -I").read()) is not 1: + exit () + else: + oled("System","Close App","Must be connected") + time.sleep(2) + elif submenus == 2 : + oled("System","Reboot","Press Button") + if GPIO.input(KEY) == 0: + os.popen('sudo reboot') + elif submenus == 3 : + oled("System","Halt System","Press Button") + if GPIO.input(KEY) == 0: + os.popen('sudo halt') + + + #interfaces + elif main_menu == 4 : + note = os.popen("sudo ifconfig").read() + if submenus == 3 : + submenus = 1 + if submenus == 0 : + submenus = 2 + elif submenus == 2 : + if "eth0" in note: + oled("Interfaces", "Eth0 Enabled", "Press Button") + if GPIO.input(KEY) == 0: + os.popen("sudo ifconfig eth0 down") + else: + oled("Interfaces", "Eth0 Disabled", "Press Button") + if GPIO.input(KEY) == 0: + os.popen("sudo ifconfig eth0 up") + elif submenus == 1: + if "wlan0" in note: + oled("Interfaces","Wlan0 Enabled", "Press Button") + if GPIO.input(KEY) == 0: + os.popen("sudo ifconfig wlan0 down") + else: + oled("Interfaces","Wlan0 Disabled", "Press Button") + if GPIO.input(KEY) == 0: + os.popen("sudo ifconfig wlan0 up") + + + else : + print ("Something went wrong") + + return (submenus) + +# Raspberry Pi pin configuration: +RST = 19 +# Note the following are only used with SPI: +DC = 16 +bus = 0 +device = 0 + +# 128x64 display with hardware SPI: +disp = SSD1306.SSD1306(RST, DC, SPI.SpiDev(bus,device)) + +# Initialize library. +disp.begin() + +# Clear display. +disp.clear() +disp.display() + +# Create blank image for drawing. +# Make sure to create image with mode '1' for 1-bit color. +width = disp.width +height = disp.height +image = Image.new('1', (width, height)) + +# Get drawing object to draw on image. +draw = ImageDraw.Draw(image) + +# Draw a black filled box to clear the image. +draw.rectangle((0,0,width,height), outline=0, fill=0) + +# Draw some shapes. +# First define some constants to allow easy resizing of shapes. +padding = 1 +top = padding +x = padding +# Load default font. +# font = ImageFont.load_default() +font_dir = os.path.dirname(os.path.realpath(__file__)) +"/KeepCalm-Medium.ttf" +font1 = ImageFont.truetype(font_dir, 15) +font2 = ImageFont.truetype(font_dir, 14) + +GPIO.setmode(GPIO.BCM) +GPIO.setup(KEY,GPIO.IN,GPIO.PUD_UP) +#GPIO.add_event_detect(KEY,GPIO.FALLING,MyInterrupt,200) + +#bmp = BMP180() +bus = smbus.SMBus(1) + +print("Starting...") +print("Version 1.0") + +try: + while True: + + bus.write_byte(address,0x0F|bus.read_byte(address)) + value = bus.read_byte(address) | 0xF0 + if value != 0xFF: + led_on() + if (value | 0xFE) != 0xFF: + values= "left" + elif (value | 0xFD) != 0xFF: + values= "up" + elif (value | 0xFB) != 0xFF: + values= "down" + else : + values= "right" + while value != 0xFF: + bus.write_byte(address,0x0F|bus.read_byte(address)) + value = bus.read_byte(address) | 0xF0 + time.sleep(0.01) + led_off() + submenus=menu() + + time.sleep(0.1) + values= "YOK" + submenus=menu() + +# for keyboard interrupt +except (KeyboardInterrupt, SystemExit): + print ("Keyboard Interrupt") + # Clear display. + disp.clear() + disp.display() + +except: + print ("ERROR") + # Clear display. + oled("There was an error","") + time.sleep(2) + disp.clear() + disp.display() diff --git a/README.md b/README.md @@ -1,2 +1,6 @@ # pioneer600 Python project for creating a headless Raspberry Pi server and easily outputting information and executing simple commands + +###### Python-Imaging is required for the OLED Display +`sudo pip install python-imaging` + diff --git a/SSD1306.py b/SSD1306.py @@ -0,0 +1,172 @@ +import spidev +import RPi.GPIO as GPIO +import time + +# Constants +SSD1306_SETCONTRAST = 0x81 +SSD1306_DISPLAYALLON_RESUME = 0xA4 +SSD1306_DISPLAYALLON = 0xA5 +SSD1306_NORMALDISPLAY = 0xA6 +SSD1306_INVERTDISPLAY = 0xA7 +SSD1306_DISPLAYOFF = 0xAE +SSD1306_DISPLAYON = 0xAF +SSD1306_SETDISPLAYOFFSET = 0xD3 +SSD1306_SETCOMPINS = 0xDA +SSD1306_SETVCOMDETECT = 0xDB +SSD1306_SETDISPLAYCLOCKDIV = 0xD5 +SSD1306_SETPRECHARGE = 0xD9 +SSD1306_SETMULTIPLEX = 0xA8 +SSD1306_SETLOWCOLUMN = 0x00 +SSD1306_SETHIGHCOLUMN = 0x10 +SSD1306_SETSTARTLINE = 0x40 +SSD1306_MEMORYMODE = 0x20 +SSD1306_COLUMNADDR = 0x21 +SSD1306_PAGEADDR = 0x22 +SSD1306_COMSCANINC = 0xC0 +SSD1306_COMSCANDEC = 0xC8 +SSD1306_SEGREMAP = 0xA0 +SSD1306_CHARGEPUMP = 0x8D +SSD1306_EXTERNALVCC = 0x1 +SSD1306_SWITCHCAPVCC = 0x2 + +# Scrolling constants +SSD1306_ACTIVATE_SCROLL = 0x2F +SSD1306_DEACTIVATE_SCROLL = 0x2E +SSD1306_SET_VERTICAL_SCROLL_AREA = 0xA3 +SSD1306_RIGHT_HORIZONTAL_SCROLL = 0x26 +SSD1306_LEFT_HORIZONTAL_SCROLL = 0x27 +SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29 +SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A + +class SSD1306(object): + """class for SSD1306 128*64 0.96inch OLED displays.""" + + def __init__(self,rst,dc,spi): + self.width = 128 + self.height = 64 + self._pages = 8 + self._buffer = [0]*(self.width*self._pages) + #Initialize DC RST pin + self._dc = dc + self._rst = rst + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(self._dc,GPIO.OUT) + GPIO.setup(self._rst,GPIO.OUT) + #Initialize SPI + self._spi = spi + def command(self,cmd): + """Send command byte to display""" + GPIO.output(self._dc,GPIO.LOW) + self._spi.writebytes([cmd]) + def data(self,val): + """Send byte of data to display""" + GPIO.output(self._dc,GPIO.HIGHT) + self._spi.writebytes([val]) + def begin(self,vccstate=SSD1306_SWITCHCAPVCC): + """Initialize dispaly""" + self._vccstate = vccstate + self.reset() + self.command(SSD1306_DISPLAYOFF) # 0xAE + self.command(SSD1306_SETDISPLAYCLOCKDIV) # 0xD5 + self.command(0x80) # the suggested ra tio 0x80 + + self.command(SSD1306_SETMULTIPLEX) # 0xA8 + self.command(0x3F) + self.command(SSD1306_SETDISPLAYOFFSET) # 0xD3 + self.command(0x0) # no offset + self.command(SSD1306_SETSTARTLINE | 0x0) # line #0 + self.command(SSD1306_CHARGEPUMP) # 0x8D + if self._vccstate == SSD1306_EXTERNALVCC: + self.command(0x10) + else: + self.command(0x14) + self.command(SSD1306_MEMORYMODE) # 0x20 + self.command(0x00) # 0x0 act like ks0108 + self.command(SSD1306_SEGREMAP | 0x1) + self.command(SSD1306_COMSCANDEC) + self.command(SSD1306_SETCOMPINS) # 0xDA + self.command(0x12) + self.command(SSD1306_SETCONTRAST) # 0x81 + if self._vccstate == SSD1306_EXTERNALVCC: + self.command(0x9F) + else: + self.command(0xCF) + self.command(SSD1306_SETPRECHARGE) # 0xd9 + if self._vccstate == SSD1306_EXTERNALVCC: + self.command(0x22) + else: + self.command(0xF1) + self.command(SSD1306_SETVCOMDETECT) # 0xDB + self.command(0x40) + self.command(SSD1306_DISPLAYALLON_RESUME) # 0xA4 + self.command(SSD1306_NORMALDISPLAY) # 0xA6 + self.command(SSD1306_DISPLAYON) + def reset(self): + """Reset the display""" + GPIO.output(self._rst,GPIO.HIGH) + time.sleep(0.001) + GPIO.output(self._rst,GPIO.LOW) + time.sleep(0.010) + GPIO.output(self._rst,GPIO.HIGH) + def display(self): + """Write display buffer to physical display""" + self.command(SSD1306_COLUMNADDR) + self.command(0) #Cloumn start address + self.command(self.width-1) #Cloumn end address + self.command(SSD1306_PAGEADDR) + self.command(0) #Page start address + self.command(self._pages-1) #Page end address + #Write buffer data + GPIO.output(self._dc,GPIO.HIGH) + self._spi.writebytes(self._buffer) + def image(self, image): + """Set buffer to value of Python Imaging Library image.""" + if image.mode != '1': + raise ValueError('Image must be in mode 1.') + imwidth, imheight = image.size + if imwidth != self.width or imheight != self.height: + raise ValueError('Image must be same dimensions as display \ + ({0}x{1}).' .format(self.width, self.height)) + + pix = image.load() + # Iterate through the memory pages + index = 0 + for page in range(self._pages): + # Iterate through all x axis columns. + for x in range(self.width): + # Set the bits for the column of pixels at the current position. + bits = 0 + # Don't use range here as it's a bit slow + for bit in [0, 1, 2, 3, 4, 5, 6, 7]: + bits = bits << 1 + bits |= 0 if pix[(x, page*8+7-bit)] == 0 else 1 + # Update buffer byte and increment to next byte. + self._buffer[index] = bits + index += 1 + def clear(self): + """Clear contents of image buffer""" + self._buffer = [0]*(self.width*self._pages) + def set_contrast(self, contrast): + """Sets the contrast of the display. + Contrast should be a value between 0 and 255.""" + if contrast < 0 or contrast > 255: + raise ValueError('Contrast must be a value from 0 to 255).') + self.command(SSD1306_SETCONTRAST) + self.command(contrast) + + def dim(self, dim): + """Adjusts contrast to dim the display if dim is True, + otherwise sets the contrast to normal brightness if dim is False.""" + # Assume dim display. + contrast = 0 + # Adjust contrast based on VCC if not dimming. + if not dim: + if self._vccstate == SSD1306_EXTERNALVCC: + contrast = 0x9F + else: + contrast = 0xCF + + + + diff --git a/add_module.py b/add_module.py @@ -0,0 +1,40 @@ +#!/usr/bin/python +# -*- coding:utf-8 -*- + +import os + +# Return CPU temperature as a character string +def getCPUtemperature(): + res = os.popen('vcgencmd measure_temp').readline() + return(res.replace("temp=","").replace("'C\n","")) + +# 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]) + +# Return % of CPU used by user as a character string +def getCPUuse(): + return(str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip())) + +# Return information about disk space as a list (unit included) +# Index 0: total disk space +# Index 1: used disk space +# Index 2: remaining disk space +# Index 3: percentage of disk used +def getDiskSpace(): + p = os.popen("df -h /") + i = 0 + while 1: + i = i +1 + line = p.readline() + if i==2: + return(line.split()[1:5])