Перейти к содержанию

Dmx-512 Визуализация Уровней Каналов


Рекомендуемые сообщения

Собираю устройство, которое подключается к DMX-512 контроллеру, получает от него данные и отображает уровни каналов на дисплее. Использован двухстрочный символьный дисплей, подключенный через SPI-драйвер.

В первой строке отображаются уровни каналов в виде столбиков, во второй - первый отображаемый на дисплее канал и общее количество каналов, на которые контроллер выдает данные.

Есть возможность листать диапазон отображаемых каналов вдумя кнопками.

Все собрал, прошил, и даже работает, но есть один косяк. В момент запуска микроконтроллера в первом отображаемом кадре вся информация верна, при отображении последующих кадров, arduino кудато-съедает несколько каналов.

Т.е. если контроллер выдает 60 каналов, то в момент включения или перезагрузки arduino, отображается общее количество каналов 60 и первый канал на дисплее является действительно первым. Но сразу после смены кадров, отображается количество кадров 57, а первым отображается, в реальности пятый.

Пробовал еще загонять сигнал на 30 каналов - тоже самое, только сначала все правильно, а потом показывает общее количество каналов 29, а на месте первого показывает вообще непонятно что.

Все остальное работает без проблем - прокрутка листает.

Да, кстати, если выдавать сигнал на 16 каналов, то отображается все коректно.

У же целый день смотрю в код и не пойму в чем косяк. Может кто-нибудь свежим взглядом увидит...

Вот код:

#include <Conceptinetics.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define DMX_SLAVE_CHANNELS   100 //ЕСЛИ БУДУТ ПРОБЛЕМЫ ТО УМЕНЬШИТЬ 

LiquidCrystal_I2C lcd(0x27,16,2);

DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

unsigned long       lastFrameReceivedTime;
unsigned long       lastFrameTranceivedTime;

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
};

int lvAr[DMX_SLAVE_CHANNELS]; // Входящие значения DMX-512 каналов
int outAr [16]; // Значения каналов, выводимые на дисплей
int chRx; // количество принятых каналов /////////////////////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#define KEY_BUTTON_1_PIN A2  //пин к которому подключена панель управления
int KeyButton1Value=0;  //значение с панели управления
long KeyButton1TimePress=0;  //последнее время когда на панели не было нажатых кнопок
long KeyButton1Latency=100000;  //задержка перед считыванием состояния панели управления после нажатия
int KeyButton1WasChecked=0;  //метка означающая что нажатие кнопки на панели было обработано
long KeyButton1RepeatLatency=1500000;  //время после которого удерживание кнопки начинает засчитываться как многократные быстрые нажатия
long KeyButton1RepeatTimePress=0;  //вспомогательная переменная для обработки повторных нажатий
long KeyButton1TimeFromPress=0;  //переменная для хранения времени между временем когда не было зажатых кнопок и временем проверки
long KeyBoardTime1=0;                //
long KeyBoardTime2=0;                // Переменные для обработки времени для обработки событий клавиатуры
long KeyBoardTimeInterval=25000;     //

int start = 0;  // +1 номер канала, который выводится на экран первым

void setup() {             
 dmx_slave.enable ();  
 dmx_slave.setStartAddress (1);
 dmx_slave.onReceiveComplete ( OnFrameReceiveComplete );
 Wire.begin();
 lcd.init();
 lcd.backlight();
 lcd.home();

 lcd.createChar(0,qa);
 lcd.createChar(1,ws);
 lcd.createChar(2,ed);
 lcd.createChar(3,rf);
 lcd.createChar(4,tg);
 lcd.createChar(5,yh);
 lcd.createChar(6,uj);
 lcd.createChar(7,ik);

 lcd.clear(); 
 pinMode (KEY_BUTTON_1_PIN, INPUT);
 pinMode (10, OUTPUT);
 pinMode (11, OUTPUT);
 pinMode (12, OUTPUT);
 pinMode (13, OUTPUT);
}

void loop() 
{
 digitalWrite(10, 1); // 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
 //проверка таймера для обработки нажатий клавиатуры
 KeyBoardTime2=micros();
 if ((KeyBoardTime2-KeyBoardTime1)>KeyBoardTimeInterval) 
   {
     KeyBoardTime1=KeyBoardTime2;
     KeyBoardCalculate();
   }
 digitalWrite(10, 0); // 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10


 digitalWrite(13, 1); // 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10

 if (lastFrameReceivedTime > lastFrameTranceivedTime){
   printLevel (outAr);  // Вывод значений на дисплей
   lastFrameTranceivedTime = millis();
 }
 digitalWrite(13, 0); // 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
}

void OnFrameReceiveComplete (unsigned short channelsReceived)
{
 digitalWrite(11, 1);  // 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
 chRx = int(channelsReceived);
 for (int i=0; i<chRx; i++){
   lvAr[i] = dmx_slave.getChannelValue (i+1);
 }

 for (int i=0; i<16; i++){
     outAr[i]=lvAr[i+start];
 }
 lastFrameReceivedTime = millis();
 digitalWrite(11, 0);  // 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
}

void printLevel(int lv[16])
{
 digitalWrite(12, 1); // 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 
 byte dispLv[16];
 for (int i=0; i<16; 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;
   }
 }
 digitalWrite(12, 0);  // 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 


 digitalWrite(12, 1);  // 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 
 lcd.setCursor(0, 0);
 for (int i=0; i<16; i++){
   lcd.write(dispLv[i]);
 }
 lcd.setCursor(0, 1);       //
 lcd.print("^");            // Вывод общего количества 
 lcd.print("     Total:");  // принятых каналов
 lcd.print(chRx);           //
 lcd.setCursor(1, 1);       // и номер первого канала на дисплее
 lcd.print(start+1);        //
 digitalWrite(12, 0);  // 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 
}

void UpPress()
{
 if((start) < (chRx-15)) start++;   
}
void DownPress()
{
 if(start > 0) start--;
}

void ButtonPress()
{
 if ((KeyButton1Value>150) and (KeyButton1Value<300))
   {
     UpPress(); 
   }
 if ((KeyButton1Value>350) and (KeyButton1Value<650))
   {
      DownPress();
   }
}

void KeyBoardCalculate()
{
 //Часть отработки нажатия клавиши
 KeyButton1Value=analogRead(KEY_BUTTON_1_PIN); 
 //если сигнал с кнопки нулевой то обнуляем метку обработки нажатия
 if ((KeyButton1Value<=50) or (KeyButton1Value>=1000))
   {
     //Сохраняем время последнего сигнала без нажатой кнопки
     KeyButton1TimePress=micros(); 
     KeyButton1WasChecked=0;
     KeyButton1RepeatTimePress=0;
   } 

 KeyButton1TimeFromPress=micros()-KeyButton1TimePress;
 //исключаем шумы
 if ((KeyButton1Value>50) and (KeyButton1Value<1000))
   {
     //отработка первого нажатия
     if ( ((KeyButton1TimeFromPress)>KeyButton1Latency) and (KeyButton1WasChecked==0))
       {
          KeyButton1Value=analogRead(KEY_BUTTON_1_PIN);  
          ButtonPress();
          KeyButton1WasChecked=1;
          KeyButton1RepeatTimePress=0;
       }

     //отработка повторных нажатий  
     if ( ((KeyButton1TimeFromPress)>(KeyButton1RepeatLatency+KeyButton1RepeatTimePress)) and (KeyButton1WasChecked==1))
       {
          KeyButton1Value=analogRead(KEY_BUTTON_1_PIN);  
          ButtonPress();
          KeyButton1RepeatTimePress=KeyButton1RepeatTimePress+100000;
       }
   }

}

Изменено пользователем a_zakharov
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...