Ambient Light Controller Software

Ambient Light Controller Software

Please read Liability Disclaimer and License Agreement CAREFULLY

This piece of software is running on the Ambient Light Controller described in Ambient light with APA102 and MQTT

The main features are:

- Read the voltage, curent and power information provided by INA260 using I2C protocol and timers

- Get the color data from Ambient Light Sensor Controller's and send gain value using USART

- Send and receive data to/from ESP8266 attached to this board (MQTT topics values) using USART

- Send data to APA102 RGB LED strips concted on SPI

- All USART receive are done using DMA to minimize the load on the MCU

In main.c I use timeToRead as a fix time period reminder to read the data from INA260, timeToSend  is used to send the energy consumption data to ESP8266. 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
{
	if(htim->Instance==TIM2) {
		timeToRead = 1;
	} else if(htim->Instance==TIM3){
		timeToSend = 1;
  }
}

The main algorithm logic is:

- If the MQTT power is set to Off, then we turn Off the LED strips

- If MQTT power topic is On, then if we are in MQTT Sensor mode we check if we got data from Ambient Light Sensor Controller and then we send the data to APA102 LED Strips

- If we are not in Sensor mode we are in automatic effects or we get the color directly from OpenHAB, in both situation we push the color data to LED strips

- If is time to read the INA260 data, we read it and we store it in a buffer.

- If is time to send the INA260 data, we use USART3 in DMA mode to send the buffer to ESP8266

- If we have new data from ESP8266 we check to see if we have updates for brightness vale and gain. If new values are available we update the old ones and forward the new values.

//The Power state has changed
		if(prevPower != frame_MQTT[Power]){
			prevPower = frame_MQTT[Power];
			//The power is ON
			if(!prevPower){
				APA_setAllColor(0, 0, 0);
				APA_setAllBrightness(0);
				APA_update(0);
				APA_update(1);
				//Stop DMAs to save power?
			}
		}
		//If Power is ON
		if(prevPower){
			// We are in sensor mode
			if(frame_MQTT[Mode]){
				//We have hata from left side sensor
				//0, 1, 2 Top Sensor - near debug interface
				//6, 7, 8 Bottom Sensor - near case wall
				if(LC_Ready){
					//tL = HAL_GetTick() - tL1;
					for(cnt = 0; cnt < FirstThird; cnt++){
						APA_setColor(cnt, rxL[0], rxL[1], rxL[2]);
						APA_setColor(cnt + FirstThird, rxL[3], rxL[4], rxL[5]);
						APA_setColor(cnt + SecondThird, rxL[6], rxL[7], rxL[8]);
					}
					APA_update(0);
					LC_Ready = 0;
					//tL1 = HAL_GetTick();
				}
				//We have hata from right side sensor
				if(RC_Ready){
					//tR = HAL_GetTick() - tR1;
					for(cnt = 0; cnt < FirstThird; cnt++){
						APA_setColor(cnt, rxR[0], rxR[1], rxR[2]);
						APA_setColor(cnt + FirstThird, rxR[3], rxR[4], rxR[5]);
						APA_setColor(cnt + SecondThird, rxR[6], rxR[7], rxR[8]);
					}
					APA_update(1);
					RC_Ready = 0;
					//tR1 = HAL_GetTick();
				}
			}	else {
				// Run lights effects
				if(frame_MQTT[Effect]){
					//If an effect was completed
					if(effectDone){
						//We start a new one
						effectDone = 0;
						switch(frame_MQTT[Effect]){
							case 1: 
								SnowFlakes();
							break;
							case 2: 
								RandomSparkle();
							break;
							case 3: 
								RainbowCycle();
							break;
							default:
								SnowFlakes();
						}				
					}
				} else {//Set color from OpenHab interface
					//update only if we have new data
					if(ESP_Ready){
						APA_setAllColor(frame_MQTT[LeftRed], frame_MQTT[LeftGreen], frame_MQTT[LeftBlue]);
						APA_update(0);
						APA_setAllColor(frame_MQTT[RightRed], frame_MQTT[RightGreen], frame_MQTT[RightBlue]);
						APA_update(1);
						ESP_Ready = 0;
					}
				}
			}
		} //Power on
		//Send energy measurements to ESP to be displayed in OpenHab
		if(timeToRead){
			if(ina260_conversion_ready()){
				ina260_get_voltage(&measures[0]);
				ina260_get_current(&measures[1]);
				ina260_get_power(&measures[2]);
				//Transform Power to Energy
				measures[3] += measures[2] * sHour;
//				for(cnt=0;cnt<4;cnt++){
//					printf("Measure %d = %.10f\r\n", cnt, measures[cnt]);
//				}
				timeToRead = 0;
			}
		}
		//Send the values every 30s to avoid loading Zigbee network
		if(timeToSend){
			//4x floats = 16bytes
			memcpy(valToSend+1, measures, 16);
			HAL_UART_Transmit_DMA(&huart3, (uint8_t *)&valToSend, txLen);
			timeToSend = 0;
		}
		// We have data from ESP (MQTT)
		if(ESP_Ready){
			//Set up LED brightness and sensor gain
			if(prevBright != frame_MQTT[Intensity]){
				prevBright = frame_MQTT[Intensity];
				APA_setAllBrightness(prevBright);
			}
			if(prevGain != frame_MQTT[Gain]){
				prevGain = frame_MQTT[Gain];
				uint8_t sendGain[3] = {sMarker, prevGain, eMarker};
				HAL_UART_Transmit(&huart1, sendGain, 3, TIME_OUT);
				HAL_UART_Transmit(&huart2, sendGain, 3, TIME_OUT);
			}
			ESP_Ready = 0;
		}

The full code can be downloaded here.

Comments powered by CComment

Who’s online

We have 34 guests and no members online