Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 8,445
» Latest member: silloka9
» Forum threads: 3,702
» Forum posts: 19,058

Full Statistics

Online Users
There are currently 30 online users.
» 0 Member(s) | 17 Guest(s)
AhrefsBot, Amazonbot, Bing, Crawl, Google, PetalBot, bot

Latest Threads
KC868-E16T added Tuya mod...
Forum: KC868-E16T
Last Post: admin
1 hour ago
» Replies: 8
» Views: 1,693
N20 CT Shorting terminal ...
Forum: N20
Last Post: admin
1 hour ago
» Replies: 3
» Views: 47
Problem with KCS flash af...
Forum: "KCS" v2 firmware system
Last Post: tidek1507
Today, 12:39 AM
» Replies: 4
» Views: 29
Bulk IFTTT mapping
Forum: "KCS" v3 firmware
Last Post: admin
Today, 12:18 AM
» Replies: 1
» Views: 16
flash kc868-a4
Forum: KC868-A series and Uair Smart Controller
Last Post: Michel.nadin
Yesterday, 03:24 PM
» Replies: 21
» Views: 687
KC868-A16 ethernet work w...
Forum: KC868-A16
Last Post: Konstantin
Yesterday, 12:18 PM
» Replies: 17
» Views: 16,172
E16P Case / Cover
Forum: KC868-E16S/E16P
Last Post: admin
Yesterday, 01:38 AM
» Replies: 1
» Views: 14
B8M Schematic
Forum: B8M
Last Post: admin
Yesterday, 01:37 AM
» Replies: 5
» Views: 41
"KCS" v3.19.0 firmware BI...
Forum: "KCS" v3 firmware
Last Post: admin
Yesterday, 01:36 AM
» Replies: 2
» Views: 145
F32 and 433 Mhz
Forum: F32
Last Post: admin
01-15-2026, 11:25 PM
» Replies: 3
» Views: 16

  [arduino code examples for DM16]-09 how to communication with Tuya WiFi module
Posted by: admin - 09-09-2025, 03:34 AM - Forum: DM16 - No Replies

Code:
/*
* Made by KinCony IoT: https://www.kincony.com
*
* This Arduino program implements communication between ESP32 and the Tuya module
* via UART (serial communication). It listens for specific packets from the Tuya module
* and responds according to the predefined commands.
*
* Functionality:
* 1. When the ESP32 receives a heartbeat packet (55 AA 00 00 00 00 FF),
*    it sends a heartbeat response (55 AA 03 00 00 01 00 03).
* 2. When the ESP32 receives a product information request (55 AA 00 01 00 00 00),
*    it sends a product information response (55 AA 03 01 ...).
* 3. When the ESP32 receives a work mode request (55 AA 00 02 00 00 01),
*    it sends a work mode response (55 AA 03 02 00 03 10 1C 14 47).
* 4. When the ESP32 receives a network status request (55 AA 00 03 00 01 00 03),
*    it sends a network status response (55 AA 03 03 00 00 05).
* 5. Subsequent heartbeat packets (55 AA 00 00 00 00 FF) are responded to with
*    (55 AA 03 00 00 01 01 04).
*/

#include <HardwareSerial.h>

// Create a HardwareSerial object for UART communication on ESP32
HardwareSerial tuyaSerial(1);

// Define the GPIO pins for TXD and RXD used for serial communication
#define TXD_PIN 16
#define RXD_PIN 17

// Set the baud rate for Tuya module communication to 9600
#define BAUD_RATE 9600

// Define the response packets for different commands from the Tuya module

// Heartbeat response: 55 AA 03 00 00 01 00 03
uint8_t heartBeatResponse[] = {0x55, 0xAA, 0x03, 0x00, 0x00, 0x01, 0x00, 0x03};

// Product info response with a detailed payload (e.g., firmware version, product name, etc.)
uint8_t productInfoResponse[] = {
  0x55, 0xAA, 0x03, 0x01, 0x00, 0x2A, 0x7B, 0x22, 0x70, 0x22, 0x3A, 0x22,
  0x63, 0x68, 0x6D, 0x7A, 0x6C, 0x67, 0x6A, 0x70, 0x61, 0x64, 0x70, 0x71,
  0x78, 0x64, 0x6B, 0x6F, 0x22, 0x2C, 0x22, 0x76, 0x22, 0x3A, 0x22, 0x31,
  0x2E, 0x30, 0x2E, 0x30, 0x22, 0x2C, 0x22, 0x6D, 0x22, 0x3A, 0x30, 0x7D, 0xAA
};

// Work mode response: 55 AA 03 02 00 03 10 1C 14 47
uint8_t workModeResponse[] = {0x55, 0xAA, 0x03, 0x02, 0x00, 0x03, 0x10, 0x1C, 0x14, 0x47};

// Network status response: 55 AA 03 03 00 00 05
uint8_t netStatusResponse[] = {0x55, 0xAA, 0x03, 0x03, 0x00, 0x00, 0x05};

// Subsequent heartbeat response: 55 AA 03 00 00 01 01 04
uint8_t secondHeartBeatResponse[] = {0x55, 0xAA, 0x03, 0x00, 0x00, 0x01, 0x01, 0x04};

void setup() {
  // Initialize the serial communication for debugging at 115200 baud rate
  Serial.begin(115200);

  // Initialize the serial communication with Tuya module at 9600 baud rate
  tuyaSerial.begin(BAUD_RATE, SERIAL_8N1, RXD_PIN, TXD_PIN);

  // Debug message to indicate that the serial communication has been initialized
  Serial.println("ESP32-Tuya serial communication initialized.");
}

void loop() {
  // Check if data is available from the Tuya module
  if (tuyaSerial.available()) {
    uint8_t incomingPacket[7];  // Array to store the received packet
    size_t bytesRead = tuyaSerial.readBytes(incomingPacket, 7); // Read 7 bytes from Tuya

    // Check if the packet has a valid header (0x55, 0xAA)
    if (bytesRead >= 2 && incomingPacket[0] == 0x55 && incomingPacket[1] == 0xAA) {
      // If less than 7 bytes were received, wait for more data
      if (bytesRead < 7) {
        Serial.println("Incomplete packet received. Waiting for remaining bytes...");
        delay(50); // Delay to allow more data to be received
        while (tuyaSerial.available()) {
          incomingPacket[bytesRead++] = tuyaSerial.read(); // Continue reading remaining bytes
          if (bytesRead >= 7) break;
        }
      }

      // If still less than 7 bytes, discard the incomplete packet
      if (bytesRead < 7) {
        Serial.println("Error: Incomplete packet discarded.");
        return;
      }

      // Debug: Print the received packet for logging
      Serial.print("Received packet: ");
      for (size_t i = 0; i < 7; i++) {
        Serial.print(incomingPacket[i], HEX);
        Serial.print(" ");
      }
      Serial.println();

      // Call the function to process the received packet
      processTuyaPacket(incomingPacket, 7);

    } else {
      // If the header is invalid, discard the packet and flush the buffer
      Serial.print("Error: Invalid packet header. Data received: ");
      for (size_t i = 0; i < bytesRead; i++) {
        Serial.print(incomingPacket[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
      tuyaSerial.flush(); // Clear the serial buffer
    }
  }

  // Delay to avoid CPU overuse
  delay(100);
}

// Function to process the received packet and send the appropriate response
void processTuyaPacket(uint8_t* packet, size_t size) {
  // Ensure the packet size is 7 and the header is valid
  if (size == 7 && packet[0] == 0x55 && packet[1] == 0xAA) {
    // Determine the command in the packet (packet[2])
    switch(packet[2]) {
      case 0x00:
        if (packet[3] == 0x00 && packet[4] == 0x00 && packet[5] == 0x00 && packet[6] == 0xFF) {
          Serial.println("Heartbeat received.");
          sendPacket(heartBeatResponse, sizeof(heartBeatResponse));
        } else if (packet[3] == 0x01 && packet[4] == 0x00 && packet[5] == 0x00 && packet[6] == 0x00) {
          Serial.println("Product info request received.");
          sendPacket(productInfoResponse, sizeof(productInfoResponse));
        } else if (packet[3] == 0x02 && packet[4] == 0x00 && packet[5] == 0x00 && packet[6] == 0x01) {
          Serial.println("Work mode request received.");
          sendPacket(workModeResponse, sizeof(workModeResponse));
        } else if (packet[3] == 0x03 && packet[4] == 0x00 && packet[5] == 0x01 && packet[6] == 0x00) {
          Serial.println("Network status request received.");
          sendPacket(netStatusResponse, sizeof(netStatusResponse));
        }
        break;

      default:
        Serial.println("Error: Unhandled command received.");
        break;
    }
  }
}

// Function to send the response packet to the Tuya module
void sendPacket(uint8_t* packet, size_t size) {
  // Send the packet via UART to Tuya module
  tuyaSerial.write(packet, size);

  // Debug: Print the sent packet for logging
  Serial.print("Sent packet: ");
  for (size_t i = 0; i < size; i++) {
    Serial.print(packet[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}
arduino ino file download:

.zip   9-tuya-wifi-config.zip (Size: 2 KB / Downloads: 242)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download: 

.zip   9-tuya-wifi-config.ino.merged.zip (Size: 184.93 KB / Downloads: 229)

Print this item

  [arduino code examples for DM16]-08 Ethernet W5500 chip work with TCP Server mode
Posted by: admin - 09-09-2025, 03:32 AM - Forum: DM16 - No Replies

Code:
/*
* Made by KinCony IoT: https://www.kincony.com
*
* This Arduino program sets up an ESP32-S3 with a W5500 Ethernet module
* as a TCP server. It listens on port 4196 and echoes back any string
* received from a client.
*
* Hardware connections:
* - CLK: GPIO1
* - MOSI: GPIO2
* - MISO: GPIO41
* - CS: GPIO42
* - RST: GPIO44
* - INT: GPIO43
*
* Static IP address: 192.168.3.55
* Subnet Mask: 255.255.255.0
* Gateway: 192.168.3.1
* DNS: 192.168.3.1
*/

#include <SPI.h>
#include <Ethernet.h>

// Define the W5500 Ethernet module pins
#define W5500_CS_PIN  42
#define W5500_RST_PIN 44
#define W5500_INT_PIN 43
#define W5500_CLK_PIN 1
#define W5500_MOSI_PIN 2
#define W5500_MISO_PIN 41

// MAC address for your Ethernet shield (must be unique on your network)
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// Static IP address configuration
IPAddress ip(192, 168, 3, 55);       // Static IP address
IPAddress subnet(255, 255, 255, 0);   // Subnet mask
IPAddress gateway(192, 168, 3, 1);    // Default gateway
IPAddress dns(192, 168, 3, 1);        // DNS server address

// Create an EthernetServer object to handle TCP connections
EthernetServer server(4196);

void setup() {
  // Initialize serial communication
  Serial.begin(115200);
  while (!Serial) {
    ; // Wait for serial port to connect
  }

  // Initialize the W5500 module
  pinMode(W5500_RST_PIN, OUTPUT);
  pinMode(W5500_INT_PIN, INPUT);
  digitalWrite(W5500_RST_PIN, LOW);  // Reset the W5500 module
  delay(100);                       // Wait for reset to complete
  digitalWrite(W5500_RST_PIN, HIGH); // Release reset

  // Initialize SPI with the correct pin definitions
  SPI.begin(W5500_CLK_PIN, W5500_MISO_PIN, W5500_MOSI_PIN);

  // Set up the Ethernet library with W5500-specific pins
  Ethernet.init(W5500_CS_PIN);

  // Start the Ethernet connection with static IP configuration
  Ethernet.begin(mac, ip, dns, gateway, subnet);

  // Print the IP address to the serial monitor
  Serial.print("IP Address: ");
  Serial.println(Ethernet.localIP());

  // Start listening for incoming TCP connections
  server.begin();
}

void loop() {
  // Check for incoming client connections
  EthernetClient client = server.available();
  if (client) {
    Serial.println("New client connected");

    // Read data from the client and echo it back
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        server.write(c);
      }
    }

    // Close the connection when done
    client.stop();
    Serial.println("Client disconnected");
  }
}
arduino ino file download:

.zip   8-Ethernet-W5500.zip (Size: 1.23 KB / Downloads: 222)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download: 

.zip   8-Ethernet-W5500.ino.merged.zip (Size: 188.93 KB / Downloads: 247)

Print this item

  [arduino code examples for DM16]-07 how to DS3231 RTC clock
Posted by: admin - 09-09-2025, 03:31 AM - Forum: DM16 - No Replies

Code:
/*
* Made by KinCony IoT: https://www.kincony.com
*
* DS3231 RTC with Arduino
*
* This program demonstrates how to use the DS3231 RTC (Real-Time Clock) module with the Arduino.
* It includes functionality to:
* - Initialize the DS3231 RTC module
* - Read the current date and time from the RTC
* - Set the RTC time based on a serial command:Command format: DYYYY-MM-DDTHH:MM:SS
*    Set date and time command example: D2024-09-19T11:50:22
*    print current date and time command: current time
*
*
* Hardware Connections:
* - SDA: GPIO 8
* - SCL: GPIO 18
*/

#include <DS3231.h>
#include <Wire.h>

String serial_cmd_rcv = ""; // Serial port receiver

typedef struct
{
  byte year;    // Last two digits of the year, library adds 2000.
  byte month;
  byte day;
  byte hour;
  byte minute;
  byte second;
} MY_DATE_STR;

MY_DATE_STR my_date_str = {0};

// Define constants for relay control
#define OPEN_RLY_DATA    26
#define OPEN_RLY_MONTH   4
#define CLOSE_RLY_DATA   2
#define CLOSE_RLY_MONTH  5

// Define pin connections
#define SDA_PIN   8
#define SCL_PIN   18

DS3231 rtc; // Create an instance of the DS3231 RTC
bool h12Flag;
bool pmFlag;
static bool bCentury = false;
static bool old_level_high = false;
static bool old_level_low = false;


/**
* @brief Print the current time from the RTC to the Serial Monitor.
*/
static void PrintfCurTime()
{
  Serial.print("Current time is: ");
  int year = rtc.getYear() + 2000;
  Serial.print(year);
  Serial.print("-");

  Serial.print(rtc.getMonth(bCentury), DEC);
  Serial.print("-");

  Serial.print(rtc.getDate(), DEC);
  Serial.print(" ");

  Serial.print(rtc.getHour(h12Flag, pmFlag), DEC);
  Serial.print(":");
  Serial.print(rtc.getMinute(), DEC);
  Serial.print(":");
  Serial.println(rtc.getSecond(), DEC);
}

/**
* @brief Process serial commands to set the RTC time.
* Command format: DYYYY-MM-DDTHH:MM:SS
*/
static void GetSerialCmd()
{
  if (Serial.available() > 0)
  {
    delay(100);
    int num_read = Serial.available();
    while (num_read--)
      serial_cmd_rcv += char(Serial.read());
  }
  else return;

  serial_cmd_rcv.trim();

  if (serial_cmd_rcv == "current time")
  {
    PrintfCurTime();
    serial_cmd_rcv = "";
    return;
  }

  Serial.print("Received length: ");
  Serial.println(serial_cmd_rcv.length());

  int indexof_d = serial_cmd_rcv.indexOf('D');
  int indexof_t = serial_cmd_rcv.indexOf('T');

  Serial.print("D index: ");
  Serial.print(indexof_d);
  Serial.print(" T index: ");
  Serial.println(indexof_t);

  if (serial_cmd_rcv.length() != 20 ||
      serial_cmd_rcv.substring(0, 1) != "D" ||
      serial_cmd_rcv.substring(11, 12) != "T") 
  {
    Serial.println(serial_cmd_rcv);
    serial_cmd_rcv = "";
    return;
  }

  Serial.println("Setting time...");

  my_date_str.year = (byte)serial_cmd_rcv.substring(3, 5).toInt();
  my_date_str.month = (byte)serial_cmd_rcv.substring(6, 8).toInt();
  my_date_str.day = (byte)serial_cmd_rcv.substring(9, 11).toInt();
  my_date_str.hour = (byte)serial_cmd_rcv.substring(12, 14).toInt();
  my_date_str.minute = (byte)serial_cmd_rcv.substring(15, 17).toInt();
  my_date_str.second = (byte)serial_cmd_rcv.substring(18).toInt();

  rtc.setYear(my_date_str.year);
  rtc.setMonth(my_date_str.month);
  rtc.setDate(my_date_str.day);
  rtc.setHour(my_date_str.hour);
  rtc.setMinute(my_date_str.minute);
  rtc.setSecond(my_date_str.second);

  serial_cmd_rcv = "";

  Serial.println("Time set.");
}

void setup() {
  // Initialize the I2C interface
  Wire.begin(SDA_PIN, SCL_PIN, 40000);
 
  // Initialize Serial communication
  Serial.begin(115200);
   
  // Set the RTC to 24-hour mode
  rtc.setClockMode(false); // 24-hour format

  // Print current time to Serial Monitor
  PrintfCurTime();

  // Clear any remaining serial data
  while (Serial.read() >= 0) {}
}

void loop() {
  // Process incoming serial commands
  GetSerialCmd();
  delay(1000); // Delay for 1 second
}
arduino ino file download:

.zip   7-DS3231-RTC.zip (Size: 1.56 KB / Downloads: 221)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download: 

.zip   7-DS3231-RTC.ino.merged.zip (Size: 191.08 KB / Downloads: 228)

Print this item

  [arduino code examples for DM16]-06 How to use SD Card
Posted by: admin - 09-09-2025, 03:01 AM - Forum: DM16 - No Replies

Code:
/*
* Made by KinCony IoT: https://www.kincony.com
*
* SD Card File Operations
*
* This program demonstrates basic file operations on an SD card using the ESP32.
* It includes functionality to:
* - Initialize and test the SD card
* - Read from, write to, append to, and delete files on the SD card
* - Measure file read and write performance
*
* Hardware Connections:
* - SCK: GPIO 11
* - MISO: GPIO 12
* - MOSI: GPIO 10
* - CS: GPIO 9
*/

#include "FS.h"
#include "SD.h"
#include "SPI.h"

// Pin definitions for SD card
#define SCK  11
#define MISO 12
#define MOSI 10
#define CS   9

/**
* @brief Reads the contents of a file from the SD card and prints it to the serial monitor.
*
* @param fs File system to use (in this case, SD).
* @param path Path of the file to read.
*/
void readFile(fs::FS &fs, const char * path) {
  Serial.printf("Reading file: %s\n", path);

  File file = fs.open(path);
  if (!file) {
    Serial.println("Failed to open file for reading");
    return;
  }

  Serial.print("Read from file: ");
  while (file.available()) {
    Serial.print((char)file.read());
  }
  file.close();
}

/**
* @brief Writes a message to a file on the SD card.
*
* @param fs File system to use (in this case, SD).
* @param path Path of the file to write.
* @param message Message to write to the file.
*/
void writeFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  if (file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}

/**
* @brief Appends a message to a file on the SD card.
*
* @param fs File system to use (in this case, SD).
* @param path Path of the file to append.
* @param message Message to append to the file.
*/
void appendFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

/**
* @brief Deletes a file from the SD card.
*
* @param fs File system to use (in this case, SD).
* @param path Path of the file to delete.
*/
void deleteFile(fs::FS &fs, const char * path) {
  Serial.printf("Deleting file: %s\n", path);
  if (fs.remove(path)) {
    Serial.println("File deleted");
  } else {
    Serial.println("Delete failed");
  }
}

/**
* @brief Tests file read and write performance.
*
* @param fs File system to use (in this case, SD).
* @param path Path of the file to test.
*/
void testFileIO(fs::FS &fs, const char * path) {
  File file = fs.open(path);
  static uint8_t buf[512];
  size_t len = 0;
  uint32_t start = millis();
  uint32_t end = start;

  if (file) {
    len = file.size();
    size_t flen = len;
    start = millis();
    while (len) {
      size_t toRead = len;
      if (toRead > 512) {
        toRead = 512;
      }
      file.read(buf, toRead);
      len -= toRead;
    }
    end = millis() - start;
    Serial.printf("%u bytes read for %u ms\n", flen, end);
    file.close();
  } else {
    Serial.println("Failed to open file for reading");
  }

  file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }

  size_t i;
  start = millis();
  for (i = 0; i < 2048; i++) {
    file.write(buf, 512);
  }
  end = millis() - start;
  Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
  file.close();
}

void setup() {
  // Initialize serial communication
  Serial.begin(115200);
 
  // Initialize SPI and SD card
  SPIClass spi = SPIClass(HSPI);
  spi.begin(SCK, MISO, MOSI, CS);

  if (!SD.begin(CS, spi, 80000000)) {
    Serial.println("Card Mount Failed");
    return;
  }

  uint8_t cardType = SD.cardType();

  if (cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }

  Serial.print("SD Card Type: ");
  if (cardType == CARD_MMC) {
    Serial.println("MMC");
  } else if (cardType == CARD_SD) {
    Serial.println("SDSC");
  } else if (cardType == CARD_SDHC) {
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }

  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);
  delay(2000);

  // Perform file operations
  deleteFile(SD, "/hello.txt");
  writeFile(SD, "/hello.txt", "Hello ");
  appendFile(SD, "/hello.txt", "World!\n");
  readFile(SD, "/hello.txt");
  testFileIO(SD, "/test.txt");
  Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
  Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));
}

void loop() {
  // No operation in loop
}
arduino ino file download:

.zip   6-SD.zip (Size: 1.53 KB / Downloads: 222)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download: 

.zip   6-SD.ino.merged.zip (Size: 221.25 KB / Downloads: 211)

Print this item

  [arduino code examples for DM16]-05 Read free GPIO state
Posted by: admin - 09-09-2025, 03:00 AM - Forum: DM16 - No Replies

Code:
/*
* Made by KinCony IoT: https://www.kincony.com
*
* GPIO Status Monitoring
*
* This program monitors the status (high or low) of multiple GPIO pins on the ESP32-S3.
* It prints the status of the pins to the serial monitor whenever a change is detected.
*
* GPIO Pins Monitored:
* - GPIO 40
* - GPIO 7
* - GPIO 48
* - GPIO 47
* - GPIO 13
* - GPIO 14
* - GPIO 21
* - GPIO 0
*
* Hardware Requirements:
* - Connect the pins to appropriate devices or pull them to HIGH/LOW for testing
*/

#define GPIO_PIN_40 40
#define GPIO_PIN_7 7
#define GPIO_PIN_48 48
#define GPIO_PIN_47 47
#define GPIO_PIN_13 13
#define GPIO_PIN_14 14
#define GPIO_PIN_21 21
#define GPIO_PIN_0 0

// Store the previous state of the GPIO pins
bool prevState[8] = {false, false, false, false, false, false, false, false};

void setup() {
  // Initialize serial communication for debugging purposes
  Serial.begin(115200); // Initialize the serial monitor at 115200 baud
  while (!Serial);      // Wait for the serial monitor to open

  // Initialize GPIO pins as inputs
  pinMode(GPIO_PIN_40, INPUT);
  pinMode(GPIO_PIN_7, INPUT);
  pinMode(GPIO_PIN_48, INPUT);
  pinMode(GPIO_PIN_47, INPUT);
  pinMode(GPIO_PIN_13, INPUT);
  pinMode(GPIO_PIN_14, INPUT);
  pinMode(GPIO_PIN_21, INPUT);
  pinMode(GPIO_PIN_0, INPUT);

  Serial.println("GPIO Status Monitoring Started");
}

void loop() {
  // Read the current state of each GPIO pin
  bool currentState[8];
  currentState[0] = digitalRead(GPIO_PIN_40);
  currentState[1] = digitalRead(GPIO_PIN_7);
  currentState[2] = digitalRead(GPIO_PIN_48);
  currentState[3] = digitalRead(GPIO_PIN_47);
  currentState[4] = digitalRead(GPIO_PIN_13);
  currentState[5] = digitalRead(GPIO_PIN_14);
  currentState[6] = digitalRead(GPIO_PIN_21);
  currentState[7] = digitalRead(GPIO_PIN_0);

  // Check for changes in GPIO pin states
  for (int i = 0; i < 8; i++) {
    if (currentState[i] != prevState[i]) {
      // Print the pin number and its new state if it has changed
      Serial.print("GPIO ");
      Serial.print(i == 0 ? GPIO_PIN_40 :
                   i == 1 ? GPIO_PIN_7 :
                   i == 2 ? GPIO_PIN_48 :
                   i == 3 ? GPIO_PIN_47 :
                   i == 4 ? GPIO_PIN_13 :
                   i == 5 ? GPIO_PIN_14 :
                   i == 6 ? GPIO_PIN_21 : GPIO_PIN_0);
      Serial.print(" changed to ");
      Serial.println(currentState[i] ? "HIGH" : "LOW");
      // Update the previous state
      prevState[i] = currentState[i];
    }
  }

  // Delay to avoid flooding the serial monitor
  delay(100); // Adjust the delay as needed
}
arduino ino file download:

.zip   5-free-gpio-state.zip (Size: 1.04 KB / Downloads: 212)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download: 

.zip   5-free-gpio-state.ino.merged.zip (Size: 179.57 KB / Downloads: 198)

Print this item

  [arduino code examples for DM16]-04 RS485 communication test
Posted by: admin - 09-09-2025, 02:59 AM - Forum: DM16 - No Replies

Code:
/*
* Made by KinCony IoT: https://www.kincony.com
*
* RS485 Communication Test
*
* This program is a simple test for RS485 communication using ESP32-S3.
* It will send a message over RS485 and then read incoming messages.
* The TXD pin is defined as GPIO 18 and RXD pin is defined as GPIO 8.
*/

#include <HardwareSerial.h>

// Define RS485 pins
#define RS485_RXD 38
#define RS485_TXD 39

// Create a hardware serial object
HardwareSerial rs485Serial(1);

void setup() {
  // Start serial communication for debugging
  Serial.begin(115200);
  while (!Serial);

  // Initialize RS485 Serial communication
  rs485Serial.begin(9600, SERIAL_8N1, RS485_RXD, RS485_TXD);
 
  Serial.println("RS485 Test Start");
}

void loop() {
  // Send a test message
  rs485Serial.println("Hello from KinCony B16!");

  // Wait for a short period
  delay(1000);

  // Check if data is available to read
  if (rs485Serial.available()) {
    String receivedMessage = "";
    while (rs485Serial.available()) {
      char c = rs485Serial.read();
      receivedMessage += c;
    }
    // Print the received message
    Serial.print("Received: ");
    Serial.println(receivedMessage);
  }

  // Wait before sending the next message
  delay(2000);
}
arduino ino file download:

.zip   4-RS485-Test.zip (Size: 763 bytes / Downloads: 207)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download: 

.zip   4-RS485-Test.ino.merged.zip (Size: 184.34 KB / Downloads: 245)

Print this item

  [arduino code examples for DM16]-03 Read ADS1115 analog input ports value
Posted by: admin - 09-09-2025, 02:53 AM - Forum: DM16 - No Replies

Code:
/*
* This program reads voltage values from the ADS1115 analog-to-digital converter
* on all four channels (A0, A1, A2, A3) and prints the results through the serial port.
* The ADS1115 communicates via the I2C protocol. This version of the code includes
* the capability to specify custom SDA and SCL pins for I2C communication.
*
* Copyright: Made by KinCony IoT: https://www.kincony.com
*
*/

#include <Wire.h>                // Library for I2C communication
#include <DFRobot_ADS1115.h>     // Library for ADS1115 ADC module

// Define the I2C SDA and SCL pins for communication with ADS1115
#define SDA_PIN 8 
#define SCL_PIN 18

// Initialize ADS1115 instance using the Wire library
DFRobot_ADS1115 ads(&Wire);

void setup(void)
{
    // Begin serial communication at a baud rate of 115200
    Serial.begin(115200);

    // Initialize the I2C bus using the defined SDA and SCL pins
    Wire.begin(SDA_PIN, SCL_PIN);

    // Set the I2C address for the ADS1115 (default: 0x49)
    ads.setAddr_ADS1115(ADS1115_IIC_ADDRESS0);   // Address is 0x49

    // Set the gain for the ADS1115 (2/3x gain allows for a maximum input voltage of 6.144V)
    ads.setGain(eGAIN_TWOTHIRDS);

    // Set the ADS1115 to operate in single-shot mode (each reading is a single conversion)
    ads.setMode(eMODE_SINGLE);

    // Set the sample rate to 128 samples per second (SPS)
    ads.setRate(eRATE_128);

    // Set the operational status mode to single-conversion start
    ads.setOSMode(eOSMODE_SINGLE);

    // Initialize the ADS1115 module
    ads.init();
}

void loop(void)
{
    // Check if the ADS1115 is properly connected and functioning
    if (ads.checkADS1115())
    {
        // Variables to store the voltage readings for each channel
        int16_t adc0, adc1, adc2, adc3;

        // Read the voltage from channel A0 and print the value
        adc0 = ads.readVoltage(0);
        Serial.print("A0:");
        Serial.print(adc0);
        Serial.print("mV,  ");    // Print the value in millivolts

        // Read the voltage from channel A1 and print the value
        adc1 = ads.readVoltage(1);
        Serial.print("A1:");
        Serial.print(adc1);
        Serial.print("mV,  ");    // Print the value in millivolts

        // Read the voltage from channel A2 and print the value
        adc2 = ads.readVoltage(2);
        Serial.print("A2:");
        Serial.print(adc2);
        Serial.print("mV,  ");    // Print the value in millivolts

        // Read the voltage from channel A3 and print the value
        adc3 = ads.readVoltage(3);
        Serial.print("A3:");
        Serial.print(adc3);
        Serial.println("mV");     // Print the value in millivolts and end the line
    }
    else
    {
        // If ADS1115 is not connected, print a message indicating disconnection
        Serial.println("ADS1115 Disconnected!");
    }

    // Wait for 1 second before the next loop iteration
    delay(1000);
}
arduino ino file download:

.zip   3-ads1115_adc.zip (Size: 1.2 KB / Downloads: 193)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download: 

.zip   3-ads1115_adc.ino.merged.zip (Size: 190.05 KB / Downloads: 204)

Print this item

  [arduino code examples for DM16]-02 Read digital input ports state
Posted by: admin - 09-09-2025, 02:51 AM - Forum: DM16 - No Replies

Code:
/*
* -----------------------------------------------------------------------------
* KinCony DM16 16-Channel Digital Input Reader using PCF8575
*
* This Arduino sketch reads the state of 16 digital input channels from a
* PCF8575 I/O expander over I2C and prints their status to the serial monitor.
*
* Input logic:
*   - Input 0 = ON
*   - Input 1 = OFF (with pull-up logic)
*
* Hardware:
*   - PCF8575 I/O Expander (I2C Address: 0x22)
*   - Custom input pin mapping as defined below
*   - I2C SDA pin: GPIO8
*   - I2C SCL pin: GPIO18
*
* Author: KinCony IoT
* Website: https://www.kincony.com
* License: MIT License
* -----------------------------------------------------------------------------
*/

#include <Wire.h>
#include "PCF8575.h"

// Define I2C pins
#define I2C_SDA 8   // SDA pin
#define I2C_SCL 18  // SCL pin

// Set the I2C address for PCF8575
PCF8575 pcf8575_IN1(0x22); // 0x22 is the I2C address for the DM16 module

void setup() {
    Serial.begin(115200);

    // Initialize I2C with specified SDA and SCL pins
    Wire.begin(I2C_SDA, I2C_SCL);

    // Start communication with PCF8575 device
    pcf8575_IN1.begin();

    Serial.println("KinCony DM16 16 channel input state 0:ON  1:OFF");
}

void loop() {
    // Define custom pin read order to match hardware mapping
    uint8_t pin_order[16] = {
        8, 9, 10, 11, 12, 13, 14, 15,
        0, 1, 2, 3, 4, 5, 6, 7
    };

    Serial.print("Input state: ");

    // Loop through all 16 pins and read their state
    for (int i = 0; i < 16; i++) {
        bool state = pcf8575_IN1.read(pin_order[i]); // Read pin state (HIGH or LOW)
        Serial.print(state); // Print state: 0 = ON, 1 = OFF
        Serial.print(" ");
    }

    Serial.println(); // Print new line
    delay(500);       // Wait for 500ms before next read
}
arduino ino file download:

.zip   2-digital-input.zip (Size: 995 bytes / Downloads: 218)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download: 

.zip   2-digital-input.ino.merged.zip (Size: 192.34 KB / Downloads: 213)

Print this item

  [arduino code examples for DM16]-01 16 Channel DAC output by digital input
Posted by: admin - 09-09-2025, 02:49 AM - Forum: DM16 - No Replies

Code:
#include <Adafruit_PCF8575.h>
#include <HardwareSerial.h>

// Define Modbus RTU frame format constants
#define MODBUS_READ_COILS 0x01
#define MODBUS_READ_REGISTERS 0x03
#define MODBUS_WRITE_SINGLE_REGISTER 0x06
#define MODBUS_WRITE_MULTIPLE_REGISTERS 0x10

/* Example for 16 input buttons that are connected from the GPIO expander pins to ground.
* Note the buttons must be connected with the other side of the switch to GROUND. There is
* a built in pull-up 'resistor' on each input, but no pull-down resistor capability.
*/

#define DM_NUMS 16 // change for 16, 32 for KinCony DM16, DM32 Smart Dimmer Controller


#define SDA_PIN 8
#define SCL_PIN 18
#define ADDRESS_PCF8575     0x22
#define ADDRESS_PCF8575_2   0x24

#define ST_RX   4 ////ESP32_RCV
#define ST_TX   6 ///ESP32_SEND
typedef enum{KEY_RELEASE=0,KEY_SHORT_PRESSED,KEY_LONG_PRESSED}KEY_STATUS;

typedef struct{
  uint8_t key_index;
  KEY_STATUS key_status;
  long key_time_start;
  long key_time_rec;
  long key_press_time;
  int16_t key_press_cnt; ////Send serial data once every 100 ms
  int16_t key_press_cnt_old;
  float current_light; ///Percentage of 0–4095
}KEY_PRESS_PROP;

KEY_PRESS_PROP key_press_prop[32] = {0};


Adafruit_PCF8575 pcf,pcf2;
HardwareSerial myst_serial(1);

TwoWire myI2c = TwoWire(0);
ushort dm_num = DM_NUMS;

// Modbus CRC16 Calculation function
uint16_t modbus_crc16(uint8_t *data, uint16_t length) {
  uint16_t crc = 0xFFFF;
 
  for (uint16_t i = 0; i < length; i++) {
    crc ^= data[i];
    for (uint8_t j = 0; j < 8; j++) {
      if (crc & 0x0001) {
        crc = (crc >> 1) ^ 0xA001;
      } else {
        crc = crc >> 1;
      }
    }
  }
  return crc;
}

/**
* Send a Modbus RTU frame
*
* @param serial HardwareSerial object
* @param address Slave address (1-247)
* @param function function code
* @param data
* @param dataLen
*/
void send_modbus_frame(HardwareSerial &serial, uint8_t address, uint8_t function,
                      const uint8_t *data, uint16_t dataLen) {
  // Create a transmit buffer
  uint16_t totalLen = 1 + 1 + dataLen + 2; // address + function code + data + CRC
  uint8_t buffer[totalLen];
 
  buffer[0] = address;
  buffer[1] = function;
 
  memcpy(&buffer[2], data, dataLen);
 
  uint16_t crc = modbus_crc16(buffer, 2 + dataLen);
 
  // Add CRC (low byte first)
  buffer[2 + dataLen] = crc & 0xFF;      // CRC low byte
  buffer[3 + dataLen] = (crc >> 8) & 0xFF; // CRC high byte
 
  // Send the complete frame
  for (uint16_t i = 0; i < totalLen; i++) {
    serial.write(buffer[i]);
  }
 
  // Flush the transmit buffer to ensure all data is sent
  serial.flush();
}

// Encapsulate commonly used Modbus functions

/**
* Send a Read Holding Registers request
*
* @param serial
* @param address
* @param startReg
* @param numRegs
*/
void modbus_read_registers(HardwareSerial &serial, uint8_t address,
                          uint16_t startReg, uint16_t numRegs) {
  uint8_t data[4];
 
 
  data[0] = (startReg >> 8) & 0xFF; // High byte of the register address
  data[1] = startReg & 0xFF;        // Low byte of the register address
  data[2] = (numRegs >> 8) & 0xFF;  // High byte of the register count
  data[3] = numRegs & 0xFF;         // Low byte of the register count
 
  send_modbus_frame(serial, address, MODBUS_READ_REGISTERS, data, sizeof(data));
}

/**
*
* @param serial
* @param address
* @param regAddress
* @param value
*/
void modbus_write_single_register(HardwareSerial &serial, uint8_t address,
                                uint16_t regAddress, uint16_t value) {
  uint8_t data[4];
 
  data[0] = (regAddress >> 8) & 0xFF; // High byte of the register address
  data[1] = regAddress & 0xFF;        // Low byte of the register address
  data[2] = (value >> 8) & 0xFF;      // High byte of the data
  data[3] = value & 0xFF;             // Low byte of the
 
  send_modbus_frame(serial, address, MODBUS_WRITE_SINGLE_REGISTER, data, sizeof(data));
}

/**
*
* @param serial
* @param address
* @param startReg
* @param values
* @param numRegs
*/
void modbus_write_multiple_registers(HardwareSerial &serial, uint8_t address,
                                   uint16_t startReg, const uint16_t *values,
                                   uint16_t numRegs) {

  uint8_t byteCount = numRegs * 2;
  uint8_t data[5 + byteCount];
 

  data[0] = (startReg >> 8) & 0xFF; 
  data[1] = startReg & 0xFF;         
  data[2] = (numRegs >> 8) & 0xFF;   
  data[3] = numRegs & 0xFF;       
  data[4] = byteCount;             
 

  for (uint8_t i = 0; i < numRegs; i++) {
    data[5 + i*2] = (values[i] >> 8) & 0xFF;   
    data[6 + i*2] = values[i] & 0xFF;         
  }
 
  send_modbus_frame(serial, address, MODBUS_WRITE_MULTIPLE_REGISTERS, data, sizeof(data));
}

void setup() {
  Serial.begin(115200);
  myI2c.begin(SDA_PIN,SCL_PIN,100000);
  myst_serial.begin(115200,SERIAL_8N1,ST_RX,ST_TX);///RXPIN FIRST

  while (!Serial) { delay(10); }
  Serial.println("Adafruit PCF8575 button read test");

  if (!pcf.begin(ADDRESS_PCF8575, &myI2c)) {
    Serial.println("err:DMxx Couldn't find 1_PCF8575!");
    while (1);
  }
  else Serial.println("Find 1_PCF8575!");

  if(dm_num==32)
  {
    if (!pcf2.begin(ADDRESS_PCF8575_2, &myI2c)) {
    Serial.println("DM32 Couldn't find 2_PCF8575");
    }
    else Serial.println("Find 2_PCF8575!");
  }
   

  for (uint8_t p=0; p<DM_NUMS; p++) {
    pcf.pinMode(p, INPUT_PULLUP);
    if(dm_num==32) pcf2.pinMode(p-16, INPUT_PULLUP);
   
    key_press_prop[p].key_index = p+1;
    key_press_prop[p].key_status = KEY_RELEASE;
    key_press_prop[p].key_press_time = 0;
  }

  Serial.println("Now, starting!");


}



static uint16_t input_value_old[2] = {0xffff,0xffff};
uint16_t input_value[2] = {0} ;
int8_t current_operator_key = -1;
int8_t key_index = -1,key_index_last = -1;
int16_t key_press_cnt_old = 0;
uint16_t write_value=0;

static int8_t get_key_press(int8_t chip,uint16_t key_value)
{
  if(key_value == 0xffff || key_value == 0) return -1;

  for(int16_t i=0;i<16;i++)
  {
    if((key_value & (1<<i) ) == 0)  return (chip==0)?i:i+16;
  }
}

static uint16_t getKeycode()
{
  uint16_t input_value = 0,tmp_value;
  uint8_t h_value = 0 ,l_value = 0;
  tmp_value = pcf.digitalReadWord();
  h_value = tmp_value>>8;
  l_value = tmp_value&0xff;
  input_value = (l_value<<8 ) | h_value;

  return input_value;
}

static uint16_t getKeycode2()
{
  uint16_t input_value = 0,tmp_value;
  uint8_t h_value = 0 ,l_value = 0;
  tmp_value = pcf2.digitalReadWord();
  h_value = tmp_value>>8;
  l_value = tmp_value&0xff;
  input_value = (l_value ) | (h_value<<8);

  return input_value;
}

static void checkKeyPress(int8_t chip);

static uint16_t key_old_arr[2] = {0};

void loop() {

  input_value[0] = getKeycode();
  /*if(key_old_arr[0] != input_value[0] )
  {
    key_old_arr[0] = input_value[0];
    Serial.printf("input0:%d\r\n",input_value[0]);
  }*/
 
  checkKeyPress(0);

  if(dm_num == 32)
  {
    delay(10);
    input_value[1] = getKeycode2();
    checkKeyPress(1);
    /*if(key_old_arr[1] != input_value[1] )
    {
      key_old_arr[1] = input_value[1];
      Serial.printf("input1:%d\r\n",input_value[1]);
    }*/
  }
 


  delay(10); // a short debounce delay
}

static void checkKeyPress(int8_t chip)
{
  uint8_t start_index = (chip==0)?0:16;
  if(input_value_old[chip] != input_value[chip])
  {
    input_value_old[chip] = input_value[chip];
    if(input_value[chip] == 0xffff)
    {
      Serial.printf("key is released!");
       
      current_operator_key = -1;
      key_index_last = key_index = -1;

      for (uint8_t p=start_index; p<16+start_index; p++) ///all key status init.
      {
        key_press_prop[p].key_index = p+1;
        key_press_prop[p].key_status = KEY_RELEASE;
        key_press_prop[p].key_time_start = 0;
        key_press_prop[p].key_press_time = 0;
        key_press_prop[p].key_time_rec = 0;
        key_press_prop[p].key_press_cnt = 0;
        key_press_prop[p].key_press_cnt_old = 0;
      }
    }
    else ///key press
    {
      //Serial.printf("input_value = %04X \r\n",input_value);
      key_index = get_key_press(chip,input_value[chip]);
      if(key_index >= 0)
      {
        key_index_last = key_index;
        Serial.printf("key %02d # is pressed! \r\n",key_index+1);
        current_operator_key = key_index;
        key_press_prop[current_operator_key].key_status = KEY_SHORT_PRESSED;
        key_press_prop[current_operator_key].key_time_start = millis();
        key_press_prop[current_operator_key].key_press_time = 0;
      }
    }
  }
  else
  {
    if(input_value[chip] != 0xffff) ///LONG PRESS!
    {
      //Serial.printf("key long pressed! \r\n");

      key_index = get_key_press(chip,input_value[chip]);
      if(key_index >= 0 && key_index_last == key_index)
      {
        //Serial.printf("key long pressed! key_index = %d\r\n",key_index);

        current_operator_key = key_index;
        key_press_prop[current_operator_key].key_status = KEY_LONG_PRESSED;
        key_press_prop[current_operator_key].key_time_rec = millis();
        key_press_prop[current_operator_key].key_press_time = key_press_prop[current_operator_key].key_time_rec - key_press_prop[current_operator_key].key_time_start;
        key_press_prop[current_operator_key].key_press_cnt = (key_press_prop[current_operator_key].key_press_time % 4080 ) / 100; ////100MS发一次

        //Serial.printf("key long time = %d, cnt = %d \r\n",key_press_prop[current_operator_key].key_press_time,key_press_prop[current_operator_key].key_press_cnt);

        if(key_press_prop[current_operator_key].key_press_cnt_old != key_press_prop[current_operator_key].key_press_cnt)
        {
          key_press_prop[current_operator_key].key_press_cnt_old = key_press_prop[current_operator_key].key_press_cnt;
          /////send st_tx information.
          key_press_prop[current_operator_key].current_light = (float)key_press_prop[current_operator_key].key_press_cnt * 100.0f;
          write_value = (uint16_t) key_press_prop[current_operator_key].current_light;

          Serial.printf("key_long_press_time = %d, current_light = %d \r\n",key_press_prop[current_operator_key].key_press_time,write_value);

          modbus_write_multiple_registers(myst_serial,1,4000+current_operator_key,&write_value,1);


        }
      }
    }
  }

}

arduino ino file download:

.zip   1-dac-16ch.zip (Size: 2.95 KB / Downloads: 22)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:

.zip   1-dac-16ch.ino.merged.zip (Size: 205.71 KB / Downloads: 20)

Print this item

  DM16 ESPHome yaml for home assistant with tuya
Posted by: admin - 09-09-2025, 02:39 AM - Forum: DM16 - No Replies

Code:
esphome:
  name: dm16
  friendly_name: dm16
  platformio_options:
    board_build.extra_flags:
      # WIFI_CONTROL_SELF_MODE = 0
      # WIFI_CONTROL_SELF_MODE = 1
      - "-DWIFI_CONTROL_SELF_MODE=1"

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: arduino

external_components:
  - source:
      type: git
      url: https://github.com/hzkincony/esphome-tuya-wifi-mcu
      ref: v1.2.0

# Enable logging
logger:
  baud_rate: 0
  hardware_uart: UART0

# Enable Home Assistant API
api:

ota:
  platform: esphome

web_server:
  port: 80

ethernet:
  type: W5500
  clk_pin: GPIO1
  mosi_pin: GPIO2
  miso_pin: GPIO41
  cs_pin: GPIO42
  interrupt_pin: GPIO43
  reset_pin: GPIO44

i2c:
   - id: bus_a
     sda: 8
     scl: 18
     scan: true
     frequency: 400kHz
     
text_sensor:
  - platform: ethernet_info
    ip_address:
      name: ESP IP Address
      id: eth_ip
      address_0:
        name: ESP IP Address 0
      address_1:
        name: ESP IP Address 1
      address_2:
        name: ESP IP Address 2
      address_3:
        name: ESP IP Address 3
      address_4:
        name: ESP IP Address 4
    dns_address:
      name: ESP DNS Address
    mac_address:
      name: ESP MAC Address

font:
  - file: "gfonts://Roboto"
    id: roboto
    size: 15

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    lambda: |-
      it.printf(0, 15, id(roboto), "IP: %s", id(eth_ip).state.c_str());
uart:
  - id: dac_uart
    rx_pin: 4
    tx_pin: 6
    baud_rate: 115200
    stop_bits: 1
    data_bits: 8
    parity: NONE
  - id: tuya_mcu_uart 
    tx_pin: 16
    rx_pin: 17
    baud_rate: 9600

tuya_wifi_mcu:
  # tuya mcu product id
  product_id: qdmpkznox0g9kkvo
  uart_id: tuya_mcu_uart
  wifi_reset_pin: 28
  wifi_led_pin: 16

modbus:
  - uart_id: dac_uart

modbus_controller:
  - address: 1
    update_interval: 5s

output:
  # CH1 (0x0FA0 / 4000)
  - platform: modbus_controller
    id: dac_ch1_out
    address: 0x0FA0
    value_type: U_WORD
    write_lambda: |-
      // state = 0.0 ~ 1.0 → 0 ~ 4095
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH2 (0x0FA1 / 4001)
  - platform: modbus_controller
    id: dac_ch2_out
    address: 0x0FA1
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH3
  - platform: modbus_controller
    id: dac_ch3_out
    address: 0x0FA2
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH4
  - platform: modbus_controller
    id: dac_ch4_out
    address: 0x0FA3
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH5
  - platform: modbus_controller
    id: dac_ch5_out
    address: 0x0FA4
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH6
  - platform: modbus_controller
    id: dac_ch6_out
    address: 0x0FA5
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH7
  - platform: modbus_controller
    id: dac_ch7_out
    address: 0x0FA6
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH8
  - platform: modbus_controller
    id: dac_ch8_out
    address: 0x0FA7
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH9
  - platform: modbus_controller
    id: dac_ch9_out
    address: 0x0FA8
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH10
  - platform: modbus_controller
    id: dac_ch10_out
    address: 0x0FA9
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH11
  - platform: modbus_controller
    id: dac_ch11_out
    address: 0x0FAA
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH12
  - platform: modbus_controller
    id: dac_ch12_out
    address: 0x0FAB
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH13
  - platform: modbus_controller
    id: dac_ch13_out
    address: 0x0FAC
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH14
  - platform: modbus_controller
    id: dac_ch14_out
    address: 0x0FAD
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH15
  - platform: modbus_controller
    id: dac_ch15_out
    address: 0x0FAE
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

  # CH16
  - platform: modbus_controller
    id: dac_ch16_out
    address: 0x0FAF
    value_type: U_WORD
    write_lambda: |-
      uint16_t reg = (uint16_t) round(x * 4095.0);
      return reg;

# -------------------
# 16 路 Light (调光灯)
# -------------------
light:
  - platform: monochromatic
    name: "DAC CH1"
    output: dac_ch1_out
    id: light_1
    default_transition_length: 0s
 
  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH1"
    # bind other light, sync state
    bind_light_id: light_1
    output: dac_ch1_out
    dp_id: 2
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH2"
    output: dac_ch2_out
    id: light_2
    default_transition_length: 0s
 
  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH2"
    # bind other light, sync state
    bind_light_id: light_2
    output: dac_ch2_out
    dp_id: 8
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH3"
    output: dac_ch3_out
    id: light_3
    default_transition_length: 0s

  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH3"
    # bind other light, sync state
    bind_light_id: light_3
    output: dac_ch3_out
    dp_id: 16
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH4"
    output: dac_ch4_out
    id: light_4
    default_transition_length: 0s
 
  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH4"
    # bind other light, sync state
    bind_light_id: light_4
    output: dac_ch4_out
    dp_id: 101
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH5"
    output: dac_ch5_out
    id: light_5
    default_transition_length: 0s

  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH5"
    # bind other light, sync state
    bind_light_id: light_5
    output: dac_ch5_out
    dp_id: 102
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH6"
    output: dac_ch6_out
    id: light_6
    default_transition_length: 0s

  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH6"
    # bind other light, sync state
    bind_light_id: light_6
    output: dac_ch6_out
    dp_id: 103
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH7"
    output: dac_ch7_out
    id: light_7
    default_transition_length: 0s
 
  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH7"
    # bind other light, sync state
    bind_light_id: light_7
    output: dac_ch7_out
    dp_id: 104
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH8"
    output: dac_ch8_out
    id: light_8
    default_transition_length: 0s
 
  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH8"
    # bind other light, sync state
    bind_light_id: light_8
    output: dac_ch8_out
    dp_id: 105
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH9"
    output: dac_ch9_out
    id: light_9
    default_transition_length: 0s
 
  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH9"
    # bind other light, sync state
    bind_light_id: light_9
    output: dac_ch9_out
    dp_id: 106
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH10"
    output: dac_ch10_out
    id: light_10
    default_transition_length: 0s

  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH10"
    # bind other light, sync state
    bind_light_id: light_10
    output: dac_ch10_out
    dp_id: 107
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH11"
    output: dac_ch11_out
    id: light_11
    default_transition_length: 0s
 
  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH11"
    # bind other light, sync state
    bind_light_id: light_11
    output: dac_ch11_out
    dp_id: 108
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH12"
    output: dac_ch12_out
    id: light_12
    default_transition_length: 0s

  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH12"
    # bind other light, sync state
    bind_light_id: light_12
    output: dac_ch12_out
    dp_id: 109
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH13"
    output: dac_ch13_out
    id: light_13
    default_transition_length: 0s

  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH13"
    # bind other light, sync state
    bind_light_id: light_13
    output: dac_ch13_out
    dp_id: 110
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH14"
    output: dac_ch14_out
    id: light_14
    default_transition_length: 0s

  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH14"
    # bind other light, sync state
    bind_light_id: light_14
    output: dac_ch14_out
    dp_id: 111
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH15"
    output: dac_ch15_out
    id: light_15
    default_transition_length: 0s
 
  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH15"
    # bind other light, sync state
    bind_light_id: light_15
    output: dac_ch15_out
    dp_id: 112
    # hide from homeassistant ui
    internal: true

  - platform: monochromatic
    name: "DAC CH16"
    output: dac_ch16_out
    id: light_16
    default_transition_length: 0s
 
  - platform: tuya_wifi_mcu
    name: "Tuya DAC CH16"
    # bind other light, sync state
    bind_light_id: light_16
    output: dac_ch16_out
    dp_id: 113
    # hide from homeassistant ui
    internal: true



pcf8574:
  - id: 'pcf8574_hub_in_1'  # for input channel 1-16
    i2c_id: bus_a
    address: 0x22
    pcf8575: true

binary_sensor:
  - platform: gpio
    name: "dm16-input01"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 8
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input02"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 9
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input03"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 10
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input04"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 11
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input05"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 12
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input06"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 13
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input07"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 14
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input08"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 15
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input09"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 0
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input10"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 1
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input11"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 2
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input12"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 3
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input13"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 4
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input14"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 5
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input15"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 6
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "dm16-input16"
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 7
      mode: INPUT
      inverted: true

ads1115:
  - address: 0x48
sensor:
  - platform: ads1115
    multiplexer: 'A0_GND'
    gain: 6.144
    resolution: 16_BITS
    name: "ADS1115 Channel A0-GND"
    update_interval: 5s
  - platform: ads1115
    multiplexer: 'A1_GND'
    gain: 6.144
    name: "ADS1115 Channel A1-GND"
    update_interval: 5s
  - platform: ads1115
    multiplexer: 'A2_GND'
    gain: 6.144
    name: "ADS1115 Channel A2-GND"
    update_interval: 5s
  - platform: ads1115
    multiplexer: 'A3_GND'
    gain: 6.144
    name: "ADS1115 Channel A3-GND"
    update_interval: 5s
esphome yaml file download:

.txt   DM16-HA-with-Tuya.txt (Size: 13.11 KB / Downloads: 126)

Print this item