Introduction: Control High-powered LED Panel by Arduino Real Time With Log Data, Luminosity Sensor, LCD Display
- Is this enough of LED controller around? Yes, there are many LED control guides we can find on the Internet. One objective of my quest was to control a powered LED panel with a defined profile light intensity and real-time clock, and a light sensor to double check the output of LED panel. The input, output of light intensity are logged into SD card for a post-analysis.
- What are the parts? Below are the parts I have in my projects, details will be present along the way.
- Optional: I want to mimic a profile of solar intensity, which depends on the region, and the reason. The profile is hours vs. intensity of light. I grew algae so that the particle properties (uE, a photon) of light is the primary metric (can be 2200 uE/m2-s in the range of 400-700 nm in the summer's noon). Other light units are W/m2, lux, candle/ft. The conversion is between those sources have to be taken into account of the light source (or the spectrum of the light source).
- Optional: The key difference of my setup with other solar simulation is that I use an array to define a solar value (between 0-100%), and another array to store time value. With a defined time interval (5min), the program reads the real-time values, check a time value stored in arrays. If a new values (time, intensity) are found, the Arduino then writes those inputs via PWM pins to the enabling pin the LED driver. See the chart for a less wordy explanation.
- Important if you have not played with LED before: To turn on the LED, a voltage larger than the forward voltage is applied. The LED (which is a special diode) turn from non-conductible (the internal resistor is very large) to conductible (the resistant is very small). The chip will allow whatever current on DC source to run through. If no heatsink is provided, the chip will be burnt out because of too much heat. You have less than 2sec to see this busting of LED chip. And limiting the current below the forward current is a MUST.
- Here is a good intro to LED light:
Step 1: Get the Parts
- 10W (cool-white) LED Chip ( https://goo.gl/hZLC1R), $13/10pcs. Specs: Forward current (If): 900 mA, Forward voltage (Vf) (9-12V) which means the LED is turned on with an applied voltage somewhere in 9-12 V, and the current run through the chip should not exceed 900 mA.
- LED driver (300-3000mA): https://goo.gl/nmx8La, $10/board. The board is step down voltage which means the input DC has to be larger than Vf of one chip or (x Vf when x of chips is wired together in series). I wired there chips in serial and applied a DC 36 V for one bank. The light intensity is controlled by PWM on the enable pin via Arduino pin with the resistors to limit the back-wash current. For this board, full output when the enabling pin is grounded, and zero with 5V reference. I would advise against wiring chips in parallel, except if you want to test the Ohm's law.
- Heatsink (or a block of metal). This one comes with bolts and thermal gel (https://goo.gl/wT995c). It is a block of aluminum ($10/block). I put 3 x 10 W chip on one block. With the temperature room about 22-25 oC, the temperature from the block is about 50-55 oC.
- Arduino Mega: ($44/board) like this one (https://goo.gl/pvSMdc), you can find a generic board on Amazon, or other electronic outlets with about 1/3 of the price. I use Mega, but Uno or Nano version should work (change pins for SD card).
- LCD display: like this one: https://goo.gl/TSZyis, $6.99
- Real-time Clock 1307 breakout, $9.90, https://goo.gl/NSv3Uu
- SD card, $5.99: https://goo.gl/1tHZMm, and SD card: +$4
- Luminosity sensor (give output as lux),$6.95 (https://goo.gl/8Mh4x3). A photoresistor would work as a raw indicator
- DC supplier. I used this one: Mean Well 36V, 350W (https://goo.gl/UY5BXK ), $50.90. This one has a built-in fan controller. It is really quite when I drew out about 4A for my system. The DC source is depended on your LED panel. It can be a wall adapter (12V, 2A) if you want to run 3x3W (LED) with LED driver.
Step 2: Let Wiring and Coding
- The wiring is rather simple. Only thing I would restate is to put the resistor to 5mm LED (220 ohm), and wires connected to GND and EN pins on LED driver. I used 4.7k ohm for that last two.
- Other independent libraries: RTClib.h, Adafruit_GFX.h, Adafruit_SSD1306.h, Adafruit_TSL2591.h. You can download them via Adafruit website or its Github.
- Here is the code. An easier way is to download .ino file and open it by Arduino IDE.
/*
Control LED intensity by a timer Log data via a lux sensor By Binh Nguyen, May 13, 2016, update Update on Nov 11, 2017 (removing extra setup for TLS 2591 */ #include // Wire libary for I2C comunication #include // Date and time functions using a DS1307 RTC connected via I2C and Wire li
RTC_DS1307 rtc;
#include // Needed for SD libarary #include // SD card to store data
#include //For OLED Display #include #define OLED_RESET 4 Adafruit_SSD1306 oled(OLED_RESET);
#include // For Luminosity sensor #include "Adafruit_TSL2591.h" Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later) long lux2; // store luminosity const int chipSelect = 53; // need to figure out for Adafruit SD breakout//https://learn.adafruit.com/adafruit-micro-sd-breakout-board-card-tutorial/wiring // CLK (52|13); DO (50|12); DI (51|11); CS (53|10) char logFileName[] = "Light.txt"; // modify logFileName to identify your experiment, for exampe PBR_01_02, datalog1 String dataString; long id = 1; //the id number to enter the log order float hour24 [] = {0.0, 1.0, 2.0, 3.0, 4.0, 4.95, 5.20, 5.45, 5.70, 5.95, 6.20, 6.45, 6.70, 6.95, 7.20, 7.45, 7.70, 7.95, 8.20, 8.45, 8.70, 8.95, 9.20, 9.45, 9.70, 9.95, 10.20, 10.45, 10.70, 10.95, 11.20, 11.45, 11.70, 11.95, 12.20, 12.45, 12.70, 12.95, 13.20, 13.45, 13.70, 13.95, 14.20, 14.45, 14.70, 14.95, 15.20, 15.45, 15.70, 15.95, 16.20, 16.45, 16.70, 16.95, 17.20, 17.45, 17.70, 17.95, 18.20, 18.45, 18.70, 18.95, 19.20, 19.45, 19.70, 19.95, 20.0, 21.0, 22.0, 23.0, 23.5, 24.0}; //hour summer 2014 float intensity [] = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, //hour 0.0, 1.0, 2.0, 3.0, 4.0, 4.95, 0.00, 0.00, 0.00, 0.00, // 5.20, 5.45, 5.70, 5.95, 0.00, 0.01, 0.02, 0.06, // 6.20, 6.45, 6.70, 6.95, 0.09, 0.13, 0.17, 0.22, // 7.20, 7.45, 7.70, 7.95, 0.26, 0.34, 0.37, 0.46, // 8.20, 8.45, 8.70, 8.95, 0.54, 0.67, 0.65, 0.69, // 9.20, 9.45, 9.70, 9.95, 0.77, 0.81, 0.90, 0.78, // 10.20, 10.45, 10.70, 10.95, 0.89, 0.76, 0.84, 0.90, // 11.20, 11.45, 11.70, 11.95, 0.87, 0.91, 1.00, 0.95, // 12.20, 12.45, 12.70, 12.95, 0.83, 0.79, 0.79, 0.84, // 13.20, 13.45, 13.70, 13.95, 0.82, 0.60, 0.48, 0.61, // 14.20, 14.45, 14.70, 14.95, 0.42, 0.42, 0.47, 0.42, // 15.20, 15.45, 15.70, 15.95, 0.39, 0.41, 0.37, 0.27, // 16.20, 16.45, 16.70, 16.95, 0.31, 0.33, 0.30, 0.32, // 17.20, 17.45, 17.70, 17.95, 0.25, 0.21, 0.18, 0.12, // 18.20, 18.45, 18.70, 18.95, 0.07, 0.04, 0.02, 0.01, // 19.20, 19.45, 19.70, 19.95, 0.00, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // 20.0, 21.0, 22.0, 23.0 float timechecker; int pinLED = 9; int pinLEDX = 10;
void advancedRead(void){ // More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum // That way you can do whatever math and comparisons you want! uint32_t lum = tsl.getFullLuminosity(); uint16_t ir, full; ir = lum >> 16; full = lum & 0xFFFF; long vis = full - ir; long lux = tsl.calculateLux(full, ir); lux2 = lux; dataString += String(ir)+","; dataString += String(vis)+","; dataString += String(lux) +","; Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] "); Serial.print("IR: "); Serial.print(ir); Serial.print(" "); Serial.print("Full: "); Serial.print(full); Serial.print(" "); Serial.print("Visible: "); Serial.print(full - ir); Serial.print(" "); Serial.print("Lux: "); Serial.println(tsl.calculateLux(full, ir)); } void unifiedSensorAPIRead(void){ sensors_event_t event; // Get a new sensor event tsl.getEvent(&event); //Serial.print("[ "); Serial.print(event.timestamp); Serial.print(" ms ] "); // Display the results (light is measured in lux) if ((event.light == 0) | // If event.light = 0 lux the sensor is probably saturated (event.light > 4294966000.0) | //if event.light is +/- 4294967040 there was a float over/underflow (event.light <-4294966000.0)) { Serial.println("Invalid data (adjust gain or timing)"); } else{ Serial.print(event.light); Serial.println(" lux");} }
void setup(){ Serial.begin(9600); // Start Serial commnication Wire.begin(); pinMode(pinLED, OUTPUT); pinMode(pinLEDX, OUTPUT); Serial.print("RTC is..."); if (! rtc.begin()){ Serial.println("RTC: Real-time clock...NOT FOUND"); while (1);// (Serial.println("RTC: Real-time clock...FOUND")); } Serial.println("RUNNING"); Serial.print("Real-time Clock..."); if (! rtc.isrunning()){ rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); } Serial.println("WORKING"); Serial.print("SD card..."); // see if the card is present and can be initialized: if (!SD.begin(chipSelect)){ Serial.println("Failed"); // don't do anything more: return; } Serial.println("OK"); Serial.print("Log File: "); Serial.print(logFileName); Serial.print("..."); File logFile = SD.open(logFileName, FILE_WRITE); // open the file. "datalog" and print the header if (logFile){ logFile.println(", , , , , , "); //indicate there were data in the previous run String header = "ID, Date Time, TimeCheck, % Ouput, IR, VIS, Lux"; logFile.println(header); logFile.close(); Serial.println("READY"); } else Serial.println("error opening datalog"); // if the file isn't open, pop up an error:
if (tsl.begin()){ // Display some basic information on this sensor Serial.println("Found a TSL2591 sensor");} else { Serial.println("No sensor found ... check your wiring?"); //while (1); //while (1) uncomment it to bypass the looping while. } tsl.setGain(TSL2591_GAIN_MED); // Setup time (duration) for intergration of light intensity, a long time for a lower light (darker) tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Setup OLED display oled.clearDisplay(); delay(1000); oled.setTextSize(1); oled.setTextColor(WHITE); oled.setCursor(0,0); oled.println("Welcome..."); oled.println("Light Control"); oled.println("SD Card READY"); oled.println("CLOCK READY"); oled.println("LogFile READY"); oled.display(); oled.clearDisplay(); id = 1; delay(4000); }
void loop(){ dataString = String(id); dataString += String(','); DateTime now = rtc.now(); int houR = (int)now.hour(); float minutE = (float)now.minute(); timechecker = houR + minutE/60; //Serial.print("Minutes/60, "); //Serial.println(minutE/60); float record; int locator; for (int i=0; i<100; i ++){ if (( hour24[i]-timechecker >=0) ){ record = intensity[i]; break; } } Serial.print("Locator:"); Serial.println(locator); int lightout = record*255; //the LED board controls the current to the MAX (set) value when ENABLE Pin is connecte to GND, and ZERO when ENABLE Pin to VNCC (5V) analogWrite(pinLED, lightout); int lightout2 = 255- lightout; //flip the small LED so it is on the trend with the high-powered LED panel. analogWrite(pinLEDX, lightout2); Serial.print("Lightout, "); Serial.println(lightout); //delay(2000); //Serial.println("Hardcode"); //analogWrite(pinLED, 150); String datE = String(now.year(), DEC)+"/"; //format date and time as yyyy/mm/dd hh:mm:ss datE += String(now.month(), DEC)+"/"; datE += String(now.day(), DEC); String timE = String(now.hour(), DEC)+":"; timE += String(now.minute(), DEC)+":"; timE += String(now.second(), DEC); datE += " " + timE; oled.setTextSize(1); oled.setTextColor(WHITE); oled.setCursor(0,0); dataString += datE + ","; dataString += String(timechecker) + ","; dataString += String(record) + ","; advancedRead(); //get the value of light sensor oled.println(datE); //print out the value and status to LCD oled.print("Time,hrs: "); oled.println(timechecker); oled.print("Output,%: "); oled.println(record); oled.print("LI: "); oled.print(lux2); oled.println(" lux"); oled.display(); File dataFile = SD.open(logFileName, FILE_WRITE); // open the file. note that only one file can be open at a time, so you have to close this one before opening another. if (dataFile){ // if the file is available, write to it: dataFile.println(dataString); dataFile.close(); Serial.print("Recording: "); Serial.println(dataString); // print to the serial port too: } else { Serial.println("error opening datalog file"); } // if the file isn't open, pop up an error: oled.clearDisplay(); delay(300000); //delay for 5 minutes
id ++; dataString = "";
}
--end of the code--
Attachments
Step 3: Outputs:
1. Output by basic parameters on 128x64 OLED display:
2. Logged data in text file that can be exported to speedsheet application (like Excel and LibreOffice Calc). Make the chart for presentation.
Step 4: Bonus: Photobioreactor and How Light Spectrum Is Colorful!
This is not a part of the tutorial but the graph of spectra is useful, especially when we are talking about colors wavelength, Also, a reactor for algae cultivation!
Acknowledgement:
I pursued this project while working on an advanced photobioreactor for algal cultivation. I would like to thank Dr. Bruce E. Rittmann at Biodesign Swette Center for Environmental Biotechnology, Arizona State Univesity and U.S. Department of Energy, Office of Energy Efficiency and Renewable Energy Targeted Algal Biofuels and Bioproducts, grant #: DE-EE0007093: “Atmospheric CO2 Enrichment and Delivery (ACED),” for the supports and the freedom to explore.