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

#include "math.h" #include "math.h"
#include "stdbool.h" #include "stdbool.h"
#include "string.h" #include "string.h"
#include <stdio.h>
/* USER CODE END Includes */ /* USER CODE END Includes */


/* Private typedef -----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/
int DaysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 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}; int DaysInMonthLeapYear[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool leapYear = false; 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 { typedef struct {
int hours; int hours;
int year; int year;
} timeAndDate; } timeAndDate;


typedef struct {
char *hours;
char *minutes;
char *seconds;
} timeAndDateChar;

timeAndDateChar time;

/* USER CODE END PV */ /* USER CODE END PV */


/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
* 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, char* alarm, RTC_AlarmTypeDef* alarmInstance)
void set_alarm(int h, int min, int weekDay, char* alarm, RTC_AlarmTypeDef* alarmInstance)
{ {
/** Enable the Alarm A*/ /** Enable the Alarm A*/




} }


/*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 // sending to UART
void transmit_uart(char *string){ void transmit_uart(char *string){
//char divider[] = ":";
//get_time(time);
uint8_t len = strlen(string); uint8_t len = strlen(string);
HAL_UART_Transmit(&huart2, (uint8_t*) string, len, 200); 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) 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) if (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) == HAL_OK)
{ {
date->day = sDate.Date; date->day = sDate.Date;
date->year = 2000 + sDate.Year; 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 */ /* USER CODE END 0 */
/* Set the L6208 library to use 1 device */ /* Set the L6208 library to use 1 device */
BSP_MotorControl_SetNbDevices(BSP_MOTOR_CONTROL_BOARD_ID_L6208, 1); BSP_MotorControl_SetNbDevices(BSP_MOTOR_CONTROL_BOARD_ID_L6208, 1);
BSP_MotorControl_Init(BSP_MOTOR_CONTROL_BOARD_ID_L6208, NULL); BSP_MotorControl_Init(BSP_MOTOR_CONTROL_BOARD_ID_L6208, NULL);

/* Attach the function MyFlagInterruptHandler (defined below) to the flag interrupt */ /* Attach the function MyFlagInterruptHandler (defined below) to the flag interrupt */
BSP_MotorControl_AttachFlagInterrupt(MyFlagInterruptHandler); BSP_MotorControl_AttachFlagInterrupt(MyFlagInterruptHandler);

/* Attach the function MyErrorHandler (defined below) to the error Handler*/ /* Attach the function MyErrorHandler (defined below) to the error Handler*/
BSP_MotorControl_AttachErrorHandler(Error_Handler); BSP_MotorControl_AttachErrorHandler(Error_Handler);

/* Set Systick Interrupt priority highest to ensure no lock by using HAL_Delay */ /* Set Systick Interrupt priority highest to ensure no lock by using HAL_Delay */
HAL_NVIC_SetPriority(SysTick_IRQn, 0x0, 0x0); HAL_NVIC_SetPriority(SysTick_IRQn, 0x0, 0x0);

/* Configure KEY Button */ /* Configure KEY Button */
BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI); BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI);

/* Disable the power bridges after initialization */ /* Disable the power bridges after initialization */
BSP_MotorControl_CmdDisable(0); BSP_MotorControl_CmdDisable(0);


0 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 */ /* USER CODE END 2 */


/* USER CODE BEGIN WHILE */ /* USER CODE BEGIN WHILE */
while (1) 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 */ /* USER CODE END 3 */
} }


/** Initialize RTC and set the Time and Date /** 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.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET; sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK) if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
} }
sDate.WeekDay = RTC_WEEKDAY_THURSDAY;
sDate.WeekDay = RTC_WEEKDAY_SUNDAY;
sDate.Month = RTC_MONTH_FEBRUARY; sDate.Month = RTC_MONTH_FEBRUARY;
sDate.Date = 18;
sDate.Date = 21;
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)
{ {
Error_Handler(); 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 */

} }


/** /**
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{ {
/* Alarm generation */ /* 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) void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)
{ {
/* Alarm generation */ /* 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