Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
DDM18SR ดิจิทัลวัตต์มิเตอร์ วัดพลังงานไฟฟ้า 1 เฟส MODBUS / RS485 https://www.ioxhop.com/p/1138
/* Dev by IOXhop.com */
#define DE_RE_PIN 4
#define MODE_SEND HIGH
#define MODE_RECV LOW
void setup() {
pinMode(DE_RE_PIN, OUTPUT);
digitalWrite(DE_RE_PIN, MODE_RECV);
Serial.begin(115200);
Serial2.begin(9600, SERIAL_8E1, 16, 17); // Rx, Tx
Serial2.setTimeout(200);
}
uint16_t CRC16(uint8_t *buf, int len) {
uint16_t crc = 0xFFFF;
for (uint16_t pos = 0; pos < len; pos++) {
crc ^= (uint16_t)buf[pos]; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
} else { // Else LSB is not set
crc >>= 1; // Just shift right
}
}
}
return crc;
}
uint8_t readModbusRTU(uint8_t devAddr, uint8_t fnCode, uint16_t startAddr, uint8_t dataLen, uint8_t* buffRead) {
uint8_t buff[8] = {
devAddr, // Devices Address
fnCode, // Function code
startAddr >> 8, // Start Address HIGH
startAddr & 0xFF, // Start Address LOW
0x00, // Q HIGH
dataLen, // Q LOW
0x00, // CRC LOW
0x00 // CRC HIGH
};
uint16_t crc = CRC16(&buff[0], 6);
buff[6] = crc & 0xFF;
buff[7] = (crc >> 8) & 0xFF;
digitalWrite(DE_RE_PIN, MODE_SEND);
Serial2.write(buff, sizeof(buff));
Serial2.flush(); // wait MODE_SEND completed
digitalWrite(DE_RE_PIN, MODE_RECV);
char findStr[] = { devAddr, fnCode, 0 };
if (Serial2.find(findStr)) {
uint8_t n = Serial2.read();
if (n != dataLen * 2) {
Serial.println("Error data size");
return 0;
}
Serial2.readBytes(buffRead, n);
if (Serial2.available() < 2) delay(1);
uint16_t crc16 = 0;
crc16 |= Serial2.read();
crc16 |= (uint16_t)Serial2.read() << 8;
return n;
}
return 0;
}
float b2f(uint8_t* buff) {
uint8_t nBuff[4] = { buff[3], buff[2], buff[1], buff[0] };
static float value = 0;
memcpy(&value, nBuff, 4);
return value;
}
float read(uint16_t offset) {
uint8_t buff[4];
uint8_t n = readModbusRTU(44, 4, offset, 2, buff);
if (n == 4) {
return b2f(buff);
}
return -999.99;
}
void loop() {
Serial.printf("Volt: %.02fV\n", read(0x0000));
Serial.printf("Current: %.02fA\n", read(0x0008));
Serial.printf("Active Power: %.02fkWh\n", read(0x0012));
Serial.printf("Power Factor: %.02f\n", read(0x002A));
Serial.printf("Frequency: %.02fHz\n", read(0x0036));
Serial.printf("Total Active Power: %.02fkWh\n", read(0x0100));
Serial.printf("---------------------------\n");
delay(500);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment