#include <Arduino.h>
// Kolejność siatek (od lewej do prawej na ekranie): G9, G8, G7, G6, G5, G4, G3, G2, G1
const uint8_t gridPins[9] = {16, 17, 18, 8, 3, 9, 10, 11, 12};
// Indeksy pinów w tablicy segPins:
// 0=a, 1=j, 2=h, 3=k, 4=b, 5=f, 6=g, 7=m, 8=c, 9=e, 10=v, 11=n, 12=p, 13=d, 14=dp
const uint8_t segPins[15] = {2, 42, 41, 40, 39, 38, 37, 36, 35, 45, 48, 47, 21, 20, 19};
// Definicje czytelnych nazw indeksów dla ułatwienia orientacji
enum { SEG_A = 0, SEG_J, SEG_H, SEG_K, SEG_B, SEG_F, SEG_G, SEG_M, SEG_C, SEG_E, SEG_V, SEG_N, SEG_P, SEG_D, SEG_DP };
// Jawna tablica stanów segmentów dla cyfr 0-9
// Każdy wiersz to cyfra, każda kolumna (0-14) odpowiada segmentowi z enum powyżej
const uint8_t digitSegments[10][15] = {
// A, J, H, K, B, F, G, M, C, E, V, N, P, D, DP
{ 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0 }, // 0
{ 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, // 1
{ 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, // 2
{ 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, // 3
{ 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0 }, // 4
{ 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, // 5
{ 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0 }, // 6
{ 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, // 7
{ 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0 }, // 8
{ 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 } // 9
};
// Bufor cyfr (od lewej G9 do prawej G1)
volatile uint8_t displayBuffer[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
volatile uint8_t currentGrid = 0;
unsigned long lastUpdate = 0;
uint32_t globalCounter = 123456789;
void IRAM_ATTR onTimer() {
portENTER_CRITICAL_ISR(&timerMux);
// BLANKING - gasimy aktualną siatkę
digitalWrite(gridPins[currentGrid], LOW);
// Inkremacja pozycji siatki
currentGrid++;
if (currentGrid >= 9) currentGrid = 0;
// Pełne czyszczenie wszystkich linii segmentów przed nowym rozdaniem
for (int i = 0; i < 15; i++) {
digitalWrite(segPins[i], LOW);
}
// Pobranie cyfry z bufora dla aktualnego wyświetlacza
uint8_t digit = displayBuffer[currentGrid] % 10;
// Wystawienie stanów wysokich tylko na segmenty przypisane do danej cyfry
for (int s = 0; s < 15; s++) {
if (digitSegments[digit][s] == 1) {
digitalWrite(segPins[s], HIGH);
}
}
// Odpalenie zasilania dla zaktualizowanej siatki
digitalWrite(gridPins[currentGrid], HIGH);
portEXIT_CRITICAL_ISR(&timerMux);
}
void setup() {
Serial.begin(115200);
delay(500);
Serial.println("[ESP32] Start czystego mapowania VFD...");
for (int i = 0; i < 9; i++) {
pinMode(gridPins[i], OUTPUT);
digitalWrite(gridPins[i], LOW);
}
for (int i = 0; i < 15; i++) {
pinMode(segPins[i], OUTPUT);
digitalWrite(segPins[i], LOW);
}
timer = timerBegin(1000000);
timerAttachInterrupt(timer, &onTimer);
timerAlarm(timer, 2000, true, 0);
// inicjalizacja bufora startową wartością
uint32_t temp = globalCounter;
for (int i = 8; i >= 0; i--) {
displayBuffer[i] = temp % 10;
temp /= 10;
}
Serial.println("[ESP32] Dynamiczny multipleks.");
}
void loop() {
// Co 500 ms podbijamy licznik i wrzucamy do bufora wyświetlacza
if (millis() - lastUpdate >= 500) {
lastUpdate = millis();
portENTER_CRITICAL(&timerMux);
uint32_t temp = globalCounter;
for (int i = 8; i >= 0; i--) {
displayBuffer[i] = temp % 10;
temp /= 10;
}
if (globalCounter < 999999999)
globalCounter++;
portEXIT_CRITICAL(&timerMux);
}
}Loading
esp32-s3-devkitc-1
esp32-s3-devkitc-1