واجهة DALI و Arduino. السريالية الحقيقية

مرحبا بالجميع. تم تكليف قسمنا بتقديم واجهة DALI الرقمية. علاوة على ذلك ، عرض تقديمي يوضح تشغيل هذه الواجهة. إذا لزم الأمر ، فمن الضروري. ما لم نفعله للتو. لهذا الغرض ، تم توفير وحدتي تحكم لمصابيح LED. تم دفع كلاهما. ماذا عن السيد؟ بدأنا في اختيار وحدة تحكم للتحكم في هذه الواجهة. نتيجة لذلك ، إما أن السعر مرتفع للغاية أو أن وقت التسليم هو نفسه. العطلة تقترب ، ولا أشعر برغبة في التأجيل. مرة أخرى ، نظرنا في الخصائص ولفتنا الانتباه إلى ميزات هذا البروتوكول الرقمي:

  • DALI هو بروتوكول مفتوح.
  • 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 من Mean Well. لكنها ستعمل مع أي شخص آخر.

وهذا هو مخطط طقم الجسم Arduino ، والذي ينقله إلى وضع DALI الرئيسي ومصدر الطاقة في نفس الوقت.



هذا هو اتصال الأزرار لرسم الاختبار.



وهنا شبكة DALI صغيرة



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


All Articles