SantyagoSantyago
Avatar

Witaj!
Blog archiwalny. Już niebawem nowy serwis!

YouTube RSS Facebook GitHub

Arduino poradnik

Wstęp

Teoria

Biblioteki

Komponenty

Czujniki i sensory

Rozwiązania i algorytmy

Narzędzia

Mikrokontrolery i Arduino IDE

Arduino i klony

Poradniki wideo

Reklama na Blogu

Najnowsze poradniki

Ostatnie komentarze

Ostatnie fotografie

polskie-gorypolskie-gorypolskie-gorypolskie-gorypolskie-gorypolskie-gorypolskie-gorypolskie-gorypolskie-gorywieliczka-szyb-danilowicza

Czujnik zbliżeniowy i natężenia światła VCNL4000

VCNL4000 jest bardzo małym (4x4 mm) czujnikiem zbliżeniowym z możliwością pomiaru natężenia oświetlenia. W odróżnieniu od standardowych czujników odległości, nie mierzy on dystansu pomiędzy czujnikiem a obiektem, a określa jedynie fakt, czy dany obiekt zbliżył się na dostatecznie bliską odległość (od 1 mm do 200mm).  Identyczną cechę posiadają czujniki montowane w telefonach komórkowych, które na przykład wygaszają ekran w momencie przyłożenia słuchawki do ucha. VCNL4000 posiada również  czujnik pomiaru natężenia oświetlenia, a więc pozwala określić gęstość strumienia świetlnego padającego na jego powierzchnię roboczą. Jednostką natężenia oświetlenia w układzie SI jest luks (lx), który równy jest liczbie lumenów na metr kwadratowy

Według normy PN-EN 12 464-1:2004 o wymaganiach oświetleniowych pomieszczeń, poziom natężenia światła powinien być odpowiedni do wykonywanej przez nas czynności:

  • 20 lx dla rozpoznania rysów twarzy
  • 50 lx dla wykonywania prostych czynności
  • 500 lx dla prac biurowych
  • 1000 lx dla prac precyzyjnych

Wrócmy jednak do samego czujnika. Na rynku dostępny jest między innymi gotowy adapter od firmy Adafriut, który jest bardzo prostą konstrukcją. Napięcie zasilania jak i  poziom logiki toleruje zakres od 3.3V do 5V. Całość komunikuje się za pomocą szyny I2C.

Zarówno czujnik zbliżeniowy jak i czujnik natężenia oświetlenia posiada 16 bitową rozdzielczość. W przypadku pomiaru natężenia oświetlenia jest to zakres do 16383 lx z rozdzielczością 0.25 lx.

Problematyczny może okazać się czujnik zbliżeniowy, który nie nada się do pomiaru odległości. Dioda IR emituje wiązkę podczerwoną, która odbijając się częściowo od powierzchni obiektu wraca do czujnika. Gęstość odbitego promienia zależy głównie od odległości pomiędzy czujnikiem, a obiektem. Nie bez znaczenia jest również rodzaj materiału z jakiego wykonany jest obiekt od którego odbija się wiązka IR. Dodatkowo należy zauważyć, że charakterystyka ta jest mocno nieliniowa.

W zależności od wartości prądu diody IR, dla szarej karty Kodak o współczynniku odbicia 18% zależność ta wygląda następująco:

Schemat połączeń

Na pin adaptera VIN (5) podłączamy zasilanie 5V oraz masę na pin GND (4). Piny sygnałowe SDA (3) i SCL (2) podłączamy odpowiednio do wejść Arduino A4 i A5. Dodatkowo wykorzystamy dwa piny cyforwe 4 i 5 do sygnalizacji diodami LED niskiego poziomu oświetlenia i sygnalizacji zbliżenia obiektu.

Program

  1. #include <Wire.h>
  2.  
  3. // Adres i2c adaptera
  4. #define VCNL4000_ADDRESS 0x13
  5.  
  6. // Komendy i stałe
  7. #define VCNL4000_COMMAND 0x80
  8. #define VCNL4000_PRODUCTID 0x81
  9. #define VCNL4000_IRLED 0x83
  10. #define VCNL4000_AMBIENTPARAMETER 0x84
  11. #define VCNL4000_AMBIENTDATA 0x85
  12. #define VCNL4000_PROXIMITYDATA 0x87
  13. #define VCNL4000_SIGNALFREQ 0x89
  14. #define VCNL4000_PROXINITYADJUST 0x8A
  15.  
  16. #define VCNL4000_3M125 0
  17. #define VCNL4000_1M5625 1
  18. #define VCNL4000_781K25 2
  19. #define VCNL4000_390K625 3
  20.  
  21. #define VCNL4000_MEASUREAMBIENT 0x10
  22. #define VCNL4000_MEASUREPROXIMITY 0x08
  23. #define VCNL4000_AMBIENTREADY 0x40
  24. #define VCNL4000_PROXIMITYREADY 0x20
  25.  
  26. void setup()
  27. {
  28.   // Otwieramy port szeregowy
  29.   Serial.begin(9600);
  30.  
  31.   // Inicjalizujemy sensor
  32.   Serial.println("Inicjalizacja VCNL");
  33.   Wire.begin();
  34.  
  35.   // Odczytujemy identyfikator produktu i sprawdzamy czy to VCNL4000
  36.   uint8_t rev = read8(VCNL4000_PRODUCTID);
  37.  
  38.   if ((rev &amp; 0xF0) != 0x10)
  39.   {
  40.     Serial.println("Nie odnaleziono sensora!");
  41.     while (1);
  42.   }
  43.     
  44.   // Ustawiamy prąd diody IR na 200mA
  45.   // Możliwy zakres: 10 - 200mA (krok 10mA)
  46.   write8(VCNL4000_IRLED, 20); // 20 * 10mA = 200mA
  47.  
  48.   // Odczytujemy prąd diody
  49.   Serial.print("Prad diody IR LED = ");
  50.   Serial.print(read8(VCNL4000_IRLED) * 10, DEC);
  51.   Serial.println(" mA");
  52.  
  53.   // Ustawiamy czestotliwosc sygnalu zbiliznia
  54.   // Domyślna wartość to 2, czyli 781.25 KHz
  55.   // write8(VCNL4000_SIGNALFREQ, VCNL4000_390K625);
  56.  
  57.   // Odczytujemy czestotliwosc pomiaru zblizenia
  58.   Serial.print("Czestotliwosc pomiaru = ");
  59.   uint8_t freq = read8(VCNL4000_SIGNALFREQ);
  60.   if (freq == VCNL4000_3M125) Serial.println("3.125 MHz");
  61.   if (freq == VCNL4000_1M5625) Serial.println("1.5625 MHz");
  62.   if (freq == VCNL4000_781K25) Serial.println("781.25 KHz");
  63.   if (freq == VCNL4000_390K625) Serial.println("390.625 KHz");
  64.  
  65.   // Ustawiamy rejestr czasu modulacji czujnika zblizeniowego
  66.   // Według karty katalogowej powinno ustawić sie wartość 129 = 0x81
  67.   write8(VCNL4000_PROXINITYADJUST, 0x81);
  68.  
  69.   // Odczytukemy czy ustawiono rejestr
  70.   Serial.print("Rejestr czasu modulacji = ");
  71.   Serial.println(read8(VCNL4000_PROXINITYADJUST), HEX);
  72.  
  73.   // Piny diod LED do sygnalzacji
  74.   pinMode(4, OUTPUT);
  75.   pinMode(5, OUTPUT);
  76.  
  77. }
  78.  
  79. // Funkcja odczytu wartosci oswietlenia
  80. uint16_t readAmbient()
  81. {
  82.   write8(VCNL4000_COMMAND, VCNL4000_MEASUREAMBIENT);
  83.   while (1)
  84.   {
  85.     uint8_t result = read8(VCNL4000_COMMAND);
  86.     if (result &amp; VCNL4000_AMBIENTREADY)
  87.     {
  88.       return read16(VCNL4000_AMBIENTDATA);
  89.     }
  90.     delay(1);
  91.   }  
  92. }
  93.  
  94. // Funkcja odczytu wartosc czujnika zblizeniowego
  95. uint16_t readProximity()
  96. {
  97.   write8(VCNL4000_COMMAND, VCNL4000_MEASUREPROXIMITY);
  98.   while (1)
  99.   {
  100.     uint8_t result = read8(VCNL4000_COMMAND);
  101.     if (result &amp; VCNL4000_PROXIMITYREADY)
  102.     {
  103.       return read16(VCNL4000_PROXIMITYDATA);
  104.     }
  105.     delay(1);
  106.   }
  107. }
  108.  
  109. void loop()
  110. {
  111.   // Odczyt natezenia swiatla
  112.   int lux = readAmbient() * 0.25;
  113.  
  114.   // Odczyt wartosci z czujnika zblizeniowegp
  115.   int pro = readProximity();
  116.  
  117.   // Jesli wartosc przekroczy 2500 cts zapal diode czerwona
  118.   if (pro > 2500)
  119.   {
  120.     digitalWrite(4, HIGH);
  121.   } else
  122.   {
  123.     digitalWrite(4, LOW);
  124.   }
  125.       
  126.   // Jesli oswietlenie spadnie ponizej 20 luksow, zapal diode zielona
  127.   if (lux < 20)
  128.   {
  129.     digitalWrite(5, HIGH);
  130.   } else
  131.   {
  132.     digitalWrite(5, LOW);
  133.   }      
  134.  
  135.   // Wyswietlenie pomiarow    
  136.   Serial.print("Natezenie swiatla = ");
  137.   Serial.print(lux);
  138.   Serial.print(" Zblizenie = ");
  139.   Serial.println(pro);
  140.  
  141.   delay(100);
  142.  }
  143.  
  144. // Funkcja odczytu 1 bajtu z podanego adresu
  145. uint8_t read8(uint8_t address)
  146. {
  147.   uint8_t data;
  148.  
  149.   Wire.beginTransmission(VCNL4000_ADDRESS);
  150.   Wire.write(address);
  151.   Wire.endTransmission();
  152.  
  153.   delayMicroseconds(170); // delay required
  154.  
  155.   Wire.requestFrom(VCNL4000_ADDRESS, 1);
  156.   while(!Wire.available());
  157.  
  158.   return Wire.read();
  159. }
  160.  
  161. // Funkcja odczytu 2 bajtow z podanego adresu
  162. uint16_t read16(uint8_t address)
  163. {
  164.   uint16_t data;
  165.  
  166.   Wire.beginTransmission(VCNL4000_ADDRESS);
  167.   Wire.write(address);
  168.   Wire.endTransmission();
  169.  
  170.   Wire.requestFrom(VCNL4000_ADDRESS, 2);
  171.   while(!Wire.available());
  172.  
  173.   data = Wire.read();
  174.   data <<= 8;
  175.   while(!Wire.available());
  176.   data |= Wire.read();
  177.  
  178.   return data;
  179. }
  180.  
  181. // Funkcja zapisu 1 bajtu do podanego adresu
  182. void write8(uint8_t address, uint8_t data)
  183. {
  184.   Wire.beginTransmission(VCNL4000_ADDRESS);
  185.   Wire.write(address);
  186.   Wire.write(data);
  187.   Wire.endTransmission();
  188. }

Uruchomienie

 

Materiały dodatkowe

Karta katlogowa czujnika VCNL4000: https://www.jarzebski.pl/datasheets/VCNL4000.pdf

Reklama

Komentarze Komentarze
Avatar 1
mieszko Android 4.4 / Safari 537.36
18 May 2014 - 08:11 Ostrów Wielkopolski

Mozna zastosowac to w raspberry pi?

Avatar 2
Korneliusz Linux x86_64 / Mozilla Firefox 29.0
19 May 2014 - 21:36 Bytom

Wygląda na to, że można: http://www.openhomeautomation.net/proximity-alarm-raspberry-pi/


Oryginalny obraz posiada rozmiar 863x487