Fórum témák

» Több friss téma
Cikkek » IV-12 VFD Óra - Négy csővel
IV-12 VFD Óra - Négy csővel
Szerző: tomcii, idő: Jan 27, 2025, Olvasva: 1131, Oldal olvasási idő: kb. 4 perc
Lapozás: OK   4 / 7

Az előző órának a programját módosítottam olyan értelemben, hogy az akkori egy digitenkénti kijelzés módosult azonos időben négy digitre. A program váza teljesen ugyan az, csak kiegészítettem a nyomógomb kezelésével, valamint switch-case szerkezettel a további adatok megjelenítéséhez az időn felül, mint például: év, hónap, nap és a jelenlegi hőmérséklet. Belekerült itt is a téli és nyári időszámítás automatikus beállítása.

Változók és könyvtárak deklarálása:

#include "Wire.h"
#include "DS3231.h"
#define DS3231 B1101000               // I2C address
const int pinPB = 6;                  // Pushbutton 1
int buttonState;                      // the current reading from the input pin
int lastButtonState = 0;            // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
const unsigned long debounceDelay = 100;     // the debounce time; increase if the output flickers
int readingButton = 0;
int switchCase = 0;

Szegmensek bájtjainak deklarálása és mellettük a lábkiosztások és portok:

byte segment_digit1[] = {0, 1, 2, 3, 4, 5, 8};                      
byte segment_digit2[] = {9, 10, 11, 12, 13, 14, 15};  
byte segment_digit3[] = {18, 19, 20, 21, 22, 23, 31};               
byte segment_digit4[] = {30, 29, 28, 27, 26, 25, 24};

További változók a DS3231-es modulhoz kapcsolódóan, Binárisból decimálisba és decimálisból binárisba való átalakítások, hőmérsékletváltozó és kalibrált értékek hozzáadása:

byte second=0, minute=0, hour=0, weekday=0, day=0, month=0, year=0;
byte year_1000 = 2;
byte year_100 = 0;
byte DECTOBCD(byte val);
byte BCDTODEC(byte val);
byte    Temperature = 0;            // Temperature variable
int8_t  MostSignificantBit = 0;     // MSB will be the whole part of the temperature LSB - Fraction of the temperature - Not used
byte    Calibration = 6;            // Calibration flag
byte degree = 10;                   // To display degree symbol and C

Alprogramok meghívása:

void updateTime();
void printTime();
void print7Digit(byte number);

Téli és nyári időszámítás beállítása:

bool isDaylightSavingTime(int year, int month, int day, int weekday) {
// The Daylight saving time will starts at the last sunday of March
if (month == 3 && (day + 7 - weekday) > 31) {
return true;
}
// The daylight saving time will ends at the last sunday of October
if (month == 10 && (day + 7 - weekday) > 31) {
return false;
}
// From April to September it is always daylight saving time
if (month > 3 && month < 10) {
return true;
}
//The default is the winter time
return false;
}

A program következő része a void setup(), mely minden indítás után csak egyszer fut le. Itt törénik a szegmensek inicializálása, és az I2C kommunikáció inicializálása is:

void setup() {
byte init_segm; // Byte for the segments initialization (for for cycle)
Wire.begin(); // Begin I2C communication

// Initialize segments and pull them down
for (init_segm=0; init_segm pinMode(segment_digit1[init_segm], OUTPUT);
pinMode(segment_digit2[init_segm], OUTPUT);
pinMode(segment_digit3[init_segm], OUTPUT);
pinMode(segment_digit4[init_segm], OUTPUT);
pinMode(pinPB, INPUT);
digitalWrite(segment_digit1[init_segm], HIGH);
digitalWrite(segment_digit2[init_segm], HIGH);
digitalWrite(segment_digit3[init_segm], HIGH);
digitalWrite(segment_digit4[init_segm], HIGH);
}
}

Ezután következik a void loop(), mely minden alkalommal meghívja az alprogramokat, az updateSubroutine()-t és a printSubroutine()-t, mely updateSubroutine()-ban az idő frissítése történik valamint a printSubroutine()-ba a változók kiirása történik a kijelzőre:

  updateSubroutine();               // Call updateTime subroutine - Updates and reads all the things which is needed for this project from the DS3231 each cycle
  printSubroutine();                // Call printTime subroutine
  checkButton();                    // Call checkButton subroutine

Az updateSubroutine()-ban kezdődik meg a kommunikáció a DS3231 modullal, valamint itt történik a másodpercek, percek, órák, hét napjai, nap, hónap és év kiolvasása. Ha például március utolsó hétvégéje van, akkor itt állítja be az óra a nyári időszámítást úgy, hogy hozzáad az órához egyet, majd amikor éjfél lesz (24:00) akkor nullázza, ezért nem fog minden alkalommal csúszni az idő egy órát. Ebben a programban történik a hőmérséklet kiolvasása is (törtszámok nem kerülnek kijelzésre) valamint a nyomógomb figyelés is ebben a programban zajlik le. 

void updateSubroutine() {
Wire.beginTransmission(DS3231);
Wire.write(0x00); // First register, seconds
Wire.endTransmission(); // End transmission of I2C
Wire.requestFrom(DS3231, 7);
second = BCDTODEC(Wire.read() & 0x7f);
minute = BCDTODEC(Wire.read());
hour = BCDTODEC(Wire.read() & 0x3f);
weekday = BCDTODEC(Wire.read());
day = BCDTODEC(Wire.read());
month = BCDTODEC(Wire.read() & 0x1f);
year = BCDTODEC(Wire.read() + 2000);

// Adjust daylight saving mode according to the actual date - On the last sunday of march it will be incremented by 1
if (isDaylightSavingTime(year, month, day, weekday)) {
hour +=1;
if (hour == 24) {
hour = 0;
}
}

// Reading the temperature from the DS3231
Wire.beginTransmission(DS3231);
Wire.write(0x11); // First byte of the temperature register
Wire.endTransmission();
Wire.requestFrom(DS3231, 2);
if(Wire.available() >= 2) {
MostSignificantBit = BCDTODEC(Wire.read());
}
Temperature = MostSignificantBit + Calibration;

A printSubroutine()-ban jelezzük ki az időt, évet, majd a hónapot és napot, valamint a hőmérsékletet. A kijelzésért egy switch-case szerkezet a felelős, mely a nyomógomb megnyomására változtatja a szerkezetét és ennek függvényében jelzi ki vagy az időt, az évet majd két másodperc múlva a hónapot és napot, vagy a hőmérsékletet. 

void printSubroutine() {
  byte printTimeVar;            // Variable for pulling the segments down (to turn them off with a for cycle)  
  // Convert from 24 hour to 12 hour mode
  byte temphour = hour % 24;
  if (temphour == 0) {
    // Not zero based, not one based, but 24 based.
    temphour = 24;
  }  
switch (switchCase){
      case 0:

      print7Digit_Hours_1(temphour / 10);
      print7Digit_Hours_2(temphour % 10);
      print7Digit_Mins_1(minute/10);
      print7Digit_Mins_2(minute%10);
      break;

      
      case 1:
      // Reading the year
      print7Digit_Hours_1(year_1000);
      print7Digit_Hours_2(year_100);
      print7Digit_Mins_1(year/10);
      print7Digit_Mins_2(year%10);
      delay(1000);
      switchCase = 2;
      break;

      case 2:
      // Display Month and Day
      print7Digit_Hours_1(month / 10);
      print7Digit_Hours_2(month % 10);
      print7Digit_Mins_1(day/10);
      print7Digit_Mins_2(day%10);
      delay(1000);
      switchCase = 3;   
      break;

      case 3:
      byte clear_segm;
      for (clear_segm=0; clear_segm        digitalWrite(segment_digit1[clear_segm], HIGH);
        digitalWrite(segment_digit2[clear_segm], HIGH);
        digitalWrite(segment_digit3[clear_segm], HIGH);
        digitalWrite(segment_digit4[clear_segm], HIGH);
      }

      print7Digit_Mins_2(weekday%10);
      delay(1000);
      switchCase = 4;
      break;
      
      case 4:
      // Display Temperature
      print7Digit_Hours_1(Temperature / 10);
      print7Digit_Hours_2(Temperature % 10);
      print7Digit_Mins_1(degree);
      print7Digit_Mins_2(degree);
      delay(1000);
      switchCase = 0;         
      }
}

A szegmenskijelzőkhöz tartozó bitmezők, melyek külön-külön deklarálják a számokat és a °C-hoz tartozó szimbólumot:

void print7Digit_Hours_1(byte number_Hours_1) {
  // Bitfield for digits 0-9
  const byte numtable_Hours_1[] = {
    B11000000,      // 0
    B11111001,      // 1
    B00100100,      // 2
    B00110000,      // 3
    B10011001,      // 4
    B00010010,      // 5
    B10000010,      // 6
    B11111000,      // 7
    B10000000,      // 8
    B10010000, };     // 9
    
  byte litpins_Hours_1 = numtable_Hours_1[number_Hours_1];
  byte nums_Hours_1;
  for (nums_Hours_1=0; nums_Hours_1    digitalWrite(segment_digit1[nums_Hours_1], (litpins_Hours_1>>nums_Hours_1) & 1);
  }
}
// Display a single digit on the 7 segment for Hours 2/2
void print7Digit_Hours_2(byte number_Hours_2) {
  // Bitfield for digits 0-9
  const byte numtable_Hours_2[] = {
    B11000000,      // 0
    B11111001,      // 1
    B00100100,      // 2
    B00110000,      // 3
    B10011001,      // 4
    B00010010,      // 5
    B10000010,      // 6
    B11111000,      // 7
    B10000000,      // 8
    B10010000, };   // 9

    
  byte litpins_Hours_2 = numtable_Hours_2[number_Hours_2];
  byte nums_Hours_2;
  for (nums_Hours_2=0; nums_Hours_2    digitalWrite(segment_digit2[nums_Hours_2], (litpins_Hours_2>>nums_Hours_2) & 1);
  }
}
// Display a single digit on the 7 segment for Minutes 1/2
void print7Digit_Mins_1(byte number_Mins_1) {
  // Bitfield for digits 0-9
  const byte numtable_Mins_1[] = {
    B11000000,      // 0
    B11111001,      // 1
    B00100100,      // 2
    B00110000,      // 3
    B10011001,      // 4
    B00010010,      // 5
    B10000010,      // 6
    B11111000,      // 7
    B10000000,      // 8
    B10010000,      // 9
    B10011100, };    // Celsius degree

    
  byte litpins_Mins_1 = numtable_Mins_1[number_Mins_1];
  byte nums_Mins_1;
  for (nums_Mins_1=0; nums_Mins_1    digitalWrite(segment_digit3[nums_Mins_1], (litpins_Mins_1>>nums_Mins_1) & 1);
  }
}
// Display a single digit on the 7 segment for Minutes 2/2
void print7Digit_Mins_2(byte number_Mins_2) {
  // Bitfield for digits 0-9
  const byte numtable_Mins_2[] = {
    B11000000,      // 0
    B11111001,      // 1
    B00100100,      // 2
    B00110000,      // 3
    B10011001,      // 4
    B00010010,      // 5
    B10000010,      // 6
    B11111000,      // 7
    B10000000,      // 8
    B10010000,      // 9
    B11000110,};    // Letter C
       
  byte litpins_Mins_2 = numtable_Mins_2[number_Mins_2];
  byte nums_Mins_2;
  for (nums_Mins_2=0; nums_Mins_2    digitalWrite(segment_digit4[nums_Mins_2], (litpins_Mins_2>>nums_Mins_2) & 1);
  }
}

A decimálisból binárisba, valamint binárisból decimálisba történő konverzió kapott helyet a program végén:

byte DECTOBCD(byte val) {
return ((val/10)<}
byte BCDTODEC(byte val) {
return (val>>4) * 10 + (val & 0xf);
}

A cikkem végén ismét közzé fogom tenni az .ino fájlt ha valaki tanulni szeretne belőle, vagy épp modosítani szeretné!


A cikk még nem ért véget, lapozz!
Következő: »»   4 / 7
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem