кто в этом что-то шарит?

Тема в разделе "Arduino & Shields", создана пользователем NorimyXXXO, 16 май 2016.

  1. ostrov

    ostrov Гуру

    Спасибо.

    Придраться есть к чему, конечно. )

    Не знаю, работает ли он в принципе, правильно ли установлены биты в массивах, все ли собрано соответствующе и так далее. Ну да ладно, будем считать что работает. Тогда, пользуясь вашим же кодом делаем такую функцию:

    Код (C++):
    void disp(int Val) {
      byte digit;
      for (byte i = 0; i < 4; i++) {
        switch (i) {
          case 0:
            digit = Val / 1000;         // тысячи
            break;
          case 1:
            digit = Val / 100 % 10;     // сотни
            break;
          case 2:
            digit = Val / 10 % 10;      // десятки
            break;
          case 3:
            digit = Val % 10;           // единицы
            break;
        }
        digitalWrite(reg, LOW);
        SPI.transfer(digit);
        SPI.transfer(pos[i]);
        digitalWrite(reg, HIGH);
        delay(delayTime);
      }
    }
     
    В loop() вставляем вызов функции примерно так:
    Код (C++):
    void loop() {
      disp (f);
    }
    В loop() же двигаем циферки циклически, как там надо то? Но избегаем delay()! Кстати, в функции disp() тоже его бы заменить хотя бы на delaymicroseconds(), при это достаточно будет 100-150 микросекунд для выравнивания яркости разрядов.
     
  2. NorimyXXXO

    NorimyXXXO Нуб

    интерес берет свое, вы бы могли написать весь этот код с нуля что бы он нормально выглядел и грамотно работал?
     
  3. ostrov

    ostrov Гуру

    Вот вторая часть балета. Для сдвига циферок добавляем до setup такие определения:
    Код (C++):
    int f = 1000; // число для отображения
    unsigned long timerS = 0;
    byte rasr[3] = {1, 0, 2};
    byte ii = 0;
    А в самом loop() сделаем так:
    Код (C++):
    void loop() {
      disp (f);
      if (millis() > timerS) {
        f = (f * 10) % 10000 + rasr[ii];
        ii > 1 ? ii = 0 : ii++;
        timerS = millis() + 100;
      }
    }
    Если я правильно понял, в массиве с цифрами все кроме 0 и 1 закодировано пробелами, значит цифра "2" должна выглядеть как пробел тоже. В моем примере цифра "10" будет двигаться сплава налево через один пробел вечно. С интервалом в десятую секунды. Пробуйте.
     
    Последнее редактирование: 17 май 2016
  4. ostrov

    ostrov Гуру

    И вообще, я кодирую сегменты более наглядно для себя же самого, в бинарном виде, вот так:
    Код (C++):
    byte segment [12] = {
      0b11101110, 0b00100101, 0b01111011, 0b01110111, 0b10110101,
      0b11010111, 0b11011111, 0b01100101, 0b11111111, 0b11110111,
      0b00000000, 0b01010011,
    };
    А вывожу на индикатор не через SPI, а напрямую через порт в цикле. Этим достигается частота кадров порядка 2-3 тысяч в секунду, что на глаз не отличить от статической индикации, то есть очень приятно и ничего не мерцает как у некоторых. )
     
  5. NorimyXXXO

    NorimyXXXO Нуб

    как я понял должен был выйти вот такой код?
    Код (C++):
    // подключаем библиотеку SPI

    #include <SPI.h>
    // провод CS подсоединяем к 8-му пину Arduino
    enum { reg = 8 };
    int f = 1000; // число для отображения
    unsigned long timerS = 0;
    byte rasr[3] = {1, 0, 2};
    byte i = 0;


    void setup()
    {
    // инициализируем SPI
      SPI.begin();  
    // определяем 8-й пин Arduino как выход      
      pinMode(reg, OUTPUT);
     
    }
    //мы разобъем число на тысячи, сотни, десятки и единицы, объявляем их здесь
    int thousand=0, hundreds=0, tens=0, ones=0;
    //время отображения каждой цифры      
    int delayTime=7;      
    //коды цифр на семисегментнике (0-9 и пустота)  
    static uint8_t digit[11] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF};
    // коды позиций зажигаемого семисегментника (крайний, левый, центральный, правый)
    static uint8_t pos[4]= {0xE7,0xEB,0xEB,0xF3};

    void disp(int Val) {
      byte digit;
      for (byte i = 0; i < 4; i++) {
        switch (i) {
          case 0:
            digit = Val / 1000;         // тысячи
            break;
          case 1:
            digit = Val / 100 % 10;     // сотни
            break;
          case 2:
            digit = Val / 10 % 10;      // десятки
            break;
          case 3:
            digit = Val % 10;           // единицы
            break;
        }
        digitalWrite(reg, LOW);
        SPI.transfer(digit);
        SPI.transfer(pos[i]);
        digitalWrite(reg, HIGH);
        delay(delayTime);
      }
    }

    void loop() {
      disp (f);
      if (millis() > timerS) {
        f = (f * 10) % 10000 + rasr[i];
        i > 1 ? i = 0 : i++;
        timerS = millis() + 100;
      }

    //начинаем передачу по SPI
      digitalWrite(reg, LOW);
     
    //передаем код цифры, соответствующей разряду тисяч      
      SPI.transfer(digit[thousand]);
    //выбираем крайний 7-сегментник      
      SPI.transfer(pos[0]);    
    //заканчиваем передачу          
      digitalWrite(reg, HIGH);
    //пауза, равная delayTime            
      delay(delayTime);  
           
    //передаем код цифры, соответствующей разряду сотен      
      SPI.transfer(digit[hundreds]);
    //выбираем левый 7-сегментник      
      SPI.transfer(pos[1]);    
    //заканчиваем передачу          
      digitalWrite(reg, HIGH);
    //пауза, равная delayTime            
      delay(delayTime);                  


    //передаем код цифры, соответствующей разряду десятков        
      digitalWrite(reg, LOW);
      SPI.transfer(digit[tens]);
    //выбираем центральный 7-сегментник          
      SPI.transfer(pos[2]);              
      digitalWrite(reg, HIGH);
      delay(delayTime);
           
    //передаем код цифры, соответствующей разряду единиц
      digitalWrite(reg, LOW);
      SPI.transfer(digit[ones]);
    //выбираем правый 7-сегментник        
      SPI.transfer(pos[3]);              
      digitalWrite(reg, HIGH);
      delay(delayTime);
     
    }
     
     
  6. ostrov

    ostrov Гуру

    Примерно, только выкидываем все лишнее:
    Код (C++):
    #include <SPI.h>

    #define reg 8

    int f = 2102;
    unsigned long timerS = 0;
    byte rasr[3] = {1, 0, 2};
    byte ii = 0;

    static uint8_t digit[11] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xFF};
    static uint8_t pos[4] = {0xE7, 0xEB, 0xEB, 0xF3};

    void setup()
    {
      SPI.begin();
      pinMode(reg, OUTPUT);
    }

    void disp(int Val) {
      byte digit;
      for (byte i = 0; i < 4; i++) {
        switch (i) {
          case 0:
            digit = Val / 1000;         // тысячи
            break;
          case 1:
            digit = Val / 100 % 10;     // сотни
            break;
          case 2:
            digit = Val / 10 % 10;      // десятки
            break;
          case 3:
            digit = Val % 10;           // единицы
            break;
        }
        digitalWrite(reg, LOW);
        SPI.transfer(digit);
        SPI.transfer(pos[i]);
        digitalWrite(reg, HIGH);
        delay(1);
      }
    }

    void loop() {
      disp (f);
      if (millis() > timerS) {
        f = (f * 10) % 10000 + rasr[ii];
        ii > 1 ? ii = 0 : ii++;
        timerS = millis() + 100;
      }
    }
    Коменты может быть были и не лишними. но они меня путали.

    Должно работать если все остальное верно, но я бы сделал по другому. )
     
  7. NorimyXXXO

    NorimyXXXO Нуб

    это всё что осталось от моего говнокода? весь тот бред нужно было записать вот таким кусочком??
     
  8. ostrov

    ostrov Гуру

    Можно бы и короче, например не разбивать на разряды число каждый раз, предварительно собирая его. Проще, короче и правильнее всего для такого случая было бы сделать 3 кадра, например так:
    Код (C++):
    byte kadr[4][3] = {
      1,0,2,1,
      0,2,1,0,
      2,1,0,2,
    }
    и крутить их в цикле. Тогда программка ужалась бы еще раза в два или три.
     
  9. NorimyXXXO

    NorimyXXXO Нуб

    а вот вы говорили прописать через бит сегмент, не могли бы вы написать код с его использованием и ужать его через кадры?
     
  10. ostrov

    ostrov Гуру

    Должно работать, но не проверял, возможно у двухмерного массива перепутаны индексы кое где, если что поменять. Работать будет при условии, повторяюсь, что биты в кодировках сегментов прописаны правильно и подключено все тоже.

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

    #define reg 8

    byte kadr[3][4] = {
      1, 0, 10, 1,
      0, 10, 1, 0,
      10, 1, 0, 10,
    };

    unsigned long timerS = 0;
    byte ii = 0;

    static uint8_t digit[11] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xFF};
    static uint8_t pos[4] = {0xE7, 0xEB, 0xEB, 0xF3};

    void setup()
    {
      SPI.begin();
      pinMode(reg, OUTPUT);
    }

    void loop() {
      if (millis() > timerS) {
        for (byte i = 0; i < 4; i++) {
          digitalWrite(reg, LOW);
          SPI.transfer(kadr[ii][i]);
          SPI.transfer(pos[i]);
          digitalWrite(reg, HIGH);
          delay(1);
        }
        ii > 1 ? ii = 0 : ii++;
        timerS = millis() + 100;
      }
    }
    ПС: давайте ко заменим двоечки на десятки, они точно пустые.
     
  11. NorimyXXXO

    NorimyXXXO Нуб

    а могу я поменять?
    Код (C++):
    static uint8_t digit[11] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xFF};
    static uint8_t pos[4] = {0xE7, 0xEB, 0xEB, 0xF3};

    на

    byte segment [12] = {
      0b11101110, 0b00100101, 0b01111011, 0b01110111, 0b10110101,
      0b11010111, 0b11011111, 0b01100101, 0b11111111, 0b11110111,
      0b00000000, 0b01010011,
    };
     
  12. ostrov

    ostrov Гуру

    Если будет паразитная засветка ненужных разрядов поиграйте задержкой но без фанатизма. Если все равно останется, то надо будет менять способ вывода.
     
  13. ostrov

    ostrov Гуру

    Вот просто так не можете, потому что у вас наверняка другое подключение сегментов. Тут каждая единица соответствует своему сегменту. Кроме того, массив для общих катодов/анодов я не выложил, он тоже зависит от способа подключения. Если у вас цифры выводились, то ничего менять не надо.
     
  14. NorimyXXXO

    NorimyXXXO Нуб

    а если же не заработает, то как быть? не хотелось бы снова вас напрягать и так уже третий день напрягаю(((
     
  15. ostrov

    ostrov Гуру

    Смотря как не заработает. Если он и раньше не работал, то это одно. Если раньше работал а теперь перестал, то это другое. Если работает, но не так как надо, то это третье. Если вообще ничего не собрано, а надо собрать и прописать, то это четвертое и желательно с благодарностью. )
     
  16. NorimyXXXO

    NorimyXXXO Нуб

    пожалуй, вариант 4 самый интересный) какова стоимость прописать этот код в человеческом виде со 100% работой, а то я уже не могу этим заниматься((( исходный мой код - говно, так что не думаю что у меня получиться его "довести до ума"
     
  17. ostrov

    ostrov Гуру

    Для 100% работоспособности кода нужно его писать применительно к конкретной схеме и задаче. То есть либо нужна готовая схема как оно все подключено, либо вы делаете так как вам ее нарисуют. А может быть вам в железе собрать надо сразу, так еще надежнее. Плюс четкое понимание того что должно быть на индикаторе. Как бегает десятка, с одним пробелом, с двумя-тремя или вообще без пробела? С какой скоростью? Может быть вообще сделать на 8 разрядов? Или на 16? Могём и так. Вы опишите что есть и что надо, если это не государственная тайна за которую могу и расстрелять, конечно.
     
  18. NorimyXXXO

    NorimyXXXO Нуб

    то, как оно будет подключено - на ваше усмотрение, лишь бы я потом смог это собрать и запустить. Должно перемещаться число "20" справа на лево ( и вариант как сменить слева на право). бегает число примерно в таком смысле (попробую объяснить на числе 11) "пусто" "пусто"11; "пусто" 11 "пусто"; 11"пусто" "пусто". скорость средняя. как это на 8 или 16 разрядов?
     
  19. ostrov

    ostrov Гуру

    Ну то есть два пробела все таки между числами. То есть 4 кадра. Меняться число будет? Направление меняться будет? Скорость меняться будет?

    8 разрядов и 16 это значит не один индикатор с 4 разрядами, а 2 или 3 или 4. То есть длиннее вся конструкция.

    [​IMG]
     
  20. NorimyXXXO

    NorimyXXXO Нуб

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