AccelStepperI2C
v 0.1
I2C wrapper (and a bit more) for the AccelStepper Arduino library
|
Go to the documentation of this file.
23 #include <AccelStepper.h>
75 #if defined(SERVO_SUPPORT)
77 #if defined(__AVR__) || defined(ESP8266)
80 #include <ESP32Servo.h>
81 #endif // defined(__AVR__)
87 #endif // defined(SERVO_SUPPORT)
94 #define log(...) Serial.print(__VA_ARGS__)
114 bool diagnosticsEnabled =
false;
117 uint32_t previousLastReceiveTime;
118 #endif // DIAGNOSTICS
127 #define EEPROM_OFFSET_I2C_ADDRESS 0 // where in eeprom is the I2C address stored, if any? [1 CRC8 + 4 marker + 1 address = 6 bytes]
129 #if defined(ESP32) || defined(ESP8266)
130 const uint32_t eepromUsedSize = 6;
131 #endif // defined(ESP32) || defined(ESP8266)
152 #if defined(ESP32) || defined(ESP8266)
154 #endif // defined(ESP32) || defined(ESP8266)
155 for (
byte i = 0; i < 6; i++) {
159 #if defined(ESP32) || defined(ESP8266)
161 #endif // defined(ESP32) || defined(ESP8266)
164 uint32_t markerTest; b.
read(markerTest);
165 uint8_t storedAddress; b.
read(storedAddress);
167 return storedAddress;
185 log(
"Writing to EEPROM: ");
186 #if defined(ESP32) || defined(ESP8266)
188 #endif // defined(ESP32) || defined(ESP8266)
189 for (
byte i = 0; i < 6; i++) {
195 #if defined(ESP32) || defined(ESP8266)
197 #endif // defined(ESP32) || defined(ESP8266)
263 asm volatile (
" jmp 0");
264 #elif defined(ESP32) || defined(ESP8266)
280 Serial.begin(115200);
282 log(
"\n\n\n=== AccelStepperI2C v");
287 Wire.begin(i2c_address);
288 log(
"I2C started with address ");
log(i2c_address);
log(
"\n\n");
305 int8_t
addStepper(uint8_t interface = AccelStepper::FULL4WIRE,
318 log(
"-- Too many steppers, failed to add new one\n");
350 log(
"~~ interrupt master with source = ");
log(source);
351 log(
" and reason = ");
log(reason);
log(
"\n");
386 log(
" | [Steppers]:states =");
401 bool timeToCheckTheEndstops =
false;
406 if (not
steppers[i].stepper->run()) {
410 timeToCheckTheEndstops =
true;
419 if (
steppers[i].stepper->distanceToGo() == 0) {
437 if (timeToCheckTheEndstops and
steppers[i].endstopsEnabled) {
439 if (es !=
steppers[i].prevEndstopState) {
440 uint32_t ms = millis();
441 if (ms >
steppers[i].endstopDebounceEnd) {
442 log(
"** es: flank detected \n");
446 log(
"** es: endstop detected!\n");
494 thenMicros = micros();
495 #endif // DIAGNOSTICS
496 log(howMany);
log(
" I\n");
499 for (uint8_t i = 0; i < howMany; i++) {
506 while (Wire.available()) {
515 previousLastReceiveTime = micros() - thenMicros;
516 #endif // DIAGNOSTICS
553 uint32_t thenMicrosP = micros();
554 #endif // DIAGNOSTICS
556 log(
"New message with ");
log(len);
log(
" bytes. ");
557 for (
int j = 0; j < len; j++) {
568 log(
"CRC8 ok. Command = ");
log(cmd);
log(
" for unit ");
log(unit);
569 log(
" with ");
log(i);
log(
" parameter bytes --> ");
757 (b & 1 << 0) != 0, (b & 1 << 1) != 0, (b & 1 << 2) != 0);
768 (b & 1 << 0) != 0, (b & 1 << 1) != 0, (b & 1 << 2) != 0, (b & 1 << 3) != 0, (b & 1 << 4) != 0);
810 pinMode(pin, internalPullup ? INPUT_PULLUP : INPUT);
844 int8_t num =
addStepper(interface, pin1, pin2, pin3, pin4, enable);
858 log(
"\n\n---> Resetting\n\n");
898 #endif // DIAGNOSTICS
936 #if defined(SERVO_SUPPORT)
970 servos[unit].write(value);
978 servos[unit].writeMicroseconds(value);
1004 #endif // defined(SERVO_SUPPORT)
1007 log(
"No matching command found");
1038 #endif // DIAGNOSTICS
1083 #if defined(ESP8266)
1090 thenMicros = micros();
1091 #endif // DIAGNOSTICS
1103 #endif // DIAGNOSTICS
const uint8_t diagnosticsCmd
const uint8_t servoWriteMicrosecondsCmd
volatile uint8_t newMessage
const uint8_t interruptReason_endstopHit
const uint8_t VersionMinor
const uint8_t state_runSpeed
corresponds to AccelStepper::runSpeed(), will remain active until stopped by user or endstop
const uint8_t setMinPulseWidthCmd
const uint8_t interruptReason_targetReachedByRunSpeedToPosition
const uint8_t runToNewPositionCmd
This struct comprises all stepper parameters needed for local slave management.
const uint32_t eepromI2CaddressMarker
const uint8_t servoDetachCmd
const uint8_t isRunningCmd
void setCRC8()
Calculate CRC8 checksum for the currently used buffer ([1]...[idx-1]) and store it in the first byte ...
const uint8_t runSpeedCmd
uint32_t cycles
Number of slave's main loop executions since the last reboot.
const uint8_t enableDiagnosticsCmd
volatile uint8_t writtenToBuffer
const uint8_t disableOutputsCmd
bool checkCRC8()
Check for correct CRC8 checksum. First byte [0] holds the checksum, rest of the currently used buffer...
const uint8_t setMaxSpeedCmd
const uint8_t enableInterruptsCmd
const uint8_t servoReadMicrosecondsCmd
const uint32_t endstopDebouncePeriod
const uint8_t AccelStepperI2CmaxBuf
const uint8_t currentPositionCmd
void read(T &value)
Read any basic data type from the buffer from the current position and increment the position pointer...
Stepper steppers[maxSteppers]
const uint8_t servoReadCmd
const uint8_t servoAttach2Cmd
Servo servos[maxServos]
Uncomment this to enable time keeping diagnostics. You probably should disable debugging,...
const uint8_t changeI2CaddressCmd
const uint8_t setInterruptPinCmd
uint16_t lastProcessTime
microseconds the slave needed to process (interpret) most recently received command
uint8_t idx
The position pointer. Remember, [0] holds the CRC8 checksum, so for an empty buffer,...
bool validStepper(int8_t s)
#define EEPROM_OFFSET_I2C_ADDRESS
const uint8_t setPinsInverted1Cmd
const uint8_t state_run
corresponds to AccelStepper::run(), will fall back to state_stopped if target reached or endstop hit
const uint8_t getStateCmd
const uint8_t maxEndstops
const uint8_t setEnablePinCmd
const uint32_t reportPeriod
void storeI2C_address(uint8_t newAddress)
Write I2C address to EEPROM.
void init(uint8_t buflen)
Allocate and reset buffer.
const uint8_t slaveDefaultAddress
const uint8_t setAccelerationCmd
void reset()
Reset the position pointer to the start of the buffer (which is[1] as [0] is the CRC8 chcksum) withou...
void loop()
Main loop, implements the state machine. Will check for each stepper's state and do the appropriate p...
const uint8_t setPinsInverted2Cmd
const uint8_t setCurrentPositionCmd
const uint8_t state_stopped
stepper state machine states
Endstop endstops[maxEndstops]
void processMessage(uint8_t len)
Used to transmit diagnostic info with AccelStepperI2C::diagnostics().
const uint8_t endstopsCmd
const uint8_t setEndstopPinCmd
const uint8_t distanceToGoCmd
uint8_t pollEndstops(uint8_t s)
const uint8_t maxSpeedCmd
uint32_t endstopDebounceEnd
const uint8_t state_runSpeedToPosition
corresponds to AccelStepper::state_runSpeedToPosition(), will fall back to state_stopped if target po...
void receiveEvent(int howMany)
Handle I2C receive event. Just read the message and inform main loop.
Arduino library for I2C-control of servo motors connected to another Arduino which runs the associate...
const uint8_t targetPositionCmd
Simple and ugly serialization buffer for any data type. Template technique and CRC8 adapted from Nick...
const uint8_t interruptReason_none
You should not encounter this, as you don't want to be interrupted without a reason....
const uint8_t enableOutputsCmd
const uint8_t maxSteppers
const uint8_t servoAttachedCmd
bool validServo(int8_t s)
const uint8_t runToPositionCmd
void triggerInterrupt(uint8_t source, uint8_t reason)
uint8_t * buffer
The allocated buffer.
const uint8_t servoAttach1Cmd
const uint8_t setSpeedCmd
void requestEvent()
Handle I2C request event. Will send results or information requested by the last command,...
const uint8_t setStateCmd
const uint8_t enableEndstopsCmd
const uint8_t getVersionCmd
uint16_t lastRequestTime
microseconds the slave spent in the most recent onRequest() interrupt
void setup()
Setup system. Retrieve I2C address from EEPROM or default and initialize I2C slave.
const uint8_t VersionPatch
uint8_t retrieveI2C_address()
Read a stored I2C address from EEPROM. If there is none, use default.
const uint8_t clearInterruptCmd
void write(const T &value)
Write any basic data type to the buffer at the current position and increment the position pointer ac...
const uint8_t interruptReason_targetReachedByRun
volatile uint8_t sentOnRequest
const uint8_t runSpeedToPositionCmd
const uint8_t servoWriteCmd
uint16_t lastReceiveTime
microseconds the slave spent in the most recent onReceive() interrupt
const uint8_t VersionMajor
int8_t addStepper(uint8_t interface=AccelStepper::FULL4WIRE, uint8_t pin1=2, uint8_t pin2=3, uint8_t pin3=4, uint8_t pin4=5, bool enable=true)
Assign and initialize new stepper. Calls the AccelStepper's[1/2] constructor