PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kameramodul



Maxtronik
28.03.2009, 13:11
Moin, Moin allerseits

Ich habe mir überlegt meinem Roboter das sehen bei zubringen.
Dazu wollte ich das Kamera modul von conrad benutzen:
http://www1.conrad.de/scripts/wgate/zcop_b2c/~flNlc3Npb249UDkwV0dBVEU6Q19BR0FURTE3OjAwMDYuMDEyO C45ODJiZjRiMSZ+aHR0cF9jb250ZW50X2NoYXJzZXQ9aXNvLTg 4NTktMSZ+U3RhdGU9NzkwNzcwMTAy====?~template=PCAT_A REA_S_BROWSE&mfhelp=&p_selected_area=%24ROOT&p_selected_area_fh=&perform_special_action=&glb_user_js=Y&shop=B2C&vgl_artikel_in_index=&product_show_id=&p_page_to_display=DirektSearch&~cookies=1&zhmmh_lfo=&zhmmh_area_kz=&s_haupt_kategorie=&p_searchstring=kamera+modul&p_searchstring_artnr=&p_searchstring_manufac_artnr=&p_search_category=alle&fh_directcall=&r3_matn=&insert_kz=&gvlon=&area_s_url=&brand=&amount=&new_item_quantity=&area_url=&direkt_aufriss_area=&p_countdown=&p_80=&p_80_category=&p_80_article=&p_next_template_after_login=&mindestbestellwert=&login=&password=&bpemail=&bpid=&url=&show_wk=&use_search=3&p_back_template=&template=&kat_save=&updatestr=&vgl_artikel_in_vgl=&titel=&darsteller=&regisseur=&anbieter=&genre=&fsk=&jahr=&jahr2=&dvd_error=X&dvd_empty_error=X&dvd_year_error=&call_dvd=&kna_news=&p_status_scenario=&documentselector=&aktiv=&gewinnspiel=&p_load_area=$ROOT&p_artikelbilder_mode=&p_sortopt=&page=&p_catalog_max_results=20

Wenn der Link nich "tutst" dann gibt im Suchfeld einfach
"S/W-KAMERA MODUL 1" ein.

Als Schaltung wollte ich diese nehmen:
http://roboterclub-freiburg.de/AtmelAVR/Hardware/AtmegaKamera/AtmegaKamera.html
Nur das ich einen Atmega168 benutzen wollte.

Nun habe ich noch einige Fragen:
-Ist das Modul geigneet
-kann ich auch einen Atmega168 benutzen
-und wie programmiere ich ihn, dass mein Atmega168 z.B. eine schwarze Linie erkennt und sie verfolgen kann?

Danke im voraus! =D>

Vitis
28.03.2009, 13:55
ja, die Kamera sollte zu der angegebenen Schaltung passen.
Denk daran, Bilddaten == meist große Datenmenge,
ergo sollte der 168 schonmal nicht schlecht sein ....
Problem ist die Verarbeitung, das kann dann schon etwas
auf die Leistung gehen, mach Dir auch Gedanken darüber
evtl. nen separaten µC zur Bildauswertung zu nehmen
und den mit dem Haupt-µC kommunizieren zu lassen.

radbruch
28.03.2009, 14:00
Hallo,

willkommen im RN-Forum.

Mit einem Mega32 (läuft anscheinend auch mit einem Mega8) kann eine einfache analoge Kamera etwa so funktionieren:

http://img.youtube.com/vi/G2F4jhsRtF4/1.jpg (http://www.youtube.com/watch?v=G2F4jhsRtF4) http://img.youtube.com/vi/txMYl7aKTBA/default.jpg (http://www.youtube.com/watch?v=txMYl7aKTBA) http://i1.ytimg.com/vi/46ts6GH04NI/1.jpg (http://www.youtube.com/watch?v=46ts6GH04NI) http://i4.ytimg.com/vi/3r_m2rGgXLk/default.jpg (http://www.youtube.com/watch?v=3r_m2rGgXLk)

Das sind Impressionen aus meinem schon etwas betagten RP6mitKamera-Thread (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=33228). Trotz einiger Ungereimtheiten, die zum Teil auf meine damalige Unerfahrenheit zurückzuführen sind, funktionierte das schon recht gut. Wenn nichts dazwischenkommt werde ich diese Kamera demnächst an meinem Deltaarm einsetzen ;)

Die Lösung vom Freiburger Roboterclub (http://roboterclub-freiburg.de) scheint mir deutlich ausgereifter und bei Bedarf bekommst du dort sicher auch zusätzliche Unterstützung bei deinem Projekt.

Viel Spaß und Erfolg.

Gruß

mic

Maxtronik
28.03.2009, 14:07
Danke Danke xD :cheesy:
WOW das das so einfach geht hät ich nich gadacht.
Werd mich gleich mal ans Werk machen!
Danke noch mal
Viele Grüße

Maxtronik
28.03.2009, 14:20
Eine Frage hätte ich noch:
Lässt sich das ganze auch in Bascom realisieren?
ich bin nämlich absolut kein c Programmierer!
(Gut man kann dat lernen, aber das dauert und ich hab die nötige Zeit nicht)
Würde mich auf eine Antwort freuen.

radbruch
28.03.2009, 15:02
Nochmals hallo

Da Bascom auch direkt auf die Register des AVRs zugreifen kann sollte eine Umsetzung damit auch möglich sein. Ob das auch mit den Config-Befehlen von Bascom funktioniert kann ich nicht sagen, aber ich würde da gar nicht lange rumexperimentieren und die paar ADC-Einstellungen einfach "von Hand" setzen. Die Einleseroutine des ADCH-Registers sollte aber unbedingt selbstgeschrieben und soweit wie möglich zeitoptimiert sein, denn vermutlich kann Bascom das nicht so optieren wie wir es möchten (nur ein Verdacht). Ich habe dazu ein Feld angelegt und arbeite mit einem Zeiger. In C habe ich das schließlich so formuliert:

...allerdings schaffe ich so nur ca. 60 Werte pro Zeile. Mehr geht einfach nicht mit C, vielleicht kann man mit Assembler hier noch etwas "rauskitzeln". Mein Code für das Einlesen eines Pixels:

do *pixelzeiger=ADCH; while (*pixelzeiger++ > 20);

Alternativen wie:

while (count_pixel) pixel[--count_pixel]=ADCH;
for (;count_pixel; pixel[--count_pixel]=ADCH);

wurden fast identisch übersetzt und brachten nur ca. 50 Lesungen pro Zeile.
Wobei die Auslesegeschwindigkeit möglicherweise gar nicht so kritisch ist falls der ADC doch nicht schnell genug wandeln sollte.

Einfache Hell/Dunkel-Erkennung ohne Speichern der Werte geht allerdings deutlich einfacher:


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);
}
Diese Funktion sucht in der 50. Zeile des Bildes von links beginnend den ersten Bildpunkt (Pixel) dessen 8-bit Helligkeitswert kleiner (=dunkler) als 100 ist und gibt die Nummer dieses Punktes zurück. Das kann man ein zu eins in Bascom umsetzen, zusammen mit der ADC-Dauerlauf-Inizialisierung war das dann schon alles.

Gruß

mic

Maxtronik
28.03.2009, 15:22
Nochmals Danke Danke :cheesy: Radbruch
aber wäre es vielleicht möglich, das es dafür schon irgendein Beispiel in Bascom gibt?Ich habe nämlich nicht wirklich alles verstanden
ADCH-Registers?(kenn nur ADC)

Ich überlege aber auch gerade ob ich das doch nich besser in c machen soll.

radbruch
28.03.2009, 16:13
Ich habe nämlich nicht wirklich alles verstandenWie auch, ich habe einige Wochen Drübernachdenkzeit Vorsprung, das kannst du an einem Nachmitag kaum einholen :)

Die ADC (Analog/Digital-Wandler) der AVRs liefern einen 10bit-Wert im 16bit-ADC-Register. Dieses Register setzt sich aber eigentlich aus den zwei 8bit-Registern ADCH und ADCL zusammen (AVRS sind 8-bit-Kontroller) auf die man jeweils auch einzeln zugreifen kann. Um alle 16 Bits auszulesen muss erst das ADCL- und dann das ADCH-Register gelesen und beide Werte zum 16Bit-Ergebniss zusammengesetzt werden (das erledigen die Compiler selbstständig). Nun darf der ADC zwischen diesen beiden 8bit-Lesungen die Werte nicht verändern, deshalb wird er automatisch gestoppt bis das ADCH auch gelesen wurde:

When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently,
if the result is left adjusted and no more than 8-bit precision is required, it is
sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH.(Aus dem Datenblatt des Mega32 Seite 217)

Für unsere Kamera benötigen wir aus mehreren Gründen nicht die volle Auflösung des ADCs, deshalb begnügen wir uns mit höchstens 8 Bit (für Hell/Dunkel würden eigentlich schon zwei genügen). Und genau dafür hat der ADC eine spezielle Funktion: Er kann das Ergebniss linksbündig darstellen. Das bedeutet, das 10Bit Ergebniss der Wandlung stehen im ADC-Register nicht in ADC:Bit9-0 sondern in ADC:Bit15-6. Wenn man nun ADCH ausliest und ADCL wegwirft erhält man die MSB des Ergebnisses als 8bit-Wert:

The ADLAR bit in ADMUX, and the MUXn bits in ADMUX affect the way the result is
read from the registers. If ADLAR is set, the result is left adjusted. If ADLAR is cleared
(default), the result is right adjusted.(Ich gehe mal davon aus ihr beherrscht Datenblattenglisch)

Ich sehe eigentlich keinen Grund dafür von Bascom nach C zu wechseln. (Bascom gefällt mir persönlich eigentlich auch besser als C. Wenn ich unter anderen Vorzeichen auf die Microkontroller gestoßen wäre, hätte ich mich vermutlich für Bascom entschieden.) Obwohl diese Anwendung einer Kamera wohl eher die Ausnahme sein dürfte kann es durchaus sein dass im WWW irgendwo ein fertiges Bascomprogramm dafür schlummert. Ich habe allerdings noch nicht danach gesucht.

Gruß

mic

Maxtronik
28.03.2009, 19:09
Ich habs jetzt glaub ich verstanden.
Werde noch nen bisschen googlen.
Also mit einem Dankeschön werd ich wohl nicht weit kommen.
Da müssten schon 100000sende her.
Aber ich muss wirklich sagen, das du richtig nett bist, dir die Mühe zu machen mir alles verständlich zu erklären!!!
DANKE
Du hast was gut bei mir!
Ich werde später mein Projekt unter fertige Bots veranschaulichen.
Viele Grüße

radbruch
28.03.2009, 20:06
So ganz ohne Eigennutz ist das dann auch nicht für mich. Es ist eine willkommene Auffrischung des Themas, im Hinblick auf meine geplante Nutzung bei meinem aktuellen Projekt. Wenn ich jemanden einen Sachverhalt so erklären kann das es für mich schlüssig ist weiß ich dass ich es selbst halbwegs kapiert habe.

Schönes WE

mic

radbruch
30.03.2009, 21:17
Hallo

Da ich sehr selten in Bascom programmiere (zuletzt beim Nunchuk (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=42153)) fehlen mir natürlich ein paar Grundlagen. Immerhin hat es trotzdem auf Anhieb funktioniert (die Bascom-Profis dürfen natürlich lachen):

'Analoge Kamera an ATMega32 (RP6) 30.3.09 mic


$regfile = "M32def.dat" ' RP6 mit Mega32
$crystal = 8000000 ' taktet mit 8MHz
$baud = 38400 ' Loader-Baud

Dim X As Byte
Dim S As String * 30 'max 30 Positionen

Config Adc = Free , Prescaler = Auto , Reference = Avcc ' Dummy-Setup!!!

' ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4 (E_INT1)
' Admux =(1 << Refs1) |(1 << Refs0) |(1 << Adlar) | 4

Admux = 0
Set Admux.refs1
Set Admux.refs0
Set Admux.adlar
Set Admux.2 'Kanal 4
'Set Admux.1
'Set Admux.0

' setze free running triggern
' Sfior =(0 << Adts2) |(0 << Adts1) |(0 << Adts0)
Sfior = 0

' 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)

Adcsr = 0
Set Adcsr.aden
Set Adcsr.adps0

Set Adcsr.5 'adate
Set Adcsr.adif

Set Adcsr.adsc

Start Adc

Do
'Cli();
Disable Interrupts
' / / Auf Bildanfang Warten
'Do
Do
' {
' i=0;
X = 0
' while (ADCH > 30);
While Adch > 30
Wend
' while (ADCH < 50) i++;
While Adch < 50
Incr X
Wend
' } while (i < 40);
Loop Until X > 40
' // die ersten 50 Zeilen überlesen
' i=50;
X = 50
' while (i--)
While X > 0
' {
' while (ADCH > 30);
While Adch > 30
Wend
' while (ADCH < 50);
While Adch < 50
Wend
Decr X
Wend
' }
' // warten auf hell-dunkel-Übergang
' i=0;
X = 0
' while (ADCH > 70) i++;
While Adch > 65 'Hell/Dunkel-Schwelle
Incr X
Wend
' sei();
Enable Interrupts

Print X ;
S = Space(x)
Print S;
Print "***"
Waitms 200
Loop

End

So kann ich im Moment ca. 23 Positionen des Striches unterscheiden:
http://i1.ytimg.com/vi/H-p-W9r-_Vk/2.jpg (http://www.youtube.com/watch?v=H-p-W9r-_Vk)
http://www.youtube.com/watch?v=H-p-W9r-_Vk

Nett, oder?

Gruß

mic

Vitis
31.03.2009, 01:36
die auskommentierten Zeilen machens dann doch etwas unübersichtlich ...
hier mal etwas gekürzt und bereinigt :


'Analoge Kamera an ATMega32 (RP6) 30.3.09 mic


$regfile = "M32def.dat" ' RP6 mit Mega32
$crystal = 8000000 ' taktet mit 8MHz
$baud = 38400 ' Loader-Baud

Dim X As Byte
Dim S As String * 30 'max 30 Positionen

Config Adc = Free , Prescaler = Auto , Reference = Avcc ' Dummy-Setup!!!

Admux = 0
Set Admux.refs1
Set Admux.refs0
Set Admux.adlar 'ausrichtung links (adch) für 8-bit
Set Admux.2 'Kanal 4
'Sfior = 0
' eventuell besser für andere Funktionen:
Sfior = Sfior And &B00011111 ' adts2=0 adts1=0 adts0=0
Adcsr = 0
Set Adcsr.aden 'ADC Enable
Set Adcsr.adps0 ' ADC Prescaler Select Bits (2)

Set Adcsr.5 'adate (ADC Auto Trigger Enable)
Set Adcsr.adif 'ADC Interrupt Flag

Set Adcsr.adsc 'ADC Start Conversion

Start Adc

Do
Disable Interrupts
' / / Auf Bildanfang Warten
Do
X = 0
While Adch > 30
Wend
While Adch < 50
Incr X
Wend
Loop Until X > 40
X = 50
While X > 0
While Adch > 30
Wend
While Adch < 50
Wend
Decr X
Wend
X = 0
While Adch > 65 'Hell/Dunkel-Schwelle
Incr X
Wend
Enable Interrupts
Print X ;
S = Space(x)
Print S;
Print "***"
Waitms 200
Loop

End

thewulf00
31.03.2009, 10:28
Sieht gut aus.
Hier wird keiner lachen, solange es funktioniert!

Scheint nur etwas langsam zu gehen? Liegt das an BASCOM oder anderen Einflüssen?

Mons
12.06.2011, 11:50
Huhu, grabt den Thread mal wieder aus; istt ein interessantes Thema!