Статическая индикация на примере светодиодного модуля индикации

Конструкции любых блоков питания, источников тока для любых назначений. Микроконтроллеры и все, что с ними связано

Модераторы: Алаев Ян, poty

Аватара пользователя
Алаев Ян
Основатель Форума
Сообщения: 2285
Зарегистрирован: 19 мар 2014, 12:05
Откуда: Саратов
Благодарил (а): 1 раз

Статическая индикация на примере светодиодного модуля индикации

#1

Сообщение Алаев Ян » 06 фев 2017, 13:17

Универсальный светодиодный модуль индикации

Подробная информация по модулю индикации представлена здесь.

Содержание:
Спойлер
Показать
1. Скетч для работы с модулем индикации на примере Arduino /viewtopic.php?f=79&t=317&p=13796#p13796
Стремление к совершенству рождает шедевры!

Аватара пользователя
Алаев Ян
Основатель Форума
Сообщения: 2285
Зарегистрирован: 19 мар 2014, 12:05
Откуда: Саратов
Благодарил (а): 1 раз

Скетч для работы с модулем индикации на примере Arduino

#2

Сообщение Алаев Ян » 28 июл 2017, 11:44

Если для статической индикации вы используете сдвиговые регистры 74HC164 (как в нашем модуле индикации), то можно использовать скетч, приведенный ниже:

Код: Выделить всё

//Прошивка для вывода измеренного значения на универсальный
//светодиодный индикатор "Алаев и Ко" Лаб. http://www.alaev.org/

int latchPin = 10;//сигнал Ready
int clockPin = 12;//сигнал Clock
int dataPin = 11;//cигнал Data

int x1;
int x2;
int x3;
int x4;

int pot;
     
float temp = -0.258;//величина, выводимая на индикатор

float temp_minus;//буферная переменная для вычисления отрицательных чисел

const byte digit[] =      //seven segment digits in bits
{  
B00111111, //0 
B00000110, //1  
B01011011, //2  
B01001111, //3  
B01100110, //4  
B01101101, //5  
B01111101, //6  
B00000111, //7  
B01111111, //8  
B01101111  //9
};

//B01110110  //H
//B00010000  //i
//B00111000  //L
//B01011100  //o

void setup(){

  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  pinMode(clockPin, OUTPUT);
}

void loop(){
  
  if(temp >= 0.0){//если число положительное
    if(temp > 9999.0){//если число выходит за верхний предел
      digitalWrite(latchPin, LOW);
     
      shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-
      shiftOut(dataPin, clockPin, MSBFIRST, B00010000);//i
      shiftOut(dataPin, clockPin, MSBFIRST, B01110110);//H
      shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-

      digitalWrite(latchPin, HIGH);      
    }
      else{
        if(temp >= 1000.0){
          pot = int(temp);
      
          x4 = pot/1000;
          x3 = (pot/100)%10;
          x2 = (pot/10)%10;
          x1 = pot%10; 
     
          digitalWrite(latchPin, LOW);
     
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x4]);

          digitalWrite(latchPin, HIGH);
        } 
        else {
          if(temp >= 100.0){
            pot = int((temp + 0.05) * 10.0);
      
            x4 = pot/1000;
            x3 = (pot/100)%10;
            x2 = (pot/10)%10;
            x1 = pot%10;
       
            digitalWrite(latchPin, LOW);
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]|B10000000);//ставим точку
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x4]);

            digitalWrite(latchPin, HIGH);       
          } 
          else{
            if(temp >= 10.0){
              pot = int((temp + 0.005) * 100.0);
      
              x4 = pot/1000;
              x3 = (pot/100)%10;
              x2 = (pot/10)%10;
              x1 = pot%10;
       
              digitalWrite(latchPin, LOW);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]|B10000000);//ставим точку
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x4]);

              digitalWrite(latchPin, HIGH);  
            }
            else{
              if(temp >= 0.0){
                pot = int((temp + 0.0005) * 1000.0);
      
                x4 = pot/1000;
                x3 = (pot/100)%10;
                x2 = (pot/10)%10;
                x1 = pot%10;
       
                digitalWrite(latchPin, LOW);
                shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
                shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
                shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
                shiftOut(dataPin, clockPin, MSBFIRST, digit[x4]|B10000000);//ставим точку

                digitalWrite(latchPin, HIGH);  
              }                                 
            }  
          }
        }
    }//конец чисел в диапазоне
  }//конец положительных чисел
  else {//если число отрицательное
    if(temp < -999.0){//если число выходит за нижний предел
      digitalWrite(latchPin, LOW);
     
      shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-
      shiftOut(dataPin, clockPin, MSBFIRST, B01011100);//o
      shiftOut(dataPin, clockPin, MSBFIRST, B00111000);//L
      shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-

      digitalWrite(latchPin, HIGH);
    }
      else{
        if(temp <= -100.0){
          temp_minus = abs(temp);
          pot = int(temp_minus + 0.05);
      
          x4 = pot/1000;
          x3 = (pot/100)%10;
          x2 = (pot/10)%10;
          x1 = pot%10; 
     
          digitalWrite(latchPin, LOW);
     
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
          shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-

          digitalWrite(latchPin, HIGH);
        } 
        else {
          if(temp <= -10.0){
            temp_minus = abs(temp);
            pot = int((temp_minus + 0.005) * 10.0);
      
            x4 = pot/1000;
            x3 = (pot/100)%10;
            x2 = (pot/10)%10;
            x1 = pot%10;
       
            digitalWrite(latchPin, LOW);
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]|B10000000);//ставим точку
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
            shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-

            digitalWrite(latchPin, HIGH);       
          } 
          else{
            if(temp < 0.0){
              temp_minus = abs(temp);
              pot = int((temp_minus + 0.0005) * 100.0);
      
              x4 = pot/1000;
              x3 = (pot/100)%10;
              x2 = (pot/10)%10;
              x1 = pot%10;
       
              digitalWrite(latchPin, LOW);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]|B10000000);//ставим точку
              shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-

              digitalWrite(latchPin, HIGH);  
            }
          }
        }
    }//конец чисел в диапазоне  
  }//конец отрицательных чисел

  delay(1000);
  
}//конец цикла
Вышеприведенный код работает с числовыми значениями в диапазоне -999...9999 с автоматической установкой разделительной точки в положение максимальной разрядности измеренного значения. В случае, если измеренное значение выходит за допустимый диапазон индикации, на индикаторе появляется соответствующее сообщение об ошибке. Приведенный код является шаблоном, который вы можете использовать для создания собственных проектов.

[Расширение pdsprj было запрещено, вложение больше недоступно.]

74HC164.jpg
Симуляция работы 74HC164 в Proteus
Если для статической индикации вы используете сдвиговые регистры 74HC595 (с защелками), то можно использовать скетч, приведенный ниже:

Код: Выделить всё

//Прошивка для вывода измеренного значения на универсальный
//светодиодный индикатор "Алаев и Ко" Лаб. http://www.alaev.org/

int latchPin = 10;//контакт ST_CP на сдвиговом регистре 74HC595
int clockPin = 12;//контакт SH_CP на сдвиговом регистре 74HC595
int dataPin = 11;//контакт DS на сдвиговом регистре 74HC595

int x1;
int x2;
int x3;
int x4;

int pot;
     
float temp = 69.96;//величина, выводимая на индикатор

float temp_minus;//буферная переменная для вычисления отрицательных чисел

const byte digit[] =      //seven segment digits in bits
{  
B00111111, //0 
B00000110, //1  
B01011011, //2  
B01001111, //3  
B01100110, //4  
B01101101, //5  
B01111101, //6  
B00000111, //7  
B01111111, //8  
B01101111  //9
};

//B01110110  //H
//B00010000  //i
//B00111000  //L
//B01011100  //o

void setup(){

  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  pinMode(clockPin, OUTPUT);
}

void loop(){
  
  if(temp >= 0.0){//если число положительное
    if(temp > 9999.0){//если число выходит за верхний предел
      digitalWrite(latchPin, LOW);
     
      shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-
      shiftOut(dataPin, clockPin, MSBFIRST, B00010000);//i
      shiftOut(dataPin, clockPin, MSBFIRST, B01110110);//H
      shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-

      digitalWrite(latchPin, HIGH);
    }
      else{
        if(temp >= 1000.0){
          pot = int(temp);
      
          x4 = pot/1000;
          x3 = (pot/100)%10;
          x2 = (pot/10)%10;
          x1 = pot%10; 
     
          digitalWrite(latchPin, LOW);
     
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x4]);

          digitalWrite(latchPin, HIGH);
        } 
        else {
          if(temp >= 100.0){
            pot = int((temp + 0.05) * 10.0);
      
            x4 = pot/1000;
            x3 = (pot/100)%10;
            x2 = (pot/10)%10;
            x1 = pot%10;
       
            digitalWrite(latchPin, LOW);
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]|B10000000);//ставим точку
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x4]);

            digitalWrite(latchPin, HIGH);       
          } 
          else{
            if(temp >= 10.0){
              pot = int((temp + 0.005) * 100.0);
      
              x4 = pot/1000;
              x3 = (pot/100)%10;
              x2 = (pot/10)%10;
              x1 = pot%10;
       
              digitalWrite(latchPin, LOW);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]|B10000000);//ставим точку
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x4]);

              digitalWrite(latchPin, HIGH);  
            }
            else{
              if(temp >= 0.0){
                pot = int((temp + 0.0005) * 1000.0);
      
                x4 = pot/1000;
                x3 = (pot/100)%10;
                x2 = (pot/10)%10;
                x1 = pot%10;
       
                digitalWrite(latchPin, LOW);
                shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
                shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
                shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
                shiftOut(dataPin, clockPin, MSBFIRST, digit[x4]|B10000000);//ставим точку

                digitalWrite(latchPin, HIGH);  
              }                                 
            }  
          }
        }
    }//конец чисел в диапазоне
  }//конец положительных чисел
  else {//если число отрицательное
    if(temp < -999.0){//если число выходит за нижний предел
      digitalWrite(latchPin, LOW);
     
      shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-
      shiftOut(dataPin, clockPin, MSBFIRST, B01011100);//o
      shiftOut(dataPin, clockPin, MSBFIRST, B00111000);//L
      shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-

      digitalWrite(latchPin, HIGH);
    }
      else{
        if(temp <= -100.0){
          temp_minus = abs(temp);
          pot = int(temp_minus + 0.05);
      
          x4 = pot/1000;
          x3 = (pot/100)%10;
          x2 = (pot/10)%10;
          x1 = pot%10; 
     
          digitalWrite(latchPin, LOW);
     
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
          shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
          shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-

          digitalWrite(latchPin, HIGH);
        } 
        else {
          if(temp <= -10.0){
            temp_minus = abs(temp);
            pot = int((temp_minus + 0.005) * 10.0);
      
            x4 = pot/1000;
            x3 = (pot/100)%10;
            x2 = (pot/10)%10;
            x1 = pot%10;
       
            digitalWrite(latchPin, LOW);
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]|B10000000);//ставим точку
            shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
            shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-

            digitalWrite(latchPin, HIGH);       
          } 
          else{
            if(temp < 0.0){
              temp_minus = abs(temp);
              pot = int((temp_minus + 0.0005) * 100.0);
      
              x4 = pot/1000;
              x3 = (pot/100)%10;
              x2 = (pot/10)%10;
              x1 = pot%10;
       
              digitalWrite(latchPin, LOW);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
              shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]|B10000000);//ставим точку
              shiftOut(dataPin, clockPin, MSBFIRST, B01000000);//-

              digitalWrite(latchPin, HIGH);  
            }
          }
        }
    }//конец чисел в диапазоне  
  }//конец отрицательных чисел  
}//конец цикла
На самом деле, оба приведенных скетча практически одинаковые и отличаются лишь временными задержками, которые необходимы для правильной симуляции кода в программе Proteus. При использовании скетчей в качестве шаблонов подойдет любой из вышеприведенных примеров.

[Расширение pdsprj было запрещено, вложение больше недоступно.]

74HC595.jpg
Симуляция работы 74HC595 в Proteus
В приведенной для 74HC595 схеме моделирования следует учитывать, что в ней отсутствуют ограничительные резисторы для светодиодов, которые обязательно должны быть установлены в реальной схеме. Для моделирования это не принципиально.
Стремление к совершенству рождает шедевры!

Аватара пользователя
seurf
Опытный
Опытный
Сообщения: 568
Зарегистрирован: 12 май 2016, 19:54
Откуда: Волгоград

#3

Сообщение seurf » 16 дек 2017, 20:56

У меня в настоящее время нет модулей индикации напряжения. Лежат в тумбочке маленькие Китайские панельки ( все в внутри) на небольшие напряжения. Покупал для контроля накалов ламп. Так и не поставил. Хотя в планах стоит.
А сейчас озаботился индикацией анодного напряжения. А это от 300 до 450 В? Но не увидел в описании технических характеристик. Может не рассмотрел? Прошу меня тогда поправить.
Применимо?

[upd=1513447254][/upd]
/viewtopic.php?f=16&t=280&start=60
75 пост. Видны мои Китайские индикаторы напряжения.

Аватара пользователя
Алаев Ян
Основатель Форума
Сообщения: 2285
Зарегистрирован: 19 мар 2014, 12:05
Откуда: Саратов
Благодарил (а): 1 раз

#4

Сообщение Алаев Ян » 17 дек 2017, 10:13

Добрый день, Александр!
Я поясню главную идею этой темы. Сейчас в нашем мире существует тенденция - сделать дешевле, проще, легче и так далее, но не всегда это бывает лучше, к сожалению. Применительно к светодиодным сегментным индикаторам - существует два способа вывода информации на них:
1. Динамическая индикация.
2. Статическая индикация.
Все китайские модули индикации, все вольтметры, амперметры и прочие показометры современного производства используют динамическую индикацию, у нее есть свои преимущества, например, меньшее число выводов, проще аппаратная обвязка (финансовая экономия на лицо, особенно при массовом производстве) и на ней очень удобно делать приборы, где наличие разных помех не имеет значения, например, часы, термометры, различные датчики тока и напряжения, когда все равно на ту цепь, где мы измеряем ток или напряжение. Но у них есть и недостатки, в нашем деле очень существенные. Главный недостаток - для вывода информации на сегментный индикатор мы должны в цикле быстро быстро перебирать сегменты между собой, при этом индикатор мерцает, как мерцает телевизор со своей разверткой кадров, просто мы этого не видим, так как происходит это достаточно быстро, но за счет этого подобный прибор постоянно дергает свой БП импульсным током и генерирует массу цифровых помех. Остановить этот процесс нельзя, в этом случае на экране индикатора ничего выведено не будет. Второй недостаток динамической индикации - контроллер, который этим управляет, постоянно кружится в этом цикле и очень часто бывает непросто выполнять другие действия, чтобы это не сказалось на качестве как индикации, так и выполнения других задач, поэтому очень часто контроллер, который занимается динамической индикацией ничего другого не делает, кроме своей индикации, все остальное делает другой контроллер. В совокупности, все это делает динамическую индикацию неприменимой в составе качественной звуковоспроизводящей аппаратуры.
Теперь по поводу статической индикации. Из недостатков у нее - много выводов у сегментных индикаторов, так как управление идет по каждому из них без каких либо переборов общих катодов или анодов. Больше аппаратной обвязки, тут речь идет о сдвиговых регистрах или прочих микросхемах управления. Но главное, что есть просто потрясающие достоинства. Из них - можно вывести информацию на индикатор и полностью выключить работу контроллера, при этом все будет работать в статическом режиме и не генерировать никаких помех. Вывод информации на индикаторы так же не сопровождается высокочастотными помехами, так как загружаются и включаются сразу все регистры с низкочастотным периодом обновления информации, помехи коммутации которых достаточно легко подавить. Поэтому статическая индикация, которая всеми забыта и почти никем не используется, которая представлена здесь, почти не имеет себе равных в плане "чистоты" применения для звуковоспроизводящих устройств.

seurf писал(а):Применимо?
на основе этих модулей можно сделать любой "показометр", это в планах, но пока не реализовано для продажи, только опытные образцы.
Стремление к совершенству рождает шедевры!

Аватара пользователя
poty
Профи
Профи
Сообщения: 3270
Зарегистрирован: 24 мар 2014, 10:00
Откуда: Россия, Москва
Поблагодарили: 1 раз

#5

Сообщение poty » 18 дек 2017, 17:05

Жалко времени нет... Надо бы создать матричный статический LED-индикатор. Допустим, RGB модули есть в установочном размере 2,3х1,5мм, а одноцветные - так ещё меньше. Другой вопрос - управление ими будет большой головной болью: даже если брать, допустим, 15х60мм, то это (для трёхцветки с необходимыми зазорами) 180 ячеек (540 управляющих сигналов). Надо применять какие-то многоножечные контроллеры, так как 68 сдвиговых регистров озвереешь на плате размещать.
Владислав

Аватара пользователя
seurf
Опытный
Опытный
Сообщения: 568
Зарегистрирован: 12 май 2016, 19:54
Откуда: Волгоград

#6

Сообщение seurf » 22 дек 2017, 10:11

В совокупности, все это делает динамическую индикацию неприменимой в составе качественной звуковоспроизводящей аппаратуры.
Вот ключевое определение.
Я нашёл на Ali под 600 В индикатор, но у него земля через прибор проходит, для измерения тока. Поэтому я этот вопрос отодвинул.

Аватара пользователя
poty
Профи
Профи
Сообщения: 3270
Зарегистрирован: 24 мар 2014, 10:00
Откуда: Россия, Москва
Поблагодарили: 1 раз

#7

Сообщение poty » 22 дек 2017, 10:18

seurf писал(а):Я нашёл на Ali под 600 В индикатор, но у него земля через прибор проходит, для измерения тока.
Мне кажется, в этом нет ничего страшного. Достаточно перенести фильтрующие резисторы на земляной провод и системную землю организовать после прибора.
Владислав

Аватара пользователя
seurf
Опытный
Опытный
Сообщения: 568
Зарегистрирован: 12 май 2016, 19:54
Откуда: Волгоград

#8

Сообщение seurf » 01 янв 2018, 22:54

Самый бюджетный вариант: Смотри, что нашлось на AliExpress
http://s.aliexpress.com/BJryQNJV
Конечно сам прибор мусор. Пара уже валяются, показывают, что захочется. С новья ещё ничего были.

[upd=1514836964][/upd]
Зато ставишь предел на 1000В и не паришься.
Сам корпус можно спрятать и оставить только экран и запитать его не от батареек, а от внутреннего трансформатора накала. Потребляет совсем ничего. Фантазирую.

[upd=1514837205][/upd]
А вот собственно 600 вольтовый прибор. Смотри, что нашлось на AliExpress
http://s.aliexpress.com/maMzuyMb
Измеряет одномоментно и ток и напряжение.
Я так понимаю, если пренебречь измерением тока, можно и без разрыва земли?
image.png
image.png
image.png

Аватара пользователя
poty
Профи
Профи
Сообщения: 3270
Зарегистрирован: 24 мар 2014, 10:00
Откуда: Россия, Москва
Поблагодарили: 1 раз

#9

Сообщение poty » 02 янв 2018, 00:49

seurf писал(а):если пренебречь измерением тока, можно и без разрыва земли?
Да-да.
Владислав

Ответить