I2Cwrapper v0.3.0
Generic framework for Arduino I2C target devices
|
Arduino library for I2C-control of stepper motors connected to another Arduino which runs the associated I2Cwrapper firmware.
See the AccelStepperI2C class reference for differences to the methods of the original AccelStepper class and for new methods of class AccelStepperI2C.
More...
Arduino library for I2C-control of stepper motors connected to another Arduino which runs the associated I2Cwrapper firmware.
See the AccelStepperI2C class reference for differences to the methods of the original AccelStepper class and for new methods of class AccelStepperI2C.
Copyright (c) 2022 juh
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
add emergency stop/break pin for target (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 isn't doing much else, what really takes time are the computations.)
update keywords.txt
clean up example sketches
implement runToPosition() and runToNewPosition() in controller - implemented
test (and adapt) target firmware for ESP8266 - implemented. However, I2C target 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 target 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 target can inform the controller 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 target - 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
Classes | |
class | AccelStepperI2C |
An I2C wrapper class for the AccelStepper library. More... | |
Macros | |
#define | log(...) |
Variables | |
const long | resError = 0 |
const uint8_t | asCmdOffset = 10 |
const uint8_t | moveToCmd = asCmdOffset + 0 |
const uint8_t | moveCmd = asCmdOffset + 1 |
const uint8_t | runCmd = asCmdOffset + 2 |
const uint8_t | runResult = 1 |
const uint8_t | runSpeedCmd = asCmdOffset + 3 |
const uint8_t | runSpeedResult = 1 |
const uint8_t | setMaxSpeedCmd = asCmdOffset + 4 |
const uint8_t | maxSpeedCmd = asCmdOffset + 5 |
const uint8_t | maxSpeedResult = 4 |
const uint8_t | setAccelerationCmd = asCmdOffset + 6 |
const uint8_t | setSpeedCmd = asCmdOffset + 7 |
const uint8_t | speedCmd = asCmdOffset + 8 |
const uint8_t | speedResult = 4 |
const uint8_t | distanceToGoCmd = asCmdOffset + 9 |
const uint8_t | distanceToGoResult = 4 |
const uint8_t | targetPositionCmd = asCmdOffset + 10 |
const uint8_t | targetPositionResult = 4 |
const uint8_t | currentPositionCmd = asCmdOffset + 11 |
const uint8_t | currentPositionResult = 4 |
const uint8_t | setCurrentPositionCmd = asCmdOffset + 12 |
const uint8_t | runToPositionCmd = asCmdOffset + 13 |
const uint8_t | runSpeedToPositionCmd = asCmdOffset + 14 |
const uint8_t | runSpeedToPositionResult = 1 |
const uint8_t | runToNewPositionCmd = asCmdOffset + 15 |
const uint8_t | stopCmd = asCmdOffset + 16 |
const uint8_t | disableOutputsCmd = asCmdOffset + 17 |
const uint8_t | enableOutputsCmd = asCmdOffset + 18 |
const uint8_t | setMinPulseWidthCmd = asCmdOffset + 19 |
const uint8_t | setEnablePinCmd = asCmdOffset + 20 |
const uint8_t | setPinsInverted1Cmd = asCmdOffset + 21 |
const uint8_t | setPinsInverted2Cmd = asCmdOffset + 22 |
const uint8_t | isRunningCmd = asCmdOffset + 23 |
const uint8_t | isRunningResult = 1 |
const uint8_t | attachCmd = asCmdOffset + 24 |
const uint8_t | attachResult = 1 |
const uint8_t | enableInterruptsCmd = asCmdOffset + 27 |
const uint8_t | setStateCmd = asCmdOffset + 28 |
const uint8_t | getStateCmd = asCmdOffset + 29 |
const uint8_t | getStateResult = 1 |
const uint8_t | setEndstopPinCmd = asCmdOffset + 30 |
const uint8_t | enableEndstopsCmd = asCmdOffset + 31 |
const uint8_t | endstopsCmd = asCmdOffset + 32 |
const uint8_t | endstopsResult = 1 |
const uint8_t | state_stopped = 0 |
stepper state machine states More... | |
const uint8_t | state_run = 1 |
corresponds to AccelStepper::run(), will fall back to state_stopped if target reached or endstop hit More... | |
const uint8_t | state_runSpeed = 2 |
corresponds to AccelStepper::runSpeed(), will remain active until stopped by user or endstop More... | |
const uint8_t | state_runSpeedToPosition = 3 |
corresponds to AccelStepper::state_runSpeedToPosition(), will fall back to state_stopped if target position reached or endstop hit More... | |
const uint8_t | interruptReason_targetReachedByRun = 1 |
const uint8_t | interruptReason_targetReachedByRunSpeedToPosition = 2 |
const uint8_t | interruptReason_endstopHit = 3 |
#define log | ( | ... | ) |
const uint8_t asCmdOffset = 10 |
const uint8_t attachCmd = asCmdOffset + 24 |
const uint8_t attachResult = 1 |
const uint8_t currentPositionCmd = asCmdOffset + 11 |
const uint8_t currentPositionResult = 4 |
const uint8_t disableOutputsCmd = asCmdOffset + 17 |
const uint8_t distanceToGoCmd = asCmdOffset + 9 |
const uint8_t distanceToGoResult = 4 |
const uint8_t enableEndstopsCmd = asCmdOffset + 31 |
const uint8_t enableInterruptsCmd = asCmdOffset + 27 |
const uint8_t enableOutputsCmd = asCmdOffset + 18 |
const uint8_t endstopsCmd = asCmdOffset + 32 |
const uint8_t endstopsResult = 1 |
const uint8_t getStateCmd = asCmdOffset + 29 |
const uint8_t getStateResult = 1 |
const uint8_t isRunningCmd = asCmdOffset + 23 |
const uint8_t isRunningResult = 1 |
const uint8_t maxSpeedCmd = asCmdOffset + 5 |
const uint8_t maxSpeedResult = 4 |
const uint8_t moveCmd = asCmdOffset + 1 |
const uint8_t moveToCmd = asCmdOffset + 0 |
const long resError = 0 |
const uint8_t runCmd = asCmdOffset + 2 |
const uint8_t runResult = 1 |
const uint8_t runSpeedCmd = asCmdOffset + 3 |
const uint8_t runSpeedResult = 1 |
const uint8_t runSpeedToPositionCmd = asCmdOffset + 14 |
const uint8_t runSpeedToPositionResult = 1 |
const uint8_t runToNewPositionCmd = asCmdOffset + 15 |
const uint8_t runToPositionCmd = asCmdOffset + 13 |
const uint8_t setAccelerationCmd = asCmdOffset + 6 |
const uint8_t setCurrentPositionCmd = asCmdOffset + 12 |
const uint8_t setEnablePinCmd = asCmdOffset + 20 |
const uint8_t setEndstopPinCmd = asCmdOffset + 30 |
const uint8_t setMaxSpeedCmd = asCmdOffset + 4 |
const uint8_t setMinPulseWidthCmd = asCmdOffset + 19 |
const uint8_t setPinsInverted1Cmd = asCmdOffset + 21 |
const uint8_t setPinsInverted2Cmd = asCmdOffset + 22 |
const uint8_t setSpeedCmd = asCmdOffset + 7 |
const uint8_t setStateCmd = asCmdOffset + 28 |
const uint8_t speedCmd = asCmdOffset + 8 |
const uint8_t speedResult = 4 |
const uint8_t state_run = 1 |
corresponds to AccelStepper::run(), will fall back to state_stopped if target reached or endstop hit
const uint8_t state_runSpeed = 2 |
corresponds to AccelStepper::runSpeed(), will remain active until stopped by user or endstop
const uint8_t state_runSpeedToPosition = 3 |
corresponds to AccelStepper::state_runSpeedToPosition(), will fall back to state_stopped if target position reached or endstop hit
const uint8_t state_stopped = 0 |
stepper state machine states
state machine is inactive, stepper can still be controlled directly
const uint8_t stopCmd = asCmdOffset + 16 |
const uint8_t targetPositionCmd = asCmdOffset + 10 |
const uint8_t targetPositionResult = 4 |