-         

Ergebnis 1 bis 2 von 2

Thema: RP6Control M32: Video Zeilenzähler 1

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791

    RP6Control M32: Video Zeilenzähler 1

    Anzeige

    Hallo Leute,

    für die Experimentierplatine, die wir hier beschrieben haben:
    http://www.roboternetz.de/phpBB2/zei...ag.php?t=53424
    ... und die hier:
    http://www.rn-wissen.de/index.php/RP...itmach-Projekt
    ... gebaut wurde, hier ein zweites Programm für die M32. Es funktioniert ab der Phase 3 des Aufbaus.
    Auf dem LCD wird die Zahl der CSync-Flanken bis zur 1. TV Zeile, die Anzahl der TV Zeilen und der Video Pegel der Austastlücke und einer TV Zeile angezeigt.
    Code:
    /* 
     * ****************************************************************************
     * RP6 ROBOT SYSTEM - RP6 CONTROL M32 TESTS
     * ****************************************************************************
     * Beispiel: Zählt die Video (TV) Zeilen einer CMOS Kamera
     * Autor(en): Dirk
     * ****************************************************************************
     * Beschreibung:
     *
     * Mit diesem Programm kann die Zeilenzahl einer CMOS Kamera (CONRAD 150001)
     * und die Zahl der CSync Flanken von VSync bis zur ersten TV Zeile auf dem
     * LCD angezeigt werden. Der Video Pegel der Austastlücke und einer TV Zeile
     * wird auch angezeigt.
     * Die Kamera ist an dieses Hardware Projekt (Phase 3 und höher) angeschlossen:
     *   http://www.rn-wissen.de/index.php/RP...itmach-Projekt
     * Die BAS Video Information (PG3) ist angeschlossen an ADC4 (M32 ADC Stecker,
     * Pin 3).
     * Die Synchronisationssignale sind wie folgt verbunden:
     *
     *	Signal		RP6 Name	Port	Funktion
     *	VSync		EINT2		PD3		INT1
     *	HSync		IO_PD6		PD6		ICP1
     *	Odd/Even	EINT3		PB2		INT2
     *
     * ############################################################################
     * Der Roboter bewegt sich NICHT in diesem Beispiel! Du kannst ihn einfach auf
     * einen Tisch neben deinen PC stellen und solltest ihn mit dem PC über das
     * USB-Interface verbinden!
     * ############################################################################
     * ****************************************************************************
     */
    
    /*****************************************************************************/
    // Einzufügende Dateien:
    
    #include "RP6ControlLib.h" 		// Die RP6 Control Bibliothek. 
    								// Muss immer eingefügt werden!
    
    /*****************************************************************************/
    // Definitionen:
    
    #define FALLING		0					// Fallende Flanken
    #define RISING		1					// Steigende Flanken
    //-------------------------------
    #define EDGE		FALLING				//<== Wähle FALLENDE oder
    										//    STEIGENDE Flanken!
    //-------------------------------
    
    #define ODD			(1<<EINT3)			// Feld 1
    #define EVEN		0					// Feld 2
    //-------------------------------
    #define FIELD		ODD					//<== Wähle Feld 1 oder Feld 2!
    //-------------------------------
    
    #define VIDEO_BLANK	108					//<== Passe den Video Pegel der
    										//    Austastlücke an!
    
    #define HSYNC		(PIND & IO_PD6)
    #define VSYNC		(PIND & EINT2)
    #define ODD_EVEN	(PINB & EINT3)
    #define IRon()		(PORTC &= ~IO_PC6)
    #define IRoff()		(PORTC |= IO_PC6)
    
    /*****************************************************************************/
    // Variablen:
    
    volatile uint16_t edgecnt;
    volatile uint16_t video;
    volatile uint8_t tvlevelflag;
    uint8_t field;
    uint16_t blankedges;
    uint16_t tvlines;
    uint16_t videolevel_1;
    uint16_t videolevel_2;
    
    /*****************************************************************************/
    // Funktionen:
    
    /**
     * TIMER1 Capture ISR
     *
     * In dieser ISR werden die fallenden/steigenden Flanken des CSync Signals
     * ab VSync gezählt, und der Video Pegel wird einmal pro Zeile mit ADC4
     * gemessen. Im Hauptprogramm muss edgecnt direkt nach der fallenden
     * Flanke von VSync auf Null zurückgesetzt werden!
     * Die komplette Zeit der Messung vom Zeitpunkt des "Sample and Hold" bis
     * zum Ergebnis in ADC liegt in der ersten Hälfte der TV Zeile, weil
     * einige Impulse in der Austastlücke einen Abstand von ca. 32 µs (eine
     * halbe TV Zeile) haben. Daher darf die ISR nicht länger als eine halbe
     * TV Zeile dauern!
     * Der Video Pegel wird NICHT nach den ersten 10 CSync Flanken nach VSync
     * gemessen.
     *
     * Ausgabe: edgecnt     -> CSync Flankenzähler
     *          video       -> 10 Bit ADC Wert (Video Pegel)
     *          tvlevelflag -> true:  TV Zeile mit Video Inhalt
     *                         false: Austastlücke
     *
     * ACHTUNG: Die Konstante VIDEO_BLANK muss auf einen Video Pegel
     *          zwischen dem Pegel der Austastlücke und dem einer TV
     *          Zeile in einem völlig dunklen Raum angepaßt werden!
     *
     */
    ISR (TIMER1_CAPT_vect)
    {uint8_t h_delay;
    	edgecnt++;
    	tvlevelflag = false;
    	if (edgecnt > 10) {
    		h_delay=15; while (h_delay--) {nop();}; 
    		ADMUX = (1<<REFS0) | (1<<REFS1) | (ADC_4<<MUX0);
    		ADCSRA = (0<<ADIE) | (1<<ADSC) | (1<<ADEN)
    		 | (1<<ADPS2) | (1<<ADPS1) | (1<<ADIF);
    		while(ADCSRA & (1<<ADIF));
    		ADCSRA |= (1<<ADIF);
    		video = ADC;
    		if (video > VIDEO_BLANK) tvlevelflag = true;
    	}
    }
    
    /*****************************************************************************/
    // Haupt Funktion - Das Programm beginnt hier:
    
    int main(void)
    {
    	initRP6Control();
    
    	initLCD();
    
    	showScreenLCD("################", "################");
    	mSleep(1500);
    	showScreenLCD("<<RP6  Control>>", "<<LC - DISPLAY>>");
    	mSleep(2500); 
    	showScreenLCD(" Video Lines Cnt", "  Version 1.00  ");
    	mSleep(2500);
    	clearLCD();
    
    	setLEDs(0b0000);
    	
    	// Initialisiere den M32 ICP Pin (PD6) als Eingang: 
    	DDRD &= ~IO_PD6;					// ==> HSync
    	PORTD |= IO_PD6;					// Pullup an
    	// Initialisiere den M32 INT1 Pin (PD3) als Eingang: 
    	DDRD &= ~EINT2;						// ==> VSync
    	PORTD |= EINT2;						// Pullup an
    	// Initialisiere den M32 INT2 Pin (PB2) als Eingang: 
    	DDRB &= ~EINT3;						// ==> Odd/Even
    	PORTB |= EINT3;						// Pullup an
    	// Initialisiere den M32 TOSC1 Pin (PC6) als Ausgang: 
    	DDRC |= IO_PC6;						// ==> IR
    	IRoff();							// IR LEDs aus
    
    	// Initialisiere die M32 Timer1 Input Capture Funktion:
     	TCCR1B = (1<<CS10)					// Trigger: Kein Vorteiler
    	 | (1<<ICNC1);						//  und Noise Canceler
    #if EDGE
    	TCCR1B |= (1<<ICES1);				//  Steigende Flanke
    #else
    	TCCR1B &= ~(1<<ICES1);				//  Fallende Flanke
    #endif
    /*
    // Zeige die ADC Werte der Austastlücke und einer TV Zeile:
    //   Wenn man VIDEO_BLANK (für eine andere Kamera) anpassen will,
    //   muss man diese Konstante auf einen Wert setzen, der zwischen
    //   den beiden hier angezeigten Werten liegt. Das muss in einem
    //   dunklen Raum gemacht werden, um einen sehr niedrigen TV
    //   Video Pegel zu erreichen!
    	TIMSK = (1<<TICIE1);				// Aktiviere Capture ISR
    	while(true)
    	{
    		while(VSYNC);					// Warte auf Seitenanfang
    		TIFR = (1<<ICF1);				// Lösche aktiven Interrupt
    		edgecnt = 0;					// Flankenzähler zurücksetzen
    		while(edgecnt < 18);			// Austastlücke!
    		videolevel_2 = video;			// Speichere Pegel der Austastlücke
    		while(edgecnt < 120);			// TV Zeilen Bereich!
    		videolevel_1 = video;			// Speichere TV Video Pegel
    		setCursorPosLCD(0, 0);
    		writeStringLCD("Video Blank ");
    		writeIntegerLengthLCD(videolevel_2, DEC, 3);
    		setCursorPosLCD(1, 0);
    		writeStringLCD("Video  TV   ");
    		writeIntegerLengthLCD(videolevel_1, DEC, 3);
    		while(!VSYNC);					// Warte auf VSync Highpegel
    	}
    */	
    // Zeige die Anzahl der CSync Flanken bis zur ersten TV Zeile,
    // die Zahl der TV Zeilen, den Video Pegel der Austastlücke und
    // einer TV Zeile an:
    //   Wenn hier keine realistischen Werte angezeigt werden, muss
    //   die Konstante VIDEO_BLANK (siehe oben!) angepaßt werden.
    	while(true)
    	{
    		while(VSYNC);					// Warte auf Seitenanfang
    		nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
    		TIFR = (1<<ICF1);				// Lösche aktiven Interrupt
    		edgecnt = 0;					// Flankenzähler zurücksetzen
    		TIMSK = (1<<TICIE1);			// Aktiviere Capture ISR
    		field = ODD_EVEN;				// Feld Nummer?
    		if ((field && FIELD)
    		 || ((!field) && (!FIELD))) { // Gewähltes Feld?
    			tvlevelflag = false;
    			while(!tvlevelflag);		// Zähle bis zur ersten TV Zeile
    			blankedges = edgecnt;
    			videolevel_1 = video;		// Speichere den TV Video Pegel
    			blankedges--;				// HSync der ersten TV Zeile!
    			while(tvlevelflag);			// Zähle bis zum Ende der TV Zeilen
    			tvlines = edgecnt - blankedges;
    			videolevel_2 = video;		// Speichere Pegel der Austastlücke
    			tvlines--;					// Anzahl TV Zeilen!
    			TIMSK &= ~(1<<TICIE1);		// Inaktiviere Capture ISR
    			setCursorPosLCD(0, 0);
    			writeStringLCD("Ebn");
    			writeIntegerLengthLCD(blankedges, DEC, 3);
    			setCursorPosLCD(0, 7);
    			writeStringLCD("Ltv");
    			writeIntegerLengthLCD(tvlines, DEC, 3);
    			if (field) writeStringLCD(" :O"); // Zeige Odd/Even Feld
    			else writeStringLCD(" :E");
    			setCursorPosLCD(1, 0);
    			writeStringLCD("Vbn");
    			writeIntegerLengthLCD(videolevel_2, DEC, 3);
    			setCursorPosLCD(1, 7);
    			writeStringLCD("Vtv");
    			writeIntegerLengthLCD(videolevel_1, DEC, 3);
    #if (EDGE == FALLING)
    			writeStringLCD(" :F");		// Zeige Falling/Rising Flanke
    #else
    			writeStringLCD(" :R");
    #endif
    			while(!VSYNC);				// Warte auf VSync Highpegel
    		}
    	}
    	return 0;
    }
    
    /******************************************************************************
     * Additional info
     * ****************************************************************************
     * Changelog:
     * - v. 1.0 (initial release) 07.05.2010 by Dirk
     *
     * ****************************************************************************
     */
    
    /*****************************************************************************/
    Viel Spaß!

    Gruß Dirk

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    27.09.2009
    Alter
    22
    Beiträge
    661
    super Dirk dickes lob!
    MfG Martinius

Berechtigungen

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