Search

All In One Led Light

About the project

Built Smart LED light with auto ON/OFF, brightness control and night mode using Microchip AVR iot WG development Board with Open Weather Maps and local time

Project info

Difficulty: Moderate

Platforms: AtmelGoogleMicrochip

Estimated time: 1 day

License: MIT license (MIT)

Items used in this project

Hardware components

AVR-IOT WG Evaluation Board AVR-IOT WG Evaluation Board x 1
Power LED Power LED x 1
PC817 Optocoupler PC817 Optocoupler (Important: Use Optocoupler to monitor Only LED Current with digital and power GND isolation) x 1
IRF520 module IRF520 module x 1
Constant Current AD-DC Led driver Constant Current AD-DC Led driver x 1
5V 1 Amp AC to DC Adaptor 5V 1 Amp AC to DC Adaptor x 1
10 JUMPER WIRES 150mm 10 JUMPER WIRES 150mm x 1
Monochrome 0.96" OLED Graphic Display Monochrome 0.96" OLED Graphic Display x 1
Transistor NPN (2N3904) Transistor NPN (2N3904) (Important: Only If INA219 is used to monitor Voltage, Current and Power - No power and digital GND isolation) x 1
LiPower - Boost Converter LiPower - Boost Converter x 1

View all

Software apps and online services

Atmel Start Atmel Start
Atmel Studio Atmel Studio
openweathermap.org openweathermap.org
Google Cloud Google Cloud

Hand tools and fabrication machines

Soldering Iron Soldering Iron x 1
Hot Glue Hot Glue x 1
Paper Cutter Paper Cutter x 1

Story

Built Smart LED light with auto ON/OFF, brightness control and night mode using Microchip AVR iot WG development Board with Open Weather Maps and Local Time based control.

With brightness control feature we can easily turn the same light into night light. Open weather maps is used to get local weather information along with sunrise and sunset time to enable the auto ON/OFF the light. INA219 is used to monitor the current comsumption at any time.

In this projecy AC-DC constant current LED driver is used to provide brightness control through out the 8 bit PWM range.

The onboard light sensor is used to continously monitor the room light and accordingly LED light intensity is varied instead of simply turning ON the LED the light and maintain the constant light level in the room.

Sunset time help indeciding when to stop adjusting the LED brightness and simply turn it on at FULL or user adjustable brightness level.

Create new sensor project using your own Google cloud account and deploying a live UI to Firebase (Help: AVR-IoT User Guide or AVR-IoT Quick Start).

Initalize the TCA0 timer into 8-bit Split mode and set the PD4 pin as output. The TCA0 clock input should be atleast "TCA_SPLIT_CLKSEL_DIV2_gc"otherwise I was getting flickering when adjusting the LED brightness. If using easyPWM library then initlize PWM as shown below;

  1. easyPWM_init(SYSCLK_DIV_2);

WINC1500/1510 wifi module has builtin SNTP feature with time keeping and it is already implemented in this example and we use that feature to check if its sunrise or sunset time. SNTP time update details can be found in "static void wifiCallback(uint8_t msgType, void *pMsg)" function under "case M2M_WIFI_RESP_GET_SYS_TIME" in "cloudwifi_service.c" file.

  1. case M2M_WIFI_RESP_GET_SYS_TIME: {
  2.     tstrSystemTime *WINCTime = (tstrSystemTime *)pMsg;
  3.     struct tm theTime;
  4.  
  5.     // Convert to UNIX_EPOCH, this mktime uses years since 1900 and months are 0 based so we
  6.     // are doing a couple of adjustments here.
  7.     if (WINCTime->u16Year > 0) {
  8.         theTime.tm_hour = WINCTime->u8Hour;
  9. theTime.tm_min = WINCTime->u8Minute;
  10. theTime.tm_sec = WINCTime->u8Second;
  11. theTime.tm_year = WINCTime->u16Year - 1900;
  12. theTime.tm_mon = WINCTime->u8Month - 1;
  13. theTime.tm_mday = WINCTime->u8Day;
  14. theTime.tm_isdst = 0;
  15. set_system_time(mktime(&theTime));
  16.     }
  17.     break;
  18. }

Now modify the "SENSORS_getLightValue(void)" function in "sensors_handling.c" to get as smooth as possible sensor readings. Without these modification TEMT6000 reading varies alot and it can cause LED flickering.

Replace this:

  1. uint16_t SENSORS_getLightValue(void)
  2. {
  3. return ADC_0_get_conversion(LIGHT_SENSOR_ADC_CHANNEL);
  4. }

with this:

  1. uint32_t ADC_0_measurement=0;
  2. uint8_t ADC_0_samples=10;
  3. uint8_t ADC_SAMPNUM=64;
  4.  
  5. uint16_t SENSORS_getLightValue(void)
  6. {
  7.     ADC_0_measurement = 0;
  8.     for(int i=0; i<ADC_0_samples; i++){
  9.      ADC_0_measurement += ADC_0_get_conversion(LIGHT_SENSOR_ADC_CHANNEL);
  10.     }
  11.     float result = ADC_0_measurement;
  12.     result /= (ADC_0_samples * ADC_SAMPNUM);
  13.     return (uint8_t)result; // easily usable value for PWM duty cycle control
  14. }
  15.  
  16.  

Also modify these line in "ADC_0_init()" function in "adc_basic.c" as shown below:

  1.     ADC0.CTRLB = ADC_SAMPNUM_ACC64_gc; /* 64 ADC sample */
  2.     ADC0.SAMPCTRL = 0x8 << ADC_SAMPLEN_gp; /* Sample length: 0x8 */
  3.     ADC0.CTRLD = 1 << ADC_ASDV_bp /* Automatic Sampling Delay Variation: enabled */
  4. | 0x0 << ADC_SAMPDLY_gp /* Sampling Delay Selection: 0x0 */
  5. | ADC_INITDLY_DLY16_gc; /* Delay 16 CLK_ADC cycles */

Create new open weather map account and get API to get weather data along with sunrise, sunset time for automatic turn on the Low power mode by turning ON the LED at full power.

  1. http://api.openweathermap.org/data/2.5/weather?q=City,XX&appid=XXXXXX API KEY XXXXXXXX

Here replace "city,XX" with your own city name and XX country code. Also replace the "XXXXXX API KEY XXXXXXXX" with default or generated api key.

Newly created account and API key will take some (few hours) setup time. You can test the above link in your browser to find out if your account and api key is setup or not. If API key is not setup yet then you will see error like shown below.

When API key is setup and then you will see this by visiting the above mentioned link.

Now we can add the details of open weather map account into our account to get the local sunrise, sunset and latest clouds information. (other data can be useful i.e: out door and indoor temperature and humidity comparison OR built a weather display etc).

  1. char *server = "api.openweathermap.org";
  2. char *apiKey = "XXXXXXXXX API key XXXXXXXXX";
  3. char *cityNames[] = {"CITY,XX"};
  4. char *currentWeather = "GET /data/2.5/weather?";

We can use the above data to send a TCP/IP GET request and pass on the received data to "parse_OWMdata" for further data processing.

Parse OWM data to assign sunrise and sunset time to these global variables using function given below

  1. uint32 t_sunrise;
  2. uint32 t_sunset;

  1. void parse_OWMdata (uint8_t *payload) {
  2. // char payload[]="{"coord":{"lon":XX.XX,"lat":XX.XX},"weather":[{"id":721,"main":"Haze","description":"haze","icon":"50n"}],"base":"stations","main":{"temp":295.51,"pressure":1010,"humidity":47,"temp_min":294.15,"temp_max":297.15},"visibility":5000,"wind":{"speed":2.6,"deg":260},"clouds":{"all":40},"dt":1554046200,"sys":{"type":1,"id":7585,"message":0.0048,"country":"XX","sunrise":1553993593,"sunset":1554038432},"id":1172451,"name":"City","cod":200}";
  3. char *sunrise = ""sunrise":";
  4. char *sunset = ""sunset":";
  5. char *subString;
  6. char *resString;
  7.  
  8. if ((subString = strstr((char *)payload, sunrise))) {
  9. int i = strlen(sunrise);
  10. int j=0;
  11. while (subString[i]!= ','){
  12. resString[j] = subString[i];
  13. j++;
  14. i++;
  15. }
  16. resString[j]='';
  17. t_sunrise = atoi(resString); //global variable
  18. }
  19. if ((subString = strstr((char *)payload, sunset))) {
  20. int i = strlen(sunset);
  21. int j=0;
  22. while (subString[i]!= ','){
  23. resString[j] = subString[i];
  24. j++;
  25. i++;
  26. }
  27. resString[j]='';
  28. t_sunset = atoi(resString); //global variable
  29. }
  30. }

Replace following line in "receivedFromCloud()" function in "main.c" to turn ON or OFF the light using cloud, as shown below;

  1. /* Replace this Line */
  2. // LED_holdYellowOn(subString[strlen(toggleToken)] == '1');
  3. /* with this Line */
  4. led_status=(subString[strlen(toggleToken)] == '1')? 1:0;

Modify the "sendToCloud()" function in "main.c" to store led current power consumption and outdoor weather (cloud) data as shown below;

  1. void sendToCloud(void)
  2. {
  3. static char json[70];
  4.  
  5. // This part runs every CFG_SEND_INTERVAL seconds
  6. int rawTemperature = SENSORS_getTempValue();
  7. int light = SENSORS_getLightValue();
  8.         /* measuring only LED current with digital and power ground isolation */
  9. int led_power = INA219_getPowerValue();
  10.         /* clouds data to estimate outdoor natural light availability */
  11. int OWM_clouds = OWM_getCloudValue();
  12. int len = sprintf(json, "{"Light":%d,"Power":%d,"Clouds":%d,"Temp":"%d.%02d"}", light, led_power, OWM_clouds, rawTemperature / 100, abs(rawTemperature) % 100);
  13.  
  14. if (len > 0) {
  15. CLOUD_publishData((uint8_t *)json, len);
  16. LED_flashYellow();
  17. }
  18. }

Final Assembly:

s

Additional Help Sources:

OpenWeatherMap: Basic GuideAPI Reference.

WINC 1510 SNTP: ASF WINC components documentation and Tutorial How to read display and set ATWINC1500 system time and WINC1500 Software Design Guide. (Already implemented in Sensor Node example)

IRF520: Datasheet.

MT3608: Datasheet.

8-bit PWM: Tutorial, Git-hub.

INA219: Tutorial, Git-hub.

 

Schematics

Circuit Diagram

Sorry for my bad handwriting and drawing

Credits

Photo of mahmood_ul_hassan

mahmood_ul_hassan

Electronics Engineer with specialization in Robotics Engineering, seven years of experience in electronics research and development. I worked mostly on designing custom labview based automatic test and measurement equipment. Hobbyist, ARM enthusiast, DIY maker

   

Leave your feedback...