#include #include #include /* Модуль управления светом на семь групп "MUS-7" управляемый по RS-485 0x03 (03) - чтение значени из регистров хранения 0x10 (16) - запись значения в регистр хранения 0x48 (72) - смена адресса устройства 00 7f 10 00 00 00 01 00 02 00 92 - запись значениия "2" в регистр №0 00 7f 10 00 00 00 02 00 01 00 01 00 93 - запись значениия "1" в регистр №0 и №1 00 7f 03 00 00 00 07 00 89 - чтение всех 7-ми регистров га устройстве по адресу 127 (0x7f) 00 7f 48 00 00 00 01 00 02 00 ca - смена адресса устройства с 127 на 2 с записью в энергонезависимую память */ #define SerialTxControl 10 //RS485 порт управления max485 arduino pin 10 #define RS485Transmit HIGH // включение режима передачи #define RS485Receive LOW // сключение режима приема const int ledDan = 13; // выход индикации на включение режима передачи int address_read; int address; int address_buf; int funct; // функция long date[100]; int col_dan; // the variable for counting the number of transmitted registers int stat = 0; int checksum; int sum; int sum_dan = 0; int s_reg; int val_a[] ={0,0,0,0,0,0,0}; // служебные регистры int val_b[] ={0,0,0,0,0,0,0}; // буферные принимаемые регистры int valOld[] ={0,0,0,0,0,0,0}; // старое значение регистров // задание портов выводов подключаемых к реле const int ledPin2 = 9; const int ledPin3 = 8; const int ledPin4 = 7; const int ledPin5 = 6; const int ledPin6 = 5; const int ledPin7 = 4; const int ledPin8 = 3; // задание портов входов подключения к выключателям const int analogInPin2 = 12; const int analogInPin3 = A0; const int analogInPin4 = A1; const int analogInPin5 = A2; const int analogInPin6 = A3; const int analogInPin7 = A4; const int analogInPin8 = A5; // устранение дребезга контактов Bounce bouncer2 = Bounce( analogInPin2, 10 ); Bounce bouncer3 = Bounce( analogInPin3, 10 ); Bounce bouncer4 = Bounce( analogInPin4, 10 ); Bounce bouncer5 = Bounce( analogInPin5, 10 ); Bounce bouncer6 = Bounce( analogInPin6, 10 ); Bounce bouncer7 = Bounce( analogInPin7, 10 ); Bounce bouncer8 = Bounce( analogInPin8, 10 ); void setup() { Serial.begin(9600); delay(100); address_read = EEPROM.read(0); if (address_read == 255) { address = 127; } else {address = address_read;} pinMode(SerialTxControl, OUTPUT); pinMode(ledDan, OUTPUT); digitalWrite(SerialTxControl, RS485Transmit); digitalWrite(ledDan, RS485Transmit); Serial.println(""); Serial.print("Address - "); Serial.print(address); Serial.print(" "); Serial.print("MUS-7"); Serial.print(" "); Serial.print("(OKbit.ru)"); Serial.println(" "); delay(100); digitalWrite(SerialTxControl, RS485Receive); digitalWrite(ledDan, RS485Receive); pinMode(ledPin2, OUTPUT); pinMode(ledPin3, OUTPUT); pinMode(ledPin4, OUTPUT); pinMode(ledPin5, OUTPUT); pinMode(ledPin6, OUTPUT); pinMode(ledPin7, OUTPUT); pinMode(ledPin8, OUTPUT); pinMode(analogInPin2,INPUT); pinMode(analogInPin3,INPUT); pinMode(analogInPin4,INPUT); pinMode(analogInPin5,INPUT); pinMode(analogInPin6,INPUT); pinMode(analogInPin7,INPUT); pinMode(analogInPin8,INPUT); } void fBus_read(){ funct = 0; col_dan = 0; sum_dan = 0; sum = 0; if (Serial.available() > 0 && stat == 0 ) { for(int i=0; i < 300; i++) { delay(10); date[i] = Serial.read(); if (i == 6) { col_dan = ((date[6] << 0) & 0xFF) + ((date[5] << 8) & 0xFF00); } //Serial.write(col_dan); //Serial.write(date[i]); if (i == col_dan*2+8) { stat = 1; break; } } funct = date[2]; s_reg = ((date[4] << 0) & 0xFF) + ((date[3] << 8) & 0xFF00); // вычисление значения сдвигового регистра // вычисление значения чексуммы checksum = ((date[8+col_dan*2] << 0) & 0xFF) + ((date[7+col_dan*2] << 8) & 0xFF00); //считывание значений регистров и их суммы если функция команды на запись "0x10" //или функция смены адресса устройства "0x03" if (funct == 0x10){ for (int a=0; a <= col_dan-1; a++) { val_b[a+s_reg] = (((date[8+a*2] << 0) & 0xFF) + ((date[7+a*2] << 8) & 0xFF00)); sum_dan = sum_dan + (((date[8+a*2] << 0) & 0xFF) + ((date[7+a*2] << 8) & 0xFF00)); } // вычисление суммы для проверки целосности sum = date[1] + date[2] + s_reg + col_dan + sum_dan; // вычисление значения чексуммы checksum = ((date[8+col_dan*2] << 0) & 0xFF) + ((date[7+col_dan*2] << 8) & 0xFF00); } //вычесление суммы данных для фунции чтения значения регистров "0x03" else if (funct == 0x03){ for (int a=0; a <= col_dan-1; a++) { sum_dan = sum_dan + val_b[a+s_reg]; } // вычисление значения чексуммы checksum = ((date[8] << 0) & 0xFF) + ((date[7] << 8) & 0xFF00); // вычисление суммы для команды чтения регистра sum = date[1] + date[2] + s_reg + col_dan; } //вычесление суммы данных для фунции чтения значения регистров "0x48" else if (funct == 0x48){ address_buf = (((date[8] << 0) & 0xFF) + ((date[7] << 8) & 0xFF00)); // вычисление значения чексуммы checksum = ((date[10] << 0) & 0xFF) + ((date[9] << 8) & 0xFF00); // вычисление суммы для команды смены адресса sum = date[1] + date[2] + s_reg + col_dan + address_buf; } // проверка что пакет пришел по протоколу fBus данному адресату и пакет целый не битый if (date[0] == 0 && date[1] == address && checksum == sum) { stat = 2; if (funct == 0x03){sum = date[1] + date[2] + s_reg + col_dan + sum_dan;} } else { stat = 1; } } // Отчистка серийного буфера от мусора если таковой есть if (Serial.available() > 0 && stat == 1) { delay(10); int zero = Serial.read(); } else if (stat == 1){ stat = 0; } } void fBus_write(){ if (stat == 2) { delay(100); digitalWrite(SerialTxControl, RS485Transmit); digitalWrite(ledDan, RS485Transmit); Serial.write(0x00); Serial.write(address); Serial.write(funct); Serial.write(((s_reg >> 8) & 0xFF)); Serial.write(((s_reg >> 0) & 0xFF)); Serial.write(((col_dan >> 8) & 0xFF)); Serial.write(((col_dan >> 0) & 0xFF)); if (funct == 0x10 || funct == 0x03){ for (int a=0; a <= col_dan-1; a++) { delay(1); Serial.write((val_b[a+s_reg] >> 8) & 0xFF); Serial.write((val_b[a+s_reg] >> 0) & 0xFF); } } if (funct == 0x48){ Serial.write((address_buf >> 8) & 0xFF); Serial.write((address_buf >> 0) & 0xFF); } Serial.write(((sum >> 8) & 0xFF)); Serial.write(((sum >> 0) & 0xFF)); stat = 1; delay(100); digitalWrite(SerialTxControl, RS485Receive); digitalWrite(ledDan, RS485Receive); } } void debounce(){ if ( bouncer2.update() ) { if ( bouncer2.read() == HIGH) { if ( val_a[0] == LOW ) { val_a[0] = HIGH; } else { val_a[0] = LOW; } valOld[0] = val_a[0]; val_b[0] = val_a[0]; } } digitalWrite(ledPin2,val_a[0]); if ( bouncer3.update() ) { if ( bouncer3.read() == HIGH) { if ( val_a[1] == LOW ) { val_a[1] = HIGH; } else { val_a[1] = LOW; } valOld[1] = val_a[1]; val_b[1] = val_a[1]; } } digitalWrite(ledPin3,val_a[1]); if ( bouncer4.update() ) { if ( bouncer4.read() == HIGH) { if ( val_a[2] == LOW ) { val_a[2] = HIGH; } else { val_a[2] = LOW; } valOld[2] = val_a[2]; val_b[2] = val_a[2]; } } digitalWrite(ledPin4,val_a[2]); if ( bouncer5.update() ) { if ( bouncer5.read() == HIGH) { if ( val_a[3] == LOW ) { val_a[3] = HIGH; } else { val_a[3] = LOW; } valOld[3] = val_a[3]; val_b[3] = val_a[3]; } } digitalWrite(ledPin5,val_a[3]); if ( bouncer6.update() ) { if ( bouncer6.read() == HIGH) { if ( val_a[4] == LOW ) { val_a[4] = HIGH; } else { val_a[4] = LOW; } valOld[4] = val_a[4]; val_b[4] = val_a[4]; } } digitalWrite(ledPin6,val_a[4]); if ( bouncer7.update() ) { if ( bouncer7.read() == HIGH) { if ( val_a[5] == LOW ) { val_a[5] = HIGH; } else { val_a[5] = LOW; } valOld[5] = val_a[5]; val_b[5] = val_a[5]; } } digitalWrite(ledPin7,val_a[5]); if ( bouncer8.update() ) { if ( bouncer8.read() == HIGH) { if ( val_a[6] == LOW ) { val_a[6] = HIGH; } else { val_a[6] = LOW; } valOld[6] = val_a[6]; val_b[6] = val_a[6]; } } digitalWrite(ledPin8,val_a[6]); } void handler(){ if (stat == 2 && funct == 0x10){ //проверка пришедших значений регистра, если значение неравно старому переключить значение выхода if (val_b[0] != valOld[0]){ val_a[0] = val_b[0]; valOld[0] = val_b[0]; } if (val_b[1] != valOld[1]){ val_a[1] = val_b[1]; valOld[1] = val_b[1]; } if (val_b[2] != valOld[2]){ val_a[2] = val_b[2]; valOld[2] = val_b[2]; } if (val_b[3] != valOld[3]){ val_a[3] = val_b[3]; valOld[3] = val_b[3]; } if (val_b[4] != valOld[4]){ val_a[4] = val_b[4]; valOld[4] = val_b[4]; } if (val_b[5] != valOld[5]){ val_a[5] = val_b[5]; valOld[5] = val_b[5]; } if (val_b[6] != valOld[6]){ val_a[6] = val_b[6]; valOld[6] = val_b[6]; } } } void check_address(){ if (stat == 2 && funct == 0x48 && address != address_buf){ address = ((address_buf >> 0) & 0xFF); EEPROM.write(0, address); } } void loop(){ fBus_read(); check_address(); debounce(); handler(); fBus_write(); }