- Akku Tests und Balkonkraftwerk Speicher         
Seite 10 von 11 ErsteErste ... 891011 LetzteLetzte
Ergebnis 91 bis 100 von 137

Thema: Minimallösung: Kamera für den RP6

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    25.02.2010
    Beiträge
    7
    hm... ich kann euch da nicht Helfen.

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

    Der Anschluß:

    Die 5V-Kamera wird am Pin 3/5(Vcc) und 1/2(GND) angeschlossen. Der Vid-Ausgang der Kamera (oder des beliebigen Composite-Video-Lieferanten) kommt an Pin 8 (E_INT1). Dies ist, außer den User_ADCs der einzig freie ADC-Kanal, der zudem noch praktischerweise am XBus liegt. Außerdem hat er einen PullDown von 10K, die optimale Last für ein Composite-Signal. Der Chinch-Stecker wird zusätzlich zwischen Pin 8 (Signal) und Pin 1/2 (GND) angeschlossen. Der ist eigentlich nur zu Kontrolle gedacht, damit man sehen kann, was der RP6 sieht. Gam(ma) ist bei meiner Kamera nicht angeschlossen, sollte man aber als Jumper vorsehen.
    (Ein Zitat aus dem Startbeitrag dieses Threads.)

    Links die Kamera, in der Mitte der Stecker für den XBUS und rechts unten der Chinchstecker zum Anschluss an den Fernseher:
    Bild hier  

    Das Videosignal hat nominale 1V an 75Ohm. Ohne Kontrollmonitor (Fernseher) ist aber nur der PullDown am E_INT1 angeschlossen. Die gemessenen Werte sind daher höher als mit Kontrollmonitor. Um diesen Effekt etwas zu dämpfen habe ich bei späteren Anwendungen einen jumperbaren 100Ohm-Widerstand als zusätzlichen PullDown eingesetzt der im Betrieb ohne Kontrollmonitor die Signalquelle mehr belastet.

    FBAS auf VGA passt nicht wirklich: http://lmgtfy.com/?q=fbas+to+vga

    Gruß

    mic
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken xbus.jpg  
    Bild hier  
    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 Roboter-Spezialist
    Registriert seit
    13.03.2010
    Ort
    Hamburg
    Beiträge
    333
    komisch ich finde den E_INT1 irgendwie nicht auf meinem RP6

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    Beiträge
    5.799
    Blog-Einträge
    8
    E_INT1 ist der Anschluß PA4 am Mega32 und der Pin8 am XBUS:

    #define UBAT (1 << PINA7) // ADC7 (Input)
    #define MCURRENT_L (1 << PINA6) // ADC6 (Input)
    #define MCURRENT_R (1 << PINA5) // ADC5 (Input)
    #define E_INT1 (1 << PINA4) // INT1 (input per default... can be output)
    #define LS_L (1 << PINA3) // ADC3 (Input)
    #define LS_R (1 << PINA2) // ADC2 (Input)
    #define ADC1 (1 << PINA1) // ADC1 (Input)
    #define ADC0 (1 << PINA0) // ADC0 (Input)
    (Aus RP6RobotBase.h)
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.03.2010
    Ort
    Hamburg
    Beiträge
    333
    Cool Danke ich werds mal versuchen \/

    Lg Alex

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

    Trotz Mitmachprojekt finden sich immer noch keine Anwendungen für diese einfache und kostengünstige Kameralösung. Weil ich die Kamera aber für mein RA2-Projekt verwenden möchte und mir gleichzeitig eher zufällig ein zur Kamera passendes sehr grobpixeliges Display in die Hände gefallen ist, habe ich eine Variante für einen 8MHz-ATMega8 geschrieben. Aufgrund der Erkenntnisse aus dem Mitmach-Thread verwende ich als Basis das einfache 24x16 Pixel-Programm. An das Display angepasst werden nur 12 der 16 möglichen x-Pixel angezeigt, die y-Auflösung wurde auf 10 Zeilen reduziert. Der ADC rennt zwar immer noch mit Prescaler /2 im Dauerlauf, aber da nun auf das Ende der AD-Wandlung gewartet wird, ist das Einlesen eines Bildes so entspannt, dass man dazu nicht mal mehr die Interrupts sperren muss:

    Code:
    uint8_t bild[4][160];
    
    uint8_t Bild_aufnehmen(void)
    {
    	static uint8_t bildnummer=0;
    	uint8_t *bildzeiger;
       uint8_t zeile, sync, c;
    
       bildnummer = (bildnummer+1) & 3; // Bildnummer von 0 bis 3
       zeile=30; // 30 Zeilen am Bildanfang überlesen
       bildzeiger = &bild[bildnummer][0];
    
       do{sync=0;while (ADCH > 20);while (ADCH < 30) sync++;}while (sync < 40);
       for(c=0; c<10; c++) // 10 Zeilen einlesen
       {
          sync=15; // 15 Werte sollen am Stück gelesen werden
          while(zeile--){while (ADCH > 20);while (ADCH < 30);} // auf Zeile warten
          *bildzeiger++=ADCH; // erster Wert!
          ADCSRA |= (1<<ADIF);
          while(sync--) // Werte 2-16 einlesen
          {
             while(!(ADCSRA & (1<<ADIF)));
             *bildzeiger++=ADCH;
             ADCSRA |= (1<<ADIF);
          }
          zeile=24; // 24 Zeilen überlesen (30+ 24*10 = 270 Zeilen)
       }
    	return(bildnummer);
    }
    Wie gehabt wird der ADC mit Prescaler /2, rechtsbündig und mit interner 2,56V-Referenz betrieben. Nach der Erkennung des Bildstarts werden 30 Zeilen überlesen, dann werden in einem Rutsch die 16 Pixel einer Zeile eingelesen. Nach jeweils einem Zeilensprung von 24 Zeilen werden dann schließlich die restlichen 9 Zeilen eingelesen. Das alles passiert innerhalb eines Halbbildes und mit freigegebenen Interrupts!

    Der Bildspeicher ist 16x10=160 Bytes groß, ich verwende davon vier Stück die ich nacheinander mit den Kameradaten fülle. Die Einlesefunktion verwendet die Bildspeicher als Ringspeicher. Die Auswertefunktion bildet das Mittel aus den einzelnen Bildspeichern und stellt die Pixel auf dem Display dar:

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

    Mein ungeputzter Arbeitscode:

    Code:
    // Kamera und acht Helligkeitsstufen                               mic 29.12.2010
    
    #include <avr/wdt.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    #include <inttypes.h>
    
    #define colors 8 // Anzahl der Farbebenen (8 ist Maximum!)
    
    // Variablen ------------------------------------------------------------------
    volatile uint8_t ebene=0, col = 0; // Bildaufbau der LED-Matrix mit Timer2-ISR
    uint8_t x, y, z, bildspeicher[colors][15];
    uint8_t bild[4][160];
    uint16_t counter=0;
    uint8_t attrib=1;
    
    prog_uint8_t font[5][17]={ // Zeichensatz für 3x5 7-Segmentanzeige 0 bis F und Blank (Speicherplatz im Flash)
    { 0b111, 0b001, 0b111, 0b111, 0b100, 0b111, 0b100, 0b111, 0b111, 0b111, 0b111, 0b100, 0b111, 0b001, 0b111, 0b111, 0b000},\
    { 0b101, 0b001, 0b001, 0b001, 0b101, 0b100, 0b100, 0b001, 0b101, 0b101, 0b101, 0b100, 0b100, 0b001, 0b100, 0b100, 0b000},\
    { 0b101, 0b001, 0b111, 0b111, 0b111, 0b111, 0b111, 0b001, 0b111, 0b111, 0b111, 0b111, 0b100, 0b111, 0b111, 0b111, 0b000},\
    { 0b101, 0b001, 0b100, 0b001, 0b001, 0b001, 0b101, 0b001, 0b101, 0b001, 0b101, 0b101, 0b100, 0b101, 0b100, 0b100, 0b000},\
    { 0b111, 0b001, 0b111, 0b111, 0b001, 0b111, 0b111, 0b001, 0b111, 0b001, 0b101, 0b111, 0b111, 0b111, 0b111, 0b100, 0b000} \
    };
    prog_uint8_t * fnt = (prog_uint8_t *) font; // Zeiger für den Zugriff auf den Zeichensatz (für plot_byte())
    
    // Funktionen -----------------------------------------------------------------
    void init(void);
    void cls(void);
    void plot_byte(uint8_t x, uint8_t y, uint8_t ziffer); // Ziffer von 0 bis F
    void write_byte(uint8_t a, uint8_t z); // z=0 ist oben, z=1 ist unten
    uint8_t Bild_aufnehmen(void);
    void Bild_darstellen(uint8_t level);
    void Bild_Info(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);
    // Potiwert P2 an ADC6 einlesen als Byte! Kanal 7 ist die Cam
    uint8_t readADC6(void);
    
    // 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(); }
    
    // Hauptschleife --------------------------------------------------------------
    int main(void)
    {
    	init();
    	for(x=0; x<12; x++)
    	   for(y=0; y<10; y++)
    			set(x, y, (colors-((x+y)/3)%colors)); // Helligkeitsstufen anzeigen
       _delay_ms(2000);
    
     	cls();
    
    	while(Bild_aufnehmen()); 				// Bildspeicher füllen
    	// Bild_Info(); // min - max - mitte - durchschnitt
    	while(1)
    	{
    		if(!col)
    		{
       		z=readADC6();
       		if(attrib)
    			{
    				for(y=5; y<10; y++)
       	   		for(x=0; x<12; x++) set(x, y, z/29); // 255/29 ergibt 8,8
    			}
    			else
    			{
    	      	while(Bild_aufnehmen());
    				Bild_darstellen(z);
    			}
       		if(z==0) if(attrib) { attrib=0; Bild_Info(); } // Bit0: Zeile
       		if(z==255) if(!attrib) { attrib=1;};
    			if(attrib) write_byte(z, attrib);
    		}
          counter++;
    	}
    	return (0);
    }
    
    // Definitionen der Funktionen ------------------------------------------------
    uint8_t Bild_aufnehmen(void)
    {
    	static uint8_t bildnummer=0;
    	uint8_t *bildzeiger;
       uint8_t zeile, sync, c;
    
       bildnummer = (bildnummer+1) & 3; // Bildnummer von 0 bis 3
       zeile=30; // 30 Zeilen am Bildanfang überlesen
       bildzeiger = &bild[bildnummer][0];
    
       do{sync=0;while (ADCH > 20);while (ADCH < 30) sync++;}while (sync < 40);
       for(c=0; c<10; c++) // 10 Zeilen einlesen
       {
          sync=15; // 15 Werte sollen am Stück gelesen werden
          while(zeile--){while (ADCH > 20);while (ADCH < 30);} // auf Zeile warten
          *bildzeiger++=ADCH; // erster Wert!
          ADCSRA |= (1<<ADIF);
          while(sync--) // Werte 2-16 einlesen
          {
             while(!(ADCSRA & (1<<ADIF)));
             *bildzeiger++=ADCH;
             ADCSRA |= (1<<ADIF);
          }
          zeile=24; // 24 Zeilen überlesen (30+ 24*10 = 270 Zeilen)
       }
    	return(bildnummer);
    }
    
    void Bild_darstellen(uint8_t level)
    {
       uint8_t x, y, temp;
       uint8_t bild_temp[160];
       uint16_t temp16;
    
       for(x=0; x<160; x++)
       {
          temp16 = bild[0][x] + bild[1][x] + bild[2][x] + bild[3][x];
          bild_temp[x] = temp = temp16/4;
    	}
    
    	if(level)
    	{
    		for(y=0; y<10; y++)
    	   	for(x=0; x<12; x++)
    			{
    		   	temp= bild_temp[16*y+x+2];
    	      	if(temp<level) set(x, 9-y, colors); else set(x, 9-y, 0);
    			}
    	}
    	else
    		for(y=0; y<10; y++)
    	   	for(x=0; x<12; x++)
    			{
    		   	temp= bild_temp[16*y+x+2];
    	      	set(x, 9-y, (temp-20)/8);
    			}
    }
    
    void Bild_Info(void)
    {
       uint8_t min=225, max=0, temp;
       uint16_t durchschnitt=0, temp16;
    
       for(x=0; x<160; x++)
       {
          temp16 = bild[0][x] + bild[1][x] + bild[2][x] + bild[3][x];
          temp = temp16/4;
          if(temp > max) max=temp;
             else if(temp>20) if(temp < min) min=temp;
    		durchschnitt += temp;
    	}
    	durchschnitt /= 160;
    
    	cls();
    	write_byte(min, 1);
    	_delay_ms(1000);
    	cls();
    	write_byte(max, 0);
    	_delay_ms(1000);
    	cls();
    	write_byte((min+max)/2, 1);
    	_delay_ms(1000);
    	cls();
    	write_byte(durchschnitt, 0);
    	_delay_ms(1000);
    }
    
    void cls(void)
    {
    	uint8_t x, y;
       for(y=0; y<colors; y++)
    		for(x=0; x<15; x++)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)));
    }
    void plot_byte(uint8_t x, uint8_t y, uint8_t ziffer)
    {
    	uint8_t c, f1=colors, f2=0, fontbyte=0;
    
    	for(c=0; c<5; c++)
    	{
    		fontbyte = pgm_read_byte_near(fnt+17*c+ziffer); // Zeichensatz ist im Flash
    		if(fontbyte & 4) set(x  , y-c, f1); else set(x  , y-c, f2);
    		if(fontbyte & 2) set(x+1, y-c, f1); else set(x+1, y-c, f2);
    		if(fontbyte & 1) set(x+2, y-c, f1); else set(x+2, y-c, f2);
    		if(fontbyte & 0) set(x+3, y-c, f1); else set(x+3, y-c, f2);
    	}
    }
    void write_byte(uint8_t a, uint8_t z) // z=0 ist oben, z=1 ist unten
    {
    	uint8_t c, temp=1;
    
    	c=0;
    	while(a >= 100) {a-=100; c++; }
    	if(c) plot_byte(0, 9-5*z, c); else { plot_byte(0, 9-5*z, 16); temp=0; }
    	c=0;
    	while(a >= 10) {a-=10; c++; }
    	if(c || temp) plot_byte(4, 9-5*z, c); else plot_byte(4, 9-5*z, 16);
    	c=0;
    	while(a >= 1) {a-=1; c++; }
    	plot_byte(8, 9-5*z, c);
    }
    uint8_t readADC6(void)
    {
     	uint8_t adc6, dummy;
    	ADCSRA = (0 << ADEN);
    	dummy=ADCH;
     	
    	// A/D Conversion (aus der asuro-Lib)
    	ADCSRA = (1 << ADEN) | (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); // clk/32
    	ADMUX = (1<<ADLAR) | (1 << REFS0) | (6);// AVCC reference with external capacitor
    	ADCSRA |= (1 << ADSC);					// Start conversion
    	while (!(ADCSRA & (1 << ADIF)));		// wait for conversion complete
    	adc6=ADCH;
    	ADCSRA |= (1 << ADIF);					// clear ADCIF
    	ADCSRA = (0 << ADEN);
    	dummy=ADCH;
    	// rechtsbündig, interne 2,56V-Referenz (0:1 5V, 1:1 2,56V) , Kanal 7
    	ADMUX = (1<<ADLAR) | (1<<REFS1) | (1<<REFS0) | 7;
    	// enable, start conversion, freerunning, prescaler /2
    	ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADFR) | (0<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
    
    	return(adc6);
    }
    void init(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
    
    	// rechtsbündig, interne 2,56V-Referenz (0:1 5V, 1:1 2,56V) , Kanal 7
    	ADMUX = (1<<ADLAR) | (1<<REFS1) | (1<<REFS0) | 7;
    	// enable, start conversion, freerunning, prescaler /2
    	ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADFR) | (0<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
    
    	sei();							    		// Interrupts erlauben
    }
    
    // ISR ------------------------------------------------------------------------
    SIGNAL (SIG_OUTPUT_COMPARE2)
    {
    	OCR2 = (1<<ebene)-1;	// hihi
    	PORTC &= ~0x0f; 		// Die Pins der Displaymatrix werden wieder auf Low gesetzt
    	PORTD &= ~0xf0;
    	PORTB &= ~0x03;
    }
    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
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hi mic,

    das ist ja mal wieder genial!

    Ich hole mir dieses PingPong erst mal vom großen C.

    Ich wußte gar nicht, dass da ein M8 drin sitzt...

    Gruß Dirk

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    06.06.2011
    Beiträge
    15
    Gibt es einen aktuelleren Quellcode?
    Ich möchte dieses Projekt für mein nächstes verwenden.

  9. #9
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    Beiträge
    5.799
    Blog-Einträge
    8
    Das ist der aktuellste Quellcode. Der ADC wird zwar auch hier gnadenlos übertaktet, aber beim Einlesen einer Bildzeile wird nicht mehr stur eingelesen sondern auf den Status des ADC geachtet. Es ist die aktuell schnellste Lösung, alle Pixel werden innerhalb eines Halbbildes eingelesen. Basis ist diese Version:

    https://www.roboternetz.de/phpBB2/ze...=500285#500285

    Bedeutend höhere Auflösungen sind auch möglich, allerdings wird so pro Halbbild nur ein Pixel pro Zeile eingelesen:

    https://www.roboternetz.de/community...l=1#post458253
    https://www.roboternetz.de/community...l=1#post457599

    Was soll die Kamera bei deinem Projekt erkennen?
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    06.06.2011
    Beiträge
    15
    Die Kamera soll drei IR Laser Orten um die Landung eines Quadrocopters autonom erfolgen zu lassen. Wenn ich fertig bin werde ich mal ein Video posten (wahrcheinlich erst in den Sommerferien).
    Danke für den aktuellen Quellcode. Mit was hast du den denn Compiliert?

    LG Matthias

Seite 10 von 11 ErsteErste ... 891011 LetzteLetzte

Stichworte

Berechtigungen

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

Solar Speicher und Akkus Tests