luni, 24 februarie 2014

DETECTOR DE OBSTACOLE CU SENZORUL ULTRASONIC HC-SR04



     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.


Niciun comentariu:

Trimiteți un comentariu