Sample program showing how to connect GR-PEACH into Watson IoT through mbed Connector and Watson's Connector Bridge

Dependencies:   AsciiFont DisplayApp GR-PEACH_video LCD_shield_config LWIPBP3595Interface_STA_for_mbed-os USBDevice

Overview

This sample program shows how to connect GR-PEACH into Watson IoT through mbed Connector and Watson's Connector Bridge. Note that this program is derived from https://github.com/ARMmbed/mbed-ethernet-sample-techcon2016.

In this program, at first, the barcode data input from camera is decoded on GR-PEACH using ZXing which is an open-source, multi-format 1D/2D barcode image processing library. Then, the decoded string is sent to Watson IoT via mbed Device Connector and Watson's Connector Bridge. At last, the delivered string is confirmed via NodeRED flow.

Required hardware

Application setup

  1. Select the connection type. For details, please refer to the following wiki:
    https://developer.mbed.org/teams/Renesas/code/mbed-os_Watson-IoT_ZXing_sample/wiki/Connection-type.
  2. Set the client credentials. For details, please refer to the following wiki:
    https://developer.mbed.org/teams/Renesas/code/mbed-os_Watson-IoT_ZXing_sample/wiki/Client-credentials.
  3. Change Ethernet settings. For details, please refer to the following wiki:
    https://developer.mbed.org/teams/Renesas/code/mbed-os_Watson-IoT_ZXing_sample/wiki/Ethernet-settings.
  4. Change Wifi settings. For details, please refer to the following wiki:
    https://developer.mbed.org/teams/Renesas/code/mbed-os_Watson-IoT_ZXing_sample/wiki/Wifi-settings.

Building this sample program

  1. Import this sample program onto mbed Compiler.
  2. Configure this sample program in accordance with Application setup.
  3. Compile the example on mbed Compiler and download the resultant binary file.
  4. Plug the Ethernet cable into GR-PEACH if you are using Ethernet mode. /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen7.png
  5. Plug the micro-USB cable into the OpenSDA port with lies on the next to the RESET button.
  6. Copy the binary previously downloaded to your PC to GR-PEACH to flash this sample program. When the copy is successfully completed, the board is ready to work.
  7. Press the RESET button on the board to run this sample program.
  8. For verification, please refer to the following wiki:
    https://developer.mbed.org/teams/Renesas/code/mbed-os_Watson-IoT_ZXing_sample/wiki/Monitoring-the-application.

Application resources

This sample program exposes two resources listed below:

  1. /311/0/5850 : Trigger to toggle LED on GR-PEACH (PUT). When "1" is sent to this resource by PUT method, LED should be turned off. Otherwise, LED should be turned on.
  2. /888/0/7700: Decode result of barcode data input from camera (GET)

Setup of Watson IoT

  1. You should create Watson IoT Instance by the following procedure:
    • Login IBM Bluemix from https://console.ng.bluemix.net/ and login it.
    • Select Services as follows: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen6.png
    • Select Internet of Things" as follows: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen7_1.png
    • Press Get Started as follows: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen8.png
    • Configure Watson IoT Instance
      • Leave unbound /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen9.png
      • Select the Free plan, then click Create /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen10.png

  2. You should create Watson IoT Application Credentials Once you successfully create Watson IoT Instance, you should see the following Watson IoT dashboard: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen11.png
    • On dashboard, launch the Connect your devices dashboard /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen12.png
    • Click APPS /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen13.png
    • Click Generate API Key /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen14_1.png
    • Record the API Key and Authenticatoin Token. Then click Generate after adding a comment /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen15.png Note that these two values will be needed in the later step.
  3. Watson IoT NodeRED Application should be created in accordance with the following procedure:
    • Go back to your Bluemix Dashboard: https://console.ng.bluemix.net
    • Click Create Application /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen16.png
    • Select Node-RED Starter /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen17.png
    • Enter a unique App name and Click Create /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen18.png
    • Application will Stage after a few minutes
    • Application will report app is running when the staging has completed
  4. Watson NodeRED Application should be binded to Watson IoT instance
    • You can now see the dashboard below: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen19.png
    • Click Connections. Then, press Connect Existing /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen20.png
    • Click on Watson IoT Instance badge. Then, press Connect /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen21.png
    • NodeRED application will restage. This will take a while. Please wait for Your app is running state /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen22.png /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen23.png
  5. You should acquire mbed Device Connector DOMAIN value
    • Go to the mbed Device Connector Dashboard: https://connector.mbed.com and log in /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen41.png
    • Select Access Key in order to create a new token /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen42.png
    • Click CREATE NEW ACCESS KEY and enter a unique name. Then, push ADD bution /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen43.png
    • an API token is generated. Need to save the generated string for later steps /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen44.png
  1. You should configure Watson IoT ARM mbed Connector Bridge
    • Go back to the Watson IoT Dashboard and select Extensions /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen24.png
    • Press Add Extension /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen25.png
    • Add ARM mbed Connector /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen26_1.png
    • Setup the bridge /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen27.png
    • Enter your Connector API Token to Access Key and MBED_DOMAIN to Domain Id, respectively. Then, click Check Connection /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen28.png
    • If the connection is successfully established, you can see Connection Established. Then, press Done /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen29.png
  2. NodeRED Flow Example should be imported
    • Open NODEFLOW_GR-PEACH.txt
    • Navigate to the URL that you recorded earlier for your Watson IoT NodeRED Application (i.e. http://<app name>.mybluemix.net) and Select Go to your NodeRED flow editor /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen30.png
    • Select menu, Import and Clipboard /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen31.png
    • Paste the entire contents of JSON code described in NODEFLOW_GR-PEACH.txt and click Import /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen32.png
  3. Watson IoT Application Node Flow should be configured
    • Double-click input node and link them to your Watson IoT instance. /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen33.png
    • Click on the edit button /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen34.png
    • First enter arbitrary name. Then, Watson API Key and Watson Auth Token previously acquired. Finally, press Add to save /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen35.png
    • Enter MBED_ENDPOINT_NAME in security.h as Device ID. Then, press Done to save /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen36.png
    • Double-click output node /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen37.png
    • Edit API Key and Device Id in the same manner as that for input node
    • Click LED OFF and LED ON node and replace MBED_ENDPOINT_NAME_GOES_HERE with MBED_ENDPOINT_NAME as shown below: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen38.png
    • Click Deproy to deploy NodeRED application /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen39.png
  4. Invoke sample program
    • Press the reset button on GR-PEACH
    • The decode result of barcode data should be shown in debug window /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen40_1.png
    • Also, you can toggle LED by clicking Turn LED OFF and Turn LED ON injection node /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen40_2.png
Revision:
0:ad834d403a8c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-endpoint-resources/ZXingResource.h	Thu Nov 24 13:59:16 2016 +0900
@@ -0,0 +1,512 @@
+/**
+ * @file    ZXingResource.h
+ * @brief   mbed CoAP Endpoint Accelerometer sensor resource supporting CoAP GET
+ * @author  Doug Anson
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ZXING_RESOURCE_H__
+#define __ZXING_RESOURCE_H__
+
+// Base class
+#include "mbed-connector-interface/DynamicResource.h"
+
+#include "DisplayBace.h"
+#include "ImageReaderSource.h"
+#include "DisplayApp.h"
+#include "AsciiFont.h"
+
+// forward declarations
+static void *_instance = NULL;
+extern "C" void _zxing_processing(const void *args);
+extern "C" void _zxing_loop(void);
+
+#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
+/*****************************/
+
+#if LCD_ONOFF
+/** LCD shield config **/
+#if (LCD_TYPE == 0)
+  #include "LCD_shield_config_4_3inch.h"
+#else
+  #include "LCD_shield_config_7_1inch.h"
+#endif
+#endif
+
+/** Video and Grapics (GRAPHICS_LAYER_0) parameter **/
+/* video input */
+#if USE_VIDEO_CH == (0)
+  #define VIDEO_INPUT_CH       (DisplayBase::VIDEO_INPUT_CHANNEL_0)
+  #define VIDEO_INT_TYPE       (DisplayBase::INT_TYPE_S0_VFIELD)
+#else
+  #define VIDEO_INPUT_CH       (DisplayBase::VIDEO_INPUT_CHANNEL_1)
+  #define VIDEO_INT_TYPE       (DisplayBase::INT_TYPE_S1_VFIELD)
+#endif
+
+/* NTSC or PAL */
+#if VIDEO_PAL == 0
+  #define COL_SYS              (DisplayBase::COL_SYS_NTSC_358)
+#else
+  #define COL_SYS              (DisplayBase::COL_SYS_PAL_443)
+#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)
+
+/* 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
+#else
+  #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
+
+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 volatile int32_t vfield_count = 0;
+static int write_buff_num = 0;
+static bool graphics_init_end = false;
+static int decode_wait_time = 0;
+
+vector<Ref<Result> > results;
+char ** decode_str;
+
+/****** 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 void Init_LCD_Display(void) {
+    DisplayBase::graphics_error_t error;
+    DisplayBase::lcd_config_t lcd_config;
+    PinName lvds_pin[8] = {
+        /* data pin */
+        P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0
+    };
+
+    lcd_pwon = 0;
+    lcd_blon = 0;
+    Thread::wait(100);
+    lcd_pwon = 1;
+    lcd_blon = 1;
+
+    Display.Graphics_Lvds_Port_Init(lvds_pin, 8);
+
+    /* Graphics initialization process */
+    lcd_config = LcdCfgTbl_LCD_shield;
+    error = Display.Graphics_init(&lcd_config);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+    graphics_init_end = true;
+}
+
+static void Start_LCD_Display(uint8_t * p_buf) {
+    DisplayBase::rect_t rect;
+
+    rect.vs = 0;
+    rect.vw = VIDEO_PIXEL_VW;
+    rect.hs = 0;
+    rect.hw = VIDEO_PIXEL_HW;
+    Display.Graphics_Read_Setting(
+        DisplayBase::GRAPHICS_LAYER_0,
+        (void *)p_buf,
+        FRAME_BUFFER_STRIDE,
+        GRAPHICS_FORMAT,
+        WR_RD_WRSWA,
+        &rect
+    );
+    Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
+}
+#endif
+
+/****** Video ******/
+static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
+    /* Interrupt callback function for Vfield interruption */
+    if (vfield_count > 0) {
+        vfield_count--;
+    }
+}
+
+static void Wait_Vfield(const int32_t wait_count) {
+    /* Wait for the specified number of times Vsync occurs */
+    vfield_count = wait_count;
+    while (vfield_count > 0) {
+        Thread::wait(1);
+    }
+}
+
+static void Init_Video(void) {
+    DisplayBase::graphics_error_t error;
+
+    /* Graphics initialization process */
+    if (graphics_init_end == false) {
+        /* When not initializing LCD, this processing is needed. */
+        error = Display.Graphics_init(NULL);
+        if (error != DisplayBase::GRAPHICS_OK) {
+            printf("Line %d, error %d\n", __LINE__, error);
+            mbed_die();
+        }
+        graphics_init_end = true;
+    }
+
+#if VIDEO_INPUT_METHOD == VIDEO_CVBS
+    error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL);
+    if( error != DisplayBase::GRAPHICS_OK ) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+#elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
+    DisplayBase::video_ext_in_config_t ext_in_config;
+    PinName cmos_camera_pin[11] = {
+        /* data pin */
+        P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0,
+        /* control pin */
+        P10_0,      /* DV0_CLK   */
+        P1_0,       /* DV0_Vsync */
+        P1_1        /* DV0_Hsync */
+    };
+
+    /* MT9V111 camera input config */
+    ext_in_config.inp_format     = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */
+    ext_in_config.inp_pxd_edge   = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing data          */
+    ext_in_config.inp_vs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Vsync signals */
+    ext_in_config.inp_hs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Hsync signals */
+    ext_in_config.inp_endian_on  = DisplayBase::OFF;                      /* External input bit endian change on/off       */
+    ext_in_config.inp_swap_on    = DisplayBase::OFF;                      /* External input B/R signal swap on/off         */
+    ext_in_config.inp_vs_inv     = DisplayBase::SIG_POL_NOT_INVERTED;     /* External input DV_VSYNC inversion control     */
+    ext_in_config.inp_hs_inv     = DisplayBase::SIG_POL_INVERTED;         /* External input DV_HSYNC inversion control     */
+    ext_in_config.inp_f525_625   = DisplayBase::EXTIN_LINE_525;           /* Number of lines for BT.656 external input */
+    ext_in_config.inp_h_pos      = DisplayBase::EXTIN_H_POS_CRYCBY;       /* Y/Cb/Y/Cr data string start timing to Hsync reference */
+    ext_in_config.cap_vs_pos     = 6;                                     /* Capture start position from Vsync */
+    ext_in_config.cap_hs_pos     = 150;                                   /* Capture start position form Hsync */
+#if ((LCD_ONOFF) && (LCD_TYPE == 0))
+    /* The same screen ratio as the screen ratio of the LCD. */
+    ext_in_config.cap_width      = 640;                                   /* Capture width */
+    ext_in_config.cap_height     = 363;                                   /* Capture height Max 468[line]
+                                                                             Due to CMOS(MT9V111) output signal timing and VDC5 specification */
+#else
+    ext_in_config.cap_width      = 640;                                   /* Capture width */
+    ext_in_config.cap_height     = 468;                                   /* Capture height Max 468[line]
+                                                                             Due to CMOS(MT9V111) output signal timing and VDC5 specification */
+#endif
+    error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config);
+    if( error != DisplayBase::GRAPHICS_OK ) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Camera input port setting */
+    error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11);
+    if( error != DisplayBase::GRAPHICS_OK ) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+#endif
+
+    /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
+    error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+}
+
+static void Start_Video(uint8_t * p_buf) {
+    DisplayBase::graphics_error_t error;
+
+    /* Video capture setting (progressive form fixed) */
+    error = Display.Video_Write_Setting(
+                VIDEO_INPUT_CH,
+                COL_SYS,
+                p_buf,
+                FRAME_BUFFER_STRIDE,
+                VIDEO_FORMAT,
+                WR_RD_WRSWA,
+                VIDEO_PIXEL_VW,
+                VIDEO_PIXEL_HW
+            );
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Video write process start */
+    error = Display.Video_Start(VIDEO_INPUT_CH);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Video write process stop */
+    error = Display.Video_Stop(VIDEO_INPUT_CH);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Video write process start */
+    error = Display.Video_Start(VIDEO_INPUT_CH);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+}
+
+/** 
+ * ZXingResource class
+ */
+class ZXingResource : public DynamicResource
+{
+private:
+    Thread * m_zxing_processor;
+    
+public:
+    /**
+    Default constructor
+    @param logger input logger instance for this resource
+    @param obj_name input the Accelerometer Object name
+    @param res_name input the Accelerometer Resource name
+    @param observable input the resource is Observable (default: FALSE)
+    */
+
+    ZXingResource(const Logger *logger,const char *obj_name,const char *res_name,const bool observable = false) : DynamicResource(logger,obj_name,res_name,"ZXing",M2MBase::GET_ALLOWED,observable) {
+        // init
+        _instance = (void *)this;
+
+#if LCD_ONOFF
+        // Initialze LCD
+        Init_LCD_Display();
+#endif
+        // Initialize Video
+        Init_Video();
+
+        // Initialize frame buffer
+        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));
+        }
+        
+        // Start Video
+        Start_Video(FrameBufferTbl[write_buff_num]);
+        /* Wait for first video drawing */
+        Wait_Vfield(2);
+
+#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;
+        /* Start of LCD */
+        Start_LCD_Display(FrameBufferTbl[write_buff_num]);
+        /* Backlight on */
+        Thread::wait(200);
+        lcd_cntrst.write(1.0);
+#endif
+        decode_timer.reset();
+        decode_timer.start();
+
+        // no Thread yet
+        this->m_zxing_processor = NULL;
+    }
+
+    /**
+    Get the value of the barcode data
+    @returns string containing the acclerometer sensor value
+    */
+    virtual string get() {
+#if 1
+        if (this->m_zxing_processor == NULL) {
+            // create the processing thread
+            this->m_zxing_processor = new Thread(_zxing_processing);
+        }  
+                        
+        if (*decode_str == NULL) {
+            return string("0\0");
+        } else {
+            return string(*decode_str);
+        }
+        
+#endif
+    }
+};
+
+void _zxing_processing(const void *args) {
+    while (true) {
+        _zxing_loop();
+        Thread::wait(5);
+    }
+}
+
+void _zxing_loop(void) {
+    DisplayBase::graphics_error_t error;
+    int decode_result = -1;
+     
+#if 1
+        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));
+        /* 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);
+            if (decode_result == 0) {
+                decode_str = (char **)&(results[0]->getText()->getText());
+                
+                if (_instance != NULL) {
+                    // observe...
+                    ((ZXingResource *)_instance)->observe();
+                }
+
+#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;
+            }
+        }
+        display_app.SendRgb888(decode_buffer, VIDEO_PIXEL_HW, VIDEO_PIXEL_VW);
+#endif
+}
+#endif // __ZXING_RESOURCE_H__