Часы на 7 сегментном LED индикаторе - нужна помощь.

finker
Offline
Зарегистрирован: 27.04.2012

 Проблема в следующем (точнее в нехватке моих знаний) - ткните пжт носом.

Идея такова:

Есть ARDUINO Uno

Есть 7 сегментный LED индикатор LD5641A/B

Хотелось создать часики!

Скетч нашел в инете - НО - немного не подходит к моему индюку

все подключил - залил скетч

часики работаю - щитают

НО - после каждой цифры стоит точка (неморгает)

нужно чтобы моргала точка после второго индикатора (сама точка распаложенна на 2ой цифре)

не сооброжу где копать (чайник еще)

но очень хочется довести до ума - помогите пож-то ???

 

Выкладываю скетч:

 

/*
Arduino clock on a standard 4-digit clock display

Connections:
LTC - Arduino
1 - nc
2 - nc
3 - nc
4 - d7
5 - d3
6 - d2
7 - d11
8 - d10
9 - d4
10 - gnd
22 - d9
23 - d5
24 - d6
25 - A0 // because d13 already has a built-in LED getting in the way
26 - d8
27 - d12
28 - A1
29 - gnd

button:
5v - button - A4 - 10k resistor - gnd

*/

#define DIGIT1 2
#define DIGIT2 3
#define DIGIT3 5
#define DIGIT4 6

#define SEGMENTA 7
#define SEGMENTB 8
#define SEGMENTC 9
#define SEGMENTD 10
#define SEGMENTE 11
#define SEGMENTF 12
#define SEGMENTG A0

#define COLON 4
#define AMPM A1

#define BUTTON A4

#define ON HIGH
#define OFF LOW

#define DELAYTIME 50

unsigned short hours, minutes, seconds;
boolean pm;
unsigned long lastTime; // keeps track of when the previous second happened

int buttonState; // the current reading from the button pin
int lastButtonState = LOW; // the previous reading from the button pin
unsigned long button_down_start = 0; // how long the button was held down
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time

void setup() {
// initialize all the required pins as output.
pinMode(DIGIT1, OUTPUT);
pinMode(DIGIT2, OUTPUT);
pinMode(DIGIT3, OUTPUT);
pinMode(DIGIT4, OUTPUT);

pinMode(SEGMENTA, OUTPUT);
pinMode(SEGMENTB, OUTPUT);
pinMode(SEGMENTC, OUTPUT);
pinMode(SEGMENTD, OUTPUT);
pinMode(SEGMENTE, OUTPUT);
pinMode(SEGMENTF, OUTPUT);
pinMode(SEGMENTG, OUTPUT);

pinMode(COLON, OUTPUT);
pinMode(AMPM, OUTPUT);

// button is input
pinMode(BUTTON, INPUT);

// set the initial time
hours = 00;
minutes = 00;
seconds = 0;
pm = true;

lastTime = millis();
}

void loop() {

// Keep showing the display while waiting for timer to expire
while (millis() - lastTime < 1000) {
clock_show_time(hours, minutes);

// blink the colon, every even second
if (seconds % 2 == 0) {
clock_show_colon();
}

// button presses increase minutes
int reading = digitalRead(BUTTON);

// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:

if (buttonState != reading) {
button_down_start = millis(); // record the start of the current button state
}

buttonState = reading;

// buttonState is now either on or off
if (buttonState == HIGH) {
// if the button was held down more than 5 seconds, make it go faster
if ((millis() - button_down_start) > 5000) {
seconds += 10;
if (seconds > 59) seconds = 59;
}

// button has been pressed
incrementTime();
}
}

lastButtonState = reading;
}

lastTime += 1000;

incrementTime();
}

//
// a call to incrementTime increases time by one second.
//
void incrementTime() {

if (seconds == 59) {
seconds = 0;

if (minutes == 59) {
minutes = 0;

if (hours == 12) {
hours = 1;
}
else {
hours++;

if (hours == 12) {
pm = !pm;
}
}
}
else {
minutes++;
}
}
else {
seconds++;
}
}

//
// clock_show_time - displays the given time on the clock display
// Note that instead of hr/min the user can also send min/sec
// Maximum hr is 99, Maximum min is 59, and minimum is 0 for both (it's unsigned, heh).
//
void clock_show_time(unsigned short hours, unsigned short minutes) {
unsigned short i;
unsigned short delaytime;
unsigned short num_leds[10] = { 6, 2, 5, 5, 4, 5, 6, 3, 7, 6 };
unsigned short digit[4];
unsigned short hide_leading_hours_digit;

// convert minutes and seconds into the individual digits
// check the boundaries
if (hours > 99) hours = 99;
if (minutes > 59) minutes = 59;

// convert hr
if (hours < 10 && hours > 0) {
hide_leading_hours_digit = 1;
}
else {
hide_leading_hours_digit = 0 ;
}

digit[0] = hours / 10;
digit[1] = hours % 10; // remainder
digit[2] = minutes / 10;
digit[3] = minutes % 10; // remainder

for (i = hide_leading_hours_digit; i < 4; i++) {
clock_all_off();
clock_show_digit(i, digit[i]);

// fewer leds = brighter display, so delay depends on number of leds lit.
delaytime = num_leds[digit[i]] * DELAYTIME;
delayMicroseconds(delaytime);
}

clock_all_off();

if (pm) {
clock_show_ampm();
}

clock_all_off();
}

//
// clock_all_off - turns off all the LEDs on the clock to give a blank display
//
void clock_all_off(void) {

// digits must be ON for any LEDs to be on
digitalWrite(DIGIT1, OFF);
digitalWrite(DIGIT2, OFF);
digitalWrite(DIGIT3, OFF);
digitalWrite(DIGIT4, OFF);

// segments must be OFF for any LEDs to be on
digitalWrite(SEGMENTA, ON);
digitalWrite(SEGMENTB, ON);
digitalWrite(SEGMENTC, ON);
digitalWrite(SEGMENTD, ON);
digitalWrite(SEGMENTE, ON);
digitalWrite(SEGMENTF, ON);
digitalWrite(SEGMENTG, ON);

// turn off colon and alarm too
digitalWrite(COLON, ON);
digitalWrite(AMPM, OFF);
}

//
// clock_show_digit - turns on the LEDs for the digit in the given position
// position can be from 0 through 3: 0 and 1 being the hour, 2 and 3 being the seconds
// value can be from 0 through 9, ie, a valid single digit.
//
// (if value is out of range, it displays a 9. if digit is out of range display remains blank)
//
void clock_show_digit(unsigned short position, unsigned short value) {
byte a;
byte b;
byte c;
byte d;
byte e;
byte f;
byte g;

switch (position) {
case 0:
digitalWrite(DIGIT1, ON);
break;
case 1:
digitalWrite(DIGIT2, ON);
break;
case 2:
digitalWrite(DIGIT3, ON);
break;
case 3:
digitalWrite(DIGIT4, ON);
break;
}

a = !(value == 1 || value == 4);
b = !(value == 5 || value == 6);
c = !(value == 2);
d = !(value == 1 || value == 4 || value == 7);
e = (value == 0 || value == 2 || value == 6 || value == 8);
f = !(value == 1 || value == 2 || value == 3 || value == 7);
g = !(value == 0 || value == 1 || value == 7);

if (a) digitalWrite(SEGMENTA, OFF);
if (b) digitalWrite(SEGMENTB, OFF);
if (c) digitalWrite(SEGMENTC, OFF);
if (d) digitalWrite(SEGMENTD, OFF);
if (e) digitalWrite(SEGMENTE, OFF);
if (f) digitalWrite(SEGMENTF, OFF);
if (g) digitalWrite(SEGMENTG, OFF);
}

//
// clock_show_colon - shows the colon that separates minutes from seconds
//
void clock_show_colon(void) {
unsigned short delaytime;

digitalWrite(COLON, ON);
// 2 leds = 2 delays needed
delaytime = DELAYTIME * 2; // must use variable to have similar delay to rest of clock
delayMicroseconds(delaytime); // because use of variable slows it down slightly.
digitalWrite(COLON, OFF);
}

//
// clock_show_alarm - shows the ampm dot (bottom right of clock display)
//
void clock_show_ampm(void) {
unsigned short delaytime;

digitalWrite(AMPM, ON);

delaytime = DELAYTIME; // must use variable to have similar delay to rest of clock
delayMicroseconds(delaytime); // because use of variable slows it down slightly.
digitalWrite(AMPM, OFF);
}
 

maksim
Offline
Зарегистрирован: 12.02.2012

Вставка программного кода в тему/комментарий

/*
Arduino clock on a standard 4-digit clock display
 
 Connections:
 LTC - Arduino
 1 - nc
 2 - nc
 3 - nc
 4 - d7
 5 - d3
 6 - d2
 7 - d11
 8 - d10
 9 - d4
 10 - gnd
 22 - d9
 23 - d5
 24 - d6
 25 - A0 // because d13 already has a built-in LED getting in the way
 26 - d8
 27 - d12
 28 - A1
 29 - gnd
 
 button:
 5v - button - A4 - 10k resistor - gnd
 
 */

#define DIGIT1 2
#define DIGIT2 3
#define DIGIT3 5
#define DIGIT4 6

#define SEGMENTA 7
#define SEGMENTB 8
#define SEGMENTC 9
#define SEGMENTD 10
#define SEGMENTE 11
#define SEGMENTF 12
#define SEGMENTG A0

#define COLON 4
#define AMPM A1

#define BUTTON A4

#define ON HIGH
#define OFF LOW

#define DELAYTIME 50

unsigned short hours, minutes, seconds;
boolean pm;
unsigned long lastTime; // keeps track of when the previous second happened

int buttonState; // the current reading from the button pin
int lastButtonState = LOW; // the previous reading from the button pin
unsigned long button_down_start = 0; // how long the button was held down
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time

void setup() { 
  // initialize all the required pins as output.
  pinMode(DIGIT1, OUTPUT);
  pinMode(DIGIT2, OUTPUT);
  pinMode(DIGIT3, OUTPUT);
  pinMode(DIGIT4, OUTPUT);

  pinMode(SEGMENTA, OUTPUT);
  pinMode(SEGMENTB, OUTPUT);
  pinMode(SEGMENTC, OUTPUT);
  pinMode(SEGMENTD, OUTPUT);
  pinMode(SEGMENTE, OUTPUT);
  pinMode(SEGMENTF, OUTPUT);
  pinMode(SEGMENTG, OUTPUT);

  pinMode(COLON, OUTPUT);
  pinMode(AMPM, OUTPUT);

  // button is input
  pinMode(BUTTON, INPUT);

  // set the initial time
  hours = 00;
  minutes = 00;
  seconds = 0;
  pm = true;

  lastTime = millis();
}

void loop() {

  // Keep showing the display while waiting for timer to expire 
  while (millis() - lastTime < 1000) {
    clock_show_time(hours, minutes);

    // blink the colon, every even second
    if (seconds % 2 == 0) {
      clock_show_colon();
    }

    // button presses increase minutes
    int reading = digitalRead(BUTTON);

    // If the switch changed, due to noise or pressing:
    if (reading != lastButtonState) {
      // reset the debouncing timer
      lastDebounceTime = millis();
    }

    if ((millis() - lastDebounceTime) > debounceDelay) {
      // whatever the reading is at, it's been there for longer
      // than the debounce delay, so take it as the actual current state:

      if (buttonState != reading) {
        button_down_start = millis(); // record the start of the current button state
      }

      buttonState = reading;

      // buttonState is now either on or off
      if (buttonState == HIGH) {
        // if the button was held down more than 5 seconds, make it go faster
        if ((millis() - button_down_start) > 5000) {
          seconds += 10;
          if (seconds > 59) seconds = 59;
        }

        // button has been pressed
        incrementTime();
      }
    }

    lastButtonState = reading;
  }

  lastTime += 1000;

  incrementTime();
}

//
// a call to incrementTime increases time by one second.
//
void incrementTime() {

  if (seconds == 59) {
    seconds = 0;

    if (minutes == 59) {
      minutes = 0;

      if (hours == 12) { 
        hours = 1;
      }
      else {
        hours++;

        if (hours == 12) {
          pm = !pm;
        }
      }
    }
    else {
      minutes++;
    }
  }
  else {
    seconds++; 
  }
}

//
// clock_show_time - displays the given time on the clock display
// Note that instead of hr/min the user can also send min/sec
// Maximum hr is 99, Maximum min is 59, and minimum is 0 for both (it's unsigned, heh).
//
void clock_show_time(unsigned short hours, unsigned short minutes) {
  unsigned short i;
  unsigned short delaytime;
  unsigned short num_leds[10] = { 
    6, 2, 5, 5, 4, 5, 6, 3, 7, 6   };
  unsigned short digit[4];
  unsigned short hide_leading_hours_digit;

  // convert minutes and seconds into the individual digits
  // check the boundaries
  if (hours > 99) hours = 99;
  if (minutes > 59) minutes = 59;

  // convert hr
  if (hours < 10 && hours > 0) {
    hide_leading_hours_digit = 1;
  }
  else {
    hide_leading_hours_digit = 0 ;
  }

  digit[0] = hours / 10;
  digit[1] = hours % 10; // remainder
  digit[2] = minutes / 10;
  digit[3] = minutes % 10; // remainder

  for (i = hide_leading_hours_digit; i < 4; i++) {
    clock_all_off();
    clock_show_digit(i, digit[i]);

    // fewer leds = brighter display, so delay depends on number of leds lit.
    delaytime = num_leds[digit[i]] * DELAYTIME; 
    delayMicroseconds(delaytime);
  }

  clock_all_off();

  if (pm) {
    clock_show_ampm();
  }

  clock_all_off();
}

//
// clock_all_off - turns off all the LEDs on the clock to give a blank display
//
void clock_all_off(void) {

  // digits must be ON for any LEDs to be on
  digitalWrite(DIGIT1, OFF);
  digitalWrite(DIGIT2, OFF);
  digitalWrite(DIGIT3, OFF);
  digitalWrite(DIGIT4, OFF);

  // segments must be OFF for any LEDs to be on
  digitalWrite(SEGMENTA, ON);
  digitalWrite(SEGMENTB, ON);
  digitalWrite(SEGMENTC, ON);
  digitalWrite(SEGMENTD, ON);
  digitalWrite(SEGMENTE, ON);
  digitalWrite(SEGMENTF, ON);
  digitalWrite(SEGMENTG, ON);

  // turn off colon and alarm too
  digitalWrite(COLON, ON);
  digitalWrite(AMPM, OFF);
}

//
// clock_show_digit - turns on the LEDs for the digit in the given position
// position can be from 0 through 3: 0 and 1 being the hour, 2 and 3 being the seconds
// value can be from 0 through 9, ie, a valid single digit.
//
// (if value is out of range, it displays a 9. if digit is out of range display remains blank)
//
void clock_show_digit(unsigned short position, unsigned short value) {
  byte a;
  byte b;
  byte c;
  byte d;
  byte e;
  byte f;
  byte g;

  switch (position) {
  case 0:
    digitalWrite(DIGIT1, ON);
    break;
  case 1:
    digitalWrite(DIGIT2, ON);
    break;
  case 2:
    digitalWrite(DIGIT3, ON);
    break;
  case 3:
    digitalWrite(DIGIT4, ON);
    break;
  }

  a = !(value == 1 || value == 4);
  b = !(value == 5 || value == 6);
  c = !(value == 2);
  d = !(value == 1 || value == 4 || value == 7);
  e = (value == 0 || value == 2 || value == 6 || value == 8);
  f = !(value == 1 || value == 2 || value == 3 || value == 7);
  g = !(value == 0 || value == 1 || value == 7);

  if (a) digitalWrite(SEGMENTA, OFF);
  if (b) digitalWrite(SEGMENTB, OFF);
  if (c) digitalWrite(SEGMENTC, OFF);
  if (d) digitalWrite(SEGMENTD, OFF);
  if (e) digitalWrite(SEGMENTE, OFF);
  if (f) digitalWrite(SEGMENTF, OFF);
  if (g) digitalWrite(SEGMENTG, OFF);
}

//
// clock_show_colon - shows the colon that separates minutes from seconds
//
void clock_show_colon(void) {
  unsigned short delaytime;

  digitalWrite(COLON, ON); 
  // 2 leds = 2 delays needed
  delaytime = DELAYTIME * 2; // must use variable to have similar delay to rest of clock
  delayMicroseconds(delaytime); // because use of variable slows it down slightly.
  digitalWrite(COLON, OFF);
}

//
// clock_show_alarm - shows the ampm dot (bottom right of clock display)
//
void clock_show_ampm(void) {
  unsigned short delaytime;

  digitalWrite(AMPM, ON);

  delaytime = DELAYTIME; // must use variable to have similar delay to rest of clock
  delayMicroseconds(delaytime); // because use of variable slows it down slightly.
  digitalWrite(AMPM, OFF);
}

 

finker
Offline
Зарегистрирован: 27.04.2012

 спасибо - учту.

а не подскажите непосредственно по моему вопросу ?

Sky
Offline
Зарегистрирован: 04.04.2012

 Распиновку индикатора в студию!

maksim
Offline
Зарегистрирован: 12.02.2012

Вроды в коде она есть

 

Sky
Offline
Зарегистрирован: 04.04.2012

 3-я нога индикатора куда подключена? Из кода я не понял, она у тебя в воздухе висит чтоль?

 

finker
Offline
Зарегистрирован: 27.04.2012

 ваш код залил

точек нету вообще

распиновка 

 

maksim
Offline
Зарегистрирован: 12.02.2012

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

finker
Offline
Зарегистрирован: 27.04.2012

 3 вывод на D4 

maksim
Offline
Зарегистрирован: 12.02.2012

В коде это

#define COLON 4

 

Sky
Offline
Зарегистрирован: 04.04.2012

 Если она у тебя в воздухе их и не будет ибо она отвечает за состояние точки. Подключи ее на 4 пин и будет тебе счастье! :)

finker
Offline
Зарегистрирован: 27.04.2012

 все подключенно

на 4 выводе

finker
Offline
Зарегистрирован: 27.04.2012

 проблема в том что после каждой цыфры стоит точка

Sky
Offline
Зарегистрирован: 04.04.2012

 

void clock_all_off(void) {
228
 
229
  // digits must be ON for any LEDs to be on
230
  digitalWrite(DIGIT1, OFF);
231
  digitalWrite(DIGIT2, OFF);
232
  digitalWrite(DIGIT3, OFF);
233
  digitalWrite(DIGIT4, OFF);
234
 
235
  // segments must be OFF for any LEDs to be on
236
  digitalWrite(SEGMENTA, ON);
237
  digitalWrite(SEGMENTB, ON);
238
  digitalWrite(SEGMENTC, ON);
239
  digitalWrite(SEGMENTD, ON);
240
  digitalWrite(SEGMENTE, ON);
241
  digitalWrite(SEGMENTF, ON);
242
  digitalWrite(SEGMENTG, ON);
243
 
244
  // turn off colon and alarm too
245
  digitalWrite(COLON, ON); Вот тут смотри!!!! ее не гасят!!!! должно быть "digitalWrite(COLON, OFF);"
246
  digitalWrite(AMPM, OFF);
247
}

 

Sky
Offline
Зарегистрирован: 04.04.2012

  А вообще хуже нет ковырять чужой код, сам бы наваял.... глядишь опыту бы набрался... :)

finker
Offline
Зарегистрирован: 27.04.2012

 это уже были мои эксперементы

когда - digitalWrite(COLON, ON) - точек нету вообще

а когда digitalWrite(COLON, OFF) - после каждой цифры стоит точка

нужно чтобы именно стояла точка после 2ой цыфры

допереть не могу 

 

самим писать - опыта маловато еще совсем

finker
Offline
Зарегистрирован: 27.04.2012

 парни а вот здесь не может заноза сидеть ?

void clock_show_colon(void) {
  unsigned short delaytime;

  digitalWrite(COLON, ON);  
                              // 2 leds = 2 delays needed
  delaytime = DELAYTIME * 2;  // must use variable to have similar delay to rest of clock
  delayMicroseconds(delaytime);   //   because use of variable slows it down slightly.
  digitalWrite(COLON, OFF);
}

 

Sky
Offline
Зарегистрирован: 04.04.2012

 Нда...... как то странно видеть динамическую индикацию без прерываний... :) 

С налету то и не скажешь где точка пропадает.....  смотри функцию show_colon()..... вызывается ли и когда и чего делает... поставь большие задержки при зажигании каждого разряда и отслеживай....

В общем переходи к отладке! :)

Заставь эту фунцию моргать диодом на 13-пине.... виднее будет...

finker
Offline
Зарегистрирован: 27.04.2012

 на 13 пине отрабатывает ! 

#define COLON 13 (вместо 4 прописал)

после цифр нету точек 
я в тупике

 

finker
Offline
Зарегистрирован: 27.04.2012

 парни подскажите пож-то

поставил другой индикатор - но там катод и анод наоборот - как в коде заменить значения ?

finker
Offline
Зарегистрирован: 27.04.2012
#define ON HIGH
#define OFF LOW

разобрался, изменил значения - это для цифр

 

digitalWrite(COLON, ON);

 это для моргающих точек

finker
Offline
Зарегистрирован: 27.04.2012

 хотелось бы добавить 1 кнопку на выставление часов и 1 кнопку на выставление минут

и кнопку для выставления будильника (и саму функцию будильника)

помогите пжт реализовать ?

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

Возник вопрос по коду часов:

if (value != 1 || value != 4){
  a = 1
}

 и

  a = !(value == 1 || value == 4);

Это одно и тоже? 

  a = !(value == 1 || value == 4);
  b = !(value == 5 || value == 6);
  c = !(value == 2);
  d = !(value == 1 || value == 4 || value == 7);
  e = (value == 0 || value == 2 || value == 6 || value == 8);
  f = !(value == 1 || value == 2 || value == 3 || value == 7);
  g = !(value == 0 || value == 1 || value == 7);

  if (a) digitalWrite(SEGMENTA, 0);
  if (b) digitalWrite(SEGMENTB, 0);
  if (c) digitalWrite(SEGMENTC, 0);
  if (d) digitalWrite(SEGMENTD, 0);
  if (e) digitalWrite(SEGMENTE, 0);
  if (f) digitalWrite(SEGMENTF, 0);
  if (g) digitalWrite(SEGMENTG, 0);

if (a) digitalWrite(SEGMENTA, 0); это условие без условия. Если правильно понял такая запись сравнивает равно 0 или 1. или не так? и почему если условие выполняется digitalWrite(SEGMENTA, 0) не в фигурных скобках?

Geronimo
Offline
Зарегистрирован: 06.05.2013
if (value != 1 || value != 4){
  a = 1
}

 и

  a = !(value == 1 || value == 4);

не одно и то же

в первом а всегда  будет 1

во втором случае а будет 1 если value отлично от 1 или 4.

 

>>if (a) digitalWrite(SEGMENTA, 0); это условие без условия. Если правильно понял такая запись сравнивает >>равно 0 или 1. или не так? и почему если условие выполняется digitalWrite(SEGMENTA, 0) не в фигурных >>скобках?

 

если а отлично от 0 то функция digitalWrite сработает, иначе нет

в с++ 0 - ложь, все что не 0 истина

Geronimo
Offline
Зарегистрирован: 06.05.2013

>>почему если условие выполняется digitalWrite(SEGMENTA, 0) не в фигурных скобках?

иф выполняет 1 оператор после себя

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

if(a) digitalWrite(SEGMENTA, 0) ;

//то же самое, что

if(a !=0)
{
digitalWrite(SEGMENTA, 0) ;
}

 

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

спасибо. прояснилось)

None
Offline
Зарегистрирован: 15.01.2016

del