Прошу помощи в написании секундомера с РАБОЧЕЙ кнопкой на дисплее ТМ1637!!!

sabatur
sabatur аватар
Offline
Зарегистрирован: 26.03.2018

Доброго времени суток, господа!

Я в програмировании почти полный ноль(только поглощаю это дело), и поэтому спустя несколько суток поспешил обратится за помощью.

У меня задача, создать секундомер/счётчик времени, чтобы при нажатой кнопке он отсчитывал, а при отжатой стоял на паузе.

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

Вот первый вариант: 

//Это есть начало сиего треша.
#include <EEPROM.h>
#include <TimerOne.h>
#include <avr/pgmspace.h>
#include <TM1637.h>
#define ON 1
#define OFF 0

int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};
unsigned char ClockPoint = 0;
unsigned char Update;
unsigned char microsecond_10 = 0;
unsigned char second;
unsigned char _microsecond_10 = 0;
unsigned char _second;
unsigned int eepromaddr;
boolean Flag_ReadTime;

#define CLK 4//pins definitions for TM1637 and can be changed to other ports        
#define DIO 5
TM1637 tm1637(CLK,DIO);

void setup()
{
  
  tm1637.set(0);// яркость в скобках от 0 до 7
  tm1637.init();
  Timer1.initialize(97979779);// чем меньше число в скобках, тем быстрее идёт время
  Timer1.attachInterrupt(TimingISR);//declare the interrupt serve routine:TimingISR  
  
}
void loop()
{
 
  if(Update == ON)
  {
    TimeUpdate();
    tm1637.display(TimeDisp);
  }
}

void TimingISR()
{
  microsecond_10 ++;
  Update = ON;
  if(microsecond_10 == 100){
    second ++;
    if(second == 99)
    {
      second = 0;
    }
    microsecond_10 = 0;  
  }
  ClockPoint = (~ClockPoint) & 0x01;
  if(Flag_ReadTime == 0)
  {
    _microsecond_10 = microsecond_10;
    _second = second;
  }
}
void TimeUpdate(void)
{
  if(ClockPoint)tm1637.point(POINT_OFF);//POINT_ON = 1,POINT_OFF = 0; включение и выключение двоеточия
  else tm1637.point(POINT_OFF); 
  TimeDisp[2] = _microsecond_10 / 10;
  TimeDisp[3] = _microsecond_10 % 10;
  TimeDisp[0] = _second / 10;
  TimeDisp[1] = _second % 10;
  Update = OFF;
}
void stopwatchStart()//timer1 on
{
  Flag_ReadTime = 0;
  
}
void stopwatchPause()//timer1 off if [CS12 CS11 CS10] is [0 0 0].
{
  TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
}
void stopwatchReset()
{
  stopwatchPause();
  Flag_ReadTime = 0;
  _microsecond_10 = 0;
  _second = 0;
  microsecond_10 = 0;
  second = 0;
  Update = ON;
}

А вот второй:

 

// неСпортивный секундомер
#include <MsTimer2.h>
#include <TM1637.h>
#include <Button.h>
#define CLK 3
#define DIO 2
TM1637 tm1637(CLK, DIO);

Button buttonReset(16, 10);  // кнопка СБРОС, вывод 16 (A2)
Button buttonStartStop(17, 10);  // кнопка ПУСК/СТОП, вывод 17 (A3)

byte mode = 0; // режим, 0 - СТОП, 1 - ПУСК
unsigned long msTime = 0; // время интервала, милисекунды
byte  minTime = 0; // время интервала, минуты
byte  decMinTime = 0; // время интервала, десятки минуты
unsigned long prevTime;  // предыдущее значение времени
unsigned long curentTime;  // текущее значение времени

//----------------------------------------------------------------------------СЕТАП БЛЯ-----------------------------------------------------------------------------
void setup() {

  MsTimer2::start();               // разрешение прерывания

  tm1637.init(); //инициализация. НЕ ТРОГАТЬ СВОИМИ КРИВЫМИ РУКАМИ
  tm1637.set(0); // яркость от 0 до 7
}

//-------------------------------------------------------------------------------ЛУП БЛЯ-------------------------------------------------------------------------------------------
void loop() {

  //--------------------------------------------------------------------- переключение режима СТАРТ/СТОП-------------------------------------------------------
  if ( buttonStartStop.flagClick == true ) {
    buttonStartStop.flagClick = false; // сброс признака
    // инверсия режима
    if ( mode == 0) {
      mode = 1;                 // СТАРТ

    }
    else {  // СТОП
      mode = 0;

    }
  }

  //----------------------------------------------------------------------------- кнопка СБРОС------------------------------------------------
  if ( buttonReset.flagClick == true ) {
    buttonReset.flagClick = false; // сброс признака
    msTime = 0;
    minTime = 0;
    decMinTime = 0;

  }

  //------------------------------------------------------------------------------- отсчет времени------------------------------------------------
  if ( mode == 0 ) {
    // СТОП
    prevTime = millis();
  }
  else {
    // ПУСК
    curentTime = millis(); // чтение текущего времени
    msTime += curentTime - prevTime;  // прибавление времени к милисекундам
    if ( msTime > 59999 ) {
      // милисекунды переполнились, больше минуты
      msTime -= 60000;
      minTime ++; // +1 к единицам минут
      if ( minTime > 9 ) {
        // единицы минут переполнились
        minTime -= 10;
        decMinTime ++;  // +1 к десяткам минут
      }
    }
    prevTime = curentTime; // перегрузка предыдущего времени
  }

  //--------------------------------------------------------------------------------------------- отображение времени  ------------------------------------------------------------------------
  //Вывод значения счетчика на дисплей
  void TimeUpdate(void)
  {
    if (ClockPoint)tm1637.point(POINT_OFF); //POINT_ON = 1,POINT_OFF = 0; включение и выключение двоеточия
    else tm1637.point(POINT_OFF);
    TimeDisp[2] = _microsecond_10 / 10;
    TimeDisp[3] = _microsecond_10 % 10;
    TimeDisp[0] = _second / 10;
    TimeDisp[1] = _second % 10;
    Update = OFF;
  }

Уважаемые форумчане, жду вашей помощи!

sabatur
sabatur аватар
Offline
Зарегистрирован: 26.03.2018

Вообщем с горем пополам, вышла такая штука:

 

//Это есть начало сиего треша.
#include <EEPROM.h>
#include <TimerOne.h>
#include <avr/pgmspace.h>
#include <TM1637.h>
#define ON 1
#define OFF 0

int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};
unsigned char ClockPoint = 0;
unsigned char Update;
unsigned char microsecond_10 = 0;
unsigned char second;
unsigned char _microsecond_10 = 0;
unsigned char _second;
unsigned int eepromaddr;
boolean Flag_ReadTime;

#define CLK 4//pins definitions for TM1637 and can be changed to other ports        
#define DIO 5
TM1637 tm1637(CLK,DIO);

void setup()
{


  tm1637.set(7);// яркость в скобках от 0 до 7
  tm1637.init();
  Timer1.initialize(999999999);// чем меньше число в скобках, тем быстрее идёт время
  Timer1.attachInterrupt(TimingISR);//declare the interrupt serve routine:TimingISR  
  pinMode(8, OUTPUT);
}

void start ()
{
  
}
void stop ()
{
  
}

void loop()
{
 
  if(Update == ON)
  {
    TimeUpdate();
    tm1637.display(TimeDisp);
  }


 if(digitalRead(8)==HIGH)//если кнопка нажата ...
 {
 Timer1.start (); //включаем светодиод
 delay (3000);
 }
 else//если не нажата...
 {
 Timer1.stop ();//выключаем
 }

}

void TimingISR()
{
  microsecond_10 ++;
  Update = ON;
  if(microsecond_10 == 100){
    second ++;
    if(second == 99)
    {
      second = 0;
    }
    microsecond_10 = 0;  
  }
  ClockPoint = (~ClockPoint) & 0x01;
  if(Flag_ReadTime == 0)
  {
    _microsecond_10 = microsecond_10;
    _second = second;
  }
}
void TimeUpdate(void)
{
  if(ClockPoint)tm1637.point(POINT_OFF);//POINT_ON = 1,POINT_OFF = 0; включение и выключение двоеточия
  else tm1637.point(POINT_OFF); 
  TimeDisp[2] = _microsecond_10 / 10;
  TimeDisp[3] = _microsecond_10 % 10;
  TimeDisp[0] = _second / 10;
  TimeDisp[1] = _second % 10;
  Update = OFF;
}

Оно заработало!)

sabatur
sabatur аватар
Offline
Зарегистрирован: 26.03.2018

Раскажу в кратце что это за устройства планируются. 
Это будет игровым устройством(для квестовых игр), ретривером - для "добычи ресурсов".  Кол-во добытых ресурсов будет отображатся на дисплее. "Добываться" они будут путём замыкания "кнопки" старт(хитрая антуражная система, не суть).  

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

sabatur
sabatur аватар
Offline
Зарегистрирован: 26.03.2018

sabatur
sabatur аватар
Offline
Зарегистрирован: 26.03.2018

Как то так!)

По началу думал для "откачивания" просто сделать другой код, аналогичный кнопке, на обратный отчёт, но в таком случае выкачивающий "ретривер" мог бы качатся от "жертвы" бесконечно, что есть читерство. 

Какие мысли есть на счёт того, чтобы "откачав" груз "ретривера" жертвы до нуля, процесс остановился? 

sabatur
sabatur аватар
Offline
Зарегистрирован: 26.03.2018

Перезалью в тему с другим названием, сие устарело

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sabatur пишет:

спустя несколько суток поспешил 

Дейстительно, поспешил. Поковырялся бы хоть несколько месяцев сам.

Тем более, что 

sabatur пишет:

Оно заработало!)

Точно - поспешил!

sabatur
sabatur аватар
Offline
Зарегистрирован: 26.03.2018

И сроки горят, и сраки горят.
Абсолютно согласен, многому ещё учится, очень многому. 

b707
Offline
Зарегистрирован: 26.05.2017

sabatur пишет:

И сроки горят, и сраки горят.
Абсолютно согласен, многому ещё учится, очень многому. 

Обьясните - нафига вы за это беретесь, если по своим же словам - полный нуль в этом? Еще и сроки какие-то горят...

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

b707 пишет:

Обьясните - нафига вы за это беретесь, если по своим же словам - полный нуль в этом? Еще и сроки какие-то горят...

Ибо сказано, дурину может кодить любая домохозяйка, а домохозяин и подавно. Забыли сказать, что тех.минимум выучить придется. А так, да, истинно, любая домохозяйка умеющая читать. Читать отставить, писать. Вот, теперь правильно.