MARMEX_VB test application program. This application works on "mbed NXP LPC1768" only. This application expects to have the MARMEX_VB module on a "MAPLE mini type-B (MARM03-BASE)" baseboard (slot2) with MARMEX_OB module (on slot1)
Dependencies: MARMEX_VB NokiaLCD mbed
This is the library test program.
The program can test features of the library (refer to MARMEX-VB's API document) and can save captured data into BMP file.
Warning!
This test program can run on "mbed NXP LPC1768" only.
Picture : sample of test program operation
The modules of MARMEX-VB and MARMEX-OB are set on the "MAPLE mini type-B (MARM03-BASE)" baseboard.
The image data from camera is mirrored and alpha graphics added by software.
Diff: main.cpp
- Revision:
- 0:343c01965543
- Child:
- 1:dbe2dc31542d
diff -r 000000000000 -r 343c01965543 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Jun 06 03:37:02 2014 +0000 @@ -0,0 +1,349 @@ +/** Test program for MARMEX_VB Camera control library + * + * @version 0.1 + * @date 10-Jun-2014 + * + * Released under the Apache License, Version 2.0 : http://mbed.org/handbook/Apache-Licence + * + * Test program for MARMEX_VB Camera control library + * + * ** This program runs on mbed_NXP_LPC1768 only ** + */ + + +#include "mbed.h" +#include "MARMEX_OB_oled.h" +#include "MARMEX_VB.h" +#include "bmp_handler.h" + +MARMEX_OB_oled oled1( p5, p7, p20, p16, p15 ); +// mosi, sclk, cs, rst, power_control -- maple-mini-type-b-board-slot1 + +MARMEX_VB camera( p5, p6, p7, p22, p26, p28, p27 ); +// mosi, miso, sclk, cs, reset, sda, scl -- maple-mini-type-b-board-slot2 + +BusOut led( LED4, LED3, LED2, LED1 ); +Timer timer; + +void test_camera( void ); +void test_camera_resolution_change( void ); + +void copy_image_from_camera_to_oled( void ); +void copy_image_from_camera_to_oled_interlaced( void ); +void line_mirroring( short *buf ); +void save_still_image( char *file_name ); +void oled_test_screen( void ); +void capture_to_bmp( void ); + +//#define SAVE_EACH_SIZES_OF_STILL_IMAGE + +alpha_param ap; + + +int main() +{ + printf( "\r\n\r\nMARY-CAMERA test program\r\n\r\n" ); + + read_alpha_BMP( "alpha.bmp", &ap ); + + + led = 0x3; + + oled1.cls(); + oled_test_screen(); + +#ifdef SAVE_EACH_SIZES_OF_STILL_IMAGE + led = 0x1; + camera.resolution( MARMEX_VB::QCIF ); + save_still_image( "i_qcif.bmp" ); + + led = 0x2; + camera.resolution( MARMEX_VB::QQVGA ); + save_still_image( "i_qqvga.bmp" ); + + led = 0x4; + camera.resolution( MARMEX_VB::QVGA ); + save_still_image( "i_qvga.bmp" ); + + led = 0x8; + camera.resolution( MARMEX_VB::VGA ); + save_still_image( "i_vga.bmp" ); + + camera.resolution( MARMEX_VB::QCIF ); +#endif + + printf( " camera operation started\r\n" ); + printf( " hit key [c] for saving data into BMP (for blue-mbed only)\r\n" ); + printf( " hit key [o] to change data reading order\r\n" ); + printf( " hit key [i] to toggle interlace mode\r\n" ); + printf( " hit key [1], [2], [3] or [4] to change resolution QCIF, QQVGA, QVGA, VGA\r\n" ); + + timer.start(); // timer for measureing frame rate + test_camera(); // this function doesn't return +} + +#if defined( TARGET_MBED_LPC1768 ) || defined( TARGET_LPC11U24_401 ) +Serial pc(USBTX, USBRX); // tx, rx +#endif + + +void test_camera( void ) +{ + int interlace = 0; + int frame_count = 0; + + while ( 1 ) { + if ( pc.readable() ) { + switch ( pc.getc() ) { + case 'c' : + capture_to_bmp(); + printf( " [c] : capture started\r\n" ); + break; + case 'o' : + printf( " [o] read order change : %s\r\n", camera.read_order_change() ? "ENABLED" : "DISABLED" ); + break; + case 'i' : + interlace = !interlace; + printf( " [i] : interlace setting : %s\r\n", interlace ? "ENABLED" : "DISABLED" ); + /* FALL THROUGH */ + case 'f' : + if ( frame_count ) { + timer.stop(); + float t = timer.read(); + printf( " [f] : %s rate : %5.3f\r\n", interlace ? "field" : "frame", (float)frame_count / t ); + frame_count = 0; + timer.reset(); + timer.start(); + } else { + printf( " [f] : no frame drawn yet. try again later\r\n" ); + } + break; + case '1' : + printf( " [1] resolution change : QCIF\r\n" ); + camera.init( MARMEX_VB::QCIF ); + break; + case '2' : + printf( " [2] resolution change : QQVGA\r\n" ); + camera.init( MARMEX_VB::QQVGA ); + break; + case '3' : + printf( " [3] resolution change : QVGA\r\n" ); + camera.init( MARMEX_VB::QVGA ); + break; + case '4' : + printf( " [4] resolution change : VGA\r\n" ); + camera.init( MARMEX_VB::VGA ); + break; + } + } + + led = 0x1; + + if ( interlace ) + copy_image_from_camera_to_oled_interlaced(); + else + copy_image_from_camera_to_oled(); + + +// camera.colorbar( ((count++ >> 2) & 0x1) ? MARMEX_VB::ON : MARMEX_VB::OFF ); + + led = 0x2; + + frame_count++; + } +} + + +void test_camera_resolution_change( void ) +{ + int count = (3 << 3); + int setting; + + while ( 1 ) { + + if ( !(count & 0x7) ) { + setting = (count >> 3) & 0x3; + camera.init( (MARMEX_VB::CameraResolution)(setting + 1) ); + led = 0x1 << setting; + } + + count++; + + copy_image_from_camera_to_oled(); + } +} + + +void alpha( int line_num, short *bf, int offset_x, int offset_y, alpha_param *app ) +{ + short r, g, b; + int y_pos; + + if ( (line_num < offset_y) || (offset_y + app->v) <= line_num || (app->buffer == NULL) ) + return; + + bf += offset_x; + y_pos = ((app->v - (line_num - offset_y + 1)) * (app->h * app->byte_per_pixel)); + + for ( int i = 0; i < 60; i++ ) { + r = ((*bf >> 1) & 0x0F) + (*(app->buffer + i * 3 + 0 + y_pos ) >> 4); + g = ((*bf >> 6) & 0x1F) + (*(app->buffer + i * 3 + 1 + y_pos ) >> 3); + b = ((*bf >> 12) & 0x0F) + (*(app->buffer + i * 3 + 2 + y_pos ) >> 4); + + *bf++ = (b << 11) | (g << 5) | (r << 0); + } +} + + +void copy_image_from_camera_to_oled( void ) +{ + short buf[ MARMEX_OB_oled::WIDTH ]; + static int count = 0; + + camera.open_transfer(); + + for ( int line = 0; line < MARMEX_OB_oled::HEIGHT; line++ ) { + camera.read_a_line( buf, line + (camera.get_vertical_size() - (int)MARMEX_OB_oled::HEIGHT) / 2, (camera.get_horizontal_size() - (int)MARMEX_OB_oled::WIDTH ) / 2, MARMEX_OB_oled::WIDTH ); + line_mirroring( buf ); + alpha( line, buf, ((count >> 4) & 1) ? 60 : 8, ((count >> 4) & 1) ^ ((count >> 3) & 1) ? ((int)MARMEX_OB_oled::HEIGHT - (ap.v + 4)) : 4, &ap ); + oled1.blit565( 0, line, MARMEX_OB_oled::WIDTH, 1, buf ); + } + + count++; + camera.close_transfer(); +} + + +void copy_image_from_camera_to_oled_interlaced( void ) +{ + short buf[ MARMEX_OB_oled::WIDTH ]; + static int count = 0; + + camera.open_transfer(); + + for ( int line = (count++) & 1; line < MARMEX_OB_oled::HEIGHT; line += 2 ) { + camera.read_a_line( buf, line + (camera.get_vertical_size() - (int)MARMEX_OB_oled::HEIGHT) / 2, (camera.get_horizontal_size() - (int)MARMEX_OB_oled::WIDTH ) / 2, MARMEX_OB_oled::WIDTH ); + line_mirroring( buf ); + alpha( line, buf, ((count >> 4) & 1) ? 60 : 8, ((count >> 4) & 1) ^ ((count >> 3) & 1) ? ((int)MARMEX_OB_oled::HEIGHT - (ap.v + 4)) : 4, &ap ); + oled1.blit565( 0, line, MARMEX_OB_oled::WIDTH, 1, buf ); + } + + camera.close_transfer(); +} + + + +void line_mirroring( short *buf ) +{ + short tmp; + + for ( int i = 0; i < (MARMEX_OB_oled::WIDTH / 2); i++ ) { + tmp = buf[ i ]; + buf[ i ] = buf[ (MARMEX_OB_oled::WIDTH - 1) - i ]; + buf[ (MARMEX_OB_oled::WIDTH - 1) - i ] = tmp; + } +} + + +void oled_test_screen( void ) +{ + oled1.background( 0x000000 ); + oled1.cls(); + + int colorbar_width = MARMEX_OB_oled::WIDTH / 8; + + for ( int i = 0; i < 8; i++ ) + oled1.fill( colorbar_width * i, 0, colorbar_width, MARMEX_OB_oled::HEIGHT, ((i & 0x4) ? 0xFF0000 : 0x000000) | ((i & 0x2) ? 0x00FF00 : 0x000000) | ((i & 0x1) ? 0x0000FF : 0x000000) ); + + oled1.fill( 50, 50, 64, 64, 0xCCCCCC );; + + oled1.locate( 0, 2 ); + oled1.printf( "MaryCemara test" ); + oled1.locate( 0, 3 ); + oled1.printf( "%s", (MARMEX_VB::NO_ERROR == camera.ready()) ? "Camera is ready" : "No Camera found" ); + oled1.locate( 0, 4 ); + oled1.printf( "%s", "saving into BMP" ); + oled1.locate( 0, 5 ); + oled1.printf( "%d", camera.get_horizontal_size() ); + oled1.locate( 0, 6 ); + oled1.printf( "%d", camera.get_vertical_size() ); + + + for (int i = 0; i < MARMEX_OB_oled::WIDTH; i++ ) + oled1.pixel( i, 80 + sin( (float)i / 5.0 ) * 10, 0x000000 ); +} + + +#include "bmp_handler.h" + +void save_still_image( char *file_name ) +{ + short buf[ camera.get_horizontal_size() ]; + + if ( open_BMP( file_name, camera.get_horizontal_size(), camera.get_vertical_size() ) ) + return; + + camera.open_transfer(); + + for ( int line = (camera.get_vertical_size() - 1); 0 <= line; line-- ) { + camera.read_a_line( buf, line, 0, camera.get_horizontal_size() ); + write_BMP( buf, camera.get_horizontal_size() ); + } + camera.close_transfer(); + + close_BMP(); +} + +void capture_to_bmp( void ) +{ + short buf[ camera.get_horizontal_size() ]; + camera.open_transfer(); + + if ( open_BMP( "RGB.bmp", camera.get_horizontal_size(), camera.get_vertical_size() ) ) + return; + + for ( int line = (camera.get_vertical_size() - 1); 0 <= line; line-- ) { + camera.read_a_line( buf, line, 0, camera.get_horizontal_size() ); +// write_BMP( buf, camera.get_horizontal_size(), 0x7 ); + write_BMP( buf, camera.get_horizontal_size() ); + } + + close_BMP(); + +#if 0 + + if ( open_BMP( "R.bmp", camera.get_horizontal_size(), camera.get_vertical_size() ) ) + return; + + for ( int line = (camera.get_vertical_size() - 1); 0 <= line; line-- ) { + camera.read_a_line( buf, line, 0, camera.get_horizontal_size() ); + write_BMP( buf, camera.get_horizontal_size(), 0x4 ); + } + + close_BMP(); + + + if ( open_BMP( "G.bmp", camera.get_horizontal_size(), camera.get_vertical_size() ) ) + return; + + for ( int line = (camera.get_vertical_size() - 1); 0 <= line; line-- ) { + camera.read_a_line( buf, line, 0, camera.get_horizontal_size() ); + write_BMP( buf, camera.get_horizontal_size(), 0x2 ); + } + + close_BMP(); + + + if ( open_BMP( "B.bmp", camera.get_horizontal_size(), camera.get_vertical_size() ) ) + return; + + for ( int line = (camera.get_vertical_size() - 1); 0 <= line; line-- ) { + camera.read_a_line( buf, line, 0, camera.get_horizontal_size() ); + write_BMP( buf, camera.get_horizontal_size(), 0x1 ); + } + + close_BMP(); + +#endif + camera.close_transfer(); +}