- 3D-Druck Einstieg und Tipps         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 24

Thema: Ping Pong umprogrammieren?

  1. #11
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Anzeige

    E-Bike
    Hallo

    Ich werde folgendes verwenden:

    WinAVR: http://sourceforge.net/projects/winavr/files/WinAVR/
    KamAVR: http://www.avrfreaks.net/index.php?m...em&item_id=632
    BurnOMat: http://avr8-burn-o-mat.aaabbb.de/
    mySmartUSB: http://shop.myavr.de/Programmer/mySm...p.php&artID=42
    myAVR ProgTool: http://shop.myavr.de/index.php?ws=do...2107_en_de.zip
    (für die Fuses, aber das werden wir wohl nicht benötigen)

    Gruß

    mic

    [Edit]
    Am Samstag um 15 Uhr wurde das Päckchen schon geliefert :)

    Sonntag 16 Uhr:

    Code:
    C:\WinAVR\bin\avrdude.exe -C C:\WinAVR\bin\avrdude.conf -p m8 -P com2 -c AVR910  -U flash:r:C:\Users\mic\Documents\pingpong.hex:a 
    
    Found programmer: Id = "AVR ISP"; type = S
        Software Version = 2.3; Hardware Version = 2.0
    Programmer supports auto addr increment.
    Programmer supports buffered memory access with buffersize = 8 bytes.
    
    Programmer supports the following devices:
    [gekürzt]
    
    Reading | ################################################## | 100% 0.06s
    
    avrdude.exe: Device signature = 0x1e9307
    avrdude.exe: reading flash memory:
    
    Reading | ################################################## | 100% 9.22s
    
    avrdude.exe: writing output file "C:\Users\mic\Documents\pingpong.hex"
    avrdude.exe: output file C:\Users\mic\Documents\pingpong.hex auto detected as Intel Hex
    
    avrdude.exe done.  Thank you.
    ISP mache ich ja eher selten, deshalb ist das für mich auch schon ein kleiner Erfolg ;)
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken packetistangekommen_480.jpg  

  2. #12
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    07.01.2010
    Ort
    Deutschland
    Beiträge
    739
    Ah
    Also ich habe jetzt WinAVR und das neuste AVRStudio.

    Wenn das Paket dann ankommt werde ich mal etwas programmieren.

    Mfg
    bnitram

  3. #13
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Inzwischen kann ich das Teil erfolgreich flashen:

    Bild hier  
    http://www.youtube.com/watch?v=MRRoa1hpnMQ
    http://www.youtube.com/watch?v=JpfsYIkHjlw


    Da wird sich meine Angetraute sicher sehr freuen, wenn ich ihr fünf so Dinger an den Christbaum hänge ;)

    Dieses Beispielprogramm von der elo-Webseite habe ich ausgewählt, weil es zeigt, wie einfach die Daten an die LCD-Matrix ausgegeben werden. Und weil es einen brauchbaren Font mitbringt:

    Code:
    /*
     * laufschrift.c
     *
     * Ein einfache "Laufschrift" auf dem Ping-Pong Board.
     *
     * Kompilierbar mittels AVR Studio 4 oder WinAVR
     *
     * Der Sourcecode und das Hexfile dürfen frei verwendet werden.
     * Nutzung erfolgt auf eigene Gefahr.
     *
     * Ver.     Date         Author           Comments
     * -------  ----------   --------------   ------------------------------
     * 1.00	    07.11.2009   Sascha Bader     initial
     */
    
    
    /* -----------------------------------------
     * Defines (Präprozessor Makros)
     * -----------------------------------------*/
    
    #define F_CPU 8000000UL	                       /* CPU Takt (für delay-Routine) */
    
    #define WIDTH 12                               /* Breite des Displays */
    #define HEIGHT 10                              /* Höhe des Displays */
    #define FONTWIDTH 8                            /* Breite des Zeichensatzes */
    #define FONTHEIGHT 10                          /* Höhe des Zeichensatzes */
    
    #define GetPixel(x,y) leds[y]&(1<<x)           /* Makro: Ein "Pixel" auslesen */
    #define SetPixel(x,y) leds[y]|=1<<x            /* Makro: Ein "Pixel" setzen */
    #define ClearPixel(x,y) leds[y]&=~(1<<x)       /* Makro: Ein "Pixel" löschen */
    
    
    /* -----------------------------------------
     * Includes
     * -----------------------------------------*/
    #include <inttypes.h>		                   /* Definition der Datentypen uint8_t usw. */
    #include <avr/interrupt.h>                     /* Interruptbehandlungsroutinen (für Timerinterrupt) */
    #include <util/delay.h>		                   /* Definition der Verzögerungsfunktionen (_delay_ms) */
    #include <avr/pgmspace.h>                      /* Hilfsfunktionen um Daten aus dem Flash zu lesen */
    #include "font.h"                              /* Definition des Zeichensatzes */
    
    
    /* -----------------------------------------
     * Globale Variablen
     * -----------------------------------------*/
    uint16_t leds[WIDTH];                          /* Inhalt der LED-Matrix */
    prog_uint8_t * fnt = (prog_uint8_t *) font;    /* Zeiger auf den Zeichensatz im Flash */
    volatile uint8_t col = 0;                      /* Aktuelle Spalte (für Interruptroutine)
                                                      "volatile", da durch Interrupt verändert */
    
    /* -----------------------------------------
     * Text der Laufschrift (Globele Variable)
     * -----------------------------------------*/
    prog_uint8_t text[] =
    " Frohes Fest und guten Rutsch :)\
     ~";  /* Ende-Kennzeichen (nicht vergessen) */
    
    /* -----------------------------------------
     * Prototypen der Funktionen
     * -----------------------------------------*/
    void PrintScrollColumn(uint8_t c, int pixelx, int y);
    void ScrollLeft(void);
    
    /* -------------------------------------------------------------------------
     * Main Funktion
     *
     * Initialisiert den Timer Interrupt und
     * behandelt die Laufschrift
     * -------------------------------------------------------------------------*/
    int main(void)
    {
    	uint8_t * tpos;
    	uint8_t softx;
    
    	cli();                              // Interrupts sperren (damit keiner dazwischenfunkt)
    
    	/*---------------------------------------------------
    	 * Ports konfigurieren (Ein-/Ausgänge)
    	 *---------------------------------------------------*/
    	DDRC = 0x0f;   // ( 0x0f PORTC als AD-Eingang)
    	DDRB = 0xff;   //  Portb = Output
    	DDRD = 0xff;   //  Portd = Output
    
    	/*---------------------------------------------------------------------------
    	 * 8-Bit Timer TCCR0 für das Multiplexing der LEDs initialisieren
    	 * Es wird ca. alle 2 Mikrosekunden ein Overflow0 Interrupt ausgelöst
    	 * Berechnung: T = Vorteiler * Wertebereich Zähler / Taktfreuenz
    	 * = 64 * 256 / ( 8000000 Hz ) = 2,048 ms
    	 *---------------------------------------------------------------------------*/
    	TCCR0 |= (1<<CS01) | (1<<CS00);		// 8-bit Timer mit 1/64 Vorteiler
    	TIFR |= (1<<TOV0); 					// Clear overflow flag (TOV0)
    	TIMSK |= (1<<TOIE0); 				// timer0 will create overflow interrupt
    
    	sei();							    // Interrupts erlauben
    
    	/*---------------------------------------------------
    	 * Hauptschleife (Laufschrift erzeugen)
    	 *---------------------------------------------------*/
    	while(1)                                              // Endlosschleife
    	{
    		for (tpos=text;pgm_read_byte(tpos)!='~';tpos++)   // Aktuelles Zeichen lesen
    		{
    			  for (softx=0;softx<FONTWIDTH;softx++)       // Pixel des Zeichens abarbeiten
    			  {
    				ScrollLeft();                             // Platz schaffen und Zeilen nach links schieben
    				PrintScrollColumn(pgm_read_byte(tpos),softx,0);  // Ganz rechts eine Spalte des Zeichens ausgeben
    				_delay_ms(35);                            // Ein bischen warten damit es nicht zu schnell wird
    			  }
    		}
    	}
    	return 0;
    }
    
    /* -------------------------------------------------------------------------
     * Funktion PrintScrollColumn
     *
     * Aktualisiert die Spalte ganz rechts mit
     * einem 1 "Pixel" breitem Ausschnitt des
     * Lauftextes.
     *
     * \param c       Auszugebendes Zeichen
     * \param pixelx  Auszugebende Spalte des Zeichens
     * \param y       Vertikale Vverschiebnung
     * -------------------------------------------------------------------------*/
    void PrintScrollColumn(uint8_t c, int pixelx, int y)
    {
      unsigned char fontbyte = 0;
      uint8_t pixelpos;
      uint8_t fonty;
      uint8_t mask;
    
      pixelpos = pixelx & 0x07;                  /* Auf 8 Pixel pro Zeichen limitieren */
    
      for (fonty=0;fonty<FONTHEIGHT;fonty++)
      {
    	fontbyte = pgm_read_byte_near(fnt+c*FONTHEIGHT+fonty);  /* Ein Byte (Zeile) des aktuellen Zeichens lesen */
    
        mask = 1<<pixelpos;                      /* Maske auf die gewünschte Spalte zurechtschieben */
        if ((fontbyte & mask) != 0)              /* Prüfen ob das Bit in der Spalte des Zeichens gesetzt ist */
        {
            leds[WIDTH-1]|=1<<fonty;             /* Setzen eines Pixels im Display ganz rechts */
        }
        else
        {
            leds[WIDTH-1]&=~(1<<fonty);          /* Löschen eines Pixels im Display ganz rechts */
        }
      }
    }
    
    /* -------------------------------------------------------------------------
     * Funktion ScrollLeft
     *
     * Verschiebt den Inhalt LED-Matrix um eine Spalte nach links.
     * Die erste Spalte tritt dabei an die Position der letzten Spalte.
     * -------------------------------------------------------------------------*/
    void ScrollLeft(void)
    {
      uint8_t xcol;                           /* Spaltenzähler */
      uint16_t first;                         /* Zwischenspeicher der ersten Spalte */
    
      first = leds[0];                        /* Erste Spalte sichern */
      for (xcol=0;xcol<WIDTH-1;xcol++)
      {
    	  leds[xcol]=leds[xcol+1];            /* Spalten nach links verschieben */
      }
      leds[WIDTH-1] = first;                  /* Erste Spalte an letzte Spalte kopieren */
    }
    
    /* -------------------------------------------------------------------------
     * Interrupt Routine
     *
     * Gibt nacheinander alle Spalten mit LED-Daten aus.
     * Dazu wird mittels der Schieberegister die aktuelle Spalte
     * ausgewählt und dann das Bitmuster derselben auf die Ports
     * gegeben.
     * Beim nächsten Interrupt ist dann die nächste Spalte dran.
     * -------------------------------------------------------------------------*/
    // interrupt routine
    SIGNAL (SIG_OVERFLOW0)
    {
    	uint16_t ledval;
    	uint8_t portcout;
    	uint8_t portdout;
    
    	cli();							/* Interrupts verbieten */
    
    	/*--------------------------------------------------
    	 * Aktuelle Spalte ermitteln
    	 *--------------------------------------------------*/
    	col++;
    	if (col == 12)
    	{
    		col = 0;
    	}
    
    	/*--------------------------------------------------
    	 * Ports initialisieren
    	 *--------------------------------------------------*/
    	PORTD = 0;
    	PORTB = 0;
    	PORTC = 0;
    
    	/*---------------------------------------------------
    	 * Eine einzelne 0 durch die Schiebergister schieben
    	 *---------------------------------------------------*/
    	if ( col == 0 )
    	{
    		PORTB &= ~(1 << 4);        /* Bei der ersten Spalte eine 0 ausgeben (PB4 = 0) */
    		                           /* Diese 0 geht auf die Reise durch die Schieberegister */
    	}
    	else
    	{
    		PORTB |= (1 << 4);         /* Danach Einsen hinterherschicken (PB4 = 1) */
    	}
    
    	/*---------------------------------------------------
    	 * Impulse für die Schieberegister generieren
    	 *---------------------------------------------------*/
    	PORTB |= (1 << 3);             /* PB3 = 1 (cl) */
    	PORTB &= ~(1 << 3);            /* PB3 = 0 (!cl) */
    
    	PORTB |= (1 << 2);             /* PB2 = 1 (str) */
    	PORTB &= ~(1 << 2);            /* PB2 = 0 (!str) */
    
    	/*---------------------------------------------------
    	 * Daten der Spalte holen und auf die Ports verteilen
    	 *---------------------------------------------------*/
    	ledval = leds[col];
    	portdout = ledval & 0xff;      /* low byte */
    	portcout = portdout & 0x0f;    /* low nibble */
    	portdout = portdout & 0xf0;    /* high nibble */
    
    	PORTD = portdout & 0xff;
    	PORTC = portcout & 0xff;
    	PORTB = (ledval >> 8) & 0x03;  /* high byte */
    
    	sei();						   /* Interrupts wieder erlauben */
    }
    (Code von http://www.elo-web.de/elo/mikrocontr...ng/laufschrift)

    Gruß

    mic

    [Edit]
    Bild hier  
    http://www.youtube.com/watch?v=tsTk4Un89uA

    Neuer Bildspeicher mit nur 15 Bytes und set()/unset()-Funktionen. Echt ein nettes Spielzeug:

    Code:
    #define F_CPU 8000000UL
    
    #include <inttypes.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    uint8_t bildspeicher[15];
    volatile uint8_t col = 0;
    uint8_t x, y;
    
    void set(uint8_t zeile, uint8_t spalte)
    {
    	uint8_t temp;
    
    	if(zeile < 8)
    	   bildspeicher[spalte] |= (1 << zeile);
    	else
    	{
    		if(spalte<4) temp = 12;
    	   	else if(spalte<8) temp = 13;
    	      	else temp = 14;
    		if(zeile & 1) bildspeicher[temp] |= (1<<((spalte%4)*2+1));  // Zeile 10
    		   else bildspeicher[temp] |= (1<<(spalte%4)*2); // Zeile 9
    	}
    }
    
    void unset(uint8_t zeile, uint8_t spalte)
    {
    	uint8_t temp;
    
    	if(zeile < 8)
    	   bildspeicher[spalte] &= ~(1 << zeile);
    	else
    	{
    		if(spalte<4) temp = 12;
    	   	else if(spalte<8) temp = 13;
    	      	else temp = 14;
    		if(zeile & 1) bildspeicher[temp] &= ~(1<<((spalte%4)*2+1));  // Zeile 10
    		   else bildspeicher[temp] &= ~(1<<(spalte%4)*2); // Zeile 9
    	}
    }
    
    int main(void)
    {
    	cli();
    
    	DDRC = 0x0f;
    	DDRB = 0xff;
    	DDRD = 0xff;
    
    	/*---------------------------------------------------------------------------
    	 * 8-Bit Timer TCCR0 für das Multiplexing der LEDs initialisieren
    	 * Es wird ca. alle 2 Mikrosekunden ein Overflow0 Interrupt ausgelöst
    	 * Berechnung: T = Vorteiler * Wertebereich Zähler / Taktfreuenz
    	 * = 64 * 256 / ( 8000000 Hz ) = 2,048 ms
    	 *---------------------------------------------------------------------------*/
    	TCCR0 |= (1<<CS01) | (1<<CS00);		// 8-bit Timer mit 1/64 Vorteiler
    	TIFR |= (1<<TOV0); 					// Clear overflow flag (TOV0)
    	TIMSK |= (1<<TOIE0); 				// timer0 will create overflow interrupt
    
    	sei();							    // Interrupts erlauben
    
    	while(1)
    	{
          for(x=0; x<15; x++) bildspeicher[x] = 0b10101010;
          _delay_ms(500);
          for(x=0; x<15; x++) bildspeicher[x] = 255; // alle LEDs an
          _delay_ms(1000);
          for(x=0; x<15; x++) bildspeicher[x] = 0; // alle LEDs aus
          _delay_ms(500);
    
    	   for(x=0; x<12; x++)
    	      for(y=0; y<10; y++)
    	      {
    	         set(y, x);
    	         _delay_ms(25);
    			}
          _delay_ms(1000);
    
    	   for(y=10; y; y--)
    			for(x=12; x; x--)
    	      {
    	         unset(y-1, x-1);
    	         _delay_ms(25);
    			}
          _delay_ms(1000);
    	}
    	return (0);
    }
    
    /* -------------------------------------------------------------------------
     * Interrupt Routine
     *
     * Gibt nacheinander alle Spalten mit LED-Daten aus.
     * Dazu wird mittels der Schieberegister die aktuelle Spalte
     * ausgewählt und dann das Bitmuster derselben auf die Ports
     * gegeben.
     * Beim nächsten Interrupt ist dann die nächste Spalte dran.
     * -------------------------------------------------------------------------*/
    // interrupt routine
    SIGNAL (SIG_OVERFLOW0)
    {
    	uint16_t ledval;
    	uint8_t portcout;
    	uint8_t portdout;
    
    	cli();							/* Interrupts verbieten */
    
    	/*--------------------------------------------------
    	 * Aktuelle Spalte ermitteln
    	 *--------------------------------------------------*/
    	col++;
    	if (col == 12)
    	{
    		col = 0;
    	}
    
    	/*--------------------------------------------------
    	 * Ports initialisieren
    	 *--------------------------------------------------*/
    	PORTD = 0;
    	PORTB = 0;
    	PORTC = 0;
    
    	/*---------------------------------------------------
    	 * Eine einzelne 0 durch die Schiebergister schieben
    	 *---------------------------------------------------*/
    	if ( col == 0 )
    	{
    		PORTB &= ~(1 << 4);        /* Bei der ersten Spalte eine 0 ausgeben (PB4 = 0) */
    		                           /* Diese 0 geht auf die Reise durch die Schieberegister */
    	}
    	else
    	{
    		PORTB |= (1 << 4);         /* Danach Einsen hinterherschicken (PB4 = 1) */
    	}
    
    	/*---------------------------------------------------
    	 * Impulse für die Schieberegister generieren
    	 *---------------------------------------------------*/
    	PORTB |= (1 << 3);             /* PB3 = 1 (cl) */
    	PORTB &= ~(1 << 3);            /* PB3 = 0 (!cl) */
    
    	PORTB |= (1 << 2);             /* PB2 = 1 (str) */
    	PORTB &= ~(1 << 2);            /* PB2 = 0 (!str) */
    
    	/*---------------------------------------------------
    	 * Daten der Spalte holen und auf die Ports verteilen
    	 *---------------------------------------------------*/
    	ledval = bildspeicher[col];
    	portdout = ledval & 0xff;      /* low byte */
    	portcout = portdout & 0x0f;    /* low nibble */
    	portdout = portdout & 0xf0;    /* high nibble */
    
    	PORTD = portdout & 0xff;
    	PORTC = portcout & 0xff;
    	if(col<4) ledval=bildspeicher[12];
    		else if(col<8) ledval=bildspeicher[13];
    			else ledval=bildspeicher[14];
    	PORTB = (ledval >> (col%4)*2) & 0x03;  /* high byte */
    
    	sei();						   /* Interrupts wieder erlauben */
    }
    Angehängte Dateien Angehängte Dateien
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #14
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    07.01.2010
    Ort
    Deutschland
    Beiträge
    739
    Hallo,
    Sieht sehr gut aus was du da gemacht hasst!
    Aber eine Frage habe ich noch:
    Ich habe das Ping Pong jetzt zuammen gebaut und warte nur noch auf den Programmer.
    Ich habe festgestellt das überwiegent KamAVR bei Elo-web benutzt wird.(radbruch benutzt es auch)
    Was mus ich in der IDE einstellen damit ich das PingPong programmieren kann??
    Muss ich irrgentetwas beachten??

    Mfg
    bnitram

  5. #15
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Um das Spiel zu testen kann man auch mit den Fingern auf P1 bis P4 oder C4 (Selbsttest) rumfummeln. Das Programm erkennt den Hautwiderstand dann als Poti ;)

    Meine Einstellungen beim KAMAvr, zusätzlich muss man dem Programm noch einmalig (klappt bei mir allerdings grad noch nicht) mitteilen, wo die WINAvr-Installation ist:

    Bild hier  

    Um die Makefiles braucht man sich dann nicht mehr kümmern, denn die werden automatisch erzeugt. Um ein neues Projekt anzulegen (oder um das aktuelle Projekt zu Clonen) speichere ich zuerst das Projekt mit [File->Save Project as..] und anschliessend die Datei mit [File->Save File as...] jeweils mit dem neuen Namen ab. Nach dem Speichern der Datei lasse ich dann noch die Projektdatei in den neuen Namen ändern (PopUp mit [Ja] beantworten) und fertig. Zusätzliche C-Dateien (wie z.B. asuro.c) werden über einen Rechtsklick auf "Files" (über dem test.c) und "Add File..." eingebunden. Die erzeugte Hex-Datei trägt immer den Projektnamen.

    Mit dem aktuellen Treiber wurde mein mySmartUSB als serieller Programmer eingebunden. Deshalb sollte meine Einstellung (über [Settings->AVRDUDE]) auch mit dem einfachen seriellen Programmer funktionieren:

    Bild hier  

    COM muss man an die eigenen Verhältnisse anpassen. (btw. hat auch mein HighTech-Board noch eine echte serielle Schnittstelle :)

    Gruß

    mic

    [Edit]
    Bild hier  
    http://www.youtube.com/watch?v=ofswO2OCq-U

    Leider ist das Video schlecht, aber mit etwas gutem Willen kann man die vier Helligkeitsstufen erkennen. Interessanterweise zeigen die blauen Phantomleds bei Sekunde drei und vier genau den gewollten Effekt;)

    Der ungeputzte Quellcode:
    Code:
    #define F_CPU 8000000UL
    
    #include <inttypes.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <avr/pgmspace.h>
    
    #define colors 4 // Anzahl der Farbebenen
    
    uint8_t bildspeicher[colors][15];
    volatile uint8_t col = 0;
    uint8_t x, y;
    
    void set(uint8_t x, uint8_t y, uint8_t c);
    
    int main(void)
    {
    	cli();
    
    	DDRC = 0x0f;
    	DDRB = 0xff;
    	DDRD = 0xff;
    
    	/*---------------------------------------------------------------------------
    	 * 8-Bit Timer TCCR0 für das Multiplexing der LEDs initialisieren
    	 * Es wird ca. alle 2 Mikrosekunden ein Overflow0 Interrupt ausgelöst
    	 * Berechnung: T = Vorteiler * Wertebereich Zähler / Taktfreuenz
    	 * = 64 * 256 / ( 8000000 Hz ) = 2,048 ms
    	 *---------------------------------------------------------------------------*/
    	TCCR0 |= (1<<CS01) | (0<<CS00);		// 8-bit Timer mit 1/8 Vorteiler !!!!!!!!!!
    	TIFR |= (1<<TOV0); 					// Clear overflow flag (TOV0)
    	TIMSK |= (1<<TOIE0); 				// timer0 will create overflow interrupt
    
    	sei();							    // Interrupts erlauben
    
       for(x=0; x<15; x++)
    		for(y=0; y<colors; y++)bildspeicher[y][x] = 0b10101010; // voll hell
       _delay_ms(300);
    	   for(x=0; x<12; x++)
    	   	for(y=0; y<10; y++)
    				set(x, y, (x/3)%colors+1); // Helligkeitsstufen anzeigen
       _delay_ms(2000);
       for(x=0; x<15; x++)
    		for(y=0; y<colors; y++)bildspeicher[y][x] = 0; // alle LEDs in allen Ebenen aus
    
    	while(1)
    	{
    	   for(x=0; x<12; x++)
    	   	for(y=0; y<10; y++)
    				set(x, y, ((x+1)^(y+3)^(col+5))%colors+1); // Zufallsfarbe ;)
          _delay_ms(100);
    	}
    	return (0);
    }
    
    SIGNAL (SIG_OVERFLOW0)
    {
    	static uint8_t ebene=0;
    	uint16_t ledval;
    	uint8_t portcout;
    	uint8_t portdout;
    
    	cli();							/* Interrupts verbieten */ // aha ;)
    
    	PORTD = 0;
    	PORTB = 0;
    	PORTC = 0;
    
    	if ( col == 0 ) PORTB &= ~(1 << 4);/* Bei der ersten Spalte eine 0 ausgeben (PB4 = 0) */
    		else PORTB |= (1 << 4);         /* Danach Einsen hinterherschicken (PB4 = 1) */
    
    	PORTB |= (1 << 3);             /* PB3 = 1 (cl) */
    	PORTB &= ~(1 << 3);            /* PB3 = 0 (!cl) */
    
    	PORTB |= (1 << 2);             /* PB2 = 1 (str) */
    	PORTB &= ~(1 << 2);            /* PB2 = 0 (!str) */
    
    	/*---------------------------------------------------
    	 * Daten der Spalte holen und auf die Ports verteilen
    	 *---------------------------------------------------*/
    	ledval = bildspeicher[ebene][col];
    	portdout = ledval & 0xff;      /* low byte */
    	portcout = portdout & 0x0f;    /* low nibble */
    	portdout = portdout & 0xf0;    /* high nibble */
    
    	PORTD = portdout & 0xff;
    	PORTC = portcout & 0xff;
    	if(col<4) ledval=bildspeicher[ebene][12];
    		else if(col<8) ledval=bildspeicher[ebene][13];
    			else ledval=bildspeicher[ebene][14];
    	PORTB = (ledval >> (col%4)*2) & 0x03;  /* high byte */
    
    	col++;
    	if(col>11)
    	{
    	   col=0;
    	   ebene++;
    		if(ebene == colors) ebene=0;
    	}
    
    	sei();						   /* Interrupts wieder erlauben */
    }
    void set(uint8_t x, uint8_t y, uint8_t c)
    {
    	uint8_t ebene, temp;
    
    	y = 9-y; // Koordinatennullpunkt unten links
    	if(y < 8)
    	   for(ebene=0; ebene<colors; ebene++)
    	   	if(c>ebene) bildspeicher[ebene][x] |= (1 << y);
    	   	   else bildspeicher[ebene][x] &= ~(1 << y);
    	else
    	{
    		if(x<4) temp = 12;
    	   	else if(x<8) temp = 13;
    	      	else temp = 14;
    		if(y & 1)
    			for(ebene=0; ebene<colors; ebene++)
    	   		if(c>ebene) bildspeicher[ebene][temp] |= (1<<((x%4)*2+1));  // y 10
    	   		   else bildspeicher[ebene][temp] &= ~(1<<((x%4)*2+1));
    		else
    			for(ebene=0; ebene<colors; ebene++)
    	   		if(c>ebene) bildspeicher[ebene][temp] |= (1<<((x%4)*2));  // y 9
    	   		   else bildspeicher[ebene][temp] &= ~(1<<((x%4)*2));
    	}
    }
    Geputzte Version:
    Code:
    // https://www.roboternetz.de/phpBB2/vi...=529702#529702 mic 15.12.2010
    
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <inttypes.h>
    
    //#define F_CPU 8000000UL // macht KAMAvr automatisch
    #define colors 4 // Anzahl der Farbebenen
    
    // Einen Bildpunkt an x, y setzen. Werte für c: 0 ist aus, 1 ist dunkel, 4 ist hell
    void set(uint8_t x, uint8_t y, uint8_t c);
    
    volatile uint8_t col = 0;
    uint8_t x, y, bildspeicher[colors][15];
    
    int main(void)
    {
    	cli();
    
    	DDRB = 0xff;
    	DDRC = 0x0f;
    	DDRD = 0xff;
    
    	TCCR0 |= (1<<CS01) | (0<<CS00);	// 8-bit Timer mit 1/8 Vorteiler !!!!!!!!!!
    	TIFR |= (1<<TOV0); 					// Clear overflow flag (TOV0)
    	TIMSK |= (1<<TOIE0); 				// timer0 will create overflow interrupt
    	sei();							    	// Interrupts erlauben
    
       for(x=0; x<15; x++)
    		for(y=0; y<colors; y++)bildspeicher[y][x] = 0b10101010; // LEDs voll hell
       _delay_ms(300);
    
    	for(x=0; x<12; x++)
    	   for(y=0; y<10; y++)
    			set(x, y, (x/3)%colors+1); // Helligkeitsstufen anzeigen
       _delay_ms(2000);
    
       for(x=0; x<15; x++)
    		for(y=0; y<colors; y++)bildspeicher[y][x] = 0; // alle LEDs in allen Ebenen aus
    
    	while(1)
    	{
    	   for(x=0; x<12; x++)
    	   	for(y=0; y<10; y++)
    				set(x, y, (x^y^TCNT0)%colors+1); // Zufallsfarbe ;)
          _delay_ms(100);
    	}
    	return (0);
    }
    
    SIGNAL (SIG_OVERFLOW0)
    {
    	static uint8_t ebene=0;
    	uint16_t ledval;
    
    	PORTB &= ~0x03; // Nur die Pins der Displaymatrix werden auf Low gesetzt
    	PORTC &= ~0x0f;
    	PORTD &= ~0xf0;
    
    // Spalten
    	if(col) PORTB |= (1<<4);	/* Danach Einsen hinterherschicken (PB4 = 1) */
    		else PORTB &= ~(1<<4);	/* Bei der ersten Spalte eine 0 ausgeben (PB4 = 0) */
    	PORTB |= (1 << 3);        	/* PB3 = 1 (cl) */
    	PORTB &= ~(1 << 3);        /* PB3 = 0 (!cl) */
    	PORTB |= (1 << 2);         /* PB2 = 1 (str) */
    	PORTB &= ~(1 << 2);        /* PB2 = 0 (!str) */
    
    // Zeilen
    	ledval = bildspeicher[ebene][col]; // y 9 bis 2
    	PORTC = ledval & 0x0f;
    	PORTD = ledval & 0xf0;
    	ledval = bildspeicher[ebene][12+(col>>2)]; // y 1 und 0
    	PORTB = (ledval >> (col%4)*2) & 0x03;
    
    	col++;
    	if(col>11)
    	{
    	   col=0;
    	   ebene++;
    		if(ebene == colors) ebene=0;
    	}
    }
    
    void set(uint8_t x, uint8_t y, uint8_t c)
    {
    	uint8_t ebene;
    
    	y = 9-y;	// Koordinatennullpunkt unten links
    	if(y < 8) // y 9 bis 2
    	   for(ebene=0; ebene<colors; ebene++)
    	   	if(c>ebene) bildspeicher[ebene][x] |= (1 << y);
    	   	   else bildspeicher[ebene][x] &= ~(1 << y);
    	else // y 1 und 0
    		for(ebene=0; ebene<colors; ebene++)
    	   	if(c>ebene) bildspeicher[ebene][12+(x>>2)] |= (1<<((x%4)*2+(y&1)));
    	   		else bildspeicher[ebene][12+(x>>2)] &= ~(1<<((x%4)*2+(y&1)));
    }
    Code:
    Aufbau der 15 Bytes des Bildspeichers:
    
    0000 0000 0011 | Bytenummer
    0123 4567 8901 |
    
    0000 0000 0000 | Bit           \
    1111 1111 1111 |                | Port C
    2222 2222 2222 |                | Pin 0-3
    3333 3333 3333 |               /
    4444 4444 4444 |               \
    5555 5555 5555 |                | Port D
    6666 6666 6666 |                | Pin 4-7
    7777 7777 7777 |               /
    
    0246 0246 0246 | Bit           \ Port B
    1357 1357 1357 |               / Pin 0 und 1
    
    |12| |13| |14| | Bytenummer
    
    Koordinatennullpunkt von set(0,0, Helligkeit)
    ist links unten.
    Code:
    // Einfache Ansteuerung des PingPong-Spiels                        mic 20.12.2010
    
    // Das Programm sollte mit der orginalen Hardware des Spiels funktionieren.
    
    // Es werden drei Funktionen zur Verfügung gestellt:
    
    // cls() löscht das Display
    // set(x, y, c) setzt an x, y eine LED. Werte für c: 0 ist aus, 1 bis 4 die Helligkeit
    // readADC(Kanal) liest den ADC, P2 ist Kanal 6, P3 ist Kanal 7
    
    // Neben den vier Helligkeitsstufen sind die LEDs nun auch dimmbar, allerdings
    // nur alle zusammen. Möglich wird das durch den Timer2, den ich hier im
    // FastPWM-Mode betreibe und eine zusätzliche ISR. Wie gehabt, werden die LEDs beim
    // Bildaufbau über die Überlauf-ISR gesetzt. Gelöscht werden sie nun aber in der
    // Compare-ISR. Diese wird immer dann aufgerufen, wenn das Zählregister des Timers
    // den selben Inhalt wie das OCR2-Register hat.
    
    // Beim Nulldurchgang des Zählregisters werden die LEDs eingeschaltet, bei OCR2
    // wieder ausgeschaltet. Somit ist die Leuchtdauer umso größer, je höher der Wert
    // im OCR2-Register ist. 0 ist dunkel, 255 ist hell.
    
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <inttypes.h>
    
    //#define F_CPU 8000000UL // macht KAMAvr automatisch
    #define colors 4 // Anzahl der Farbebenen
    
    void cls(void); // alle LEDs in allen Ebenen aus
    
    // Einen Bildpunkt an x, y setzen. Werte für c: 0 ist aus, 1 ist dunkel, 4 ist hell
    void set(uint8_t x, uint8_t y, uint8_t c);
    
    // Potiwerte einlesen, P2 ist Kanal 6, P3 ist Kanal 7
    uint16_t readADC(uint8_t channel);
    
    volatile uint8_t col = 0;
    uint8_t x, y, z, bildspeicher[colors][15];
    
    int main(void)
    {
    	cli();
    
    	DDRB = 0xff;
    	DDRC = 0x0f;
    	DDRD = 0xf0;
    
    	TCCR2 = (1<<CS21) | (0<<CS20);		// 8-bit Timer mit 1/8 Vorteiler
    	TCCR2 |= (1<<WGM21) | (1<<WGM20); 	// Fast PWM
    	TCCR2 |= (0<<COM21) | (0<<COM20); 	// no OC2-Pin
    	OCR2 = 20;                          // 0=dunkel, 255=hell
    	TIFR = (1<<OCF2) | (1<<TOV2); 		// Clear old flags
    	TIMSK |= (1<<TOIE2) | (1<<OCIE2);	// overflow and compare interrupt
    
     	// A/D Conversion (aus der asuro-Lib)
    	ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // clk/64
    
    	sei();							    	// Interrupts erlauben
    
    	for(x=0; x<12; x++)
    	   for(y=0; y<10; y++)
    			set(x, y, (x/3)%colors+1); // Helligkeitsstufen anzeigen
       _delay_ms(2000);
    
    	DDRD |= (1<<PD2); //GND für Potis
    	PORTD |= (1<<PD2);
    	while(1)
    	{
    	   z=readADC(6)/110+1;
    	   OCR2=readADC(7)/4;
    	   for(x=0; x<12; x++)
    	   {
    		   if(z==x) set(x, 0, 0); else set(x, 0, 2);
    			for(y=1; y<9; y++)
    	         if(z==x-1) set(x, y, 3);
    	         else if(z==x) set(x, y, 4);
    	         else if(z==x+1) set(x, y, 3);
    	         else set(x, y, 1);
    		   if(z==x) set(x, 9, 0); else set(x, 9, 2);
    		}
    		_delay_ms(50);
    	}
    	return (0);
    }
    
    void cls(void)
    {
    	uint8_t x, y;
    	for(x=0; x<15; x++)
    		for(y=0; y<colors; y++)bildspeicher[y][x] = 0;
    }
    void set(uint8_t x, uint8_t y, uint8_t c)
    {
    	uint8_t ebene;
    
    	y = 9-y;	// Koordinatennullpunkt unten links
    	if(y < 8) // y 9 bis 2
    	   for(ebene=0; ebene<colors; ebene++)
    	   	if(c>ebene) bildspeicher[ebene][x] |= (1 << y);
    	   	   else bildspeicher[ebene][x] &= ~(1 << y);
    	else // y 1 und 0
    		for(ebene=0; ebene<colors; ebene++)
    	   	if(c>ebene) bildspeicher[ebene][12+(x>>2)] |= (1<<((x%4)*2+(y&1)));
    	   		else bildspeicher[ebene][12+(x>>2)] &= ~(1<<((x%4)*2+(y&1)));
    }
    uint16_t readADC(uint8_t channel)
    {
    	ADMUX = (1 << REFS0) | (channel & 7);// AVCC reference with external capacitor
    	ADCSRA |= (1 << ADSC);					// Start conversion
    	while (!(ADCSRA & (1 << ADIF)));		// wait for conversion complete
    	ADCSRA |= (1 << ADIF);					// clear ADCIF
    	return(ADC);
    }
    SIGNAL (SIG_OUTPUT_COMPARE2)
    {
    	PORTB &= ~0x03; // Die Pins der Displaymatrix werden auf Low gesetzt
    	PORTC &= ~0x0f;
    	PORTD &= ~0xf4; // PD2 ist GND für Potis!
    }
    SIGNAL (SIG_OVERFLOW2)
    {
    	static uint8_t ebene=0;
    	uint16_t ledval, portb;
    
    // Spalten
    	if(col) PORTB |= (1<<4);	/* Danach Einsen hinterherschicken (PB4 = 1) */
    		else PORTB &= ~(1<<4);	/* Bei der ersten Spalte eine 0 ausgeben (PB4 = 0) */
    	PORTB |= (1 << 3);        	/* PB3 = 1 (cl) */
    	PORTB &= ~(1 << 3);        /* PB3 = 0 (!cl) */
    	PORTB |= (1 << 2);         /* PB2 = 1 (str) */
    	PORTB &= ~(1 << 2);        /* PB2 = 0 (!str) */
    
    // Zeilen
    	ledval = bildspeicher[ebene][12+(col>>2)]; // y 1 und 0
    	portb = (ledval >> (col%4)*2) & 0x03;
    	ledval = bildspeicher[ebene][col]; // y 9 bis 2
    	PORTC |= ledval & 0x0f;
    	PORTD |= ledval & 0xf0;
    	PORTB |= portb;
    
    	col++;
    	if(col>11)
    	{
    		col=0;
    		ebene++;
    		if(ebene == colors) ebene=0;
    	}
    }
    Angehängte Dateien Angehängte Dateien
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  6. #16
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Nachdem ich nun noch etwas an der Software rumgeschnitzt habe, kann sich das Ergebniss wirklich sehen lassen:

    Bild hier  
    http://www.youtube.com/watch?v=EpW4n09WuZA

    Das sind jetzt vier deutlich unterscheidbare Helligkeitsstufen. Der Trick: Jetzt wird Timer2 im FastPWM-Mode verwendet. Das ermöglicht zwei getrennte ISR, die Overflow-ISR setzt die LEDs, die OutputCompare-ISR löscht sie wieder:

    Code:
    // Scrollen mit vier Helligkeitsstufen                             mic 27.12.2010
    
    #include <avr/wdt.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <inttypes.h>
    
    #define colors 4 // Anzahl der Farbebenen
    
    volatile uint8_t ebene=0, col = 0;
    uint8_t x, y, z, bildspeicher[colors][15];
    
    // alle LEDs in allen Ebenen aus
    void cls(void);
    
    // Einen Bildpunkt an x, y setzen. Werte für c: 0 ist aus, 1 ist dunkel, 4 ist hell
    void set(uint8_t x, uint8_t y, uint8_t c);
    
    // Potiwerte einlesen, P2 ist Kanal 6, P3 ist Kanal 7
    uint16_t readADC(uint8_t channel);
    
    // WatchDog beim Initialisieren ausschalten
    // https://www.roboternetz.de/phpBB2/vi...=531597#531597
    void kill_WD(void) __attribute__((naked)) __attribute__((section(".init3")));
    void kill_WD(void) { MCUSR = 0; wdt_disable(); }
    
    int main(void)
    {
    	cli();
    
    	DDRB = 0xff;
    	DDRC = 0x0f;
    	DDRD = 0xf0;
    
    	TCCR2 = (1<<CS21) | (0<<CS20);		// 8-bit Timer mit 1/8 Vorteiler
    	TCCR2 |= (1<<WGM21) | (1<<WGM20); 	// Fast PWM
    	TCCR2 |= (0<<COM21) | (0<<COM20); 	// no OC2-Pin
    	OCR2 = 100;                          // 0=dunkel, 255=hell
    	TIFR = (1<<OCF2) | (1<<TOV2); 		// Clear old flags
    	TIMSK |= (1<<TOIE2) | (1<<OCIE2);	// overflow and compare interrupt
    
     	// A/D Conversion (aus der asuro-Lib)
    	ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // clk/64
    
    	sei();							    	// Interrupts erlauben
    
    	for(x=0; x<12; x++)
    	   for(y=0; y<10; y++)
    			set(x, y, (x/3)%colors+1); // Helligkeitsstufen anzeigen
       _delay_ms(1000);
    
    	cls();
    	z=0;
    
    	while(1)
    	{
    		for(x=0; x<12; x++)
    	   	for(y=0; y<10; y++)
    				set(x, y, ((x+y+(z%12))/3)%colors+1);
    		_delay_ms(50);
    		z++;
    	}
    	return (0);
    }
    
    void cls(void)
    {
    	uint8_t x, y;
    	for(x=0; x<15; x++)
    		for(y=0; y<colors; y++)bildspeicher[y][x] = 0;
    }
    void set(uint8_t x, uint8_t y, uint8_t c)
    {
    	uint8_t ebene;
    
    	y = 9-y;	// Koordinatennullpunkt unten links
    	if(y < 8) // y 9 bis 2
    	   for(ebene=0; ebene<colors; ebene++)
    	   	if(c>ebene) bildspeicher[ebene][x] |= (1 << y);
    	   	   else bildspeicher[ebene][x] &= ~(1 << y);
    	else // y 1 und 0
    		for(ebene=0; ebene<colors; ebene++)
    	   	if(c>ebene) bildspeicher[ebene][12+(x>>2)] |= (1<<((x%4)*2+(y&1)));
    	   		else bildspeicher[ebene][12+(x>>2)] &= ~(1<<((x%4)*2+(y&1)));
    }
    uint16_t readADC(uint8_t channel)
    {
    	ADMUX = (1 << REFS0) | (channel & 7);// AVCC reference with external capacitor
    	ADCSRA |= (1 << ADSC);					// Start conversion
    	while (!(ADCSRA & (1 << ADIF)));		// wait for conversion complete
    	ADCSRA |= (1 << ADIF);					// clear ADCIF
    	return(ADC);
    }
    SIGNAL (SIG_OUTPUT_COMPARE2)
    {
    	OCR2 = (24<<ebene);	// hihi
    	PORTB &= ~0x03; 		// Die Pins der Displaymatrix werden auf Low gesetzt
    	PORTC &= ~0x0f;
    	PORTD &= ~0xf0;
    }
    SIGNAL (SIG_OVERFLOW2)
    {
    	uint8_t ledval, portb;
    
    // Spalten
    	if(col) PORTB |= (1<<4);	/* Danach Einsen hinterherschicken (PB4 = 1) */
    		else PORTB &= ~(1<<4);	/* Bei der ersten Spalte eine 0 ausgeben (PB4 = 0) */
    	PORTB |= (1 << 3);        	/* PB3 = 1 (cl) */
    	PORTB &= ~(1 << 3);        /* PB3 = 0 (!cl) */
    	PORTB |= (1 << 2);         /* PB2 = 1 (str) */
    	PORTB &= ~(1 << 2);        /* PB2 = 0 (!str) */
    
    // Zeilen
    	ledval = bildspeicher[ebene][12+(col>>2)]; // y 1 und 0
    	portb = (ledval >> (col%4)*2) & 0x03;
    	ledval = bildspeicher[ebene][col]; // y 9 bis 2
    	PORTC |= ledval & 0x0f;
    	PORTD |= ledval & 0xf0;
    	PORTB |= portb;
    
    	col++;
    	
    	if(col>11)
    	{
    		col=0;
    		ebene++;
    		if(ebene == colors) ebene=0;
    	}
    }
    Gruß

    mic

    Ein Vorkucker:
    Bild hier   Bild hier   Bild hier  
    http://www.youtube.com/watch?v=z18KkJU_0Ic
    http://www.youtube.com/watch?v=IKszXFViHR8
    http://www.youtube.com/watch?v=ngim6DzIcGQ


    Die 0,00012 Megapixelkamera:
    https://www.roboternetz.de/phpBB2/vi...=531996#531996
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  7. #17
    Benutzer Stammmitglied
    Registriert seit
    24.08.2009
    Beiträge
    30
    Hi, kannst du vielleicht auch einen Schaltplan deines Lochrasteraufbaus online stellen. Was hast du für eine Kamera verwendet?

  8. #18
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Bild hier   Bild hier  

    Mit den Stiftleisten J1 und J4 kann man zwischen VBat oder Vcc/P1 bzw. GND oder P4 auswählen. J2 und J3 sind Anschlüsse für externe Sensoren oder Aktoren, von links nach rechts Spannung, GND und Signal.

    Ursprünglich hatte ich die PingPong-Platine nur in die Verbindungsstiftleisten eingesteckt (siehe Video oben). Nachdem ich aber einen Mega8 abgeschossen habe, sind die Verbindungen nun verlötet. (Trotzdem habe ich inzwischen einen zweiten Mega8 gekillt)

    Die 3mm-Klinkenbuchse ist direkt mit P2, P3 und GND verbunden. Zwischen P3 (ADC7) und GND brückt ein Jumper einen Lastwiderstand (im Bild unten), wenn kein Monitor angeschlossen ist.

    Ganz unten erkennt man eine achtpinnige Stiftleiste. Diese ist noch nicht angeschlossen und nur gesteckt.

    Es ist die 15€-Kamera aus dem Mitmachprojekt und sie hängt am P3 (J2).

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  9. #19
    Hallo mic,

    da Du die Pong Platine ja besser kennst als der Hersteller folgende Frage:

    ich möchte den Scroller so anpassen, dass ich zwei Platinen (oder mehr) per I2C/TWI verbinde. Ich möchte, dass die Werte, die im Prinzip dann Links Außen herausgeschoben würden auf der zweiten Platte angezeigt werden. Wie kann ich das machen? Kannst Du ein Beispiel in diesen Code von Sascha Bader implementieren:

    http://www.elo-web.de/elo/mikrocontr...ng/laufschrift

    Ich habe mir auch sechs davon aus dem Regal genommem. 5,- ist ein Schnapper. Konnte auch schon ein wenig herumexperimentieren:

    http://www.youtube.com/watch?v=3ck8w9r_Ogs

    oder

    http://www.youtube.com/watch?v=jk-GG6OIgl8

    Ich danke Dir sehr dafür!

  10. #20
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Mit I2C habe ich noch nichts gemacht und den Code des Zeichenscrollers habe ich auch noch nicht genauer untersucht. Mir ging es bisher in erster Linie um den Aufbau und die Ansteuerung der LED-Matrix.

    Der einfachste Ansatz wäre wohl, jedes Modul getrennt scrollen zu lassen und nur die Darstellung zu synconisieren. Dazu müßte das hintere Modul zuerst starten und das vordere Modul müßte abwarten, bis es über eine Signalleitung den Start der Laufschrift und in Folge dann jedes einzelne Weiterscollen mitgeteilt bekommt. Wenn man dazu zwei getrennte Pins verwendet, also Eingang und Ausgang getrennt, kann man sogar mehrere Module kaskadieren. Das erste Modul könnte man z.B. mit einem Jumper am Eingang als solches definieren. Das würde für alle Module das selbe Programm ermöglichen.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress