2017 멀티캠퍼스/Raspberry Pi

#13 라즈베리파이 FND

꿈꾸는어린이 2018. 1. 30. 23:12

//

일시 : 2018.01.12 9:10AM ~ 12:00PM

내용 : FND

//

I2C FND

  • 7개의 LED를 배열하여 0~9까지의 10진수를 표시

  • Dot제외 7개의 직사각형 LED로 하나의 수를 특정 위치에 표현

    7-segment라고도 함

  • FND 개별 요소 하나를 8개 출력으로 생각해야 함(LED와 동일한 제어 방법)


  • SEG_C0 ~ C5가 High이면 불이 켜짐.(6자리에서 어떤 것을 켤지 정함)

  • SEG_A ~ H핀으로 숫자 하나를 제어.(어떤 숫자를 출력할 지 정함)

  • 총 6 + 8 = 14개의 핀을 GPIO에 물리기에는 너무 많으니까 하나의 칩을 사용해 GPIO칩에 두 개만 물리도록.


  • 한 순간에 다른 여려 숫자를 만들기는 불가능. 하나 켜고 delay주고 그 다음 숫자 켜고... 빠른 반복으로 잔상 효과를 주어 전부 켜져있는 것처럼 보이도록 하는 게 최선

  • 14개의 선을 제어하는 칩의 전원을 주기 위해 슬레이브 어드레스(A0,A1,A2)를 셋팅. 각 16개의핀을 어떻게 제어할 것인지(input/output) 명령어들을 I2C로 알려주어야함.


  • 제일 먼저 slave address 보내주고, output설정을 위한 command byte 보내주고(Input/Output), 내가 쓰고 싶은 데이터를 쓰기 위한 command byte(Read 1/Write 0)를 한 바이트씩 보내줌.





실습

- 0 ~ 9까지 순차 출력

  import smbus2 as smbus
import time

bus = smbus.SMBus(1)  # cpu에서 제공하는 채널의 번호 1번 채널
addr = 0x20

config_port = 0x06 # output설정을 위한 command
out_port = 0x02  # 데이터를 쓰기위한 command

#             0     1     2     3     4     5     6     7     8     9
data = (0xFC,0x60,0xDA,0xF2,0x66,0xB6,0x3E,0xE0,0xFE,0xF6)   # 튜플로 만듦
#         seg1, seg2, seg3, seg4, seg5, seg6
digit = (0x7F, 0xBF, 0xDF, 0xEF,  0xF7, 0xFB)  # 켜고 싶은 자리 select

out_disp=0  # 출력할 값

try :
   bus.write_word_data(addr, config_port, 0x0000)
   # 16개의 핀을 출력으로 설정
   
   # seg1부터 seg6까지, 0~9까지 반복하면서 출력
   for i in range(0, 6, 1):
       for j in range(0, 10, 1):
           out_disp = data[j] << 8 | digit[i]
           bus.write_word_data(addr, out_port, out_disp)
           time.sleep(1)
       
except KeyboardInterrupt:
   pass



- 123456 연달아 보이게 하는 코드

  
import smbus2 as smbus
import time

bus = smbus.SMBus(1)
addr = 0x20

config_port = 0x06
out_port = 0x02

data = (0xFC,0x60,0xDA,0xF2,0x66,0xB6,0x3E,0xE0,0xFE,0xF6)
digit = (0x7F, 0xBF, 0xDF, 0xEF,  0xF7, 0xFB)

out_disp = 0

try :
   bus.write_word_data(addr, config_port, 0x0000)
   
   while True:
       j = 1
       for i in range(0, 6, 1):
           out_disp = data[j] << 8 | digit[i]
           bus.write_word_data(addr, out_port, out_disp)
           j += 1
       time.sleep(0.00005)
       
except KeyboardInterrupt:
   pass



- 사용자가 입력한 숫자를 출력하는 코드

  
import smbus2 as smbus
import time

bus = smbus.SMBus(1)
addr = 0x20

config_port = 0x06
out_port = 0x02

data = (0xFC,0x60,0xDA,0xF2,0x66,0xB6,0x3E,0xE0,0xFE,0xF6)
digit = (0x7F, 0xBF, 0xDF, 0xEF,  0xF7, 0xFB)

out_disp = 0

try :
   bus.write_word_data(addr, config_port, 0x0000)
   
   str = input("숫자 6개를 입력하세요 : ")
   
   while True:
     
       for i in range(0, 6):
           j = int(str[i])
           out_disp = data[j] << 8 | digit[i]
           bus.write_word_data(addr, out_port, out_disp)
           j = 0
           
       time.sleep(0.0000005)
       
except KeyboardInterrupt:
   pass

  
import smbus2 as smbus
import time

bus = smbus.SMBus(1)
addr = 0x20

config_port = 0x06
out_port = 0x02

data = (0xFC,0x60,0xDA,0xF2,0x66,0xB6,0x3E,0xE0,0xFE,0xF6)
digit = (0x7F, 0xBF, 0xDF, 0xEF,  0xF7, 0xFB)

out_disp = 0


try :
   bus.write_word_data(addr, config_port, 0x0000)
   
   
   while True:
       str = input("숫자 6개를 입력하세요 : ")
       
       for k in range(500) : ##3초동안 표시되게 3000/6
     
           for i in range(0, 6):
               j = int(str[i])
               out_disp = data[j] << 8 | digit[i]
               bus.write_word_data(addr, out_port, out_disp)
               j = 0
           
          time.sleep(0.0000005)
       
except KeyboardInterrupt:
   pass



- 스레드로 표현

  
import smbus2 as smbus
import time
from threading import Thread

bus = smbus.SMBus(1)
addr = 0x20

config_port = 0x06
out_port = 0x02

data = (0xFC,0x60,0xDA,0xF2,0x66,0xB6,0x3E,0xE0,0xFE,0xF6)
digit = (0x7F, 0xBF, 0xDF, 0xEF,  0xF7, 0xFB)

out_disp = 0

str="000000"

def fnd_thread(val):
   global str
   
   while True:
       for i in range(0, 6):
           out_disp = data[int(str[i])] << 8 | digit[i]
           bus.write_word_data(addr, out_port, out_disp)
               
           time.sleep(0.0000005)
       

try :
   t1 = Thread(target=fnd_thread, args=(1,))
   t1.start()
   
   bus.write_word_data(addr, config_port, 0x0000)
   
   
   while True:
       str = input("숫자 6개를 입력하세요 : ")
       
except KeyboardInterrupt:
   pass



- fnd_thread 1

  
from threading import Thread
import time
val=0

class fnd:
   
   def __init__(self):
       self.threadStop=False    
   
   def fndThread(self, val):
       while self.threadStop != True:
           print("fndTread")
           time.sleep(1)
   
   def start(self):
       self.t1 = Thread(target=self.fndThread, args=(1,) )
       self.t1.start()
       return self.t1
   
   def stop(self):
       self.threadStop=True
   
try:
   if __name__ == "__main__":
       iFnd = fnd()
       threadId=iFnd.start()

       time.sleep(3)
       iFnd.stop()
       
       threadId.join()
       print("fndThread exit")

except KeyboardInterrupt:
   pass
finally:
   pass



- fnd_thread v2

  
from threading import Thread
import smbus2 as smbus
import time
val=0

class fnd:    

   def __init__(self):
       self.threadStop=False
       self.bus = smbus.SMBus(1)
       self.addr = 0x20
       self.out_port = 0x02
       self.displayData="000000"
   
   def fndThread(self, val):
       
       config_port = 0x06
       
       out_disp=0
       data = (0xFC,0x60,0xDA,0xF2,0x66,0xB6,0x3E,0xE0,0xFE,0xF6)
       digit = (0x7F,0xBF,0xDF,0xEF,0xF7,0xFB)
       
       while self.threadStop != True:
           cnt=0
           for i in range(6):
               cnt=len(self.displayData)
               if i >= cnt:
                   continue
               
               self.fndI2cWrite(data[int(self.displayData[i])] , digit[i])
               time.sleep(0.001)
               
   def fndI2cWrite(self, data, digit):
       self.out_disp =  data << 8 | digit
       self.bus.write_word_data(self.addr, self.out_port, self.out_disp)
       
   def displayFnd(self, val):
       self.displayData=val
       
   def start(self):
       self.t1 = Thread(target=self.fndThread, args=(1,) )
       self.t1.start()
       return self.t1
   
   def stop(self):
       self.threadStop=True
       time.sleep(0.1) # Waiting Thread exit
       self.fndI2cWrite(0x00, 0xff)

try:
   if __name__ == "__main__":
       iFnd = fnd()
       threadId=iFnd.start()
       
       for i in range(3):
           dispData=input("입력 :" )
           iFnd.displayFnd(dispData)
       
       iFnd.stop()
       
       threadId.join()
       print("fndThread exit")

except KeyboardInterrupt:
   pass
finally:
   pass