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

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 8,335
» Latest member: fiber6465
» Forum threads: 3,638
» Forum posts: 18,791

Full Statistics

Online Users
There are currently 15 online users.
» 0 Member(s) | 6 Guest(s)
AhrefsBot, Amazonbot, Google, bot

Latest Threads
kWh resolution
Forum: N30
Last Post: admin
1 hour ago
» Replies: 1
» Views: 3
Goes Offline
Forum: KC868-E16S/E16P
Last Post: admin
1 hour ago
» Replies: 3
» Views: 19
WHATS FIRMWARE
Forum: "KCS" v3 firmware
Last Post: admin
2 hours ago
» Replies: 7
» Views: 634
kincony a16 modbus + Wall...
Forum: KC868-A series and Uair Smart Controller
Last Post: admin
2 hours ago
» Replies: 1
» Views: 13
OUTPUT DO1
Forum: KC868-AIO
Last Post: Lupi84
Yesterday, 07:55 AM
» Replies: 8
» Views: 71
sample code to receive ht...
Forum: F16
Last Post: admin
Yesterday, 04:53 AM
» Replies: 10
» Views: 54
N20 Problem with Home Ass...
Forum: N20
Last Post: Luismical1
12-29-2025, 04:13 PM
» Replies: 5
» Views: 40
Loxone RS485
Forum: KinCony integrate with Loxone home automation
Last Post: admin
12-29-2025, 01:36 PM
» Replies: 11
» Views: 1,168
adaptor V2 and KC868 h32b...
Forum: KC868-ATC / Tuya adapter V2
Last Post: admin
12-29-2025, 08:25 AM
» Replies: 3
» Views: 55
Problems and general Feed...
Forum: N30
Last Post: admin
12-28-2025, 11:58 PM
» Replies: 1
» Views: 18

  [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: 207)
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: 197)

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: 203)
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: 187)

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: 197)
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: 232)

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: 179)
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: 193)

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: 192)
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: 196)

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: 9)
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: 8)

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: 120)

Print this item

  KinCony DM16 Smart Dimmer Controller released
Posted by: admin - 09-09-2025, 02:25 AM - Forum: News - No Replies

KinCony DM16 ESP32 smart dimmer controller based on ESP32-S3-WROOM-1U (N16R8) wifi chip. Support 16 channel DC 0-10v output, 7 channel 1-wire GPIOs, 4 channel ADS1115 16bit analog input ports. One SD card using SPI bus. DM16 include DS3231 high precision RTC clock chip. OLED display will show wifi and ethernet IP address and Tuya connection state. DM16 have 2pcs of RS485 port. one RS485 connect with ARM CPU, support use by modbus directly. Another RS485 work with ESP32. You can write any code by Arduino IDE / MicroPython / ESP-IDF development tool to ESP32 module. We will supply Arduino / ESP-IDF demo code for different samples. Everyone can modify and change the code for your own smart home automation system project. it support use by ESPHome for home assistant or tasmota firmware for smart home automation DIY. DM16 use KCS v3 firmware, it support home assistant auto discovery function by MQTT, so without write any config code (zero code) for home assistant. KCS v3 support KinCony cloud service (official shop customer free 2 years), remote monitor and control device by webpage in anywhere. KCS v3 support KinCony board integrate to Loxone Miniserver. Support Apple HomeKit for Siri.
[Image: DM16-1.jpg]
Model No. KinCony DM16
Description: KinCony 16 Channel ESP32-S3 Smart Dimmer Controller – DM16
Power supply: 12-24V DC
Processor: ESP32-S3-WROOM-1U (N16R8)
Size: 174mm*83mm*59mm
interfaces: Ethernet(RJ45)-LAN 100Mbps IPv4/IPv6,WiFi,RS485,Bluetooth,USB-C,OLED,Tuya Module
RTC: DS3231 high precision chip (battery socket on PCB)
SD Card: SPI bus
Installation method: DIN RAIL
OLED: SSD1306 I2C display
Outputs:
16CH 0-10v Outputs.
Inputs:
ADS1115 16bit ADC: 2CH analog input DC0-5V (A1,A2) 2CH analog input 4-20mA (A3,A4)
16CH dry contact inputs (optocoupler isolation, long distance circuit for MAX 500 meters cable)
4 buttons: 1:ESP32 Reset 2:ESP32 Download 3:Tuya config 4: ARM CPU Reset
1-Wire GPIO: 4CH (with pull-up resistance on PCB)
Free GPIO: 4CH (ESP32 pin directly, without pull-up resistance on PCB)
[Image: DM16-2.jpg]

Print this item

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

Code:
esphome:
  name: dm16
  friendly_name: dm16

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

# Enable logging
logger:

# 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
  debug:

modbus:

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 Channel Dimmer
# -------------------
light:
  - platform: monochromatic
    name: "DAC CH1"
    output: dac_ch1_out
    default_transition_length: 0s

  - platform: monochromatic
    name: "DAC CH2"
    output: dac_ch2_out
    default_transition_length: 0s

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

  - platform: monochromatic
    name: "DAC CH4"
    output: dac_ch4_out
    default_transition_length: 0s

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

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

  - platform: monochromatic
    name: "DAC CH7"
    output: dac_ch7_out
    default_transition_length: 0s

  - platform: monochromatic
    name: "DAC CH8"
    output: dac_ch8_out
    default_transition_length: 0s

  - platform: monochromatic
    name: "DAC CH9"
    output: dac_ch9_out
    default_transition_length: 0s

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

  - platform: monochromatic
    name: "DAC CH11"
    output: dac_ch11_out
    default_transition_length: 0s

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

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

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

  - platform: monochromatic
    name: "DAC CH15"
    output: dac_ch15_out
    default_transition_length: 0s

  - platform: monochromatic
    name: "DAC CH16"
    output: dac_ch16_out
    default_transition_length: 0s



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-without Tuya.txt (Size: 9.49 KB / Downloads: 111)

Print this item

Sad AG Pro - Disappointed
Posted by: vishal.alex@gmail.com - 09-08-2025, 11:54 AM - Forum: KC868-AG / AG Pro / AG8 / Z1 - Replies (5)

I brought the AG Pro in June of 2024 when i saw that it had all in one as a Gateway. It was advertised in such a way that it was all in one solution. But as soon as i received it, i found that many of the things advertised is not functioning out of the box. the Zigbee had to be used with tasmota and remaining functions like IR, RF, Tuya and to be with Kincony firmware. and on top of this both firmware cannot work together. I some how managed to flash the Tasmota firmware because i needed the ZHA integration.. and this worked until last month. Now the tasmota firmware has failed to recognize the Zigbee device inside. i tried rolling back to several tasmota version but it all remains the same. 

I sent a message to their support and all the response i get is to change the firmware. I feel dumped.. Kincony should have either fixed the firmware issues or informed the customer that these problems exits. 92$(inc Shipping) wasted.

Print this item