<?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 - MT4v2]]></title>
		<link>https://www.kincony.com/forum/</link>
		<description><![CDATA[Smart Home Automation Forum - https://www.kincony.com/forum]]></description>
		<pubDate>Mon, 09 Nov 2026 16:19:35 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[DRV8262DDWR driver chip datasheet PDF file]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9899</link>
			<pubDate>Sun, 25 Oct 2026 09:29:46 +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=9899</guid>
			<description><![CDATA[<!-- 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=10655" target="_blank" title="">drv8262.pdf</a> (Size: 2.79 MB / Downloads: 57)
<!-- 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/pdf.png" title="Adobe Acrobat PDF" border="0" alt=".pdf" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=10655" target="_blank" title="">drv8262.pdf</a> (Size: 2.79 MB / Downloads: 57)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[MT4v2 Driver Board Web Tool]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9891</link>
			<pubDate>Tue, 20 Oct 2026 11:37: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=9891</guid>
			<description><![CDATA[download: <!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/html.png" title="HTML File" border="0" alt=".html" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=10647" target="_blank" title="">MT4V2_Driver_Board_Web.html</a> (Size: 11.16 KB / Downloads: 56)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[download: <!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/html.png" title="HTML File" border="0" alt=".html" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=10647" target="_blank" title="">MT4V2_Driver_Board_Web.html</a> (Size: 11.16 KB / Downloads: 56)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[ARM CPU Modbus communication protocol]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9890</link>
			<pubDate>Tue, 20 Oct 2026 11:36:32 +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=9890</guid>
			<description><![CDATA[download: <!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/html.png" title="HTML File" border="0" alt=".html" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=10646" target="_blank" title="">MT4V2 Driver Board Tutorial.html</a> (Size: 14.42 KB / Downloads: 62)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[download: <!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.kincony.com/forum/images/attachtypes/html.png" title="HTML File" border="0" alt=".html" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=10646" target="_blank" title="">MT4V2 Driver Board Tutorial.html</a> (Size: 14.42 KB / Downloads: 62)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-11 IR receiver decode]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9889</link>
			<pubDate>Tue, 20 Oct 2026 11:35:06 +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=9889</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * SimpleReceiver.cpp<br />
 *<br />
 * Demonstrates receiving ONLY NEC protocol IR codes with IRremote<br />
 * If no protocol is defined, all protocols (except Bang&amp;Olufsen) are active.<br />
 *<br />
 *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.<br />
 *<br />
 ************************************************************************************<br />
 * MIT License<br />
 *<br />
 * Copyright (c) 2020-2025 Armin Joachimsmeyer<br />
 *<br />
 * Permission is hereby granted, free of charge, to any person obtaining a copy<br />
 * of this software and associated documentation files (the "Software"), to deal<br />
 * in the Software without restriction, including without limitation the rights<br />
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br />
 * copies of the Software, and to permit persons to whom the Software is furnished<br />
 * to do so, subject to the following conditions:<br />
 *<br />
 * The above copyright notice and this permission notice shall be included in all<br />
 * copies or substantial portions of the Software.<br />
 *<br />
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,<br />
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A<br />
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT<br />
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF<br />
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE<br />
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.<br />
 *<br />
 ************************************************************************************<br />
 */<br />
<br />
#include &lt;Arduino.h&gt;<br />
#include &lt;IRremote.hpp&gt; // include the library<br />
<br />
uint8_t sender_pins[] = {47, 48};<br />
uint8_t receiver_pin = 13;<br />
<br />
int sender_pin_num = sizeof(sender_pins) / sizeof(sender_pins[0]);<br />
uint8_t sender_pin_idx = 0;<br />
uint8_t receive_cnt = 0;<br />
uint8_t sCommand = 0x34;<br />
uint8_t sRepeats = 0;<br />
<br />
void setup() {<br />
    Serial.begin(115200);<br />
    IrReceiver.begin(receiver_pin, false);<br />
    IrSender.begin(sender_pins[0]);<br />
<br />
    xTaskCreate(<br />
      sendIr,    // Function that should be called<br />
      "Send IR", &nbsp;&nbsp;// Name of the task (for debugging)<br />
      4096,            // Stack size (bytes)<br />
      NULL,            // Parameter to pass<br />
      1,             &nbsp;&nbsp;// Task priority<br />
      NULL           &nbsp;&nbsp;// Task handle<br />
  );<br />
}<br />
<br />
void sendIr(void * parameter) {<br />
  <br />
  delay(2000);<br />
  IrSender.setSendPin(47);<br />
  IrSender.sendNEC(0x00, sCommand, sRepeats);<br />
  Serial.printf("send by pin: %d&#92;n", 47);<br />
  delay(2000);<br />
<br />
  IrSender.setSendPin(48);<br />
  IrSender.sendNEC(0x00, sCommand, sRepeats);<br />
  Serial.printf("send by pin: %d&#92;n", 48);<br />
<br />
  delay(2000);<br />
  vTaskDelete(NULL);<br />
}<br />
<br />
void loop() {<br />
  if (IrReceiver.decode()) {<br />
      Serial.println("recv data");<br />
      if (IrReceiver.decodedIRData.protocol == UNKNOWN) {<br />
          Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));<br />
          // We have an unknown protocol here, print extended info<br />
          IrReceiver.printIRResultRawFormatted(&amp;Serial, true);<br />
<br />
          IrReceiver.resume(); // Do it here, to preserve raw data for printing with printIRResultRawFormatted()<br />
      } else {<br />
          IrReceiver.resume(); // Early enable receiving of the next IR frame<br />
<br />
          IrReceiver.printIRResultShort(&amp;Serial);<br />
          IrReceiver.printIRSendUsage(&amp;Serial);<br />
      }<br />
  } else {<br />
    // Serial.println("no data");<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=10644" target="_blank" title="">11-IR-receiver.zip</a> (Size: 1.61 KB / Downloads: 54)
<!-- 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=10645" target="_blank" title="">11-IR-receiver.ino.merged.zip</a> (Size: 194.06 KB / Downloads: 50)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * SimpleReceiver.cpp<br />
 *<br />
 * Demonstrates receiving ONLY NEC protocol IR codes with IRremote<br />
 * If no protocol is defined, all protocols (except Bang&amp;Olufsen) are active.<br />
 *<br />
 *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.<br />
 *<br />
 ************************************************************************************<br />
 * MIT License<br />
 *<br />
 * Copyright (c) 2020-2025 Armin Joachimsmeyer<br />
 *<br />
 * Permission is hereby granted, free of charge, to any person obtaining a copy<br />
 * of this software and associated documentation files (the "Software"), to deal<br />
 * in the Software without restriction, including without limitation the rights<br />
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br />
 * copies of the Software, and to permit persons to whom the Software is furnished<br />
 * to do so, subject to the following conditions:<br />
 *<br />
 * The above copyright notice and this permission notice shall be included in all<br />
 * copies or substantial portions of the Software.<br />
 *<br />
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,<br />
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A<br />
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT<br />
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF<br />
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE<br />
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.<br />
 *<br />
 ************************************************************************************<br />
 */<br />
<br />
#include &lt;Arduino.h&gt;<br />
#include &lt;IRremote.hpp&gt; // include the library<br />
<br />
uint8_t sender_pins[] = {47, 48};<br />
uint8_t receiver_pin = 13;<br />
<br />
int sender_pin_num = sizeof(sender_pins) / sizeof(sender_pins[0]);<br />
uint8_t sender_pin_idx = 0;<br />
uint8_t receive_cnt = 0;<br />
uint8_t sCommand = 0x34;<br />
uint8_t sRepeats = 0;<br />
<br />
void setup() {<br />
    Serial.begin(115200);<br />
    IrReceiver.begin(receiver_pin, false);<br />
    IrSender.begin(sender_pins[0]);<br />
<br />
    xTaskCreate(<br />
      sendIr,    // Function that should be called<br />
      "Send IR", &nbsp;&nbsp;// Name of the task (for debugging)<br />
      4096,            // Stack size (bytes)<br />
      NULL,            // Parameter to pass<br />
      1,             &nbsp;&nbsp;// Task priority<br />
      NULL           &nbsp;&nbsp;// Task handle<br />
  );<br />
}<br />
<br />
void sendIr(void * parameter) {<br />
  <br />
  delay(2000);<br />
  IrSender.setSendPin(47);<br />
  IrSender.sendNEC(0x00, sCommand, sRepeats);<br />
  Serial.printf("send by pin: %d&#92;n", 47);<br />
  delay(2000);<br />
<br />
  IrSender.setSendPin(48);<br />
  IrSender.sendNEC(0x00, sCommand, sRepeats);<br />
  Serial.printf("send by pin: %d&#92;n", 48);<br />
<br />
  delay(2000);<br />
  vTaskDelete(NULL);<br />
}<br />
<br />
void loop() {<br />
  if (IrReceiver.decode()) {<br />
      Serial.println("recv data");<br />
      if (IrReceiver.decodedIRData.protocol == UNKNOWN) {<br />
          Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));<br />
          // We have an unknown protocol here, print extended info<br />
          IrReceiver.printIRResultRawFormatted(&amp;Serial, true);<br />
<br />
          IrReceiver.resume(); // Do it here, to preserve raw data for printing with printIRResultRawFormatted()<br />
      } else {<br />
          IrReceiver.resume(); // Early enable receiving of the next IR frame<br />
<br />
          IrReceiver.printIRResultShort(&amp;Serial);<br />
          IrReceiver.printIRSendUsage(&amp;Serial);<br />
      }<br />
  } else {<br />
    // Serial.println("no data");<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=10644" target="_blank" title="">11-IR-receiver.zip</a> (Size: 1.61 KB / Downloads: 54)
<!-- 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=10645" target="_blank" title="">11-IR-receiver.ino.merged.zip</a> (Size: 194.06 KB / Downloads: 50)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-10 Print TEXT on SSD1306 OLED displayer]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9888</link>
			<pubDate>Tue, 20 Oct 2026 11:33:49 +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=9888</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 = IO18, SDA = IO8)<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=10642" target="_blank" title="">10-oled-ssd1306.zip</a> (Size: 1.11 KB / Downloads: 53)
<!-- 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=10643" target="_blank" title="">10-oled-ssd1306.ino.merged.zip</a> (Size: 202.58 KB / Downloads: 61)
<!-- 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 = IO18, SDA = IO8)<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=10642" target="_blank" title="">10-oled-ssd1306.zip</a> (Size: 1.11 KB / Downloads: 53)
<!-- 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=10643" target="_blank" title="">10-oled-ssd1306.ino.merged.zip</a> (Size: 202.58 KB / Downloads: 61)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-09 how to communication with Tuya WiFi module]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9887</link>
			<pubDate>Tue, 20 Oct 2026 11:32:41 +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=9887</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 6<br />
#define RXD_PIN 7<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=10641" target="_blank" title="">9-tuya-wifi-config.zip</a> (Size: 2 KB / Downloads: 55)
<!-- 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 6<br />
#define RXD_PIN 7<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=10641" target="_blank" title="">9-tuya-wifi-config.zip</a> (Size: 2 KB / Downloads: 55)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-08 Ethernet W5500 chip work with TCP Server mode]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9886</link>
			<pubDate>Tue, 20 Oct 2026 11:31:35 +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=9886</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: GPIO42<br />
 * - MOSI: GPIO43<br />
 * - MISO: GPIO44<br />
 * - CS: GPIO41<br />
 * - RST: GPIO1<br />
 * - INT: GPIO2<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=10639" target="_blank" title="">8-Ethernet-W5500.zip</a> (Size: 1.23 KB / Downloads: 53)
<!-- 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=10640" target="_blank" title="">8-Ethernet-W5500.ino.merged.zip</a> (Size: 191.06 KB / Downloads: 50)
<!-- 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: GPIO42<br />
 * - MOSI: GPIO43<br />
 * - MISO: GPIO44<br />
 * - CS: GPIO41<br />
 * - RST: GPIO1<br />
 * - INT: GPIO2<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=10639" target="_blank" title="">8-Ethernet-W5500.zip</a> (Size: 1.23 KB / Downloads: 53)
<!-- 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=10640" target="_blank" title="">8-Ethernet-W5500.ino.merged.zip</a> (Size: 191.06 KB / Downloads: 50)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-07 RF433MHz wireless recevier decode]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9885</link>
			<pubDate>Tue, 20 Oct 2026 11:30:24 +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=9885</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#include &lt;RCSwitch.h&gt;<br />
<br />
RCSwitch mySwitch = RCSwitch();<br />
<br />
void setup() {<br />
  Serial.begin(9600);<br />
  mySwitch.enableReceive(digitalPinToInterrupt(14)); <br />
  Serial.print("begin test");<br />
}<br />
<br />
void loop() {<br />
  if (mySwitch.available()) {<br />
    <br />
    Serial.print("Received ");<br />
    Serial.print( mySwitch.getReceivedValue() );<br />
    Serial.print(" / ");<br />
    Serial.print( mySwitch.getReceivedBitlength() );<br />
    Serial.print("bit ");<br />
    Serial.print("Protocol: ");<br />
    Serial.println( mySwitch.getReceivedProtocol() );<br />
<br />
    mySwitch.resetAvailable();<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=10637" target="_blank" title="">7-RF-433M-receiver.zip</a> (Size: 417 bytes / Downloads: 49)
<!-- 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=10638" target="_blank" title="">7-RF-433M-receiver.ino.merged.zip</a> (Size: 181.95 KB / Downloads: 62)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#include &lt;RCSwitch.h&gt;<br />
<br />
RCSwitch mySwitch = RCSwitch();<br />
<br />
void setup() {<br />
  Serial.begin(9600);<br />
  mySwitch.enableReceive(digitalPinToInterrupt(14)); <br />
  Serial.print("begin test");<br />
}<br />
<br />
void loop() {<br />
  if (mySwitch.available()) {<br />
    <br />
    Serial.print("Received ");<br />
    Serial.print( mySwitch.getReceivedValue() );<br />
    Serial.print(" / ");<br />
    Serial.print( mySwitch.getReceivedBitlength() );<br />
    Serial.print("bit ");<br />
    Serial.print("Protocol: ");<br />
    Serial.println( mySwitch.getReceivedProtocol() );<br />
<br />
    mySwitch.resetAvailable();<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=10637" target="_blank" title="">7-RF-433M-receiver.zip</a> (Size: 417 bytes / Downloads: 49)
<!-- 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=10638" target="_blank" title="">7-RF-433M-receiver.ino.merged.zip</a> (Size: 181.95 KB / Downloads: 62)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-06 How to use SD Card]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9884</link>
			<pubDate>Tue, 20 Oct 2026 11:28: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=9884</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=10635" target="_blank" title="">6-SD.zip</a> (Size: 1.53 KB / Downloads: 60)
<!-- 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=10636" target="_blank" title="">6-SD.ino.merged.zip</a> (Size: 219.15 KB / Downloads: 54)
<!-- 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=10635" target="_blank" title="">6-SD.zip</a> (Size: 1.53 KB / Downloads: 60)
<!-- 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=10636" target="_blank" title="">6-SD.ino.merged.zip</a> (Size: 219.15 KB / Downloads: 54)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-05 Read free GPIO state]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9883</link>
			<pubDate>Tue, 20 Oct 2026 11:27:41 +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=9883</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * ESP32 GPIO State Reader<br />
 * Reads the state of GPIO47, GPIO48, GPIO7, GPIO40, GPIO0, and GPIO5<br />
 * and prints the results to the serial monitor.<br />
 * <br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 */<br />
<br />
<br />
#define GPIO_40  40<br />
#define GPIO_48  48<br />
#define GPIO_0 &nbsp;&nbsp;0<br />
#define GPIO_47  47<br />
#define GPIO_17  17<br />
<br />
<br />
<br />
void setup() {<br />
    Serial.begin(115200); // Initialize serial communication at 115200 baud rate<br />
    <br />
    // Set GPIOs as input<br />
<br />
    pinMode(GPIO_40, INPUT);<br />
    pinMode(GPIO_48, INPUT);<br />
    pinMode(GPIO_0, INPUT);<br />
    pinMode(GPIO_47, INPUT);<br />
    pinMode(GPIO_17, INPUT);            <br />
}<br />
<br />
void loop() {<br />
    // Read GPIO states<br />
    int state_40 = digitalRead(GPIO_40);<br />
    int state_48 = digitalRead(GPIO_48);<br />
    int state_0  = digitalRead(GPIO_0);<br />
    int state_47 = digitalRead(GPIO_47);<br />
    int state_17 = digitalRead(GPIO_17);<br />
<br />
<br />
    // Print GPIO states to the serial monitor<br />
    Serial.printf("GPIO40: %d, GPIO48: %d, GPIO0: %d, GPIO47: %d, GPIO17: %d&#92;n",<br />
                  state_40, state_48, state_0, state_47, state_17);<br />
    <br />
    delay(1000); // Read GPIO states every 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=10633" target="_blank" title="">5-free-gpio-state.zip</a> (Size: 685 bytes / Downloads: 52)
<!-- 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=10634" target="_blank" title="">5-free-gpio-state.ino.merged.zip</a> (Size: 180.12 KB / Downloads: 51)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * ESP32 GPIO State Reader<br />
 * Reads the state of GPIO47, GPIO48, GPIO7, GPIO40, GPIO0, and GPIO5<br />
 * and prints the results to the serial monitor.<br />
 * <br />
 * Made by KinCony IoT: https://www.kincony.com<br />
 */<br />
<br />
<br />
#define GPIO_40  40<br />
#define GPIO_48  48<br />
#define GPIO_0 &nbsp;&nbsp;0<br />
#define GPIO_47  47<br />
#define GPIO_17  17<br />
<br />
<br />
<br />
void setup() {<br />
    Serial.begin(115200); // Initialize serial communication at 115200 baud rate<br />
    <br />
    // Set GPIOs as input<br />
<br />
    pinMode(GPIO_40, INPUT);<br />
    pinMode(GPIO_48, INPUT);<br />
    pinMode(GPIO_0, INPUT);<br />
    pinMode(GPIO_47, INPUT);<br />
    pinMode(GPIO_17, INPUT);            <br />
}<br />
<br />
void loop() {<br />
    // Read GPIO states<br />
    int state_40 = digitalRead(GPIO_40);<br />
    int state_48 = digitalRead(GPIO_48);<br />
    int state_0  = digitalRead(GPIO_0);<br />
    int state_47 = digitalRead(GPIO_47);<br />
    int state_17 = digitalRead(GPIO_17);<br />
<br />
<br />
    // Print GPIO states to the serial monitor<br />
    Serial.printf("GPIO40: %d, GPIO48: %d, GPIO0: %d, GPIO47: %d, GPIO17: %d&#92;n",<br />
                  state_40, state_48, state_0, state_47, state_17);<br />
    <br />
    delay(1000); // Read GPIO states every 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=10633" target="_blank" title="">5-free-gpio-state.zip</a> (Size: 685 bytes / Downloads: 52)
<!-- 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=10634" target="_blank" title="">5-free-gpio-state.ino.merged.zip</a> (Size: 180.12 KB / Downloads: 51)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-04 RS485 communication test]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9882</link>
			<pubDate>Tue, 20 Oct 2026 11:26:12 +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=9882</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");<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=10631" target="_blank" title="">4-RS485-Test.zip</a> (Size: 758 bytes / Downloads: 54)
<!-- 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=10632" target="_blank" title="">4-RS485-Test.ino.merged.zip</a> (Size: 185.84 KB / Downloads: 58)
<!-- 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");<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=10631" target="_blank" title="">4-RS485-Test.zip</a> (Size: 758 bytes / Downloads: 54)
<!-- 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=10632" target="_blank" title="">4-RS485-Test.ino.merged.zip</a> (Size: 185.84 KB / Downloads: 58)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-03 Read ADS1115 analog input ports value]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9881</link>
			<pubDate>Tue, 20 Oct 2026 11:24:38 +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=9881</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=10629" target="_blank" title="">3-ads1115_adc.zip</a> (Size: 1.2 KB / Downloads: 54)
<!-- 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=10630" target="_blank" title="">3-ads1115_adc.ino.merged.zip</a> (Size: 194.32 KB / Downloads: 55)
<!-- 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=10629" target="_blank" title="">3-ads1115_adc.zip</a> (Size: 1.2 KB / Downloads: 54)
<!-- 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=10630" target="_blank" title="">3-ads1115_adc.ino.merged.zip</a> (Size: 194.32 KB / Downloads: 55)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-02 Read digital input ports state]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9880</link>
			<pubDate>Tue, 20 Oct 2026 11:22:41 +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=9880</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 />
 * Description:<br />
 * This Arduino program reads the state of a 16-channel PCF8574 I/O expander<br />
 * and prints the state of all input pins to the Serial Monitor. The state of <br />
 * each pin is represented as a bit in a 8-bit value, where each bit corresponds <br />
 * to an input pin. The program prints the input state in binary format.<br />
 *<br />
 * Pin Definitions:<br />
 * - SDA: GPIO 8<br />
 * - SCL: GPIO 18<br />
 * - PCF8575 I2C Address: 0x22<br />
 */<br />
<br />
#include "Arduino.h"<br />
#include "PCF8574.h"<br />
<br />
// Define I2C pins<br />
#define I2C_SDA 8  // Define SDA pin<br />
#define I2C_SCL 18  // Define SCL pin<br />
<br />
// Set I2C address<br />
PCF8574 pcf8574_IN1(0x22); // The I2C address of the PCF8575<br />
<br />
void setup() {<br />
    Serial.begin(115200);<br />
<br />
    // Initialize I2C communication<br />
    Wire.begin(I2C_SDA, I2C_SCL); // Initialize I2C with defined SDA and SCL pins<br />
<br />
    pcf8574_IN1.pinMode(P0, INPUT);<br />
    pcf8574_IN1.pinMode(P1, INPUT);<br />
    pcf8574_IN1.pinMode(P2, INPUT);<br />
    pcf8574_IN1.pinMode(P3, INPUT);<br />
    pcf8574_IN1.pinMode(P4, INPUT);<br />
    pcf8574_IN1.pinMode(P5, INPUT);<br />
    pcf8574_IN1.pinMode(P6, INPUT);<br />
    pcf8574_IN1.pinMode(P7, INPUT);<br />
<br />
    pcf8574_IN1.begin(); // Initialize the PCF8575<br />
<br />
    Serial.println("KinCony 8 channel input state 0:ON  1:OFF");<br />
}<br />
<br />
void loop() {<br />
    uint16_t state = 0;<br />
<br />
    // Read the state of each pin (assuming 16 pins)<br />
    for (int pin = 0; pin &lt; 8; pin++) {<br />
        if (pcf8574_IN1.digitalRead(pin)) {<br />
            state |= (1 &lt;&lt; pin); // Set the bit for the active pin<br />
        }<br />
    }<br />
<br />
    Serial.print("Input state: ");<br />
    Serial.println(state, BIN); // Print the state of inputs in binary<br />
<br />
    delay(500); // Delay 500ms<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=10627" target="_blank" title="">2-digital-input.zip</a> (Size: 890 bytes / Downloads: 56)
<!-- 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=10628" target="_blank" title="">2-digital-input.ino.merged.zip</a> (Size: 195.59 KB / Downloads: 59)
<!-- 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 />
 * Description:<br />
 * This Arduino program reads the state of a 16-channel PCF8574 I/O expander<br />
 * and prints the state of all input pins to the Serial Monitor. The state of <br />
 * each pin is represented as a bit in a 8-bit value, where each bit corresponds <br />
 * to an input pin. The program prints the input state in binary format.<br />
 *<br />
 * Pin Definitions:<br />
 * - SDA: GPIO 8<br />
 * - SCL: GPIO 18<br />
 * - PCF8575 I2C Address: 0x22<br />
 */<br />
<br />
#include "Arduino.h"<br />
#include "PCF8574.h"<br />
<br />
// Define I2C pins<br />
#define I2C_SDA 8  // Define SDA pin<br />
#define I2C_SCL 18  // Define SCL pin<br />
<br />
// Set I2C address<br />
PCF8574 pcf8574_IN1(0x22); // The I2C address of the PCF8575<br />
<br />
void setup() {<br />
    Serial.begin(115200);<br />
<br />
    // Initialize I2C communication<br />
    Wire.begin(I2C_SDA, I2C_SCL); // Initialize I2C with defined SDA and SCL pins<br />
<br />
    pcf8574_IN1.pinMode(P0, INPUT);<br />
    pcf8574_IN1.pinMode(P1, INPUT);<br />
    pcf8574_IN1.pinMode(P2, INPUT);<br />
    pcf8574_IN1.pinMode(P3, INPUT);<br />
    pcf8574_IN1.pinMode(P4, INPUT);<br />
    pcf8574_IN1.pinMode(P5, INPUT);<br />
    pcf8574_IN1.pinMode(P6, INPUT);<br />
    pcf8574_IN1.pinMode(P7, INPUT);<br />
<br />
    pcf8574_IN1.begin(); // Initialize the PCF8575<br />
<br />
    Serial.println("KinCony 8 channel input state 0:ON  1:OFF");<br />
}<br />
<br />
void loop() {<br />
    uint16_t state = 0;<br />
<br />
    // Read the state of each pin (assuming 16 pins)<br />
    for (int pin = 0; pin &lt; 8; pin++) {<br />
        if (pcf8574_IN1.digitalRead(pin)) {<br />
            state |= (1 &lt;&lt; pin); // Set the bit for the active pin<br />
        }<br />
    }<br />
<br />
    Serial.print("Input state: ");<br />
    Serial.println(state, BIN); // Print the state of inputs in binary<br />
<br />
    delay(500); // Delay 500ms<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=10627" target="_blank" title="">2-digital-input.zip</a> (Size: 890 bytes / Downloads: 56)
<!-- 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=10628" target="_blank" title="">2-digital-input.ino.merged.zip</a> (Size: 195.59 KB / Downloads: 59)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[[arduino code examples for MT4v2]-01 Control 4 channel DC motor]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9879</link>
			<pubDate>Tue, 20 Oct 2026 11:18:33 +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=9879</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * KinCony MT4V2 DC Motor Test<br />
 * Power ON -&gt; M1-M4 run at 100%<br />
 *<br />
 * Made by KinCony IoT<br />
 * https://www.kincony.com<br />
 */<br />
<br />
#include &lt;Arduino.h&gt;<br />
<br />
#define RXD 15<br />
#define TXD 16<br />
<br />
HardwareSerial MotorSerial(1);<br />
<br />
uint16_t crc16(const uint8_t *data, uint8_t len)<br />
{<br />
  uint16_t crc = 0xFFFF;<br />
<br />
  while (len--)<br />
  {<br />
    crc ^= *data++;<br />
<br />
    for (uint8_t i = 0; i &lt; 8; i++)<br />
      crc = (crc &amp; 1) ? (crc &gt;&gt; 1) ^ 0xA001 : crc &gt;&gt; 1;<br />
  }<br />
<br />
  return crc;<br />
}<br />
<br />
void sendFrame(uint8_t *data)<br />
{<br />
  uint16_t crc = crc16(data, 6);<br />
<br />
  MotorSerial.write(data, 6);<br />
  MotorSerial.write(crc &amp; 0xFF);<br />
  MotorSerial.write(crc &gt;&gt; 8);<br />
  MotorSerial.flush();<br />
<br />
  delay(50);<br />
<br />
  // Clear ARM response<br />
  while (MotorSerial.available())<br />
    MotorSerial.read();<br />
}<br />
<br />
void enableMotor()<br />
{<br />
  uint8_t cmd[] = {<br />
    1, 0x05,<br />
    0x01, 0xF7,   &nbsp;&nbsp;// Coil 503<br />
    0xFF, 0x00      // ON<br />
  };<br />
<br />
  sendFrame(cmd);<br />
}<br />
<br />
void setMotor(uint8_t motor, int16_t speed)<br />
{<br />
  uint16_t reg = 2000 + motor - 1;<br />
<br />
  uint8_t cmd[] = {<br />
    1, 0x06,<br />
    uint8_t(reg &gt;&gt; 8),<br />
    uint8_t(reg),<br />
    uint8_t(speed &gt;&gt; 8),<br />
    uint8_t(speed)<br />
  };<br />
<br />
  sendFrame(cmd);<br />
}<br />
<br />
void startMotors()<br />
{<br />
  enableMotor();<br />
<br />
  setMotor(1, 100);  //100 is speed<br />
  setMotor(2, 100);  //100 is speed<br />
  setMotor(3, 100);  //100 is speed<br />
  setMotor(4, 100);  //100 is speed<br />
}<br />
<br />
void setup()<br />
{<br />
  MotorSerial.begin(115200, SERIAL_8N1, RXD, TXD);<br />
<br />
  // Wait for ARM CPU startup<br />
  delay(3000);<br />
<br />
  startMotors();<br />
}<br />
<br />
void loop()<br />
{<br />
  // Refresh commands every 2 seconds<br />
  delay(2000);<br />
<br />
  startMotors();<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=10625" target="_blank" title="">1-motor.zip</a> (Size: 797 bytes / Downloads: 51)
<!-- 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=10626" target="_blank" title="">1-motor.ino.merged.zip</a> (Size: 185.77 KB / Downloads: 50)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>/*<br />
 * KinCony MT4V2 DC Motor Test<br />
 * Power ON -&gt; M1-M4 run at 100%<br />
 *<br />
 * Made by KinCony IoT<br />
 * https://www.kincony.com<br />
 */<br />
<br />
#include &lt;Arduino.h&gt;<br />
<br />
#define RXD 15<br />
#define TXD 16<br />
<br />
HardwareSerial MotorSerial(1);<br />
<br />
uint16_t crc16(const uint8_t *data, uint8_t len)<br />
{<br />
  uint16_t crc = 0xFFFF;<br />
<br />
  while (len--)<br />
  {<br />
    crc ^= *data++;<br />
<br />
    for (uint8_t i = 0; i &lt; 8; i++)<br />
      crc = (crc &amp; 1) ? (crc &gt;&gt; 1) ^ 0xA001 : crc &gt;&gt; 1;<br />
  }<br />
<br />
  return crc;<br />
}<br />
<br />
void sendFrame(uint8_t *data)<br />
{<br />
  uint16_t crc = crc16(data, 6);<br />
<br />
  MotorSerial.write(data, 6);<br />
  MotorSerial.write(crc &amp; 0xFF);<br />
  MotorSerial.write(crc &gt;&gt; 8);<br />
  MotorSerial.flush();<br />
<br />
  delay(50);<br />
<br />
  // Clear ARM response<br />
  while (MotorSerial.available())<br />
    MotorSerial.read();<br />
}<br />
<br />
void enableMotor()<br />
{<br />
  uint8_t cmd[] = {<br />
    1, 0x05,<br />
    0x01, 0xF7,   &nbsp;&nbsp;// Coil 503<br />
    0xFF, 0x00      // ON<br />
  };<br />
<br />
  sendFrame(cmd);<br />
}<br />
<br />
void setMotor(uint8_t motor, int16_t speed)<br />
{<br />
  uint16_t reg = 2000 + motor - 1;<br />
<br />
  uint8_t cmd[] = {<br />
    1, 0x06,<br />
    uint8_t(reg &gt;&gt; 8),<br />
    uint8_t(reg),<br />
    uint8_t(speed &gt;&gt; 8),<br />
    uint8_t(speed)<br />
  };<br />
<br />
  sendFrame(cmd);<br />
}<br />
<br />
void startMotors()<br />
{<br />
  enableMotor();<br />
<br />
  setMotor(1, 100);  //100 is speed<br />
  setMotor(2, 100);  //100 is speed<br />
  setMotor(3, 100);  //100 is speed<br />
  setMotor(4, 100);  //100 is speed<br />
}<br />
<br />
void setup()<br />
{<br />
  MotorSerial.begin(115200, SERIAL_8N1, RXD, TXD);<br />
<br />
  // Wait for ARM CPU startup<br />
  delay(3000);<br />
<br />
  startMotors();<br />
}<br />
<br />
void loop()<br />
{<br />
  // Refresh commands every 2 seconds<br />
  delay(2000);<br />
<br />
  startMotors();<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=10625" target="_blank" title="">1-motor.zip</a> (Size: 797 bytes / Downloads: 51)
<!-- 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=10626" target="_blank" title="">1-motor.ino.merged.zip</a> (Size: 185.77 KB / Downloads: 50)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[MT4v2 ESPHome yaml for home assistant without tuya]]></title>
			<link>https://www.kincony.com/forum/showthread.php?tid=9878</link>
			<pubDate>Tue, 20 Oct 2026 11:15:47 +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=9878</guid>
			<description><![CDATA[<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>esphome:<br />
  name: mt4v2<br />
  friendly_name: mt4v2<br />
<br />
<br />
# ============================================================<br />
# ESP32-S3<br />
# ============================================================<br />
<br />
esp32:<br />
  board: esp32-s3-devkitc-1<br />
  framework:<br />
    type: arduino<br />
<br />
<br />
# ============================================================<br />
# Logger<br />
# ============================================================<br />
<br />
logger:<br />
  hardware_uart: USB_SERIAL_JTAG<br />
<br />
<br />
# ============================================================<br />
# Home Assistant API<br />
# ============================================================<br />
<br />
api:<br />
<br />
<br />
# ============================================================<br />
# Ethernet - W5500<br />
# ============================================================<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 />
<br />
# ============================================================<br />
# I2C<br />
# ============================================================<br />
<br />
i2c:<br />
  - id: bus_a<br />
    sda: 8<br />
    scl: 18<br />
    scan: true<br />
    frequency: 400kHz<br />
<br />
<br />
# ============================================================<br />
# PCF8574 - Digital Inputs<br />
# ============================================================<br />
<br />
pcf8574:<br />
  - id: pcf8574_hub_in_1<br />
    i2c_id: bus_a<br />
    address: 0x24<br />
<br />
<br />
# ============================================================<br />
# UART<br />
# ============================================================<br />
<br />
uart:<br />
<br />
  # RS485 UART<br />
  - id: uart_1<br />
    baud_rate: 9600<br />
    tx_pin: 39<br />
    rx_pin: 38<br />
    debug:<br />
      direction: BOTH<br />
      dummy_receiver: true<br />
      after:<br />
        timeout: 10ms<br />
<br />
  # ARM CPU Motor Control UART<br />
  # ESP32-S3 TX GPIO16 -&gt; ARM RX<br />
  # ESP32-S3 RX GPIO15 &lt;- ARM TX<br />
  # MODBUS RTU 115200 / 8N1<br />
  - id: uart_motor<br />
    baud_rate: 115200<br />
    tx_pin: 16<br />
    rx_pin: 15<br />
    data_bits: 8<br />
    parity: NONE<br />
    stop_bits: 1<br />
<br />
<br />
# ============================================================<br />
# Global Motor Speed Variables<br />
#<br />
# Positive = Forward<br />
# Negative = Reverse<br />
# 0        = Stop<br />
# ============================================================<br />
<br />
globals:<br />
<br />
  - id: motor1_speed<br />
    type: int<br />
    restore_value: no<br />
    initial_value: '100'<br />
<br />
  - id: motor2_speed<br />
    type: int<br />
    restore_value: no<br />
    initial_value: '100'<br />
<br />
  - id: motor3_speed<br />
    type: int<br />
    restore_value: no<br />
    initial_value: '100'<br />
<br />
  - id: motor4_speed<br />
    type: int<br />
    restore_value: no<br />
    initial_value: '100'<br />
<br />
<br />
# ============================================================<br />
# Motor MODBUS Scripts<br />
# ============================================================<br />
<br />
script:<br />
<br />
  # ----------------------------------------------------------<br />
  # Motor Master Enable<br />
  # Coil 503 = ON<br />
  # ----------------------------------------------------------<br />
<br />
  - id: motor_enable<br />
    then:<br />
      - lambda: |-<br />
          uint8_t data[6] = {<br />
            0x01, 0x05,<br />
            0x01, 0xF7,<br />
            0xFF, 0x00<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
  # ----------------------------------------------------------<br />
  # Motor 1 - Register 2000<br />
  # ----------------------------------------------------------<br />
<br />
  - id: motor1_write<br />
    mode: restart<br />
    then:<br />
      - lambda: |-<br />
          int16_t speed = id(motor1_speed);<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x06,<br />
            0x07, 0xD0,<br />
            (uint8_t)(speed &gt;&gt; 8),<br />
            (uint8_t)speed<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
  # ----------------------------------------------------------<br />
  # Motor 2 - Register 2001<br />
  # ----------------------------------------------------------<br />
<br />
  - id: motor2_write<br />
    mode: restart<br />
    then:<br />
      - lambda: |-<br />
          int16_t speed = id(motor2_speed);<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x06,<br />
            0x07, 0xD1,<br />
            (uint8_t)(speed &gt;&gt; 8),<br />
            (uint8_t)speed<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
  # ----------------------------------------------------------<br />
  # Motor 3 - Register 2002<br />
  # ----------------------------------------------------------<br />
<br />
  - id: motor3_write<br />
    mode: restart<br />
    then:<br />
      - lambda: |-<br />
          int16_t speed = id(motor3_speed);<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x06,<br />
            0x07, 0xD2,<br />
            (uint8_t)(speed &gt;&gt; 8),<br />
            (uint8_t)speed<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
  # ----------------------------------------------------------<br />
  # Motor 4 - Register 2003<br />
  # ----------------------------------------------------------<br />
<br />
  - id: motor4_write<br />
    mode: restart<br />
    then:<br />
      - lambda: |-<br />
          int16_t speed = id(motor4_speed);<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x06,<br />
            0x07, 0xD3,<br />
            (uint8_t)(speed &gt;&gt; 8),<br />
            (uint8_t)speed<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
# ============================================================<br />
# Motor Speed Sliders<br />
#<br />
# 0 &nbsp;&nbsp;= Stop<br />
# 100 = Full Speed<br />
#<br />
# Slider changes motor speed immediately.<br />
# Current direction is retained.<br />
# ============================================================<br />
<br />
number:<br />
<br />
  - platform: template<br />
    name: "Motor 1 Speed"<br />
    id: motor1_speed_slider<br />
    min_value: 0<br />
    max_value: 100<br />
    step: 1<br />
    initial_value: 100<br />
    optimistic: true<br />
    mode: slider<br />
    set_action:<br />
      - lambda: |-<br />
          if (id(motor1_speed) &lt; 0)<br />
            id(motor1_speed) = -(int)x;<br />
          else<br />
            id(motor1_speed) = (int)x;<br />
      - script.execute: motor1_write<br />
<br />
<br />
  - platform: template<br />
    name: "Motor 2 Speed"<br />
    id: motor2_speed_slider<br />
    min_value: 0<br />
    max_value: 100<br />
    step: 1<br />
    initial_value: 100<br />
    optimistic: true<br />
    mode: slider<br />
    set_action:<br />
      - lambda: |-<br />
          if (id(motor2_speed) &lt; 0)<br />
            id(motor2_speed) = -(int)x;<br />
          else<br />
            id(motor2_speed) = (int)x;<br />
      - script.execute: motor2_write<br />
<br />
<br />
  - platform: template<br />
    name: "Motor 3 Speed"<br />
    id: motor3_speed_slider<br />
    min_value: 0<br />
    max_value: 100<br />
    step: 1<br />
    initial_value: 100<br />
    optimistic: true<br />
    mode: slider<br />
    set_action:<br />
      - lambda: |-<br />
          if (id(motor3_speed) &lt; 0)<br />
            id(motor3_speed) = -(int)x;<br />
          else<br />
            id(motor3_speed) = (int)x;<br />
      - script.execute: motor3_write<br />
<br />
<br />
  - platform: template<br />
    name: "Motor 4 Speed"<br />
    id: motor4_speed_slider<br />
    min_value: 0<br />
    max_value: 100<br />
    step: 1<br />
    initial_value: 100<br />
    optimistic: true<br />
    mode: slider<br />
    set_action:<br />
      - lambda: |-<br />
          if (id(motor4_speed) &lt; 0)<br />
            id(motor4_speed) = -(int)x;<br />
          else<br />
            id(motor4_speed) = (int)x;<br />
      - script.execute: motor4_write<br />
<br />
<br />
# ============================================================<br />
# Motor Control Buttons<br />
# ============================================================<br />
<br />
button:<br />
<br />
  # Motor 1<br />
  - platform: template<br />
    name: "Motor 1 Forward"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor1_speed) =<br />
            abs((int)id(motor1_speed_slider).state);<br />
      - script.execute: motor1_write<br />
<br />
  - platform: template<br />
    name: "Motor 1 Reverse"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor1_speed) =<br />
            -abs((int)id(motor1_speed_slider).state);<br />
      - script.execute: motor1_write<br />
<br />
  - platform: template<br />
    name: "Motor 1 Stop"<br />
    on_press:<br />
      - lambda: |-<br />
          id(motor1_speed) = 0;<br />
      - script.execute: motor1_write<br />
<br />
<br />
  # Motor 2<br />
  - platform: template<br />
    name: "Motor 2 Forward"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor2_speed) =<br />
            abs((int)id(motor2_speed_slider).state);<br />
      - script.execute: motor2_write<br />
<br />
  - platform: template<br />
    name: "Motor 2 Reverse"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor2_speed) =<br />
            -abs((int)id(motor2_speed_slider).state);<br />
      - script.execute: motor2_write<br />
<br />
  - platform: template<br />
    name: "Motor 2 Stop"<br />
    on_press:<br />
      - lambda: |-<br />
          id(motor2_speed) = 0;<br />
      - script.execute: motor2_write<br />
<br />
<br />
  # Motor 3<br />
  - platform: template<br />
    name: "Motor 3 Forward"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor3_speed) =<br />
            abs((int)id(motor3_speed_slider).state);<br />
      - script.execute: motor3_write<br />
<br />
  - platform: template<br />
    name: "Motor 3 Reverse"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor3_speed) =<br />
            -abs((int)id(motor3_speed_slider).state);<br />
      - script.execute: motor3_write<br />
<br />
  - platform: template<br />
    name: "Motor 3 Stop"<br />
    on_press:<br />
      - lambda: |-<br />
          id(motor3_speed) = 0;<br />
      - script.execute: motor3_write<br />
<br />
<br />
  # Motor 4<br />
  - platform: template<br />
    name: "Motor 4 Forward"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor4_speed) =<br />
            abs((int)id(motor4_speed_slider).state);<br />
      - script.execute: motor4_write<br />
<br />
  - platform: template<br />
    name: "Motor 4 Reverse"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor4_speed) =<br />
            -abs((int)id(motor4_speed_slider).state);<br />
      - script.execute: motor4_write<br />
<br />
  - platform: template<br />
    name: "Motor 4 Stop"<br />
    on_press:<br />
      - lambda: |-<br />
          id(motor4_speed) = 0;<br />
      - script.execute: motor4_write<br />
<br />
<br />
# ============================================================<br />
# RS485 Test Switch<br />
# ============================================================<br />
<br />
switch:<br />
<br />
  - platform: uart<br />
    uart_id: uart_1<br />
    name: "RS485 Button"<br />
    data: [0x11, 0x22, 0x33, 0x44, 0x55]<br />
<br />
<br />
# ============================================================<br />
# Digital Inputs<br />
# ============================================================<br />
<br />
binary_sensor:<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input01"<br />
    id: mt4v2_input01<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 0<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input02"<br />
    id: mt4v2_input02<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 1<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input03"<br />
    id: mt4v2_input03<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 2<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input04"<br />
    id: mt4v2_input04<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 3<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input05"<br />
    id: mt4v2_input05<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 4<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input06"<br />
    id: mt4v2_input06<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 5<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input07"<br />
    id: mt4v2_input07<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 6<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input08"<br />
    id: mt4v2_input08<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 7<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
<br />
  # GPIO inputs with pull-up resistors on PCB<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-W1-io47"<br />
    pin:<br />
      number: 47<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-W1-io48"<br />
    pin:<br />
      number: 48<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-W1-io17"<br />
    pin:<br />
      number: 17<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-W1-io40"<br />
    pin:<br />
      number: 40<br />
      inverted: true<br />
<br />
<br />
  # ==========================================================<br />
  # DRV8262 Fault Status<br />
  #<br />
  # Register 2020 = DRV8262 #1<br />
  # Register 2021 = DRV8262 #2<br />
  #<br />
  # OFF = Normal<br />
  # ON  = Problem<br />
  # ==========================================================<br />
<br />
  - platform: template<br />
    name: "DRV8262-1 Fault"<br />
    id: drv8262_1_fault<br />
    device_class: problem<br />
<br />
  - platform: template<br />
    name: "DRV8262-2 Fault"<br />
    id: drv8262_2_fault<br />
    device_class: problem<br />
<br />
<br />
# ============================================================<br />
# ADS1115<br />
# ============================================================<br />
<br />
ads1115:<br />
  - address: 0x48<br />
<br />
<br />
# ============================================================<br />
# Sensors<br />
# ============================================================<br />
<br />
sensor:<br />
<br />
  # ADS1115 Channel 1<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 />
<br />
  # ADS1115 Channel 2<br />
  - platform: ads1115<br />
    multiplexer: A1_GND<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A1-GND"<br />
    update_interval: 5s<br />
<br />
  # ADS1115 Channel 3<br />
  - platform: ads1115<br />
    multiplexer: A2_GND<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A2-GND"<br />
    update_interval: 5s<br />
<br />
  # ADS1115 Channel 4<br />
  - platform: ads1115<br />
    multiplexer: A3_GND<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A3-GND"<br />
    update_interval: 5s<br />
<br />
<br />
  # ==========================================================<br />
  # Motor Current<br />
  #<br />
  # ARM MODBUS Registers:<br />
  # 2010 = Motor 1 Current<br />
  # 2011 = Motor 2 Current<br />
  # 2012 = Motor 3 Current<br />
  # 2013 = Motor 4 Current<br />
  #<br />
  # Values are displayed as raw register values.<br />
  # ==========================================================<br />
<br />
  - platform: template<br />
    name: "Motor 1 Current"<br />
    id: motor1_current<br />
    accuracy_decimals: 0<br />
    update_interval: never<br />
<br />
  - platform: template<br />
    name: "Motor 2 Current"<br />
    id: motor2_current<br />
    accuracy_decimals: 0<br />
    update_interval: never<br />
<br />
  - platform: template<br />
    name: "Motor 3 Current"<br />
    id: motor3_current<br />
    accuracy_decimals: 0<br />
    update_interval: never<br />
<br />
  - platform: template<br />
    name: "Motor 4 Current"<br />
    id: motor4_current<br />
    accuracy_decimals: 0<br />
    update_interval: never<br />
<br />
<br />
# ============================================================<br />
# MODBUS Status Polling<br />
#<br />
# Every 2 seconds:<br />
#<br />
# Read 2010-2013 -&gt; Motor Current<br />
# Read 2020-2021 -&gt; DRV8262 Fault<br />
# ============================================================<br />
<br />
interval:<br />
<br />
  - interval: 2s<br />
    then:<br />
<br />
      # ======================================================<br />
      # Read Motor Current<br />
      #<br />
      # FC03<br />
      # Start Register = 2010<br />
      # Quantity     &nbsp;&nbsp;= 4<br />
      # ======================================================<br />
<br />
      - lambda: |-<br />
<br />
          // Clear old UART receive data<br />
          while (id(uart_motor).available()) {<br />
            uint8_t c;<br />
            id(uart_motor).read_byte(&amp;c);<br />
          }<br />
<br />
          // MODBUS request:<br />
          // Slave 1<br />
          // Function 03<br />
          // Start address 2010 = 0x07DA<br />
          // Read 4 registers<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x03,<br />
            0x07, 0xDA,<br />
            0x00, 0x04<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          // Calculate MODBUS RTU CRC16<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          // Send MODBUS request<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          // Send CRC<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
      # Wait for ARM CPU response<br />
      - delay: 50ms<br />
<br />
<br />
      # ======================================================<br />
      # Process Motor Current Response<br />
      # ======================================================<br />
<br />
      - lambda: |-<br />
<br />
          uint8_t rx[32];<br />
          int len = 0;<br />
<br />
          // Read UART response<br />
          while (id(uart_motor).available() &amp;&amp; len &lt; 32) {<br />
            id(uart_motor).read_byte(&amp;rx[len]);<br />
            len++;<br />
          }<br />
<br />
          // Expected response:<br />
          //<br />
          // 01 03 08<br />
          // M1_H M1_L<br />
          // M2_H M2_L<br />
          // M3_H M3_L<br />
          // M4_H M4_L<br />
          // CRC_L CRC_H<br />
          //<br />
          // Total = 13 bytes<br />
<br />
          if (len &gt;= 13 &amp;&amp;<br />
              rx[0] == 0x01 &amp;&amp;<br />
              rx[1] == 0x03 &amp;&amp;<br />
              rx[2] == 0x08) {<br />
<br />
            uint16_t m1 =<br />
              ((uint16_t)rx[3] &lt;&lt; 8) | rx[4];<br />
<br />
            uint16_t m2 =<br />
              ((uint16_t)rx[5] &lt;&lt; 8) | rx[6];<br />
<br />
            uint16_t m3 =<br />
              ((uint16_t)rx[7] &lt;&lt; 8) | rx[8];<br />
<br />
            uint16_t m4 =<br />
              ((uint16_t)rx[9] &lt;&lt; 8) | rx[10];<br />
<br />
            // Publish values to ESPHome<br />
            id(motor1_current).publish_state(m1);<br />
            id(motor2_current).publish_state(m2);<br />
            id(motor3_current).publish_state(m3);<br />
            id(motor4_current).publish_state(m4);<br />
          }<br />
<br />
<br />
      # ======================================================<br />
      # Read DRV8262 Fault Status<br />
      #<br />
      # FC03<br />
      # Start Register = 2020<br />
      # Quantity     &nbsp;&nbsp;= 2<br />
      # ======================================================<br />
<br />
      - lambda: |-<br />
<br />
          // Clear UART receive buffer<br />
          while (id(uart_motor).available()) {<br />
            uint8_t c;<br />
            id(uart_motor).read_byte(&amp;c);<br />
          }<br />
<br />
          // MODBUS request:<br />
          // Slave 1<br />
          // Function 03<br />
          // Start address 2020 = 0x07E4<br />
          // Read 2 registers<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x03,<br />
            0x07, 0xE4,<br />
            0x00, 0x02<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          // Calculate MODBUS RTU CRC16<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          // Send MODBUS request<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          // Send CRC<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
      # Wait for ARM CPU response<br />
      - delay: 50ms<br />
<br />
<br />
      # ======================================================<br />
      # Process DRV8262 Fault Response<br />
      # ======================================================<br />
<br />
      - lambda: |-<br />
<br />
          uint8_t rx[16];<br />
          int len = 0;<br />
<br />
          // Read UART response<br />
          while (id(uart_motor).available() &amp;&amp; len &lt; 16) {<br />
            id(uart_motor).read_byte(&amp;rx[len]);<br />
            len++;<br />
          }<br />
<br />
          // Expected response:<br />
          //<br />
          // 01 03 04<br />
          // Fault1_H Fault1_L<br />
          // Fault2_H Fault2_L<br />
          // CRC_L CRC_H<br />
          //<br />
          // Total = 9 bytes<br />
<br />
          if (len &gt;= 9 &amp;&amp;<br />
              rx[0] == 0x01 &amp;&amp;<br />
              rx[1] == 0x03 &amp;&amp;<br />
              rx[2] == 0x04) {<br />
<br />
            uint16_t fault1 =<br />
              ((uint16_t)rx[3] &lt;&lt; 8) | rx[4];<br />
<br />
            uint16_t fault2 =<br />
              ((uint16_t)rx[5] &lt;&lt; 8) | rx[6];<br />
<br />
            // 0 = Normal<br />
            // Non-zero = Fault<br />
            id(drv8262_1_fault).publish_state(<br />
              fault1 != 0<br />
            );<br />
<br />
            id(drv8262_2_fault).publish_state(<br />
              fault2 != 0<br />
            );<br />
          }<br />
<br />
<br />
# ============================================================<br />
# Web Server<br />
# ============================================================<br />
<br />
web_server:<br />
  port: 80<br />
<br />
<br />
# ============================================================<br />
# OLED Font<br />
# ============================================================<br />
<br />
font:<br />
  - file: "gfonts://Roboto"<br />
    id: roboto<br />
    size: 20<br />
<br />
<br />
# ============================================================<br />
# OLED Display<br />
# ============================================================<br />
<br />
display:<br />
<br />
  - platform: ssd1306_i2c<br />
    i2c_id: bus_a<br />
    model: "SSD1306 128x64"<br />
    address: 0x3C<br />
<br />
    lambda: |-<br />
      it.printf(<br />
        0,<br />
        0,<br />
        id(roboto),<br />
        "KinCony MT4v2"<br />
      );</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=10624" target="_blank" title="">MT4v2-HA-Motor-Current-Without-Tuya.txt</a> (Size: 22.74 KB / Downloads: 58)
<!-- 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: mt4v2<br />
  friendly_name: mt4v2<br />
<br />
<br />
# ============================================================<br />
# ESP32-S3<br />
# ============================================================<br />
<br />
esp32:<br />
  board: esp32-s3-devkitc-1<br />
  framework:<br />
    type: arduino<br />
<br />
<br />
# ============================================================<br />
# Logger<br />
# ============================================================<br />
<br />
logger:<br />
  hardware_uart: USB_SERIAL_JTAG<br />
<br />
<br />
# ============================================================<br />
# Home Assistant API<br />
# ============================================================<br />
<br />
api:<br />
<br />
<br />
# ============================================================<br />
# Ethernet - W5500<br />
# ============================================================<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 />
<br />
# ============================================================<br />
# I2C<br />
# ============================================================<br />
<br />
i2c:<br />
  - id: bus_a<br />
    sda: 8<br />
    scl: 18<br />
    scan: true<br />
    frequency: 400kHz<br />
<br />
<br />
# ============================================================<br />
# PCF8574 - Digital Inputs<br />
# ============================================================<br />
<br />
pcf8574:<br />
  - id: pcf8574_hub_in_1<br />
    i2c_id: bus_a<br />
    address: 0x24<br />
<br />
<br />
# ============================================================<br />
# UART<br />
# ============================================================<br />
<br />
uart:<br />
<br />
  # RS485 UART<br />
  - id: uart_1<br />
    baud_rate: 9600<br />
    tx_pin: 39<br />
    rx_pin: 38<br />
    debug:<br />
      direction: BOTH<br />
      dummy_receiver: true<br />
      after:<br />
        timeout: 10ms<br />
<br />
  # ARM CPU Motor Control UART<br />
  # ESP32-S3 TX GPIO16 -&gt; ARM RX<br />
  # ESP32-S3 RX GPIO15 &lt;- ARM TX<br />
  # MODBUS RTU 115200 / 8N1<br />
  - id: uart_motor<br />
    baud_rate: 115200<br />
    tx_pin: 16<br />
    rx_pin: 15<br />
    data_bits: 8<br />
    parity: NONE<br />
    stop_bits: 1<br />
<br />
<br />
# ============================================================<br />
# Global Motor Speed Variables<br />
#<br />
# Positive = Forward<br />
# Negative = Reverse<br />
# 0        = Stop<br />
# ============================================================<br />
<br />
globals:<br />
<br />
  - id: motor1_speed<br />
    type: int<br />
    restore_value: no<br />
    initial_value: '100'<br />
<br />
  - id: motor2_speed<br />
    type: int<br />
    restore_value: no<br />
    initial_value: '100'<br />
<br />
  - id: motor3_speed<br />
    type: int<br />
    restore_value: no<br />
    initial_value: '100'<br />
<br />
  - id: motor4_speed<br />
    type: int<br />
    restore_value: no<br />
    initial_value: '100'<br />
<br />
<br />
# ============================================================<br />
# Motor MODBUS Scripts<br />
# ============================================================<br />
<br />
script:<br />
<br />
  # ----------------------------------------------------------<br />
  # Motor Master Enable<br />
  # Coil 503 = ON<br />
  # ----------------------------------------------------------<br />
<br />
  - id: motor_enable<br />
    then:<br />
      - lambda: |-<br />
          uint8_t data[6] = {<br />
            0x01, 0x05,<br />
            0x01, 0xF7,<br />
            0xFF, 0x00<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
  # ----------------------------------------------------------<br />
  # Motor 1 - Register 2000<br />
  # ----------------------------------------------------------<br />
<br />
  - id: motor1_write<br />
    mode: restart<br />
    then:<br />
      - lambda: |-<br />
          int16_t speed = id(motor1_speed);<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x06,<br />
            0x07, 0xD0,<br />
            (uint8_t)(speed &gt;&gt; 8),<br />
            (uint8_t)speed<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
  # ----------------------------------------------------------<br />
  # Motor 2 - Register 2001<br />
  # ----------------------------------------------------------<br />
<br />
  - id: motor2_write<br />
    mode: restart<br />
    then:<br />
      - lambda: |-<br />
          int16_t speed = id(motor2_speed);<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x06,<br />
            0x07, 0xD1,<br />
            (uint8_t)(speed &gt;&gt; 8),<br />
            (uint8_t)speed<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
  # ----------------------------------------------------------<br />
  # Motor 3 - Register 2002<br />
  # ----------------------------------------------------------<br />
<br />
  - id: motor3_write<br />
    mode: restart<br />
    then:<br />
      - lambda: |-<br />
          int16_t speed = id(motor3_speed);<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x06,<br />
            0x07, 0xD2,<br />
            (uint8_t)(speed &gt;&gt; 8),<br />
            (uint8_t)speed<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
  # ----------------------------------------------------------<br />
  # Motor 4 - Register 2003<br />
  # ----------------------------------------------------------<br />
<br />
  - id: motor4_write<br />
    mode: restart<br />
    then:<br />
      - lambda: |-<br />
          int16_t speed = id(motor4_speed);<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x06,<br />
            0x07, 0xD3,<br />
            (uint8_t)(speed &gt;&gt; 8),<br />
            (uint8_t)speed<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
# ============================================================<br />
# Motor Speed Sliders<br />
#<br />
# 0 &nbsp;&nbsp;= Stop<br />
# 100 = Full Speed<br />
#<br />
# Slider changes motor speed immediately.<br />
# Current direction is retained.<br />
# ============================================================<br />
<br />
number:<br />
<br />
  - platform: template<br />
    name: "Motor 1 Speed"<br />
    id: motor1_speed_slider<br />
    min_value: 0<br />
    max_value: 100<br />
    step: 1<br />
    initial_value: 100<br />
    optimistic: true<br />
    mode: slider<br />
    set_action:<br />
      - lambda: |-<br />
          if (id(motor1_speed) &lt; 0)<br />
            id(motor1_speed) = -(int)x;<br />
          else<br />
            id(motor1_speed) = (int)x;<br />
      - script.execute: motor1_write<br />
<br />
<br />
  - platform: template<br />
    name: "Motor 2 Speed"<br />
    id: motor2_speed_slider<br />
    min_value: 0<br />
    max_value: 100<br />
    step: 1<br />
    initial_value: 100<br />
    optimistic: true<br />
    mode: slider<br />
    set_action:<br />
      - lambda: |-<br />
          if (id(motor2_speed) &lt; 0)<br />
            id(motor2_speed) = -(int)x;<br />
          else<br />
            id(motor2_speed) = (int)x;<br />
      - script.execute: motor2_write<br />
<br />
<br />
  - platform: template<br />
    name: "Motor 3 Speed"<br />
    id: motor3_speed_slider<br />
    min_value: 0<br />
    max_value: 100<br />
    step: 1<br />
    initial_value: 100<br />
    optimistic: true<br />
    mode: slider<br />
    set_action:<br />
      - lambda: |-<br />
          if (id(motor3_speed) &lt; 0)<br />
            id(motor3_speed) = -(int)x;<br />
          else<br />
            id(motor3_speed) = (int)x;<br />
      - script.execute: motor3_write<br />
<br />
<br />
  - platform: template<br />
    name: "Motor 4 Speed"<br />
    id: motor4_speed_slider<br />
    min_value: 0<br />
    max_value: 100<br />
    step: 1<br />
    initial_value: 100<br />
    optimistic: true<br />
    mode: slider<br />
    set_action:<br />
      - lambda: |-<br />
          if (id(motor4_speed) &lt; 0)<br />
            id(motor4_speed) = -(int)x;<br />
          else<br />
            id(motor4_speed) = (int)x;<br />
      - script.execute: motor4_write<br />
<br />
<br />
# ============================================================<br />
# Motor Control Buttons<br />
# ============================================================<br />
<br />
button:<br />
<br />
  # Motor 1<br />
  - platform: template<br />
    name: "Motor 1 Forward"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor1_speed) =<br />
            abs((int)id(motor1_speed_slider).state);<br />
      - script.execute: motor1_write<br />
<br />
  - platform: template<br />
    name: "Motor 1 Reverse"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor1_speed) =<br />
            -abs((int)id(motor1_speed_slider).state);<br />
      - script.execute: motor1_write<br />
<br />
  - platform: template<br />
    name: "Motor 1 Stop"<br />
    on_press:<br />
      - lambda: |-<br />
          id(motor1_speed) = 0;<br />
      - script.execute: motor1_write<br />
<br />
<br />
  # Motor 2<br />
  - platform: template<br />
    name: "Motor 2 Forward"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor2_speed) =<br />
            abs((int)id(motor2_speed_slider).state);<br />
      - script.execute: motor2_write<br />
<br />
  - platform: template<br />
    name: "Motor 2 Reverse"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor2_speed) =<br />
            -abs((int)id(motor2_speed_slider).state);<br />
      - script.execute: motor2_write<br />
<br />
  - platform: template<br />
    name: "Motor 2 Stop"<br />
    on_press:<br />
      - lambda: |-<br />
          id(motor2_speed) = 0;<br />
      - script.execute: motor2_write<br />
<br />
<br />
  # Motor 3<br />
  - platform: template<br />
    name: "Motor 3 Forward"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor3_speed) =<br />
            abs((int)id(motor3_speed_slider).state);<br />
      - script.execute: motor3_write<br />
<br />
  - platform: template<br />
    name: "Motor 3 Reverse"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor3_speed) =<br />
            -abs((int)id(motor3_speed_slider).state);<br />
      - script.execute: motor3_write<br />
<br />
  - platform: template<br />
    name: "Motor 3 Stop"<br />
    on_press:<br />
      - lambda: |-<br />
          id(motor3_speed) = 0;<br />
      - script.execute: motor3_write<br />
<br />
<br />
  # Motor 4<br />
  - platform: template<br />
    name: "Motor 4 Forward"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor4_speed) =<br />
            abs((int)id(motor4_speed_slider).state);<br />
      - script.execute: motor4_write<br />
<br />
  - platform: template<br />
    name: "Motor 4 Reverse"<br />
    on_press:<br />
      - script.execute: motor_enable<br />
      - delay: 50ms<br />
      - lambda: |-<br />
          id(motor4_speed) =<br />
            -abs((int)id(motor4_speed_slider).state);<br />
      - script.execute: motor4_write<br />
<br />
  - platform: template<br />
    name: "Motor 4 Stop"<br />
    on_press:<br />
      - lambda: |-<br />
          id(motor4_speed) = 0;<br />
      - script.execute: motor4_write<br />
<br />
<br />
# ============================================================<br />
# RS485 Test Switch<br />
# ============================================================<br />
<br />
switch:<br />
<br />
  - platform: uart<br />
    uart_id: uart_1<br />
    name: "RS485 Button"<br />
    data: [0x11, 0x22, 0x33, 0x44, 0x55]<br />
<br />
<br />
# ============================================================<br />
# Digital Inputs<br />
# ============================================================<br />
<br />
binary_sensor:<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input01"<br />
    id: mt4v2_input01<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 0<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input02"<br />
    id: mt4v2_input02<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 1<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input03"<br />
    id: mt4v2_input03<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 2<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input04"<br />
    id: mt4v2_input04<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 3<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input05"<br />
    id: mt4v2_input05<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 4<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input06"<br />
    id: mt4v2_input06<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 5<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input07"<br />
    id: mt4v2_input07<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 6<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-input08"<br />
    id: mt4v2_input08<br />
    pin:<br />
      pcf8574: pcf8574_hub_in_1<br />
      number: 7<br />
      mode: INPUT<br />
      inverted: true<br />
<br />
<br />
  # GPIO inputs with pull-up resistors on PCB<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-W1-io47"<br />
    pin:<br />
      number: 47<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-W1-io48"<br />
    pin:<br />
      number: 48<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-W1-io17"<br />
    pin:<br />
      number: 17<br />
      inverted: true<br />
<br />
  - platform: gpio<br />
    name: "mt4v2-W1-io40"<br />
    pin:<br />
      number: 40<br />
      inverted: true<br />
<br />
<br />
  # ==========================================================<br />
  # DRV8262 Fault Status<br />
  #<br />
  # Register 2020 = DRV8262 #1<br />
  # Register 2021 = DRV8262 #2<br />
  #<br />
  # OFF = Normal<br />
  # ON  = Problem<br />
  # ==========================================================<br />
<br />
  - platform: template<br />
    name: "DRV8262-1 Fault"<br />
    id: drv8262_1_fault<br />
    device_class: problem<br />
<br />
  - platform: template<br />
    name: "DRV8262-2 Fault"<br />
    id: drv8262_2_fault<br />
    device_class: problem<br />
<br />
<br />
# ============================================================<br />
# ADS1115<br />
# ============================================================<br />
<br />
ads1115:<br />
  - address: 0x48<br />
<br />
<br />
# ============================================================<br />
# Sensors<br />
# ============================================================<br />
<br />
sensor:<br />
<br />
  # ADS1115 Channel 1<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 />
<br />
  # ADS1115 Channel 2<br />
  - platform: ads1115<br />
    multiplexer: A1_GND<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A1-GND"<br />
    update_interval: 5s<br />
<br />
  # ADS1115 Channel 3<br />
  - platform: ads1115<br />
    multiplexer: A2_GND<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A2-GND"<br />
    update_interval: 5s<br />
<br />
  # ADS1115 Channel 4<br />
  - platform: ads1115<br />
    multiplexer: A3_GND<br />
    gain: 6.144<br />
    name: "ADS1115 Channel A3-GND"<br />
    update_interval: 5s<br />
<br />
<br />
  # ==========================================================<br />
  # Motor Current<br />
  #<br />
  # ARM MODBUS Registers:<br />
  # 2010 = Motor 1 Current<br />
  # 2011 = Motor 2 Current<br />
  # 2012 = Motor 3 Current<br />
  # 2013 = Motor 4 Current<br />
  #<br />
  # Values are displayed as raw register values.<br />
  # ==========================================================<br />
<br />
  - platform: template<br />
    name: "Motor 1 Current"<br />
    id: motor1_current<br />
    accuracy_decimals: 0<br />
    update_interval: never<br />
<br />
  - platform: template<br />
    name: "Motor 2 Current"<br />
    id: motor2_current<br />
    accuracy_decimals: 0<br />
    update_interval: never<br />
<br />
  - platform: template<br />
    name: "Motor 3 Current"<br />
    id: motor3_current<br />
    accuracy_decimals: 0<br />
    update_interval: never<br />
<br />
  - platform: template<br />
    name: "Motor 4 Current"<br />
    id: motor4_current<br />
    accuracy_decimals: 0<br />
    update_interval: never<br />
<br />
<br />
# ============================================================<br />
# MODBUS Status Polling<br />
#<br />
# Every 2 seconds:<br />
#<br />
# Read 2010-2013 -&gt; Motor Current<br />
# Read 2020-2021 -&gt; DRV8262 Fault<br />
# ============================================================<br />
<br />
interval:<br />
<br />
  - interval: 2s<br />
    then:<br />
<br />
      # ======================================================<br />
      # Read Motor Current<br />
      #<br />
      # FC03<br />
      # Start Register = 2010<br />
      # Quantity     &nbsp;&nbsp;= 4<br />
      # ======================================================<br />
<br />
      - lambda: |-<br />
<br />
          // Clear old UART receive data<br />
          while (id(uart_motor).available()) {<br />
            uint8_t c;<br />
            id(uart_motor).read_byte(&amp;c);<br />
          }<br />
<br />
          // MODBUS request:<br />
          // Slave 1<br />
          // Function 03<br />
          // Start address 2010 = 0x07DA<br />
          // Read 4 registers<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x03,<br />
            0x07, 0xDA,<br />
            0x00, 0x04<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          // Calculate MODBUS RTU CRC16<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          // Send MODBUS request<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          // Send CRC<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
      # Wait for ARM CPU response<br />
      - delay: 50ms<br />
<br />
<br />
      # ======================================================<br />
      # Process Motor Current Response<br />
      # ======================================================<br />
<br />
      - lambda: |-<br />
<br />
          uint8_t rx[32];<br />
          int len = 0;<br />
<br />
          // Read UART response<br />
          while (id(uart_motor).available() &amp;&amp; len &lt; 32) {<br />
            id(uart_motor).read_byte(&amp;rx[len]);<br />
            len++;<br />
          }<br />
<br />
          // Expected response:<br />
          //<br />
          // 01 03 08<br />
          // M1_H M1_L<br />
          // M2_H M2_L<br />
          // M3_H M3_L<br />
          // M4_H M4_L<br />
          // CRC_L CRC_H<br />
          //<br />
          // Total = 13 bytes<br />
<br />
          if (len &gt;= 13 &amp;&amp;<br />
              rx[0] == 0x01 &amp;&amp;<br />
              rx[1] == 0x03 &amp;&amp;<br />
              rx[2] == 0x08) {<br />
<br />
            uint16_t m1 =<br />
              ((uint16_t)rx[3] &lt;&lt; 8) | rx[4];<br />
<br />
            uint16_t m2 =<br />
              ((uint16_t)rx[5] &lt;&lt; 8) | rx[6];<br />
<br />
            uint16_t m3 =<br />
              ((uint16_t)rx[7] &lt;&lt; 8) | rx[8];<br />
<br />
            uint16_t m4 =<br />
              ((uint16_t)rx[9] &lt;&lt; 8) | rx[10];<br />
<br />
            // Publish values to ESPHome<br />
            id(motor1_current).publish_state(m1);<br />
            id(motor2_current).publish_state(m2);<br />
            id(motor3_current).publish_state(m3);<br />
            id(motor4_current).publish_state(m4);<br />
          }<br />
<br />
<br />
      # ======================================================<br />
      # Read DRV8262 Fault Status<br />
      #<br />
      # FC03<br />
      # Start Register = 2020<br />
      # Quantity     &nbsp;&nbsp;= 2<br />
      # ======================================================<br />
<br />
      - lambda: |-<br />
<br />
          // Clear UART receive buffer<br />
          while (id(uart_motor).available()) {<br />
            uint8_t c;<br />
            id(uart_motor).read_byte(&amp;c);<br />
          }<br />
<br />
          // MODBUS request:<br />
          // Slave 1<br />
          // Function 03<br />
          // Start address 2020 = 0x07E4<br />
          // Read 2 registers<br />
<br />
          uint8_t data[6] = {<br />
            0x01, 0x03,<br />
            0x07, 0xE4,<br />
            0x00, 0x02<br />
          };<br />
<br />
          uint16_t crc = 0xFFFF;<br />
<br />
          // Calculate MODBUS RTU CRC16<br />
          for (int p = 0; p &lt; 6; p++) {<br />
            crc ^= data[p];<br />
<br />
            for (int i = 0; i &lt; 8; i++) {<br />
              crc = (crc &amp; 1)<br />
                    ? (crc &gt;&gt; 1) ^ 0xA001<br />
                    : crc &gt;&gt; 1;<br />
            }<br />
          }<br />
<br />
          // Send MODBUS request<br />
          id(uart_motor).write_array(data, 6);<br />
<br />
          // Send CRC<br />
          uint8_t crc_data[2] = {<br />
            (uint8_t)(crc &amp; 0xFF),<br />
            (uint8_t)(crc &gt;&gt; 8)<br />
          };<br />
<br />
          id(uart_motor).write_array(crc_data, 2);<br />
<br />
<br />
      # Wait for ARM CPU response<br />
      - delay: 50ms<br />
<br />
<br />
      # ======================================================<br />
      # Process DRV8262 Fault Response<br />
      # ======================================================<br />
<br />
      - lambda: |-<br />
<br />
          uint8_t rx[16];<br />
          int len = 0;<br />
<br />
          // Read UART response<br />
          while (id(uart_motor).available() &amp;&amp; len &lt; 16) {<br />
            id(uart_motor).read_byte(&amp;rx[len]);<br />
            len++;<br />
          }<br />
<br />
          // Expected response:<br />
          //<br />
          // 01 03 04<br />
          // Fault1_H Fault1_L<br />
          // Fault2_H Fault2_L<br />
          // CRC_L CRC_H<br />
          //<br />
          // Total = 9 bytes<br />
<br />
          if (len &gt;= 9 &amp;&amp;<br />
              rx[0] == 0x01 &amp;&amp;<br />
              rx[1] == 0x03 &amp;&amp;<br />
              rx[2] == 0x04) {<br />
<br />
            uint16_t fault1 =<br />
              ((uint16_t)rx[3] &lt;&lt; 8) | rx[4];<br />
<br />
            uint16_t fault2 =<br />
              ((uint16_t)rx[5] &lt;&lt; 8) | rx[6];<br />
<br />
            // 0 = Normal<br />
            // Non-zero = Fault<br />
            id(drv8262_1_fault).publish_state(<br />
              fault1 != 0<br />
            );<br />
<br />
            id(drv8262_2_fault).publish_state(<br />
              fault2 != 0<br />
            );<br />
          }<br />
<br />
<br />
# ============================================================<br />
# Web Server<br />
# ============================================================<br />
<br />
web_server:<br />
  port: 80<br />
<br />
<br />
# ============================================================<br />
# OLED Font<br />
# ============================================================<br />
<br />
font:<br />
  - file: "gfonts://Roboto"<br />
    id: roboto<br />
    size: 20<br />
<br />
<br />
# ============================================================<br />
# OLED Display<br />
# ============================================================<br />
<br />
display:<br />
<br />
  - platform: ssd1306_i2c<br />
    i2c_id: bus_a<br />
    model: "SSD1306 128x64"<br />
    address: 0x3C<br />
<br />
    lambda: |-<br />
      it.printf(<br />
        0,<br />
        0,<br />
        id(roboto),<br />
        "KinCony MT4v2"<br />
      );</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=10624" target="_blank" title="">MT4v2-HA-Motor-Current-Without-Tuya.txt</a> (Size: 22.74 KB / Downloads: 58)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
	</channel>
</rss>