first upload
This commit is contained in:
commit
1f9edb14b4
36
I2CMasterUtils.cpp
Normal file
36
I2CMasterUtils.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "I2CMasterUtils.h"
|
||||||
|
#include "I2CCommands.h"
|
||||||
|
|
||||||
|
void I2CMasterUtils::scanI2C(Stream &output) {
|
||||||
|
output.println("Scanning for I2C devices...");
|
||||||
|
for (uint8_t addr = 1; addr < 127; addr++) {
|
||||||
|
Wire.beginTransmission(addr);
|
||||||
|
if (Wire.endTransmission() == 0) {
|
||||||
|
output.print("Found device at 0x");
|
||||||
|
output.println(addr, HEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2CMasterUtils::changeSlaveAddress(uint8_t oldAddr, uint8_t newAddr, Stream &output) {
|
||||||
|
Wire.beginTransmission(oldAddr);
|
||||||
|
Wire.write(0xAA); // Command code for address change
|
||||||
|
Wire.write(newAddr);
|
||||||
|
Wire.endTransmission();
|
||||||
|
output.print("Sent address change command to 0x");
|
||||||
|
output.print(oldAddr, HEX);
|
||||||
|
output.print(" -> 0x");
|
||||||
|
output.println(newAddr, HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool I2CMasterUtils::parseChangeAddressCommand(const String &input, uint8_t &oldAddr, uint8_t &newAddr) {
|
||||||
|
if (!input.startsWith("ch")) return false;
|
||||||
|
int o, n;
|
||||||
|
int matched = sscanf(input.c_str(), "ch %x %x", &o, &n);
|
||||||
|
if (matched == 2) {
|
||||||
|
oldAddr = (uint8_t)o;
|
||||||
|
newAddr = (uint8_t)n;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
14
I2CMasterUtils.h
Normal file
14
I2CMasterUtils.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef I2CMASTERUTILS_H
|
||||||
|
#define I2CMASTERUTILS_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
class I2CMasterUtils {
|
||||||
|
public:
|
||||||
|
static void scanI2C(Stream &output = Serial);
|
||||||
|
static void changeSlaveAddress(uint8_t oldAddr, uint8_t newAddr, Stream &output = Serial);
|
||||||
|
static bool parseChangeAddressCommand(const String &input, uint8_t &oldAddr, uint8_t &newAddr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 FABLAB Bahrain
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
20
README.md
Normal file
20
README.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Relay8I2C Library
|
||||||
|
**By Fatima @ FABLAB Bahrain**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Control 8-relay modules via I2C with dynamic address configuration. Designed for ESP8266 and Arduino platforms.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- I2C communication protocol
|
||||||
|
- Dynamic slave address configuration
|
||||||
|
- Master controller with serial interface
|
||||||
|
- Active LOW relay support
|
||||||
|
- EEPROM storage for persistent addressing
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
1. Download the library ZIP
|
||||||
|
2. Arduino IDE: Sketch > Include Library > Add .ZIP Library
|
||||||
|
3. Select the downloaded ZIP file
|
||||||
|
|
||||||
|
## Usage
|
65
examples/Master/Master.ino
Normal file
65
examples/Master/Master.ino
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include <Wire.h>
|
||||||
|
#include <I2CRelay.h>
|
||||||
|
#include <I2CMasterUtils.h>
|
||||||
|
|
||||||
|
RelayI2CMaster relayMaster(0x08); // Default address, can be changed via setAddress()
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
delay(1000);
|
||||||
|
relayMaster.begin();
|
||||||
|
Serial.println("Enter:");
|
||||||
|
Serial.println(" s - to scan I2C bus");
|
||||||
|
Serial.println(" ch <old> <new> - to change slave address");
|
||||||
|
Serial.println(" <relay> <on/off> - to set relay (e.g. 3 on)");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (Serial.available()) {
|
||||||
|
String input = Serial.readStringUntil('\n');
|
||||||
|
input.trim();
|
||||||
|
|
||||||
|
if (input == "s") {
|
||||||
|
I2CMasterUtils::scanI2C();
|
||||||
|
} else if (input.startsWith("ch")) {
|
||||||
|
uint8_t oldAddr, newAddr;
|
||||||
|
if (I2CMasterUtils::parseChangeAddressCommand(input, oldAddr, newAddr)) {
|
||||||
|
I2CMasterUtils::changeSlaveAddress(oldAddr, newAddr);
|
||||||
|
relayMaster.setAddress(newAddr); // Update master's address
|
||||||
|
Serial.print("Changed address to 0x");
|
||||||
|
Serial.println(newAddr, HEX);
|
||||||
|
} else {
|
||||||
|
Serial.println("Invalid command format. Use: ch <old_addr> <new_addr>");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int spaceIndex = input.indexOf(' ');
|
||||||
|
if (spaceIndex > 0) {
|
||||||
|
String relayStr = input.substring(0, spaceIndex);
|
||||||
|
String stateStr = input.substring(spaceIndex + 1);
|
||||||
|
|
||||||
|
int relayNum = relayStr.toInt();
|
||||||
|
bool state = false;
|
||||||
|
|
||||||
|
stateStr.toLowerCase();
|
||||||
|
if (stateStr == "on") state = true;
|
||||||
|
else if (stateStr == "off") state = false;
|
||||||
|
else {
|
||||||
|
Serial.println("Invalid state! Use 'on' or 'off'.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relayNum >= 1 && relayNum <= 8) {
|
||||||
|
relayMaster.setRelay(relayNum, state);
|
||||||
|
Serial.print("Relay ");
|
||||||
|
Serial.print(relayNum);
|
||||||
|
Serial.print(" turned ");
|
||||||
|
Serial.println(state ? "ON" : "OFF");
|
||||||
|
} else {
|
||||||
|
Serial.println("Invalid relay number! Use 1-8.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.println("Invalid command! Format: <relay_number> <on/off>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
examples/Slave/Slave.ino
Normal file
65
examples/Slave/Slave.ino
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include <Wire.h>
|
||||||
|
#include <EEPROM.h>
|
||||||
|
|
||||||
|
// EEPROM settings
|
||||||
|
#define ADDR_EEPROM_LOC 0
|
||||||
|
#define EEPROM_SIZE 64
|
||||||
|
|
||||||
|
// Relay pins: GPIO0 to GPIO7
|
||||||
|
const int relayPins[8] = {0, 1, 2, 3, 4, 5, 6, 7}; // GPIOs 0-7
|
||||||
|
|
||||||
|
uint8_t i2cAddress;
|
||||||
|
|
||||||
|
// Unified I2C receive event
|
||||||
|
void receiveEvent(int howMany) {
|
||||||
|
if (howMany >= 2) {
|
||||||
|
uint8_t first = Wire.read();
|
||||||
|
uint8_t second = Wire.read();
|
||||||
|
|
||||||
|
// Check for address change command
|
||||||
|
if (first == 0xAA) {
|
||||||
|
// Change I2C address and store in EEPROM
|
||||||
|
uint8_t newAddr = second;
|
||||||
|
EEPROM.write(ADDR_EEPROM_LOC, newAddr);
|
||||||
|
EEPROM.commit();
|
||||||
|
Serial.print("I2C address changed to: 0x");
|
||||||
|
Serial.println(newAddr, HEX);
|
||||||
|
delay(100);
|
||||||
|
ESP.restart();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, treat as relay control
|
||||||
|
int relay = first; // Relay number: 1-8
|
||||||
|
int state = second; // State: 1=ON, 0=OFF
|
||||||
|
if (relay >= 1 && relay <= 8) {
|
||||||
|
digitalWrite(relayPins[relay - 1], state ? LOW : HIGH); // Active LOW relays
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
EEPROM.begin(EEPROM_SIZE);
|
||||||
|
|
||||||
|
// Read I2C address from EEPROM or use default
|
||||||
|
i2cAddress = EEPROM.read(ADDR_EEPROM_LOC);
|
||||||
|
if (i2cAddress == 0xFF || i2cAddress == 0) i2cAddress = 0x08; // Default address
|
||||||
|
|
||||||
|
Serial.print("Using I2C address: 0x");
|
||||||
|
Serial.println(i2cAddress, HEX);
|
||||||
|
|
||||||
|
// Initialize relay pins
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
pinMode(relayPins[i], OUTPUT);
|
||||||
|
digitalWrite(relayPins[i], HIGH); // Relays OFF initially (active LOW)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start I2C slave
|
||||||
|
Wire.begin(i2cAddress);
|
||||||
|
Wire.onReceive(receiveEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Nothing needed here for basic operation
|
||||||
|
}
|
16
keywords.txt
Normal file
16
keywords.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#######################################
|
||||||
|
# Syntax coloring for Relay8I2C Library
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
# Classes
|
||||||
|
RelayI2CMaster KEYWORD1
|
||||||
|
I2CMasterUtils KEYWORD1
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
begin KEYWORD2
|
||||||
|
setRelay KEYWORD2
|
||||||
|
scanI2C KEYWORD2
|
||||||
|
changeSlaveAddress KEYWORD2
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
CMD_CHANGE_ADDR LITERAL1
|
9
library.properties
Normal file
9
library.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name=I2CMasterUtils
|
||||||
|
version=1.0.0
|
||||||
|
author=Fatima Idrees <fatimaxidrees@gmail.com>
|
||||||
|
maintainer=Fatima Idrees <fatimaxidrees@gmail.com>
|
||||||
|
sentence=Control DC motors via I2C with scanning and configuration utilities.
|
||||||
|
paragraph=Provides easy control of 8-relay modules via I2C communication with dynamic address configuration. Includes master/slave implementation for ESP8266/Arduino platforms.
|
||||||
|
category=Device Control
|
||||||
|
url=https://github.com/fablabbh/I2CMasterUtils
|
||||||
|
architectures=*
|
6
src/I2CCommands.h
Normal file
6
src/I2CCommands.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef I2C_COMMANDS_H
|
||||||
|
#define I2C_COMMANDS_H
|
||||||
|
|
||||||
|
#define CMD_CHANGE_ADDR 0xAA // Use the same value as in your slave
|
||||||
|
|
||||||
|
#endif
|
36
src/I2CMasterUtils.cpp
Normal file
36
src/I2CMasterUtils.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "I2CMasterUtils.h"
|
||||||
|
#include "I2CCommands.h"
|
||||||
|
|
||||||
|
void I2CMasterUtils::scanI2C(Stream &output) {
|
||||||
|
output.println("Scanning for I2C devices...");
|
||||||
|
for (uint8_t addr = 1; addr < 127; addr++) {
|
||||||
|
Wire.beginTransmission(addr);
|
||||||
|
if (Wire.endTransmission() == 0) {
|
||||||
|
output.print("Found device at 0x");
|
||||||
|
output.println(addr, HEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2CMasterUtils::changeSlaveAddress(uint8_t oldAddr, uint8_t newAddr, Stream &output) {
|
||||||
|
Wire.beginTransmission(oldAddr);
|
||||||
|
Wire.write(CMD_CHANGE_ADDR); // Use the command code from I2CCommands.h
|
||||||
|
Wire.write(newAddr);
|
||||||
|
Wire.endTransmission();
|
||||||
|
output.print("Sent address change command to 0x");
|
||||||
|
output.print(oldAddr, HEX);
|
||||||
|
output.print(" -> 0x");
|
||||||
|
output.println(newAddr, HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool I2CMasterUtils::parseChangeAddressCommand(const String &input, uint8_t &oldAddr, uint8_t &newAddr) {
|
||||||
|
if (!input.startsWith("ch")) return false;
|
||||||
|
int o, n;
|
||||||
|
int matched = sscanf(input.c_str(), "ch %x %x", &o, &n);
|
||||||
|
if (matched == 2) {
|
||||||
|
oldAddr = (uint8_t)o;
|
||||||
|
newAddr = (uint8_t)n;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
14
src/I2CMasterUtils.h
Normal file
14
src/I2CMasterUtils.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef I2CMASTERUTILS_H
|
||||||
|
#define I2CMASTERUTILS_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
class I2CMasterUtils {
|
||||||
|
public:
|
||||||
|
static void scanI2C(Stream &output = Serial);
|
||||||
|
static void changeSlaveAddress(uint8_t oldAddr, uint8_t newAddr, Stream &output = Serial);
|
||||||
|
static bool parseChangeAddressCommand(const String &input, uint8_t &oldAddr, uint8_t &newAddr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
35
src/I2CRelay.cpp
Normal file
35
src/I2CRelay.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include <Wire.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "I2CRelay.h"
|
||||||
|
#include "I2CMasterUtils.h"
|
||||||
|
#include "I2CCommands.h"
|
||||||
|
|
||||||
|
RelayI2CMaster::RelayI2CMaster(uint8_t slaveAddress) : _slaveAddress(slaveAddress) {}
|
||||||
|
|
||||||
|
void RelayI2CMaster::setAddress(uint8_t newAddress) {
|
||||||
|
_slaveAddress = newAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RelayI2CMaster::begin() {
|
||||||
|
Wire.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RelayI2CMaster::setRelay(uint8_t relayIndex, bool state) {
|
||||||
|
Wire.beginTransmission(_slaveAddress);
|
||||||
|
Wire.write(relayIndex);
|
||||||
|
Wire.write(state ? 1 : 0);
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t RelayI2CMaster::scanDevices(uint8_t* foundAddresses, uint8_t maxDevices) {
|
||||||
|
uint8_t count = 0;
|
||||||
|
for(uint8_t addr = 1; addr < 127; addr++) {
|
||||||
|
Wire.beginTransmission(addr);
|
||||||
|
if(Wire.endTransmission() == 0) {
|
||||||
|
if(count < maxDevices) {
|
||||||
|
foundAddresses[count++] = addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
20
src/I2CRelay.h
Normal file
20
src/I2CRelay.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef RELAY_I2C_MASTER_H
|
||||||
|
#define RELAY_I2C_MASTER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
class RelayI2CMaster {
|
||||||
|
public:
|
||||||
|
RelayI2CMaster(uint8_t slaveAddress);
|
||||||
|
void begin();
|
||||||
|
void setRelay(uint8_t relayIndex, bool state);
|
||||||
|
uint8_t scanDevices(uint8_t* foundAddresses, uint8_t maxDevices);
|
||||||
|
void setAddress(uint8_t newAddress);
|
||||||
|
void handleI2CCommand();
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t _slaveAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user