Различия
Показаны различия между двумя версиями страницы.
| Предыдущая версия справа и слева Предыдущая версия | |||
| zheleznaja_chast:dmx-512_tester_na_mikrokontrollere_arduino_mini [2017/06/09 20:05] – внешнее изменение 127.0.0.1 | zheleznaja_chast:dmx-512_tester_na_mikrokontrollere_arduino_mini [2025/12/21 18:51] (текущий) – удалено 216.73.216.10 | ||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| - | ====== DMX 512 Тестер сигнала своими руками на контроллере Arduino ====== | ||
| - | По роду деятельности, | ||
| - | {{ : | ||
| - | |||
| - | |||
| - | ---- | ||
| - | |||
| - | Стоят копейки у китайцев. Я очень люблю эти декодеры. С их помощью легко можно масштабировать систему от трех до 512 каналов. | ||
| - | |||
| - | Для меня самый удобный вариант всем известная плата **Arduino**. Очень удобно держать в ящике десяток-другой клонов **Arduino Pro Mini** и по мере надобности использовать их в подобных проектах. Люблю его за то что на его базе можно быстро собрать достаточно компактное устройство и стоят эти клоны в Китае, примерно столько же, как и голая **Atmaga328**. | ||
| - | |||
| - | И вот при разработке эффектов для очередного контроллера на 16 каналов, | ||
| - | |||
| - | Изначально я решил, что нужен прибор, | ||
| - | |||
| - | Отображение уровней каналов в режиме реального времени в относительных единицах; | ||
| - | Отображение общего количества каналов, | ||
| - | Отображение уровня одного выбранного канала в абсолютных единицах (**0-255**); | ||
| - | |||
| - | Выводить уровни каналов, | ||
| - | |||
| - | Ну раз задача поставлена, | ||
| - | |||
| - | Данные мы будем получать через простейший переходник __TTL to RS-485__, основанный на **MAX485**. | ||
| - | " | ||
| - | {{ : | ||
| - | |||
| - | Ну и выводить информацию будем на **LCD-дисплей 16х2** (// | ||
| - | |||
| - | Сказано — сделано. | ||
| - | {{ : | ||
| - | <code **c** dmxtester.uno> | ||
| - | #include < | ||
| - | #include < | ||
| - | #include < | ||
| - | |||
| - | #define DMX_SLAVE_CHANNELS | ||
| - | |||
| - | #define LCD_W | ||
| - | |||
| - | LiquidCrystal lcd(12, 11, 5, 4, 3, 2); | ||
| - | |||
| - | DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS ); | ||
| - | |||
| - | unsigned long | ||
| - | unsigned long | ||
| - | |||
| - | byte qa[8] = | ||
| - | { | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B11111 | ||
| - | }; | ||
| - | byte ws[8] = | ||
| - | { | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B11111, | ||
| - | B11111 | ||
| - | }; | ||
| - | byte ed[8] = | ||
| - | { | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111 | ||
| - | }; | ||
| - | byte rf[8] = | ||
| - | { | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111 | ||
| - | }; | ||
| - | byte tg[8] = | ||
| - | { | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111 | ||
| - | }; | ||
| - | byte yh[8] = | ||
| - | { | ||
| - | B00000, | ||
| - | B00000, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111 | ||
| - | }; | ||
| - | byte uj[8] = | ||
| - | { | ||
| - | B00000, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111 | ||
| - | }; | ||
| - | byte ik[8] = | ||
| - | { | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111, | ||
| - | B11111 | ||
| - | }; | ||
| - | |||
| - | byte outAr [LCD_W]; // Значения каналов, | ||
| - | unsigned short chRx; // количество принятых каналов | ||
| - | |||
| - | #define KEY_BUTTON_1_PIN A2 //пин к которому подключена клавиатура | ||
| - | unsigned int KeyButton1Value=0; | ||
| - | unsigned long KeyButton1TimePress=0; | ||
| - | unsigned long KeyButton1Latency=100; | ||
| - | unsigned int KeyButton1WasChecked=0; | ||
| - | unsigned long KeyButton1RepeatLatency=1500; | ||
| - | unsigned long KeyButton1RepeatTimePress=0; | ||
| - | unsigned long KeyButton1TimeFromPress=0; | ||
| - | unsigned long KeyBoardTime1=0; | ||
| - | unsigned long KeyBoardTime2=0; | ||
| - | unsigned long KeyBoardTimeInterval=25; | ||
| - | |||
| - | byte start = 0; // +1 номер канала, | ||
| - | |||
| - | void setup() { | ||
| - | lcd.begin(LCD_W, | ||
| - | dmx_slave.enable (); | ||
| - | dmx_slave.setStartAddress (1); | ||
| - | dmx_slave.onReceiveComplete ( OnFrameReceiveComplete ); | ||
| - | |||
| - | lcd.createChar(0, | ||
| - | lcd.createChar(1, | ||
| - | lcd.createChar(2, | ||
| - | lcd.createChar(3, | ||
| - | lcd.createChar(4, | ||
| - | lcd.createChar(5, | ||
| - | lcd.createChar(6, | ||
| - | lcd.createChar(7, | ||
| - | | ||
| - | pinMode (KEY_BUTTON_1_PIN, | ||
| - | pinMode (10, OUTPUT); | ||
| - | pinMode (9, OUTPUT); | ||
| - | digitalWrite(9, | ||
| - | } | ||
| - | |||
| - | void loop() | ||
| - | { | ||
| - | // | ||
| - | KeyBoardTime2=millis(); | ||
| - | if ((KeyBoardTime2-KeyBoardTime1)> | ||
| - | { | ||
| - | KeyBoardTime1=KeyBoardTime2; | ||
| - | KeyBoardCalculate(); | ||
| - | } | ||
| - | | ||
| - | if (lastFrameReceivedTime > lastFrameTranceivedTime){ //если получен новый пакет | ||
| - | printLevel (outAr); | ||
| - | lastFrameTranceivedTime = millis(); | ||
| - | } | ||
| - | else if ((lastFrameReceivedTime==0 && lastFrameTranceivedTime ==0)||(KeyBoardTime2-lastFrameReceivedTime> | ||
| - | lcd.clear(); | ||
| - | delay (500); | ||
| - | lcd.setCursor(0, | ||
| - | lcd.print(" | ||
| - | delay (500); | ||
| - | } | ||
| - | | ||
| - | } | ||
| - | |||
| - | void OnFrameReceiveComplete (unsigned short channelsReceived) // функция, | ||
| - | { | ||
| - | chRx = channelsReceived; | ||
| - | for (byte i=0; i<LCD_W; i++){ // цикл запиди уровней каналов в массив для отображения на дисплее | ||
| - | outAr[i]=dmx_slave.getChannelValue (i+start+1); | ||
| - | } | ||
| - | lastFrameReceivedTime = millis(); | ||
| - | } | ||
| - | |||
| - | void printLevel(byte lv[LCD_W]) | ||
| - | { | ||
| - | byte dispLv[LCD_W]; | ||
| - | for (byte i=0; i<LCD_W; i++){ | ||
| - | switch (lv[i]/32) { //// добавить регулировку чувствительности | ||
| - | case 0: | ||
| - | dispLv[i]=0; | ||
| - | break; | ||
| - | case 1: | ||
| - | dispLv[i]=1; | ||
| - | break; | ||
| - | case 2: | ||
| - | dispLv[i]=2; | ||
| - | break; | ||
| - | case 3: | ||
| - | dispLv[i]=3; | ||
| - | break; | ||
| - | case 4: | ||
| - | dispLv[i]=4; | ||
| - | break; | ||
| - | case 5: | ||
| - | dispLv[i]=5; | ||
| - | break; | ||
| - | case 6: | ||
| - | dispLv[i]=6; | ||
| - | break; | ||
| - | case 7: | ||
| - | dispLv[i]=7; | ||
| - | break; | ||
| - | } | ||
| - | } | ||
| - | lcd.setCursor(0, | ||
| - | for (byte i=0; i<LCD_W; i++){ // | ||
| - | lcd.write(dispLv[i]); | ||
| - | } // | ||
| - | lcd.setCursor(0, | ||
| - | lcd.print(" | ||
| - | if ((start+1)< | ||
| - | lcd.print((start+1)); | ||
| - | lcd.print(" | ||
| - | } else if ((start+1)< | ||
| - | | ||
| - | | ||
| - | } else lcd.print((start+1)); | ||
| - | lcd.setCursor(5, | ||
| - | lcd.print(" | ||
| - | if (lv[0]< | ||
| - | lcd.print(" | ||
| - | lcd.print(lv[0]); | ||
| - | } else if (lv[0]< | ||
| - | | ||
| - | | ||
| - | } else lcd.print(lv[0]); | ||
| - | lcd.setCursor(11, | ||
| - | lcd.print(" | ||
| - | lcd.print(chRx); | ||
| - | } | ||
| - | |||
| - | |||
| - | void ButtonPress() // Распознаем, | ||
| - | { | ||
| - | if ((KeyButton1Value> | ||
| - | { | ||
| - | if((start) < (chRx-LCD_W) && chRx> | ||
| - | } | ||
| - | if ((KeyButton1Value> | ||
| - | { | ||
| - | | ||
| - | } | ||
| - | } | ||
| - | |||
| - | void KeyBoardCalculate() | ||
| - | { | ||
| - | // | ||
| - | KeyButton1Value=analogRead(KEY_BUTTON_1_PIN); | ||
| - | //если сигнал с кнопки нулевой то обнуляем метку обработки нажатия | ||
| - | if ((KeyButton1Value< | ||
| - | { | ||
| - | // | ||
| - | KeyButton1TimePress=millis(); | ||
| - | KeyButton1WasChecked=0; | ||
| - | KeyButton1RepeatTimePress=0; | ||
| - | } | ||
| - | | ||
| - | KeyButton1TimeFromPress=millis()-KeyButton1TimePress; | ||
| - | // | ||
| - | if ((KeyButton1Value> | ||
| - | { | ||
| - | // | ||
| - | if ( ((KeyButton1TimeFromPress)> | ||
| - | { | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | } | ||
| - | | ||
| - | // | ||
| - | if ( ((KeyButton1TimeFromPress)> | ||
| - | { | ||
| - | | ||
| - | | ||
| - | | ||
| - | } | ||
| - | } | ||
| - | | ||
| - | } | ||
| - | </ | ||
| - | И как ни странно, | ||
| - | |||
| - | В момент запуска микроконтроллера в первом отображаемом кадре вся информация верна, при отображении последующих кадров, | ||
| - | |||
| - | Все остальное работает без проблем — прокрутка листает. Может кто-нибудь свежим взглядом увидит… Да, кстати, | ||
| - | |||
| - | Думал над этой проблемой неделю, | ||