This is a mbed Client sample where ZXing is incorporated, and works on GR-PEACH and GR-LYCHEE.
Dependencies: DisplayApp AsciiFont
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-PEACH ( https://developer.mbed.org/platforms/Renesas-GR-PEACH/ )
- Audio Camera Shield ( https://developer.mbed.org/teams/Renesas/wiki/Audio_Camera-shield )
- LCD Shield ( https://developer.mbed.org/teams/Renesas/wiki/LCD-shield )
- Ethernet cable and connection to the internet
- Wireless Camera shieled (This is GR-PEACH' Wifi(ESP32) optional.)
- 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/teams/Renesas/code/GR-PEACH_mbed-os-client-ZXingSample/wiki/Connection-type. - Set the client credentials. For details, please refer to the following wiki:
https://os.mbed.com/teams/Renesas/code/GR-PEACH_mbed-os-client-ZXingSample/wiki/Client-credentials. - Change Ethernet settings. For details, please refer to the following wiki:
https://developer.mbed.org/teams/Renesas/code/GR-PEACH_mbed-os-client-ZXingSample/wiki/Ethernet-settings. - Change Wifi settings. For details, please refer to the following wiki:
https://os.mbed.com/teams/Renesas/code/GR-PEACH_mbed-os-client-ZXingSample/wiki/Wifi-settings. - Set up an IP address. (This step is optional.) For details, please refer to the following wiki:
https://os.mbed.com/teams/Renesas/code/GR-PEACH_mbed-os-client-ZXingSample/wiki/IP-address-setup.
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 Ethernet cable into GR-PEACH or GR-LYCHEE if you are using Ethernet mode.
- 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-PEACH or 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://developer.mbed.org/teams/Renesas/code/GR-PEACH_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 red, green, blue, cyan, yellow and magenta is acceptable if you are using GR-PEACH board (PUT).
- 3201/0/5855. Blink color, used by the blink function. Any of green, yellow, orange and red is acceptable if you are using GR-LYCHEE board (PUT).
For more info on how to get notifications when resource 1 changes, or how to use resource 2, 3 and 4, please look at
Import programGR-PEACH_mbed-connector-ZXingSample-node
Node.js based Web Application for mbed Device Connector specific to GR-PEACH_mbed-os-client-ZXingSample
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;
}
+
