Sistem Mobil Comandat Prin Raspberry Pi
Sistem mobil comandat prin Raspberry Pi
Capitolul 1
Introducere
Sisteme de calcul
Sistemul de calcul este o mașină de prelucrat date și informații conform unei liste de instrucțiuni numită program. Un sistem de calcul este un dispozitiv de uz general, care poate fi programat pentru a efectua o serie de operații aritmetice sau logice automat. Din moment ce o secvență de operații poate fi schimbată ușor, computerul poate rezolva mai mult de un tip de probleme. În prezent calculatoarele se construiesc din componente electronice și de aceea cuvântul calculator înseamnă defapt calculator electronic. Calculatoarele ce sunt progrmabile liber și pot prelucra în principiu orice fel de informații sau date, se numesc calculatoare universale. Sistemele de calcul nu sunt doar mașini de prelucrat date și informații, ci și dispozitive care facilitează comunicația intre utilizatori sub diferite forme cum ar fi text, video, audio sau multimedia. [1]
Convențional, un calculator este compus din cel puțin un element de procesare, de obicei o unitate de procesare centrală (CPU), și o formă de memorie. Elementul de procesare efectuează operațiile aritmetice și logice. Dispozitivele periferice permit ca informațiile să fie primite de la o sursă externă, iar rezultatul operațiunilor să salvat și retransmis dacă este nevoie. [1]
Știința prelucrării informațiilor cu ajutorul calculatoarelor se numește informatică (engleză Computer Science). Tehnologia necesară pentru folosirea lor poartă numele Tehnologia Informației, prescurtat TI sau IT (de la termenul englezesc Information Technology). [1]
Microcontrolere
Un microcontroller este un circuit electronic care integrează un microprocesor și alte dispozitive periferice într-o singură capsulă astfel reducând costul necesar producerii unui asemenea microsistem, cât și energia electrică consumată de acesta. Principala diferența dintre un microcontroller (µC) și un microprocesor (µP) o constituie faptul că un microcontroller integrează memoria de program, memoria de date și alte interfețe de intrare / ieșire sau periferice într-un singur chip iar un microprocesor comunică cu acestea folosind magistrale de date și adrese. [2]
Din cauza integrării unui număr mare de periferice și a costului redus de producție, un microcontroller operează la viteze reduse, din gama zecilor sau sutelor de MHz. Aceasta este cu un ordin de mărime mai mică decât frecvență a unui microprocesor. Cu toate acestea, microcontrollerele se pretează la o gamă variată de aplicații fiind folosite atât în mediul industrial cât și în produse de larg consum, de la sisteme din industria aerospațială până la telefoane mobile, produse electrocaznice, și electronică auto. [2]
Majoritatea microcontroller-elor nu au o magistrală externă de adrese sau date deoarece toate memoriile de date sunt interne. Acest lucru duce la integrarea acestora în capsule cu un număr relativ mic de pini și reduse ca dimensiuni, oferind avantajul unui cost de producție redus. [2]
Cele mai întâlnite structuri din circuitul integrat al unui microcontroller sunt următoarele:
Unitatea centrală de procesare (nucleul – procesorul) cu o arhitectură care poate fi pe 8, 16, 32 sau 64 de biți.
Memorie de date volatilă (RAM) sau nevolatilă folosită pentru date sau programe (Flash sau EEPROM)
Porturi digitale de intrare-iesire (I/O)
Interfețe seriale (RS232, SPI, I2C, CAN, RS485)
Timere, generatoare de PWM sau watchdog
Convertoare analog-digitale
Suport pentru programare și depanare (Debugging) (ISP)
Raspberry Pi
Raspberry Pi este un SBC (Single-Board Computer) de dimensiunile unui card de credit, care poate fi utilizat conectat la un monitor sau un televizor folosind o tatstatură și un mouse standard. Este produs în Marea Britanie de către Raspberry Pi Foundation cu scopul de a promova învățarea noțiunilor de bază din domeniul informaticii în școli. Este un dispozitiv mic, capabil care permite oamenilor de toate vârstele sa exploreze mediul virtual si sa programeze in lombaje precum Scratch sau Python. Are capabilitatea de a îndeplini sarcini asemănătoare cu cele ale unui computer Desktop, de a naviga pe internet, redarea clipurilor video de înaltă definiție, de a realiza foi de calcul, procesare a cuvintelor si chiar mici jocuri. Mai mult, Raspberry Pi are capacitatea de a interacționa cu lumea exterioară și este folosit într-o gamă foarte mare de proiecte in diferite domenii. [3]
Ideea din spatele unui calculator de dimensiuni mici și accesibil din punct de vedere financiar a venit in 2006 cand Eben Upton, Rob Mullins, Jack Lang și Alan Mycroft, colegi la Universitatea Cambridge , au devenit preocupați de numărul din ce in ce mai mic de studenți care participă și sunt interesați de cursurile din domeniul informaticii. De la o situație din anii 1990 în care majoritatea celor care se prezentau la cursuri erau faceau programarea ca un hobby, in anii 2000 peisajul era foarte diferit, în sensul că un solicitant tipic poate doar a realizat un mic web design. [3,4]
La încept, conceptele incipiente ale Raspberry Pi erau bazate pe un microcontroler Atmel ATmega644. Dispunerea PCB-ului și schema electronică sunt disponibile pentru descărcare. Computerul a fost inspirat din BBC Micro lansat de Acorn în 1981. Primul prototip de computer bazat pe un procesor ARM a fost ambalat într-o carcasă de dimensiunea unui stick USB de memorie. Avea la un capăt un port USB și la capătul celălalt un port HDMI. [3,4]
In 2008, procesoarele proiectate pentru dispozitivele mobile au devenit mult mai accesibile, și suficient de puternice pentru a oferi o procesare multimedia la un nivel bun, aceasta fiind o caracteristică ideala pentru a face placa artactivă și pentru persoanele care nu voiau neapărat un dispozitiv pur orientat programării. Deci proiectul a inceput sa pară cu timpul destul de realizabil. Eben (chip Architect la Broadcom), Rob, Jack și Alan au făcut o echipă cu Pete Lomas și David Braben au pus bazele fundației Raspberry Pi. Trei ani mai târziu a intrat în producție în masă modelul Raspberry Pi B sub licența Element14/Premier Farnell si Rs Electronics, in doi ani fiind vândute peste 2 milioane de unități. [3,4]
Datorită prețului extrem de redus pentru un sistem asemănător unui calculator în toată regula Raspberry Pi a devenit enorm de popular și in afara mediului academic. Are un procesor ARM de 700 mhz, 512mb RAM si o placă video capabilă să redea filme în format 1080p.Un alt avantaj e acela că poate fi conectat în rețea și accesat prin SSH (fără să mai necesite mouse și tastatură) și poate fi utilizat ca server în toată regula, un server de dimensiunea unui card de credit. Dupa cum am spus anterior Raspberry Pi poate fi uitlizat într-o gamaă foarte largă de aplicatii, având și pini de port paralel sau serial în care se pot conecta anumiți senzori și alte dispozitive cum ar fi camere video și ecrane LCD. Placa poate fi transformata și într-un sistem Media Box datorită capacitații de a reda video 1080p, sau poate fi utilizat ca un sistem de alarmă, prin adăugarea unui senzor de mișcare, sau orice alt sistem inteligent, numarul aplicațiilor fiind limitat doar de imaginația utilizatorului. O configurare a unui astfel de microcalculator se poate observa din figura urmatoare. [3,4]
Fig. 1.1 Accesoriile unui Raspberry Pi. [6]
După cum se poate observa din Figura 1.1 sistemul Raspberry are nevoie de sistemul de operare linux, sistem despre care vom vorbi la punctul urmator
Linux și Raspberry Pi
Linux este o familie de sisteme de operare de tip Unix care folosesc Nucleul Linux (în engleză kernel). Linux poate fi instalat pe o varietate largă de hardware, începând cu telefoane mobile, tablete, console video, continuând cu calculatoare personale până la supercomputere. Linux este cunoscut în principal pentru utilizarea sa ca server, în 2009 i se estima o cotă de piață între 20-40%. Cota de piață de desktop este estimată între 1-2% și 4.8%.În ultimii ani, Linux a început să devină tot mai popular atât datorită unor distribuții precum Ubuntu, openSUSE, Fedora, precum și datorită apariției netbook-urilor și a noii generații de telefoane inteligente (în engleză smart phone) care rulează o versiune embedded de Linux. [5]
Uneori mai este întâlnit sub numele de GNU/Linux și este cel mai cunoscut exemplu de colaborare și dezvoltare Software liber sub licență GPL (General Public License- licență software a Fundației pentru Software Liber). [5]
Termenul Linux se referă și la nucleul Linux, însă în mod uzual este folosit pentru a descrie întregul sistem de operare pentru calculatoare, compus din nucleul Linux, biblioteci software și diverse unelte. O "distribuție Linux" adaugă acestor componente de bază o mare cantitate de programe, organizate în „pachete”. Folosirea termenului „Linux” pentru întreg sistemul, deși foarte răspândită, este contestată de către Richard Stallman și Free Software Foundation(autorii Proiectului GNU, ale cărui produse sunt incluse în cea mai mare parte din distribuțiile Linux). Aceștia propun utilizarea termenului GNU/Linux ("GNU și Linux") sau GNU+Linux ("GNU plus Linux"). [5]
Inițial dezvoltat și utilizat de către programatori voluntari, Linux a câștigat suportul industriei IT și al marilor companii ca IBM, Hewlett-Packard, Dell, Sun Microsystems, Google, Novell sau Nokia, și a depășit ca folosire versiunile proprietare de Unix. Analiștii atribuie succesul sistemului faptului că este independent de furnizor, implementarea are un cost scăzut, iar securitatea și fiabilitatea sistemului sunt considerate de către specialiști drept foarte bune. [5]
Dezvoltarea sistemului a fost începută de către inginerul finlandez Linus Torvalds, care inițial dorea să obțină un sistem similar cu Minix, dar fără limitările acestuia. Linux a fost dezvoltat sub Licența Publică Generală GNU GPL, astfel încât nu numai Linux însuși, dar și codul său sursă sunt disponibile tuturor celor interesați. [5]
Nucleul (kernel-ul) Linux este unul monolitic in care întregul nucleu se rulează în spațiul nucleului și în mod administrator. Cu toate acestea, spre deosebire de multe alte nuclee monolitice, driver-ii se pot încărca în memoria de lucru la utilizare, și se pot șterge de acolo ulterior, eliberând resursele utilizate, fără a necesita resetarea sistemului sau recompilarea nucleului. Facilitățile oferite de nucleu includ, printre altele: [5]
multitasking real și complet,
suport pentru memorie virtuală,
distribuția executabilelor la scriere,
management avansat al memoriei,
suport avansat pentru TCP/IP (inclusiv rutare și filtrare),
până la un miliard de procese simultane,
sistem de sunet modularizat (OSS sau ALSA).
Nucleul este scris integral în C și poate fi compilat folosind compilatorul GCC.
Sistemele Linux includ nucleul, bibliotecile de sistem, bibliotecile de dezvoltare și un număr (de obicei destul de ridicat) de programe utilitare și aplicații, servere grafice (X), sisteme de ferestre si managere de desktop-uri (KDE, Gnome, Blackbox, Fluxbox, Xfce etc.), browsere web (Firefox, Lynx, Konqueror), aplicații și suite de aplicații „de birou” (OpenOffice.org), software de prelucrare grafică (Gimp), software de configurare, servere de web etc. Instalarea programelor noi se poate face fie prin compilare directă, fie prin intermediul pachetelor, care verifică existența și disponibilitatea altor programe necesare pe sistem înainte de a instala noul program. Managerele de pachete moderne asigură descărcarea pachetelor lipsă necesare (dacă este cazul) și instalarea lor automată „dintr-un clic”. Sistemele moderne Linux au atât capacități multimedia avansate, (grafică 3D accelerată hardware, sunet surround, suport pentru tehnologie bluetooth etc.), cât și suport pentru hardware mai vechi, fiind adaptabile și scalabile în funcție de necesități. [5]
Sistemele de operare bazate pe Linux sunt disponibile în general sub formă de "distribuții" (denumite mai rar și "arome"). Unele dintre acestea sunt orientate spre utilizatorul particular, altele către servere sau către utilizatorii cu calculatoare mai vechi. Câteva din cele mai folosite distribuții de Linux sunt: [5]
Ubuntu, un proiect orientat spre utilizatorul obișnuit bazat pe Debian GNU/Linux, care a câștigat o mare popularitate prin faptul că este ușor de utilizat și configurat, fiind în același timp puternic și stabil. Distribuții înrudite:Kubuntu (folosește KDE), Xubuntu (folosește Xfce), Edubuntu (orientat spre aplicații pentru educație). În prezent, Ubuntu este cea mai populară distribuție Linux.
Fedora (distribuție Linux) – născută din proiectul Red Hat Linux, dar conținând exclusiv software liber și disponibil gratuit de pe Internet. [5]
Debian GNU/Linux, una din distribuțiile cele mai cuprinzătoare din Internet, conținând un număr uriaș de pachete. Creatorii proiectului au dezvoltat managerul de pachete APT și al pachetele DEB. După cum știm sistemulde operare de pe care este folosit de plăcile Raspberry Pi are la bază sistemul Debian[5]
Knoppix, o distribuție „live” care rulează direct de pe CD sau DVD, fără a instala nimic pe discul dur, ce poate fi utilizată, printre altele, în călătorii, demonstrații sau pentru diagnosticări de sistem, reparări, recuperări de date etc.
Capitolul 2
Proiectarea robotului
La realizarea unui robot inteligent pot fi luate in calcul o mulțime de variante, deoarece sunt atâtea oportunități de a configura o astfel de mașina. Faza de proiectare a robotului trebuie să iți dea oportunitatea de a căpăta experiență atât in domeniul hardware cât și in software. Aceste lucruri oferă proiectatntului sau inginerului sa folosească componentele potrivite si configurația potrivită pentru a creea un robot unicat care să fie potrivit pentru cerintele de proiectare. [7]
Ca platformă pentru suportul robotului s-a ales kit-ul digilent RSK (Robotic Starter Kit), aceasta fiind o platformă ideala pentru alpicațiile robotice. Aceasta poate fi controlată atât prin intermediul porduselor puse la dispoziție ce către compania Digilent dar și alte controlere sau plăci de dezvoltare precum Raspberry Pi. A fost aleasă această platformă datorită compatibilității ei cu majoritatea controlerelor dar și proprietății ei de reutilizare in cadrul altor proiecte și aplicații. [7]
2.1 Cerințe de proiectare.
Înaintea începerii oricărui proiect trebuie să se știe cu exactitate ce trebuie realizat. Acest luru poate parea destul de evident în primă fază, dar transpunerea ideilor într-o specificație scrisă poate ajuta la luarea deciziilor in fazele ulterioare. Cerințele de proiectare ar trebui să descrie obiectivele proiectului nu componentele si dispozitivele care vor fi folosite. Chiar dacă ideea de proiectare este una relevantă, in momentul dispunerii specificațiilor într-o listă, pot aparea idei noi și in acest mod proiectul care trebuie realizat va fi unul optimizat. La acest stadiu nu trebuie inclusă proiectarea software, deoarece aceasta va fi realizată mai târziu in cadrul proiectului. [7]
Fluxul de informație care va fi inclus în cerințele de proiectare depinde foarte mult de complexitatea proiectului, și de cine va fi beneficiarul acestuia. Dacă este doar un simplu proiect ralizat din plăcere, cerințele de proiectare pot fi pe scurt și concise, dar dacă este nevoie de sponsorizarea cuiva, sau va fi nevoie ca acesta sa fie introduse in documentația unui proiect școlar sau proiect de diplomă, cerințele de proiectare trebuie să fie mult mai detaliate. În acest proiect este prezentat unul din varietatea de moduri în care se pot realiza cerințele de proiectare. S-a început cu o scurtă prezentare a cerințelor proiectului, apoi se pune la dispoziția proiectantului o lista de cereri și obiective. În unele cazuri s-a permis o oarecare libertate în alegerea componentelor, ca de exemplu în loc de alegerea unui model specific de senzor sau motoare, s-a lăsat la alegerea proiectantului să ia aceste decizii, dar anumite cerințe au rămas fixe cum ar fi utilizarea obligatorie a sistemului Raspberry Pi sau
încadrarea într-o anumită sumă de bani . [7]
2.2 Obiective.
Obiectivul proiectului este acela de a realiza un vehicul robotic independent, autonom care să poată evita obiectele care sunt in calea sa in momentul deplasării. Acest proiect trebuie să scoată în evidență principiile și tehnologiile incluse în acesta. Vehicolul robotic trebuie să fie relativ ieftin și ușor de realizat pentru ca anterior să poată fi ușor de replicat de studenți. [7]
Proiectul trebuie sa fie ușor de realizat folosind unelte prezente pe un stand de lucru clasic.
Vehicolul trebuie să se deplazeze in interiorul unei încăperi pe o suprafață plană fără să se lovească de obstacolele din jurul său.
Oferirea unei posibilități de conectare si control al vehicolului de pe calculator
Costul maxim sub 150 euro (din care se exclud bateriile)
Proiectul trebuie să ofere o anumită flexibilitate în adăugarea de componente și dispozitive adiționale.
Vehicolul robotic trebuie sa fie autonom
Comunicația cu mediul exterior trebuie să fie wireless pentru a nu fi nevoie de atașarea unor cabluri suplimentare vehicolului.
Vehicolul trebuie să aibă dimensiuni relativ mici pentru a putea fi luat la evenimente pentru a face demonstrații.
2. 3 Alegerea componentelor principale.
După cum se precizează mai sus in cerințele de proiectare nu ne sunt indicate unelte obligatorii pe care le putem folosi ci doar unelte care se pot regăsi pe un stand de lucru obișnuit, astfel ca în alegerea componentelor trebuie luat în calcul și acest aspect. Ca un exemplu cu uneltele necesare platforma robotică poate fi confecționată și cu un 3D printer o unealtă care devine din ce în ce mai populară dar cu siguranță nu se găsește pe orice stand obișnuit de lucru. [7]
Ca platformă robotică pentru a nu necesita multe unelte pentru ansamblare si datorită compatibilității cu majoritatea controlerelor s-a ales kit-ul Digilent RSK (Robotic Starter Kit), iar ca unitate de control se va folosi sistemul Raspberry Pi. [7]
Înainte de finalizarea proiectării este indicat să se găsească și alternative pentru componente. De exemplu o bună alternativă pentru platforma robotică a proiectului este de exemplu Magician Robot Chassis. De exemplu alte alternative pentru șasiul robotului nu se puteau încadra în cerințele proiectului (adică se putea depăși limita maximă de cost a intregului proiect). De altfel putea fi luat în considerare și placa de dezvoltare Arduino în detrimentul Raspberry Pi, dar și în acest fel se adăuga un cost suplimentar iar programarea unui Raspberry Pi este în general considerată mai laândemână decât cea a unui Arduino. [7]
După ce s-a luat decizia componentelor principale o altă decizie importantă este ce metodă de comunicație wireless ar fi mai optim să fie utilizată. În acest caz se poate folosi ori un adaptor Wi-Fi ori un modul Bluetooth. Niciunul din aceste două metode nu este oferit în fază inițială de către Raspberry Pi, dar pot fi adăugate cu ușurință datorita compatibilității sistemului. Pentru o calitate mai bună a comunicației și pentru o conectare mai viabilă s-a folosit un adaptor Wi-Fi. [7]
Adaptorul ales petnru conunicația wireless este un adaptor Asus USB-N10 datorită dimensiunilor mici, costului redus si performanței superioare pe care o oferă. Folosește o antenă de calitate superioară de tip MIFA pentru a permite streaming HD de calitate bună si o acoperire wireless extinsă. De asemenea, pe langa faptul ca interfața 802.11n oferă o lațime de bandă și acoperire suficientă, este compatibil cu tehnologiile anterioare implementate in rețelele 11g si 11b. Un alt avantaj al acestui adaptor este acela că oferă conectare rapidă la rețelele wireless indiferent de platforma sistemului de operare. Este compatibil cu majoritatea sistemelor de operare, inclusiv Windows, Linux, Mac. Mai multe detalii despre configurarea acestui adaptor se vor discuta ulterior în cadrul proiectului. [7, 10]
Kit-ul Digilent RSK (Robotic Starter Kit)
Este o platformă ideeală pentru aplicațiile robotice. Acest tip de șasiu este conceput în special pentru a fi folosit împreună cu produsele puse la dispoziție de catre compania Digilent, adică este compatibilă cu gama foarte largă de module periferice(Pmod), astfel putând fi realizate o varietate foarte mare de aplicații cu aceasta. Pentru acest proiect a fost ales acest tip de șasiu datorită calității pe care acesta o are, nu doar din punctul de vedere al materialelor folosite (platforma fiind metalică) ci și datorită motoarelor și controlerelor de motoare incluse în acest pachet. . [7, 9]
Părțile componente ale acestui pachet de șasiu sunt:
Platforma din metal dur cu găuri de 1,27mm
Două motoare cu raportul 1/19 cu cutie de viteze (reductor) cu senzori de trurație
Doua module periferice PMOD HB5 2A și cleme de prindere
Roți din plastic
Suport din metal pentru motoare
Suport baterie și toate componentele necesare pentru asamblare.
După respectarea fiecărui pas din documentația de asamblare a pachetului, platforma robotică va arăta ca în imaginea următoare.
Fig. 2.1. Pachetul Digilent RSK (Robotic Starter Kit)
Despre particularitățile modulelor periferice Pmod HB3 sau HB5 si despre controlul motoarelor se va face referire ulterior in cadrul proiectului.
Raspberry Pi Modelul B +
Este varianta finală a modelului original Raspberry Pi. A înlocuit modelul B in iulie 2014 și a fost inlocuită de Raspberry Pi 2 Modelul B in februarie 2015. În comparație cu modelul inițial B are următoarele plusuri: . [7, 8]
Mai multe porturi GPIO. Conectorul cu pini a crescut de la 26 la 40 de pini în comparație cu modelele A și B.
Mai multe porturi USB. Spre deosebire de modelele anterioare care aveau două modelul B+ are patru porturi USB si un comportament mult mai bun comportament la supracurent.
Cardul este Micro SD
Consum mic de energie
O mai bună dispunere a conectorilor pentru periferice, deoarece variantele anterioare nu excelau la acest aspect.
Raspberry Pi B+ dispune de chip-ul BCM2835 care include procesorul ARM1176JZF cu frecvența ceasului de 700MHz (cu posibilitate de overcloking până la frecvența de 1GHz dar cu radiator suplimentar pentru răcire) și o placă video cu două nuclee care poate reda videoclipuri cu o calitate de până la 1080p. Memoria este una de tipul SDRAM de 512MB, iar ca suport de stocare a datelor se poate folosi un card Micro SD, pe care se rulează sistemul de operare Raspbian (Linux Debian) personalizat de către Raspberry. [7, 8]
BCM2835 ARM
Perifericele microprocesorului BCM2835
Timere
Controller de întreruperi
GPIO
USB
PCM/I2C
Controler DMA
Interfețe prin intermediul GPIO
I2C
SPI0/1
PWM
UART
Fig. 2.2 Dispunerea pinilor de ieșire din Raspberry Pi [7, 8]
GPIO
GPIO(General-Purpose Input/Output) sunt pini generic ai unui circuit al căror comportament, indifferent că sunt configurați ca pini de intrare sau de ieșire poate fi controlat de către utilizator în momentul utilizării. Pinii GPIO nu au initial o utilitate predefinită, deci în mod implicit aceștia sunt definiți unused (neutilizat). [7, 8]
Raspberry Pi modelul B+ dispune de un conector de 40 de pini dispuși pe două rânduri de câte 20 de pini la distanța de 2,54 mm din care 17 sunt GPIO (de uz general), ceilalți fiind atât pini de alimentare 3,3V și 5V plus conectorii de masă (GND) cât și pini pe care se poate realiza comunicații seriale I2C, UART, SPI. [7, 8]
De reținut faptul că deși placa dispune de pini de alimentare de 5V, nivelul de tensiune de 1 logic pentru Raspberry Pi este de 3,3V, iar în cazul aplicării unei tensiuni mai mari pe acești pini se va ajunge la distrugerea pinului pe care s-a aplicat tensiune mai mare sau chiar distrugerea chip-ului BCM2835 deoarece nu există protective la supra-tensiuni. [7, 8]
După cum se observă din figura 4.32 implicit doar anumiți pini sunt pentru funcții special cum ar fi SPI, I2C sau UART, dar pe acest dispozitiv majoritatea pinilor pot fi reconfigurați pentru a îndeplini aceste funcții. [7, 8]
În nucleul official nu există posibilitatea folosirii întreruperilor pentru GPIO, dar totuși există un pachet care face posibil acest lucru prin recompilarea codului sursă al nucleului. În sistemul Raspbian care este versiunea recomandată pentru Raspberry Pi este posibilă folosirea întreruperilor prin intermediul GPIO. Întreruperile la nivelul GPIO pot fi pe toate fronturile semnalului cât și pe nivel de High și Low high/low/raise/fall/change. [7, 8]
În multe aplicații este nevoie de introducerea unui rezistor de Pull-Up/Down, de exemplu pentru citirea unui buton. Pinii de uz general de pe dispozitivul Raspberry Pi pot fi configurați în acest mod. Valoarea rezistorului de Pull-Up/Down poate fi echivalată cu cea a unui rezistor real de 50kΩ. [7, 8]
Capitolul 3
Proiectare Hardware
Componentele folosite la realizarea robotului:
Robotic Starter Kyt (platforma robotului care include șasiul, modulele periferice Pmhod HB5 și motoarele cu reductor de 12V 2A )
Raspberry Pi – Modelul B+
Senzor cu ultrasunete – HC-SR04
Servomotor – Futaba S3003
Shield (interfață Raspberry – Restul componentelor)
Adaptor USB (pentru comandă Wireless)
3.1 Senzorul cu ultrasunete HC-SR04
Funcționează pe principiul sonarului pentru a aprecia distanța intre el și un obstacol. Oferă o precizie de măsurare mare până la 3mm între 2cm și 400cm. Modulul cuprinde atât transmițătorul (care emite semnalul Trigger) cât și receptorul (care recepționează semnalul transmis care poartă numele de Echo) . [11]
Modulul dispune de 4 pini:
1. Vcc – Tensiunea de alimentare +5,0V;
2. Trig – Pinul pe care se comandă transmiterea semnalului;
3. Echo – Pinul de pe care se face citirea recepționării Ecoului (+5,0V)
4. Gnd – Reprezintă pinul pe care se realizează conectarea modulului la masa circuitului.
După cum știm modulul HC-SR04 generează semnal pe pinul Echo cu valoarea amplitudinii egală cu 5,0V, iar pinii de intrare ai plăcii Raspberry Pi nu suportă tensiuni mai mari de 3,3V, astfel vom fi nevoiți să realizăm un divizor de tensiune pentru a aduce tensiunea generată pe pinul Echo la o valoare pe care o poate citi Raspberry. [11]
După cum se precizează în documentația componentei pentru a utiliza senzorul cu ultrasunete HC-SR04 este nevoie de 4 pini (2 de alimentare 2 de port paralel) interconectarea acestora este prezentată în figura 3.1.
Alocarea pinilor :
Vcc – Pinul fizic 4
Trig – Pinul fizic 38
Echo – Pinul fizic 40
Gnd – GND
Fig. 3.1. Conectarea Senzorului cu ultrasunete HC-SR04
Modul de funcționare al acestui sensor se va prezenta în ineriorul capitolului Proiectare Software.
3.2 Servomotorul Futaba S3003
Este un servomotor standard, ușor de utilizat și fiabil pentru aplicațiile ce necesită o asemenea componentă. În cadrul proiectului s-a folosit un servomotor pentru a centra senzorul cu ultrasunete HC-SR04 pe anumite direcții prestabilite in vederea obținerii unei arii cât mai mari de acoperire pentru acest tip de senzor. Folosind un servomotor nu mai este nevoie de utilizarea mai multor senzori HC-SR04, în cazul de față pentru a acoperi toată aria pe care servomotorul baleează senzorul erau necesari cinci senzori. În acest mod se scade și costul aplicației, iar numărul de porturi paralele necesare este de doar 3 (2 pentru HC-SR04 și unul care suportă PWM pentru Servomotor) în comparație cu un număr de 10 porturi GPIO necesare pentru cinci senzori HC-SR04. [12]
Servomotorul FutabaS3003 are o greutate de 37g, poate fi conectat atât la o sursă de alimentare ce generează 4.8V, puterea pe care o oferă la această tensiune fiind de 3.17 kg/cm și o viteză de 0.23sec/60, cât și la 6.0V cu o putere de 4.10kg/cm și o viteză de 0.19sec/60 ̊.
Pentru a controla servomotorul trebuie generat un semal cu modulație a lațimii impulsului (PWM), cu o perioadă de 25ms iar lățimea impulsului între 500-2500μs. [12]
Pentru utilizarea servomotorului Futaba S3003 este nevoie doar de 3 pini ( unul de port paralel ce suportă PWM și 2 de alimentare). Având în vedere că Raspberry Pi nu are disponibil decât doi pini ce pot generea PWM va trebui să găsim o soluție care poate genera PWM software. Generarea clasică a unui semnal PWM software nu este posibilă astfel că pentru această funcție va fin nevoie de instalarea programului ServoBlaster, program care poate genera semnal PWM pe orice pin de port paralel al Raspberry Pi. [12]
În acest moment va trebui ales un pin convenabil din punct de vedere al așezării astfel încât să poată fi conectat ușor la servomotor (figura 3.2). Alimentarea servomotorului va fi de la o sursă separată din motive de protecție a plăcii Raspberry Pi . [12]
Alocarea pinilor:
SIG – Pinul 22
VCC – Sursă externă
GND – GND
Fig. 3.2. Conectarea servomotorului la conectorul Raspberry Pi
3.3 PmodHB5 (Peripheral module H-Briedge)
Modulul Digilent PmodHB5 2A este o soluție ideală pentru robotică sau alte aplicații unde se folosesc semnale logice pentru controlul motoarelor de curent continuu de dimensiuni medii sau mici ca de exemplu motoarele cu reductor oferite de Digilent. [13]
Caracteristici :
Punte H ce suportă curenți până la 2 A pentru tensiuni ce pot ajunge la 12V
Un conector special pentru conectarea motoarelor cu reductor Digilent
Două canale cu codare în cuadratură su senzori Hall pentru a detecta viteza motoarelor
Dimensiuni mici
Descrierea funcționării:
Puntea HB5 funcționează conectat la o tensiune de alimentare între 2.5V și 5V, în mod normal fiind conectat la 3.3V datorită faptului că majoritatea plăcilor de dezvoltare cu care este compatibil funcționează la acestă tensiune. [13]
Fig. 3.3. Schemă internă a PmodHB5
HB5 ete controlat de o placă din exterior prin intermediul conectorului J1. Direcția motorului este controlată de nivelul logic de pe pinul Direcție. Curentul va trece prin punte în momentul în care pinul de Enable este adus în starea 1 logic. Viteza de rotire a motorului este controlată de un semnal PWM (modulația lățimii impulsului) aplicat pe pinul Enable. Mai multe detalii despre PWM se vor găsi într-o descriere ulterioară. Direcția motorului nu trebuie schimbată în timp ce pinul de Enable este activ. Dacă direcția motorului se va schimba în timp ce motorul funcționeză este posibilă apariția unui scurtcircuit în puntea h deoarece o ramură va fi pornită în timp ce cealată se va opri. Acest lucru poate duce la deteriorarea Tranzitorilor. [13]
Două intrări de tipul trigger schmit se găsesc pe conectorul J2 pentru a furniza semnalele ce poartă informația despre viteza de rotire a motorului pentru a avea un control mult mai bun asupra motoarelor. Motoarele Digilent cu reductor au dispuși senzori cu efect Hall ca un codor în cuadratură. [13]
Semnalele în cuadratură sunt o pereche de semnale dreptunghiulare a căror frecvență este proporțională cu viteza de rotație a motorului și sunt defazate cu 90̊. Viteza de rotație a motorlui determinată de frecvență și direcția de rotație poate fi obșinută din relația de fază a ceor două semnale. [13]
3.3.1 Puntea H
Motoarele ce vor fi controlate în cadrul proiectului sunt motoare standart cu reductor. Pentru controloul acestora nu avem decât 2 fire care sunt de alimentare. Direcția de rotire a motorului este dată de direcția curentului care trece prin motor, deci inversând polaritatea se va inversa și direcția motorului. [7,13]
Configurația în punte H este un mod relativ simplu de a schimba direcția sursei de alimentare. Numele de punte H este dat de forma circuitului care este asemenea literei H, care folosește două perechi de comutatoare care vor trebui comutate împreună. Cel mai simplu mod de a înțelege funcționarea acestor circuite este prin studierea figurilor prezentate în continuare. Perechile de comutatoare sunt diagonal opuse unul celuilalt, fiecare pereche va fi comutată în același timp. În figurile de mai jos perechile de comutatoare sunt : S1 cu S4 și S2 cu S3. [7,13]
Dacă toate comutatoarele sunt deschise motorul nu va fi alimentat deci puntea H este în modul oprit (figura 3.4) . [7,13]
Fig. 3.4. Puntea H inactivă
Fig. 3.5. Puntea H activă direcție 1
Pentru ca motorul să funcționeze într-o direcție o pereche de comutatoare trebuie să fie pe poziția închis iar celelalte două pe poziția deschis (dacă toate cele 4 comutatoare vor vi deschise circuitul se poate distruge). În figura 3.5 este prezentat cazul în care perechea de comutatoare Sw1 si S4 sunt închise iar motorul va acționa pe direcția 1. [7,13]
Fig. 3.6. Puntea H activă direcție 2
În cazul 2 (figura 3.6) perechea de comutatoare Sw2 și Sw3 este pe poziția închis astfel motorul ma acționa în sens opus direcției 1.
Punțile H pot fi realizate cu circuite integrate cu relee cât si cu componente discrete cu tranzistoare cu efect de câmp (FET) , de exemplu Sw1,Sw2 pot fi tranzisoare cu canal N iar Sw3,Sw4 tranzistoare cu canal P. [7,13]
După cum se precizează și în datasheet pentru a controla modulele periferice HB5 este nevoie de utilizarea pinilor următori:
Direction
Enable
Sensor A
Sensor B
GND
Vcc (3.3 – 5v)
Știm că pe pinul Enable trebuie să aplicăm semnal PWM, iar RaspberrY Pi modelul B+ are doar 2 pini care suportă PWM portul 23 (BCM_GPIO13 fizic 33) și portul 1 (BCM_GPIO18 fizic 12) . Pentru o conectare mai ușoară atât pinii GPIO corespunzători senzorilor Hall cât și cel de direcție au fost aleși cât mai aproape de cel care suportă semnal PWM. [7,13]
Conectarea Modulului periferic stânga :
Direction – Pin 31
Enable – Pin 33
Sensor A – Pin 35
Sensor B – Pin 37
GND – GND
Vcc (3.3 – 5v) – Pin 17
Conectarea Modulului periferic dreapta :
Direction – Pin 16
Enable – Pin 12
Sensor A – Pin 18
Sensor B – Pin 32
GND – GND
Vcc (3.3 – 5v) – Pin 1
Interconectarea modulelor cu conectorul păcii Raspberry Pi se poate observa și din figura 3.7 .
Fig. 3.7.Modul de conectare a celor două module la Raspberry Pi.
3.4 Realizarea cablajului pentru conectarea modulelor la placa Raspberry Pi
Cablajul imprimat a fost realizat în programul PADS Mentor Graphics. Schematicul a fost realizat în subprogramul PADS Logic cablajul în PADS Layout și Router .
PADS Logic
PADS Logic este o unealtă robustă pentru proiectarea schemelor electrice, fiind un mediu simplu și foarte eficient. Această soluție oferă un acces rapid la orice pagină a proiectului, la componentele stocate online și la managementul librăriilor dar și ajutor pentru navigare în interiorul programului. Este integrat pe deplin cu PADS Layout pentru un transfer al designului eficient între schematic și layout. PADS Logic permite identificarea rapidă a componentelor corespondente, deci asigură o acuratețe a plasării mai mare. [14]
PADS Logic întâmpină utilizatorul cu o pagină de bun venit (figura 3.8 a) unde acesta poate să creeze un nou design sau să deschidă un design la care a lucrat anterior. Pe această pagină sunt și alte opțiuni precum un scurt tur al mediului de proiectare, tutoriale și un buton de Help. [14]
Mediul de proiectare PADS Logic dispune de o multitudine de meniuri și bări de unelte care ușurează accesul la unele funcții, figura 3.9 prezintă poziționarea meniurilor și uneltelor importante. [14]
Fig. 3.9 Meniuri și unelte PADS Logic
PADS Layout
Interfața utilizator pentru PADS Layout și modul de interacționare cu programul este asemănătoare cu interfețele altor aplicații Windows. Modul de utilizare al uneltei PADS Layout este foarte asemanător cu modul de utilizare al uneltei PADS Logic, făcând parte din aceeși categorie de programe și fiind realizate de același producător. [14]
Deasemenea interfața PADS Layout oferă posibilități nelimitate pentru utilizatorul experimentat dar este intuitiv și ușor de folosit pentru utilizatorul începător. [14]
Asemenea PADS Logic, PADS Layout întâmpină utilizatorul cu o pagina de bun venit (figura 3.10 a) unde acesta poate să deschidă un proiect realizat anterior sau să înceapă un proiect nou. În general începerea unui proiect nou se face prin importarea netlist-ului din PADS Logic în PADS Layout. După apăsarea butonului „Start a new design” se deschide pagina de lucru (figura 3.10 b) unde utilizatorul începe realizarea propriu-zisă a cablajului imprimat folosind datele trimise de la PADS Logic sau importând un nou netlist compatibil. [14]
Unealta PADS Layout dispune de o multitudine de meniuri și bări de unelte care ușurează accesul la unele funcții, meniul de bază este prezentat în figura 3.11. Figura 3.12 prezintă bările de unelte importante. [14]
Fig. 3.11 Meniul de bază pentru PADS Layout
Fig. 3.12 Bările de unelte specific PADS Layout
PADS Router
Interfața utilizator specifică PADS Router este asemănătoare cu intefața utilizator a celorlalte două unelte de proiectare PCB. Modul de interacționare cu programul este asemănător cu modul de lucru în majoritatea aplicațiilor Windows. [14]
Există posibilitatea de mânuire a acestui mediu de proiectare atât cu ajutorul scurtăturilor de la tastatură cât și prin meniurile intutiv creeate să ofere suportul necesar proiectantului avansat dar și proiectantului începător. [14]
Asemănător PADS Logic și PADS Layout, PADS Router întămpină proiectantul cu o pagină de bun venit (figura 3.13 a) pe care se pot găsi tutoriale dar și butoane pentru a deschide un design realizat anterior. PADS Router nu dispune de facilitatea deschiderii unui nou proiect deoarece nu se poate face un proiect nou fără a exista un proiect Layout. [14]
Asemanator PADS Logic și PADS Layout, PADS Router este o unealtă de proiectare puternică care dispune de o multitudine de meniuri, bări de unelte și scurtături care ușurează accesul la funcțiile importante, meniul de bază al acestui program este prezentat în figura 3.14. [14]
Fig. 3.14 Meniul de bază specific PADS Router
Fig. 3.15 PADS Router, bări de unelte
Realizarea Schematic-ului.
Schematicul pentru placa ce trebuie realizată constă în realizarea unor conexiuni între Raspberry Pi și modulele periferice. Acest aspect a fost prezentat anterior astfel că la acest punct rămâne prezentarea generală a schemei și a sursei de alimentare folosite. [14]
Fig. 3.16 Schemă Electrică Bloc Alimentare
După cum se vede sa blocul de alimentare este constituit din două surse de alimentare. Deoarece Raspberry Pi este foarte sensibil la fluctuații ale tensiunii de alimentare s-a ales varianta cu două regulatoare 7805 pentru ca servomotorul să fie alimentat separat.
Fig. 3.17 Schemă Electrică Finală
Realizarea Cablajului.
După cum s-a prezentat mai devreme, cablajul a fost realizat în cele două programe PADS Layout și PADS Router.
Fig. 3.18 Cablajul Realizat În PADS Layout
Fig. 3.19 Cablajul Realizat Suprafața Bottom
Realizarea efectivă a cablajului s-a efectuat prin corodare în clorură ferică. După acest pas se trece la lipirea componentelor pe placă și apoi la asamblarea robotului. Rezultatul final este prezentat în figura 3.20.
Fig. 3.20 Robotul realizat în urma asamblării acestuia
Capitolul 4
Configurarea Plăcii
4.1 Configurarea Raspberry Pi
Petnru început pentru a putea utiliza placa Raspberry Pi este nevoie de accesoriile prezente în figura 4.1
Fig. 4.1. Accesoriile minim necesare pentru configurarea unui Raspberry Pi.
După cum se observă din figură pe cardul MicroSD se va instala sistemul de operare Raspbian.
4.1.1 Instalarea sistemului de operare Raspbian Linux
Raspbian Linux este un sistem de operare optimizat pentru setul de instrucțiuni al arhitecturii ARMv6, pe care se bazează microcalculatorul Raspberry Pi. Acesta derivă din sistemul de operare Debian 7 “Wheezy”. Numele “Raspian” reprezintă un joc de cuvinte dintre Raspberry si Debian. Acest sistem de operare oferă peste 35000 de pachete software precompilate si usor de instalat, optimizate pentru a rula pe hardware-ul ARM11 al Raspberry Pi. [15]
Un alt sistem de operare utilizabil pe Raspberry Pi este sistemul RaspBMC, o distribuțe minimă bazată pe Debian care aduce funcționalitățile sistemului de operare pentru echipamente multimedia XBMC lui Raspberry Pi. [15]
În general pentru utilizatorii Windows sistemul de operare Linux este unul destul de străin și puțin cam greu de utilizat asta datorită consolei text în care acesta lucrează. La sistemul Raspbian acest lucru nu este un impediment deoarece acesta are și o interfață grafică atractivă, usor de ințeles și utilizat. Totuși având în vedere ca acesta lucrează pe un procesor fără prea mare putere calitatea GUI nu excelează în comparație cu sistemele de mare putere cum ar fi un calculator desktop sau laptop, unde Linux-ul poate oferi o calitate mult mai înaltă a interfeței grafice. [7]
Un lucru care este diferit la Linux față de alte sisteme de operare este acela ca poți utiliza întregul sistem fără a fi nevoie de a încărca mediul grafic și poate fi comandat de la distanță prin intermediul liniior de comandă în consolă. Cum am precizat mai sus acest lucru poate fi destul de ciudat pentru utilizatorii care sunt obișnuiți cu iconițele și ferestrele din Windows, dar consola oferă un control total si o putere destul de mare. Comanda prin intermediul consolei poate fi folositoare în proiecte precum un sistem robotic, deoarece nu necesită conectarea la un monitor sau un televizor. [7]
Înainte de începerea oricărui proiect cu Raspberry este indicat ca utilizatorul să petrecă un timp doar utilizând sistemul de operare Linux, pentru a se putea obișnui cu acesta. Pentru a avea acces la anumite particularități ale Raspberry-ului va fi nevoie să facem anumite configurări de bază. [7]
În continuare se va prezanta instalarea sistemului de operare Raspbian, pentru a aduce la viață placuța Raspberry Pi. Dacă sunteți deja familiarizați cu Raspberry Pi se poate trece peste acest punct, dar asigurațivă că veți studia secținuea în care se prezintă creearea unui hotspot Wi-Fi dacă doriți să controlați robotul din afara razei casei sau incintei în care vă aflați. [7]
Pentru acest proiect se va folosi sitemul de operare Raspbian, deoarece acesta este cel mai ușor de istallat folosint imagine software NOOBS. Este disponibilă și varianta cumpărării unui card SD/MicroSD cu sistemul de operare preinstalat, dar se poate descărca și software-ul gratuit de pe site-ul producătorului si installarea acestuia pe un card SD normal. [7]
Petru a nu avea probleme la instalarea sistemului de operare producătorul recomandă un card cu dimensiunea minimă de 4GB. Dacă acesta este now pre-formatat, poate fi folosit direct, dacă nu va fi nevoie de decărcarea unui software specializat pentru formatarea card-ului. [7]
Adresa pentru descărcarea software-ului pentru formatarea card-ului SD :
https://www.sdcard.org/downloads/formatter_4/
Adresa pentru descărcarea imaginii NOOBS de pe site-ul organizației Raspberry:
http://www.raspberrypi.org/downloads
Odată ce s-a descărcat fișierul (care ar trebui să aibe extenzia .zip), acesta va trebui să se extragă fișierele și mutarea lor pe card-ul SD.
Urmează pornirea plăcii Raspberry Pi după configurația afișată în figura 3.1, adică conectarea acesteia temporar la un televizor sau un ecran și o tastatură. După cum se observă din imagine Raspberry Pi poate fi conectat la un televizor prin intermediul unui cablu HDMI standard, iar dacă monitorul are interfață DVI acesta poate fi conectat prin intermediul unui conector HDMI către DVI. La plăcile anterioare modelului B+ conectarea la un televizor analogic putea fi realizată folosind un cablu RCA. Pentru ca placa să știe că se va utiliza conectorul RCA va fi nevoie să se apese o tasta (tasta 3 pentru sistemul PAL utilizat în Europa, iar tasta 4 pentru sistemul NTSC utilizat in USA). [7]
La start-up card-ul SD va trebui să fie inserat in slotul ce se găseste pe Raspberry Pi, ca de altfel și tastatura să fie conectată. Configurația inițială poate fi realizată și doar cu o tastatură, dar dacă se dorește se poate conecta și un mouse. La modelul B+ nu este nevoie de un hub de alimentare suplimentar, dar la alte modele mai vechi este nevoie, acestea neavând capacitata de a suporta mai multe dispozitive conectate pe usb la un moment dat sau nu au suficiente porturi. [7]
În final se poate conecta și sursa alimentarea micro-USB (folosit la telefoanele mobile) în conectorul de alimentare, după care se va afișa pe ecran imaginea de pornire a NOOBS (figura 4.2). Aici o să apară un meniu din care se poate alege instalarea mai multor sisteme de operare, de unde se va alege Raspbian care este soluția recomandată de către Raspberry, prin apăsarea tastei space, apoi alegeți începerea instalării ( o iconiță in partea stângă ”install”) [7]
Fig. 4.2. Ecranul de pornire la configurarea unui Raspberry Pi.
După ce s-a început instalarea va dura o perioadă până când se va repartiționa si instala sistemul de operare, după care se va restarta pornind cu sisemul Linux. În timpul instalării se vor afișa mai multe informații utile pentru configurare și utilizare. Trebuie să se precizeze că instalarea sistemului de operare va dura destul de mult, asta pentru a nu a avea vreo temere că ar fi apărut vreo problemeă la instalare sau că s-a blocat sistemul. [7]
Odată cu terminarea instalării și restartarea plăcii, sistemul de operare va porni pentru prima dată în ”Raspberry Pi Software Configuration Tool” (figura 4.3) care poate fi pornit și ulterior prin comanda raspi-config .Acest tool oferă un meniu de unde se poate configura cu ușurință anumite particularități ale sistemului de operare cum ar fi : [7]
Schimbarea Parolei
Setările de internaționale (în funcție de ce tastatură folosiți )
Opțiuni avansate, cum ar fi alocarea unui spațiu de memorie de 16MB pentru a putea folosi un nume unic pentru Raspberry-ul dumneavoastră.
Setări despre oră so dată
Pornirea directă în interfața grafică (nu este indicat să se activeze această opțiune în momentul în care se realizează configurarea pentru prima oară)
E.t.c
La încheierea setărilor se va alege opțiunea finish și apoi se va reporni sistemul. [7]
Fig. 4.3. Meniul raspi-config pentru configurarea unui Raspberry Pi. [7]
Introducere în linia de comandă a sistemului de operare Linux
LINUX are un sistem de fișiere arborescent. Spre deosebire de sistemul de fișiere DOS/Windows, separatorul între componentele numelui de fișier (directoare și numele propriu-zis) este caracterul / (slash) și nu \ (backslash). De asemenea, numele de fișiere nu conțin un identificator al discului fizic (A:, C:, etc.), ci întreaga ierarhie de fișiere pornește de la o rădăcină unică, notată /. În continuare, numele comenzilor sunt scrise cu caractere tip mașină de scris, argumentele lor sunt scrise cursiv, iar textul între [ ] denotă un argument opțional. [16]
Cîteva comenzi de bază sunt: [16]
mkdir nume_director
Creează un director (directory) cu numele dat.
cd [nume_director]
Schimbă directorul curent, trecînd in cel specificat (implicit: în directorul personal (home directory) al utilizatorului). La fel ca și sub DOS/Windows, . denotă directorul curent, iar .. directorul părinte. Notația ~ se referă la directorul personal al utilizatorului curent.
ls [nume_catalog]
Listează (afișează numele pentru) fișierele din directorul dat (implicit: directorul curent).
cat fișier
Afișează conținutul fișierului
cp [opțiuni] fișier1 fișier2
Face o copie a lui fișier1, cu numele fișier2
cp [opțiuni] fișier1 fișier2 fișier_n dir
Copiază fisierele indicate în directorul dir.
Opțiuni: -i (interactiv): întreabă înainte de a suprascrie; -r (recursiv, folosit): copiază toate fișierele și subdirectoarele din directorul sursă indicat.
mv [optiuni] fișier1 fișier2
Redenumește fișier1, cu numele fișier2
mv [opțiuni] fișier1 fișier2 fișier_n dir
Mută fișierele indicate în directorul dir.
Opțiuni: -i (interactiv): întreabă înainte de a suprascrie. (Un catalog e mutat implicit împreună cu întreg conținutul, deci opțiunea -r nu mai apare, spre deosebire de copiere)
rm [opțiuni] nume_fisier
șterge fișierul specificat. Opțiunea -i (interactiv) solicită confirmare, -f forțează (fără confirmare) iar -r șterge recursiv tot conținutul directorului indicat.
rmdir nume_director
șterge directorul indicat (acesta trebuie să fie gol).
man nume_comandă/apel sistem/funcție de bibliotecă
Afișează pagina de manual pentru comanda indicată (cu toate opțiunile).
Pentru o navigare și manipulare mai facilă a fișierelor se poate folosi programul Midnight Commander (mc), similar lui Norton Commander/Total Commander din mediul DOS/Windows. [16]
Pentru început este indicat să nu se ruleze sistemul în interfața grafică, ci in linia decomandă, cel puțin până la configurarea finală a Raspberry-ului. Deci la pornire vor apărea anumite texte care rulează pe ecran, acestea fiind normale, defapt majoritatea calculatoarelor generează mesaje similare cu acestea dar sunt ascunse pentru a creea un mediu cât mai prietenos cu utilizatorul. Defapt pe calculatoarele normale aceste texte sunt ascunse, numai că la Raspberry Pi pot fi utile la înțelegerea modului în care un calculator rulează și își încarcă sistemul de operare, totodată fiind util și în momentul în care apare o eroare la pornire, deoarece se poate identifica din textul care rulează pe ecran.[7]
Pentru început se vor ignora textele care rulează pe ecran. În momentul în care acestea vor termina de încărcat, pe ecran o să apară linia de autentificare. Se introduce numele utilizatorului, care implicit este pi, după care se introduce parola care va fi raspberry, acest lucru doar dacă nu cestea au fost schimbate din faza de configurare generală. De remarcat că in momentul în care se tastează parola pe ecran nu se vor vedea nici un fel de caractere, acest lucru doar din punct de vedere al securității, pentru ca atât aceasta cât și numărul de caractere să fie confidențiale. După autentificare se va o linie de text care se încheie cu semnul $. Prefixul liniei va conține informații despre calculatorul pe care se rulează sistemul de operare. Aceste aspeccte pot fi observate și din figura 4.4 cu precizarea că această autentificare a fost realizată prin SSH prin intermediul programului Putty, dar acest aspect va fi prezentat ulterior în cadrul proiectului. [7]
Fig. 4.4. Ecranul de autentificare Raspberry Pi.
Simbolul $ este numit prompt de comandă și indică faptul că consola este pregătită pentru a primi comenzi de intare. Textul din stânga după cum se vede din figură arată numele utilizatorului care este autentificat, numele de host al calculatorului și directorul în care se lucrează. Linia de comandă poate să se termine cu # în locul $, ceea ce înseamnă că se rulează cu drepturi de super-user, și va fi nevoie să aveți grijă ce comenzi realizați deoarece acestea vor fi permanente. Dacă utilizatorul este familiarizat cu consloa windows poate observa anumite asemănări între acestea dar si multe diferențe. Pentru a vedea în directorul curent se folosește comanda pwd . [7]
Directorul va fi afișat după cum se poate vedea de mai sus, pe linia următoare ” /home/pi”, iar apoi se va returna un prompt care așteaptă o altă comandă. Pentru a rula un program se poate introduce doar numele acestuia în linia de comandă, urmat de tasta Enter. În anumite cazuri este necesară introducerea unei intrucțiuni comenzii după numele acesteia .
Exemplu de comandă care returnează ecranul de mai jos. ” nano test.txt ”
4.2 Conexiune WiFi la Raspberry Pi
După cum deja se știe la Raspberry Pi se poate conecta la internet sau rețea locală doar prin cablul Ethernet. Este evident faptul că aplicația în care este folosit Raspberry-ul nu va fi folosit întotdeauna în apropierea unui cablu Ethernet, astfel că va fi nevoie de găsirea unei soluții optime pentru a îl utiliza. [7]
Cea mai bună soluție este aceea de a cumpăra un adaptor USB WiFi în scopul de al conecta la unul din porturile USB pentru a avea accesul la o rețea locală wireless. [7]
Înainte de a începe, este importantă alegerea adaptorului corect. După cum ați observat nu toate dispozitivele sunt ușor de utilizat (adică plug-n play), de foarte multe ori fiind nevoie de descărcarea unui driver (soft prestabilit) în vederea aducerii dispozitivului în starea de funcționare. Cum driverele sunt în majoritatea cazurilor prezente pentru sistemele Windows, în cazul Linux și Raspberry este cu totul altă problemă. Este foarte important de reținut ca pe documentația dispozitivului WiFi pe care doriți să îl achiziționați sau folosiți să se regăsească termenul compatibilitate Linux. În cadrul proiectului se poate folosi adaptorul wireless Asus USB-N10 Nano, 150Mbps standard WiFi 802.11b/g/n ,cât și Edimax – Wireless 802.11b/g/n Nano, asta datorită prețurilor accesibile și compatibilitaății lor cu sistemul de operare Linux. [7]
4.2.1 Conectarea adaptorului WiFi la Raspberry Pi
Se introduce adaptorul în unul dintre potrurile libere USB ale Raspberry Pi. Se conectează alimentarea, la acest moment adaptorul nu funcționează, și va fi încă nevoie ca mouseul ,tastatura și monitorul să fie conectate, sau să existe conexiune la rețea locală prin ssh prin ethernet. [7, 17]
După încărcare și autentificare pentru a ști că Raspberry-ul recunoaște adaptorul USB va fi nevoie verificarea acestui lucru prin intermediul comenzii: [7, 17]
dmesg | more
Această comandă va returna pe ecran un text care se poate derula folosind tasta space, iar aici se va găsi, sau nu numele adaptorului WiFi sau faptul că există un dispozitiv USB conectat. [7, 17]
[ 2.840460] hub 1-1:1.0: USB hub found
[ 2.846425] hub 1-1:1.0: 5 ports detected
[ 3.127380] usb 1-1.1: new high-speed USB device number 3 using dwc_otg
[ 3.247686] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00
[ 3.258684] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[ 3.273391] smsc95xx v1.0.4
[ 3.342160] smsc95xx 1-1.1:1.0 eth0: register 'smsc95xx' at usb-bcm2708_usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:bc:f7:42
Din acest text se poate ieși apăsând tasta ”q” și se poate continua configurarea WiFi.
4.2.2 Configurarea Rețelei WiFi
Pe Raspberry (și în general pe majoritatea sistemelor Linux), configurarea rețelei se face modificând fișierul ”/etc/network/interfaces”, care poate fi editat folosind comanda următoare. [7, 17]
sudo nano /etc/network/interfaces
Această linie de comandă va deschide un editor de text numit nano , un editor ușor de utilizat chiar și de utilizatorii care nu sunt foarte familiarizați cu sistemul de operare Linux. După deschiderea editorului de text nano va fi afișat următorul ecran (textul ce va modificat pentru rețeaua locală utilizată în cadrul proiectului): [7, 17]
Fig. 4.5. Editarea fișierului ”/etc/network/interfaces”.
Pentru a configura rețeaua wireless proprie se vor face modificări ale fișierului text după cum urmează:
auto lo
iface lo inet loopback
iface eth0 inet dhcp
allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-ssid "Rețeaua WiFi SSID"
wpa-psk "Parola"
Fig. 4.6. Fișierul ”/etc/network/interfaces” pentru conectarea la o rețea WiFi proprie.
Pentru a salva se va folosi combinația de taste Ctrl+O, după care se va putea ieși din editorul text nano folosind combinația Ctrl+X. Dacă apare mesajul dacă se doreste salvarea se apasă Y urmat de tasta Enter. [7, 17]
După ce s-a configurat totul va fi nevoie de restartarea interdețelor de rețea. Acest lucru putând fi realizat prin comanda:
sudo service networking reload
Dacă sunteți conectat prin ssh veți pierde conexiunea cu placa. După reâncărcarea interfeței de rețea (și reconectarea la Raspberry dacă s-a pierdut conexiunea ssh) se va putea verifica starea conexiunii WiFi prin comanda :
ifconfig
Rezultatul comenzii va fi ca cel de mai jos (în cazul în care configurarea a fost una cu succes adică la inet addr se găsește o adresă IP validă)
wlan0 Link encap:Ethernet HWaddr ac:9e:17:5b:74:bf
inet addr:192.168.173.132 Bcast:192.168.173.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:947 errors:0 dropped:0 overruns:0 frame:0
TX packets:449 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:193574 (189.0 KiB) TX bytes:85285 (83.2 KiB)
4.2.2.1 Instalarea software-ului adițional necesar
Presupunem că acum avem conexiune la internet (dacă nu urmați pașii de la punctul anterior) acum se poate realiza o actualizare a sistemului și softului de pe Raspberry Pi și adăugarea aplicațiilor necesare mai târziu. Acest lucru trebuie realizat înainte de configurarea Raspberry Pi ca hostpot deoarece vom creea o rețea independentă și vom pierde accesul la rețeaua de internet. Pentru acest lucru avem magazinul de aplicații Raspberry Pi (App store), care are la bază un conept similar cu cel de pe platformele mobile dar acolo este un installer software care funcționează similar cu cel de pe Linux adică instalarea peste internet, lucru care este prezent la sistemul acesta de operare cu mult înaintea magazinelor de aplicații de pe telefoane. [7, 17]
Pentru instalarea aplicațiilor vom folosii apt-get care instalează programele care au formatul pachetului tip Debian. Acesta este folosit pentru sistemul de operare principal (va fi folosit aici pentru actualizare), petru aplicații de mici dimensiuni până la aplicații cum ar fi un mai mari cum ar fi un editor foto sau un pachet office. Aplicațiile istalate prin apt-get nu instalează pe lângă aplicații nedorite. [7, 17]
Comanda folosită pentru actualizarea de bază a sistemului este :
sudo apt-get update
sudo apt-get dist-upgrade
Actualizarea sistemului poate dura o perioadă de timp până se descarcă software-ul adițional, de la instalarea imaginii până în momentul realizării operației de actualizare. După realizarea actualizărilor se poate trece la instalarea de software adițional. Softwareul poate fi instalat printr-o singură comandă dar pentru a înțelege mai bine comenzile și funcționarea apt-get această instalare va fi realizată prin mai multe linii de comandă. [7, 17]
Comanda următoare este folosită pentru a interoga interfața rețelei wireless. Nu este neapărat necesară dar ajută in detectarea potențialelor probleme.
sudo apt-get install iw
Pentru a configura calculatorul ca punct de acces wireless va fi nevoie de softul hostapd. Acesta este un daemon care rulează în background pentru a intreține rețeaua wireless.
sudo apt-get install hostapd
După cum știm un router alocă clienților săi un IP folosind DHCP, deci vom avea nevoie de unul și pe Raspberri Pi, acest lucru putând fi realizat prin ISC DHCP server.
sudo apt-get install isc-dhcp-server
Din acest moment, dacă mai este vreun tool/soft care va fi folosit în cadrul proiectului se poate instala, deoarece mai târziu conexiunea la internet nu va mai fi valabilă avân în vedere că vom folosi Raspberry Pi ca și punct de acces.â
4.2.2.2 Configurarea Raspberry pi ca access point/hotspot
Crearea unui server DHCP
În continuare se va edita fișierul /etc/dhcp/dhcpd.conf, fișier care ne creează un server DHCP, care permite alocarea dinamică a adresei IP,DNS,etc în mod automat în monentul conexiunii la hotspot. [7, 17]
sudo nano /etc/dhcp/dhcpd.conf
Folosind o adresă IP pentru conectarea la robot nu vom avea nevoie ca numele domeniului să existe în fișierul dhcp.conf, astfel că va trebui să cautăm in text anumite linii și să executăm anumite modificări ale acestuia. [7, 17]
Se caută liniile de mai jos
option domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org;
se modifică adăugând # inaintea fiecărei linii
#option domain-name "example.org";
#option domain-name-servers ns1.example.org, ns2.example.org;
se caută liniile
# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
#authoritative;
și se șterge # la linia 3 textul arătând astfel
# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;
după se va configura secțiunea “#A slightly different configuration for an internal subnet” astfel încât să arate ca mai jos
subnet 192.168.42.0 netmask 255.255.255.0 {
range 192.168.42.10 192.168.42.50;
option broadcast-address 192.168.42.255;
option routers 192.168.42.1;
default-lease-time 600;
max-lease-time 7200;
option domain-name "local";
option domain-name-servers 8.8.8.8, 8.8.4.4;
}
După configurarea fișierului se va salva folosind Ctrl+X apoi Y apoi Enter.
Urmează configurarea scriptului de pornire implicit pentru a seta interfața, acest lucru fiind posibil prin configurarea isc_dhcp_server.
Se reulează comanda:
sudo nano /etc/default/isc_dhcp_server
aici se va modifica fisierul modificând interfața astfel:
INTERFACES=”wlan0”
Acum serverul DHCP este cofigurat, el poate fi configurat atât manual cât și automat prin repornirea Raspberry-ului la finalizarea tuturor pașilor.
Configurarea unui IP static pentru wlan0
Acum va fi nevoie de configurarea unui IP static pentru rețea. Se poate configura un IP care se află în zona de adrese a rețelei WiFi, astfel eviând anumite probleme care pot apărea folosind un IP de altă clasă. Acest lucru va fi util în momentul în care se va dori o conexiune de la un calculator din rețeaua locală de ethernet, dar prin WiFi. [7, 17]
Dacă wlan0 este activ deoarece el a fost configurat, scrieți în linia de comandă sudo ifdown wlan0 .
Există o serie de intervale în care se pot introduce adrese IP private pentru uz local, și sunt șanse ca rețeaua locală pe care o folosim sa aibă una din aceste adrese. Vom seta robotului o adresă statică pentru ca acesta să poată fi găsit în permanentă la acea adresă IP.
Se rulează comanda:
sudo nano /etc/network/interfaces
se găsește locul unde se introduc datele pentru LAN wireless care le-am modificat anterior și vom scrie aici in locul celor anterioare :
iface wlan0 inet static
address 192.168.42.10
netmask 255.255.255.0
Configurarea softului pentru Access Point [7, 17]
La acest punct se va configura un nou fișier /etc/hostapd/hostapd.conf. Acest fișier nu există, dar în momentul în care vom încerca editarea unui fișier care nu există unealta nano va creea una cu numele celei care dorim să o modificăm, deci se va rula în linia de comandă
sudo nano /etc/hostapd/hostapd.conf
Aici se va introduce următorul text cu mențiunea că va trebui să schimbăm SSID-ul rețelei noastre wireless si o parolă.
# Host access point config file
# device name
interface=wlan0
# Driver interface
driver=hostap
# SSID for the network
ssid=<SSID/numele retelei noastre>
# set appropriate country parameters (maybe required for regulatory reasons)
country_code=GB
# Operation mode – for 802.11n still use g to indicate using same band as g
devices
hw_mode=g
# set channel – channel=0 for Automatic Channel Select
channel=0
# mac address access list – 0 = accept unless in deny
macaddr_acl=0
# Use shared key authentication
auth_algs=1
# Enable WPA2
wpa=2
# set passphrase
wpa_passphrase=<passphrase/parola>
# Use WPA PSK
wpa_key_mgmt=WPA-PSK
# Pairwise cipher for WPA (v1)
wpa_pairwise=TKIP
# Pairwise cipher for RSN/WPA2
rsn_pairwise=CCMP
După introducerea acestui text în fișier și salvarea acestuia conexiunea hotspot a Raspberry Pi ar trebui să funcționeze. Dacă pașii prin care s-a trecut pentru configurare trebuiesc reluați cu atenție.
4.3 Conectarea la raspberry Pi prin SSH (Putty)
Secure Shell (SSH) este un protocol de rețea criptografic ce permite ca datele să fie transferate folosind un canal securizat intre dispozitive de rețea. Cele două mari versiuni ale protocolului sunt SSH1 sau SSH-1 șiSSH2 sau SSH-2. Folosit cu precădere în sistemele de operare multiutilizator linux și unix, SSH a fost dezvoltat ca un înlocuitor al Telnet-ului și al altor protocoale nesigure de acces de la distanță, care trimit informatia, în special parola, în clartext, făcând posibilă descoperirea ei prin analiza traficului. Criptarea folosita de SSH intenționează să asigure confidențialitatea și integritatea datelor transmise printr-o rețea nesigură cum este Internetul. [18, 19]
SSH permite utilizatorilor să se conecteze la un calculator din rețea. Utilizatorii pot începe o sesiune la distanța specificând un calculator distant (prin nume sau IP) la care vor să se conecteze. Din acest moment până la sfarșitul sesiunii orice acțiune a utilizatorului este transmisă calculatorului distant. Stația locală a utilizatorului se va comporta ca un terminal simplu al calculatorului distant. Acest serviciu folosește protocolul cu același nume al modelului TCP/IP. Oricare din aplicațiile client de telnet funcționeaza pe nivelul Aplicație al modelului TCP/IP. SSH (Secure Shell) este un serviciu specific sistemelor de operare (SO) Linux. Avantajul acestui protocol față de protocolul Telnet este securizarea comunicației intre cele doua calculatoare. [18, 19]
Spre deosebire de alte sisteme de operare sitemele Microsoft Windows nu include inițial o interfață client SSH. Putty este unul din cele trei programe care pot să ofere această opțiune și în spațiul windows, o aplicație cu interfață grafică, dar care oferă accesul la aceeași consolă text standard folosită de OpenSSH in Linux. [18, 19]
PuTTY este un program gratuit și open-source ce emulează un terminal fiind un client pentru SSH, Telnet, rlogin, și raw TCP protocol precum și client pentru serial console. Numele "PuTTY" nu are o semnificație anume acesta reflectând procedura "prin TTY" unde "TTY" se referă la "terminal" în terminologia UNIX (TTY este prescurtare pentru Teletype).
PuTTY a fost scris original pentru Microsoft Windows dar ulterior a fost portat și pe alte sisteme de operare. Există versiuni oficiale disponibile pentru unele platforme Unix-like și se lucrează constant și pentru versiuni ale Mac OS și Mac OS X. Versiuni neoficiale pot fi găsite pentru sisteme ca Symbian și Windows Mobile PuTTY a fost scris și întreținut în mod oficial de către Simon Tatham fiind și în prezent categorizat ca beta software. [18, 19]
Fig. 4.7. Interfața grafică a programului Putty.
Dacă este pentru prima dată când Putty se conectează la un calculator, va afișa un ecran de atenționare cu anumite detalii despre calculatorul la care doriți să vă conectați, pentru a decide dacă se va mai continua conexiunea sau nu. Dacă se vrea verificarea cu adevărat a conexiunii cu Raspberry Pi, va fi nevoie de rularea în linia de comandă a ”ssh-keygen-l”, atunci când există o conexiune fizică intre placă și client,apoi fiind obligat să dispuneți fișierl corespunzător cu cheia SSH. În realitate dacă se știe că este un calculator la care nu a mai fost conectat, se poate trece peste acest pas apăsând butonul yes. Dacă ulterior se primește un avertisment că cheia a fost schimbată va trebui luat în calcul faptul că cineva maschează calculatorul la care se dorește conectarea, totuși dacă calculatorul a fost reinstalat va apărea același avertisment. Un exemplu este prezentat in figura următoare (Fig. 4.8.) [18, 19]
Fig. 4.8. Fereastra de alertă de securitate Putty
După ce se confirmă continuarea va fi prezentat utilizatorului un ecran de autentificare, unde se poate accesa introducând numele utilizatorului si parola pentru Raspberry Pi. După autentificare comenzile care sunt introduse vor rula pe calcultatorul comandat deci nu pe calculatorul de pe care se dă comanda. Pentru a fi sigur că utilizați calculatorul vizat trebuie să verificați de fiecare dată numele utilizatorului, înainte de a introduce in linia de comandă vreo instrucțiune. [18, 19]
4.4 Instalarea Geany (mediu de programare software)
Geany este un soft integrat de dezvoltare ușor de utilizat și de dimensiuni mic. Acesta a fost dezvoltat pentru a oferi un IDE (Integrated Development Environment) mic și rapid, care are doar câteva dependențe față de alte pachete. Un alt obiectiv a fost ca acesta să fie cât mai independent cu putință de mediu de birou cum ar fi KDE sau GNOME – Geany necesită doar bibliotecile de rulare GTK2. Ca avantaj major acesta nu are nevoie de resurse multe astfel că acesta poate rula și pe Raspberry PI destul de bine. [20]
Unele caracteristici de bază ale Geany:
Evidențierea sintaxei
Codul de pliere
Autocompletare de simboluri / cuvinte
Construirea completă / fragmente
Auto-închidere a etichetelor (tag-uri) XML și HTML
Calltips
Suportă multe tipuri de fișiere, inclusiv C, Java, PHP, HTML, Python, Perl, Pascal și altele
Listele simbol
Cod de navigare
Construiște un sistem pentru a compila și executa codul
Management de proiect simplu
Interfață plugin
Pentru a putea lucra în Geany, trebuie să-l instalați separat pe sistemu de operare Rasbian. Inițial când se folosește sistemul de operare se introduc urmatătoarele linii de comandă:
pi@raspberrypi ~ $ sudo apt-get update
pi@raspberrypi ~ $ sudo apt-get upgrade
pi@raspberrypi ~ $ sudo apt-get install geany
După instalare se poate rula comanda startx pentru a putea intra în interfața grafică a sistemului de operare Raspbian, în același mod se poate instala soft-ul Geany și din GUI, dar din LXterminal. [20]
Fig. 4.9. Interfață grafică Geany
Pentru a vă asigura că puteți utiliza pinii de port paralel GPIO puteți utiliza unul din exemplele de bază funizate de librăria bmc2835, exemplu în care se realizează aprinderea și stingerea unui LED. Acest lucru se face prin introducerea codului furnizat într-un fișier nou creat, main.c, într-un proiect nou. [20]
Pașii de creearea a unui proiect nou:
Project > New. Se introduce numele proiectului și locația unde se dorește salvarea acestuia.
File > New cu sau fără template > main.c
Se salvează ca main.c
Codul care trebuie introdus în fișierul main.c
#include <bcm2835.h>
// Blinks on RPi pin GPIO 11
#define PIN RPI_GPIO_P1_11
int main(int argc, char **argv)
{
if (!bcm2835_init())
return 1;
// Set the pin to be an output
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP);
// Blink
while (1)
{
// Turn it on
bcm2835_gpio_write(PIN, HIGH);
// wait a bit
delay(500);
// turn it off
bcm2835_gpio_write(PIN, LOW);
// wait a bit
delay(500);
}
return 0;
}
Compilarea fișierului unui proiect:
Compile – Compileză fișierul sursă curent într-un fișier obiect binar
Build – Conectează fișierul sursă și cel obiect într-un executabil (deci pentru a putea executa, mai întâi se va face operația de compilare)
Compilarea proiectelor cu mai multe fișiere:
Soft-ul Geany nu compilează proiectul ca atare el compilează fișiere. Pentru a rezolva această problemă va trebui să se folosească un makefile
Comanda din Geany ”make” o să folosească un fișier de compilare numit implicit ”makefile”, deci va trebui să denumiți fișierul dumneavostră de compilare cu acest nume și sa fie salvat în același folder cu fișierele proiectului.
Exemplu de makefile folosit în cadrul proiectului:
all: output_file_name
output_file_name: main.o
gcc main.o -lbcm2835 -o output/file/name
main.o: main.c
gcc -c main.c
clean:
rm -rf *o output/file/name
4.5 Wiring Pi – Librarie de interfațare GPIO pentru Raspberry PI [21]
Este conceput pentru a fi ușor de utilizat de către persoanele care sunt familiarizate cu limbajul plăcuțelor Arduino.[21]
La început librăria a fost concepută pentru modelul Raspberry Pi B, care avea un conector cu 26 de pini GPIO (General Purpose Input/Output), dar ulterior a fost modificată și pentru celelalte modele de Raspberry, ca de exemplu modelul B+ ce oferă un număr de 40 de pini GPIO. [21]
Librăria se poate obține de pe platforma GIT datorită ușurinței cu care se pot face modificări și actualizări asupra ei, dar în cazul în care nu aveți accesu la GIT există și o a doua variantă. [21]
Dacă pe Raspberry-ul pe care se dorește instalarea nu există GIT instalat, indiferent de varianta de Debian folosită puteți folosi următoarea comandă pentru instalare:
sudo apt-get install git-core
În cazul apatiției anumitor erori de instalare, trebuie verificată actualizarea sistemului de operare pe care se dorește instalarea folosind comenzile:
sudo apt-get update
sudo apt-get upgrade
Pentru a descărca librăria WiringPi se va folosi următoarea comandă:
git clone git://git.drogon.net/wiringPi
Dacă operația de clonare a fost realizată pentru prima oara atunci se va realiza următoarea comandă:
cd wiringPi
git pull origin
Acest lucru va aduce librăria într-o versiune actualizată, apoi va fi nevoie să se ruleze scriptul de mai jos:
cd wiringPi
./build
Acest nou script va compila și va instala totul, fără a mai fi nevoie de vreo intervenție din exterior. Mare atenție la conținutul script-ului deoarece acesta folosește comanda sudo, deci o bună ideea ar fi să verificați înainte de a folosi această comandă. [21]
Dacă accesul la platforma GIT nu este posibil, există și o variantă de rezervă, adică accesarea link-ului oferit pe pagina web a librariei WiringPi ” https://git.drogon.net/?p=wiringPi;a=summary ”, după care se va accesa link-ul snapshot din partea dreaptă a paginii. Din acest moment se va începe descărcarea unui fișier cu terminația tar.gz cu numele wiringPi-98bcb20.tar.gz . Atenție la faptul că terminația de cifre și litere de după wiringPi-XXXXXX.tar.gz va fi probabil diferită, deoarece ea reprezintă codul versiunii librăriei pe care o veți folosi. [21]
După descăracare va fi nevoie de următoarele comenzi pentru instalarea librăriei:
tar xfz wiringPi-98bcb20.tar.gz
cd wiringPi-98bcb20
./build
Pentru a verifica dacă instalarea a fost realizată corect se vor rula comenzile:
gpio -v
gpio readall
Fig. 4.10. Structura GPIO în librăria WiringPi
După cum se poate observa din figura anterioară numerotarea pinilor GPIO în cadrul librăriei wringPi este diferită de cea a librăriei BCM2835.
Înainte de a folosi librăria pentru GPIO wiringPi va fi nevoie de includerea în fișierul header al programului următoarea linie:
#include <wiringPi.h>
De altfel va fi nevoie si de adăugarea următoarei linii în comanda de compilare, forma comenzii fiind diferită în funcție de ce compilator folosiți. Partea cea mai importantă din această linie este ”-lwiringPi ”:
-I/usr/local/include -L/usr/local/lib -lwiringPi
Funcții oferite de către librăria wiringPi : [21]
WiringPi Setup functions (funcțiile de setare a plăcii)
Core wiringPi functions (funcțiile de bază ale wirngPi)
Acestea două fiind cele mai importante caracteristici ale librăriei, iar în continuare sunt menționate librării care sunt deasemenea importante și folositoare la programarea RaspberryPi:
Raspberry Pi specific functions (funcții speciale)
Timing functions (funcții de delay atât în milisecunde cât și în microsecunde)
Program priority, timing and threads (lucrul cu întreruperi cu thread-uri)
Serial library
SPI library
I2C library
Shift library
Software PWM library
Software tone library
Funcții de bază ale wiringPi: [21]
Funcțiile ce urmează a fi prezentate funcționează direct pe Raspberry Pi cât și cu anumite module de extensie a porturilor GPIO, dar evident nu toate suportă toate funcțiile de exemplu PiFace, este preconfigurată pentru ieșrile și intrările ei, iar RaspberryPi nu are parte analogică inițial.
void pinMode (int pin, int mode) ;
Această comandă setează starea pinului dorit în următoarele moduri : INPUT, OUTPUT, PWM_OUTPUT sau GPIO_CLK. Atenție la faptul că doar pinul 1 al librăriei wiringPi (BCM_GPIO18) suportă semnal PWM, iar pin-ul 7(BCM_GPIO4) suportă semnal de ceas. La modelul B+ se mai poate genera semnal PWM și pe portul 24 (BCM_GPIO19).
void pullUpDnControl (int pin, int pud) ;
Această funcție modul cu rezistor pull-up sau pull-down pe pinul dorit, care în mod normal trebuie setat ca pin de intrare. Spre deosebire de Arduino, BCM2835 are ambele variante de rezistori interni, atât de pull-up cât și pull-down. Parametrul pud va trebui să fie de felul : PUD_OFF,(fară rezistor de pull-up/down), PUD_DOWN (tras în 0V) sau PUD_UP(tras în 3.3V). Rezistorii de pull up/down au o valoare de aproximativ 50KΩ la plăcile RaspberryPI.
Această funcție nu are niciun efect asupra pinilor RaspberryPi in modul Sys. Dacă va fi nevoie de activarea acestei opțiuni, va fi nevoie de realizarea unui script înainte de pornirea programului ce urmează a fi rulat.
void digitalWrite (int pin, int value) ;
Se scrie valoarea HIGH (1 logic) sau LOW (0 logic) pe pinul care a fost setat ulterior ca port de ieșire. De reținut este faptul că orice număr diferit de 0 este interpretat de wiringPi ca HIGH, iar singura reprezentare pentru LOW este 0.
void pwmWrite (int pin, int value) ;
Se scrie valoarea în registrul de PWM pentru pin-ul selectat. Raspberry Pi are doar doi pini care suportă PWM portul 23 (BCM_GPIO13) și portul 1 (BCM_GPIO18). Valoare scrisă în registrul PWM poate lua valori în gama 0-1024
int digitalRead (int pin) ;
Această funcție returnează valoarea citită de pe pinul dat. Poate fi HIGH sau LOW (1 sau 0) în fucție de nivelul logic de pe pin.
analogRead (int pin) ;
Se returnează valoarea citită de pe intrarea analogică oferită. Va fi nevoie de înregistrarea modulelor analogice adiționale pentru a activa acestă funcție pentru extensii cum ar fi Gertboard sau placa analogică quick2Wire .
analogWrite (int pin, int value) ;
Se scrie o valoare analogică pe pinul analogic suplimentar selectat valoarea introdusă de către utilizator. Va fi nevoie de înregistrarea modulelor analogice adiționale pentru a activa acestă funcție pentru extensii cum ar fi Gertboard sau placa analogică quick2Wire
Capitolul 5
Proiectarea Software
5.1 Breviar Teoretic
5.1.1 Limbajul C [22]
Limbajul C este un limbaj de nivel înalt, care oderă în același timp, prin instrucțiuni și operatori specifici, acces la nivelul hard-ului, ca și limbajele de asamblare. Spre deosebire de limbajele de asamblare,programele scrise în C sunt portabile, nefiind dependente de un anume tip de procesor . De aceea limbajul C a fost supranumit limbaj de asamblare universal.
Dezvoltarea acestui limbaj a început în anul 1970, când doi programatori, Brian Kerininhan și Dennis Ritchie, au creeat acest nou limbaj de programare, în scopul rescrierii sistemului de operare UNIX, pentru a-l face portabil pe teoate platformele existente.
C-ul este un limbaj procedural,așadar un program scris în C presupune definirea structurilor de date, apoi definirea funcțiilor ce lucrează cu aceste structuri.
În anul 1980, Bjarne Stroustrup a conceput limbajul C++, extizând limbajul C prin adăugarea unor facilități, dintre care cea mai importantă este lucrul pe clase. Limbajul C++ este un limbaj mixt și procedural orientat pe obiecte. Programele scrise în C++ funcționează și în C++, ele putând fi transformate în C++, în general cu eforturi minime. C++ este astăzi unul din cele mai populare limbaje pentru dezvoltarea profesională de software.
Limbajul C a crescut în popularitate și a început să stea la baza altor limbaje odata cu apariția calculatoarelor personale. Un fapt cu totul inedit a fost acela că, mare parte din implementările C-ului au dovedit un mare grad de compatibilitate: un program scris pentru una din variante putea fi compilat cu succes folosind o altă variantă. Se înțelege că au existat și neconcordanțe în multitudinea de “dialecte” ale limbajului. În 1983 s-a creat o comisie care să stabilească standardele acestor noi limbaje. Standardul ANSI (American National Standard Institute) a fost redactat abia în decembrie 1989 și a fost pus la dispoziția celor interesați la începutul lui 1990. Firma Borland a folosit acest standard în faza de proiect și a realizat implementările Turbo C care se bucură de un succes remarcabil. De altfel, în prezent, toate compilatoarele C sunt compatibile cu standardul ANSI C; unele din acestea au adăugate o serie de facilități sau extensii proprii, care nu împiedică compilarea unui program standard.
Limbajul C combină cele mai reușite elemente ale limbajelor de nivel înalt ( Pascal, Fortran, Algol, Modula, Ada) cu flexibilitatea și gradul de control oferite de către limbajul de asamblare. C permite un acces foarte liber la elementele de bază ale unui calculator cum ar fi biții, byte, word și altele. Caracteristicile distinctive ale limbajului au fost clar definite de la început, ele păstrîndu-se în toate dezvoltările ulterioare:
Este un limbaj de bază simplu, cu importante funcționalități cum ar fi funcțiile matematice sau cele de manipulare ale fișierelor
Este focalizat pe paradigma programării procedurale, care facilitează programarea într-un mod structurat
Utilizează un set simplu de tipuri de date ce împiedică multe operații neintenționate
Folosește un limbaj preprocesor, preprocesorul C, pentru sarcini cum ar fi definirea de macrouri și includerea mai multor fișiere sursă
Permite accesarea la nivel scăzut a memoriei calculatorului prin utilizarea pointerilor
Permite folosirea parametrilor, care sunt comunicați funcțiilor prin valoare și nu prin referință
Pointeri la funcții, ce permit forme rudimentare de închidere (engleză closure) și polimorfism
Declararea variabilelor
Structuri de date sau tipuri de date agregate, definite de utilizator prin (struct), ce permit ca date înrudite să fie combinate și manipulate ca un întreg.
Printre caracteristicile ce lipsesc în C, dar care pot fi găsite în alte limbaje de programare se enumeră:
Un sistem automat de colectare a reziduurilor (de memorie) (engleză Garbage collection)
Clasele și obiectele (programarea orientată pe obiecte)
Un sistem avansat de tipuri de date
Programarea generică
Supraîncărcarea
Metaprogramarea
Suport nativ pentru programarea multifir (engleză multithreaded) și funcțiile de rețea
Procesarea listelor
5.1.2 Etapele dezvoltării unui program în limbajul C [22,23]
Dezvoltarea unui program pe calculator se face parcurgând următoarele etape:
Analiza
Proiectare
Implementare
Testare
Toate aceste etape se parcurg în cazul uneiaplicații mari, ”industriale”. În cazul aplicațiilor simple, mici ca număr de linii, se face o analiză sumară, putându-se trece direct la implementare.
În faza de analiză se decide ce urmează să facă efectiv programul. Rezultatul acestei etape este în general, un document scris ce conține cerințele programului (cerințe impuse cel mai adesea de beneficiarul programului). O parte din acest document poate să fie chiar un manual de utilizare a programului, în care se arată cum se operează programul.
În faza de proiectare se dezvoltă un plan despre modul în care se vor implemeta cerințele. Programatorul alege algoritmii și structurile de date care vor fi folosite.
În faza de implementare se scrie codul programului (se editeazaă textul sursă al programului) și se compilează, pentru a obține în final codul executabil.
Textul sursă este editat în unl sau mai multe fișiere. În limbajul C, extensia numelui fișierului sursă este .c sau .cpp . Se recomandă utilizarea extensiei .cpp pentru a putea beneficia de facilitățile limbajului C++. Pentru programele simple (ce au număr un număr mic de linii de cod) un singur fișier sursă este suficient. Programele mari se realizează sub formă de proiect, împărțindu-se în mai multe fișiere sursă, scrise eventual de mai multți programatori.
În cazul limbajului C, pentru a traduce fiecare fisier sursă într-un fisier obiect ce conține cod mașină, se folosește un instrument software denumit compilator. Fiecare fișier sursă, trebuie compilat separat. Dacă trebuie ulterior să modificăm un fișier sursă trebuie recompilat doar fișierul respectiv și nu întregul program. Acesta este unul dintre motivele pentru care se preferă organizarea sub formă de fișiere sursă multiple (sub formă de proiect) a programelor mari.
Apoi, în vederea obținerii codului executabil, se folosește un alt instrument software: link-editorul. Acesta este un program care face legarea fișierelor obiect între ele, câ și includerea codului obiect pentru funcțiile de bibliotecă apelate de program. Rezultatul acestei oprații este fișierul executabil, ce conține tot codul mașină necesar programului pentru a putea rla pe calculator.
Chiar dacă un program conține doar un singur fișier sursă, operația de link-editare este necesară pentru a combina codul din fișierul obiect cu codul funcțiilor de bibliotecă apelate de program.
După compilarea și linkarea cu succes a programului, toate erorile de sintaxă au fost eliminate. În general, erorile apar într-un program, sunt de două tipuri:
De sintaxă
De execuție
Ultima etapă a realizării unui program este testarea programului. În această fază se elimină erorile de execuție ale programului. În această fază se elimină erorile de execuție ale programului. Pentru descoperirea acestor erori se recomandă testarea programului atât cu date de intrare normale cât și cu date de intrare extreme (foarte mici sau foarte mari), date ce nu sunt în mod normal asteptate în exploatarea uzuală a programului.
În general, programele mari au erori de execuție ce pot fi puse în evidență doar cu anumite seturi de date de intrare. Deci, pentru anumite date de intrare programul, deși mai are erori, se comportă normal (erorile nu sunt evidențiate de aceste date de intrare). Erorile rămase nedescoperite într-un program, se cheamă erori latente. Costul de corectare a acestor erori latente este foarte mare, mai ales după ce programul a fost comercializat. Datorită acestori erori latente, în exploatare, în funcție de natura aplicației, programul, în momentul întâlnirii unei combinații de intrări ce activeză eroarea latentă, poate determina consecințe catastrofale.
Evident un program cu cât este mai lung cu atât este mai dificil de testat. Pentru că erorile latente au consecințe în general foarte costisitoare, în scopul eliminării lor, se recomandă ca testarea programelor (când este vorba de programele mari, industriale) să se facă de o altă echipă decât cea care a creeat progrmul respectiv. De asemenea, se recomandă ca partea de testare să fie alcoată celor mai buni programatori.
5.1.3 Tipuri de date [22, 23]
C are un sistem de tipuri de date similar cu cel al descendenților ALGOL, cum ar fi Pascal, dar totuși cu anumite diferențe. Cuprinde tipuri de date cum ar fi întregi de diferite dimensiuni, cu sau fără semn, numere în virgulă mobilă, enumerări (enum), structuri de date (struct) și uniuni (union).
C utilizează foarte mult pointerii, un tip de referință foarte simplu, care păstrează adresa locației din memorie. Adresa poate fi manipulată cu ajutorul atribuirilor și a aritmeticii pointerilor. În momentul rulării unui program, un pointer reprezintă o adresă de memorie. În momentul compilării, un pointer este un tip de dată complex, ce reprezintă atât adresa de memorie cât și tipul de dată. Acest lucru permite expresiilor ce utilizează pointeri să fie evaluate după tipul de dată. Pointerii au mai multe utilizări în C. De exemplu, șirurile de caractere (engleză text string) sunt adesea reprezentate printr-un pointer la un vector de caractere. Alocarea dinamică a memoriei este realizată tot cu ajutorul pointerilor.
Un pointer null are o valoare rezervată, indicând faptul că face referire la o locație nevalidă. Acest lucru este folositor în cazuri speciale cum ar fi pointerul next (următorul) în nodul final al unei liste înlănțuite. Dereferențierea unui pointer null poate cauza un comportament imprevizibil al aplicației. De asemenea, există și pointeri de tip void, fapt ce indică referirea la un obiect de tip necunoscut. Acești pointeri sunt foarte folositori în programarea generică. Deoarece dimensiunea și tipul obiectelor la care acest tip de pointeri face referire sunt necunoscute, aceștia nu pot fi dereferențiați, dar pot fi convertiți la alt tip de pointeri.
În C, anterior standardului C99, tablourile (vectorii) sunt de dimensiune fixă, statică, cunoscută la momentul compilării; în practică, acest lucru nu reprezintă o piedică, având în vedere că se pot aloca blocuri de memorie în momentul rulării, tratându-le ca pe tablouri utilizând librăria standard. Spre deosebire de multe alte limbaje de programare, C reprezintă tablourile ca și pe pointeri: o adresă și un tip de dată. Prin urmare, valorile index pot depăși dimensiunea actuală a unui tablou.
De asemenea, C oferă posibilitatea de lucru cu tablouri multidimensionale. Din punct de vedere semantic, tablourile multidimensionale sunt tablouri de tablouri, dar, din punct de vedere fizic, acestea sunt stocate ca un singur tablou unidimensional cu un offsetcalculat.
C este adesea folosit în programarea de nivel scăzut, unde poate fi necesar ca un întreg să fie tratat ca o adresă de memorie, un număr în virgulă mobilă ca un întreg sau un tip de pointer ca un alt tip de pointer. Pentru astfel de cazuri C oferă operatorul de casting, care forțează explicit conversia unei valori dintr-un tip de dată în alt tip de dată.
5.1.4 Alocarea memoriei [22, 23]
Una din cele mai importante funcții ale unui limbaj de programare este ca acesta să furnizeze metode de management a memoriei și al obiectelor stocate în memorie. C furnizează trei metode distincte de alocare a memoriei pentru obiecte:
Alocarea statică a memoriei: adresele și dimensiunile obiectelor ce fac uz de alocarea statică a memoriei sunt fixate în momentul compilării și pot fi plasate într-o zonă de dimensiune fixă ce corespunde unei secțiuni din cadrul fișierului linkedidat final. Acest tip de alocare a memoriei se numește statică deoarece locația și dimensiunea lor nu variază pe durata de execuție a programului.
Alocarea automată a memoriei: obiectele temporare (variabilele locale declarate în cadrul unui bloc de cod) sunt stocate în cadrul de stivă asociat funcției apelate, iar spațiul alocat este automat eiberat și reutilizat după ce s-a părăsit blocul în care acestea au fost declarate.
Alocarea dinamică a memoriei: blocuri de memorie de orice dimensiune pot fi alocate într-o zonă de memorie numită heap prin intermediul funcțiilor malloc(), calloc() și realloc(). Aceste blocuri de memorie pot fi reutilizate după ce zona de memorie a fost eliberată prin apelul funcției free().
Nu toate variabilele sunt automat alocate. Următoarele tipuri de variabilă sunt alocate static:
toate variabilele globale, indiferent dacă au fost sau nu declarate ca statice;
variabilele locale declarate explicit ca fiind statice.
Variabilele alocate static au alocată locația lor de memorie și inițializată înainte ca funcția main să fie executată și nu sunt dealocate până când se termină execuția funcției main.
Variabilele alocate static nu sunt reinițializate la fiecare apel al funcției în cadrul cărora au fost declarate. O variabilă alocată static are avantajul că își păstrează valoarea, chiar dacă funcțiile care accesează acea valoare nu mai sunt active.
Acolo unde este posibil, alocarea automată sau statică este preferată deoarece alocarea memoriei este coordonată de compilator, nemaifiind nevoie ca programatorul să aloce iar apoi să elibereze memoria – operație ce adesea generează erori. Totuși, multe structuri de date sunt variabile în dimensini și deoarece alocarea automată și cea statică trebuie să fie de dimensiune fixă în momentul compilării, sunt multe situații în care alocarea dinamică trebuie folosită. Un exemplu ar fi tablourile de dimensiuni variabile.
5.2 Realizarea funcțiilor [22, 23]
Software-ul robotului nu a fost realizat ca un singur program, ci un ansamblu de funcții pentru o proiectare cat mai optim posibilă. După cum am precizat anterior în brviarul teoretic este indicat ca în realizarea unui proiect software, anumite bucăți de cod care sunt folosite pentru o anumită operație să fie realizate în funcții. În continnuare software-ul robotului va fi prezentat pe funcții, nu ca un întreg program.
5.2.1 Funcția de măsurare a distanței cu senzorul HC-SR04 [24]
Senzorul HC-SR04 funcționează pe principiul sonarului pentru a precia distanța intre el și un obstacol.
Calculul distanței de la senzor la obstacol:
Știm că viteza sunetului este de 340,29 m/s. Luând în calcul că vom măsura timpul care se scurge dus-întors viteza va scădea la jumatate.
x
Deci timpul în care unda parcurge 1cm este de 58,772
Modul de funcționare al senzorului cu ultrasunete HC-SR04 este prezentat în figura 5.1, deci pentru a porni orice măsurare pe pinul TRIG va fi nevoie de menținerea unui semnal în 1 logic o perioadă de 10μs, apoi oprirea acestui semnal. Odată ce a fost activat pinul Trigger, se va genera un semnal format din 8 impulsuri cu frecvența de 40kHz (domeniul ultrasunetelor). După ce au fost transmise aceste impulsuri pinul Echo va trece în starea 1 logic și se va astepta recepția semnalului, adică trecerea pinului Echo în 0 logic.
Fig. 5.1. Modul de funcționare al senzorului cu ultrasunete HC-SR04
În principal exită două cazuri de propagare a semnalului și de recepție a acetuia:
Cazul 1 – Este cel ideal în care semnalul transmis (semnalul Trigger) întâlnește un obstacol orientat către senzor(obstacol paralel cu senzorul HC-SR04) și se reflectă înapoi către senzor (semnalul Echo) unde va fi recepționat iar cu formula 4.1 se va calcula distanța
Cazul 2 – Este un caz în care obstacolul nu are suprafața dreaptă (poate fi și un obstacol cilindric) sau nu este paralel cu senzorul, iar semnalul transmis (semnalul Trigger) nu se va mai reflecta înapoi spre senzor ne mai putând fi recepționat aecst lucru putând fi observat și din figura 5.2 unde rezultatul măsurării va fi unul eronat.
Fig. 5.2. Cazuri de propagare a semnalelor Transmis/Recepționat (Trigger/Echo)
Pentru a reduce nivelul erorilor de acest gen (cazul 2) senzorul cu ultrasunete va fi poziționat pe un servomotor care va baleea incinta în care se află robotul și în cazul întâlnirii unui obstacol, indiferent de poziția acestuia în raport cu robotul se poate detecta prezența obiectului.
În figura 5.3 sunt prezentate cazuri care pot apărea în momentul deplasării robotului pe direcția înainte, deci va fi nevoie ca senzorul să facă măsurători în toate aceste direcții.
În concluzie vor trebui efectuate măsurători pe următoarele poziții:
Poziția 1 (obstacol în partea dreaptă 0 ̊ )
Poziția 2 (obstacol în partea dreaptă 45 ̊ )
Poziția 3 (obstacol în partea dreaptă 90 ̊ )
Poziția 4 (obstacol în partea dreaptă 135 ̊ )
Poziția 5 (obstacol în partea dreaptă 180 ̊ )
Fig. 5.3. Modul de verificare a zonei din fața robotului cu ajutorul servomotorului
Principiul care stă la baza unei măsurători fost prezentat anterior, astfel că se poate trece la proiectarea software a funcției care realizază obținerea distanței. În continuare se va prezenta sub forma unei organigrame modul de structurare al funcției getCM2(), funcția pentru măsurarea distanței folosită în cadrul proiectului.
Programul ce urmărește organigrama prezentată mai jos se află în partea de anexe (Anexa 3 Programul pentru senzorul cu ultrasunete). Atenție programul realizează doar o masurătoare, pentru a realiza toate cele 5 masurători necesarea acesta va trebui apelat de 5 ori , în momentul în care servomotorul a adus senzorul cu ultrasunete în poziția corespunzătoare
Trebuie precizat faptul că nici în acest punct măsurătorile nu sunt 100% relevante, acest lucru depinzând foarte mult și de poziția robotului în raport cu obstacolele din jurul său. De cele mai multe ori, decizia de schimbare a direcției robotului nu se va lua în funcție de distanța obținută într-o anumită direcție, ci de o comparare a tururor direcțiilor, în special celor adiacente distanței maxime, asta datorită faptului că în momentul în care semnalul Echo nu mai este recepționat rezultatul măsurării va fi maxim (400 cm) deci această distanță va fi una eronată, iar verificarea vecinilor poate da un rezultat relevant. În acest mod se reduce cu mult eroarea de măsurare a senzorului, iar direcția pe care se va deplasa robotul va fi una optimă.
Fig. 5.4. Organigrama funcției getCM2() (Anexa 3)
5.3 Controlul servomotorului Futaba S3003 [25]
Pentru a controla servomotorul trebuie generat un semal cu modulație a lațimii impulsului (PWM), cu o perioadă de 25ms iar lățimea impulsului între 500-2500μs.
Având în vedere că Raspberry Pi B+ nu are decât 2 pini pe care se poate genera PWM generarea semnalului se va realiza cu ajutorul ServoBlaster (o aplicație care generează pwm software pe orice pin GPIO special realizată pentru Raspberry)
Instalarea ServoBlaster va avea nevoie de introducerea următoarelor comenzi :
git clone https://github.com/richardghirst/PiBits.git
sudo apt-get install git-core
cd PiBits/ServoBlaster/kernel
make install
sudo modprobe servoblaster
make install_autostart
cd PiBits/ServoBlaster/user
make
./servod
ServoBlaster este un soft special conceput pentru Raspberry Pi, care oferă posibilitatea de a controla mai mutle servomotoare prin intermediul GPIO. Controlarea poziției servomotoarelor se realizează prin intermediul unui driver prin transmiterea unui impuls pwm pe un anumit port. Driver-ul va menține acel semnal până se va da o comandă de schimbare a acestuia.
Implicit driver-ul ServoBlaster este configurat să poată controla până la 8 servomotoare, dar manual poate fi configurat să comande până la 21. Servomotoarele în mod normal au nevoie de un impuls activ undeva între 0.5ms și 2.5ms, acest impuls controlând poziția acestuia. Impulsul trebuie să se repete la aproximativ 20ms, dar această perioadă nu este fixă, singurul lucru care afectează direct poziția servoului fiind lățimea impulsului. În plus pentru un control mult mai ușor și natural al servomotorului, ServoBlaster poate fi configurat să genereze impuls între 0% și 100% dintr-o lățime maximă a impulsului presetată (figura 5.5).
Fig. 5.5. Forma semnalului PWM în funcție de direcția dorită
După installare singurele linii de cod care trebuiesc introduse pentru a activa modulul ServoBlaster și a controla poziția unui servomotor sunt următoarele:
Știm că ServoBlaster este un soft pentru linia de comandă în C deci se folosește comanda specială pentru controlul consolei system(”comandă consolă”)
Pentru activarea software-ului,alegerea frecvenței semnalului, lățimii impulsului și port-ului GPIO pe care se va genera semnalul PWM se va folosi linia :
system (" sudo ./servod –pcm –cycle-time 25000 –max=220 –p1pins=22");
Pentru a seta o anumită poziție a servomotorului se va folosi linia de cod:
system ("echo 0=50% > /dev/servoblaster");
5.4 Funcția de control a motoarelor prin intermediul moduleleor Periferice Pmod HB5.
Într-un circuit analogic, viteza motoarelor este controlată prin varierea tensiunii de intrare a unui circuit. Într-un circuit digital, după cum știm nu avem decât două stări pentru tensiunea ce o putem aplica pe circuitul de control al motorului, ”1” logic sau ”0” logic. Deci există două moduri în care putem controla viteza unui motor cu un circuit digital: folosirea unui circuit cu rezistență veriabilă, pentru a controla tenziunea aplicată pe motor, sau pulsarea tensiunii pe motor. Stiind că realizarea unui circuit cu rezistență variabilă este destul de scumpă, complexă, durează, iar pierderea de energie sub formă de căldură este una destul de importantă, soluția mai bună este modulația PWM . [7]
Termenul PWM vine din limba engleză de la (Pulse Witdh Modulation și înseamnă că avem un semnal modulat în lățimea impulsului).Modulația în lățime a impulsuli este o metodă digitală a transmiterii unui semnal analogic, iar acest lucru este unul potrivit pentru controlarea motarelor. [7]
În figura 5.6 sunt ilustrate semnale PWM cu frecvența de 2KHz. Viteza motorului este controlată de timpul în care semnalul stă în 1 logic. La primul exemplu este exemplificat un procent de 10% „duty cycle” unde semnalul este în 1 logic adică avem un factor de umplere de 1/10. Acest 10% de nivel de 1 logic este egal cu 10% din intrarea de 3.3V, sau 0,33V. Exemplele 2 și 3 arată un duty cycle de 50% respectiv 75%. [7]
Fig. 5.6. Semnale modulate în lățimea impulsului (PWM) [7]
Realizarea programului software constă în funcția void motor(char direction) și este realiztă urmând pașii din organigrama prezentată mai jos. După cum se poate observa și din organigramă primul pas care se realizează în momentul în care se apelează funcția motor(char direction) este oprirea ambelor motoare pentru a evita distrugerea punților H ce controlează motoarele. Funcția are un singur parametru pe care trebuie să îl verifice ”direction”, în funcție de acesta se vor executa anumite operații asupra logicii pinilor plăcii Raspberry conectați la puntea H. [7]
Fig. 5.7. Organigrama programului funcției motor(char direction).
Fișierul sursă al funcției realizată după organigrama din figura 5.7 este prezentat la secțiunea anexe (Anexa 3). Această funcție este una secundară, utilizată în cadrul funcției de decizie ”decision()” a cărei organigramă va fi prezentată ulterior în cadrul proiectului.
5.5 Programul Principal
După cum s-a precizat în cerințele proiectului, robotul trebuie să fie unul autonom, deci va trebui să se deplaseze în interiorul unei încăperi, iar în momentul în care întâlnește un obstacol să se oprească să schimbe direcția și să își continue deplasarea.
Pecând de la aceste principii se va concepe organigrama programului principal (figura 5.8.) :
Fig. 5.8. Organigrama programului principal
Codul ce urmărește pașii descriși de această organigramă se găsește la secțiunea anexe, acesta făcând parte din fișierul main.c al aplicației. (Anexa 2 Fișierul main.c)
Pentru contolul logicii robotului se vor folosi două funcții de bază: obstacle_detection() și decision() adică funcția de detectare a unui obstacol și funcția de decizie.
Funcția obstacle_detection() returnează dacă există sau nu obstacol pe direcția în care se deplasează robotul. În interiorul acestei funcții este controlat servomotorul, care centrează senzorul HC-SR04 pe direcția pe care se dorește măsurarea și este folosită funcția de măsurare getCM2() . De reținut faptul că funcția obstacle_detection() nu salvează niciuna dintre distanțele pe care le măsoară doar returnează variabila locală obs care poate lua valoarea 0 logic în cazul în care nu există niciun obstacol la o distanță mai mică decât 30 cm în direcția de deplasare a robotului și valoarea 1 logic în cazul în care există obstacol. În cazul în care există un obstacol nu se mai continuă și cu verificarea celorlalte direcții ci se iese din funcție cu valoarea returnată obs=1 . Dacă nu pe direcția de deplasare a robotului nu se regăște nicun obstacol direcția de deplasare va fi înainte.
Lând în calcul principil de funcționare precizat mai sus se va realiza mai întâi o organigramă pe care putem urmări mai ușor funcția ce urmeaza a fi realizată (figura 5.9)
Fig. 5.9. Organigrama funcției obstacle_detection()
Codul ce urmărește pașii descriși de această organigramă se găsește la secțiunea anexe, acesta făcând parte din fișierul main.c al aplicației. (Anexa 2 Fișierul main.c). Pentru a avea continuitate în măsurarea distanțelor în interiorul aceleiași funcții s-a realizat verificarea distanțelor de la poziția 1 la poziția 4 și invers.
Funcția decision() va fi rulată decât în cazul în care valoarea returnată de către funcția obstacle_detection() este obs=1 . În ineriorul acestei funcții se va realiza măsurarea distanței pe toate cele 5 direcții prezentate in figura 5.10 dar cu avantajul că robotul stă pe loc iar eroarea de măsurare cauzată de deplasarea robotului este redusă la 0. Aceste măsurători vor fi salvate în variabile locale corespunzătoare fiecărei distanțe după care se va calcula atât distanța minimă cât și distanța maximă (funcțiile calcMaxDist(int dist1, int dist2, int dist3, int dist4, int dist5) și calcMinDist(int dist1, int dist2, int dist3, int dist4, int dist5) ).
Fig. 5.10. Cazuri de poziționare a obstacolelor în interiorul unei încăperi
În mod normal direcția în care se găsește maximul va fi și direcția de deplasare a robotului. Totuși va trebui luată în calcul eroarea de măsurare a robotului cauzată în special de poziționarea acestuia în raport cu obstacolul/obstacolele. După cum s-a prezentat mai sus în subcapitolul de proiectare al senzorului cu ultrasunete, rezultatul unei măsurători în cazul în care nu se mai recepționează semnalul echo este egal cu distanța maximă pe care o poate măsura senzorul adică în jur de 400 cm. Deci un obstacol poate fi mult mai aproape decât rezultatul obținut prin măsurare.
Evitarea erorii de măsurare se realizează prin comparare cu distanțele din imediata apropiere a distanței maxime (figura 5.11) . În momentul în care una dintre distanțe este mai mică decât distanța de gardă (30 cm) se va considera cazul în care unda este reflectată în afara razei de recepție a senzorului iar măsurătoarea va fi eronată.
Fig. 5.11. Caz în care una din distanțele masurate este eronată
În exemplul de mai sus este prezentat cazul în care unda echo de la măsurătoarea de pe poziția 2 nu se mai întoarce iar distanța este maximă. În acest caz se vor verifica și distanțele vecine poziției 2 (poziția 1 și poziția 3). În cazul de față pe ambele poziții se avflă un obstacol deci în acest caz este foarte probabil ca robotul să se afle lângă un obstacol care are forma din figura 5.12.
Fig. 5.12. Caz în care se poate obține o eroare de măsuare
Fig. 5.13. Organigrama funcției decision()
Programul realizat după organigrama din figura 5.13 se regăsește la secțiunea anexe facând parte din fișierul main.c (Anexa 2 Fișierul main.c).
Bibliografie
1. https://ro.wikipedia.org/wiki/Calculator
2. https://cs.curs.pub.ro/wiki/pm/lab/lab0?do=export_pd
3. https://ro.wikipedia.org/wiki/Raspberry_Pi
4. https://www.raspberrypi.org/help/faqs/
5. http://ro.wikipedia.org/wiki/Linux
6. https://blog.omgmog.net/post/
7. http://www.penguintutor.com/electronics/rpirobot
8. https://www.raspberrypi.org/community
9. http://digilentinc.com/Products/Detail.cfm?NavPath=2,398,1136&Prod=RSK
10. https://www.asus.com/ro/Networking/USBN10_NANO/
11. https://www.modmypi.com/blog/hc-sr04-ultrasonic-range-sensor-on-the-raspberry-pi
12. http://www.futaba-rc.com/servos/analog.html
13. http://www.digilentinc.com/Products/Detail.cfm?&Prod=PMOD-HB5
14. http://www.pads.com/
15. http:// stst.elia.pub.ro/news/SOA/Teme_SOA_13_14/SOA%20Raspi.ppt
16. Laborator Retele si servicii ionescu valeriu manuel.
17. https://learn.adafruit.com/setting-up-a-raspberry-pi-as-a-wifi-access-point
18. http://ro.wikipedia.org/wiki/SSH
19. http://ro.wikipedia.org/wiki/PuTTY
20.http://www.raspberry-projects.com/pi/programming-in-c/compilers-and-ides/geany/installing-geany
21. http://wiringpi.com/
22. http://ro.wikipedia.org/wiki/C_%28limbaj_de_programare%29
23. Alexandru ene Limbajul C/C++
24. http://macduino.blogspot.ro/2013/11/HC-SR04-part1.html
25. https://github.com/richardghirst/PiBits/tree/master/ServoBlaster
Anexe
Anexa 1 Fișierul header main.h
/*
File Name: main.h
File Type: header
Prject Name: Projectx1
Description:
*/
#ifndef MAIN_
#define MAIN_H
/* Flag */
char main_flag; //this is a flag for servomotor position
char motor_flag;
char reset_main_flag ; // this is a flag to reset the position of the servomotor
char stop_flag; //this is a flag to stop the robot until the check is finished
/* */
char current_state;
/* Ditante */
int first_state_distance;
int second_state_distance;
int third_state_distance;
int forth_state_distance;
int fifth_state_distance;
int sixth_state_distance;
int seventh_state_distance;
int eighth_state_distance;
int detection_contor;
int forward_flag;
int min_dist;
/* + Distance defs */
#define TRUE 1
#define TRIG2 29
#define ECHO2 28
/* – Distance defs */
int semafor;
int getCM();
int getCM2();
void setup1 (void);
void setHighPri (void);
void *displayDigits (void *dummy);
void teenager1 (void);
void teenager12 (void);
void intro(void);
void setup_pwm();
void motor(char direction);
int decision();
int obstacle_detection();
int calcMaxDist(int dist1, int dist2, int dist3, int dist4, int dist5);
int calcMinDist(int dist1, int dist2, int dist3, int dist4, int dist5);
enum{
FIRST_STATE = 0,
SECOND_STATE,
THIRD_STATE,
FORTH_STATE,
FIFTH_STATE,
SIXTH_STATE,
SEVENTH_STATE,
EIGHTH_STATE
};
enum{
LEFT = 0,
RIGHT,
FORWARD,
BACKWARD,
STOP
};
#endif /* end MAIN_H */
Anexa 2 Fișierul main.c
/*
File Name: main.C
File Type: source
Prject Name: Projectx1
Description:
*/
# include <stdio.h>
# include <stdlib.h>
# include <wiringPi.h>
# include "main.h"
void setup() {
wiringPiSetup();
pinMode(TRIG2, OUTPUT);
pinMode(ECHO2, INPUT);
/*Pwm Setup + */
pinMode (23, PWM_OUTPUT) ;
pinMode (1, PWM_OUTPUT) ;
pinMode (4, OUTPUT);
pinMode (22, OUTPUT);
/*Pwm Setup – */
digitalWrite(TRIG2, LOW);
delay (30);
}
int main(void)
{
setup();
system (" sudo ./servod –pcm –cycle-time 25000 –max=220 –p1pins=22");
system ("echo 0=50% > /dev/servoblaster");
printf ("Asteapta calibrarea Servomotorului/Robotului \n") ;
delay (2000);
printf ("Raspberry Pi wiringPi PWM Dc Motor Test \nPress CTRL+C to EXIT program\n") ;
while (1)
{
if(obstacle_detection() == 0){
motor(FORWARD);
}
else{
motor(decision());
delay (550);
motor(STOP);
delay (450);
}
}
}
int obstacle_detection(){
int obs = 0;
int dist = 0 ;
// Forward
system ("echo 0=50% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
//Right 25%
system ("echo 0=25% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
//Right 0%
system ("echo 0=0% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
//Right 25%
system ("echo 0=25% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
// Forward
system ("echo 0=50% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
// Left 75%
system ("echo 0=75% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
// Left 100%
system ("echo 0=100% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
// Left 75%
system ("echo 0=75% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
return obs;
}
int decision(){
int maxDist = 0;
int returnValue = -1;
int dist_right = 0, dist_right25 = 0, dist_forward = 0, dist_left75 = 0, dist_left = 0 ;
motor(STOP);
delay(50);
system ("echo 0=0% > /dev/servoblaster");
delay(600);
dist_right=getCM2();
system ("echo 0=25% > /dev/servoblaster");
delay(300);
dist_right25=getCM2();
system ("echo 0=50% > /dev/servoblaster");
delay(300);
dist_forward=getCM2();
system ("echo 0=75% > /dev/servoblaster");
delay(300);
dist_left75=getCM2();
system ("echo 0=100% > /dev/servoblaster");
delay(300);
dist_left=getCM2();
system ("echo 0=50% > /dev/servoblaster");
delay(400);
printf ("Distantele: %d,%d,%d,%d,%d\n",dist_right,dist_right25,dist_forward,dist_left75,dist_left) ;
maxDist = calcMaxDist(dist_right, dist_right25, dist_forward, dist_left75, dist_left);
if(maxDist == dist_right){
if((dist_right25 > 30)&(dist_forward > 30)){
returnValue = RIGHT;
}
else{
returnValue = LEFT;
}
}
else if(maxDist == dist_right25){
if((dist_right > 30)&(dist_forward > 30)){
returnValue = RIGHT;
}
else if((dist_forward < 30)&(dist_left < 30)){
returnValue = RIGHT;
}
else{
returnValue = LEFT;
}
}
else if(maxDist == dist_forward){
if((dist_right25 > 30)&(dist_left75 > 30)&(dist_right > 20)&(dist_left >20)){
returnValue = FORWARD;
}
else if((dist_right > 30)&(dist_right25 > 30)){
returnValue = RIGHT;
}
else if((dist_left > 30)&(dist_left75 > 30)){
returnValue = LEFT;
}
else{
returnValue = BACKWARD;
}
}
else if(maxDist == dist_left75){
if((dist_left > 30)&(dist_forward > 30)){
returnValue = LEFT;
}
else if ((dist_forward < 30)&(dist_right < 30)){
returnValue = LEFT;
}
else{
returnValue = RIGHT;
}
}
else if(maxDist == dist_left){
if((dist_left75 > 30)&(dist_forward > 30)){
returnValue = LEFT;
}
else{
returnValue = RIGHT;
}
}
return returnValue;
}
// Detect max
int calcMaxDist(int dist1, int dist2, int dist3, int dist4, int dist5){
int maxDist = 0;
maxDist = dist1;
if(maxDist < dist2){
maxDist = dist2;
}
if(maxDist < dist3){
maxDist = dist3;
}
if(maxDist < dist4){
maxDist = dist4;
}
if(maxDist < dist5){
maxDist = dist5;
}
return maxDist;
}
// Detect min
int calcMinDist(int dist1, int dist2, int dist3, int dist4, int dist5){
int minDist = 10000;
minDist = dist1;
if(minDist > dist2){
minDist = dist2;
}
if(minDist > dist3){
minDist = dist3;
}
if(minDist > dist4){
minDist = dist4;
}
if(minDist > dist5){
minDist = dist5;
}
return minDist;
}
Anexa 3 Controlul motoarelor Funcția motor();
/*
***********************************************************************
File Name: pwm.C
File Type: source
Prject Name: Projectx1
Description:
***********************************************************************
*/
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "main.h"
void motor(char direction){
pwmWrite (23,0 );
pwmWrite (1, 0) ;
delay (10) ;
if (direction == FORWARD){
digitalWrite(4 , 0);
digitalWrite(22 , 1);
}
else if(direction == LEFT){
digitalWrite(4 , 0);
digitalWrite(22 , 0);
}
else if(direction == RIGHT){
digitalWrite(4 , 1);
digitalWrite(22 , 1);
}
else if(direction == BACKWARD){
digitalWrite(4 , 1);
digitalWrite(22 , 0);
}
delay(1);
if (direction == STOP)
{
pwmWrite (23,0 );
pwmWrite (1, 0) ;
delay (1) ;
}
if (direction == FORWARD){
pwmWrite (23, 440) ;
pwmWrite (1, 440) ;
}
else if(direction == LEFT){
pwmWrite (23, 440) ;
pwmWrite (1, 440) ;
}
else if(direction == RIGHT){
pwmWrite (23, 440) ;
pwmWrite (1, 440) ;
}
else if(direction == BACKWARD){
pwmWrite (23, 440) ;
pwmWrite (1, 440) ;
}
}
Anexa 4 Programul pentru senzorul cu ultrasunete
/*
File Name: ussensor.c
File Type: source
Prject Name: Projectx1
Description:
*/
# include <wiringPi.h>
# include "main.h"
int getCM2() {
digitalWrite(TRIG2, HIGH);
delayMicroseconds (20);
digitalWrite(TRIG2, LOW);
while(digitalRead(ECHO2)==LOW);
long startTime2 = micros();
while(digitalRead(ECHO2)==HIGH);
long travelTime2=micros() – startTime2;
int distance2 = travelTime2/58;
return distance2;
}
Bibliografie
1. https://ro.wikipedia.org/wiki/Calculator
2. https://cs.curs.pub.ro/wiki/pm/lab/lab0?do=export_pd
3. https://ro.wikipedia.org/wiki/Raspberry_Pi
4. https://www.raspberrypi.org/help/faqs/
5. http://ro.wikipedia.org/wiki/Linux
6. https://blog.omgmog.net/post/
7. http://www.penguintutor.com/electronics/rpirobot
8. https://www.raspberrypi.org/community
9. http://digilentinc.com/Products/Detail.cfm?NavPath=2,398,1136&Prod=RSK
10. https://www.asus.com/ro/Networking/USBN10_NANO/
11. https://www.modmypi.com/blog/hc-sr04-ultrasonic-range-sensor-on-the-raspberry-pi
12. http://www.futaba-rc.com/servos/analog.html
13. http://www.digilentinc.com/Products/Detail.cfm?&Prod=PMOD-HB5
14. http://www.pads.com/
15. http:// stst.elia.pub.ro/news/SOA/Teme_SOA_13_14/SOA%20Raspi.ppt
16. Laborator Retele si servicii ionescu valeriu manuel.
17. https://learn.adafruit.com/setting-up-a-raspberry-pi-as-a-wifi-access-point
18. http://ro.wikipedia.org/wiki/SSH
19. http://ro.wikipedia.org/wiki/PuTTY
20.http://www.raspberry-projects.com/pi/programming-in-c/compilers-and-ides/geany/installing-geany
21. http://wiringpi.com/
22. http://ro.wikipedia.org/wiki/C_%28limbaj_de_programare%29
23. Alexandru ene Limbajul C/C++
24. http://macduino.blogspot.ro/2013/11/HC-SR04-part1.html
25. https://github.com/richardghirst/PiBits/tree/master/ServoBlaster
Anexe
Anexa 1 Fișierul header main.h
/*
File Name: main.h
File Type: header
Prject Name: Projectx1
Description:
*/
#ifndef MAIN_
#define MAIN_H
/* Flag */
char main_flag; //this is a flag for servomotor position
char motor_flag;
char reset_main_flag ; // this is a flag to reset the position of the servomotor
char stop_flag; //this is a flag to stop the robot until the check is finished
/* */
char current_state;
/* Ditante */
int first_state_distance;
int second_state_distance;
int third_state_distance;
int forth_state_distance;
int fifth_state_distance;
int sixth_state_distance;
int seventh_state_distance;
int eighth_state_distance;
int detection_contor;
int forward_flag;
int min_dist;
/* + Distance defs */
#define TRUE 1
#define TRIG2 29
#define ECHO2 28
/* – Distance defs */
int semafor;
int getCM();
int getCM2();
void setup1 (void);
void setHighPri (void);
void *displayDigits (void *dummy);
void teenager1 (void);
void teenager12 (void);
void intro(void);
void setup_pwm();
void motor(char direction);
int decision();
int obstacle_detection();
int calcMaxDist(int dist1, int dist2, int dist3, int dist4, int dist5);
int calcMinDist(int dist1, int dist2, int dist3, int dist4, int dist5);
enum{
FIRST_STATE = 0,
SECOND_STATE,
THIRD_STATE,
FORTH_STATE,
FIFTH_STATE,
SIXTH_STATE,
SEVENTH_STATE,
EIGHTH_STATE
};
enum{
LEFT = 0,
RIGHT,
FORWARD,
BACKWARD,
STOP
};
#endif /* end MAIN_H */
Anexa 2 Fișierul main.c
/*
File Name: main.C
File Type: source
Prject Name: Projectx1
Description:
*/
# include <stdio.h>
# include <stdlib.h>
# include <wiringPi.h>
# include "main.h"
void setup() {
wiringPiSetup();
pinMode(TRIG2, OUTPUT);
pinMode(ECHO2, INPUT);
/*Pwm Setup + */
pinMode (23, PWM_OUTPUT) ;
pinMode (1, PWM_OUTPUT) ;
pinMode (4, OUTPUT);
pinMode (22, OUTPUT);
/*Pwm Setup – */
digitalWrite(TRIG2, LOW);
delay (30);
}
int main(void)
{
setup();
system (" sudo ./servod –pcm –cycle-time 25000 –max=220 –p1pins=22");
system ("echo 0=50% > /dev/servoblaster");
printf ("Asteapta calibrarea Servomotorului/Robotului \n") ;
delay (2000);
printf ("Raspberry Pi wiringPi PWM Dc Motor Test \nPress CTRL+C to EXIT program\n") ;
while (1)
{
if(obstacle_detection() == 0){
motor(FORWARD);
}
else{
motor(decision());
delay (550);
motor(STOP);
delay (450);
}
}
}
int obstacle_detection(){
int obs = 0;
int dist = 0 ;
// Forward
system ("echo 0=50% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
//Right 25%
system ("echo 0=25% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
//Right 0%
system ("echo 0=0% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
//Right 25%
system ("echo 0=25% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
// Forward
system ("echo 0=50% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
// Left 75%
system ("echo 0=75% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
// Left 100%
system ("echo 0=100% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
// Left 75%
system ("echo 0=75% > /dev/servoblaster");
delay(200);
dist = getCM2();
if(dist < 30){
motor(STOP);
obs = 1;
return obs;
}
return obs;
}
int decision(){
int maxDist = 0;
int returnValue = -1;
int dist_right = 0, dist_right25 = 0, dist_forward = 0, dist_left75 = 0, dist_left = 0 ;
motor(STOP);
delay(50);
system ("echo 0=0% > /dev/servoblaster");
delay(600);
dist_right=getCM2();
system ("echo 0=25% > /dev/servoblaster");
delay(300);
dist_right25=getCM2();
system ("echo 0=50% > /dev/servoblaster");
delay(300);
dist_forward=getCM2();
system ("echo 0=75% > /dev/servoblaster");
delay(300);
dist_left75=getCM2();
system ("echo 0=100% > /dev/servoblaster");
delay(300);
dist_left=getCM2();
system ("echo 0=50% > /dev/servoblaster");
delay(400);
printf ("Distantele: %d,%d,%d,%d,%d\n",dist_right,dist_right25,dist_forward,dist_left75,dist_left) ;
maxDist = calcMaxDist(dist_right, dist_right25, dist_forward, dist_left75, dist_left);
if(maxDist == dist_right){
if((dist_right25 > 30)&(dist_forward > 30)){
returnValue = RIGHT;
}
else{
returnValue = LEFT;
}
}
else if(maxDist == dist_right25){
if((dist_right > 30)&(dist_forward > 30)){
returnValue = RIGHT;
}
else if((dist_forward < 30)&(dist_left < 30)){
returnValue = RIGHT;
}
else{
returnValue = LEFT;
}
}
else if(maxDist == dist_forward){
if((dist_right25 > 30)&(dist_left75 > 30)&(dist_right > 20)&(dist_left >20)){
returnValue = FORWARD;
}
else if((dist_right > 30)&(dist_right25 > 30)){
returnValue = RIGHT;
}
else if((dist_left > 30)&(dist_left75 > 30)){
returnValue = LEFT;
}
else{
returnValue = BACKWARD;
}
}
else if(maxDist == dist_left75){
if((dist_left > 30)&(dist_forward > 30)){
returnValue = LEFT;
}
else if ((dist_forward < 30)&(dist_right < 30)){
returnValue = LEFT;
}
else{
returnValue = RIGHT;
}
}
else if(maxDist == dist_left){
if((dist_left75 > 30)&(dist_forward > 30)){
returnValue = LEFT;
}
else{
returnValue = RIGHT;
}
}
return returnValue;
}
// Detect max
int calcMaxDist(int dist1, int dist2, int dist3, int dist4, int dist5){
int maxDist = 0;
maxDist = dist1;
if(maxDist < dist2){
maxDist = dist2;
}
if(maxDist < dist3){
maxDist = dist3;
}
if(maxDist < dist4){
maxDist = dist4;
}
if(maxDist < dist5){
maxDist = dist5;
}
return maxDist;
}
// Detect min
int calcMinDist(int dist1, int dist2, int dist3, int dist4, int dist5){
int minDist = 10000;
minDist = dist1;
if(minDist > dist2){
minDist = dist2;
}
if(minDist > dist3){
minDist = dist3;
}
if(minDist > dist4){
minDist = dist4;
}
if(minDist > dist5){
minDist = dist5;
}
return minDist;
}
Anexa 3 Controlul motoarelor Funcția motor();
/*
***********************************************************************
File Name: pwm.C
File Type: source
Prject Name: Projectx1
Description:
***********************************************************************
*/
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "main.h"
void motor(char direction){
pwmWrite (23,0 );
pwmWrite (1, 0) ;
delay (10) ;
if (direction == FORWARD){
digitalWrite(4 , 0);
digitalWrite(22 , 1);
}
else if(direction == LEFT){
digitalWrite(4 , 0);
digitalWrite(22 , 0);
}
else if(direction == RIGHT){
digitalWrite(4 , 1);
digitalWrite(22 , 1);
}
else if(direction == BACKWARD){
digitalWrite(4 , 1);
digitalWrite(22 , 0);
}
delay(1);
if (direction == STOP)
{
pwmWrite (23,0 );
pwmWrite (1, 0) ;
delay (1) ;
}
if (direction == FORWARD){
pwmWrite (23, 440) ;
pwmWrite (1, 440) ;
}
else if(direction == LEFT){
pwmWrite (23, 440) ;
pwmWrite (1, 440) ;
}
else if(direction == RIGHT){
pwmWrite (23, 440) ;
pwmWrite (1, 440) ;
}
else if(direction == BACKWARD){
pwmWrite (23, 440) ;
pwmWrite (1, 440) ;
}
}
Anexa 4 Programul pentru senzorul cu ultrasunete
/*
File Name: ussensor.c
File Type: source
Prject Name: Projectx1
Description:
*/
# include <wiringPi.h>
# include "main.h"
int getCM2() {
digitalWrite(TRIG2, HIGH);
delayMicroseconds (20);
digitalWrite(TRIG2, LOW);
while(digitalRead(ECHO2)==LOW);
long startTime2 = micros();
while(digitalRead(ECHO2)==HIGH);
long travelTime2=micros() – startTime2;
int distance2 = travelTime2/58;
return distance2;
}
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Sistem Mobil Comandat Prin Raspberry Pi (ID: 163552)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
