Browse Source

Multiple Alarm Test

alice
Gregor Wüst 3 years ago
parent
commit
10f8906648
2 changed files with 153 additions and 81 deletions
  1. 152
    80
      RTC/Core/Src/main.c
  2. 1
    1
      RTC/RTC.ioc

+ 152
- 80
RTC/Core/Src/main.c View File

#include "main.h" #include "main.h"
#include "math.h" #include "math.h"
#include "stdbool.h" #include "stdbool.h"
#include "string.h"


/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
RTC_DateTypeDef sDate; RTC_DateTypeDef sDate;
RTC_AlarmTypeDef sAlarm; RTC_AlarmTypeDef sAlarm;


//Nuernberg coordinates
//Nuremberg coordinates
int latitude_nbg = 49; int latitude_nbg = 49;
int longitude_nbg = 11; int longitude_nbg = 11;


int UTC_DER_win = 1; int UTC_DER_win = 1;
bool winterTime = true; 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 BEGIN PV */


/* USER CODE END PV */ /* USER CODE END PV */
* Description : checks if year is a leap year * Description : checks if year is a leap year
* Return : false: no leap year, true: 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)) if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{ {
return true;
leapYear = true;
}
else
{
leapYear = false;
} }
return false;
} }


/******************************************************************************* /*******************************************************************************
int doy = day; //day of year int doy = day; //day of year


// check for leap 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; days_in_feb = 29;
} }
* Description : calculates the sunrise and sunset time of a specific date * Description : calculates the sunrise and sunset time of a specific date
* Source : General Solar Position Calculations, NOAA Global Monitoring Division * 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; double gamma = 0;
bool leap_year;
double eqtime = 0; double eqtime = 0;
double decl = 0; double decl = 0;
double decl_deg = 0;
//double decl_deg = 0;
double zenith_sun = 0; double zenith_sun = 0;
double lat_nbg_rad = 0; double lat_nbg_rad = 0;
double ha = 0; double ha = 0;
int int_sunrise_min = 0; int int_sunrise_min = 0;
int int_sunset_min = 0; int int_sunset_min = 0;


int day = initialDate->day;
int month = initialDate->month;
int year = initialDate->year;

//day of year calculation //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 // fractional year (γ) in radians
// check for leap year // 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 //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); gamma = ((2 * M_PI)/365)*(day_of_year - 1);
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); 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 //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 //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 //special case of sunrise or sunset, the zenith is set to 90.833Deg
sunset_h = sunset_h + UTC_DER_sum; 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;
} }


/******************************************************************************* /*******************************************************************************
* Description : calculates tomorrow's date * Description : calculates tomorrow's date
* Source : https://github.com/vyacht/stm32/blob/master/vynmea/rtc.c * 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 day++; // next day
wday++; // next weekday wday++; // next weekday
{ {
wday = 1; // Monday wday = 1; // Monday
} }
if(day > DaysInMonth[month-1])
if(day > yearToUse[month-1])
{ // next month { // next month
day = 1; day = 1;
month++; month++;
year++; 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;


} }


* Function Name : set_Alarm * Function Name : set_Alarm
* Description : sets the wake up 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*/ /** Enable the Alarm A*/

sAlarm.AlarmTime.Hours = h; sAlarm.AlarmTime.Hours = h;
sAlarm.AlarmTime.Minutes = min; sAlarm.AlarmTime.Minutes = min;
sAlarm.AlarmTime.Seconds = 0; sAlarm.AlarmTime.Seconds = 0;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL; sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_WEEKDAY; sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_WEEKDAY;
sAlarm.AlarmDateWeekDay = weekDay; sAlarm.AlarmDateWeekDay = weekDay;
sAlarm.Alarm = RTC_ALARM_A;

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) if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
} }


} }


// sending to UART // sending to UART
HAL_UART_Transmit(&huart2, (uint8_t*) string, len, 200); 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 */ /* USER CODE END 0 */


MX_USART2_UART_Init(); MX_USART2_UART_Init();
MX_RTC_Init(); MX_RTC_Init();
/* USER CODE BEGIN 2 */ /* 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 */ /* USER CODE END 2 */


/* Infinite loop */ /* Infinite loop */
/* USER CODE BEGIN WHILE */ /* USER CODE BEGIN WHILE */

while (1) 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 //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);

// 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, 22, 1);
set_Alarm(16, 18, 4, "A");
set_Alarm(16, 20, 4, "B");


HAL_Delay(5000); 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 // Suspend Tick increment to prevent wake up by Systick interrupt
HAL_SuspendTick(); HAL_SuspendTick();


HAL_ResumeTick(); 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 */ /* USER CODE END 3 */
} }
*/ */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON; 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.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
/** Initialize RTC and set the Time and Date /** Initialize RTC and set the Time and Date
*/ */
sTime.Hours = 16; sTime.Hours = 16;
sTime.Minutes = 20;
sTime.Minutes = 16;
sTime.Seconds = 30; sTime.Seconds = 30;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET; sTime.StoreOperation = RTC_STOREOPERATION_RESET;
{ {
Error_Handler(); 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; sDate.Year = 21;


if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK) if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{ {
/* Alarm generation */ /* 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");
} }





+ 1
- 1
RTC/RTC.ioc View File

VP_SYS_VS_Systick.Signal=SYS_VS_Systick VP_SYS_VS_Systick.Signal=SYS_VS_Systick
board=NUCLEO-F401RE board=NUCLEO-F401RE
boardIOC=true boardIOC=true
isbadioc=false
isbadioc=true

Loading…
Cancel
Save