HobbyElectro

Petrescu Cristian . Un produs Blogger.

sâmbătă, 14 ianuarie 2017

Primii pasi cu Raspberry Pi (2) - GPIO

0 comentarii | Read more...
Salutare tuturor!

     In acest articol vom pune bazele lucrului cu GPIO-ul micutului computer numit Raspberry Pi. Daca nu ati parcurs articolul anterior va recomand sa o faceti acesand pagina de aici

     GPIO este o abreviere de la englezescul general purpose in-out. Cu alte cuvinte, pe langa pinii microprocesorului (si nu ai microcontroller-ului :) ) care asigura functii speciale, exista si un set de pini care ne sunt pusi la dispozitie si pe care putem sa ii programam dupa bunul plac. 

In functie de versiunea de Raspberry Pi pe care o detineti acesti pini sunt diferiti. Prin diferiti se intelege atat pozitionarea lor pe placa cat si functiile auxiliare pe care le indeplinesc. Pentru acest articol am folosit un Raspberry Pi V2 al carui header este urmatorul:


Daca detineti o alta versiune va recomand cu caldura sa accesati pagina aceasta.

ATENTIE: 


TENSIUNEA PE CARE O FURNIZEAZA UN PIN ESTE DE 3.3V, ATUNCI CAND ESTE CONFIGURAT CA SI PIN DE IESIRE. LA FEL SI IN CAZUL IN CARE ESTE CONFIGURAT CA PIN DE INTRARE: VALOAREA MAXIMA PE CARE O POATE "CITI" ESTE TOT DE 3.3V. O TENSIUNE MAI MARE SI... PLICI! 
IN CAZUL CURENTILOR, LUCRURILE SUNT UN PIC MAI COMPLICATE: CURENTUL TOTAL PE CARE IL POATE FURNIZA - PENTRU TOTI PINII - ESTE DE 50mA. CONSIDERAND CA FOLOSIM TOTI CEI 17 PINI DISPONIBILI, CURENTUL MAXIM/PIN ESTE DE 50/17=3mA. IN GENERAL, CA REGULA DE BAZA CURENTUL PER PIN TREBUIE SA FIE CAT MAI MIC CU PUTINTA!

Cum in articolul de fata ne vom juca cu leduri, consider ca este necesar sa explic un pic montajul:







     Asadar bargraph-ul contine 10 leduri. Conform datasheet-ului, caderea de tensiune pe fiecare led este de 2V. Din totalul de 3.3V mai raman 1.3V, caderea de tensiune pe fiecare rezistenta.Cunoscand valoarea unei rezistente (1000 ohmi) se poate calcula curentul consumat de fiecare led: 1.3/1000=1.3mA. Cum avem 10 leduri, atunci cand toate sunt aprinse, curentul maxim consumat de pe bara de 3.3V este de 13mA. Deci este OK.
     Intregul montaj a fost conceput pe un breadboard. Si sa nu uit, va recomand din tot sufletul sa cumparati un adaptor pentru breadboard la header-ul Raspberry Pi.



Programarea...

     In scop demonstrativ au fost realizate 4 programe, de la simplu la complex. Ce a iesit puteti vedea in clipul de mai jos:



     Inainte de a ne baga nasul in Python trebuie instalata libraria care ne ofera acces la GPIO. Pentru aceasta realizati o conexiune la Pi printr-un client SSH (Putty, MobaXterm) si dupa logare tastati urmatoarea coamanda:



sudo apt-get install rpi.gpio

Dupa instalarea librariei urmati urmatorii pasi:

  1. Porniti programul MobaXterm;
  2. Deschideti o sesiune SSH cu Raspberry Pi (vezi articol anterior);
  3. Deschideti tabul  Sftp;
  4. Creati un folder nou: GPIO_SCRIPTS;



Acum in interiorul folder-ului creati primul fisier python cu numele : GPIO_0.PY:




Click dreapta pe fisierul noucreat si alegeti deschiderea acestuia cu editorul incorporat in MobaXterm:



Primul program...

Dupa cum spuneam si in randurile de mai sus cele 4  programe sunt realizate de la simplu la complex. Primul program va "clipi" doua leduri pe rand la interval de o secunda. Listingul il gasiti mai jos:



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import RPi.GPIO as gp
import time
import os
os.system('clear')
print('Running...')
gp.setmode(gp.BCM)

pin1 =26
pin2=19

cnt=0;
gp.setup(pin1,gp.OUT)
gp.setup(pin2,gp.OUT) 

while(1):
  gp.output(pin1,1)
  gp.output(pin2,0)
  time.sleep(1)
  gp.output(pin1,0)
  gp.output(pin2,1)
  time.sleep(1)

Pentru cei care au experienta cu Arduino codul pare familiar: 

  • In linia 1 de cod se importa libraria GPIO;
  • Pentru a putea avea acces la delay-uri se importa modulul time;
  • In liniile 12 si 13  se seteaza directia pininilor, in cazul de fata este OUT
  • Incepand cu linia 15 se creaza bucla infinita care va "clipi" ledurile la interval de 1 secunda.
     Am lasat la urma explicatia pentru cea mai importanta linie de cod: linia cu numarul 6. Dupa cum spuneam si la inceputul articolului arnajarea pinilor pe placa este un pic confuza. Exista doua numerotari: numerotarea pinilor in ordinea plantarii acestora pe header (de la 1 la 40) si numerotarea in functie de terminalele microprocesorului, cea in care apare prefixul GPIO. Cand se importa modulul GPIO ambele optiuni pot fi luate in calcul.

Daca se doresete utilizarea pinilor in ordinea plantarii pe placa se va folosi instructiunea,

gp.setmode(gp.BOARD)

iar daca se doreste utilizarea pinilor in functie de numele pe care le au terminalele microprocesorului, se va utiliza instructiunea


gp.setmode(gp.BCM)

In cazul de fata, deoarece mi-a fost mult mai comod sa folosesc denumiriele deja gravate pe adaptorul de breadboard, am utilizat cea de-a doua varianta. Astfel, ca o ultima lamurire, in cazul de fata GPIO26 corespunde de fapt celui de-al 37-lea pin iar GPIO19 celui de-al 35-lea.

Mare atentie: alegeti intotdeauna varianta pentru care ati facut montajul deoarece exista posibilitatea (destul de mare) sa ardeti computerul.

Copiati codul de mai sus (fara numarul liniei de cod) si paste in editorul de text deschis. Salvati, dupa care in SSH tastati scuccesiv comenzile:


cd GPIO_SCRIPTS
sudo python3 GPIO_0.PY




Programul va rula. Nu uitati ca sunteti intr-o bucla infinita. Pentru a inchide programul tastati in acelasi timp CTRL+C.

Al doilea program...

Cel de-al doilea program este ceva mai complicat, dar nu foarte... Acesta va aprinde si va stinge ledurile succesiv, la interval de o secunda.
Urmand pasii de mai sus creati un al doilea fisier numit de data aceasta GPIO_1.PY. Si copiati listingul de mai jos:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import RPi.GPIO as gp
import time
gp.setmode(gp.BCM)

pins=[26,19,13,6,5,22,27,17,4,21]

cnt=0;
for i in pins:
 gp.setup(i,gp.OUT)
 gp.output(pins[cnt],False) 
 cnt=cnt+1
 
while(1):
 for i in range(0,10):
  gp.output(pins[i],True)
  time.sleep(1);
  
 for i in range(0,10):
  gp.output(pins[i],False)
  time.sleep(1); 

Rulati programul cu comanda:


sudo python3 GPIO_1.PY

Al treilea program...

     Daca pana acum "am fost martori" la ceea ce face Pi-ul, acum a sosit momentul sa ii trimitem comenzi. Programul de fata aprinde si stinge ledurile in functie de numarul acestora care a fost preluat de la tastatura. Nu voi explica prea mult programul  deoarece contine elemente proprii limbajului de programare Python3 lucru care nu face obiectul articolului de fata. Pentru un tutorial foarte bun in ceea ce priveste limbajul de programare mai sus mentionat va recomand cu caldura sa mergeti aici.

Urmati pasii anteriori si creati un fisier denumit GPIO_1.PY. Copiati si salvati listingul urmator:



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import RPi.GPIO as gp
import time
import os
from colorama import Fore, Back, Style

os.system('clear')

gp.setmode(gp.BCM)

pins=[26,19,13,6,5,22,27,17,4,21]
state=[0,0,0,0,0,0,0,0,0,0]
check=False
cnt=0;
for i in pins:
 gp.setup(i,gp.OUT)
 gp.output(pins[cnt],False) 
 cnt=cnt+1
def printLeds():
 print(Fore.YELLOW+"RASPBERRY PI SSH LED CONTROL")
 print(Back.BLACK+"",end='\n')
 for i in state:
  if i==1:
   print(Back.RED+' ',end='')
  else:
   print(Back.WHITE+' ',end='')
  print(Fore.WHITE+Back.BLACK+"|",end='') 
 print(Back.BLACK+"",end='\n')
 for i in range(0,10):
  print(Fore.GREEN+str(i),end='')
  print(Fore.WHITE+Back.BLACK+"|",end='')
 print(Back.BLACK+"",end='\n')

printLeds() 
while(1):
 print("")
 pin=input(Fore.GREEN+"Insert led number:")
 if pin.isnumeric():
  check=False
  k=int(pin)
  #check if it's a valid led number
  for i in range(0,10):
   if k==i:
    os.system('clear')
    print("")
    check=True;
    if state[i]==0:
     state[i]=1
     gp.output(pins[i],True)
    else:
     state[i]=0
     gp.output(pins[i],False)
    printLeds() 
  if check==False:
   print(Fore.RED+"No led number!")
 else:
  print(Fore.RED+"Insert a number in range 0-9")


Rulati programul cu urmatoarea comanda:




sudo python3 GPIO_2.PY



Dupa incarcare puteti comanda ledurile tastand numarul ledului (de la 0 la 9) iar ledul isi va schimba starea.




Al patrulea program...


     Programul de mai sus ne permite in sfarsit sa interactionam cu Raspberry Pi. Problema este ca nu putem citi starea curenta a ledurilor. Acest lucru este de dorit daca sunt mai multi utilizatori care vor sa comande ledurile. Urmatorul program rezolva (partial) problema. Starea ledurilor este salvata intr-un fisier. Acest lucru ne permite sa rulam mai multe instante ale programului si chiar daca sunt procese diferite toate vor imparti aceeasi resursa: fisierul text in care sunt salvate starile. Cum python nu ne permite (in mod direct) sa aflam daca un fisier este deschis sau nu, mecanismul prin care se incerca evitarea scrierii concomitente de catre doi sau mai multi utilizatori in fiser este... redenumirea fisierului. Ca si in cazul programului anterior va recomand sa urmati cat mai multe tutoriale Python3.

Fisierul se va numi "status", si va trebui sa se afle in acelasi folder ca si programul. Continutul initial al fisierului este urmatorul:


0,0,0,0,0,0,0,0,0,0

Dupa cum se observa, initial toate ledurile sunt stinse.

Cunoscand deja mecanismul vom crea al 4-lea (si ultimul fisier) cu denumirea GPIO_3.PY. Apoi vom copia codul din listingul de mai jos:



  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
import RPi.GPIO as gp
import time
import os
from colorama import Fore, Back, Style

os.system('clear')

gp.setmode(gp.BCM)

pins=[26,19,13,6,5,22,27,17,4,21]
state=[0,0,0,0,0,0,0,0,0,0]
check=False
cnt=0;
for i in pins:
 gp.setup(i,gp.OUT)
 gp.output(pins[cnt],False) 
 cnt=cnt+1
def printLeds():
 print(Back.BLACK+"",end='\n')
 for i in state:
  if i==1:
   print(Back.RED+' ',end='')
  else:
   print(Back.WHITE+' ',end='')
  print(Fore.WHITE+Back.BLACK+"|",end='') 
 print(Back.BLACK+"",end='\n')
 for i in range(0,10):
  print(Fore.GREEN+str(i),end='')
  print(Fore.WHITE+Back.BLACK+"|",end='')
 print(Back.BLACK+"",end='\n')

  
def renameFile():
 r=False
 while(r==False):
  try:
   os.rename('status','temp')
   r=True
  except IOError:
   r=False



def writeFile():
 renameFile()
 print(Fore.YELLOW+"RASPBERRY PI SSH LED CONTROL")
 print('Writing data...')
 try:
  temp=open('temp','r+')
  a=''
  for i in state:
   a=a+str(i)+',' 
  temp.write(a[0:len(a)-1])
  temp.close()
  os.rename('temp','status')
  print('Writing complete!')
 except IOError:
  print('File not found...')


def readFile():
 os.system('clear')
 renameFile()
 print(Fore.YELLOW+"RASPBERRY PI SSH LED CONTROL")
 print('Reading data...')
 try:
  temp=open('temp','r+')
  a=temp.readline().split(',')
  for i in range(0,10):
   state[i]=int(a[i])
   gp.output(pins[i],state[i]) 
  temp.close()
  os.rename('temp','status')
  print('Reading complete!') 
  printLeds()
 except IOError:
  print('File not found...')
  
readFile()

while(1):
 print("")
 pin=input(Fore.GREEN+"Insert led number or r to read status:")
 if pin.isnumeric():
  check=False
  k=int(pin)
  #check if it's a valid led number
  for i in range(0,10):
   if k==i:
    os.system('clear')
    print("")
    check=True;
    if state[i]==0:
     state[i]=1
     gp.output(pins[i],state[i])
    else:
     state[i]=0
     gp.output(pins[i],state[i])
    writeFile()  
    printLeds()
    break 
  if check==False:
   readFile()
   print(Fore.RED+"No such command...")
 elif pin=='r':
  readFile()
 else:
  readFile()
  print(Fore.RED+"No such command...")



Cam atat pentru azi. Fisierele cu codurile sursa se pot descarca de aici.

Sa auzim de bine !!!!

P.S. Nu va sfiiti sa lasati comentarii !!!

vineri, 6 ianuarie 2017

Primii pasi cu Raspberry Pi (1)

0 comentarii | Read more...
Preambul...

     Detin de ceva vreme un Raspberry Pi. Minunata jucarie ! Un computer cat un card de credit cu acces la GPIO-ul procesorului... Tot ceea ce nu este Arduino. Internetul geme de sute de mii de aplicatii care de care mai traznite: roboti, console de jocuri, mini laptop-uri, servere de... orice ! Ce mai lumea intreaga la picioare! Dar... Exista un DAR: LINUX ! Micutul computer ruleaza (si) Linux.      Pentru cineva care si-a petrecut intraga viata in compania Windows-ului Linux-ul nu este cel mai prietenos  sistem de operare. Acesta este si cazul meu. Cum intotdeauna sunt deschis catre lucruri noi, am zis sa incerc si eu Raspberry Pi-ul.


     Partea buna este aceea ca exista documentatie pentru orice. Daca la inceput copii comenzi, fara sa intelegi mare lucru din ce fac acestea incet, incet incepi sa te prinzi cum functioneaza si incepi sa te simti din ce in ce mai mult stapan pe situatie. 

     In articoul de azi nu voi prezenta decat instalarea sistemului de operare Raspbian si cateva trick-uri pentru a face un pic viata mai usoara celor care incearca sa programeze Pi-ul. Sa incepem...

Instalarea...

     In scurta mea experienta cu Raspberry Pi am ajuns la concluzia ca este mult mai simplu sa comanzi Pi-ul prin intermediul unui client SSH, sa ii accesezi interfata grafica prin intermediul unui client VNC si sa manipulezi fisierele stocate direct din reteaua locala. La sfarsitul acestui articol veti avea si voi toate acestea instalate, urmad ca in articolele urmatoare sa ajungem la fructul dulce numit GPIO :).

1. Instalare Raspbian.

Pentru aceasta parte aveti nevoie de urmatoarele resurse hardware: 
  • Raspberry Pi cu alimentator 5V/1A:)
  • Televizor/monitor cu port HDMI;
  • Cablu HDMI;
  • Tastatura si mouse conectate la Raspberry Pi;
  • Card microSd de minim 8Gb;
  • Dongle Wi-Fi conectat la Raspberry Pi.
     Mergeti   aici si descarcati NOOBS. Dupa download dezarhivati arhiva intr-un folder oarecare. Pregatiti cardul microSD introducand-ul cu ajutorul unui adaptor intr-un port USB.
Acum va trebui formatat cardul. Pentru formatare se utilizeaza programul SDFormatter. Programul se poate descarca de aici. Lansati programul si formatati cardul:


     Dupa formatare copiati continutul folderului in care ati dezarhivat NOOBS direct in radacina cardului SD. Daca toate dispozitivele periferice (mouse, tastatura, cablu HDMI, dongle Wi-Fi) sunt conecate puteti alimenta Raspberry-ul. In acest moment incepe instalarea sistemului de operare:


Pentru a instala sistemul de operare tot ceea ce aveti de facut este sa apasati pe Install si sa astepati.

O data instalarea terminata urmatorul pas este sa adaugam Raspeberry-ul in reteaua locala si sa ii oferim acces la internet:






     Dupa ce ne-am conectat la reteaua locala urmatorul pas este acela de a afla adresa IP a Raspberry-ului. Pentru aceasta deschideti un terminal nou si tastati 


ifconfig




Cautati sectiunea wlan0 si notati IP-ul din dreptul inet addr. 

Din acest moment nu veti mai avea nevoie de HDMI, tastatura si mouse, totul se va face prin magia TCP/IP-ului.


2. SSH...

     SSH este acronimul pentru Secure SHell si reprezinta un protocol de retea criptat. In cazul de fata vom folosi SSH-ul pentru a transmite comenzi remote Raspberry-ului. Pentru aceasta trebuie instalat Putty. Descaracrea se poate face de aici. Dupa instalare rulam Putty.exe:


In caseta HostName se introduce adresa IP a Raspberry-ului. Click pe Open si ne va intampina urmatoarea fereastra:



Click Yes, pentru a putea comunica cu Pi. Mai departe ne sunt cerute datele de autentificare. Datele implicite sunt:


user: pi                

password: raspberry



Daca totul a decurs corect ar trebui sa primiti urmatorul mesaj:



2. VNC...

     Cand am zis ca tastatura, mouse-ul si HDMI-ul nu ne mai sunt utile nu am vrut sa spun ca vom renunta definitiv la interfata grafica a Raspbian-ului. Exista posibilitatea de a rula interfata grafica a Raspbianului utilizand un VNC(Virtual Network Computing). Pentru aceasta este necesar a se instala doua programe distincte: un client si un server. Clientul (RealVnc) se va instala pe Windows si server-ul (tightvnc) pe Raspberry Pi. RealVnc se poate descarca de aici. Pentru partea de server se vor urma pasii:


  • Se deschide Putty si se realizeaza o conexiune la Raspberry Pi;


  • Dupa autenficare se scrie urmatoarea comanda:

sudo apt-get install tightvncserver  


  • Tastati y si astepati ca instalarea sa se termine.
Dupa instalare trebuie pornit serverul VNC. Pornirea se realizeaza cu urmatoarea comanda:


tightvncserver


     Inainte de pornire vi se va cere sa introduceti o parola de maximum 8 caractere. Notati aceasta parola deoarece va fi necesara pentru autentificare.



Mai este un singur pas pana cand server-ul sa devina perfect functional. Va trebui sa cream un script prin care sa pastram setarile de rezolutie si de adancime de culoare. Pentru aceasta vor trebui rulate urmatoarele comenzi:



nano vnc.sh  

Comanda de mai sus va crea si va deschide in editorul de text numit "nano" fisierul vnc cu extensia .sh. In acest fisier vor fi scrise seatarile mai sus mentionate.





#!/bin/sh
vncserver :1 -geometry 1280x1024 -depth 24 -dpi 96



Dupa editare apasati simultan "CTRL+X" pentru inchidere si apoi "y" pentru salvare. Frumusetea Linux-ului este ca orice fisier poate fi executabil, asadar dupa logare  putem porni server-ul cu setarile mai sus mentionate. Pentru a face acest lucru posibil se introduce urmatoare comanda:



sudo chmod +x vnc.sh



Acum ori de cate ori doriti sa porniti server-ul tot ce aveti de facut este sa tastati in terminal comanda:


./vnc.sh

Acum dupa toata bataia asta de cap haideti sa vedem un mic filmulet cu VNC-ul in actiune:





3. Accesarea fisierelor...

Cand am inceput sa scriu tutorialul de fata m-am gandit sa instalez pe Pi un server Samba. Datorita faptului ca instalarea este greoaie si pe alocuri frustranta am incercat sa gasesc "workaround-uri" si am gasit MobaXterm. Varianta gratis ne permite sa facem browsing prin SFTP si unde mai pui ca este si client de SSH. Nu sunt prea multe de explicat aici. In filmultetul de mai jos am creat un fisier python direct in Raspberry dupa care l-am rulat  din SSH:





Cam atat pentru articolul de azi. Poate a fost un pic cam sec dar credeti-ma a fost absolut necesar. In articolele urmatoare ne vom juca si cu GPIO-ul.

Sa auzim de bine!

Totalul afișărilor de pagină

Despre

Blog cu si despre electronica !