AccelStepperI2C  v 0.1
I2C wrapper (and a bit more) for the AccelStepper Arduino library
Error_checking.ino
Go to the documentation of this file.
1 /*
2  AccelStepperI2C errror checking demo
3  (c) juh 2022
4 
5  Demonstrates the different error checking capabilities.
6 
7 */
8 
9 #include <Arduino.h>
10 #include <AccelStepperI2C.h>
11 #include <Wire.h>
12 
13 // Config. Change as needed for your hardware setup
14 const uint8_t addr = 0x8; // i2c address of slave
15 
16 I2Cwrapper wrapper(addr); // each slave device is represented by a wrapper...
17 AccelStepperI2C stepper(&wrapper); // ...that the stepper uses to communicate with the slave
18 
19 
20 void setup()
21 {
22 
23  Serial.begin(115200);
24  Wire.begin();
25  // Wire.setClock(10000); // uncomment for ESP8266 slaves, to be on the safe side
26 
27  Serial.println("\n\n\nAccelStepperI2C errror checking demo\n\n");
28 
29  /*
30  * Use this to see if the slave device can be reached.
31  */
32  if (!wrapper.ping()) {
33  Serial.println("Slave not found! Check connections and restart.");
34  while (true) {}
35  }
36 
37  wrapper.reset(); // reset the slave device
38  delay(500); // and give it time to reboot
39 
40  /*
41  * Use this to see if master and slave run the same version of the library
42  * (currently only implemented for AccelStepperI2C)
43  */
44 
45 ################################
46 
47  if (!checkVersion(addr)) {
48  Serial.println("Warning: Master and slave are not using the same library version.");
49  Serial.print("Master version is "); Serial.print(AccelStepperI2C_VersionMajor);
50  Serial.print("."); Serial.println(AccelStepperI2C_VersionMinor);
51  uint16_t v = getVersion(addr);
52  Serial.print("Slave version is "); Serial.print(v >> 8);
53  Serial.print("."); Serial.println(v & 0xFF);
54  while (true) {}
55  } else {
56  Serial.println("Slave's and master's versions match. Proceeding...");
57  }
58 
59  // add and init stepper
60 
61  Serial.println("\nAdding stepper(s)");
62  X = new AccelStepperI2C(addr,
63  AccelStepper::DRIVER, /* <-- driver type */
64  stepPin, /* <-- step pin */
65  dirPin, /* <-- dir pin */
66  0, /* <-- pin3 (unused for driver type DRIVER) */
67  0 /* <-- pin4 (unused for driver type DRIVER) */
68  );
69  if (X->myNum < 0 ) {
70  while (1) {} // failed, halting.
71  }
72 
73  // configure endstop
74 
75  X->setEndstopPin(endstopPin, // <-- endstop pin
76  true, // internal pullup
77  true // activeLow works nicely together with internal pullup
78  );
79  X->enableEndstops();
80 
81  // configure interrupt
82 
83  setInterruptPin(addr,
84  interruptPinSlave, // <-- interrupt pin
85  true // activeHigh = master will have to look out for a RISING flank
86  );
87  X->enableInterrupts(); // make slave send out interrupts for this stepper
88  attachInterrupt(digitalPinToInterrupt(interruptPinMaster), interruptFromSlave, RISING); // make master notice them
89 
90 
91  X->setMaxSpeed(maxRunSpeed);
92  if (X->endstops() != 0) {
93  Serial.println("\nWarning: Please move stepper away from endstop,\n"
94  "because I don't know in which direction I have to move to get away from it.\n\nHALTING.");
95  while (true) {}
96  }
97 
98  findEndstops();
99  Serial.print("Endstops found at positions 0 (lower endstop) and ");
100  Serial.print(upperEndStop); Serial.println(" (upper endstop).\n");
101 
102  Serial.println("\n\n\n\n");
103  X->moveTo(upperEndStop / 2); // start with some initial target
104  X->runState(); // go there with acceleration
105 
106 }
107 
109 {
110  while (!interruptFlag) {}
111  interruptFlag = false;
112 }
113 
115 {
116 
117  X->setSpeed(-homingSpeed); // start in negative direction, as we're looking for point zero first
118  X->runSpeedState(); // run at constant speed (= interrupt can only be triggered by endstop, not by target reached)
119  waitForInterrupt(); // and wait for endstop (state machine will stop there)
120  X->setCurrentPosition(0); // let's define this endstop as position 0
121  lowerEndStop = 0;
122 
123  X->setSpeed(homingSpeed); // now let's look in the positive direction
124  X->runSpeedState(); // run at constant (slow) speed
125  waitForInterrupt(); // and wait for endstop (state machine will stop there)
126  upperEndStop = X->currentPosition(); // save it
127 
128 }
129 
130 /*
131  For testing purposes, the loop will run the stepper to random targets
132  which might be invalid, i.e. outside of the endstop limits. If it hits
133  an endstop, it runs to the middle position, and starts over. If it
134  arrives at a valid target posistion, it just sets another target.
135 */
136 const long chance = 20; // % chance that target will be off limits
137 void loop()
138 {
139 
141 
142  // determine what caused the interrupt, state machine will have stopped in any case
143  if (X->endstops() != 0) {
144 
145  Serial.println("ran into endstop, returning to middle position.");
146  X->moveTo(upperEndStop / 2);
147  X->runState(); // go there with acceleration
148 
149  } else if (!X->isRunning()) {
150 
151  Serial.print("target reached, setting new target to ");
152  long offLimits = (upperEndStop * chance / 100) / 2;
153  long newPos = random(-offLimits, upperEndStop + offLimits) ;
154  Serial.println(newPos);
155  X->moveTo(newPos);
156  X->runState(); // go there with acceleration
157 
158  } else {
159 
160  Serial.println("\nWarning: Interrupt due to unknown reason\n\nHALTING.");
161  while (true) {}
162 
163  }
164 
165 }
166 
167 
168 #if defined(ESP8266)
169 ICACHE_RAM_ATTR void
170 #endif
172 {
173  interruptFlag = true; // just set a flag, leave interrupt as quickly as possible
174 }
I2Cwrapper
A helper class for the AccelStepperI2C (and ServoI2C) library.
Definition: I2Cwrapper.h:79
wrapper
I2Cwrapper wrapper(addr)
Definition: Error_checking.ino:17
findEndstops
void findEndstops()
Definition: Error_checking.ino:114
maxRunSpeed
const float maxRunSpeed
Definition: Interrupt_Endstop.ino:29
addr
const uint8_t addr
Definition: Error_checking.ino:14
AccelStepperI2C
An I2C wrapper class for the AccelStepper library.
Definition: AccelStepperI2C.h:163
AccelStepperI2C.h
chance
const long chance
Definition: Error_checking.ino:136
setup
void setup()
Definition: Error_checking.ino:20
loop
void loop()
Definition: Error_checking.ino:137
interruptFromSlave
interruptFromSlave()
Definition: Error_checking.ino:171
interruptPinSlave
const uint8_t interruptPinSlave
Definition: Interrupt_Endstop.ino:26
interruptPinMaster
const uint8_t interruptPinMaster
Definition: Interrupt_Endstop.ino:27
endstopPin
const uint8_t endstopPin
Definition: Interrupt_Endstop.ino:25
I2Cwrapper::ping
bool ping()
Test if slave is listening.
Definition: I2Cwrapper.cpp:101
stepPin
const uint8_t stepPin
Definition: Stepper_and_Servo_together.ino:17
dirPin
const uint8_t dirPin
Definition: Stepper_and_Servo_together.ino:18
waitForInterrupt
void waitForInterrupt()
Definition: Error_checking.ino:108
homingSpeed
const float homingSpeed
Definition: Interrupt_Endstop.ino:28
I2Cwrapper::reset
void reset()
Tells the slave to reset to it's default state. It is recommended to reset the slave every time the m...
Definition: I2Cwrapper.cpp:107
interruptFlag
volatile bool interruptFlag
Definition: Interrupt_Endstop.ino:38