########################################################################
# Filename    : PCF8574.py
# Description : PCF8574 as Raspberry GPIO
# Author      : freenove
# modification: 2017/04/18
########################################################################
import smbus
import time
class PCF8574_I2C(object):
	OUPUT = 0
	INPUT = 1
	
	def __init__(self,address):
		# Note you need to change the bus number to 0 if running on a revision 1 Raspberry Pi.
		self.bus = smbus.SMBus(1)
		self.address = address
		self.currentValue = 0
		self.writeByte(0)	#I2C test.
		
	def readByte(self):#Read PCF8574 all port of the data
		#value = self.bus.read_byte(self.address)
		return self.currentValue#value
		
	def writeByte(self,value):#Write data to PCF8574 port
		self.currentValue = value
		self.bus.write_byte(self.address,value)

	def digitalRead(self,pin):#Read PCF8574 one port of the data
		value = readByte()	
		return (value&(1<<pin)==(1<<pin)) and 1 or 0
		
	def digitalWrite(self,pin,newvalue):#Write data to PCF8574 one port
		value = self.currentValue #bus.read_byte(address)
		if(newvalue == 1):
			value |= (1<<pin)
		elif (newvalue == 0):
			value &= ~(1<<pin)
		self.writeByte(value)	

def loop():
	mcp = PCF8574_I2C(0x27)
	while True:
		#mcp.writeByte(0xff)
		mcp.digitalWrite(3,1)
		print 'Is 0xff? %x'%(mcp.readByte())
		time.sleep(1)
		mcp.writeByte(0x00)
		#mcp.digitalWrite(7,1)
		print 'Is 0x00? %x'%(mcp.readByte())
		time.sleep(1)
		
class PCF8574_GPIO(object):#Standardization function interface
	OUT = 0
	IN = 1
	BCM = 0
	BOARD = 0
	def __init__(self,address):
		self.chip = PCF8574_I2C(address)
		self.address = address
	def setmode(self,mode):#PCF8574 port belongs to two-way IO, do not need to set the input and output model
		pass
	def setup(self,pin,mode):
		pass
	def input(self,pin):#Read PCF8574 one port of the data
		return self.chip.digitalRead(pin)
	def output(self,pin,value):#Write data to PCF8574 one port
		self.chip.digitalWrite(pin,value)
		
def destroy():
	bus.close()
	
if __name__ == '__main__':
	print 'Program is starting ... '
	try:
		loop()
	except KeyboardInterrupt:
		destroy()
		
	
