Dirk
02.05.2010, 13:14
Hallo Leute,
für die Experimentierplatine, die wir hier beschrieben haben:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=53424
... und die hier:
http://www.rn-wissen.de/index.php/RP6_Kamera_-_Mitmach-Projekt
... gebaut wurde, hier ein erstes Programm für die RP6Base. Es funktioniert ab der Phase 3 des Aufbaus.
Ein 32x32 Pixel Bild wird auf dem Terminal ausgegeben. Das ursprüngliche Programm hat radbruch geschrieben.
Was habe ich geändert:
- Nutzung der Signale HSync und VSync des Sync-Separators auf der Exp
/*
* ************************************************** **************************
* RP6 ROBOT SYSTEM - ROBOT BASE TESTS
* ************************************************** **************************
* Example: Grab video pictures and show them on the terminal
* Author(s): radbruch, modified: Dirk
* ************************************************** **************************
* Description:
*
* With this program (written by radbruch) the picture of a CMOS camera
* (CONRAD 150001) can be displayed on the terminal.
* The camera is connected to this hardware project:
* http://www.rn-wissen.de/index.php/RP6_Kamera_-_Mitmach-Projekt
* The BAS video information (PG3) is connected to ADC4 (PG4).
* The synchronization signals are connected as follows:
*
* Signal RP6 Name Port Function
* VSync SCL PC0 SCL
* HSync SDA PC1 SDA
*
* If you use SCL and SDA this way, you can not use the I2C bus any more!
*
* ************************************************** **************************
*
* ACHTUNG: Den Jumper auf JP10 (Stellung H) nur aufstecken, wenn das Programm
* schon läuft! Bitte den Jumper entfernen, wenn kein Programm auf
* der RP6Base läuft! Der Bootloader würde sonst das zuletzt geladene
* Programm immer wieder neu starten!
*
* ################################################## ##########################
* The Robot does NOT move in this example! You can simply put it on a table
* next to your PC and you should connect it to the PC via the USB Interface!
* ################################################## ##########################
* ************************************************** **************************
*/
/************************************************** ***************************/
// Includes:
#include "RP6RobotBaseLib.h" // The RP6 Robot Base Library.
// Always needs to be included!
/************************************************** ***************************/
// Defines:
#define HSYNC (PINC & SDA)
#define VSYNC (PINC & SCL)
#define IRon() {statusLEDs.LED1 = false; updateStatusLEDs();}
#define IRoff() {statusLEDs.LED1 = true; updateStatusLEDs();}
/************************************************** ***************************/
// Variables:
uint8_t bildspeicher[1024], *bildzeiger; // 32*32=1KB * 8Bit Bildspeicher
/************************************************** ***************************/
// Functions:
void bild_einlesen(void)
{
uint8_t pixel[32],*pixelzeiger;
uint8_t i, zeilen, step, lines, rows, h_step, h_delay;
zeilen=32; // Das fertige Bild soll 32 Zeilen haben
step=7; // sichtbares TV-Bild ist ca. 30-260=230/32 ergibt Zeilensprung=7
rows=0; // Anzahl der Spalten (32x32, rechengünstig,aber verzerrt)
do
{
lines=zeilen; // Anzahl der einzulesenden Zeilen
pixelzeiger=&pixel[0]; // Zeiger auf Start Pixelspeicher
cli();
// VSync abwarten (Seitenanfang)
while(VSYNC);
// 40 Zeilen Austastzeit & ein Stück oberen Bildrand überlesen
h_step=40; while (h_step) { while (HSYNC); while (!HSYNC); h_step--; }
// Der Lesecursor befindet sich jetzt oben links im TV-Bild
// ab hier werden in step-Sprüngen in allen Zeilen jeweils das Pixel eingelesen,
// das sich im zeitlichen h_delay-Abstand vom linken TV-Bildrand befinden
// (= eine TV-Bildspalte)
while (lines--)
{
// auf die nächste gültige Zeile warten
h_step=step; while (h_step) { while (HSYNC); while (!HSYNC); h_step--; }
// mit h_delay steuern wir nun den Pixel an
// Nach dem sync fängt das Bild etwas verzögert an (Schwarzschulter), bei mir 10
// bei ca. 110 beginnt die 2.Schwarzschulter.
h_delay=10+3*rows; while (h_delay--) {nop();}
*pixelzeiger=ADCH; // letzten ADC-Wert auslesen und wegwerfen
*pixelzeiger++=ADCH; // aktuellsten ADC-Werte speichern
}
sei();
pixelzeiger=&pixel[0];
bildzeiger=&bildspeicher[32*rows];
for (i=0; i<32; i++) *bildzeiger++ = *pixelzeiger++;
} while (++rows < zeilen);
}
/************************************************** ***************************/
// Main function - The program starts here:
int main(void)
{
initRobotBase(); // Always call this first! The Processor will not work
// correctly otherwise.
// ---------------------------------------
// Write messages to the Serial Interface:
writeString_P("\n\n _______________________\n");
writeString_P(" \\| RP6 ROBOT SYSTEM |/\n");
writeString_P(" \\_-_-_-_-_-_-_-_-_-_/\n\n");
writeString_P("################\n");
writeString_P("<<RP6 Base>>\n");
writeString_P("Video Grabber 1 \n");
writeString_P(" Version 1.10 \n");
writeString_P("################\n\n");
mSleep(2500);
setLEDs(0b111111); // Turn all LEDs on
mSleep(500); // delay 500ms
setLEDs(0b000000); // All LEDs off
// Initialize the M32 SDA pin (PC1) as input:
DDRC &= ~SDA; // ==> HSync
PORTC |= SDA; // Pullup on
// Initialize the M32 SCL pin (PC0) as input:
DDRC &= ~SCL; // ==> VSync
PORTC |= SCL; // Pullup on
// Switch the IR-LEDs off:
IRoff(); // IR LEDs off
uint16_t i, j;
extIntOFF(); // schaltet den E_INT1-Port auf Eingang für den ADC
// ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4
ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR) | 4;
// setzte free running triggern
SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// kein interupt, Wandler einschalten, prescaler /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);
while(true)
{
bild_einlesen();
for (i=0; i<32; i++)
{
for (j=0; j<32; j++)
{
if (bildspeicher[j+32*i] > 55) writeString_P("*");
else writeString_P(" ");
}
writeInteger(i,DEC);
writeString_P("\n\r");
}
mSleep(200);
}
return 0;
}
/************************************************** ****************************
* Additional info
* ************************************************** **************************
* Changelog:
* - v. 1.1 (workout for the hardware project) 02.05.2010 by Dirk
* - v. 1.0 (initial release) 20.08.2007 by radbruch
*
* ************************************************** **************************
*/
/************************************************** ***************************/
Viel Spaß!
Dirk
für die Experimentierplatine, die wir hier beschrieben haben:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=53424
... und die hier:
http://www.rn-wissen.de/index.php/RP6_Kamera_-_Mitmach-Projekt
... gebaut wurde, hier ein erstes Programm für die RP6Base. Es funktioniert ab der Phase 3 des Aufbaus.
Ein 32x32 Pixel Bild wird auf dem Terminal ausgegeben. Das ursprüngliche Programm hat radbruch geschrieben.
Was habe ich geändert:
- Nutzung der Signale HSync und VSync des Sync-Separators auf der Exp
/*
* ************************************************** **************************
* RP6 ROBOT SYSTEM - ROBOT BASE TESTS
* ************************************************** **************************
* Example: Grab video pictures and show them on the terminal
* Author(s): radbruch, modified: Dirk
* ************************************************** **************************
* Description:
*
* With this program (written by radbruch) the picture of a CMOS camera
* (CONRAD 150001) can be displayed on the terminal.
* The camera is connected to this hardware project:
* http://www.rn-wissen.de/index.php/RP6_Kamera_-_Mitmach-Projekt
* The BAS video information (PG3) is connected to ADC4 (PG4).
* The synchronization signals are connected as follows:
*
* Signal RP6 Name Port Function
* VSync SCL PC0 SCL
* HSync SDA PC1 SDA
*
* If you use SCL and SDA this way, you can not use the I2C bus any more!
*
* ************************************************** **************************
*
* ACHTUNG: Den Jumper auf JP10 (Stellung H) nur aufstecken, wenn das Programm
* schon läuft! Bitte den Jumper entfernen, wenn kein Programm auf
* der RP6Base läuft! Der Bootloader würde sonst das zuletzt geladene
* Programm immer wieder neu starten!
*
* ################################################## ##########################
* The Robot does NOT move in this example! You can simply put it on a table
* next to your PC and you should connect it to the PC via the USB Interface!
* ################################################## ##########################
* ************************************************** **************************
*/
/************************************************** ***************************/
// Includes:
#include "RP6RobotBaseLib.h" // The RP6 Robot Base Library.
// Always needs to be included!
/************************************************** ***************************/
// Defines:
#define HSYNC (PINC & SDA)
#define VSYNC (PINC & SCL)
#define IRon() {statusLEDs.LED1 = false; updateStatusLEDs();}
#define IRoff() {statusLEDs.LED1 = true; updateStatusLEDs();}
/************************************************** ***************************/
// Variables:
uint8_t bildspeicher[1024], *bildzeiger; // 32*32=1KB * 8Bit Bildspeicher
/************************************************** ***************************/
// Functions:
void bild_einlesen(void)
{
uint8_t pixel[32],*pixelzeiger;
uint8_t i, zeilen, step, lines, rows, h_step, h_delay;
zeilen=32; // Das fertige Bild soll 32 Zeilen haben
step=7; // sichtbares TV-Bild ist ca. 30-260=230/32 ergibt Zeilensprung=7
rows=0; // Anzahl der Spalten (32x32, rechengünstig,aber verzerrt)
do
{
lines=zeilen; // Anzahl der einzulesenden Zeilen
pixelzeiger=&pixel[0]; // Zeiger auf Start Pixelspeicher
cli();
// VSync abwarten (Seitenanfang)
while(VSYNC);
// 40 Zeilen Austastzeit & ein Stück oberen Bildrand überlesen
h_step=40; while (h_step) { while (HSYNC); while (!HSYNC); h_step--; }
// Der Lesecursor befindet sich jetzt oben links im TV-Bild
// ab hier werden in step-Sprüngen in allen Zeilen jeweils das Pixel eingelesen,
// das sich im zeitlichen h_delay-Abstand vom linken TV-Bildrand befinden
// (= eine TV-Bildspalte)
while (lines--)
{
// auf die nächste gültige Zeile warten
h_step=step; while (h_step) { while (HSYNC); while (!HSYNC); h_step--; }
// mit h_delay steuern wir nun den Pixel an
// Nach dem sync fängt das Bild etwas verzögert an (Schwarzschulter), bei mir 10
// bei ca. 110 beginnt die 2.Schwarzschulter.
h_delay=10+3*rows; while (h_delay--) {nop();}
*pixelzeiger=ADCH; // letzten ADC-Wert auslesen und wegwerfen
*pixelzeiger++=ADCH; // aktuellsten ADC-Werte speichern
}
sei();
pixelzeiger=&pixel[0];
bildzeiger=&bildspeicher[32*rows];
for (i=0; i<32; i++) *bildzeiger++ = *pixelzeiger++;
} while (++rows < zeilen);
}
/************************************************** ***************************/
// Main function - The program starts here:
int main(void)
{
initRobotBase(); // Always call this first! The Processor will not work
// correctly otherwise.
// ---------------------------------------
// Write messages to the Serial Interface:
writeString_P("\n\n _______________________\n");
writeString_P(" \\| RP6 ROBOT SYSTEM |/\n");
writeString_P(" \\_-_-_-_-_-_-_-_-_-_/\n\n");
writeString_P("################\n");
writeString_P("<<RP6 Base>>\n");
writeString_P("Video Grabber 1 \n");
writeString_P(" Version 1.10 \n");
writeString_P("################\n\n");
mSleep(2500);
setLEDs(0b111111); // Turn all LEDs on
mSleep(500); // delay 500ms
setLEDs(0b000000); // All LEDs off
// Initialize the M32 SDA pin (PC1) as input:
DDRC &= ~SDA; // ==> HSync
PORTC |= SDA; // Pullup on
// Initialize the M32 SCL pin (PC0) as input:
DDRC &= ~SCL; // ==> VSync
PORTC |= SCL; // Pullup on
// Switch the IR-LEDs off:
IRoff(); // IR LEDs off
uint16_t i, j;
extIntOFF(); // schaltet den E_INT1-Port auf Eingang für den ADC
// ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4
ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR) | 4;
// setzte free running triggern
SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// kein interupt, Wandler einschalten, prescaler /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);
while(true)
{
bild_einlesen();
for (i=0; i<32; i++)
{
for (j=0; j<32; j++)
{
if (bildspeicher[j+32*i] > 55) writeString_P("*");
else writeString_P(" ");
}
writeInteger(i,DEC);
writeString_P("\n\r");
}
mSleep(200);
}
return 0;
}
/************************************************** ****************************
* Additional info
* ************************************************** **************************
* Changelog:
* - v. 1.1 (workout for the hardware project) 02.05.2010 by Dirk
* - v. 1.0 (initial release) 20.08.2007 by radbruch
*
* ************************************************** **************************
*/
/************************************************** ***************************/
Viel Spaß!
Dirk