#!/usr/bin/python
# -*- encoding: utf-8 -*-

# ovladani 4x sedmisegmentovy displej 

# port A je pripojen na jednotlive segmenty
# spodni 4 bity portu B se staraji o multiplexovani spolecnych elektrod


import smbus
import time
import datetime

bus = smbus.SMBus(1) # novejsi varianta RasPi (512MB)
addr_exp = 0x21     # i2c adresa expanderu

seg={}
# definice jednotlivych sviticich segmentu na displeji pro prislusny znak
#
#      AAAA
#     F    B
#     F    B
#     F    B
#      GGGG
#     E    C
#     E    C
#     E    C
#      DDDD
#
#
#   pri displeji se spolecnou anodou je svitici segment v "0"
#           1GFEDCBA
seg[0]  = 0b11000000   # 0
seg[1]  = 0b11111001   # 1
seg[2]  = 0b10100100   # 2
seg[3]  = 0b10110000   # 3
seg[4]  = 0b10011001   # 4
seg[5]  = 0b10010010   # 5
seg[6]  = 0b10000010   # 6
seg[7]  = 0b11011000   # 7
seg[8]  = 0b10000000   # 8
seg[9]  = 0b10010000   # 9
seg[10] = 0b10001000   # A
seg[11] = 0b10000011   # b
seg[12] = 0b11000110   # C
seg[13] = 0b10100001   # d
seg[14] = 0b10000110   # E
seg[15] = 0b10001110   # F
seg[16] = 0b10001001   # H
seg[17] = 0b11111011   # i
seg[18] = 0b11100001   # J
seg[19] = 0b11000111   # L
seg[20] = 0b11001000   # M
seg[21] = 0b10101011   # n
seg[22] = 0b10100011   # o
seg[23] = 0b10001100   # P
seg[24] = 0b10101111   # r
seg[25] = 0b11100011   # u
seg[26] = 0b10011100   # stupen
seg[27] = 0b10111111   # minus
seg[28] = 0b11110111   # podtrzitko
seg[29] = 0b11111111   # mezera


# pouzito pro preklad ze znaku na kod
slovnik={}
slovnik[0] = "0"
slovnik[1] = "1"
slovnik[2] = "2"
slovnik[3] = "3"
slovnik[4] = "4"
slovnik[5] = "5"
slovnik[6] = "6"
slovnik[7] = "7"
slovnik[8] = "8"
slovnik[9] = "9"
slovnik[10] = "A"
slovnik[11] = "b"
slovnik[12] = "C"
slovnik[13] = "d"
slovnik[14] = "E"
slovnik[15] = "F"
slovnik[16] = "H"
slovnik[17] = "i"
slovnik[18] = "J"
slovnik[19] = "L"
slovnik[20] = "M"
slovnik[21] = "n"
slovnik[22] = "o"
slovnik[23] = "P"
slovnik[24] = "r"
slovnik[25] = "u"
slovnik[26] = "'"  # misto stupnu se musi psat apostrof (napr: "25'C")
slovnik[27] = "-"
slovnik[28] = "_"
slovnik[29] = " "


dis={}

bus.write_byte_data(addr_exp,0x00,0b00000000 ) # cely port A nastavit na vystup
bus.write_byte_data(addr_exp,0x01,0b00000000 ) # cely port B nastavit na vystup



# tohle je jen demo - 20 napisu, ktere se postupne zobrazi na displeji
napis={}
napis[1]  = "1234"
napis[2]  = "5678"
napis[3]  = "9AbC"
napis[4]  = "dEFH"
napis[5]  = "iJLM"
napis[6]  = "noPr"
napis[7]  = "u'-_"
napis[8]  = "    "
napis[9] = "   A"
napis[10] = "  AH"
napis[11] = " AHo"
napis[12] = "AHoJ"
napis[13] = "HoJ "
napis[14] = "oJ  "
napis[15] = "J   "
napis[16] = "    "


for n in napis:  # smycka pro zobrazeni 16 napisu

  text = napis[n]
  
  dvojtecka = 0    # dvojtecka v teto casti dema nesvti   
      
  # preklad znaku na sedmisegmentovy kod 
  for i in range(4):
    dis[i+1] = seg[29]  # pokud se nepodari preklad, zustane sedmisegmentovka zhasnuta (kod mezery je seg[29])
    for j in slovnik:
      if (slovnik[j] == text[i:i+1]):
        dis[i+1] = seg[j]
  
    
  if (dvojtecka == 1):
    dis[2]= dis[2] & 0b01111111                  # kdyz ma dvojtecka svitit, musi se nastavit 7. bit druhe jednotky do "0"
  
  
  
  mezipauza  = 0.003    # jak dlouho bude svitit jedna jednotka
  mezipauza2 = 0.001    # jak dlouho budou zhasnuty jednotky pred zobrazenim dalsiho znaku 

  cas0 = time.time()
  cas = cas0
  
  if (n < 8):                   # pri zobrazeni obycejnych napisu se napisy zobrazuji po 2 sekundach
    prodleva = 2   
  else:                         # pri zobrazeni rotujiciho napisu "AHoJ" je prodleva jen 0.3 sekundy
    prodleva = 0.3  

    
  while (cas0 + prodleva) > cas:   # zobrazeni udaje na displeji trva 0.3 nebo 2 sekundy
    cas = time.time()
  
    # prvni jednotka (leva)
    bus.write_byte_data(addr_exp,0x13,0b11111111)  # zhasnout vsechny 4 jednotky
    time.sleep(mezipauza2)
    bus.write_byte_data(addr_exp,0x12,dis[1])      # nastavit data pro prvni jednotku
    bus.write_byte_data(addr_exp,0x13,0b11111110)  # rozsvitit prvni jednotku
    time.sleep(mezipauza)
  
    # druha jednotka
    bus.write_byte_data(addr_exp,0x13,0b11111111)  # zhasnout vsechny 4 jednotky
    time.sleep(mezipauza2)
    bus.write_byte_data(addr_exp,0x12,dis[2])      # nastavit data pro druhou jednotku
    bus.write_byte_data(addr_exp,0x13,0b11111101)  # rozsvitit druhou jednotku
    time.sleep(mezipauza)
  
    # treti jednotka
    bus.write_byte_data(addr_exp,0x13,0b11111111)  # zhasnout vsechny 4 jednotky
    time.sleep(mezipauza2)
    bus.write_byte_data(addr_exp,0x12,dis[3])      # nastavit data pro treti jednotku
    bus.write_byte_data(addr_exp,0x13,0b11111011)  # rozsvitit treti jednotku
    time.sleep(mezipauza)
  
    # ctvrta jednotka (prava)
    bus.write_byte_data(addr_exp,0x13,0b11111111)  # zhasnout vsechny 4 jednotky
    time.sleep(mezipauza2)
    bus.write_byte_data(addr_exp,0x12,dis[4])      # nastavit data pro ctvrtou jednotku
    bus.write_byte_data(addr_exp,0x13,0b11110111)  # rozsvitit ctvrtou jednotku
    time.sleep(mezipauza)
  


#=============================================================
# zobrazeni casu s blikajici dvojteckou

dvojtecka = 0  # zacina se se zhasnutou dvojteckou

while True:
  datcas = datetime.datetime.now()
  hod = str(datcas.hour).rjust(2," ")     # hodiny se do dvou znaku doplnuji mezerami
  min = str(datcas.minute).rjust(2,"0")   # minuty se do dvou znaku doplnuji nulami

  text = hod + min   # text ma 4 znaky a obsahuje aktualni cas (hodiny a minuty).


  # preklad 4 znaku z textu na sedmisegmentovy kod 
  for i in range(4):
    dis[i+1] = seg[29]  # pokud se nepodari preklad, zustane sedmisegmentovka zhasnuta (kod mezery je seg[29])
    for j in slovnik:
      if (slovnik[j] == text[i:i+1]):
        dis[i+1] = seg[j]



  if (dvojtecka == 0):                # pri kazdem pruchodu (kazdou 1/2 sekundu) dochazi ke zmene stavu dvojtecky 
    dvojtecka = 1
    dis[2]= dis[2] & 0b01111111       # kdyz ma dvojtecka svitit, musi se nastavit 7. bit druhe jednotky do "0"
  else:
    dvojtecka = 0
      


  cas0 = time.time()
  cas = cas0

  while (cas0 + 0.5) > cas:   # zobrazeni udaje na displeji trva 0.5 sekundy. Pak se provadi aktualizace
    cas = time.time()
  
    # prvni jednotka (leva)
    bus.write_byte_data(addr_exp,0x13,0b11111111)  # zhasnout vsechny 4 jednotky
    time.sleep(mezipauza2)
    bus.write_byte_data(addr_exp,0x12,dis[1])      # nastavit data pro prvni jednotku
    bus.write_byte_data(addr_exp,0x13,0b11111110)  # rozsvitit prvni jednotku
    time.sleep(mezipauza)
  
    # druha jednotka
    bus.write_byte_data(addr_exp,0x13,0b11111111)  # zhasnout vsechny 4 jednotky
    time.sleep(mezipauza2)
    bus.write_byte_data(addr_exp,0x12,dis[2])      # nastavit data pro druhou jednotku
    bus.write_byte_data(addr_exp,0x13,0b11111101)  # rozsvitit druhou jednotku
    time.sleep(mezipauza)
  
    # treti jednotka
    bus.write_byte_data(addr_exp,0x13,0b11111111)  # zhasnout vsechny 4 jednotky
    time.sleep(mezipauza2)
    bus.write_byte_data(addr_exp,0x12,dis[3])      # nastavit data pro treti jednotku
    bus.write_byte_data(addr_exp,0x13,0b11111011)  # rozsvitit treti jednotku
    time.sleep(mezipauza)
  
    # ctvrta jednotka (prava)
    bus.write_byte_data(addr_exp,0x13,0b11111111)  # zhasnout vsechny 4 jednotky
    time.sleep(mezipauza2)
    bus.write_byte_data(addr_exp,0x12,dis[4])      # nastavit data pro ctvrtou jednotku
    bus.write_byte_data(addr_exp,0x13,0b11110111)  # rozsvitit ctvrtou jednotku
    time.sleep(mezipauza)




