Digitale letterklok (Opgelost)

Hallo,

Ik ben een digitale letterklok aan het maken met de arduino mega. Ik heb een led matrix van 10 op 11 erop aangesloten om zo letters op te lichten, maar mijn leds geven niet genoeg licht.
(Ik laat ze zo snel achter elkaar oplichten dat ze precies heel de tijd aanstaan maar eigenlijk gaan heel de tijd snel aan en uit, maar daardoor geven ze niet genoeg licht...)

Ik denk dat ik mijn code hier voor moet aanpassen maar heb geen idee hoe. Als ik de leds een voor een achter elkaar laat oplichten geven ze wel genoeg licht. Dus het licht niet aan de voorschakelweerstand. (Een led matrix module kan ik niet gebruiken aangezien deze veel te klein is en ik er dan een stuk of 10 moet gebruiken. Vandaar dat ik de de led matrix rechtstreeks aansluit op de arduino. Het is een led matrix die ik zelf gemaakt heb met led, de leds zijn dus met 10 rijen en 11 kolommen aangesloten op de arduino)

Als er nog vragen zijn stel maar, alle hulp is welkom!

Mijn code:

#include <TimerThree.h>

int rijen[] = {10, 11, 12, 13 , 14 , 15 , 16 , 17 , 18 , 19}; // Anode's (Blauw) (pinnen)

int kolommen[] = {20, 21, 22, 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30}; // Kathode's (Groen) (pinnen)

// Array met alle mogelijke coördinaten van de letters

int woorden[] = {0, 0 , 0, 1 , 0, 2 , 0, 3 , 0, 4 , 0, 5 , 0, 6, 0, 7 , 0, 8 , 0, 9 , 0, 10 , 1, 0 , 1, 1 , 1, 2 , 1, 3 , 1, 4 , 1, 5 , 1, 6 , 1, 7 , 1, 8, 1, 9 , 1, 10, 2, 0, 2, 1, 2, 2 , 2, 3 , 2, 4 , 2, 5 , 2, 6 , 2, 7 , 2, 8 , 2, 9 , 2, 10, 3, 0 , 3, 1 , 3, 2 , 3, 3 , 3, 4 , 3, 5 , 3, 6 , 3, 7 , 3, 8 , 3, 9 , 3, 10, 4, 0 , 4, 1 , 4, 2 , 4, 3, 4, 4 , 4, 5 , 4, 6 , 4, 7 , 4, 8 , 4, 9 , 4, 10, 5, 0 , 5, 1 , 5, 2 , 5, 3 , 5, 4 , 5, 5 , 5, 6 , 5, 7 , 5, 8 , 5, 9 , 5, 10, 6, 0, 6, 1 , 6, 2 , 6, 3 , 6, 4 , 6, 5 , 6, 6 , 6, 7 , 6, 8 , 6, 9 , 6, 10, 7, 0 , 7, 1 , 7, 2 , 7, 3 , 7, 4 , 7, 5 , 7, 6 , 7, 7 , 7, 8 , 7, 9 , 7, 10, 8, 0 , 8, 1 , 8, 2 , 8, 3 , 8, 4 , 8, 5 , 8, 6 , 8, 7 , 8, 8 , 8, 9, 8, 10, 9, 0 , 9, 1 , 9, 2 , 9, 3 , 9, 4 , 9, 5 , 9, 6 , 9, 7 , 9, 8 , 9, 9 , 9, 10 };
// H E T K I S A V I J F T I E N B T Z V O O R O V E R M E K W A R T H A L F S P W O V E R V O O R T H G E E N S T W E E P V C D R I E V I E R V I J F Z E S Z E V E N O N E G E N A C H T T I E N E L F T W A A L F B F U U R

int urenArray1[] = {102, 110, 124, 132, 140, 148, 154, 176, 166, 184, 192, 198}; // Declareren van het start punt van het uur
int urenArray2[] = {107, 117, 131, 139, 147, 153, 163, 183, 175, 191, 197, 209}; // Declareren van het eind punt van het uur

int intS = 0; // Variabele voor de seconden
int intH = 1; // Variabele voor het uur
int intM = 5; // Variabele voor de minuten
int intUren; // Tijdelijke variabele voor het uur +1 bij te houden
const byte switchUur = 2; // Drukknop voor het uur
const byte switchMin = 3; // Drukknop voor de minuten

void setup() {
//
// Alle pins van de LED-matrix als output zetten
for (int Pins = 10 ; Pins <= 30; Pins++)
{
pinMode(Pins , OUTPUT);
}

Serial.begin(9600); // bps instellen

// Timer initializeren
Timer3.initialize(1000000); // snelheid van de timer instellen
Timer3.attachInterrupt(VerhoogSeconden); // verhoogseconden als interruptµ

pinMode(2, INPUT); // Pin 2 als input zetten
pinMode(3, INPUT); // Pin 3 als input zetten
attachInterrupt(digitalPinToInterrupt(2), ExtInterrupt_Verhoog_Met_1uur, LOW); // Interrupt aan pin 2 toevoegen
attachInterrupt(digitalPinToInterrupt(3), ExtInterrupt_Verhoog_Met_1min, LOW); // Interrupt aan pin 3 toevoegen

}

void loop() {

toonWoord(0, 5); // het tonen
toonWoord(8, 11); // is tonen
ToonMinuten(); // minuten tonen
ToonUren(); // uren tonen

}

// Externe interrupt om de minuten te verhogen met telkens 1 uur
void ExtInterrupt_Verhoog_Met_1uur()
{

if (digitalRead (switchUur) == HIGH)
{
intH++;
}
else if (intH == 13)
{
intH = 1;
}

delay (1000);

Serial.println("Drukknop waarde m:");
Serial.println(intH);

}

// Externe interrupt om de minuten te verhogen met telkens 1minuut
void ExtInterrupt_Verhoog_Met_1min()
{

if (digitalRead (switchMin) == HIGH)
{
intM++;
}
else if (intM == 60)
{
intM = 0;
intH++;

}

delay (1000);

Serial.println("Drukknop waarde m:");
Serial.println(intM);
}

// Functie om de minuten te laten tonen
void ToonMinuten()
{

if (intM >= 5 && intM < 10)
{
toonWoord(14 , 21); // 5
toonWoord(44 , 51); // over
}

else if (intM >= 10 && intM < 15)
{
toonWoord(22, 29); // 10
toonWoord(44, 51); // over
}

else if (intM >= 15 && intM < 20)
{
toonWoord(56, 65); // kwart
toonWoord(80, 87); // over
}

else if (intM >= 20 && intM < 25)
{
toonWoord(22, 29); // 10
toonWoord(36, 43); // voor
toonWoord(66, 73); // half
}

else if (intM >= 25 && intM < 30)
{
toonWoord(14, 21); // 5
toonWoord(36, 43); // voor
toonWoord(66, 73); // half
}

else if (intM >= 30 && intM < 35)
{
toonWoord(66, 73); // half
}

else if (intM >= 35 && intM < 40)
{
toonWoord(14, 21); // 5
toonWoord(44, 51); // over
toonWoord(66, 73); // half
}

else if (intM >= 40 && intM < 45)
{
toonWoord(22, 29); // 10
toonWoord(44, 51); // over
toonWoord(66, 73); // half
}

else if (intM >= 45 && intM < 50)
{
toonWoord(56, 65); // kwart
toonWoord(88, 95); // voor
}

else if (intM >= 50 && intM < 55)
{
toonWoord(22, 29); // 10
toonWoord(88, 95); // voor
}

else if (intM >= 55 && intM < 60)
{
toonWoord(14, 21); // 5
toonWoord(88, 95); // voor
}

}

// Functie om het uur te laten tonen
void ToonUren() {

// Tijdelijke Variabele die het uur bijhoudt en +1 doet zodat het uur goed wordt getoont op de klok
intUren = intH;

if (intM >= 20) {
intUren++;
}

toonWoord(urenArray1[intUren - 1], urenArray2[intUren - 1]); // Uitlezen van het uur op de klok

// Als de minuut tussen 0 en 5 zitten moet er uur getoont worden op de klok
if (intM == 0 || intM < 5) {
toonWoord(214, 219); //uur
}
}

// Functie om de seconden te verhogen als deze 60 is.
void VerhoogSeconden()
{
intS++;

if (intS == 60)
{
intS = 0;
VerhoogMinuten();
}

}

// Functie om de minuten te verhogen als deze 60 is
void VerhoogMinuten()
{
intM ++;

if (intM == 60)
{
intM = 0;
VerhoogUur();
}

}

// Functie om het uur te verhogen
void VerhoogUur()
{
if (intH == 13)
{
intH = 1;
}
else
{
intH++;
}
}

// Interrupt voor de seconden te verhogen
void InterruptSeconden()
{
VerhoogSeconden();

}

// Functie om de woorden op de klok te tonen ( er moet een begin en eindwaarde mee gegeven worden zodat de functie deze waarden uit de array woorden kan halen)
void toonWoord(int beginwaarde , int eindwaarde)
{
// Alle pinnen worden hoog gezet (er zal dus niks branden)
for (int Pin = 20; Pin <= 30; Pin++)
{
digitalWrite(Pin, HIGH);
}
// Bekijken welke rij aangezet moet worden en welke kolommen laag moeten gezet worden om het woord te tonen
for (int Woord = beginwaarde ; Woord <= eindwaarde ; Woord++)
{

digitalWrite(rijen[woorden[Woord]] , HIGH);
digitalWrite(kolommen[woorden[Woord + 1]] , LOW);
Woord++;
delay(1.8);
}

// Alle rijen terug afzetten
for (int Rij = 10; Rij <= 19; Rij++)
{
digitalWrite(Rij, LOW);
}
}

Sandervandevelde99:
Vandaar dat ik de de led matrix rechtstreeks aansluit op de arduino.

Rechtstreeks aan je i/o pinnen, zonder aparte voeding en transistors of driver chips?

Een 'woord' staat horizontaal op 1 rij. Dus per woord is rijen[woorden[Woord]] steeds dezelfde en kolommen[woorden[Woord + 1]] is steeds een andere.
Als je een woord van 4 letters hebt, zoals 'vier', zet je 1 rij hoog en 4 kolommen laag.

1 i/o pin kan niet voldoende stroom leveren voor 4 LEDs.

Verder, multiplex je per woord. Dat betekent dat een tijd van weinig woorden feller is dan een tijd met veel woorden.

Het is zes uur - 4 woorden, elk woord staat 1/4 van de tijd aan.
Het is vijf over half negen - 6 woorden, elk woord staat 1/6 van de tijd aan.

Verder heb je een delay() in de for-loop die de letters van een woord aan zet. Dus de eerste letter van elk woord staat het langst aan, de laatste letter het kortst. Ik zou die delay buiten die for-loop zetten, en voor dat je alle rijen weer terug af zet. (De waarde die je aan delay() voert is unsigned long, dus 1.8 is hetzelfde als 1. Je kan delayMicroseconds() gebruiken als milliseconden te grofkorrelig zijn. Die 1.8 wordt trouwens als een smiley weergegeven in je post omdat je geen code-tags hebt gebruikt.)

Dit heeft niets met felheid van de LEDs te maken maar de verhoogUur() functie ziet er een beetje anders uit dan de andere verhoog-functies. Zoals het er nu staat krijg je 13 uur.

Zie ook hier: Digital Wordclock leds - LEDs and Multiplexing - Arduino Forum

Bedankt voor de uitleg, mijn leds flikkeren en al niet meer door de delay naar delaymicroseconds aan te passen.
en door er transistors tussen te steken zullen ze ook wel meer licht geven.
Bedankt!

Toch nog 2 tips: (Om mooi soepel en helder te multiplexen is snelheid belangrijk, en de 'donker-tijd' zo kort mogelijk houden. Of beter: de ratio licht/(licht + donker) zo hoog mogelijk.)

In toonWoord hoef je maar 1 rij hoog te zetten. Om voor elke letter dezelfde rij opnieuw hoog te zetten is zonde van de tijd. Je hoeft ook niet alle rijen terug af te zetten, alleen die ene rij die hoog staat. Eerst alle kolommen, dan die ene rij. Dan gaan ze allemaal tegelijk, i.p.v. 1 voor 1.

Aan het eind van de toonWoord() functie zet je alles weer uit. Je kan het ook aan laten, en aan het begin van de (volgende) toonWoord() pas weer uitzetten. Zo is de donker-tijd weer iets korter. (Alleen die ene rij die je de vorige keer hoog hebt gezet. Dus dat moet je onthouden.)

Om de licht/donker ratio hoog te krijgen moet niet alleen de donker-tijd kort zijn, maar ook de licht-tijd lang. (Maar niet zo lang dat het knippert.) De klok 60x per seconde tekenen is ruim voldoende voor een mooi stabiel knipper-vrij beeld. Dat is 16.666... ms per zin. Je langste zin is 6 woorden. Dus 2777 microseconden per woord.