This is a sample program that uses two Si1143 sensors.

Dependencies:   GR-PEACH_video SI1143 mbed-rtos mbed

Information

Japanese version is available in lower part of this page.

このページの後半に日本語版が用意されています.

What is this ?

This is a sample program that uses two gesture sensors.
This program displays image of rectangle on the screen of the LCD shield depending on the sensors.

About Si1143

Si1143 is a gesture sensor and can be controlled by using the I2C.
This can be detected from the shortest 1cm up to 200cm.
Si1143 emits three infrared LED that is mounted on a substrate, and detects the movement by measuring the reflected light from the external object.

Composition

GR-PEACH, LCD Shield and two gesture sensors(Si1143).

About wiring

First Sensor

SensorGR-PEACH
VDD3.3V
SCLD15
SDAD14
GNDGND

Second Sensor

SensorGR-PEACH
VDD3.3V
SCLP1_6
SDAP1_7
GNDGND


How to use

  1. Please connect GR-PEACH ,LCD Shield and two jesture sensors. Then turn on the power to GR-PEACH.
  2. Please press the reset button of GR-PEACH.
  3. The screen which "Program Setting" is drawn is displayed on the LCD.
  4. When the sensor of the setting is completed, the screen which "Program Started!!" is drawn is displayed on the LCD.
  5. When you hold your hand on the upper of LED1 - LED3 of the two jesture sensors, six rectangles is drawn on the screen of LCD Shield.
hand onDraw
the upper of LED1 of the first sensor
/media/uploads/1050186/jesturesensor_handsonled1.png
red rectangle
/media/uploads/1050186/red_rectangle.png
the upper of LED2 of the first sensor
/media/uploads/1050186/jesturesensor_handsonled2.png
green rectangle
/media/uploads/1050186/green_rectangle.png
the upper of LED3 of the first sensor
/media/uploads/1050186/jesturesensor_handsonled3.png
blue rectangle
/media/uploads/1050186/blue_rectangle.png
the upper of LED1 of the second sensor
/media/uploads/1050186/jesturesensor_handsonled1.png
yellow rectangle
/media/uploads/1050186/yellow_rectangle.png
the upper of LED2 of the second sensor
/media/uploads/1050186/jesturesensor_handsonled2.png
light blue rectangle
/media/uploads/1050186/lightblue_rectangle.png
the upper of LED3 of the second sensor
/media/uploads/1050186/jesturesensor_handsonled3.png
pink rectangle
/media/uploads/1050186/pink_rectangle.png




概要

これは2つのジェスチャーセンサーを使ったサンプルプログラムです。
このプログラムは、センサーに応じて四角形の画像をLCDシールドの画面上に表示します。

Si1143について

Si1143はジェスチャーセンサであり、I2C通信を使ってセンサを制御します。
センサとの距離範囲は1cm200cmです。
Si1143は、基板上に搭載された3つの赤外線LEDを放射し、物体からの反射光を測定することによって、動きを検出します。

構成

GR-PEACH, LCD Shield and two gesture sensors(Si1143).

ジェスチャーセンサとGR-PEACHの接続

1つ目のSensor

SensorGR-PEACH
VDD3.3V
SCLD15
SDAD14
GNDGND

2つ目のSensor

SensorGR-PEACH
VDD3.3V
SCLP1_6
SDAP1_7
GNDGND


使い方

  1. GR-PEACHとLCDシールドを接続し、GR-PEACHに電源を入れます。
  2. GR-PEACHのリセットボタンを押します。
  3. "Program Setting"という画面がLCDに表示されます。
  4. センサのセットアップが終わると、"Program Start!!"という画面がLCDに表示されます。
  5. 2つのジェスチャーセンサのLED1~LED3に手をかざすと、6種類の四角形がLCD上に描画されます。
手をかざす場所描画
1つ目のセンサのLED1の上
/media/uploads/1050186/jesturesensor_handsonled1.png
赤色の四角形
/media/uploads/1050186/red_rectangle.png
1つ目のセンサのLED2の上
/media/uploads/1050186/jesturesensor_handsonled2.png
緑色の四角形
/media/uploads/1050186/green_rectangle.png
1つ目のセンサのLED3の上
/media/uploads/1050186/jesturesensor_handsonled3.png
青色の四角形
/media/uploads/1050186/blue_rectangle.png
2つ目のセンサのLED1の上
/media/uploads/1050186/jesturesensor_handsonled1.png
黄色の四角形
/media/uploads/1050186/yellow_rectangle.png
2つ目のセンサのLED2の上
/media/uploads/1050186/jesturesensor_handsonled2.png
水色の四角形
/media/uploads/1050186/lightblue_rectangle.png
2つ目のセンサのLED3の上
/media/uploads/1050186/jesturesensor_handsonled3.png
ピンク色の四角形
/media/uploads/1050186/pink_rectangle.png



main.cpp

Committer:
1050186
Date:
2016-05-31
Revision:
1:8eddef24a632
Parent:
0:7e5105dee0cb

File content as of revision 1:8eddef24a632:

#include "mbed.h"
#include "DisplayBace.h"
#include "rtos.h"
#include "SI1143.h"
#include "image_data.h"

/**** LCD Parameter **********/
#define LCD_DE_MODE            (0)
#define LCD_SYNC_MODE          (1)

#define LCD_DOT_CLOCK          (13.40f)            // 13.4MHz

#define LCD_H_WIDTH            (480u)
#define LCD_H_BACK_PORCH       (43u)
#define LCD_H_FRONT_PORCH      (52u)
#define LCD_H_SYNC_WIDTH       (41u)

#define LCD_V_WIDTH            (272u)
#define LCD_V_BACK_PORCH       (12u)
#define LCD_V_FRONT_PORCH      (2u)
#define LCD_V_SYNC_WIDTH       (10u)

#define LCD_MODE               (LCD_SYNC_MODE)

/*****************************/


#define FRAME_BUFFER_BYTE_PER_PIXEL      (2u)
#define VIDEO_BUFFER_STRIDE    (((LCD_H_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
#define VIDEO_BUFFER_HEIGHT    (LCD_V_WIDTH)

#define IMG_RGB565             (0)
#define IMG_ARGB1555           (2)
#define IMG_ARGB4444           (3)
#define IMG_CLUT8              (6)
#define IMG_CLUT4              (7)
#define IMG_CLUT1              (8)
#define IMG_XRGB8888           (9)
#define IMG_ARGB8888           (10)
#define IMG_YUV422             (11)

enum {
    IMG_SETTING,
    IMG_START,
    IMG_RED,
    IMG_GREEN,
    IMG_BLUE,
    IMG_YELLOW,
    IMG_LIGHTBLUE,
    IMG_PINK,
    IMG_WHITE
};

enum {
    SENSE1_NON,
    SENSE1_1,
    SENSE1_2,
    SENSE1_3
};

enum {
    SENSE2_NON,
    SENSE2_1,
    SENSE2_2,
    SENSE2_3
};

DigitalOut lcd_pwon(P7_15);
DigitalOut lcd_blon(P8_1);
PwmOut     lcd_cntrst(P8_15);
SI1143     sensor1(I2C_SDA, I2C_SCL);
SI1143     sensor2(P1_7, P1_6);

typedef struct {
    uint32_t    dummy1;
    uint32_t    offset_to_image;
    uint32_t    dummy2;
    uint16_t    width;
    uint16_t    height;
    uint8_t     type;
    uint8_t     dummy3;
    uint32_t    dummy4;
} graphics_image_t;

typedef struct {
    const graphics_image_t* image;
    uint32_t pos_x;
    uint32_t pos_y;
} draw_info_t;

typedef struct {
    draw_info_t curr;
    draw_info_t last;
} image_draw_t;

static const graphics_image_t* image_file[9] = {
    g_setting, g_start, g_red, g_gren, g_blue, g_yellow, g_lightblue, g_pink, g_white
};

static uint8_t user_frame_buffer[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));  //32 bytes aligned!;
static uint8_t user_frame_buffer2[VIDEO_BUFFER_STRIDE * VIDEO_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));  //32 bytes aligned!;
static volatile int32_t vsync_count;
static uint8_t* disp_buff_addr;
static int sense1[3] = {0, 0, 0};
static int sense2[3] = {0, 0, 0};
static image_draw_t img1_info;
static image_draw_t img2_info;

static void IntCallbackFunc_Vsync(DisplayBase::int_type_t int_type)
{
    //Interrupt callback function for Vsync interruption
    if (vsync_count > 0) {
        vsync_count--;
    }
}

static void Wait_Vsync(const int32_t wait_count)
{
    //Wait for the specified number of times Vsync occurs
    vsync_count = wait_count;
    while (vsync_count > 0) {
        /* Do nothing */
    }
}

static void Clr_FrameBuffer(uint8_t frmbuf_num) {
    int vcnt, wcnt;
    uint16_t * fb_base;
    uint16_t * fb_pos;

    if ((frmbuf_num & 0x01) != 0) {
        fb_base = (uint16_t *)user_frame_buffer;
        for (vcnt = 0; vcnt < LCD_V_WIDTH; vcnt++) {
            fb_pos = fb_base + (vcnt * LCD_H_WIDTH);
            for (wcnt = 0; wcnt < LCD_H_WIDTH; wcnt++) {
                fb_pos[wcnt] = 0xFFFF;
            }
        }
    }
    if ((frmbuf_num & 0x02) != 0) {
        fb_base = (uint16_t *)user_frame_buffer2;
        for (vcnt = 0; vcnt < LCD_V_WIDTH; vcnt++) {
            fb_pos = fb_base + (vcnt * LCD_H_WIDTH);
            for (wcnt = 0; wcnt < LCD_H_WIDTH; wcnt++) {
                fb_pos[wcnt] = 0xFFFF;
            }
        }
    }
}

static void Draw_Image(void * dst_buff, uint32_t dst_stride, const graphics_image_t * src_image, uint32_t pos_x, uint32_t pos_y) {
    uint32_t    offset_to_image;
    uint16_t    width;
    uint16_t    height;
    uint8_t     type;
    uint16_t  * pSrc16;
    uint32_t  * pSrc32;
    uint16_t  * pDst16;
    uint32_t  * pDst32;
    uint32_t    x,y;

    if (src_image != NULL) {
        offset_to_image   = src_image->offset_to_image;
        width             = src_image->width;
        height            = src_image->height;
        type              = src_image->type;

        if (type == IMG_ARGB4444) {
            pDst16 = (uint16_t *)dst_buff;
            pSrc16 = (uint16_t *)((uint8_t *)src_image +  offset_to_image );

            for (y = 0; y < height; y++) {
                for (x = 0; x < width; x++) {
                    if ((pSrc16[(y * width) + x] & 0xf000) != 0) {
                        /* Copy the pixel value if its alpha value is not 0 */
                        pDst16[((y + pos_y) * dst_stride / 2) + (x + pos_x)] = pSrc16[(y * width) + x];
                    }
                }
            }
        } else if (type == IMG_ARGB8888) {
            pDst32 = (uint32_t *)dst_buff;
            pSrc32 = (uint32_t *)((uint8_t *)src_image + offset_to_image);

            for (y = 0; y < height; y++) {
                for (x = 0; x < width; x++) {
                    if ((pSrc32[(y * width) + x] & 0xff000000) != 0) {
                        /* Copy the pixel value if its alpha value is not 0 */
                        pDst32[((y + pos_y) * dst_stride / 4) + (x + pos_x)] = pSrc32[(y * width) + x];
                    }
                }
            }
        } else if (type == IMG_RGB565) {
            pDst16 = (uint16_t *)dst_buff;
            pSrc16 = (uint16_t *)((uint8_t *)src_image + offset_to_image);

            for (y = 0; y < height; y++) {
                for (x = 0; x < width; x++) {
                    pDst16[((y + pos_y) * dst_stride / 2) + (x + pos_x)] = pSrc16[(y * width) + x];
                }
            }
        }
    }
}

static int Get_Sensor1(void) {
    int sense_num = SENSE1_NON;

    // Read each led sensor
    sense1[0] = sensor1.get_ps1(5);
    sense1[1] = sensor1.get_ps2(5);
    sense1[2] = sensor1.get_ps3(5);

    if (sense1[0] > 500 || sense1[1] > 500 || sense1[2] > 500) {
        if (sense1[0] > sense1[1] && sense1[0] > sense1[2]) {
            sense_num = SENSE1_1;
        } else if (sense1[1] > sense1[0] && sense1[1] > sense1[2]) {
            sense_num = SENSE1_2;
        } else if (sense1[2] > sense1[0] && sense1[2] > sense1[1]) {
            sense_num = SENSE1_3;
        }
    }

    return sense_num;
}

static int Get_Sensor2(void) {
    int sense_num = SENSE2_NON;

    // Read each led sensor
    sense2[0] = sensor2.get_ps1(5);
    sense2[1] = sensor2.get_ps2(5);
    sense2[2] = sensor2.get_ps3(5);

    if (sense2[0] > 500 || sense2[1] > 500 || sense2[2] > 500) {
        if (sense2[0] > sense2[1] && sense2[0] > sense2[2]) {
            sense_num = SENSE2_1;
        } else if (sense2[1] > sense2[0] && sense2[1] > sense2[2]) {
            sense_num = SENSE2_2;
        } else if (sense2[2] > sense2[0] && sense2[2] > sense2[1]) {
            sense_num = SENSE2_3;
        }
    }

    return sense_num;
}

static void Swap_FrameBuffer(void) {
    if (disp_buff_addr == user_frame_buffer) {
        disp_buff_addr = user_frame_buffer2;
        Clr_FrameBuffer(0x02);
    } else {
        disp_buff_addr = user_frame_buffer;
        Clr_FrameBuffer(0x01);
    }
}

int main(void)
{
    /* Create DisplayBase object */
    DisplayBase Display;
    DisplayBase::graphics_error_t error;
    DisplayBase::lcd_config_t lcd_config;
    disp_buff_addr = user_frame_buffer;
    int sense1 = SENSE1_NON;
    int sense2 = SENSE2_NON;
    img1_info.curr.image = image_file[IMG_START];
    img1_info.curr.pos_x = 0;
    img1_info.curr.pos_y = 0;
    img1_info.last.image = image_file[IMG_WHITE];
    img1_info.last.pos_x = 0;
    img1_info.last.pos_y = 0;
    img2_info.curr.image = image_file[IMG_START];
    img2_info.curr.pos_x = 0;
    img2_info.curr.pos_y = 0;
    img2_info.last.image = image_file[IMG_WHITE];
    img2_info.last.pos_x = 240;
    img2_info.last.pos_y = 0;

    lcd_pwon = 0;
    lcd_blon = 0;
    Thread::wait(100);
    lcd_pwon = 1;
    lcd_blon = 1;
    Thread::wait(100);

    // Setup display
    vsync_count = 0;
    PinName lvds_pin[8] = {
        /* data pin */
        P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0
    };
    DisplayBase::rect_t rect;

    lcd_config.lcd_type             = DisplayBase::LCD_TYPE_LVDS;
    lcd_config.intputClock          = 66.67f;
    lcd_config.outputClock          = LCD_DOT_CLOCK;
    lcd_config.lcd_outformat        = DisplayBase::LCD_OUTFORMAT_RGB888;
    lcd_config.lcd_edge             = DisplayBase::EDGE_RISING;
#if(LCD_MODE) //SYNC Mode
    lcd_config.h_toatal_period      = (LCD_H_BACK_PORCH + LCD_H_WIDTH + LCD_H_FRONT_PORCH);
    lcd_config.v_toatal_period      = (LCD_V_BACK_PORCH + LCD_V_WIDTH + LCD_V_FRONT_PORCH);
 
    lcd_config.h_disp_widht         = (LCD_H_WIDTH);
    lcd_config.v_disp_widht         = (LCD_V_WIDTH);
    lcd_config.h_back_porch         = (LCD_H_BACK_PORCH);
    lcd_config.v_back_porch         = (LCD_V_BACK_PORCH);
 
    lcd_config.h_sync_port          = DisplayBase::LCD_TCON_PIN_2;
    lcd_config.h_sync_port_polarity = DisplayBase::SIG_POL_INVERTED;
    lcd_config.h_sync_width         = LCD_H_SYNC_WIDTH;
 
    lcd_config.v_sync_port          = DisplayBase::LCD_TCON_PIN_0;
    lcd_config.v_sync_port_polarity = DisplayBase::SIG_POL_INVERTED;
    lcd_config.v_sync_width         = LCD_V_SYNC_WIDTH;
 
    lcd_config.de_port              = DisplayBase::LCD_TCON_PIN_3;
    lcd_config.de_port_polarity     = DisplayBase::SIG_POL_NOT_INVERTED;
#else  //DE Mode
    lcd_config.h_toatal_period      = (LCD_H_WIDTH + 80u);
    lcd_config.v_toatal_period      = (LCD_V_WIDTH);

    lcd_config.h_disp_widht         = (LCD_H_WIDTH);
    lcd_config.v_disp_widht         = (LCD_V_WIDTH);
    lcd_config.h_back_porch         = (68u);
    lcd_config.v_back_porch         = (18u);

    lcd_config.h_sync_port          = DisplayBase::LCD_TCON_PIN_NON;
    lcd_config.h_sync_port_polarity = DisplayBase::SIG_POL_NOT_INVERTED;
    lcd_config.h_sync_width         = 0;

    lcd_config.v_sync_port          = DisplayBase::LCD_TCON_PIN_NON;
    lcd_config.v_sync_port_polarity = DisplayBase::SIG_POL_NOT_INVERTED;
    lcd_config.v_sync_width         = 0;

    lcd_config.de_port              = DisplayBase::LCD_TCON_PIN_3;
    lcd_config.de_port_polarity     = DisplayBase::SIG_POL_INVERTED;
#endif

    /* Graphics initialization process */
    error = Display.Graphics_init(&lcd_config);
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        while (1);
    }

    /* Interrupt callback function setting (Vsync signal output from scaler 0) */
    error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_LO_VSYNC, 0, IntCallbackFunc_Vsync);
    if (error != DisplayBase::GRAPHICS_OK) {
        printf("Line %d, error %d\n", __LINE__, error);
        while (1);
    }

    Display.Graphics_Lvds_Port_Init(lvds_pin, 8);
    rect.vs = 0;
    rect.vw = LCD_V_WIDTH;
    rect.hs = 0;
    rect.hw = LCD_H_WIDTH;

    Display.Graphics_Read_Setting(
        DisplayBase::GRAPHICS_LAYER_0,
        (void *)disp_buff_addr,
        VIDEO_BUFFER_STRIDE,
        DisplayBase::GRAPHICS_FORMAT_RGB565,
        DisplayBase::WR_RD_WRSWA_32_16BIT,
        &rect
    );
    Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
    lcd_cntrst.write(1.0);

    // Setup the baseline
    Draw_Image(disp_buff_addr, VIDEO_BUFFER_STRIDE, image_file[IMG_SETTING], 0, 0);
    printf("SI1143 Gesture Sensor setting...\n");
    sensor1.bias(1,5);
    sensor2.bias(1,5);
    Thread::wait(1000);
    Draw_Image(disp_buff_addr, VIDEO_BUFFER_STRIDE, image_file[IMG_START], 0, 0);
    printf("SI1143 Gesture Sensor setting finished!\n");
    while (1) {
        sense1 = Get_Sensor1();
        switch (sense1) {
            case SENSE1_1 :
                img1_info.curr.image = image_file[IMG_RED];
                img1_info.curr.pos_x = 0;
                img1_info.curr.pos_y = 0;
                break;
            case SENSE1_2 :
                img1_info.curr.image = image_file[IMG_GREEN];
                img1_info.curr.pos_x = 80;
                img1_info.curr.pos_y = 0;
                break;
            case SENSE1_3 :
                img1_info.curr.image = image_file[IMG_BLUE];
                img1_info.curr.pos_x = 160;
                img1_info.curr.pos_y = 0;
                break;
            default :
                img1_info.curr.image = NULL;
                img1_info.curr.pos_x = 0;
                img1_info.curr.pos_y = 0;
                break;
        }
        sense2 = Get_Sensor2();
        switch (sense2) {
            case SENSE2_1 :
                img2_info.curr.image = image_file[IMG_YELLOW];
                img2_info.curr.pos_x = 240;
                img2_info.curr.pos_y = 0;
                break;
            case SENSE2_2 :
                img2_info.curr.image = image_file[IMG_LIGHTBLUE];
                img2_info.curr.pos_x = 320;
                img2_info.curr.pos_y = 0;
                break;
            case SENSE2_3 :
                img2_info.curr.image = image_file[IMG_PINK];
                img2_info.curr.pos_x = 400;
                img2_info.curr.pos_y = 0;
                break;
            default :
                img2_info.curr.image = NULL;
                img2_info.curr.pos_x = 0;
                img2_info.curr.pos_y = 0;
                break;
        }

        if ((sense1 != 0) || (sense2 != 0)) {
            /* Draw Image */
            Swap_FrameBuffer();
            if (sense1 != 0) {
                Draw_Image(disp_buff_addr, VIDEO_BUFFER_STRIDE, img1_info.curr.image, img1_info.curr.pos_x, img1_info.curr.pos_y);
                Draw_Image(disp_buff_addr, VIDEO_BUFFER_STRIDE, img2_info.last.image, img2_info.last.pos_x, img2_info.last.pos_y);
                img1_info.last.image = img1_info.curr.image;
                img1_info.last.pos_x = img1_info.curr.pos_x;
                img1_info.last.pos_y = img1_info.curr.pos_y;
            }
            if (sense2 != 0) {
                Draw_Image(disp_buff_addr, VIDEO_BUFFER_STRIDE, img1_info.last.image, img1_info.last.pos_x, img1_info.last.pos_y);
                Draw_Image(disp_buff_addr, VIDEO_BUFFER_STRIDE, img2_info.curr.image, img2_info.curr.pos_x, img2_info.curr.pos_y);
                img2_info.last.image = img2_info.curr.image;
                img2_info.last.pos_x = img2_info.curr.pos_x;
                img2_info.last.pos_y = img2_info.curr.pos_y;
            }
            Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0, (void *)disp_buff_addr);
            Wait_Vsync(1);
        }
    }
}