Multiple Alarm Test

This commit is contained in:
Gregor Wüst 2021-02-18 17:33:01 +01:00
parent 13ea9efba4
commit 10f8906648
2 changed files with 153 additions and 81 deletions

View File

@ -21,6 +21,7 @@
#include "main.h"
#include "math.h"
#include "stdbool.h"
#include "string.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
@ -49,7 +50,7 @@ RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
RTC_AlarmTypeDef sAlarm;
//Nuernberg coordinates
//Nuremberg coordinates
int latitude_nbg = 49;
int longitude_nbg = 11;
@ -58,6 +59,20 @@ int UTC_DER_sum = 2;
int UTC_DER_win = 1;
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;
typedef struct {
int hours;
int minutes;
int seconds;
int weekDay;
int month;
int day;
int year;
} timeAndDate;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
@ -100,13 +115,18 @@ double rad_to_deg(double rad)
* Description : checks if year is a leap year
* Return : false: no leap year, true: leap year
*******************************************************************************/
int leap_year_check(int year)
void leap_year_check(int initialyear)
{
int year = initialyear;
if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
return true;
leapYear = true;
}
return false;
else
{
leapYear = false;
}
}
/*******************************************************************************
@ -121,8 +141,8 @@ int calc_day_of_year(int day, int mon, int year)
int doy = day; //day of year
// check for leap year
bool leap_year = leap_year_check(year);
if(leap_year == true)
//bool leap_year = leap_year_check(year);
if(leapYear == true)
{
days_in_feb = 29;
}
@ -171,13 +191,12 @@ int calc_day_of_year(int day, int mon, int year)
* Description : calculates the sunrise and sunset time of a specific date
* Source : General Solar Position Calculations, NOAA Global Monitoring Division
*******************************************************************************/
void calc_sunrise_sunset(int date, int month, int year, int sunrise_time[2], int sunset_time[2])
void calc_sunrise_sunset(timeAndDate* initialDate, timeAndDate* sunriseStruct, timeAndDate* sunsetStruct, timeAndDate* tomorrowsDate)
{
double gamma = 0;
bool leap_year;
double eqtime = 0;
double decl = 0;
double decl_deg = 0;
//double decl_deg = 0;
double zenith_sun = 0;
double lat_nbg_rad = 0;
double ha = 0;
@ -191,13 +210,17 @@ void calc_sunrise_sunset(int date, int month, int year, int sunrise_time[2], int
int int_sunrise_min = 0;
int int_sunset_min = 0;
int day = initialDate->day;
int month = initialDate->month;
int year = initialDate->year;
//day of year calculation
int day_of_year = calc_day_of_year(date, month, year);
int day_of_year = calc_day_of_year(day, month, year);
// fractional year (γ) in radians
// check for leap year
leap_year = leap_year_check(year);
if(leap_year == false)
//leap_year = leap_year_check(year);
if(leapYear == false)
{
//The back part of the formula was omitted, because there is no difference in the result
gamma = ((2 * M_PI)/365)*(day_of_year - 1);
@ -213,7 +236,7 @@ void calc_sunrise_sunset(int date, int month, int year, int sunrise_time[2], int
decl = 0.006918 - 0.399912*cos(gamma) + 0.070257*sin(gamma) - 0.006758*cos(2*gamma) + 0.000907*sin(2*gamma) - 0.002697*cos(3*gamma) + 0.00148*sin(3*gamma);
//Solar declination angle in degrees
decl_deg = rad_to_deg(decl);
//decl_deg = rad_to_deg(decl);
//Hour angle in degrees, positive number corresponds to sunrise, negative to sunset
//special case of sunrise or sunset, the zenith is set to 90.833Deg
@ -262,10 +285,16 @@ void calc_sunrise_sunset(int date, int month, int year, int sunrise_time[2], int
sunset_h = sunset_h + UTC_DER_sum;
}
sunrise_time[0] = sunrise_h;
sunrise_time[1] = int_sunrise_min;
sunset_time[0] = sunset_h;
sunset_time[1] = int_sunset_min;
sunriseStruct->hours = sunrise_h;
sunriseStruct->minutes = int_sunrise_min;
sunsetStruct->hours = sunset_h;
sunsetStruct->minutes = int_sunset_min;
sunriseStruct->day = sunsetStruct->day = tomorrowsDate->day;
sunriseStruct->weekDay = sunsetStruct->weekDay = tomorrowsDate->weekDay;
sunriseStruct->month = sunsetStruct->month = tomorrowsDate->month;
sunriseStruct->year = sunsetStruct->year = tomorrowsDate->year;
}
/*******************************************************************************
@ -273,9 +302,20 @@ void calc_sunrise_sunset(int date, int month, int year, int sunrise_time[2], int
* Description : calculates tomorrow's date
* Source : https://github.com/vyacht/stm32/blob/master/vynmea/rtc.c
*******************************************************************************/
void calc_tomorrows_date(int day, int wday, int month, int year, int DaysInMonth[12], int tomorrows_date[4])
void calc_tomorrows_date(timeAndDate* initialDate, timeAndDate* tomorrowsDate)
{
bool leap_year;
int yearToUse[12];
if (leapYear == true){
memcpy(yearToUse, DaysInMonthLeapYear, sizeof yearToUse);
} else {
memcpy(yearToUse, DaysInMonth, sizeof yearToUse);
}
int day = initialDate->day;
int wday = initialDate->weekDay;
int month = initialDate->month;
int year = initialDate->year;
day++; // next day
wday++; // next weekday
@ -283,7 +323,7 @@ void calc_tomorrows_date(int day, int wday, int month, int year, int DaysInMonth
{
wday = 1; // Monday
}
if(day > DaysInMonth[month-1])
if(day > yearToUse[month-1])
{ // next month
day = 1;
month++;
@ -295,10 +335,10 @@ void calc_tomorrows_date(int day, int wday, int month, int year, int DaysInMonth
year++;
}
tomorrows_date[0] = day;
tomorrows_date[1] = wday;
tomorrows_date[2] = month;
tomorrows_date[3] = year;
tomorrowsDate->day = day;
tomorrowsDate->weekDay = wday;
tomorrowsDate->month = month;
tomorrowsDate->year = year;
}
@ -306,9 +346,10 @@ void calc_tomorrows_date(int day, int wday, int month, int year, int DaysInMonth
* Function Name : set_Alarm
* Description : sets the wake up Alarm
*******************************************************************************/
void set_Alarm(int h, int min, int weekDay)
void set_Alarm(int h, int min, int weekDay, char* alarm)
{
/** Enable the Alarm A*/
sAlarm.AlarmTime.Hours = h;
sAlarm.AlarmTime.Minutes = min;
sAlarm.AlarmTime.Seconds = 0;
@ -319,11 +360,19 @@ void set_Alarm(int h, int min, int weekDay)
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_WEEKDAY;
sAlarm.AlarmDateWeekDay = weekDay;
if (strcmp("A", alarm) == 0) {
sAlarm.Alarm = RTC_ALARM_A;
} else {
sAlarm.Alarm = RTC_ALARM_B;
}
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
}
// sending to UART
@ -332,6 +381,26 @@ void transmit_uart(char *string){
HAL_UART_Transmit(&huart2, (uint8_t*) string, len, 200);
}
void setTime(timeAndDate *time){
if (HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK)
{
time->hours = sTime.Hours;
time->minutes = sTime.Minutes;
time->seconds = sTime.Seconds;
}
}
void setDate(timeAndDate *date){
if (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) == HAL_OK)
{
date->weekDay = sDate.WeekDay;
date->month = sDate.Month;
date->day = sDate.Date;
date->year = 2000 + sDate.Year;
}
}
/* USER CODE END 0 */
@ -366,68 +435,52 @@ int main(void)
MX_USART2_UART_Init();
MX_RTC_Init();
/* USER CODE BEGIN 2 */
int hours = 0;
int minutes = 0;
int seconds = 0;
int weekDay = 0;
int month = 0;
int date = 0;
int year = 0;
int sunrise_h = 0;
int sunset_h = 0;
int int_sunrise_min = 0;
int int_sunset_min = 0;
int sunrise_time[2] = {0};
int sunset_time[2] = {0};
int tomorrows_date[4] = {0};
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 leap_year = false;
timeAndDate sunrise, sunset, wakeUpTimeForStep, tomorrowsDate, initialDate;
sunrise = sunset = wakeUpTimeForStep = tomorrowsDate = initialDate = (timeAndDate) {\
0,
0,
0,
0,
0,
0,
0
};
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
setTime(&initialDate);
setDate(&initialDate);
leap_year_check(initialDate.year);
//Get Time and Date
if (HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK)
{
hours = sTime.Hours;
minutes = sTime.Minutes;
seconds = sTime.Seconds;
}
if (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) == HAL_OK)
{
weekDay = sDate.WeekDay;
month = sDate.Month;
date = sDate.Date;
year = 2000 + sDate.Year;
}
// check for leap year
leap_year = leap_year_check(year);
if (leap_year)
{
//Calculate tomorrow's date
calc_tomorrows_date(date, weekDay, month, year, DaysInMonthLeapYear, tomorrows_date);
} else {
//Calculate tomorrow's date
calc_tomorrows_date(date, weekDay, month, year, DaysInMonth, tomorrows_date);
}
calc_tomorrows_date(&initialDate, &tomorrowsDate);
//Calculate sunrise and sunset time for tomorrow
calc_sunrise_sunset(tomorrows_date[0], tomorrows_date[2], tomorrows_date[3], sunrise_time, sunset_time);
calc_sunrise_sunset(&initialDate, &sunrise, &sunset, &tomorrowsDate);
set_Alarm(16, 22, 1);
// 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
set_Alarm(16, 18, 4, "A");
set_Alarm(16, 20, 4, "B");
HAL_Delay(5000);
transmit_uart("Ich gehe schlafen!\r\n");
transmit_uart("A: Ich gehe schlafen!\r\n");
// Suspend Tick increment to prevent wake up by Systick interrupt
HAL_SuspendTick();
@ -436,7 +489,19 @@ int main(void)
HAL_ResumeTick();
transmit_uart("Bin wieder wach!\r\n");
transmit_uart("A: Bin wieder wach!\r\n");
transmit_uart("B: Ich gehe schlafen!\r\n");
// Suspend Tick increment to prevent wake up by Systick interrupt
HAL_SuspendTick();
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); //Interrupt for wake up
HAL_ResumeTick();
transmit_uart("B: Bin wieder wach!\r\n");
}
/* USER CODE END 3 */
}
@ -460,7 +525,8 @@ void SystemClock_Config(void)
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
//RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
@ -529,7 +595,7 @@ static void MX_RTC_Init(void)
/** Initialize RTC and set the Time and Date
*/
sTime.Hours = 16;
sTime.Minutes = 20;
sTime.Minutes = 16;
sTime.Seconds = 30;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
@ -537,9 +603,9 @@ static void MX_RTC_Init(void)
{
Error_Handler();
}
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 11;
sDate.WeekDay = RTC_WEEKDAY_THURSDAY;
sDate.Month = RTC_MONTH_FEBRUARY;
sDate.Date = 18;
sDate.Year = 21;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
@ -646,7 +712,13 @@ void Error_Handler(void)
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
/* Alarm generation */
transmit_uart("Alarm!!!!\r\n");
transmit_uart("A: Alarm!!!!\r\n");
}
void HAL_RTC_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)
{
/* Alarm generation */
transmit_uart("B: Alarm!!!!\r\n");
}

View File

@ -175,4 +175,4 @@ VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
board=NUCLEO-F401RE
boardIOC=true
isbadioc=false
isbadioc=true