I2Cwrapper v0.3.0
Generic framework for Arduino I2C target devices
AccelStepperI2C.h File Reference

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...

Detailed Description

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.

Author

Copyright (c) 2022 juh

License

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.

Todo:

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
 

Macro Definition Documentation

◆ log

#define log (   ...)

Variable Documentation

◆ asCmdOffset

const uint8_t asCmdOffset = 10

◆ attachCmd

const uint8_t attachCmd = asCmdOffset + 24

◆ attachResult

const uint8_t attachResult = 1

◆ currentPositionCmd

const uint8_t currentPositionCmd = asCmdOffset + 11

◆ currentPositionResult

const uint8_t currentPositionResult = 4

◆ disableOutputsCmd

const uint8_t disableOutputsCmd = asCmdOffset + 17

◆ distanceToGoCmd

const uint8_t distanceToGoCmd = asCmdOffset + 9

◆ distanceToGoResult

const uint8_t distanceToGoResult = 4

◆ enableEndstopsCmd

const uint8_t enableEndstopsCmd = asCmdOffset + 31

◆ enableInterruptsCmd

const uint8_t enableInterruptsCmd = asCmdOffset + 27

◆ enableOutputsCmd

const uint8_t enableOutputsCmd = asCmdOffset + 18

◆ endstopsCmd

const uint8_t endstopsCmd = asCmdOffset + 32

◆ endstopsResult

const uint8_t endstopsResult = 1

◆ getStateCmd

const uint8_t getStateCmd = asCmdOffset + 29

◆ getStateResult

const uint8_t getStateResult = 1

◆ isRunningCmd

const uint8_t isRunningCmd = asCmdOffset + 23

◆ isRunningResult

const uint8_t isRunningResult = 1

◆ maxSpeedCmd

const uint8_t maxSpeedCmd = asCmdOffset + 5

◆ maxSpeedResult

const uint8_t maxSpeedResult = 4

◆ moveCmd

const uint8_t moveCmd = asCmdOffset + 1

◆ moveToCmd

const uint8_t moveToCmd = asCmdOffset + 0

◆ resError

const long resError = 0

◆ runCmd

const uint8_t runCmd = asCmdOffset + 2

◆ runResult

const uint8_t runResult = 1

◆ runSpeedCmd

const uint8_t runSpeedCmd = asCmdOffset + 3

◆ runSpeedResult

const uint8_t runSpeedResult = 1

◆ runSpeedToPositionCmd

const uint8_t runSpeedToPositionCmd = asCmdOffset + 14

◆ runSpeedToPositionResult

const uint8_t runSpeedToPositionResult = 1

◆ runToNewPositionCmd

const uint8_t runToNewPositionCmd = asCmdOffset + 15

◆ runToPositionCmd

const uint8_t runToPositionCmd = asCmdOffset + 13

◆ setAccelerationCmd

const uint8_t setAccelerationCmd = asCmdOffset + 6

◆ setCurrentPositionCmd

const uint8_t setCurrentPositionCmd = asCmdOffset + 12

◆ setEnablePinCmd

const uint8_t setEnablePinCmd = asCmdOffset + 20

◆ setEndstopPinCmd

const uint8_t setEndstopPinCmd = asCmdOffset + 30

◆ setMaxSpeedCmd

const uint8_t setMaxSpeedCmd = asCmdOffset + 4

◆ setMinPulseWidthCmd

const uint8_t setMinPulseWidthCmd = asCmdOffset + 19

◆ setPinsInverted1Cmd

const uint8_t setPinsInverted1Cmd = asCmdOffset + 21

◆ setPinsInverted2Cmd

const uint8_t setPinsInverted2Cmd = asCmdOffset + 22

◆ setSpeedCmd

const uint8_t setSpeedCmd = asCmdOffset + 7

◆ setStateCmd

const uint8_t setStateCmd = asCmdOffset + 28

◆ speedCmd

const uint8_t speedCmd = asCmdOffset + 8

◆ speedResult

const uint8_t speedResult = 4

◆ state_run

const uint8_t state_run = 1

corresponds to AccelStepper::run(), will fall back to state_stopped if target reached or endstop hit

◆ state_runSpeed

const uint8_t state_runSpeed = 2

corresponds to AccelStepper::runSpeed(), will remain active until stopped by user or endstop

◆ state_runSpeedToPosition

const uint8_t state_runSpeedToPosition = 3

corresponds to AccelStepper::state_runSpeedToPosition(), will fall back to state_stopped if target position reached or endstop hit

◆ state_stopped

const uint8_t state_stopped = 0

stepper state machine states

state machine is inactive, stepper can still be controlled directly

◆ stopCmd

const uint8_t stopCmd = asCmdOffset + 16

◆ targetPositionCmd

const uint8_t targetPositionCmd = asCmdOffset + 10

◆ targetPositionResult

const uint8_t targetPositionResult = 4