-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathError_checking.ino
178 lines (132 loc) · 5.79 KB
/
Error_checking.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
/*
I2Cwrapper errror checking demo
(c) juh 2022
A variant of the AccelStepperI2C sweep demo that demonstrates the available error checking
and safeguarding capabilities.
If and how often you use them in your own sketches will depend on your
degree of paranoia and the severity of potential harm done by uncontrolled
hardware driven by the target device.
Note that checking for errors is done at the wrapper's level, as it is
the wrapper which handles communication for the modules' objects.
To be used it with a target device which has the AccelStepperI2C
module enabled.
*/
#include <Arduino.h>
#include <AccelStepperI2C.h>
#include <Wire.h>
// --- Config. Change as needed for your hardware setup ---
const uint8_t addr = 0x8; // i2c address of target
const uint8_t stepPin = 8; // stepstick driver pin
const uint8_t dirPin = 7; // stepstick driver pin
const uint8_t enablePin = 2; // stepstick driver pin
const uint8_t endstopPin = 17; // Arduino Uno/Nano pin A3 (it's safer to use raw pin nr., since "A3" might mean sth. different if the controller uses a different hardware platform)
const uint8_t interruptPinTarget = 9; // needs to be wired to interruptPinController
const uint8_t interruptPinController = 2; // wired to interruptPinTarget, needs to be a hardware interrupt pin (2 or 3 on Arduino Uno/Nano)
const float homingSpeed = 100.0; // in steps/second. Adapt this for your stepper/gear/microstepping setup
const float maxRunSpeed = 600.0; // in steps/second. Adapt this for your stepper/gear/microstepping setup
const float acceleration = maxRunSpeed / 4; // 4 seconds from 0 to max speed. Adapt this for your stepper/gear/microstepping setup
// --- End of config ---
long target = 3000; // initial target for sweep motion
I2Cwrapper wrapper(addr); // each target device is represented by a wrapper...
AccelStepperI2C stepper(&wrapper); // ...that the stepper uses to communicate with the controller
void setup()
{
Serial.begin(115200);
Wire.begin();
// Wire.setClock(10000); // uncomment for ESP8266 targets, to be on the safe side
Serial.println("\n\n\n*** I2Cwrapper errror checking demo ***\n\n");
/*
Use this to see if the target device is listening.
*/
if (!wrapper.ping()) {
halt("Target not found! Check connections and restart.");
} else {
Serial.println("Target found as expected. Proceeding.\n");
}
wrapper.reset(); // reset the target device
// new in v0.3.0
Serial.print("I2C delay set to ");
Serial.print(wrapper.autoAdjustI2Cdelay()); // uses default safetyMargin of 2ms and max. length transmissions
Serial.print(" ms (default was ");
Serial.print(I2CdefaultDelay);
Serial.println(" ms)");
delay(1000);
printVersions();
/*
Use this to see if controller and target use the same version of the library
*/
if (!wrapper.checkVersion(I2Cw_Version)) {
/*
Note: according to semver versioning (https://semver.org/), API changes
are indicated by upping the major version. So in real world settings is
should be sufficient to check if the major version numbers match,
granted that future version of this software will implement the semver
version as intended.
*/
halt("Warning: Controller and target are not using the same library version.");
} else {
Serial.println("Target's and controller's versions match. Proceeding\n");
}
/*
Attaching will usually only fail if the target runs out of its (default)
eight preallocated drivers (that's why it's important to reset the target
together with the controller, see above).
*/
stepper.attach(AccelStepper::DRIVER, stepPin, dirPin);
if (stepper.myNum < 0) { // should not happen after a reset
halt("Error: stepper could not be allocated.");
}
/*
Let's set up the system. Instead of checking each single transmission, we'll use
transmissionErrors() at the end, as nothing critical is happening until then.
*/
stepper.setEnablePin(enablePin);
stepper.setPinsInverted(false, false, true); // directionInvert, stepInvert, enableInvert
stepper.enableOutputs();
stepper.setMaxSpeed(maxRunSpeed);
stepper.setAcceleration(acceleration);
if (wrapper.transmissionErrors() > 0) { // check for an error in any of the above transmissions
halt("Error: at least one transmission during setup failed.");
} else {
Serial.println("Target device successfully configured. Proceeding.");
}
}
void loop()
{
stepper.moveTo(target);
if (!wrapper.sentOK ) {
halt("Couldn't set target.\n");
}
stepper.runState(); // (re)start the state machine
if (!wrapper.sentOK ) {
halt("Couldn't activate state machine.\n");
}
// isRunning() is non void, i.e. it comprises a command sent and a result received,
// so we'll need to check for both of them (or check for transmissionErrors()==0)
while (stepper.isRunning() and wrapper.sentOK and wrapper.resultOK) {
delay(200);
};
if (wrapper.transmissionErrors() > 0) {
halt("Error while waiting for state machine to stop.");
}
Serial.println("<---> Target reached, turning around");
target = - target;
}
void halt(const char* m) {
Serial.println(m);
Serial.println("\n\nHalting.\n");
while (true) {
yield(); // prevent ESPs from watchdog reset
}
}
void printVersions() {
Serial.print("Controller's version of I2Cwrapper package is ");
Serial.print(I2Cw_VersionMajor); Serial.print(".");
Serial.print(I2Cw_VersionMinor); Serial.print(".");
Serial.println(I2Cw_VersionPatch);
uint32_t v = wrapper.getVersion();
Serial.print("Target's version of I2Cwrapper package is ");
Serial.print(v >> 16 & 0xff); Serial.print(".");
Serial.print(v >> 8 & 0xff); Serial.print(".");
Serial.println(v & 0xff);
}