-         

Ergebnis 1 bis 4 von 4

Thema: Projekt "LaserText": Bitte um Denkhilfe

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.08.2006
    Ort
    Würzburg, Germany
    Beiträge
    672

    Projekt "LaserText": Bitte um Denkhilfe

    Anzeige

    Hallo,

    ich habe mir mal wieder ein neues Projekt einfallen lassen, bzw. über Google gefunden und wollte es nachbauen. Da ich nur das Prinzip übernehmen wollte und alles andere selbst entwickeln möchte halte ich den Link zu meiner Inspiration vorerst geheim. Mein Aufbau sieht folgendermassen aus:

    Klicke auf die Grafik für eine größere Ansicht

Name:	LaserText1.jpg
Hits:	20
Größe:	47,7 KB
ID:	26963 Klicke auf die Grafik für eine größere Ansicht

Name:	LaserText2.jpg
Hits:	18
Größe:	80,8 KB
ID:	26964

    Das Prinzip ist folgendes: 8 Spiegel rotieren auf einem Lüfter. Jeder Spiegel hat einen leicht anderen Kippwinkel. Auf die Spiegel lasse ich einen Laser strahlen. Durch die 8 verschiedenen Winkel habe ich somit 8 verschiedene Abstrahlwinkel in der Höhe. Durch die Rotation erhalte ich damit 8 horizontale, parallele Linien an der Wand. (Das klappt auch einwandfrei)

    Durch "pulsen" des Lasers möchte ich dann "Pixel" auf diesen Linien erstellen. Geplant ist eine Auflöung von 128 Pixel in der X-Achse und 8 Pixel in der Y-Achse (durch die Anzahl der Spiegel vorgegeben)

    Die Lüfterdrehzahl ohne "Last" (Gewicht der Spiegel) ist laut Datenblatt 2200 Umdrehungen pro Minute bzw. ca. 37 in der Sekunde. Das bedeutet ca. 27 Millisekunden pro Umdrehung. Geteilt durch 8 Zeilen und 128 Pixel ergibt dass einen Pixel-Clock von ca. 38kHz wenn ich mich nicht verrechnet habe. Das sollte mit einem Atmel machbar sein. Entschieden habe ich mich für einen ATmega8 mit einem 16MHz Quarz. Das heißt pro Pixel habe ich ca. 420 Clocks. Das sollte genügen oder?

    Da ich nur einen Lüfter ohne Tacho-Signal da hatte habe ich noch eine Lichtschranke für die Synchronisierung angebracht. Weiterhin ist noch eine Status-LED und ein Taster auf der Platine.

    Hier ist der Quellcode bis jetzt:

    Code:
    #define AVRGCC 
    
    #define LCD
    
    #include <avr/io.h> 
    #include <compiler.h>
    #include <util/delay.h>
    #ifdef LCD
        #include <ISP_LCD.h>
    #endif
    #include <font.h>
    
    
    
    /** 
    LaserText:
    
    8 rotierende Spiegel, die einen Laserstrahl auf 8 verschiedene Winkel in der Y-Achse ablenken.
    X-Achse wird über ein/ausschalt-Timing des Lasers gelöst.
    
    Buchstabe:    5x8 Pixel
    Abstand:    1 Pixel
    Buchstaben:    16
    -->Breite:    (5 + 1) * 16 = 96 Pixel
    --> Fläche:    128x8 Pixel
    
    
    
    
    ATmega8 @16 MHz
    
    IOs:
    
    PB0        OUT        Motor ein (kann auch PWM-Signal sein)
    PB1        OUT        Laser ein
    PB2        frei
    PB3        MOSI
    PB4        MISO
    PB5        SCK
    
    PC0        frei
    PC1        frei
    PC2        frei
    PC3        frei
    PC4        frei
    PC5        frei
    
    PD0        RXD
    PD1        TXD
    PD2        INT0    Tacho
    PD3        IN        Taste
    PD4        frei
    PD5        frei
    PD6        OUT        LED
    PD7        OUT        Lichtschranke ein
    
    
    
    Timer 0: (zur Ermittlung der Rotiergeschwindigkeit)
    
    FCPU            = 16000000
    Prescaler        = 64 (8x wie andere Timer, damit das Teilen durch 8 Zeilen gleich entfällt)
    Timer-Frequenz    = 250 KHz
    normaler Modus; im Overflow-Interrupt wird ein 8 Bit-Counter gezählt um die Reichweite auf 16 Bit zu erhöhen
    
    
    
    Timer 1: (zum timen der Zeilen)
    
    Prescaler        = 8
    Timer-Frequenz    = 2 MHz
    CTC-Modus um mit OCR1A im Interrupt das den Zeilen-Start zu generieren
    
    
    
    Timer 2: (zum timen der Pixel)
    Prescaler        = 8
    Timer-Frequenz    = 2 MHz
    CTC-Modus um mit OCR2 im Intterrupt den Pixel-Clock zu generieren
    
    
    
    erwartete Werte:
    
    Lüfterdrehzahl (ca.):    2200    U/min
                            36,6    U/sek
    Umdrehungsdauer:        27,3    ms
                            54545    Ticks (Prescaler 8; Timer 1 und 2)
    Segmentdauer:            6818    Ticks (Timer 0)
    Pixeldauer:                53        Ticks (Prescaler 8; Timer 1 und 2)
    
    
    
    tatsächliche Werte:
    
    Segmentdauer (ca.):        9500    Ticks (Timer 0)
    Pixeldauer:                74        Ticks (Prescaler 8; Timer 1 und 2)
    Umdrehungsdauer:        76000    Ticks (Prescaler 8; Timer 1 und 2)
                            38        ms
    Lüfterdrehzahl:            26,3    U/sek
                            1579    U/min    (kommt vermutlich durch das Gewicht der Spiegel und deren Halterung)
    **/
    
    
    
    #define BAUD                    9600l                        // Baud-Rate für USART
    #define UBRRValue                (F_CPU / (BAUD * 16) - 1)
    
    #define USART_BufferSize        32                            // Größe des USART-Input-Buffers
    
    
    
    #define    lines                    8                            // 8 Spiegel für Y-Auflösung
    #define    cols                    96                            // 96 nutzbare Pixel in X-Achse (bei 6 Pixel pro Buchstabe 16 Buchstaben)
    #define colsBorder                32                            // nicht nutzbarer Rand um Versatz zu korrigieren und auf 2^7 Gesamtpixel zu kommen
    #define colStart                16                            // Erster Pixel mit Nutz-Daten
    #define colDivider                7                            // Teiler für den Pixel-Clock (2^7 = 128 = 96 + 32)
    #define    colBytes                16                            // Benötigte Bytes pro Zeile (128 Bit : 8 Bit = 16 Byte)
    
    
    
    #define Motor_aus        PORTB = ~(~PORTB | (1<<PB0))        // Motor-Kontrolle
    #define Motor_ein        PORTB = (PORTB | (1<<PB0))
    #define Motor_Status    ((PORTB & (1<<PB0)) != 0)            // Motor-Status
    
    #define Laser_aus        PORTB = ~(~PORTB | (1<<PB1))        // Laser-Kontrolle
    #define Laser_ein        PORTB = (PORTB | (1<<PB1))
    
    #define LED_aus            PORTD = ~(~PORTD | (1<<PD6))        // Status-Led-Kontrolle
    #define LED_ein            PORTD = (PORTD | (1<<PD6))
    
    #define LS_aus            PORTD = ~(~PORTD | (1<<PD7))        // Lichtschranken-Kontrolle
    #define LS_ein            PORTD = (PORTD | (1<<PD7))
    
    #define Tacho            ((PIND & (1<<PD2)) == 0)            // Lichtschranken-Eingang-Status
    
    #define Taste            ((PIND & (1<<PD3)) == 0)            // Tasten-Status
    
    #define USART_ready        ((UCSRA & (1<<UDRE)) != 0)            // alle Zeichen im USART versendet?
    
    #define PixelIRQ_aus    TIMSK = (1<<TOIE0) | (1<<OCIE1A)    // Timer-Interrupts konfigurieren
    #define PixelIRQ_ein    TIMSK = (1<<TOIE0) | (1<<OCIE1A) | (1<<OCIE2)
    
    
    
    volatile            U8        TachoCounter                    = 0;        // Overflow-Variable für Timer 0 um auf 16 Bit Datengröße zu kommen
    volatile            U16        lineTime                        = 0;        // berechnete Ticks in Timer 1 pro Zeile --> Wert für OCR1A
    volatile            U8        pixelTime                        = 0;        // berechnete Ticks in Timer 2 pro Pixel --> Wert für OCR2
    
    volatile            U8        USART_Pointer                    = 0;        // Pointer im USART-Buffer
    volatile            char    USART_data[USART_BufferSize];                // USART-Buffer
    
    volatile            U8        Pixel[lines][colBytes];                        // Pixel-Daten
    
    volatile            U8        CursorY;                                    // Zeilen-Cursor
    volatile            U8        CursorXoffset;                                // Daten-Byte-Zähler für Pixel
    volatile            U8        CursorXbit;                                    // Bit-Zähler im Daten-Byte für Pixel
    volatile            U8        CursorXdataTmp;                                // aktuelles Daten-Byte für Pixel
    volatile            bool    lineFinished                    = FALSE;    // Flag, ob alle Pixel der Zeile angezeigt wurden
    
    
    
    volatile    const    U16        lineOffset[lines]                = {0, 0, 0, 0, 0, 0, 0, 0};            // zum kalibrieren des Versatzes
    
    
    
    void sendMsg (char *Msg, bool addCR)                        // sendet eine Nachricht über den USART
    {
        while (*Msg != 0)
        {
            while (!USART_ready);
            UDR = *Msg++;
        }
    
        if (addCR)
            sendMsg ("\r\n", FALSE);
    }
    
    
    
    
    void Pixel_clearScreen (void)                                // löscht alle Pixel in den Pixel-Daten
    {
        U8 i1;
        U8 i2;
    
        for (i1 = 0; i1 < lines; i1++)
        for (i2 = 0; i2 < colBytes; i2++)
            Pixel[i1][i2] = 0;
    }
    
    void Pixel_set (U8 x, U8 y, bool value)                        // setzt oder löscht einen Pixel (je nach value)
    {
        x = (cols + colsBorder) - (colStart + x);                // Pixel-Offset addieren und von rechts nach links umrechnen
        U8 offset = x>>3;                                        // Offset-Byte in Pixel-Daten berechnen (:8)
        x = x - (offset<<3);                                    // Start-Wert des Offset-Byte abziehen
        
        if (value)
            Pixel[y][offset] |= (1<<x);
        else
            Pixel[y][offset] = ~(~Pixel[y][offset] | (1<<x));
    }
    
    void Pixel_lineX (U8 x, U8 y, U8 length, bool value)        // zeichnet oder löscht eine Linie in X-Richtung (je nach value)
    {
        U8 i1;
        for (i1 = 0; i1 < length; i1++)
            Pixel_set (x + i1, y, value);
    }
    
    void Pixel_lineY (U8 x, U8 y, U8 length, bool value)        // zeichent oder löscht eine Linie in Y-Richtung (je nach value)
    {
        U8 i1;
        for (i1 = 0; i1 < length; i1++)
            Pixel_set (x, y + i1, value);
    }
    
    void Char (U8 x, U8 y, U8 ASCII)                            // zeichnet einen Buchstaben
    {
        ASCII = ASCII - 16;                                        // Font ASCII-Offset abziehen
    
        U8 i1;
        for (i1 = 0; i1 < 5; i1++)                                // Buchstabe wird Spaltenweise gezeichnet
        {
            U8 tmp = Font[ASCII][i1];                            // Spalten-Daten aus Font holen
            U8 i2;
            for (i2 = 0; i2 < 8; i2++)
            {
                Pixel_set (x + i1, y + i2, ((tmp & 1) != 0));    // Pixel setzen oder löschen, wenn entsprechendes Bit gesetzt oder gelöscht
                tmp = tmp>>1;                                    // Spalten-Daten weiter schieben
            }
        }
    }
    
    void Text (U8 x, U8 y, char *textdata)                        // zeichnet einen Text
    {
        while (*textdata != 0)
        {
            Char (x, y, *textdata++);
            x = x + 6;
        }
    }
    
    
    
    SIGNAL (INT0_vect)                                            // 1 Umdrehung startet (und letzte Umdrehung abgeschlossen):
    {
        U16 tmp = TachoCounter;                                    // Gesamt-Wert für letzte Umdrehung in tmp berechnen
        tmp = (tmp<<8) + TCNT0;
        
        
        
        TCNT0 = 0;                                                // Timer für Umdrehungs-Dauer reset
        TachoCounter = 0;
    
        
        
        TCNT1 = 0;                                                // Timer für Zeilen Reset
        OCR1A = 0x8000;
    
        
        
        PixelIRQ_aus;                                            // Falls noch alte Umdrehung läuft --> Deaktivieren
        Laser_aus;
    
        
        
        if (tmp < 0xFF00)                                        // Umdrehung schnell genug?
        {
            lineTime = tmp;                                        // Zeilen-Zeit speichern
            pixelTime = tmp>>colDivider;                        // Pixel-Zeit berechnen und speichern
            
            lineFinished = TRUE;                                // Flag beim Start initialisieren
            CursorY = 0;                                        // Zeilen-Cursor Reset
    
            TCNT1 = 0;                                            // Zeilen-Timer Reset
            OCR1A = (lineTime>>1) + lineOffset[0];                // und Start-Offset des ersten Segment auf halbe Zeilenzeit + Offset
    
            OCR2 = pixelTime;                                    // Pixel-Clock initialisieren
        }
        else
            CursorY = 0xFF;                                        // ungültige Zeile, damit keine gestartet wird
    }
    
    
    
    SIGNAL (TIMER0_OVF_vect)                                    // Timer für ermittlung der Umdrehungs-Dauer (Overflow)
    {
        if (TachoCounter < 0xFF)                                // wenn noch nicht auf Maximum, dann Overflow-Wert erhöhen
            TachoCounter++;
        else                                                    // ansonsten ist die Drehzahl zu langsam --> Laser ausschalten
        {
            CursorY = 0xFF;
            OCR1A = 0x8000;
            PixelIRQ_aus;
            Laser_aus;
        }
    }
    
    
    
    SIGNAL (TIMER1_COMPA_vect)                                    // Zeilen-Start:
    {
        if (lineFinished & (CursorY < lines))                    // Zeilen-Cursor gültig?
        {
            OCR1A = lineTime + lineOffset[CursorY];                // OCR1A setzen
                                                                
                                                                // Zeilen-Start:
            CursorXoffset    = 0;                                // Offset-Byte auf 0
            CursorXbit        = 0;                                // Bit auf 0
            CursorXdataTmp    = Pixel[CursorY][0];                // Erstes Datenbyte in Temp laden
            TCNT2            = 0;                                // Pixel-Timer Reset,
            PixelIRQ_ein;                                        // und starten
            lineFinished    = FALSE;                            // Flag löschen
        }
        else
        {
            CursorY = 0xFF;
            OCR1A = 0x8000;
            PixelIRQ_aus;
            Laser_aus;
        }
    }
    
    
    
    SIGNAL (TIMER2_COMP_vect)                                    // Timer-Clock:
    {
        // Test-Code:
    
        if (CursorXbit == 0)            // Erster Pixel?
        {
            Laser_ein;                    // dann Laser ein
            CursorXbit++;
        }
        else
        {                                // zweiter Pixel:
            PixelIRQ_aus;
            Laser_aus;
            lineFinished = TRUE;
            CursorY++;
        }
    
    
        
        
        /** normaler Code:
    
        if ((CursorXdataTmp & 1) == 0)                            // Bit prüfen, Laser ein oder aus?
            Laser_aus;
        else
            Laser_ein;
    
        if (++CursorXbit == 8)                                    // letzte Bit in Temp-Byte?
        {
            if (++CursorXoffset == colBytes)                    // und letztes Temp-Byte?
            {
                PixelIRQ_aus;                                    // dann Pixel-Timer aus
                lineFinished = TRUE;                            // Flag setzen
                CursorY++;                                        // und nächste Zeile...
            }
            else
            {
                CursorXdataTmp = Pixel[CursorY][CursorXoffset];    // ansonsten nächstes Temp-Byte laden
                CursorXbit = 0;                                    // und Bit wieder auf 0
            }
        }
        else
            CursorXdataTmp = CursorXdataTmp>>1;                    // ansonsten Bits im Temp-Register weiter schieben...
        **/
    }
    
    
    
    SIGNAL (USART_RXC_vect)                                        // USART-Datenempfang:
    {
        char value = UDR;                                        // USART-Datenregister auf jeden Fall einlesen
    
        if (USART_Pointer < USART_BufferSize);                    // wenn Buffer noch nicht voll, dann Zeichen anhängen
            USART_data[USART_Pointer++] = value;
    }
    
    
    
    
    
    
    int main(void)
    { 
        DDRB =  0b00000011;                                        // Ports initialiseren:
        PORTB = 0b00000000;
    
        DDRC =  0b00000000;
        PORTC = 0b01000000;
    
        DDRD =  0b11000000;
        PORTD = 0b00001100;
    
    
        
        LED_ein;                                                // Einschalt-Reset LED anzeige:
        _delay_ms (1000);
    
        #ifdef LCD
            LCD_Init (&PORTB, &DDRB, PB3, PB4, PB5);            // wenn LCD, dann initialisieren und Begrüßung anzeigen:
            LCD_Clear ();
            LCD_Text ("LaserText");
        #endif
    
    
    
        MCUCR = (1<<ISC01);                                        // INT0 konfigurieren: fallende Flanke
        GICR = (1<<INT0);                                        // INT0 aktivieren
    
        
        
        TCCR0 = (1<<CS01) | (1<<CS00);                            // Timer 0 konfigurieren: Prescaler 64
    
        TCCR1A = 0;                                                // Timer 1 konfigurieren: normal port operation und CTC-Mode
        TCCR1B = (1<<WGM12) |(1<<CS11);                            // CTC-Mode und Prescaler 8
        OCR1A = 0x8000;                                            // OCR1A auf Mittelwert
    
        TCCR2 = (1<<WGM21) | (1<<CS21);                            // Timer 2 konfigurieren: normal port operation und CTC-Mode und Prescaler 8
        OCR2 = 0x80;                                            // OCR2 auf Mittelwert
    
        PixelIRQ_aus;                                            // Timer 0 Overflow und Timer 1 OCIE1 Interrupt aktivieren
    
        
        
        UCSRB = (1<<RXCIE) | (1<<TXEN) | (1<<RXEN);                // USART konfigurieren: Sender und Empfänger ein und Receive-Interrupt ein
        UCSRC = (1<<UCSZ1) | (1<<UCSZ0);                        // 8 Bit, 1 Stop-Bit, kein Parity
        UBRRH = (U8)(UBRRValue>>8);                                // BAUD-Rate setzen
        UBRRL = (U8)UBRRValue;
    
    
    
        Pixel_clearScreen ();                                    // alle Pixel löschen
    
        // Test-Ausgaben:
        //Pixel_lineX (0, 0, 96, TRUE);
        //Pixel_lineX (0, 1, 96, TRUE);
        //Pixel_set (0, 0, TRUE);
        //Text (0, 0, "Hallo");
    
    
    
        sei ();                                                    // los gehts, Interrupts freigeben
    
        LED_aus;                                                // Einschalt-Reset-LED aus
    
    
    
    
        while (1)
        {
            #ifdef LCD                                            // wenn LCD, dann Zeitwerte anzeigen:
                LCD_Cursor (1, 2);
                LCD_Text ("L ");
                LCD_Zahl (lineTime, 5, FALSE);
                LCD_Text ("/ P ");
                LCD_Zahl (pixelTime, 3, FALSE);
                LCD_Text ("/ Y ");
                if (CursorY <lines)
                    LCD_Zahl (CursorY, 1, FALSE);
                else
                    LCD_Zeichen ('-');
            #endif
    
    
            
            /**
            #ifdef LCD                                            // wenn LCD, dann USART anzeigen:
                LCD_Cursor (1, 3);
                LCD_Zahl (USART_Pointer, 2, FALSE);
                if (USART_Pointer > 0)
                {
                    LCD_Cursor (1, 4);
                    U8 i1;
                    for (i1 = 0; i1 < USART_Pointer; i1++)
                        LCD_Zeichen (USART_data[i1]);
                }
            #endif
            **/
    
                    
            
            if (Taste)                                            // Taste gedrückt?
            {
                if (Motor_Status)
                {                                                // wenn Motor eingeschaltet, dann abschalten:
                    PixelIRQ_aus;
    
                    Motor_aus;
                    LS_aus;
                    Laser_aus;
    
                    OCR1A = 0x8000;
                    OCR2 = 0x80;
                    
                    lineTime = 0;
                    pixelTime = 0;
                    CursorY = 0xFF;
                }
                else
                {                                                // ansonsten einschalten:
                    Motor_ein;
                    LS_ein;
                }
    
    
    
                while (Taste)                                    // warten, bis Taste losgelassen wurde:
                    _delay_ms (10);
            }
        }
    
           return(0); 
    }
    Und hier das Ergebnis als Video: http://www.car-mp3.de/RNetz/Lasertext.avi

    Wie im Video zu sehen ist klappt das gar nicht. Die Berechnungen der Zeiten im LCD passen. Nur irgendwo scheine ich einen Fehler bei der Konfiguration der Timer zu haben. Aber ich bin schon zwei Tage am Suchen und finde ihn nicht.

    Ich weiß, dass dieses Projekt sehr umfangreich ist. Aber vielleicht hat ja jemand Lust bekommen und denkt sich durch und findet meinen Fehler.

    Viele Grüße
    Andreas

    - - - Aktualisiert - - -

    Hier noch der Schaltplan zur Vollständigkeit. Ist nichts besonderes. Manche Bauteile sind etwas überdimensioniert. Das liegt daran, das ich sie rumliegen hatte.

    - die Schaltung wird über ein 12V Netzteil versorgt.
    - davon wird über einen IRF5305 der Lüfter geschaltet (125mA).
    - ebenfalls an 12V hängt die Lichtschranke über einen BC557 geschaltet (10mA). Danach noch ein Pegel-Wandler für den Atmel-Eingang.
    - der Standard 7805 für die 5V für den Atmel
    - eine USART-Schnittstelle und eine ISP-Schnittstelle, über die auch das LCD angeschlossen werden kann
    - dann ein LM317 für die Erzeugung der Spannung des Lasers (4V). Der Laser wird dann über einen BD240 getaktet. (später 300mA, derzeit 30mA). Den IRF5305 konnte ich dafür nicht nehmen, da die Spannung zu niedrig war um das Gate durchzusteuern.
    - Quarz, Taster und LED
    - was noch fehlt ist der Pegelwandler für den USART um die Schaltung später mit Daten zu füttern. Was das wird habe ich noch nicht entschieden. Vermutlich ein USB-RS232-Wandler. (oder Luxus: ein Bluetooth- oder WLAN-Modul)

    Klicke auf die Grafik für eine größere Ansicht

Name:	LaserText_SP.jpg
Hits:	9
Größe:	88,7 KB
ID:	26967

    Insgesamt musste ich für das Projekt nur die Spiegel für ca. 5€ kaufen. Alles andere war in der Bastelkiste. Die Halterung für die Spiegel hat mir ein Kumpel ausgelasert und gekanntet. Ist praktisch, wenn man auf sowas Zugriff hat.

    Wenn alles läuft möchte ich die Spiegelhalterung noch 3D-Drucken lassen um Gewicht zu sparen. (höhere Refresh-Rate) Obwohl die Linien zur Zeit auch flakerfrei dargestellt werden. Das Flackern im Video kommt von der Kamera und vom falschen Timing.
    Außerdem soll der Laser durch einen stärkeren ersetzt werden, damit man auch am Tag gut was erkennen kann.

    Viele Grüße
    Andreas

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.783
    Blog-Einträge
    8
    Hallo

    Zwei Tage ist doch noch kein Aufwand ;)

    Solange wird wohl allein schon das "Reindenken" in deinen Code dauern.

    http://www.roboternetz.de/community/...Laserprojektor

    Gruß

    mic

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

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Andree-HB
    Registriert seit
    10.12.2004
    Ort
    Bremen
    Alter
    47
    Beiträge
    2.556
    ...ich kann mir aber gar nicht vorstellen, dass die Laserdiode das langfristig so problemlos mitmachen wird.
    Wie pulst Du denn ? Einfaches an/aus ?
    Danke an Alle, die uns bei der erfolgreichen 1.000€-Aktion der IngDiba unterstützt haben! | https://www.hackerspace-bremen.de | http://www.pixelklecks.de |

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.08.2006
    Ort
    Würzburg, Germany
    Beiträge
    672
    Hallo,

    ich hatte heute und jetzt nur kurz Zeit. (Ein Streß immer mit den Weihnachtsmärkten und Weihnachtsfeiern...)

    Aber ich möchte kurz was zu den Antworten schreiben:

    @Radbruch: Die Software war in ca. 1 Stunde geschrieben. Die komplette Projektplanung inkl. Berechnungen und zusammenlöten des Prototyen und Software habe ich in 2 Tagen (ein Wochenende) geschafft. Dann war ich weitere 2 Tage (noch ein Wochenende) am Timing-Problem gesessen. Ich halte deshalb 2 Tage fürs einarbeiten für Übertrieben. Aber du hast recht: Zumuten kann man das niemand. Deshalb habe ich bereits in meinem ersten Post geschrieben, dass es nur für Leute gedacht ist, die Lust auf sowas haben. Vielleicht baut es ja jemand nach?
    Ich kann mir mal die Mühe machen den relevanten Teil des Codes für das Laser-Timing hervorzuheben. Im Endeffekt ist es vermutlich ca. "ein Bildschirm" mit Variablen-Deklarationen und Initialisierung und noch ein weiterer mit dem Timer-Code.
    Der Rest ist schon alles Luxes (Pixel-Speicher, Font, USART, etc.) der für das jetztige Problem noch gar nicht benötigt wird.

    Den verlinkten Laser-Projekter muss ich mir ein anderes mal ansehen. Wie gesagt möchte ich alles selbst entwickeln und erlernen und mich aus den Fehlern weiterbilden.

    Ich habe diesen Thread auch erstellt und geschrieben um meine Gedanken zu sortieren. Ich glaube es hat geholfen. Heute früh hatte ich kurz Zeit und habe die Timer mithilfe von Zählvariablen überprüft. Das passt alles. Ich habe ein paar Kleinigkeiten geändert und nun erhalte ich zumindest ein (fast) stehendes Bild. Es sind ab und zu kurze Aussetzer drin und das Bild hat noch nicht viel mit dem Inhalt im Pixel-Speicher zu tun. Das könnte aber auch daran liegen, dass die Kippwinkel der Spiegel noch nicht ausgerichtet sind. Auf jeden Fall bin ich durch mein Gedankensortieren ein gutes Stück weiter gekommen.

    @Andree-HB: Dies ist mein erstes Projekt mit einem Laser. Ich habe mich vorher informiert und im Netz nichts gefunden, das pulsen für Laser-Dioden schädlich sein soll. Ich schalte den Laser über einen PNP-Transistor ein und aus. Er ist übrigens inklusive Elektronik zur Strombegrenzung. Den Laser habe ich von Pollin. Die genaue Bezeichnung müsste ich heraussuchen. Ich habe einfach an die Kontakte wo die Batterien angeklemmt werden den Ausgang meines Transistors gelötet. Was könnte da schädlich für den Laser sein?

    Viele Grüße
    Andreas

Ähnliche Themen

  1. Projekt MIT -> "SnapIn" CNC für 500,- Dollar
    Von Andree-HB im Forum Mechanik
    Antworten: 4
    Letzter Beitrag: 04.06.2011, 00:06
  2. Bitte um grobe "Suchrichtung"
    Von mccmcc im Forum ARM - 32-bit-Mikrocontroller-Architektur
    Antworten: 0
    Letzter Beitrag: 07.05.2009, 20:38
  3. Antworten: 8
    Letzter Beitrag: 28.07.2008, 20:04
  4. Bitte einmal mein "Mini-Mega32" Board überprüfen
    Von nico_hann im Forum AVR Hardwarethemen
    Antworten: 5
    Letzter Beitrag: 19.06.2006, 10:44
  5. Bitte um "HILFE" Problem mit RN-KeyLCD
    Von phantom01 im Forum Bauanleitungen, Schaltungen & Software nach RoboterNetz-Standard
    Antworten: 6
    Letzter Beitrag: 09.12.2005, 17:13

Berechtigungen

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