Hallo tobimc,
das sieht mir nach einem Überlauf von 255 auf 0 aus, da es nur in den hellen Bereichen auftritt. Ich tippe auf einen Fehler im Auswerteprogramm.Was sollen diese komischen 'Schlieren' also diese Großen Kontraständerungen?
Gruß, Michael
Hallo tobimc,
das sieht mir nach einem Überlauf von 255 auf 0 aus, da es nur in den hellen Bereichen auftritt. Ich tippe auf einen Fehler im Auswerteprogramm.Was sollen diese komischen 'Schlieren' also diese Großen Kontraständerungen?
Gruß, Michael
habe hier mal ein programm zusammengestellt aus auszügen für die gameboy-cam in winavr-c. die daten werden bei mir seriell mit 9600baud zum pc übertragen zum programm von tobi. ich habe ein AVR16 mit 8mhz intern und den adc-port-a0 benutzt.
adc.h :
gameboy-cam:Code:#define ADCchannel_init DDRA=0x00 // ADC Port als Eingang deklarieren #define ADCinit ADCSRA|=_BV(ADEN) // Teilt dem Board mit das der jeweilige Port für ADC verwendet wird #define ADCdisable ADCSRA &=~_BV(ADEN) // machs das vorherige wieder rückgänig #define ADCstart ADCSRA|=_BV(ADSC) // startet eine konvertierung auf dem gewünschten Kannal/Pin #define ADCfree ADCSRA|=_BV(ADATE) // schaltet den freilaufenden Modus ein #define ADCvintern ADMUX|=_BV(REFS0) // interne Spannungsversorgung #define ADCinterrupt_on ADCSRA|=_BV(ADIE) // ADC interrupt wird freigeschalten #define ADCprescaler_2 ADCSRA |=_BV(ADPS0) // gewünschter Teilungsfaktor/Prescaler #define ADCprescaler_4 ADCSRA|=_BV(ADPS1) #define ADCprescaler_8 ADCSRA=_BV(ADPS1) | _BV(ADPS0) #define ADCprescaler_16 ADCSRA|=_BV(ADPS2) #define ADCprescaler_32 ADCSRA=_BV(ADPS2) | _BV(ADPS0) #define ADCprescaler_64 ADCSRA=_BV(ADPS2) | _BV(ADPS1) #define ADCprescaler_128 ADCSRA=_BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0) #define ADCprescaler_reset ADCSRA = ~_BV(ADPS2) & ~_BV(ADPS1) & ~_BV(ADPS0) #define ADCchannel_1 //gewünschter Kannal z.B bei ATmega32 PINA0 - PINA7 #define ADCchannel_2 ADMUX|=_BV(MUX0) // bei nicht freilaufen muss ADCchannel_x vor #define ADCchannel_3 ADMUX|=_BV(MUX1) // ADCstart kommen dann kann man mit getadc() der #define ADCchannel_4 ADMUX= _BV(MUX1) | _BV(MUX0) // Adcwert des gewählten Kannals auslesen #define ADCchannel_5 ADMUX|=_BV(MUX2) #define ADCchannel_6 ADMUX= _BV(MUX2) | _BV(MUX0) #define ADCchannel_7 ADMUX= _BV(MUX2) | _BV(MUX1) #define ADCchannel_8 ADMUX= _BV(MUX2) | _BV(MUX1) | _BV(MUX0) #define ADCchannel_reset ADMUX= ~_BV(MUX2) & ~_BV(MUX1) & ~_BV(MUX0) uint16_t getadc(void) { while (ADCSRA & _BV(ADSC)) {} return ADC; }
mfg pebisoftCode:#include <inttypes.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #include <string.h> #include <stdint.h> #include <avr/delay.h> #include "adc.h" #define READ 1 #define WRITE 2 #define USART_BAUD_RATE 9600 #define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16l)-1) #define GBPORT PORTB #define GBDDR DDRB #define GBPIN PINB #define CCLK 7 #define CLOAD 6 #define CSIN 5 #define CREAD 4 #define CSTART 1 #define CRESET 0 void delay_us(uint16_t us) { uint16_t zaehler; while (us) { zaehler = F_CPU / 5000000; while (zaehler) { asm volatile ("nop"); zaehler--; } us--; } } void usart_init(int Enable, int Interupts) { if (Enable & READ) UCSRB = (1<<RXEN); if (Enable & WRITE) UCSRB |= (1<<TXEN); if (Interupts & READ) UCSRB |= (1<<RXCIE); if (Interupts & WRITE) UCSRB |= (1<<TXCIE); UBRRL = (unsigned char) USART_BAUD_SELECT; } void usart_writeChar(unsigned char c) { while (!(UCSRA & (1<<UDRE))) {} UDR = c; while(!(UCSRA & (1<<TXC))) {} } void usart_writeString(unsigned char *string) { while (!(UCSRA & (1<<UDRE))) {} while ( *string) usart_writeChar(*string++); } // Laden der Register der gbcam void gbcam_load_register(uint8_t adresse, uint8_t daten) { /* 3-Bit Adresse und 8-Bit Daten Die Übertragung erfolgt über ein syncrones Protkoll mit CCLK, CSIN und CLOAD */ uint8_t i; adresse &= 0x07; // Übertragen der Adresse ( 3-Bit ) for (i=0;i<3;i++) { if ( ( adresse & 0x04 ) > 0 ) { GBPORT |= (1<<CSIN); } adresse <<= 1; GBPORT |= (1<<CCLK); delay_us(10); GBPORT &= ~(1<<CCLK); delay_us(1); GBPORT &= ~(1<<CSIN); delay_us(1); } // Übertragen der Daten ( 8-Bit ) for (i=0;i<8;i++) { if ( ( daten & 0x80 ) > 0 ) GBPORT |= (1<<CSIN); daten <<= 1; GBPORT |= (1<<CCLK); /* Beim letzen Bit muß zusätzlich die CLOAD Leitung gesetzt werden, Nachdem CCLK gesetzt wurde */ delay_us(5); if (i == 7) { PORTB |= (1<<CLOAD); } delay_us(5); GBPORT &= ~(1<<CCLK); delay_us(1); GBPORT &= ~((1<<CSIN)|(1<<CLOAD)); delay_us(1); } } // Starten der Aufnahme void gbcam_start(void) { // Startsignal erzeugen GBPORT |= (1<<CSTART); delay_us(1); GBPORT |= (1<<CCLK); delay_us(10); GBPORT &= ~(1<<CSTART); delay_us(1); GBPORT &= ~(1<<CCLK); delay_us(1); } // Kamera zurücksetzen void gbcam_reset(void) { // Resetleitung auf Low ziehen GBPORT &= ~(1<<CRESET); delay_us(1); GBPORT |= (1<<CCLK); delay_us(10); GBPORT |= (1<<CRESET); delay_us(1); GBPORT &= ~(1<<CCLK); delay_us(1); } // Intitialisieren der Gameboy Kamera void gbcam_init(void) { GBDDR = (1<<CCLK)|(1<<CLOAD)|(1<<CSIN)|(1<<CSTART)|(1<<CRESET); GBPORT = (1<<CRESET)|(1<<CREAD); gbcam_reset(); /* Laden der Register der Gameboy Kamera, Einstellungen für ein normales Bild */ gbcam_load_register( 0x00,0); // 000 GAIN gbcam_load_register( 0x01, 7); // Belichtungszeit gbcam_load_register( 0x02, 54); gbcam_load_register( 0x03, 1 ); gbcam_load_register( 0x04, 1 ); gbcam_load_register( 0x05, 0 ); gbcam_load_register( 0x06, 1 ); gbcam_load_register( 0x07, 7 ); } int main (void) { char wert_str[10]; uint16_t adc_wert; usart_init( (READ + WRITE) , READ); ADCchannel_init; ADCinit; ADCprescaler_16; ADCchannel_1; gbcam_reset(); gbcam_init(); gbcam_start(); /* Warten bis die gbcam bereit ist */ while ( ( GBPIN & (1<<CREAD) ) == 0 ) { GBPORT |= (1<<CCLK); delay_us(1); GBPORT &= ~(1<<CCLK); delay_us(1); } // 16384 Pixel auslesen while( ( GBPIN & (1<<CREAD ) ) != 0 ) { GBPORT |= (1<<CCLK); delay_us(1); // AD Wandler starten ADCstart; adc_wert=getadc(); // Daten einlesen itoa( adc_wert,wert_str, 10); usart_writeString(wert_str); GBPORT &= ~(1<<CCLK); delay_us(1); } }
Hi Jungs!
Das habe ich bereits versucht, aber dann geht READ nicht auf LOW!!Zitat von DerInder
Das kann gut sein. Bei mir aber nichtmehr, sonst würde ja kein Bild kommen... Schätz' ich zumendest mal!Zitat von pebisoft
Das Programm nicht, nein. das ist aber dermaßen in Subroutinen und Funktionen verstrickt, dass ich immer selber gucken muss, welche Funktion gerade was macht...das programm zum auslesen der gameboy-cam wird wohl kein geheimnis sein.
Aber wenns ihr's unbedingt wollt...
Für welches denn?danke für dein verständnis.
Das habe ich mir auch schon gedacht!!Zitat von Michael
Ich werde in den Logfiles mal nachsehen, wenn da 0 steht, dann liegts beim Auslesen des COMs, bzw. an der AVR-Software.
Wer wille eigentlich den GB Cam Viewer 0.5d (beta)?
Mit Bilddreh-Funktion!
Habe jetzt übrigens 2 wunderschöne Antennen für Suny!
Viele liebe Grüße;
Tobi
http://www.tobias-schlegel.de
"An AVR can solve (almost) every problem" - ts
habe mir nach vielen stunden der gameboy-cam-darstellung heute die cmucam 2 bei roboter-teile.de bestellt. in einpaar tagen geht es los.
diese cam kann einmal video über mein videofunk auf dem robby zum pc senden, zum anderen ein bild als byte-werte über seriell-funk zum pc zum auswerten senden, die bilddaten werden auf der cmucamplatine im ram festgehalten, also nicht flüchtig und kann den robby daten übergeben zum steuern, je nach auswertung des bildausschnittes. wird eine interessante spielerei für eine lange lange zeit.
mfg pebisoft
HI!
So kannst du's natürlich auch machen...
Verkaufst du mir deine Gameboy Cam?
Viele liebe Grüße,
Tobi
http://www.tobias-schlegel.de
"An AVR can solve (almost) every problem" - ts
hallo tobi, die cmucam 2 ist zum auswerten der daten und für die steuerung des robby gedacht im zusammenspiel mit dem pc. das auswerten der daten für die gameboy-cam bleib weiterhin im forschungsbereich. du wolltest mir ja noch einmal ein platinenvorschlag mit ram unterbreiten für die speicherung der gameboy-daten. das angebot bleibt weiterhin bestehen. du wolltest doch noch einmal dein code für die auswertung reinstellen. macht nichts, wenn er verschachtelt ist. ich nehme keine bewertung vor. kannst ihn ja mal gleich reinstellen.
mfg pebisoft.
Hi pebisoft!
OK.
Aber wenn du nur noch auf MCUCam-Trip bist, dann kannst du mir ja deine GBC verkaufen...
Die Platinen.......................................... ... .
Der jetzige Code ist folgender:
Bitte schaut auch nach Fehlern!! Ich bin nicht sicher, ob da nicht der ein oder andere Fehler dabei ist!Code:$regfile = "m8def.dat" 'ATmega8-Deklarationen $crystal = 16000000 'Quarz: 16 MHz $baud = 9600 'Baudrate der UART: 9600 Baud, 8N1 Dim A As Byte Dim I As Byte Dim Adcv As Byte Dim Msb As Byte Dim Lsb As Byte Dim Regadr As Byte Dim Regvalue As Byte Dim C0 As Byte Dim C1 As Byte Dim G As Byte Dim O As Byte Dim Rda As Word Config Adc = Single , Prescaler = Auto Declare Function Laybus(byval Value As Byte) As Byte Declare Function Readbus() As Byte Declare Sub Writeram() Declare Sub Readramstart() Declare Sub Readramstop() Declare Sub Flashadrlsb() Declare Sub Flashadrmsb() Declare Sub Formatram() Declare Sub Resetcam() Declare Sub Loadreg() Declare Sub Camimp() Declare Sub Capture() Declare Sub Camdelay() Ddrb = &B00111111 'Alles Ausgaenge :D (Ausser QUARZ!) Ddrc = &B11111111 'Die auch Ddrd = &B11101111 'und da bin ich noch nciht ganz sicher. A = Laybus(0) 'Bus auf 00000000 (=0x00) setzen Portd.7 = 1 'Outputenable Active: LOW Portd.6 = 1 'WriteEnable Active: LOW Portc.2 = 0 'LATCH ENABLE des LSB vom Adressbus/RAM ACTIVE HIGH Portc.3 = 0 'LATCH ENABLE des MSB vom Adressbus/RAM ACTIVE HIGH Portc.4 = 0 'Start, -et Aufnahmeprozess (HIGH) Portc.5 = 0 'Sin, daten f. Register (HIGH) Portd.2 = 0 'Load, Speichern Register (HIGH) 'Reset, System + Speicherreset Portd.3 = 1 'Reset, Speicher + Systemreset (LOW) Portd.5 = 0 'XCK, Taktleitung 'Portd.4 'READ, Zeigt, Ob Bild vorliegt Call Formatram() Print "" Print "=======================================================" Print " CAMTEST.bas " Print " Testet die Camera für LOG " Print " Testphase3: Kamera auslesen. " Print "=======================================================" Print "" Print "Protocol:" Print "" I = 0 A = 0 '1.: Auslösen eines Resets Call Resetcam() 'Print "CAM resetted" A = Laybus(0) '2.: Laden der Register. Startproc: Print "Bitte geben sie C1 (Reg 2 MSB) ein:" Do If Ucsra.rxc = 1 Then C1 = Udr A = 255 End If Loop Until A <> 0 A = 0 Print "C1 beträgt: " ; C1 Print "Bitte geben sie C0 (Reg 3 LSB) ein:" Do If Ucsra.rxc = 1 Then C0 = Udr A = 255 End If Loop Until A <> 0 A = 0 Print "C0 beträgt: " ; C0 Print "Bitte geben sie G (Reg 1) ein:" Do If Ucsra.rxc = 1 Then G = Udr A = 255 End If Loop Until A <> 0 A = 0 Print "Gain beträgt: " ; G Print "Bitte geben sie O (Reg 0) ein:" Do If Ucsra.rxc = 1 Then O = Udr A = 255 End If Loop Until A <> 0 A = 0 Print "Offest beträgt: " ; O Print "" Print "Beginne in 5 Sekunden!" Wait 8 Regadr = 1 'Register NUMMER 1: Regvalue = G Call Loadreg() Regadr = 2 'Register NUMMER 2: Regvalue = C1 Call Loadreg() Regadr = 3 'Register NUMMER 3: Regvalue = C0 Call Loadreg() Regadr = 4 'Register NUMMER 4: Regvalue = 1 Call Loadreg() Regadr = 5 'Register NUMMER 5: Regvalue = 0 Call Loadreg() Regadr = 6 'Register NUMMER 6: Regvalue = 1 Call Loadreg() Regadr = 7 'Register NUMMER 7: Regvalue = 7 Call Loadreg() Regadr = 0 'Register NUMMER 0: Regvalue = O Call Loadreg() 'Print "Registers loaded." '3. : Bild machen :D Call Capture() 'Print "Startsignal done." '4. : auf de voll krass Bild warten ey! 'Print "creating wait-clock" I = 0 Do Call Camimp() I = I + 1 Loop Until Pind.4 = 1 'Print "Camera ready. Clocks created: " ; I Call Camdelay() '5. : voll krass de bild abhole, ey! ;D www.stophiphop.de Evolution. Mit uns. gegen HipHop. 'Print "ADC-Werte:" 'Print "" Rda = 0 Do Portd.5 = 0 Portd.5 = 1 Call Camdelay() Portd.5 = 0 Start Adc Adcv = Getadc(7) Stop Adc 'RAM-Prozedur Rda = Rda + 1 Msb = High(rda) A = Laybus(msb) Call Flashadrmsb() Lsb = Low(rda) A = Laybus(lsb) Call Flashadrlsb() A = Laybus(adcv) Call Writeram() 'ENDE RAM Waitus 2 Loop Until Pind.4 = 0 Rda = 0 For Rda = 0 To 16384 Msb = High(rda) A = Laybus(msb) Call Flashadrmsb() Lsb = Low(rda) A = Laybus(lsb) Call Flashadrlsb() Call Readramstart() Adcv = Readbus() Call Readramstop Printbin Adcv Printbin 59 Waitms 3 Next A = Laybus(0) Printbin 255 Call Formatram() Wait 2 Goto Startproc End '=============================================================================================== Function Laybus(byval Value As Byte) Ddrb = &B00111111 'Alles Ausgaenge :D (Ausser QUARZ!) Ddrc = &B11111111 'Die auch, Portc.1 = Value.0 Portc.0 = Value.1 Portb.5 = Value.2 Portb.4 = Value.3 Portb.3 = Value.4 Portb.2 = Value.5 Portb.1 = Value.6 Portb.0 = Value.7 End Function Function Readbus() Dim Value As Byte Ddrb = &B00000000 'Alles Ausgaenge :D (Ausser QUARZ!) Ddrc = &B11111100 'Die auch Value.0 = Pinc.1 Value.1 = Pinc.0 Value.2 = Pinb.5 Value.3 = Pinb.4 Value.4 = Pinb.3 Value.5 = Pinb.2 Value.6 = Pinb.1 Value.7 = Pinb.0 Readbus = Value End Function Sub Writeram() Portd.6 = 1 Portd.6 = 0 'ACTIVE LOW Portd.6 = 1 End Sub Sub Readramstart() Portd.7 = 1 Portd.7 = 0 'ACTIVE LOW End Sub Sub Readramstop() Portd.7 = 1 End Sub Sub Flashadrlsb() Portc.2 = 0 Portc.2 = 1 'Active HIGH Portc.2 = 0 End Sub Sub Flashadrmsb() Portc.3 = 0 Portc.3 = 1 'ACTIVE HIGH Portc.3 = 0 End Sub Sub Formatram() Msb = 0 Lsb = 0 Do Lsb = Lsb + 1 If Lsb = 255 Then Msb = Msb + 1 Lsb = 0 End If A = Laybus(msb) Call Flashadrmsb() A = Laybus(lsb) Call Flashadrlsb() A = Laybus(0) Call Writeram() If Msb = 255 Then Exit Do End If Loop End Sub Sub Resetcam() Ddrc = &B11111111 'Die auch Ddrd = &B11101111 'und da bin ich noch nciht ganz sicher. Portd.3 = 1 Portd.5 = 0 Call Camdelay() Portd.3 = 0 Call Camdelay() Portd.5 = 1 Call Camdelay() Portd.3 = 1 Call Camdelay() Portd.5 = 0 End Sub Sub Camimp() Portd.5 = 0 Portd.5 = 1 Call Camdelay() Portd.5 = 0 Call Camdelay() End Sub Sub Loadreg() Dim Iii As Byte 'Print Regadr ; ": " ; Regvalue 'Erst: Adresse: Portd.5 = 0 Portc.5 = Regadr.0 Call Camdelay() Portd.5 = 1 Call Camdelay() Portc.5 = 0 Call Camdelay() Portd.5 = 0 Call Camdelay() Portc.5 = Regadr.1 Call Camdelay() Portd.5 = 1 Call Camdelay() Portc.5 = 0 Call Camdelay() Portd.5 = 0 Call Camdelay() Portc.5 = Regadr.2 Call Camdelay() Portd.5 = 1 Call Camdelay() Portc.5 = 0 Call Camdelay() Portd.5 = 0 'Call Camdelay() '=====================0 For Iii = 7 To 0 Step -1 If Iii = 0 Then Portd.5 = 0 Portc.5 = Regvalue.iii Waitus 5 Portd.5 = 1 Call Camdelay() Portd.2 = 0 Portd.2 = 1 Call Camdelay() Portd.5 = 0 Portc.5 = 0 Call Camdelay() Portd.2 = 0 Exit For End If Portd.5 = 0 Portc.5 = Regvalue.iii Waitus 5 Portd.5 = 1 Call Camdelay() Portc.5 = 0 Call Camdelay() Portd.5 = 0 Call Camdelay() Next 'Call Camimp() End Sub Sub Capture() ' Call Camdelay() Portc.4 = 0 Portd.5 = 0 Portc.4 = 1 Call Camdelay() Portd.5 = 1 Call Camdelay() Portc.4 = 0 Call Camdelay() Portd.5 = 0 End Sub Sub Camdelay() Waitus 5 End Sub
Da können/müssen welche drin sein, sonst müsste ich ja Bilder kriegen wie Kjion!
Viele liebe Grüße,
Tobi
http://www.tobias-schlegel.de
"An AVR can solve (almost) every problem" - ts
hallo tobi, compelier dein programm mit Bascom für eine avr-objekt-datei und lass es mal im avr-studio 4 laufen. deine waitus-zeiten stimmen nicht mehr, durch den sprung usw. Bascom verschlabbert zuviel zeit. ein bascomprogramm lässt sich für solche sachen sehr schlecht schreiben.
Bascom ist ein bummelprogramm.
mfg pebisoft
Hi pebisoft!
An den Zeiten kanns nicht liegen, die sind nur dazu da um sicherzustellen, dass die Höchstfrequenz (>= 500KHz) nicht überschritten wird.
Aber man könnte sie kürzer machen, da hast du recht!
Viele liebe Grüße,
Tobi
http://www.tobias-schlegel.de
"An AVR can solve (almost) every problem" - ts
Mein Readpin geht jetzt auch auf LOW. \/
Ich habe aber nicht allzuviel an meinem Programm verändert, scheint wirklich irgendwie mit den Registern zusammen zu hängen.
@tombic:
Ich habe deine Register übernommen, aber ich kann auch ruhig Register 3 auf 0 setzen:
Regwert(1) = 7
Regwert(2) = 64
Regwert(3) = 0
Regwert(4) = 1
Regwert(5) = 0
Regwert(6) = 1
Regwert(7) = 7
Regwert(8 ) = 0
Lesezeichen