From 1702ce6ce430a66bb7af51644b91b7c196e719d9 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 29 Jun 2022 11:03:02 +0300 Subject: =?UTF-8?q?=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D1=8E=20=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D1=8B=D0=B9=20=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=B9.=20=D0=9F=D1=80=D0=BE=D0=B3=D1=80?= =?UTF-8?q?=D0=B0=D0=BC=D0=BC=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=81=D0=B8=D0=B8=20NixieClock=5Fv2.=20=D0=A0=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82,=20=D1=87=D0=B0=D1=81?= =?UTF-8?q?=D1=8B=20=D1=82=D0=B8=D0=BA=D0=B0=D1=8E=D1=82.=20=D0=95=D1=81?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BF=D1=80=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC=D0=B0?= =?UTF-8?q?,=20=D1=87=D1=82=D0=BE=20=D1=81=D0=BA=D0=B0=D1=87=D0=B5=D1=82?= =?UTF-8?q?=20=D0=B2=D1=82=D0=BE=D1=80=D0=B0=D1=8F=20=D1=81=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=80=D0=BD=D0=B0=D1=8F=20=D0=BA=D0=BD=D0=BE=D0=BF?= =?UTF-8?q?=D0=BA=D0=B0=20(=D0=BE=D0=BD=D0=B0=20=D0=B2=20=D0=B4=D1=80?= =?UTF-8?q?=D1=83=D0=B3=D0=BE=D0=BC=20=D0=BA=D0=B0=D0=BD=D0=B0=D0=BB=D0=B5?= =?UTF-8?q?).=20=D0=9F=D0=BE=D1=8D=D1=82=D0=BE=D0=BC=D1=83=20=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BD=D0=B5=D0=B5=20=D1=81=D0=BE=D0=B1=D0=B8=D1=80=D0=B0?= =?UTF-8?q?=D1=8E=D1=81=D1=8C=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C?= =?UTF-8?q?=20=D0=B0=D0=BD=D1=82=D0=B8=D0=B4=D1=80=D0=B5=D0=B1=D0=B5=D0=B7?= =?UTF-8?q?=D0=B3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Libraries/LightSensor/light_sensor_task.c | 225 ++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 Libraries/LightSensor/light_sensor_task.c (limited to 'Libraries/LightSensor/light_sensor_task.c') 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 -- cgit v1.2.3