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
- #include <Wire.h>
- // Adres i2c adaptera
- #define VCNL4000_ADDRESS 0x13
- // Komendy i stałe
- #define VCNL4000_COMMAND 0x80
- #define VCNL4000_PRODUCTID 0x81
- #define VCNL4000_IRLED 0x83
- #define VCNL4000_AMBIENTPARAMETER 0x84
- #define VCNL4000_AMBIENTDATA 0x85
- #define VCNL4000_PROXIMITYDATA 0x87
- #define VCNL4000_SIGNALFREQ 0x89
- #define VCNL4000_PROXINITYADJUST 0x8A
- #define VCNL4000_3M125 0
- #define VCNL4000_1M5625 1
- #define VCNL4000_781K25 2
- #define VCNL4000_390K625 3
- #define VCNL4000_MEASUREAMBIENT 0x10
- #define VCNL4000_MEASUREPROXIMITY 0x08
- #define VCNL4000_AMBIENTREADY 0x40
- #define VCNL4000_PROXIMITYREADY 0x20
- void setup()
- {
- // Otwieramy port szeregowy
- Serial.begin(9600);
- // Inicjalizujemy sensor
- Serial.println("Inicjalizacja VCNL");
- Wire.begin();
- // Odczytujemy identyfikator produktu i sprawdzamy czy to VCNL4000
- uint8_t rev = read8(VCNL4000_PRODUCTID);
- if ((rev & 0xF0) != 0x10)
- {
- Serial.println("Nie odnaleziono sensora!");
- while (1);
- }
- // Ustawiamy prąd diody IR na 200mA
- // Możliwy zakres: 10 - 200mA (krok 10mA)
- write8(VCNL4000_IRLED, 20); // 20 * 10mA = 200mA
- // Odczytujemy prąd diody
- Serial.print("Prad diody IR LED = ");
- Serial.print(read8(VCNL4000_IRLED) * 10, DEC);
- Serial.println(" mA");
- // Ustawiamy czestotliwosc sygnalu zbiliznia
- // Domyślna wartość to 2, czyli 781.25 KHz
- // write8(VCNL4000_SIGNALFREQ, VCNL4000_390K625);
- // Odczytujemy czestotliwosc pomiaru zblizenia
- Serial.print("Czestotliwosc pomiaru = ");
- uint8_t freq = read8(VCNL4000_SIGNALFREQ);
- if (freq == VCNL4000_3M125) Serial.println("3.125 MHz");
- if (freq == VCNL4000_1M5625) Serial.println("1.5625 MHz");
- if (freq == VCNL4000_781K25) Serial.println("781.25 KHz");
- if (freq == VCNL4000_390K625) Serial.println("390.625 KHz");
- // Ustawiamy rejestr czasu modulacji czujnika zblizeniowego
- // Według karty katalogowej powinno ustawić sie wartość 129 = 0x81
- write8(VCNL4000_PROXINITYADJUST, 0x81);
- // Odczytukemy czy ustawiono rejestr
- Serial.print("Rejestr czasu modulacji = ");
- Serial.println(read8(VCNL4000_PROXINITYADJUST), HEX);
- // Piny diod LED do sygnalzacji
- pinMode(4, OUTPUT);
- pinMode(5, OUTPUT);
- }
- // Funkcja odczytu wartosci oswietlenia
- uint16_t readAmbient()
- {
- write8(VCNL4000_COMMAND, VCNL4000_MEASUREAMBIENT);
- while (1)
- {
- uint8_t result = read8(VCNL4000_COMMAND);
- if (result & VCNL4000_AMBIENTREADY)
- {
- return read16(VCNL4000_AMBIENTDATA);
- }
- delay(1);
- }
- }
- // Funkcja odczytu wartosc czujnika zblizeniowego
- uint16_t readProximity()
- {
- write8(VCNL4000_COMMAND, VCNL4000_MEASUREPROXIMITY);
- while (1)
- {
- uint8_t result = read8(VCNL4000_COMMAND);
- if (result & VCNL4000_PROXIMITYREADY)
- {
- return read16(VCNL4000_PROXIMITYDATA);
- }
- delay(1);
- }
- }
- void loop()
- {
- // Odczyt natezenia swiatla
- int lux = readAmbient() * 0.25;
- // Odczyt wartosci z czujnika zblizeniowegp
- int pro = readProximity();
- // Jesli wartosc przekroczy 2500 cts zapal diode czerwona
- if (pro > 2500)
- {
- digitalWrite(4, HIGH);
- } else
- {
- digitalWrite(4, LOW);
- }
- // Jesli oswietlenie spadnie ponizej 20 luksow, zapal diode zielona
- if (lux < 20)
- {
- digitalWrite(5, HIGH);
- } else
- {
- digitalWrite(5, LOW);
- }
- // Wyswietlenie pomiarow
- Serial.print("Natezenie swiatla = ");
- Serial.print(lux);
- Serial.print(" Zblizenie = ");
- Serial.println(pro);
- delay(100);
- }
- // Funkcja odczytu 1 bajtu z podanego adresu
- uint8_t read8(uint8_t address)
- {
- uint8_t data;
- Wire.beginTransmission(VCNL4000_ADDRESS);
- Wire.write(address);
- Wire.endTransmission();
- delayMicroseconds(170); // delay required
- Wire.requestFrom(VCNL4000_ADDRESS, 1);
- while(!Wire.available());
- return Wire.read();
- }
- // Funkcja odczytu 2 bajtow z podanego adresu
- uint16_t read16(uint8_t address)
- {
- uint16_t data;
- Wire.beginTransmission(VCNL4000_ADDRESS);
- Wire.write(address);
- Wire.endTransmission();
- Wire.requestFrom(VCNL4000_ADDRESS, 2);
- while(!Wire.available());
- data = Wire.read();
- data <<= 8;
- while(!Wire.available());
- data |= Wire.read();
- return data;
- }
- // Funkcja zapisu 1 bajtu do podanego adresu
- void write8(uint8_t address, uint8_t data)
- {
- Wire.beginTransmission(VCNL4000_ADDRESS);
- Wire.write(address);
- Wire.write(data);
- Wire.endTransmission();
- }
Uruchomienie
Materiały dodatkowe
Karta katlogowa czujnika VCNL4000: https://www.jarzebski.pl/datasheets/VCNL4000.pdf
Reklama
Komentarze
Mozna zastosowac to w raspberry pi?
Wygląda na to, że można: http://www.openhomeautomation.net/proximity-alarm-raspberry-pi/
Oryginalny obraz posiada rozmiar 863x487