16x16 led aansturing met 74HC595/74HC138
10 berichten
• Pagina 1 van 1
16x16 led aansturing met 74HC595/74HC138
Ik heb een 16x16 dot red LED display, uitgerust met een 74HC595 en 74HC138 chip voor de aansturing. Ik had eigenlijk verwacht dat ik net zoals bij een LCD display met chip slechts eenmaal de data naar het display zou hoeven sturen en dat het de control chips er dan voor zouden zorgen dat het zichtbaar blijft tot de volgende update. Dat dat niet zo is, is dat omdat het anders aangestuurd moet worden of omdat het nou eenmaal zo werkt? Het valt mij op dat het verwerken van de gegevens best veel tijd kost. Bij het onderstaande programma (dat steeds een extra pixel aan/uit zet) is het met het oog gewoon te volgen. Zodra ik de update vertraging instel van een seconde valt het hele effect kwijt.
Is dit de manier of zou ik een andere aansturing moeten kiezen?
cpp code
Is dit de manier of zou ik een andere aansturing moeten kiezen?
cpp code
#include <Arduino.h>
//IO
#define LEDARRAY_D 23
#define LEDARRAY_C 22
#define LEDARRAY_B 25
#define LEDARRAY_A 24
#define LEDARRAY_G 27
#define LEDARRAY_DI 26
#define LEDARRAY_CLK 29
#define LEDARRAY_LAT 28
unsigned char Display_Buffer[2];
unsigned char data[32];
const unsigned char *left = &data[0];
const unsigned char *right = &data[16];
uint8_t ledarray[] = {LEDARRAY_A, LEDARRAY_B, LEDARRAY_C, LEDARRAY_D};
void draw(uint8_t x, uint8_t y, boolean on) {
if (x >= 0 && x <= 15 && y >= 0 && y <= 15) {
unsigned char *p = left;
if (x >= 8) {
p = right;
x -= 8;
}
int bitmask = 0b10000000 >> x;
p += y;
if (on) {
*p &= 0xFF ^ bitmask;
} else {
*p |= bitmask;
}
}
}
void setup()
{
Serial.begin(9600);
pinMode(LEDARRAY_D, OUTPUT);
pinMode(LEDARRAY_C, OUTPUT);
pinMode(LEDARRAY_B, OUTPUT);
pinMode(LEDARRAY_A, OUTPUT);
pinMode(LEDARRAY_G, OUTPUT);
pinMode(LEDARRAY_DI, OUTPUT);
pinMode(LEDARRAY_CLK, OUTPUT);
pinMode(LEDARRAY_LAT, OUTPUT);
for (int i = 0; i < 32; i++) {
data[i] = 0b11111111;
}
}
void loop()
{
static int x = 0;
static int y = 0;
static int d = 1;
const unsigned long now = millis();
static unsigned long nextUpdate = now + 500;
if (now >= nextUpdate) {
display(data);
draw(x, y, d > 0);
x++;
if (x == 16) {
x = 0;
y += d;
if (y > 15) {
d = -1;
} else if (y < 0) {
d = 1;
}
}
// nextUpdate = now + 1000;
}
}
//************************************************************
//*************************************************************
void display(const unsigned char data[32])
{
unsigned short i;
unsigned short db1;
unsigned short db2;
for ( i = 0 ; i < 16 ; i++ )
{
digitalWrite(LEDARRAY_G, HIGH);
db1 = data[i];
db2 = data[i + 16];
send(db2);
send(db1);
digitalWrite(LEDARRAY_LAT, HIGH);
delayMicroseconds(1);
digitalWrite(LEDARRAY_LAT, LOW);
delayMicroseconds(1);
scanline(i);
digitalWrite(LEDARRAY_G, LOW);
delayMicroseconds(500);
}
}
//****************************************************
//****************************************************
void scanline(uint8_t line)
{
for (uint8_t i = 0; i < 4; i++) {
digitalWrite(ledarray[i], (line & 0x01) ? HIGH : LOW);
line >>= 1;
}
}
//****************************************************
//****************************************************
void send(uint8_t data)
{
digitalWrite(LEDARRAY_CLK, LOW);
delayMicroseconds(1);
digitalWrite(LEDARRAY_LAT, LOW);
delayMicroseconds(1);
for (uint8_t i = 0 ; i < 8 ; i++ ) {
digitalWrite(LEDARRAY_DI, (data & 0x01) ? HIGH : LOW);
delayMicroseconds(1);
digitalWrite(LEDARRAY_CLK, HIGH);
delayMicroseconds(1);
digitalWrite(LEDARRAY_CLK, LOW);
delayMicroseconds(1);
data >>= 1;
}
}
Advertisement
- nicoverduin
- Berichten: 5043
- Geregistreerd: 13 Mei 2013, 20:57
- Woonplaats: Heemskerk
Re: 16x16 led aansturing met 74HC595/74HC138
Je zou het wat uitnodigender maken als je wat commentaar toevoegt waarom je de dingen doet zoals je ze doet.....
Re: 16x16 led aansturing met 74HC595/74HC138
Tsja, de code is geleend van voorbeeldcode die op de website staat, het originele product kwam zonder enige aanwijzingen...
Ik kwam er vrij snel achter dat een hoge bit betekent 'uit' en een lage bit 'aan', lekker contra-intuïtief. De line selectie in de originele code was een uitgeschreven switch. De timing en de rest is niet aangepast.
Ik kwam er vrij snel achter dat een hoge bit betekent 'uit' en een lage bit 'aan', lekker contra-intuïtief. De line selectie in de originele code was een uitgeschreven switch. De timing en de rest is niet aangepast.
Re: 16x16 led aansturing met 74HC595/74HC138
Ik heb de delayMicroseconds verwijderd. Het programma is nu veel sneller, maar het display is ook minder fel. Als ik in de main loop weer een vertraging toe voeg zie je dat de leds even aan gaan, en dan gelijk weer uit...
Helpt dit? "Each row controlled by two 74hc138, each column controlled by two 74hc595."
Helpt dit? "Each row controlled by two 74hc138, each column controlled by two 74hc595."
Re: 16x16 led aansturing met 74HC595/74HC138
Ik zal dit schema eens goed bestuderen om te begrijpen hoe het e.e.a. werkt...
Re: 16x16 led aansturing met 74HC595/74HC138
zoals je uit het schema kunt halen zijn er hooguit 16 ledjes tegelijk aan, dat heet multiplex, dus je moet steeds een rij met ABC (op de 138) aanzetten en dan met een shift op de 595 bepalen welke ledjes in die rij aan moeten door ze naar Gnd te trekken.
en dat dus telkens 16 keer. dus eigenlijk laat je telkens 1 rij branden en de rest is uit.
dat is wel een nadeel van multiplexen, het voordeel is dat er niet naar elke led 2 draadjes moeten lopen en dan zou je dus veel meer uitgangen nodig hebben. (16*16=256 en dat doe je nu dus met 2*16=32 uitgangen .
die zijn er overigens wel hoor dat je gewoon alle leds apart aanstuurt.
of dat je dit in een chipje oplost, dat bespaart natuurlijk heel veel processor tijd.
en dat dus telkens 16 keer. dus eigenlijk laat je telkens 1 rij branden en de rest is uit.
dat is wel een nadeel van multiplexen, het voordeel is dat er niet naar elke led 2 draadjes moeten lopen en dan zou je dus veel meer uitgangen nodig hebben. (16*16=256 en dat doe je nu dus met 2*16=32 uitgangen .
die zijn er overigens wel hoor dat je gewoon alle leds apart aanstuurt.
of dat je dit in een chipje oplost, dat bespaart natuurlijk heel veel processor tijd.
paul deelen
shooter@home.nl
shooter@home.nl
Re: 16x16 led aansturing met 74HC595/74HC138
@shooter,
Het probleem is iets anders, maar wat weet ik nog niet. Na het schrijven van de data naar de shift registers gaan ze steeds weer uit. Nu heb ik als experiment in display() de for loop niet tot 16 rijen maar tot 4 rijen beperkt. De eerste drie rijen gaan gelijk weer uit, de vierde blijft (fel) aan, ook met een eenmalige aanroep in setup(), dus zonder aanroepen in loop().
Het probleem is iets anders, maar wat weet ik nog niet. Na het schrijven van de data naar de shift registers gaan ze steeds weer uit. Nu heb ik als experiment in display() de for loop niet tot 16 rijen maar tot 4 rijen beperkt. De eerste drie rijen gaan gelijk weer uit, de vierde blijft (fel) aan, ook met een eenmalige aanroep in setup(), dus zonder aanroepen in loop().
Re: 16x16 led aansturing met 74HC595/74HC138
@shooter, wellicht begreep ik je reactie verkeerd, volgens jou is dit correct gedrag? Ik hoef voor die éne regel slechts eenmaal data te sturen, de regel blijft dan weergeven wat er heen geschreven was, en op volledige felheid. Op de Arduino blijven de A,B,C en D pins blijven natuurlijk staan zoals ze waren, maar de DI natuurlijk niet.
Ik kan me ook niet goed voorstellen dat je meer dan de helft van de helderheid verliest omdat de rest van de lijnen steeds doven.
Ik kan me ook niet goed voorstellen dat je meer dan de helft van de helderheid verliest omdat de rest van de lijnen steeds doven.
Re: 16x16 led aansturing met 74HC595/74HC138
sterker nog je hebt maar 1/16 van de totale helderheid, want er is echt maar 1 rij tegelijk aan.
en ja dat is dan steeds de laatste regel natuurlijk.
dat multiplexen moet dus continu doorlopen worden.
en nog snel ook. minimaal 10 keer per seconde.
en dan moet je ook nog een middenweg zoeken tussen snelheid en brandtijd.
om te experimenteren zet eens een delay bij elke regel en per compleet scherm.
als je de regel delay hoog zet zie je elke regel even oplichten.
als je de scherm delay omhoog zet dan gaat het hele display dimmen.
die hele routine komt straks natuurlijk in een functie terecht, zodat je ook nog andere dingen kunt zoals een tijd of een lichtkrant.
en ja dat is dan steeds de laatste regel natuurlijk.
dat multiplexen moet dus continu doorlopen worden.
en nog snel ook. minimaal 10 keer per seconde.
en dan moet je ook nog een middenweg zoeken tussen snelheid en brandtijd.
om te experimenteren zet eens een delay bij elke regel en per compleet scherm.
als je de regel delay hoog zet zie je elke regel even oplichten.
als je de scherm delay omhoog zet dan gaat het hele display dimmen.
die hele routine komt straks natuurlijk in een functie terecht, zodat je ook nog andere dingen kunt zoals een tijd of een lichtkrant.
paul deelen
shooter@home.nl
shooter@home.nl
- nicoverduin
- Berichten: 5043
- Geregistreerd: 13 Mei 2013, 20:57
- Woonplaats: Heemskerk
Re: 16x16 led aansturing met 74HC595/74HC138
En als het dan nog niet werkt.... Dan heb je altijd nog assembly
10 berichten
• Pagina 1 van 1
Wie is er online?
Gebruikers in dit forum: Geen geregistreerde gebruikers en 3 gasten