Помогите с кодом что то запутался.

Тема в разделе "Arduino & Shields", создана пользователем Knyaz243, 28 янв 2022.

  1. Knyaz243

    Knyaz243 Нуб

    Помогите с кодом собираюсь сделать таймер обратного отсчета до 10 минут на 7-ми сегментниках. Нашел на просторах код, немного под себя отредактировал. Только у него отсчет только в секундах а мне нужно чтобы были отдельно минуты на первом разряде а на 2 и3 секунды. Помогите или объясните буду благодарен!!!


    Код (C++):
    #include <math.h>

    int digit_pin[] = {7, 8, 9}; // PWM Display digit pins from left to right

    #define dataPin  10             // пин подключен к входу 74HC595 DS
    #define latchPin 11             // пин подключен к входу 74HC595 ST_CP
    #define clockPin 12             // пин подключен к входу 74HC595 SH_CP


    #define DIGIT_ON  LOW
    #define DIGIT_OFF  HIGH


    int button1=18;    // кнопка старт
    int button2=19;    //кнопка воврата времени к установленному
    int button3=16;    // кнопка - уменьшение таймера
    int button4=17;    // кнопка + увеличение таймера

    int countdown_time = 60;

    struct struct_digits {
        int digit[3];
      };


    void setup() {              
      for (int i=0; i<3; i++) {
        pinMode(digit_pin[i], OUTPUT);
      }

      pinMode(button1,INPUT_PULLUP);
      pinMode(button2,INPUT_PULLUP);
      pinMode(button3,INPUT_PULLUP);
      pinMode(button4,INPUT_PULLUP);
       pinMode(latchPin, OUTPUT);
       pinMode(clockPin, OUTPUT);
       pinMode(dataPin, OUTPUT);
       digitalWrite(latchPin, LOW );    // ставим HIGH на "защёлку", чтобы регистр не принимал сигнал
    }


    void lightNumber(int numberToDisplay) {
      switch (numberToDisplay){

      case 0:
        digitalWrite(latchPin, LOW);  // цифра ноль
        shiftOut(dataPin, clockPin, LSBFIRST, B00000001);
        digitalWrite(latchPin, HIGH);
        break;

      case 1:
        digitalWrite(latchPin, LOW);  // цифра один
        shiftOut(dataPin, clockPin, LSBFIRST, B01001111);
        digitalWrite(latchPin, HIGH);
     
        break;

      case 2:
        digitalWrite(latchPin, LOW);  // цифра два
        shiftOut(dataPin, clockPin, LSBFIRST, B00010010);
        digitalWrite(latchPin, HIGH);
        break;

      case 3:
        digitalWrite(latchPin, LOW);  // цифра три
        shiftOut(dataPin, clockPin, LSBFIRST, B00000110);
        digitalWrite(latchPin, HIGH);
        break;

      case 4:
        digitalWrite(latchPin, LOW);  // цифра четыре
        shiftOut(dataPin, clockPin, LSBFIRST, B01001100);
        digitalWrite(latchPin, HIGH);
        break;

      case 5:
        digitalWrite(latchPin, LOW);  // цифра пять
        shiftOut(dataPin, clockPin, LSBFIRST, B00100100);
        digitalWrite(latchPin, HIGH);
        break;

      case 6:
        digitalWrite(latchPin, LOW);  // цифра шесть
        shiftOut(dataPin, clockPin, LSBFIRST, B00100000);
        digitalWrite(latchPin, HIGH);
        break;

      case 7:
        digitalWrite(latchPin, LOW);  // цифра семь
        shiftOut(dataPin, clockPin, LSBFIRST, B00001111);
        digitalWrite(latchPin, HIGH);
        break;

      case 8:
       digitalWrite(latchPin, LOW);  // цифра восемь
        shiftOut(dataPin, clockPin, LSBFIRST, B00000000);
        digitalWrite(latchPin, HIGH);
        break;

      case 9:
       digitalWrite(latchPin, LOW);  // цифра девять
        shiftOut(dataPin, clockPin, LSBFIRST, B00000100);
        digitalWrite(latchPin, HIGH);
        break;

      case 10:
      digitalWrite(latchPin, LOW);  // очистка всех символов
        shiftOut(dataPin, clockPin, LSBFIRST, B01111111);
        digitalWrite(latchPin, HIGH);
     
        break;
      }
    }

    void SwitchDigit(int digit) {
      for (int i=0; i<3; i++) {
        if (i == digit) {
          digitalWrite(digit_pin[i], DIGIT_OFF);
        } else {
          digitalWrite(digit_pin[i], DIGIT_ON);
        }
      }
    }


    struct struct_digits IntToDigits(int n)
    {
      struct struct_digits dig;
      int zeros=0;
      int d;
      for (int i=0; i<3; i++)
      {
        d=n/pow(10,2-i);// 10 в степени 2,1,0
        zeros += d;
        n = n - d*pow(10,2-i);
        if (zeros!=0 || i==2)
        {
          dig.digit[i]=d;
        } else
        {
          dig.digit[i]=10; //
        }
      }
      return dig;
    }


    void PrintNumber(int n, int time)
    {
      struct struct_digits dig;

      dig = IntToDigits(n);
     
      for (int i=0; i<= time/15; i++)
      {
        if (digitalRead(button2)==LOW)     // кнопка "Reset"
        {
          return;
        }
        for (int j=0; j<3; j++) {
          SwitchDigit(j);
          lightNumber(dig.digit[j]);
          delay(5);
        }
      }
    }

    bool Countdown(int n, int del) // возврат времени к установленному ранее значению кнопка " Reset"
    {
      for (int q=n; q>0; q--)
      {
        PrintNumber(q,del);
        if (digitalRead(button2)==LOW)
        {
          return false;
        }
      }
      PrintNumber(0,0);

      return true;
    }


    void reset()
    {
      int m, zeros, d, pressed3 = 0,pressed4 = 0;
      m=countdown_time;
        struct struct_digits dig;

      dig = IntToDigits(countdown_time);
     
      while (digitalRead(button1)==HIGH) // Кнопка " Start"
      {
        for (int j=0; j<3; j++) {
          SwitchDigit(j);
          lightNumber(dig.digit[j]);
          delay(5);
        }
        if (digitalRead(button3)==LOW) // кнопка "-"
        {
          if (pressed3 == 0 || pressed3 > 30) // скорость уменьшения тайменра
          {
            if (countdown_time > 0)
            {
              countdown_time -= 1 ;
            }
            dig = IntToDigits(countdown_time);
          }
          pressed3 += 1;
        }
                else if (digitalRead(button4)==LOW)   // кнопка "+"
                  {
                if (pressed4 == 0 || pressed4 > 30)  //скорость увеличения таймера
                      {
                if (countdown_time <999)
                         {
                    countdown_time += 1 ;
                         }
                   
                   dig = IntToDigits(countdown_time);
                       }
                  pressed4 += 1;
                   }
        if (digitalRead(button3)==HIGH)
        {
          pressed3=0;
        }
         if (digitalRead(button4)==HIGH) {
         pressed4=0;
        }
      }
    }
    void loop(){
      reset();
      while (!Countdown(countdown_time,962))
      {
        reset();
      }
      while (digitalRead(button2)==1){};
    }
     
  2. b707

    b707 Гуру

    нужно переписать функцию IntToDigits(int n) так, чтобы третью цифру(начиная справа) меняло не после 99 отсчетов, а после 59.
    Тогда третья цифра превратится из сотен секунд в минуты.

    Но вообще код явно писал какой-то новичок, могут быть ошибки и косяки.
     
    Airbus нравится это.
  3. Airbus

    Airbus Радиохулиган Модератор

    [​IMG]
     
    Рокки1945 нравится это.
  4. Knyaz243

    Knyaz243 Нуб

    ну да
     
  5. b707

    b707 Гуру

    сессия?
    Я вам подсказал как делать - дерзайте.
    Писать за вас я не стану.
     
  6. Knyaz243

    Knyaz243 Нуб

    l
    Ну я понял что в этом месте нужно поменять, только как? А какие могут быть косяки? может как то можно понять ? просто хочу человеку помочь, вот только третий день пытаюсь что то написать пока много вопросов((( Сори
     
  7. Knyaz243

    Knyaz243 Нуб

     
  8. b707

    b707 Гуру

    не знаю, может и нет косяков, но вот функция lightNumber(int numberToDisplay) - довольно криво написано, десять одинаковых кейсов где можно было обойтись 3 строчками. Из этого я делаю вывод, что писал начинающий, а начинающие часто делают ошибки...
     
  9. Knyaz243

    Knyaz243 Нуб


    Нет просто, ему нужно сделать табло для проведения соревнований.
    Мог бы и помочь,)или подскажи где почитать полезную информацию. Буду благодарен,+1 в карму))
     
  10. SergeiL

    SergeiL Оракул Модератор

    Так вроде @b707 и помог, написал, что поправить.
    Или в Вашем понимании помочь - это сделать все за вас?
    Вы же взялись помогать человеку, ну сделайте хоть что ни будь, попробуйте разобраться.
    Задавайте вопросы, о том, что не получается, вот увидите - вам помогут! ;)
     
  11. Knyaz243

    Knyaz243 Нуб

    Спасибо. уже пытаюсь
     
  12. Knyaz243

    Knyaz243 Нуб

    Добрый день. Вроде получилось. Не могли бы еще дать совет почему немного подсвечиваются соседние(не задействованные сегменты на дисплее).И еще время отстает секунд на пять за 5 минут с чем это может быть связано? Спасибо

    Код (C++):
    #include <math.h>

    int digit_pin[] = {9, 8, 7}; // PWM Display digit pins from left to right

    #define dataPin  10             // пин подключен к входу 74HC595 DS
    #define latchPin 11             // пин подключен к входу 74HC595 ST_CP
    #define clockPin 12             // пин подключен к входу 74HC595 SH_CP


    #define DIGIT_ON  LOW
    #define DIGIT_OFF  HIGH


    int button1=18;    // кнопка старт
    int button2=19;    //кнопка воврата времени к установленному
    int button3=16;    // кнопка - уменьшение таймера
    int button4=17;    // кнопка + увеличение таймера

    int countdown_time = 135;

    struct struct_digits {
        int digit[3];
      };


    void setup() {              
      for (int i=0; i<3; i++) {
        pinMode(digit_pin[i], OUTPUT);
      }

      pinMode(button1,INPUT_PULLUP);
      pinMode(button2,INPUT_PULLUP);
      pinMode(button3,INPUT_PULLUP);
      pinMode(button4,INPUT_PULLUP);
       pinMode(latchPin, OUTPUT);
       pinMode(clockPin, OUTPUT);
       pinMode(dataPin, OUTPUT);
       digitalWrite(latchPin, LOW );    // ставим HIGH на "защёлку", чтобы регистр не принимал сигнал
    }


    void lightNumber(int numberToDisplay) {
      switch (numberToDisplay){

      case 0:
        digitalWrite(latchPin, LOW);  // цифра ноль
        shiftOut(dataPin, clockPin, LSBFIRST, B00000001);
        digitalWrite(latchPin, HIGH);
        break;

      case 1:
        digitalWrite(latchPin, LOW);  // цифра один
        shiftOut(dataPin, clockPin, LSBFIRST, B01001111);
        digitalWrite(latchPin, HIGH);
     
        break;

      case 2:
        digitalWrite(latchPin, LOW);  // цифра два
        shiftOut(dataPin, clockPin, LSBFIRST, B00010010);
        digitalWrite(latchPin, HIGH);
        break;

      case 3:
        digitalWrite(latchPin, LOW);  // цифра три
        shiftOut(dataPin, clockPin, LSBFIRST, B00000110);
        digitalWrite(latchPin, HIGH);
        break;

      case 4:
        digitalWrite(latchPin, LOW);  // цифра четыре
        shiftOut(dataPin, clockPin, LSBFIRST, B01001100);
        digitalWrite(latchPin, HIGH);
        break;

      case 5:
        digitalWrite(latchPin, LOW);  // цифра пять
        shiftOut(dataPin, clockPin, LSBFIRST, B00100100);
        digitalWrite(latchPin, HIGH);
        break;

      case 6:
        digitalWrite(latchPin, LOW);  // цифра шесть
        shiftOut(dataPin, clockPin, LSBFIRST, B00100000);
        digitalWrite(latchPin, HIGH);
        break;

      case 7:
        digitalWrite(latchPin, LOW);  // цифра семь
        shiftOut(dataPin, clockPin, LSBFIRST, B00001111);
        digitalWrite(latchPin, HIGH);
        break;

      case 8:
       digitalWrite(latchPin, LOW);  // цифра восемь
        shiftOut(dataPin, clockPin, LSBFIRST, B00000000);
        digitalWrite(latchPin, HIGH);
        break;

      case 9:
       digitalWrite(latchPin, LOW);  // цифра девять
        shiftOut(dataPin, clockPin, LSBFIRST, B00000100);
        digitalWrite(latchPin, HIGH);
        break;

      case 10:
      digitalWrite(latchPin, LOW);  // очистка всех символов
        shiftOut(dataPin, clockPin, LSBFIRST, B01111111);
        digitalWrite(latchPin, HIGH);
     
        break;
      }
    }

    void SwitchDigit(int digit) {
      for (int i=0; i<3; i++) {
        if (i == digit) {
          digitalWrite(digit_pin[i], DIGIT_OFF);
        } else {
          digitalWrite(digit_pin[i], DIGIT_ON);
        }
      }
    }


    struct struct_digits IntToDigits(int n)
    {
      struct struct_digits dig;
      int zeros=0;
      int sec;
      int sec1;           //=(n-n/60)/10;
      int sec2;          //=(n-n/60)-sec1;
      int d;
        for (int i=2; i>=0;  i--)
      {                    
                d=n/60;          
                sec=n-d*60;
                sec1=sec/10;
                sec2=sec-sec1*10;
                if (d!=0 && i==2 )
                {
                  dig.digit[i]=d;
                }
                else if (sec<60 && i==1)
                {
                  //sec1=sec/10;
                  dig.digit[i]=sec1;
                }
                else if (sec2<10 && i==0)
                {
                  //sec2=sec-sec1*10;
                  dig.digit[i]=sec2;
                }
                 else
                {
                  dig.digit[i]=10;
                }
                                   
      }
      return dig;
    }

    void PrintNumber(int n, int time)
    {
      struct struct_digits dig;

      dig = IntToDigits(n);

      for (int i=0; i<= time/15; i++)
      {
        if (digitalRead(button2)==LOW)     // кнопка "Reset"
        {
          return;
        }
        for (int j=0; j<3; j++) {
          SwitchDigit(j);
          lightNumber(dig.digit[j]);
          delay(5);
        }
      }
    }



    bool Countdown(int n, int del) // возврат времени к установленному ранее значению кнопка " Reset"
    {
      for (int q=n; q>0; q--)
      {
        PrintNumber(q,del);
        if (digitalRead(button2)==LOW)
        {
          return false;
        }
      }
      PrintNumber(0,0);

      return true;
    }


    void reset()
    {
         int m, zeros, d,  pressed3 = 0,pressed4 = 0;
    //    m=countdown_time;
     
        struct struct_digits dig;
        dig = IntToDigits(countdown_time);

      while (digitalRead(button1)==HIGH) // Кнопка " Start"
      {
        for (int j=0; j<3; j++) {
          SwitchDigit(j);
          lightNumber(dig.digit[j]);
          delay(5);
        }
        if (digitalRead(button3)==LOW) // кнопка "-"
        {
          if (pressed3 == 0 || pressed3 > 30) // скорость уменьшения тайменра
          {
            if (countdown_time > 0)
            {
              countdown_time -= 1 ;
            }
            dig = IntToDigits(countdown_time);
          }
          pressed3 += 1;
        }
                else if (digitalRead(button4)==LOW)   // кнопка "+"
                  {
                if (pressed4 == 0 || pressed4 > 30)  //скорость увеличения таймера
                      {
                if (countdown_time <599)
                         {
                    countdown_time += 1 ;
                         }
                 
                   dig = IntToDigits(countdown_time);
                       }
                  pressed4 += 1;
                   }
        if (digitalRead(button3)==HIGH)
        {
          pressed3=0;
        }
         if (digitalRead(button4)==HIGH) {
         pressed4=0;
        }
      }
    }



    void loop(){
      reset();
      while (!Countdown(countdown_time,962))
      {
        reset();
      }
      while (digitalRead(button2)==1){};
    }
     
    Последнее редактирование: 30 янв 2022
  13. User248

    User248 Гик

    Потому что нет строгой синхронизации. Исполнение кода тоже занимает время, отсюда и погрешность. Нужно сделать прерывание по внутреннему таймеру и выполнять код во время прерывания.
    Вот здесь есть пример кода с прерыванием:
    https://create.arduino.cc/projecthu...r-pedal-b2ba96?ref=user&ref_id=87774&offset=2

    Там все сегменты соединены параллельно? Тогда, из-за скорости стробирования. Нужно попробовать поменять эту скорость. Или слишком большой ток идёт на сегменты.
     

    Вложения:

    Последнее редактирование: 30 янв 2022
  14. SergeiL

    SergeiL Оракул Модератор

    Не знаю как остальным, а для меня этот код оказался за гранью моего понимания. Потерял нить в передаче параметров...
    Прошелся по нему несколько раз, так и не увидел где и чем задается точность тиканья "таймера".
    Похоже просто случайно получилось время около 1сек, или я не понял? :(
     
  15. Knyaz243

    Knyaz243 Нуб

    Спасибо попробую.сА такой еще вопрос можно два отдельных не зависимых друг от друга таймера таким же образозом реализовать на одной Ардуино?
     
  16. User248

    User248 Гик

    Думаю, можно, если хватит выводов данных.

    Кстати, про точность. Здесь в двух местах есть delay(5). Наверно, это и есть регулятор точности хода. Можно заменить их на delayMicroseconds() и уменьшать это значение, если отстаёт. Только в обоих местах одинаковое значение делать.
    Код (C++):

    #define tdelay 5000
    ...
    delayMicroseconds (tdelay);
    ...
    delayMicroseconds (tdelay);
     
     
  17. SergeiL

    SergeiL Оракул Модератор

    Тут, конечно, многое нужно исправлять, например, есть глобальная структура с массивом, и ... локальная с тем же именем (ясное дело, что это уже другая переменная), она же, локальная, как возвращаемое значение из функции, причем в глобальную переменную - Ну это за гранью.

    С чего то нужно начать, чтобы не все сразу переписывать, чтобы не сломать все и сразу.
    Поэтому пока просто меняем одно на другое и проверяем работу.
    Пока ,просто компилируем, загружаем и проверяем, что ничего не сломалось... ;)

    Меняем это:
    Код (C++):
    void lightNumber(int numberToDisplay) {
      switch (numberToDisplay){

      case 0:
        digitalWrite(latchPin, LOW);  // цифра ноль
        shiftOut(dataPin, clockPin, LSBFIRST, B00000001);
        digitalWrite(latchPin, HIGH);
        break;

      case 1:
        digitalWrite(latchPin, LOW);  // цифра один
        shiftOut(dataPin, clockPin, LSBFIRST, B01001111);
        digitalWrite(latchPin, HIGH);
        break;

      case 2:
        digitalWrite(latchPin, LOW);  // цифра два
        shiftOut(dataPin, clockPin, LSBFIRST, B00010010);
        digitalWrite(latchPin, HIGH);
        break;

      case 3:
        digitalWrite(latchPin, LOW);  // цифра три
        shiftOut(dataPin, clockPin, LSBFIRST, B00000110);
        digitalWrite(latchPin, HIGH);
        break;

      case 4:
        digitalWrite(latchPin, LOW);  // цифра четыре
        shiftOut(dataPin, clockPin, LSBFIRST, B01001100);
        digitalWrite(latchPin, HIGH);
        break;

      case 5:
        digitalWrite(latchPin, LOW);  // цифра пять
        shiftOut(dataPin, clockPin, LSBFIRST, B00100100);
        digitalWrite(latchPin, HIGH);
        break;

      case 6:
        digitalWrite(latchPin, LOW);  // цифра шесть
        shiftOut(dataPin, clockPin, LSBFIRST, B00100000);
        digitalWrite(latchPin, HIGH);
        break;

      case 7:
        digitalWrite(latchPin, LOW);  // цифра семь
        shiftOut(dataPin, clockPin, LSBFIRST, B00001111);
        digitalWrite(latchPin, HIGH);
        break;

      case 8:
       digitalWrite(latchPin, LOW);  // цифра восемь
        shiftOut(dataPin, clockPin, LSBFIRST, B00000000);
        digitalWrite(latchPin, HIGH);
        break;

      case 9:
       digitalWrite(latchPin, LOW);  // цифра девять
        shiftOut(dataPin, clockPin, LSBFIRST, B00000100);
        digitalWrite(latchPin, HIGH);
        break;

      case 10:
      digitalWrite(latchPin, LOW);  // очистка всех символов
        shiftOut(dataPin, clockPin, LSBFIRST, B01111111);
        digitalWrite(latchPin, HIGH);
        break;
      }
    }
     
    На это:
    Код (C++):
    const uint8_t    digitFonts[11] = {B00000001, B01001111, B00010010, B00000110, B01001100, B00100100, B00100000, B00001111, B00000000, B00000100,B01111111};

    void lightNumber(int numberToDisplay)
    {
        if ( numberToDisplay >= 0 && numberToDisplay <=10)
        {
            digitalWrite(latchPin, LOW);  // цифра ноль
            shiftOut(dataPin, clockPin, LSBFIRST, digitFonts[numberToDisplay]);
            digitalWrite(latchPin, HIGH);
        }
    }
     
    Пока это самая безобидная замена, но читать код буде несколько проще.
    Выложите схему таймера, а то разбираться по переводу пинов из 1 в 0 и обратно влом.
     
  18. Knyaz243

    Knyaz243 Нуб


    Да спасибо я об этой замене думал(просто пока не дошел до этого , головой понимаю как это должно работать а ккак правильно написать еще не очень только учусь. Вторую неделю этим змнимаюсь) , схему чуть позже закину, в командировку отправили.
     
  19. User248

    User248 Гик

    Knyaz243, ставьте запятые. Трудно читать ваши сообщения.
     
    Последнее редактирование: 2 фев 2022
  20. Knyaz243

    Knyaz243 Нуб

    Добрый день. Попробовал ваши изменения SergeiL по поводу функции отображения цифр, все работает. Так же с помощью задержки подогнал примерно время. Но кажется функция подсчета времени чуть чуть по другому должна работать, поэтому буду сейчас вопрос с ней решать. Еще такой вопрос как изменить кнопку "старт" что бы при последующем нажатии она останавливала время и потом после нажатия опять продолжала отсчет.
    TAIMER 3X ZNACHNII _bb.jpg