111 lines
3.1 KiB
C++
111 lines
3.1 KiB
C++
#include "I2CRelay.h"
|
|
|
|
// Command codes
|
|
#define CMD_SET_ADDR 0x01
|
|
#define CMD_SET_NAME 0x02
|
|
#define CMD_RELAY_SET 0x10
|
|
#define CMD_RELAY_ALL 0x11
|
|
#define CMD_RELAY_TIMER 0x12
|
|
#define CMD_RELAY_ALL_TIMER 0x13
|
|
|
|
I2CRelay::I2CRelay(uint8_t sda, uint8_t scl)
|
|
: _sda(sda), _scl(scl) {}
|
|
|
|
void I2CRelay::begin() {
|
|
Wire.begin(_sda, _scl);
|
|
}
|
|
|
|
void I2CRelay::scan(Stream &out) {
|
|
out.println("Scanning I2C bus...");
|
|
uint8_t count = 0;
|
|
for (uint8_t address = 1; address < 127; address++) {
|
|
Wire.beginTransmission(address);
|
|
uint8_t error = Wire.endTransmission();
|
|
if (error == 0) {
|
|
out.print("I2C device found at address 0x");
|
|
if (address < 16) out.print("0");
|
|
out.print(address, HEX);
|
|
out.println(" !");
|
|
count++;
|
|
}
|
|
delay(2);
|
|
}
|
|
if (count == 0) {
|
|
out.println("No I2C devices found.");
|
|
} else {
|
|
out.print("Scan complete, devices found: ");
|
|
out.println(count);
|
|
}
|
|
out.println();
|
|
}
|
|
|
|
void I2CRelay::setSlaveAddress(uint8_t oldAddr, uint8_t newAddr, Stream &out) {
|
|
Wire.beginTransmission(oldAddr);
|
|
Wire.write(CMD_SET_ADDR);
|
|
Wire.write(newAddr);
|
|
Wire.endTransmission();
|
|
out.print("Sent address change command: 0x");
|
|
out.print(oldAddr, HEX);
|
|
out.print(" -> 0x");
|
|
out.println(newAddr, HEX);
|
|
delay(1200); // Give slave time to restart
|
|
}
|
|
|
|
void I2CRelay::setSlaveName(uint8_t addr, const char* newName, Stream &out) {
|
|
Wire.beginTransmission(addr);
|
|
Wire.write(CMD_SET_NAME);
|
|
Wire.write((const uint8_t*)newName, strlen(newName));
|
|
Wire.endTransmission();
|
|
out.print("Sent name change command to 0x");
|
|
out.print(addr, HEX);
|
|
out.print(": ");
|
|
out.println(newName);
|
|
}
|
|
|
|
String I2CRelay::requestSlaveInfo(uint8_t addr) {
|
|
Wire.requestFrom(addr, (uint8_t)40);
|
|
String response = "";
|
|
while (Wire.available()) {
|
|
char c = Wire.read();
|
|
response += c;
|
|
}
|
|
return response;
|
|
}
|
|
|
|
// Relay control
|
|
bool I2CRelay::setRelay(uint8_t addr, uint8_t relay, bool on) {
|
|
Wire.beginTransmission(addr);
|
|
Wire.write(CMD_RELAY_SET);
|
|
Wire.write(relay);
|
|
Wire.write(on ? 1 : 0);
|
|
return Wire.endTransmission() == 0;
|
|
}
|
|
|
|
bool I2CRelay::setAllRelays(uint8_t addr, bool on) {
|
|
Wire.beginTransmission(addr);
|
|
Wire.write(CMD_RELAY_ALL);
|
|
Wire.write(on ? 1 : 0);
|
|
return Wire.endTransmission() == 0;
|
|
}
|
|
|
|
bool I2CRelay::setRelayTimer(uint8_t addr, uint8_t relay, uint32_t ms) {
|
|
Wire.beginTransmission(addr);
|
|
Wire.write(CMD_RELAY_TIMER);
|
|
Wire.write(relay);
|
|
Wire.write((uint8_t)(ms & 0xFF));
|
|
Wire.write((uint8_t)((ms >> 8) & 0xFF));
|
|
Wire.write((uint8_t)((ms >> 16) & 0xFF));
|
|
Wire.write((uint8_t)((ms >> 24) & 0xFF));
|
|
return Wire.endTransmission() == 0;
|
|
}
|
|
|
|
bool I2CRelay::setAllRelaysTimer(uint8_t addr, uint32_t ms) {
|
|
Wire.beginTransmission(addr);
|
|
Wire.write(CMD_RELAY_ALL_TIMER);
|
|
Wire.write((uint8_t)(ms & 0xFF));
|
|
Wire.write((uint8_t)((ms >> 8) & 0xFF));
|
|
Wire.write((uint8_t)((ms >> 16) & 0xFF));
|
|
Wire.write((uint8_t)((ms >> 24) & 0xFF));
|
|
return Wire.endTransmission() == 0;
|
|
}
|