Mbed Client sample for GR-LYCHEE where ZXing is incorporated.
Dependencies: DisplayApp AsciiFont
Fork of GR-PEACH_mbed-os-client-ZXingSample by
Overview
This sample program shows how to use mbed Client together with ZXing which is an open-source, multi-format 1D/2D barcode image processing library. For more info on ZXing, please refer to https://github.com/zxing/zxing.
Required hardware
- GR-LYCHEE ( https://developer.mbed.org/platforms/Renesas-GR-LYCHEE/ )
Application setup
- Select the connection type. For details, please refer to the following wiki:
https://os.mbed.com/users/1050186/code/GR-LYCHEE_mbed-os-client-ZXingSample/wiki/Connection-type. - Set the client credentials. For details, please refer to the following wiki:
https://os.mbed.com/users/1050186/code/GR-LYCHEE_mbed-os-client-ZXingSample/wiki/Client-credentials. - Change Wifi settings. For details, please refer to the following wiki:
https://os.mbed.com/users/1050186/code/GR-LYCHEE_mbed-os-client-ZXingSample/wiki/Wifi-settings.
Building the example
To build this example:
- Import this example onto mbed Compiler.
- Configure the example in accordance with Application setup.
- Compile the example on mbed Compiler and download the resultant binary file.
- Plug the micro-USB cable into the OpenSDA port which lies on the next to the RESET button.
- Copy the binary previously downloaded to your PC to GR-LYCHEE to flash this example. When the copy is successfully completed, the board is ready to work.
- Press the RESET button on the board to run the example.
- For verification, please refer to the following wiki:
https://os.mbed.com/users/1050186/code/GR-LYCHEE_mbed-os-client-ZXingSample/wiki/Monitoring-the-application.
Application resources
This example exposes four resources listed below:
- 3202/0/5700. Decode result of barcode data input from camera (GET).
- 3201/0/5850. Blink function, blinks LED when executed (POST).
- 3201/0/5853. Blink pattern, used by the blink function to determine how to blink. In the format of 1000:500:1000:500:1000:500 (PUT).
- 3201/0/5855. Blink color, used by the blink function. Any of green, yellow, orange and red is acceptable (PUT).
Diff: zxing_main.cpp
- Revision:
- 2:6ec5c1c1d41c
- Parent:
- 0:eb73febb2bba
- Child:
- 4:076b3dd7c0e6
diff -r 5d3134f9efae -r 6ec5c1c1d41c zxing_main.cpp --- a/zxing_main.cpp Wed Oct 19 15:58:43 2016 +0900 +++ b/zxing_main.cpp Tue Mar 28 11:02:34 2017 +0000 @@ -1,28 +1,24 @@ - -#include <vector> #include "mbed.h" #include "rtos.h" #include "DisplayBace.h" #include "ImageReaderSource.h" -#include "DisplayApp.h" -#include "AsciiFont.h" #define VIDEO_CVBS (0) /* Analog Video Signal */ #define VIDEO_CMOS_CAMERA (1) /* Digital Video Signal */ -#define VIDEO_RGB888 (1) /**** User Selection *********/ /** Camera setting **/ #define VIDEO_INPUT_METHOD (VIDEO_CMOS_CAMERA) /* Select VIDEO_CVBS or VIDEO_CMOS_CAMERA */ -#define VIDEO_INPUT_FORMAT (VIDEO_RGB888) /* Select VIDEO_RGB888 */ #define USE_VIDEO_CH (0) /* Select 0 or 1 If selecting VIDEO_CMOS_CAMERA, should be 0.) */ #define VIDEO_PAL (0) /* Select 0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */ /** LCD setting **/ #define LCD_ONOFF (1) /* Select 0(without LCD) or 1(with LCD) */ -#if LCD_ONOFF #define LCD_TYPE (0) /* Select 0(4.3inch) or 1(7.1inch) */ -#endif +/** JPEG out setting **/ +#define JPEG_SEND (0) /* Select 0(JPEG images are not output to PC) or 1(JPEG images are output to PC on USB(CDC) for focusing the camera) */ +/** Decode hints **/ +#define DECODE_HINTS (DecodeHints::ONED_HINT | DecodeHints::QR_CODE_HINT | DecodeHints::DATA_MATRIX_HINT | DecodeHints::AZTEC_HINT) /*****************************/ #if LCD_ONOFF @@ -32,6 +28,12 @@ #else #include "LCD_shield_config_7_1inch.h" #endif + #include "AsciiFont.h" +#endif + +#ifdef JPEG_SEND + #include "JPEG_Converter.h" + #include "DisplayApp.h" #endif /** Video and Grapics (GRAPHICS_LAYER_0) parameter **/ @@ -52,83 +54,48 @@ #endif /* Video input */ -#define VIDEO_FORMAT (DisplayBase::VIDEO_FORMAT_RGB888) -#define GRAPHICS_FORMAT (DisplayBase::GRAPHICS_FORMAT_RGB888) -#define WR_RD_WRSWA (DisplayBase::WR_RD_WRSWA_32BIT) +#define VIDEO_FORMAT (DisplayBase::VIDEO_FORMAT_YCBCR422) +#define GRAPHICS_FORMAT (DisplayBase::GRAPHICS_FORMAT_YCBCR422) +#define WR_RD_WRSWA (DisplayBase::WR_RD_WRSWA_16BIT) +#define FRAME_BUFFER_BYTE_PER_PIXEL (2u) + +#if VIDEO_INPUT_METHOD == VIDEO_CVBS + #define WAIT_VFIELD_CNT (2) +#else + #define WAIT_VFIELD_CNT (1) +#endif /* The size of the video input */ #if ((LCD_ONOFF) && (LCD_TYPE == 0)) - #define VIDEO_PIXEL_HW LCD_PIXEL_WIDTH - #define VIDEO_PIXEL_VW LCD_PIXEL_HEIGHT + #define VIDEO_PIXEL_HW LCD_PIXEL_WIDTH + #define VIDEO_PIXEL_VW LCD_PIXEL_HEIGHT #else - #define VIDEO_PIXEL_HW (640) /* VGA */ - #define VIDEO_PIXEL_VW (480) /* VGA */ + #define VIDEO_PIXEL_HW (640) /* VGA */ + #define VIDEO_PIXEL_VW (480) /* VGA */ #endif /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128 in accordance with the frame buffer burst transfer mode. */ /* FRAME BUFFER Parameter GRAPHICS_LAYER_0 */ -#define FRAME_BUFFER_NUM (2u) -#define FRAME_BUFFER_BYTE_PER_PIXEL (4u) -#define FRAME_BUFFER_STRIDE (((VIDEO_PIXEL_HW * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u) - -#if LCD_ONOFF -#define VIDEO_PIXEL_HW_STR (VIDEO_PIXEL_HW - 64) -#define VIDEO_PIXEL_VW_STR (VIDEO_PIXEL_VW - 64) -#define FRAME_BUFFER_BYTE_PER_PIXEL_STR (2u) -#define FRAME_BUFFER_STRIDE_STR (((VIDEO_PIXEL_HW_STR * FRAME_BUFFER_BYTE_PER_PIXEL_STR) + 31u) & ~31u) -#endif +#define FRAME_BUFFER_STRIDE (((VIDEO_PIXEL_HW * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u) static DisplayBase Display; -static DisplayApp display_app; static Timer decode_timer; -#if LCD_ONOFF -static DigitalOut lcd_pwon(P7_15); -static DigitalOut lcd_blon(P8_1); -static PwmOut lcd_cntrst(P8_15); -#endif /* 32 bytes aligned */ -static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW]__attribute((aligned(32))); -static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW]__attribute((aligned(32))); -#if LCD_ONOFF -static uint8_t user_frame_buffer_string[FRAME_BUFFER_STRIDE_STR * VIDEO_PIXEL_VW_STR]__attribute((aligned(32))); -static AsciiFont ascii_font(user_frame_buffer_string, VIDEO_PIXEL_HW_STR, VIDEO_PIXEL_VW_STR, FRAME_BUFFER_STRIDE_STR, FRAME_BUFFER_BYTE_PER_PIXEL_STR); -static bool string_draw; -#endif -static uint8_t * decode_buffer = user_frame_buffer0; -static uint8_t * FrameBufferTbl[FRAME_BUFFER_NUM] = {user_frame_buffer0, user_frame_buffer1}; +static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW]__attribute((section("NC_BSS"),aligned(32))); + static volatile int32_t vfield_count = 0; -static int write_buff_num = 0; static bool graphics_init_end = false; static int decode_wait_time = 0; static void (*p_callback_func)(char * addr, int size); -/****** cache control ******/ -static void dcache_clean(void * p_buf, uint32_t size) { - uint32_t start_addr = (uint32_t)p_buf & 0xFFFFFFE0; - uint32_t end_addr = (uint32_t)p_buf + size; - uint32_t addr; - - /* Data cache clean */ - for (addr = start_addr; addr < end_addr; addr += 0x20) { - __v7_clean_dcache_mva((void *)addr); - } -} - -static void dcache_invalid(void * p_buf, uint32_t size){ - uint32_t start_addr = (uint32_t)p_buf & 0xFFFFFFE0; - uint32_t end_addr = (uint32_t)p_buf + size; - uint32_t addr; - - /* Data cache invalid */ - for (addr = start_addr; addr < end_addr; addr += 0x20) { - __v7_inv_dcache_mva((void *)addr); - } -} - #if LCD_ONOFF /****** LCD ******/ +static DigitalOut lcd_pwon(P7_15); +static DigitalOut lcd_blon(P8_1); +static PwmOut lcd_cntrst(P8_15); + static void Init_LCD_Display(void) { DisplayBase::graphics_error_t error; DisplayBase::lcd_config_t lcd_config; @@ -172,7 +139,120 @@ ); Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); } -#endif + +#define VIDEO_PIXEL_HW_STR (VIDEO_PIXEL_HW - 64) +#define VIDEO_PIXEL_VW_STR (VIDEO_PIXEL_VW - 64) +#define FRAME_BUFFER_BYTE_PER_PIXEL_STR (2u) +#define FRAME_BUFFER_STRIDE_STR (((VIDEO_PIXEL_HW_STR * FRAME_BUFFER_BYTE_PER_PIXEL_STR) + 31u) & ~31u) + +static uint8_t user_frame_buffer_string[FRAME_BUFFER_STRIDE_STR * VIDEO_PIXEL_VW_STR]__attribute((section("NC_BSS"),aligned(32))); +static AsciiFont ascii_font(user_frame_buffer_string, VIDEO_PIXEL_HW_STR, VIDEO_PIXEL_VW_STR, FRAME_BUFFER_STRIDE_STR, FRAME_BUFFER_BYTE_PER_PIXEL_STR); +static bool string_draw; + +static void decode_string_init(void) { + DisplayBase::rect_t rect; + + /* The layer by which the touch panel location is drawn */ + ascii_font.Erase(0x00000000); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ + rect.vs = 32; + rect.vw = VIDEO_PIXEL_VW_STR; + rect.hs = 32; + rect.hw = VIDEO_PIXEL_HW_STR; + Display.Graphics_Read_Setting( + DisplayBase::GRAPHICS_LAYER_1, + (void *)user_frame_buffer_string, + FRAME_BUFFER_STRIDE_STR, + DisplayBase::GRAPHICS_FORMAT_ARGB4444, + DisplayBase::WR_RD_WRSWA_32_16BIT, + &rect + ); + Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_1); + string_draw = false; +} + +static void decode_string_disp(char ** decode_str) { + if ((decode_str != NULL) && (*decode_str != NULL)) { + /* Drow string */ + ascii_font.Erase(0x00000090); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ + int rest_size = strlen(*decode_str); + int draw_idx = 0; + int draw_size; + int draw_line = 0; + + while (rest_size > 0) { + draw_size = ascii_font.DrawStr(*decode_str + draw_idx, 6, 5 + (18 * draw_line), 0x0000ffff, 2); + if (draw_size <= 0) { + break; + } + rest_size -= draw_size; + draw_idx += draw_size; + draw_line++; + } + string_draw = true; + } else { + if (string_draw != false) { + /* Clear string */ + ascii_font.Erase(0x00000000); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ + string_draw = false; + } + } +} +#endif // LCD_ONOFF + +#ifdef JPEG_SEND +/****** Jpeg Send ******/ +#define JPEG_ENC_MAX_SIZE (1024 * 63) +#define JPEG_SIGNAL_CAP_COMP (1L) + +#define JPEGSEND_STB (0) +#define JPEGSEND_ENC (1) + +static Thread jpegsendTask(osPriorityAboveNormal, 2048); +static DisplayApp display_app; +static uint8_t JpegBuffer[JPEG_ENC_MAX_SIZE]__attribute((section("NC_BSS"),aligned(8))); //8 bytes aligned!; +volatile static uint32_t jpegsend_status = JPEGSEND_STB; + +static void jpegsendTask_main( void ) { + JPEG_Converter Jcu; + size_t jcu_encode_size; + + while (1) { + Thread::signal_wait(JPEG_SIGNAL_CAP_COMP, 80); + jpegsend_status = JPEGSEND_ENC; + + /* JPEG Enc Start */ + JPEG_Converter::bitmap_buff_info_t bitmap_buff_info; + JPEG_Converter::encode_options_t encode_options; + bitmap_buff_info.width = VIDEO_PIXEL_HW; + bitmap_buff_info.height = VIDEO_PIXEL_VW; + bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422; + bitmap_buff_info.buffer_address = (void *)user_frame_buffer0; + encode_options.encode_buff_size = sizeof(JpegBuffer); + encode_options.p_EncodeCallBackFunc = NULL; + encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_16_8BIT; + jcu_encode_size = 0; + if (Jcu.encode(&bitmap_buff_info, JpegBuffer, &jcu_encode_size, &encode_options) != JPEG_Converter::JPEG_CONV_OK) { + jcu_encode_size = 0; + } + + /* JPEG Data Send */ + if ((jcu_encode_size > 256) && (jcu_encode_size < JPEG_ENC_MAX_SIZE)) { + display_app.SendJpeg(JpegBuffer, jcu_encode_size); + } + jpegsend_status = JPEGSEND_STB; + } +} + +static void jpegsendTask_init( void ) { + jpegsendTask.start(jpegsendTask_main); +} + +static void jpegsend_cap_comp( void ) { + if (jpegsend_status == JPEGSEND_STB) { + jpegsendTask.signal_set(JPEG_SIGNAL_CAP_COMP); + } +} +#endif // JPEG_SEND /****** Video ******/ static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) { @@ -180,6 +260,9 @@ if (vfield_count > 0) { vfield_count--; } +#ifdef JPEG_SEND + jpegsend_cap_comp(); +#endif // JPEG_SEND } static void Wait_Vfield(const int32_t wait_count) { @@ -310,49 +393,31 @@ /****** zxing_init ******/ void zxing_init(void (*pfunc)(char * addr, int size)) { +#ifdef JPEG_SEND + jpegsendTask_init(); +#endif // JPEG_SEND #if LCD_ONOFF /* Initialization of LCD */ Init_LCD_Display(); /* When using LCD, please call before than Init_Video(). */ -#endif +#endif // LCD_ONOFF /* Initialization of Video */ Init_Video(); /* Initialization memory */ - for (int i = 0; i < FRAME_BUFFER_NUM; i++) { - memset(FrameBufferTbl[i], 0, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW)); - dcache_clean(FrameBufferTbl[i], (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW)); - } + memset(user_frame_buffer0, 0, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW)); /* Start of Video */ - Start_Video(FrameBufferTbl[write_buff_num]); + Start_Video(user_frame_buffer0); /* Wait for first video drawing */ - Wait_Vfield(2); + Wait_Vfield(WAIT_VFIELD_CNT); #if LCD_ONOFF - DisplayBase::rect_t rect; - - /* The layer by which the touch panel location is drawn */ - ascii_font.Erase(0x00000000); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ - dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string)); - rect.vs = 32; - rect.vw = VIDEO_PIXEL_VW_STR; - rect.hs = 32; - rect.hw = VIDEO_PIXEL_HW_STR; - Display.Graphics_Read_Setting( - DisplayBase::GRAPHICS_LAYER_1, - (void *)user_frame_buffer_string, - FRAME_BUFFER_STRIDE_STR, - DisplayBase::GRAPHICS_FORMAT_ARGB4444, - DisplayBase::WR_RD_WRSWA_32_16BIT, - &rect - ); - Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_1); - string_draw = false; + decode_string_init(); /* Start of LCD */ - Start_LCD_Display(FrameBufferTbl[write_buff_num]); + Start_LCD_Display(user_frame_buffer0); /* Backlight on */ Thread::wait(200); lcd_cntrst.write(1.0); -#endif +#endif // LCD_ONOFF p_callback_func = pfunc; decode_timer.reset(); decode_timer.start(); @@ -363,72 +428,30 @@ DisplayBase::graphics_error_t error; int decode_result = -1; vector<Ref<Result> > results; + char ** decode_str = NULL; - decode_buffer = FrameBufferTbl[write_buff_num]; - write_buff_num++; - if (write_buff_num >= FRAME_BUFFER_NUM) { - write_buff_num = 0; - } - /* Change video buffer */ - error = Display.Video_Write_Change(VIDEO_INPUT_CH, FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE); - if (error != DisplayBase::GRAPHICS_OK) { - printf("Line %d, error %d\n", __LINE__, error); - mbed_die(); - } - Wait_Vfield(2); -#if LCD_ONOFF - /* Change LCD buffer */ - Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0, (void *)FrameBufferTbl[write_buff_num]); -#endif - dcache_invalid(decode_buffer, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW)); + Wait_Vfield(WAIT_VFIELD_CNT); /* Decode barcode image */ if (decode_timer.read_ms() >= decode_wait_time) { decode_timer.reset(); - decode_result = ex_decode(decode_buffer, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW), VIDEO_PIXEL_HW, VIDEO_PIXEL_VW, &results); + DecodeHints hints(DECODE_HINTS); + hints.setTryHarder(false); + decode_result = ex_decode(user_frame_buffer0, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW), VIDEO_PIXEL_HW, VIDEO_PIXEL_VW, &results, hints); if (decode_result == 0) { - char ** decode_str; - int size; - decode_str = (char **)&(results[0]->getText()->getText()); - size = strlen(*decode_str); + int size = strlen(*decode_str); if (p_callback_func != NULL) { p_callback_func(*decode_str, size); } -#if LCD_ONOFF - /* Drow string */ - ascii_font.Erase(0x00000090); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ - int rest_size = strlen(*decode_str); - int draw_idx = 0; - int draw_size; - int draw_line = 0; - - while (rest_size > 0) { - draw_size = ascii_font.DrawStr(*decode_str + draw_idx, 6, 5 + (18 * draw_line), 0x0000ffff, 2); - if (draw_size <= 0) { - break; - } - rest_size -= draw_size; - draw_idx += draw_size; - draw_line++; - } - - dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string)); - string_draw = true; -#endif decode_wait_time = 500; } else { -#if LCD_ONOFF - if (string_draw != false) { - /* Clear string */ - ascii_font.Erase(0x00000000); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ - dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string)); - string_draw = false; - } -#endif decode_wait_time = 10; } +#if LCD_ONOFF + decode_string_disp(decode_str); +#endif // LCD_ONOFF } - display_app.SendRgb888(decode_buffer, VIDEO_PIXEL_HW, VIDEO_PIXEL_VW); return decode_result; } +