AccelStepperI2C  v 0.1
I2C wrapper (and a bit more) for the AccelStepper Arduino library
CNCShieldv3.ino
Go to the documentation of this file.
1 /*
2  AccelStepper I2C demo for CNC shield V3.00
3  (c) juh 2022
4 
5  1. install library to Arduino environment
6  2. upload firmware.ino to Arduino UNO with CNC V3.00 shield (slave)
7  3. upload this example to another Arduino-like (master), I used a Wemos D1 mini with ESP8266
8  4. connect the I2C bus of both devices (usually A4<>A4, A5<>A5, GND<>GND)
9  5. don't fortget two I2C pullups and level-shifters if needed
10  6. also connect +5V<>+5V to power one board from the other, if needed
11  7. connect steppers (and Stepstick drivers, of course) to axes X, Y, and Z
12  8. now (not earlier) provide external power to the steppers and power to the Arduinos
13  9. smile.
14 */
15 
16 //#include <AccelStepper.h>
17 
18 #include <Arduino.h>
19 #include <AccelStepperI2C.h>
20 #include <Wire.h>
21 
22 const uint8_t addr = 0x8; // i2c address of slave
23 const uint8_t endstopXpin = 9;
24 
25 AccelStepperI2C* X; // do not invoke the constructors here, as we need to establish I2C connection first.
28 
30 {
31  Serial.print("currentPosition()= "); Serial.print(O->currentPosition());
32  Serial.print(" targetPosition()= "); Serial.print(O->targetPosition());
33  Serial.print(" distanceToGo()= "); Serial.print(O->distanceToGo());
34  Serial.print(" speed()= "); Serial.print(O->speed());
35  Serial.print(" maxSpeed()= "); Serial.println(O->maxSpeed());
36 }
37 
38 void testDryRun()
39 {
40  Serial.print("Let's do some dry run tests, first.\n\n");
41  delay(2000);
42 
43  Serial.print("\nTesting target/position related commands:\n1. set position to 500000 (long): setCurrentPosition(500000)");
44  X->setCurrentPosition(500000);
45  printStats(X); delay(2000);
46 
47  Serial.print("\n2. absolute movement (long): moveTo(500500)");
48  X->moveTo(500500);
49  printStats(X); delay(2000);
50 
51  Serial.print("\n3. relative movement (long): move(-500500)");
52  X->move(-500500);
53  printStats(X); delay(2000);
54 
55  Serial.print("\n\nTesting speed related commands:\n4. set speed limit (float): setMaxSpeed(345.34)");
56  X->setMaxSpeed(345.34);
57  printStats(X); delay(2000);
58 
59  Serial.print("\n5. set speed (float): setSpeed(23.43)");
60  X->setSpeed(23.43);
61  printStats(X); delay(2000);
62 }
63 
64 
65 void setup()
66 {
67 
68  // Important: initialize Wire before creating AccelStepperI2C objects
69  Wire.begin();
70  Serial.begin(115200);
71  while (!Serial) {
72  }
73 
74  Serial.println("\n\nAccelStepperI2C demo - CNC Shield V3.00\n\n");
75 
76  // If the slave's and master's reset is not synchronized by hardware, after a master's reset the slave might
77  // think the master wants another stepper, not a first one, and will run out of steppers, sooner or later.
78  Serial.println("\n\nresetting slave\n");
79  resetAccelStepperSlave(addr);
80  delay(500);
81 
82  // X = new AccelStepperI2C(addr, AccelStepper::DRIVER, /* step pin */ 2, /* dir pin */ 5);
83  X = new AccelStepperI2C(addr, AccelStepper::DRIVER, /* step pin */ 4, /* dir pin */ 2);
84  Serial.println(X->myNum);
85  delay(5000);
86  // Y = new AccelStepperI2C(addr, AccelStepper::DRIVER, 3, 6, 0, 0, true);
87  Y = new AccelStepperI2C(addr, AccelStepper::DRIVER, 15, 0, 0, 0, true);
88  Serial.println(Y->myNum);
89  delay(5000);
90  // Z = new AccelStepperI2C(addr, AccelStepper::DRIVER, 4, 7, 0, 0, true);
91  Z = new AccelStepperI2C(addr, AccelStepper::DRIVER, 32, 33, 0, 0, true);
92  Serial.println(Z->myNum);
93  delay(5000);
94  // you could add stepper A on pins 12 (step) and 13 (dir) after installing
95  // the two jumpers directly above the power terminal
96 
97  if ((X->myNum == -1) or (Y->myNum == -1) or (Z->myNum == -1)) {
98  Serial.print("Error: Could not add one or more steppers. Halting\n\n");
99  while (true) {}
100  }
101  Serial.print("Steppers added with internal numbers X = ");
102  Serial.print(X->myNum); Serial.print(", Y = ");
103  Serial.print(Y->myNum); Serial.print(", Z = ");
104  Serial.print(Z->myNum); Serial.print(".\n\n");
105 
106  /* The CNC shield by default pulls the four drivers' _EN_ pins high, making them inactive.
107  You can enable theim either by installing a jumper next to the reset button between EN and GND
108  *or* by software. As all four EN are connected to Arduino pin 8, we have to tell Accelstepper
109  about that pin and to call enableOutputs(). Before that, we have to tell it that _EN_ is active low
110  with setPinsInverted().
111  */
112  bool res = true;
113 
114  X->setEnablePin(8); res &= X->sentOK;
115  // directionInvert, stepInvert, enableInvert
116  X->setPinsInverted(false, false, true); res &= X->sentOK;
117  X->enableOutputs(); res &= X->sentOK;
118 
119  Y->setEnablePin(8); res &= Y->sentOK;
120  Y->setPinsInverted(false, false, true); res &= Y->sentOK;
121  Y->enableOutputs(); res &= Y->sentOK;
122 
123  Z->setEnablePin(8); res &= Z->sentOK;
124  Z->setPinsInverted(false, false, true); res &= Z->sentOK;
125  Z->enableOutputs(); res &= Z->sentOK;
126 
127  if (!res) {
128  Serial.print("transmission error");
130  }
131 
132  // tailor MaxSpeeds and acceleration to your steppers, here X is a Nema-14, Y and Z are geared 28BYJ-48's
133  X->setMaxSpeed(2000); Y->setMaxSpeed(500); Z->setMaxSpeed(500);
134  X->setAcceleration(200); Y->setAcceleration(300); Z->setAcceleration(300);
135 
136  // install endstop switch
137  X->setEndstopPin(endstopXpin, true, true); // activeLow works nicely together with internal pullup
138  X->enableEndstops(); // true by default
139 
140  X->moveTo(5000); Y->moveTo(8000); Z->moveTo(12000); // set targets
141  X->runState(); Y->runState(); Z->runState(); // start the three state machines
142 
143  // X->setSpeed(500); Y->setSpeed(500); Z->setSpeed(500);
144  //X->runSpeedState(); Y->runSpeedState(); Z->runSpeedState();
145 
146  // while (true) {
147  // ESP.wdtFeed();
148  // yield(); // prevent ESP watchdog reset
149  // }
150  // X->setMaxSpeed(100); X->setAcceleration(20); X->moveTo(500);
151  // Y->setMaxSpeed(100); Y->setAcceleration(20); Y->moveTo(500);
152  // Z->setMaxSpeed(100); Z->setAcceleration(20); Z->moveTo(500);
153 }
154 
155 void loop()
156 {
157  Serial.print("X endstops="); Serial.print(X->endstops()); Serial.print(" - "); printStats(X); //Serial.print("Y - "); printStats(Y); Serial.print("Z - "); printStats(Z);
158  delay (1000);
159  if (abs(X->distanceToGo()) == 0) {
160  X->moveTo(0 - X->currentPosition());
161  // after the target has been reached, the state machine resets itself to state_stopped. So we must start it again.
162  X->runState();
163  }
164 
165  if (abs(Y->distanceToGo()) == 0) {
166  Y->moveTo(0 - Y->currentPosition()); Y->runState();
167  }
168 
169  if (abs(Z->distanceToGo()) == 0) {
170  Z->moveTo(0 - Z->currentPosition()); Z->runState();
171  }
172 
173 }
174 
175 /* test protocol
176 ok void moveTo(long absolute);
177 ok void move(long relative);
178 ok boolean run();
179 ok boolean runSpeed();
180 ok void setMaxSpeed(float speed);
181 ok float maxSpeed();
182 ok void setAcceleration(float acceleration);
183 ok void setSpeed(float speed);
184 ok float speed();
185 ok long distanceToGo();
186 ok long targetPosition();
187 ok long currentPosition();
188  void setCurrentPosition(long position);
189  void runToPosition();
190  boolean runSpeedToPosition();
191  void runToNewPosition(long position);
192  void stop();
193  virtual void disableOutputs();
194 ok virtual void enableOutputs();
195  void setMinPulseWidth(unsigned int minWidth);
196 ok void setEnablePin(uint8_t enablePin = 0xff);
197 ok void setPinsInverted(bool directionInvert = false, bool stepInvert = false, bool enableInvert = false);
198  void setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert);
199  bool isRunning();
200 
201 */
addr
const uint8_t addr
Definition: CNCShieldv3.ino:22
AccelStepperI2C::setPinsInverted
void setPinsInverted(bool directionInvert=false, bool stepInvert=false, bool enableInvert=false)
Definition: AccelStepperI2C.cpp:218
AccelStepperI2C::moveTo
void moveTo(long absolute)
Definition: AccelStepperI2C.cpp:49
AccelStepperI2C::setEnablePin
void setEnablePin(uint8_t enablePin=0xff)
Definition: AccelStepperI2C.cpp:210
AccelStepperI2C::enableOutputs
void enableOutputs()
Definition: AccelStepperI2C.cpp:195
AccelStepperI2C::targetPosition
long targetPosition()
Definition: AccelStepperI2C.cpp:112
Y
AccelStepperI2C * Y
Definition: CNCShieldv3.ino:26
AccelStepperI2C::distanceToGo
long distanceToGo()
Definition: AccelStepperI2C.cpp:101
AccelStepperI2C::myNum
int8_t myNum
Stepper number with myNum >= 0 for successfully added steppers.
Definition: AccelStepperI2C.h:365
AccelStepperI2C::endstops
uint8_t endstops()
Read current state of endstops.
Definition: AccelStepperI2C.cpp:358
testDryRun
void testDryRun()
Definition: CNCShieldv3.ino:38
Z
AccelStepperI2C * Z
Definition: CNCShieldv3.ino:27
AccelStepperI2C
An I2C wrapper class for the AccelStepper library.
Definition: AccelStepperI2C.h:156
AccelStepperI2C.h
AccelStepperI2C::setMaxSpeed
void setMaxSpeed(float speed)
Definition: AccelStepperI2C.cpp:142
X
AccelStepperI2C * X
Definition: CNCShieldv3.ino:25
AccelStepperI2C::currentPosition
long currentPosition()
Definition: AccelStepperI2C.cpp:123
AccelStepperI2C::runState
void runState()
Will poll run(), i.e. run to the target with acceleration and stop the state machine upon reaching it...
Definition: AccelStepperI2C.cpp:320
AccelStepperI2C::setAcceleration
void setAcceleration(float acceleration)
Definition: AccelStepperI2C.cpp:161
AccelStepperI2C::setSpeed
void setSpeed(float speed)
Definition: AccelStepperI2C.cpp:169
AccelStepperI2C::speed
float speed()
Definition: AccelStepperI2C.cpp:177
AccelStepperI2C::maxSpeed
float maxSpeed()
Definition: AccelStepperI2C.cpp:150
loop
void loop()
Definition: CNCShieldv3.ino:155
AccelStepperI2C::setCurrentPosition
void setCurrentPosition(long position)
Definition: AccelStepperI2C.cpp:134
setup
void setup()
Definition: CNCShieldv3.ino:65
AccelStepperI2C::move
void move(long relative)
Definition: AccelStepperI2C.cpp:57
endstopXpin
const uint8_t endstopXpin
Definition: CNCShieldv3.ino:23
AccelStepperI2C::setEndstopPin
void setEndstopPin(int8_t pin, bool activeLow, bool internalPullup)
Define a new endstop pin. Each stepper can have up to two, so don't call this more than twice per ste...
Definition: AccelStepperI2C.cpp:338
printStats
void printStats(AccelStepperI2C *O)
Definition: CNCShieldv3.ino:29
AccelStepperI2C::enableEndstops
void enableEndstops(bool enable=true)
Tell the state machine to check the endstops regularly. If two switches are used, it does not differe...
Definition: AccelStepperI2C.cpp:350