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

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 10,190
» Latest member: new88host
» Forum threads: 4,264
» Forum posts: 21,145

Full Statistics

Online Users
There are currently 14 online users.
» 0 Member(s) | 9 Guest(s)
Amazonbot, bot

Latest Threads
SSD not visible for insta...
Forum: Pi5R16
Last Post: Verresen
2 hours ago
» Replies: 10
» Views: 30
KC868-A16 and Tuya
Forum: KC868-A series and Uair Smart Controller
Last Post: newdos
Yesterday, 09:33 AM
» Replies: 8
» Views: 48
KC868-AI mDNS problem
Forum: KC868-AI
Last Post: admin
Yesterday, 07:53 AM
» Replies: 1
» Views: 8
remember relay state
Forum: KC868-E16T
Last Post: admin
Yesterday, 07:51 AM
» Replies: 9
» Views: 458
N30 (KCS): energy counter...
Forum: N30
Last Post: admin
10-09-2026, 11:12 PM
» Replies: 1
» Views: 18
Bricked KC868-A16
Forum: KC868-A series and Uair Smart Controller
Last Post: admin
10-09-2026, 11:09 PM
» Replies: 7
» Views: 101
KinCony G1 ESP32-S3 SIM76...
Forum: News
Last Post: admin
10-09-2026, 11:09 PM
» Replies: 4
» Views: 1,618
Current direction detecti...
Forum: N30
Last Post: dominique_manas@hotmail.com
10-09-2026, 07:31 AM
» Replies: 4
» Views: 437
KC868-A8 on Heat Pump for...
Forum: KC868-HxB series Smart Controller
Last Post: marktuan
10-09-2026, 03:17 AM
» Replies: 2
» Views: 644
B32M maximum voltage
Forum: DIY Project
Last Post: felixandrea
10-09-2026, 03:14 AM
» Replies: 5
» Views: 631

  No ethernet communication
Posted by: philippe - 09-02-2026, 01:25 AM - Forum: KC868-A series and Uair Smart Controller - Replies (10)

Hi, I just received a new  board. I cant accees it through ethernet. I guess the kcs comes with dhcp enabled. if yes, I cant see it with a scanner, I cant find it with the kincony scan tool. I reflashed with esp home and the A8 yaml file, no way. I reflash with the kincony flashing tool and kscv3, no way. The port I am using on the switch is fine, thats the one I am using for my PC . By the way, the board is V1.7.1, I is it the new board? I hope so, I just got it, expecting to use it with 1wire sensors expecting the kcs v3 to solve my 1wire instable sensors issue.
Thanks
     

Print this item

  [arduino code examples for CO16]-10 ST7789 TFT color display
Posted by: admin - 08-31-2026, 12:16 AM - Forum: CO16 - No Replies

Code:
#include <Adafruit_GFX.h>
#include <driver/gpio.h>
#include <driver/spi_master.h>
#include <esp_heap_caps.h>

namespace {

// CO16 ST7789 (GMT020-02-7P) pin mapping from kcs_co16.h.
constexpr gpio_num_t kTftSclk = GPIO_NUM_11;
constexpr gpio_num_t kTftMosi = GPIO_NUM_10;
constexpr gpio_num_t kTftMiso = GPIO_NUM_12;
constexpr gpio_num_t kTftCs = GPIO_NUM_4;
constexpr gpio_num_t kTftDc = GPIO_NUM_0;
constexpr gpio_num_t kTftReset = GPIO_NUM_5;
constexpr gpio_num_t kTftBacklight = GPIO_NUM_40;

constexpr int16_t kDisplayWidth = 320;
constexpr int16_t kDisplayHeight = 240;
constexpr int16_t kTransferChunkHeight = 10;
constexpr uint32_t kDisplaySpiFrequency = 20 * 1000 * 1000;
constexpr uint8_t kCo16Madctl = 0x68;  // MX | MV | BGR.

constexpr uint16_t kBlack = 0x0000;
constexpr uint16_t kBlue = 0x001F;
constexpr uint16_t kRed = 0xF800;
constexpr uint16_t kGreen = 0x07E0;
constexpr uint16_t kCyan = 0x07FF;
constexpr uint16_t kMagenta = 0xF81F;
constexpr uint16_t kYellow = 0xFFE0;
constexpr uint16_t kWhite = 0xFFFF;

class Co16St7789 : public Adafruit_GFX {
public:
  Co16St7789() : Adafruit_GFX(kDisplayWidth, kDisplayHeight) {}

  bool begin() {
    gpio_reset_pin(kTftCs);
    gpio_set_direction(kTftCs, GPIO_MODE_OUTPUT);
    gpio_set_level(kTftCs, 1);

    gpio_reset_pin(kTftDc);
    gpio_set_direction(kTftDc, GPIO_MODE_OUTPUT);
    gpio_set_level(kTftDc, 1);

    gpio_reset_pin(kTftBacklight);
    gpio_set_direction(kTftBacklight, GPIO_MODE_OUTPUT);
    gpio_set_level(kTftBacklight, 0);

    spi_bus_config_t busConfig = {};
    busConfig.sclk_io_num = kTftSclk;
    busConfig.mosi_io_num = kTftMosi;
    busConfig.miso_io_num = kTftMiso;
    busConfig.quadwp_io_num = -1;
    busConfig.quadhd_io_num = -1;
    busConfig.max_transfer_sz =
        kDisplayWidth * kTransferChunkHeight * sizeof(uint16_t);

    esp_err_t err =
        spi_bus_initialize(SPI3_HOST, &busConfig, SPI_DMA_CH_AUTO);
    if (err != ESP_OK) {
      Serial.printf("SPI3 initialization failed: %s\n", esp_err_to_name(err));
      return false;
    }

    spi_device_interface_config_t deviceConfig = {};
    deviceConfig.clock_speed_hz = kDisplaySpiFrequency;
    deviceConfig.mode = 0;
    deviceConfig.spics_io_num = -1;
    deviceConfig.queue_size = 1;

    err = spi_bus_add_device(SPI3_HOST, &deviceConfig, &spiDevice_);
    if (err != ESP_OK) {
      Serial.printf("ST7789 SPI device setup failed: %s\n",
                    esp_err_to_name(err));
      return false;
    }

    drawBuffer_ = static_cast<uint8_t*>(heap_caps_malloc(
        kDisplayWidth * kTransferChunkHeight * sizeof(uint16_t),
        MALLOC_CAP_DMA));
    if (drawBuffer_ == nullptr) {
      Serial.println("ST7789 DMA buffer allocation failed");
      return false;
    }

    // GPIO5 is shared with the optional LoRa module. Match the working KCS
    // firmware and issue one reset pulse before initializing the controller.
    gpio_reset_pin(kTftReset);
    gpio_set_direction(kTftReset, GPIO_MODE_OUTPUT);
    gpio_set_level(kTftReset, 1);
    delay(1);
    gpio_set_level(kTftReset, 0);
    delay(1);
    gpio_set_level(kTftReset, 1);
    delay(10);

    if (!initializeController()) {
      return false;
    }

    fillScreen(kBlack);
    delay(120);
    if (!writeCommand(0x29)) {  // Display on.
      return false;
    }
    delay(120);

    gpio_set_level(kTftBacklight, 1);
    initialized_ = true;
    return true;
  }

  void drawPixel(int16_t x, int16_t y, uint16_t color) override {
    fillRect(x, y, 1, 1, color);
  }

  void writePixel(int16_t x, int16_t y, uint16_t color) override {
    fillRect(x, y, 1, 1, color);
  }

  void fillRect(int16_t x, int16_t y, int16_t width, int16_t height,
                uint16_t color) override {
    if (x < 0) {
      width += x;
      x = 0;
    }
    if (y < 0) {
      height += y;
      y = 0;
    }
    if (x + width > kDisplayWidth) {
      width = kDisplayWidth - x;
    }
    if (y + height > kDisplayHeight) {
      height = kDisplayHeight - y;
    }
    if (drawBuffer_ == nullptr || width <= 0 || height <= 0) {
      return;
    }

    const uint8_t high = color >> 8;
    const uint8_t low = color;
    for (int16_t row = y; row < y + height;
         row += kTransferChunkHeight) {
      const int16_t chunkHeight =
          min<int16_t>(kTransferChunkHeight, y + height - row);
      const size_t pixelCount = width * chunkHeight;
      for (size_t index = 0; index < pixelCount; ++index) {
        drawBuffer_[index * 2] = high;
        drawBuffer_[index * 2 + 1] = low;
      }

      if (!setWindow(x, row, x + width, row + chunkHeight) ||
          !writePixels(drawBuffer_, pixelCount * sizeof(uint16_t))) {
        Serial.println("ST7789 pixel transfer failed");
        return;
      }
    }
  }

  void writeFillRect(int16_t x, int16_t y, int16_t width, int16_t height,
                     uint16_t color) override {
    fillRect(x, y, width, height, color);
  }

  bool initialized() const { return initialized_; }

private:
  bool transmit(const void* data, size_t length, int dcLevel) {
    if (data == nullptr || length == 0) {
      return true;
    }

    gpio_set_level(kTftDc, dcLevel);
    spi_transaction_t transaction = {};
    transaction.length = length * 8;
    transaction.tx_buffer = data;
    const esp_err_t err = spi_device_polling_transmit(spiDevice_, &transaction);
    if (err != ESP_OK) {
      Serial.printf("ST7789 SPI transfer failed: %s\n", esp_err_to_name(err));
      return false;
    }
    return true;
  }

  bool writeCommand(uint8_t command) {
    gpio_set_level(kTftCs, 0);
    const bool success = transmit(&command, sizeof(command), 0);
    gpio_set_level(kTftCs, 1);
    return success;
  }

  bool writeCommandData(uint8_t command, const uint8_t* data, size_t length) {
    gpio_set_level(kTftCs, 0);
    const bool success = transmit(&command, sizeof(command), 0) &&
                         transmit(data, length, 1);
    gpio_set_level(kTftCs, 1);
    return success;
  }

  bool setWindow(int16_t x1, int16_t y1, int16_t x2, int16_t y2) {
    const uint8_t columns[] = {
        static_cast<uint8_t>(x1 >> 8), static_cast<uint8_t>(x1),
        static_cast<uint8_t>((x2 - 1) >> 8), static_cast<uint8_t>(x2 - 1),
    };
    const uint8_t rows[] = {
        static_cast<uint8_t>(y1 >> 8), static_cast<uint8_t>(y1),
        static_cast<uint8_t>((y2 - 1) >> 8), static_cast<uint8_t>(y2 - 1),
    };
    return writeCommandData(0x2A, columns, sizeof(columns)) &&
           writeCommandData(0x2B, rows, sizeof(rows));
  }

  bool writePixels(const uint8_t* data, size_t length) {
    constexpr uint8_t kRamWrite = 0x2C;
    gpio_set_level(kTftCs, 0);
    const bool success = transmit(&kRamWrite, sizeof(kRamWrite), 0) &&
                         transmit(data, length, 1);
    gpio_set_level(kTftCs, 1);
    return success;
  }

  bool initializeController() {
    const uint8_t madctl[] = {kCo16Madctl};
    const uint8_t displayFunction[] = {0x0A, 0x82};
    const uint8_t pixelFormat[] = {0x55};
    const uint8_t porchControl[] = {0x0C, 0x0C, 0x00, 0x33, 0x33};
    const uint8_t gateControl[] = {0x35};
    const uint8_t vcom[] = {0x28};
    const uint8_t lcmControl[] = {0x0C};
    const uint8_t vdvVrhEnable[] = {0x01, 0xFF};
    const uint8_t vrh[] = {0x10};
    const uint8_t vdv[] = {0x20};
    const uint8_t frameRate[] = {0x0F};
    const uint8_t powerControl[] = {0xA4, 0xA1};
    const uint8_t positiveGamma[] = {
        0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x32,
        0x44, 0x42, 0x06, 0x0E, 0x12, 0x14, 0x17,
    };
    const uint8_t negativeGamma[] = {
        0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x31,
        0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1B, 0x1E,
    };

    if (!writeCommand(0x11)) {  // Sleep out.
      return false;
    }
    delay(120);

    return writeCommand(0x13) &&
           writeCommandData(0x36, madctl, sizeof(madctl)) &&
           writeCommandData(0xB6, displayFunction, sizeof(displayFunction)) &&
           writeCommandData(0x3A, pixelFormat, sizeof(pixelFormat)) &&
           (delay(10), true) &&
           writeCommandData(0xB2, porchControl, sizeof(porchControl)) &&
           writeCommandData(0xB7, gateControl, sizeof(gateControl)) &&
           writeCommandData(0xBB, vcom, sizeof(vcom)) &&
           writeCommandData(0xC0, lcmControl, sizeof(lcmControl)) &&
           writeCommandData(0xC2, vdvVrhEnable, sizeof(vdvVrhEnable)) &&
           writeCommandData(0xC3, vrh, sizeof(vrh)) &&
           writeCommandData(0xC4, vdv, sizeof(vdv)) &&
           writeCommandData(0xC6, frameRate, sizeof(frameRate)) &&
           writeCommandData(0xD0, powerControl, sizeof(powerControl)) &&
           writeCommandData(0xE0, positiveGamma, sizeof(positiveGamma)) &&
           writeCommandData(0xE1, negativeGamma, sizeof(negativeGamma)) &&
           writeCommand(0x21);  // Display inversion on.
  }

  spi_device_handle_t spiDevice_ = nullptr;
  uint8_t* drawBuffer_ = nullptr;
  bool initialized_ = false;
};

Co16St7789 display;
uint32_t frameCount = 0;

void drawColorBars() {
  constexpr uint16_t colors[] = {
      kRed,
      kGreen,
      kBlue,
      kCyan,
      kMagenta,
      kYellow,
  };
  constexpr size_t colorCount = sizeof(colors) / sizeof(colors[0]);
  const int barWidth = kDisplayWidth / colorCount;

  for (size_t index = 0; index < colorCount; ++index) {
    const int x = index * barWidth;
    const int width =
        (index == colorCount - 1) ? kDisplayWidth - x : barWidth;
    display.fillRect(x, 132, width, 44, colors[index]);
  }
}

void drawStaticScreen() {
  display.fillScreen(kBlack);
  display.drawRect(0, 0, kDisplayWidth, kDisplayHeight, kWhite);

  display.setTextWrap(false);
  display.setTextColor(kCyan);
  display.setTextSize(3);
  display.setCursor(34, 20);
  display.print("KinCony CO16");

  display.setTextColor(kWhite);
  display.setTextSize(2);
  display.setCursor(24, 64);
  display.print("ST7789 display test");
  display.setCursor(24, 92);
  display.print("SPI3 native driver");

  drawColorBars();

  display.setTextColor(kGreen);
  display.setCursor(24, 194);
  display.print("Frame:");
}

void updateFrameCounter() {
  display.fillRect(108, 190, 190, 28, kBlack);
  display.setTextColor(kGreen);
  display.setTextSize(2);
  display.setCursor(108, 194);
  display.print(frameCount++);
}

}  // namespace

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

  Serial.println();
  Serial.println("KinCony CO16 standalone ST7789 example");
  Serial.printf("SPI3 SCLK=%d MOSI=%d MISO=%d CS=%d mode=0 clock=%u Hz\n",
                kTftSclk, kTftMosi, kTftMiso, kTftCs,
                kDisplaySpiFrequency);
  Serial.printf("LCD DC=%d RESET=%d BACKLIGHT=%d\n", kTftDc, kTftReset,
                kTftBacklight);

  if (!display.begin()) {
    Serial.println("Display initialization failed");
    while (true) {
      delay(1000);
    }
  }

  drawStaticScreen();
  updateFrameCounter();

  Serial.printf("Display initialized: %dx%d, MADCTL=0x%02X, invert=on\n",
                display.width(), display.height(), kCo16Madctl);
}

void loop() {
 
  updateFrameCounter();
  delay(1000);
}
   
arduino ino file download: 

.zip   10-TFT-LCD-ST7789.zip (Size: 3.05 KB / Downloads: 102)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:

.zip   10-TFT-LCD-ST7789.ino.merged.zip (Size: 211.33 KB / Downloads: 108)
before run code , need install these arduino library:
   
   

Print this item

  [arduino code examples for CO16]-09 digital INPUT trigger OUTPUT directly
Posted by: admin - 08-31-2026, 12:11 AM - Forum: CO16 - No Replies

Code:
/*
  Made by KinCony IoT: https://www.kincony.com

  Program functionality:
  This program uses ESP32-S3 to read inputs from PCA9555 I/O expander chip (I2C address 0x24)
  for channels 1-16, and control corresponding relays using PCF8575 I/O expander chip (I2C address 0x22)
  for controlling 16 relays (1-16). When input (DI) is triggered (LOW), corresponding relay (OUTPUT) is activated (LOW).
*/

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

// Initialize the PCA9555 objects for reading inputs (channels 1-16)
PCA9555 input_ioex1;  // For channels 1-16 (I2C address 0x24)

// Set I2C address of the PCF8575 module for output relays
#define I2C_ADDRESS 0x22
PCF8575 pcf8575_R1(I2C_ADDRESS);

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

    // Initialize I2C bus: SDA=GPIO8, SCL=GPIO18, 100kHz
    Wire.begin(8, 18, 100000);

    // Initialize PCF8575 for outputs
    pcf8575_R1.begin();

    // Turn off all relays initially (set all pins HIGH - relay OFF)
    for (int i = 0; i < 16; i++) {
        pcf8575_R1.write(i, HIGH);
    }

    // Configure input PCA9555 (for inputs 1-16)
    input_ioex1.attach(Wire, 0x24);
    input_ioex1.polarity(PCA95x5::Polarity::ORIGINAL_ALL);
    input_ioex1.direction(PCA95x5::Direction::IN_ALL);

    delay(50);
}

void loop() {
    // Read input states from XL9535 (inputs 1-16)
    uint16_t inputs_1_16 = input_ioex1.read();
   
    // Control outputs based on inputs
    // When input is LOW, set corresponding output to LOW (activate relay)
    for (int channel = 0; channel < 16; channel++) {
        if (!(inputs_1_16 & (1 << channel))) {
            pcf8575_R1.write(channel, LOW);   // Input triggered, activate relay
        } else {
            pcf8575_R1.write(channel, HIGH);  // Input not triggered, deactivate relay
        }
    }
   
    delay(100);
}
arduino ino file download:

.zip   9-input-trigger-output.zip (Size: 997 bytes / Downloads: 107)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:

.zip   9-input-trigger-output.ino.merged.zip (Size: 197.75 KB / Downloads: 117)

Print this item

  [arduino code examples for CO16]-08 Ethernet W5500 chip work with TCP Server mode
Posted by: admin - 08-31-2026, 12:09 AM - Forum: CO16 - No Replies

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Print this item

  [arduino code examples for CO16]-07 how to DS3231 RTC clock
Posted by: admin - 08-31-2026, 12:08 AM - Forum: CO16 - No Replies

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

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

String serial_cmd_rcv = ""; // Serial port receiver

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

MY_DATE_STR my_date_str = {0};

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

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

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


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

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

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

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

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

  serial_cmd_rcv.trim();

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

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

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

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

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

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

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

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

  serial_cmd_rcv = "";

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

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

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

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

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

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

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

Print this item

  [arduino code examples for CO16]-06 How to use SD Card
Posted by: admin - 08-31-2026, 12:06 AM - Forum: CO16 - No Replies

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  uint8_t cardType = SD.cardType();

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

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

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

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

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

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

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

Print this item

  [arduino code examples for CO16]-05 Read PT100 temperature sensor
Posted by: admin - 08-31-2026, 12:04 AM - Forum: CO16 - No Replies

Code:
#include <Adafruit_MAX31865.h>

namespace {

// CO16 MAX31865 software-SPI pins.
constexpr int kPt100Sclk = 11;
constexpr int kPt100Mosi = 10;
constexpr int kPt100Miso = 12;
constexpr int kPt100Cs = 14;

// NX3L4051PW channel select pins. S3 is fixed LOW on CO16.
constexpr int kMuxS1 = 7;
constexpr int kMuxS2 = 21;
constexpr uint8_t kPt100ChannelCount = 4;
constexpr uint32_t kMuxSettlingTimeMs = 20;

constexpr float kRtdNominalOhms = 100.0F;
constexpr float kReferenceResistorOhms = 400.0F;

Adafruit_MAX31865 pt100(kPt100Cs, kPt100Mosi, kPt100Miso, kPt100Sclk);

void selectPt100Channel(uint8_t channel) {
  const uint8_t muxAddress = channel - 1;

  // S3 is fixed LOW, so S2/S1 select PT100 channels 1-4.
  digitalWrite(kMuxS1, muxAddress & 0x01);
  digitalWrite(kMuxS2, (muxAddress >> 1) & 0x01);
  delay(kMuxSettlingTimeMs);
}

void printFault(uint8_t fault) {
  Serial.printf(" fault=0x%02X", fault);
  if (fault & MAX31865_FAULT_HIGHTHRESH) {
    Serial.print(" RTD_HIGH_THRESHOLD");
  }
  if (fault & MAX31865_FAULT_LOWTHRESH) {
    Serial.print(" RTD_LOW_THRESHOLD");
  }
  if (fault & MAX31865_FAULT_REFINLOW) {
    Serial.print(" REFIN_HIGH");
  }
  if (fault & MAX31865_FAULT_REFINHIGH) {
    Serial.print(" REFIN_LOW_OR_FORCE_OPEN");
  }
  if (fault & MAX31865_FAULT_RTDINLOW) {
    Serial.print(" RTDIN_LOW_OR_FORCE_OPEN");
  }
  if (fault & MAX31865_FAULT_OVUV) {
    Serial.print(" OVER_UNDERVOLTAGE");
  }
}

}  // namespace

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

  pinMode(kMuxS1, OUTPUT);
  pinMode(kMuxS2, OUTPUT);
  selectPt100Channel(1);

  Serial.println();
  Serial.println("KinCony CO16 four-channel PT100 example");
  Serial.printf("MUX S3=LOW S2=%d S1=%d; SPI SCLK=%d MOSI=%d MISO=%d CS=%d\n",
                kMuxS2, kMuxS1, kPt100Sclk, kPt100Mosi, kPt100Miso,
                kPt100Cs);

  pt100.begin(MAX31865_3WIRE);
  pt100.enable50Hz(true);
}

void loop() {
  for (uint8_t channel = 1; channel <= kPt100ChannelCount; ++channel) {
    selectPt100Channel(channel);

    const uint16_t raw = pt100.readRTD();
    const float resistance =
        static_cast<float>(raw) * kReferenceResistorOhms / 32768.0F;
    const float temperature = pt100.calculateTemperature(
        raw, kRtdNominalOhms, kReferenceResistorOhms);
    const uint8_t fault = pt100.readFault(MAX31865_FAULT_NONE);

    Serial.printf("CH%u raw=%u resistance=%.3f ohm temperature=%.2f C",
                  channel, raw, resistance, temperature);
    if (fault != 0) {
      printFault(fault);
      pt100.clearFault();
    } else {
      Serial.print(" fault=0x00");
    }
    Serial.println();
  }

  Serial.println();
  delay(1000);
}
arduino ino file download: 

.zip   5-PT100.zip (Size: 1.11 KB / Downloads: 108)
BIN file (you can use esp32 download tool download to ESP32-S3 with address 0x0 then directly to use) download:

.zip   5-PT100.ino.merged.zip (Size: 198.5 KB / Downloads: 106)
before run code , need install max31865 arduino library
   
   

Print this item

  [arduino code examples for CO16]-04 RS485 communication test
Posted by: admin - 08-31-2026, 12:02 AM - Forum: CO16 - No Replies

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

#include <HardwareSerial.h>

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

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

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

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

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

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

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

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

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

.zip   4-RS485-Test.ino.merged.zip (Size: 190.1 KB / Downloads: 90)

Print this item

  [arduino code examples for CO16]-03 Read analog input ports value
Posted by: admin - 08-31-2026, 12:00 AM - Forum: CO16 - No Replies

Code:
/*
* KinCony 16-Channel Analog Input Monitor
*
* Four ADS1115 ADC modules are used:
*
* ADS1115-1 (U35): CH1-CH4   I2C address: 0x48
* ADS1115-2 (U7):  CH5-CH8   I2C address: 0x49
* ADS1115-3 (U15): CH9-CH12  I2C address: 0x4B
* ADS1115-4 (U19): CH13-CH16 I2C address: 0x4A
*
* ESPHome equivalent configuration:
*
* gain: 4.096
* filters:
*   - lambda: 'return x <= 0.0025f ? 0.0f : x;'
*   - multiply: 5.16696
*   - clamp:
*       min_value: 0.0
*       max_value: 10.0
*
* Only channels with an input voltage greater than 0.5V
* will be printed.
*
* Copyright: Made by KinCony IoT: https://www.kincony.com
*/

#include <Wire.h>
#include <DFRobot_ADS1115.h>

// I2C pins
#define SDA_PIN 8
#define SCL_PIN 18

// ADS1115 I2C addresses
#define ADS1115_1_ADDR 0x48
#define ADS1115_2_ADDR 0x49
#define ADS1115_3_ADDR 0x4B
#define ADS1115_4_ADDR 0x4A

// ESPHome calibration multiplier
#define VOLTAGE_MULTIPLIER 5.16696f

// ESPHome zero threshold
#define ADC_ZERO_THRESHOLD 0.0025f

// Print threshold
#define PRINT_THRESHOLD 0.5f

// Maximum input voltage
#define MAX_INPUT_VOLTAGE 10.0f


// Create ADS1115 objects
DFRobot_ADS1115 ads1(&Wire);
DFRobot_ADS1115 ads2(&Wire);
DFRobot_ADS1115 ads3(&Wire);
DFRobot_ADS1115 ads4(&Wire);


/*
* Read ADS1115 channel and convert to actual input voltage.
*
* DFRobot readVoltage() returns voltage in mV.
*
* ESPHome:
*     x <= 0.0025V -> 0V
*     x * 5.16696
*     clamp 0~10V
*/
float readInputVoltage(DFRobot_ADS1115 &ads, uint8_t channel)
{
    // Read ADC voltage in mV
    uint16_t adc_mV = ads.readVoltage(channel);

    // Convert mV to V
    float adcVoltage = adc_mV / 1000.0f;

    // ESPHome lambda filter
    if (adcVoltage <= ADC_ZERO_THRESHOLD)
    {
        return 0.0f;
    }

    // ESPHome multiply filter
    float inputVoltage = adcVoltage * VOLTAGE_MULTIPLIER;

    // ESPHome clamp filter
    if (inputVoltage < 0.0f)
    {
        inputVoltage = 0.0f;
    }

    if (inputVoltage > MAX_INPUT_VOLTAGE)
    {
        inputVoltage = MAX_INPUT_VOLTAGE;
    }

    return inputVoltage;
}


/*
* Check one analog channel.
*
* If the actual input voltage is greater than 0.5V,
* print the channel number and voltage.
*/
void checkChannel(
    DFRobot_ADS1115 &ads,
    uint8_t adcChannel,
    uint8_t channelNumber)
{
    float voltage = readInputVoltage(ads, adcChannel);

    if (voltage > PRINT_THRESHOLD)
    {
        Serial.print("CH");
        Serial.print(channelNumber);
        Serial.print(": ");

        Serial.print(voltage, 2);

        Serial.println(" V");
    }
}


void setup(void)
{
    // Initialize serial communication
    Serial.begin(115200);

    // Initialize I2C
    Wire.begin(SDA_PIN, SCL_PIN);

    /*
     * ADS1115 gain = 4.096V
     *
     * This corresponds to ESPHome:
     *
     * gain: 4.096
     *
     * DFRobot library:
     * eGAIN_ONE = 4.096V
     */

    // ADS1115-1
    ads1.setAddr_ADS1115(ADS1115_1_ADDR);
    ads1.setGain(eGAIN_ONE);
    ads1.setMode(eMODE_SINGLE);
    ads1.setRate(eRATE_128);
    ads1.setOSMode(eOSMODE_SINGLE);
    ads1.init();

    // ADS1115-2
    ads2.setAddr_ADS1115(ADS1115_2_ADDR);
    ads2.setGain(eGAIN_ONE);
    ads2.setMode(eMODE_SINGLE);
    ads2.setRate(eRATE_128);
    ads2.setOSMode(eOSMODE_SINGLE);
    ads2.init();

    // ADS1115-3
    ads3.setAddr_ADS1115(ADS1115_3_ADDR);
    ads3.setGain(eGAIN_ONE);
    ads3.setMode(eMODE_SINGLE);
    ads3.setRate(eRATE_128);
    ads3.setOSMode(eOSMODE_SINGLE);
    ads3.init();

    // ADS1115-4
    ads4.setAddr_ADS1115(ADS1115_4_ADDR);
    ads4.setGain(eGAIN_ONE);
    ads4.setMode(eMODE_SINGLE);
    ads4.setRate(eRATE_128);
    ads4.setOSMode(eOSMODE_SINGLE);
    ads4.init();

    Serial.println();
    Serial.println("KinCony 16-Channel Analog Input Test");
    Serial.println("--------------------------------------");
    Serial.println("ADS1115 Gain: 4.096V");
    Serial.println("Multiplier: 5.16696");
    Serial.println("Print threshold: 0.50V");
    Serial.println();
}


void loop(void)
{
    // ADS1115-1: CH1 ~ CH4
    if (ads1.checkADS1115())
    {
        checkChannel(ads1, 0, 1);
        checkChannel(ads1, 1, 2);
        checkChannel(ads1, 2, 3);
        checkChannel(ads1, 3, 4);
    }
    else
    {
        Serial.println("ADS1115-1 (0x48) Disconnected!");
    }


    // ADS1115-2: CH5 ~ CH8
    if (ads2.checkADS1115())
    {
        checkChannel(ads2, 0, 5);
        checkChannel(ads2, 1, 6);
        checkChannel(ads2, 2, 7);
        checkChannel(ads2, 3, 8);
    }
    else
    {
        Serial.println("ADS1115-2 (0x49) Disconnected!");
    }


    // ADS1115-3: CH9 ~ CH12
    if (ads3.checkADS1115())
    {
        checkChannel(ads3, 0, 9);
        checkChannel(ads3, 1, 10);
        checkChannel(ads3, 2, 11);
        checkChannel(ads3, 3, 12);
    }
    else
    {
        Serial.println("ADS1115-3 (0x4B) Disconnected!");
    }


    // ADS1115-4: CH13 ~ CH16
    if (ads4.checkADS1115())
    {
        checkChannel(ads4, 0, 13);
        checkChannel(ads4, 1, 14);
        checkChannel(ads4, 2, 15);
        checkChannel(ads4, 3, 16);
    }
    else
    {
        Serial.println("ADS1115-4 (0x4A) Disconnected!");
    }


    // Scan every 1 second
    delay(1000);
}
arduino ino file download:

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

.zip   3-ads1115_adc.ino.merged.zip (Size: 195.04 KB / Downloads: 96)

Print this item

  [arduino code examples for CO16]-02 Read digital input ports state
Posted by: admin - 08-30-2026, 11:58 PM - Forum: CO16 - No Replies

Code:
/*
  Made by KinCony IoT: https://www.kincony.com

  Program functionality:
  This program uses an ESP32-S3 to read inputs from an XL9535 I/O expander chip
  (I2C address 0x24) via I2C. The XL9535 chip handles channels 1-16.
  The program reads the state of all these inputs and prints them in binary format
  to the serial monitor.

  Key points:
  - The I2C bus is initialized on GPIO pins 8 (SDA) and 18 (SCL) with a frequency of 40kHz.
  - The XL9535 chip reads the state of input pins for channels 1-16.
  - The state of the inputs is printed to the serial monitor in binary format every second.
  - Note: The original description mentioned three expander chips, but this implementation
    currently uses only one XL9535 (PCA9555 compatible) at address 0x24.
*/

#include <PCA95x5.h>
#include <Wire.h>

// Initialize the PCA9555 object for XL9535 chip (channels 1-16)
PCA9555 ioex1;  // XL9535 I/O expander at I2C address 0x24, handles channels 1-16

void setup() {
    // Start serial communication for debugging
    Serial.begin(115200);
    delay(2000);  // Wait for 2 seconds to ensure serial monitor is ready

    // Initialize the I2C bus with GPIO 8 as SDA and GPIO 18 as SCL, 40kHz frequency
    Wire.begin(8, 18, 40000);

    // Attach the PCA9555 device at I2C address 0x24
    ioex1.attach(Wire, 0x24);
   
    // Set polarity to original (no inversion)
    ioex1.polarity(PCA95x5::Polarity::ORIGINAL_ALL);
   
    // Configure all 16 pins as inputs
    ioex1.direction(PCA95x5::Direction::IN_ALL);
}

void loop() {
    // Read and print the state of inputs from the XL9535 (channels 1-16)
    Serial.print("1-16 input states: ");
    // Read all 16 pins and print as 16-bit binary value
    Serial.println(ioex1.read(), BIN);

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

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

.zip   2-digital-input.ino.merged.zip (Size: 197.84 KB / Downloads: 110)

Print this item