Forum: Mikrocontroller und Digitale Elektronik LED Cube programmieren


von Torben K. (Firma: privat) (schnagglz)


Angehängte Dateien:

Lesenswert?

Nabend :)

Ich habe mir einen 5x5x5 Led Cube gebaut und den mit einer 
selbstgelöteten Platine verkabelt, welche von einem ATMega8a betrieben 
wird.
Das ganze habe ich leider nicht selbst entworfen, weshalb ich auch nicht 
völlig durch die Platine durchblicke (bin ein Amateur in sachen mC 
Programmierung), und nach eurem Rat frage.

1. Bei den Ebenen des Cubes sind die Anoden verlötet, bei den Säulen die 
Kathoden. Herausfinden welche Pins zu den Ebenen führen, konnte ich noch 
recht einfach, da dort eben 1 Pin zu jeweils einer Ebene führt.
Nur stellt sich das Problem, wenn ich einzelne LEDs über einzelne Säulen 
ansteuern will, da für die Säulen nicht jeweils ein Pin des 
Mikrocontrollers zur Verfügung steht, und ich mir nun nicht vorstellen 
kann, wie ich eine Säule ansteuer :(
Das ganze zeigt sich im Schaltplan, welcher sich im Anhang befindet.

Bisher habe ich nur ein simples Programm in C geschrieben, bei welchem 
auf die einzelnen EbenenPins nacheinander Strom gelegt wird, sodass 
jeweils eine Ebene leuchtet.
Das ganze sieht im moment so aus:
----
1
#define F_CPU 8000000UL //8 Mega Herz 
2
#include <util/delay.h>
3
#include <avr/io.h>
4
5
int main(void)                                                                     
6
{
7
  DDRC=0b0011111; //Port C Ausgänge: 0,1,2,3,4
8
  while(1)
9
    {
10
    PORTC=0b0000001;
11
    _delay_ms(30);
12
    PORTC=0b0000011;
13
    _delay_ms(30); 
14
    PORTC=0b0000111;
15
    _delay_ms(30);  
16
    PORTC=0b0001111;
17
    _delay_ms(30);  
18
    PORTC=0b0011111;
19
    _delay_ms(30);
20
    }
21
}
----
2. Das Programm startet sobald es hochgeladen ist nicht direkt. Damit es 
anspringt muss ich ein wenig mit dem Finger über die Lötstellen des 
Wannensteckers gehen, um vermutlich einen "Startimpuls" auszusenden.
Dann fangen meist zunächst einzelne LEDs der gerade angesteuerten Ebenen 
an zu leuchten, und darauf hin die kompletten Ebenen.
Liegt dies vielleicht daran, dass ich im Setup vor der while Schleife 
noch was hinzufügen muss?

Dass die Schaltung ohne "Finger an Lötstellen halten" funktioniert, und 
es möglich ist einzelne LEDs anzusteuern, zeigt auch, dass ein nicht von 
mir geschriebenes Assembler Programm funktioniert. Leider beherrsche ich 
Assembler nicht ansatzweise, und kann in dem Programm so gut wie nichts 
nachvollziehen, und ich muss und möchte den Cube in C programmieren.

Danke im Vorraus schonmal für Ratschläge und Tipps

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Häng den Schaltplan mal in einem Format an, das nicht EAGLE Benutzer 
auch (am besten direkt im Browser) ansehen können, mein Favorit ist 
*.png

von Torben K. (Firma: privat) (schnagglz)


Angehängte Dateien:

Lesenswert?

Entschuldige, hab jetzt n Screenshot als png drangehängt, falls du das 
meintest.

von holger (Gast)


Lesenswert?

>Entschuldige, hab jetzt n Screenshot als png drangehängt, falls du das
>meintest.

Ich denke er meinte etwas was man erkennen kann und keinen
Fliegenschiss auf der Fensterscheibe.

Was man auf jeden Fall erkennen kann ist das
da mal wieder die Abblockkondensatoren fehlen.

von Max H. (hartl192)


Lesenswert?

Man kann zwar fast nichts erkennen, ich vermute aber, dass du die SPI 
Pins erst als Ausgang/Eingang konfigurieren musst und Daten in die 
Schieberegister (74HC595?) scheiben musst. Falls die Pins des ATmega 
nach dem Reset als Eingang konfiguriert sind, sind die Eingänge des 
Schieberegisters floating und du schiebst durch die Berührung der Pins 
irgendwelche mehr oder weniger zufälligen Daten ins Schieberegister.


Wie hast du dir eigentlich vorgestellt, dass die Schaltung sinnvoll 
funktionieren soll, ohne dass du etwas in die Schieberegister scheibst?

Edit: Wenn ich es richtig erkennen kann, ist das Schieberegister 
ziemlich suboptimal am ATmega angeschlossen...

: Bearbeitet durch User
von Torben K. (Firma: privat) (schnagglz)


Lesenswert?

Max H. schrieb:
> Wie hast du dir eigentlich vorgestellt, dass die Schaltung sinnvoll
> funktionieren soll, ohne dass du etwas in die Schieberegister scheibst?

Ganz einfach, hab mir das Ding nicht ausgedacht, soll es nur 
programmieren. Dabei hab ich bisher nur grundlegende Arduino Kenntnisse, 
sonst allgemein weniger Erfahrung.
Ich les mich mal schlau!

von Max H. (hartl192)


Lesenswert?

Torben K. schrieb:
> Ganz einfach, hab mir das Ding nicht ausgedacht, soll es nur
> programmieren.
Ganz ehrlich, wie hast du dir vorgestellt es sinnvoll zu programmieren 
ohne auch nur ein bisschen verstanden zu habe was die Hardware macht, 
das geht höchsten mit einem LED-Cube-Shield...

P.S. Auf deinem Schaltplan kann man kein einziges Wort lesen.

Lesestoff: Porterweiterung mit SPI

: Bearbeitet durch User
von Torben K. (Firma: privat) (schnagglz)


Lesenswert?

Alles klar, Danke. Werde ich mir alles mal anschauen, damit ich da 
reinkomm.

von Torben K. (Firma: privat) (schnagglz)


Lesenswert?

Hab mich jetzt in Sachen Schieberegistern ein wenig schlau gelesen, 
jetzt scheint das alles auch mehr Sinn zu machen.
Hauptsächlich hab ich mich da an diesem Tutorial orientiert:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister

Zum Programmieren:
Die einzelnen Bits, müssen dann über den Seriellen Eingang des 74HC595N 
geschoben werden, und gelangen dann über QH* Ausgang in die nächsten 
Schieberegister, sodass ich damit alle 4 Register "beschieben" kann.

Im Tutorial steht leider nur, wie man dies in Assembler umsetzt, was ich 
leider nicht beherrsche.

Kann jemand verraten, wie ich einzelne Bits über C auf die Register 
schiebe?

von Max H. (hartl192)


Lesenswert?

Torben K. schrieb:
> Kann jemand verraten, wie ich einzelne Bits über C auf die Register
> schiebe?
Soft-SPI Routine in C:
1
unsigned char SPI_transfer( unsigned char value )
2
{
3
  uint8_t bit_ctr;
4
  for(bit_ctr=0;bit_ctr<8;bit_ctr++)   // output 8-bit
5
  {
6
    if(value & 0x80)
7
    {
8
      PORTC |= (1<<PC0);
9
    }
10
    else
11
    {
12
      PORTC &= ~(1<<PC0);    
13
    }
14
15
    value = (value << 1);           // shift next bit into MSB..
16
    PORTC |= (1<<PC6);            // Set SCK high..
17
    if(PINB & (1<<PB7))
18
      value |= 1;             // capture current MISO bit
19
    else
20
      value &= ~1;
21
  
22
    PORTC &= ~(1<<PC6);                  // ..then set SCK low again
23
  }
24
  return(value);                 // return read UINT8
25
}

von Karl H. (kbuchegg)


Lesenswert?

Max H. schrieb:
> Torben K. schrieb:
>> Kann jemand verraten, wie ich einzelne Bits über C auf die Register
>> schiebe?
> Soft-SPI Routine in C:

zu Maxens Routinen.

Den Teil mit der Auswertung des MISO Bits kannst du bei reinen 595 
Anwendungen auch weglassen, solange du nicht vom anderen Ende der 
Schieberegister wieder einliest (aber warum sollte man das bei 595 tun?)

Dafür fehlt noch etwas: Nachdem du alle (bei dir) 4 Schieberegister mit 
den neuen Bits geladen hast, muss RCK noch einmal auf 1 und wieder auf 0 
gewackelt werden, damit die Bits dann auch am Ausgang tatsächlich 
aufscheinen.

: Bearbeitet durch User
von Torben K. (Firma: privat) (schnagglz)


Lesenswert?

Hab das Programm ein wenig angepasst, leider blinkt der Cube immer noch 
nicht. Die Register sind an Port B angeschlossen.
1
#define F_CPU 8000000UL //8 Mega Herz 
2
#include <util/delay.h>
3
#include <avr/io.h>
4
5
unsigned char SPI_transfer(unsigned char value)
6
{
7
  uint8_t bit_ctr;
8
  for(bit_ctr=0;bit_ctr<8;bit_ctr++)   // output 8-bit
9
  {
10
    if(value & 0x80)
11
    {
12
      PORTB |= (1<<PB0);
13
    }
14
    else
15
    {
16
      PORTB &= ~(1<<PB0);
17
    }
18
19
    value = (value << 1);           // shift next bit into MSB..
20
    PORTB |= (1<<PB1);        // Set SCK high..
21
    PORTB &= ~(1<<PB1);             // ..then set SCK low again
22
  }
23
  return(value);                 // return read UINT8
24
}
25
26
int main(void)                                                                     
27
{
28
  DDRC=0b0011111; //Port C Ausgänge: Ebenen: 0,1,2,3,4
29
  DDRB=0b0001111; //Port B Ausgänge: 0=SER, 1=CLOCK, 2=CLEAR, 3=LATCH
30
  
31
  static int timeperiod = 100;
32
  
33
  while(1)
34
    {
35
    SPI_transfer(0b10101010);
36
    SPI_transfer(0b10101010);
37
    SPI_transfer(0b10101010);
38
    
39
    PORTB=0b0001000; //LATCH On-Off
40
    PORTB=0b0000000;
41
    
42
    PORTC=0b0000001;    // Ebene 1-5 Werden angesteuert.
43
    _delay_ms(timeperiod);
44
    PORTC=0b0000010;
45
    _delay_ms(timeperiod); 
46
    PORTC=0b0000100;
47
    _delay_ms(timeperiod);  
48
    PORTC=0b0001000;
49
    _delay_ms(timeperiod);  
50
    PORTC=0b0010000;
51
    _delay_ms(timeperiod);
52
    
53
    }
54
}

Hab ich irgendwas nicht bedacht?

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Ich würde mal die Spannung an den Ausgängen des 74HC595 messen um zu 
sehen ob der Fehler bei der Ansteuerung der 595er liegt.
Zur Fehlersuche wäre ein Schaltplan auf dem man den Text lesen kann 
nicht schlecht.

von Wolfgang (Gast)


Lesenswert?

Torben K. schrieb:
> Entschuldige, hab jetzt n Screenshot als png drangehängt, falls du das
> meintest.

holger schrieb:
> Ich denke er meinte etwas was man erkennen kann und keinen
> Fliegenschiss auf der Fensterscheibe.

Ack

Torben, guck mal in EAGLE unter Menü Datei|Exportieren|Image ...

von Torben K. (Firma: privat) (schnagglz)


Angehängte Dateien:

Lesenswert?

Wolfgang schrieb:
> Torben, guck mal in EAGLE unter Menü Datei|Exportieren|Image ...

Ah vielen Dank, hab jetzt ein erkennbares Bild des Schaltplanes 
angehängt. :)

von Max H. (hartl192)


Lesenswert?

Torben K. schrieb:
> PORTB=0b0001000; //LATCH On-Off
> PORTB=0b0000000;
SCL (RB2) wird in diesen Zeilen auf null gesetzt, das heißt die 
Flipflops des Schieberegister werden dauernd resetiert. RB2 muss 
konstant auf '1' sein.

Die Entkoppelkondensatoren* für die 74HC595 fehlen.

* 100nF zwischen Vdd und Vss bei jeden IC
https://www.mikrocontroller.net/articles/Kondensator#Entkoppelkondensator

: Bearbeitet durch User
von Torben K. (Firma: privat) (schnagglz)


Lesenswert?

Max H. schrieb:
> Die Entkoppelkondensatoren* für die 74HC595 fehlen.

Heißt dass, dass es "nur" optimal wäre Entkoppelkondensatoren 
einzulöten, oder dringend notwendig?

Max H. schrieb:
> * 100nF zwischen Vdd und Vss bei jeden IC

Versteh ich leider nicht so Ganz,
 ? ist Vdd=Vcc, und Vss=Gnd ?

Und hier ist doch ein Kondensator am mC zwischen Vcc und Gnd (C1), der 
somit auch bei den Spannungsversorgungen der Schieberegister wirkt.

von Max H. (hartl192)


Lesenswert?

Torben K. schrieb:
> Max H. schrieb:
>> Die Entkoppelkondensatoren* für die 74HC595 fehlen.
> Heißt dass, dass es "nur" optimal wäre Entkoppelkondensatoren
> einzulöten, oder dringend notwendig?
Es kann ohne funktionieren, muss es aber nicht. Ich habe aber noch keine 
Erfahrung mit fehlenden Entkoppel-Cs gesammelt.

> Max H. schrieb:
>> * 100nF zwischen Vdd und Vss bei jeden IC
>
> Versteh ich leider nicht so Ganz,
>  ? ist Vdd=Vcc, und Vss=Gnd ?
Stimmt, beim 74HC595 heißen die anderes.

> Und hier ist doch ein Kondensator am mC zwischen Vcc und Gnd (C1), der
> somit auch bei den Spannungsversorgungen der Schieberegister wirkt.

Zitat 
https://www.mikrocontroller.net/articles/Kondensator#Entkoppelkondensator
> Jeder Digitalschaltkreis benötigt einen 100nF Keramikkondensator nah
> (kleiner 20mm) an den Anschlüssen von VCC und GND. Je schneller der IC
> schalten kann, umso wichtiger ist er.
> Für jedes Anschlusspaar von VCC und GND eines ICs muss ein Kondensator
> verwendet werden. Sparen geht hier oft schief!

: Bearbeitet durch User
von Torben K. (Firma: privat) (schnagglz)


Lesenswert?

Alles Klar, es lag daran, dass ich den Port B2 (an dem "Clear" 
angeschlossen war) durchgehend auf low hatte.

Jetzt funktioniert alles wie gewollt, B2 ist durchgehend auf High, und 
ich kann die Bits prima schieben, und der Cube leuchtet wie gewollt!

Vielen Dank!

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Die Entkoppel-C's würde ich trotzdem nachrüsten.

von Dirk K. (dekoepi)


Lesenswert?

Habe heute meine gestern angekommenen 74HC595 mal zum Spielen 
ausgepackt. Haben erst nur 3 LEDs mitgespielt, erst nach Einsetzen eines 
100nF CerCo, einmal komplett stromlos machen und neu anstöpseln lief 
das.

Das ist also kein Gewäsch, sondern offenbar für die Zuverlässigkeit der 
Schaltung unabdingbar. Jetzt mal den verlinkten Artikel lesen, ob das da 
auch erklärt wird, warum dem so ist ;)

https://www.youtube.com/watch?v=OMEXsjAo5TE

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.