Jste zde

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: