Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[arduino code examples for DM16]-01 16 Channel DAC output by digital input
#1
Code:
/*
* ----------------------------------------------------------------------------
* Copyright (c) 2025 KinCony IoT
*
* ----------------------------------------------------------------------------
*/

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

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

/* Example for 16 input buttons that are connected from the GPIO expander pins to ground.
* Note: The buttons must be connected with the other side of the switch to GROUND.
* There is a built-in pull-up resistor on each input, but no pull-down resistor capability.
*/
#define SDA_PIN 8
#define SCL_PIN 18
#define ADDRESS_PCF8575 0x22

#define ST_RX   4 //// ESP32 receive pin
#define ST_TX   6 //// ESP32 send pin
typedef enum {KEY_RELEASE=0, KEY_SHORT_PRESSED, KEY_LONG_PRESSED} KEY_STATUS;

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

KEY_PRESS_PROP key_press_prop[16] = {0};

Adafruit_PCF8575 pcf;
HardwareSerial myst_serial(1);

TwoWire myI2c = TwoWire(0);

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

/**
* Send Modbus RTU frame
*
* @param serial HardwareSerial object
* @param address Slave address (1-247)
* @param function Function code
* @param data Data section
* @param dataLen Data length
*/
void send_modbus_frame(HardwareSerial &serial, uint8_t address, uint8_t function,
                      const uint8_t *data, uint16_t dataLen) {
  // Create send buffer
  uint16_t totalLen = 1 + 1 + dataLen + 2; // Address + Function code + Data + CRC
  uint8_t buffer[totalLen];
 
  // Fill address and function code
  buffer[0] = address;
  buffer[1] = function;
 
  // Copy data
  memcpy(&buffer[2], data, dataLen);
 
  // Calculate CRC (excluding CRC section)
  uint16_t crc = modbus_crc16(buffer, 2 + dataLen);
 
  // Add CRC (little-endian: low byte first)
  buffer[2 + dataLen] = crc & 0xFF;         // CRC low byte
  buffer[3 + dataLen] = (crc >> 8) & 0xFF;  // CRC high byte
 
  // Send complete frame
  for (uint16_t i = 0; i < totalLen; i++) {
    serial.write(buffer[i]);
  }
 
  // Flush send buffer to ensure all data is sent
  serial.flush();
}

// Encapsulation of common Modbus functions

/**
* Send "Read Holding Registers" request
*
* @param serial HardwareSerial object
* @param address Slave address
* @param startReg Start register address
* @param numRegs Number of registers to read
*/
void modbus_read_registers(HardwareSerial &serial, uint8_t address,
                          uint16_t startReg, uint16_t numRegs) {
  uint8_t data[4];
 
  // Fill register address and quantity in big-endian
  data[0] = (startReg >> 8) & 0x
arduino ino file download:

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

.zip   1-dac-16ch.ino.merged.zip (Size: 205.57 KB / Downloads: 174)
Reply


Forum Jump:


Users browsing this thread:
1 Guest(s)