From 367c294f1c7ef419491e9f2f59e26279bddc190f Mon Sep 17 00:00:00 2001 From: Gregor Wuest Date: Sun, 21 Feb 2021 16:31:17 +0100 Subject: [PATCH] Added main loop with stepper functionality Added working alarms Code currently working with modified sunrise, sunset and steps for debugging purposes --- RTC/Core/Src/main.c | 269 +++++++++++++++++++++++++++++--------------- 1 file changed, 178 insertions(+), 91 deletions(-) diff --git a/RTC/Core/Src/main.c b/RTC/Core/Src/main.c index d5525e2..9e8db95 100644 --- a/RTC/Core/Src/main.c +++ b/RTC/Core/Src/main.c @@ -25,6 +25,7 @@ #include "math.h" #include "stdbool.h" #include "string.h" +#include /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -66,6 +67,11 @@ bool winterTime = true; int DaysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int DaysInMonthLeapYear[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; bool leapYear = false; +int singleStepsFor180Deg = 100; // The stepper motor needs 200 single steps for 360 deg, equals 100 steps for 180 deg +int leapsFor180Deg = 5; // Determines how big the amount of single steps is to complete 180 degrees of rotation +bool alarmSunriseFlag = false; +bool alarmSunsetFlag = false; +bool makeStepFlag = false; typedef struct { int hours; @@ -77,6 +83,14 @@ typedef struct { int year; } timeAndDate; +typedef struct { + char *hours; + char *minutes; + char *seconds; +} timeAndDateChar; + +timeAndDateChar time; + /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ @@ -350,7 +364,7 @@ void calc_tomorrows_date(timeAndDate* initialDate, timeAndDate* tomorrowsDate) * Function Name : set_Alarm * Description : sets the wake up Alarm *******************************************************************************/ -void set_Alarm(int h, int min, int weekDay, char* alarm, RTC_AlarmTypeDef* alarmInstance) +void set_alarm(int h, int min, int weekDay, char* alarm, RTC_AlarmTypeDef* alarmInstance) { /** Enable the Alarm A*/ @@ -379,23 +393,44 @@ void set_Alarm(int h, int min, int weekDay, char* alarm, RTC_AlarmTypeDef* alarm } +/*timeAndDateChar get_time(timeAndDateChar *time){ + + if (HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK) + { + sprintf(time->hours, "%d", sTime.Hours); + sprintf(time->minutes, "%d", sTime.Minutes); + sprintf(time->seconds, "%d", sTime.Seconds); + } + +} +*/ // sending to UART void transmit_uart(char *string){ + //char divider[] = ":"; + //get_time(time); uint8_t len = strlen(string); HAL_UART_Transmit(&huart2, (uint8_t*) string, len, 200); } -void setTime(timeAndDate *time){ +void set_time_and_date(timeAndDate *timeanddate){ if (HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK) { - time->hours = sTime.Hours; - time->minutes = sTime.Minutes; - time->seconds = sTime.Seconds; + timeanddate->hours = sTime.Hours; + timeanddate->minutes = sTime.Minutes; + timeanddate->seconds = sTime.Seconds; + } + + if (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) == HAL_OK) + { + timeanddate->weekDay = sDate.WeekDay; + timeanddate->month = sDate.Month; + timeanddate->day = sDate.Date; + timeanddate->year = 2000 + sDate.Year; } } -void setDate(timeAndDate *date){ +/*void setDate(timeAndDate *date){ if (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) == HAL_OK) { @@ -404,6 +439,21 @@ void setDate(timeAndDate *date){ date->day = sDate.Date; date->year = 2000 + sDate.Year; } +}*/ + +int calc_interval_duration(timeAndDate *sunrise, timeAndDate *sunset){ + int duration_h=0; + int duration_m=0; + + duration_h = sunset->hours - sunrise->hours; + duration_m = sunset->minutes - sunrise->minutes; + + if (duration_m < 0) { + duration_h = duration_h - 1; + duration_m = 60 - sunrise->minutes + sunset->minutes; + } + + return (duration_h * 60 + duration_m) / leapsFor180Deg; } /* USER CODE END 0 */ @@ -444,14 +494,19 @@ int main(void) /* Set the L6208 library to use 1 device */ BSP_MotorControl_SetNbDevices(BSP_MOTOR_CONTROL_BOARD_ID_L6208, 1); BSP_MotorControl_Init(BSP_MOTOR_CONTROL_BOARD_ID_L6208, NULL); + /* Attach the function MyFlagInterruptHandler (defined below) to the flag interrupt */ BSP_MotorControl_AttachFlagInterrupt(MyFlagInterruptHandler); + /* Attach the function MyErrorHandler (defined below) to the error Handler*/ BSP_MotorControl_AttachErrorHandler(Error_Handler); + /* Set Systick Interrupt priority highest to ensure no lock by using HAL_Delay */ HAL_NVIC_SetPriority(SysTick_IRQn, 0x0, 0x0); + /* Configure KEY Button */ BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI); + /* Disable the power bridges after initialization */ BSP_MotorControl_CmdDisable(0); @@ -466,8 +521,13 @@ int main(void) 0 }; - int32_t pos; - uint32_t freqPwm, timeToNextStep; + int32_t pos=0; + uint32_t freqPwm=0; + uint32_t timeToNextStep_m=0; + uint32_t alarmB_h = 0; + uint32_t alarmB_m = 0; + uint32_t alarmB_wd = 0; + uint32_t stepsToMake = singleStepsFor180Deg / leapsFor180Deg; // The amount of single steps to make to complete 180/5 degrees /* USER CODE END 2 */ @@ -475,76 +535,129 @@ int main(void) /* USER CODE BEGIN WHILE */ while (1) { - HAL_Delay(2000); - freqPwm = BSP_MotorControl_GetBridgeInputPwmFreq(0); - BSP_MotorControl_SetBridgeInputPwmFreq(0, freqPwm>>1); - pos = BSP_MotorControl_GetPosition(0); + HAL_Delay(2000); - BSP_MotorControl_SetHome(0, pos); + transmit_uart("Resetting motor position and calculating new dates and times.\r\n"); - BSP_MotorControl_SelectStepMode(0, STEP_MODE_FULL); + freqPwm = BSP_MotorControl_GetBridgeInputPwmFreq(0); - BSP_MotorControl_Move(0, FORWARD, 25); - BSP_MotorControl_WaitWhileActive(0); + BSP_MotorControl_SetBridgeInputPwmFreq(0, freqPwm>>1); - BSP_MotorControl_Move(0, FORWARD, 25); - BSP_MotorControl_WaitWhileActive(0); + pos = BSP_MotorControl_GetPosition(0); - BSP_MotorControl_Move(0, FORWARD, 25); - BSP_MotorControl_WaitWhileActive(0); + BSP_MotorControl_SetHome(0, pos); - /* USER CODE END WHILE */ + BSP_MotorControl_SelectStepMode(0, STEP_MODE_FULL); - /* USER CODE BEGIN 3 */ - setTime(&initialDate); - setDate(&initialDate); - leap_year_check(initialDate.year); + BSP_MotorControl_Move(0, FORWARD, stepsToMake); + BSP_MotorControl_WaitWhileActive(0); - calc_tomorrows_date(&initialDate, &tomorrowsDate); + BSP_MotorControl_Move(0, FORWARD, stepsToMake); + BSP_MotorControl_WaitWhileActive(0); - //Calculate sunrise and sunset time for tomorrow - calc_sunrise_sunset(&initialDate, &sunrise, &sunset, &tomorrowsDate); + BSP_MotorControl_Move(0, FORWARD, stepsToMake); + BSP_MotorControl_WaitWhileActive(0); - // Enter inner Loop with Alarm at sunrise - // Loop: Make a step every x minutes (calculated) - // 1. Calculate and Set Alarm for next step - // 2. Go to sleep: uC, Motor - // 3. Alarm: Make Step - // 4. Go to 1 - // Exit inner Loop with alarm at sunset - // Make Calculations for the next day - // Set alarm for sunrise - // Go to Sleep + BSP_MotorControl_GoHome(0); + BSP_MotorControl_WaitWhileActive(0); + /* USER CODE END WHILE */ - set_Alarm(16, 18, 4, "A", &sAlarmA); - set_Alarm(16, 20, 4, "B", &sAlarmB); + /* USER CODE BEGIN 3 */ + set_time_and_date(&initialDate); - HAL_Delay(5000); + leap_year_check(initialDate.year); - transmit_uart("A: Ich gehe schlafen!\r\n"); + calc_tomorrows_date(&initialDate, &tomorrowsDate); - // Suspend Tick increment to prevent wake up by Systick interrupt - HAL_SuspendTick(); + //Calculate sunrise and sunset time for tomorrow + calc_sunrise_sunset(&initialDate, &sunrise, &sunset, &tomorrowsDate); - HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); //Interrupt for wake up + //Test code + sunrise.hours = 14; + sunrise.minutes = 0; + sunrise.weekDay = 7; - HAL_ResumeTick(); + sunset.hours = 14; + sunset.minutes = 30; + sunset.weekDay = 7; - transmit_uart("A: Bin wieder wach!\r\n"); + //Calculate the time for next motor step in minutes + timeToNextStep_m = calc_interval_duration(&sunrise, &sunset); - transmit_uart("B: Ich gehe schlafen!\r\n"); + // Set Alarm for sunrise - // Suspend Tick increment to prevent wake up by Systick interrupt - HAL_SuspendTick(); + transmit_uart("Setting alarm for sunrise.\r\n"); + set_alarm(sunrise.hours, sunrise.minutes, sunrise.weekDay, "A", &sAlarmA); - HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); //Interrupt for wake up + HAL_Delay(2000); - HAL_ResumeTick(); + transmit_uart("Entering sleep mode.\r\n"); + HAL_SuspendTick(); + HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); + HAL_ResumeTick(); - transmit_uart("B: Bin wieder wach!\r\n"); + if (alarmSunriseFlag == true) { + transmit_uart("Sunrise statement entered.\r\n"); + // Reset the flags + alarmSunsetFlag = false; + alarmSunriseFlag = false; + + // The alarm for the next step is incremented from sunrise as the initial time. + alarmB_h = sunrise.hours; + alarmB_m = sunrise.minutes; + alarmB_wd = sunrise.weekDay; + + // Set Alarm for sunset, it overwrites the alarm for sunrise because the sunrise already happenend + // The timeframes for both alarms dont overlap so 1 alarm is enough + transmit_uart("Setting alarm for sunset.\r\n"); + set_alarm(sunset.hours, sunset.minutes, sunset.weekDay, "A", &sAlarmA); + + HAL_Delay(2000); + + while (alarmSunsetFlag != true) { + + transmit_uart("|--------------------------------------------------------|\r\n\r\n"); + // Increment alarm time with the precalculated timeToNextStep + int minAdd_tmp=0; + + minAdd_tmp = alarmB_m + timeToNextStep_m; + + // Consider minutes overflow ^= hours + 1 + if (minAdd_tmp > 60) { + alarmB_h = alarmB_h + 1; + alarmB_m = minAdd_tmp - 60; + } else { + alarmB_m = minAdd_tmp; + } + + transmit_uart("Setting alarm for next step.\r\n"); + set_alarm(alarmB_h, alarmB_m, alarmB_wd, "B", &sAlarmB); + + HAL_Delay(2000); + + transmit_uart("Entering sleep mode.\r\n"); + HAL_SuspendTick(); + HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); + HAL_ResumeTick(); + + if (makeStepFlag) { + transmit_uart("Making a step.\r\n"); + BSP_MotorControl_Move(0, FORWARD, stepsToMake); + BSP_MotorControl_WaitWhileActive(0); + } + + makeStepFlag = true; + + transmit_uart("\r\n"); + + }; + } + + BSP_MotorControl_GoHome(0); + BSP_MotorControl_WaitWhileActive(0); } /* USER CODE END 3 */ } @@ -641,55 +754,24 @@ static void MX_RTC_Init(void) /** Initialize RTC and set the Time and Date */ - sTime.Hours = 16; - sTime.Minutes = 16; - sTime.Seconds = 30; + sTime.Hours = 13; + sTime.Minutes = 56; + sTime.Seconds = 10; sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; sTime.StoreOperation = RTC_STOREOPERATION_RESET; if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK) { Error_Handler(); } - sDate.WeekDay = RTC_WEEKDAY_THURSDAY; + sDate.WeekDay = RTC_WEEKDAY_SUNDAY; sDate.Month = RTC_MONTH_FEBRUARY; - sDate.Date = 18; + sDate.Date = 21; sDate.Year = 21; if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK) { Error_Handler(); } - /** Enable the Alarm A - */ - /** - sAlarm.AlarmTime.Hours = 0; - sAlarm.AlarmTime.Minutes = 0; - sAlarm.AlarmTime.Seconds = 0; - sAlarm.AlarmTime.SubSeconds = 0; - sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; - sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET; - sAlarm.AlarmMask = RTC_ALARMMASK_NONE; - sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL; - sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; - sAlarm.AlarmDateWeekDay = 1; - sAlarm.Alarm = RTC_ALARM_A; - if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK) - { - Error_Handler(); - } - /** Enable the Alarm B - */ - /* - sAlarm.AlarmDateWeekDay = 1; - sAlarm.Alarm = RTC_ALARM_B; - if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN RTC_Init 2 */ - - /* USER CODE END RTC_Init 2 */ - } /** @@ -767,13 +849,18 @@ static void MX_GPIO_Init(void) void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) { /* Alarm generation */ - transmit_uart("A: Alarm!!!!\r\n"); + alarmSunriseFlag = true; + alarmSunsetFlag = true; + transmit_uart("Alarm A Callback triggered.\r\n"); + transmit_uart("Setting sunrise and sunset flags.\r\n"); } void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc) { /* Alarm generation */ - transmit_uart("B: Alarm!!!!\r\n"); + makeStepFlag = true; + transmit_uart("Alarm B Callback triggered.\r\n"); + transmit_uart("Setting makeStep flag.\r\n"); } /**