<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title><![CDATA[Smart Home Automation Forum - DM16]]></title>
		<link>https://www.kincony.com/forum/</link>
		<description><![CDATA[Smart Home Automation Forum - https://www.kincony.com/forum]]></description>
		<pubDate>Mon, 06 Apr 2026 21:42:09 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[DM8 DM16 DM32 PC software using USB-RS485 adapter]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9006</link>
			<pubDate>Tue, 03 Feb 2026 08:27:15 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=9006</guid>
			<description><![CDATA[<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=9140" target="_blank" title="">DMxx_pc.png</a> (Size: 31.14 KB / Downloads: 71)
<!-- end: postbit_attachments_attachment --><br />
PC software download:<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=9141" target="_blank" title="">DMxx_SIMPLE1220.zip</a> (Size: 1.66 MB / Downloads: 77)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=9140" target="_blank" title="">DMxx_pc.png</a> (Size: 31.14 KB / Downloads: 71)
<!-- end: postbit_attachments_attachment --><br />
PC software download:<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=9141" target="_blank" title="">DMxx_SIMPLE1220.zip</a> (Size: 1.66 MB / Downloads: 77)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[DM16 output not turning off LED fully]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8766</link>
			<pubDate>Tue, 25 Nov 2025 16:23:32 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=9287">autolifetech</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8766</guid>
			<description><![CDATA[Hi,<br />
<br />
I am using kincony DM16 as controller and Meanwell pwm 200 series for led driver to control my 24V LED strip<br />
<br />
I am using the ESPhome code that was provided by you in the forum.<br />
Issue now is I cannot turn the LED off fully when it is at 0%. When I short the wire to GND directly, the light can turn off, but when i use the channel, the light cannot off at 0%. How to solve this issue?<br />
<br />
At this moment i cannot afford to buy new LED driver.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/pdf.png" title="Adobe Acrobat PDF" border="0" alt=".pdf" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8662" target="_blank" title="">PWM-200-spec.pdf</a> (Size: 661.26 KB / Downloads: 123)
<!-- end: postbit_attachments_attachment --><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/image.png" title="JPEG Image" border="0" alt=".jpeg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8660" target="_blank" title="">Img_2025_11_25_16_00_13.jpeg</a> (Size: 95.9 KB / Downloads: 140)
<!-- end: postbit_attachments_attachment --><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/image.png" title="JPEG Image" border="0" alt=".jpeg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8661" target="_blank" title="">Img_2025_11_25_16_00_05.jpeg</a> (Size: 88.31 KB / Downloads: 142)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[Hi,<br />
<br />
I am using kincony DM16 as controller and Meanwell pwm 200 series for led driver to control my 24V LED strip<br />
<br />
I am using the ESPhome code that was provided by you in the forum.<br />
Issue now is I cannot turn the LED off fully when it is at 0%. When I short the wire to GND directly, the light can turn off, but when i use the channel, the light cannot off at 0%. How to solve this issue?<br />
<br />
At this moment i cannot afford to buy new LED driver.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/pdf.png" title="Adobe Acrobat PDF" border="0" alt=".pdf" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8662" target="_blank" title="">PWM-200-spec.pdf</a> (Size: 661.26 KB / Downloads: 123)
<!-- end: postbit_attachments_attachment --><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/image.png" title="JPEG Image" border="0" alt=".jpeg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8660" target="_blank" title="">Img_2025_11_25_16_00_13.jpeg</a> (Size: 95.9 KB / Downloads: 140)
<!-- end: postbit_attachments_attachment --><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/image.png" title="JPEG Image" border="0" alt=".jpeg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8661" target="_blank" title="">Img_2025_11_25_16_00_05.jpeg</a> (Size: 88.31 KB / Downloads: 142)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for DM16]-10 Print TEXT on SSD1306 OLED displayer]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8517</link>
			<pubDate>Tue, 09 Sep 2025 11:36:21 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8517</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 * <br />
 * This Arduino program demonstrates how to display text on an SSD1306 128x64 OLED display using the U8g2 library.<br />
 * The program draws two lines of text on the display:<br />
 * - The first line is "KINCONY" in a larger font.<br />
 * - The second line is "www.kincony.com" in a smaller font.<br />
 * <br />
 * The display is connected via I2C (software implementation) with:<br />
 * - SCL (clock) on pin IO18<br />
 * - SDA (data) on pin IO8<br />
 * <br />
 * The display's I2C address is set to 0x3C.<br />
 */<br />
<br />
#include &lt;U8g2lib.h&gt;  // Include the U8g2 library for controlling the OLED display<br />
#include &lt;Wire.h&gt;   &nbsp;&nbsp;// Include the Wire library for I2C communication<br />
<br />
// Initialize the display using the software I2C method (SCL = IO39, SDA = IO38)<br />
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0,  18, 8, U8X8_PIN_NONE);  // Screen rotation: U8G2_R0<br />
<br />
// Function to display page 1 content<br />
void page1() {<br />
  // Set font size 18 for the larger "KINCONY" text<br />
  u8g2.setFont(u8g2_font_timR18_tf);  // Use the Times Roman font, size 18<br />
  u8g2.setFontPosTop();             &nbsp;&nbsp;// Set the text position at the top of the display<br />
  u8g2.setCursor(5, 0);             &nbsp;&nbsp;// Position the cursor at coordinates (5, 0)<br />
  u8g2.print("KINCONY");              // Display the text "KINCONY" on the screen<br />
<br />
  // Set font size 12 for the smaller "www.kincony.com" text<br />
  u8g2.setFont(u8g2_font_timR12_tf);  // Use the Times Roman font, size 12<br />
  u8g2.setCursor(0, 40);              // Position the cursor at coordinates (0, 40)<br />
  u8g2.print("www.kincony.com");      // Display the text "www.kincony.com"<br />
}<br />
<br />
// Setup function, runs once when the program starts<br />
void setup() {<br />
  // Set the I2C address for the display to 0x3C<br />
  u8g2.setI2CAddress(0x3C*2);  // I2C address shift for 8-bit format<br />
  <br />
  // Initialize the display<br />
  u8g2.begin();<br />
  <br />
  // Enable UTF-8 character printing for the display<br />
  u8g2.enableUTF8Print();  // Allow UTF-8 encoded text to be printed<br />
}<br />
<br />
// Main loop function, continuously runs after setup()<br />
void loop() {<br />
  // Begin the display drawing process<br />
  u8g2.firstPage();  // Prepare the first page for drawing<br />
  do {<br />
    // Call the page1() function to draw content on the display<br />
    page1();<br />
  } while (u8g2.nextPage());  // Continue to the next page until all pages are drawn<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8308" target="_blank" title="">10-oled-ssd1306.zip</a> (Size: 1.12 KB / Downloads: 295)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8309" target="_blank" title="">10-oled-ssd1306.ino.merged.zip</a> (Size: 201.24 KB / Downloads: 302)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 * <br />
 * This Arduino program demonstrates how to display text on an SSD1306 128x64 OLED display using the U8g2 library.<br />
 * The program draws two lines of text on the display:<br />
 * - The first line is "KINCONY" in a larger font.<br />
 * - The second line is "www.kincony.com" in a smaller font.<br />
 * <br />
 * The display is connected via I2C (software implementation) with:<br />
 * - SCL (clock) on pin IO18<br />
 * - SDA (data) on pin IO8<br />
 * <br />
 * The display's I2C address is set to 0x3C.<br />
 */<br />
<br />
#include &lt;U8g2lib.h&gt;  // Include the U8g2 library for controlling the OLED display<br />
#include &lt;Wire.h&gt;   &nbsp;&nbsp;// Include the Wire library for I2C communication<br />
<br />
// Initialize the display using the software I2C method (SCL = IO39, SDA = IO38)<br />
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0,  18, 8, U8X8_PIN_NONE);  // Screen rotation: U8G2_R0<br />
<br />
// Function to display page 1 content<br />
void page1() {<br />
  // Set font size 18 for the larger "KINCONY" text<br />
  u8g2.setFont(u8g2_font_timR18_tf);  // Use the Times Roman font, size 18<br />
  u8g2.setFontPosTop();             &nbsp;&nbsp;// Set the text position at the top of the display<br />
  u8g2.setCursor(5, 0);             &nbsp;&nbsp;// Position the cursor at coordinates (5, 0)<br />
  u8g2.print("KINCONY");              // Display the text "KINCONY" on the screen<br />
<br />
  // Set font size 12 for the smaller "www.kincony.com" text<br />
  u8g2.setFont(u8g2_font_timR12_tf);  // Use the Times Roman font, size 12<br />
  u8g2.setCursor(0, 40);              // Position the cursor at coordinates (0, 40)<br />
  u8g2.print("www.kincony.com");      // Display the text "www.kincony.com"<br />
}<br />
<br />
// Setup function, runs once when the program starts<br />
void setup() {<br />
  // Set the I2C address for the display to 0x3C<br />
  u8g2.setI2CAddress(0x3C*2);  // I2C address shift for 8-bit format<br />
  <br />
  // Initialize the display<br />
  u8g2.begin();<br />
  <br />
  // Enable UTF-8 character printing for the display<br />
  u8g2.enableUTF8Print();  // Allow UTF-8 encoded text to be printed<br />
}<br />
<br />
// Main loop function, continuously runs after setup()<br />
void loop() {<br />
  // Begin the display drawing process<br />
  u8g2.firstPage();  // Prepare the first page for drawing<br />
  do {<br />
    // Call the page1() function to draw content on the display<br />
    page1();<br />
  } while (u8g2.nextPage());  // Continue to the next page until all pages are drawn<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8308" target="_blank" title="">10-oled-ssd1306.zip</a> (Size: 1.12 KB / Downloads: 295)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8309" target="_blank" title="">10-oled-ssd1306.ino.merged.zip</a> (Size: 201.24 KB / Downloads: 302)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for DM16]-09 how to communication with Tuya WiFi module]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8516</link>
			<pubDate>Tue, 09 Sep 2025 11:34:19 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8516</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 * <br />
 * This Arduino program implements communication between ESP32 and the Tuya module<br />
 * via UART (serial communication). It listens for specific packets from the Tuya module<br />
 * and responds according to the predefined commands.<br />
 * <br />
 * Functionality:<br />
 * 1. When the ESP32 receives a heartbeat packet (55 AA 00 00 00 00 FF),<br />
 *    it sends a heartbeat response (55 AA 03 00 00 01 00 03).<br />
 * 2. When the ESP32 receives a product information request (55 AA 00 01 00 00 00),<br />
 *    it sends a product information response (55 AA 03 01 ...).<br />
 * 3. When the ESP32 receives a work mode request (55 AA 00 02 00 00 01),<br />
 *    it sends a work mode response (55 AA 03 02 00 03 10 1C 14 47).<br />
 * 4. When the ESP32 receives a network status request (55 AA 00 03 00 01 00 03),<br />
 *    it sends a network status response (55 AA 03 03 00 00 05).<br />
 * 5. Subsequent heartbeat packets (55 AA 00 00 00 00 FF) are responded to with<br />
 *    (55 AA 03 00 00 01 01 04).<br />
 */<br />
<br />
#include &lt;HardwareSerial.h&gt;<br />
<br />
// Create a HardwareSerial object for UART communication on ESP32<br />
HardwareSerial tuyaSerial(1);<br />
<br />
// Define the GPIO pins for TXD and RXD used for serial communication<br />
#define TXD_PIN 16<br />
#define RXD_PIN 17<br />
<br />
// Set the baud rate for Tuya module communication to 9600<br />
#define BAUD_RATE 9600<br />
<br />
// Define the response packets for different commands from the Tuya module<br />
<br />
// Heartbeat response: 55 AA 03 00 00 01 00 03<br />
uint8_t heartBeatResponse[] = {0x55, 0xAA, 0x03, 0x00, 0x00, 0x01, 0x00, 0x03};<br />
<br />
// Product info response with a detailed payload (e.g., firmware version, product name, etc.)<br />
uint8_t productInfoResponse[] = {<br />
  0x55, 0xAA, 0x03, 0x01, 0x00, 0x2A, 0x7B, 0x22, 0x70, 0x22, 0x3A, 0x22, <br />
  0x63, 0x68, 0x6D, 0x7A, 0x6C, 0x67, 0x6A, 0x70, 0x61, 0x64, 0x70, 0x71, <br />
  0x78, 0x64, 0x6B, 0x6F, 0x22, 0x2C, 0x22, 0x76, 0x22, 0x3A, 0x22, 0x31, <br />
  0x2E, 0x30, 0x2E, 0x30, 0x22, 0x2C, 0x22, 0x6D, 0x22, 0x3A, 0x30, 0x7D, 0xAA<br />
};<br />
<br />
// Work mode response: 55 AA 03 02 00 03 10 1C 14 47<br />
uint8_t workModeResponse[] = {0x55, 0xAA, 0x03, 0x02, 0x00, 0x03, 0x10, 0x1C, 0x14, 0x47};<br />
<br />
// Network status response: 55 AA 03 03 00 00 05<br />
uint8_t netStatusResponse[] = {0x55, 0xAA, 0x03, 0x03, 0x00, 0x00, 0x05};<br />
<br />
// Subsequent heartbeat response: 55 AA 03 00 00 01 01 04<br />
uint8_t secondHeartBeatResponse[] = {0x55, 0xAA, 0x03, 0x00, 0x00, 0x01, 0x01, 0x04};<br />
<br />
void setup() {<br />
  // Initialize the serial communication for debugging at 115200 baud rate<br />
  Serial.begin(115200);<br />
<br />
  // Initialize the serial communication with Tuya module at 9600 baud rate<br />
  tuyaSerial.begin(BAUD_RATE, SERIAL_8N1, RXD_PIN, TXD_PIN);<br />
<br />
  // Debug message to indicate that the serial communication has been initialized<br />
  Serial.println("ESP32-Tuya serial communication initialized.");<br />
}<br />
<br />
void loop() {<br />
  // Check if data is available from the Tuya module<br />
  if (tuyaSerial.available()) {<br />
    uint8_t incomingPacket[7];  // Array to store the received packet<br />
    size_t bytesRead = tuyaSerial.readBytes(incomingPacket, 7); // Read 7 bytes from Tuya<br />
<br />
    // Check if the packet has a valid header (0x55, 0xAA)<br />
    if (bytesRead &gt;= 2 &amp;&amp; incomingPacket[0] == 0x55 &amp;&amp; incomingPacket[1] == 0xAA) {<br />
      // If less than 7 bytes were received, wait for more data<br />
      if (bytesRead &lt; 7) {<br />
        Serial.println("Incomplete packet received. Waiting for remaining bytes...");<br />
        delay(50); // Delay to allow more data to be received<br />
        while (tuyaSerial.available()) {<br />
          incomingPacket[bytesRead++] = tuyaSerial.read(); // Continue reading remaining bytes<br />
          if (bytesRead &gt;= 7) break;<br />
        }<br />
      }<br />
<br />
      // If still less than 7 bytes, discard the incomplete packet<br />
      if (bytesRead &lt; 7) {<br />
        Serial.println("Error: Incomplete packet discarded.");<br />
        return;<br />
      }<br />
<br />
      // Debug: Print the received packet for logging<br />
      Serial.print("Received packet: ");<br />
      for (size_t i = 0; i &lt; 7; i++) {<br />
        Serial.print(incomingPacket[i], HEX);<br />
        Serial.print(" ");<br />
      }<br />
      Serial.println();<br />
<br />
      // Call the function to process the received packet<br />
      processTuyaPacket(incomingPacket, 7);<br />
<br />
    } else {<br />
      // If the header is invalid, discard the packet and flush the buffer<br />
      Serial.print("Error: Invalid packet header. Data received: ");<br />
      for (size_t i = 0; i &lt; bytesRead; i++) {<br />
        Serial.print(incomingPacket[i], HEX);<br />
        Serial.print(" ");<br />
      }<br />
      Serial.println();<br />
      tuyaSerial.flush(); // Clear the serial buffer<br />
    }<br />
  }<br />
<br />
  // Delay to avoid CPU overuse<br />
  delay(100);<br />
}<br />
<br />
// Function to process the received packet and send the appropriate response<br />
void processTuyaPacket(uint8_t* packet, size_t size) {<br />
  // Ensure the packet size is 7 and the header is valid<br />
  if (size == 7 &amp;&amp; packet[0] == 0x55 &amp;&amp; packet[1] == 0xAA) {<br />
    // Determine the command in the packet (packet[2])<br />
    switch(packet[2]) {<br />
      case 0x00:<br />
        if (packet[3] == 0x00 &amp;&amp; packet[4] == 0x00 &amp;&amp; packet[5] == 0x00 &amp;&amp; packet[6] == 0xFF) {<br />
          Serial.println("Heartbeat received.");<br />
          sendPacket(heartBeatResponse, sizeof(heartBeatResponse));<br />
        } else if (packet[3] == 0x01 &amp;&amp; packet[4] == 0x00 &amp;&amp; packet[5] == 0x00 &amp;&amp; packet[6] == 0x00) {<br />
          Serial.println("Product info request received.");<br />
          sendPacket(productInfoResponse, sizeof(productInfoResponse));<br />
        } else if (packet[3] == 0x02 &amp;&amp; packet[4] == 0x00 &amp;&amp; packet[5] == 0x00 &amp;&amp; packet[6] == 0x01) {<br />
          Serial.println("Work mode request received.");<br />
          sendPacket(workModeResponse, sizeof(workModeResponse));<br />
        } else if (packet[3] == 0x03 &amp;&amp; packet[4] == 0x00 &amp;&amp; packet[5] == 0x01 &amp;&amp; packet[6] == 0x00) {<br />
          Serial.println("Network status request received.");<br />
          sendPacket(netStatusResponse, sizeof(netStatusResponse));<br />
        }<br />
        break;<br />
<br />
      default:<br />
        Serial.println("Error: Unhandled command received.");<br />
        break;<br />
    }<br />
  }<br />
}<br />
<br />
// Function to send the response packet to the Tuya module<br />
void sendPacket(uint8_t* packet, size_t size) {<br />
  // Send the packet via UART to Tuya module<br />
  tuyaSerial.write(packet, size);<br />
<br />
  // Debug: Print the sent packet for logging<br />
  Serial.print("Sent packet: ");<br />
  for (size_t i = 0; i &lt; size; i++) {<br />
    Serial.print(packet[i], HEX);<br />
    Serial.print(" ");<br />
  }<br />
  Serial.println();<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8306" target="_blank" title="">9-tuya-wifi-config.zip</a> (Size: 2 KB / Downloads: 306)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8307" target="_blank" title="">9-tuya-wifi-config.ino.merged.zip</a> (Size: 184.93 KB / Downloads: 301)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 * <br />
 * This Arduino program implements communication between ESP32 and the Tuya module<br />
 * via UART (serial communication). It listens for specific packets from the Tuya module<br />
 * and responds according to the predefined commands.<br />
 * <br />
 * Functionality:<br />
 * 1. When the ESP32 receives a heartbeat packet (55 AA 00 00 00 00 FF),<br />
 *    it sends a heartbeat response (55 AA 03 00 00 01 00 03).<br />
 * 2. When the ESP32 receives a product information request (55 AA 00 01 00 00 00),<br />
 *    it sends a product information response (55 AA 03 01 ...).<br />
 * 3. When the ESP32 receives a work mode request (55 AA 00 02 00 00 01),<br />
 *    it sends a work mode response (55 AA 03 02 00 03 10 1C 14 47).<br />
 * 4. When the ESP32 receives a network status request (55 AA 00 03 00 01 00 03),<br />
 *    it sends a network status response (55 AA 03 03 00 00 05).<br />
 * 5. Subsequent heartbeat packets (55 AA 00 00 00 00 FF) are responded to with<br />
 *    (55 AA 03 00 00 01 01 04).<br />
 */<br />
<br />
#include &lt;HardwareSerial.h&gt;<br />
<br />
// Create a HardwareSerial object for UART communication on ESP32<br />
HardwareSerial tuyaSerial(1);<br />
<br />
// Define the GPIO pins for TXD and RXD used for serial communication<br />
#define TXD_PIN 16<br />
#define RXD_PIN 17<br />
<br />
// Set the baud rate for Tuya module communication to 9600<br />
#define BAUD_RATE 9600<br />
<br />
// Define the response packets for different commands from the Tuya module<br />
<br />
// Heartbeat response: 55 AA 03 00 00 01 00 03<br />
uint8_t heartBeatResponse[] = {0x55, 0xAA, 0x03, 0x00, 0x00, 0x01, 0x00, 0x03};<br />
<br />
// Product info response with a detailed payload (e.g., firmware version, product name, etc.)<br />
uint8_t productInfoResponse[] = {<br />
  0x55, 0xAA, 0x03, 0x01, 0x00, 0x2A, 0x7B, 0x22, 0x70, 0x22, 0x3A, 0x22, <br />
  0x63, 0x68, 0x6D, 0x7A, 0x6C, 0x67, 0x6A, 0x70, 0x61, 0x64, 0x70, 0x71, <br />
  0x78, 0x64, 0x6B, 0x6F, 0x22, 0x2C, 0x22, 0x76, 0x22, 0x3A, 0x22, 0x31, <br />
  0x2E, 0x30, 0x2E, 0x30, 0x22, 0x2C, 0x22, 0x6D, 0x22, 0x3A, 0x30, 0x7D, 0xAA<br />
};<br />
<br />
// Work mode response: 55 AA 03 02 00 03 10 1C 14 47<br />
uint8_t workModeResponse[] = {0x55, 0xAA, 0x03, 0x02, 0x00, 0x03, 0x10, 0x1C, 0x14, 0x47};<br />
<br />
// Network status response: 55 AA 03 03 00 00 05<br />
uint8_t netStatusResponse[] = {0x55, 0xAA, 0x03, 0x03, 0x00, 0x00, 0x05};<br />
<br />
// Subsequent heartbeat response: 55 AA 03 00 00 01 01 04<br />
uint8_t secondHeartBeatResponse[] = {0x55, 0xAA, 0x03, 0x00, 0x00, 0x01, 0x01, 0x04};<br />
<br />
void setup() {<br />
  // Initialize the serial communication for debugging at 115200 baud rate<br />
  Serial.begin(115200);<br />
<br />
  // Initialize the serial communication with Tuya module at 9600 baud rate<br />
  tuyaSerial.begin(BAUD_RATE, SERIAL_8N1, RXD_PIN, TXD_PIN);<br />
<br />
  // Debug message to indicate that the serial communication has been initialized<br />
  Serial.println("ESP32-Tuya serial communication initialized.");<br />
}<br />
<br />
void loop() {<br />
  // Check if data is available from the Tuya module<br />
  if (tuyaSerial.available()) {<br />
    uint8_t incomingPacket[7];  // Array to store the received packet<br />
    size_t bytesRead = tuyaSerial.readBytes(incomingPacket, 7); // Read 7 bytes from Tuya<br />
<br />
    // Check if the packet has a valid header (0x55, 0xAA)<br />
    if (bytesRead &gt;= 2 &amp;&amp; incomingPacket[0] == 0x55 &amp;&amp; incomingPacket[1] == 0xAA) {<br />
      // If less than 7 bytes were received, wait for more data<br />
      if (bytesRead &lt; 7) {<br />
        Serial.println("Incomplete packet received. Waiting for remaining bytes...");<br />
        delay(50); // Delay to allow more data to be received<br />
        while (tuyaSerial.available()) {<br />
          incomingPacket[bytesRead++] = tuyaSerial.read(); // Continue reading remaining bytes<br />
          if (bytesRead &gt;= 7) break;<br />
        }<br />
      }<br />
<br />
      // If still less than 7 bytes, discard the incomplete packet<br />
      if (bytesRead &lt; 7) {<br />
        Serial.println("Error: Incomplete packet discarded.");<br />
        return;<br />
      }<br />
<br />
      // Debug: Print the received packet for logging<br />
      Serial.print("Received packet: ");<br />
      for (size_t i = 0; i &lt; 7; i++) {<br />
        Serial.print(incomingPacket[i], HEX);<br />
        Serial.print(" ");<br />
      }<br />
      Serial.println();<br />
<br />
      // Call the function to process the received packet<br />
      processTuyaPacket(incomingPacket, 7);<br />
<br />
    } else {<br />
      // If the header is invalid, discard the packet and flush the buffer<br />
      Serial.print("Error: Invalid packet header. Data received: ");<br />
      for (size_t i = 0; i &lt; bytesRead; i++) {<br />
        Serial.print(incomingPacket[i], HEX);<br />
        Serial.print(" ");<br />
      }<br />
      Serial.println();<br />
      tuyaSerial.flush(); // Clear the serial buffer<br />
    }<br />
  }<br />
<br />
  // Delay to avoid CPU overuse<br />
  delay(100);<br />
}<br />
<br />
// Function to process the received packet and send the appropriate response<br />
void processTuyaPacket(uint8_t* packet, size_t size) {<br />
  // Ensure the packet size is 7 and the header is valid<br />
  if (size == 7 &amp;&amp; packet[0] == 0x55 &amp;&amp; packet[1] == 0xAA) {<br />
    // Determine the command in the packet (packet[2])<br />
    switch(packet[2]) {<br />
      case 0x00:<br />
        if (packet[3] == 0x00 &amp;&amp; packet[4] == 0x00 &amp;&amp; packet[5] == 0x00 &amp;&amp; packet[6] == 0xFF) {<br />
          Serial.println("Heartbeat received.");<br />
          sendPacket(heartBeatResponse, sizeof(heartBeatResponse));<br />
        } else if (packet[3] == 0x01 &amp;&amp; packet[4] == 0x00 &amp;&amp; packet[5] == 0x00 &amp;&amp; packet[6] == 0x00) {<br />
          Serial.println("Product info request received.");<br />
          sendPacket(productInfoResponse, sizeof(productInfoResponse));<br />
        } else if (packet[3] == 0x02 &amp;&amp; packet[4] == 0x00 &amp;&amp; packet[5] == 0x00 &amp;&amp; packet[6] == 0x01) {<br />
          Serial.println("Work mode request received.");<br />
          sendPacket(workModeResponse, sizeof(workModeResponse));<br />
        } else if (packet[3] == 0x03 &amp;&amp; packet[4] == 0x00 &amp;&amp; packet[5] == 0x01 &amp;&amp; packet[6] == 0x00) {<br />
          Serial.println("Network status request received.");<br />
          sendPacket(netStatusResponse, sizeof(netStatusResponse));<br />
        }<br />
        break;<br />
<br />
      default:<br />
        Serial.println("Error: Unhandled command received.");<br />
        break;<br />
    }<br />
  }<br />
}<br />
<br />
// Function to send the response packet to the Tuya module<br />
void sendPacket(uint8_t* packet, size_t size) {<br />
  // Send the packet via UART to Tuya module<br />
  tuyaSerial.write(packet, size);<br />
<br />
  // Debug: Print the sent packet for logging<br />
  Serial.print("Sent packet: ");<br />
  for (size_t i = 0; i &lt; size; i++) {<br />
    Serial.print(packet[i], HEX);<br />
    Serial.print(" ");<br />
  }<br />
  Serial.println();<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8306" target="_blank" title="">9-tuya-wifi-config.zip</a> (Size: 2 KB / Downloads: 306)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8307" target="_blank" title="">9-tuya-wifi-config.ino.merged.zip</a> (Size: 184.93 KB / Downloads: 301)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for DM16]-08 Ethernet W5500 chip work with TCP Server mode]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8515</link>
			<pubDate>Tue, 09 Sep 2025 11:32:40 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8515</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 * This Arduino program sets up an ESP32-S3 with a W5500 Ethernet module<br />
 * as a TCP server. It listens on port 4196 and echoes back any string <br />
 * received from a client.<br />
 *<br />
 * Hardware connections:<br />
 * - CLK: GPIO1<br />
 * - MOSI: GPIO2<br />
 * - MISO: GPIO41<br />
 * - CS: GPIO42<br />
 * - RST: GPIO44<br />
 * - INT: GPIO43<br />
 *<br />
 * Static IP address: 192.168.3.55<br />
 * Subnet Mask: 255.255.255.0<br />
 * Gateway: 192.168.3.1<br />
 * DNS: 192.168.3.1<br />
 */<br />
<br />
#include &lt;SPI.h&gt;<br />
#include &lt;Ethernet.h&gt;<br />
<br />
// Define the W5500 Ethernet module pins<br />
#define W5500_CS_PIN  42<br />
#define W5500_RST_PIN 44<br />
#define W5500_INT_PIN 43<br />
#define W5500_CLK_PIN 1<br />
#define W5500_MOSI_PIN 2<br />
#define W5500_MISO_PIN 41<br />
<br />
// MAC address for your Ethernet shield (must be unique on your network)<br />
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };<br />
<br />
// Static IP address configuration<br />
IPAddress ip(192, 168, 3, 55);     &nbsp;&nbsp;// Static IP address<br />
IPAddress subnet(255, 255, 255, 0); &nbsp;&nbsp;// Subnet mask<br />
IPAddress gateway(192, 168, 3, 1);    // Default gateway<br />
IPAddress dns(192, 168, 3, 1);        // DNS server address<br />
<br />
// Create an EthernetServer object to handle TCP connections<br />
EthernetServer server(4196);<br />
<br />
void setup() {<br />
  // Initialize serial communication<br />
  Serial.begin(115200);<br />
  while (!Serial) {<br />
    ; // Wait for serial port to connect<br />
  }<br />
<br />
  // Initialize the W5500 module<br />
  pinMode(W5500_RST_PIN, OUTPUT);<br />
  pinMode(W5500_INT_PIN, INPUT);<br />
  digitalWrite(W5500_RST_PIN, LOW);  // Reset the W5500 module<br />
  delay(100);                     &nbsp;&nbsp;// Wait for reset to complete<br />
  digitalWrite(W5500_RST_PIN, HIGH); // Release reset<br />
<br />
  // Initialize SPI with the correct pin definitions<br />
  SPI.begin(W5500_CLK_PIN, W5500_MISO_PIN, W5500_MOSI_PIN);<br />
<br />
  // Set up the Ethernet library with W5500-specific pins<br />
  Ethernet.init(W5500_CS_PIN);<br />
<br />
  // Start the Ethernet connection with static IP configuration<br />
  Ethernet.begin(mac, ip, dns, gateway, subnet);<br />
<br />
  // Print the IP address to the serial monitor<br />
  Serial.print("IP Address: ");<br />
  Serial.println(Ethernet.localIP());<br />
<br />
  // Start listening for incoming TCP connections<br />
  server.begin();<br />
}<br />
<br />
void loop() {<br />
  // Check for incoming client connections<br />
  EthernetClient client = server.available();<br />
  if (client) {<br />
    Serial.println("New client connected");<br />
<br />
    // Read data from the client and echo it back<br />
    while (client.connected()) {<br />
      if (client.available()) {<br />
        char c = client.read();<br />
        server.write(c);<br />
      }<br />
    }<br />
<br />
    // Close the connection when done<br />
    client.stop();<br />
    Serial.println("Client disconnected");<br />
  }<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8304" target="_blank" title="">8-Ethernet-W5500.zip</a> (Size: 1.23 KB / Downloads: 285)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8305" target="_blank" title="">8-Ethernet-W5500.ino.merged.zip</a> (Size: 188.93 KB / Downloads: 318)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 * This Arduino program sets up an ESP32-S3 with a W5500 Ethernet module<br />
 * as a TCP server. It listens on port 4196 and echoes back any string <br />
 * received from a client.<br />
 *<br />
 * Hardware connections:<br />
 * - CLK: GPIO1<br />
 * - MOSI: GPIO2<br />
 * - MISO: GPIO41<br />
 * - CS: GPIO42<br />
 * - RST: GPIO44<br />
 * - INT: GPIO43<br />
 *<br />
 * Static IP address: 192.168.3.55<br />
 * Subnet Mask: 255.255.255.0<br />
 * Gateway: 192.168.3.1<br />
 * DNS: 192.168.3.1<br />
 */<br />
<br />
#include &lt;SPI.h&gt;<br />
#include &lt;Ethernet.h&gt;<br />
<br />
// Define the W5500 Ethernet module pins<br />
#define W5500_CS_PIN  42<br />
#define W5500_RST_PIN 44<br />
#define W5500_INT_PIN 43<br />
#define W5500_CLK_PIN 1<br />
#define W5500_MOSI_PIN 2<br />
#define W5500_MISO_PIN 41<br />
<br />
// MAC address for your Ethernet shield (must be unique on your network)<br />
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };<br />
<br />
// Static IP address configuration<br />
IPAddress ip(192, 168, 3, 55);     &nbsp;&nbsp;// Static IP address<br />
IPAddress subnet(255, 255, 255, 0); &nbsp;&nbsp;// Subnet mask<br />
IPAddress gateway(192, 168, 3, 1);    // Default gateway<br />
IPAddress dns(192, 168, 3, 1);        // DNS server address<br />
<br />
// Create an EthernetServer object to handle TCP connections<br />
EthernetServer server(4196);<br />
<br />
void setup() {<br />
  // Initialize serial communication<br />
  Serial.begin(115200);<br />
  while (!Serial) {<br />
    ; // Wait for serial port to connect<br />
  }<br />
<br />
  // Initialize the W5500 module<br />
  pinMode(W5500_RST_PIN, OUTPUT);<br />
  pinMode(W5500_INT_PIN, INPUT);<br />
  digitalWrite(W5500_RST_PIN, LOW);  // Reset the W5500 module<br />
  delay(100);                     &nbsp;&nbsp;// Wait for reset to complete<br />
  digitalWrite(W5500_RST_PIN, HIGH); // Release reset<br />
<br />
  // Initialize SPI with the correct pin definitions<br />
  SPI.begin(W5500_CLK_PIN, W5500_MISO_PIN, W5500_MOSI_PIN);<br />
<br />
  // Set up the Ethernet library with W5500-specific pins<br />
  Ethernet.init(W5500_CS_PIN);<br />
<br />
  // Start the Ethernet connection with static IP configuration<br />
  Ethernet.begin(mac, ip, dns, gateway, subnet);<br />
<br />
  // Print the IP address to the serial monitor<br />
  Serial.print("IP Address: ");<br />
  Serial.println(Ethernet.localIP());<br />
<br />
  // Start listening for incoming TCP connections<br />
  server.begin();<br />
}<br />
<br />
void loop() {<br />
  // Check for incoming client connections<br />
  EthernetClient client = server.available();<br />
  if (client) {<br />
    Serial.println("New client connected");<br />
<br />
    // Read data from the client and echo it back<br />
    while (client.connected()) {<br />
      if (client.available()) {<br />
        char c = client.read();<br />
        server.write(c);<br />
      }<br />
    }<br />
<br />
    // Close the connection when done<br />
    client.stop();<br />
    Serial.println("Client disconnected");<br />
  }<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8304" target="_blank" title="">8-Ethernet-W5500.zip</a> (Size: 1.23 KB / Downloads: 285)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8305" target="_blank" title="">8-Ethernet-W5500.ino.merged.zip</a> (Size: 188.93 KB / Downloads: 318)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for DM16]-07 how to DS3231 RTC clock]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8514</link>
			<pubDate>Tue, 09 Sep 2025 11:31:29 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8514</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 * DS3231 RTC with Arduino<br />
 *<br />
 * This program demonstrates how to use the DS3231 RTC (Real-Time Clock) module with the Arduino.<br />
 * It includes functionality to:<br />
 * - Initialize the DS3231 RTC module<br />
 * - Read the current date and time from the RTC<br />
 * - Set the RTC time based on a serial command:Command format: DYYYY-MM-DDTHH:MM:SS<br />
*    Set date and time command example: D2024-09-19T11:50:22<br />
*    print current date and time command: current time<br />
*<br />
 *<br />
 * Hardware Connections:<br />
 * - SDA: GPIO 8<br />
 * - SCL: GPIO 18<br />
 */<br />
<br />
#include &lt;DS3231.h&gt;<br />
#include &lt;Wire.h&gt;<br />
<br />
String serial_cmd_rcv = ""; // Serial port receiver<br />
<br />
typedef struct<br />
{<br />
  byte year;    // Last two digits of the year, library adds 2000.<br />
  byte month;<br />
  byte day;<br />
  byte hour;<br />
  byte minute;<br />
  byte second;<br />
} MY_DATE_STR;<br />
<br />
MY_DATE_STR my_date_str = {0};<br />
<br />
// Define constants for relay control<br />
#define OPEN_RLY_DATA    26<br />
#define OPEN_RLY_MONTH &nbsp;&nbsp;4<br />
#define CLOSE_RLY_DATA &nbsp;&nbsp;2<br />
#define CLOSE_RLY_MONTH  5<br />
<br />
// Define pin connections<br />
#define SDA_PIN &nbsp;&nbsp;8<br />
#define SCL_PIN &nbsp;&nbsp;18<br />
<br />
DS3231 rtc; // Create an instance of the DS3231 RTC<br />
bool h12Flag;<br />
bool pmFlag;<br />
static bool bCentury = false;<br />
static bool old_level_high = false;<br />
static bool old_level_low = false;<br />
<br />
<br />
/**<br />
 * @brief Print the current time from the RTC to the Serial Monitor.<br />
 */<br />
static void PrintfCurTime()<br />
{<br />
  Serial.print("Current time is: ");<br />
  int year = rtc.getYear() + 2000;<br />
  Serial.print(year);<br />
  Serial.print("-");<br />
<br />
  Serial.print(rtc.getMonth(bCentury), DEC);<br />
  Serial.print("-");<br />
<br />
  Serial.print(rtc.getDate(), DEC);<br />
  Serial.print(" ");<br />
<br />
  Serial.print(rtc.getHour(h12Flag, pmFlag), DEC);<br />
  Serial.print(":");<br />
  Serial.print(rtc.getMinute(), DEC);<br />
  Serial.print(":");<br />
  Serial.println(rtc.getSecond(), DEC);<br />
}<br />
<br />
/**<br />
 * @brief Process serial commands to set the RTC time.<br />
 * Command format: DYYYY-MM-DDTHH:MM:SS<br />
 */<br />
static void GetSerialCmd()<br />
{<br />
  if (Serial.available() &gt; 0)<br />
  {<br />
    delay(100);<br />
    int num_read = Serial.available();<br />
    while (num_read--)<br />
      serial_cmd_rcv += char(Serial.read());<br />
  }<br />
  else return;<br />
<br />
  serial_cmd_rcv.trim();<br />
<br />
  if (serial_cmd_rcv == "current time")<br />
  {<br />
    PrintfCurTime();<br />
    serial_cmd_rcv = "";<br />
    return;<br />
  }<br />
<br />
  Serial.print("Received length: ");<br />
  Serial.println(serial_cmd_rcv.length());<br />
<br />
  int indexof_d = serial_cmd_rcv.indexOf('D');<br />
  int indexof_t = serial_cmd_rcv.indexOf('T');<br />
<br />
  Serial.print("D index: ");<br />
  Serial.print(indexof_d);<br />
  Serial.print(" T index: ");<br />
  Serial.println(indexof_t);<br />
<br />
  if (serial_cmd_rcv.length() != 20 || <br />
      serial_cmd_rcv.substring(0, 1) != "D" ||<br />
      serial_cmd_rcv.substring(11, 12) != "T")  <br />
  {<br />
    Serial.println(serial_cmd_rcv);<br />
    serial_cmd_rcv = "";<br />
    return;<br />
  }<br />
<br />
  Serial.println("Setting time...");<br />
<br />
  my_date_str.year = (byte)serial_cmd_rcv.substring(3, 5).toInt();<br />
  my_date_str.month = (byte)serial_cmd_rcv.substring(6, 8).toInt();<br />
  my_date_str.day = (byte)serial_cmd_rcv.substring(9, 11).toInt();<br />
  my_date_str.hour = (byte)serial_cmd_rcv.substring(12, 14).toInt();<br />
  my_date_str.minute = (byte)serial_cmd_rcv.substring(15, 17).toInt();<br />
  my_date_str.second = (byte)serial_cmd_rcv.substring(18).toInt();<br />
<br />
  rtc.setYear(my_date_str.year);<br />
  rtc.setMonth(my_date_str.month);<br />
  rtc.setDate(my_date_str.day);<br />
  rtc.setHour(my_date_str.hour);<br />
  rtc.setMinute(my_date_str.minute);<br />
  rtc.setSecond(my_date_str.second);<br />
<br />
  serial_cmd_rcv = "";<br />
<br />
  Serial.println("Time set.");<br />
}<br />
<br />
void setup() {<br />
  // Initialize the I2C interface<br />
  Wire.begin(SDA_PIN, SCL_PIN, 40000);<br />
  <br />
  // Initialize Serial communication<br />
  Serial.begin(115200);<br />
 &nbsp;&nbsp;<br />
  // Set the RTC to 24-hour mode<br />
  rtc.setClockMode(false); // 24-hour format<br />
<br />
  // Print current time to Serial Monitor<br />
  PrintfCurTime();<br />
<br />
  // Clear any remaining serial data<br />
  while (Serial.read() &gt;= 0) {}<br />
}<br />
<br />
void loop() {<br />
  // Process incoming serial commands<br />
  GetSerialCmd(); <br />
  delay(1000); // Delay for 1 second<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8302" target="_blank" title="">7-DS3231-RTC.zip</a> (Size: 1.56 KB / Downloads: 288)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8303" target="_blank" title="">7-DS3231-RTC.ino.merged.zip</a> (Size: 191.08 KB / Downloads: 298)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 * DS3231 RTC with Arduino<br />
 *<br />
 * This program demonstrates how to use the DS3231 RTC (Real-Time Clock) module with the Arduino.<br />
 * It includes functionality to:<br />
 * - Initialize the DS3231 RTC module<br />
 * - Read the current date and time from the RTC<br />
 * - Set the RTC time based on a serial command:Command format: DYYYY-MM-DDTHH:MM:SS<br />
*    Set date and time command example: D2024-09-19T11:50:22<br />
*    print current date and time command: current time<br />
*<br />
 *<br />
 * Hardware Connections:<br />
 * - SDA: GPIO 8<br />
 * - SCL: GPIO 18<br />
 */<br />
<br />
#include &lt;DS3231.h&gt;<br />
#include &lt;Wire.h&gt;<br />
<br />
String serial_cmd_rcv = ""; // Serial port receiver<br />
<br />
typedef struct<br />
{<br />
  byte year;    // Last two digits of the year, library adds 2000.<br />
  byte month;<br />
  byte day;<br />
  byte hour;<br />
  byte minute;<br />
  byte second;<br />
} MY_DATE_STR;<br />
<br />
MY_DATE_STR my_date_str = {0};<br />
<br />
// Define constants for relay control<br />
#define OPEN_RLY_DATA    26<br />
#define OPEN_RLY_MONTH &nbsp;&nbsp;4<br />
#define CLOSE_RLY_DATA &nbsp;&nbsp;2<br />
#define CLOSE_RLY_MONTH  5<br />
<br />
// Define pin connections<br />
#define SDA_PIN &nbsp;&nbsp;8<br />
#define SCL_PIN &nbsp;&nbsp;18<br />
<br />
DS3231 rtc; // Create an instance of the DS3231 RTC<br />
bool h12Flag;<br />
bool pmFlag;<br />
static bool bCentury = false;<br />
static bool old_level_high = false;<br />
static bool old_level_low = false;<br />
<br />
<br />
/**<br />
 * @brief Print the current time from the RTC to the Serial Monitor.<br />
 */<br />
static void PrintfCurTime()<br />
{<br />
  Serial.print("Current time is: ");<br />
  int year = rtc.getYear() + 2000;<br />
  Serial.print(year);<br />
  Serial.print("-");<br />
<br />
  Serial.print(rtc.getMonth(bCentury), DEC);<br />
  Serial.print("-");<br />
<br />
  Serial.print(rtc.getDate(), DEC);<br />
  Serial.print(" ");<br />
<br />
  Serial.print(rtc.getHour(h12Flag, pmFlag), DEC);<br />
  Serial.print(":");<br />
  Serial.print(rtc.getMinute(), DEC);<br />
  Serial.print(":");<br />
  Serial.println(rtc.getSecond(), DEC);<br />
}<br />
<br />
/**<br />
 * @brief Process serial commands to set the RTC time.<br />
 * Command format: DYYYY-MM-DDTHH:MM:SS<br />
 */<br />
static void GetSerialCmd()<br />
{<br />
  if (Serial.available() &gt; 0)<br />
  {<br />
    delay(100);<br />
    int num_read = Serial.available();<br />
    while (num_read--)<br />
      serial_cmd_rcv += char(Serial.read());<br />
  }<br />
  else return;<br />
<br />
  serial_cmd_rcv.trim();<br />
<br />
  if (serial_cmd_rcv == "current time")<br />
  {<br />
    PrintfCurTime();<br />
    serial_cmd_rcv = "";<br />
    return;<br />
  }<br />
<br />
  Serial.print("Received length: ");<br />
  Serial.println(serial_cmd_rcv.length());<br />
<br />
  int indexof_d = serial_cmd_rcv.indexOf('D');<br />
  int indexof_t = serial_cmd_rcv.indexOf('T');<br />
<br />
  Serial.print("D index: ");<br />
  Serial.print(indexof_d);<br />
  Serial.print(" T index: ");<br />
  Serial.println(indexof_t);<br />
<br />
  if (serial_cmd_rcv.length() != 20 || <br />
      serial_cmd_rcv.substring(0, 1) != "D" ||<br />
      serial_cmd_rcv.substring(11, 12) != "T")  <br />
  {<br />
    Serial.println(serial_cmd_rcv);<br />
    serial_cmd_rcv = "";<br />
    return;<br />
  }<br />
<br />
  Serial.println("Setting time...");<br />
<br />
  my_date_str.year = (byte)serial_cmd_rcv.substring(3, 5).toInt();<br />
  my_date_str.month = (byte)serial_cmd_rcv.substring(6, 8).toInt();<br />
  my_date_str.day = (byte)serial_cmd_rcv.substring(9, 11).toInt();<br />
  my_date_str.hour = (byte)serial_cmd_rcv.substring(12, 14).toInt();<br />
  my_date_str.minute = (byte)serial_cmd_rcv.substring(15, 17).toInt();<br />
  my_date_str.second = (byte)serial_cmd_rcv.substring(18).toInt();<br />
<br />
  rtc.setYear(my_date_str.year);<br />
  rtc.setMonth(my_date_str.month);<br />
  rtc.setDate(my_date_str.day);<br />
  rtc.setHour(my_date_str.hour);<br />
  rtc.setMinute(my_date_str.minute);<br />
  rtc.setSecond(my_date_str.second);<br />
<br />
  serial_cmd_rcv = "";<br />
<br />
  Serial.println("Time set.");<br />
}<br />
<br />
void setup() {<br />
  // Initialize the I2C interface<br />
  Wire.begin(SDA_PIN, SCL_PIN, 40000);<br />
  <br />
  // Initialize Serial communication<br />
  Serial.begin(115200);<br />
 &nbsp;&nbsp;<br />
  // Set the RTC to 24-hour mode<br />
  rtc.setClockMode(false); // 24-hour format<br />
<br />
  // Print current time to Serial Monitor<br />
  PrintfCurTime();<br />
<br />
  // Clear any remaining serial data<br />
  while (Serial.read() &gt;= 0) {}<br />
}<br />
<br />
void loop() {<br />
  // Process incoming serial commands<br />
  GetSerialCmd(); <br />
  delay(1000); // Delay for 1 second<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8302" target="_blank" title="">7-DS3231-RTC.zip</a> (Size: 1.56 KB / Downloads: 288)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8303" target="_blank" title="">7-DS3231-RTC.ino.merged.zip</a> (Size: 191.08 KB / Downloads: 298)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for DM16]-06 How to use SD Card]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8513</link>
			<pubDate>Tue, 09 Sep 2025 11:01:40 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8513</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 * SD Card File Operations<br />
 *<br />
 * This program demonstrates basic file operations on an SD card using the ESP32.<br />
 * It includes functionality to:<br />
 * - Initialize and test the SD card<br />
 * - Read from, write to, append to, and delete files on the SD card<br />
 * - Measure file read and write performance<br />
 *<br />
 * Hardware Connections:<br />
 * - SCK: GPIO 11<br />
 * - MISO: GPIO 12<br />
 * - MOSI: GPIO 10<br />
 * - CS: GPIO 9<br />
 */<br />
<br />
#include "FS.h"<br />
#include "SD.h"<br />
#include "SPI.h"<br />
<br />
// Pin definitions for SD card<br />
#define SCK  11<br />
#define MISO 12<br />
#define MOSI 10<br />
#define CS &nbsp;&nbsp;9<br />
<br />
/**<br />
 * @brief Reads the contents of a file from the SD card and prints it to the serial monitor.<br />
 * <br />
 * @param fs File system to use (in this case, SD).<br />
 * @param path Path of the file to read.<br />
 */<br />
void readFile(fs::FS &amp;fs, const char * path) {<br />
  Serial.printf("Reading file: %s&#92;n", path);<br />
<br />
  File file = fs.open(path);<br />
  if (!file) {<br />
    Serial.println("Failed to open file for reading");<br />
    return;<br />
  }<br />
<br />
  Serial.print("Read from file: ");<br />
  while (file.available()) {<br />
    Serial.print((char)file.read());<br />
  }<br />
  file.close();<br />
}<br />
<br />
/**<br />
 * @brief Writes a message to a file on the SD card.<br />
 * <br />
 * @param fs File system to use (in this case, SD).<br />
 * @param path Path of the file to write.<br />
 * @param message Message to write to the file.<br />
 */<br />
void writeFile(fs::FS &amp;fs, const char * path, const char * message) {<br />
  Serial.printf("Writing file: %s&#92;n", path);<br />
<br />
  File file = fs.open(path, FILE_WRITE);<br />
  if (!file) {<br />
    Serial.println("Failed to open file for writing");<br />
    return;<br />
  }<br />
  if (file.print(message)) {<br />
    Serial.println("File written");<br />
  } else {<br />
    Serial.println("Write failed");<br />
  }<br />
  file.close();<br />
}<br />
<br />
/**<br />
 * @brief Appends a message to a file on the SD card.<br />
 * <br />
 * @param fs File system to use (in this case, SD).<br />
 * @param path Path of the file to append.<br />
 * @param message Message to append to the file.<br />
 */<br />
void appendFile(fs::FS &amp;fs, const char * path, const char * message) {<br />
  Serial.printf("Appending to file: %s&#92;n", path);<br />
<br />
  File file = fs.open(path, FILE_APPEND);<br />
  if (!file) {<br />
    Serial.println("Failed to open file for appending");<br />
    return;<br />
  }<br />
  if (file.print(message)) {<br />
    Serial.println("Message appended");<br />
  } else {<br />
    Serial.println("Append failed");<br />
  }<br />
  file.close();<br />
}<br />
<br />
/**<br />
 * @brief Deletes a file from the SD card.<br />
 * <br />
 * @param fs File system to use (in this case, SD).<br />
 * @param path Path of the file to delete.<br />
 */<br />
void deleteFile(fs::FS &amp;fs, const char * path) {<br />
  Serial.printf("Deleting file: %s&#92;n", path);<br />
  if (fs.remove(path)) {<br />
    Serial.println("File deleted");<br />
  } else {<br />
    Serial.println("Delete failed");<br />
  }<br />
}<br />
<br />
/**<br />
 * @brief Tests file read and write performance.<br />
 * <br />
 * @param fs File system to use (in this case, SD).<br />
 * @param path Path of the file to test.<br />
 */<br />
void testFileIO(fs::FS &amp;fs, const char * path) {<br />
  File file = fs.open(path);<br />
  static uint8_t buf[512];<br />
  size_t len = 0;<br />
  uint32_t start = millis();<br />
  uint32_t end = start;<br />
<br />
  if (file) {<br />
    len = file.size();<br />
    size_t flen = len;<br />
    start = millis();<br />
    while (len) {<br />
      size_t toRead = len;<br />
      if (toRead &gt; 512) {<br />
        toRead = 512;<br />
      }<br />
      file.read(buf, toRead);<br />
      len -= toRead;<br />
    }<br />
    end = millis() - start;<br />
    Serial.printf("%u bytes read for %u ms&#92;n", flen, end);<br />
    file.close();<br />
  } else {<br />
    Serial.println("Failed to open file for reading");<br />
  }<br />
<br />
  file = fs.open(path, FILE_WRITE);<br />
  if (!file) {<br />
    Serial.println("Failed to open file for writing");<br />
    return;<br />
  }<br />
<br />
  size_t i;<br />
  start = millis();<br />
  for (i = 0; i &lt; 2048; i++) {<br />
    file.write(buf, 512);<br />
  }<br />
  end = millis() - start;<br />
  Serial.printf("%u bytes written for %u ms&#92;n", 2048 * 512, end);<br />
  file.close();<br />
}<br />
<br />
void setup() {<br />
  // Initialize serial communication<br />
  Serial.begin(115200);<br />
  <br />
  // Initialize SPI and SD card<br />
  SPIClass spi = SPIClass(HSPI);<br />
  spi.begin(SCK, MISO, MOSI, CS);<br />
<br />
  if (!SD.begin(CS, spi, 80000000)) {<br />
    Serial.println("Card Mount Failed");<br />
    return;<br />
  }<br />
<br />
  uint8_t cardType = SD.cardType();<br />
<br />
  if (cardType == CARD_NONE) {<br />
    Serial.println("No SD card attached");<br />
    return;<br />
  }<br />
<br />
  Serial.print("SD Card Type: ");<br />
  if (cardType == CARD_MMC) {<br />
    Serial.println("MMC");<br />
  } else if (cardType == CARD_SD) {<br />
    Serial.println("SDSC");<br />
  } else if (cardType == CARD_SDHC) {<br />
    Serial.println("SDHC");<br />
  } else {<br />
    Serial.println("UNKNOWN");<br />
  }<br />
<br />
  uint64_t cardSize = SD.cardSize() / (1024 * 1024);<br />
  Serial.printf("SD Card Size: %lluMB&#92;n", cardSize);<br />
  delay(2000);<br />
<br />
  // Perform file operations<br />
  deleteFile(SD, "/hello.txt");<br />
  writeFile(SD, "/hello.txt", "Hello ");<br />
  appendFile(SD, "/hello.txt", "World!&#92;n");<br />
  readFile(SD, "/hello.txt");<br />
  testFileIO(SD, "/test.txt");<br />
  Serial.printf("Total space: %lluMB&#92;n", SD.totalBytes() / (1024 * 1024));<br />
  Serial.printf("Used space: %lluMB&#92;n", SD.usedBytes() / (1024 * 1024));<br />
}<br />
<br />
void loop() {<br />
  // No operation in loop<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8300" target="_blank" title="">6-SD.zip</a> (Size: 1.53 KB / Downloads: 278)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8301" target="_blank" title="">6-SD.ino.merged.zip</a> (Size: 221.25 KB / Downloads: 283)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 * SD Card File Operations<br />
 *<br />
 * This program demonstrates basic file operations on an SD card using the ESP32.<br />
 * It includes functionality to:<br />
 * - Initialize and test the SD card<br />
 * - Read from, write to, append to, and delete files on the SD card<br />
 * - Measure file read and write performance<br />
 *<br />
 * Hardware Connections:<br />
 * - SCK: GPIO 11<br />
 * - MISO: GPIO 12<br />
 * - MOSI: GPIO 10<br />
 * - CS: GPIO 9<br />
 */<br />
<br />
#include "FS.h"<br />
#include "SD.h"<br />
#include "SPI.h"<br />
<br />
// Pin definitions for SD card<br />
#define SCK  11<br />
#define MISO 12<br />
#define MOSI 10<br />
#define CS &nbsp;&nbsp;9<br />
<br />
/**<br />
 * @brief Reads the contents of a file from the SD card and prints it to the serial monitor.<br />
 * <br />
 * @param fs File system to use (in this case, SD).<br />
 * @param path Path of the file to read.<br />
 */<br />
void readFile(fs::FS &amp;fs, const char * path) {<br />
  Serial.printf("Reading file: %s&#92;n", path);<br />
<br />
  File file = fs.open(path);<br />
  if (!file) {<br />
    Serial.println("Failed to open file for reading");<br />
    return;<br />
  }<br />
<br />
  Serial.print("Read from file: ");<br />
  while (file.available()) {<br />
    Serial.print((char)file.read());<br />
  }<br />
  file.close();<br />
}<br />
<br />
/**<br />
 * @brief Writes a message to a file on the SD card.<br />
 * <br />
 * @param fs File system to use (in this case, SD).<br />
 * @param path Path of the file to write.<br />
 * @param message Message to write to the file.<br />
 */<br />
void writeFile(fs::FS &amp;fs, const char * path, const char * message) {<br />
  Serial.printf("Writing file: %s&#92;n", path);<br />
<br />
  File file = fs.open(path, FILE_WRITE);<br />
  if (!file) {<br />
    Serial.println("Failed to open file for writing");<br />
    return;<br />
  }<br />
  if (file.print(message)) {<br />
    Serial.println("File written");<br />
  } else {<br />
    Serial.println("Write failed");<br />
  }<br />
  file.close();<br />
}<br />
<br />
/**<br />
 * @brief Appends a message to a file on the SD card.<br />
 * <br />
 * @param fs File system to use (in this case, SD).<br />
 * @param path Path of the file to append.<br />
 * @param message Message to append to the file.<br />
 */<br />
void appendFile(fs::FS &amp;fs, const char * path, const char * message) {<br />
  Serial.printf("Appending to file: %s&#92;n", path);<br />
<br />
  File file = fs.open(path, FILE_APPEND);<br />
  if (!file) {<br />
    Serial.println("Failed to open file for appending");<br />
    return;<br />
  }<br />
  if (file.print(message)) {<br />
    Serial.println("Message appended");<br />
  } else {<br />
    Serial.println("Append failed");<br />
  }<br />
  file.close();<br />
}<br />
<br />
/**<br />
 * @brief Deletes a file from the SD card.<br />
 * <br />
 * @param fs File system to use (in this case, SD).<br />
 * @param path Path of the file to delete.<br />
 */<br />
void deleteFile(fs::FS &amp;fs, const char * path) {<br />
  Serial.printf("Deleting file: %s&#92;n", path);<br />
  if (fs.remove(path)) {<br />
    Serial.println("File deleted");<br />
  } else {<br />
    Serial.println("Delete failed");<br />
  }<br />
}<br />
<br />
/**<br />
 * @brief Tests file read and write performance.<br />
 * <br />
 * @param fs File system to use (in this case, SD).<br />
 * @param path Path of the file to test.<br />
 */<br />
void testFileIO(fs::FS &amp;fs, const char * path) {<br />
  File file = fs.open(path);<br />
  static uint8_t buf[512];<br />
  size_t len = 0;<br />
  uint32_t start = millis();<br />
  uint32_t end = start;<br />
<br />
  if (file) {<br />
    len = file.size();<br />
    size_t flen = len;<br />
    start = millis();<br />
    while (len) {<br />
      size_t toRead = len;<br />
      if (toRead &gt; 512) {<br />
        toRead = 512;<br />
      }<br />
      file.read(buf, toRead);<br />
      len -= toRead;<br />
    }<br />
    end = millis() - start;<br />
    Serial.printf("%u bytes read for %u ms&#92;n", flen, end);<br />
    file.close();<br />
  } else {<br />
    Serial.println("Failed to open file for reading");<br />
  }<br />
<br />
  file = fs.open(path, FILE_WRITE);<br />
  if (!file) {<br />
    Serial.println("Failed to open file for writing");<br />
    return;<br />
  }<br />
<br />
  size_t i;<br />
  start = millis();<br />
  for (i = 0; i &lt; 2048; i++) {<br />
    file.write(buf, 512);<br />
  }<br />
  end = millis() - start;<br />
  Serial.printf("%u bytes written for %u ms&#92;n", 2048 * 512, end);<br />
  file.close();<br />
}<br />
<br />
void setup() {<br />
  // Initialize serial communication<br />
  Serial.begin(115200);<br />
  <br />
  // Initialize SPI and SD card<br />
  SPIClass spi = SPIClass(HSPI);<br />
  spi.begin(SCK, MISO, MOSI, CS);<br />
<br />
  if (!SD.begin(CS, spi, 80000000)) {<br />
    Serial.println("Card Mount Failed");<br />
    return;<br />
  }<br />
<br />
  uint8_t cardType = SD.cardType();<br />
<br />
  if (cardType == CARD_NONE) {<br />
    Serial.println("No SD card attached");<br />
    return;<br />
  }<br />
<br />
  Serial.print("SD Card Type: ");<br />
  if (cardType == CARD_MMC) {<br />
    Serial.println("MMC");<br />
  } else if (cardType == CARD_SD) {<br />
    Serial.println("SDSC");<br />
  } else if (cardType == CARD_SDHC) {<br />
    Serial.println("SDHC");<br />
  } else {<br />
    Serial.println("UNKNOWN");<br />
  }<br />
<br />
  uint64_t cardSize = SD.cardSize() / (1024 * 1024);<br />
  Serial.printf("SD Card Size: %lluMB&#92;n", cardSize);<br />
  delay(2000);<br />
<br />
  // Perform file operations<br />
  deleteFile(SD, "/hello.txt");<br />
  writeFile(SD, "/hello.txt", "Hello ");<br />
  appendFile(SD, "/hello.txt", "World!&#92;n");<br />
  readFile(SD, "/hello.txt");<br />
  testFileIO(SD, "/test.txt");<br />
  Serial.printf("Total space: %lluMB&#92;n", SD.totalBytes() / (1024 * 1024));<br />
  Serial.printf("Used space: %lluMB&#92;n", SD.usedBytes() / (1024 * 1024));<br />
}<br />
<br />
void loop() {<br />
  // No operation in loop<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8300" target="_blank" title="">6-SD.zip</a> (Size: 1.53 KB / Downloads: 278)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8301" target="_blank" title="">6-SD.ino.merged.zip</a> (Size: 221.25 KB / Downloads: 283)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for DM16]-05 Read free GPIO state]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8512</link>
			<pubDate>Tue, 09 Sep 2025 11:00:30 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8512</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 * GPIO Status Monitoring<br />
 *<br />
 * This program monitors the status (high or low) of multiple GPIO pins on the ESP32-S3.<br />
 * It prints the status of the pins to the serial monitor whenever a change is detected.<br />
 *<br />
 * GPIO Pins Monitored:<br />
 * - GPIO 40<br />
 * - GPIO 7<br />
 * - GPIO 48<br />
 * - GPIO 47<br />
 * - GPIO 13<br />
 * - GPIO 14<br />
 * - GPIO 21<br />
 * - GPIO 0<br />
 *<br />
 * Hardware Requirements:<br />
 * - Connect the pins to appropriate devices or pull them to HIGH/LOW for testing<br />
 */<br />
<br />
#define GPIO_PIN_40 40<br />
#define GPIO_PIN_7 7<br />
#define GPIO_PIN_48 48<br />
#define GPIO_PIN_47 47<br />
#define GPIO_PIN_13 13<br />
#define GPIO_PIN_14 14<br />
#define GPIO_PIN_21 21<br />
#define GPIO_PIN_0 0<br />
<br />
// Store the previous state of the GPIO pins<br />
bool prevState[8] = {false, false, false, false, false, false, false, false};<br />
<br />
void setup() {<br />
  // Initialize serial communication for debugging purposes<br />
  Serial.begin(115200); // Initialize the serial monitor at 115200 baud<br />
  while (!Serial);      // Wait for the serial monitor to open<br />
<br />
  // Initialize GPIO pins as inputs<br />
  pinMode(GPIO_PIN_40, INPUT);<br />
  pinMode(GPIO_PIN_7, INPUT);<br />
  pinMode(GPIO_PIN_48, INPUT);<br />
  pinMode(GPIO_PIN_47, INPUT);<br />
  pinMode(GPIO_PIN_13, INPUT);<br />
  pinMode(GPIO_PIN_14, INPUT);<br />
  pinMode(GPIO_PIN_21, INPUT);<br />
  pinMode(GPIO_PIN_0, INPUT);<br />
<br />
  Serial.println("GPIO Status Monitoring Started");<br />
}<br />
<br />
void loop() {<br />
  // Read the current state of each GPIO pin<br />
  bool currentState[8];<br />
  currentState[0] = digitalRead(GPIO_PIN_40);<br />
  currentState[1] = digitalRead(GPIO_PIN_7);<br />
  currentState[2] = digitalRead(GPIO_PIN_48);<br />
  currentState[3] = digitalRead(GPIO_PIN_47);<br />
  currentState[4] = digitalRead(GPIO_PIN_13);<br />
  currentState[5] = digitalRead(GPIO_PIN_14);<br />
  currentState[6] = digitalRead(GPIO_PIN_21);<br />
  currentState[7] = digitalRead(GPIO_PIN_0);<br />
<br />
  // Check for changes in GPIO pin states<br />
  for (int i = 0; i &lt; 8; i++) {<br />
    if (currentState[i] != prevState[i]) {<br />
      // Print the pin number and its new state if it has changed<br />
      Serial.print("GPIO ");<br />
      Serial.print(i == 0 ? GPIO_PIN_40 : <br />
                 &nbsp;&nbsp;i == 1 ? GPIO_PIN_7 : <br />
                 &nbsp;&nbsp;i == 2 ? GPIO_PIN_48 : <br />
                 &nbsp;&nbsp;i == 3 ? GPIO_PIN_47 : <br />
                 &nbsp;&nbsp;i == 4 ? GPIO_PIN_13 : <br />
                 &nbsp;&nbsp;i == 5 ? GPIO_PIN_14 : <br />
                 &nbsp;&nbsp;i == 6 ? GPIO_PIN_21 : GPIO_PIN_0);<br />
      Serial.print(" changed to ");<br />
      Serial.println(currentState[i] ? "HIGH" : "LOW");<br />
      // Update the previous state<br />
      prevState[i] = currentState[i];<br />
    }<br />
  }<br />
<br />
  // Delay to avoid flooding the serial monitor<br />
  delay(100); // Adjust the delay as needed<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8298" target="_blank" title="">5-free-gpio-state.zip</a> (Size: 1.04 KB / Downloads: 283)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8299" target="_blank" title="">5-free-gpio-state.ino.merged.zip</a> (Size: 179.57 KB / Downloads: 267)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 * GPIO Status Monitoring<br />
 *<br />
 * This program monitors the status (high or low) of multiple GPIO pins on the ESP32-S3.<br />
 * It prints the status of the pins to the serial monitor whenever a change is detected.<br />
 *<br />
 * GPIO Pins Monitored:<br />
 * - GPIO 40<br />
 * - GPIO 7<br />
 * - GPIO 48<br />
 * - GPIO 47<br />
 * - GPIO 13<br />
 * - GPIO 14<br />
 * - GPIO 21<br />
 * - GPIO 0<br />
 *<br />
 * Hardware Requirements:<br />
 * - Connect the pins to appropriate devices or pull them to HIGH/LOW for testing<br />
 */<br />
<br />
#define GPIO_PIN_40 40<br />
#define GPIO_PIN_7 7<br />
#define GPIO_PIN_48 48<br />
#define GPIO_PIN_47 47<br />
#define GPIO_PIN_13 13<br />
#define GPIO_PIN_14 14<br />
#define GPIO_PIN_21 21<br />
#define GPIO_PIN_0 0<br />
<br />
// Store the previous state of the GPIO pins<br />
bool prevState[8] = {false, false, false, false, false, false, false, false};<br />
<br />
void setup() {<br />
  // Initialize serial communication for debugging purposes<br />
  Serial.begin(115200); // Initialize the serial monitor at 115200 baud<br />
  while (!Serial);      // Wait for the serial monitor to open<br />
<br />
  // Initialize GPIO pins as inputs<br />
  pinMode(GPIO_PIN_40, INPUT);<br />
  pinMode(GPIO_PIN_7, INPUT);<br />
  pinMode(GPIO_PIN_48, INPUT);<br />
  pinMode(GPIO_PIN_47, INPUT);<br />
  pinMode(GPIO_PIN_13, INPUT);<br />
  pinMode(GPIO_PIN_14, INPUT);<br />
  pinMode(GPIO_PIN_21, INPUT);<br />
  pinMode(GPIO_PIN_0, INPUT);<br />
<br />
  Serial.println("GPIO Status Monitoring Started");<br />
}<br />
<br />
void loop() {<br />
  // Read the current state of each GPIO pin<br />
  bool currentState[8];<br />
  currentState[0] = digitalRead(GPIO_PIN_40);<br />
  currentState[1] = digitalRead(GPIO_PIN_7);<br />
  currentState[2] = digitalRead(GPIO_PIN_48);<br />
  currentState[3] = digitalRead(GPIO_PIN_47);<br />
  currentState[4] = digitalRead(GPIO_PIN_13);<br />
  currentState[5] = digitalRead(GPIO_PIN_14);<br />
  currentState[6] = digitalRead(GPIO_PIN_21);<br />
  currentState[7] = digitalRead(GPIO_PIN_0);<br />
<br />
  // Check for changes in GPIO pin states<br />
  for (int i = 0; i &lt; 8; i++) {<br />
    if (currentState[i] != prevState[i]) {<br />
      // Print the pin number and its new state if it has changed<br />
      Serial.print("GPIO ");<br />
      Serial.print(i == 0 ? GPIO_PIN_40 : <br />
                 &nbsp;&nbsp;i == 1 ? GPIO_PIN_7 : <br />
                 &nbsp;&nbsp;i == 2 ? GPIO_PIN_48 : <br />
                 &nbsp;&nbsp;i == 3 ? GPIO_PIN_47 : <br />
                 &nbsp;&nbsp;i == 4 ? GPIO_PIN_13 : <br />
                 &nbsp;&nbsp;i == 5 ? GPIO_PIN_14 : <br />
                 &nbsp;&nbsp;i == 6 ? GPIO_PIN_21 : GPIO_PIN_0);<br />
      Serial.print(" changed to ");<br />
      Serial.println(currentState[i] ? "HIGH" : "LOW");<br />
      // Update the previous state<br />
      prevState[i] = currentState[i];<br />
    }<br />
  }<br />
<br />
  // Delay to avoid flooding the serial monitor<br />
  delay(100); // Adjust the delay as needed<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8298" target="_blank" title="">5-free-gpio-state.zip</a> (Size: 1.04 KB / Downloads: 283)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8299" target="_blank" title="">5-free-gpio-state.ino.merged.zip</a> (Size: 179.57 KB / Downloads: 267)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for DM16]-04 RS485 communication test]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8511</link>
			<pubDate>Tue, 09 Sep 2025 10:59:21 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8511</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 * RS485 Communication Test<br />
 *<br />
 * This program is a simple test for RS485 communication using ESP32-S3.<br />
 * It will send a message over RS485 and then read incoming messages.<br />
 * The TXD pin is defined as GPIO 18 and RXD pin is defined as GPIO 8.<br />
 */<br />
<br />
#include &lt;HardwareSerial.h&gt;<br />
<br />
// Define RS485 pins<br />
#define RS485_RXD 38<br />
#define RS485_TXD 39<br />
<br />
// Create a hardware serial object<br />
HardwareSerial rs485Serial(1);<br />
<br />
void setup() {<br />
  // Start serial communication for debugging<br />
  Serial.begin(115200);<br />
  while (!Serial);<br />
<br />
  // Initialize RS485 Serial communication<br />
  rs485Serial.begin(9600, SERIAL_8N1, RS485_RXD, RS485_TXD);<br />
  <br />
  Serial.println("RS485 Test Start");<br />
}<br />
<br />
void loop() {<br />
  // Send a test message<br />
  rs485Serial.println("Hello from KinCony B16!");<br />
<br />
  // Wait for a short period<br />
  delay(1000);<br />
<br />
  // Check if data is available to read<br />
  if (rs485Serial.available()) {<br />
    String receivedMessage = "";<br />
    while (rs485Serial.available()) {<br />
      char c = rs485Serial.read();<br />
      receivedMessage += c;<br />
    }<br />
    // Print the received message<br />
    Serial.print("Received: ");<br />
    Serial.println(receivedMessage);<br />
  }<br />
<br />
  // Wait before sending the next message<br />
  delay(2000);<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8296" target="_blank" title="">4-RS485-Test.zip</a> (Size: 763 bytes / Downloads: 280)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8297" target="_blank" title="">4-RS485-Test.ino.merged.zip</a> (Size: 184.34 KB / Downloads: 330)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 * RS485 Communication Test<br />
 *<br />
 * This program is a simple test for RS485 communication using ESP32-S3.<br />
 * It will send a message over RS485 and then read incoming messages.<br />
 * The TXD pin is defined as GPIO 18 and RXD pin is defined as GPIO 8.<br />
 */<br />
<br />
#include &lt;HardwareSerial.h&gt;<br />
<br />
// Define RS485 pins<br />
#define RS485_RXD 38<br />
#define RS485_TXD 39<br />
<br />
// Create a hardware serial object<br />
HardwareSerial rs485Serial(1);<br />
<br />
void setup() {<br />
  // Start serial communication for debugging<br />
  Serial.begin(115200);<br />
  while (!Serial);<br />
<br />
  // Initialize RS485 Serial communication<br />
  rs485Serial.begin(9600, SERIAL_8N1, RS485_RXD, RS485_TXD);<br />
  <br />
  Serial.println("RS485 Test Start");<br />
}<br />
<br />
void loop() {<br />
  // Send a test message<br />
  rs485Serial.println("Hello from KinCony B16!");<br />
<br />
  // Wait for a short period<br />
  delay(1000);<br />
<br />
  // Check if data is available to read<br />
  if (rs485Serial.available()) {<br />
    String receivedMessage = "";<br />
    while (rs485Serial.available()) {<br />
      char c = rs485Serial.read();<br />
      receivedMessage += c;<br />
    }<br />
    // Print the received message<br />
    Serial.print("Received: ");<br />
    Serial.println(receivedMessage);<br />
  }<br />
<br />
  // Wait before sending the next message<br />
  delay(2000);<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8296" target="_blank" title="">4-RS485-Test.zip</a> (Size: 763 bytes / Downloads: 280)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8297" target="_blank" title="">4-RS485-Test.ino.merged.zip</a> (Size: 184.34 KB / Downloads: 330)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for DM16]-03 Read ADS1115 analog input ports value]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8510</link>
			<pubDate>Tue, 09 Sep 2025 10:53:02 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8510</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * This program reads voltage values from the ADS1115 analog-to-digital converter<br />
 * on all four channels (A0, A1, A2, A3) and prints the results through the serial port.<br />
 * The ADS1115 communicates via the I2C protocol. This version of the code includes <br />
 * the capability to specify custom SDA and SCL pins for I2C communication.<br />
 *<br />
 * Copyright: Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 */<br />
<br />
#include &lt;Wire.h&gt;                // Library for I2C communication<br />
#include &lt;DFRobot_ADS1115.h&gt;   &nbsp;&nbsp;// Library for ADS1115 ADC module<br />
<br />
// Define the I2C SDA and SCL pins for communication with ADS1115<br />
#define SDA_PIN 8  <br />
#define SCL_PIN 18 <br />
<br />
// Initialize ADS1115 instance using the Wire library<br />
DFRobot_ADS1115 ads(&amp;Wire);<br />
<br />
void setup(void) <br />
{<br />
    // Begin serial communication at a baud rate of 115200<br />
    Serial.begin(115200);<br />
<br />
    // Initialize the I2C bus using the defined SDA and SCL pins<br />
    Wire.begin(SDA_PIN, SCL_PIN);<br />
<br />
    // Set the I2C address for the ADS1115 (default: 0x49)<br />
    ads.setAddr_ADS1115(ADS1115_IIC_ADDRESS0); &nbsp;&nbsp;// Address is 0x49<br />
<br />
    // Set the gain for the ADS1115 (2/3x gain allows for a maximum input voltage of 6.144V)<br />
    ads.setGain(eGAIN_TWOTHIRDS);<br />
<br />
    // Set the ADS1115 to operate in single-shot mode (each reading is a single conversion)<br />
    ads.setMode(eMODE_SINGLE);<br />
<br />
    // Set the sample rate to 128 samples per second (SPS)<br />
    ads.setRate(eRATE_128);<br />
<br />
    // Set the operational status mode to single-conversion start<br />
    ads.setOSMode(eOSMODE_SINGLE);<br />
<br />
    // Initialize the ADS1115 module<br />
    ads.init();<br />
}<br />
<br />
void loop(void) <br />
{<br />
    // Check if the ADS1115 is properly connected and functioning<br />
    if (ads.checkADS1115())<br />
    {<br />
        // Variables to store the voltage readings for each channel<br />
        int16_t adc0, adc1, adc2, adc3;<br />
<br />
        // Read the voltage from channel A0 and print the value<br />
        adc0 = ads.readVoltage(0);<br />
        Serial.print("A0:");<br />
        Serial.print(adc0);<br />
        Serial.print("mV,  ");    // Print the value in millivolts<br />
<br />
        // Read the voltage from channel A1 and print the value<br />
        adc1 = ads.readVoltage(1);<br />
        Serial.print("A1:");<br />
        Serial.print(adc1);<br />
        Serial.print("mV,  ");    // Print the value in millivolts<br />
<br />
        // Read the voltage from channel A2 and print the value<br />
        adc2 = ads.readVoltage(2);<br />
        Serial.print("A2:");<br />
        Serial.print(adc2);<br />
        Serial.print("mV,  ");    // Print the value in millivolts<br />
<br />
        // Read the voltage from channel A3 and print the value<br />
        adc3 = ads.readVoltage(3);<br />
        Serial.print("A3:");<br />
        Serial.print(adc3);<br />
        Serial.println("mV");   &nbsp;&nbsp;// Print the value in millivolts and end the line<br />
    }<br />
    else<br />
    {<br />
        // If ADS1115 is not connected, print a message indicating disconnection<br />
        Serial.println("ADS1115 Disconnected!");<br />
    }<br />
<br />
    // Wait for 1 second before the next loop iteration<br />
    delay(1000);<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8294" target="_blank" title="">3-ads1115_adc.zip</a> (Size: 1.2 KB / Downloads: 262)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8295" target="_blank" title="">3-ads1115_adc.ino.merged.zip</a> (Size: 190.05 KB / Downloads: 275)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * This program reads voltage values from the ADS1115 analog-to-digital converter<br />
 * on all four channels (A0, A1, A2, A3) and prints the results through the serial port.<br />
 * The ADS1115 communicates via the I2C protocol. This version of the code includes <br />
 * the capability to specify custom SDA and SCL pins for I2C communication.<br />
 *<br />
 * Copyright: Made by KinCony IoT: https://www.kincony.com<br />
 *<br />
 */<br />
<br />
#include &lt;Wire.h&gt;                // Library for I2C communication<br />
#include &lt;DFRobot_ADS1115.h&gt;   &nbsp;&nbsp;// Library for ADS1115 ADC module<br />
<br />
// Define the I2C SDA and SCL pins for communication with ADS1115<br />
#define SDA_PIN 8  <br />
#define SCL_PIN 18 <br />
<br />
// Initialize ADS1115 instance using the Wire library<br />
DFRobot_ADS1115 ads(&amp;Wire);<br />
<br />
void setup(void) <br />
{<br />
    // Begin serial communication at a baud rate of 115200<br />
    Serial.begin(115200);<br />
<br />
    // Initialize the I2C bus using the defined SDA and SCL pins<br />
    Wire.begin(SDA_PIN, SCL_PIN);<br />
<br />
    // Set the I2C address for the ADS1115 (default: 0x49)<br />
    ads.setAddr_ADS1115(ADS1115_IIC_ADDRESS0); &nbsp;&nbsp;// Address is 0x49<br />
<br />
    // Set the gain for the ADS1115 (2/3x gain allows for a maximum input voltage of 6.144V)<br />
    ads.setGain(eGAIN_TWOTHIRDS);<br />
<br />
    // Set the ADS1115 to operate in single-shot mode (each reading is a single conversion)<br />
    ads.setMode(eMODE_SINGLE);<br />
<br />
    // Set the sample rate to 128 samples per second (SPS)<br />
    ads.setRate(eRATE_128);<br />
<br />
    // Set the operational status mode to single-conversion start<br />
    ads.setOSMode(eOSMODE_SINGLE);<br />
<br />
    // Initialize the ADS1115 module<br />
    ads.init();<br />
}<br />
<br />
void loop(void) <br />
{<br />
    // Check if the ADS1115 is properly connected and functioning<br />
    if (ads.checkADS1115())<br />
    {<br />
        // Variables to store the voltage readings for each channel<br />
        int16_t adc0, adc1, adc2, adc3;<br />
<br />
        // Read the voltage from channel A0 and print the value<br />
        adc0 = ads.readVoltage(0);<br />
        Serial.print("A0:");<br />
        Serial.print(adc0);<br />
        Serial.print("mV,  ");    // Print the value in millivolts<br />
<br />
        // Read the voltage from channel A1 and print the value<br />
        adc1 = ads.readVoltage(1);<br />
        Serial.print("A1:");<br />
        Serial.print(adc1);<br />
        Serial.print("mV,  ");    // Print the value in millivolts<br />
<br />
        // Read the voltage from channel A2 and print the value<br />
        adc2 = ads.readVoltage(2);<br />
        Serial.print("A2:");<br />
        Serial.print(adc2);<br />
        Serial.print("mV,  ");    // Print the value in millivolts<br />
<br />
        // Read the voltage from channel A3 and print the value<br />
        adc3 = ads.readVoltage(3);<br />
        Serial.print("A3:");<br />
        Serial.print(adc3);<br />
        Serial.println("mV");   &nbsp;&nbsp;// Print the value in millivolts and end the line<br />
    }<br />
    else<br />
    {<br />
        // If ADS1115 is not connected, print a message indicating disconnection<br />
        Serial.println("ADS1115 Disconnected!");<br />
    }<br />
<br />
    // Wait for 1 second before the next loop iteration<br />
    delay(1000);<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8294" target="_blank" title="">3-ads1115_adc.zip</a> (Size: 1.2 KB / Downloads: 262)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8295" target="_blank" title="">3-ads1115_adc.ino.merged.zip</a> (Size: 190.05 KB / Downloads: 275)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for DM16]-02 Read digital input ports state]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8509</link>
			<pubDate>Tue, 09 Sep 2025 10:51:42 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8509</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * -----------------------------------------------------------------------------<br />
 * KinCony DM16 16-Channel Digital Input Reader using PCF8575<br />
 * <br />
 * This Arduino sketch reads the state of 16 digital input channels from a <br />
 * PCF8575 I/O expander over I2C and prints their status to the serial monitor.<br />
 * <br />
 * Input logic:<br />
 * &nbsp;&nbsp;- Input 0 = ON<br />
 * &nbsp;&nbsp;- Input 1 = OFF (with pull-up logic)<br />
 * <br />
 * Hardware:<br />
 * &nbsp;&nbsp;- PCF8575 I/O Expander (I2C Address: 0x22)<br />
 * &nbsp;&nbsp;- Custom input pin mapping as defined below<br />
 * &nbsp;&nbsp;- I2C SDA pin: GPIO8<br />
 * &nbsp;&nbsp;- I2C SCL pin: GPIO18<br />
 * <br />
 * Author: KinCony IoT<br />
 * Website: https://www.kincony.com<br />
 * License: MIT License<br />
 * -----------------------------------------------------------------------------<br />
 */<br />
<br />
#include &lt;Wire.h&gt;<br />
#include "PCF8575.h"<br />
<br />
// Define I2C pins<br />
#define I2C_SDA 8 &nbsp;&nbsp;// SDA pin<br />
#define I2C_SCL 18  // SCL pin<br />
<br />
// Set the I2C address for PCF8575<br />
PCF8575 pcf8575_IN1(0x22); // 0x22 is the I2C address for the DM16 module<br />
<br />
void setup() {<br />
    Serial.begin(115200);<br />
<br />
    // Initialize I2C with specified SDA and SCL pins<br />
    Wire.begin(I2C_SDA, I2C_SCL);<br />
<br />
    // Start communication with PCF8575 device<br />
    pcf8575_IN1.begin();<br />
<br />
    Serial.println("KinCony DM16 16 channel input state 0:ON  1:OFF");<br />
}<br />
<br />
void loop() {<br />
    // Define custom pin read order to match hardware mapping<br />
    uint8_t pin_order[16] = {<br />
        8, 9, 10, 11, 12, 13, 14, 15,<br />
        0, 1, 2, 3, 4, 5, 6, 7<br />
    };<br />
<br />
    Serial.print("Input state: ");<br />
<br />
    // Loop through all 16 pins and read their state<br />
    for (int i = 0; i &lt; 16; i++) {<br />
        bool state = pcf8575_IN1.read(pin_order[i]); // Read pin state (HIGH or LOW)<br />
        Serial.print(state); // Print state: 0 = ON, 1 = OFF<br />
        Serial.print(" ");<br />
    }<br />
<br />
    Serial.println(); // Print new line<br />
    delay(500);     &nbsp;&nbsp;// Wait for 500ms before next read<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8292" target="_blank" title="">2-digital-input.zip</a> (Size: 995 bytes / Downloads: 288)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8293" target="_blank" title="">2-digital-input.ino.merged.zip</a> (Size: 192.34 KB / Downloads: 287)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * -----------------------------------------------------------------------------<br />
 * KinCony DM16 16-Channel Digital Input Reader using PCF8575<br />
 * <br />
 * This Arduino sketch reads the state of 16 digital input channels from a <br />
 * PCF8575 I/O expander over I2C and prints their status to the serial monitor.<br />
 * <br />
 * Input logic:<br />
 * &nbsp;&nbsp;- Input 0 = ON<br />
 * &nbsp;&nbsp;- Input 1 = OFF (with pull-up logic)<br />
 * <br />
 * Hardware:<br />
 * &nbsp;&nbsp;- PCF8575 I/O Expander (I2C Address: 0x22)<br />
 * &nbsp;&nbsp;- Custom input pin mapping as defined below<br />
 * &nbsp;&nbsp;- I2C SDA pin: GPIO8<br />
 * &nbsp;&nbsp;- I2C SCL pin: GPIO18<br />
 * <br />
 * Author: KinCony IoT<br />
 * Website: https://www.kincony.com<br />
 * License: MIT License<br />
 * -----------------------------------------------------------------------------<br />
 */<br />
<br />
#include &lt;Wire.h&gt;<br />
#include "PCF8575.h"<br />
<br />
// Define I2C pins<br />
#define I2C_SDA 8 &nbsp;&nbsp;// SDA pin<br />
#define I2C_SCL 18  // SCL pin<br />
<br />
// Set the I2C address for PCF8575<br />
PCF8575 pcf8575_IN1(0x22); // 0x22 is the I2C address for the DM16 module<br />
<br />
void setup() {<br />
    Serial.begin(115200);<br />
<br />
    // Initialize I2C with specified SDA and SCL pins<br />
    Wire.begin(I2C_SDA, I2C_SCL);<br />
<br />
    // Start communication with PCF8575 device<br />
    pcf8575_IN1.begin();<br />
<br />
    Serial.println("KinCony DM16 16 channel input state 0:ON  1:OFF");<br />
}<br />
<br />
void loop() {<br />
    // Define custom pin read order to match hardware mapping<br />
    uint8_t pin_order[16] = {<br />
        8, 9, 10, 11, 12, 13, 14, 15,<br />
        0, 1, 2, 3, 4, 5, 6, 7<br />
    };<br />
<br />
    Serial.print("Input state: ");<br />
<br />
    // Loop through all 16 pins and read their state<br />
    for (int i = 0; i &lt; 16; i++) {<br />
        bool state = pcf8575_IN1.read(pin_order[i]); // Read pin state (HIGH or LOW)<br />
        Serial.print(state); // Print state: 0 = ON, 1 = OFF<br />
        Serial.print(" ");<br />
    }<br />
<br />
    Serial.println(); // Print new line<br />
    delay(500);     &nbsp;&nbsp;// Wait for 500ms before next read<br />
}</code></div></div> arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8292" target="_blank" title="">2-digital-input.zip</a> (Size: 995 bytes / Downloads: 288)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:  <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8293" target="_blank" title="">2-digital-input.ino.merged.zip</a> (Size: 192.34 KB / Downloads: 287)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for DM16]-01 16 Channel DAC output by digital input]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8508</link>
			<pubDate>Tue, 09 Sep 2025 10:49:43 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8508</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#include &lt;Adafruit_PCF8575.h&gt;<br />
#include &lt;HardwareSerial.h&gt;<br />
<br />
// Define Modbus RTU frame format constants<br />
#define MODBUS_READ_COILS 0x01<br />
#define MODBUS_READ_REGISTERS 0x03<br />
#define MODBUS_WRITE_SINGLE_REGISTER 0x06<br />
#define MODBUS_WRITE_MULTIPLE_REGISTERS 0x10<br />
<br />
/* Example for 16 input buttons that are connected from the GPIO expander pins to ground.<br />
 * Note the buttons must be connected with the other side of the switch to GROUND. There is<br />
 * a built in pull-up 'resistor' on each input, but no pull-down resistor capability.<br />
 */<br />
<br />
#define DM_NUMS 16 // change for 16, 32 for KinCony DM16, DM32 Smart Dimmer Controller<br />
<br />
<br />
#define SDA_PIN 8<br />
#define SCL_PIN 18<br />
#define ADDRESS_PCF8575   &nbsp;&nbsp;0x22<br />
#define ADDRESS_PCF8575_2 &nbsp;&nbsp;0x24<br />
<br />
#define ST_RX &nbsp;&nbsp;4 ////ESP32_RCV<br />
#define ST_TX &nbsp;&nbsp;6 ///ESP32_SEND<br />
typedef enum{KEY_RELEASE=0,KEY_SHORT_PRESSED,KEY_LONG_PRESSED}KEY_STATUS;<br />
<br />
typedef struct{<br />
  uint8_t key_index;<br />
  KEY_STATUS key_status;<br />
  long key_time_start;<br />
  long key_time_rec;<br />
  long key_press_time;<br />
  int16_t key_press_cnt; ////Send serial data once every 100 ms<br />
  int16_t key_press_cnt_old;<br />
  float current_light; ///Percentage of 0–4095<br />
}KEY_PRESS_PROP;<br />
<br />
KEY_PRESS_PROP key_press_prop[32] = {0};<br />
<br />
<br />
Adafruit_PCF8575 pcf,pcf2;<br />
HardwareSerial myst_serial(1);<br />
<br />
TwoWire myI2c = TwoWire(0);<br />
ushort dm_num = DM_NUMS;<br />
<br />
// Modbus CRC16 Calculation function<br />
uint16_t modbus_crc16(uint8_t *data, uint16_t length) {<br />
  uint16_t crc = 0xFFFF;<br />
  <br />
  for (uint16_t i = 0; i &lt; length; i++) {<br />
    crc ^= data[i];<br />
    for (uint8_t j = 0; j &lt; 8; j++) {<br />
      if (crc &amp; 0x0001) {<br />
        crc = (crc &gt;&gt; 1) ^ 0xA001;<br />
      } else {<br />
        crc = crc &gt;&gt; 1;<br />
      }<br />
    }<br />
  }<br />
  return crc;<br />
}<br />
<br />
/**<br />
 * Send a Modbus RTU frame<br />
 * <br />
 * @param serial HardwareSerial object<br />
 * @param address Slave address (1-247)<br />
 * @param function function code<br />
 * @param data <br />
 * @param dataLen<br />
 */<br />
void send_modbus_frame(HardwareSerial &amp;serial, uint8_t address, uint8_t function, <br />
                      const uint8_t *data, uint16_t dataLen) {<br />
  // Create a transmit buffer<br />
  uint16_t totalLen = 1 + 1 + dataLen + 2; // address + function code + data + CRC<br />
  uint8_t buffer[totalLen];<br />
  <br />
  buffer[0] = address;<br />
  buffer[1] = function;<br />
  <br />
  memcpy(&amp;buffer[2], data, dataLen);<br />
  <br />
  uint16_t crc = modbus_crc16(buffer, 2 + dataLen);<br />
  <br />
  // Add CRC (low byte first)<br />
  buffer[2 + dataLen] = crc &amp; 0xFF;      // CRC low byte<br />
  buffer[3 + dataLen] = (crc &gt;&gt; 8) &amp; 0xFF; // CRC high byte<br />
  <br />
  // Send the complete frame<br />
  for (uint16_t i = 0; i &lt; totalLen; i++) {<br />
    serial.write(buffer[i]);<br />
  }<br />
  <br />
  // Flush the transmit buffer to ensure all data is sent<br />
  serial.flush();<br />
}<br />
<br />
// Encapsulate commonly used Modbus functions<br />
<br />
/**<br />
 * Send a Read Holding Registers request<br />
 * <br />
 * @param serial <br />
 * @param address <br />
 * @param startReg <br />
 * @param numRegs<br />
 */<br />
void modbus_read_registers(HardwareSerial &amp;serial, uint8_t address, <br />
                          uint16_t startReg, uint16_t numRegs) {<br />
  uint8_t data[4];<br />
  <br />
  <br />
  data[0] = (startReg &gt;&gt; 8) &amp; 0xFF; // High byte of the register address<br />
  data[1] = startReg &amp; 0xFF;        // Low byte of the register address<br />
  data[2] = (numRegs &gt;&gt; 8) &amp; 0xFF;  // High byte of the register count<br />
  data[3] = numRegs &amp; 0xFF;       &nbsp;&nbsp;// Low byte of the register count<br />
  <br />
  send_modbus_frame(serial, address, MODBUS_READ_REGISTERS, data, sizeof(data));<br />
}<br />
<br />
/**<br />
 * <br />
 * @param serial <br />
 * @param address <br />
 * @param regAddress <br />
 * @param value<br />
 */<br />
void modbus_write_single_register(HardwareSerial &amp;serial, uint8_t address,<br />
                                uint16_t regAddress, uint16_t value) {<br />
  uint8_t data[4];<br />
  <br />
  data[0] = (regAddress &gt;&gt; 8) &amp; 0xFF; // High byte of the register address<br />
  data[1] = regAddress &amp; 0xFF;        // Low byte of the register address<br />
  data[2] = (value &gt;&gt; 8) &amp; 0xFF;      // High byte of the data<br />
  data[3] = value &amp; 0xFF;           &nbsp;&nbsp;// Low byte of the<br />
  <br />
  send_modbus_frame(serial, address, MODBUS_WRITE_SINGLE_REGISTER, data, sizeof(data));<br />
}<br />
<br />
/**<br />
 * <br />
 * @param serial <br />
 * @param address <br />
 * @param startReg <br />
 * @param values <br />
 * @param numRegs <br />
 */<br />
void modbus_write_multiple_registers(HardwareSerial &amp;serial, uint8_t address,<br />
                                 &nbsp;&nbsp;uint16_t startReg, const uint16_t *values,<br />
                                 &nbsp;&nbsp;uint16_t numRegs) {<br />
<br />
  uint8_t byteCount = numRegs * 2;<br />
  uint8_t data[5 + byteCount];<br />
  <br />
<br />
  data[0] = (startReg &gt;&gt; 8) &amp; 0xFF;  <br />
  data[1] = startReg &amp; 0xFF;       &nbsp;&nbsp;<br />
  data[2] = (numRegs &gt;&gt; 8) &amp; 0xFF; &nbsp;&nbsp;<br />
  data[3] = numRegs &amp; 0xFF;     &nbsp;&nbsp;<br />
  data[4] = byteCount;              <br />
  <br />
<br />
  for (uint8_t i = 0; i &lt; numRegs; i++) {<br />
    data[5 + i*2] = (values[i] &gt;&gt; 8) &amp; 0xFF; &nbsp;&nbsp;<br />
    data[6 + i*2] = values[i] &amp; 0xFF;          <br />
  }<br />
  <br />
  send_modbus_frame(serial, address, MODBUS_WRITE_MULTIPLE_REGISTERS, data, sizeof(data));<br />
}<br />
<br />
void setup() {<br />
  Serial.begin(115200);<br />
  myI2c.begin(SDA_PIN,SCL_PIN,100000);<br />
  myst_serial.begin(115200,SERIAL_8N1,ST_RX,ST_TX);///RXPIN FIRST<br />
<br />
  while (!Serial) { delay(10); }<br />
  Serial.println("Adafruit PCF8575 button read test");<br />
<br />
  if (!pcf.begin(ADDRESS_PCF8575, &amp;myI2c)) {<br />
    Serial.println("err:DMxx Couldn't find 1_PCF8575!");<br />
    while (1);<br />
  }<br />
  else Serial.println("Find 1_PCF8575!");<br />
<br />
  if(dm_num==32)<br />
  {<br />
    if (!pcf2.begin(ADDRESS_PCF8575_2, &amp;myI2c)) {<br />
    Serial.println("DM32 Couldn't find 2_PCF8575"); <br />
    }<br />
    else Serial.println("Find 2_PCF8575!");<br />
  }<br />
 &nbsp;&nbsp;<br />
<br />
  for (uint8_t p=0; p&lt;DM_NUMS; p++) {<br />
    pcf.pinMode(p, INPUT_PULLUP);<br />
    if(dm_num==32) pcf2.pinMode(p-16, INPUT_PULLUP);<br />
    <br />
    key_press_prop[p].key_index = p+1;<br />
    key_press_prop[p].key_status = KEY_RELEASE;<br />
    key_press_prop[p].key_press_time = 0;<br />
  }<br />
<br />
  Serial.println("Now, starting!"); <br />
<br />
<br />
}<br />
<br />
<br />
<br />
static uint16_t input_value_old[2] = {0xffff,0xffff};<br />
uint16_t input_value[2] = {0} ;<br />
int8_t current_operator_key = -1;<br />
int8_t key_index = -1,key_index_last = -1;<br />
int16_t key_press_cnt_old = 0;<br />
uint16_t write_value=0;<br />
<br />
static int8_t get_key_press(int8_t chip,uint16_t key_value)<br />
{<br />
  if(key_value == 0xffff || key_value == 0) return -1;<br />
<br />
  for(int16_t i=0;i&lt;16;i++) <br />
  {<br />
    if((key_value &amp; (1&lt;&lt;i) ) == 0)  return (chip==0)?i:i+16; <br />
  }<br />
}<br />
<br />
static uint16_t getKeycode()<br />
{<br />
  uint16_t input_value = 0,tmp_value;<br />
  uint8_t h_value = 0 ,l_value = 0;<br />
  tmp_value = pcf.digitalReadWord();<br />
  h_value = tmp_value&gt;&gt;8;<br />
  l_value = tmp_value&amp;0xff;<br />
  input_value = (l_value&lt;&lt;8 ) | h_value;<br />
<br />
  return input_value;<br />
}<br />
<br />
static uint16_t getKeycode2()<br />
{<br />
  uint16_t input_value = 0,tmp_value;<br />
  uint8_t h_value = 0 ,l_value = 0;<br />
  tmp_value = pcf2.digitalReadWord();<br />
  h_value = tmp_value&gt;&gt;8;<br />
  l_value = tmp_value&amp;0xff;<br />
  input_value = (l_value ) | (h_value&lt;&lt;8);<br />
<br />
  return input_value;<br />
}<br />
<br />
static void checkKeyPress(int8_t chip);<br />
<br />
static uint16_t key_old_arr[2] = {0};<br />
<br />
void loop() { <br />
<br />
  input_value[0] = getKeycode(); <br />
  /*if(key_old_arr[0] != input_value[0] )<br />
  {<br />
    key_old_arr[0] = input_value[0];<br />
    Serial.printf("input0:%d&#92;r&#92;n",input_value[0]);<br />
  }*/<br />
  <br />
  checkKeyPress(0);<br />
<br />
  if(dm_num == 32)<br />
  {<br />
    delay(10);<br />
    input_value[1] = getKeycode2();<br />
    checkKeyPress(1);<br />
    /*if(key_old_arr[1] != input_value[1] )<br />
    {<br />
      key_old_arr[1] = input_value[1];<br />
      Serial.printf("input1:%d&#92;r&#92;n",input_value[1]);<br />
    }*/<br />
  }<br />
  <br />
<br />
<br />
  delay(10); // a short debounce delay<br />
}<br />
<br />
static void checkKeyPress(int8_t chip)<br />
{<br />
  uint8_t start_index = (chip==0)?0:16;<br />
  if(input_value_old[chip] != input_value[chip])<br />
  {<br />
    input_value_old[chip] = input_value[chip];<br />
    if(input_value[chip] == 0xffff)<br />
    {<br />
      Serial.printf("key is released!");<br />
     &nbsp;&nbsp;<br />
      current_operator_key = -1;<br />
      key_index_last = key_index = -1;<br />
<br />
      for (uint8_t p=start_index; p&lt;16+start_index; p++) ///all key status init.<br />
      {<br />
        key_press_prop[p].key_index = p+1;<br />
        key_press_prop[p].key_status = KEY_RELEASE;<br />
        key_press_prop[p].key_time_start = 0;<br />
        key_press_prop[p].key_press_time = 0;<br />
        key_press_prop[p].key_time_rec = 0;<br />
        key_press_prop[p].key_press_cnt = 0;<br />
        key_press_prop[p].key_press_cnt_old = 0;<br />
      }<br />
    }<br />
    else ///key press<br />
    {<br />
      //Serial.printf("input_value = %04X &#92;r&#92;n",input_value);<br />
      key_index = get_key_press(chip,input_value[chip]);<br />
      if(key_index &gt;= 0) <br />
      {<br />
        key_index_last = key_index;<br />
        Serial.printf("key %02d # is pressed! &#92;r&#92;n",key_index+1); <br />
        current_operator_key = key_index;<br />
        key_press_prop[current_operator_key].key_status = KEY_SHORT_PRESSED;<br />
        key_press_prop[current_operator_key].key_time_start = millis();<br />
        key_press_prop[current_operator_key].key_press_time = 0;<br />
      }<br />
    }<br />
  }<br />
  else<br />
  {<br />
    if(input_value[chip] != 0xffff) ///LONG PRESS!<br />
    {<br />
      //Serial.printf("key long pressed! &#92;r&#92;n");<br />
<br />
      key_index = get_key_press(chip,input_value[chip]);<br />
      if(key_index &gt;= 0 &amp;&amp; key_index_last == key_index) <br />
      { <br />
        //Serial.printf("key long pressed! key_index = %d&#92;r&#92;n",key_index);<br />
<br />
        current_operator_key = key_index;<br />
        key_press_prop[current_operator_key].key_status = KEY_LONG_PRESSED;<br />
        key_press_prop[current_operator_key].key_time_rec = millis();<br />
        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;<br />
        key_press_prop[current_operator_key].key_press_cnt = (key_press_prop[current_operator_key].key_press_time % 4080 ) / 100; ////100MS发一次<br />
<br />
        //Serial.printf("key long time = %d, cnt = %d &#92;r&#92;n",key_press_prop[current_operator_key].key_press_time,key_press_prop[current_operator_key].key_press_cnt);<br />
<br />
        if(key_press_prop[current_operator_key].key_press_cnt_old != key_press_prop[current_operator_key].key_press_cnt)<br />
        {<br />
          key_press_prop[current_operator_key].key_press_cnt_old = key_press_prop[current_operator_key].key_press_cnt;<br />
          /////send st_tx information.<br />
          key_press_prop[current_operator_key].current_light = (float)key_press_prop[current_operator_key].key_press_cnt * 100.0f;<br />
          write_value = (uint16_t) key_press_prop[current_operator_key].current_light;<br />
<br />
          Serial.printf("key_long_press_time = %d, current_light = %d &#92;r&#92;n",key_press_prop[current_operator_key].key_press_time,write_value);<br />
<br />
          modbus_write_multiple_registers(myst_serial,1,4000+current_operator_key,&amp;write_value,1);<br />
<br />
<br />
        }<br />
      }<br />
    }<br />
  }<br />
<br />
}</code></div></div><br />
arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8848" target="_blank" title="">1-dac-16ch.zip</a> (Size: 2.95 KB / Downloads: 105)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8849" target="_blank" title="">1-dac-16ch.ino.merged.zip</a> (Size: 205.71 KB / Downloads: 99)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#include &lt;Adafruit_PCF8575.h&gt;<br />
#include &lt;HardwareSerial.h&gt;<br />
<br />
// Define Modbus RTU frame format constants<br />
#define MODBUS_READ_COILS 0x01<br />
#define MODBUS_READ_REGISTERS 0x03<br />
#define MODBUS_WRITE_SINGLE_REGISTER 0x06<br />
#define MODBUS_WRITE_MULTIPLE_REGISTERS 0x10<br />
<br />
/* Example for 16 input buttons that are connected from the GPIO expander pins to ground.<br />
 * Note the buttons must be connected with the other side of the switch to GROUND. There is<br />
 * a built in pull-up 'resistor' on each input, but no pull-down resistor capability.<br />
 */<br />
<br />
#define DM_NUMS 16 // change for 16, 32 for KinCony DM16, DM32 Smart Dimmer Controller<br />
<br />
<br />
#define SDA_PIN 8<br />
#define SCL_PIN 18<br />
#define ADDRESS_PCF8575   &nbsp;&nbsp;0x22<br />
#define ADDRESS_PCF8575_2 &nbsp;&nbsp;0x24<br />
<br />
#define ST_RX &nbsp;&nbsp;4 ////ESP32_RCV<br />
#define ST_TX &nbsp;&nbsp;6 ///ESP32_SEND<br />
typedef enum{KEY_RELEASE=0,KEY_SHORT_PRESSED,KEY_LONG_PRESSED}KEY_STATUS;<br />
<br />
typedef struct{<br />
  uint8_t key_index;<br />
  KEY_STATUS key_status;<br />
  long key_time_start;<br />
  long key_time_rec;<br />
  long key_press_time;<br />
  int16_t key_press_cnt; ////Send serial data once every 100 ms<br />
  int16_t key_press_cnt_old;<br />
  float current_light; ///Percentage of 0–4095<br />
}KEY_PRESS_PROP;<br />
<br />
KEY_PRESS_PROP key_press_prop[32] = {0};<br />
<br />
<br />
Adafruit_PCF8575 pcf,pcf2;<br />
HardwareSerial myst_serial(1);<br />
<br />
TwoWire myI2c = TwoWire(0);<br />
ushort dm_num = DM_NUMS;<br />
<br />
// Modbus CRC16 Calculation function<br />
uint16_t modbus_crc16(uint8_t *data, uint16_t length) {<br />
  uint16_t crc = 0xFFFF;<br />
  <br />
  for (uint16_t i = 0; i &lt; length; i++) {<br />
    crc ^= data[i];<br />
    for (uint8_t j = 0; j &lt; 8; j++) {<br />
      if (crc &amp; 0x0001) {<br />
        crc = (crc &gt;&gt; 1) ^ 0xA001;<br />
      } else {<br />
        crc = crc &gt;&gt; 1;<br />
      }<br />
    }<br />
  }<br />
  return crc;<br />
}<br />
<br />
/**<br />
 * Send a Modbus RTU frame<br />
 * <br />
 * @param serial HardwareSerial object<br />
 * @param address Slave address (1-247)<br />
 * @param function function code<br />
 * @param data <br />
 * @param dataLen<br />
 */<br />
void send_modbus_frame(HardwareSerial &amp;serial, uint8_t address, uint8_t function, <br />
                      const uint8_t *data, uint16_t dataLen) {<br />
  // Create a transmit buffer<br />
  uint16_t totalLen = 1 + 1 + dataLen + 2; // address + function code + data + CRC<br />
  uint8_t buffer[totalLen];<br />
  <br />
  buffer[0] = address;<br />
  buffer[1] = function;<br />
  <br />
  memcpy(&amp;buffer[2], data, dataLen);<br />
  <br />
  uint16_t crc = modbus_crc16(buffer, 2 + dataLen);<br />
  <br />
  // Add CRC (low byte first)<br />
  buffer[2 + dataLen] = crc &amp; 0xFF;      // CRC low byte<br />
  buffer[3 + dataLen] = (crc &gt;&gt; 8) &amp; 0xFF; // CRC high byte<br />
  <br />
  // Send the complete frame<br />
  for (uint16_t i = 0; i &lt; totalLen; i++) {<br />
    serial.write(buffer[i]);<br />
  }<br />
  <br />
  // Flush the transmit buffer to ensure all data is sent<br />
  serial.flush();<br />
}<br />
<br />
// Encapsulate commonly used Modbus functions<br />
<br />
/**<br />
 * Send a Read Holding Registers request<br />
 * <br />
 * @param serial <br />
 * @param address <br />
 * @param startReg <br />
 * @param numRegs<br />
 */<br />
void modbus_read_registers(HardwareSerial &amp;serial, uint8_t address, <br />
                          uint16_t startReg, uint16_t numRegs) {<br />
  uint8_t data[4];<br />
  <br />
  <br />
  data[0] = (startReg &gt;&gt; 8) &amp; 0xFF; // High byte of the register address<br />
  data[1] = startReg &amp; 0xFF;        // Low byte of the register address<br />
  data[2] = (numRegs &gt;&gt; 8) &amp; 0xFF;  // High byte of the register count<br />
  data[3] = numRegs &amp; 0xFF;       &nbsp;&nbsp;// Low byte of the register count<br />
  <br />
  send_modbus_frame(serial, address, MODBUS_READ_REGISTERS, data, sizeof(data));<br />
}<br />
<br />
/**<br />
 * <br />
 * @param serial <br />
 * @param address <br />
 * @param regAddress <br />
 * @param value<br />
 */<br />
void modbus_write_single_register(HardwareSerial &amp;serial, uint8_t address,<br />
                                uint16_t regAddress, uint16_t value) {<br />
  uint8_t data[4];<br />
  <br />
  data[0] = (regAddress &gt;&gt; 8) &amp; 0xFF; // High byte of the register address<br />
  data[1] = regAddress &amp; 0xFF;        // Low byte of the register address<br />
  data[2] = (value &gt;&gt; 8) &amp; 0xFF;      // High byte of the data<br />
  data[3] = value &amp; 0xFF;           &nbsp;&nbsp;// Low byte of the<br />
  <br />
  send_modbus_frame(serial, address, MODBUS_WRITE_SINGLE_REGISTER, data, sizeof(data));<br />
}<br />
<br />
/**<br />
 * <br />
 * @param serial <br />
 * @param address <br />
 * @param startReg <br />
 * @param values <br />
 * @param numRegs <br />
 */<br />
void modbus_write_multiple_registers(HardwareSerial &amp;serial, uint8_t address,<br />
                                 &nbsp;&nbsp;uint16_t startReg, const uint16_t *values,<br />
                                 &nbsp;&nbsp;uint16_t numRegs) {<br />
<br />
  uint8_t byteCount = numRegs * 2;<br />
  uint8_t data[5 + byteCount];<br />
  <br />
<br />
  data[0] = (startReg &gt;&gt; 8) &amp; 0xFF;  <br />
  data[1] = startReg &amp; 0xFF;       &nbsp;&nbsp;<br />
  data[2] = (numRegs &gt;&gt; 8) &amp; 0xFF; &nbsp;&nbsp;<br />
  data[3] = numRegs &amp; 0xFF;     &nbsp;&nbsp;<br />
  data[4] = byteCount;              <br />
  <br />
<br />
  for (uint8_t i = 0; i &lt; numRegs; i++) {<br />
    data[5 + i*2] = (values[i] &gt;&gt; 8) &amp; 0xFF; &nbsp;&nbsp;<br />
    data[6 + i*2] = values[i] &amp; 0xFF;          <br />
  }<br />
  <br />
  send_modbus_frame(serial, address, MODBUS_WRITE_MULTIPLE_REGISTERS, data, sizeof(data));<br />
}<br />
<br />
void setup() {<br />
  Serial.begin(115200);<br />
  myI2c.begin(SDA_PIN,SCL_PIN,100000);<br />
  myst_serial.begin(115200,SERIAL_8N1,ST_RX,ST_TX);///RXPIN FIRST<br />
<br />
  while (!Serial) { delay(10); }<br />
  Serial.println("Adafruit PCF8575 button read test");<br />
<br />
  if (!pcf.begin(ADDRESS_PCF8575, &amp;myI2c)) {<br />
    Serial.println("err:DMxx Couldn't find 1_PCF8575!");<br />
    while (1);<br />
  }<br />
  else Serial.println("Find 1_PCF8575!");<br />
<br />
  if(dm_num==32)<br />
  {<br />
    if (!pcf2.begin(ADDRESS_PCF8575_2, &amp;myI2c)) {<br />
    Serial.println("DM32 Couldn't find 2_PCF8575"); <br />
    }<br />
    else Serial.println("Find 2_PCF8575!");<br />
  }<br />
 &nbsp;&nbsp;<br />
<br />
  for (uint8_t p=0; p&lt;DM_NUMS; p++) {<br />
    pcf.pinMode(p, INPUT_PULLUP);<br />
    if(dm_num==32) pcf2.pinMode(p-16, INPUT_PULLUP);<br />
    <br />
    key_press_prop[p].key_index = p+1;<br />
    key_press_prop[p].key_status = KEY_RELEASE;<br />
    key_press_prop[p].key_press_time = 0;<br />
  }<br />
<br />
  Serial.println("Now, starting!"); <br />
<br />
<br />
}<br />
<br />
<br />
<br />
static uint16_t input_value_old[2] = {0xffff,0xffff};<br />
uint16_t input_value[2] = {0} ;<br />
int8_t current_operator_key = -1;<br />
int8_t key_index = -1,key_index_last = -1;<br />
int16_t key_press_cnt_old = 0;<br />
uint16_t write_value=0;<br />
<br />
static int8_t get_key_press(int8_t chip,uint16_t key_value)<br />
{<br />
  if(key_value == 0xffff || key_value == 0) return -1;<br />
<br />
  for(int16_t i=0;i&lt;16;i++) <br />
  {<br />
    if((key_value &amp; (1&lt;&lt;i) ) == 0)  return (chip==0)?i:i+16; <br />
  }<br />
}<br />
<br />
static uint16_t getKeycode()<br />
{<br />
  uint16_t input_value = 0,tmp_value;<br />
  uint8_t h_value = 0 ,l_value = 0;<br />
  tmp_value = pcf.digitalReadWord();<br />
  h_value = tmp_value&gt;&gt;8;<br />
  l_value = tmp_value&amp;0xff;<br />
  input_value = (l_value&lt;&lt;8 ) | h_value;<br />
<br />
  return input_value;<br />
}<br />
<br />
static uint16_t getKeycode2()<br />
{<br />
  uint16_t input_value = 0,tmp_value;<br />
  uint8_t h_value = 0 ,l_value = 0;<br />
  tmp_value = pcf2.digitalReadWord();<br />
  h_value = tmp_value&gt;&gt;8;<br />
  l_value = tmp_value&amp;0xff;<br />
  input_value = (l_value ) | (h_value&lt;&lt;8);<br />
<br />
  return input_value;<br />
}<br />
<br />
static void checkKeyPress(int8_t chip);<br />
<br />
static uint16_t key_old_arr[2] = {0};<br />
<br />
void loop() { <br />
<br />
  input_value[0] = getKeycode(); <br />
  /*if(key_old_arr[0] != input_value[0] )<br />
  {<br />
    key_old_arr[0] = input_value[0];<br />
    Serial.printf("input0:%d&#92;r&#92;n",input_value[0]);<br />
  }*/<br />
  <br />
  checkKeyPress(0);<br />
<br />
  if(dm_num == 32)<br />
  {<br />
    delay(10);<br />
    input_value[1] = getKeycode2();<br />
    checkKeyPress(1);<br />
    /*if(key_old_arr[1] != input_value[1] )<br />
    {<br />
      key_old_arr[1] = input_value[1];<br />
      Serial.printf("input1:%d&#92;r&#92;n",input_value[1]);<br />
    }*/<br />
  }<br />
  <br />
<br />
<br />
  delay(10); // a short debounce delay<br />
}<br />
<br />
static void checkKeyPress(int8_t chip)<br />
{<br />
  uint8_t start_index = (chip==0)?0:16;<br />
  if(input_value_old[chip] != input_value[chip])<br />
  {<br />
    input_value_old[chip] = input_value[chip];<br />
    if(input_value[chip] == 0xffff)<br />
    {<br />
      Serial.printf("key is released!");<br />
     &nbsp;&nbsp;<br />
      current_operator_key = -1;<br />
      key_index_last = key_index = -1;<br />
<br />
      for (uint8_t p=start_index; p&lt;16+start_index; p++) ///all key status init.<br />
      {<br />
        key_press_prop[p].key_index = p+1;<br />
        key_press_prop[p].key_status = KEY_RELEASE;<br />
        key_press_prop[p].key_time_start = 0;<br />
        key_press_prop[p].key_press_time = 0;<br />
        key_press_prop[p].key_time_rec = 0;<br />
        key_press_prop[p].key_press_cnt = 0;<br />
        key_press_prop[p].key_press_cnt_old = 0;<br />
      }<br />
    }<br />
    else ///key press<br />
    {<br />
      //Serial.printf("input_value = %04X &#92;r&#92;n",input_value);<br />
      key_index = get_key_press(chip,input_value[chip]);<br />
      if(key_index &gt;= 0) <br />
      {<br />
        key_index_last = key_index;<br />
        Serial.printf("key %02d # is pressed! &#92;r&#92;n",key_index+1); <br />
        current_operator_key = key_index;<br />
        key_press_prop[current_operator_key].key_status = KEY_SHORT_PRESSED;<br />
        key_press_prop[current_operator_key].key_time_start = millis();<br />
        key_press_prop[current_operator_key].key_press_time = 0;<br />
      }<br />
    }<br />
  }<br />
  else<br />
  {<br />
    if(input_value[chip] != 0xffff) ///LONG PRESS!<br />
    {<br />
      //Serial.printf("key long pressed! &#92;r&#92;n");<br />
<br />
      key_index = get_key_press(chip,input_value[chip]);<br />
      if(key_index &gt;= 0 &amp;&amp; key_index_last == key_index) <br />
      { <br />
        //Serial.printf("key long pressed! key_index = %d&#92;r&#92;n",key_index);<br />
<br />
        current_operator_key = key_index;<br />
        key_press_prop[current_operator_key].key_status = KEY_LONG_PRESSED;<br />
        key_press_prop[current_operator_key].key_time_rec = millis();<br />
        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;<br />
        key_press_prop[current_operator_key].key_press_cnt = (key_press_prop[current_operator_key].key_press_time % 4080 ) / 100; ////100MS发一次<br />
<br />
        //Serial.printf("key long time = %d, cnt = %d &#92;r&#92;n",key_press_prop[current_operator_key].key_press_time,key_press_prop[current_operator_key].key_press_cnt);<br />
<br />
        if(key_press_prop[current_operator_key].key_press_cnt_old != key_press_prop[current_operator_key].key_press_cnt)<br />
        {<br />
          key_press_prop[current_operator_key].key_press_cnt_old = key_press_prop[current_operator_key].key_press_cnt;<br />
          /////send st_tx information.<br />
          key_press_prop[current_operator_key].current_light = (float)key_press_prop[current_operator_key].key_press_cnt * 100.0f;<br />
          write_value = (uint16_t) key_press_prop[current_operator_key].current_light;<br />
<br />
          Serial.printf("key_long_press_time = %d, current_light = %d &#92;r&#92;n",key_press_prop[current_operator_key].key_press_time,write_value);<br />
<br />
          modbus_write_multiple_registers(myst_serial,1,4000+current_operator_key,&amp;write_value,1);<br />
<br />
<br />
        }<br />
      }<br />
    }<br />
  }<br />
<br />
}</code></div></div><br />
arduino ino file download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8848" target="_blank" title="">1-dac-16ch.zip</a> (Size: 2.95 KB / Downloads: 105)
<!-- end: postbit_attachments_attachment --><br />
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download: <br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/zip.png" title="ZIP File" border="0" alt=".zip" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8849" target="_blank" title="">1-dac-16ch.ino.merged.zip</a> (Size: 205.71 KB / Downloads: 99)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[DM16 ESPHome yaml for home assistant with tuya]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8507</link>
			<pubDate>Tue, 09 Sep 2025 10:39:55 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8507</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>esphome:<br />
  name: dm16<br />
  friendly_name: dm16<br />
  platformio_options:<br />
    board_build.extra_flags:<br />
      # WIFI_CONTROL_SELF_MODE = 0<br />
      # WIFI_CONTROL_SELF_MODE = 1<br />
      - "-DWIFI_CONTROL_SELF_MODE=1"<br />
<br />
esp32:<br />
  board: esp32-s3-devkitc-1<br />
  framework:<br />
    type: arduino<br />
<br />
external_components:<br />
  - source:<br />
      type: git<br />
      url: https://github.com/hzkincony/esphome-tuya-wifi-mcu<br />
      ref: v1.2.0<br />
<br />
# Enable logging<br />
logger:<br />
  baud_rate: 0<br />
  hardware_uart: UART0<br />
<br />
# Enable Home Assistant API<br />
api:<br />
<br />
ota:<br />
  platform: esphome<br />
<br />
web_server:<br />
  port: 80<br />
<br />
ethernet:<br />
  type: W5500<br />
  clk_pin: GPIO1<br />
  mosi_pin: GPIO2<br />
  miso_pin: GPIO41<br />
  cs_pin: GPIO42<br />
  interrupt_pin: GPIO43<br />
  reset_pin: GPIO44<br />
<br />
i2c:<br />
 &nbsp;&nbsp;- id: bus_a<br />
   &nbsp;&nbsp;sda: 8<br />
   &nbsp;&nbsp;scl: 18<br />
   &nbsp;&nbsp;scan: true<br />
   &nbsp;&nbsp;frequency: 400kHz<br />
   &nbsp;&nbsp;<br />
text_sensor:<br />
  - platform: ethernet_info<br />
    ip_address:<br />
      name: ESP IP Address<br />
      id: eth_ip<br />
      address_0:<br />
        name: ESP IP Address 0<br />
      address_1:<br />
        name: ESP IP Address 1<br />
      address_2:<br />
        name: ESP IP Address 2<br />
      address_3:<br />
        name: ESP IP Address 3<br />
      address_4:<br />
        name: ESP IP Address 4<br />
    dns_address:<br />
      name: ESP DNS Address<br />
    mac_address:<br />
      name: ESP MAC Address<br />
<br />
font:<br />
  - file: "gfonts://Roboto"<br />
    id: roboto<br />
    size: 15<br />
<br />
display:<br />
  - platform: ssd1306_i2c<br />
    model: "SSD1306 128x64"<br />
    address: 0x3C<br />
    lambda: |-<br />
      it.printf(0, 15, id(roboto), "IP: %s", id(eth_ip).state.c_str());<br />
uart:<br />
  - id: dac_uart<br />
    rx_pin: 4<br />
    tx_pin: 6<br />
    baud_rate: 115200<br />
    stop_bits: 1<br />
    data_bits: 8<br />
    parity: NONE<br />
  - id: tuya_mcu_uart  <br />
    tx_pin: 16<br />
    rx_pin: 17<br />
    baud_rate: 9600<br />
<br />
tuya_wifi_mcu:<br />
  # tuya mcu product id<br />
  product_id: qdmpkznox0g9kkvo <br />
  uart_id: tuya_mcu_uart<br />
  wifi_reset_pin: 28<br />
  wifi_led_pin: 16<br />
<br />
modbus:<br />
  - uart_id: dac_uart<br />
<br />
modbus_controller:<br />
  - address: 1<br />
    update_interval: 5s<br />
<br />
output:<br />
  # CH1 (0x0FA0 / 4000)<br />
  - platform: modbus_controller<br />
    id: dac_ch1_out<br />
    address: 0x0FA0<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      // state = 0.0 ~ 1.0 → 0 ~ 4095<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH2 (0x0FA1 / 4001)<br />
  - platform: modbus_controller<br />
    id: dac_ch2_out<br />
    address: 0x0FA1<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH3<br />
  - platform: modbus_controller<br />
    id: dac_ch3_out<br />
    address: 0x0FA2<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH4<br />
  - platform: modbus_controller<br />
    id: dac_ch4_out<br />
    address: 0x0FA3<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH5<br />
  - platform: modbus_controller<br />
    id: dac_ch5_out<br />
    address: 0x0FA4<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH6<br />
  - platform: modbus_controller<br />
    id: dac_ch6_out<br />
    address: 0x0FA5<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH7<br />
  - platform: modbus_controller<br />
    id: dac_ch7_out<br />
    address: 0x0FA6<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH8<br />
  - platform: modbus_controller<br />
    id: dac_ch8_out<br />
    address: 0x0FA7<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH9<br />
  - platform: modbus_controller<br />
    id: dac_ch9_out<br />
    address: 0x0FA8<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH10<br />
  - platform: modbus_controller<br />
    id: dac_ch10_out<br />
    address: 0x0FA9<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH11<br />
  - platform: modbus_controller<br />
    id: dac_ch11_out<br />
    address: 0x0FAA<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH12<br />
  - platform: modbus_controller<br />
    id: dac_ch12_out<br />
    address: 0x0FAB<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH13<br />
  - platform: modbus_controller<br />
    id: dac_ch13_out<br />
    address: 0x0FAC<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH14<br />
  - platform: modbus_controller<br />
    id: dac_ch14_out<br />
    address: 0x0FAD<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH15<br />
  - platform: modbus_controller<br />
    id: dac_ch15_out<br />
    address: 0x0FAE<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH16<br />
  - platform: modbus_controller<br />
    id: dac_ch16_out<br />
    address: 0x0FAF<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
# -------------------<br />
# 16 路 Light (调光灯)<br />
# -------------------<br />
light:<br />
  - platform: monochromatic<br />
    name: "DAC CH1"<br />
    output: dac_ch1_out<br />
    id: light_1<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH1"<br />
    # bind other light, sync state<br />
    bind_light_id: light_1<br />
    output: dac_ch1_out<br />
    dp_id: 2<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH2"<br />
    output: dac_ch2_out<br />
    id: light_2<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH2"<br />
    # bind other light, sync state<br />
    bind_light_id: light_2<br />
    output: dac_ch2_out<br />
    dp_id: 8<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH3"<br />
    output: dac_ch3_out<br />
    id: light_3<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH3"<br />
    # bind other light, sync state<br />
    bind_light_id: light_3<br />
    output: dac_ch3_out<br />
    dp_id: 16<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH4"<br />
    output: dac_ch4_out<br />
    id: light_4<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH4"<br />
    # bind other light, sync state<br />
    bind_light_id: light_4<br />
    output: dac_ch4_out<br />
    dp_id: 101<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH5"<br />
    output: dac_ch5_out<br />
    id: light_5<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH5"<br />
    # bind other light, sync state<br />
    bind_light_id: light_5<br />
    output: dac_ch5_out<br />
    dp_id: 102<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH6"<br />
    output: dac_ch6_out<br />
    id: light_6<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH6"<br />
    # bind other light, sync state<br />
    bind_light_id: light_6<br />
    output: dac_ch6_out<br />
    dp_id: 103<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH7"<br />
    output: dac_ch7_out<br />
    id: light_7<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH7"<br />
    # bind other light, sync state<br />
    bind_light_id: light_7<br />
    output: dac_ch7_out<br />
    dp_id: 104<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH8"<br />
    output: dac_ch8_out<br />
    id: light_8<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH8"<br />
    # bind other light, sync state<br />
    bind_light_id: light_8<br />
    output: dac_ch8_out<br />
    dp_id: 105<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH9"<br />
    output: dac_ch9_out<br />
    id: light_9<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH9"<br />
    # bind other light, sync state<br />
    bind_light_id: light_9<br />
    output: dac_ch9_out<br />
    dp_id: 106<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH10"<br />
    output: dac_ch10_out<br />
    id: light_10<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH10"<br />
    # bind other light, sync state<br />
    bind_light_id: light_10<br />
    output: dac_ch10_out<br />
    dp_id: 107<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH11"<br />
    output: dac_ch11_out<br />
    id: light_11<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH11"<br />
    # bind other light, sync state<br />
    bind_light_id: light_11<br />
    output: dac_ch11_out<br />
    dp_id: 108<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH12"<br />
    output: dac_ch12_out<br />
    id: light_12<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH12"<br />
    # bind other light, sync state<br />
    bind_light_id: light_12<br />
    output: dac_ch12_out<br />
    dp_id: 109<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH13"<br />
    output: dac_ch13_out<br />
    id: light_13<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH13"<br />
    # bind other light, sync state<br />
    bind_light_id: light_13<br />
    output: dac_ch13_out<br />
    dp_id: 110<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH14"<br />
    output: dac_ch14_out<br />
    id: light_14<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH14"<br />
    # bind other light, sync state<br />
    bind_light_id: light_14<br />
    output: dac_ch14_out<br />
    dp_id: 111<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH15"<br />
    output: dac_ch15_out<br />
    id: light_15<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH15"<br />
    # bind other light, sync state<br />
    bind_light_id: light_15<br />
    output: dac_ch15_out<br />
    dp_id: 112<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH16"<br />
    output: dac_ch16_out<br />
    id: light_16<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH16"<br />
    # bind other light, sync state<br />
    bind_light_id: light_16<br />
    output: dac_ch16_out<br />
    dp_id: 113<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
<br />
<br />
pcf8574:<br />
  - id: 'pcf8574_hub_in_1'  # for input channel 1-16<br />
    i2c_id: bus_a<br />
    address: 0x22<br />
    pcf8575: true<br />
<br />
binary_sensor:<br />
  - platform: gpio<br />
    name: "dm16-input01"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 8<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input02"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 9<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input03"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 10<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input04"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 11<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input05"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 12<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input06"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 13<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input07"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 14<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input08"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 15<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input09"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 0<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input10"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 1<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input11"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 2<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input12"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 3<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input13"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 4<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input14"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 5<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input15"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 6<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input16"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 7<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
ads1115:<br />
  - address: 0x48<br />
sensor:<br />
  - platform: ads1115<br />
    multiplexer: 'A0_GND'<br />
    gain: 6.144<br />
    resolution: 16_BITS<br />
    name: "ADS1115 Channel A0-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A1_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A1-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A2_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A2-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A3_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A3-GND"<br />
    update_interval: 5s</code></div></div>esphome yaml file download:<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/txt.png" title="Text Document" border="0" alt=".txt" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8289" target="_blank" title="">DM16-HA-with-Tuya.txt</a> (Size: 13.11 KB / Downloads: 193)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>esphome:<br />
  name: dm16<br />
  friendly_name: dm16<br />
  platformio_options:<br />
    board_build.extra_flags:<br />
      # WIFI_CONTROL_SELF_MODE = 0<br />
      # WIFI_CONTROL_SELF_MODE = 1<br />
      - "-DWIFI_CONTROL_SELF_MODE=1"<br />
<br />
esp32:<br />
  board: esp32-s3-devkitc-1<br />
  framework:<br />
    type: arduino<br />
<br />
external_components:<br />
  - source:<br />
      type: git<br />
      url: https://github.com/hzkincony/esphome-tuya-wifi-mcu<br />
      ref: v1.2.0<br />
<br />
# Enable logging<br />
logger:<br />
  baud_rate: 0<br />
  hardware_uart: UART0<br />
<br />
# Enable Home Assistant API<br />
api:<br />
<br />
ota:<br />
  platform: esphome<br />
<br />
web_server:<br />
  port: 80<br />
<br />
ethernet:<br />
  type: W5500<br />
  clk_pin: GPIO1<br />
  mosi_pin: GPIO2<br />
  miso_pin: GPIO41<br />
  cs_pin: GPIO42<br />
  interrupt_pin: GPIO43<br />
  reset_pin: GPIO44<br />
<br />
i2c:<br />
 &nbsp;&nbsp;- id: bus_a<br />
   &nbsp;&nbsp;sda: 8<br />
   &nbsp;&nbsp;scl: 18<br />
   &nbsp;&nbsp;scan: true<br />
   &nbsp;&nbsp;frequency: 400kHz<br />
   &nbsp;&nbsp;<br />
text_sensor:<br />
  - platform: ethernet_info<br />
    ip_address:<br />
      name: ESP IP Address<br />
      id: eth_ip<br />
      address_0:<br />
        name: ESP IP Address 0<br />
      address_1:<br />
        name: ESP IP Address 1<br />
      address_2:<br />
        name: ESP IP Address 2<br />
      address_3:<br />
        name: ESP IP Address 3<br />
      address_4:<br />
        name: ESP IP Address 4<br />
    dns_address:<br />
      name: ESP DNS Address<br />
    mac_address:<br />
      name: ESP MAC Address<br />
<br />
font:<br />
  - file: "gfonts://Roboto"<br />
    id: roboto<br />
    size: 15<br />
<br />
display:<br />
  - platform: ssd1306_i2c<br />
    model: "SSD1306 128x64"<br />
    address: 0x3C<br />
    lambda: |-<br />
      it.printf(0, 15, id(roboto), "IP: %s", id(eth_ip).state.c_str());<br />
uart:<br />
  - id: dac_uart<br />
    rx_pin: 4<br />
    tx_pin: 6<br />
    baud_rate: 115200<br />
    stop_bits: 1<br />
    data_bits: 8<br />
    parity: NONE<br />
  - id: tuya_mcu_uart  <br />
    tx_pin: 16<br />
    rx_pin: 17<br />
    baud_rate: 9600<br />
<br />
tuya_wifi_mcu:<br />
  # tuya mcu product id<br />
  product_id: qdmpkznox0g9kkvo <br />
  uart_id: tuya_mcu_uart<br />
  wifi_reset_pin: 28<br />
  wifi_led_pin: 16<br />
<br />
modbus:<br />
  - uart_id: dac_uart<br />
<br />
modbus_controller:<br />
  - address: 1<br />
    update_interval: 5s<br />
<br />
output:<br />
  # CH1 (0x0FA0 / 4000)<br />
  - platform: modbus_controller<br />
    id: dac_ch1_out<br />
    address: 0x0FA0<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      // state = 0.0 ~ 1.0 → 0 ~ 4095<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH2 (0x0FA1 / 4001)<br />
  - platform: modbus_controller<br />
    id: dac_ch2_out<br />
    address: 0x0FA1<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH3<br />
  - platform: modbus_controller<br />
    id: dac_ch3_out<br />
    address: 0x0FA2<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH4<br />
  - platform: modbus_controller<br />
    id: dac_ch4_out<br />
    address: 0x0FA3<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH5<br />
  - platform: modbus_controller<br />
    id: dac_ch5_out<br />
    address: 0x0FA4<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH6<br />
  - platform: modbus_controller<br />
    id: dac_ch6_out<br />
    address: 0x0FA5<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH7<br />
  - platform: modbus_controller<br />
    id: dac_ch7_out<br />
    address: 0x0FA6<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH8<br />
  - platform: modbus_controller<br />
    id: dac_ch8_out<br />
    address: 0x0FA7<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH9<br />
  - platform: modbus_controller<br />
    id: dac_ch9_out<br />
    address: 0x0FA8<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH10<br />
  - platform: modbus_controller<br />
    id: dac_ch10_out<br />
    address: 0x0FA9<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH11<br />
  - platform: modbus_controller<br />
    id: dac_ch11_out<br />
    address: 0x0FAA<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH12<br />
  - platform: modbus_controller<br />
    id: dac_ch12_out<br />
    address: 0x0FAB<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH13<br />
  - platform: modbus_controller<br />
    id: dac_ch13_out<br />
    address: 0x0FAC<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH14<br />
  - platform: modbus_controller<br />
    id: dac_ch14_out<br />
    address: 0x0FAD<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH15<br />
  - platform: modbus_controller<br />
    id: dac_ch15_out<br />
    address: 0x0FAE<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH16<br />
  - platform: modbus_controller<br />
    id: dac_ch16_out<br />
    address: 0x0FAF<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
# -------------------<br />
# 16 路 Light (调光灯)<br />
# -------------------<br />
light:<br />
  - platform: monochromatic<br />
    name: "DAC CH1"<br />
    output: dac_ch1_out<br />
    id: light_1<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH1"<br />
    # bind other light, sync state<br />
    bind_light_id: light_1<br />
    output: dac_ch1_out<br />
    dp_id: 2<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH2"<br />
    output: dac_ch2_out<br />
    id: light_2<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH2"<br />
    # bind other light, sync state<br />
    bind_light_id: light_2<br />
    output: dac_ch2_out<br />
    dp_id: 8<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH3"<br />
    output: dac_ch3_out<br />
    id: light_3<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH3"<br />
    # bind other light, sync state<br />
    bind_light_id: light_3<br />
    output: dac_ch3_out<br />
    dp_id: 16<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH4"<br />
    output: dac_ch4_out<br />
    id: light_4<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH4"<br />
    # bind other light, sync state<br />
    bind_light_id: light_4<br />
    output: dac_ch4_out<br />
    dp_id: 101<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH5"<br />
    output: dac_ch5_out<br />
    id: light_5<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH5"<br />
    # bind other light, sync state<br />
    bind_light_id: light_5<br />
    output: dac_ch5_out<br />
    dp_id: 102<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH6"<br />
    output: dac_ch6_out<br />
    id: light_6<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH6"<br />
    # bind other light, sync state<br />
    bind_light_id: light_6<br />
    output: dac_ch6_out<br />
    dp_id: 103<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH7"<br />
    output: dac_ch7_out<br />
    id: light_7<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH7"<br />
    # bind other light, sync state<br />
    bind_light_id: light_7<br />
    output: dac_ch7_out<br />
    dp_id: 104<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH8"<br />
    output: dac_ch8_out<br />
    id: light_8<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH8"<br />
    # bind other light, sync state<br />
    bind_light_id: light_8<br />
    output: dac_ch8_out<br />
    dp_id: 105<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH9"<br />
    output: dac_ch9_out<br />
    id: light_9<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH9"<br />
    # bind other light, sync state<br />
    bind_light_id: light_9<br />
    output: dac_ch9_out<br />
    dp_id: 106<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH10"<br />
    output: dac_ch10_out<br />
    id: light_10<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH10"<br />
    # bind other light, sync state<br />
    bind_light_id: light_10<br />
    output: dac_ch10_out<br />
    dp_id: 107<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH11"<br />
    output: dac_ch11_out<br />
    id: light_11<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH11"<br />
    # bind other light, sync state<br />
    bind_light_id: light_11<br />
    output: dac_ch11_out<br />
    dp_id: 108<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH12"<br />
    output: dac_ch12_out<br />
    id: light_12<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH12"<br />
    # bind other light, sync state<br />
    bind_light_id: light_12<br />
    output: dac_ch12_out<br />
    dp_id: 109<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH13"<br />
    output: dac_ch13_out<br />
    id: light_13<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH13"<br />
    # bind other light, sync state<br />
    bind_light_id: light_13<br />
    output: dac_ch13_out<br />
    dp_id: 110<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH14"<br />
    output: dac_ch14_out<br />
    id: light_14<br />
    default_transition_length: 0s<br />
<br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH14"<br />
    # bind other light, sync state<br />
    bind_light_id: light_14<br />
    output: dac_ch14_out<br />
    dp_id: 111<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH15"<br />
    output: dac_ch15_out<br />
    id: light_15<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH15"<br />
    # bind other light, sync state<br />
    bind_light_id: light_15<br />
    output: dac_ch15_out<br />
    dp_id: 112<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH16"<br />
    output: dac_ch16_out<br />
    id: light_16<br />
    default_transition_length: 0s<br />
  <br />
  - platform: tuya_wifi_mcu<br />
    name: "Tuya DAC CH16"<br />
    # bind other light, sync state<br />
    bind_light_id: light_16<br />
    output: dac_ch16_out<br />
    dp_id: 113<br />
    # hide from homeassistant ui<br />
    internal: true<br />
<br />
<br />
<br />
pcf8574:<br />
  - id: 'pcf8574_hub_in_1'  # for input channel 1-16<br />
    i2c_id: bus_a<br />
    address: 0x22<br />
    pcf8575: true<br />
<br />
binary_sensor:<br />
  - platform: gpio<br />
    name: "dm16-input01"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 8<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input02"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 9<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input03"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 10<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input04"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 11<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input05"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 12<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input06"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 13<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input07"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 14<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input08"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 15<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input09"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 0<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input10"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 1<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input11"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 2<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input12"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 3<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input13"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 4<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input14"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 5<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input15"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 6<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input16"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 7<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
ads1115:<br />
  - address: 0x48<br />
sensor:<br />
  - platform: ads1115<br />
    multiplexer: 'A0_GND'<br />
    gain: 6.144<br />
    resolution: 16_BITS<br />
    name: "ADS1115 Channel A0-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A1_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A1-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A2_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A2-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A3_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A3-GND"<br />
    update_interval: 5s</code></div></div>esphome yaml file download:<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/txt.png" title="Text Document" border="0" alt=".txt" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8289" target="_blank" title="">DM16-HA-with-Tuya.txt</a> (Size: 13.11 KB / Downloads: 193)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[DM16 ESPHome yaml for home assistant without tuya]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8505</link>
			<pubDate>Tue, 09 Sep 2025 10:17:52 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8505</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>esphome:<br />
  name: dm16<br />
  friendly_name: dm16<br />
<br />
esp32:<br />
  board: esp32-s3-devkitc-1<br />
  framework:<br />
    type: arduino<br />
<br />
# Enable logging<br />
logger:<br />
<br />
# Enable Home Assistant API<br />
api:<br />
<br />
ota:<br />
  platform: esphome<br />
<br />
web_server:<br />
  port: 80<br />
<br />
ethernet:<br />
  type: W5500<br />
  clk_pin: GPIO1<br />
  mosi_pin: GPIO2<br />
  miso_pin: GPIO41<br />
  cs_pin: GPIO42<br />
  interrupt_pin: GPIO43<br />
  reset_pin: GPIO44<br />
<br />
i2c:<br />
 &nbsp;&nbsp;- id: bus_a<br />
   &nbsp;&nbsp;sda: 8<br />
   &nbsp;&nbsp;scl: 18<br />
   &nbsp;&nbsp;scan: true<br />
   &nbsp;&nbsp;frequency: 400kHz<br />
   &nbsp;&nbsp;<br />
text_sensor:<br />
  - platform: ethernet_info<br />
    ip_address:<br />
      name: ESP IP Address<br />
      id: eth_ip<br />
      address_0:<br />
        name: ESP IP Address 0<br />
      address_1:<br />
        name: ESP IP Address 1<br />
      address_2:<br />
        name: ESP IP Address 2<br />
      address_3:<br />
        name: ESP IP Address 3<br />
      address_4:<br />
        name: ESP IP Address 4<br />
    dns_address:<br />
      name: ESP DNS Address<br />
    mac_address:<br />
      name: ESP MAC Address<br />
<br />
font:<br />
  - file: "gfonts://Roboto"<br />
    id: roboto<br />
    size: 15<br />
<br />
display:<br />
  - platform: ssd1306_i2c<br />
    model: "SSD1306 128x64"<br />
    address: 0x3C<br />
    lambda: |-<br />
      it.printf(0, 15, id(roboto), "IP: %s", id(eth_ip).state.c_str());<br />
uart:<br />
  id: dac_uart<br />
  rx_pin: 4<br />
  tx_pin: 6<br />
  baud_rate: 115200<br />
  stop_bits: 1<br />
  data_bits: 8<br />
  parity: NONE<br />
  debug: <br />
<br />
modbus:<br />
<br />
modbus_controller:<br />
  - address: 1<br />
    update_interval: 5s<br />
<br />
output:<br />
  # CH1 (0x0FA0 / 4000)<br />
  - platform: modbus_controller<br />
    id: dac_ch1_out<br />
    address: 0x0FA0<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      // state = 0.0 ~ 1.0 → 0 ~ 4095<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH2 (0x0FA1 / 4001)<br />
  - platform: modbus_controller<br />
    id: dac_ch2_out<br />
    address: 0x0FA1<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH3<br />
  - platform: modbus_controller<br />
    id: dac_ch3_out<br />
    address: 0x0FA2<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH4<br />
  - platform: modbus_controller<br />
    id: dac_ch4_out<br />
    address: 0x0FA3<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH5<br />
  - platform: modbus_controller<br />
    id: dac_ch5_out<br />
    address: 0x0FA4<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH6<br />
  - platform: modbus_controller<br />
    id: dac_ch6_out<br />
    address: 0x0FA5<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH7<br />
  - platform: modbus_controller<br />
    id: dac_ch7_out<br />
    address: 0x0FA6<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH8<br />
  - platform: modbus_controller<br />
    id: dac_ch8_out<br />
    address: 0x0FA7<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH9<br />
  - platform: modbus_controller<br />
    id: dac_ch9_out<br />
    address: 0x0FA8<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH10<br />
  - platform: modbus_controller<br />
    id: dac_ch10_out<br />
    address: 0x0FA9<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH11<br />
  - platform: modbus_controller<br />
    id: dac_ch11_out<br />
    address: 0x0FAA<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH12<br />
  - platform: modbus_controller<br />
    id: dac_ch12_out<br />
    address: 0x0FAB<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH13<br />
  - platform: modbus_controller<br />
    id: dac_ch13_out<br />
    address: 0x0FAC<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH14<br />
  - platform: modbus_controller<br />
    id: dac_ch14_out<br />
    address: 0x0FAD<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH15<br />
  - platform: modbus_controller<br />
    id: dac_ch15_out<br />
    address: 0x0FAE<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH16<br />
  - platform: modbus_controller<br />
    id: dac_ch16_out<br />
    address: 0x0FAF<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
# -------------------<br />
# 16 Channel Dimmer<br />
# -------------------<br />
light:<br />
  - platform: monochromatic<br />
    name: "DAC CH1"<br />
    output: dac_ch1_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH2"<br />
    output: dac_ch2_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH3"<br />
    output: dac_ch3_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH4"<br />
    output: dac_ch4_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH5"<br />
    output: dac_ch5_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH6"<br />
    output: dac_ch6_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH7"<br />
    output: dac_ch7_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH8"<br />
    output: dac_ch8_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH9"<br />
    output: dac_ch9_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH10"<br />
    output: dac_ch10_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH11"<br />
    output: dac_ch11_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH12"<br />
    output: dac_ch12_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH13"<br />
    output: dac_ch13_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH14"<br />
    output: dac_ch14_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH15"<br />
    output: dac_ch15_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH16"<br />
    output: dac_ch16_out<br />
    default_transition_length: 0s<br />
<br />
<br />
<br />
pcf8574:<br />
  - id: 'pcf8574_hub_in_1'  # for input channel 1-16<br />
    i2c_id: bus_a<br />
    address: 0x22<br />
    pcf8575: true<br />
<br />
binary_sensor:<br />
  - platform: gpio<br />
    name: "dm16-input01"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 8<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input02"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 9<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input03"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 10<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input04"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 11<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input05"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 12<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input06"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 13<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input07"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 14<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input08"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 15<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input09"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 0<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input10"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 1<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input11"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 2<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input12"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 3<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input13"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 4<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input14"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 5<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input15"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 6<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input16"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 7<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
ads1115:<br />
  - address: 0x48<br />
sensor:<br />
  - platform: ads1115<br />
    multiplexer: 'A0_GND'<br />
    gain: 6.144<br />
    resolution: 16_BITS<br />
    name: "ADS1115 Channel A0-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A1_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A1-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A2_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A2-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A3_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A3-GND"<br />
    update_interval: 5s</code></div></div><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8287" target="_blank" title="">HA-web.png</a> (Size: 178.02 KB / Downloads: 362)
<!-- end: postbit_attachments_attachment --><br />
esphome yaml file download:<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/txt.png" title="Text Document" border="0" alt=".txt" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8288" target="_blank" title="">DM16-HA-without Tuya.txt</a> (Size: 9.49 KB / Downloads: 191)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>esphome:<br />
  name: dm16<br />
  friendly_name: dm16<br />
<br />
esp32:<br />
  board: esp32-s3-devkitc-1<br />
  framework:<br />
    type: arduino<br />
<br />
# Enable logging<br />
logger:<br />
<br />
# Enable Home Assistant API<br />
api:<br />
<br />
ota:<br />
  platform: esphome<br />
<br />
web_server:<br />
  port: 80<br />
<br />
ethernet:<br />
  type: W5500<br />
  clk_pin: GPIO1<br />
  mosi_pin: GPIO2<br />
  miso_pin: GPIO41<br />
  cs_pin: GPIO42<br />
  interrupt_pin: GPIO43<br />
  reset_pin: GPIO44<br />
<br />
i2c:<br />
 &nbsp;&nbsp;- id: bus_a<br />
   &nbsp;&nbsp;sda: 8<br />
   &nbsp;&nbsp;scl: 18<br />
   &nbsp;&nbsp;scan: true<br />
   &nbsp;&nbsp;frequency: 400kHz<br />
   &nbsp;&nbsp;<br />
text_sensor:<br />
  - platform: ethernet_info<br />
    ip_address:<br />
      name: ESP IP Address<br />
      id: eth_ip<br />
      address_0:<br />
        name: ESP IP Address 0<br />
      address_1:<br />
        name: ESP IP Address 1<br />
      address_2:<br />
        name: ESP IP Address 2<br />
      address_3:<br />
        name: ESP IP Address 3<br />
      address_4:<br />
        name: ESP IP Address 4<br />
    dns_address:<br />
      name: ESP DNS Address<br />
    mac_address:<br />
      name: ESP MAC Address<br />
<br />
font:<br />
  - file: "gfonts://Roboto"<br />
    id: roboto<br />
    size: 15<br />
<br />
display:<br />
  - platform: ssd1306_i2c<br />
    model: "SSD1306 128x64"<br />
    address: 0x3C<br />
    lambda: |-<br />
      it.printf(0, 15, id(roboto), "IP: %s", id(eth_ip).state.c_str());<br />
uart:<br />
  id: dac_uart<br />
  rx_pin: 4<br />
  tx_pin: 6<br />
  baud_rate: 115200<br />
  stop_bits: 1<br />
  data_bits: 8<br />
  parity: NONE<br />
  debug: <br />
<br />
modbus:<br />
<br />
modbus_controller:<br />
  - address: 1<br />
    update_interval: 5s<br />
<br />
output:<br />
  # CH1 (0x0FA0 / 4000)<br />
  - platform: modbus_controller<br />
    id: dac_ch1_out<br />
    address: 0x0FA0<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      // state = 0.0 ~ 1.0 → 0 ~ 4095<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH2 (0x0FA1 / 4001)<br />
  - platform: modbus_controller<br />
    id: dac_ch2_out<br />
    address: 0x0FA1<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH3<br />
  - platform: modbus_controller<br />
    id: dac_ch3_out<br />
    address: 0x0FA2<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH4<br />
  - platform: modbus_controller<br />
    id: dac_ch4_out<br />
    address: 0x0FA3<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH5<br />
  - platform: modbus_controller<br />
    id: dac_ch5_out<br />
    address: 0x0FA4<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH6<br />
  - platform: modbus_controller<br />
    id: dac_ch6_out<br />
    address: 0x0FA5<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH7<br />
  - platform: modbus_controller<br />
    id: dac_ch7_out<br />
    address: 0x0FA6<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH8<br />
  - platform: modbus_controller<br />
    id: dac_ch8_out<br />
    address: 0x0FA7<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH9<br />
  - platform: modbus_controller<br />
    id: dac_ch9_out<br />
    address: 0x0FA8<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH10<br />
  - platform: modbus_controller<br />
    id: dac_ch10_out<br />
    address: 0x0FA9<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH11<br />
  - platform: modbus_controller<br />
    id: dac_ch11_out<br />
    address: 0x0FAA<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH12<br />
  - platform: modbus_controller<br />
    id: dac_ch12_out<br />
    address: 0x0FAB<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH13<br />
  - platform: modbus_controller<br />
    id: dac_ch13_out<br />
    address: 0x0FAC<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH14<br />
  - platform: modbus_controller<br />
    id: dac_ch14_out<br />
    address: 0x0FAD<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH15<br />
  - platform: modbus_controller<br />
    id: dac_ch15_out<br />
    address: 0x0FAE<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
  # CH16<br />
  - platform: modbus_controller<br />
    id: dac_ch16_out<br />
    address: 0x0FAF<br />
    value_type: U_WORD<br />
    write_lambda: |-<br />
      uint16_t reg = (uint16_t) round(x * 4095.0);<br />
      return reg;<br />
<br />
# -------------------<br />
# 16 Channel Dimmer<br />
# -------------------<br />
light:<br />
  - platform: monochromatic<br />
    name: "DAC CH1"<br />
    output: dac_ch1_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH2"<br />
    output: dac_ch2_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH3"<br />
    output: dac_ch3_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH4"<br />
    output: dac_ch4_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH5"<br />
    output: dac_ch5_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH6"<br />
    output: dac_ch6_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH7"<br />
    output: dac_ch7_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH8"<br />
    output: dac_ch8_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH9"<br />
    output: dac_ch9_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH10"<br />
    output: dac_ch10_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH11"<br />
    output: dac_ch11_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH12"<br />
    output: dac_ch12_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH13"<br />
    output: dac_ch13_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH14"<br />
    output: dac_ch14_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH15"<br />
    output: dac_ch15_out<br />
    default_transition_length: 0s<br />
<br />
  - platform: monochromatic<br />
    name: "DAC CH16"<br />
    output: dac_ch16_out<br />
    default_transition_length: 0s<br />
<br />
<br />
<br />
pcf8574:<br />
  - id: 'pcf8574_hub_in_1'  # for input channel 1-16<br />
    i2c_id: bus_a<br />
    address: 0x22<br />
    pcf8575: true<br />
<br />
binary_sensor:<br />
  - platform: gpio<br />
    name: "dm16-input01"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 8<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input02"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 9<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input03"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 10<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input04"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 11<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input05"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 12<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input06"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 13<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input07"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 14<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input08"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 15<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input09"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 0<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input10"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 1<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input11"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 2<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input12"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 3<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input13"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 4<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input14"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 5<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input15"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 6<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "dm16-input16"<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 7<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
ads1115:<br />
  - address: 0x48<br />
sensor:<br />
  - platform: ads1115<br />
    multiplexer: 'A0_GND'<br />
    gain: 6.144<br />
    resolution: 16_BITS<br />
    name: "ADS1115 Channel A0-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A1_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A1-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A2_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A2-GND"<br />
    update_interval: 5s<br />
  - platform: ads1115<br />
    multiplexer: 'A3_GND'<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A3-GND"<br />
    update_interval: 5s</code></div></div><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8287" target="_blank" title="">HA-web.png</a> (Size: 178.02 KB / Downloads: 362)
<!-- end: postbit_attachments_attachment --><br />
esphome yaml file download:<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/txt.png" title="Text Document" border="0" alt=".txt" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=8288" target="_blank" title="">DM16-HA-without Tuya.txt</a> (Size: 9.49 KB / Downloads: 191)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[DM16 ESP32-S3 IO pins define]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=8499</link>
			<pubDate>Sun, 07 Sep 2025 10:31:07 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://www.kincony.com/forum/member.php?action=profile&uid=1">admin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.kincony.com/forum/showthread.php?tid=8499</guid>
			<description><![CDATA[SDA:GPIO8<br />
SCL:GPIO18<br />
<br />
PCF8575: (input1-16): i2c address:0x22 by B16-core<br />
<br />
P8:input1<br />
P9:input2<br />
P10:input3<br />
P11:input4<br />
P12:input5<br />
P13:input6<br />
P14:input7<br />
P15:input8<br />
<br />
P0:input9<br />
P1:input10<br />
P2:input11<br />
P3:input12<br />
P4:input13<br />
P5:input14<br />
P6:input15<br />
P7:input16<br />
<br />
ADS1115 (4CH ADC): i2c address:0x48<br />
Analog input (A1: DC 0-5v)<br />
Analog input (A2: DC 0-5v)<br />
Analog input (A3: DC 4-20mA)<br />
Analog input (A4: DC 4-20mA)<br />
<br />
24C02 EPROM i2c address: 0x50<br />
DS3231 RTC i2c address: 0x68<br />
<br />
1-wire (pull-up resistance on PCB): <br />
1-wire1:GPIO47<br />
1-wire2:GPIO48<br />
1-wire3:GPIO7<br />
1-wire4:GPIO40<br />
<br />
free GPIOs:<br />
GPIO13<br />
GPIO14<br />
GPIO21<br />
<br />
-----------------------<br />
Ethernet (W5500) I/O define:<br />
<br />
clk_pin: GPIO1<br />
mosi_pin: GPIO2<br />
miso_pin: GPIO41<br />
cs_pin: GPIO42<br />
<br />
interrupt_pin: GPIO43<br />
reset_pin: GPIO44<br />
<br />
--------------------<br />
RS485: <br />
RXD:GPIO38<br />
TXD:GPIO39<br />
<br />
Tuya module:<br />
RXD:GPIO17<br />
TXD:GPIO16<br />
<br />
Tuya network button: Tuya module's P28<br />
Tuya network LED: Tuya module's P16<br />
<br />
ARM CPU TXD:GPIO4<br />
ARM CPU RXD:GPIO6<br />
<br />
SD Card:<br />
SPI-MOSI:GPIO10<br />
SPI-SCK:GPIO11<br />
SPI-MISO:GPIO12<br />
SPI-CS:GPIO9<br />
SD-Detect: GPIO5]]></description>
			<content:encoded><![CDATA[SDA:GPIO8<br />
SCL:GPIO18<br />
<br />
PCF8575: (input1-16): i2c address:0x22 by B16-core<br />
<br />
P8:input1<br />
P9:input2<br />
P10:input3<br />
P11:input4<br />
P12:input5<br />
P13:input6<br />
P14:input7<br />
P15:input8<br />
<br />
P0:input9<br />
P1:input10<br />
P2:input11<br />
P3:input12<br />
P4:input13<br />
P5:input14<br />
P6:input15<br />
P7:input16<br />
<br />
ADS1115 (4CH ADC): i2c address:0x48<br />
Analog input (A1: DC 0-5v)<br />
Analog input (A2: DC 0-5v)<br />
Analog input (A3: DC 4-20mA)<br />
Analog input (A4: DC 4-20mA)<br />
<br />
24C02 EPROM i2c address: 0x50<br />
DS3231 RTC i2c address: 0x68<br />
<br />
1-wire (pull-up resistance on PCB): <br />
1-wire1:GPIO47<br />
1-wire2:GPIO48<br />
1-wire3:GPIO7<br />
1-wire4:GPIO40<br />
<br />
free GPIOs:<br />
GPIO13<br />
GPIO14<br />
GPIO21<br />
<br />
-----------------------<br />
Ethernet (W5500) I/O define:<br />
<br />
clk_pin: GPIO1<br />
mosi_pin: GPIO2<br />
miso_pin: GPIO41<br />
cs_pin: GPIO42<br />
<br />
interrupt_pin: GPIO43<br />
reset_pin: GPIO44<br />
<br />
--------------------<br />
RS485: <br />
RXD:GPIO38<br />
TXD:GPIO39<br />
<br />
Tuya module:<br />
RXD:GPIO17<br />
TXD:GPIO16<br />
<br />
Tuya network button: Tuya module's P28<br />
Tuya network LED: Tuya module's P16<br />
<br />
ARM CPU TXD:GPIO4<br />
ARM CPU RXD:GPIO6<br />
<br />
SD Card:<br />
SPI-MOSI:GPIO10<br />
SPI-SCK:GPIO11<br />
SPI-MISO:GPIO12<br />
SPI-CS:GPIO9<br />
SD-Detect: GPIO5]]></content:encoded>
		</item>
	</channel>
</rss>