2015-10-30

Counter tiuningas

Na va, nepraėjo nei metai ir "klientui" prireikė patobulinimų. Ir iš tiesų, pradinė mintis, kad paleidinėti ir stabdyti skaitliuką su nuotoliniu pulteliu buvo nebloga, bet tik tol kol realiai nepradedi tai naudoti. Kaip ir kiekvienas gaminys apsišlifuoja ir pasimato nepatogumai tik jį pradėjus intensyviai naudoti.

Čia gi tas pat. Pakabinus monitorių į vietą






pultelis pradėjo nebeveikti nuo palangės (kaip paaiškėjo vėliai tereikėjo pakeisti bateriją). Reikėjo atsistoti tiesiai prieš monitorių ir iš ten paleisti. Taip pultelis prarado savo nuolatinę vietą. Kažas įsideda į kišenę, kažkas deda ant lankų laikiklio(nukrenta). Žodžiu sprendimas - pririšti :)



Sekantis įkyrus dalykas pasirodė, tai kaskart įjungus nustatinėti. Nors tų parametrų viso labo tik keturi, bet juk galima ir jų išvengti. Taigi po įjungimo defaultiniai parametrai dabar iškart pakraurnami ir belieka sulaukti START komados. Ir dar. dėl to jog treniruotės vyksta žymiai dažniau nei varžybos defaultinis serijų skaičius dabar 99.

Taip kur kas geriau! Po kurio laiko užkniso vis siekti to pririšto pultelio, taigi pasiūliau ir visai  teigiamai buvo sutikta mintis mechaniniams mygtukams:






Man čia pasitaikė kaip tik gera proga pasiaiškinti su GPIO portais. Papildomai prie viso to teko susiinstaliuoti python-dev headerius debianui, parsitempti RPi.GPIO ARMui iš https://pypi.python.org/pypi/RPi.GPIO, ir susiinstaliavus (unzip RPi*; cd RPi*; python setup.py install) pridevelopint funkcionalumą. Beje headeriai nenorėjo lyst kol nepraleidau apt-get update. Matyt pasikeitė keliai, versija... Taigi teko šitam bananui laikinai ir internetą duot :

Kadangi po pradinio varianto buvo dar kaikas pakeista, įmesiu pilną kodą:
 #!/usr/bin/python  
 #import Tkinter as tk  
 from Tkinter import *  
 from time import sleep  
 import os  
 #gpio part  
 import RPi.GPIO as GPIO  
 GPIO.setmode(GPIO.BCM)  
 GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)  
 GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)  
 def ck_stop_button():  
      if (GPIO.input(18) == GPIO.LOW): stop()  
      root.after(10,ck_stop_button)  
 def ck_start_button():  
      if (GPIO.input(23) == GPIO.LOW): start()  
      root.after(10,ck_start_button)  
 #gpio part end  
 def togglepauseplay(e=None): os.popen('mocp -M /root/c/.moc1 -G')  
 def mforward(e=None): os.popen('mocp -M /root/c/.moc1 -k 10')  
 def mrewind(e=None): os.popen('mocp -M /root/c/.moc1 -k -10')  
 def mstop(e=None): os.popen('mocp -M /root/c/.moc1 -s')  
 def mplay(e=None): os.popen('mocp -M /root/c/.moc1 -p')  
 def mnext(e=None): os.popen('mocp -M /root/c/.moc1 -f')  
 def mprev(e=None): os.popen('mocp -M /root/c/.moc1 -r')  
 def decrease():  
      global job, curtim  
      tim.configure(text=curtim, fg="#00ff00")  
      if curtim>=0:  
           curtim=curtim-1  
           job=root.after(1000, decrease)  
      else:  
           stop()  
 def start(e=None):  
      global job, var, curtim, timval, curind, indval, curser, serval  
      if var==5 and job==0:  
                curtim=timval  
                os.popen('/root/c/start')  
                decrease()  
 def stop(e=None):  
      global job, timval, curind, curser, serval, indval  
      if job!=0:  
           tim.configure(fg="#ff0000")  
           root.after_cancel(job)  
           job=0  
           os.popen('/root/c/stop &')  
           sleep(5)  
           if (curind==indval and curser==serval):  
                power()  
                return 0  
           nextind()  
           tim.configure(text=timval)  
 def power(e=None):  
      global modval, indval, serval, timval, var, job, w  
      if job==0:  
            job=0  
            var=0  
            modval="Train"  
            indval=0  
            serval=0  
            timval=0  
           mod.place(x=0, y=0)  
           ser.place(x=w/3, y=0)  
           ind.place(x=w/3*2, y=0)  
           mod.configure(text="Mode", fg="gray15")  
           ind.configure(text="Index", fg="gray15")  
           ser.configure(text="Series", fg="gray15")  
           tim.configure(text="Time", fg="gray15")  
 def n(i):  
      global var, modval, indval, serval, timval  
      if var==1:  
           modval=("Train","Comp")[i==0]  
           mod.configure(text=modval)  
      if var==3:  
           indval=i  
           if indval==0: indval=1  
           ind.configure(text=indval)  
      if var==2:  
           serval=serval*10+i  
           if serval==0: serval=1  
           if serval>=99: serval=99  
           ser.configure(text=serval)  
      if var==4:  
           timval=timval*10+i  
           if timval==0: timval=1  
           if timval>=300: timval=300  
           tim.configure(text=timval)  
 def ok(e=None):  
      global var, modval, indval, serval, timval, curind, curser, w  
      if var<5:  
           var=var+1  
           if var==1:  
                mod.configure(fg="yellow")  
           if var==2:  
                if modval=="Train" or modval=="Comp": mod.configure(fg="gray50")  
                else: mod.configure(fg="gray15")  
                ser.configure(fg="yellow")  
           if var==3:  
                if serval>0 and serval<100: ser.configure(fg="gray50")  
                else: ser.configure(fg="gray15")  
                ind.configure(fg="yellow")  
           if var==4:  
                if indval>0 and indval<10: ind.configure(fg="gray50")  
                else: ind.configure(fg="gray15")  
                tim.configure(fg="yellow")  
           if var==5:  
                if modval=="": modval="Train"  
                if indval==0: indval=1  
                if serval==0: serval=99  
                if timval==0: timval=90  
                if modval=="Train": os.popen('touch /root/c/mp3_play')  
                else: os.popen('rm -rf /root/c/mp3_play')  
                 curind=1  
                curser=1  
                curtime=timval  
                modval=""  
                ser.place(x=0, y=0)  
                ind.place(x=w/2, y=0)  
                updinfo()  
 def reset(e=None):  
      global var, modval, indval, serval, timval  
      if var==1: modval=""; mod.configure(text="Mode")  
      if var==3: indval=0; ind.configure(text="Index")  
      if var==2: serval=0; ser.configure(text="Series")  
      if var==4: timval=0; tim.configure(text="Time")  
 def prevind(e=None):  
      global job, curind, indval, curser  
      if job==0:  
           if curind>1:  
                curind=curind-1  
           else:  
                if curser>1:  
                     curser=curser-1  
                     curind=indval  
           updinfo()  
 def nextind(e=None):  
      global job, curind, indval, curser, serval  
      if job==0:  
           if curind<indval:  
                curind=curind+1  
           else:  
                if curser<serval:  
                     curser=curser+1  
                     curind=1  
           updinfo()  
 def updinfo(e=None):  
      indname=['-','A','B','C','D','E','F','G','H','I']  
      global curind, indval, curser, serval, modval, timval  
      #ind.configure(fg="gray50", text="I: "+indname[curind])  
      #ser.configure(fg="gray50", text="S: "+str(curser)+"/"+str(serval))  
      ind.configure(fg="#ffffff", text=indname[curind])  
      ser.configure(fg="#ffffff", text=str(curser))  
      mod.configure(fg="gray50", text=modval)  
      tim.configure(fg="#ff0000", text=timval)  
 var=10  
 val=0  
 modval=""  
 indval=0  
 serval=0  
 timval=0  
 job=0  
 k="b"  
 root=Tk()  
 w=root.winfo_screenwidth()  
 h=root.winfo_screenheight()  
 if k=="b":  
      root.bind('o', prevind)  
      root.bind('p', nextind)  
      root.bind('<F9>', power)  
      root.bind('e', ok)  
      root.bind('q', reset)  
      root.bind('u', start)  
      root.bind('y', stop)  
      root.bind('w', lambda e: n(0))  
      root.bind('3', lambda e: n(1))  
      root.bind('7', lambda e: n(2))  
      root.bind('1', lambda e: n(3))  
      root.bind('<Tab>', lambda e: n(4))  
      root.bind('4', lambda e: n(5))  
      root.bind('5', lambda e: n(6))  
      root.bind('-', lambda e: n(7))  
      root.bind('=', lambda e: n(8))  
      root.bind('9', lambda e: n(9))  
      root.bind('t', togglepauseplay)  
      #root.bind(']', mplay)  
      #root.bind('[', mstop)  
      ##root.bind('o', mrewind)  
      ##root.bind('p', mforward)  
      #root.bind('a', gtournament)  
      #root.bind('s', gtraining)  
      #root.bind('p', mnext)  
      #root.bind('o', mprev)  
 else:  
      #w=640; h=480  
      root.bind('o', prevind)  
      root.bind('p', nextind)  
      root.bind('<Escape>', power)  
      root.bind('<Return>', ok)  
      root.bind('<BackSpace>', reset)  
      root.bind('<F1>', start)  
      root.bind('<space>', stop)  
      root.bind('0', lambda e: n(0))  
      root.bind('1', lambda e: n(1))  
      root.bind('2', lambda e: n(2))  
      root.bind('3', lambda e: n(3))  
      root.bind('4', lambda e: n(4))  
      root.bind('5', lambda e: n(5))  
      root.bind('6', lambda e: n(6))  
      root.bind('7', lambda e: n(7))  
      root.bind('8', lambda e: n(8))  
      root.bind('9', lambda e: n(9))  
 if (1.0*w/h)<1.5: ftim=h/5*3  
 else: ftim=h/8*6  
 ytim=(h/2)-(ftim/2)  
 finfo=h/7  
 root.wm_title("Counter 4 STRELE.LT")  
 root.configure(bg='black')  
 root.geometry('%dx%d+%d+%d' % (w, h, 0, 0))  
 tim=Label(root, text="Time", fg="gray5", bg="black", font=('Times', -ftim, 'bold'))  
 mod=Label(root, text="Mode", fg="gray5", bg="black", font=('Times', -finfo))  
 ind=Label(root, text="Index", fg="gray5", bg="black", font=('Times', -finfo))  
 ser=Label(root, text="Series", fg="gray5", bg="black", font=('Times', -finfo))  
 tim.place(x=0, y=ytim)  
 mod.place(x=0, y=0)  
 ser.place(x=w/3, y=0)  
 ind.place(x=w/3*2, y=0)

 # Disable powersaving
 os.popen('xset s off')
 os.popen('xset -dpms')
 os.popen('xset s noblank')

 #Autostart 
 power()  
 ok()  
 ok()  
 ok()  
 ok()  
 ok()  
 #start()  
 #gpio buttons check  
 root.after(10,ck_stop_button)  
 root.after(10,ck_start_button)  
 #gpio buttons check end  
 root.mainloop()  



Kadangi naudoju Banana Pi, o ne Raspbery Pi, gpio pinoutas šiek tiek skiriasi, todėl kad daug negalvot ir neskaityt dokumentacijos kalnų, porai mygtukų pinus radau taip: Prijungiau laidą prie GND pino, o poto prilietęs prie betkurio kito prasukdavau šitą kodą:
 #!/usr/bin/python 
 import RPi.GPIO as GPIO  
 GPIO.setmode(GPIO.BCM)  
 GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)  
 for i in range (0, 24):  
      GPIO.setup(i, GPIO.IN, pull_up_down=GPIO.PUD_UP)  
 for i in range (0, 24):  
      if (GPIO.input(i) == GPIO.LOW):  
           print "%s YESSS" % i  


Tada atjungęs prasukdavau kodą darsyk. Taip rasdavau skirtumą kuriuose pinuose krinta frontas. Galiausiai radau pasirinkau kombinaciją kur abipus GND yra kažkoks IO. Mano atveju pinai P12, P14 ir P16:


kur P12 atitinka IO18, o P16 - IO23.
Nežinau kodėl visur dokumentacijoj rodo, jog tai IO1 ir IO4, bet man mano skriptukas parodė ką kitą:


Taigi ant IO 18 pakabinau STOP mygtuką, o ant 23 START. Sumoje trys laidukai ir 12 eilučių kodo:
Visa kita liko po senovei:
Turbūt neveltui atsiranda tokie posakiai "bėda po vieną nevaikšto", "kur trunka ten plyšta", "žingsnis pirmyn, du atgal" ir t.t. Programuotojai pasiskolino Enšteino formule E=mc^2 ir pritaikė sau - Errors=more code^2. Taigi, kuo daugiau kodo tuo daugiau bėdų. Nors mano atveju gal šitas ir nelabai tiktų. Žodžiu, kai padarėm valdymą mygtukais per GPIO ir nebespaudinėjam distancinio, tas mūsų "bananas" pradėjo galvot kad jo niekas nebečiupinėja ir liūdnas po dešimties minučių nueidavo miegot. Nežinau kodėl, bet pažadint jį būvo galima tik nutraukus maitinimą. Šiek tiek pabrausinus radau sprendimą nes ne vienas entuziastas su tuo jau susidūrė ir maloniai pasidalino webe (http://crunchbang.org/forums/viewtopic.php?id=13990). Kadangi čia gerokai apkarpyta distribucija ir .xinitrc nesuveikė (nors turėjo) lengviausia pasirodė paleisti iš counter.py nes reik nustatymus sukišt jau startavusiai X sesijai:
 # Disable powersaving
 os.popen('xset s off')
 os.popen('xset -dpms')
 os.popen('xset s noblank') 

Kaip pagalvoji anoks čia stebuklas, tereikia mokėt šiek tiek programuot, truputį sysadmino žinių, networko pagrindų, geros/naudingos idėjos ir gabumų pamatyt sprendimo kelią apjungiant į vienumą komponentus iš skirtingų sferų.

Čia aš šiaip pamoralizavau, nes vakar gavau repliką daugmaž tokią:
- Ble jūs AjTyšnikai, nieko neveikiat ir tūkstančius gaunat! Už tokias babkes ir aš galėčiau dirbt tokį darbą. Svarbu ką nors protingo pasakyt kai paklausia... na ką nors krūčiau negu tiesiog: 'Spausk ENTER'. Tarkim... 'C6' spausk!... ir viskas, atrodai kietas, babkes gauni...

Net kažkuriuo momentu pasijutau kaltu!! Jofana...!

Nepasiūliau, tik namo parėjus dašilo, reikėjo pasakyt: "taigi va, kaip tik laisva vieta bus po savaitės, gali eit į mano poziciją. Bus proga pasakyt ar pašoliuot kaip arkliui c6-d8 arba c6-e7... spausk... varyk..."

Na ir velniop... Eina jie šikt... Neskaitau, kad jie nedirba, bet bent jau krintančią atsakomybę tegu palygina... Suerzino...