Mini proiect (44) - Citirea unui senzor RGB TCS3472 și afișarea culorii într-o pagină web

Citirea unui senzor RGB TCS3472 și afișarea culorii într-o pagină web

Dispozitivul TCS3472 pe care l-am testat azi,  oferă detectare digitală a valorilor luminii roșii, verzi și albastre (RGB).  

Un filtru de blocare IR, integrat pe cip și localizat pe fotodiodele de detectare a culorii, minimizează componenta spectrală IR a luminii care intră și permite măsurătorilor de culoare să fie efectuate cu precizie. 

Sensibilitate ridicată, gama largă dinamică și filtrul de blocare IR fac din TCS3472 o soluție ideală de senzor de culoare pentru utilizare în condiții variate de iluminare dar poate fi folosit și prin materiale de atenuare , cum ar fi sticla colorata sau de transparență diferită.  

Datele detectate de senzor sunt transferate prin intermediul  I2C către ESP32.

Dar din păcate valorile returnate de acest senzor sunt pe 16 biți, iar aceste valori nu se pot folosi direct pe o pagină web. A fost nevoie de normalizarea valorile RGB, apoi conversia pe 8 biți, și de a amplifica diferența dintre valorile culorilor (vezi funcția GetRGB888_format).  

Pe lângă citirea culorilor am implementat și un webserver care returnează codul html, care afișează culorile citite. 

Componente

Schema electronică/sistem

Conexiunile senzorului le-am realizat conform cu schema de mai jos: 

  • VIN -> 5 V ESP32
  • GND -> GND ESP32
  • SCL -> D22
  • SDA -> D21 

Rezultat

Mai jos am testat culorile de bază roșu, verde și albastru. Se poate observa în pozele de mai jos și afișarea culorilor în pagina web returnată de severul web implementat pe ESP32.

Citirea culorii roșii

 

 Citirea culorii verzi

 

Citirea culorii albastre

 
 

Valorile RGB pe serial

Valorile le-am afișat și pe serial după cum se poate observa în screen-shotul  mai jos.

Cod de test

/*
Florin Simedru
Complete project details at https://automatic-house.blogspot.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
/***************************************************
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = esp32dev
[env]
monitor_port = COM7
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
upload_port = COM7
lib_deps =
adafruit/Adafruit TCS34725@^1.4.2
ottowinter/ESPAsyncWebServer-esphome@^3.0.0
*/
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include "Adafruit_TCS34725.h"
#include <WiFi.h>
#include <WebServer.h>
String SendHTML(uint8_t red_stat,uint8_t green_stat,uint8_t blue_stat );
void GetRGB888_format(uint16_t red_p, uint16_t green_p, uint16_t blue_p,uint16_t clear);
void handle_NotFound();
void handle_OnConnect();
/* Put your SSID & Password */
const char* ssid = "WIFI_SSID"; // Enter SSID here
const char* password = "WIFI_PASSWORD"; //Enter Password here
WebServer server(80);
uint16_t red_sr =1;
uint16_t green_sr =1;
uint16_t blue_sr =1;
uint16_t clear_sr =1;
uint16_t colorTemp=0;
uint16_t lux =1;
uint16_t red_global = 1;
uint16_t green_global= 1;
uint16_t blue_global= 1;
/* Initialise with default values (int time = 2.4ms, gain = 1x) */
// Adafruit_TCS34725 tcs = Adafruit_TCS34725();
/* Initialise with specific int time and gain values */
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_300MS, TCS34725_GAIN_4X);
void setup(void)
{
Serial.begin(115200);
if (tcs.begin()) {
Serial.println("Found sensor");
} else {
Serial.println("No TCS3472 found ... check your connections");
while (1);
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
delay(100);
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");
// Print ESP32 Local IP Address
Serial.println(WiFi.localIP());
// Now we're ready to get readings!
}
void loop(void)
{
tcs.getRawData(&red_sr, &green_sr, &blue_sr, &clear_sr);
GetRGB888_format((uint16_t)red_sr,(uint16_t)green_sr,(uint16_t)blue_sr,clear_sr);
colorTemp = tcs.calculateColorTemperature_dn40(red_sr, green_sr, blue_sr, clear_sr);
lux = tcs.calculateLux(red_sr, green_sr, blue_sr);
Serial.print("Color Temp: "); Serial.print(colorTemp, DEC); Serial.print(" K - ");
Serial.print("Lux: "); Serial.print(lux, DEC); Serial.print(" - ");
Serial.print("R: "); Serial.print(red_sr, DEC); Serial.print("- R_8b: "); Serial.print(red_global, DEC); Serial.print(" ");
Serial.print("G: "); Serial.print(green_sr, DEC);Serial.print("- G_8b: "); Serial.print(green_global, DEC); Serial.print(" ");
Serial.print("B: "); Serial.print(blue_sr, DEC);Serial.print("- B_8b: "); Serial.print(blue_global, DEC); Serial.print(" ");
Serial.print("C: "); Serial.print(clear_sr, DEC); Serial.print(" ");
Serial.println(" ");
server.handleClient();
}
void handle_OnConnect()
{
server.send(200, "text/html", SendHTML(red_sr,green_sr,blue_sr));
}
void handle_NotFound()
{
server.send(404, "text/plain", "Not found");
}
String SendHTML(uint8_t red_stat,uint8_t green_stat,uint8_t blue_stat )
{
String red_string_sr = String( red_sr);
String green_string_sr = String(green_sr);
String blue_string_sr = String( blue_sr);
String red_string_en = String( red_global);
String green_string_en = String( green_global);
String blue_string_en = String( blue_global);
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>TCS3472 RGB sensor</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
ptr +=".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
ptr +=".button-on {background-color: #3498db;}\n";
ptr +=".button-on:active {background-color: #2980b9;}\n";
ptr +=".button-off {background-color: #34495e;}\n";
ptr +=".button-off:active {background-color: #2c3e50;}\n";
ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<h1>ESP32 Web Server</h1>\n";
ptr +="<h3>Using Access Point(AP) Mode</h3>\n";
ptr +="<p> TCS3472 RGB sensor read </p>\n";
ptr +="<h2 style=\"background-color:rgb(" + red_string_sr + "," + green_string_sr + ","+blue_string_sr+ ");\">TCS3472 RGB 16 bits sensor rgb(" + red_string_sr + "," + green_string_sr + ","+blue_string_sr+ ")</h1>\n";
ptr +="<h2 style=\"background-color:rgb(" + red_string_en + "," + green_string_en + ","+blue_string_en+ ");\">Normalized and Amplify data differences RGB 8 bits(" + red_string_en + "," + green_string_en + ","+blue_string_en+ ")</h1>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
void GetRGB888_format(uint16_t red_p, uint16_t green_p, uint16_t blue_p, uint16_t clear)
{
float i=1;
uint16_t red_l = red_p;
uint16_t green_l = green_p;
uint16_t blue_l = blue_p;
uint16_t sum_l = clear;
//Limit data range
if((red_l >= green_l) && (red_l >= blue_l)){
i = (float)red_l / 256.0 + 1.0;
}
else if((green_l >= red_l) && (green_l >= blue_l)){
i = (float)green_l / 256.0 + 1.0;
}
else if((blue_l >= green_l) && (blue_l >= red_l)){
i = (float)blue_l / 256.0 + 1.0;
}
if(i!=0)
{
red_l = (red_l) / i;
green_l = (green_l) / i;
blue_l = (blue_l) / i;
}
//Amplify data differences
/*Please don't try to make the data negative,
unless you don't change the data type*/
if(red_l > 20)
red_l = red_l - 20;
if(green_l > 20)
green_l = green_l - 20;
if(blue_l> 20)
blue_l = blue_l - 20;
red_l = red_l * 255 / 170;
green_l = green_l * 255 / 170;
blue_l = blue_l * 255 / 170;
if(red_l >255)
red_l = 255;
if(green_l>255)
green_l= 255;
if(blue_l>255)
blue_l = 255;
red_global = red_l;
green_global = green_l;
blue_global = blue_l;
}

Documentație proiect

Alte mini proiecte interesante

Afiliere eMag:

 Linkurile de la secțiunea "Componente" conțin adresa mea de afiliere la eMag.ro, iar dacă cumperi folosind aceste linkuri vei susține blogul meu. Mulțumesc! 

eMag Genius:
Hai și tu în Genius! Abonează-te la Genius 12 luni și primești beneficii premium și 20 lei card cadou eMAG. Profită acum! eMag Genius

Mulțumesc pentru atenție!

Pentru întrebari și/sau consultanță tehnică vă stau la dispoziție pe blog mai jos în secțiunea de comentarii sau pe email simedruflorin@automatic-house.ro. O zi și seară plăcută tuturor !  
 



Etichete

Afișați mai multe

Arhiva

Afișați mai multe