-
Notifications
You must be signed in to change notification settings - Fork 0
/
CEB_Control_Code_v1901.ino
262 lines (231 loc) · 10.2 KB
/
CEB_Control_Code_v1901.ino
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/* Open Source Ecology CEB Press v19.01 with Arduino Uno or Mega as controller of choice.
CC-BY-SA, GPLv3, and OSE License for Distributive Economics
Use Mega to keep consistency with OSE D3D 3D Printer to minimize GVCS part count.
Switches FET's HIGH/LOW to control two hydraulic solenoids,
measures piston motion time relative to pressure sensor trigger,
and repeats cycle while auto calibrating timing from previous cycles and startup positions.
Extension time is measured. Orientation of machine is such that cylinder retracts to the right.
See sequence at http://bit.ly/2Hnuk6F
Faults should be self-resolving based on pressing sequence: pressure trigger reverses direction
at fault point and no block results. There is one likely place for faults to occur: soil load into chamber.
Uses HiLetgo Relay Shield 5V 4 Channel for Arduino:
https://www.amazon.com/HiLetgo-Relay-Shield-Channel-Arduino/dp/B07F7Y55Z7/ref=sr_1_2?ie=UTF8&qid=1547696929&sr=8-2&keywords=hiletgo+relay+shield
Note pins must be trimmed flat under Relay 1 connector and must be insulated to prevent shorts.
Relay 1 is controlled by digital pin 7
Relay 2 is controlled by digital pin 6
Relay 3 is controlled by digital pin 5
Relay 4 is controlled by digital pin 4
A high written to a pin turns the relay ON
A low written to a pin turns the relay OFF
Contributions by:
Abe Anderson
http://opensourceecology.org/wiki/AbeAnd_Log
Marcin Jakubowski
http://opensourceecology.org/wiki/Marcin_Log
Unfamiliar with code structures? See https://www.arduino.cc/en/Reference/HomePage
*/
//Defines are preprocessor directives, which do a text find and replace prior to compilation. They can make it easier to alter data that is likely to need changed.
#define SOLENOID_UP 7 //Extension. See pin mapping above.
#define SOLENOID_DOWN 6 //swap these pin numbers for wire inversion
#define SOLENOID_LEFT 5 //Extension.
#define SOLENOID_RIGHT 4 //swap these pin numbers for wire inversion
//THE FOLLOWING PINS WERE SELECTED AS THE MID 6 PINS OF THE UPPER RIGHT 8 PIN HEADER ON RELAY SHIELD
#define PRESSURE_SENSOR 13 //Needs pins adjacent to get 6-pin dupont housing for both selector and sensor
#define SELECTOR_FULL 12 //Primary cylinder thickness setting is based on secondary cylinder motion.
#define SELECTOR_THREEQUARTER 11 //Secondary cylinder timing is measured only.
#define SELECTOR_HALF 10 // QUARTER to FULL refers to brick thickness.
#define SELECTOR_QUARTER 9 //Reset is the absence of any brick thickness selection.
//Reset is the shutdown/initialization procedure. It's selected by non-selection.
#define PRESSURE_SENSOR_DEBOUNCE 20 //milliseconds to delay for pressure sensor debounce
#define TURNOFF_DELAY 50 //Addresses 40 ms turnoff time of solenoid. Loses 1 second every minute.
#define PRESS_DELAY 500 // 1/2 sec extra to compress brick via main Cyl (default 500ms)
//user defined function declarations tell compiler what type parameters to expect for function definitions
bool checkPressure(); //function to read pressure sensor
//bool checkPressure( bool previousState );
bool resetSelected(); //checks for selection of position 0 for reset state
bool quarterSelected(); // 1/4 brick mode
bool halfSelected(); // 1/2 brick mode
bool threequarterSelected(); // 3/4 mode
bool fullSelected(); // checks for selection switch position for FULL size brick mode
//Global variables
unsigned long drawerExtTime = 0; //Time measurement for calibrating motion.
unsigned long previousMillis = 0; //time measurement for expansion
void setup() {
//initialize pin I/O Inputs and turn everything off to avoid startup glitches
//always consider internal pullup resistor states when making wiring changes to prevent damage to the microcontroller pins
pinMode(SELECTOR_QUARTER, INPUT_PULLUP);
pinMode(SELECTOR_HALF, INPUT_PULLUP);
pinMode(SELECTOR_THREEQUARTER, INPUT_PULLUP);
pinMode(SELECTOR_FULL, INPUT_PULLUP);
pinMode(SOLENOID_RIGHT, OUTPUT);
digitalWrite(SOLENOID_RIGHT, LOW);
pinMode(SOLENOID_LEFT, OUTPUT);
digitalWrite(SOLENOID_LEFT, LOW);
pinMode(SOLENOID_DOWN, OUTPUT);
digitalWrite(SOLENOID_DOWN, LOW);
pinMode(SOLENOID_UP, OUTPUT);
digitalWrite(SOLENOID_UP, LOW);
pinMode(PRESSURE_SENSOR, INPUT);
digitalWrite(PRESSURE_SENSOR, INPUT_PULLUP);
}
void loop() {
//*****************************************************************************************************************
//Reset should be done at end of pressing. If state of machine is correct,
//no need to select reset at beginning. Turn the machine on and select 1-4.
//Step 0 Reset/Initialize - Brick pressing sequence - http://bit.ly/2Hnuk6F
while (resetSelected() == true) {
while (checkPressure() == false) { //Move drawer cylinder right
digitalWrite(SOLENOID_RIGHT, HIGH);
}
digitalWrite(SOLENOID_RIGHT, LOW);
delay(TURNOFF_DELAY); //***************************************************************
while (checkPressure() == false) { //Move main cylinder up
digitalWrite(SOLENOID_UP, HIGH);
}
digitalWrite(SOLENOID_RIGHT, LOW);
delay(10000); //After reset - repeat every 10 seconds
}
//***********************************************************************************************************
//Step 1 Calibration + Soil Loading/Brick Ejection
if (resetSelected() == false) { //Proceeds only if selector is not on 0 (reset) position
previousMillis = millis(); //checkPressure() call adds a slight debounce delay to the millis diffirence
while (checkPressure() == false) { //Here we eject brick if this is a repeat cycle.
digitalWrite(SOLENOID_LEFT, HIGH);
}
digitalWrite(SOLENOID_LEFT, LOW);
drawerExtTime = millis() - previousMillis;
delay(TURNOFF_DELAY); //***************************************************************
}
if (quarterSelected() == true) { //Goes through different selections.
digitalWrite(SOLENOID_DOWN, HIGH); //Selects brick thickness as in http://bit.ly/2RYpQYa
delay(drawerExtTime*0.5); //Thickness multiplier of 0.5 based on cylinder diameters
digitalWrite(SOLENOID_DOWN, LOW);
}
if (halfSelected() == true) {
digitalWrite(SOLENOID_DOWN, HIGH);
delay(drawerExtTime*0.9);
digitalWrite(SOLENOID_DOWN, LOW);
}
if (threequarterSelected() == true) {
digitalWrite(SOLENOID_DOWN, HIGH);
delay(drawerExtTime*1.3);
digitalWrite(SOLENOID_DOWN, LOW);
}
if (fullSelected() == true) {
while (checkPressure() == false) {
digitalWrite(SOLENOID_DOWN, HIGH);
}
digitalWrite(SOLENOID_DOWN, LOW);
}
//Step 2 Compression Chamber Closure
if (resetSelected() == false) {
digitalWrite(SOLENOID_RIGHT, HIGH);
delay(drawerExtTime*0.75*0.5); //0.5 is the half-way point of drawer cylinder; 0.75 is the Drawer Multiplier
digitalWrite(SOLENOID_RIGHT, LOW); //Can modify the 0.5 to fine tune the drawer closure location
}
//Step 3 Compression by main cylinder with delay
if (resetSelected() == false) {
while (checkPressure() == false) {
digitalWrite(SOLENOID_UP, HIGH);
}
delay(PRESS_DELAY);
digitalWrite(SOLENOID_UP, LOW);
}
//Step 4 Ejection
if (resetSelected() == false) {
while (checkPressure() == false) {
digitalWrite(SOLENOID_RIGHT, HIGH);
}
digitalWrite(SOLENOID_RIGHT, LOW);
while (checkPressure() == false) {
digitalWrite(SOLENOID_UP, HIGH);
}
digitalWrite(SOLENOID_UP, LOW);
}
//Cycle through sequence from 1 (recalibration)
} //end of loop
//user defined function definitions are code that can be called from almost anywhere (within scope).
//reads pressure sensor state HIGH is true and LOW is false
bool checkPressure() {
//bool checkPressure( bool previousState ) {
bool readState = digitalRead(PRESSURE_SENSOR);
//bool previousState;
//bool stateChange = false;
/*
if (readState == stateChange) {
previousState = readState;
}
*/
if (readState == HIGH) {
delay(PRESSURE_SENSOR_DEBOUNCE);
if (readState == HIGH) {
return true;
}
else {
//checkPressure( previousState );
checkPressure();
}
}
else {
return false;
}}
//reads selector - HIGH is false, LOW is true- SELECTOR_RESET, SELECTOR_QUARTER, SELECTOR_HALF, SELECTOR_THREEQUARTER, SELECTOR_FULL,
bool resetSelected() {
if (fullSelected() == false &&threequarterSelected() == false && halfSelected() == false && quarterSelected() == false && quarterSelected() == false) {
return true;
}
else {
return false;
}}
bool quarterSelected() {
if (digitalRead(SELECTOR_QUARTER) == HIGH) {
delay(PRESSURE_SENSOR_DEBOUNCE);
if (digitalRead(SELECTOR_QUARTER) == HIGH) {
return false;
}
else {
return true;
}
}
else {
return true;
}}
bool halfSelected() {
if (digitalRead(SELECTOR_HALF) == HIGH) {
delay(PRESSURE_SENSOR_DEBOUNCE);
if (digitalRead(SELECTOR_HALF) == HIGH) {
return false;
}
else {
return true;
}
}
else {
return true;
}}
bool threequarterSelected() {
if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
delay(PRESSURE_SENSOR_DEBOUNCE);
if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
return false;
}
else {
return true;
}
}
else {
return true;
}}
bool fullSelected() {
if (digitalRead(SELECTOR_FULL) == HIGH) {
delay(PRESSURE_SENSOR_DEBOUNCE);
if (digitalRead(SELECTOR_FULL) == HIGH) {
return false;
}
else {
return true;
}
}
else {
return true;
}}