Помогите с индикацей на 4-х разрядный 7-ми сегментный индикатор с сдвиговыми регистрами 74HC595

gosha2393
Offline
Зарегистрирован: 08.12.2014

Привет, всем! Спасибо огромное denis64, что научил пользоваться индикатором!)) 

Но блин всё равно у меня проблемы. хотел сделать стробоскоп с индикацией частоты мегания. отдельно индикация и отдельно стробоскоп работает. А вместе не хочет нормально работать(

Имею: arduino uno, кнопка, потенциометр 1КОм, 4-х разрядный 7-ми сегментный индикатор с сдвиговыми регистрами 74HC595 (имеющий контакты +, -, DIO, SCRL, Rclr), светодиод и сопротивления.

Система должна работать так так: включаешь питание горит индикатор с показанием частоты, регулируешь частоту потенциометром, на индикотре меняются значения, нажимаешь кнопку и светодиод начинает моргать, ещё раз нажимаешь кнопку светодиод перестает моргать. Индикатор должен работать всегда.

Система работает так: включаешь питание горит индикатор с с показанием частоты, регулируешь частоту потенциометром, на индикотре меняются значения, нажимаешь кнопку и светодиод начинает моргать а индикатор гаснет, ещё раз нажимаешь кнопку светодиод перестает моргать, а индикатор загорается. 

При детальном рассмотрении выяснил, что при включённом режиме моргания система ведет себя так: загорается светодиод, горит установленной время, выключается, в выключенном состоянии находиться заданное время, на долю секунды высвечивается показания на индикаторе (причем вродебы в пол яркости), и светодиод включается снова. далее цикл повторяется бесконечно.

Можете посмотреть на видео, но там плохо видно мерцание индикатора во время моргания светодиода: 

Думаю что ошибка в коде, но незнаю какая...

001 /* стробоскоп с индикацией частоты на 4-х разрядный 7-ми сегментный индикатор*/
002 int x; // переменная для работы с кнопкой
003 int switchPin = 7; // кнопка
004 int ledPin = A1; // светодиод
005 int potPin = A0; // потенциометр
006 int latchPin = 8; // контакт RCLK на индикаторе
007 int clockPin = 12; // контакт SCLK на индикаторе
008 int dataPin = 11; // контакт DIO на индикаторе
009 boolean lastButton = LOW; // это для нормальной работы кнопки
010 boolean currentButton = LOW; // это для нормальной работы кнопки
011 boolean ledOn = false// это для нормальной работы кнопки
012 const byte digit[10] =      //seven segment digits in bits
013 {  
014 B11000000, //0 
015 B11111001, //1  
016 B10100100, //2  
017 B10110000, //3  
018 B10011001, //4  
019 B10010010, //5  
020 B10000010, //6  
021 B11111000, //7  
022 B10000000, //8  
023 B10010000  //9
024 };
025  
026  
027  
028 void setup() {
029    //устанавливаем режимы для пинов
030   pinMode(potPin, INPUT);
031   pinMode(latchPin, OUTPUT);
032   pinMode(dataPin, OUTPUT); 
033   pinMode(clockPin, OUTPUT);
034   pinMode(switchPin, INPUT);
035   pinMode(ledPin, OUTPUT);
036  
037 }
038 // boolean тоже для нормальной работы кнопки
039 boolean debounce(boolean last)
040 {
041   boolean current = digitalRead(switchPin);
042   if (last != current)
043   {
044     delay(5);
045     current = digitalRead(switchPin);
046   }
047   return current;
048 }
049  
050  
051 void loop() {
052    int pot1 = analogRead(potPin); // считываем значения с потенциометра
053   int time = map(pot1,0,1023,20,200); // переводим их во время горения светодиода
054     if (x == 1)  // если после предыдущего цикла х остался 1 то он так и остается 1, а если нет то в 0
055   {
056     x = 1;
057   }
058   else
059   {
060     x = 0;
061   }
062     currentButton = debounce(lastButton);
063   if (lastButton == LOW && currentButton == HIGH) // если нажимаем на кнопку
064   {
065   switch (x)
066   {
067    case 0: //если х равен 0 то будет 1
068   x = x + 1;
069   break;
070   case 1: //если х равен 1 то будет 0
071   x = x - 1;
072   break;
073   }
074   }
075    lastButton = currentButton;
076  
077 if ( x == 1) // если х равен 1 то включаем светодиод и выключаем его
078 {
079   digitalWrite(ledPin, HIGH);
080   delay(time);
081   digitalWrite(ledPin, LOW);
082   delay(time);
083 }
084   
085

  int pot = map(time,20,200,20,202); // значения с параметра время переводим в значения для индикатора и далее делим на разряды

086   int x1;
087   int x2;
088   int x3;
089   int x4;
090   x4 = pot / 1000;
091   x3 = pot /100;
092   x2 = (pot / 10) % 10;
093   x1 = pot % 10;
094  
095   // далее отдельно каждый разряд числа выводим на индикатор
096   
097   digitalWrite(latchPin, LOW);
098   shiftOut(dataPin, clockPin, MSBFIRST, digit[x1]);
099   shiftOut(dataPin, clockPin, MSBFIRST, B0001);
100   digitalWrite(latchPin, HIGH);
101   digitalWrite(latchPin, LOW);
102   shiftOut(dataPin, clockPin, MSBFIRST, digit[x2]);
103   shiftOut(dataPin, clockPin, MSBFIRST, B0010);
104   digitalWrite(latchPin, HIGH);
105     digitalWrite(latchPin, LOW);
106   shiftOut(dataPin, clockPin, MSBFIRST, digit[x3]);
107   shiftOut(dataPin, clockPin, MSBFIRST, B0100);
108   digitalWrite(latchPin, HIGH);
109   digitalWrite(latchPin, LOW);
110   shiftOut(dataPin, clockPin, MSBFIRST, digit[x4]);
111   shiftOut(dataPin, clockPin, MSBFIRST, B1000);
112   digitalWrite(latchPin, HIGH);
113 }

Как сделать чтобы индикатор всегда был включён? Заранее очень благодарен)

P.S. если есть ошибки в орфографии - простите)

Radjah
Offline
Зарегистрирован: 06.08.2014

Есть вот такая штука http://www.ebay.com/itm/351195307338 на MAX7219

Контроллер сам будет индикацию поддерживать. Только с примерами надо погонять. У меня например текст выводился с противоположного края.

vov4ik
Offline
Зарегистрирован: 10.09.2013

Удалите 112 строку    digitalWrite(latchPin, HIGH); или переместите её в 96строку не проверял но попробуйте, очередность в некоторых случаях очень важна.

vov4ik
Offline
Зарегистрирован: 10.09.2013

если не поможет тогда делайте так делей меняем на миллес 

 

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Мерцает? а вы не пробовали дергать latch, когда закончили передачу, а не постоянно. latch это передача данных из последовательного регистра в паралельный. Вообще я бы использовал Q7' выход для того чтобы последовательно соединить регистры и передавал бы 4 байта через SPI.transfer(), поотм дергал бы latch - и ничего бы не мерцало.

Вот такая схема не мерцает:

Если обновлять только при изменении, коротким дерганьем latch.

А если у вас "Матрица", то надо использовать специальный драйвер или выводить по таймеру.

gosha2393
Offline
Зарегистрирован: 08.12.2014

vov4ik, спасибо огромное!! помгло изменение делея на милис. Ещё не разобрался как это работает (я начинающий владелец arduino), но это работает!!! Изменения с переносом строки с latch практически ничего не меняет. NeiroN, постоянно дергаю latch так как, если сразу передавать 4 байта на индикаторе ничего не горит. А второй метод указанный вами я ещё не знаю, надеюсь что в будущем освою) 

ВСЕМ БОЛЬШОЕ СПАСИБО!)

faraddin
Offline
Зарегистрирован: 11.08.2013

http://avrproject.ru/publ/kak_podkljuchit/bascom_avr_74hc595/2-1-0-44

посмотрите на анимацию, сразу станет ясно как это работает

vov4ik
Offline
Зарегистрирован: 10.09.2013
Я как-то об этом догадавылся теперь понятно почему у чела моргает, внести немного изменений в код

 

 

Nemo
Offline
Зарегистрирован: 07.03.2015

Помогите и мне пожалуйста. Та же проблема - мерцание. Если не сложно - гляньте пожалуйста код.

http://arduino.ru/forum/proekty/vyvod-informatsii-na-4-razryadnyi-7segme...

сообщение № 87

Nemo
Offline
Зарегистрирован: 07.03.2015

Кто еще сталкнется с подобной проблемой - мужики в соседней ветке помогли с решением:

http://arduino.ru/forum/proekty/vyvod-informatsii-na-4-razryadnyi-7segme...

Смотрим пост № 97 - 2 кода и оба рабочих.