diff options
Diffstat (limited to 'Libraries/LightSensor')
-rw-r--r-- | Libraries/LightSensor/light_sensor_task.c | 225 | ||||
-rw-r--r-- | Libraries/LightSensor/light_sensor_task.h | 26 |
2 files changed, 251 insertions, 0 deletions
diff --git a/Libraries/LightSensor/light_sensor_task.c b/Libraries/LightSensor/light_sensor_task.c new file mode 100644 index 0000000..59a0a3f --- /dev/null +++ b/Libraries/LightSensor/light_sensor_task.c @@ -0,0 +1,225 @@ +#include "light_sensor_task.h" +#include "ltimers.h" + +// FreeRTOS includes +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +// Если используется фоторезистор: +// - калибровка датчика освещенности ? +// - добавить гистерезис +// - плавное изменение яркости +// - как будет реагировать фоторезистор на мерцание 50 Гц, 100 Гц на диодное и тд. + +// * Фоторезистор GL5516 стоит в нижнем плече делителя. В врехнем плече на питание +// +3.3В подключен резистор 10К. +// Фоторезистор в полной темноте дает сопротивление до 6МОм, на свету у окна +// в пасмурную питерскую погоду около 200 Ом, а если на ярком солнце, то и еще +// меньше. +// В итоге, чем ярче освещение, тем ниже сопротивление, тем ниже напряжение +// на АЦП. +// +// Порог переключения яркости ламп нужно в приложении настраивать под себя. +// И сделать по умолчанию. +// +// - теперь нужно опытным путем определить порог, когда лампам нужно убавить яркость +// Для начала сделать только два варианта - светло/темно. + +#define LIGHT_THREHSOLD 3300 // Значение АЦП, подобранное опытным путем +#define LIGHT 0 +#define DARK 1 + +#define TIME_LIGHT_SENSOR 3000 //ms + +static void ADC_Config(void); + +static uint16_t ADC_ConvertedValue = 0;//, ADC_ConvertedVoltage = 0; +QueueHandle_t queue_light_sensor; + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +void LightSensorInit ( void ) +{ + // - ADC init + ADC_Config (); + queue_light_sensor = xQueueCreate ( 1, sizeof (LightSensorState_t) ); + configASSERT( queue_light_sensor ); +} + + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +static void ADC_Config(void) +{ + ADC_InitTypeDef ADC_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + + /* GPIOC Periph clock enable */ + RCC_AHBPeriphClockCmd(LIGHT_SENSOR_RCC_AHBPeriph_GPIOx, ENABLE); + + /* ADC1 Periph clock enable */ + LIGHT_SENSOR_RCC_APBxPeriphClockCmd(LIGHT_SENSOR_RCC_APBxPeriph_ADCx, ENABLE); + + /* Configure ADC Channelx as analog input */ + GPIO_InitStructure.GPIO_Pin = LIGHT_SENSOR_GPIO_PINx ; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; + GPIO_Init(LIGHT_SENSOR_GPIOx, &GPIO_InitStructure); + + /* GPIO pin configuration */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; + GPIO_Init ( GPIOB, &GPIO_InitStructure ); + + /* ADCs DeInit */ + ADC_DeInit(LIGHT_SENSOR_ADCx); + + /* Initialize ADC structure */ + ADC_StructInit(&ADC_InitStructure); + + /* Configure the ADC1 in continuous mode with a resolution equal to 12 bits */ + ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; + ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; + ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; + ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; + ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward; + ADC_Init(LIGHT_SENSOR_ADCx, &ADC_InitStructure); + + /* Convert the ADC1 Channel 11 with 239.5 Cycles as sampling time */ + ADC_ChannelConfig(LIGHT_SENSOR_ADCx, LIGHT_SENSOR_ADC_Channelx , ADC_SampleTime_239_5Cycles); + + /* ADC Calibration */ + ADC_GetCalibrationFactor(LIGHT_SENSOR_ADCx); + + /* Enable the ADC peripheral */ + ADC_Cmd(LIGHT_SENSOR_ADCx, ENABLE); + + /* Wait the ADRDY flag */ + while(!ADC_GetFlagStatus(LIGHT_SENSOR_ADCx, ADC_FLAG_ADRDY)); + + /* ADC1 regular Software Start Conv */ + ADC_StartOfConversion(LIGHT_SENSOR_ADCx); + +} + + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +void ProcessFSM_LightSensor ( void ) +{ + static uint8_t process_light_state = 0; + LightSensorState_t light_sensor_state; + + // - curr и prev light + //static uint8_t curr_light = DARK; + //static uint8_t prev_light = LIGHT; + + /* Test EOC flag */ + // - заменить этот файл на проверку и выход + while(ADC_GetFlagStatus(LIGHT_SENSOR_ADCx, ADC_FLAG_EOC) == RESET); + + /* Get ADC1 converted data */ + ADC_ConvertedValue = ADC_GetConversionValue(LIGHT_SENSOR_ADCx); + + switch ( process_light_state ) + { + case 0: // ждем когда посветлеет + if (ADC_ConvertedValue < LIGHT_THREHSOLD) // если стало светло + { + // - запускаем таймер, в течение которого проверяем освещение + StartLTimer (LTIMER_LIGHT_SENSOR); + // - переходим в состояние проверки яркости в течение таймера + process_light_state = 2; + } + break; + + case 1: // ждем когда потемнет + if (ADC_ConvertedValue > LIGHT_THREHSOLD) // если стало темно + { + // - запускаем таймер, в течение которого проверяем освещение + StartLTimer (LTIMER_LIGHT_SENSOR); + // - переходим в состояние проверки яркости в течение таймера + process_light_state = 3; + } + break; + + case 2: + if ( GetLTimer (LTIMER_LIGHT_SENSOR) >= TIME_LIGHT_SENSOR ) + { + // - если таймер вышел, значит подтверждается новое значение + // освещенности + // - отправляем сообщение на смену режима + light_sensor_state = LIGHT_SENSOR_STATE_LIGHT; + xQueueSend ( queue_light_sensor, &light_sensor_state, 0 ); + // - а затем идем проверять когда потемнеет + process_light_state = 1; + } + else + { + // - если таймер еще тикает, то проверяем освещенность + // и, если она изменилась, то возвращаемся в состояние 0 + // то есть в начало алгоритма проверки яркости (освещенности) + if (ADC_ConvertedValue < LIGHT_THREHSOLD) + { + // то ничего не меняем + } + else + { + process_light_state = 0; + } + } + break; + + case 3: + if ( GetLTimer (LTIMER_LIGHT_SENSOR) >= TIME_LIGHT_SENSOR ) + { + // - если таймер вышел, значит подтверждается новое значение + // освещенности + // - отправляем сообщение на смену режима + light_sensor_state = LIGHT_SENSOR_STATE_DARK; + xQueueSend ( queue_light_sensor, &light_sensor_state, 0 ); + // - а затем идем проверять когда посветлеет + process_light_state = 0; + } + else + { + // - если таймер еще тикает, то проверяем освещенность + // и, если она изменилась, то возвращаемся в состояние 0 + // то есть в начало алгоритма проверки яркости (освещенности) + if (ADC_ConvertedValue > LIGHT_THREHSOLD) + { + // то ничего не меняем + } + else + { + process_light_state = 1; + } + } + break; + + default: + break; + + } + + vTaskDelay (100); + //GPIOB->ODR ^= GPIO_Pin_2; +} + + +// ---------------------------------------------------------------------------- +// Задача ОС, реализующая головную задачу программы +// ---------------------------------------------------------------------------- +void LightSensor_Task ( void *pvParameters ) +{ + while(1)ProcessFSM_LightSensor (); + //vTaskDelete(NULL); +}
\ No newline at end of file diff --git a/Libraries/LightSensor/light_sensor_task.h b/Libraries/LightSensor/light_sensor_task.h new file mode 100644 index 0000000..f797ecc --- /dev/null +++ b/Libraries/LightSensor/light_sensor_task.h @@ -0,0 +1,26 @@ +#ifndef LIGHT_SENSOR_TASK_INCLUDED +#define LIGHT_SENSOR_TASK_INCLUDED + +#include "stm32f0xx_conf.h" + +#define LIGHT_SENSOR_GPIO_PINx GPIO_Pin_6 +#define LIGHT_SENSOR_GPIOx GPIOA +#define LIGHT_SENSOR_RCC_AHBPeriph_GPIOx RCC_AHBPeriph_GPIOA + +#define LIGHT_SENSOR_ADCx ADC1 +#define LIGHT_SENSOR_ADC_Channelx ADC_Channel_6 +#define LIGHT_SENSOR_RCC_APBxPeriphClockCmd RCC_APB2PeriphClockCmd +#define LIGHT_SENSOR_RCC_APBxPeriph_ADCx RCC_APB2Periph_ADC1 + +typedef enum { + + LIGHT_SENSOR_STATE_LIGHT, + LIGHT_SENSOR_STATE_DARK + +} LightSensorState_t; + +void LightSensorInit ( void ); + +void LightSensor_Task ( void *pvParameters ); + +#endif //LIGHT_SENSOR_TASK_INCLUDED
\ No newline at end of file |