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.
- Datasheet of Si1143
http://www.silabs.com/Support%20Documents/TechnicalDocs/Si114x.pdf
Composition
GR-PEACH, LCD Shield and two gesture sensors(Si1143).
About wiring
First Sensor
| Sensor | GR-PEACH |
| VDD | 3.3V |
| SCL | D15 |
| SDA | D14 |
| GND | GND |
Second Sensor
| Sensor | GR-PEACH |
| VDD | 3.3V |
| SCL | P1_6 |
| SDA | P1_7 |
| GND | GND |
How to use
- Please connect GR-PEACH ,LCD Shield and two jesture sensors. Then turn on the power to GR-PEACH.
- Please press the reset button of GR-PEACH.
- The screen which "Program Setting" is drawn is displayed on the LCD.
- When the sensor of the setting is completed, the screen which "Program Started!!" is drawn is displayed on the LCD.
- 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 on | Draw |
the upper of LED1 of the first sensor![]() | red rectangle![]() |
the upper of LED2 of the first sensor![]() | green rectangle![]() |
the upper of LED3 of the first sensor![]() | blue rectangle![]() |
the upper of LED1 of the second sensor![]() | yellow rectangle![]() |
the upper of LED2 of the second sensor![]() | light blue rectangle![]() |
the upper of LED3 of the second sensor![]() | pink rectangle![]() |
概要
これは2つのジェスチャーセンサーを使ったサンプルプログラムです。
このプログラムは、センサーに応じて四角形の画像をLCDシールドの画面上に表示します。
Si1143について
Si1143はジェスチャーセンサであり、I2C通信を使ってセンサを制御します。
センサとの距離範囲は1cm200cmです。
Si1143は、基板上に搭載された3つの赤外線LEDを放射し、物体からの反射光を測定することによって、動きを検出します。
構成
GR-PEACH, LCD Shield and two gesture sensors(Si1143).
ジェスチャーセンサとGR-PEACHの接続
1つ目のSensor
| Sensor | GR-PEACH |
| VDD | 3.3V |
| SCL | D15 |
| SDA | D14 |
| GND | GND |
2つ目のSensor
| Sensor | GR-PEACH |
| VDD | 3.3V |
| SCL | P1_6 |
| SDA | P1_7 |
| GND | GND |
使い方
- GR-PEACHとLCDシールドを接続し、GR-PEACHに電源を入れます。
- GR-PEACHのリセットボタンを押します。
- "Program Setting"という画面がLCDに表示されます。
- センサのセットアップが終わると、"Program Start!!"という画面がLCDに表示されます。
- 2つのジェスチャーセンサのLED1~LED3に手をかざすと、6種類の四角形がLCD上に描画されます。
| 手をかざす場所 | 描画 |
1つ目のセンサのLED1の上![]() | 赤色の四角形![]() |
1つ目のセンサのLED2の上![]() | 緑色の四角形![]() |
1つ目のセンサのLED3の上![]() | 青色の四角形![]() |
2つ目のセンサのLED1の上![]() | 黄色の四角形![]() |
2つ目のセンサのLED2の上![]() | 水色の四角形![]() |
2つ目のセンサのLED3の上![]() | ピンク色の四角形![]() |
main.cpp
- Committer:
- 1050186
- Date:
- 2016-05-31
- Revision:
- 0:7e5105dee0cb
File content as of revision 0:7e5105dee0cb:
#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);
}
}
}








