• English
  • logo

    4-místný 7-segmentový 12-pinový LED + 74HC595

    Popis

    Zobrazení na LED displeji je zařízeno dvěma posuvnými 8-mi bitovými registry 74HC595, kdy jeden slouží ke spínání segmentů na jednom znaku a druhý ke spínání jednotlivých znaků (v tomto zapojení je využito pouze 4 bitů, takže druhá polovina může ovládat další LED). Je použit LED se společnou katodou (GND). Z důvodu malého proudu z pinů arduina je nutné spínat LED přes tranzistory (např. BC547).

    Obvod

    Příklad kódu
    V tomto příkladu je využita knihovna TimerOne.

    #include <TimerOne.h>
    
    const int pinLatch = 9;
    const int pinClock = 8;
    const int pinData = 10;
    
    const int BUFFER_SIZE = 10;
    const int DISPLAY_LENGTH = 4;
    byte disp[DISPLAY_LENGTH];
    byte decimalPointIndex = 255;
    
    byte digits[] = {
      B00111111, //0
      B00000110, //1
      B01011011, //2
      B01001111, //3
      B01100110, //4
      B01101101, //5
      B01111101, //6
      B00100111, //7
      B01111111, //8
      B01101111 //9
    };
    
    float numbers[] = {
      765.4,
      765.912,
      123,
      56.0,
      78.1,
      12.34,
      64.345,
      98,
      1.4,
      5.0,
      0.789,
      0.1,
      .88,
      .123,
      .4567,
      3.7891
    };
    
    int numberIndex = 0;
    
    void setup() {
      Serial.begin(9600);
      Timer1.initialize(10000);
    
      pinMode(pinLatch, OUTPUT);
      pinMode(pinClock, OUTPUT);
      pinMode(pinData, OUTPUT);
    
      setNumber(0);
      Timer1.attachInterrupt(showNumber);
    }
    
    void loop() {
      noInterrupts();
      setNumber(numbers[numberIndex]);
      Serial.println("OK");
      Serial.println(numbers[numberIndex], DEC);
    
      interrupts();
      numberIndex++;
      if (numberIndex > 15)
        numberIndex = 0;
      delay(2000);
    }
    
    void showNumber() {
      byte show = 0;
      for (int i = 0; i < DISPLAY_LENGTH; i++) {
        byte value = digits[disp[i]];
        if (decimalPointIndex == i) value |= 128;
        shiftOut(pinData, pinClock, MSBFIRST, (disp[i] > 9 || disp[i] < 0) ? B00000000 : value);
        shiftOut(pinData, pinClock, MSBFIRST, B00000001 << i);
        digitalWrite(pinLatch, LOW);
        digitalWrite(pinLatch, HIGH);
        delayMicroseconds(1000);
      }
      shiftOut(pinData, pinClock, LSBFIRST, 0);
      shiftOut(pinData, pinClock, LSBFIRST, ~0);
      digitalWrite(pinLatch, LOW);
      digitalWrite(pinLatch, HIGH);
    }
    
    void setNumber(float number) {
      if (number >= 10000 || number < 0) return;
      byte num[BUFFER_SIZE];
      byte dec[BUFFER_SIZE];
      byte numCount = 0;
      byte decCount = 0;
      getWholeNumbers(number, num, numCount);
      getDecimals(number, dec, decCount, 4); // find decimal point
      decimalPointIndex = (byte) 255;
      for (int i = 0; i < DISPLAY_LENGTH; i++) {
        disp[i] = (byte) 255;
      }
      if (number >= 1000.0) {
        for (int i = 0; i < DISPLAY_LENGTH; i++) {
          disp[i] = num[i];
        }
      } else if (number >= 100) {
        int startIndex = 1;
        if (decCount > 0) {
          decimalPointIndex = 2;
          startIndex = 0;
          disp[3] = dec[0];
        }
        for (int i = 0; i < 3; i++) {
          disp[i + startIndex] = num[i];
        }
      } else if (number >= 10) {
        int startIndex = 2;
        if (decCount > 0) {
          int maxDecLength = DISPLAY_LENGTH - numCount;
          int numberOfDP = (maxDecLength < decCount) ? maxDecLength : decCount;
          startIndex = maxDecLength - numberOfDP;
          for (int i = 0; i < numberOfDP; i++) {
            disp[i + startIndex + 2] = dec[i];
          }
          decimalPointIndex = (byte)(startIndex + 1);
        }
        for (int i = 0; i < 2; i++) {
          disp[i + startIndex] = num[i];
        }
      } else {
        int startIndex = 3;
        if (decCount > 0) {
          int maxDecLength = DISPLAY_LENGTH - numCount;
          int numberOfDP = (maxDecLength < decCount) ? maxDecLength : decCount;
          startIndex = maxDecLength - numberOfDP;
          for (int i = 0; i < numberOfDP; i++) {
            disp[i + startIndex + 1] = dec[i];
          }
          decimalPointIndex = (byte)(startIndex);
        }
        for (int i = 0; i < 1; i++) {
          disp[i + startIndex] = num[i];
        }
      }
    }
    
    void getWholeNumbers(float value, byte pData[], byte & count) {
      byte n[BUFFER_SIZE];
      int p = (int) value;
      int l = 1;
      for (int i = 0; i < BUFFER_SIZE; i++) {
        n[i] = (byte)(p % 10);
        p -= n[i];
        if (p > 9)
          l++;
        p /= 10;
      }
    
      count = l;
      for (int i = 0; i < l; i++) {
        pData[i] = n[l - 1 - i];
      }
    }
    
    void getDecimals(float value, byte pData[], byte & count, int maxCount) {
      byte n[BUFFER_SIZE];
      float f = value;
      for (int i = 0; i < BUFFER_SIZE; i++) {
        if (i >= maxCount) {
          n[i] = 0;
        } else {
          f *= 10;
          n[i] = (byte)(fmod(f, 10));
        }
      }
    
      int len = 0;
      for (int i = 0; i < BUFFER_SIZE; i++) {
        if (n[BUFFER_SIZE - 1 - i] == 0) continue;
        len = BUFFER_SIZE - i;
        break;
      }
      count = len;
      for (int i = 0; i < len; i++) {
        pData[i] = n[i];
      }
    }

    Soubory

  • Copyright © 2025 BEERDUINO