-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbead-dispenser.ino
154 lines (127 loc) · 4.39 KB
/
bead-dispenser.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
// ------------------------------------------------------------------------------------------------------
// Resources:
// - Adjusted Example 4 from: https://forum.arduino.cc/index.php?topic=396450.msg2727728#msg2727728
// - make sure to set EOL to Newline (LF)
// - Extend by the Arduino IR Breakbeam example: https://learn.adafruit.com/ir-breakbeam-sensors/arduino
// ------------------------------------------------------------------------------------------------------
#include <Wire.h>
#include <AccelStepper.h>
#include <Adafruit_MotorShield.h>
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Connect a stepper motor with 200 steps per revolution (1.8 degree) to motor port #1 (M1 and M2)
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 1);
// =============================================
// IR BREAKBEAM PART
// =============================================
// IR Breakbeam Sensor Definitions
#define SENSORPIN 4
// IR breakbeam sensor state variables
int currentSensorState = 0, lastSensorState = 0; // either LOW or HIGH (i.e., 0 or 1. NB: LOW means beam is broken, HIGH means unbroken)
// IR counter
int counter = 0;
bool isCounting = false;
// =============================================
// SERIAL INPUT PART
// =============================================
char receivedChars[32]; // an array to store the received data
bool newData = false;
int dataNumber = 0;
// =============================================
// MOTOR
// =============================================
// SINGLE may create bad motion behavior!
void forwardstep1() {
myMotor->onestep(FORWARD, DOUBLE);
}
void backwardstep1() {
myMotor->onestep(BACKWARD, DOUBLE);
}
AccelStepper Astepper1(forwardstep1, backwardstep1); // use functions to step
// =============================================
// SETUP
// =============================================
void setup() {
// initialize the sensor pin as an input:
pinMode(SENSORPIN, INPUT_PULLUP);
AFMS.begin();
Astepper1.setMaxSpeed(500);
Serial.begin(9600);
Serial.println("Arduino Ready");
}
// =============================================
// LOOP
// =============================================
void loop() {
// get serial input
recvWithEndMarker();
// initialize motor with given user input
if (newData == true) {
initMotor();
}
}
// =============================================
// FUNCTIONS
// =============================================
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = '\n';
char rc;
if (Serial.available() > 0) {
rc = Serial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= 32) {
ndx = 32 - 1;
}
} else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
}
void initMotor() {
dataNumber = 0;
// cast char to int
dataNumber = atoi(receivedChars);
Serial.print("Counting to ... ");
Serial.println(dataNumber);
// start counting mode
isCounting = true;
while (isCounting) {
// start Motor
Astepper1.setSpeed(300);
Astepper1.runSpeed();
// --------------------------------------------------------------------------------------------------
// Sensor Algorithm
// --------------------------------------------------------------------------------------------------
// read the current sensor state
currentSensorState = digitalRead(SENSORPIN);
// if there is a diff in currentSensorState and lastSensorState
if (currentSensorState == HIGH && lastSensorState == LOW) {
Serial.println("Unbroken");
}
if (currentSensorState == LOW && lastSensorState == HIGH) {
Serial.println("Broken");
// if beam is broken we can assume that an object is blocking it, so incrementing the counter
counter += 1;
}
// --------------------------------------------------------------------------------------------------
Serial.println(counter);
// synchronize states (this should be at the end)
lastSensorState = currentSensorState;
// reset isCounting when reached the counter
if (dataNumber == counter) {
// stop motor
Astepper1.stop();
Serial.println("Done Counting");
isCounting = false;
// reset counter to 0 to prepare for next runs
counter = 0;
}
}
// reset new data to avoid re-initing the motor
newData = false;
}