HobbyElectro

Petrescu Cristian . Un produs Blogger.

sâmbătă, 16 august 2014

MACARA DIN MECCANO SI ARDUINO

0 comentarii | Read more...

Cum a inceput...


     Cand omul nu are ce face ... isi gaseste !  Asa si eu. Tot discutand cu un prieten (salutare Viorel) despre infinitele posibilitati pe care le ofera microcontroller-le si implicit Arduino m-am gandit ca nu ar fi rau daca as incerca sa realizez un proiect in care sa se imbine electronica cu mecanica. Cum sunt mare fan MECCANO si cum detin vreo trei kituri (mai mult sau mai putin complete) am tras concluzia ca o macara ar  fi numai buna pentru inceput.

     Asadar acest proiect nu reprezinta o provocare din punct de vedere electronic ci mai degraba din punct de vedere mecanic, deoarece a fost destul de complicat de realizat aceasta parte.



Ce s-a dorit...

     Ideea era sa realizam un mecanism de ridicare-coborare asezat pe o platforma care sa il plimbe acolo unde se gasea sarcina. Astfel, dupa multe variante (si sute de suruburi asamblate si dezasamblate) am cazut de acord  ca mecanismul trebuie sa aiba urmatoarele functii:

  1. Ridicare - Coborare carlig
  2. Translatie - pe orizontala a sarcinii
Toata hardughia trebuie sa fie manevrata dintr-un joystick!

Ce a iesit...

Se vede in poze !



VEDERE DE ANSAMBLU


MECANISME DE RIDICARE SI TRANSLATIE


VEDERE GENERALA 


PARTEA DE COMANDA

Cum s-a facut...

     Creierul este un Arduino DueMilaNove , ajutat de doua drivere de motoare de cc L293D. Fiecare Driver poate comanda 2 motoare in ambele sensuri de turatie. Pentru a scadea puterea disipata pe fiecare driver s-a considerat intercalarea motoarelor, in sensul ca daca se doreste miscarea platformei cu ambele motoare in fuctiune fiecare motor sa fie conecatat la un driver separat. Asadar fiecare driver are conectat la el doua motoare: unul al macaralei si unul care plimba platforma. Comanda motoarelor este evident realizata prin modificarea factorului de umplere (PWM). Alimentarea montajelor se relizeaza astfel:
  • pentru Arduino - baterie de 9V
  • motoare 4 baterii R6 - 6V.
     Comanda efectiva este realizata utilizand un gamepad, care a fost modificat pentru a fi interfatat cat mai usor cu Arduino. In acest sens se utilizeaza cele patru sageti pentru manevrarea platformei si doua butoane, care daca sunt tinute apasate, in combinate cu cele patru directii actioneaza mecanismul de ridicare-coborare respectiv cel de transalatie al macaralei.

     Sasiul a fost realizat din placaj din carton presat taiat cu muuulta rabdare cu traforajul (oare nu se se mai gaseste nicaieri  placaj adevarat de traforaj ?).

     Cam asta ar fi, singura parere de rau este faptul ca pentru a putea face noi proiecte va trebui demontata toata jucaria!









sâmbătă, 9 august 2014

Despre Pinguino

0 comentarii | Read more...

Zvarcolindu-ma de caldura m-am apucat sa hoinaresc hai-hui pe plaiurile internetului, ca de obicei fara un scop precis. Din-ntruna in alta am dat peste un proiect (evident open source) care incearca sa pastreze simplitatea lui Arduino utilizand insa un microcontroller de tip PIC : PINGUINO. 

De ce l-au numit asa ? Probabil dezvoltatorii sunt mari iubitori de Linux sau poate este o iornie fina la adresa celor care se perpelesc la 40 de grade Celsius facandu-i astfel  sa viseze catre meleaguri mai racoroase.  

Din cate am vazut, proiectul este inceput de cativa ani insa, desi (cel putin din punctul meu de vedere) prezinta potential, nu a facut prea mare valva.  In esenta se pot utiliza uC-le PIC din seria 18F cu conditia sa aiba suficenta memorie ROM pentru a putea incarca bootloader-ul (7KB !!!!!!) dar si un modul USB integrat hardware. Pe pagina oficiala se gasesc detalii despre uC suportate si schemele de realizare practica a placutelor de dezvoltare. 

M-am hotarat sa realizez si eu un "PINGUINO" in configuratia PIC 18F4550 cu cristal de 20MHz, concluziile fiindu-va prezentate in ele ce urmeaza. 

Plecand de la schema electronica propusa de producatori am realizat un cablaj imprimat pe care am plantat componentele.



Schema electronica originala propusa de producatori


Pentru inceput...

Initial cand am vazut schema am fost foarte incantat pentru ca am intuit faptul ca atat pentru programare cat si pentru comunicatia cu PC-ul se utilizeaza direct conexiunea USB. Adio programatoare externe oricare ar fi ele: FTDI, convertoare TTL, PICKIT 2 sau 3 etc. Dar ca de obicei exista un "dar", pe care il voi discuta ceva mai tarziu. Deocamdata toate sunt bune si frumoase.

Revenind la schema, nimic nu pare complicat: nu este decat minim-minmorum-ul necesar pentru a se putea utiliza uC-ul. In fine, poate doar RUN LED necesita ceva explicatii. In esenta este un fel de PIN 13 al lui Arduino care permite testarea placii fara a utiliza componente externe dar are si rolul de a semnaliza daca uC-ul este modul bootloader sau in modul de executie a programului scris de utilizator. Ce???? 

Da. Aici incepe prima parte a lui "dar". Dupa ce se realizeaza montajul si dupa ce se "arde" in uC bootloader-ul butonul de reset nu mai este ceea ce a fost la inceput:  un simplu buton de reset ci este unealta prin care se schimba starea uC-ului din modul de executie a programului in modul bootloader. O data apasat butonul (presupunand ca in uC se afla incarcat un program, altul decat bootloader-ul) programul utilizatorului se sterge putandu-se astfel incarca un nou program. Nu incercati sa incarcati un alt program daca uC-ul nu este modul bootloader pentru ca IDE-ul nu il va detecta. De ce asa ?? Nu stiu, dar probabil exista un scop bine intemeiat pentru care dezvoltatorii au facut chestia asta. Singura cale de a reseta uC-ul este aceea de a intrerupe alimentarea, deci un comutator fie pe masa fie pe "plus".  Revenind la RUN LED acesta pulseaza foarte repede in modul bootloader facand astfel semnalizarea posibila. Problema este ca in modul de rulare a programului scris de utilizator RUN LED se aprinde numai daca PIN 6 este pus la masa. Asadar comanda digitalWrite(USERLED, HIGH) este echivalenta cu stingerea ledului iar digitalWrite(USERLED, LOW) este echivalenta cu aprinderea ledului. De ce ?? Nu stiu. 

Cablajul...

Am realizat doua cablaje: primul dupa schema originala, executat si testat, si al doilea cu RUN LED -ul conecat cu anodul la PIN 6 pentru a preintampina problema descrisa mai sus. 

1. Schema originala - RUN LED cu catodul la PIN 6.

Scheama realizata dupa indicatiile dezvoltatorilor


Plasarea componentelor



2. Schema modificata - RUN LED cu anodul la PIN 6.


Schema modificata RUNLED cu anod la PIN6

Plasarea componentelor varianta 2

Se observa clar modul ca pentru a putea inghesui montajul intr-un spatiu cat mai  mic este necesar sa se monteze uC pe un soclu pentru ca rezistentele (R1,R2,R3) si condensatoarele (C1 si C4) SA poata fi montate sub el. Cablajele in format pdf le puteti descarca de aici.

Instalarea...

Aici incepe cea de-a doua parte a lui "dar". Pentru a putea utiliza ceea ce am realizat mai sus trebuie instalate doua drivere: primul dintre ele reprezinta driverul pentru modul de bootloader si practic face posibila transfrarea codului din PC in PIC iar cel de-al doilea este necesar atunci cand se doreste realizarea unei comunicatii seriale cu PC-ul (dupa ce a fost incarcat codul utilizatorului). Cel de-al doilea driver este utilizat de PC numai atunci cand utilizatorul a scris un cod care utilizeaza libraria CDC (Communication Device Class). Este un driver pus la dispozitie de Microchip si  realizeaza un port COM virtual pentru a se putea realiza comunicatia seriala. Pentru a nu trece prin chinurile instalarii o sa descriu aici procedura de instalare in cativa pasi simpli.
  1. Scrieti un cod care utilizeaza libraria CDC, poate fi chiar unul din cele doua exemple.
  2. Treceti Pinguino in modul bootloader apasand butonul de reset.
  3. Uploadati codul in PIC. Atentie!!!!! In IDE trebuie sa alegeti placa si botloader-ul corespunzator.
  4. Windows-ul fericit va detecta un nou device. Apoi nefericit va zice ca nu are drivere pentru el.
  5. Deschideti device manager-ul si veti vedea acolo un device numit PINGUINO cu un semn de exclamare galben.
  6. Downloadati driverul de aici.
  7. Instalati driverul in Windows 95 style :-) . 
  8. Click dreapta pe PINGUINO alegeti properties, update driver, browse my computer, let me pick, ports (com & lpt), click next, click have disk, alegeti folderul in care ati dezarhivat driverul. Windows-ul il va instala nu inainte de a va atentiona ca... bla bla bla. 

Pentru a putea trimite si primi date (la fel ca ) la Arduino va recomad din tot sufletul sa utilizati Putty.
Este gratis si functioneaza perfect. Si aici va vand un pont: dupa ce il configurati pentru modul serial pentru a
fi vizualizate datele trimise din consola este bine sa se bifeze in sectiunea Terminal Local eccho - Force on
si  Local line editing - Force on.

Utilizarea ...

Mediul de programare este destul de prietenos si se doreste a fi o clona a celui utilizat de Arduino. Si aici 
gasim o multitudine librarii unele pentru device-uri altele pentru utilizarea mai usoara a modulelor interne ale
PIC-ului (timere, intreruperi, PWM etc.).  Ca si la Arduino exista cele doua functii obligatorii void setup()
si void loop()  partea frumoasa, zic eu, este ca in setup se pot seta parametrii uC-ului in doua moduri.
Primul mod este "Arduino Style" iar cel de-al doilea este tipc pentru PIC utilizand registrii interni ai acestuia.
De fapt aceasta facilitate poate fi utilizata oriunde in program facand din PINGUINO o unealta mult mai 
versatila decat Arduino.

Incheiere...

Personal cred voi petrece ceva timp jucandu-ma cu PINGUINO testanad diverse programe. Nu este atat
de prietenos ca Arduino dar prezinta posibilitati de utilizare destul de interesante pe care daca timpul imi va
permite as dori sa le exploatez.
Iaca si ceva poze cu motajul realizat de mine:

PARTEA PLANTATA

TRASEE SI LIPITURI







duminică, 9 martie 2014

ANIMATIE MATRICE 8X8 CU ARDUINO SI PROCESING

1 comentarii | Read more...

     In timp ce ma pregateam sa dezasamblez montajul din articolul trecut mi-a venit o idee : ce ar fi daca as trimite date de la PC la Arduino in asa fel incat sa se creeze o animatie pe matricea de leduri?



   La prima vedere parea destul de simplu insa pe masura ce am inceput sa scriu codul pentru PC lucrurile au inceput sa se complice, insa in final am reusit sa ating obiectivul propus.
    Ideea este urmatoarea: se pot inregistra maxim 8 frameuri, care printr-o simpla apasare de buton vor fi trimise prin interfata seriala catre Arduino acesta ruland fiecare frame o anumita perioada de timp, apoi trecand la urmatorul. Cum niste imagini fac mai mult decat 1000 de cuvinte sa vedem cum functioneaza programul:

BUTOANE DE COMANDA

     Asadar dupa alegerea tiparului (apsand ledurile dorite a fi aprinse pentru frame-ul respectiv) se apasa butonul "REC" . Se va observa ca dupa apsarea acestuia se vor intampla doua lucruri : primul culoarea numarului "FRAME CURENT" se va schimba in verde, semn ca frameul este inregistrat iar al doilea lucru care se intampla este ca vom putea trece la frame-ul urmator prin apasarea butonului ">>" :

PRIMUL FRAME

     Dupa inregistrare se poate trece la frame-ul urmator unde pentru o mai usoara orientare a fost deja copiat frameul anterior fara insa a fi inregistrat (se observa culoarea alba a numarului de frame):

FRAME-UL 2 NEINREGISTRAT


     Dupa editarile aferente se inregistreaza si acest frame :


FRAME-UL 2 INREGISTRAT
     Se continua acest algoritm pentru un numar de maximum 8 frame-uri iar cand cand au fost terminate inregistrarile se trimit catre Arduino apasand butonul "SEND".  Dupa primirea datelor, Arduino va rula programul independent de Processing, adica datele sunt salvate in ram. Daca se doreste stocarea definitiva a unui anumit tipar, acesta poate fi salvat in eeprom-ul lui Arduino. Eu nu mi-am batut prea tare capul cu asta deoarece am fost interesat doar de metoda propriu-zisa de comunicare. 
     Daca a fost gresit introdus unul din frame-uri sau daca se doreste modificarea tiparului butoanele "<<" si ">>" ne permit navigarea pana la frame-ul dorit. O data ajunsi acolo realizam modificarile dupa care le inregistram si le trimitem mai departe lui Arduino. Destul de simplu zic eu...  

      Deoarece codul este destul de lung si greu de urmarit voi atasat arhiva cu codurile sursa care se poate descarca de (download AICI (HERE) .

      Enjoy !!

vineri, 28 februarie 2014

MATRICE LEDURI CU ARDUINO SI PROCESSING

0 comentarii | Read more...

     Imi doream de ceva vreme sa experimentez cu o matrice cu leduri. La vremea cand ma batea acest gand nu am gasit de vanzare matrici 8x8, asa ca mi-am construit una. Acum ca am gasit resursele de timp necesare am zis sa ma joc putin cu ea impreuna bineinteles cu Arduino. De la inceput am remarcat ca pentru a afisa diferite tipare pe matrice trebuie introduse in programul scris pentru Arduino datele respective sub forma de bytes. Daca dupa incarcare rezultatul nu este cel dorit ... se modifica programul cu datele noi ... se reincarca si tot asa. Ce ar fi insa daca Arduino ar primi datele de pe un PC, printr-o  interfata grafica prietenoasa urmand ca apoi sa le afiseze in timp real pe matrice? 
     Urmarind ideea de mai sus am scris un mic programel in processing care fix asta face. Iata un screenshot: 

INTERFATA PROCESSING

CEEA CE SE VEDE :)




    Asadar: dupa rularea programului in Processing suntem intampinati de fereastra de mai sus. Mai departe totul este intuitiv: se deseneaza tiparul printr-un simplu click pe fiecare led iar apoi se trimit datele catre Arduino apasand butonul send. 
     Inainte de a posta codurile sa aruncam un ochi pe schema pentru a intelege modul de functionare:

SCHEMA ELECTRONICA
     Tranzistoarele Q1-Q8 reprezinta coloanele iar Q9-Q16 reprezinta liniile. Odata polarizat, un tranzistor "de coloana", va permite aprinderea oricarui led care apartine acelei coloane cu conditia ca ledul la randul sau  sa fie polarizat corespunzator. De acest fapt se ocupa tranzistoarele "de linii". Dupa cum se vede si in schema Q1 fiind deschis va permite aprinderea oricarui led de pe coloana 1 cu conditia ca tranzistorul aferent acelei linii sa fie deschis.Urmarind rationamentul si privind poza inseamna ca Q9-Q16 sunt deschise. Daca Q1 se inchide si se deschide Q2 atunci toata coloana 2 se va aprinde, si asa mai departe. Din cele mentionate anterior rezulta ca o anumita imagine pe matrice se poate obtine daca se deschid pe rand tranzistoarele "de coloana", iar in timpul in care acestea sunt in stare de conductie se deschid numai tranzistoarele "de linie" care formeaza imaginea.  

      Iata si codurile:

1. Processing :
    1.1. Programul propriuzis:


import processing.serial.*;
Serial arduino;


led[] led_matrix  = new led [64];
int [] columns = new int[8];
byte[] to_send=new byte [16];
int y;
int x;
int startx=50;
int starty=50;
int back=125;
button send=new button(120,350,30,100,"SEND");

void setup() {
  size(500,400);
  background(back);
  arduino = new Serial(this, Serial.list()[0], 9600);
  for(int i=0;i<64;i++){
    if(i%8==0&&i>0){
      y++;
      x=0;
    }
    led_matrix[i]=new led(30,startx+x*35,starty+y*35);
    x++;
  }
}

void split(){
  int j=0;
  int h_nibble=240;
  int l_nibble=15;
  for(int i=0;i<8;i++){
    to_send[j]= (byte)(((h_nibble & columns[i])>>4)|16);
    to_send[j+1]= (byte)((l_nibble & columns[i])|16);
    print(to_send[j]);
    print("/");
    print(to_send[j+1]);
    print("//");
    j=j+2;
  } 
  println("");
  println("_______________________________________________________");
  for(int i=0;i<16;i++){
    arduino.write(to_send[i]);
  }
}

void draw(){
  stroke(0,0,0);
  int index=0;
  fill(0,255,0);
  rect(send.x_corner,send.y_corner,send.b_width,send.b_height);
  fill(0,0,255);
  textSize(16);
  text(send.caption,send.x_corner+30,send.y_corner+20);
  for(int i=0;i<led_matrix[0].size; i++){
    if(!led_matrix[i].state){
      fill(100,0,0);
    }
    if(led_matrix[i].state){
      fill(255,0,0);
    }
    ellipse(led_matrix[i].x_center,led_matrix[i].y_center,30,30);
  }
  fill(back);
  noStroke();
  rect(led_matrix[0].x_center-10,led_matrix[0].y_center-50,290,30);
  for(int i=0;i<8;i++){
    fill(255,255,255); 
    text(columns[i],led_matrix[i].x_center-5,led_matrix[i].y_center-30);
  }
}

void mouseClicked(){
  int end=0;
  int start=0;
  int j=0;
  int col_val=0;
  int step=0;
  boolean k=false;
  for(int i=0;i<64;i++){
    if((led_matrix[i].x_center-15<mouseX && led_matrix[i].x_center+15>mouseX) &&
    (led_matrix[i].y_center-15<mouseY && led_matrix[i].y_center+15>mouseY)
    ){
      led_matrix[i].state =!led_matrix[i].state;
      led_matrix[i].bin=abs(led_matrix[i].bin-1);
    }
  }
  if((send.x_corner<mouseX&&(send.x_corner+send.b_width)>mouseX)&&
  (send.y_corner<mouseY&&(send.y_corner+send.b_height)>mouseY)){
    k=true;
  }
  while(end<64){
    end=64-(7-start);
    for(int i=start;i<end;i=i+8){
      if(led_matrix[i].state==true){
        col_val=col_val|led_matrix[i].bin<<step;
      }
      step++;
    }
    start++;
    columns[j]=col_val;
    col_val=0;
    j++;
    step=0;
  }
  if(k){
    split();
    k=false;
  }
}

    1.2. Clasa led:


class led{
  static int size;
  public int diameter;
  public int x_center;
  public int y_center;
  public boolean state;
  public int bin;
  public led(int d, int x,int y){
    size++;
    this.diameter=d;
    this.x_center=x;
    this.y_center=y;
    this.state=false;
  }
}

    1.3. Clasa button:


class button {
  public int x_corner;
  public int y_corner;
  public int b_height;
  public int b_width;
  public String caption;
  
  public button(int x,int y, int h, int w, String c){
    this.x_corner=x;
    this.y_corner=y;
    this.b_height=h;
    this.b_width=w;
    this.caption=c;    
  }

}

2. Programul pentru Arduino :


int columns[8]={2,3,4,5,6,7,8,9};
int rows[8]={24,26,28,30,32,34,36,38};

char buffer[16];
int data[8];
int i;
int j;
void setup(){
 for(i=0;i<8;i++){
  pinMode(rows[i],OUTPUT);
  pinMode(columns[i],OUTPUT);
 }
 Serial.begin(9600);
 
}

void loop(){
 if(Serial.available()>0){
  int index=0;
  Serial.readBytes(buffer,16);
  for(i=0;i<16;i=i+2){
   data[index]=((buffer[i]^16)<<4|(buffer[i+1]^16));
   index++;
  }
 }


  for(i=0;i<8;i++){
   digitalWrite(columns[i],HIGH);
   for(j=0;j<8;j++){
    int k=data[i]&(1<<j);
    digitalWrite(rows[j],k);
    delayMicroseconds(250);
    digitalWrite(rows[j],LOW);
    //delayMicroseconds(10);
   } 
   digitalWrite(columns[i],LOW);
  }
 
}

     Cele doua programe se pot downloada de AICI.
     Cam asta ar fi pentru azi. Succes.


luni, 24 februarie 2014

DETECTOR DE OBSTACOLE CU SENZORUL ULTRASONIC HC-SR04

0 comentarii | Read more...


     Acum ceva timp mi-a cazut in mana un senzor ultrasonic HC-SR04, numai bun interfatat cu Arduino. Cum planuiesc de ceva vreme sa construiesc un robotel multifunctional, adica pe acelasi sasiu sa fie montati mai multi senzori, am zis sa incep prin a face niste teste pentru cel de obstacole, teste pe care vreau sa vi le prezint si voua. 
    Cautand prin "cutia cu maimute" am dat peste un motor pas cu pas unipolar (despre care nu am gasit nici o informatie pe tot internetul) si un driver Darlington - ULN 2003. Masurand rezistenta infasurarilor ~240 ohmi, am ajuns la concluzia ca nu ar fi nici o problema daca as alimenta motorasul la 9V, si intr-adevar "merge uns". 
     Scopul proiectului este simplu : senzorul masoara la intervale regulate distanta pana la primul obstacol si daca distanta este mai mare de 15 cm "il doare la basca". Daca in schimb distanta este sub acesta valoare va incerca sa gaseasca o alta directie fara obstacol :







Cablarea componentelor


CONECTAREA COMPONENTELOR.
    
    Nu voi intra prea mult in detalii constructive pentru ca proiectul nu prezinta dificultati de acest sens. Trebuie totusi spus faptul ca tinand cont ca se utilizeaza un motor unipolar prizele mediane ale bobinelor ( fierele galbene ) trebuie legate la 9V. In libraria celor de la Fritzing am gasit un unipolar cu sase fire. In realitate motorul meu, ca multe altele de pe piata au doar 5 fire, lucru care reprezinta de fapt ca legatura intre cele doua fire galbene este realizata intern. Indiferent de caz cablarea se face exact ca in schema.

     Senzorul ultrasonic HC-SR04 nu reprezinta o provocare. Desi pe internet sunt prezenate o groaza de programe cu ajutorul carora se masoara distante, nu are o precizie extraordinara si uneori mai da  rateuri. Principiul de functionare este urmatorul: se aplica un puls de minim 10 microsecunde pinului "trigger" dupa care se  masoara intervalul de timp in care pinul "echo" este HIGH, acest interval de timp fiind de ordinul milisecundelor. Se imparte timpul masurat la 58 si astfel rezulta distanta. Producatorul recomanda o pauza de macar 60 ms intre masuratori tocmai pentru a nu citii de doua ori propriul ecou.
 
    Cate ceva despre program...

    In faza in care este montajul acum senzorul trbuie rotit manual intr-o pozitie cunoscuta. De ce? Pentru ca am cumparat niste limitatoare ale caror contacte s-au dovedit destul de greu de apasat pentru motor, si asta nu pentru ca nu ar dezvolta un cuplu suficient de mare ci pentru ca masa senzorului si a suportului pe care este montat este prea mica. Voi rezolva problema schimband limitatoarele cu unele mai slabe, dar pentru moment am rezolvat problema din soft. Plecand din pozitia cunoscuta stepperul se va duce pana la un unghi de ~90 grade dupa care senzorul va urmarii daca exista vreun obstacol in fata sa. Daca apare un obstacol se va roti 30 de grade fie la stanga fie la dreapta. Aici trebuie facuta o scurta mentiune : motorul cu care ma joc efectueaza o rotatie de 7.5 grade pentru fiecare pas.  Am considerat ca patru pasi (30 grade) executati cu o pauza de 25 ms sunt suficienti pentru a detecta si evita  obstacolele  efieicient.

    Iata si codul :


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
///DETECTOR DE OBSTACOLE///
///CU MOTOR PAS CU PAS////
///SI SENZOr ULTRASONIC HC-SR04///
///PETRESCU CRISTIAN ///
///FEB. 2014///

int i;
int j;
int k;
int steps;
int cw[4]={B1000,B0100,B0010,B0001}; 
int ccw[4]={B0001,B0010,B0100,B1000};
int pins[4]={24,26,28,30};
int trigger=4;
int echo=5;
int distance;
int num_steps;
boolean reset;
boolean first_time=true;
int center=4;
void setup(){
 for(i=0;i<4;i++){
  pinMode(pins[i], OUTPUT);
 }
 pinMode(trigger,OUTPUT);
 pinMode(echo,INPUT);
 Serial.begin(9600);
}

void rotate(int *k){
 byte test;
 for(j=0;j<4;j++){
  for(i=0;i<4;i++){
   test=((*(k+j)&(8>>i))>>(3-i));
   digitalWrite(pins[i],test);
  }
  delay(25); 
 }
}

int get_dist(){
 digitalWrite(trigger,HIGH);
 delayMicroseconds(12);
 digitalWrite(trigger,LOW);
 unsigned int dist=pulseIn(echo,HIGH)/58;
 return dist;
}

int set_center(int pos){
 int a;
 int index;
 if(pos<center){
  a=center-pos;
  for(index=0;index<a;index++){
   rotate(ccw);
  }
 }
 if(pos>center){
  a=pos-center;
  for(index=0;index<a;index++){
   rotate(cw);
  }
 }
 return a;
}


void loop(){
 distance=0;
 if(first_time){
  steps=set_center(steps);
  first_time=false;
  Serial.println(steps);
  delay(2000);
 }
 int distance =get_dist();
 
  delay(150);
  
  
 if(steps>=4&&steps<=7){
  distance=get_dist();
  delay(150);
  while(steps>=0&&(distance>0&&distance<15)){
   rotate(cw);
   steps--;
   distance=get_dist();
   delay(150);
   Serial.println(steps);
  }
 }
 if(steps>=0&&steps<4){
  distance=get_dist();
  delay(150);
  while(steps>=0&&(distance>0&&distance<15)){
   rotate(ccw);
   steps++;
   distance=get_dist();
   delay(150);
   Serial.println(steps);
  }
 }
}

    Cam asta ar fi pentru azi.


sâmbătă, 15 februarie 2014

Arduino+Stepper=Encoder

0 comentarii | Read more...

     Din ciclul  proiecte "mai putin utile" dar cu mare scop didactic sau cum se imbina teoria cu prctica va prezint:

           Cum se poate face un encoder rotativ dintr-un motor pas cu pas, un comparator si... Arduino.





     Un pic de teorie...

     Dupa leagea lui Faraday si constatarea lui Lenz se poate afirma ca daca o bobina se misca (fie rectiliniu, fie unghiular) intr-un camp magnetic prin aceasta va incepe sa circule un curent care va avea sensul opus cauzei care l-a creat (miscarea). Practic orice motor este un convertor de energie: daca se aplica la ax o putere mecanica la borne va aparea o tensiune electromotoare iar daca se aplica la borne o tensiune electromotoare la ax vom avea o putere mecanica. GATA? Nu chiar... Pentru acest proiect intereseaza partea in care se aplica putere mecanica la ax iar la borne apare o t.e.m. Tensiunea aparuta la borne depinde de doi factori : intensitatea si densitatea campului magnetic si rata variatie a vitezei cu care bobina se misca in acesta. Ideal ar fi sa fie indplinite ambele conditii dar exista niste constrangeri despre care nu voi vorbi acum.      Sa presupunem ca avem un camp magnetic dat,  la care nu se poate "umbla" asadar, pentru a obtine o tensiune la bornele motorului, va trebui sa rotim bobina in camp. Dar daca facem acest lucru manual ce tensiune se obtine? Una foarte mica daca rotim incet si una mai mare daca rotim mai repede. Acum este GATA teoria !!

    Ce este un encoder rotativ?

    Un encoder roatativ poate fi comparat cu doua contacte rotative defazate intre ele cu 90 de grade. Cum o poza face mai mult de 100 de cuvinte eu zic sa privim urmatoarea imagine:




Principiu encoder roattiv

     OK. Conatactele sunt C1 (rosu) si C2 (verde). Sa zicem ca la inceputul utilizarii cele doua contacte sunt in pozitia P1, adica C1 este "la masa" si C2 este la 5V. Citim aceste valori cu Arduino (sau alt microcontroller). Rotim contactele pana in P2 si citim si aceste avalori. Mai departe se rotesc contactele pana la P4. Se obesrva ca la P5 cele doua contacte ajung la tensiuni  similare cu cele pe care le-au avut in pozitia P1. La ce ne ajuta asta? La stabilirea sensului miscarii! Citind succesiv starea contactelor se pot elabora algoritimi care in functie de tiparul miscarii sa stabilieasca sensul miscarii.
   
    Ce legatura are un motor pas cu pas cu un encoder?

    Are. Un motor pas cu pas (mpp) bipolar este realizat din 2 bobine dispuse in asa fel incat infasurarile acestora creaza campuri elctromagnetice defazate intre ele. Pentru mai multe detalii despre cum este construit un mpp puteti vedea filmuletele de mai jos :


   

     Acum : daca rotim manual axul mpp-ului cele doua bobine vor fi rotite in campul magnetic al magnetului permanent. Asta insemna ca la bornele lor vom citii o tensiune electromotoare. Ordinea aparitiei acestei tensiuni la bornele celor doua bobine este dependenta de sensul in care rotim axul. Aici apar doua probleme :

  1. Tensiunile de la borne sunt sinusoidale.
  2. Valorile lor sunt mici.
  Cele doua probleme se rezolva daca utilizam urmatorul montaj ( schema este proprietatea sitelui http://home.clear.net.nz/pages/joecolquitt/stepper_as_encoder.html , site pe care va rog sa il vizitati pentru lamuriri)  :



     Urmarind schema solutiile celor doua probleme devin evidente: pentru a scapa de alternata negativa se utilizeaza doua diode, iar pentru a citii valori corecte se utilizeaza doua comparatoare care au setat ca prag tensiunea data de potentiometrul de 50k pe intrarile neinversoare. O solutie inteligenta pe care autorul a adoptat-o a fost aplicarea unui curent (~6mA) bobinelor pentru a amplifica efctul de inductie, dar si pentru a scapa de tensiunile parazite (explicatia se gaseste pe site).

     In sfarsit, in formele de unda ale celor doua iesiri se observa clar cum ordinea in care acestea isi schimba starea depinde de sensul de rotatie.
     Pentru a face mai usoara utilizarea am creat pe baza schemei un cablaj (pe care l-am si realizat) :

Cablaj encoder
Amplasare componente



Cablajul realizat

     Dupa cum se observa am utilizat un LM339 (4 AO cu colector in gol) tocmai pentru a utiliza doua motoare (am o idee pe care vreau sa o pun in practica). Ceva ce mi-a scapt a fost marcarea contectorului "SIL1" (fapt important deoarce prin acesta se face conexiunea cu Arduino) ordinea este urmatoarea:

  1. Pin 1 VCC
  2. Pin 2 iesirea AO1
  3. Pin 3 iesirea AO2
  4. Pin 4 iesirea AO3
  5. Pin 5 iesirea AO4
  6. Pin 6 GND.

     Cablajul in format PDF se poate descarca de aici.

     Interfatarea cu Arduino....

    Pentru a demonstra ca montajul functioneaza am conceput urmatorul program :



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//// ENCODER FROM STEPPER ////
////ARDUINO MEGA 2560/////
////PETRESCU CRISTIAN////
////FEB.2014////////////

int counter;
int pin1=2;
int pin2=3;
int i;
int leds[8]={24,26,28,30,32,34,36,38};
boolean val_pin1;
boolean val_pin2;
int k;
int old_k;
int index;
int test[3]; 

void setup(){
 pinMode(pin1,INPUT);
 pinMode(pin2,INPUT);
 noInterrupts();
 interrupts();
 for(i=0;i<8;i++){
  pinMode(leds[i],OUTPUT);
 }
 Serial.begin(9600);
}

void loop(){
 while(!(test[0])){
  val_pin1=digitalRead(pin1);
  val_pin2=digitalRead(pin2);
  k=val_pin1|(val_pin2<<1);
 
  if(k!=3 && k!=old_k && k!=0){
   old_k=k;
   index++;
   test[index]=k;
  }
  if(k==3){
   if(index==2)
   test[0]=1;
   index=0;
  }
 }
 if(test[1]==2&&test[2]==1){
  counter++;
 }
 if(test[1]==1&&test[2]==2){
  counter--;
 }
 test[0]=0;
 for(i=0;i<8;i++){
  if(counter&(1<<i)){
   digitalWrite(leds[i],HIGH);
  }
  if(!(counter&(1<<i))){
   digitalWrite(leds[i],LOW);
  }
 }
 delay(150);
}

     Programul nu face altceva decat sa monitorizeze schimbarea starii a pinilor 2 si 3 ai lui Arduino, iar dupa ce stabileste tiparul schimbarii acestora  (in prima bucla "while") incrementeza su decreamenteza variabila " counter". Pe baza acestei variabile in bucla "for" se aprind sau se sting 8 leduri, starea acestora reprezntand transpunerea in binar a variabilei counter. 
    Cam asta ar fi ceea ce aveam de prezentat


Totalul afișărilor de pagină

Despre

Blog cu si despre electronica !