Christian
Published © GPL3+

Professional Hydroponics Light Monitoring

Build a Monitoring System that will measure your light levels

IntermediateFull instructions provided2 hours978

Things used in this project

Hardware components

IO Expander Bundle
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Professional Hydroponics Light Monitoring

Wiring Diagram

Code

Professional Hydroponics Light Monitoring

C/C++
Calculate the light color temperature in degrees Kelvin and Luminescence level in lux by using the raw Red, Green, and Blue components
const char ONEWIRE_TO_I2C_LIGHT[] = "i2s58"; // I2C BUS - Light Sensor
const char LIGHT_SENSOR[] =     "st15;sp2";  // TCS34725 RGB Sensor; Turn LED off
 
...
 
  int color_temp, lux;
 
...
 
        // Check for RGB light sensor
        color_temp = -1; lux = -1;
        if (SerialCmdNoError(ONEWIRE_TO_I2C_LIGHT) &&
            SerialCmdDone(LIGHT_SENSOR)) {
          SerialCmd("sr");
          if (SerialReadInt(&r))
          {
            SerialReadInt(&g);
            SerialReadInt(&b);
            SerialReadInt(&c);
            SerialReadInt(&atime);
            SerialReadInt(&gain);
            if (r == 0 && g == 0 && b == 0) {
              color_temp = lux = 0;
            }
            else {
              /* AMS RGB sensors have no IR channel, so the IR content must be */
              /* calculated indirectly. */
              ir = (r g b > c) ? (r g b - c) / 2 : 0;
 
              /* Remove the IR component from the raw RGB values */
              r2 = r - ir;
              g2 = g - ir;
              b2 = b - ir;
 
              /* Calculate the counts per lux (CPL), taking into account the optional
                    arguments for Glass Attenuation (GA) and Device Factor (DF).
 
                    GA = 1/T where T is glass transmissivity, meaning if glass is 50%
                    transmissive, the GA is 2 (1/0.5=2), and if the glass attenuates light
                    95% the GA is 20 (1/0.05). A GA of 1.0 assumes perfect transmission.
 
                    NOTE: It is recommended to have a CPL > 5 to have a lux accuracy
                          < +/- 0.5 lux, where the digitization error can be calculated via:
                          'DER = (+/-2) / CPL'.
              */
              float cpl = (((256 - atime) * 2.4f) * gain) / (1.0f * 310.0f);
 
              /* Determine lux accuracy (+/- lux) */
              float der = 2.0f / cpl;
 
              /* Determine the maximum lux value */
              float max_lux = 65535.0 / (cpl * 3);
 
              /* Lux is a function of the IR-compensated RGB channels and the associated
                 color coefficients, with G having a particularly heavy influence to
                 match the nature of the human eye.
 
                 NOTE: The green value should be > 10 to ensure the accuracy of the lux
                       conversions. If it is below 10, the gain should be increased, but
                       the clear<100 check earlier should cover this edge case.
              */
              gl =  0.136f * (float)r2                   /** Red coefficient. */
                    1.000f * (float)g2                   /** Green coefficient. */
                    -0.444f * (float)b2;                    /** Blue coefficient. */
 
              lux = gl / cpl;
 
              /* A simple method of measuring color temp is to use the ratio of blue */
              /* to red light, taking IR cancellation into account. */
              color_temp = (3810 * (uint32_t)b2) /        /** Color temp coefficient. */
                           (uint32_t)r2 1391;           /** Color temp offset. */
            }
          }
          else {
            // Check for over saturation
            SerialReadUntil(NULL, NULL, 0, '\n');
            SerialReadString(error, sizeof(error));
            SerialDebug.println(error);
            if (!strcmp(error, "E13")) color_temp = ERROR_OVER_SATURATED;
          }
          SerialReadUntilDone();
        }
        else color_temp = ERROR_NO_ROM;
 
...
 
            if (color_temp != ERROR_NO_ROM) {
              if (co2 == ERROR_NO_ROM || clk.tm_min & 1 == 0) {
                Serial.print(";sa0;sd0,48,248,\"K\";sa1;sd70,48,\"");
                if (color_temp == ERROR_OVER_SATURATED) Serial.print("SAT\"");
                else {
                  Serial.print(color_temp);
                  Serial.print("\";sd127,48,\"");
                  Serial.print(lux);
                  Serial.print("\"");
                }
              }
            }
 

Credits

Christian

Christian

24 projects • 134 followers
Senior Embedded Engineer

Comments