AccelStepperI2C  v 0.1
I2C wrapper (and a bit more) for the AccelStepper Arduino library
I2Cwrapper.cpp
Go to the documentation of this file.
1 
13 #include <Wire.h>
14 #include "I2Cwrapper.h"
15 
16 
17 // Constructor
18 I2Cwrapper::I2Cwrapper(uint8_t i2c_address, uint8_t maxBuf)
19 {
20  address = i2c_address;
21  buf.init(maxBuf);
22 }
23 
24 
25 // Jan's little sister: wait I2Cdelay, adjusted by the time already spent
26 void I2Cwrapper::doDelay()
27 {
28  uint32_t now = millis();
29  delay(max(0, I2Cdelay - int16_t(now - lastI2Ctransmission)));
30  lastI2Ctransmission = now;
31 }
32 
33 // reset buffer and write header bytes...
34 void I2Cwrapper::prepareCommand(uint8_t cmd, uint8_t unit)
35 {
36  buf.reset();
37  buf.write(cmd); // [1]: command
38  buf.write(unit); // [2]: subunit to be addressed
39  log(" Sending command #"); log(cmd);
40  log(" to unit #"); log(int8_t(unit));
41 }
42 
43 // ... compute checksum and send it.
44 // returns true if sending was successful.
45 // Also updates sentOK and sentErrors for client to check
47 {
48  doDelay(); // give slave time in between transmissions
49  buf.setCRC8(); // [0]: CRC8
50  Wire.beginTransmission(address);
51  Wire.write(buf.buffer, buf.idx);
52 #ifdef DEBUG
53  log(" with CRC="); log(buf.buffer[0]); log(" and ");
54  log(buf.idx - 3); log(" paramter bytes: ");
55  for (uint8_t d = 3; d < buf.idx; d++) {
56  log(buf.buffer[d]); log(" ");
57  }
58  log("\n");
59 #endif
60  sentOK = (Wire.endTransmission() == 0);
61  if (!sentOK) {
62  sentErrorsCount++;
63  }
64  return sentOK;
65 }
66 
67 // read slave's reply, numBytes is *without* CRC8 byte
68 // returns true if received data was correct regarding expected lenght and checksum
69 // Also updates resultOK and resultErrors for client to check
70 bool I2Cwrapper::readResult(uint8_t numBytes)
71 {
72  doDelay(); // give slave time in between transmissions
73  buf.reset();
74  bool resultOK = false;
75 
76  if (Wire.requestFrom(address, uint8_t(numBytes + 1)) > 0) { // +1 for CRC8
77  log(" Requesting result (");
78  log(numBytes + 1);
79  log(" bytes incl. CRC8): ");
80  uint8_t i = 0;
81  while ((i <= numBytes) and (i < buf.maxLen)) {
82  buf.buffer[i++] = Wire.read(); // accessing buffer directly to put CRC8 where it belongs, ### improve
83  log(buf.buffer[i - 1], HEX);
84  log(" ");
85  }
86  buf.idx = i;
88  log((i <= numBytes) ? " -- buffer out of space! " : "");
89  log(" total bytes = ");
90  log(buf.idx);
91  log(resultOK ? " CRC8 ok\n" : " CRC8 wrong!\n");
92  } // else some transmission error occured, resultOK = false
93 
94  buf.reset(); // reset for reading
95  if (!resultOK) {
96  resultErrorsCount++;
97  }
98  return resultOK;
99 }
100 
101 
103 {
104  Wire.beginTransmission(address);
105  return Wire.endTransmission() == 0;
106 }
107 
109 {
111  sendCommand();
112 }
113 
115 {
118  sendCommand();
119 }
120 
121 int16_t I2Cwrapper::setI2Cdelay(int16_t delay)
122 {
123  int16_t d = I2Cdelay;
124  I2Cdelay = delay;
125  return d;
126 }
127 
129  bool activeHigh)
130 {
132  buf.write(pin);
133  buf.write(activeHigh);
134  sendCommand();
135 }
136 
138 {
140  uint8_t res = 0xff;
142  buf.read(res);
143  }
144  return res;
145 }
146 
148 {
150  uint32_t res = 0xffffffff;
152  buf.read(res);
153  }
154  return res;
155 }
156 
157 bool I2Cwrapper::checkVersion(uint32_t masterVersion)
158 {
159  return masterVersion == getSlaveVersion();
160 }
161 
163 {
164  uint16_t se = sentErrorsCount;
165  sentErrorsCount = 0;
166  return se;
167 }
168 
170 {
171  uint16_t re = resultErrorsCount;
172  resultErrorsCount = 0;
173  return re;
174 }
175 
177 {
178  return sentErrors() + resultErrors();
179 }
SimpleBuffer::setCRC8
void setCRC8()
Calculate CRC8 checksum for the currently used buffer ([1]...[idx-1]) and store it in the first byte ...
Definition: SimpleBuffer.cpp:49
I2Cwrapper::resultOK
bool resultOK
True if return value from previous function call was received successfully.
Definition: I2Cwrapper.h:192
I2Cwrapper::prepareCommand
void prepareCommand(uint8_t cmd, uint8_t unit=-1)
Definition: I2Cwrapper.cpp:34
I2Cwrapper::sentOK
bool sentOK
True if previous function call was successfully transferred to slave.
Definition: I2Cwrapper.h:191
I2Cwrapper::I2Cwrapper
I2Cwrapper(uint8_t i2c_address, uint8_t maxBuf=maxBufDefault)
Constructor.
Definition: I2Cwrapper.cpp:18
SimpleBuffer::checkCRC8
bool checkCRC8()
Check for correct CRC8 checksum. First byte [0] holds the checksum, rest of the currently used buffer...
Definition: SimpleBuffer.cpp:54
now
uint32_t now
Definition: firmware.ino:102
I2Cwrapper::clearInterrupt
uint8_t clearInterrupt()
Acknowledge a received interrupt to slave so that it can clear the interupt condition and return the ...
Definition: I2Cwrapper.cpp:137
I2Cwrapper::resultErrors
uint16_t resultErrors()
Return and reset the number of failed receive events since the last time this method was used....
Definition: I2Cwrapper.cpp:169
I2Cwrapper::buf
SimpleBuffer buf
Definition: I2Cwrapper.h:190
SimpleBuffer::read
void read(T &value)
Read any basic data type from the buffer from the current position and increment the position pointer...
Definition: SimpleBuffer.h:112
changeI2CaddressCmd
const uint8_t changeI2CaddressCmd
Definition: I2Cwrapper.h:39
I2Cwrapper::transmissionErrors
uint16_t transmissionErrors()
Return and reset the sum of failed commands sent and failed receive events since the last time this m...
Definition: I2Cwrapper.cpp:176
setInterruptPinCmd
const uint8_t setInterruptPinCmd
Definition: I2Cwrapper.h:40
SimpleBuffer::idx
uint8_t idx
The position pointer. Remember, [0] holds the CRC8 checksum, so for an empty buffer,...
Definition: SimpleBuffer.h:90
I2Cwrapper.h
A helper class for the AccelStepperI2C (and ServoI2C) library.
I2Cwrapper::readResult
bool readResult(uint8_t numBytes)
Definition: I2Cwrapper.cpp:70
SimpleBuffer::init
void init(uint8_t buflen)
Allocate and reset buffer.
Definition: SimpleBuffer.cpp:16
SimpleBuffer::reset
void reset()
Reset the position pointer to the start of the buffer (which is[1] as [0] is the CRC8 chcksum) withou...
Definition: SimpleBuffer.cpp:23
resetCmd
const uint8_t resetCmd
Definition: I2Cwrapper.h:38
I2Cwrapper::sentErrors
uint16_t sentErrors()
Return and reset the number of failed commands sent since the last time this method was used....
Definition: I2Cwrapper.cpp:162
log
#define log(...)
Definition: firmware.ino:94
SimpleBuffer::maxLen
uint8_t maxLen
Maximum length of buffer in bytes. Read and write operations use this to check for sufficient space (...
Definition: SimpleBuffer.h:96
I2Cwrapper::ping
bool ping()
Test if slave is listening.
Definition: I2Cwrapper.cpp:102
I2Cwrapper::getSlaveVersion
uint32_t getSlaveVersion()
Get semver compliant version of slave firmware.
Definition: I2Cwrapper.cpp:147
I2Cwrapper::changeI2Caddress
void changeI2Caddress(uint8_t newAddress)
Permanently change the I2C address of the device. New address is stored in EEPROM (AVR) or flash memo...
Definition: I2Cwrapper.cpp:114
newAddress
const uint8_t newAddress
Definition: Change_address.ino:17
SimpleBuffer::buffer
uint8_t * buffer
The allocated buffer.
Definition: SimpleBuffer.h:84
getVersionResult
const uint8_t getVersionResult
Definition: I2Cwrapper.h:42
getVersionCmd
const uint8_t getVersionCmd
Definition: I2Cwrapper.h:42
clearInterruptResult
const uint8_t clearInterruptResult
Definition: I2Cwrapper.h:41
I2Cwrapper::setI2Cdelay
int16_t setI2Cdelay(int16_t delay)
Define a minimum time that the master keeps between I2C transmissions. This is to make sure that the ...
Definition: I2Cwrapper.cpp:121
clearInterruptCmd
const uint8_t clearInterruptCmd
Definition: I2Cwrapper.h:41
I2Cwrapper::reset
void reset()
Tells the slave to reset to it's default state. It is recommended to reset the slave every time the m...
Definition: I2Cwrapper.cpp:108
SimpleBuffer::write
void write(const T &value)
Write any basic data type to the buffer at the current position and increment the position pointer ac...
Definition: SimpleBuffer.h:103
I2Cwrapper::checkVersion
bool checkVersion(uint32_t masterVersion)
Get version of slave firmware and compare it with library version.
Definition: I2Cwrapper.cpp:157
I2Cwrapper::sendCommand
bool sendCommand()
Definition: I2Cwrapper.cpp:46
I2Cwrapper::setInterruptPin
void setInterruptPin(int8_t pin, bool activeHigh=true)
Define a global interrupt pin which can be used by device units (steppers, servos....
Definition: I2Cwrapper.cpp:128