#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; }