Browse Source

Added main loop with stepper functionality

Added working alarms
Code currently working with modified sunrise, sunset and steps for debugging purposes
alice
Gregor Wüst 3 years ago
parent
commit
367c294f1c
1 changed files with 178 additions and 91 deletions
  1. 178
    91
      RTC/Core/Src/main.c

+ 178
- 91
RTC/Core/Src/main.c View File

@@ -25,6 +25,7 @@
#include "math.h"
#include "stdbool.h"
#include "string.h"
#include <stdio.h>
/* 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);

transmit_uart("Resetting motor position and calculating new dates and times.\r\n");

freqPwm = BSP_MotorControl_GetBridgeInputPwmFreq(0);

BSP_MotorControl_SetHome(0, pos);
BSP_MotorControl_SetBridgeInputPwmFreq(0, freqPwm>>1);

BSP_MotorControl_SelectStepMode(0, STEP_MODE_FULL);
pos = BSP_MotorControl_GetPosition(0);

BSP_MotorControl_Move(0, FORWARD, 25);
BSP_MotorControl_WaitWhileActive(0);
BSP_MotorControl_SetHome(0, pos);

BSP_MotorControl_Move(0, FORWARD, 25);
BSP_MotorControl_WaitWhileActive(0);
BSP_MotorControl_SelectStepMode(0, STEP_MODE_FULL);

BSP_MotorControl_Move(0, FORWARD, 25);
BSP_MotorControl_WaitWhileActive(0);
BSP_MotorControl_Move(0, FORWARD, stepsToMake);
BSP_MotorControl_WaitWhileActive(0);

/* USER CODE END WHILE */
BSP_MotorControl_Move(0, FORWARD, stepsToMake);
BSP_MotorControl_WaitWhileActive(0);

/* 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_GoHome(0);
BSP_MotorControl_WaitWhileActive(0);

//Calculate sunrise and sunset time for tomorrow
calc_sunrise_sunset(&initialDate, &sunrise, &sunset, &tomorrowsDate);
/* USER CODE END WHILE */

// 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
/* USER CODE BEGIN 3 */
set_time_and_date(&initialDate);

leap_year_check(initialDate.year);

set_Alarm(16, 18, 4, "A", &sAlarmA);
set_Alarm(16, 20, 4, "B", &sAlarmB);
calc_tomorrows_date(&initialDate, &tomorrowsDate);

HAL_Delay(5000);
//Calculate sunrise and sunset time for tomorrow
calc_sunrise_sunset(&initialDate, &sunrise, &sunset, &tomorrowsDate);

transmit_uart("A: Ich gehe schlafen!\r\n");
//Test code
sunrise.hours = 14;
sunrise.minutes = 0;
sunrise.weekDay = 7;

// Suspend Tick increment to prevent wake up by Systick interrupt
HAL_SuspendTick();
sunset.hours = 14;
sunset.minutes = 30;
sunset.weekDay = 7;

HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); //Interrupt for wake up
//Calculate the time for next motor step in minutes
timeToNextStep_m = calc_interval_duration(&sunrise, &sunset);

HAL_ResumeTick();
// Set Alarm for sunrise

transmit_uart("A: Bin wieder wach!\r\n");
transmit_uart("Setting alarm for sunrise.\r\n");
set_alarm(sunrise.hours, sunrise.minutes, sunrise.weekDay, "A", &sAlarmA);

transmit_uart("B: Ich gehe schlafen!\r\n");
HAL_Delay(2000);

// Suspend Tick increment to prevent wake up by Systick interrupt
HAL_SuspendTick();
transmit_uart("Entering sleep mode.\r\n");
HAL_SuspendTick();
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
HAL_ResumeTick();

HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); //Interrupt for wake up
if (alarmSunriseFlag == true) {

HAL_ResumeTick();
transmit_uart("Sunrise statement entered.\r\n");
// Reset the flags
alarmSunsetFlag = false;
alarmSunriseFlag = false;

transmit_uart("B: Bin wieder wach!\r\n");
// 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");
}

/**

Loading…
Cancel
Save