Vielen Dank für deine Bemühungen Radbruch =D> =D>
Hallo
Die Experimentierplatine nur mit Stiftleiste und Cinch-Buchse bestückt mache ich erste Tests mit der neuen Kamera:
Die Ausgabe dazu beim Blick auf ein Blatt Papier mit eingesteckem Kontrollmonitor als 75Ohm-Last:Code:// Kleines Testprogramm zur Funktionsprüfung 1.4.10 mic #include "RP6RobotBaseLib.h" void ADC_Init(void) { extIntOFF(); // schaltet den E_INT1-Port auf Eingang für den ADC // 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, prescaler /2, ADC läuft nun mit 4MHz! 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 empfohlene Initiallesung while (!(ADCSRA & (1<<ADIF))); ADCSRA |= (1<<ADIF); } int main(void) { uint8_t bildspeicher[1024], *bildzeiger; // 1KB * 8Bit Bildspeicher bereitstellen uint8_t spalte, zeile, sync, c; initRobotBase(); ADC_Init(); while(1) { writeString_P("---------------------------\n"); for(c=0; c<255; c++) // Bildspeicher löschen (mit Byte-Variable) { bildspeicher[c]=bildspeicher[256+c]=\ bildspeicher[2*256+c]=bildspeicher[3*256+c]=0; } for(c=0; c<4; c++) // viermal den selben Bereich einlesen { bildzeiger=&bildspeicher[256*c]; // Zeiger auf Start des Bildspeicherbereich cli(); do // Warten auf langen Syncbereich = Bildstart { sync=0; while (ADCH > 20); // warten solange Bilddaten erkannt werden while (ADCH < 30) sync++; // Länge des Sync-Signal zählen }while (sync < 40); // größer 40 bedeutet Bildstart zeile=150; // durchhangeln bis Zeile 150 while(zeile--) { while (ADCH > 20); // Bilddaten while (ADCH < 30); // Sync } spalte=255; // oje do *bildzeiger++=ADCH; while(spalte--); // 254 Werte einlesen //while(spalte--) *bildzeiger++=ADCH; // dito //do *bildzeiger=ADCH; while(*bildzeiger++ > 20); // schneller ;) sei(); } for(spalte=0; spalte != 255; spalte++) // Alle Durchgänge gemeinsam ausgeben { writeInteger(spalte, 10); writeString_P(": "); writeInteger(bildspeicher[spalte], 10); writeString_P(" "); writeInteger(bildspeicher[256+spalte], 10); writeString_P(" "); writeInteger(bildspeicher[2*256+spalte], 10); writeString_P(" "); writeInteger(bildspeicher[3*256+spalte], 10); writeString_P("\n"); } while(!(getBumperLeft() || getBumperRight())); // Nochmal? Terminal löschen! } return(0); }
Ausgabe mit alternativer EinlesezeileCode:Terminal cleared! --------------------------- 0: 56 56 54 56 1: 56 56 54 56 2: 56 56 54 56 3: 56 57 56 57 4: 56 57 56 57 5: 56 57 56 57 6: 60 57 60 60 7: 60 57 60 60 8: 60 57 60 60 9: 62 60 62 60 10: 62 60 62 60 11: 62 60 62 60 12: 62 62 62 60 13: 62 62 62 62 14: 62 62 62 62 15: 62 62 62 62 16: 63 62 62 62 17: 63 62 62 62 18: 63 62 62 62 19: 62 62 62 62 20: 62 62 62 62 21: 62 62 62 62 22: 60 60 62 62 23: 60 60 62 62 24: 60 60 62 62 25: 60 56 62 62 26: 56 56 60 60 27: 56 56 60 60 28: 56 56 60 60 29: 57 56 57 57 30: 57 56 57 57 31: 57 56 57 57 32: 56 56 56 56 33: 56 56 56 56 34: 56 56 56 56 35: 56 56 56 56 36: 56 56 56 56 37: 56 56 56 56 38: 56 54 56 56 39: 56 54 56 56 40: 56 54 56 56 41: 56 54 56 56 42: 56 56 56 56 43: 56 56 56 56 44: 56 56 56 56 45: 56 56 56 51 46: 56 56 56 51 47: 56 56 56 51 48: 54 51 51 54 49: 54 51 51 54 50: 54 51 51 54 51: 54 30 51 54 52: 15 30 31 35 53: 15 30 31 35 54: 15 30 31 35 55: 4 6 6 6 56: 4 6 6 6 57: 4 6 6 6 58: 28 28 28 28 59: 28 28 28 28 60: 28 28 28 28 61: 28 28 28 28 62: 28 28 28 28 63: 28 28 28 28 64: 28 56 28 28 65: 56 56 56 56 66: 56 56 56 56 67: 56 56 56 56 68: 56 57 56 56 69: 56 57 56 56 70: 56 57 56 56 71: 57 60 60 60 72: 57 60 60 60 73: 57 60 60 60 74: 60 62 62 60 75: 60 62 62 60 76: 60 62 62 60 77: 60 62 62 60 78: 62 62 60 62 79: 62 62 60 62 80: 62 62 60 62 81: 62 62 62 62 82: 62 62 62 62 83: 62 62 62 62 84: 60 60 62 63 85: 60 60 62 63 86: 60 60 62 63 87: 57 60 60 62 88: 57 60 60 62 89: 57 60 60 62 90: 57 56 60 62 91: 56 56 57 56 92: 56 56 57 56 93: 56 56 57 56 94: 56 56 57 57 95: 56 56 57 57 96: 56 56 57 57 97: 56 56 56 56 98: 56 56 56 56 99: 56 56 56 56 100: 56 56 56 56 101: 56 56 56 56 102: 56 56 56 56 103: 56 56 56 56 104: 56 56 56 56 105: 56 56 56 56 106: 56 56 56 56 107: 54 54 56 56 108: 54 54 56 56 109: 54 54 56 56 110: 51 54 56 51 111: 51 54 56 51 112: 51 54 56 51 113: 49 51 51 56 114: 49 51 51 56 115: 49 51 51 56 116: 49 7 51 56 117: 7 7 30 30 118: 7 7 30 30 119: 7 7 30 30 120: 3 3 6 6 121: 3 3 6 6 122: 3 3 6 6 123: 28 28 28 28 124: 28 28 28 28 125: 28 28 28 28 126: 49 31 28 28 127: 49 31 28 28 128: 49 31 28 28 129: 49 56 28 28 130: 57 56 56 56 131: 57 56 56 56 132: 57 56 56 56 133: 60 60 57 56 134: 60 60 57 56 135: 60 60 57 56 136: 60 60 60 60 137: 60 60 60 60 138: 60 60 60 60 139: 62 62 63 60 140: 62 62 63 60 141: 62 62 63 60 142: 62 62 63 60 143: 62 62 63 62 144: 62 62 63 62 145: 62 62 63 62 146: 62 62 63 62 147: 62 62 63 62 148: 62 62 63 62 149: 60 62 62 62 150: 60 62 62 62 151: 60 62 62 62 152: 60 56 60 60 153: 60 56 60 60 154: 60 56 60 60 155: 60 56 60 60 156: 56 56 56 56 157: 56 56 56 56 158: 56 56 56 56 159: 56 56 57 56 160: 56 56 57 56 161: 56 56 57 56 162: 56 56 56 56 163: 56 56 56 56 164: 56 56 56 56 165: 56 56 56 56 166: 56 56 56 56 167: 56 56 56 56 168: 56 56 56 56 169: 56 56 56 55 170: 56 56 56 55 171: 56 56 56 55 172: 56 51 56 54 173: 56 51 56 54 174: 56 51 56 54 175: 51 54 56 56 176: 51 54 56 56 177: 51 54 56 56 178: 44 49 54 51 179: 44 49 54 51 180: 44 49 54 51 181: 44 7 54 51 182: 7 7 7 7 183: 7 7 7 7 184: 7 7 7 7 185: 28 17 3 3 186: 28 17 3 3 187: 28 17 3 3 188: 28 28 28 28 189: 28 28 28 28 190: 28 28 28 28 191: 56 54 28 28 192: 56 54 28 28 193: 56 54 28 28 194: 56 60 28 28 195: 56 60 56 56 196: 56 60 56 56 197: 56 60 56 56 198: 60 60 60 56 199: 60 60 60 56 200: 60 60 60 56 201: 62 62 60 60 202: 62 62 60 60 203: 62 62 60 60 204: 62 62 62 60 205: 62 62 62 60 206: 62 62 62 60 207: 62 62 62 60 208: 60 62 62 60 209: 60 62 62 60 210: 60 62 62 60 211: 62 63 62 62 212: 62 63 62 62 213: 62 63 62 62 214: 56 60 60 60 215: 56 60 60 60 216: 56 60 60 60 217: 57 60 60 56 218: 57 60 60 56 219: 57 60 60 56 220: 57 56 60 56 221: 56 56 56 56 222: 56 56 56 56 223: 56 56 56 56 224: 56 56 56 56 225: 56 56 56 56 226: 56 56 56 56 227: 56 56 56 56 228: 56 56 56 56 229: 56 56 56 56 230: 56 56 54 56 231: 56 56 54 56 232: 56 56 54 56 233: 56 56 54 56 234: 56 56 56 54 235: 56 56 56 54 236: 56 56 56 54 237: 56 54 56 49 238: 56 54 56 49 239: 56 54 56 49 240: 51 54 51 51 241: 51 54 51 51 242: 51 54 51 51 243: 30 30 49 49 244: 30 30 49 49 245: 30 30 49 49 246: 30 6 49 49 247: 6 6 7 7 248: 6 6 7 7 249: 6 6 7 7 250: 28 28 6 3 251: 28 28 6 3 252: 28 28 6 3 253: 28 28 28 28 254: 28 28 28 28
do *bildzeiger=ADCH; while(*bildzeiger++ > 20);
Neue Erkenntniss durch diese Versuche: Die Variablen dürfen nicht global definiert sein. So wird alles total langsam:Code:Terminal cleared! --------------------------- 0: 51 51 55 51 1: 51 51 55 51 2: 51 51 55 51 3: 51 51 55 51 4: 56 56 56 56 5: 56 56 56 56 6: 56 56 56 56 7: 56 56 56 56 8: 56 56 57 56 9: 56 56 57 56 10: 56 56 57 56 11: 56 56 57 56 12: 56 60 60 56 13: 60 60 60 56 14: 60 60 60 56 15: 60 60 60 56 16: 60 60 60 56 17: 60 60 60 60 18: 60 60 60 60 19: 60 60 60 60 20: 60 60 60 60 21: 62 62 62 60 22: 62 62 62 60 23: 62 62 62 60 24: 62 62 62 60 25: 62 62 62 62 26: 62 62 62 62 27: 62 62 62 62 28: 62 62 62 62 29: 62 62 62 62 30: 60 60 60 60 31: 60 60 60 60 32: 60 60 60 60 33: 60 60 60 60 34: 60 56 56 57 35: 60 56 56 57 36: 60 56 56 57 37: 60 56 56 57 38: 60 56 56 56 39: 56 56 56 56 40: 56 56 56 56 41: 56 56 56 56 42: 56 56 56 56 43: 56 56 56 56 44: 56 56 56 56 45: 56 56 56 56 46: 56 56 56 56 47: 56 56 56 56 48: 56 56 56 56 49: 56 56 56 56 50: 56 56 56 56 51: 56 54 56 54 52: 56 54 56 54 53: 56 54 56 54 54: 56 54 56 54 55: 56 54 56 54 56: 52 52 51 51 57: 52 52 51 51 58: 52 52 51 51 59: 52 52 51 51 60: 54 51 51 49 61: 54 51 51 49 62: 54 51 51 49 63: 54 51 51 49 64: 54 49 49 49 65: 49 49 49 49 66: 49 49 49 49 67: 49 49 49 49 68: 49 49 49 49 69: 33 17 7 30 70: 33 0 0 30 71: 33 0 0 30 72: 33 0 0 30 73: 6 0 0 6 74: 0 0 0 0 75: 0 0 0 0 76: 0 0 0 0
Compileroptimierung steht bei mir übrigends auf "Size".Code:uint8_t bildspeicher[1024], *bildzeiger; // 1KB * 8Bit Bildspeicher bereitstellen uint8_t spalte, zeile, sync, c; int main(void) { initRobotBase(); ADC_Init();
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!
wie kommt man an die RP6RobotBaseLib.h?
Hallo
Das Programm:
Der Versuchsaufbau:Code:// RP6 sendet eine 64x48-Bitmap über die serielle Schnittstelle 2.4.10 mic // Der RP6 sendet eine Bitmap über die serielle Schnittstelle zum PC. // Dort wird es von einem kleinen Tool empfangen und abgespeichert: // http://www.mikrocontroller.net/topic/74659#616065 // Den Header habe ich von einer echten Bitmap mit passendem Format abgeschrieben. // Infos zum Aufbau einer BMP-Datei bei Wikipedia: // http://de.wikipedia.org/wiki/Windows_Bitmap // Es werden die unveränderten Kameradaten verwendet. #include "RP6RobotBaseLib.h" void ADC_Init(void) { extIntOFF(); // schaltet den E_INT1-Port auf Eingang für den ADC // 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, prescaler /2, ADC läuft nun mit 4MHz! 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 empfohlene Initiallesung while (!(ADCSRA & (1<<ADIF))); ADCSRA |= (1<<ADIF); } int main(void) { uint8_t bildspeicher[100], *bildzeiger; // 100 Byte Bildspeicher sollten reichen uint8_t zeile, sync, c; // und dürfen NICHT global sein! uint8_t bmp_header_64_48_24bit[54]={ // Header für ein 64x48x24-BMP hat 54 Bytes 0x42, 0x4d, 0x36, 0x24, 00, 00, 00, 00, 00, 00, 0x36, 00, 00, 00, 0x28, 00, 00, 00, 0x40, 00, 00, 00, 0x30, 00, 00, 00, 01, 00, 0x18, 00, 00, 00, 00, 00, 00, 0x24, 00, 00, 0xc4, 0x0e, 00, 00, 0xc4, 0x0e, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}; initRobotBase(); ADC_Init(); while(1) { for(c=0; c<54; c++) writeChar(bmp_header_64_48_24bit[c]); // Header senden for(c=0; c<48; c++) // 48 Bildzeilen einlesen und als RGB-Pixel senden { setLEDs(c); // working bildzeiger=&bildspeicher[0]; // Zeiger auf Start des Bildspeicherbereich zeile=c*5+35; // aktuelle Zeile (35 Zeilen sind der Schrott beim Bildstart) cli(); do // Warten auf langen Syncbereich = Bildstart { sync=0; while (ADCH > 20); // warten solange Bilddaten erkannt werden while (ADCH < 30) sync++; // Länge des Sync-Signal zählen }while (sync < 40); // größer 40 bedeutet Bildstart while(zeile--) { while (ADCH > 20); // Bilddaten while (ADCH < 30); // Sync } do *bildzeiger=ADCH; while(*bildzeiger++ > 20); // eine schnelle Zeile einlesen sei(); // (das sind ca. 70 Werte) for(zeile=0; zeile<64; zeile++) // 64 Pixel senden { if (bildspeicher[zeile] > 20) { writeChar(bildspeicher[zeile]); // RGB in Pixelfarbe writeChar(bildspeicher[zeile]); writeChar(bildspeicher[zeile]); } else { writeChar(0); // oder Schwarz writeChar(0); writeChar(0); } } } setLEDs(63); // ready while(!(getBumperLeft() || getBumperRight())); // Neues Bild senden? } return(0); }
Bild hier
Das Ergebniss:
Bild hier
(Die orginalen Bilder gibt es hier als Zip-Archiv.)
Was ist das? Der RP6 erzeugt Bitmap-Dateien ;) Das ist so zwar etwas fummeilg, aber es funktioniert. Wenn auch im Moment noch spiegelbildlich ;)
Wie funktioniert es? Der RP6 errechnet aus den Kameradaten ein 64x48-Bitmap-Bild und sendet es über die serielle Schnittstelle zum PC. Dort werden die seriellen Daten von einem kleinen Tool empfangen und als BMP-Datei abgespeichert.
Die Grundlagen dazu habe ich mir aus Wikipedia: Windows_Bitmap angelesen,
das Tool (mit 38400 Baud an der Schnittstelle des RP6-USB-Moduls) habe ich hier gefunden:
http://www.mikrocontroller.net/topic/74659#616065
Das wollte ich ja schon lange mal machen. Jetzt sieht man endlich das, was der RP6 sieht. Die Zeilen werden hier jeweils "in einem Rutsch" eingelesen und gesendet. Eine "Aufnahme" mit 64x48 Pixeln dauert so ca. 6 Sekunden. In der vierfachen Vergrößerung sieht man schon deutlich die Pixelgröße.
Viel Spaß beim Nachmachen.
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!
hey, das ist ja mal cool
jetzt erzeugt der RP6 auch schon bitmap dateien, nicht schlecht, sobald ich auch die nötigen teile zur hand habe setze ich mich gleich mal ans nachmachen
MfG
wieder hier
Hallo
Das sieht doch sehr gut aus!
Ich denke damit lässt sich ne Menge anfangen.
Bin mal gespannt wie meins wird wenn ich die Bauteile beisammen hab...
Gruß Thund3r
Dein Gott sei mein Zeuge!
Das stimmt so nicht. Die Bilder stehen auf dem Kopf. Der Grund dafür ist einfach und eher banal: Im Header wird die Höhe des Bildes mit +48 angegeben. Bei positiven Bildhöhen wird das BMP-Bild von unten nach oben aufgebaut, ich sende aber die oberste Zeile zuerst. Abhilfe wäre entweder ein negativer Wert für die Bildhöhe im Header, das scheitert aber an der Erzeugung der Long-Darstellung des negativen Wertes, oder das Lesen der Bildzeilen von unten nach oben.Wenn auch im Moment noch spiegelbildlich
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Lesezeichen