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

@@ -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;
}
else
{
leapYear = false;
}
return 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;
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)
{
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);

// 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);

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");
}



+ 1
- 1
RTC/RTC.ioc 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

Loading…
Cancel
Save