Mbed Client sample for GR-LYCHEE where ZXing is incorporated.

Dependencies:   DisplayApp AsciiFont

Fork of GR-PEACH_mbed-os-client-ZXingSample by Renesas

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

Application setup

  1. 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.
  2. 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.
  3. 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:

  1. Import this example onto mbed Compiler.
  2. Configure the example in accordance with Application setup.
  3. Compile the example on mbed Compiler and download the resultant binary file.
  4. Plug the micro-USB cable into the OpenSDA port which lies on the next to the RESET button.
  5. 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.
  6. Press the RESET button on the board to run the example.
  7. 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:

  1. 3202/0/5700. Decode result of barcode data input from camera (GET).
  2. 3201/0/5850. Blink function, blinks LED when executed (POST).
  3. 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).
  4. 3201/0/5855. Blink color, used by the blink function. Any of green, yellow, orange and red is acceptable (PUT).
Revision:
2:6ec5c1c1d41c
Parent:
0:eb73febb2bba
Child:
4:076b3dd7c0e6
--- 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;
 }
+