AccelStepperI2C  v0.2.2
I2C wrapper (and a bit more) for the AccelStepper Arduino library
Todo List
page %AccelStepperI2C library

add emergency stop/break pin for slave (just use reset pin for the moment)

ATM data is not protected against updates from ISRs while it is being used in the main program (see http://gammon.com.au/interrupts). Check if this could be a problem in our case.

ESP32: make use of dual cores?

use interrupts for endstops instead of main loop polling (not sure how much of a difference this would make in practice, though. The main loop is't doing much else, what really takes time are the computations.)

Multimaster? Master stop/start bit?

update keywords.txt

clean up example sketches

implement runToPosition() and runToNewPosition() in master - implemented

test (and adapt) slave firmware for ESP8266 - implemented. However, I2C slave mode on ESP8266s is no fun. Run only with 160MHz CPU and start testing with 10kHz (that's right: ten kHz) I2C clock speed.

checking each transmission with sentOK and resultOK is tedious. We could use some counter to accumulate errors and check them summarily, e.g. at the end of setup etc. - AccelStepperI2C::sentErrors(), AccelStepperI2C::resultErrors() and AccelStepperI2C::transmissionErrors() added

make time the slave has to answer I2C requests (I2CrequestDelay) configurable, as it will depend on µC and bus frequency etc. - setI2Cdelay() implemented

Versioning, I2C command to request version (important, as library and firmware always need to match) - getVersion() and checkVersion() implemented

Implement interrupt mechanism, so that the slave can inform the master about finished tasks or other events - setInterruptPin() and enableInterrupts() implemented

implement diagnostic functions, e.g. measurements how long messages take to be processed or current stepper pulse frequency - done, performance graphs included in documentation

add ESP32 compatibility for slave - done, but needs further testing

Make the I2C address programmable and persistent in EEPROM. - done

Error handling and sanity checks are rudimentary. Currently the system is not stable against transmission errors, partly due to the limitations of Wire.requestFrom() and Wire.available(). A better protocol would be needed, which would mean more overhead. Need testing to see how important this is in practics. - CRC8 implemented

Implement end stops/reference stops. - endstop polling implemented, interrupt would be better

Member AccelStepperI2C::enableEndstops (bool enable=true)
Find solution for moving a stepper out of an endstop's zone. implemented debounce and active-flank detection so that there's no danger of repeated interrupts being triggered while in an endstop's active zone.
File firmware.ino

return messages (results) should ideally come with an id, too, so that master can be sure it's the correct result. Currently only CRC8, i.e. correct transmission is checked.

volatile variables / ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {}

Module support (Servo, pin control, ...) needs to be outsourced and centralized. Currently there are a number of places that need to be adapted if a new module is added: Init section, startup message in setup(), processMessage().

make i2c address configurable with pins or via i2c/EEPROM

implement endstops/reference positions

File I2Cwrapper.h

Enhance diagnostics with a self-diagnosing function to determine the optimal/minimal I2Cdelay in a given master-slave setup.

AccelStepperI2C and ServoI2C should be derived from a common base class, atm there's some unhealthy copy and pasteimplemented with I2Cwrapper, but with client instead of inheritance relation.

Member I2Cwrapper::setI2Cdelay (unsigned long delay)
I2Cdelay is currently global; make it a per-slave setting. implemented with I2Cwrapper.
Member loop ()
endstop polling: overhead to check if polling is needed (timeToCheckTheEndstops) might cost more than it saves, so maybe just check each cycle even if it might be much more often than needed.
Class PinI2C
Only tested on AVRs.
Member processMessage (uint8_t len)
Implement blocking functions runToPositionCmd() and runToNewPositionCmd() on the master's side/in the library?
Member receiveEvent (int howMany)
Just read the buffer here, move interpretation out of the interrupt.
Member requestEvent ()
<done>Find sth. meaningful to report from requestEvent() if no message is pending, e.g. current position etc.</done> not implemented, ESP32 can't do that (doh)