- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 5 von 14 ErsteErste ... 34567 ... LetzteLetzte
Ergebnis 41 bis 50 von 137

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

  1. #41
    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

    Mein aktuelles Projekt bringt mich wieder zurück zur einfachen Kamera:
    Bild hier  
    http://www.youtube.com/watch?v=XTYzLqgKMLM

    Das sieht zwar schon recht schick aus, aber die Ergebnisse mit den Phototransistoren sind einfach unbefriedigend wenn man die Leistung der Kamera kennt ;)

    Im Moment mache ich noch Tests mit dem RP6 (8MHz Mega32) als Steuerung, geplant ist das aber eigentlich für einen tiny13 mit 9,6MHz. Deshalb muss der Code deutlich schlanker werden, was zur Folge hat, dass alles auch etwas übersichtlicher ist. Zur allgemeinen Erheiterung zeige ich euch deshalb mal den aktuellen Stand meiner Vorversuche. Ziel ist dabei u.a. möglichst wenig Ram zu verbraten denn der tiny hat davon nicht wirklich viel:
    Code:
    // cd-racer mit cam (erste Tests mit RP6)                          25.9.2008 mic
    
    #include "RP6RobotBaseLib.h"
    
    uint8_t get_line(void)
    {
    	uint8_t i;
    
    	cli();
    	
    	// auf Bildanfang warten
    	do
    	{
    		i=0; while (ADCH > 30); while (ADCH < 50) i++;
    	} while (i < 40);
    
    	// die ersten 50 Zeilen überlesen
    	i=50;
    	while (i--)
    	{
    		while (ADCH > 30); while (ADCH < 50);
    	}
    
     	// warten auf hell-dunkel-Übergang
    	while (ADCH > 110) i++; // Zeile einlesen bis Wert deutlich Richtung dunkel
    	sei();
    	return(i);
    }
    
    int main(void)
    {
    	uint8_t linie;
    	uint16_t i, servo=1550, dummy;
    
    	initRobotBase();
    	extIntOFF(); // schaltet den E_INT1-Port auf Eingang für den ADC
    	//powerON();
    
    // ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4 (E_INT1)
    	ADMUX = (1<<REFS1) | (1<<REFS0)  | (1<<ADLAR) | 4;
    // setze free running triggern
    	SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
    // kein Interupt, Wandler einschalten, prescaller /2
    	ADCSRA = (0<<ADIE) | (1<<ADEN) | (0<<ADPS2) | (0<<ADPS1)  | (1<<ADPS0);
    // Autotriggern bedeutet jetzt free running aktivieren, altes Flag löschen
    	ADCSRA |= (1<<ADATE) | (1<<ADIF);
    // Initialisierung starten
    	ADCSRA |= (1<<ADSC);
    // und noch die wohl eher unnötige Initiallesung
    	while (!(ADCSRA & (1<<ADIF)));
    	ADCSRA |= (1<<ADIF);
    	
    	// SCL (Pin10) auf Ausgang und Low zur Servoansteuerung
    	DDRC |= 1;
    	PORTC &= ~1;
    
    	while (1)
    	{
    		linie=get_line(); // linke Kante der Linie suchen
    
       	if((linie > 0) && (linie < 70)) // Linie im "Bild"?
       	{
    			if(linie > 36 && servo <2000) servo+=(linie-35)*2; // Servoposition
    			if(linie < 34 && servo > 675) servo-=(35-linie)*2; // korrigieren
    
    			i=servo; // Servo blockierend auf Position stellen
    			cli();
    			PORTC |= 1;
    			while(i--) dummy ^= i;
    			PORTC &= ~1;
    			sei();
    			i=15000;
    			while(i--) dummy ^= i;
    		}
    	}
    	return(0);
    }
    Wie gehabt hängt die Kamera wieder direkt an einem ADC-Pin. Der ADC rennt wieder im Dauerlauf mit kleinstem Prescaler und die Werte werden auch wieder ohne Rücksicht auf den ADC-Status linksbündig als 8bit-Wert eingelesen. Der Ablauf ist zu Beginn ebenfalls wie gehabt: Warten auf neues Bild und dann Zeilen zählen bis der Start der gewünschten Zeile erreicht ist. Dann kommt eine kleine Änderung: Ich zähle wie oft der eingelesene Wert einen (im Moment noch festen) Wert überschreitet (=heller als Linie) und interpretiere diesen Zählwert dann als linke Kante der Linie. So erhalte ich Werte zwischen 0="Linie links aus dem Bild" bis 69="Linie rechts aus dem Bild".

    Mit diesem Wert steuere ich dann ein Servo (ohne großen Schnickschnack über eine Zählschleife mit gesperrten Interrupts) und halte so die Kamera bei einem Wert zwischen 34 und 36:
    Bild hier  
    http://www.youtube.com/watch?v=46ts6GH04NI

    Weil das so wunderbar funktioniert werde ich wohl nochmals einen kleinen Versuch mit einem liniefolgenden RP6 unternehmen ;)

    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!

  2. #42
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.12.2007
    Ort
    Berlin
    Alter
    40
    Beiträge
    211

    Erstmal respekt an die erbrachten Leißtungen ! Wow

    Ich habe da so eine Idee, aber leider noch nicht soo viel Ahnung vons Janze, wie das halt öfter so ist : ) .

    Wäre es möglich mit der erweiterung M32 ein 8-Bit Graustufenblid zu erkennen?

    Die Idee dahinter ist folgende.
    Ich dachte mir man könnte das Bild als Raster berechnen, um Bewegung/-en in den verschiedenen Sektoren des Rasters zu erkennen.
    Anschliesend lässt man den RP6 immmer in die Richtung der Sektoren fahren, welche sich wenig verändern.
    Stellt man sich nun einen raum, z.B. sein Zimmer vor, fährt der RP6 immer in die Tiefe des Abblides von dem Raum, bzw. zu den unveränderten Sektoren. Sollte es so sein, das er auf eine weisse Wand zufährt gibt es dafür noch andere Sensoren.

    Ich hoffe es ist einigermaßen nachzuvollziehen was ich meine.

    Was haltet ihr davon ?

    gruss toco

  3. #43
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Wäre es möglich mit der erweiterung M32 ein 8-Bit Graustufenblid zu erkennen?
    Ein 32x32Pixel-Bild würde dann 1k Ram belegen. Der Mega32 hat davon aber nur 2k zur Verfügung. Für echte Bildverarbeitung wie man sie vom PC/Mac kennt sind die AVRs wohl nicht geeignet, auch wenn manche Typen noch deutlich mehr Ram anbieten können.
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #44
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    384
    Macht das kein Sinn om einen LM1881 zu nutzen für Erkennung von H-sync und V-sync ? Dan wird die Auslastung von mega32 etwas geringer soll ich denken, und moglich die Erkennung genauer. Den IC selbst soll billig sein und besteht auch in DIP Gehause.

  5. #45
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Macht das kein Sinn om einen LM1881 zu nutzen...
    Das würde schon Sinn machen, aber ich finde, der besondere Reiz liegt eben im Verzicht auf weitere Hardware. Nur die Kamera und der AVR und ein paar Codezeilen und die Sache funzt. Deshalb auch der Threadtitel: "Minimallösung" :)
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  6. #46
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    25.10.2007
    Ort
    Solingen
    Alter
    32
    Beiträge
    177
    hi, da das mit dem Atmega32 nicht so gut geht, wäre das mit dem AT7000 besser zu bewerkstelligen, würde das dann vllt auch mit Farbe funtionieren, es würden auch 32x32 Pixel reichen.

    Wäre toll so Farben zu verfolgen.

    MfG, blenderkid

  7. #47
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.12.2007
    Ort
    Berlin
    Alter
    40
    Beiträge
    211
    Aber für was ließe sich die "minimallösung" einsetzen, wenn ich einen autonomen roboter bauen will?

    mfg carlitoco

  8. #48
    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

    Der RP6 ist einfach zu fett für den engen RN-Kurs:

    Bild hier   Bild hier   Bild hier  
    http://www.youtube.com/watch?v=h7bdUD3mJfg
    http://www.youtube.com/watch?v=sm3WrykPj4M
    http://www.youtube.com/watch?v=3r_m2rGgXLk


    Aber als Test für mein Projekt reicht mir das erstmal. Andere Anwendungen wären z.B. Objekt-, Muster- und Hindernisserkennung, Barcodelesen, Abstandsmessung (mit Laserpointer) und möglicherweise auch Licht-/IR-Kommunikation. Vielleicht fällt mir noch was nettes ein, vorerst bleibe ich mal beim Liniensuchen. Hier noch der Code:

    Code:
    // RP6 folgt einer Linie die mit der Kamera erkannt wird           26.9.2008 mic
    
    #include "RP6RobotBaseLib.h"
    
    #define mitte 1550
    
    // Achtung! Die PWM-Werte werden hier OHNE Rampe verändert!
    void setMotorPWM(uint8_t power_links, uint8_t power_rechts)
    {
    extern uint8_t mleft_ptmp, mright_ptmp;
    
    	if(power_links > 210) power_links = 210;
    	if(power_rechts > 210) power_rechts = 210;
    	mleft_power=mleft_ptmp=power_links;
    	mright_power=mright_ptmp=power_rechts;
    
    	OCR1BL = power_links;
    	OCR1AL = power_rechts;
    
    	if(power_links || power_rechts)
    		TCCR1A = (1 << WGM11) | (1 << COM1A1) | (1 << COM1B1);
    	else
    		TCCR1A = 0;
    }
    
    uint8_t get_line(void)
    {
    	uint8_t i;
    	cli();
    		// auf Bildanfang warten
    	do { i=0; while (ADCH > 30); while (ADCH < 50) i++; } while (i < 40);
    	// die ersten 50 Zeilen überlesen
    	i=50; while (i--) { while (ADCH > 30); while (ADCH < 50); }
    	// warten auf hell-dunkel-Übergang
    	i=0; while (ADCH > 100) i++;
    	sei();
    	return(i);
    }
    
    int main(void)
    {
    	uint8_t linie;
    	uint16_t i, servo=mitte, dummy;
    
    	initRobotBase();
    	extIntOFF(); // schaltet den E_INT1-Port auf Eingang für den ADC
    	//powerON();
    
    // ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4 (E_INT1)
    	ADMUX = (1<<REFS1) | (1<<REFS0)  | (1<<ADLAR) | 4;
    // setze free running triggern
    	SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
    // kein Interupt, Wandler einschalten, prescaller /2
    	ADCSRA = (0<<ADIE) | (1<<ADEN) | (0<<ADPS2) | (0<<ADPS1)  | (1<<ADPS0);
    // Autotriggern bedeutet jetzt free running aktivieren, altes Flag löschen
    	ADCSRA |= (1<<ADATE) | (1<<ADIF);
    // Initialisierung starten
    	ADCSRA |= (1<<ADSC);
    // und noch die wohl eher unnötige Initiallesung
    	while (!(ADCSRA & (1<<ADIF)));
    	ADCSRA |= (1<<ADIF);
    	
    	// SCL (Pin10) auf Ausgang und Low zur Servoansteuerung
    	DDRC |= 1;
    	PORTC &= ~1;
    	setMotorDir(BWD,BWD);
    	//setMotorPWM(100,100);
    
    	while (1)
    	{
    		linie=get_line(); // linke Kante der Linie suchen
    
       	if((linie > 0) && (linie < 70)) // Linie im "Bild"?
       	{
    			if(linie > 36 && servo <mitte+800) servo+=(linie-35)*2; // Servoposition
    			if(linie < 34 && servo >mitte-1000) servo-=(35-linie)*2; // korrigieren
    
    			i=servo; // Servo blockierend auf Position stellen
    			cli();
    			PORTC |= 1;
    			while(i--) dummy ^= i;
    			PORTC &= ~1;
    			sei();
    			i=15000;
    			while(i--) dummy ^= i;
    			
    			if(servo < mitte) setMotorPWM(100, 100-(mitte-servo)/10);
    			if(servo > mitte) setMotorPWM(100-(servo-mitte)/10, 100);
    
    			if(servo < mitte-300)
    			{
    				setMotorDir(BWD,FWD);
    				setMotorPWM(100, (mitte-servo)/10);
    			}
    			else if(servo > mitte+300)
    			{
    				setMotorDir(FWD,BWD);
    				setMotorPWM((servo-mitte)/10, 100);
    			}
    			else setMotorDir(BWD,BWD);
    
    		} // else setMotorPWM(0,0);
    	}
    	return(0);
    }
    Übrigends ist die hier vorgestellte Anwendung bei weitem nicht so zeit- und rechenintensiv wie allgemein angenommen ;)

    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. #49
    Erfahrener Benutzer Roboter Experte Avatar von ikarus_177
    Registriert seit
    31.12.2007
    Ort
    Grein
    Alter
    31
    Beiträge
    601
    Hi,

    ich hab mich auch man an die (Bascom-) Signalerkennung/verarbeitung "gewagt", und mir ein 15€ - Kameramodul vom C zugelegt. Das Kamerasignal wird auch schon recht brav ausgewertet, der schwarze Strich recht zuverlässig erkannt: http://www.youtube.com/watch?v=3WcBV3fSolg

    Vielen Dank an radbruch für die gute Erklärung der Auswertung in C (wie man sieht, funktionierts auch in Bascom recht passabel )!

    In so einer "einfachen" Kamera steckt sicher noch viel Potential, z.B.: ein Laser-Entfernungsmesser,...

    Viele Grüße
    ikarus_177

  10. #50
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.01.2008
    Beiträge
    164
    Sieht gut aus.

    Wie sieht der Bascomcode aus?

    mfg

Seite 5 von 14 ErsteErste ... 34567 ... LetzteLetzte

Stichworte

Berechtigungen

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

LiFePO4 Speicher Test