работа с семи сегментними индикаторами

sp1run33
Offline
Зарегистрирован: 23.07.2019

Доброго времени суток хотел собрать простинький проект . повторить чужое творение немного подругому подключил сигменти к плате и незнаю как подкоректировать код в данном случае чтоб все работало 

подскажите как подкоректировать чтоб работало и где можно узнать больше о етих индикаторах и как с ними работать 

/*


 // Пины подключения индикаторов
 ANODES:
 D0 - a
 D1 - b
 D2 - c
 D3 - d
 D4 - e
 D5 - f
 D6 - g
 D7 - dp (digital point)

 D0 - dp (digital point) мое реально подключение
 D1 - a
 D2 - b
 D3 - g
 D4 - c
 D5 - f
 D6 - d
 D7 - e
 
      a
   ********
   *      *
 f *      * b
   *  g   *
   ********
   *      *
 e *      * c
   *  d   *
   ******** # dp
 
 CATHODES:
 D8 - cathode 3
 D9 - cathode 2
 D10 - cathode 1
 */

// -------------------------------------------------- не изменять, это для Сегментов -----------------------------------------------
byte const digits[] = {
   B00001001,B11101011,B00110001,B10100001,B11000011,B10000101,B00000101,B11101001,B00000001,B10000001};



/* byte const digits[] = {
  B00001001,B11101011,B00110001,B10100001,B11000011,B10000101,B00000101,B11101001,B00000001,B10000001};
*/
  




  
/*
  byte  digits[] = {
  B00001001,B11101011,B00110001,B10100001,B11000011,B10000101,B00000101,B11101001,B00000001,B10000001};

  
  byte const digits[] = {
  B00111111,B00000110,B01011011,B01001111,B01100110,B01101101,B01111101,B00000111,B01111111,B01101111};*/

int digit_common_pins[]={16,15,12};  // пины для разрядов сегментов(при изменении убедитесь что Ваш порт не используется)
int refresh_delay = 5;
int count_delay = 300; // COUNTING SECONDS IF count_delay = 1000
long actual_count_delay = 0;
long actual_refresh_delay = 0;
int increment = 0;   //Стартовое значение на сегментах
int max_digits =3;  //  Кол-во знаков
int current_digit=max_digits-1;
int increment_max = pow(10,max_digits);
// -------------------------------------------------- не изменять, это для Сегментов -----------------------------------------------


//--------------------- переменные паяльника -----------------------------
int knup = 3; //Пин кнопки вверх in(красный светодиод)
int kndn = 2; //Пин кнопки вниз in(синий светодиод)

int nagr = 11; // пин вывода нагревательного элемента(через транзистор)
int tin = 0; // Пин Датчика температуры IN Analog через LM358N
int tdat =  0; //Переменная Датчика температура
int ustt =  210; // Выставленная температура по умолчанию (+ увеличение и уменьшение при нажатии кнопок)
int mintemp = 140; // Минимальная температура
int maxtemp = 310; // Максимальная температура 
int nshim = 0; // Начальное значение шим для нагрузки 

void setup(){
  Serial.begin(9600);
  pinMode(nagr,OUTPUT);     // Порт нагрузки (паяльника) настраиваем на выход
  analogWrite(nagr, nshim);     //Вывод шим в нагрузку паяльника (выводим 0 - старт с выключенным паяльником - пока не определим состояние температуры)
  
 
  // -------------------------------------------------- не изменять, это для Сегментов -----------------------------------------------
  DDRD = B11111111;
  for (int y=0;y<max_digits;y++)
          {
           pinMode(digit_common_pins[y],OUTPUT);
           digitalWrite(digit_common_pins[y], HIGH);    
          }
  // -------------------------------------------------- не изменять, это для Сегментов -----------------------------------------------
 
}

void loop() {
    show(increment);   // Вывести значение переменной на экран (LED)
    //delay(50);
    Serial.println( nshim);
    Serial.println( nagr);
    Serial.println( tdat);
    Serial.println( tin);
    Serial.println( ustt);
    
   if (tdat < ustt ){   // Если температура паяльника ниже установленной температуры то:
      
            if ((ustt - tdat) < 16 & (ustt - tdat) > 6 ) // Проверяем разницу между установленной температурой и текущей паяльника,
                                     // Если разница меньше 10 градусов, то 
                             { 
                              nshim = 99;  // Понижаем мощность нагрева (шим 0-255, мы делаем 99) - таким образом мы убираем инерцию перегрева
                              }
             else  if ((ustt - tdat) < 7 & (ustt - tdat) > 3)
                                                                {              
                                                                  nshim = 80;  // Понижаем мощность нагрева (шим 0-255, мы делаем 99) - таким образом мы убираем инерцию перегрева
                                                                 }
                              
                         else if ((ustt - tdat) < 4 )
                                                      {              
                                                       nshim = 45;  // Понижаем мощность нагрева (шим 0-255, мы делаем 99) - таким образом мы убираем инерцию перегрева
                                                       }  
                                                     
                                                     
                            else {
                                  nshim = 230; // Иначе поднимаем мощность нагрева (шим 0-255, мы делаем 230) на максимум для быстрого нагрева до нужной температуры
                                 }
                        
                              
      analogWrite(nagr, nshim);     //Вывод в шим порт (на транзистор) значение мощности
    }
   else { //Иначе (если температура паяльника равняется или выше установленной) 
            
            nshim = 0;  // Выключаем мощность нагрева (шим 0-255  мы делаем 0)  - таким образом мы отключаем паяльник
            analogWrite(nagr, nshim);   //Вывод в шим порт (на транзистор) значение мощности
          } 
  
    
  if(millis() - actual_count_delay > count_delay) // это для сегментов 

  {  
    actual_count_delay = millis();
     // Здесь мы пишем нашу прогу по считыванию состояния кнопок (это место в счетчик не будет тормозить вывод на сегменты)
   
    tdat = analogRead(tin); // Считать состояние датчика температуры и присвоить tdat
    tdat =map(tdat,0,430,25,310); // калибровка п умолчанию 0,430,25,310
    increment = tdat; // присвоить текущее значение температуры переменной сегмента
     
    if (analogRead(kndn) < 1)  // Если нажата синяя кнопка, то понизить температуру на 5
                               {
                               if( ustt <= mintemp || (ustt-5) <= mintemp )
                                                          {
                                                            ustt= mintemp;
                                                            increment = ustt;
                                                          }
                                       else { 
                                             ustt=ustt-5;
                                             increment = ustt;
                                              } 
                                 
                                 
                              
                               }
  
          else if (analogRead(knup) < 1)  // Если нажата красная кнопка, то повысить температуру на 5
                                       {
                                       ustt=ustt+5;
                                       if( ustt >=maxtemp)
                                                          {
                                                            ustt= maxtemp;
                                                          }
                                       increment = ustt;
                                       } 
  
} 



}

void show(int value) { //------------------------------- подпрограмма для вывода на сегменты - лучше не изменять ---------------------------------------------
  int digits_array[]={};  
  int y=0;
  boolean empty_most_significant = true; 
  

  
  if(millis() - actual_refresh_delay >= refresh_delay)
  {  

  for (int z=max_digits-1;z>=0;z--)
  {


    digits_array[z] = value / pow(10,z); //rounding down by converting from float to int
    
    if(digits_array[z] != 0 ) empty_most_significant = false;  // DON'T SHOW LEADING ZEROS
    
    value = value - digits_array[z] * pow(10,z);




 
   if(z==current_digit)
   {
    if(!empty_most_significant || z==0){ // DON'T SHOW LEADING ZEROS EXCEPT FOR THE LEAST SIGNIFICANT
            
                        PORTD = digits[digits_array[z]];
               }
    else
    {
      PORTD = B00000000;  
    }

  
     digitalWrite(digit_common_pins[z], LOW);
   }else{
     digitalWrite(digit_common_pins[z], HIGH);
    }

}
  

      current_digit--;
      if(current_digit < 0) 
      {
        current_digit= max_digits; // NEED AN EXTRA REFRESH CYCLE TO CLEAR ALL DIGITS
      }
 
 actual_refresh_delay =  millis();     
 }

}

 

bwn
Offline
Зарегистрирован: 25.08.2014

sp1run33 пишет:

 как с ними работать 

Выкинуть из скетча все лишнее и научиться зажигать сегменты, для начала. И схему бы, неплохо. Надеюсь, общие аноды/катоды, через ключи подключены и резисторы токоограничительные имеются.

Гриша
Offline
Зарегистрирован: 27.04.2014

bwn пишет:

sp1run33 пишет:

 как с ними работать 

Выкинуть из скетча все лишнее и научиться зажигать сегменты, для начала. И схему бы, неплохо. Надеюсь, общие аноды/катоды, через ключи подключены и резисторы токоограничительные имеются.

поддерживаю, информации по этому вопросу в интернете полно и переписывать ее +100500 раз бессмысленно. А не умея программировать лопатить чужой код не только бессмысленно, но и глупо - проще заказать готовое устройство (дещевле и быстрее).  

sp1run33
Offline
Зарегистрирован: 23.07.2019

уважаемий ' если у ж я на етом форуме то вариант купить готовое устройство как то дико не устраивает 
занимаюсь електроникой давно интересуюсь в данний момент именно семисегментним индикатором ' а вот на чужом коде все и учатся ' резистори есть ключей нету ибо ненужни они там сегменти работают и даже иногда показивали  999 

но подключение неправельное а описание работи с ними нету вообще никакого 

Гриша
Offline
Зарегистрирован: 27.04.2014

sp1run33 пишет:

 ' а вот на чужом коде все и учатся ' 

 

учатся на уроках, пусть и чужих, а готовые проекты они на то и проекты - хотите учиться на них обращайтесь к автору проекта. 

Вам конкретный совет дали - напишите код для своего индикатора самостоятельно (по урокам), тогда поймете и все поправите сами.

UPD чужой проект - это шаблон, чтоб время не терять, но на практике чаще самому написать программу проще, чем чужую поправить (факт)

 

bwn
Offline
Зарегистрирован: 25.08.2014

sp1run33 пишет:

резистори есть ключей нету ибо ненужни они там сегменти работают и даже иногда показивали  999 

но подключение неправельное а описание работи с ними нету вообще никакого

5мА х 8сег = 40мА (предельное для пина), а ток на сегмент может и 20мА достигать, а значит любая цифра кроме единицы - писец общему пину.

А что описывать в работе семи светодиодов, подвешенных на общий анод или катод? На аноде плюс, катоде минус. Все.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

sp1run33 пишет:

.... как с ними работать 

Надо понять главное - семисегментники отображают информацию последовательно. То есть для "высвечивания" "0" (нуля) нужно последовательно "зажечь и погасить" 6 (шесть) элементов семисегментника. Это все делается в цикле и для глаза человека "кажется" (или незаметно, кому как удобнее), что они горят постоянно,  хотя на самом деле это не так (они очень часто моргают просто)...

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

bwn пишет:

5мА х 8сег = 40мА (предельное для пина), а ток на сегмент может и 20мА достигать, а значит любая цифра кроме единицы - писец общему пину.

 

А надо делать не "по циферную" динамическую индикацию, а "по-сегментную" когда в каждый момент времени горит только один сегмент. Таким образом не только проблемы с перегрузкой выходов устраняется, но и исчезает неравномерность яркости цифр.

Но все равно, ограничительные резисторы желательно поставить.

bwn
Offline
Зарегистрирован: 25.08.2014

asam пишет:

А надо делать не "по циферную" динамическую индикацию, а "по-сегментную" когда в каждый момент времени горит только один сегмент. Таким образом не только проблемы с перегрузкой выходов устраняется, но и исчезает неравномерность яркости цифр.

Но все равно, ограничительные резисторы желательно поставить.

Можно и так, но нам, непрограммистам, сложно.)))) Две динамики, сегменты и общие, я бы тогда 7219 влепил и не маялся.))))
Обычно леплю резистор на каждый сегмент и ключ на общий, с яркостью проблем нет, за токи не вылазим. Но это ИМХО.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

bwn пишет:

 так, но нам, непрограммистам, сложно.)))) Две динамики, сегменты и общие, я бы тогда 7219 влепил и не маялся.))))

Обычно леплю резистор на каждый сегмент и ключ на общий, с яркостью проблем нет, за токи не вылазим. Но это ИМХО.

 

Ну если с ключем, то да, с яркостью проблем нет. Но я программист, мне лишние детальки паять лень, проще программным способом :)

sp1run33
Offline
Зарегистрирован: 23.07.2019

я тоже склоняюсь к способу решить проблему програмно . хоть у меня и есть дисплей 1602 но мне реально интересен семисегментник . и так может какой материал почитать подскажете ибо гуглом пользоватся не умею постоянно какуето дич вижу но ничего конкретного 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Так двое же сказали - «зажигать» сегменты. 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

sp1run33 пишет:

я тоже склоняюсь к способу решить проблему програмно . хоть у меня и есть дисплей 1602 но мне реально интересен семисегментник . и так может какой материал почитать подскажете ибо гуглом пользоватся не умею постоянно какуето дич вижу но ничего конкретного 

 

http://www.circuitbasics.com/arduino-7-segment-display-tutorial/

Гриша
Offline
Зарегистрирован: 27.04.2014

sp1run33 пишет:
  и так может какой материал почитать подскажете 

бегло проглядел, вроде ровно написано на этом ресурсе, даже похоже на предыдущую ссылку... 

кода нет, но есть физика процессов