DALI और Arduino इंटरफ़ेस। असली अतियथार्थवाद

सभी को नमस्कार। हमारे विभाग को DALI डिजिटल इंटरफ़ेस प्रस्तुत करने का काम सौंपा गया था। इसके अलावा, इस इंटरफ़ेस के संचालन को प्रदर्शित करने वाली एक प्रस्तुति। यदि आवश्यक हो, तो यह आवश्यक है। हमने अभी क्या नहीं किया इस उद्देश्य के लिए, एलईडी ल्यूमिनेयरों के लिए दो नियंत्रण मॉड्यूल प्रदान किए गए थे। दोनों को भगा दिया गया। गुरु के बारे में क्या? हमने इस इंटरफ़ेस को नियंत्रित करने के लिए एक नियंत्रक चुनना शुरू किया। नतीजतन, या तो कीमत आसमानी है या डिलीवरी का समय समान है। और छुट्टी आ रही है, और मैं इसे अब स्थगित नहीं करना चाहता। एक बार फिर, हमने विशेषताओं को देखा और इस डिजिटल प्रोटोकॉल की विशेषताओं पर ध्यान आकर्षित किया:

  • DALI एक खुला प्रोटोकॉल है;
  • DALI एक विकेन्द्रीकृत बस है, अर्थात इसमें केंद्रीय नियंत्रक नहीं है और यह किसी भी टोपोलॉजी की अनुमति देता है।

यह सब बहुत आकर्षक लग रहा था और कार्य पूरी तरह से मुश्किल नहीं लग रहा था। पहली नज़र में। हमने Arduino पर DALI स्वामी बनाने का फैसला किया।

हेबर पर अपने प्रकाशन के लिए तैमूर नबाव को बहुत धन्यवाद। कृपया पढ़ें। मैं खुद को नहीं दोहराऊंगा, उन्होंने एक अच्छा सिद्धांत निर्धारित किया। इंटरफ़ेस लेआउट - यह कोई आसान नहीं होता है। लेकिन उन्होंने जो पुस्तकालय प्रकाशित किया, उससे हमारे लिए कुछ खास कारगर नहीं हुआ।

इसलिए, हमने अपने स्केच बनाने का फैसला किया। उन्होंने दो किए। पहले नेटवर्क के सभी "सदस्यों" को छोटे पते आवंटित करना है।
नज़र
#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); } 

या डाउनलोड करें

और यह एक परीक्षा है। हम DALI से जुड़े दो मॉड्यूल को नियंत्रित करते हैं।
नज़र
 #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); } 

या डाउनलोड करें
बहुत काम किया गया है और इसलिए मैं इसे सभी के साथ साझा करना चाहता हूं। शायद यह किसी के लिए विकास को आसान बना देगा।

नेटवर्क पर कोई पूर्ण लाइब्रेरी नहीं मिली। कृपया उपयोग करें, सब कुछ वास्तव में काम करता है। प्रश्न पूछें, मैं अपने सहयोगियों के साथ हर बात का जवाब देने की कोशिश करूंगा। शायद तुरंत नहीं, हम वास्तव में दो सप्ताह के लिए छुट्टी पर जाते हैं।

किए गए कार्य पर वीडियो रिपोर्ट में।

मतलब वेल से DAP-04 और LCM-60DA मॉड्यूल का परीक्षण किया। लेकिन यह किसी भी अन्य के साथ काम करेगा।

और यह Arduino बॉडी किट स्कीम है, जो इसे उसी समय DALI मास्टर मोड और पावर सप्लाई में ट्रांसफर करती है।



यह परीक्षण स्केच के लिए बटन का कनेक्शन है।



और यहाँ एक छोटा DALI नेटवर्क है



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


All Articles