Сдвиговый регистр 74HC595, почему мигают светодиоды?

neospromiy
Offline
Зарегистрирован: 15.07.2013

Ребята помогите пожалуйста, почему програют светодыоды вместо того чтобы гореть?

Прмер брал отсюда

/*
 Программа поочередно включается все светодиоды, подключенные к двум
сдвиговым регистрам 74HC595 .Created 22 May 2009
 Modified 23 Mar 2010
 by Tom Igoe
 */
 
//Пин подключен к ST_CP входу 74HC595
const int latchPin = 8;
//Пин подключен к SH_CP входу 74HC595
const int clockPin = 12;
//Пин подключен к DS входу 74HC595
const int dataPin = 11;
 
char inputString[2];
 
void setup() {
   //устанавливаем режим OUTPUT
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  pinMode(clockPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("reset");
}
 
void loop() {
  // проходим циклом по всем 16 выходам двух регистров
  for (int thisLed = 0; thisLed < 16; thisLed++) {
    // записываем сигнал в регистр для очередного светодиода
    registerWrite(thisLed, HIGH);
    // если это не первый светодиод, то отключаем предыдущий
    if (thisLed > 0) {
      registerWrite(thisLed - 1, LOW);
    }
    // если это первый светодиод, то отключаем последний
    else {
      registerWrite(15, LOW);
    }
    // делаем паузу перед следующией итерацией
    delay(250);
  }
 
}
 
// этот метод отсылает бит на сдвиговый регистр
 
void registerWrite(int whichPin, int whichState) {
  // для хранения 16 битов используем unsigned int
  unsigned int bitsToSend = 0;   
 
  // выключаем светодиоды на время передачи битов
  digitalWrite(latchPin, LOW);
 
  // устанавливаем HIGH в соответствующий бит
  bitWrite(bitsToSend, whichPin, whichState);
 
  // разбиваем наши 16 бит на два байта
  // для записи в первый и второй регистр
  byte registerOne = highByte(bitsToSend);
  byte registerTwo = lowByte(bitsToSend);
 
  // "проталкиваем" байты в регистры
  shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne);
 
  // "защелкиваем" регистр, чтобы биты появились на выходах регистра
  digitalWrite(latchPin, HIGH);
}

В коде использовал для включения светодиодов registerWrite(10, HIGH) или registerWrite(thisLed, HIGH); и т.д

Вот код полностью

#include <OneWire.h>

#include <DallasTemperature.h>
#define ONE_WIRE_BUS 7
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress Thermometer1 = {
  0x28, 0x6C, 0x4D, 0xCE, 0x04, 0x00, 0x00, 0x17};
  DeviceAddress Thermometer2 = {
    0x28, 0x59, 0x4F, 0xCE, 0x04, 0x00, 0x00, 0x92};
  
#include <LiquidCrystal.h>

#include <EEPROM.h>



long previousMillis = 0; 
int val=0; 
int regim = 1;
int muteTap=0;
long previousMillisTap=0;
long startMillisTap=0;
int muteType=0;
long ledTime=100;
long ledStart=0;
boolean ledON=false;
unsigned long flag = 0;
unsigned long eventTime = 0;
unsigned long pauseMillis = 0;
int mediaknopki; //Порт А1 это кнопки мультимедиа
int cruiseknopki; //Порт А0 кнопки круиз контроля

//Пин SH_CP
int SH_CP = 4;
//Пин ST_CP
int ST_CP = 3;
//Пин DS
int DS = 2;
                                                                                                                                                                                         
int pioneer_mute = 1;
int pioneer_next = 2;
int pioneer_prev = 3;
int pioneer_volup = 4;
int pioneer_voldown =5;

int bluetooth_mute = 6;
int bluetooth_next = 7;
int bluetooth_prev = 8;
int bluetooth_volup = 9;
int bluetooth_voldown =10;

int nexus = 11; //на экранчкик пионер
int pioneer = 12; //на экранчкик нексус
int bluettoch = 13; //на экранчкик блютус


int avto = 14;
int rese = 15;
int up = 16;
int down = 5;

int knopka_vibora;

int knopka_pioneer_mute;
int knopka_pioneer_next;
int knopka_pioneer_prev;
int knopka_pioneer_volup;
int knopka_pioneer_voldown;

int knopka_bluetooth_mute;
int knopka_bluetooth_next;
int knopka_bluetooth_prev;
int knopka_bluetooth_volup;
int knopka_bluetooth_voldown;

int knopka_nexus_mute;
int knopka_nexus_next;
int knopka_nexus_prev;
int knopka_nexus_volup;
int knopka_nexus_voldown;

void setup() {
sensors.begin();
sensors.setResolution(Thermometer1, 7);
sensors.setResolution(Thermometer2, 7);

   EEPROM.write(2,0);
   Keyboard.begin();
   Serial.begin(9600);
   pinMode(SH_CP, OUTPUT);
   pinMode(ST_CP, OUTPUT);
   pinMode(DS, OUTPUT);
   pinMode(nexus, OUTPUT);
   pinMode(pioneer, OUTPUT);
   pinMode(bluettoch, OUTPUT);
   pinMode(down, OUTPUT);
} 
     
 void printTemperature(DeviceAddress deviceAddress) {
  float tempC = sensors.getTempC(deviceAddress);
  Serial.println(tempC);       
}

void loop() {

  {
 
  sensors.requestTemperatures();
  Serial.print("IN Car temperature   ");
  printTemperature(Thermometer1);
 
  Serial.print("OUT Car temperature  ");
  printTemperature(Thermometer2);
}
  
  knopka_pioneer_mute = (mediaknopki>50&&mediaknopki<200                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                );
  knopka_pioneer_next = (mediaknopki>350&&mediaknopki<450);
  knopka_pioneer_prev = (mediaknopki>50&&mediaknopki<200);
  knopka_pioneer_volup = (mediaknopki>350&&mediaknopki<450);
  knopka_pioneer_voldown = (mediaknopki>350&&mediaknopki<450);

  knopka_bluetooth_mute = (mediaknopki>50&&mediaknopki<200);
  knopka_bluetooth_next = (mediaknopki>350&&mediaknopki<450);
  knopka_bluetooth_prev = (mediaknopki>350&&mediaknopki<450);
  knopka_bluetooth_volup = (mediaknopki>50&&mediaknopki<200);
  knopka_bluetooth_voldown =(mediaknopki>350&&mediaknopki<450);
  
  knopka_nexus_mute = (mediaknopki>50&&mediaknopki<200);
  knopka_nexus_next = (mediaknopki>350&&mediaknopki<450);
  knopka_nexus_prev = (mediaknopki>350&&mediaknopki<450);
  knopka_nexus_volup = (mediaknopki>350&&mediaknopki<450)                                                                                                                                                                                                         ;
  knopka_nexus_voldown =(mediaknopki>350&&mediaknopki<450);
  
  knopka_vibora = (mediaknopki>50&&mediaknopki<200);
  
  mediaknopki=analogRead(A0); //читаем значение нажатых резистивных кнопок
  cruiseknopki=analogRead(A1); //читаем значение нажатых резистивных кнопок
    
  
 Serial.print("cruiseknopki   ");
  Serial.println(cruiseknopki);
   Serial.print("mediaknopki    ");
    Serial.println(mediaknopki);
  //Serial.println(EEPROM.read(2));
   //Serial.println(EEPROM.read(1));
    //Serial.println(EEPROM.read(0));
   
  
   
    if(knopka_vibora)//если кнопка нажата ... 
   { 
       if (millis() - previousMillis >1200)    
     { 
        previousMillis = millis();     
        val++; 
     } 
     } 
     else 
     { 
       val=0; 
     } 
        
     if(val>=5) 
     { val=0; 
       regim++; 
       
       if(regim>3)
       regim=1;
           
      
        
        if(regim==1) //пионер 
        {
       EEPROM.write(2,0);
       EEPROM.write(1,0);
       EEPROM.write(0,1);
              
       }
       if(regim==2) //нексу
       {
       EEPROM.write(2,0);
       EEPROM.write(1,1);
       EEPROM.write(0,0);
       
        }
       if(regim==3) //блютус
       {
       EEPROM.write(2,1); 
       EEPROM.write(1,0);
       EEPROM.write(0,0);  
            
       }
        
     } 
       
        else if (EEPROM.read(1)==1) registerWrite(pioneer,HIGH);
     
     else
     {
     registerWrite(pioneer,LOW);
     }
     
     if (EEPROM.read(0)==1) registerWrite(nexus,HIGH);
     
     else
     registerWrite(nexus,LOW);
     
      if (EEPROM.read(2)==1) registerWrite(bluettoch,HIGH);
     
     else
     registerWrite(bluettoch,LOW);
     
    
     
     
      if (knopka_vibora)
      {
        if (muteTap==0)
        startMillisTap=millis();
        muteTap=1; 
        if (EEPROM.read(0)==1) muteType=1;
        if (EEPROM.read(1)==1) muteType=2;
        if (EEPROM.read(2)==1) muteType=3;
        
       if ((millis() - previousMillisTap>1200) )
        {
          previousMillisTap = millis();     
          muteTap++; 
        }
          
      }
     else 
     { 
       
       
       if (((muteTap>0)&&((millis()-startMillisTap)<5000))||(ledON))
       {
         switch (muteType)
          {
            case 1:
            if (ledStart==0) 
            {
            registerWrite(pioneer_mute, HIGH);
            ledON=true;
            ledStart=millis();
            }
            else if (millis()-ledStart>ledTime)
            {
              ledStart=0;
              registerWrite(pioneer_mute, LOW);
               ledON=false;
              muteTap=0;
            }
            break;
            case 2:  
            if (ledStart==0) 
            {
            Remote.play_pause();
              ledON=true;
            ledStart=millis();
            }
            else if (millis()-ledStart>ledTime)
            {
              ledStart=0;
               Remote.clear();
                 ledON=false;
              muteTap=0;
            }
            break;
            
            
            case 3:  
             if (ledStart==0) 
            {
            registerWrite(bluetooth_mute, HIGH);
              ledON=true;
            ledStart=millis();
            }
            else if (millis()-ledStart>ledTime)
            {
              ledStart=0;
              registerWrite(bluetooth_mute, LOW);
                 ledON=false;
              muteTap=0;
            }
            break;
          }
      
      
       }
       muteTap=0;
     }                                                                                                                                                                                                                                                                                                                                                                             
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
     ///////////////////////////////////////////////УПРАВЛЕНЕ ПИОНЕР///////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////////////////////////////////////
     
       if (knopka_pioneer_next&&(EEPROM.read(0)==1)) 
      registerWrite(pioneer_next, HIGH);
     else registerWrite (pioneer_next, LOW);
     
       if (knopka_pioneer_prev&&(EEPROM.read(0)==1)) 
      registerWrite(pioneer_prev, HIGH);
     else registerWrite (pioneer_prev, LOW);
     
     if (knopka_pioneer_volup)registerWrite(pioneer_volup, HIGH);
       else registerWrite(pioneer_volup, LOW);
          
       if (knopka_pioneer_voldown)registerWrite(pioneer_voldown, HIGH);
     else registerWrite (pioneer_voldown, LOW);
     
     
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////УПРАВЛЕНИЕ NEXUS///////////////////////////////////////////////
     /////////////////////////////////////////////////////////////////////////////////////////////////////////////

     if(knopka_vibora<=60 && flag == 0) // все кнопки отпущены
     
     {
    eventTime=millis();
     }
     
      if(millis()-eventTime>10 && millis()-eventTime<499 && knopka_nexus_next &&(EEPROM.read(1)==1))
     // короткое нажатие кнопки от 10 до 499 миллисекунд (изменяется здесь millis()-eventTime>10 && millis()-eventTime<499)
     { 
    flag = 2;
     }
     if(mediaknopki<=60 && flag == 2) // действие после короткого нажатия кнопки, следующая песня
   {
    Remote.next();
    flag = 0;
    delay(10);
    Remote.clear();
   }
     if(millis()-eventTime>500 && knopka_nexus_volup && flag == 2 || knopka_nexus_volup && flag == 3&&(EEPROM.read(1)==1))
    // удержание кнопки от 500 до ? миллисекунд (изменяется здесь millis()-eventTime>500)
     { 
    Remote.increase(); // действие после удержание кнопки, увеличение громкости
    flag = 3;
    Remote.clear();
    delay(100);
   }
    
           if(millis()-eventTime>10 && millis()-eventTime<499 &&  knopka_nexus_prev&&(EEPROM.read(1)==1))
     // короткое нажатие кнопки от 10 до 499 миллисекунд (изменяется здесь millis()-eventTime>10 && millis()-eventTime<499)
     { 
    flag = 4;
     }
     if(mediaknopki<=60 && flag == 4) // действие после короткого нажатия кнопки, предидущая песня
   {
     Remote.previous();
    flag = 0;
    delay(10);
    Remote.clear();
   }
     if(millis()-eventTime>500 && knopka_nexus_voldown && flag == 4 || knopka_nexus_voldown && flag == 3&&(EEPROM.read(1)==1))
    // удержание кнопки от 500 до ? миллисекунд (изменяется здесь millis()-eventTime>500)
     { 
    Remote.decrease(); // действие после удержание кнопки, уменьшение громкости
    flag = 3;
    Remote.clear();
    delay(100);
   }
     
     
      if(mediaknopki<=60 && flag == 3 || mediaknopki<=60 && flag == 5 || mediaknopki<=60 && flag == 6) // действие после отпускания кнопки
   {
    flag = 0;
   }   
     
     ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     ///////////////////////////////////////////////////////УПРАВЛЕНИЕ БЛЮТУС///////////////////////////////////////////////////////////
     ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   
         if (knopka_bluetooth_mute&&(EEPROM.read(2)==1))
      registerWrite(bluetooth_mute, HIGH);
     else registerWrite (bluetooth_mute, LOW);
     
     if (knopka_bluetooth_next&&(EEPROM.read(2)==1))
      registerWrite(bluetooth_next, HIGH);
     else registerWrite (bluetooth_next, LOW);
     
     if (knopka_bluetooth_prev&&(EEPROM.read(2)==1))
      registerWrite(bluetooth_prev, HIGH);
     else registerWrite (bluetooth_prev, LOW);
     
           

} 
   

 
// Метод для отсылки данных в регистры
void registerWrite(int num, int state) {
 // Для хранения 16 битов используется unsigned int
 unsigned int bitsToSend = 0;
 // 0b000000000000000
 // Инициализируем начало приема данных
 digitalWrite(ST_CP, LOW);
 
 // Устанавливаем 1 в соответствующий бит
 bitWrite(bitsToSend, num, state);
 
 // 16 бит необходимо разделить на два байта:
 // И записать каждый байт в соответствующий регистр
 byte register1 = highByte(bitsToSend);
 byte register2 = lowByte(bitsToSend);
 
 // Последовательная передача данных на пин DS
 shiftOut(DS, SH_CP, MSBFIRST, register2);
 shiftOut(DS, SH_CP, MSBFIRST, register1);
 
 // Инициализируем окончание передачи данных.
 // Регистры подадут напряжение на указанные выходы
 digitalWrite(ST_CP, HIGH);
}

 

std
Offline
Зарегистрирован: 05.01.2012

Запись в 2 регистра подряд, поэтому мигает. Первый успевает показать инфу, предназначенную для второго.

Лечится отдельным проводом защёлки для второго регистра. То есть надо 2 провода - Latch1 и Latch2. А соединение между Q7' первого и SI второго - убрать. Вместо этого SI обоих регистров надо соединить параллельно.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

все std. буду тебя рекомендовать, когда нужно будет найти ошибку в большом коде

 

neospromiy
Offline
Зарегистрирован: 15.07.2013

Извенте неправильно выразился, мигают не все диоды а тока те кторые выставлены в HIGH т.е. включенные.

Большой код работает замечательно кроме этого косяка, кстати этот же косяк появляеться если я добавляю delay в код из прмера. например так

при этом получаеться. 9 горит стабильно, остальные 8,10,11,12 моргают

если переставить delay скажем на строку нижу то получаеться 10 горит стабильно, а 8,9,11,12 моргают

из за этого и в готовом большом коде всё моргает

//Пин подключен к ST_CP входу 74HC595
const int latchPin = 3;
//Пин подключен к SH_CP входу 74HC595
const int clockPin = 4;
//Пин подключен к DS входу 74HC595
const int dataPin = 2;
 
char inputString[2];
 
void setup() {
    pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  pinMode(clockPin, OUTPUT); }
 
void loop() {
  

  
  registerWrite(8, HIGH);
      registerWrite(9, HIGH);
   delay (250);
      registerWrite(10, HIGH);
       registerWrite(11, HIGH);
      registerWrite(12, HIGH);
 
}
 
// этот метод отсылает бит на сдвиговый регистр
 void registerWrite(int whichPin, int whichState) {
  // для хранения 16 битов используем unsigned int
  unsigned int bitsToSend = 0;   
   // выключаем светодиоды на время передачи битов
  digitalWrite(latchPin, LOW);
   // устанавливаем HIGH в соответствующий бит
  bitWrite(bitsToSend, whichPin, whichState);
   // разбиваем наши 16 бит на два байта
  // для записи в первый и второй регистр
  byte registerOne = highByte(bitsToSend);
  byte registerTwo = lowByte(bitsToSend);
   // "проталкиваем" байты в регистры
  shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne);
   // "защелкиваем" регистр, чтобы биты появились на выходах регистра
  digitalWrite(latchPin, HIGH);
}

 

neospromiy
Offline
Зарегистрирован: 15.07.2013

1

NikGurik
Offline
Зарегистрирован: 05.12.2015

Скажите пожалуйста, вы решили эту проблему?