Вывод информации на 4 разрядный 7сегментный индикатор при помощи двух 74hc595

Тема в разделе "Arduino & Shields", создана пользователем Nemo31, 8 мар 2015.

  1. Nemo31

    Nemo31 Нуб

    Купил готовый шилд.
    Описания нет. На нем помимо самого индикатора и двух схем 74НС595 есть 5 выходов.
    Если с двумя все ясно (питание и земля), то с остальными - нет.
    QH; RCLK; SCLK
    Помогите пожалуйста разобраться где тут тактирование где данные а где - защелка защёлка.

    В даташитах к 74НС595 есть DS; ST_CP; SH_CP и есть пример кода как с помощью DS; ST_CP; SH_CP можно выводить цифры на индикатор.

    Но как сопоставить QH; RCLK; SCLK на шилде и DS; ST_CP; SH_CP непонятно. Что есть что?
    Метод "тупого подбора" ничего не дал. Да и спалить чего боюсь.

    Помогите пожалуйста, кто знает.
     
  2. ANV

    ANV Гуру

    А прозвонить тестером или посмотреть куда идут дорожки?
     
  3. X-Dron

    X-Dron Гик

    Хотя бы фотку шилда, или ссылку на страничку в магазине, где покупали.
    С вероятностью 95% могу утверждать, что нет там 2-х 74НС595. Вторая микросхема вероятнее всего 74LS247. Если это действительно шилд типа этого.
    http://www.robotshop.com/en/4x-7-segment-arduino-compatible-digit-shield.html
     
    Последнее редактирование: 8 мар 2015
  4. Salk

    Salk Гик

    Нечего там боятся "чего-нибудь спалить", не питание же путаете.
    Похоже, что RCLK - это защелка (SS, STcp); SCLK - тактовый (CLK, SHcp); а QH - остается пин данных (SDI, DS).
    Вообще их везде по разному обозначают, а так ANV верно подметил, что мешает прозвонить мультиметром не посредственно выходы на шилде и к каким выводам микросхем они ведут (74HC595), а там уже по рспиновке узнать, что это.
     
    Nemo31 нравится это.
  5. Nemo31

    Nemo31 Нуб

    Вот ссылка на девайс.
    http://www.aliexpress.com/snapshot/6494994863.html?orderId=65798713751283
    Там именно 2 шт 74 НС595.
    Куда идут дорожки? Они идут под плату, и уже изнутри подходят к ногам.
    Мультиметр есть, ток тямы нет. Ардуино же позиционировалось как мир МК для не посвященных . Вот и повелся. С программированием мне гораздо легче. Вот датчик DS18B20 подключил. Данные получаю на ПК сразу с 3х зон. Осталось по задумке навесить индикаторы рядом с датчиками на вывод температуры. Чтобы по компу мониторить из дома, а визуально видеть показания находясь непосредственно рядом с датчиком.
    Salk - спасибо. Попробую ваше предположение по выходам.
     
  6. Nemo31

    Nemo31 Нуб

    Проверил. Именно так! Все работает. Спасибо.
     
  7. Nemo31

    Nemo31 Нуб

    Добавив датчик ds18b20 - cобрал я все в кучу. Запустил.
    Получил вот такой вот код:

    Код (Text):
    #include <OneWire.h>

    // Диапазон отражения температурных значений на индикаторе max = 327.67 min = 99.99

    byte latchPin = 8;    // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
    byte clockPin = 12;    // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
    byte dataPin = 11;    // Пин "данных" подключен к QH (SDI, DS) входу 74HC595

    // Настройка комбинации для отображения каждого номера на индикаторе
    // Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
    byte g_digits[25]={
      B11000000, B11111001, B10100100, B10110000, B10011001,  // 0 1 2 3 4
      B10010010, B10000010, B11111000, B10000000, B10010000,  // 5 6 7 8 9
      B01000000, B01111001, B00100100, B00110000, B00011001,  // 0. 1. 2. 3. 4.
      B00010010, B00000010, B01111000, B00000000, B00010000,  // 5. 6. 7. 8. 9.
      B01111111, B10111111, B10011100, B11000110,  // точка, прочерк, градус, цельсия
      B11111111, };                                // все сегменты выключены
    byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды

    OneWire ds (10);    // Пин где подвешен ds18b20
    byte data[12];
    float celsius;      // Переменная для хранения измеренной температуры
    int raw;
    unsigned long time=0;
    boolean flag=1;

    void setup()
    { // обозначаем все пины как выходы
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
    }

    void loop()
    {
      if(flag)
      {
        DS_start();
        time=millis();
        flag=0;
      }
      if((millis()-time) > 750 && !flag)
      {
        DS_read();
        flag=1;
      }
      //а здесь постоянно выводим. температуру брать из celsius
      ledDigitDisplay(celsius); // Можете подставить любые значения.
      // Следите чтобы стояла именно "." (например 5.75 а не 5,75) иначе - ошибка компаиляции вам обеспечена
      // Диапазон отражения температурных значений на индикаторе max = 327.67 min = 99.99
      // max - потому что int-диапазон только до 32767
      // min - потому что в не думаю что где то меньше значение потребуется
    }

    void DS_start()
    {
      ds.reset();
      ds.write(0xCC);
      ds.write(0x44); // начать преобразования, с паразитным питанием на в конце
    }

    void DS_read()
    {
      ds.reset();
      ds.write(0xCC);
      ds.write(0xBE); // Чтение Scratchpad
      for (byte i = 0; i < 9; i++)
        { //  нам нужно 9 байт (с сотыми после запятой)
          data[i] = ds.read ();
        }
      raw =  (data[1] << 8) | data[0];  //  Пересчитываем в температуру
      celsius =  (float)raw / 16.0;
    }

    void ledDigitDisplay(float temperature)
      {
        int disp;                  // Переменная для целых чисел температуры            
        int floatingPoint = 0;    // Переменная "плавающая точка" для хранения номера регистра в котором стоит "."
        int index;

        disp = temperature * 100;  // Избавляемся от десятых и сотых (оставляем челую часть числа)
        if (disp < 0) disp = abs(disp); // используем модуль дабы избавиться от минуса. Его мы подставим в процессе
        if (disp > 9999) disp = int (disp / 10); // сдвиг до отображения только десятых в положительном диапазоне > 99.99
        if (temperature <= -10) disp = int (disp / 10); // сдвиг до отображения только десятых в отрицательных диапазонах < -10

        // Определяемся в каком именно разряде ставить точку
        if ((temperature <= -10 && temperature > -100) || (temperature > 100 && temperature < 1000))
            floatingPoint = 1;
        else
            if ((temperature < 0 && temperature > -10) || (temperature > 0 && temperature < 100))
                floatingPoint = 2;
            else floatingPoint = 4;

        if (temperature < -99.99 || temperature > 327.67)
          {
            // Обработаем выход за пределы min и max температур
            for (int i = 0; i < 4; i++)
                Indicate( i, 21 ); // Ставим во всех разрядах прочерки
          }
        else
          {
            if(temperature < 0) Indicate( 3, 21 );  // если значение минусовое то ставим минус в первом индикаторе
            if((disp / 100) < 1) Indicate( 2, 10 );
            if((disp / 10) < 1) Indicate( 1, 0 );
            if(temperature >= 0) index = 4;
              else index = 3;
         
            // Собственно, основной цыкл. Тут все и происходит
            for (int i = 0; i < index; i++)
                {
                  if (i == 0 || disp != 0)
                      if (i == floatingPoint)
                          Indicate( i, (disp % 10) + 10 );
                      else
                          Indicate( i, disp % 10 );
                  else
                    Indicate( i, 24 );
                  disp /= 10;
                }
          }
      }

    void Indicate(byte r, byte x) // Функция собственно, отображения цыфр на индикаторе.
      {
        byte TimeLight = 1;    // Время для разогрева сегментов - не более 2, иначе будет мерцание около-нулевых значений
        byte SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
        byte RazrDisplay=g_registerArray[r];  // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
        digitalWrite(latchPin, LOW);  // устанавливаем синхронизацию "защелки" на LOW
          shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay);  // Записываем информацию для первого регистра (Номер символа)
          shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
        digitalWrite(latchPin, HIGH);  //"защелкиваем" регистр, тем самым устанавливая значения на выходах

        delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
      }
    Самое интересное, что работает! Только вот помигивает немного.
    Подскажите пожалуйста, может кто подскажет как исправить.