Сдвиговый регистр 74HC595, почему мигают светодиоды?
- Войдите на сайт для отправки комментариев
Сб, 27/09/2014 - 08:37
Ребята помогите пожалуйста, почему програют светодыоды вместо того чтобы гореть?
Прмер брал отсюда
/*
Программа поочередно включается все светодиоды, подключенные к двум
сдвиговым регистрам 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);
}
Запись в 2 регистра подряд, поэтому мигает. Первый успевает показать инфу, предназначенную для второго.
Лечится отдельным проводом защёлки для второго регистра. То есть надо 2 провода - Latch1 и Latch2. А соединение между Q7' первого и SI второго - убрать. Вместо этого SI обоих регистров надо соединить параллельно.
все std. буду тебя рекомендовать, когда нужно будет найти ошибку в большом коде
Извенте неправильно выразился, мигают не все диоды а тока те кторые выставлены в 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); }1
Скажите пожалуйста, вы решили эту проблему?