Antarmuka DALI dan Arduino. Surealisme nyata

Halo semuanya. Departemen kami ditugaskan untuk menghadirkan antarmuka digital DALI. Selain itu, presentasi menunjukkan pengoperasian antarmuka ini. Jika perlu, maka itu perlu. Apa yang tidak kami lakukan. Untuk tujuan ini, dua modul kontrol untuk luminer LED disediakan. Keduanya terdorong. Bagaimana dengan tuannya? Kami mulai memilih pengontrol untuk mengontrol antarmuka ini. Akibatnya, harganya sangat tinggi atau waktu pengirimannya sama. Dan liburan semakin dekat, dan saya tidak ingin menunda lagi. Sekali lagi, kami melihat karakteristik dan memperhatikan fitur dari protokol digital ini:

  • DALI adalah protokol terbuka;
  • DALI adalah bus terdesentralisasi, yaitu, ia tidak memiliki pengontrol pusat dan memungkinkan topologi apa pun.

Semua ini tampak sangat menarik dan tugas itu tampaknya sama sekali tidak sulit. Sekilas. Kami memutuskan untuk membuat master DALI di Arduino.

Terima kasih banyak kepada Timur Nabiev untuk publikasi tentang Habré . Silakan baca. Saya tidak akan mengulangi lagi, ia memberikan teori yang bagus. Tata letak antarmuka - itu tidak terjadi lebih mudah. Tetapi dengan perpustakaan yang dia terbitkan, sesuatu tidak berjalan dengan baik bagi kami.

Karena itu, kami memutuskan untuk membuat sketsa kami. Mereka melakukan dua. Yang pertama adalah menetapkan alamat pendek untuk semua "anggota" jaringan.
Lihat
#define DALI_TX_PIN 3 #define DALI_RX_PIN A0 #define LED_PIN 13 #define RESET 0b00100000 #define INITIALISE 0xA5 #define RANDOMISE 0xA7 #define SEARCHADDRH 0xB1 #define SEARCHADDRM 0xB3 #define SEARCHADDRL 0xB5 #define PRG_SHORT_ADDR 0xB7 #define COMPARE 0xA9 #define WITHDRAW 0xAB #define TERMINATE 0xA1 #define START_SHORT_ADDR 2 #define DALI_ANALOG_LEVEL 650 #define DALI_HALF_BIT_TIME 416 //microseconds #define DALI_TWO_PACKET_DELAY 10 //miliseconds #define DALI_RESPONSE_DELAY_COUNT 15 //   //  uint8_t ShortAddr = START_SHORT_ADDR; void setup() { pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); pinMode(DALI_TX_PIN, OUTPUT); digitalWrite(DALI_TX_PIN, HIGH); Serial.begin(115200); DaliInit(); } //----------------------------------------------------- void loop() { } //----------------------------------------------------- void DaliInit() { Serial.println("Initialization..."); DaliTransmitCMD(RESET, 0x00); delay(2*DALI_TWO_PACKET_DELAY); DaliTransmitCMD(RESET, 0x00); delay(2*DALI_TWO_PACKET_DELAY); delay(100); DaliTransmitCMD(INITIALISE, 0x00); delay(DALI_TWO_PACKET_DELAY); DaliTransmitCMD(INITIALISE, 0x00); delay(DALI_TWO_PACKET_DELAY); DaliTransmitCMD(INITIALISE, 0x00); delay(DALI_TWO_PACKET_DELAY); delay(100); DaliTransmitCMD(RANDOMISE, 0x00); delay(DALI_TWO_PACKET_DELAY); DaliTransmitCMD(RANDOMISE, 0x00); delay(DALI_TWO_PACKET_DELAY); delay(100); while(ShortAddr < 64) { long SearchAddr = 0xFFFFFF; bool Response = 0; long LowLimit = 0; long HighLimit = 0x1000000; Response = SearchAndCompare(SearchAddr); delay(DALI_TWO_PACKET_DELAY); if(Response) { digitalWrite(LED_PIN, LOW); Serial.println("Device detected, address searching..."); if(!SearchAndCompare(SearchAddr - 1)) { delay(DALI_TWO_PACKET_DELAY); SearchAndCompare(SearchAddr); delay(DALI_TWO_PACKET_DELAY); DaliTransmitCMD(PRG_SHORT_ADDR, ((ShortAddr << 1) | 1)); delay(3*DALI_TWO_PACKET_DELAY); DaliTransmitCMD(WITHDRAW, 0x00); Serial.print("24-bit address found: 0x"); Serial.println(SearchAddr, HEX); Serial.print("Assigning short address "); Serial.println(ShortAddr); break; } } else { Serial.println("No devices detected"); break; } while(1) { SearchAddr = (long)((LowLimit + HighLimit) / 2); Response = SearchAndCompare(SearchAddr); delay(DALI_TWO_PACKET_DELAY); if (Response) { digitalWrite(LED_PIN, LOW); if ((SearchAddr == 0) || (!SearchAndCompare(SearchAddr - 1))) break; HighLimit = SearchAddr; } else LowLimit = SearchAddr; } delay(DALI_TWO_PACKET_DELAY); SearchAndCompare(SearchAddr); delay(DALI_TWO_PACKET_DELAY); DaliTransmitCMD(PRG_SHORT_ADDR, ((ShortAddr << 1) | 1)); delay(5*DALI_TWO_PACKET_DELAY); DaliTransmitCMD(WITHDRAW, 0x00); delay(DALI_TWO_PACKET_DELAY); Serial.print("24-bit address found: 0x"); Serial.println(SearchAddr, HEX); Serial.print("Assigning short address "); Serial.println(ShortAddr); ShortAddr++; // break; //    } delay(DALI_TWO_PACKET_DELAY); DaliTransmitCMD(TERMINATE, 0x00); delay(DALI_TWO_PACKET_DELAY); Serial.println("Init complete"); } //------------------------------------------------- bool SearchAndCompare(long SearchAddr) { bool Response = 0; uint8_t HighByte = SearchAddr >> 16; uint8_t MiddleByte = SearchAddr >> 8; uint8_t LowByte = SearchAddr; for(uint8_t i = 0; i < 3; i++) { DaliTransmitCMD(SEARCHADDRH, HighByte); delay(DALI_TWO_PACKET_DELAY); DaliTransmitCMD(SEARCHADDRM, MiddleByte); delay(DALI_TWO_PACKET_DELAY); DaliTransmitCMD(SEARCHADDRL, LowByte); delay(DALI_TWO_PACKET_DELAY); } DaliTransmitCMD(COMPARE, 0x00); delayMicroseconds(7 * DALI_HALF_BIT_TIME); for(uint8_t i = 0; i < DALI_RESPONSE_DELAY_COUNT; i++) { if (analogRead(DALI_RX_PIN) < DALI_ANALOG_LEVEL) { Response = 1; digitalWrite(LED_PIN, HIGH); break; } delayMicroseconds(DALI_HALF_BIT_TIME); } return Response; } //------------------------------------------------- void DaliTransmitCMD(uint8_t Part1, uint8_t Part2) { uint8_t DALI_CMD[] = { Part1, Part2 }; //  digitalWrite(DALI_TX_PIN, LOW); delayMicroseconds(DALI_HALF_BIT_TIME); digitalWrite(DALI_TX_PIN, HIGH); delayMicroseconds(DALI_HALF_BIT_TIME); // for (uint8_t CmdPart = 0; CmdPart < 2; CmdPart++) { for(int i = 7; i >= 0; i--) { bool BitToSend = false; if ((DALI_CMD[CmdPart] >> i) & 1) BitToSend = true; if (BitToSend) digitalWrite(DALI_TX_PIN, LOW); else digitalWrite(DALI_TX_PIN, HIGH); delayMicroseconds(DALI_HALF_BIT_TIME); if (BitToSend) digitalWrite(DALI_TX_PIN, HIGH); else digitalWrite(DALI_TX_PIN, LOW); delayMicroseconds(DALI_HALF_BIT_TIME); } } digitalWrite(DALI_TX_PIN, HIGH); } 

Atau unduh

Dan ini adalah ujian. Kami mengontrol dua modul yang terhubung ke DALI.
Lihat
 #define DALI_TX_PIN 3 #define DALI_RX_PIN A0 #define BROADCAST_CMD 0b11111111 #define DOWN 0b00000010 #define UP 0b00000001 #define DALI_CHNL_COUNT 4 #define LAMP_OFF_VALUE 0 #define DALI_HALF_BIT_TIME 416 //microseconds #define DALI_TWO_PACKET_DELAY 10 //miliseconds //  uint8_t AnalogPins[DALI_CHNL_COUNT] = {A1, A2, A3, A4, }; // uint8_t KeyPins[DALI_CHNL_COUNT] = {4, 5, 6, 7, }; uint8_t DALIPrevVals[DALI_CHNL_COUNT] = {0, 0, 0, 0}; uint8_t LampState[DALI_CHNL_COUNT] = {0, 0, 0, 0}; void setup() { pinMode(DALI_TX_PIN, OUTPUT); digitalWrite(DALI_TX_PIN, HIGH); for(uint8_t i = 0; i < DALI_CHNL_COUNT; i++) { pinMode(KeyPins[i], INPUT); digitalWrite(KeyPins[i], HIGH); } } void loop() { for(uint8_t PWM = 2; PWM < DALI_CHNL_COUNT; PWM++) { if (LampState[PWM] == 1) { uint16_t ADCValue = analogRead(AnalogPins[PWM]); if (ADCValue > 1016) ADCValue = 1016; ADCValue /= 4; uint8_t PWMVal = ADCValue; if (abs(DALIPrevVals[PWM] - PWMVal) >= 1) { DALIPrevVals[PWM] = PWMVal; DaliTransmitCMD(PWM << 1, PWMVal); if (LampState[PWM] == 0) LampState[PWM] = 1; delay(DALI_TWO_PACKET_DELAY); } } } for(uint8_t KEY = 0; KEY < DALI_CHNL_COUNT; KEY++) { if (digitalRead(KeyPins[KEY]) == LOW) { delay(70); if (KEY == 0) { DaliTransmitCMD(BROADCAST_CMD, UP); delay(DALI_TWO_PACKET_DELAY); break; } else if (KEY == 1) { DaliTransmitCMD(BROADCAST_CMD, DOWN); delay(DALI_TWO_PACKET_DELAY); break; } if (digitalRead(KeyPins[KEY]) == LOW) { if (LampState[KEY] == 0) { LampState[KEY] = 1; uint16_t ADCValue = analogRead(AnalogPins[KEY]); if (ADCValue > 1016) ADCValue = 1016; ADCValue /= 4; uint8_t PWMVal = ADCValue; DaliTransmitCMD(KEY << 1, PWMVal); } else { LampState[KEY] = 0; DaliTransmitCMD(KEY << 1, LAMP_OFF_VALUE); } delay(DALI_TWO_PACKET_DELAY); } delay(500); } } } //------------------------------------------------- void DaliTransmitCMD(uint8_t Part1, uint8_t Part2) { uint8_t DALI_CMD[] = { Part1, Part2 }; //  digitalWrite(DALI_TX_PIN, LOW); delayMicroseconds(DALI_HALF_BIT_TIME); digitalWrite(DALI_TX_PIN, HIGH); delayMicroseconds(DALI_HALF_BIT_TIME); // for (uint8_t CmdPart = 0; CmdPart < 2; CmdPart++) { for(int i = 7; i >= 0; i--) { bool BitToSend = false; if ((DALI_CMD[CmdPart] >> i) & 1) BitToSend = true; if (BitToSend) digitalWrite(DALI_TX_PIN, LOW); else digitalWrite(DALI_TX_PIN, HIGH); delayMicroseconds(DALI_HALF_BIT_TIME); if (BitToSend) digitalWrite(DALI_TX_PIN, HIGH); else digitalWrite(DALI_TX_PIN, LOW); delayMicroseconds(DALI_HALF_BIT_TIME); } } digitalWrite(DALI_TX_PIN, HIGH); } 

Atau unduh
Banyak pekerjaan yang telah dilakukan dan oleh karena itu saya ingin membagikannya kepada semua orang. Mungkin ini akan membuat pengembangan lebih mudah bagi seseorang.

Tidak ada perpustakaan lengkap yang ditemukan di jaringan. Silakan gunakan, semuanya benar-benar berfungsi. Ajukan pertanyaan, saya akan mencoba menjawab semuanya dengan kolega saya. Mungkin tidak segera, kami benar-benar pergi berlibur selama dua minggu.

Dalam laporan video tentang pekerjaan yang dilakukan.

Diuji modul DAP-04 dan LCM-60DA dari Mean Well. Tapi itu akan berhasil dengan yang lain.

Dan ini adalah skema body kit Arduino, yang mentransfernya ke mode master DALI dan catu daya secara bersamaan.



Ini adalah koneksi tombol untuk sketsa uji.



Dan di sini ada jaringan DALI kecil



Source: https://habr.com/ru/post/id410105/


All Articles