This repository has been archived by the owner on Jul 26, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Autofeeder.c
97 lines (79 loc) · 4.12 KB
/
Autofeeder.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "Autofeeder.h"
static volatile uint32_t currentSecond = 0; // Variable, which stores current second value
//static const uint32_t period = 169800; // Feeding period
volatile uint8_t feedCounter = 0;
static const uint32_t period = 1; // Variable for debugging,
void AutoFeeder_SetPulse (uint8_t pulse_time)
{
TCCR2A |= 1 << COM2A1 | 0 << COM2A0 | 0 << COM2B1 | 0 << COM2B0 | 1 << WGM21 | 1 << WGM20; // Fast PWM, normal mode
TCCR2B |= 0 << WGM22 | 1 << CS22 | 1 << CS21 | 1 << CS20; // Clock prescaler = 1024
OCR2A = pulse_time; // Set pulse width
}
void AutoFeeder_StopTheRotation (void)
{
TCCR2A &= ~(1 << COM2A1 | 0 << COM2A0 | 0 << COM2B1 | 0 << COM2B0 | 1 << WGM21 | 1 << WGM20); // Turn off PWM
TCCR2B &= ~(0 << WGM22 | 1 << CS22 | 1 << CS21 | 1 << CS20); //
}
void AutoFeeder_Timer1_Init (void)
{
OCR1AH = 0x3D; // F_CPU / Clock prescaler = 15625 clock cycles
OCR1AL = 0x09; // This is 1 second
TCCR1B |= 1 << WGM12 | 1 << CS12 | 1 << CS10; // Set prescaler = 1024; Set Timer Mode - CTC
TIMSK1 |= 1 << OCIE1A; // Enable Interrupt on compare
}
void AutoFeeder_Init (void)
{
AUTOFEEDER_DDR |= 1 << AUTOFEEDER_SERVO_PIN;
AutoFeeder_SetPulse(8); // Set initial servo position
_delay_ms(1500);
AutoFeeder_StopTheRotation();
AutoFeeder_Timer1_Init(); // Turn on time counter
AUTOFEEDER_DDR &= ~(1 << AUTOFEEDER_SERVO_PIN);
}
ISR (TIMER1_COMPA_vect)
{
SMCR &= ~(1 << SE); // To avoid the MCU entering the sleep mode, it is recommended to clear the SE bit immediately after waking up.
uint32_t temporarySecond = currentSecond;
if (temporarySecond < period)
{
temporarySecond++; // Count the time to the desired value
currentSecond = temporarySecond;
}
else // And when the time has come
{
AUTOFEEDER_DDR |= 1 << AUTOFEEDER_SERVO_PIN | 1 << AUTOFEEDER_LED_PIN_1 | 1 << AUTOFEEDER_LED_PIN_2 | 1 << AUTOFEEDER_LED_PIN_3 | 1 << AUTOFEEDER_LED_PIN_4 | 1 << AUTOFEEDER_LED_PIN_5; // Set outputs for LED and servo pins
for (uint8_t i = 0; i < 3; i++) // Turn on the cycle of LED alert
{
for (uint8_t j = 0; j < 17; j++)
{
AUTOFEEDER_PORT |= 1 << AUTOFEEDER_LED_PIN_1 | 1 << AUTOFEEDER_LED_PIN_2 | 1 << AUTOFEEDER_LED_PIN_3 | 1 << AUTOFEEDER_LED_PIN_4 | 1 << AUTOFEEDER_LED_PIN_5;
_delay_ms(200);
AUTOFEEDER_PORT &= ~(1 << AUTOFEEDER_LED_PIN_1 | 1 << AUTOFEEDER_LED_PIN_2 | 1 << AUTOFEEDER_LED_PIN_3);
_delay_ms(70);
}
_delay_ms(1200);
}
AUTOFEEDER_PORT |= 1 << AUTOFEEDER_LED_PIN_1 | 1 << AUTOFEEDER_LED_PIN_2 | 1 << AUTOFEEDER_LED_PIN_3 | 1 << AUTOFEEDER_LED_PIN_4 | 1 << AUTOFEEDER_LED_PIN_5; // Turn on LED lighting
_delay_ms(1500);
PRR &= ~(1 << PRTIM2); // Enable the Timer 2
for (uint8_t i = 0; i < 1; i++) // Rotate the servo i times
{
AutoFeeder_SetPulse(32);
_delay_ms(1490);
AutoFeeder_StopTheRotation();
_delay_ms(100);
AutoFeeder_SetPulse(8);
_delay_ms(1490);
AutoFeeder_StopTheRotation();
_delay_ms(2000);
}
_delay_ms(30000); // Leave the lighting
AUTOFEEDER_PORT &= ~(1 << AUTOFEEDER_LED_PIN_1 | 1 << AUTOFEEDER_LED_PIN_2 | 1 << AUTOFEEDER_LED_PIN_3 | 1 << AUTOFEEDER_LED_PIN_4 | 1 << AUTOFEEDER_LED_PIN_5); // Turn off lighting
AUTOFEEDER_DDR &= ~( 1 << AUTOFEEDER_SERVO_PIN | 1 << AUTOFEEDER_LED_PIN_1 | 1 << AUTOFEEDER_LED_PIN_2 | 1 << AUTOFEEDER_LED_PIN_3 | 1 << AUTOFEEDER_LED_PIN_4 | 1 << AUTOFEEDER_LED_PIN_5); // Set PORT in Hi-Z statement
currentSecond = 0; // Reset timer
uint8_t temporaryFeedCounter = feedCounter;
temporaryFeedCounter++;
feedCounter = temporaryFeedCounter;
EEPROM_PutByte(temporaryFeedCounter, 1); // Write in the EEPROM memory, that the feed cycle was successful
}
}