-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbartender.c
163 lines (129 loc) · 3.28 KB
/
bartender.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "bartender.h"
#include "Arduino.h"
#include "error.h"
#include <math.h>
#include <util/atomic.h>
/**
* Step distance array. Hardik can't measure.
*/
uint16_t step_distances[13] = {880, 635, 675, 675, 660, 675, 675, 675, 675, 675, 645, 675, 675};
void bartender_init(bartender_t *bartender, stepper_t *stepper, toggle_driver_t *toggler, uint8_t location)
{
bartender->stepper = stepper;
bartender->toggler = toggler;
bartender->location = location;
}
uint8_t bartender_move_to_location(bartender_t *bartender, uint8_t location)
{
// Make sure that we are not doing anything
if (bartender->status != STATUS_NONE)
{
return E_BUSY;
}
// We are moving
bartender->status = STATUS_MOVING;
uint8_t direction = FORWARD;
if (bartender->location > location)
{
direction = REVERSE;
}
// While the location doesn't equal location
while (bartender->location != location)
{
uint16_t steps = 0;
// Get the number of steps to the new location
if (direction == FORWARD)
{
steps = step_distances[bartender->location];
}
else
{
steps = step_distances[bartender->location - 1];
}
// Special case. Keep going until we hit the bump sensor
// Side note: I personally disagree with this case but the hardware guys
// demand I implement it. Hooray for relying on safety systems for normal
// operation
if (location == 0 && bartender->location == 1)
{
steps = 0xFFFF;
}
// Now step baby step (as long as our status doesn't change)
for (uint16_t i = 0; (i < steps) && (bartender->status == STATUS_MOVING); i++)
{
stepper_step(bartender->stepper, direction);
}
// We were interrupted
if (bartender->status == STATUS_INT)
{
stepper_release(bartender->stepper);
bartender->location = 0;
bartender->status = STATUS_NONE;
return E_NO_ERROR;
}
// Update the location variable
if (direction == FORWARD)
{
bartender->location++;
}
else
{
bartender->location--;
}
}
// Release the stepper
stepper_release(bartender->stepper);
// We are done
bartender->status = STATUS_NONE;
return E_NO_ERROR;
}
uint8_t bartender_pour(bartender_t *bartender, uint8_t amount)
{
// Make sure that we are not doing anything
if (bartender->status != STATUS_NONE)
{
return E_BUSY;
}
// We are pouring
bartender->status = STATUS_POURING;
// Up. Delay. Down. Delay.
for (uint8_t i = 0; i < amount; i++)
{
toggle_driver_move(bartender->toggler, UP);
delay(5000);
toggle_driver_move(bartender->toggler, DOWN);
delay(5000);
toggle_driver_stop(bartender->toggler);
}
// We are done
bartender->status = STATUS_NONE;
return E_NO_ERROR;
}
uint8_t bartender_stop(bartender_t *bartender)
{
// Let other functions know we are stopped
bartender->status = STATUS_STOPPED;
return E_NO_ERROR;
}
uint8_t bartender_reset(bartender_t *bartender)
{
// Make sure that we are in the stopped state
if (bartender->status != STATUS_STOPPED)
{
return E_INV_CALL;
}
// Lower the linear actuator for pouring
toggle_driver_move(bartender->toggler, DOWN);
delay(5000);
toggle_driver_stop(bartender->toggler);
// Move to location 0
while (bartender->status != STATUS_INT)
{
stepper_step(bartender->stepper, REVERSE);
}
// Reset the location
bartender->location = 0;
// Reset the status
bartender->status = STATUS_NONE;
return E_NO_ERROR;
}