From 168dd7b49bbacbd56e761ddb886c1218a3e47d3e Mon Sep 17 00:00:00 2001 From: Fatima Idrees Date: Tue, 13 May 2025 11:11:33 +0300 Subject: [PATCH] Modify the code --- examples/Master/Master.ino | 158 ++++++++++++++++++++++++----------- examples/Slave/Slave.ino | 164 +++++++++++++++++++++++++++---------- src/I2CCommands.h | 6 -- src/I2CMasterUtils.cpp | 36 -------- src/I2CMasterUtils.h | 14 ---- 5 files changed, 232 insertions(+), 146 deletions(-) delete mode 100644 src/I2CCommands.h delete mode 100644 src/I2CMasterUtils.cpp delete mode 100644 src/I2CMasterUtils.h diff --git a/examples/Master/Master.ino b/examples/Master/Master.ino index 2338524..89fdd31 100644 --- a/examples/Master/Master.ino +++ b/examples/Master/Master.ino @@ -1,55 +1,121 @@ #include -#define I2C_DEV_ADDR 0x55 // Must match slave +#define SLAVE_ADDRESS 0x08 void setup() { Serial.begin(115200); - Wire.begin(); // default pins for ESP32-C3: SDA=8, SCL=9 - Serial.println("Enter number of pixels:"); + Wire.begin(); + + delay(1000); + Serial.println("Testing I2C LED Strip Slave..."); + + // 1. Set device name (optional, not in slave code above, but included for completeness) + // setDeviceName("LivingRoomLEDs"); + + // 2. Set number of LEDs to 10 (for testing) + setLedCount(10); + delay(200); + + // 3. Set brightness to 128 (half) + setBrightness(128); + delay(200); + + // 4. Set all pixels to red + setAllPixels(255, 0, 0); + delay(1000); + + // 5. Set pixel 0 to green + setPixel(0, 0, 255, 0); + delay(500); + + // 6. Set pixel 1 to blue + setPixel(1, 0, 0, 255); + delay(500); + + // 7. Set all pixels to white + setAllPixels(255, 255, 255); + delay(1000); + + // 8. Clear all pixels (turn off) + clearAll(); + delay(500); + + // 9. Request status from slave and print it + requestStatus(); + + Serial.println("Test complete."); } void loop() { - static int numPixels = 0; - static bool pixelsSet = false; - - // Step 1: Get number of pixels from user - if (!pixelsSet && Serial.available()) { - numPixels = Serial.parseInt(); - if (numPixels > 0 && numPixels <= 100) { // reasonable limit - Wire.beginTransmission(I2C_DEV_ADDR); - Wire.write(0x01); // Command: set pixel count - Wire.write(numPixels); - Wire.endTransmission(); - pixelsSet = true; - Serial.println("Enter command: (example: ALL 255 0 0 128) or (PIXEL 3 0 255 0 255)"); - Serial.println("Format:"); - Serial.println("ALL R G B I"); - Serial.println("PIXEL N R G B I"); - } else { - Serial.println("Invalid pixel count. Try again."); - } - } - - // Step 2: Get lighting commands from user - if (pixelsSet && Serial.available()) { - String cmd = Serial.readStringUntil('\n'); - cmd.trim(); - - if (cmd.startsWith("ALL")) { - int r, g, b, i; - sscanf(cmd.c_str(), "ALL %d %d %d %d", &r, &g, &b, &i); - Wire.beginTransmission(I2C_DEV_ADDR); - Wire.write(0x02); // Command: set all pixels - Wire.write(r); Wire.write(g); Wire.write(b); Wire.write(i); - Wire.endTransmission(); - } else if (cmd.startsWith("PIXEL")) { - int n, r, g, b, i; - sscanf(cmd.c_str(), "PIXEL %d %d %d %d %d", &n, &r, &g, &b, &i); - Wire.beginTransmission(I2C_DEV_ADDR); - Wire.write(0x03); // Command: set one pixel - Wire.write(n); Wire.write(r); Wire.write(g); Wire.write(b); Wire.write(i); - Wire.endTransmission(); - } - Serial.println("Command sent."); - } + // Nothing here +} + +// --------- Helper Functions --------- + +void setPixel(uint8_t pixel, uint8_t r, uint8_t g, uint8_t b) { + Wire.beginTransmission(SLAVE_ADDRESS); + Wire.write(0xA0); // Command: Set individual pixel + Wire.write(pixel); + Wire.write(r); + Wire.write(g); + Wire.write(b); + Wire.endTransmission(); + Serial.print("Set pixel "); Serial.print(pixel); + Serial.print(" to RGB("); Serial.print(r); Serial.print(","); Serial.print(g); Serial.print(","); Serial.print(b); Serial.println(")"); +} + +void setAllPixels(uint8_t r, uint8_t g, uint8_t b) { + Wire.beginTransmission(SLAVE_ADDRESS); + Wire.write(0xA1); // Command: Set all pixels + Wire.write(r); + Wire.write(g); + Wire.write(b); + Wire.endTransmission(); + Serial.print("Set all pixels to RGB("); Serial.print(r); Serial.print(","); Serial.print(g); Serial.print(","); Serial.print(b); Serial.println(")"); +} + +void setBrightness(uint8_t brightness) { + Wire.beginTransmission(SLAVE_ADDRESS); + Wire.write(0xA2); // Command: Set brightness + Wire.write(brightness); + Wire.endTransmission(); + Serial.print("Set brightness to "); Serial.println(brightness); +} + +void clearAll() { + Wire.beginTransmission(SLAVE_ADDRESS); + Wire.write(0xB0); // Command: Clear all + Wire.endTransmission(); + Serial.println("Cleared all pixels (off)"); +} + +void setLedCount(uint16_t count) { + Wire.beginTransmission(SLAVE_ADDRESS); + Wire.write(0xD0); // Command: Set LED count + Wire.write((count >> 8) & 0xFF); // High byte + Wire.write(count & 0xFF); // Low byte + Wire.endTransmission(); + Serial.print("Set LED count to "); Serial.println(count); +} + +// Optional: Set device name (if supported in slave code) +void setDeviceName(const char* name) { + Wire.beginTransmission(SLAVE_ADDRESS); + Wire.write(0xD0); // Command: Set device name + for (uint8_t i = 0; i < strlen(name); i++) { + Wire.write(name[i]); + } + Wire.endTransmission(); + Serial.print("Set device name to "); Serial.println(name); +} + +void requestStatus() { + Wire.requestFrom(SLAVE_ADDRESS, 40); // Request up to 40 bytes (enough for status string) + String status = ""; + while (Wire.available()) { + char c = Wire.read(); + status += c; + } + Serial.print("Status from slave: "); + Serial.println(status); } diff --git a/examples/Slave/Slave.ino b/examples/Slave/Slave.ino index 9854074..d2e6746 100644 --- a/examples/Slave/Slave.ino +++ b/examples/Slave/Slave.ino @@ -1,56 +1,132 @@ #include +#include #include -#define I2C_DEV_ADDR 0x55 -#define NEOPIXEL_PIN 19 // Change as needed -#define MAX_PIXELS 100 +#define DEFAULT_ADDRESS 0x08 +#define DEFAULT_LED_COUNT 30 +#define MAX_NAME_LENGTH 24 +#define LED_PIN 6 -Adafruit_NeoPixel strip(MAX_PIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); +struct Config { + uint8_t address; + char deviceName[MAX_NAME_LENGTH+1]; + uint16_t ledCount; + uint8_t brightness; +}; -uint8_t pixelCount = 1; +Config config; +Adafruit_NeoPixel strip; -void receiveEvent(int len) { - delay(50); // Add more delay for stability as requested - - if (len < 1) return; - uint8_t cmd = Wire.read(); - - if (cmd == 0x01 && len >= 2) { // Set pixel count - pixelCount = Wire.read(); - strip.updateLength(pixelCount); - strip.begin(); - strip.show(); - } - else if (cmd == 0x02 && len >= 5) { // Set all pixels: R G B I - uint8_t r = Wire.read(); - uint8_t g = Wire.read(); - uint8_t b = Wire.read(); - uint8_t intensity = Wire.read(); - for (int i = 0; i < pixelCount; i++) { - strip.setPixelColor(i, strip.Color(r * intensity / 255, g * intensity / 255, b * intensity / 255)); - } - strip.show(); - } - else if (cmd == 0x03 && len >= 6) { // Set one pixel: N R G B I - uint8_t n = Wire.read(); - uint8_t r = Wire.read(); - uint8_t g = Wire.read(); - uint8_t b = Wire.read(); - uint8_t intensity = Wire.read(); - if (n < pixelCount) { - strip.setPixelColor(n, strip.Color(r * intensity / 255, g * intensity / 255, b * intensity / 255)); - strip.show(); - } - } -} +void handleCommand(int numBytes); +void saveConfig(); +void loadConfig(); +void updateStrip(); void setup() { + Serial.begin(115200); + EEPROM.begin(sizeof(Config)); + loadConfig(); + + strip = Adafruit_NeoPixel(config.ledCount, LED_PIN, NEO_GRB + NEO_KHZ800); strip.begin(); - strip.show(); - Wire.begin(I2C_DEV_ADDR, 8, 9); // ESP32-S3 default I2C pins: SDA=8, SCL=9 - Wire.onReceive(receiveEvent); + strip.setBrightness(config.brightness); + strip.show(); // Initialize all off + + Wire.onReceive(handleCommand); + Wire.onRequest([]() { + String response = String(config.address) + ",LED-Strip," + + config.deviceName + "," + + String(config.ledCount) + "," + + String(config.brightness); + Wire.print(response); + }); + + Wire.begin(config.address); } -void loop() { - delay(100); // Main loop delay, not critical +void loop() { /* Empty */ } + +void handleCommand(int numBytes) { + uint8_t cmd = Wire.read(); + + switch(cmd) { + case 0xA0: // Set individual pixel + if(numBytes >= 5) { + uint8_t pixel = Wire.read(); + uint8_t r = Wire.read(); + uint8_t g = Wire.read(); + uint8_t b = Wire.read(); + + if(pixel < config.ledCount) { + strip.setPixelColor(pixel, strip.Color(r, g, b)); + updateStrip(); + } + } + break; + + case 0xA1: // Set all pixels + if(numBytes >= 4) { + uint8_t r = Wire.read(); + uint8_t g = Wire.read(); + uint8_t b = Wire.read(); + + for(int i=0; i= 2) { + config.brightness = Wire.read(); + strip.setBrightness(config.brightness); + saveConfig(); + updateStrip(); + } + break; + + case 0xB0: // Clear all + strip.clear(); + updateStrip(); + break; + + case 0xC0: // Set address + if(numBytes >= 2) { + config.address = Wire.read(); + saveConfig(); + Wire.begin(config.address); + } + break; + + case 0xD0: // Set LED count + if(numBytes >= 3) { + config.ledCount = Wire.read() << 8; + config.ledCount |= Wire.read(); + saveConfig(); + strip.updateLength(config.ledCount); + updateStrip(); + } + break; + } +} + +void updateStrip() { + strip.show(); +} + +void loadConfig() { + EEPROM.get(0, config); + if(config.address < 0x08 || config.address > 0x77) { + config.address = DEFAULT_ADDRESS; + config.ledCount = DEFAULT_LED_COUNT; + config.brightness = 255; + strcpy(config.deviceName, "LED Controller"); + saveConfig(); + } +} + +void saveConfig() { + EEPROM.put(0, config); + EEPROM.commit(); } diff --git a/src/I2CCommands.h b/src/I2CCommands.h deleted file mode 100644 index 2ae5463..0000000 --- a/src/I2CCommands.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef I2C_COMMANDS_H -#define I2C_COMMANDS_H - -#define CMD_CHANGE_ADDR 0xAA // Use the same value as in your slave - -#endif diff --git a/src/I2CMasterUtils.cpp b/src/I2CMasterUtils.cpp deleted file mode 100644 index b8b04c4..0000000 --- a/src/I2CMasterUtils.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#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; -} diff --git a/src/I2CMasterUtils.h b/src/I2CMasterUtils.h deleted file mode 100644 index 5be05b9..0000000 --- a/src/I2CMasterUtils.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef I2CMASTERUTILS_H -#define I2CMASTERUTILS_H - -#include -#include - -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