├── Chapter 1 └── example bash_profile.sh ├── Chapter 10 ├── matrixControl.py ├── matrixMenu.py ├── missileControl.py ├── missileMenu.py ├── robotarmControl.py ├── serialControl.py ├── serialMenu.py ├── serialTest.py ├── socketControl.py ├── socketMenu.py └── spiTest.py ├── Chapter 3 ├── encryptdecrypt.py ├── filehandler.py ├── graphicmenu.py ├── photohandler.py ├── photohandler_1stpart.py └── tkencryptdecrypt.py ├── Chapter 6 ├── btntest.py ├── gpiokeys-events.py ├── gpiokeys-mouse.py ├── gpiokeys.py ├── ledtest.py ├── rgbled-part1.py ├── rgbled-rand.py ├── rgbled.py ├── rgbledrainbow.py ├── shtdwn.py └── shtdwn_full.py ├── Chapter 7 ├── data.log ├── data_adc.py ├── data_local.py ├── del_data_lite.php ├── lcd_i2c.py ├── live_graph.py ├── live_graph_light.py ├── log_adc.py ├── log_graph.py ├── log_local.py ├── mysqlite_adc.py ├── mysqlite_local.py ├── show_data_lite.php └── xivelylog.py ├── Chapter 8 ├── Story.png ├── animateGUI.py ├── cameraGUI.py ├── cameraGUI1normal.py ├── cameraGUI2timelapse.py ├── cameraGUI3animate.py ├── cameraGUI4qrcodes.py ├── cameraGUIframe.py ├── cameraGUItimelapse.py ├── genQRCodes.py ├── generateQRCodes.py ├── opencv_color_detect.py ├── opencv_display.py ├── opencv_motion_detect.py ├── openimage.py ├── qrcodeGUI.py ├── shutterCam.py └── timelapseGUI.py ├── Chapter 9 ├── XLoBorg3-part1.py ├── XLoBorg3.py ├── avoidance.py ├── bug_drive.py ├── compassDrive.py ├── rover_drive.py ├── rover_drive_hwpwm.py ├── rover_drive_i2c.py ├── rover_drive_swpwm.py ├── rover_drivefwd.py ├── servoAdafruit.py ├── servo_control.py └── sonic.py ├── LICENSE └── README.md /Chapter 1/example bash_profile.sh: -------------------------------------------------------------------------------- 1 | function proxyenable { 2 | # Define proxy settings 3 | PROXY_ADDR="proxy.address.com:port" 4 | # Login name (leave blank if not required): 5 | LOGIN_USER="login_name" 6 | # Login Password (leave blank to prompt): 7 | LOGIN_PWD= 8 | #If login specified - check for password 9 | if [[ -z $LOGIN_USER ]]; then 10 | #No login for proxy 11 | PROXY_FULL=$PROXY_ADDR 12 | else 13 | #Login needed for proxy Prompt for password -s option hides input 14 | if [[ -z $LOGIN_PWD ]]; then 15 | read -s -p "Provide proxy password (then Enter):" LOGIN_PWD 16 | echo 17 | fi 18 | PROXY_FULL=$LOGIN_USER:$LOGIN_PWD@$PROXY_ADDR 19 | fi 20 | #Web Proxy Enable: http_proxy or HTTP_PROXY environment variables 21 | export http_proxy="http://$PROXY_FULL/" 22 | export HTTP_PROXY=$http_proxy 23 | export https_proxy="https://$PROXY_FULL/" 24 | export HTTPS_PROXY=$https_proxy 25 | export ftp_proxy="ftp://$PROXY_FULL/" 26 | export FTP_PROXY=$ftp_proxy 27 | #Remove info no longer needed from environment 28 | unset LOGIN_USER LOGIN_PWD PROXY_ADDR PROXY_FULL 29 | echo Proxy Enabled 30 | } 31 | 32 | function proxydisable { 33 | #Disable proxy values, apt-get and get settings 34 | unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY ftp_proxy FPT_PROXY 35 | echo Proxy Disabled 36 | } 37 | -------------------------------------------------------------------------------- /Chapter 10/matrixControl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # matrixControl.py 3 | import wiringpi 4 | import time 5 | 6 | MAX7219_NOOP = 0x00 7 | DIG0=0x01; DIG1=0x02; DIG2=0x03; DIG3=0x04 8 | DIG4=0x05; DIG5=0x06; DIG6=0x07; DIG7=0x08 9 | MAX7219_DIGIT=[DIG0,DIG1,DIG2,DIG3,DIG4,DIG5,DIG6,DIG7] 10 | MAX7219_DECODEMODE = 0x09 11 | MAX7219_INTENSITY = 0x0A 12 | MAX7219_SCANLIMIT = 0x0B 13 | MAX7219_SHUTDOWN = 0x0C 14 | MAX7219_DISPLAYTEST = 0x0F 15 | SPI_CS=0 16 | SPI_SPEED=100000 17 | 18 | class matrix(): 19 | def __init__(self,DEBUG=False): 20 | self.DEBUG=DEBUG 21 | wiringpi.wiringPiSPISetup(SPI_CS,SPI_SPEED) 22 | self.sendCmd(MAX7219_SCANLIMIT, 7) # enable outputs 23 | self.sendCmd(MAX7219_DECODEMODE, 0) # no digit decode 24 | self.sendCmd(MAX7219_DISPLAYTEST, 0) # display test off 25 | self.clear() 26 | self.brightness(15) # brightness 0-15 27 | self.sendCmd(MAX7219_SHUTDOWN, 1) # start display 28 | def sendCmd(self, register, data): 29 | buffer=(register<<8)+data 30 | buffer=buffer.to_bytes(2, byteorder='big') 31 | if self.DEBUG:print("Send byte: 0x%04x"% 32 | int.from_bytes(buffer,'big')) 33 | wiringpi.wiringPiSPIDataRW(SPI_CS,buffer) 34 | if self.DEBUG:print("Response: 0x%04x"% 35 | int.from_bytes(buffer,'big')) 36 | return buffer 37 | def clear(self): 38 | if self.DEBUG:print("Clear") 39 | for row in MAX7219_DIGIT: 40 | self.sendCmd(row + 1, 0) 41 | def brightness(self,intensity): 42 | self.sendCmd(MAX7219_INTENSITY, intensity % 16) 43 | 44 | def letterK(matrix): 45 | print("K") 46 | K=(0x0066763e1e366646).to_bytes(8, byteorder='big') 47 | for idx,value in enumerate(K): 48 | matrix.sendCmd(idx+1,value) 49 | 50 | def main(): 51 | myMatrix=matrix(DEBUG=True) 52 | letterK(myMatrix) 53 | while(1): 54 | time.sleep(5) 55 | myMatrix.clear() 56 | time.sleep(5) 57 | letterK(myMatrix) 58 | 59 | def main2(): 60 | myMatrix=matrix(DEBUG=True) 61 | print("Display TEST OFF") 62 | myMatrix.sendCmd(MAX7219_DISPLAYTEST, 0) # display test OFF 63 | time.sleep(2) 64 | print("Display TEST ON") 65 | myMatrix.sendCmd(MAX7219_DISPLAYTEST, 1) # display test ON 66 | time.sleep(2) 67 | print("Display TEST OFF") 68 | myMatrix.sendCmd(MAX7219_DISPLAYTEST, 0) # display test OFF 69 | time.sleep(2) 70 | print("Display") 71 | myMatrix.sendCmd(1, 0x55) 72 | time.sleep(2) 73 | print("Display Show") 74 | while(1): 75 | for a in range(255): 76 | for b in range(8): 77 | time.sleep(0.1) 78 | print(b+1,":",a) 79 | myMatrix.sendCmd(b+1,a) 80 | 81 | 82 | 83 | if __name__ == '__main__': 84 | main() 85 | #End 86 | -------------------------------------------------------------------------------- /Chapter 10/matrixMenu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #matrixMenu.py 3 | import tkinter as TK 4 | import time 5 | import matrixControl as MC 6 | 7 | #Enable/Disable DEBUG 8 | DEBUG = True 9 | #Set display sizes 10 | BUTTON_SIZE = 10 11 | NUM_BUTTON = 8 12 | NUM_LIGHTS=NUM_BUTTON*NUM_BUTTON 13 | MAX_VALUE=0xFFFFFFFFFFFFFFFF 14 | MARGIN = 2 15 | WINDOW_H = MARGIN+((BUTTON_SIZE+MARGIN)*NUM_BUTTON) 16 | WINDOW_W = WINDOW_H 17 | TEXT_WIDTH=int(2+((NUM_BUTTON*NUM_BUTTON)/4)) 18 | LIGHTOFFON=["red4","red"] 19 | OFF = 0; ON = 1 20 | colBg = "black" 21 | 22 | def isBitSet(value,bit): 23 | return (value>>bit & 1) 24 | 25 | def setBit(value,bit,state=1): 26 | mask=1<', self.mouseClick) 66 | 67 | def mouseClick(self,event): 68 | itemsClicked=self.canvas.find_overlapping(event.x, 69 | event.y,event.x+1,event.y+1) 70 | for item in itemsClicked: 71 | self.toggleLight(item) 72 | 73 | def setLight(self,num): 74 | state=isBitSet(self.lightStatus,num) 75 | self.canvas.itemconfig(self.light[num], 76 | fill=LIGHTOFFON[state]) 77 | 78 | def toggleLight(self,num): 79 | if num != 0: 80 | self.lightStatus=toggleBit(self.lightStatus,num-1) 81 | self.setLight(num-1) 82 | self.generateCode() 83 | 84 | def generateCode(self): 85 | self.codeText.set("0x%016x"%self.lightStatus) 86 | 87 | def changedCode(self,*args): 88 | updated=False 89 | try: 90 | codeValue=int(self.codeText.get(),16) 91 | if(codeValue>MAX_VALUE): 92 | codeValue=codeValue>>4 93 | self.updateLight(codeValue) 94 | updated=True 95 | except: 96 | self.generateCode() 97 | updated=False 98 | return updated 99 | 100 | def updateLight(self,lightsetting): 101 | self.lightStatus=lightsetting 102 | for num in range(NUM_LIGHTS): 103 | self.setLight(num) 104 | self.generateCode() 105 | self.updateHardware() 106 | 107 | def updateHardware(self): 108 | sendBytes=self.lightStatus.to_bytes(NUM_BUTTON, 109 | byteorder='big') 110 | print(sendBytes) 111 | for idx,row in enumerate(MC.MAX7219_DIGIT): 112 | response = self.matrix.sendCmd(row,sendBytes[idx]) 113 | print(response) 114 | 115 | def main(): 116 | global root 117 | root=TK.Tk() 118 | root.title("Matrix GUI") 119 | myMatrixHW=MC.matrix(DEBUG) 120 | myMatrixGUI=matrixGUI(root,myMatrixHW) 121 | TK.mainloop() 122 | 123 | if __name__ == '__main__': 124 | main() 125 | #End 126 | -------------------------------------------------------------------------------- /Chapter 10/missileControl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # missileControl.py 3 | import time 4 | import usb.core 5 | 6 | class SamMissile(): 7 | idVendor=0x1130 8 | idProduct=0x0202 9 | idName="Tenx Technology SAM Missile" 10 | # Protocol control bytes 11 | bmRequestType=0x21 12 | bmRequest=0x09 13 | wValue=0x02 14 | wIndex=0x01 15 | # Protocol command bytes 16 | INITA = [ord('U'), ord('S'), ord('B'), ord('C'), 17 | 0, 0, 4, 0] 18 | INITB = [ord('U'), ord('S'), ord('B'), ord('C'), 19 | 0, 64, 2, 0] 20 | CMDFILL = [ 8, 8, 21 | 0, 0, 0, 0, 0, 0, 0, 0, 22 | 0, 0, 0, 0, 0, 0, 0, 0, 23 | 0, 0, 0, 0, 0, 0, 0, 0, 24 | 0, 0, 0, 0, 0, 0, 0, 0, 25 | 0, 0, 0, 0, 0, 0, 0, 0, 26 | 0, 0, 0, 0, 0, 0, 0, 0, 27 | 0, 0, 0, 0, 0, 0, 0, 0]#48 zeros 28 | STOP = [ 0, 0, 0, 0, 0, 0] 29 | LEFT = [ 0, 1, 0, 0, 0, 0] 30 | RIGHT = [ 0, 0, 1, 0, 0, 0] 31 | UP = [ 0, 0, 0, 1, 0, 0] 32 | DOWN = [ 0, 0, 0, 0, 1, 0] 33 | LEFTUP = [ 0, 1, 0, 1, 0, 0] 34 | RIGHTUP = [ 0, 0, 1, 1, 0, 0] 35 | LEFTDOWN = [ 0, 1, 0, 0, 1, 0] 36 | RIGHTDOWN = [ 0, 0, 1, 0, 1, 0] 37 | FIRE = [ 0, 0, 0, 0, 0, 1] 38 | def __init__(self): 39 | self.dev = usb.core.find(idVendor=self.idVendor, 40 | idProduct=self.idProduct) 41 | def move(self,cmd,duration): 42 | print("Move:%s %d sec"% (cmd,duration)) 43 | self.dev.ctrl_transfer(self.bmRequestType, 44 | self.bmRequest,self.wValue, 45 | self.wIndex, self.INITA) 46 | self.dev.ctrl_transfer(self.bmRequestType, 47 | self.bmRequest,self.wValue, 48 | self.wIndex, self.INITB) 49 | self.dev.ctrl_transfer(self.bmRequestType, 50 | self.bmRequest, self.wValue, 51 | self.wIndex, cmd+self.CMDFILL) 52 | time.sleep(duration) 53 | self.dev.ctrl_transfer(self.bmRequestType, 54 | self.bmRequest, self.wValue, 55 | self.wIndex, self.INITA) 56 | self.dev.ctrl_transfer(self.bmRequestType, 57 | self.bmRequest, self.wValue, 58 | self.wIndex, self.INITB) 59 | self.dev.ctrl_transfer(self.bmRequestType, 60 | self.bmRequest, self.wValue, 61 | self.wIndex, self.STOP+self.CMDFILL) 62 | 63 | class ChesenMissile(): 64 | idVendor=0x0a81 65 | idProduct=0x0701 66 | idName="Chesen Electronics/Dream Link" 67 | # Protocol control bytes 68 | bmRequestType=0x21 69 | bmRequest=0x09 70 | wValue=0x0200 71 | wIndex=0x00 72 | # Protocol command bytes 73 | DOWN = [0x01] 74 | UP = [0x02] 75 | LEFT = [0x04] 76 | RIGHT = [0x08] 77 | FIRE = [0x10] 78 | STOP = [0x20] 79 | def __init__(self): 80 | self.dev = usb.core.find(idVendor=self.idVendor, 81 | idProduct=self.idProduct) 82 | def move(self,cmd,duration): 83 | print("Move:%s"%cmd) 84 | self.dev.ctrl_transfer(self.bmRequestType, 85 | self.bmRequest, 86 | self.wValue, self.wIndex, cmd) 87 | time.sleep(duration) 88 | self.dev.ctrl_transfer(self.bmRequestType, 89 | self.bmRequest, self.wValue, 90 | self.wIndex, self.STOP) 91 | 92 | class ThunderMissile(): 93 | idVendor=0x2123 94 | idProduct=0x1010 95 | idName="Dream Cheeky Thunder" 96 | # Protocol control bytes 97 | bmRequestType=0x21 98 | bmRequest=0x09 99 | wValue=0x00 100 | wIndex=0x00 101 | # Protocol command bytes 102 | CMDFILL = [0,0,0,0,0,0] 103 | DOWN = [0x02,0x01] 104 | UP = [0x02,0x02] 105 | LEFT = [0x02,0x04] 106 | RIGHT = [0x02,0x08] 107 | FIRE = [0x02,0x10] 108 | STOP = [0x02,0x20] 109 | def __init__(self): 110 | self.dev = usb.core.find(idVendor=self.idVendor, 111 | idProduct=self.idProduct) 112 | def move(self,cmd,duration): 113 | print("Move:%s"%cmd) 114 | self.dev.ctrl_transfer(self.bmRequestType, 115 | self.bmRequest, self.wValue, 116 | self.wIndex, cmd+self.CMDFILL) 117 | time.sleep(duration) 118 | self.dev.ctrl_transfer(self.bmRequestType, 119 | self.bmRequest, self.wValue, 120 | self.wIndex, self.STOP+self.CMDFILL) 121 | 122 | 123 | class Missile(): 124 | def __init__(self): 125 | print("Initialize Missiles") 126 | self.usbDevice=SamMissile() 127 | 128 | if self.usbDevice.dev is not None: 129 | print("Device Initialized:" + 130 | " %s" % self.usbDevice.idName) 131 | #Detach the kernel driver if active 132 | if self.usbDevice.dev.is_kernel_driver_active(0): 133 | print("Detaching kernel driver 0") 134 | self.usbDevice.dev.detach_kernel_driver(0) 135 | if self.usbDevice.dev.is_kernel_driver_active(1): 136 | print("Detaching kernel driver 1") 137 | self.usbDevice.dev.detach_kernel_driver(1) 138 | self.usbDevice.dev.set_configuration() 139 | else: 140 | raise Exception("Missile device not found") 141 | def __enter__(self): 142 | return self 143 | def left(self,duration=1): 144 | self.usbDevice.move(self.usbDevice.LEFT,duration) 145 | def right(self,duration=1): 146 | self.usbDevice.move(self.usbDevice.RIGHT,duration) 147 | def up(self,duration=1): 148 | self.usbDevice.move(self.usbDevice.UP,duration) 149 | def down(self,duration=1): 150 | self.usbDevice.move(self.usbDevice.DOWN,duration) 151 | def fire(self,duration=1): 152 | self.usbDevice.move(self.usbDevice.FIRE,duration) 153 | def stop(self,duration=1): 154 | self.usbDevice.move(self.usbDevice.STOP,duration) 155 | def __exit__(self, type, value, traceback): 156 | print("Exit") 157 | 158 | def main(): 159 | try: 160 | with Missile() as myMissile: 161 | myMissile.down() 162 | time.sleep(2) 163 | myMissile.up() 164 | except Exception as detail: 165 | print("Error: %s" % detail) 166 | 167 | if __name__ == '__main__': 168 | main() 169 | #End 170 | -------------------------------------------------------------------------------- /Chapter 10/missileMenu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #missileMenu.py 3 | import tkinter as TK 4 | import missileControl as MC 5 | 6 | BTN_SIZE=10 7 | 8 | def menuInit(): 9 | btnLeft = TK.Button(root, text="Left", 10 | command=sendLeft, width=BTN_SIZE) 11 | btnRight = TK.Button(root, text="Right", 12 | command=sendRight, width=BTN_SIZE) 13 | btnUp = TK.Button(root, text="Up", 14 | command=sendUp, width=BTN_SIZE) 15 | btnDown = TK.Button(root, text="Down", 16 | command=sendDown, width=BTN_SIZE) 17 | btnFire = TK.Button(root, text="Fire",command=sendFire, 18 | width=BTN_SIZE, bg="red") 19 | btnLeft.grid(row=2,column=0) 20 | btnRight.grid(row=2,column=2) 21 | btnUp.grid(row=1,column=1) 22 | btnDown.grid(row=3,column=1) 23 | btnFire.grid(row=2,column=1) 24 | 25 | def sendLeft(): 26 | print("Left") 27 | myMissile.left() 28 | 29 | def sendRight(): 30 | print("Right") 31 | myMissile.right() 32 | 33 | def sendUp(): 34 | print("Up") 35 | myMissile.up() 36 | 37 | def sendDown(): 38 | print("Down") 39 | myMissile.down() 40 | 41 | def sendFire(): 42 | print("Fire") 43 | myMissile.fire() 44 | 45 | 46 | root = TK.Tk() 47 | root.title("Missile Command") 48 | prompt = "Select action" 49 | label1 = TK.Label(root, text=prompt, width=len(prompt), 50 | justify=TK.CENTER, bg='lightblue') 51 | label1.grid(row=0,column=0,columnspan=3) 52 | menuInit() 53 | with MC.Missile() as myMissile: 54 | root.mainloop() 55 | #End 56 | -------------------------------------------------------------------------------- /Chapter 10/robotarmControl.py: -------------------------------------------------------------------------------- 1 | class OwiArm(): 2 | idVendor=0x1267 3 | idProduct=0x0000 4 | idName="Owi Robot Arm" 5 | # Protocol control bytes 6 | bmRequestType=0x40 7 | bmRequest=0x06 8 | wValue=0x0100 9 | wIndex=0x00 10 | # Protocol command bytes 11 | BASE_CCW = [0x00,0x01,0x00] 12 | BASE_CW = [0x00,0x02,0x00] 13 | SHOLDER_UP = [0x40,0x00,0x00] 14 | SHOLDER_DWN = [0x80,0x00,0x00] 15 | ELBOW_UP = [0x10,0x00,0x00] 16 | ELBOW_DWN = [0x20,0x00,0x00] 17 | WRIST_UP = [0x04,0x00,0x00] 18 | WRIST_DOWN = [0x08,0x00,0x00] 19 | GRIP_OPEN = [0x02,0x00,0x00] 20 | GRIP_CLOSE = [0x01,0x00,0x00] 21 | LIGHT_ON = [0x00,0x00,0x01] 22 | LIGHT_OFF = [0x00,0x00,0x00] 23 | STOP = [0x00,0x00,0x00] 24 | -------------------------------------------------------------------------------- /Chapter 10/serialControl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #serialControl.py 3 | import serial 4 | import time 5 | 6 | #Serial Port settings 7 | SERNAME="/dev/ttyUSB0" 8 | #SERNAME="/dev/ttyAMA0" 9 | #default setting is 9600,8,N,1 10 | IDLE=0; SEND=1; RECEIVE=1 11 | 12 | def b2s(message): 13 | '''Byte to String''' 14 | return bytes.decode(message) 15 | def s2b(message): 16 | '''String to Byte''' 17 | return bytearray(message,"ascii") 18 | 19 | class serPort(): 20 | def __init__(self,serName="/dev/ttyAMA0"): 21 | self.ser = serial.Serial(serName) 22 | print (self.ser.name) 23 | print (self.ser) 24 | self.state=IDLE 25 | def __enter__(self): 26 | return self 27 | def send(self,message): 28 | if self.state==IDLE and self.ser.isOpen(): 29 | self.state=SEND 30 | self.ser.write(s2b(message)) 31 | self.state=IDLE 32 | 33 | def receive(self, chars=1, timeout=5, echo=True, 34 | terminate="\r"): 35 | message="" 36 | if self.state==IDLE and self.ser.isOpen(): 37 | self.state=RECEIVE 38 | self.ser.timeout=timeout 39 | while self.state==RECEIVE: 40 | echovalue="" 41 | while self.ser.inWaiting() > 0: 42 | echovalue += b2s(self.ser.read(chars)) 43 | if echo==True: 44 | self.ser.write(s2b(echovalue)) 45 | message+=echovalue 46 | if terminate in message: 47 | self.state=IDLE 48 | return message 49 | def __exit__(self,type,value,traceback): 50 | self.ser.close() 51 | 52 | def main(): 53 | try: 54 | with serPort(serName=SERNAME) as mySerialPort: 55 | mySerialPort.send("Send some data to me!\r\n") 56 | while True: 57 | print ("Waiting for input:") 58 | print (mySerialPort.receive()) 59 | except OSError: 60 | print ("Check selected port is valid: %s" %serName) 61 | except KeyboardInterrupt: 62 | print ("Finished") 63 | 64 | if __name__=="__main__": 65 | main() 66 | #End 67 | -------------------------------------------------------------------------------- /Chapter 10/serialMenu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #serialMenu.py 3 | import time 4 | import RPi.GPIO as GPIO 5 | import serialControl as SC 6 | SERNAME = "/dev/ttyUSB0" 7 | running=True 8 | 9 | CMD=0;PIN=1;STATE=2;OFF=0;ON=1 10 | GPIO_PINS=[7,11,12,13,15,16,18,22] 11 | GPIO_STATE=["OFF","ON"] 12 | EXIT="EXIT" 13 | 14 | def gpioSetup(): 15 | GPIO.setmode(GPIO.BOARD) 16 | for pin in GPIO_PINS: 17 | GPIO.setup(pin,GPIO.OUT) 18 | 19 | def handleCmd(cmd): 20 | global running 21 | commands=cmd.upper() 22 | commands=commands.split() 23 | valid=False 24 | print ("Received: "+ str(commands)) 25 | if len(commands)==3: 26 | if commands[CMD]=="GPIO": 27 | for pin in GPIO_PINS: 28 | if str(pin)==commands[PIN]: 29 | print ("GPIO pin is valid") 30 | if GPIO_STATE[OFF]==commands[STATE]: 31 | print ("Switch GPIO %s %s"% (commands[PIN], 32 | commands[STATE])) 33 | GPIO.output(pin,OFF) 34 | valid=True 35 | elif GPIO_STATE[ON]==commands[STATE]: 36 | print ("Switch GPIO %s %s"% (commands[PIN], 37 | commands[STATE])) 38 | GPIO.output(pin,ON) 39 | valid=True 40 | elif commands[CMD]==EXIT: 41 | print("Exit") 42 | valid=True 43 | running=False 44 | if valid==False: 45 | print ("Received command is invalid") 46 | response=" Invalid:GPIO Pin#(%s) %s\r\n"% ( 47 | str(GPIO_PINS), str(GPIO_STATE)) 48 | else: 49 | response=" OK\r\n" 50 | return (response) 51 | 52 | def main(): 53 | try: 54 | gpioSetup() 55 | with SC.serPort(serName=SERNAME) as mySerialPort: 56 | mySerialPort.send("\r\n") 57 | mySerialPort.send(" GPIO Serial Control\r\n") 58 | mySerialPort.send(" -------------------\r\n") 59 | mySerialPort.send(" CMD PIN STATE "+ 60 | "[GPIO Pin# ON]\r\n") 61 | while running==True: 62 | print ("Waiting for command...") 63 | mySerialPort.send(">>") 64 | cmd = mySerialPort.receive(terminate="\r\n") 65 | response=handleCmd(cmd) 66 | mySerialPort.send(response) 67 | mySerialPort.send(" Finished!\r\n") 68 | except OSError: 69 | print ("Check selected port is valid: %s" %serName) 70 | except KeyboardInterrupt: 71 | print ("Finished") 72 | finally: 73 | GPIO.cleanup() 74 | 75 | main() 76 | #End 77 | -------------------------------------------------------------------------------- /Chapter 10/serialTest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #serialTest.py 3 | import serial 4 | import time 5 | 6 | WAITTIME=1 7 | serName="/dev/ttyAMA0" 8 | ser = serial.Serial(serName) 9 | print (ser.name) 10 | print (ser) 11 | if ser.isOpen(): 12 | try: 13 | print("For Serial Loopback - connect GPIO Pin8 and Pin10") 14 | print("[Type Message and Press Enter to continue]") 15 | print("#:") 16 | command=input() 17 | ser.write(bytearray(command+"\r\n","ascii")) 18 | time.sleep(WAITTIME) 19 | out="" 20 | while ser.inWaiting() > 0: 21 | out += bytes.decode(ser.read(1)) 22 | if out != "": 23 | print (">>" + out) 24 | else: 25 | print ("No data Received") 26 | except KeyboardInterrupt: 27 | ser.close() 28 | #End 29 | 30 | -------------------------------------------------------------------------------- /Chapter 10/socketControl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # socketControl.py 3 | import time 4 | import RPi.GPIO as GPIO 5 | #HARDWARE SETUP 6 | # P1 7 | # 2[V=G====XI====]26[=======]40 8 | # 1[=====321=====]25[=======]39 9 | #V=5V G=Gnd 10 | sw_num=[15,13,11]#Pins for Switch 1,2,3 11 | sw_state=[16,18]#Pins for State X=Off,I=On 12 | MSGOFF=0; MSGON=1 13 | SW_ACTIVE=0; SW_INACTIVE=1 14 | 15 | class Switch(): 16 | def __init__(self): 17 | self.setup() 18 | def __enter__(self): 19 | return self 20 | def setup(self): 21 | print("Do init") 22 | #Setup the wiring 23 | GPIO.setmode(GPIO.BOARD) 24 | for pin in sw_num: 25 | GPIO.setup(pin,GPIO.OUT) 26 | for pin in sw_state: 27 | GPIO.setup(pin,GPIO.OUT) 28 | self.clear() 29 | def message(self,number,state): 30 | print ("SEND SW_CMD: %s %d" % (number,state)) 31 | if state==MSGON: 32 | self.on(number) 33 | else: 34 | self.off(number) 35 | def on(self,number): 36 | print ("ON: %d"% number) 37 | GPIO.output(sw_num[number-1],SW_ACTIVE) 38 | GPIO.output(sw_state[MSGON],SW_ACTIVE) 39 | GPIO.output(sw_state[MSGOFF],SW_INACTIVE) 40 | time.sleep(0.5) 41 | self.clear() 42 | def off(self,number): 43 | print ("OFF: %d"% number) 44 | GPIO.output(sw_num[number-1],SW_ACTIVE) 45 | GPIO.output(sw_state[MSGON],SW_INACTIVE) 46 | GPIO.output(sw_state[MSGOFF],SW_ACTIVE) 47 | time.sleep(0.5) 48 | self.clear() 49 | def clear(self): 50 | for pin in sw_num: 51 | GPIO.output(pin,SW_INACTIVE) 52 | for pin in sw_state: 53 | GPIO.output(pin,SW_INACTIVE) 54 | def __exit__(self, type, value, traceback): 55 | self.clear() 56 | GPIO.cleanup() 57 | 58 | def main(): 59 | with Switch() as mySwitches: 60 | mySwitches.on(1) 61 | time.sleep(5) 62 | mySwitches.off(1) 63 | 64 | if __name__ == "__main__": 65 | main() 66 | #End 67 | -------------------------------------------------------------------------------- /Chapter 10/socketMenu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #socketMenu.py 3 | import tkinter as TK 4 | import socketControl as SC 5 | 6 | #Define Switches ["Switch name","Switch number"] 7 | switch1 = ["Living Room Lamp",1] 8 | switch2 = ["Coffee Machine",2] 9 | switch3 = ["Bedroom Fan",3] 10 | sw_list = [switch1,switch2,switch3] 11 | SW_NAME = 0; SW_CMD = 1 12 | SW_COLOR=["gray","green"] 13 | 14 | class swButtons: 15 | def __init__(self,gui,sw_index,switchCtrl): 16 | #Add the buttons to window 17 | self.msgType=TK.IntVar() 18 | self.msgType.set(SC.MSGOFF) 19 | self.btn = TK.Button(gui, 20 | text=sw_list[sw_index][SW_NAME], 21 | width=30, command=self.sendMsg, 22 | bg=SW_COLOR[self.msgType.get()]) 23 | self.btn.pack() 24 | msgOn = TK.Radiobutton(gui,text="On", 25 | variable=self.msgType, value=SC.MSGON) 26 | msgOn.pack() 27 | msgOff = TK.Radiobutton(gui,text="Off", 28 | variable=self.msgType,value=SC.MSGOFF) 29 | msgOff.pack() 30 | self.sw_num=sw_list[sw_index][SW_CMD] 31 | self.sw_ctrl=switchCtrl 32 | def sendMsg(self): 33 | print ("SW_CMD: %s %d" % (self.sw_num, 34 | self.msgType.get())) 35 | self.btn.configure(bg=SW_COLOR[self.msgType.get()]) 36 | self.sw_ctrl.message(self.sw_num, 37 | self.msgType.get()) 38 | 39 | root = TK.Tk() 40 | root.title("Remote Switches") 41 | prompt = "Control a switch" 42 | label1 = TK.Label(root, text=prompt, width=len(prompt), 43 | justify=TK.CENTER, bg='lightblue') 44 | label1.pack() 45 | #Create the switch 46 | with SC.Switch() as mySwitches: 47 | #Create menu buttons from sw_list 48 | for index, app in enumerate(sw_list): 49 | swButtons(root,index,mySwitches) 50 | root.mainloop() 51 | #End 52 | -------------------------------------------------------------------------------- /Chapter 10/spiTest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # spiTest.py 3 | import wiringpi 4 | 5 | print("Add SPI Loopback - connect GPIO Pin19 and Pin21") 6 | print("[Press Enter to continue]") 7 | input() 8 | wiringpi.wiringPiSPISetup(1,500000) 9 | buffer=str.encode("HELLO") 10 | print("Buffer sent %s" % buffer) 11 | wiringpi.wiringPiSPIDataRW(1,buffer) 12 | print("Buffer received %s" % buffer) 13 | print("Remove the SPI Loopback") 14 | print("[Press Enter to continue]") 15 | input() 16 | buffer=str.encode("HELLO") 17 | print("Buffer sent %s" % buffer) 18 | wiringpi.wiringPiSPIDataRW(1,buffer) 19 | print("Buffer received %s" % buffer) 20 | #End 21 | -------------------------------------------------------------------------------- /Chapter 3/encryptdecrypt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #encryptdecrypt.py 3 | 4 | #Takes the input_text and encrypts it, returning the result 5 | def encryptText(input_text,key): 6 | input_text=input_text.upper() 7 | result = "" 8 | for letter in input_text: 9 | #Ascii Uppercase 65-90 Lowercase 97-122 (Full range 32-126) 10 | ascii_value=ord(letter) 11 | #Exclude non-characters from encryption 12 | if (ord("A") > ascii_value) or (ascii_value > ord("Z")): 13 | result+=letter 14 | else: 15 | #Apply encryption key 16 | key_value = ascii_value+key 17 | #Ensure we just use A-Z regardless of key 18 | if not((ord("A")) < key_value < ord("Z")): 19 | key_value=ord("A") + (key_value-ord("A"))% 20 | (ord("Z")-ord("A")+1) 21 | #Add the encoded letter to the result string 22 | result+=str(chr(key_value)) 23 | return result 24 | 25 | #Test function, only called if script executed directly 26 | def main(): 27 | print ("Please enter text to scramble:") 28 | #Get user input 29 | try: 30 | user_input = input() 31 | scrambled_result = encryptText(user_input,10) 32 | print ("Result: " + scrambled_result) 33 | print ("To un-scramble, press enter again") 34 | input() 35 | unscrambled_result = encryptText(scrambled_result,-10) 36 | print ("Result: " + unscrambled_result) 37 | except UnicodeDecodeError: 38 | print ("Sorry: Only ASCII Characters are supported") 39 | 40 | if __name__=="__main__": 41 | main() 42 | #End 43 | -------------------------------------------------------------------------------- /Chapter 3/filehandler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #filehandler.py 3 | import os 4 | import shutil 5 | import photohandler as PH 6 | from operator import itemgetter 7 | 8 | FOLDERSONLY=True 9 | DEBUG=True 10 | defaultpath="" 11 | NAME=0 12 | DATE=1 13 | 14 | class FileList: 15 | def __init__(self,folder): 16 | """Class constructor""" 17 | self.folder=folder 18 | self.listFileDates() 19 | 20 | def getPhotoNamedates(self): 21 | """returns the list of filenames and dates""" 22 | return self.photo_namedates 23 | 24 | def listFileDates(self): 25 | """Generate list of filenames and dates""" 26 | self.photo_namedates = list() 27 | if os.path.isdir(self.folder): 28 | for filename in os.listdir(self.folder): 29 | if filename.lower().endswith(".jpg"): 30 | aPhoto = PH.Photo(os.path.join(self.folder,filename)) 31 | if aPhoto.filevalid: 32 | if (DEBUG):print("NameDate: %s %s"% 33 | (filename,aPhoto.getDate())) 34 | self.photo_namedates.append((filename, 35 | aPhoto.getDate())) 36 | self.photo_namedates = sorted(self.photo_namedates, 37 | key=lambda date: date[DATE]) 38 | 39 | def genFolders(self): 40 | """function to generate folders""" 41 | for i,namedate in enumerate(self.getPhotoNamedates()): 42 | #Remove the - from the date format 43 | new_folder=namedate[DATE].replace("-","") 44 | newpath = os.path.join(self.folder,new_folder) 45 | #If path does not exist create folder 46 | if not os.path.exists(newpath): 47 | if (DEBUG):print ("New Path: %s" % newpath) 48 | os.makedirs(newpath) 49 | if (DEBUG):print ("Found file: %s move to %s" % 50 | (namedate[NAME],newpath)) 51 | src_file = os.path.join(self.folder,namedate[NAME]) 52 | dst_file = os.path.join(newpath,namedate[NAME]) 53 | try: 54 | if (DEBUG):print ("File moved %s to %s" % 55 | (src_file, dst_file)) 56 | if (FOLDERSONLY==False):shutil.move(src_file, dst_file) 57 | except IOError: 58 | print ("Skipped: File not found") 59 | 60 | def main(): 61 | """called only when run directly, allowing module testing""" 62 | import tkinter as TK 63 | from tkinter import filedialog 64 | app = TK.Tk() 65 | app.withdraw() 66 | dirname = TK.filedialog.askdirectory(parent=app, 67 | initialdir=defaultpath, 68 | title='Select your pictures folder') 69 | if dirname != "": 70 | ourFileList=FileList(dirname) 71 | ourFileList.genFolders() 72 | 73 | if __name__=="__main__": 74 | main() 75 | #End 76 | -------------------------------------------------------------------------------- /Chapter 3/graphicmenu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # graphicmenu.py 3 | import tkinter as tk 4 | from subprocess import call 5 | import threading 6 | 7 | #Define applications ["Display name","command"] 8 | leafpad = ["Leafpad","leafpad"] 9 | scratch = ["Scratch","scratch"] 10 | pistore = ["Pi Store","pistore"] 11 | app_list = [leafpad,scratch,pistore] 12 | APP_NAME = 0 13 | APP_CMD = 1 14 | 15 | class runApplictionThread(threading.Thread): 16 | def __init__(self,app_cmd): 17 | threading.Thread.__init__(self) 18 | self.cmd = app_cmd 19 | def run(self): 20 | #Run the command, if valid 21 | try: 22 | call(self.cmd) 23 | except: 24 | print ("Unable to run: %s" % self.cmd) 25 | 26 | class appButtons: 27 | def __init__(self,gui,app_index): 28 | #Add the buttons to window 29 | btn = tk.Button(gui, text=app_list[app_index][APP_NAME], 30 | width=30, command=self.startApp) 31 | btn.pack() 32 | self.app_cmd=app_list[app_index][APP_CMD] 33 | def startApp(self): 34 | print ("APP_CMD: %s" % self.app_cmd) 35 | runApplictionThread(self.app_cmd).start() 36 | 37 | root = tk.Tk() 38 | root.title("App Menu") 39 | prompt = ' Select an application ' 40 | label1 = tk.Label(root, text=prompt, width=len(prompt), bg='green') 41 | label1.pack() 42 | #Create menu buttons from app_list 43 | for index, app in enumerate(app_list): 44 | appButtons(root,index) 45 | #Run the tk window 46 | root.mainloop() 47 | #End -------------------------------------------------------------------------------- /Chapter 3/photohandler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #photohandler.py 3 | from PIL import Image 4 | from PIL import ExifTags 5 | import datetime 6 | import os 7 | 8 | #set module values 9 | previewsize=240,240 10 | defaultimagepreview="./preview.ppm" 11 | filedate_to_use="Exif DateTime" 12 | #Define expected inputs 13 | ARG_IMAGEFILE=1 14 | ARG_LENGTH=2 15 | 16 | class Photo: 17 | def __init__(self,filename): 18 | """Class constructor""" 19 | self.filename=filename 20 | self.filevalid=False 21 | self.exifvalid=False 22 | img=self.initImage() 23 | if self.filevalid==True: 24 | self.initExif(img) 25 | self.initDates() 26 | 27 | def initImage(self): 28 | """opens the image and confirms if valid, returns Image""" 29 | try: 30 | img=Image.open(self.filename) 31 | self.filevalid=True 32 | except IOError: 33 | print ("Target image not found/valid %s" % 34 | (self.filename)) 35 | img=None 36 | self.filevalid=False 37 | return img 38 | 39 | def initExif(self,image): 40 | """gets any Exif data from the photo""" 41 | try: 42 | self.exif_info={ 43 | ExifTags.TAGS[x]:y 44 | for x,y in image._getexif().items() 45 | if x in ExifTags.TAGS 46 | } 47 | self.exifvalid=True 48 | except AttributeError: 49 | print ("Image has no Exif Tags") 50 | self.exifvalid=False 51 | 52 | 53 | def initDates(self): 54 | """determines the date the photo was taken""" 55 | #Gather all the times available into YYYY-MM-DD format 56 | self.filedates={} 57 | if self.exifvalid: 58 | #Get the date info from Exif info 59 | exif_ids=["DateTime","DateTimeOriginal", 60 | "DateTimeDigitized"] 61 | for id in exif_ids: 62 | dateraw=self.exif_info[id] 63 | self.filedates["Exif "+id]=\ 64 | dateraw[:10].replace(":","-") 65 | modtimeraw = os.path.getmtime(self.filename) 66 | self.filedates["File ModTime"]="%s" %\ 67 | datetime.datetime.fromtimestamp(modtimeraw).date() 68 | createtimeraw = os.path.getctime(self.filename) 69 | self.filedates["File CreateTime"]="%s" %\ 70 | datetime.datetime.fromtimestamp(createtimeraw).date() 71 | 72 | def getDate(self): 73 | """returns the date the image was taken""" 74 | try: 75 | date = self.filedates[filedate_to_use] 76 | except KeyError: 77 | print ("Exif Date not found") 78 | date = self.filedates["File ModTime"] 79 | return date 80 | 81 | def previewPhoto(self): 82 | """creates a thumbnail image suitable for tk to display""" 83 | imageview=self.initImage() 84 | imageview=imageview.convert('RGB') 85 | imageview.thumbnail(previewsize,Image.ANTIALIAS) 86 | imageview.save(defaultimagepreview,format='ppm') 87 | return defaultimagepreview 88 | 89 | #Module test code 90 | def dispPreview(aPhoto): 91 | """Create a test GUI""" 92 | import tkinter as TK 93 | 94 | #Define the app window 95 | app = TK.Tk() 96 | app.title("Photo View Demo") 97 | 98 | #Define TK objects 99 | # create an empty canvas object the same size as the image 100 | canvas = TK.Canvas(app, width=previewsize[0], 101 | height=previewsize[1]) 102 | canvas.grid(row=0,rowspan=2) 103 | # Add list box to display the photo data 104 | #(including xyscroll bars) 105 | photoInfo=TK.Variable() 106 | lbPhotoInfo=TK.Listbox(app,listvariable=photoInfo, 107 | height=18,width=45, 108 | font=("monospace",10)) 109 | yscroll=TK.Scrollbar(command=lbPhotoInfo.yview, 110 | orient=TK.VERTICAL) 111 | xscroll=TK.Scrollbar(command=lbPhotoInfo.xview, 112 | orient=TK.HORIZONTAL) 113 | lbPhotoInfo.configure(xscrollcommand=xscroll.set, 114 | yscrollcommand=yscroll.set) 115 | lbPhotoInfo.grid(row=0,column=1,sticky=TK.N+TK.S) 116 | yscroll.grid(row=0,column=2,sticky=TK.N+TK.S) 117 | xscroll.grid(row=1,column=1,sticky=TK.N+TK.E+TK.W) 118 | 119 | # Generate the preview image 120 | preview_filename = aPhoto.previewPhoto() 121 | photoImg = TK.PhotoImage(file=preview_filename) 122 | # anchor image to NW corner 123 | canvas.create_image(0,0, anchor=TK.NW, image=photoImg) 124 | 125 | # Populate infoList with dates and exif data 126 | infoList=[] 127 | for key,value in aPhoto.filedates.items(): 128 | infoList.append(key.ljust(25) + value) 129 | if aPhoto.exifvalid: 130 | for key,value in aPhoto.exif_info.items(): 131 | infoList.append(key.ljust(25) + str(value)) 132 | # Set listvariable with the infoList 133 | photoInfo.set(tuple(infoList)) 134 | 135 | app.mainloop() 136 | 137 | def main(): 138 | """called only when run directly, allowing module testing""" 139 | import sys 140 | #Check the arguments 141 | if len(sys.argv) == ARG_LENGTH: 142 | print ("Command: %s" %(sys.argv)) 143 | #Create an instance of the Photo class 144 | viewPhoto = Photo(sys.argv[ARG_IMAGEFILE]) 145 | #Test the module by running a GUI 146 | if viewPhoto.filevalid==True: 147 | dispPreview(viewPhoto) 148 | else: 149 | print ("Usage: photohandler.py imagefile") 150 | 151 | if __name__=='__main__': 152 | main() 153 | #End 154 | 155 | -------------------------------------------------------------------------------- /Chapter 3/photohandler_1stpart.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #photohandler.py 3 | from PIL import Image 4 | from PIL import ExifTags 5 | import datetime 6 | import os 7 | 8 | #set module values 9 | previewsize=240,240 10 | defaultimagepreview="./preview.ppm" 11 | filedate_to_use="Exif DateTime" 12 | #Define expected inputs 13 | ARG_IMAGEFILE=1 14 | ARG_LENGTH=2 15 | 16 | class Photo: 17 | def __init__(self,filename): 18 | """Class constructor""" 19 | self.filename=filename 20 | self.filevalid=False 21 | self.exifvalid=False 22 | img=self.initImage() 23 | if self.filevalid==True: 24 | self.initExif(img) 25 | self.initDates() 26 | 27 | def initImage(self): 28 | """opens the image and confirms if valid, returns Image""" 29 | try: 30 | img=Image.open(self.filename) 31 | self.filevalid=True 32 | except IOError: 33 | print ("Target image not found/valid %s" % 34 | (self.filename)) 35 | img=None 36 | self.filevalid=False 37 | return img 38 | 39 | def initExif(self,image): 40 | """gets any Exif data from the photo""" 41 | try: 42 | self.exif_info={ 43 | ExifTags.TAGS[x]:y 44 | for x,y in image._getexif().items() 45 | if x in ExifTags.TAGS 46 | } 47 | self.exifvalid=True 48 | except AttributeError: 49 | print ("Image has no Exif Tags") 50 | self.exifvalid=False 51 | 52 | 53 | def initDates(self): 54 | """determines the date the photo was taken""" 55 | #Gather all the times available into YYYY-MM-DD format 56 | self.filedates={} 57 | if self.exifvalid: 58 | #Get the date info from Exif info 59 | exif_ids=["DateTime","DateTimeOriginal", 60 | "DateTimeDigitized"] 61 | for id in exif_ids: 62 | dateraw=self.exif_info[id] 63 | self.filedates["Exif "+id]=\ 64 | dateraw[:10].replace(":","-") 65 | modtimeraw = os.path.getmtime(self.filename) 66 | self.filedates["File ModTime"]="%s" %\ 67 | datetime.datetime.fromtimestamp(modtimeraw).date() 68 | createtimeraw = os.path.getctime(self.filename) 69 | self.filedates["File CreateTime"]="%s" %\ 70 | datetime.datetime.fromtimestamp(createtimeraw).date() 71 | 72 | def getDate(self): 73 | """returns the date the image was taken""" 74 | try: 75 | date = self.filedates[filedate_to_use] 76 | except KeyError: 77 | print ("Exif Date not found") 78 | date = self.filedates["File ModTime"] 79 | return date 80 | 81 | def previewPhoto(self): 82 | """creates a thumbnail image suitable for tk to display""" 83 | imageview=self.initImage() 84 | imageview=imageview.convert('RGB') 85 | imageview.thumbnail(previewsize,Image.ANTIALIAS) 86 | imageview.save(defaultimagepreview,format='ppm') 87 | return defaultimagepreview 88 | 89 | -------------------------------------------------------------------------------- /Chapter 3/tkencryptdecrypt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #tkencryptdecrypt 3 | import encryptdecrypt as ENC 4 | import tkinter as TK 5 | 6 | def encryptButton(): 7 | encryptvalue.set(ENC.encryptText(encryptvalue.get(), 8 | keyvalue.get())) 9 | 10 | def decryptButton(): 11 | encryptvalue.set(ENC.encryptText(encryptvalue.get(), 12 | -keyvalue.get())) 13 | #Define Tkinter application 14 | root=TK.Tk() 15 | root.title("Encrypt/Decrypt GUI") 16 | #Set control & test value 17 | encryptvalue = TK.StringVar() 18 | encryptvalue.set("My Message") 19 | keyvalue = TK.IntVar() 20 | keyvalue.set(20) 21 | prompt="Enter message to encrypt:" 22 | key="Key:" 23 | 24 | label1=TK.Label(root,text=prompt,width=len(prompt),bg='green') 25 | textEnter=TK.Entry(root,textvariable=encryptvalue, 26 | width=len(prompt)) 27 | encryptButton=TK.Button(root,text="Encrypt",command=encryptButton) 28 | decryptButton=TK.Button(root,text="Decrypt",command=decryptButton) 29 | label2=TK.Label(root,text=key,width=len(key)) 30 | keyEnter=TK.Entry(root,textvariable=keyvalue,width=8) 31 | #Set layout 32 | label1.grid(row=0,columnspan=2,sticky=TK.E+TK.W) 33 | textEnter.grid(row=1,columnspan=2,sticky=TK.E+TK.W) 34 | encryptButton.grid(row=2,column=0,sticky=TK.E) 35 | decryptButton.grid(row=2,column=1,sticky=TK.W) 36 | label2.grid(row=3,column=0,sticky=TK.E) 37 | keyEnter.grid(row=3,column=1,sticky=TK.W) 38 | 39 | TK.mainloop() 40 | -------------------------------------------------------------------------------- /Chapter 6/btntest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #btntest.py 3 | import time 4 | import os 5 | import RPi.GPIO as GPIO 6 | #HARDWARE SETUP 7 | # P1 8 | # 2[==X==1=======]26 9 | # 1[=============]25 10 | #Button Config 11 | BTN = 12 12 | 13 | def gpio_setup(): 14 | #Setup the wiring 15 | GPIO.setmode(GPIO.BOARD) 16 | #Setup Ports 17 | GPIO.setup(BTN,GPIO.IN,pull_up_down=GPIO.PUD_UP) 18 | 19 | 20 | def main(): 21 | gpio_setup() 22 | count=0 23 | btn_closed = True 24 | while True: 25 | btn_val = GPIO.input(BTN) 26 | if btn_val and btn_closed: 27 | print("OPEN") 28 | btn_closed=False 29 | elif btn_val==False and btn_closed==False: 30 | count+=1 31 | print("CLOSE %s" % count) 32 | os.system("flite -t '%s'" % count) 33 | btn_closed=True 34 | time.sleep(0.1) 35 | 36 | try: 37 | main() 38 | finally: 39 | GPIO.cleanup() 40 | print("Closed Everything. END") 41 | #End 42 | -------------------------------------------------------------------------------- /Chapter 6/gpiokeys-events.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #gpiokeys-events.py 3 | import time 4 | import RPi.GPIO as GPIO 5 | import uinput 6 | 7 | #HARDWARE SETUP 8 | # P1 9 | # 2[==G=====<=V==]26 10 | # 1[===2=1>^=====]25 11 | B_DOWN = 22 #V 12 | B_LEFT = 18 #< 13 | B_UP = 15 #^ 14 | B_RIGHT = 13 #> 15 | B_1 = 11 #1 16 | B_2 = 7 #2 17 | 18 | DEBUG=False 19 | 20 | BTN = [B_UP,B_DOWN,B_LEFT,B_RIGHT,B_1,B_2] 21 | MSG = ["UP","DOWN","LEFT","RIGHT","1","2"] 22 | 23 | #Setup the DPad module pins and pull-ups 24 | def dpad_setup(): 25 | #Set up the wiring 26 | GPIO.setmode(GPIO.BOARD) 27 | # Setup BTN Ports as INPUTS 28 | for val in BTN: 29 | # set up GPIO input with pull-up control 30 | #(pull_up_down can be: 31 | # PUD_OFF, PUD_UP or PUD_DOWN, default PUD_OFF) 32 | GPIO.setup(val, GPIO.IN, pull_up_down=GPIO.PUD_UP) 33 | 34 | def main(): 35 | #Setup uinput 36 | events_dpad = (uinput.KEY_UP,uinput.KEY_DOWN,uinput.KEY_LEFT, 37 | uinput.KEY_RIGHT,uinput.KEY_ENTER,uinput.KEY_ENTER) 38 | events_z80 = (uinput.KEY_Q,uinput.KEY_A,uinput.KEY_O, 39 | uinput.KEY_P,uinput.KEY_M,uinput.KEY_ENTER) 40 | events=events_z80 41 | 42 | device = uinput.Device(events) 43 | time.sleep(2) # seconds 44 | dpad_setup() 45 | print("DPad Ready!") 46 | 47 | btn_state=[False,False,False,False,False,False] 48 | key_state=[False,False,False,False,False,False] 49 | while True: 50 | #Catch all the buttons pressed before pressing the related keys 51 | for idx, val in enumerate(BTN): 52 | if GPIO.input(val) == False: 53 | btn_state[idx]=True 54 | else: 55 | btn_state[idx]=False 56 | 57 | #Perform the button presses/releases 58 | #(but only change state once) 59 | for idx, val in enumerate(btn_state): 60 | if val == True and key_state[idx] == False: 61 | if DEBUG:print (str(val) + ":" + MSG[idx]) 62 | device.emit(events[idx], 1) # Press. 63 | key_state[idx]=True 64 | elif val == False and key_state[idx] == True: 65 | if DEBUG:print (str(val) + ":!" + MSG[idx]) 66 | device.emit(events[idx], 0) # Release. 67 | key_state[idx]=False 68 | 69 | time.sleep(.1) 70 | 71 | try: 72 | main() 73 | finally: 74 | GPIO.cleanup() 75 | #End 76 | -------------------------------------------------------------------------------- /Chapter 6/gpiokeys-mouse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #gpiokeys-mouse.py 3 | import time 4 | import RPi.GPIO as GPIO 5 | import uinput 6 | 7 | #HARDWARE SETUP 8 | # P1 9 | # 2[==G=====<=V==]26 10 | # 1[===2=1>^=====]25 11 | B_DOWN = 22 #V 12 | B_LEFT = 18 #< 13 | B_UP = 15 #^ 14 | B_RIGHT = 13 #> 15 | B_1 = 11 #1 16 | B_2 = 7 #2 17 | 18 | DEBUG=False 19 | 20 | BTN = [B_UP,B_DOWN,B_LEFT,B_RIGHT,B_1,B_2] 21 | #MSG = ["UP","DOWN","LEFT","RIGHT","1","2"] 22 | MSG = ["M_UP","M_DOWN","M_LEFT","M_RIGHT","1","Enter"] 23 | 24 | #Setup the DPad module pins and pull-ups 25 | def dpad_setup(): 26 | #Set up the wiring 27 | GPIO.setmode(GPIO.BOARD) 28 | # Setup BTN Ports as INPUTS 29 | for val in BTN: 30 | # set up GPIO input with pull-up control 31 | #(pull_up_down can be: 32 | # PUD_OFF, PUD_UP or PUD_DOWN, default PUD_OFF) 33 | GPIO.setup(val, GPIO.IN, pull_up_down=GPIO.PUD_UP) 34 | 35 | def main(): 36 | #Setup uinput 37 | events_mouse=(uinput.REL_Y,uinput.REL_Y, uinput.REL_X, 38 | uinput.REL_X,uinput.BTN_LEFT,uinput.BTN_RIGHT) 39 | events = events_mouse 40 | device = uinput.Device(events) 41 | time.sleep(2) # seconds 42 | dpad_setup() 43 | print("DPad Ready!") 44 | 45 | btn_state=[False,False,False,False,False,False] 46 | key_state=[False,False,False,False,False,False] 47 | while True: 48 | #Catch all the buttons pressed before pressing the related keys 49 | for idx, val in enumerate(BTN): 50 | if GPIO.input(val) == False: 51 | btn_state[idx]=True 52 | else: 53 | btn_state[idx]=False 54 | 55 | #Perform the button presses/releases 56 | #(but only change state once) 57 | for idx, val in enumerate(btn_state): 58 | if MSG[idx] == "M_UP" or MSG[idx] == "M_LEFT": 59 | state = -1 60 | else: 61 | state = 1 62 | if val == True: 63 | device.emit(events[idx], state) # Press. 64 | elif val == False: 65 | device.emit(events[idx], 0) # Release. 66 | 67 | time.sleep(0.01) 68 | 69 | try: 70 | main() 71 | finally: 72 | GPIO.cleanup() 73 | #End 74 | -------------------------------------------------------------------------------- /Chapter 6/gpiokeys.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #gpiokeys.py 3 | import time 4 | import RPi.GPIO as GPIO 5 | import uinput 6 | 7 | #HARDWARE SETUP 8 | # P1 9 | # 2[==G=====<=V==]26 10 | # 1[===2=1>^=====]25 11 | B_DOWN = 22 #V 12 | B_LEFT = 18 #< 13 | B_UP = 15 #^ 14 | B_RIGHT = 13 #> 15 | B_1 = 11 #1 16 | B_2 = 7 #2 17 | 18 | DEBUG=True 19 | BTN = [B_UP,B_DOWN,B_LEFT,B_RIGHT,B_1,B_2] 20 | MSG = ["UP","DOWN","LEFT","RIGHT","1","2"] 21 | 22 | #Setup the DPad module pins and pull-ups 23 | def dpad_setup(): 24 | #Set up the wiring 25 | GPIO.setmode(GPIO.BOARD) 26 | # Setup BTN Ports as INPUTS 27 | for val in BTN: 28 | # set up GPIO input with pull-up control 29 | #(pull_up_down can be: 30 | # PUD_OFF, PUD_UP or PUD_DOWN, default PUD_OFF) 31 | GPIO.setup(val, GPIO.IN, pull_up_down=GPIO.PUD_UP) 32 | 33 | def main(): 34 | #Setup uinput 35 | events = (uinput.KEY_UP,uinput.KEY_DOWN,uinput.KEY_LEFT, 36 | uinput.KEY_RIGHT,uinput.KEY_ENTER,uinput.KEY_ENTER) 37 | device = uinput.Device(events) 38 | time.sleep(2) # seconds 39 | dpad_setup() 40 | print("DPad Ready!") 41 | 42 | btn_state=[False,False,False,False,False,False] 43 | key_state=[False,False,False,False,False,False] 44 | while True: 45 | #Catch all the buttons pressed before pressing the related keys 46 | for idx, val in enumerate(BTN): 47 | if GPIO.input(val) == False: 48 | btn_state[idx]=True 49 | else: 50 | btn_state[idx]=False 51 | 52 | #Perform the button presses/releases 53 | #(but only change state once) 54 | for idx, val in enumerate(btn_state): 55 | if val == True and key_state[idx] == False: 56 | if DEBUG:print (str(val) + ":" + MSG[idx]) 57 | device.emit(events[idx], 1) # Press. 58 | key_state[idx]=True 59 | elif val == False and key_state[idx] == True: 60 | if DEBUG:print (str(val) + ":!" + MSG[idx]) 61 | device.emit(events[idx], 0) # Release. 62 | key_state[idx]=False 63 | 64 | time.sleep(.1) 65 | 66 | try: 67 | main() 68 | finally: 69 | GPIO.cleanup() 70 | #End 71 | -------------------------------------------------------------------------------- /Chapter 6/ledtest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #ledtest.py 3 | import time 4 | import RPi.GPIO as GPIO 5 | # RGB LED module 6 | #HARDWARE SETUP 7 | # P1 8 | # 2[======XRG=B==]26 9 | # 1[=============]25 10 | # X=GND R=Red G=Green B=Blue 11 | 12 | #Setup Active States 13 | #Common Cathode RGB-LED (Cathode=Active Low) 14 | RGB_ENABLE = 1; RGB_DISABLE = 0 15 | 16 | #LED CONFIG - Set GPIO Ports 17 | RGB_RED = 16; RGB_GREEN = 18; RGB_BLUE = 22 18 | RGB = [RGB_RED,RGB_GREEN,RGB_BLUE] 19 | 20 | def led_setup(): 21 | #Setup the wiring 22 | GPIO.setmode(GPIO.BOARD) 23 | #Setup Ports 24 | for val in RGB: 25 | GPIO.setup(val,GPIO.OUT) 26 | 27 | def main(): 28 | led_setup() 29 | for val in RGB: 30 | GPIO.output(val,RGB_ENABLE) 31 | print("LED ON") 32 | time.sleep(5) 33 | GPIO.output(val,RGB_DISABLE) 34 | print("LED OFF") 35 | 36 | try: 37 | main() 38 | finally: 39 | GPIO.cleanup() 40 | print("Closed Everything. END") 41 | #End 42 | -------------------------------------------------------------------------------- /Chapter 6/rgbled-part1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #rgbled-part1.py 3 | import time 4 | import RPi.GPIO as GPIO 5 | 6 | #Setup Active states 7 | #Common Cathode RGB-LEDs (Cathode=Active Low) 8 | LED_ENABLE = 0; LED_DISABLE = 1 9 | RGB_ENABLE = 1; RGB_DISABLE = 0 10 | #HARDWARE SETUP 11 | # P1 12 | # 2[=====1=23=4==]26 13 | # 1[===5=RGB=====]25 14 | #LED CONFIG - Set GPIO Ports 15 | LED1 = 12; LED2 = 16; LED3 = 18; LED4 = 22; LED5 = 7 16 | LED = [LED1,LED2,LED3,LED4,LED5] 17 | RGB_RED = 11; RGB_GREEN = 13; RGB_BLUE = 15 18 | RGB = [RGB_RED,RGB_GREEN,RGB_BLUE] 19 | #Mixed Colors 20 | RGB_CYAN = [RGB_GREEN,RGB_BLUE] 21 | RGB_MAGENTA = [RGB_RED,RGB_BLUE] 22 | RGB_YELLOW = [RGB_RED,RGB_GREEN] 23 | RGB_WHITE = [RGB_RED,RGB_GREEN,RGB_BLUE] 24 | RGB_LIST = [RGB_RED,RGB_GREEN,RGB_BLUE,RGB_CYAN, 25 | RGB_MAGENTA,RGB_YELLOW,RGB_WHITE] 26 | 27 | def led_setup(): 28 | '''Setup the RGB-LED module pins and state.''' 29 | #Set up the wiring 30 | GPIO.setmode(GPIO.BOARD) 31 | # Setup Ports 32 | for val in LED: 33 | GPIO.setup(val, GPIO.OUT) 34 | for val in RGB: 35 | GPIO.setup(val, GPIO.OUT) 36 | led_clear() 37 | 38 | def led_gpiocontrol(pins,state): 39 | '''This function will control the state of 40 | a single or multiple pins in a list.''' 41 | #determine if "pins" is a single integer or not 42 | if isinstance(pins,int): 43 | #Single integer - reference directly 44 | GPIO.output(pins,state) 45 | else: 46 | #if not, then cycle through the "pins" list 47 | for i in pins: 48 | GPIO.output(i,state) 49 | 50 | def led_activate(led,color): 51 | '''Enable the selected led(s) and set the required color(s) 52 | Will accept single or multiple values''' 53 | #Enable led 54 | led_gpiocontrol(led,LED_ENABLE) 55 | #Enable color 56 | led_gpiocontrol(color,RGB_ENABLE) 57 | 58 | def led_deactivate(led,color): 59 | '''Deactivate the selected led(s) and set the required 60 | color(s) will accept single or multiple values''' 61 | #Disable led 62 | led_gpiocontrol(led,LED_DISABLE) 63 | #Disable color 64 | led_gpiocontrol(color,RGB_DISABLE) 65 | 66 | def led_time(led, color, timeon): 67 | '''Switch on the led and color for the timeon period''' 68 | led_activate(led,color) 69 | time.sleep(timeon) 70 | led_deactivate(led,color) 71 | 72 | def led_clear(): 73 | '''Set the pins to default state.''' 74 | for val in LED: 75 | GPIO.output(val, LED_DISABLE) 76 | for val in RGB: 77 | GPIO.output(val, RGB_DISABLE) 78 | 79 | def led_cleanup(): 80 | '''Reset pins to default state and release GPIO''' 81 | led_clear() 82 | GPIO.cleanup() 83 | 84 | def main(): 85 | '''Directly run test function. 86 | This function will run if the file is executed directly''' 87 | led_setup() 88 | led_time(LED1,RGB_RED,5) 89 | led_time(LED2,RGB_GREEN,5) 90 | led_time(LED3,RGB_BLUE,5) 91 | led_time(LED,RGB_MAGENTA,2) 92 | led_time(LED,RGB_YELLOW,2) 93 | led_time(LED,RGB_CYAN,2) 94 | 95 | if __name__=='__main__': 96 | try: 97 | main() 98 | finally: 99 | led_cleanup() 100 | #End 101 | -------------------------------------------------------------------------------- /Chapter 6/rgbled-rand.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #rgbled-rand.py 3 | import time 4 | from random import randint 5 | import RPi.GPIO as GPIO 6 | 7 | #Setup Active states 8 | #Common Cathode RGB-LEDs (Cathode=Active Low) 9 | LED_ENABLE = 0; LED_DISABLE = 1 10 | RGB_ENABLE = 1; RGB_DISABLE = 0 11 | #HARDWARE SETUP 12 | # P1 13 | # 2[=====1=23=4==]26 14 | # 1[===5=RGB=====]25 15 | #LED CONFIG - Set GPIO Ports 16 | LED1 = 12; LED2 = 16; LED3 = 18; LED4 = 22; LED5 = 7 17 | LED = [LED1,LED2,LED3,LED4,LED5] 18 | RGB_RED = 11; RGB_GREEN = 13; RGB_BLUE = 15 19 | RGB = [RGB_RED,RGB_GREEN,RGB_BLUE] 20 | #Mixed Colors 21 | RGB_CYAN = [RGB_GREEN,RGB_BLUE] 22 | RGB_MAGENTA = [RGB_RED,RGB_BLUE] 23 | RGB_YELLOW = [RGB_RED,RGB_GREEN] 24 | RGB_WHITE = [RGB_RED,RGB_GREEN,RGB_BLUE] 25 | RGB_LIST = [RGB_RED,RGB_GREEN,RGB_BLUE,RGB_CYAN, 26 | RGB_MAGENTA,RGB_YELLOW,RGB_WHITE] 27 | 28 | def led_setup(): 29 | '''Setup the RGB-LED module pins and state.''' 30 | #Set up the wiring 31 | GPIO.setmode(GPIO.BOARD) 32 | # Setup Ports 33 | for val in LED: 34 | GPIO.setup(val, GPIO.OUT) 35 | for val in RGB: 36 | GPIO.setup(val, GPIO.OUT) 37 | led_clear() 38 | 39 | def led_gpiocontrol(pins,state): 40 | '''This function will control the state of 41 | a single or multiple pins in a list.''' 42 | #determine if "pins" is a single integer or not 43 | if isinstance(pins,int): 44 | #Single integer - reference directly 45 | GPIO.output(pins,state) 46 | else: 47 | #if not, then cycle through the "pins" list 48 | for i in pins: 49 | GPIO.output(i,state) 50 | 51 | def led_activate(led,color): 52 | '''Enable the selected led(s) and set the required color(s) 53 | Will accept single or multiple values''' 54 | #Enable led 55 | led_gpiocontrol(led,LED_ENABLE) 56 | #Enable color 57 | led_gpiocontrol(color,RGB_ENABLE) 58 | 59 | def led_deactivate(led,color): 60 | '''Deactivate the selected led(s) and set the required 61 | color(s) will accept single or multiple values''' 62 | #Disable led 63 | led_gpiocontrol(led,LED_DISABLE) 64 | #Disable color 65 | led_gpiocontrol(color,RGB_DISABLE) 66 | 67 | def led_time(led, color, timeon): 68 | '''Switch on the led and color for the timeon period''' 69 | led_activate(led,color) 70 | time.sleep(timeon) 71 | led_deactivate(led,color) 72 | 73 | def led_clear(): 74 | '''Set the pins to default state.''' 75 | for val in LED: 76 | GPIO.output(val, LED_DISABLE) 77 | for val in RGB: 78 | GPIO.output(val, RGB_DISABLE) 79 | 80 | def led_cleanup(): 81 | '''Reset pins to default state and release GPIO''' 82 | led_clear() 83 | GPIO.cleanup() 84 | 85 | def led_rgbrandom(led,period,colors): 86 | ''' Light up the selected led, for period in seconds, 87 | in one of the possible colors. The colors can be 88 | 1 to 3 for RGB, or 1-6 for RGB plus combinations, 89 | 1-7 includes white. Anything over 7 will be set as 90 | OFF (larger the number more chance of OFF).''' 91 | value = randint(1,colors) 92 | if value < len(RGB_LIST): 93 | led_time(led,RGB_LIST[value-1],period) 94 | 95 | 96 | def main(): 97 | '''Directly run test function. 98 | This function will run if the file is executed directly''' 99 | led_setup() 100 | led_time(LED1,RGB_RED,5) 101 | led_time(LED2,RGB_GREEN,5) 102 | led_time(LED3,RGB_BLUE,5) 103 | led_time(LED,RGB_MAGENTA,2) 104 | led_time(LED,RGB_YELLOW,2) 105 | led_time(LED,RGB_CYAN,2) 106 | for i in range(20): 107 | for j in LED: 108 | #Select from all, plus OFF 109 | led_rgbrandom(j,0.1,20) 110 | 111 | 112 | if __name__=='__main__': 113 | try: 114 | main() 115 | finally: 116 | led_cleanup() 117 | #End 118 | -------------------------------------------------------------------------------- /Chapter 6/rgbled.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #rgbled-part2.py 3 | import time 4 | import RPi.GPIO as GPIO 5 | 6 | #Setup Active states 7 | #Common Cathode RGB-LEDs (Cathode=Active Low) 8 | LED_ENABLE = 0; LED_DISABLE = 1 9 | RGB_ENABLE = 1; RGB_DISABLE = 0 10 | #HARDWARE SETUP 11 | # P1 12 | # 2[=====1=23=4==]26 13 | # 1[===5=RGB=====]25 14 | #LED CONFIG - Set GPIO Ports 15 | LED1 = 12; LED2 = 16; LED3 = 18; LED4 = 22; LED5 = 7 16 | LED = [LED1,LED2,LED3,LED4,LED5] 17 | RGB_RED = 11; RGB_GREEN = 13; RGB_BLUE = 15 18 | RGB = [RGB_RED,RGB_GREEN,RGB_BLUE] 19 | #Mixed Colors 20 | RGB_CYAN = [RGB_GREEN,RGB_BLUE] 21 | RGB_MAGENTA = [RGB_RED,RGB_BLUE] 22 | RGB_YELLOW = [RGB_RED,RGB_GREEN] 23 | RGB_WHITE = [RGB_RED,RGB_GREEN,RGB_BLUE] 24 | RGB_LIST = [RGB_RED,RGB_GREEN,RGB_BLUE,RGB_CYAN, 25 | RGB_MAGENTA,RGB_YELLOW,RGB_WHITE] 26 | #Combo Colors 27 | RGB_AQUA = [RGB_CYAN,RGB_GREEN] 28 | RGB_LBLUE = [RGB_CYAN,RGB_BLUE] 29 | RGB_PINK = [RGB_MAGENTA,RGB_RED] 30 | RGB_PURPLE = [RGB_MAGENTA,RGB_BLUE] 31 | RGB_ORANGE = [RGB_YELLOW,RGB_RED] 32 | RGB_LIME = [RGB_YELLOW,RGB_GREEN] 33 | RGB_COLORS = [RGB_LIME,RGB_YELLOW,RGB_ORANGE,RGB_RED, 34 | RGB_PINK,RGB_MAGENTA,RGB_PURPLE,RGB_BLUE, 35 | RGB_LBLUE,RGB_CYAN,RGB_AQUA,RGB_GREEN] 36 | 37 | def led_combo(pins,colors,period): 38 | #determine if "colors" is a single integer or not 39 | if isinstance(colors,int): 40 | #Single integer - reference directly 41 | led_time(pins,colors,period) 42 | else: 43 | #if not, then cycle through the "colors" list 44 | for i in colors: 45 | led_time(pins,i,period) 46 | 47 | def led_setup(): 48 | '''Setup the RGB-LED module pins and state.''' 49 | #Set up the wiring 50 | GPIO.setmode(GPIO.BOARD) 51 | # Setup Ports 52 | for val in LED: 53 | GPIO.setup(val, GPIO.OUT) 54 | for val in RGB: 55 | GPIO.setup(val, GPIO.OUT) 56 | led_clear() 57 | 58 | def led_gpiocontrol(pins,state): 59 | '''This function will control the state of 60 | a single or multiple pins in a list.''' 61 | #determine if "pins" is a single integer or not 62 | if isinstance(pins,int): 63 | #Single integer - reference directly 64 | GPIO.output(pins,state) 65 | else: 66 | #if not, then cycle through the "pins" list 67 | for i in pins: 68 | GPIO.output(i,state) 69 | 70 | def led_activate(led,color): 71 | '''Enable the selected led(s) and set the required color(s) 72 | Will accept single or multiple values''' 73 | #Enable led 74 | led_gpiocontrol(led,LED_ENABLE) 75 | #Enable color 76 | led_gpiocontrol(color,RGB_ENABLE) 77 | 78 | def led_deactivate(led,color): 79 | '''Deactivate the selected led(s) and set the required 80 | color(s) will accept single or multiple values''' 81 | #Disable led 82 | led_gpiocontrol(led,LED_DISABLE) 83 | #Disable color 84 | led_gpiocontrol(color,RGB_DISABLE) 85 | 86 | def led_time(led, color, timeon): 87 | '''Switch on the led and color for the timeon period''' 88 | led_activate(led,color) 89 | time.sleep(timeon) 90 | led_deactivate(led,color) 91 | 92 | def led_clear(): 93 | '''Set the pins to default state.''' 94 | for val in LED: 95 | GPIO.output(val, LED_DISABLE) 96 | for val in RGB: 97 | GPIO.output(val, RGB_DISABLE) 98 | 99 | def led_cleanup(): 100 | '''Reset pins to default state and release GPIO''' 101 | led_clear() 102 | GPIO.cleanup() 103 | 104 | def main(): 105 | '''Directly run test function. 106 | This function will run if the file is executed directly''' 107 | led_setup() 108 | led_time(LED1,RGB_RED,5) 109 | led_time(LED2,RGB_GREEN,5) 110 | led_time(LED3,RGB_BLUE,5) 111 | led_time(LED,RGB_MAGENTA,2) 112 | led_time(LED,RGB_YELLOW,2) 113 | led_time(LED,RGB_CYAN,2) 114 | 115 | if __name__=='__main__': 116 | try: 117 | main() 118 | finally: 119 | led_cleanup() 120 | #End 121 | -------------------------------------------------------------------------------- /Chapter 6/rgbledrainbow.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #rgbledrainbow.py 3 | import time 4 | import rgbled as RGBLED 5 | 6 | def next_value(number,max): 7 | number = number % max 8 | return number 9 | 10 | def main(): 11 | print ("Setup the RGB module") 12 | RGBLED.led_setup() 13 | 14 | # Multiple LEDs with different Colors 15 | print ("Switch on Rainbow") 16 | led_num = 0 17 | col_num = 0 18 | for l in range(5): 19 | print ("Cycle LEDs") 20 | for k in range(100): 21 | #Set the starting point for the next set of colors 22 | col_num = next_value(col_num+1,len(RGBLED.RGB_COLORS)) 23 | for i in range(20): #cycle time 24 | for j in range(5): #led cycle 25 | led_num = next_value(j,len(RGBLED.LED)) 26 | led_color = next_value(col_num+led_num, 27 | len(RGBLED.RGB_COLORS)) 28 | RGBLED.led_combo(RGBLED.LED[led_num], 29 | RGBLED.RGB_COLORS[led_color],0.001) 30 | 31 | print ("Cycle COLORs") 32 | for k in range(100): 33 | #Set the next color 34 | col_num = next_value(col_num+1,len(RGBLED.RGB_COLORS)) 35 | for i in range(20): #cycle time 36 | for j in range(5): #led cycle 37 | led_num = next_value(j,len(RGBLED.LED)) 38 | RGBLED.led_combo(RGBLED.LED[led_num], 39 | RGBLED.RGB_COLORS[col_num],0.001) 40 | print ("Finished") 41 | 42 | if __name__=='__main__': 43 | try: 44 | main() 45 | finally: 46 | RGBLED.led_cleanup() 47 | #End 48 | -------------------------------------------------------------------------------- /Chapter 6/shtdwn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #shtdown.py 3 | import time 4 | import RPi.GPIO as GPIO 5 | import os 6 | 7 | # Shutdown Script 8 | DEBUG=False 9 | SNDON=True 10 | #HARDWARE SETUP 11 | # P1 12 | # 2[==X==L=======]26 13 | # 1[===1=========]25 14 | #BTN CONFIG - Set GPIO Ports 15 | GPIO_MODE=GPIO.BOARD 16 | SHTDWN_BTN = 7 #1 17 | LED = 12 #L 18 | 19 | def gpio_setup(): 20 | #Setup the wiring 21 | GPIO.setmode(GPIO_MODE) 22 | #Setup Ports 23 | GPIO.setup(SHTDWN_BTN,GPIO.IN,pull_up_down=GPIO.PUD_UP) 24 | GPIO.setup(LED,GPIO.OUT) 25 | 26 | def doShutdown(): 27 | if(DEBUG):print("Press detected") 28 | time.sleep(3) 29 | if GPIO.input(SHTDWN_BTN): 30 | if(DEBUG):print("Ignore the shutdown (<3sec)") 31 | else: 32 | if(DEBUG):print ("Would shutdown the RPi Now") 33 | GPIO.output(LED,0) 34 | time.sleep(0.5) 35 | GPIO.output(LED,1) 36 | if(SNDON):os.system("flite -t 'Warning commencing power down'") 37 | if(DEBUG==False):os.system("sudo shutdown -h now") 38 | if(DEBUG):GPIO.cleanup() 39 | if(DEBUG):exit() 40 | 41 | def main(): 42 | gpio_setup() 43 | GPIO.output(LED,1) 44 | while True: 45 | if(DEBUG):print("Waiting for >3sec button press") 46 | if GPIO.input(SHTDWN_BTN)==False: 47 | doShutdown() 48 | time.sleep(1) 49 | 50 | try: 51 | main() 52 | finally: 53 | GPIO.cleanup() 54 | print("Closed Everything. END") 55 | #End 56 | -------------------------------------------------------------------------------- /Chapter 6/shtdwn_full.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import time 3 | import RPi.GPIO as GPIO 4 | import os 5 | 6 | # Shutdown Script 7 | DEBUG=False 8 | SNDON=True 9 | #HARDWARE SETUP 10 | # P1 11 | # 2[==X==L=======]26 12 | # 1[===1=2=======]25 13 | #BTN CONFIG - Set GPIO Ports 14 | GPIO_MODE=GPIO.BOARD 15 | SHTDWN_BTN = 7 #1 16 | LAN_SW = 11 #2 17 | LED = 12 #L 18 | 19 | 20 | def gpio_setup(): 21 | #Setup the wiring 22 | GPIO.setmode(GPIO_MODE) 23 | #Setup Ports 24 | GPIO.setup(SHTDWN_BTN,GPIO.IN,pull_up_down=GPIO.PUD_UP) 25 | GPIO.setup(LAN_SWA,GPIO.IN,pull_up_down=GPIO.PUD_UP) 26 | GPIO.setup(LED,GPIO.OUT) 27 | 28 | def doShutdown(): 29 | if(DEBUG):print("Press detected") 30 | time.sleep(3) 31 | if GPIO.input(SHTDWN_BTN): 32 | if(DEBUG):print("Ignore the shutdown (<3sec)") 33 | else: 34 | if(DEBUG):print ("Would shutdown the RPi Now") 35 | GPIO.output(LED,0) 36 | time.sleep(0.5) 37 | GPIO.output(LED,1) 38 | if(SNDON):os.system("flite -t 'Warning commencing power down in 3 2 1'") 39 | if(DEBUG==False):os.system("sudo shutdown -h now") 40 | if(DEBUG):GPIO.cleanup() 41 | if(DEBUG):exit() 42 | 43 | def doChangeLAN(direct): 44 | if(DEBUG):print("Direct LAN: %s" % direct) 45 | if GPIO.input(LAN_SWA) and direct==True: 46 | if(DEBUG):print("LAN Switch OFF") 47 | cmd="sudo dhclient eth0" 48 | direct=False 49 | GPIO.output(LED,1) 50 | elif GPIO.input(LAN_SWA)==False and direct==False: 51 | if(DEBUG):print("LAN Switch ON") 52 | cmd="sudo ifconfig eth0 169.254.69.69" 53 | direct=True 54 | else: 55 | return direct 56 | os.system(cmd) 57 | if(SNDON):os.system("hostname -I | flite") 58 | return direct 59 | 60 | def flashled(ledon): 61 | if ledon: 62 | ledon=False 63 | else: 64 | ledon=True 65 | GPIO.output(LED,ledon) 66 | return ledOn 67 | 68 | def main(): 69 | gpio_setup() 70 | GPIO.output(LED,1) 71 | directlan=False 72 | ledon=True 73 | while True: 74 | if(DEBUG):print("Waiting for >3sec button press") 75 | if GPIO.input(SHTDWN_BTN)==False: 76 | doShutdown() 77 | directlan = doChangeLAN(directlan) 78 | if directlan: 79 | flashled(ledon) 80 | time.sleep(1) 81 | 82 | try: 83 | main() 84 | finally: 85 | GPIO.cleanup() 86 | print("Closed Everything. END") 87 | #End 88 | -------------------------------------------------------------------------------- /Chapter 7/data.log: -------------------------------------------------------------------------------- 1 | Time 0:Light 1:Temperature 2:External 3:Potentiometer 2 | 1 2015-05-27 20:34:55 217.000000 216.000000 149.000000 224.000000 3 | 2 2015-05-27 20:34:56 216.000000 216.000000 126.000000 224.000000 4 | 3 2015-05-27 20:34:58 217.000000 216.000000 142.000000 224.000000 5 | 4 2015-05-27 20:34:59 217.000000 216.000000 143.000000 224.000000 6 | 5 2015-05-27 20:35:00 216.000000 216.000000 125.000000 224.000000 7 | 6 2015-05-27 20:35:01 217.000000 216.000000 142.000000 224.000000 8 | 7 2015-05-27 20:35:02 217.000000 216.000000 143.000000 224.000000 9 | 8 2015-05-27 20:35:03 216.000000 216.000000 124.000000 224.000000 10 | 9 2015-05-27 20:35:04 217.000000 216.000000 141.000000 224.000000 11 | 10 2015-05-27 20:35:05 176.000000 216.000000 147.000000 224.000000 12 | 11 2015-05-27 20:35:06 174.000000 216.000000 121.000000 224.000000 13 | 12 2015-05-27 20:35:08 175.000000 216.000000 140.000000 224.000000 14 | 13 2015-05-27 20:35:09 176.000000 216.000000 149.000000 224.000000 15 | 14 2015-05-27 20:35:10 174.000000 216.000000 122.000000 224.000000 16 | 15 2015-05-27 20:35:11 175.000000 216.000000 142.000000 224.000000 17 | 16 2015-05-27 20:35:12 176.000000 216.000000 144.000000 224.000000 18 | 17 2015-05-27 20:35:13 174.000000 216.000000 121.000000 224.000000 19 | 18 2015-05-27 20:35:14 175.000000 216.000000 145.000000 224.000000 20 | 19 2015-05-27 20:35:15 176.000000 216.000000 141.000000 224.000000 21 | 20 2015-05-27 20:35:16 175.000000 216.000000 121.000000 224.000000 22 | 21 2015-05-27 20:35:17 174.000000 216.000000 142.000000 224.000000 23 | 22 2015-05-27 20:35:19 176.000000 216.000000 149.000000 224.000000 24 | 23 2015-05-27 20:35:20 174.000000 216.000000 123.000000 224.000000 25 | 24 2015-05-27 20:35:21 176.000000 216.000000 132.000000 224.000000 26 | 25 2015-05-27 20:35:22 175.000000 216.000000 150.000000 224.000000 27 | 26 2015-05-27 20:35:23 174.000000 216.000000 127.000000 224.000000 28 | 27 2015-05-27 20:35:24 176.000000 216.000000 124.000000 224.000000 29 | 28 2015-05-27 20:35:25 174.000000 216.000000 148.000000 224.000000 30 | 29 2015-05-27 20:35:26 176.000000 216.000000 134.000000 224.000000 31 | 30 2015-05-27 20:35:27 176.000000 216.000000 120.000000 224.000000 32 | 31 2015-05-27 20:35:29 174.000000 216.000000 146.000000 224.000000 33 | 32 2015-05-27 20:35:30 176.000000 216.000000 144.000000 224.000000 34 | 33 2015-05-27 20:35:31 216.000000 216.000000 124.000000 224.000000 35 | 34 2015-05-27 20:35:32 217.000000 216.000000 139.000000 224.000000 36 | 35 2015-05-27 20:35:33 217.000000 216.000000 147.000000 224.000000 37 | 36 2015-05-27 20:35:34 217.000000 216.000000 124.000000 224.000000 38 | 37 2015-05-27 20:35:35 217.000000 216.000000 139.000000 224.000000 39 | 38 2015-05-27 20:35:36 217.000000 216.000000 147.000000 224.000000 40 | 39 2015-05-27 20:35:37 217.000000 216.000000 126.000000 224.000000 41 | 40 2015-05-27 20:35:39 217.000000 216.000000 134.000000 224.000000 42 | 41 2015-05-27 20:35:40 217.000000 216.000000 147.000000 224.000000 43 | 42 2015-05-27 20:35:41 217.000000 216.000000 128.000000 224.000000 44 | 43 2015-05-27 20:35:42 217.000000 216.000000 128.000000 224.000000 45 | 44 2015-05-27 20:35:43 217.000000 216.000000 146.000000 224.000000 46 | 45 2015-05-27 20:35:44 217.000000 216.000000 131.000000 224.000000 47 | 46 2015-05-27 20:35:45 217.000000 216.000000 126.000000 224.000000 48 | 47 2015-05-27 20:35:46 217.000000 216.000000 145.000000 224.000000 49 | 48 2015-05-27 20:35:47 217.000000 216.000000 135.000000 224.000000 50 | 49 2015-05-27 20:35:48 217.000000 216.000000 124.000000 224.000000 51 | 50 2015-05-27 20:35:50 217.000000 216.000000 143.000000 224.000000 52 | 51 2015-05-27 20:35:51 217.000000 216.000000 140.000000 224.000000 53 | 52 2015-05-27 20:35:52 217.000000 216.000000 124.000000 224.000000 54 | 53 2015-05-27 20:35:53 217.000000 216.000000 143.000000 224.000000 55 | 54 2015-05-27 20:35:54 217.000000 216.000000 143.000000 224.000000 56 | 55 2015-05-27 20:35:55 217.000000 216.000000 124.000000 224.000000 57 | 56 2015-05-27 20:35:56 217.000000 216.000000 139.000000 224.000000 58 | 57 2015-05-27 20:35:57 217.000000 216.000000 147.000000 224.000000 59 | 58 2015-05-27 20:35:58 217.000000 216.000000 126.000000 224.000000 60 | 59 2015-05-27 20:36:00 217.000000 216.000000 134.000000 224.000000 61 | 60 2015-05-27 20:36:01 217.000000 216.000000 145.000000 224.000000 62 | 61 2015-05-27 20:36:02 217.000000 216.000000 131.000000 224.000000 63 | 62 2015-05-27 20:36:03 217.000000 216.000000 124.000000 224.000000 64 | 63 2015-05-27 20:36:04 217.000000 216.000000 145.000000 224.000000 65 | 64 2015-05-27 20:36:05 217.000000 216.000000 136.000000 224.000000 66 | 65 2015-05-27 20:36:06 217.000000 216.000000 124.000000 224.000000 67 | 66 2015-05-27 20:36:07 218.000000 216.000000 140.000000 224.000000 68 | 67 2015-05-27 20:36:08 217.000000 216.000000 147.000000 224.000000 69 | 68 2015-05-27 20:36:09 217.000000 216.000000 127.000000 224.000000 70 | 69 2015-05-27 20:36:11 217.000000 216.000000 128.000000 224.000000 71 | 70 2015-05-27 20:36:12 217.000000 216.000000 146.000000 224.000000 72 | 71 2015-05-27 20:36:13 217.000000 216.000000 132.000000 224.000000 73 | 72 2015-05-27 20:36:14 214.000000 216.000000 123.000000 224.000000 74 | 73 2015-05-27 20:36:15 123.000000 216.000000 144.000000 224.000000 75 | 74 2015-05-27 20:36:16 76.000000 216.000000 134.000000 224.000000 76 | 75 2015-05-27 20:36:17 67.000000 216.000000 116.000000 224.000000 77 | 76 2015-05-27 20:36:18 116.000000 216.000000 152.000000 224.000000 78 | 77 2015-05-27 20:36:19 84.000000 216.000000 140.000000 224.000000 79 | 78 2015-05-27 20:36:21 53.000000 216.000000 114.000000 224.000000 80 | 79 2015-05-27 20:36:22 49.000000 216.000000 152.000000 224.000000 81 | 80 2015-05-27 20:36:23 60.000000 216.000000 140.000000 224.000000 82 | 81 2015-05-27 20:36:24 52.000000 216.000000 113.000000 224.000000 83 | 82 2015-05-27 20:36:25 48.000000 216.000000 151.000000 224.000000 84 | 83 2015-05-27 20:36:26 63.000000 216.000000 143.000000 224.000000 85 | 84 2015-05-27 20:36:27 50.000000 216.000000 113.000000 224.000000 86 | 85 2015-05-27 20:36:28 49.000000 216.000000 150.000000 224.000000 87 | 86 2015-05-27 20:36:29 45.000000 216.000000 145.000000 224.000000 88 | 87 2015-05-27 20:36:30 48.000000 216.000000 112.000000 224.000000 89 | 88 2015-05-27 20:36:32 64.000000 216.000000 144.000000 224.000000 90 | 89 2015-05-27 20:36:33 217.000000 216.000000 144.000000 224.000000 91 | 90 2015-05-27 20:36:34 217.000000 216.000000 124.000000 224.000000 92 | 91 2015-05-27 20:36:35 217.000000 216.000000 141.000000 224.000000 93 | 92 2015-05-27 20:36:36 217.000000 216.000000 143.000000 224.000000 94 | 93 2015-05-27 20:36:37 217.000000 216.000000 124.000000 224.000000 95 | 94 2015-05-27 20:36:38 217.000000 216.000000 141.000000 224.000000 96 | 95 2015-05-27 20:36:39 218.000000 216.000000 143.000000 224.000000 97 | 96 2015-05-27 20:36:40 217.000000 216.000000 124.000000 224.000000 98 | 97 2015-05-27 20:36:42 202.000000 216.000000 142.000000 224.000000 99 | 98 2015-05-27 20:36:43 119.000000 216.000000 142.000000 224.000000 100 | 99 2015-05-27 20:36:44 70.000000 216.000000 118.000000 224.000000 101 | 100 2015-05-27 20:36:45 152.000000 216.000000 147.000000 224.000000 102 | 101 2015-05-27 20:36:46 58.000000 216.000000 135.000000 224.000000 103 | 102 2015-05-27 20:36:47 62.000000 216.000000 122.000000 224.000000 104 | 103 2015-05-27 20:36:48 94.000000 216.000000 147.000000 224.000000 105 | 104 2015-05-27 20:36:49 112.000000 216.000000 131.000000 224.000000 106 | 105 2015-05-27 20:36:50 125.000000 216.000000 129.000000 224.000000 107 | 106 2015-05-27 20:36:51 140.000000 216.000000 147.000000 224.000000 108 | 107 2015-05-27 20:36:53 156.000000 216.000000 126.000000 224.000000 109 | 108 2015-05-27 20:36:54 171.000000 216.000000 135.000000 224.000000 110 | 109 2015-05-27 20:36:55 184.000000 216.000000 147.000000 224.000000 111 | 110 2015-05-27 20:36:56 214.000000 216.000000 124.000000 224.000000 112 | 111 2015-05-27 20:36:57 217.000000 216.000000 140.000000 224.000000 113 | 112 2015-05-27 20:36:58 217.000000 216.000000 143.000000 224.000000 114 | 113 2015-05-27 20:36:59 217.000000 216.000000 124.000000 224.000000 115 | 114 2015-05-27 20:37:00 217.000000 216.000000 143.000000 224.000000 116 | 115 2015-05-27 20:37:01 220.000000 216.000000 139.000000 224.000000 117 | 116 2015-05-27 20:37:03 219.000000 216.000000 123.000000 224.000000 118 | 117 2015-05-27 20:37:04 218.000000 216.000000 146.000000 224.000000 119 | 118 2015-05-27 20:37:05 229.000000 216.000000 131.000000 224.000000 120 | 119 2015-05-27 20:37:06 220.000000 216.000000 130.000000 224.000000 121 | 120 2015-05-27 20:37:07 219.000000 216.000000 147.000000 224.000000 122 | 121 2015-05-27 20:37:08 221.000000 216.000000 125.000000 224.000000 123 | 122 2015-05-27 20:37:09 220.000000 216.000000 140.000000 224.000000 124 | 123 2015-05-27 20:37:10 232.000000 216.000000 135.000000 224.000000 125 | 124 2015-05-27 20:37:11 233.000000 216.000000 125.000000 224.000000 126 | 125 2015-05-27 20:37:12 217.000000 216.000000 147.000000 224.000000 127 | 126 2015-05-27 20:37:14 217.000000 216.000000 127.000000 224.000000 128 | 127 2015-05-27 20:37:15 218.000000 216.000000 138.000000 224.000000 129 | 128 2015-05-27 20:37:16 217.000000 216.000000 140.000000 224.000000 130 | 129 2015-05-27 20:37:17 217.000000 216.000000 123.000000 224.000000 131 | 130 2015-05-27 20:37:18 217.000000 216.000000 145.000000 224.000000 132 | 131 2015-05-27 20:37:19 217.000000 216.000000 131.000000 224.000000 133 | 132 2015-05-27 20:37:20 218.000000 216.000000 124.000000 224.000000 134 | 133 2015-05-27 20:37:21 217.000000 216.000000 147.000000 224.000000 135 | 134 2015-05-27 20:37:22 217.000000 216.000000 132.000000 224.000000 136 | 135 2015-05-27 20:37:24 217.000000 216.000000 127.000000 224.000000 137 | 136 2015-05-27 20:37:25 217.000000 216.000000 146.000000 224.000000 138 | 137 2015-05-27 20:37:26 217.000000 216.000000 130.000000 224.000000 139 | 138 2015-05-27 20:37:27 217.000000 216.000000 129.000000 224.000000 140 | 139 2015-05-27 20:37:28 217.000000 216.000000 147.000000 224.000000 141 | 140 2015-05-27 20:37:29 217.000000 216.000000 126.000000 224.000000 142 | 141 2015-05-27 20:37:30 217.000000 216.000000 137.000000 224.000000 143 | 142 2015-05-27 20:37:31 217.000000 216.000000 145.000000 224.000000 144 | 143 2015-05-27 20:37:32 217.000000 216.000000 124.000000 224.000000 145 | 144 2015-05-27 20:37:33 217.000000 216.000000 143.000000 224.000000 146 | 145 2015-05-27 20:37:35 217.000000 216.000000 139.000000 224.000000 147 | -------------------------------------------------------------------------------- /Chapter 7/data_adc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #data_adc.py 3 | import wiringpi2 4 | import time 5 | 6 | DEBUG=False 7 | LIGHT=0;TEMP=1;EXT=2;POT=3 8 | ADC_CH=[LIGHT,TEMP,EXT,POT] 9 | ADC_ADR=0x48 10 | ADC_CYCLE=0x04 11 | BUS_GAP=0.25 12 | DATANAME=["0:Light","1:Temperature", 13 | "2:External","3:Potentiometer"] 14 | 15 | class device: 16 | # Constructor: 17 | def __init__(self,addr=ADC_ADR): 18 | self.NAME=DATANAME 19 | self.i2c = wiringpi2.I2C() 20 | self.devADC=self.i2c.setup(addr) 21 | pwrup = self.i2c.read(self.devADC) #flush power up value 22 | if DEBUG==True and pwrup!=-1: 23 | print("ADC Ready") 24 | self.i2c.read(self.devADC) #flush first value 25 | time.sleep(BUS_GAP) 26 | self.i2c.write(self.devADC,ADC_CYCLE) 27 | time.sleep(BUS_GAP) 28 | self.i2c.read(self.devADC) #flush first value 29 | 30 | def getName(self): 31 | return self.NAME 32 | 33 | def getNew(self): 34 | data=[] 35 | for ch in ADC_CH: 36 | time.sleep(BUS_GAP) 37 | data.append(self.i2c.read(self.devADC)) 38 | return data 39 | 40 | def main(): 41 | ADC = device() 42 | print (str(ADC.getName())) 43 | for i in range(10): 44 | dataValues = ADC.getNew() 45 | print (str(dataValues)) 46 | time.sleep(1) 47 | 48 | if __name__=='__main__': 49 | main() 50 | #End 51 | -------------------------------------------------------------------------------- /Chapter 7/data_local.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #data_local.py 3 | import subprocess 4 | from random import randint 5 | import time 6 | 7 | MEM_TOTAL=0 8 | MEM_USED=1 9 | MEM_FREE=2 10 | MEM_OFFSET=7 11 | DRIVE_USED=0 12 | DRIVE_FREE=1 13 | DRIVE_OFFSET=9 14 | DEBUG=False 15 | DATANAME=["CPU_Load","System_Temp","CPU_Frequency", 16 | "Random","RAM_Total","RAM_Used","RAM_Free", 17 | "Drive_Used","Drive_Free"] 18 | 19 | def read_loadavg(): 20 | # function to read 1 minute load average from system uptime 21 | value = subprocess.check_output( 22 | ["awk '{print $1}' /proc/loadavg"], shell=True) 23 | return float(value) 24 | 25 | def read_systemp(): 26 | # function to read current system temperature 27 | value = subprocess.check_output( 28 | ["cat /sys/class/thermal/thermal_zone0/temp"], 29 | shell=True) 30 | return int(value) 31 | 32 | def read_cpu(): 33 | # function to read current clock frequency 34 | value = subprocess.check_output( 35 | ["cat /sys/devices/system/cpu/cpu0/cpufreq/"+ 36 | "scaling_cur_freq"], shell=True) 37 | return int(value) 38 | 39 | def read_rnd(): 40 | return randint(0,255) 41 | 42 | def read_mem(): 43 | # function to read RAM info 44 | value = subprocess.check_output(["free"], shell=True) 45 | memory=[] 46 | for val in value.split()[MEM_TOTAL+ 47 | MEM_OFFSET:MEM_FREE+ 48 | MEM_OFFSET+1]: 49 | memory.append(int(val)) 50 | return(memory) 51 | 52 | def read_drive(): 53 | # function to read drive info 54 | value = subprocess.check_output(["df"], shell=True) 55 | memory=[] 56 | for val in value.split()[DRIVE_USED+ 57 | DRIVE_OFFSET:DRIVE_FREE+ 58 | DRIVE_OFFSET+1]: 59 | memory.append(int(val)) 60 | return(memory) 61 | 62 | class device: 63 | # Constructor: 64 | def __init__(self,addr=0): 65 | self.NAME=DATANAME 66 | 67 | def getName(self): 68 | return self.NAME 69 | 70 | def getNew(self): 71 | data=[] 72 | data.append(read_loadavg()) 73 | data.append(read_systemp()) 74 | data.append(read_cpu()) 75 | data.append(read_rnd()) 76 | memory_ram = read_mem() 77 | data.append(memory_ram[MEM_TOTAL]) 78 | data.append(memory_ram[MEM_USED]) 79 | data.append(memory_ram[MEM_FREE]) 80 | memory_drive = read_drive() 81 | data.append(memory_drive[DRIVE_USED]) 82 | data.append(memory_drive[DRIVE_FREE]) 83 | return data 84 | 85 | def main(): 86 | LOCAL = device() 87 | print (str(LOCAL.getName())) 88 | for i in range(10): 89 | dataValues = LOCAL.getNew() 90 | print (str(dataValues)) 91 | time.sleep(1) 92 | 93 | if __name__=='__main__': 94 | main() 95 | #End -------------------------------------------------------------------------------- /Chapter 7/del_data_lite.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Remove all the data in the table. 5 |
6 | query($strSQL); 12 | 13 | if ($response == 1) 14 | { 15 | echo "Result: DELETED DATA"; 16 | } 17 | else 18 | { 19 | echo "Error: Ensure table exists and database directory is owned by www-data"; 20 | } 21 | 22 | ?> 23 |

24 | Press button to return to data display. 25 |
26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter 7/lcd_i2c.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import wiringpi2 3 | import time 4 | import datetime 5 | import data_adc as dataDevice 6 | 7 | AF_BASE=100 8 | AF_E=AF_BASE+13; AF_RW=AF_BASE+14; AF_RS=AF_BASE+15 9 | 10 | AF_DB4=AF_BASE+12; AF_DB5=AF_BASE+11; AF_DB6=AF_BASE+10; AF_DB7=AF_BASE+9 11 | 12 | AF_SELECT=AF_BASE+0; AF_RIGHT=AF_BASE+1; AF_DOWN=AF_BASE+2 13 | AF_UP=AF_BASE+3; AF_LEFT=AF_BASE+4; AF_BACK=AF_BASE+5 14 | 15 | AF_GREEN=AF_BASE+6; AF_BLUE=AF_BASE+7; AF_RED=AF_BASE+8 16 | BNK=" "*16 #16spaces 17 | 18 | def gpiosetup(): 19 | global lcd 20 | wiringpi2.wiringPiSetup() 21 | wiringpi2.mcp23017Setup(AF_BASE,0x20) 22 | wiringpi2.pinMode(AF_RIGHT,0) 23 | wiringpi2.pinMode(AF_LEFT,0) 24 | wiringpi2.pinMode(AF_SELECT,0) 25 | wiringpi2.pinMode(AF_RW,1) 26 | wiringpi2.digitalWrite(AF_RW,0) 27 | #lcdInit(int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) 28 | lcd=wiringpi2.lcdInit(2,16,4,AF_RS,AF_E,AF_DB4,AF_DB5,AF_DB6,AF_DB7,0,0,0,0) 29 | #wiringpi2.lcdHome(lcd) 30 | #wiringpi2.lcdClear(lcd) 31 | #wiringpi2.lcdPosition(lcd,0,0) 32 | 33 | def printLCD(line0="",line1=""): 34 | wiringpi2.lcdPosition(lcd,0,0) 35 | wiringpi2.lcdPrintf(lcd,line0+BNK) 36 | wiringpi2.lcdPosition(lcd,0,1) 37 | wiringpi2.lcdPrintf(lcd,line1+BNK) 38 | 39 | def checkBtn(idx,size): 40 | global run 41 | if wiringpi2.digitalRead(AF_LEFT): 42 | idx-=1 43 | printLCD() 44 | elif wiringpi2.digitalRead(AF_RIGHT): 45 | idx+=1 46 | printLCD() 47 | if wiringpi2.digitalRead(AF_SELECT): 48 | printLCD("Exit Display") 49 | run=False 50 | return idx%size 51 | 52 | def main(): 53 | global run 54 | gpiosetup() 55 | myData = dataDevice.device() 56 | myDataNames=myData.getName() 57 | run=True 58 | index=0 59 | while(run): 60 | data=myData.getNew() 61 | printLCD(myDataNames[index],str(data[index])) 62 | time.sleep(1) 63 | index = checkBtn(index,len(myDataNames)) 64 | 65 | 66 | 67 | main() 68 | 69 | -------------------------------------------------------------------------------- /Chapter 7/live_graph.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #live_graph.py 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | import matplotlib.animation as animation 6 | import data_local as dataDevice 7 | 8 | PADDING=5 9 | myData = dataDevice.device() 10 | dispdata = [] 11 | timeplot=0 12 | fig, ax = plt.subplots() 13 | line, = ax.plot(dispdata) 14 | 15 | def update(data): 16 | global dispdata,timeplot 17 | timeplot+=1 18 | dispdata.append(data) 19 | ax.set_xlim(0, timeplot) 20 | ymin = min(dispdata)-PADDING 21 | ymax = max(dispdata)+PADDING 22 | ax.set_ylim(ymin, ymax) 23 | line.set_data(range(timeplot),dispdata) 24 | return line 25 | 26 | def data_gen(): 27 | while True: 28 | yield myData.getNew()[1]/1000 29 | 30 | ani = animation.FuncAnimation(fig, update, 31 | data_gen, interval=1000) 32 | plt.show() 33 | #End -------------------------------------------------------------------------------- /Chapter 7/live_graph_light.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #live_graph.py 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | import matplotlib.animation as animation 6 | import data_adc as dataDevice 7 | 8 | PADDING=5 9 | myData = dataDevice.device() 10 | dispdata = [] 11 | timeplot=0 12 | fig, ax = plt.subplots() 13 | line, = ax.plot(dispdata) 14 | 15 | def update(data): 16 | global dispdata,timeplot 17 | timeplot+=1 18 | dispdata.append(data) 19 | ax.set_xlim(0, timeplot) 20 | ymin = min(dispdata)-PADDING 21 | ymax = max(dispdata)+PADDING 22 | ax.set_ylim(ymin, ymax) 23 | line.set_data(range(timeplot),dispdata) 24 | return line 25 | 26 | def data_gen(): 27 | while True: 28 | yield myData.getNew()[0] 29 | 30 | ani = animation.FuncAnimation(fig, update, 31 | data_gen, interval=1000) 32 | plt.show() 33 | #End 34 | -------------------------------------------------------------------------------- /Chapter 7/log_adc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #log_adc.py 3 | import time 4 | import datetime 5 | import data_adc as dataDevice 6 | 7 | DEBUG=True 8 | FILE=True 9 | VAL0=0;VAL1=1;VAL2=2;VAL3=3 #Set data order 10 | FORMATHEADER="\t%s\t%s\t%s\t%s\t%s" 11 | FORMATBODY="%d\t%s\t%f\t%f\t%f\t%f" 12 | 13 | if(FILE):f = open("data.log",'w') 14 | 15 | def timestamp(): 16 | ts=time.time() 17 | return datetime.datetime.fromtimestamp(ts).strftime( 18 | '%Y-%m-%d %H:%M:%S') 19 | 20 | def main(): 21 | counter=0 22 | myData = dataDevice.device() 23 | myDataNames=myData.getName() 24 | header=(FORMATHEADER%("Time", 25 | myDataNames[VAL0],myDataNames[VAL1], 26 | myDataNames[VAL2],myDataNames[VAL3])) 27 | if(DEBUG):print (header) 28 | if(FILE):f.write(header+"\n") 29 | while(1): 30 | data=myData.getNew() 31 | counter+=1 32 | body=(FORMATBODY%(counter,timestamp(), 33 | data[VAL0],data[VAL1],data[VAL2],data[VAL3])) 34 | if(DEBUG):print (body) 35 | if(FILE):f.write(body+"\n") 36 | time.sleep(0.1) 37 | 38 | try: 39 | main() 40 | finally: 41 | f.close() 42 | #End 43 | -------------------------------------------------------------------------------- /Chapter 7/log_graph.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #log_graph.py 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | 6 | filename = "data.log" 7 | OFFSET=2 8 | with open(filename) as f: 9 | header = f.readline().split('\t') 10 | 11 | data = np.genfromtxt(filename, delimiter='\t', skip_header=1, 12 | names=['sample', 'date', 'DATA0', 13 | 'DATA1', 'DATA2', 'DATA3']) 14 | fig = plt.figure(1) 15 | ax1 = fig.add_subplot(211)#numrows, numcols, fignum 16 | ax2 = fig.add_subplot(212) 17 | ax1.plot(data['sample'],data['DATA0'],'r', 18 | label=header[OFFSET+0]) 19 | ax2.plot(data['sample'],data['DATA1'],'b', 20 | label=header[OFFSET+1]) 21 | ax1.set_title("ADC Samples") 22 | ax1.set_xlabel('Samples') 23 | ax1.set_ylabel('Reading') 24 | ax2.set_xlabel('Samples') 25 | ax2.set_ylabel('Reading') 26 | 27 | leg1 = ax1.legend() 28 | leg2 = ax2.legend() 29 | 30 | plt.show() 31 | #End -------------------------------------------------------------------------------- /Chapter 7/log_local.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #log_local.py 3 | import time 4 | import datetime 5 | import data_adc as dataDevice 6 | 7 | DEBUG=True 8 | FILE=True 9 | VAL0=0;VAL1=1;VAL2=2;VAL3=3 #Set data order 10 | FORMATHEADER="\t%s\t%s\t%s\t%s\t%s" 11 | FORMATBODY="%d\t%s\t%f\t%f\t%f\t%f" 12 | 13 | if(FILE):f = open("data.log",'w') 14 | def timestamp(): 15 | ts=time.time() 16 | return datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S') 17 | 18 | def main(): 19 | counter=0 20 | myData = dataDevice.device() 21 | myDataNames=myData.getName() 22 | header=(FORMATHEADER%("Time",myDataNames[VAL0],myDataNames[VAL1],myDataNames[VAL2],myDataNames[VAL3])) 23 | if(DEBUG):print (header) 24 | if(FILE):f.write(header+"\n") 25 | while(1): 26 | data=myData.getNew() 27 | counter+=1 28 | body=(FORMATBODY%(counter,timestamp(),data[0],data[1],data[2],data[3])) 29 | if(DEBUG):print (body) 30 | if(FILE):f.write(body+"\n") 31 | time.sleep(0.1) 32 | 33 | try: 34 | main() 35 | finally: 36 | f.close() 37 | #end 38 | -------------------------------------------------------------------------------- /Chapter 7/mysqlite_adc.py: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/python3 3 | #mysql_adc.py 4 | import sqlite3 5 | import datetime 6 | import data_adc as dataDevice 7 | import time 8 | import os 9 | 10 | DEBUG=True 11 | SHOWSQL=True 12 | CLEARDATA=False 13 | VAL0=0;VAL1=1;VAL2=2;VAL3=3 #Set data order 14 | FORMATBODY="%5s %8s %14s %12s %16s" 15 | FORMATLIST="%5s %12s %10s %16s %7s" 16 | DATEBASE_DIR="/var/databases/datasite/" 17 | DATEBASE=DATEBASE_DIR+"mydatabase.db" 18 | TABLE="recordeddata" 19 | DELAY=1 #approximate seconds between samples 20 | 21 | def captureSamples(cursor): 22 | if(CLEARDATA):cursor.execute("DELETE FROM %s" %(TABLE)) 23 | myData = dataDevice.device() 24 | myDataNames=myData.getName() 25 | 26 | if(DEBUG):print(FORMATBODY%("##",myDataNames[VAL0], 27 | myDataNames[VAL1],myDataNames[VAL2], 28 | myDataNames[VAL3])) 29 | for x in range(10): 30 | data=myData.getNew() 31 | for i,dataName in enumerate(myDataNames): 32 | sqlquery = "INSERT INTO %s (itm_name, itm_value) " %(TABLE) + \ 33 | "VALUES('%s', %s)" \ 34 | %(str(dataName),str(data[i])) 35 | if (SHOWSQL):print(sqlquery) 36 | cursor.execute(sqlquery) 37 | # cursor.execute("INSERT INTO ? (itm_name, itm_value) VALUES('?', ?)", 38 | # (TABLE,str(dataName),data[i])) 39 | # cursor.execute("INSERT INTO ? (itm_name, itm_value) VALUES('?', ?)", 40 | # (str(TABLE),str(dataName),str(data[i]))) 41 | ## sqlquery = "INSERT INTO %s (itm_name, itm_value) VALUES(?, ?)" %(TABLE) 42 | # sqlquery = "INSERT INTO ? (itm_name, itm_value) VALUES(?, ?)" 43 | ## cursor.execute(sqlquery,(str(dataName),str(data[i]))) 44 | 45 | if(DEBUG):print(FORMATBODY%(x, 46 | data[VAL0],data[VAL1], 47 | data[VAL2],data[VAL3])) 48 | time.sleep(DELAY) 49 | cursor.commit() 50 | 51 | def displayAll(connect): 52 | sqlquery="SELECT * FROM %s" %(TABLE) 53 | if (SHOWSQL):print(sqlquery) 54 | cursor = connect.execute (sqlquery) 55 | print(FORMATLIST%("","Date","Time","Name","Value")) 56 | 57 | for x,column in enumerate(cursor.fetchall()): 58 | print(FORMATLIST%(x,str(column[0]),str(column[1]), 59 | str(column[2]),str(column[3]))) 60 | 61 | def createTable(cursor): 62 | print("Create a new table: %s" %(TABLE)) 63 | sqlquery="CREATE TABLE %s (" %(TABLE) + \ 64 | "itm_date DEFAULT (date('now','localtime')), " + \ 65 | "itm_time DEFAULT (time('now','localtime')), " + \ 66 | "itm_name, itm_value)" 67 | if (SHOWSQL):print(sqlquery) 68 | cursor.execute(sqlquery) 69 | cursor.commit() 70 | 71 | def openTable(cursor): 72 | try: 73 | displayAll(cursor) 74 | except sqlite3.OperationalError: 75 | print("Table does not exist in database") 76 | createTable(cursor) 77 | finally: 78 | captureSamples(cursor) 79 | displayAll(cursor) 80 | 81 | try: 82 | if not os.path.exists(DATEBASE_DIR): 83 | os.makedirs(DATEBASE_DIR) 84 | connection = sqlite3.connect(DATEBASE) 85 | try: 86 | openTable(connection) 87 | finally: 88 | connection.close() 89 | except sqlite3.OperationalError: 90 | print("Unable to open Database") 91 | finally: 92 | print("Done") 93 | 94 | #End 95 | -------------------------------------------------------------------------------- /Chapter 7/mysqlite_local.py: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/python3 3 | #mysql_adc.py 4 | import sqlite3 5 | import datetime 6 | import data_local as dataDevice 7 | import time 8 | import os 9 | 10 | DEBUG=True 11 | SHOWSQL=True 12 | CLEARDATA=False 13 | VAL0=0;VAL1=1;VAL2=2;VAL3=3 #Set data order 14 | FORMATBODY="%5s %8s %14s %12s %16s" 15 | FORMATLIST="%5s %12s %10s %16s %7s" 16 | DATEBASE_DIR="/var/databases/datasite/" 17 | DATEBASE=DATEBASE_DIR+"mydatabase.db" 18 | TABLE="recordeddata" 19 | DELAY=1 #approximate seconds between samples 20 | 21 | def captureSamples(cursor): 22 | if(CLEARDATA):cursor.execute("DELETE FROM %s" %(TABLE)) 23 | myData = dataDevice.device() 24 | myDataNames=myData.getName() 25 | 26 | if(DEBUG):print(FORMATBODY%("##",myDataNames[VAL0], 27 | myDataNames[VAL1],myDataNames[VAL2], 28 | myDataNames[VAL3])) 29 | for x in range(10): 30 | data=myData.getNew() 31 | for i,dataName in enumerate(myDataNames): 32 | sqlquery = "INSERT INTO %s (itm_name, itm_value) " %(TABLE) + \ 33 | "VALUES('%s', %s)" \ 34 | %(str(dataName),str(data[i])) 35 | if (SHOWSQL):print(sqlquery) 36 | cursor.execute(sqlquery) 37 | # cursor.execute("INSERT INTO ? (itm_name, itm_value) VALUES('?', ?)", 38 | # (TABLE,str(dataName),data[i])) 39 | # cursor.execute("INSERT INTO ? (itm_name, itm_value) VALUES('?', ?)", 40 | # (str(TABLE),str(dataName),str(data[i]))) 41 | ## sqlquery = "INSERT INTO %s (itm_name, itm_value) VALUES(?, ?)" %(TABLE) 42 | # sqlquery = "INSERT INTO ? (itm_name, itm_value) VALUES(?, ?)" 43 | ## cursor.execute(sqlquery,(str(dataName),str(data[i]))) 44 | 45 | if(DEBUG):print(FORMATBODY%(x, 46 | data[VAL0],data[VAL1], 47 | data[VAL2],data[VAL3])) 48 | time.sleep(DELAY) 49 | cursor.commit() 50 | 51 | def displayAll(connect): 52 | sqlquery="SELECT * FROM %s" %(TABLE) 53 | if (SHOWSQL):print(sqlquery) 54 | cursor = connect.execute (sqlquery) 55 | print(FORMATLIST%("","Date","Time","Name","Value")) 56 | 57 | for x,column in enumerate(cursor.fetchall()): 58 | print(FORMATLIST%(x,str(column[0]),str(column[1]), 59 | str(column[2]),str(column[3]))) 60 | 61 | def createTable(cursor): 62 | print("Create a new table: %s" %(TABLE)) 63 | sqlquery="CREATE TABLE %s (" %(TABLE) + \ 64 | "itm_date DEFAULT (date('now','localtime')), " + \ 65 | "itm_time DEFAULT (time('now','localtime')), " + \ 66 | "itm_name, itm_value)" 67 | if (SHOWSQL):print(sqlquery) 68 | cursor.execute(sqlquery) 69 | cursor.commit() 70 | 71 | def openTable(cursor): 72 | try: 73 | displayAll(cursor) 74 | except sqlite3.OperationalError: 75 | print("Table does not exist in database") 76 | createTable(cursor) 77 | finally: 78 | captureSamples(cursor) 79 | displayAll(cursor) 80 | 81 | try: 82 | if not os.path.exists(DATEBASE_DIR): 83 | os.makedirs(DATEBASE_DIR) 84 | connection = sqlite3.connect(DATEBASE) 85 | try: 86 | openTable(connection) 87 | finally: 88 | connection.close() 89 | except sqlite3.OperationalError: 90 | print("Unable to open Database") 91 | finally: 92 | print("Done") 93 | 94 | #End 95 | -------------------------------------------------------------------------------- /Chapter 7/show_data_lite.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | Database Data 4 | 5 | 6 | 7 | 8 | Press button to remove the table data 9 |
10 | 11 |

12 | Recorded Data
13 | query($strSQL); 20 | //Loop through the response 21 | while($column = $response->fetch()) 22 | { 23 | //Display the content of the response 24 | echo $column[0] . " "; 25 | echo $column[1] . " "; 26 | echo $column[2] . " "; 27 | echo $column[3] . "
"; 28 | } 29 | ?> 30 | Done 31 | 32 | 33 | -------------------------------------------------------------------------------- /Chapter 7/xivelylog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #xivelylog.py 3 | import xively 4 | import time 5 | import datetime 6 | import requests 7 | from random import randint 8 | import data_local as dataDevice 9 | 10 | # Set the FEED_ID and API_KEY from your account 11 | FEED_ID = 399948883 12 | API_KEY = "CcRxJbP5TuHp1PiOGVrN2kTGeXVsb6QZRJU236v6PjOdtzze" 13 | api = xively.XivelyAPIClient(API_KEY) # initialize api client 14 | DEBUG=True 15 | 16 | myData = dataDevice.device() 17 | myDataNames=myData.getName() 18 | 19 | def get_datastream(feed,name,tags): 20 | try: 21 | datastream = feed.datastreams.get(name) 22 | if DEBUG:print ("Found existing datastream") 23 | return datastream 24 | except: 25 | if DEBUG:print ("Creating new datastream") 26 | datastream = feed.datastreams.create(name, tags=tags) 27 | return datastream 28 | 29 | def run(): 30 | print ("Connecting to Xively") 31 | feed = api.feeds.get(FEED_ID) 32 | if DEBUG:print ("Got feed" + str(feed)) 33 | datastreams=[] 34 | for dataName in myDataNames: 35 | dstream = get_datastream(feed,dataName,dataName) 36 | #dstream.max_value = None 37 | #dstream.min_value = None 38 | if DEBUG:print ("Got %s datastream:%s"%(dataName,dstream)) 39 | datastreams.append(dstream) 40 | 41 | while True: 42 | data=myData.getNew() 43 | for idx,dataValue in enumerate(data): 44 | if DEBUG: 45 | print ("Updating %s: %s" % (dataName,dataValue)) 46 | datastreams[idx].current_value = dataValue 47 | datastreams[idx].at = datetime.datetime.utcnow() 48 | try: 49 | for ds in datastreams: 50 | ds.update() 51 | except requests.HTTPError as e: 52 | print ("HTTPError({0}): {1}".format(e.errno, e.strerror)) 53 | time.sleep(60) 54 | 55 | run() 56 | #End 57 | -------------------------------------------------------------------------------- /Chapter 8/Story.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Raspberry-Pi-for-Python-Programmers-Cookbook-Second-Edition/6df896e590e3b95b72d51f779ce732f0191f64ca/Chapter 8/Story.png -------------------------------------------------------------------------------- /Chapter 8/animateGUI.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #animateGUI.py 3 | import tkinter as TK 4 | from tkinter import messagebox 5 | import time 6 | import os 7 | import cameraGUI as camGUI 8 | 9 | class SET(camGUI.SET): 10 | TL_SIZE=(1920,1080) 11 | ENC_PROG="mencoder -nosound -ovc lavc -lavcopts" 12 | ENC_PROG+=" vcodec=mpeg4:aspect=16/9:vbitrate=8000000" 13 | ENC_PROG+=" -vf scale=%d:%d"%(TL_SIZE[0],TL_SIZE[1]) 14 | ENC_PROG+=" -o %s -mf type=jpeg:fps=24 mf://@%s" 15 | LIST_FILE="image_list.txt" 16 | 17 | class cameraGUI(camGUI.cameraGUI): 18 | def diff(a, b): 19 | b = set(b) 20 | return [aa for aa in a if aa not in b] 21 | 22 | def __init__(self,parent): 23 | super(cameraGUI,self).__init__(parent) 24 | self.parent=parent 25 | TK.Frame.__init__(self,self.parent, 26 | background="white") 27 | self.theList = TK.Variable() 28 | self.imageListbox=TK.Listbox(self.parent, 29 | listvariable=self.theList, 30 | selectmode=TK.EXTENDED) 31 | self.imageListbox.grid(row=0, column=4,columnspan=2, 32 | sticky=TK.N+TK.S+TK.E+TK.W) 33 | yscroll = TK.Scrollbar(command=self.imageListbox.yview, 34 | orient=TK.VERTICAL) 35 | yscroll.grid(row=0, column=6, sticky=TK.N+TK.S) 36 | self.imageListbox.configure(yscrollcommand=yscroll.set) 37 | self.trimBtn=TK.Button(self.parent,text="Trim", 38 | command=self.trim) 39 | self.trimBtn.grid(row=1,column=4) 40 | self.speed = TK.IntVar() 41 | self.speed.set(20) 42 | self.speedScale=TK.Scale(self.parent,from_=1,to=30, 43 | orient=TK.HORIZONTAL, 44 | variable=self.speed, 45 | label="Speed (fps)") 46 | self.speedScale.grid(row=2,column=4) 47 | self.genBtn=TK.Button(self.parent,text="Generate", 48 | command=self.generate) 49 | self.genBtn.grid(row=2,column=5) 50 | self.btnAniTxt=TK.StringVar() 51 | self.btnAniTxt.set("Animate") 52 | self.animateBtn=TK.Button(self.parent, 53 | textvariable=self.btnAniTxt, 54 | command=self.animate) 55 | self.animateBtn.grid(row=1,column=5) 56 | self.animating=False 57 | self.updateList() 58 | 59 | def shutter(self): 60 | super(cameraGUI,self).shutter() 61 | self.updateList() 62 | 63 | def updateList(self): 64 | filelist=[] 65 | for files in os.listdir("."): 66 | if files.endswith(".jpg"): 67 | filelist.append(files) 68 | filelist.sort() 69 | self.theList.set(tuple(filelist)) 70 | self.canvas.update() 71 | 72 | def generate(self): 73 | self.msg("Generate video...") 74 | cameraGUI.run("ls *.jpg > "+SET.LIST_FILE) 75 | filename=cameraGUI.timestamp()+".avi" 76 | cameraGUI.run(SET.ENC_PROG%(filename,SET.LIST_FILE)) 77 | self.msg(filename) 78 | TK.messagebox.showinfo("Encode Complete", 79 | "Video: "+filename) 80 | def trim(self): 81 | print("Trim List") 82 | selected = map(int,self.imageListbox.curselection()) 83 | trim=cameraGUI.diff(range(self.imageListbox.size()), 84 | selected) 85 | for item in trim: 86 | filename=self.theList.get()[item] 87 | self.msg("Rename file %s"%filename) 88 | #We could delete os.remove() but os.rename() allows 89 | #us to change our minds (files are just renamed). 90 | os.rename(filename, 91 | filename.replace(".jpg",".jpg.bak")) 92 | self.imageListbox.selection_clear(0, 93 | last=self.imageListbox.size()) 94 | self.updateList() 95 | 96 | def animate(self): 97 | print("Animate Toggle") 98 | if (self.animating==True): 99 | self.btnAniTxt.set("Animate") 100 | self.animating=False 101 | else: 102 | self.btnAniTxt.set("STOP") 103 | self.animating=True 104 | self.doAnimate() 105 | 106 | def doAnimate(self): 107 | imageList=[] 108 | selected = self.imageListbox.curselection() 109 | if len(selected)==0: 110 | selected=range(self.imageListbox.size()) 111 | print(selected) 112 | if len(selected)==0: 113 | TK.messagebox.showinfo("Error", 114 | "There are no images to display!") 115 | self.animate() 116 | elif len(selected)==1: 117 | filename=self.theList.get()[int(selected[0])] 118 | self.updateDisp(filename,SET.PV_SIZE) 119 | self.animate() 120 | else: 121 | for idx,item in enumerate(selected): 122 | self.msg("Generate Image: %d/%d"%(idx+1, 123 | len(selected))) 124 | filename=self.theList.get()[int(item)] 125 | aImage=cameraGUI.getTKImage(filename,SET.PV_SIZE) 126 | imageList.append(aImage) 127 | print("Apply Images") 128 | canvasList=[] 129 | for idx,aImage in enumerate(imageList): 130 | self.msg("Apply Image: %d/%d"%(idx+1, 131 | len(imageList))) 132 | canvasList.append(self.canvas.create_image(0, 0, 133 | anchor=TK.NW, 134 | image=imageList[idx], 135 | state=TK.HIDDEN)) 136 | self.cycleImages(canvasList) 137 | 138 | def cycleImages(self,canvasList): 139 | while (self.animating==True): 140 | print("Cycle Images") 141 | for idx,aImage in enumerate(canvasList): 142 | self.msg("Cycle Image: %d/%d"%(idx+1, 143 | len(canvasList))) 144 | self.canvas.itemconfigure(canvasList[idx], 145 | state=TK.NORMAL) 146 | if idx>=1: 147 | self.canvas.itemconfigure(canvasList[idx-1], 148 | state=TK.HIDDEN) 149 | elif len(canvasList)>1: 150 | self.canvas.itemconfigure( 151 | canvasList[len(canvasList)-1], 152 | state=TK.HIDDEN) 153 | self.canvas.update() 154 | time.sleep(1/self.speed.get()) 155 | #End 156 | -------------------------------------------------------------------------------- /Chapter 8/cameraGUI.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #cameraGUI.py 3 | import tkinter as TK 4 | from PIL import Image 5 | import subprocess 6 | import time 7 | import datetime 8 | import picamera as picam 9 | 10 | class SET(): 11 | PV_SIZE=(320,240) 12 | NORM_SIZE=(2592,1944) 13 | NO_RESIZE=(0,0) 14 | PREVIEW_FILE="PREVIEW.jpg" 15 | TEMP_FILE="PREVIEW.ppm" 16 | 17 | class cameraGUI(TK.Frame): 18 | def run(cmd): 19 | print("Run:"+cmd) 20 | subprocess.call([cmd], shell=True) 21 | 22 | def camCapture(filename,size=SET.NORM_SIZE): 23 | with picam.PiCamera() as camera: 24 | camera.resolution = size 25 | print("Image: %s"%filename) 26 | camera.capture(filename) 27 | 28 | def getTKImage(filename,previewsize=SET.NO_RESIZE): 29 | encoding=str.split(filename,".")[1].lower() 30 | print("Image Encoding: %s"%encoding) 31 | try: 32 | if encoding=="gif" and previewsize==SET.NO_RESIZE: 33 | theTKImage=TK.PhotoImage(file=filename) 34 | else: 35 | imageview=Image.open(filename) 36 | if previewsize!=SET.NO_RESIZE: 37 | imageview.thumbnail(previewsize,Image.ANTIALIAS) 38 | imageview.save(SET.TEMP_FILE,format="ppm") 39 | theTKImage=TK.PhotoImage(file=SET.TEMP_FILE) 40 | except IOError: 41 | print("Unable to get: %s"%filename) 42 | return theTKImage 43 | 44 | def timestamp(): 45 | ts=time.time() 46 | tstring=datetime.datetime.fromtimestamp(ts) 47 | return tstring.strftime("%Y%m%d_%H%M%S") 48 | 49 | def __init__(self,parent): 50 | self.parent=parent 51 | TK.Frame.__init__(self,self.parent) 52 | self.parent.title("Camera GUI") 53 | self.previewUpdate = TK.IntVar() 54 | self.filename=TK.StringVar() 55 | self.canvas = TK.Canvas(self.parent, 56 | width=SET.PV_SIZE[0], 57 | height=SET.PV_SIZE[1]) 58 | self.canvas.grid(row=0,columnspan=4) 59 | self.shutterBtn=TK.Button(self.parent,text="Shutter", 60 | command=self.shutter) 61 | self.shutterBtn.grid(row=1,column=0) 62 | exitBtn=TK.Button(self.parent,text="Exit", 63 | command=self.exit) 64 | exitBtn.grid(row=1,column=3) 65 | previewChk=TK.Checkbutton(self.parent,text="Preview", 66 | variable=self.previewUpdate) 67 | previewChk.grid(row=1,column=1) 68 | labelFilename=TK.Label(self.parent, 69 | textvariable=self.filename) 70 | labelFilename.grid(row=2,column=0,columnspan=3) 71 | self.preview() 72 | 73 | def msg(self,text): 74 | self.filename.set(text) 75 | self.update() 76 | 77 | def btnState(self,state): 78 | self.shutterBtn["state"] = state 79 | 80 | def shutter(self): 81 | self.btnState("disabled") 82 | self.msg("Taking photo...") 83 | self.update() 84 | if self.previewUpdate.get() == 1: 85 | self.preview() 86 | else: 87 | self.normal() 88 | self.btnState("active") 89 | 90 | def normal(self): 91 | name=cameraGUI.timestamp()+".jpg" 92 | cameraGUI.camCapture(name,SET.NORM_SIZE) 93 | self.updateDisp(name,previewsize=SET.PV_SIZE) 94 | self.msg(name) 95 | 96 | def preview(self): 97 | cameraGUI.camCapture(SET.PREVIEW_FILE,SET.PV_SIZE) 98 | self.updateDisp(SET.PREVIEW_FILE) 99 | self.msg(SET.PREVIEW_FILE) 100 | 101 | def updateDisp(self,filename,previewsize=SET.NO_RESIZE): 102 | self.msg("Loading Preview...") 103 | self.myImage=cameraGUI.getTKImage(filename,previewsize) 104 | self.theImage=self.canvas.create_image(0,0, 105 | anchor=TK.NW, 106 | image=self.myImage) 107 | self.update() 108 | 109 | def exit(self): 110 | exit() 111 | #End 112 | -------------------------------------------------------------------------------- /Chapter 8/cameraGUI1normal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #cameraGUI1normal.py 3 | import tkinter as TK 4 | import cameraGUI as GUI 5 | 6 | root=TK.Tk() 7 | root.title("Camera GUI") 8 | cam=GUI.cameraGUI(root) 9 | TK.mainloop() 10 | #End 11 | -------------------------------------------------------------------------------- /Chapter 8/cameraGUI2timelapse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #cameraGUI2timelapse.py 3 | import tkinter as TK 4 | import timelapseGUI as GUI 5 | 6 | root=TK.Tk() 7 | root.title("Camera GUI") 8 | cam=GUI.cameraGUI(root) 9 | TK.mainloop() 10 | #End -------------------------------------------------------------------------------- /Chapter 8/cameraGUI3animate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #cameraGUI3animate.py 3 | import tkinter as TK 4 | import animateGUI as GUI 5 | 6 | #Define Tkinter App 7 | root=TK.Tk() 8 | root.title("Camera GUI") 9 | cam=GUI.cameraGUI(root) 10 | TK.mainloop() 11 | #End -------------------------------------------------------------------------------- /Chapter 8/cameraGUI4qrcodes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #cameraGUI4qrcodes.py 3 | import tkinter as TK 4 | import qrcodeGUI as GUI 5 | 6 | #Define Tkinter App 7 | root=TK.Tk() 8 | root.title("Camera GUI") 9 | cam=GUI.cameraGUI(root) 10 | TK.mainloop() 11 | #End -------------------------------------------------------------------------------- /Chapter 8/cameraGUIframe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import tkinter as TK 3 | from PIL import Image 4 | import time 5 | import subprocess 6 | from tkinter import messagebox 7 | import datetime 8 | 9 | pv_size=320,240 10 | CAM_OUTPUT=" --output " 11 | CAM_PREVIEW="raspistill --nopreview --width 320 --height 240 --timeout 100 --rotation 90 --encoding gif" 12 | CAM_NORMAL="raspistill --rotation 90 --timeout 100" 13 | CAM_TL="raspistill --nopreview --width 320 --height 240 --timeout 100 --rotation 90" 14 | PREVIEW_FILE="PREVIEW.gif" 15 | TEMP_FILE="PREVIEW.ppm" 16 | NO_RESIZE=(0,0) 17 | ENC_PROG="mencoder -nosound -ovc lavc -lavcopts vcodec=mpeg4:aspect=16/9:vbitrate=8000000 -vf scale=1920:1080 -o %s -mf type=jpeg:fps=24 mf://@image_list.txt" 18 | 19 | def run(cmd): 20 | print("Run:"+cmd) 21 | subprocess.call([cmd], shell=True) 22 | 23 | def getTKImage(filename,previewsize=(0,0)): 24 | encoding=str.split(filename,".")[1].lower() 25 | print("Image Encoding: %s"%encoding) 26 | try: 27 | if encoding=="gif" and previewsize==(0,0): 28 | theTKImage=TK.PhotoImage(file=filename) 29 | else: 30 | imageview=Image.open(filename) 31 | if previewsize!=(0,0): 32 | imageview.thumbnail(previewsize,Image.ANTIALIAS) 33 | imageview.save(TEMP_FILE,format='ppm') 34 | theTKImage=TK.PhotoImage(file=TEMP_FILE) 35 | except IOError: 36 | print("Unable to get: %s"%filename) 37 | print("Filename: %s"%filename) 38 | return theTKImage 39 | 40 | def timestamp(): 41 | ts=time.time() 42 | return datetime.datetime.fromtimestamp(ts).strftime('%Y%m%d_%H%M%S') 43 | 44 | class frameGUI(TK.Frame): 45 | def __init__(self,parent): 46 | self.parent=parent 47 | TK.Frame.__init__(self,self.parent,background="white") 48 | self.numImageTL=TK.StringVar() 49 | self.peroidTL=TK.StringVar() 50 | self.totalTimeTL=TK.StringVar() 51 | self.genVideoTL=TK.IntVar() 52 | self.numImageTL.set(10) 53 | self.peroidTL.set(5) 54 | self.calcTLTotalTime() 55 | self.genVideoTL.set(1) 56 | labelnumImgTK=TK.Label(self.parent,text="TL:#Images") 57 | labelperoidTK=TK.Label(self.parent,text="TL:Delay") 58 | labeltotalTimeTK=TK.Label(self.parent,text="TL:TotalTime") 59 | self.numImgSpn=TK.Spinbox(self.parent,textvariable=self.numImageTL,from_=1, to=99999,width=5,command=self.calcTLTotalTime) 60 | self.peroidSpn=TK.Spinbox(self.parent,textvariable=self.peroidTL,from_=1, to=99999,width=5,command=self.calcTLTotalTime) 61 | self.totalTime=TK.Label(self.parent,textvariable=self.totalTimeTL) 62 | self.TLBtn=TK.Button(self.parent,text="TL GO!",command=self.timelapse) 63 | genChk=TK.Checkbutton(self.parent,text="GenVideo",command=self.genVideoChk,variable=self.genVideoTL) 64 | labelnumImgTK.grid(row=3,column=0) 65 | self.numImgSpn.grid(row=4,column=0) 66 | labelperoidTK.grid(row=3,column=1) 67 | self.peroidSpn.grid(row=4,column=1) 68 | labeltotalTimeTK.grid(row=3,column=2) 69 | self.totalTime.grid(row=4,column=2) 70 | self.TLBtn.grid(row=3,column=3) 71 | genChk.grid(row=4,column=3) 72 | 73 | def calcTLTotalTime(self): 74 | numImg=float(self.numImageTL.get())-1 75 | peroid=float(self.peroidTL.get()) 76 | if numImg<0: 77 | numImg=1 78 | self.totalTimeTL.set(numImg*peroid) 79 | 80 | def timelapse(self): 81 | print("Timelapse") 82 | self.TLBtn['state'] = 'disabled' 83 | self.update() 84 | self.tstamp="TL"+timestamp() 85 | cmd=CAM_TL+" --timelapse "+str(float(self.peroidTL.get())*1000) 86 | cmd+=" --timeout "+str(float(self.totalTimeTL.get())*1000) 87 | cmd+=CAM_OUTPUT+self.tstamp+"_%03d.jpg" 88 | run(cmd) 89 | if self.genVideoTL.get() == 1: 90 | self.genTLVideo() 91 | self.TLBtn['state'] = 'active' 92 | TK.messagebox.showinfo("Timelapse Complete","Processing complete") 93 | self.update() 94 | def genVideoChk(self): 95 | if self.genVideoTL.get() == 1: 96 | TK.messagebox.showinfo("Generate Video Enabled","Video will be generated") 97 | else: 98 | TK.messagebox.showinfo("Generate Video Disabled","Only images will be generated") 99 | def genTLVideo(self): 100 | #ls "$fname"*.jpg > $dir/image_list.txt 101 | run("ls "+self.tstamp+"*.jpg > image_list.txt") 102 | run(ENC_PROG%(self.tstamp+".avi")) 103 | 104 | class cameraGUI(TK.Frame): 105 | def __init__(self,parent): 106 | self.parent=parent 107 | TK.Frame.__init__(self,self.parent,background="white") 108 | self.count=0 109 | self.running = True 110 | self.parent.title("Camera GUI") 111 | self.previewUpdate = TK.IntVar() 112 | self.filename=TK.StringVar() 113 | self.canvas = TK.Canvas(self.parent, width=pv_size[0], height=pv_size[1]) 114 | self.shutterBtn=TK.Button(self.parent,text="Shutter",command=self.shutter) 115 | exitBtn=TK.Button(self.parent,text="Exit",command=self.exit) 116 | previewChk=TK.Checkbutton(self.parent,text="Preview",variable=self.previewUpdate) 117 | labelFilename=TK.Label(self.parent,textvariable=self.filename) 118 | frameGUI(self.parent).grid(row=3,columnspan=4) 119 | self.canvas.grid(row=0,columnspan=4) 120 | self.shutterBtn.grid(row=1,column=0) 121 | previewChk.grid(row=2,column=0) 122 | labelFilename.grid(row=1,column=1,columnspan=2) 123 | exitBtn.grid(row=1,column=3) 124 | self.preview() 125 | 126 | def shutter(self): 127 | self.shutterBtn['state'] = 'disabled' 128 | self.update() 129 | if cam.previewUpdate.get() == 1: 130 | self.preview() 131 | else: 132 | self.normal() 133 | self.shutterBtn['state'] = 'active' 134 | def normal(self): 135 | self.count+=1 136 | name=timestamp()+".jpg"#"%02d"%(self.count)+DEFAULT_FILE 137 | self.filename.set(name) 138 | run(CAM_NORMAL+CAM_OUTPUT+self.filename.get()) 139 | self.updateDisp(self.filename.get(),previewsize=pv_size) 140 | def preview(self): 141 | self.filename.set(PREVIEW_FILE) 142 | run(CAM_PREVIEW+CAM_OUTPUT+self.filename.get()) 143 | self.updateDisp(self.filename.get()) 144 | def updateDisp(self,filename,previewsize=NO_RESIZE): 145 | self.myImage=getTKImage(filename,previewsize) 146 | self.theImage=self.canvas.create_image(0, 0,anchor=TK.NW,image=self.myImage) 147 | self.update() 148 | def exit(self): 149 | exit() 150 | 151 | #Define Tkinter App 152 | root=TK.Tk() 153 | root.title("Camera GUI") 154 | #root.geometry("%dx%d+%d+%d"%(w,h,x,y)) 155 | cam=cameraGUI(root) 156 | TK.mainloop() -------------------------------------------------------------------------------- /Chapter 8/cameraGUItimelapse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import tkinter as TK 3 | from PIL import Image 4 | import time 5 | import subprocess 6 | from tkinter import messagebox 7 | import datetime 8 | 9 | pv_size=320,240 10 | CAM_OUTPUT=" --output " 11 | CAM_PREVIEW="raspistill --nopreview --width 320 --height 240 --timeout 100 --rotation 90 --encoding gif" 12 | CAM_NORMAL="raspistill --rotation 90 --timeout 100" 13 | CAM_TL="raspistill --nopreview --width 320 --height 240 --timeout 100 --rotation 90" 14 | PREVIEW_FILE="PREVIEW.gif" 15 | DEFAULT_FILE="Image.jpg" 16 | TEMP_FILE="PREVIEW.ppm" 17 | NO_RESIZE=(0,0) 18 | ENC_PROG="mencoder -nosound -ovc lavc -lavcopts vcodec=mpeg4:aspect=16/9:vbitrate=8000000 -vf scale=1920:1080 -o %s -mf type=jpeg:fps=24 mf://@image_list.txt" 19 | 20 | def run(cmd): 21 | print("Run:"+cmd) 22 | subprocess.call([cmd], shell=True) 23 | 24 | def getTKImage(filename,previewsize=(0,0)): 25 | encoding=str.split(filename,".")[1].lower() 26 | print("Image Encoding: %s"%encoding) 27 | try: 28 | if encoding=="gif" and previewsize==(0,0): 29 | theTKImage=TK.PhotoImage(file=filename) 30 | else: 31 | imageview=Image.open(filename) 32 | if previewsize!=(0,0): 33 | imageview.thumbnail(previewsize,Image.ANTIALIAS) 34 | imageview.save(TEMP_FILE,format='ppm') 35 | theTKImage=TK.PhotoImage(file=TEMP_FILE) 36 | except IOError: 37 | print("Unable to get: %s"%filename) 38 | print("Filename: %s"%filename) 39 | return theTKImage 40 | 41 | def timestamp(): 42 | ts=time.time() 43 | return datetime.datetime.fromtimestamp(ts).strftime('%Y%m%d_%H%M%S') 44 | 45 | class frameGUI(TK.Frame): 46 | def __init__(self,parent): 47 | self.parent=parent 48 | TK.Frame.__init__(self,self.parent,background="white") 49 | self.numImageTL=TK.StringVar() 50 | self.peroidTL=TK.StringVar() 51 | self.totalTimeTL=TK.StringVar() 52 | self.genVideoTL=TK.IntVar() 53 | self.numImageTL.set(10) 54 | self.peroidTL.set(5) 55 | self.calcTLTotalTime() 56 | self.genVideoTL.set(1) 57 | labelnumImgTK=TK.Label(self.parent,text="TL:#Images") 58 | labelperoidTK=TK.Label(self.parent,text="TL:Delay") 59 | labeltotalTimeTK=TK.Label(self.parent,text="TL:TotalTime") 60 | self.numImgSpn=TK.Spinbox(self.parent,textvariable=self.numImageTL,from_=1, to=99999,width=5,command=self.calcTLTotalTime) 61 | self.peroidSpn=TK.Spinbox(self.parent,textvariable=self.peroidTL,from_=1, to=99999,width=5,command=self.calcTLTotalTime) 62 | self.totalTime=TK.Label(self.parent,textvariable=self.totalTimeTL) 63 | self.TLBtn=TK.Button(self.parent,text="TL GO!",command=self.timelapse) 64 | genChk=TK.Checkbutton(self.parent,text="GenVideo",command=self.genVideoChk,variable=self.genVideoTL) 65 | labelnumImgTK.grid(row=3,column=0) 66 | self.numImgSpn.grid(row=4,column=0) 67 | labelperoidTK.grid(row=3,column=1) 68 | self.peroidSpn.grid(row=4,column=1) 69 | labeltotalTimeTK.grid(row=3,column=2) 70 | self.totalTime.grid(row=4,column=2) 71 | self.TLBtn.grid(row=3,column=3) 72 | genChk.grid(row=4,column=3) 73 | 74 | def calcTLTotalTime(self): 75 | numImg=float(self.numImageTL.get())-1 76 | peroid=float(self.peroidTL.get()) 77 | if numImg<0: 78 | numImg=1 79 | self.totalTimeTL.set(numImg*peroid) 80 | 81 | def timelapse(self): 82 | print("Timelapse") 83 | self.TLBtn['state'] = 'disabled' 84 | self.update() 85 | self.tstamp="TL"+timestamp() 86 | cmd=CAM_TL+" --timelapse "+str(float(self.peroidTL.get())*1000) 87 | cmd+=" --timeout "+str(float(self.totalTimeTL.get())*1000) 88 | cmd+=CAM_OUTPUT+self.tstamp+"_%03d.jpg" 89 | run(cmd) 90 | if self.genVideoTL.get() == 1: 91 | self.genTLVideo() 92 | self.TLBtn['state'] = 'active' 93 | TK.messagebox.showinfo("Timelapse Complete","Processing complete") 94 | self.update() 95 | def genVideoChk(self): 96 | if self.genVideoTL.get() == 1: 97 | TK.messagebox.showinfo("Generate Video Enabled","Video will be generated") 98 | else: 99 | TK.messagebox.showinfo("Generate Video Disabled","Only images will be generated") 100 | def genTLVideo(self): 101 | #ls "$fname"*.jpg > $dir/image_list.txt 102 | run("ls "+self.tstamp+"*.jpg > image_list.txt") 103 | run(ENC_PROG%(self.tstamp+".avi")) 104 | 105 | class cameraGUI(TK.Frame): 106 | def __init__(self,parent): 107 | self.parent=parent 108 | TK.Frame.__init__(self,self.parent,background="white") 109 | self.count=0 110 | self.running = True 111 | self.parent.title("Camera GUI") 112 | self.previewUpdate = TK.IntVar() 113 | self.filename=TK.StringVar() 114 | self.canvas = TK.Canvas(self.parent, width=pv_size[0], height=pv_size[1]) 115 | self.shutterBtn=TK.Button(self.parent,text="Shutter",command=self.shutter) 116 | exitBtn=TK.Button(self.parent,text="Exit",command=self.exit) 117 | previewChk=TK.Checkbutton(self.parent,text="Preview",variable=self.previewUpdate) 118 | labelFilename=TK.Label(self.parent,textvariable=self.filename) 119 | frameGUI(self.parent).grid(row=3,columnspan=4) 120 | self.canvas.grid(row=0,columnspan=4) 121 | self.shutterBtn.grid(row=1,column=0) 122 | previewChk.grid(row=2,column=0) 123 | labelFilename.grid(row=1,column=1,columnspan=2) 124 | exitBtn.grid(row=1,column=3) 125 | self.preview() 126 | 127 | def shutter(self): 128 | self.shutterBtn['state'] = 'disabled' 129 | self.update() 130 | if cam.previewUpdate.get() == 1: 131 | self.preview() 132 | else: 133 | self.normal() 134 | self.shutterBtn['state'] = 'active' 135 | def normal(self): 136 | self.count+=1 137 | name=timestamp()+".jpg"#"%02d"%(self.count)+DEFAULT_FILE 138 | self.filename.set(name) 139 | run(CAM_NORMAL+CAM_OUTPUT+self.filename.get()) 140 | self.updateDisp(self.filename.get(),previewsize=pv_size) 141 | def preview(self): 142 | self.filename.set(PREVIEW_FILE) 143 | run(CAM_PREVIEW+CAM_OUTPUT+self.filename.get()) 144 | self.updateDisp(self.filename.get()) 145 | def updateDisp(self,filename,previewsize=NO_RESIZE): 146 | self.myImage=getTKImage(filename,previewsize) 147 | self.theImage=self.canvas.create_image(0, 0,anchor=TK.NW,image=self.myImage) 148 | self.update() 149 | def exit(self): 150 | exit() 151 | 152 | #Define Tkinter App 153 | root=TK.Tk() 154 | root.title("Camera GUI") 155 | #root.geometry("%dx%d+%d+%d"%(w,h,x,y)) 156 | cam=cameraGUI(root) 157 | TK.mainloop() -------------------------------------------------------------------------------- /Chapter 8/genQRCodes.py: -------------------------------------------------------------------------------- 1 | import pyqrcode 2 | qr_code = pyqrcode.create("Once upon a time, there was a princess") 3 | qr_code.png("Story.png") 4 | print("Generated QR-Code") 5 | print("Completed") -------------------------------------------------------------------------------- /Chapter 8/generateQRCodes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #generateQRCodes.py 3 | import pyqrcode 4 | valid=False 5 | print("QR-Code generator") 6 | while(valid==False): 7 | inputpages=input("How many pages?") 8 | try: 9 | PAGES=int(inputpages) 10 | valid=True 11 | except ValueError: 12 | print("Enter valid number.") 13 | pass 14 | print("Creating QR-Codes for "+str(PAGES)+" pages:") 15 | for i in range(PAGES): 16 | file="page%03d"%(i+1) 17 | qr_code = pyqrcode.create(file+".mp3") 18 | qr_code.png(file+".png") 19 | print("Generated QR-Code for "+file) 20 | print("Completed") 21 | #End -------------------------------------------------------------------------------- /Chapter 8/opencv_color_detect.py: -------------------------------------------------------------------------------- 1 | # import the necessary packages 2 | #from picamera.array import PiRGBArray 3 | #from picamera import PiCamera 4 | #import time 5 | import cv2 6 | import numpy as np 7 | 8 | BLUR=(5,5) 9 | threshold=0 10 | #Set the BGR color thresholds 11 | THRESH_TXT=["Blue","Green","Red","Magenta","Yellow"] 12 | THRESH_LOW=[[80,40,0],[40,80,0],[40,0,80],[80,0,80],[0,80,80]] 13 | THRESH_HI=[[220,100,80],[100,220,80],[100,80,220],[220,80,220],[80,220,220]] 14 | 15 | def process_image(raw_image,control): 16 | global threshold 17 | text=[] 18 | images=[] 19 | 20 | #Switch color threshold 21 | if control == ord("c"): 22 | threshold=(threshold+1)%len(THRESH_LOW) 23 | 24 | #Keep a copy of the raw image 25 | text.append("Raw Image %s"%THRESH_TXT[threshold]) 26 | images.append(raw_image) 27 | #Blur the raw image 28 | text.append("with Blur...%s"%THRESH_TXT[threshold]) 29 | images.append(cv2.blur(raw_image, BLUR)) 30 | 31 | lower = np.array(THRESH_LOW[threshold],dtype="uint8") 32 | upper = np.array(THRESH_HI[threshold], dtype="uint8") 33 | 34 | text.append("with Threshold...%s"%THRESH_TXT[threshold]) 35 | images.append(cv2.inRange(images[-1], lower, upper)) 36 | 37 | 38 | # find contours in the threshold image 39 | text.append("with Contours...%s"%THRESH_TXT[threshold]) 40 | images.append(images[-1].copy()) 41 | image, contours, hierarchy = cv2.findContours(images[-1], 42 | cv2.RETR_LIST, 43 | cv2.CHAIN_APPROX_SIMPLE) 44 | 45 | # finding contour with maximum area and store it as best_cnt 46 | max_area = 0 47 | best_cnt = 1 48 | for cnt in contours: 49 | area = cv2.contourArea(cnt) 50 | if area > max_area: 51 | max_area = area 52 | best_cnt = cnt 53 | 54 | # finding centroids of best_cnt and draw a circle there 55 | M = cv2.moments(best_cnt) 56 | cx,cy = int(M['m10']/M['m00']), int(M['m01']/M['m00']) 57 | 58 | if max_area>0: 59 | cv2.circle(raw_image,(cx,cy),8,(THRESH_HI[threshold]),-1) 60 | cv2.circle(raw_image,(cx,cy),4,(THRESH_LOW[threshold]),-1) 61 | 62 | return(images,text) 63 | #End 64 | 65 | -------------------------------------------------------------------------------- /Chapter 8/opencv_display.py: -------------------------------------------------------------------------------- 1 | # import the necessary packages 2 | from picamera.array import PiRGBArray 3 | from picamera import PiCamera 4 | import time 5 | import cv2 6 | #import numpy as np 7 | 8 | import opencv_motion_detect as PROCESS 9 | #import opencv_color_detect as PROCESS 10 | 11 | 12 | 13 | def show_images(images,text,MODE): 14 | # show the frame 15 | MODE=MODE%len(images) 16 | cv2.putText(images[MODE], "%s:%s" %(MODE,text[MODE]), (10,20), 17 | cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 2) 18 | cv2.imshow("Frame", images[MODE]) 19 | 20 | def begin_capture(): 21 | # initialize the camera and grab a reference to the raw camera capture 22 | camera = PiCamera() 23 | camera.resolution = (640, 480) 24 | camera.framerate = 50 25 | camera.hflip = True 26 | 27 | rawCapture = PiRGBArray(camera, size=(640, 480)) 28 | 29 | # allow the camera to warmup 30 | time.sleep(0.1) 31 | print("Starting camera...") 32 | MODE=0 33 | 34 | # capture frames from the camera 35 | for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): 36 | # capture any key presses 37 | key = cv2.waitKey(1) & 0xFF 38 | 39 | # grab the raw NumPy array representing the image 40 | images, text = PROCESS.process_image(frame.array,key) 41 | 42 | # if the `q` key was pressed, break from the loop 43 | if key == ord("m"): 44 | MODE=(MODE+1)#%MODE_MAX 45 | elif key == ord("q"): 46 | print("Quit") 47 | break 48 | 49 | show_images(images,text,MODE) 50 | 51 | # clear the stream in preparation for the next frame 52 | rawCapture.truncate(0) 53 | 54 | 55 | begin_capture() 56 | #End 57 | 58 | -------------------------------------------------------------------------------- /Chapter 8/opencv_motion_detect.py: -------------------------------------------------------------------------------- 1 | #import the necessary packages 2 | import cv2 3 | import numpy as np 4 | 5 | BLUR=(5,5) 6 | HIBLUR=(30,30) 7 | GAUSSIAN=(21,21) 8 | 9 | imageBG=None 10 | gray=True 11 | 12 | movement=[] 13 | AVG=2 14 | avgX=0 15 | avgY=0 16 | count=0 17 | 18 | def process_image(raw_image,control): 19 | global imageBG 20 | global count,avgX,avgY,movement,gray 21 | 22 | text=[] 23 | images=[] 24 | reset=False 25 | 26 | #Toggle Gray and reset background 27 | if control == ord("g"): 28 | if gray: 29 | gray=not gray 30 | reset=True 31 | print("Toggle Gray") 32 | #Display contour and hierarchy details 33 | elif control == ord("i"): 34 | print("Contour: %s"%contours) 35 | print("Hierarchy: %s"%hierarchy) 36 | #Reset the background image 37 | elif control == ord("r"): 38 | reset=True 39 | 40 | #Clear movement record and reset background 41 | if reset: 42 | print("Reset Background") 43 | imageBG=None 44 | movement=[] 45 | 46 | #Keep a copy of the raw image 47 | text.append("Raw Image") 48 | images.append(raw_image) 49 | 50 | if gray: 51 | raw_image=cv2.cvtColor(raw_image,cv2.COLOR_BGR2GRAY) 52 | 53 | #Blur the raw image 54 | text.append("with Gaussian Blur...") 55 | images.append(cv2.GaussianBlur(raw_image, GAUSSIAN, 0)) 56 | 57 | #Initialise background 58 | if imageBG is None: 59 | imageBG=images[-1] 60 | 61 | text.append("with image delta...") 62 | images.append(cv2.absdiff(imageBG,images[-1])) 63 | 64 | text.append("with threshold mask...") 65 | images.append(cv2.threshold(images[-1], 25, 255, 66 | cv2.THRESH_BINARY)[1]) 67 | 68 | text.append("with dilation...") 69 | images.append(cv2.dilate(images[-1],None, iterations=3)) 70 | #text.append("with dilation kernel...") 71 | #kernel=np.ones((1,1),np.uint8) 72 | #images.append(cv2.dilate(images[-2],kernel, iterations=3)) 73 | 74 | #Find contours 75 | if not gray: 76 | #Require gray image to find contours 77 | text.append("with dilation gray...") 78 | images.append(cv2.cvtColor(images[-1],cv2.COLOR_BGR2GRAY)) 79 | text.append("with contours...") 80 | images.append(images[-1].copy()) 81 | aimage, contours, hierarchy = cv2.findContours(images[-1], 82 | cv2.RETR_LIST, 83 | cv2.CHAIN_APPROX_SIMPLE) 84 | 85 | #Determine the area of each of the contours 86 | largest_area=0 87 | found_contour=None 88 | for cnt in contours: 89 | area = cv2.contourArea(cnt) 90 | #Find which one is largest 91 | if area > largest_area: 92 | largest_area=area 93 | found_contour=cnt 94 | 95 | 96 | if found_contour != None: 97 | #Find the centre of the contour 98 | M=cv2.moments(found_contour) 99 | cx,cy=int(M['m10']/M['m00']),int(M['m01']/M['m00']) 100 | #Calculate the average 101 | if count 1: 115 | for i,j in enumerate(movement): 116 | if i>1: 117 | cv2.line(images[0],movement[i-1],movement[i],(255,255,255)) 118 | 119 | return(images,text) 120 | 121 | 122 | #End 123 | 124 | -------------------------------------------------------------------------------- /Chapter 8/openimage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #openimage.py 3 | import cv2 4 | 5 | # Load a color image in grayscale 6 | img = cv2.imread('testimage.jpg',0) 7 | cv2.imshow('image',img) 8 | cv2.waitKey(0) 9 | cv2.destroyAllWindows() 10 | 11 | -------------------------------------------------------------------------------- /Chapter 8/qrcodeGUI.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #qrcodeGUI 3 | import tkinter as TK 4 | from tkinter import messagebox 5 | import subprocess 6 | import cameraGUI as camGUI 7 | 8 | class SET(camGUI.SET): 9 | QR_SIZE=(640,480) 10 | READ_QR="zbarimg " 11 | 12 | class cameraGUI(camGUI.cameraGUI): 13 | def run_p(cmd): 14 | print("RunP:"+cmd) 15 | proc=subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE) 16 | result="" 17 | for line in proc.stdout: 18 | result=str(line,"utf-8") 19 | return result 20 | 21 | def __init__(self,parent): 22 | super(cameraGUI,self).__init__(parent) 23 | self.parent=parent 24 | TK.Frame.__init__(self,self.parent,background="white") 25 | self.qrScan=TK.IntVar() 26 | self.qrRead=TK.IntVar() 27 | self.qrStream=TK.IntVar() 28 | self.resultQR=TK.StringVar() 29 | self.btnQrTxt=TK.StringVar() 30 | self.btnQrTxt.set("QR GO!") 31 | self.QRBtn=TK.Button(self.parent,textvariable=self.btnQrTxt, 32 | command=self.qrGet) 33 | readChk=TK.Checkbutton(self.parent,text="Read", 34 | variable=self.qrRead) 35 | streamChk=TK.Checkbutton(self.parent,text="Stream", 36 | variable=self.qrStream) 37 | labelQR=TK.Label(self.parent,textvariable=self.resultQR) 38 | readChk.grid(row=3,column=0) 39 | streamChk.grid(row=3,column=1) 40 | self.QRBtn.grid(row=3,column=3) 41 | labelQR.grid(row=4,columnspan=4) 42 | self.scan=False 43 | 44 | def qrGet(self): 45 | if (self.scan==True): 46 | self.btnQrTxt.set("QR GO!") 47 | self.btnState("active") 48 | self.scan=False 49 | else: 50 | self.msg("Get QR Code") 51 | self.btnQrTxt.set("STOP") 52 | self.btnState("disabled") 53 | self.scan=True 54 | self.qrScanner() 55 | 56 | def qrScanner(self): 57 | found=False 58 | while self.scan==True: 59 | self.resultQR.set("Taking image...") 60 | self.update() 61 | cameraGUI.camCapture(SET.PREVIEW_FILE,SET.QR_SIZE) 62 | self.resultQR.set("Scanning for QRCode...") 63 | self.update() 64 | #check for QR code in image 65 | qrcode=cameraGUI.run_p(SET.READ_QR+SET.PREVIEW_FILE) 66 | if len(qrcode)>0: 67 | self.msg("Got barcode: %s"%qrcode) 68 | qrcode=qrcode.strip("QR-Code:").strip('\n') 69 | self.resultQR.set(qrcode) 70 | self.scan=False 71 | found=True 72 | else: 73 | self.resultQR.set("No QRCode Found") 74 | if found: 75 | self.qrAction(qrcode) 76 | self.btnState("active") 77 | self.btnQrTxt.set("QR GO!") 78 | self.update() 79 | 80 | def qrAction(self,qrcode): 81 | if self.qrRead.get() == 1: 82 | self.msg("Read:"+qrcode) 83 | cameraGUI.run("sudo flite -t '"+qrcode+"'") 84 | if self.qrStream.get() == 1: 85 | self.msg("Stream:"+qrcode) 86 | cameraGUI.run("omxplayer '"+qrcode+"'") 87 | if self.qrRead.get() == 0 and self.qrStream.get() == 0: 88 | TK.messagebox.showinfo("QR Code",self.resultQR.get()) 89 | #End 90 | -------------------------------------------------------------------------------- /Chapter 8/shutterCam.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #shutterCam.py 3 | import RPi.GPIO as GPIO 4 | import cameraGUI as camGUI 5 | import time 6 | 7 | 8 | GPIO.setmode(GPIO.BOARD) 9 | CAMERA_BTN=12 #GPIO Pin 12 10 | GPIO.setup(CAMERA_BTN,GPIO.IN,pull_up_down=GPIO.PUD_UP) 11 | count=1 12 | try: 13 | while True: 14 | btn_val = GPIO.input(CAMERA_BTN) 15 | #Take photo when Pin 12 at 0V 16 | if btn_val==False: 17 | camGUI.cameraGUI.camCapture("Snap%03d.jpg"%count, 18 | camGUI.SET.NORM_SIZE) 19 | count+=1 20 | time.sleep(0.1) 21 | finally: 22 | GPIO.cleanup() 23 | #End 24 | -------------------------------------------------------------------------------- /Chapter 8/timelapseGUI.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #timelapseGUI.py 3 | import tkinter as TK 4 | from tkinter import messagebox 5 | import cameraGUI as camGUI 6 | import time 7 | 8 | class SET(camGUI.SET): 9 | TL_SIZE=(1920,1080) 10 | ENC_PROG="mencoder -nosound -ovc lavc -lavcopts" 11 | ENC_PROG+=" vcodec=mpeg4:aspect=16/9:vbitrate=8000000" 12 | ENC_PROG+=" -vf scale=%d:%d"%(TL_SIZE[0],TL_SIZE[1]) 13 | ENC_PROG+=" -o %s -mf type=jpeg:fps=24 mf://@%s" 14 | LIST_FILE="image_list.txt" 15 | 16 | class cameraGUI(camGUI.cameraGUI): 17 | def camTimelapse(filename,size=SET.TL_SIZE, 18 | timedelay=10,numImages=10): 19 | with camGUI.picam.PiCamera() as camera: 20 | camera.resolution = size 21 | for count, name in \ 22 | enumerate(camera.capture_continuous(filename)): 23 | print("Timelapse: %s"%name) 24 | if count == numImages: 25 | break 26 | time.sleep(timedelay) 27 | 28 | def __init__(self,parent): 29 | super(cameraGUI,self).__init__(parent) 30 | self.parent=parent 31 | TK.Frame.__init__(self,self.parent,background="white") 32 | self.numImageTL=TK.StringVar() 33 | self.peroidTL=TK.StringVar() 34 | self.totalTimeTL=TK.StringVar() 35 | self.genVideoTL=TK.IntVar() 36 | labelnumImgTK=TK.Label(self.parent,text="TL:#Images") 37 | labelperoidTK=TK.Label(self.parent,text="TL:Delay") 38 | labeltotalTimeTK=TK.Label(self.parent, 39 | text="TL:TotalTime") 40 | self.numImgSpn=TK.Spinbox(self.parent, 41 | textvariable=self.numImageTL, 42 | from_=1,to=99999, 43 | width=5,state="readonly", 44 | command=self.calcTLTotalTime) 45 | self.peroidSpn=TK.Spinbox(self.parent, 46 | textvariable=self.peroidTL, 47 | from_=1,to=99999,width=5, 48 | command=self.calcTLTotalTime) 49 | self.totalTime=TK.Label(self.parent, 50 | textvariable=self.totalTimeTL) 51 | self.TLBtn=TK.Button(self.parent,text="TL GO!", 52 | command=self.timelapse) 53 | genChk=TK.Checkbutton(self.parent,text="GenVideo", 54 | command=self.genVideoChk, 55 | variable=self.genVideoTL) 56 | labelnumImgTK.grid(row=3,column=0) 57 | self.numImgSpn.grid(row=4,column=0) 58 | labelperoidTK.grid(row=3,column=1) 59 | self.peroidSpn.grid(row=4,column=1) 60 | labeltotalTimeTK.grid(row=3,column=2) 61 | self.totalTime.grid(row=4,column=2) 62 | self.TLBtn.grid(row=3,column=3) 63 | genChk.grid(row=4,column=3) 64 | self.numImageTL.set(10) 65 | self.peroidTL.set(5) 66 | self.genVideoTL.set(1) 67 | self.calcTLTotalTime() 68 | 69 | def btnState(self,state): 70 | self.TLBtn["state"] = state 71 | super(cameraGUI,self).btnState(state) 72 | 73 | def calcTLTotalTime(self): 74 | numImg=float(self.numImageTL.get())-1 75 | peroid=float(self.peroidTL.get()) 76 | if numImg<0: 77 | numImg=1 78 | self.totalTimeTL.set(numImg*peroid) 79 | 80 | def timelapse(self): 81 | self.msg("Running Timelapse") 82 | self.btnState("disabled") 83 | self.update() 84 | self.tstamp="TL"+cameraGUI.timestamp() 85 | cameraGUI.camTimelapse(self.tstamp+'{counter:03d}.jpg', 86 | SET.TL_SIZE, 87 | float(self.peroidTL.get()), 88 | int(self.numImageTL.get())) 89 | if self.genVideoTL.get() == 1: 90 | self.genTLVideo() 91 | self.btnState("active") 92 | TK.messagebox.showinfo("Timelapse Complete", 93 | "Processing complete") 94 | self.update() 95 | 96 | def genVideoChk(self): 97 | if self.genVideoTL.get() == 1: 98 | TK.messagebox.showinfo("Generate Video Enabled", 99 | "Video will be generated") 100 | else: 101 | TK.messagebox.showinfo("Generate Video Disabled", 102 | "Only images will be generated") 103 | 104 | def genTLVideo(self): 105 | self.msg("Generate video...") 106 | cameraGUI.run("ls "+self.tstamp+"*.jpg > " 107 | +SET.LIST_FILE) 108 | cameraGUI.run(SET.ENC_PROG%(self.tstamp+".avi", 109 | SET.LIST_FILE)) 110 | self.msg(self.tstamp+".avi") 111 | #End 112 | -------------------------------------------------------------------------------- /Chapter 9/XLoBorg3-part1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #XLoBorg3-part1.py 3 | import wiringpi2 4 | import struct 5 | import time 6 | 7 | global DEBUG 8 | DEBUG=False 9 | 10 | def readBlockData(bus,device,register,words): 11 | magData=[] 12 | for i in range(words): 13 | magData.append(bus.readReg16(device,register+i)) 14 | return magData 15 | 16 | class compass: 17 | def __init__(self): 18 | addr = 0x0E #compass 19 | self.i2c = wiringpi2.I2C() 20 | self.devMAG=self.i2c.setup(addr) 21 | self.initCompass() 22 | 23 | def initCompass(self): 24 | # Acquisition mode 25 | register = 0x11 # CTRL_REG2 26 | data = (1 << 7) # Reset before each acquisition 27 | data |= (1 << 5) # Raw mode, do not apply user offsets 28 | data |= (0 << 5) # Disable reset cycle 29 | self.i2c.writeReg8(self.devMAG,register,data) 30 | # System operation 31 | register = 0x10 # CTRL_REG1 32 | data = (0 << 5) # Output data rate 33 | # (10 Hz when paired with 128 oversample) 34 | data |= (3 << 3) # Oversample of 128 35 | data |= (0 << 2) # Disable fast read 36 | data |= (0 << 1) # Continuous measurement 37 | data |= (1 << 0) # Active mode 38 | self.i2c.writeReg8(self.devMAG,register,data) 39 | 40 | def readCompassRaw(self): 41 | #x, y, z = readCompassRaw() 42 | self.i2c.write(self.devMAG,0x00) 43 | [status, xh, xl, yh, yl, 44 | zh, zl, who, sm, oxh, oxl, 45 | oyh, oyl, ozh, ozl, 46 | temp, c1, c2] = readBlockData(self.i2c,self.devMAG, 0, 18) 47 | # Convert from unsigned to correctly signed values 48 | bytes = struct.pack('BBBBBB', xl, xh, yl, yh, zl, zh) 49 | x, y, z = struct.unpack('hhh', bytes) 50 | return x, y, z 51 | 52 | if __name__ == '__main__': 53 | DEBUG=True 54 | myCompass=compass() 55 | try: 56 | while True: 57 | # Read the MAG Data 58 | mx, my, mz = myCompass.readCompassRaw() 59 | print ("mX = %+06d, mY = %+06d, mZ = %+06d" % (mx, my, mz)) 60 | time.sleep(0.1) 61 | except KeyboardInterrupt: 62 | print("Finished") 63 | #End 64 | -------------------------------------------------------------------------------- /Chapter 9/XLoBorg3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #XLoBorg3.py 3 | import wiringpi2 4 | import struct 5 | import time 6 | import math 7 | 8 | CAL=100 #take CAL samples 9 | FILENAME="mag.cal" 10 | global DEBUG 11 | DEBUG=False 12 | 13 | def readBlockData(bus,device,register,words): 14 | magData=[] 15 | for i in range(words): 16 | magData.append(bus.readReg16(device,register+i)) 17 | return magData 18 | 19 | class compass: 20 | def __init__(self,newCal=False): 21 | addr = 0x0E #compass 22 | self.i2c = wiringpi2.I2C() 23 | self.devMAG=self.i2c.setup(addr) 24 | self.initCompass() 25 | self.offset,self.scaling=self.readCal(newCal) 26 | if DEBUG:print("offset:%s scaling:%s"%(str(self.offset), 27 | str(self.scaling))) 28 | 29 | def initCompass(self): 30 | # Acquisition mode 31 | register = 0x11 # CTRL_REG2 32 | data = (1 << 7) # Reset before each acquisition 33 | data |= (1 << 5) # Raw mode, do not apply user offsets 34 | data |= (0 << 5) # Disable reset cycle 35 | self.i2c.writeReg8(self.devMAG,register,data) 36 | # System operation 37 | register = 0x10 # CTRL_REG1 38 | data = (0 << 5) # Output data rate 39 | # (10 Hz when paired with 128 oversample) 40 | data |= (3 << 3) # Oversample of 128 41 | data |= (0 << 2) # Disable fast read 42 | data |= (0 << 1) # Continuous measurement 43 | data |= (1 << 0) # Active mode 44 | self.i2c.writeReg8(self.devMAG,register,data) 45 | 46 | def readCal(self,newCal=False,filename=FILENAME): 47 | if newCal==False: 48 | try: 49 | with open(FILENAME,'r') as magCalFile: 50 | line=magCalFile.readline() 51 | offset=line.split() 52 | line=magCalFile.readline() 53 | scaling=line.split() 54 | if len(offset)==0 or len(scaling)==0: 55 | raise ValueError() 56 | else: 57 | offset=list(map(float, offset)) 58 | scaling=list(map(float, scaling)) 59 | except (OSError,IOError,TypeError,ValueError) as e: 60 | print("No Cal Data") 61 | newCal=True 62 | pass 63 | if newCal==True: 64 | print("Perform New Calibration") 65 | offset,scaling=self.calibrateCompass() 66 | self.writeCal(offset,scaling) 67 | return offset,scaling 68 | 69 | def writeCal(self,offset,scaling): 70 | if DEBUG:print("Write Calibration") 71 | if DEBUG:print("offset:"+str(offset)) 72 | if DEBUG:print("scaling:"+str(scaling)) 73 | with open(FILENAME,'w') as magCalFile: 74 | for value in offset: 75 | magCalFile.write(str(value)+" ") 76 | magCalFile.write("\n") 77 | for value in scaling: 78 | magCalFile.write(str(value)+" ") 79 | magCalFile.write("\n") 80 | 81 | def calibrateCompass(self,samples=CAL): 82 | MAXS16=32768 83 | SCALE=1000.0 84 | avg=[0,0,0] 85 | min=[MAXS16,MAXS16,MAXS16];max=[-MAXS16,-MAXS16,-MAXS16] 86 | print("Move sensor around axis (start in 5 sec)") 87 | time.sleep(5) 88 | for calibrate in range(samples): 89 | for idx,value in enumerate(self.readCompassRaw()): 90 | avg[idx]+=value 91 | avg[idx]/=2 92 | if(value>max[idx]): 93 | max[idx]=value 94 | if(value180: 20 | CMD=LEFT 21 | else: 22 | CMD=RIGHT 23 | return CMD 24 | 25 | def main(): 26 | myCompass=XLoBorg.compass() 27 | myBot=drive.motor() 28 | while(True): 29 | print("Enter target angle:") 30 | ANGLE=input() 31 | try: 32 | angleTarget=float(ANGLE) 33 | CMD=LEFT 34 | while (CMD!=DONE): 35 | angleCompass=myCompass.readCompassAngle() 36 | CMD=calDir(angleTarget,angleCompass) 37 | print("CMD: %s"%CMD) 38 | time.sleep(1) 39 | myBot.cmd(CMD) 40 | print("Angle Reached!") 41 | except ValueError: 42 | print("Enter valid angle!") 43 | pass 44 | 45 | if __name__ == '__main__': 46 | try: 47 | main() 48 | except KeyboardInterrupt: 49 | print ("Finish") 50 | #End 51 | -------------------------------------------------------------------------------- /Chapter 9/rover_drive.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #rover_drivefwd.py 3 | #HARDWARE SETUP 4 | # P1 5 | # 2[==X====lRr===]26[=======]40 6 | # 1[=======L=====]25[=======]39 7 | import time 8 | import wiringpi2 9 | ON=1;OFF=0 10 | IN=0;OUT=1 11 | STEP=0.2 12 | PINS=[15,16,18,22] # PINS=[L_FWD,L_BWD,R_FWD,R_BWD] 13 | FWD=[ON,OFF,ON,OFF] 14 | BWD=[OFF,ON,OFF,ON] 15 | RIGHT=[OFF,ON,ON,OFF] 16 | LEFT=[ON,OFF,OFF,ON] 17 | DEBUG=True 18 | 19 | class motor: 20 | # Constructor 21 | def __init__(self,pins=PINS,steptime=STEP): 22 | self.pins = pins 23 | self.steptime=steptime 24 | self.GPIOsetup() 25 | 26 | def GPIOsetup(self): 27 | wiringpi2.wiringPiSetupPhys() 28 | for gpio in self.pins: 29 | wiringpi2.pinMode(gpio,OUT) 30 | 31 | def off(self): 32 | for gpio in self.pins: 33 | wiringpi2.digitalWrite(gpio,OFF) 34 | 35 | def drive(self,drive,step=STEP): 36 | for idx,gpio in enumerate(self.pins): 37 | wiringpi2.digitalWrite(gpio,drive[idx]) 38 | if(DEBUG):print("%s:%s"%(gpio,drive[idx])) 39 | time.sleep(step) 40 | self.off() 41 | 42 | def cmd(self,char,step=STEP): 43 | if char == 'f': 44 | self.drive(FWD,step) 45 | elif char == 'b': 46 | self.drive(BWD,step) 47 | elif char == 'r': 48 | self.drive(RIGHT,step) 49 | elif char == 'l': 50 | self.drive(LEFT,step) 51 | elif char == '#': 52 | time.sleep(step) 53 | 54 | def main(): 55 | import os 56 | if "CMD" in os.environ: 57 | CMD=os.environ["CMD"] 58 | INPUT=False 59 | print("CMD="+CMD) 60 | else: 61 | INPUT=True 62 | roverPi=motor() 63 | if INPUT: 64 | print("Enter CMDs [f,b,r,l,#]:") 65 | CMD=input() 66 | for idx,char in enumerate(CMD.lower()): 67 | if(DEBUG):print("Step %s of %s: %s"%(idx+1,len(CMD),char)) 68 | roverPi.cmd(char) 69 | 70 | if __name__ == '__main__': 71 | try: 72 | main() 73 | except KeyboardInterrupt: 74 | print ("Finish") 75 | #End 76 | -------------------------------------------------------------------------------- /Chapter 9/rover_drive_hwpwm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import time 3 | import wiringpi2 4 | ON=1;OFF=0 5 | IN=0;OUT=1 6 | STEP=0.2 7 | PINS=[15,16,18,22] # PINS=[L_FWD,L_BWD,R_FWD,R_BWD] 8 | FWD=[ON,OFF,ON,OFF] 9 | BWD=[OFF,ON,OFF,ON] 10 | RIGHT=[OFF,ON,ON,OFF] 11 | LEFT=[ON,OFF,OFF,ON] 12 | PWM_PIN=12; PWM=2; ON_TIME=512 #0-1024 Off-On 13 | DEBUG=True 14 | 15 | class motor: 16 | # Constructor 17 | def __init__(self,pins=PINS,steptime=STEP): 18 | self.pins = pins 19 | self.steptime=steptime 20 | self.GPIOsetup() 21 | 22 | def GPIOsetup(self): 23 | wiringpi2.wiringPiSetupPhys() 24 | wiringpi2.pinMode(PWM_PIN,PWM) 25 | wiringpi2.pwmWrite(PWM_PIN,ON_TIME) 26 | for gpio in self.pins: 27 | wiringpi2.pinMode(gpio,OUT) 28 | 29 | def off(self): 30 | for gpio in self.pins: 31 | wiringpi2.digitalWrite(gpio,OFF) 32 | 33 | def drive(self,drive,step=STEP): 34 | for idx,gpio in enumerate(self.pins): 35 | wiringpi2.digitalWrite(gpio,drive[idx]) 36 | if(DEBUG):print("%s:%s"%(gpio,drive[idx])) 37 | time.sleep(step) 38 | self.off() 39 | 40 | def cmd(self,char,step=STEP): 41 | if char == 'f': 42 | self.drive(FWD,step) 43 | elif char == 'b': 44 | self.drive(BWD,step) 45 | elif char == 'r': 46 | self.drive(RIGHT,step) 47 | elif char == 'l': 48 | self.drive(LEFT,step) 49 | elif char == '#': 50 | time.sleep(step) 51 | 52 | def main(): 53 | import os 54 | if "CMD" in os.environ: 55 | CMD=os.environ["CMD"] 56 | INPUT=False 57 | print("CMD="+CMD) 58 | else: 59 | INPUT=True 60 | roverPi=motor() 61 | if INPUT: 62 | print("Enter CMDs [f,b,r,l,#]:") 63 | CMD=input() 64 | for idx,char in enumerate(CMD.lower()): 65 | print("Step %s of %s: %s"%(idx+1,len(CMD),char)) 66 | roverPi.cmd(char) 67 | 68 | if __name__ == '__main__': 69 | try: 70 | main() 71 | except KeyboardInterrupt: 72 | print ("Finish") 73 | #End 74 | 75 | -------------------------------------------------------------------------------- /Chapter 9/rover_drive_i2c.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import time 3 | import wiringpi2 4 | ON=1;OFF=0 5 | IN=0;OUT=1 6 | STEP=0.2 7 | PINS=[15,16,18,22] # PINS=[L_FWD,L_BWD,R_FWD,R_BWD] 8 | FWD=[ON,OFF,ON,OFF] 9 | BWD=[OFF,ON,OFF,ON] 10 | RIGHT=[OFF,ON,ON,OFF] 11 | LEFT=[ON,OFF,OFF,ON] 12 | IO_ADDR=0x20 13 | DEBUG=True 14 | 15 | class motor: 16 | # Constructor 17 | def __init__(self,pins=PINS,steptime=STEP,pinbase=0,ADDR=IO_ADDR): 18 | self.pins=[] 19 | for p in pins: 20 | self.pins.append(p+pinbase) 21 | self.steptime=steptime 22 | self.GPIOsetup(pinbase) 23 | 24 | def GPIOsetup(self,pinbase=0,ADDR=IO_ADDR): 25 | wiringpi2.wiringPiSetupPhys() 26 | if (pinbase!=0): 27 | wiringpi2.mcp23017Setup(pinbase,ADDR) 28 | for gpio in self.pins: 29 | wiringpi2.pinMode(gpio,OUT) 30 | 31 | def off(self): 32 | for gpio in self.pins: 33 | wiringpi2.digitalWrite(gpio,OFF) 34 | 35 | def drive(self,drive,step=STEP): 36 | for idx,gpio in enumerate(self.pins): 37 | wiringpi2.digitalWrite(gpio,drive[idx]) 38 | if(DEBUG):print("%s:%s"%(gpio,drive[idx])) 39 | time.sleep(step) 40 | self.off() 41 | 42 | def cmd(self,char,step=STEP): 43 | if char == 'f': 44 | self.drive(FWD,step) 45 | elif char == 'b': 46 | self.drive(BWD,step) 47 | elif char == 'r': 48 | self.drive(RIGHT,step) 49 | elif char == 'l': 50 | self.drive(LEFT,step) 51 | elif char == '#': 52 | time.sleep(step) 53 | 54 | def main(): 55 | import os 56 | if "CMD" in os.environ: 57 | CMD=os.environ["CMD"] 58 | INPUT=False 59 | print("CMD="+CMD) 60 | else: 61 | INPUT=True 62 | roverPi=motor(pins=[0,1,2,3],pinbase=100) 63 | if INPUT: 64 | print("Enter CMDs [f,b,r,l,#]:") 65 | CMD=input() 66 | for idx,char in enumerate(CMD.lower()): 67 | print("Step %s of %s: %s"%(idx+1,len(CMD),char)) 68 | roverPi.cmd(char) 69 | 70 | if __name__ == '__main__': 71 | try: 72 | main() 73 | except KeyboardInterrupt: 74 | print ("Finish") 75 | #End 76 | 77 | -------------------------------------------------------------------------------- /Chapter 9/rover_drive_swpwm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import time 3 | import wiringpi2 4 | ON=1;OFF=0 5 | IN=0;OUT=1 6 | STEP=0.2 7 | PINS=[15,16,18,22] # PINS=[L_FWD,L_BWD,R_FWD,R_BWD] 8 | FWD=[ON,OFF,ON,OFF] 9 | BWD=[OFF,ON,OFF,ON] 10 | RIGHT=[OFF,ON,ON,OFF] 11 | LEFT=[ON,OFF,OFF,ON] 12 | PWM_PIN_ENA=7;PWM_PIN_ENA=11;RANGE=100 #0-100 (100Hz Max) 13 | ON_TIME1=20; ON_TIME2=75 #0-100 14 | DEBUG=True 15 | 16 | class motor: 17 | # Constructor 18 | def __init__(self,pins=PINS,steptime=STEP): 19 | self.pins = pins 20 | self.steptime=steptime 21 | self.GPIOsetup() 22 | 23 | def GPIOsetup(self): 24 | wiringpi2.wiringPiSetupPhys() 25 | wiringpi2.softPwmCreate(PWM_PIN_ENA,ON_TIME1,RANGE) 26 | wiringpi2.softPwmCreate(PWM_PIN_ENB,ON_TIME2,RANGE) 27 | for gpio in self.pins: 28 | wiringpi2.pinMode(gpio,OUT) 29 | 30 | def off(self): 31 | for gpio in self.pins: 32 | wiringpi2.digitalWrite(gpio,OFF) 33 | 34 | def drive(self,drive,step=STEP): 35 | for idx,gpio in enumerate(self.pins): 36 | wiringpi2.digitalWrite(gpio,drive[idx]) 37 | if(DEBUG):print("%s:%s"%(gpio,drive[idx])) 38 | time.sleep(step) 39 | self.off() 40 | 41 | def cmd(self,char,step=STEP): 42 | if char == 'f': 43 | self.drive(FWD,step) 44 | elif char == 'b': 45 | self.drive(BWD,step) 46 | elif char == 'r': 47 | self.drive(RIGHT,step) 48 | elif char == 'l': 49 | self.drive(LEFT,step) 50 | elif char == '#': 51 | time.sleep(step) 52 | 53 | def main(): 54 | import os 55 | if "CMD" in os.environ: 56 | CMD=os.environ["CMD"] 57 | INPUT=False 58 | print("CMD="+CMD) 59 | else: 60 | INPUT=True 61 | roverPi=motor() 62 | if INPUT: 63 | print("Enter CMDs [f,b,r,l,#]:") 64 | CMD=input() 65 | for idx,char in enumerate(CMD.lower()): 66 | print("Step %s of %s: %s"%(idx+1,len(CMD),char)) 67 | roverPi.cmd(char) 68 | 69 | if __name__ == '__main__': 70 | try: 71 | main() 72 | except KeyboardInterrupt: 73 | print ("Finish") 74 | #End 75 | 76 | -------------------------------------------------------------------------------- /Chapter 9/rover_drivefwd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #rover_drivefwd.py 3 | #HARDWARE SETUP 4 | # P1 5 | # 2[==X====LR====]26[=======]40 6 | # 1[=============]25[=======]39 7 | import time 8 | import wiringpi2 9 | ON=1;OFF=0 10 | IN=0;OUT=1 11 | STEP=0.5 12 | PINS=[16,18] # PINS=[L-motor,R-motor] 13 | FWD=[ON,ON] 14 | RIGHT=[ON,OFF] 15 | LEFT=[OFF,ON] 16 | DEBUG=True 17 | 18 | class motor: 19 | # Constructor 20 | def __init__(self,pins=PINS,steptime=STEP): 21 | self.pins = pins 22 | self.steptime=steptime 23 | self.GPIOsetup() 24 | 25 | def GPIOsetup(self): 26 | wiringpi2.wiringPiSetupPhys() 27 | for gpio in self.pins: 28 | wiringpi2.pinMode(gpio,OUT) 29 | 30 | def off(self): 31 | for gpio in self.pins: 32 | wiringpi2.digitalWrite(gpio,OFF) 33 | 34 | def drive(self,drive,step=STEP): 35 | for idx,gpio in enumerate(self.pins): 36 | wiringpi2.digitalWrite(gpio,drive[idx]) 37 | if(DEBUG):print("%s:%s"%(gpio,drive[idx])) 38 | time.sleep(step) 39 | self.off() 40 | 41 | def cmd(self,char,step=STEP): 42 | if char == 'f': 43 | self.drive(FWD,step) 44 | elif char == 'r': 45 | self.drive(RIGHT,step) 46 | elif char == 'l': 47 | self.drive(LEFT,step) 48 | elif char == '#': 49 | time.sleep(step) 50 | 51 | def main(): 52 | import os 53 | if "CMD" in os.environ: 54 | CMD=os.environ["CMD"] 55 | INPUT=False 56 | print("CMD="+CMD) 57 | else: 58 | INPUT=True 59 | roverPi=motor() 60 | if INPUT: 61 | print("Enter CMDs [f,r,l,#]:") 62 | CMD=input() 63 | for idx,char in enumerate(CMD.lower()): 64 | if(DEBUG):print("Step %s of %s: %s"%(idx+1,len(CMD),char)) 65 | roverPi.cmd(char) 66 | 67 | if __name__ == '__main__': 68 | try: 69 | main() 70 | except KeyboardInterrupt: 71 | print ("Finish") 72 | #End 73 | 74 | -------------------------------------------------------------------------------- /Chapter 9/servoAdafruit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #servoAdafruit.py 3 | import wiringpi2 4 | import time 5 | 6 | #PWM Registers 7 | MODE1=0x00 8 | PRESCALE=0xFE 9 | LED0_ON_L=0x06 10 | LED0_ON_H=0x07 11 | LED0_OFF_L=0x08 12 | LED0_OFF_H=0x09 13 | 14 | PWMHZ=50 15 | PWMADR=0x40 16 | 17 | 18 | class servo: 19 | # Constructor 20 | def __init__(self,pwmFreq=PWMHZ,addr=PWMADR): 21 | self.i2c = wiringpi2.I2C() 22 | self.devPWM=self.i2c.setup(addr) 23 | self.GPIOsetup(pwmFreq,addr) 24 | 25 | def GPIOsetup(self,pwmFreq,addr): 26 | self.i2c.read(self.devPWM) 27 | self.pwmInit(pwmFreq) 28 | 29 | def pwmInit(self,pwmFreq): 30 | prescale = 25000000.0 / 4096.0 # 25MHz / 12-bit 31 | prescale /= float(pwmFreq) 32 | prescale = prescale - 0.5 #-1 then +0.5 to round to 33 | # nearest value 34 | prescale = int(prescale) 35 | self.i2c.writeReg8(self.devPWM,MODE1,0x00) #RESET 36 | mode=self.i2c.read(self.devPWM) 37 | self.i2c.writeReg8(self.devPWM,MODE1, 38 | (mode & 0x7F)|0x10) #SLEEP 39 | self.i2c.writeReg8(self.devPWM,PRESCALE,prescale) 40 | self.i2c.writeReg8(self.devPWM,MODE1,mode) #restore mode 41 | time.sleep(0.005) 42 | self.i2c.writeReg8(self.devPWM,MODE1,mode|0x80) #restart 43 | 44 | def setPWM(self,channel, on, off): 45 | on=int(on) 46 | off=int(off) 47 | self.i2c.writeReg8(self.devPWM, 48 | LED0_ON_L+4*channel,on & 0xFF) 49 | self.i2c.writeReg8(self.devPWM,LED0_ON_H+4*channel,on>>8) 50 | self.i2c.writeReg8(self.devPWM, 51 | LED0_OFF_L+4*channel,off & 0xFF) 52 | self.i2c.writeReg8(self.devPWM,LED0_OFF_H+4*channel,off>>8) 53 | 54 | def main(): 55 | servoMin = 205 # Min pulse 1ms 204.8 (50Hz) 56 | servoMax = 410 # Max pulse 2ms 409.6 (50Hz) 57 | myServo=servo() 58 | myServo.setPWM(0,0,servoMin) 59 | time.sleep(2) 60 | myServo.setPWM(0,0,servoMax) 61 | 62 | if __name__ == '__main__': 63 | try: 64 | main() 65 | except KeyboardInterrupt: 66 | print ("Finish") 67 | #End 68 | 69 | -------------------------------------------------------------------------------- /Chapter 9/servo_control.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #servo_control.py 3 | import curses 4 | import os 5 | #HARDWARE SETUP 6 | # GPIO 7 | # 2[=VX==2=======]26[=======]40 8 | # 1[===013=======]25[=======]39 9 | # V=5V X=Gnd 10 | # Servo 0=Turn 1=Shoulder 2=Elbox 3=Claw 11 | name=["Turn","Shoulder","Elbow","Claw"] 12 | CAL=[90,90,90,90] 13 | MIN=[0,60,40,60]; MAX=[180,165,180,180] 14 | POS=list(CAL) 15 | KEY_CMD=[ord('c'),ord('x')] 16 | #Keys to rotate counter-clockwise 17 | KEY_LESS={ord('d'):0,ord('s'):1,ord('j'):2,ord('k'):3} 18 | #Keys to rotate clockwise 19 | KEY_MORE={ord('a'):0,ord('w'):1,ord('l'):2,ord('i'):3} 20 | 21 | STEP=5; LESS=-STEP; MORE=STEP #Define control steps 22 | DEG2MS=8.3333; OFFSET=1000 #mseconds 23 | IDLE=2000 #Timeout servo after command 24 | SERVOD="/home/pi/PiBits/ServoBlaster/user/servod" #Location of servod 25 | DEBUG=True 26 | text="Use a-d, w-s, j-l and i-k to control the MeArm. c=Cal x=eXit" 27 | 28 | def initalise(): 29 | cmd=("sudo %s --idle-timeout=%s"%(SERVOD, IDLE)) 30 | os.system(cmd) 31 | 32 | def limitServo(servo,value): 33 | global text 34 | if value > MAX[servo]: 35 | text=("Max %s position %s:%s"%(name[servo],servo,POS[servo])) 36 | return MAX[servo] 37 | elif value < MIN[servo]: 38 | text=("Min %s position %s:%s"%(name[servo],servo,POS[servo])) 39 | return MIN[servo] 40 | else: 41 | return value 42 | 43 | def updateServo(servo,change): 44 | global text 45 | POS[servo]=limitServo(servo,POS[servo]+change) 46 | setServo(servo,POS[servo]) 47 | text=str(POS) 48 | 49 | def setServo(servo,position): 50 | ms=OFFSET+(position*DEG2MS) 51 | os.system("echo %d=%dus > /dev/servoblaster" %(servo,ms)) 52 | 53 | def calibrate(): 54 | global text 55 | text="Calibrate 90deg" 56 | for i,value in enumerate(CAL): 57 | POS[i]=value 58 | setServo(i,value) 59 | 60 | def main(term): 61 | term.nodelay(1) 62 | term.addstr(text) 63 | term.refresh() 64 | while True: 65 | term.move(1,0) 66 | c = term.getch() 67 | if c != -1: 68 | if c in KEY_MORE: 69 | updateServo(KEY_MORE[c],MORE) 70 | elif c in KEY_LESS: 71 | updateServo(KEY_LESS[c],LESS) 72 | elif c in KEY_CMD: 73 | if c == ord('c'): 74 | calibrate() 75 | elif c == ord('x'): 76 | exit() 77 | if DEBUG:term.addstr(text+" ") 78 | 79 | if __name__=='__main__': 80 | initalise() 81 | curses.wrapper(main) 82 | #End 83 | -------------------------------------------------------------------------------- /Chapter 9/sonic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #sonic.py 3 | import wiringpi2 4 | import time 5 | import datetime 6 | 7 | ON=1;OFF=0; IN=0;OUT=1 8 | TRIGGER=15 9 | ECHO=7 10 | PULSE=0.00001 #10us pulse 11 | SPEEDOFSOUND=34029 #34029 cm/s 12 | 13 | def gpiosetup(): 14 | wiringpi2.wiringPiSetupPhys() 15 | wiringpi2.pinMode(TRIGGER,OUT) 16 | wiringpi2.pinMode(ECHO,IN) 17 | wiringpi2.digitalWrite(TRIGGER,OFF) 18 | time.sleep(0.5) 19 | 20 | def pulse(): 21 | wiringpi2.digitalWrite(TRIGGER,ON) 22 | time.sleep(PULSE) 23 | wiringpi2.digitalWrite(TRIGGER,OFF) 24 | starttime=time.time() 25 | stop=starttime 26 | start=starttime 27 | while wiringpi2.digitalRead(ECHO)==0 and start