UZ senzor HC-SR04, senzor barv TCS 230, virtualni prikaz

Slika 1: Virtualni in dejanski prikaz zaznavanja barve.

Ultrazvočni senzor HC-SR04 zagotavlja brezkontaktno merjenje razdalje od 2 cm do 400 cm z natančnostjo 3 mm. Njegova delovna frekvenca znaša 40 kHz. Senzor ima štiri priključke, dva za napetostno napajanje (Vcc priključimo na napetost 5 V, GND pa na maso), priključek Trig za proženje in priključek Echo za odmev.

Slika 2: Ultrazvočni senzor HC-SR04 (vir: https://www.aimagin.com/hc-sr04-ultrasonic-sensor.html)

Za proženje senzorja pošljemo na priključek Trig impulz dolžine 10 µs. To sproži serijo osmih impulzov frekvence 40 kHz na oddajniku, katerih odboj od predmeta sprejme sprejemnik, ki poda na priključku Echo pozitivni impulz. Dolžina tega pozitivnega impulza (timp) je odvisna od oddaljenosti predmeta. Oddaljenost predmeta od senzorja (s) izračunamo po formuli:

s = (timp * vzv) / 2

vzv je zvočna hitrost in znaša 346,05 m/s pri temperaturi zraka 25 °C (glej kalkulator za izračun hitrosti zvoka). Z 2 delimo zato, ker zvok potuje od senzorja do predmeta in nazaj.

Čeprav je maksimalni čas odziva 38 ms (ko senzor ni zaznal nobene ovire), proizvajalec priporoča, da med enim in drugim proženjem preteče vsaj 60 ms, da ne bi prišlo do motenj.

Senzor barv TCS 230 smo spoznali že v vaji Zaznavanje barv s senzorjem TCS 230.

Zahteve za našo nalogo:

Senzor HC-SR04 bomo uporabili za ugotavljanje prisotnosti predmeta, ki je lahko rdeče, zelene ali modre barve. Če je prisoten predmet v območju od 2 cm do 15 cm od senzorja HC-SR04 rdeče barve, se naj vklopi svetilo rdeče barve, če je prisoten predmet zelene barve, se naj vklopi svetilo zelene barve, v kolikor pa je prisoten predmet modre barve, se naj vklopi svetilo modre barve. Če senzor HC-SR04 ni zaznal prisotnosti predmeta, svetilo izklopi oziroma ostane izklopljeno:

Nalogo bi lahko uporabili za krmiljenje tekočega traka, na katerem bi sortirali predmete v odvisnosti od njihove barve.

Priključitev senzorjev in svetila na razvojno ploščo Arduino Uno:

Svetilo (RGB LED dioda):

Rdeča => pin 11 (preko upora 470 ohm)

Zelena => pin 10 (preko upora 470 ohm)

Modra => pin 6 (preko upora 470 ohm)

Katoda skupna => masa (GND)

Priključitev HC-SR04:

Vcc => +5 V

GND => masa

Trig => pin 12

Echo => pin 13

Priključitev TCS 230:

S0 => masa (GND)

S1 => +5 V

S2 => pin 7

S3 => pin 8

OUT => pin 4

Vcc => +5 V

GND => masa

Program Arduino:

 /*

  Uproaba UZ senzorja HC-SR04 za ugotavljanje prisotnosti predmeta.

  Zaznavanje barv s senzorjem TCS 230, Arduino Uno.

  Krmiljenje svetila v odvisnosti od prisotnosti in barve predmeta.

  Avtor: Milan Ivič

  Julij 2015

 */

 //UZ senzor HC-SR04:

 int TrigPin = 12;

 int EchoPin = 13;

 float pingTime;                      //Čas potovanja od senzorja HC-SR04 do ovire in nazaj.

 float Razdalja_do_ovire;         //Razdalja od senzorja do ovire v cm.

 float Hitrost_zvoka=346.05;    //Hitrost zvoka v m/s pri temp. zraka 25 °C.

 //RGB LED dioda:

 int RdecaPin = 11;

 int ZelenaPin = 10;

 int ModraPin = 6;

 //Barvni senzor TCS 230:

 int S2 = 7;

 int S3 = 8;

 int Izhod = 4;

 //Spremenljivke za posamezne barve:

 int RdecaBarva;

 int ZelenaBarva;

 int ModraBarva;

 int SirinaPulza = 0;          //Spremenljivka za branje dolžine impulza v µs, inicializacija.

 void setup()

 {

   Serial.begin(115200);      //Komunikacija s serijskim portom, 115200 bit/s.

   //Določitev vhodov in izhodov:

   pinMode(TrigPin, OUTPUT);

   pinMode(EchoPin, INPUT);   

   pinMode(RdecaPin, OUTPUT);

   pinMode(ZelenaPin, OUTPUT);

   pinMode(ModraPin, OUTPUT);

   pinMode(S2, OUTPUT);

   pinMode(S3, OUTPUT);

   pinMode(Izhod, INPUT);

 }

 void loop()

 {

  digitalWrite(TrigPin, LOW);

  delayMicroseconds(10);

  digitalWrite(TrigPin, HIGH);    //Za proženje moramo dovesti pozitivni impulz dolžine vsaj 10 µs ali več.

  delayMicroseconds(60);         //Zakasnitev, da ne pride do motenj.

  digitalWrite(TrigPin, LOW);

 

  pingTime = pulseIn(EchoPin, HIGH);                    //Branje dolžine impulza v µs.

  pingTime=pingTime/1000000;                              //Pretvorba iz µs v sekunde.

  Razdalja_do_ovire= Hitrost_zvoka * pingTime;      //V metrih (m/s * s = m).

  Razdalja_do_ovire=Razdalja_do_ovire/2;         //Impulz potuje od senzorja do predmeta in nazaj. Razdalja do predmeta je polovica celotne razdalje.

  Razdalja_do_ovire= Razdalja_do_ovire*100;    //Pretvorba iz metrov v cm.

  int Razdalja = Razdalja_do_ovire;                   //Podatek o razdalji naj bo celo število (tip int).

 

  //Začnemo z branjem komponente rdeče barve:

  //S2 in S3 postvimo na LOW.

  digitalWrite(S2, LOW);

  digitalWrite(S3, LOW);

  SirinaPulza = pulseIn(Izhod, LOW);     //Branje dolžine impulza (polperiode, ko je logično stanje 0) v µs. (Duty cycle je 50 %).

  RdecaBarva = SirinaPulza/44;             //Kalibriranje za rdeco barvo.

  RdecaBarva = (255 - RdecaBarva);

  //Začnemo z branjem komponente zelene barve:

  //S2 in S3 postvimo na HIGH.

  digitalWrite(S2, HIGH);

  digitalWrite(S3, HIGH);

  SirinaPulza = pulseIn(Izhod, LOW);

  ZelenaBarva = SirinaPulza/65;            //Kalibriranje za zeleno barvo.

  ZelenaBarva = (255 - ZelenaBarva);

  //Začnemo z branjem komponente modre barve:

  //S2 postavimo na LOW, S3 postvimo na HIGH.

  digitalWrite(S2, LOW);

  digitalWrite(S3, HIGH);

  SirinaPulza = pulseIn(Izhod, LOW);

  ModraBarva = SirinaPulza/58;             //Kalibriranje za modro barvo.

  ModraBarva = (255 - ModraBarva);  

  if(RdecaBarva > ModraBarva && RdecaBarva > ZelenaBarva)

   {

     RdecaBarva = 255;

     ZelenaBarva = 0;

     ModraBarva = 0;

     digitalWrite(RdecaPin, HIGH);    //Vklop rdeče RGB LED diode.

     digitalWrite(ZelenaPin, LOW);

     digitalWrite(ModraPin, LOW);

   }

   if(ZelenaBarva > ModraBarva && ZelenaBarva > RdecaBarva)

   {

     RdecaBarva = 0;

     ZelenaBarva = 255;

     ModraBarva = 0;

     digitalWrite(RdecaPin, LOW);

     digitalWrite(ZelenaPin, HIGH);    //Vklop zelene RGB LED diode.

     digitalWrite(ModraPin, LOW);

   }

   if(ModraBarva > RdecaBarva && ModraBarva > ZelenaBarva)

   {

     RdecaBarva = 0;

     ZelenaBarva = 0;

     ModraBarva = 255;

     digitalWrite(RdecaPin, LOW);

     digitalWrite(ZelenaPin, LOW);

     digitalWrite(ModraPin, HIGH);    //Vklop modre RGB LED diode.

   }

   if(Razdalja > 15)

   {

     digitalWrite(RdecaPin, LOW);    //Izklop vseh RGB LED diod. Svetilo je izklopljeno.

     digitalWrite(ZelenaPin, LOW);

     digitalWrite(ModraPin, LOW);   

   }

  //Izpis vrednosti posameznih spremenljivk, ločenih z vejico, na serijski port, v našem primeru COM9.

  Serial.print(RdecaBarva);

  Serial.print(" , ");

  Serial.print(ZelenaBarva);

  Serial.print(" , ");

  Serial.print(ModraBarva);

  Serial.print(" , ");

  Serial.print(Razdalja);

  Serial.println("");

   

  delay(400);

 }

Slika 3: Primer izpisa na serijski vmesnik.

Na sliki 3 vidimo primer izpisa na serijskem vmesniku. Prva kolona predstavlja vrednost spremenljivke za rdečo barvo, druga za zeleno, tretja kolona za modro barvo, četrta kolona pa prikazuje oddaljenost predmeta od senzorja HC-SR04 v cm. Te podatke bo neprestano "pregledoval" Python, saj bosta Python in Arduino komunicirala preko porta COM9.

Program Python:

import serial                #Uvozimo knjižnico za serijsko komunikacijo, da bosta lahko komunicirala Python in Arduino preko COM9.

from visual import *      #Uvoz vseh vPython knjižnic.

MojPogled = display(title='Senzor barve TCS 230 zaznava barvo predmeta, UZ senzor HC-SR04 pa prisotnost predmeta.')

MojPogled.width=800            #V pixlih.

MojPogled.height=600           #V pixlih.

MojPogled.autoscale = False              #Povemo vPython-u da ne razširja okna.

MojPogled.range = (80,80,80)             #Delovna površina okna.

BarvniPredmet = box(color=color.white, lenght=20, width=30, height=40, pos=(-36,0,0))    #Kreiranje objekta za predmet.

Senzor = box(color=color.gray(0.5), lenght=14, width=16, height=18, pos=(-52,0,0))          #Kreiranje objekta za senzor barv.

Senzor1 = box(color=color.yellow, lenght=4, width=4, height=4, pos=(-51,0,0))

LED1 = cylinder(color=color.white, pos = (-52,-6,5), radius = 1.5, length = 3)           #Objekt predstavlja LED diodo na senzorju barv.

LED2 = cylinder(color=color.white, pos = (-52,6,5), radius = 1.5, length = 3)

LED3 = cylinder(color=color.white, pos = (-52,-6,-5), radius = 1.5, length = 3)

LED4 = cylinder(color=color.white, pos = (-52,6,-5), radius = 1.5, length = 3)

Svetilo = sphere(pos=(30,2,1), radius=16)                                                            #Objekt Svetilo predstavlja krogla.

Zapis=label(pos=(-5,38,0), height=12, depth=-0.3)

Zapis1=label(pos=(30,26,0), height=12, depth=-0.3)

Zapis2=label(pos=(-60,20,0), height=12, depth=-0.3)

PodatkiSenzorja = serial.Serial('COM9', 115200)    #Kreiranje objekta PodatkiSenzorja za branje podatkov od Arduina (COM9).

while (1==1):                                                      #Neskončna zanka.

    rate(20)

    while(PodatkiSenzorja.inWaiting()==0):                 #Ni podatka na COM9.

        pass                                                              #Ne  ničesar, dokler ni nobenih podatkov na portu COM9.

    PodatkiEneVrstice=PodatkiSenzorja.readline()      #Prebere celotno vrstico znakov, ki jih pošilja Arduino na COM9.

    LoceniPodatki=PodatkiEneVrstice.split(',')             #Loči posamezne podatke znakovnega niza, ki so v vrstici ločeni z vejico.

    Rdeca=float(LoceniPodatki[0])                              #Prvi podatek iz znakovnega niza pretvorimo v realno število.

    Zelena=float(LoceniPodatki[1])                              #Drugi podatek iz znakovnega niza pretvorimo v realno število.

    Modra=float(LoceniPodatki[2])

    Razdalja=float(LoceniPodatki[3])

    Zapis1.text='Svetilo'

    Zapis2.text='Senzor barv TCS 230'

    

    print PodatkiEneVrstice                                     #Preverimo ali je Python prejel vse podatke od Arduina.

    if(Rdeca>250 and Razdalja<15):                         #Ali je predmet rdeče barve in ga je senzor HC-SR04 zaznal v razdalji do 15 cm?

        Zapis.text='Senzor je zaznal predmet rdece barve'     #Izpiše se naj, da je senzor zaznal predmet rdeče barve.  

        BarvniPredmet.color=(Rdeca/250.,Zelena/250.,Modra/250.)    #Določimo parametre 1,0,0 => rdeča barva.

        Svetilo.color=(Rdeca/250.,Zelena/250.,Modra/250.)                #(250/250=1, 0/250=0)

    if(Zelena>250 and Razdalja<15):

        Zapis.text='Senzor je zaznal predmet zelene barve'

        BarvniPredmet.color=(Rdeca/250.,Zelena/250.,Modra/250.)     #Določimo parametre 0,1,0 => zelena barva.

        Svetilo.color=(Rdeca/250.,Zelena/250.,Modra/250.)        

    if(Modra>250 and Razdalja<15):

        Zapis.text='Senzor je zaznal predmet mode barve'

        BarvniPredmet.color=(Rdeca/250.,Zelena/250.,Modra/250.)     #Določimo parametre 0,0,1 => modra barva.

        Svetilo.color=(0,0,1)                                                             #Lahko določimo barvo tudi tako.

    elif(Razdalja>=15):                                                                   #Ali je prisoten predmet v območju od 2 cm do 15 cm od senzorja?

        Zapis.text='Senzor ni zaznal predmeta v svoji bljizini'

        BarvniPredmet = box(color=color.white, lenght=20, width=30, height=40, pos=(-36,0,0))    #Barvni predmet naj bo bele barve.

        Svetilo = sphere(pos=(30,2,1), radius=16)                                                                      #Svetilo (krogla) naj bo bele barve.        

Razlaga programa Python je v komentarjih. Kreiranje 3D objektov si lahko pogledamo na tej strani, glede barv pa na tej strani.