You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
7.4 KiB
C++

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

const int MC9_CH[] = {1000, 1008, 1016, 1024, 1100, 1108, 1116, 1124};
// 10DWR,02,0302,0001,0501,0001
// Auto Tune. 0302(Ch Sel) 0001(Ch.1) 0501(AT) 0001(On, Off=0000)
void setupMC9_1(int i, int data){
RS485_1_Addr[i] = data;
Serial.println("MC9 No."+ String(i) + " 's address set as " + String(data));
}
String msg_MC9_PV(int addr){
String message = "";
if(addr < 10){
message += "0";
}
message += String(addr); // Address
message += "DRS,08,0001"; // Data Read Seris 08 data from 0001(PV) ch
message += sumMC9(message); // Check Sum
message = "" + message; // Start with STX
return message;
}
String msg_MC9_SV(int addr){
String message = "";
if(addr < 10){
message += "0";
}
message += String(addr); // Address
message += "DRS,08,0011"; // Data Read Seris 08 data from 0001(SV) ch
message += sumMC9(message); // Check Sum
message = "" + message; // Start with STX
return message;
}
int msg_MC9_SV_set(unsigned int data[], int dataSize){
String message = "";
int lp0, lp1;
if(dataSize > 8){
lp0 = 8;
lp1 = dataSize;
}else{
lp0 = dataSize;
lp1 = 0;
}
if(RS485_1_Addr[0] != 0){
if(RS485_1_Addr[0] < 10){
message += "0";
}
message = String(RS485_1_Addr[0]);
message += "DWR,0" + String(lp0) + ",";
for(int i=0 ; i<lp0 ; i++){
char hexStr[5]; // Buffer to hold the hexadecimal string (4 characters + null terminator)
sprintf(hexStr, "%04X", data[i]); // Format as 4 digit uppercase hexadecimal
message += MC9_CH[i] + 1; // ZONE 1
message += ",";
message += String(hexStr);
if(i != (lp0-1)){
message += ",";
}
}
message += sumMC9(message);
message = "" + message + CRLF;
write_buff_first(Buff_485_1_Wr, message);
}
if((RS485_1_Addr[1] != 0) && (lp1>0)){
if(RS485_1_Addr[1] < 10){
message += "0";
}
message = String(RS485_1_Addr[1]);
message += "DWR,0" + String(lp1-8) + ",";
for(int i=8 ; i<lp1 ; i++){
char hexStr[5]; // Buffer to hold the hexadecimal string (4 characters + null terminator)
sprintf(hexStr, "%04X", data[i]); // Format as 4 digit uppercase hexadecimal
message += MC9_CH[i%8] + 1; // ZONE 1
message += ",";
message += String(hexStr);
if(i != (lp1-1)){
message += ",";
}
}
message += sumMC9(message);
message = "" + message + CRLF;
write_buff_first(Buff_485_1_Wr, message);
}
return 0;
}
int msg_MC9_AT_set(unsigned int data[], int dataSize){
String message = "";
bool at[16];
int lp0, lp1;
// Number to boolean array
unsigned int data0 = data[0];
for (int i = 0; i < 16; i++) {
at[i] = (bitRead(data0, i) ? HIGH : LOW);
}
lp0 = 8;
lp1 = 8;
message = "";
if(RS485_1_Addr[0] != 0){
if(RS485_1_Addr[0] < 10){
message += "0";
}
message += String(RS485_1_Addr[0]);
message += "DWR,16,";
for(int i=0 ; i<8 ; i++){
String atFlag;
if(at[i]){
atFlag = "0001"; // Auto Tuen On
}else{
atFlag = "0000"; // Auto Tuen Off
}
message += "0302,"; // Ch No cmd.
message += "000" + String(i+1) + ","; // Ch No.
message += "0501,"; // AT cmd.
message += atFlag; // AT flag
if(i != 7){
message += ",";
}
}
message += sumMC9(message);
message = "" + message + CRLF;
write_buff_first(Buff_485_1_Wr, message);
}
message = "";
if((RS485_1_Addr[1] != 0) && (lp1>0)){
if(RS485_1_Addr[1] < 10){
message += "0";
}
message += String(RS485_1_Addr[1]);
message += "DWR,16,";
for(int i=0 ; i<8 ; i++){
String atFlag;
if(at[i+8]){
atFlag = "0001";
}else{
atFlag = "0000";
}
message += "0302,"; // Ch No cmd.
message += "000" + String(i+1) + ","; // Ch No.
message += "0501,"; // AT cmd.
message += atFlag; // AT flag
if(i != 7){
message += ",";
}
}
message += sumMC9(message);
message = "" + message + CRLF;
write_buff_first(Buff_485_1_Wr, message);
}
return 0;
}
int saveMC9(String message){
int addr;
int idx = -1;
String mode;
int data[8];
int crc;
if (!parseMC9(message, addr, mode, data, crc)) {
for(int i=0 ; i < 2 ; i++){ // RS485_1 has two rooms for two MC9s
if(RS485_1_Addr[i] == addr){
idx = i;
break;
}
}
if(idx < 0){
return -1;
}
if(latest_sent_msg.indexOf("DRS,08,0001") != -1){ // if sent message is PV CMD
//rcv_10_PV = true;
RS485_1_Rcv_PV[idx] = true;
for(int i = 0 ; i < RS485_1_Rcv_size ; i++){
RS485_1_Values_PV[i + idx*8] = data[i];
}
}
if(latest_sent_msg.indexOf("DRS,08,0011") != -1){ // if sent message is SV CMD
//rcv_10_SV = true;
RS485_1_Rcv_SV[idx] = true;
for(int i = 0 ; i < RS485_1_Rcv_size ; i++){
RS485_1_Values_SV[i + idx*8] = data[i];
}
}
return 0;
} else {
Serial.println("error 485 read");
return -1;
}
}
int timeoutMC9(){
int addr;
int idx = -1;
String msg, mode, cmd;
char dummy[4];
int data[8];
int crc;
// Message parsing
msg = latest_sent_msg.substring(1);
sscanf(msg.c_str(), "%2d%3s", &addr, &dummy);
Serial.print("485 not responced... (Timeout) Req msg : " + latest_sent_msg);
if (latest_sent_msg.indexOf("DRS") != -1) {
for(int i=0 ; i < 2 ; i++){ // RS485_1 has two rooms for two MC9s
// Find idx of array
if(RS485_1_Addr[i] == addr){
idx = i;
break;
}
}
// If not matched, return error
if(idx < 0){
Serial.println();
return -1;
}
if(latest_sent_msg.indexOf("DRS,08,0001") != -1){ // if sent message is PV CMD
RS485_1_Rcv_PV[idx] = false;
Serial.print(" >> PV @");
Serial.println(idx);
}
if(latest_sent_msg.indexOf("DRS,08,0011") != -1){ // if sent message is SV CMD
RS485_1_Rcv_SV[idx] = false;
Serial.print(" >> SV @");
Serial.println(idx);
}
return 0;
} else {
Serial.println();
return -1;
}
/*
if(latest_sent_msg == MC9_10_PV){
//rcv_10_PV = false;
}
if(latest_sent_msg == MC9_10_SV){
//rcv_10_SV = false;
}else {
Serial.println("error 485 read");
return -1;
}
*/
}
int parseMC9(const String& message, int& addr, String& mode, int data[8], int& crc) {
char addrC[3], modeC[4], statusC[3];
int dataC[8], crcC;
// Remove start-of-text character if present
if (message[0] == '\x02') {
message = message.substring(1);
}
// Parse the MC9 message
int ret = sscanf(message.c_str(), "%2s%3s,%2s,%4x,%4x,%4x,%4x,%4x,%4x,%4x,%4x%2x",
addrC, modeC, statusC, &dataC[0], &dataC[1], &dataC[2], &dataC[3], &dataC[4], &dataC[5], &dataC[6], &dataC[7], &crcC);
// Check the parsed status and the number of extracted elements
if (strcmp(statusC, "OK") != 0 || ret != 12) {
return -1;
}
// Copy data to the output parameters
addr = atoi(addrC);
mode = String(modeC);
for (int i = 0; i < 8; i++) {
data[i] = dataC[i];
}
crc = crcC;
return 0;
}
String sumMC9(String input) {
int sum = 0;
for (char c : input) {
sum += c;
}
sum = sum & 0xFF; // Make sure we only keep the least significant byte
String hexSum = String(sum, HEX); // Convert the sum to hexadecimal
hexSum.toUpperCase(); // Make it upper-case
return hexSum;
}