小凌派手势+oled演示
1.前言:
接上篇,当手势传感器案例可以运行之后,我们就可以想办法更好玩一些了,想要好玩一些的话当然就是上屏幕啦.
2.oled驱动
官方demo里面其实有oled的测试用例,只要准备一块ssd1306的屏幕就行了,对于我一个老鸿蒙来说当然不缺了,立马就找出来一个oled模组出来.
官方的demo在这里:vendor/lockzhiner/rk2206/samples/b5_oled
只要在BUILD.gn和Makefile里稍微改一下就能运行,但是运行之后发现这个刷新太慢了,一看代码原来没有用缓存的方式.
然后就找来之前玩润和板子的代码,在这篇帖子里有介绍:
https://bbs.elecfans.com/jishu_2008577_1_1.html
这篇帖子里介绍的方式就用的是缓存,简单来说就是事先把点阵信息用一个大数组存起来,然后刷新的时候只改数据里面的内容,最后再update更新一下所有的点阵数据就行.
不过原来那套代码里用的是润和的i2c接口,现在要改成小凌派的方式:
- static uint32_t ssd1306_SendData(uint8_t* data, size_t size)
- {
- uint32_t ret = LzI2cWrite(OLED_I2C_BUS, OLED_I2C_ADDRESS, data, size);
- if (ret != 0)
- {
- printf("%s, %s, %d: LzI2cWrite failed(%d)!n", __FILE__, __func__, __LINE__, ret);
- }
- return ret;
- }
- static uint32_t ssd1306_WiteByte(uint8_t regAddr, uint8_t byte)
- {
- uint8_t buffer[] = {regAddr, byte};
- uint32_t ret = LzI2cWrite(OLED_I2C_BUS, OLED_I2C_ADDRESS, buffer, 2);
- if (ret != 0)
- {
- printf("%s, %s, %d: LzI2cWrite failed(%d)!n", __FILE__, __func__, __LINE__, ret);
- }
- return ret;
- }
- // Send a byte to the command register
- void ssd1306_WriteCommand(uint8_t byte) {
- ssd1306_WiteByte(SSD1306_CTRL_CMD, byte);
- }
- // Send data
- void ssd1306_WriteData(uint8_t* buffer, size_t buff_size) {
- uint8_t data[SSD1306_WIDTH * 2] = {0};
- for (size_t i = 0; i < buff_size; i++) {
- data[i*2] = SSD1306_CTRL_DATA | SSD1306_MASK_CONT;
- data[i*2+1] = buffer[i];
- }
- data[(buff_size - 1) * 2] = SSD1306_CTRL_DATA;
- ssd1306_SendData(data, sizeof(data));
- }
复制代码
3.oled显示
然后把显示线程配置好就可以显示了:
- //oled show and update
- static void *OLedTask(const char *arg)
- {
- (void)arg;
- uint32_t ret=0;
- ssd1306_Init();
- printf("OLedTask queueId=%dn",queueId);
- int text_area_width = 64;
- int text_area_height = 64;
- int text_per_line_num = text_area_height / font_width;
- int mod = hope_num % text_per_line_num;
- int text_line_num = hope_num / text_per_line_num;
- if (mod)
- {
- text_line_num += 1;
- }
- printf("title_addr=%p,dir_addr=%pn", title_arr,dir_arr);
- int text_alredy_show = 0;
- int x = 0;
- int y = 0;
- ssd1306_Fill(Black);
- ssd1306_SetCursor(0, 0);
- printf("hope_num =%dn", hope_num);
- // int start_num = text_alredy_show * text_per_line_num;
- int showed_num = 0;
- for (int i = text_alredy_show; i < 14; i++)
- {
- printf("&title[i]=%pn",&title_arr[i]);
- ssd1306_DrawRegion(x, y, font_height, font_width, title_arr[i], sizeof(title_arr[0]), 0);
- x += font_width;
- if (x >= text_area_width)
- {
- y += font_height;
- x = 0;
- }
- showed_num++;
- if (y >= text_area_height)
- {
- break;
- }
- }
- ssd1306_DrawRegion(64, 0, 64, 64, picture_arr, sizeof(picture_arr), 0);
- ssd1306_UpdateScreen();
- while (1)
- {
- uint32_t flag = 0;
- uint32_t rLen =4;
- printf(">>>>>>queueId=%dn",queueId);
- ret = LOS_QueueReadCopy(queueId,
- &flag,
- &rLen,
- LOS_WAIT_FOREVER);
- // LOS_Msleep(OLED_INTERVAL_TIME_US);
- printf("READ ret = %d,FLAG =%02xn",ret,flag);
-
- int idx=0;
- for(;idx<9;idx++){
- if(flag&(1<
- break;
- }
- }
- printf("x=%d,y=%d,idx=%d,titlearr=%dn",x, y,idx,sizeof(dir_arr[0]));
- // LOS_Msleep(OLED_INTERVAL_TIME_US*5);
- ssd1306_DrawRegion(x, y, font_height, font_width, dir_arr[idx], sizeof(dir_arr[0]), 0);
- ssd1306_UpdateScreen();
- }
- return NULL;
- }
复制代码
本来以为能顺顺利利的显示出图形并接收手势传感器发过来的手势信息,结果系统在第一次启动的时候的确能收到手势信息,但是过了一会再打手势会导致内核重新启动,日志如下图:
然后就从早上9点多一直调到晚上8点多,然而还是没有解决,意识到这个问题不简单,就发到群里去了.还拜托@乔楚 乔帮主帮忙找问题,害得乔帮主烧掉一块屏幕.
感谢技术@王小彬,今天顺利的解决问题,原来是内核的问题,下午告诉我解决,晚上回到家立马测试,一看果然好使.
4.手势数据发送
关于手势发送的地方在主线程:
- void e53_gs_process(void *arg)
- {
- unsigned int ret = 0;
- unsigned short flag = 0;
-
- e53_gs_init();
-
- while (1)
- {
- ret = e53_gs_get_gesture_state(&flag);
- if (ret != 0)
- {
- printf(">>Get Gesture Statu: 0x%xn", flag);
- if (flag & GES_UP)
- {
- printf("tUpn");
- }
- if (flag & GES_DOWM)
- {
- printf("tDownn");
- }
- if (flag & GES_LEFT)
- {
- printf("tLeftn");
- }
- if (flag & GES_RIGHT)
- {
- printf("tRightn");
- }
- if (flag & GES_FORWARD)
- {
- printf("tForwardn");
- }
- if (flag & GES_BACKWARD)
- {
- printf("tBackwardn");
- }
- if (flag & GES_CLOCKWISE)
- {
- printf("tClockwisen");
- }
- if (flag & GES_COUNT_CLOCKWISE)
- {
- printf("tCount Clockwisen");
- }
- if (flag & GES_WAVE)
- {
- printf("tWaven");
- }
-
- e53_gs_led_up_set((flag & GES_UP) ? (1) : (0));
- e53_gs_led_down_set((flag & GES_DOWM) ? (1) : (0));
- e53_gs_led_left_set((flag & GES_LEFT) ? (1) : (0));
- e53_gs_led_right_set((flag & GES_RIGHT) ? (1) : (0));
- e53_gs_led_forward_set((flag & GES_FORWARD) ? (1) : (0));
- e53_gs_led_backward_set((flag & GES_BACKWARD) ? (1) : (0));
- e53_gs_led_cw_set((flag & GES_CLOCKWISE) ? (1) : (0));
- e53_gs_led_ccw_set((flag & GES_COUNT_CLOCKWISE) ? (1) : (0));
- e53_gs_led_wave_set((flag & GES_WAVE) ? (1) : (0));
- ret = LOS_QueueWriteCopy(queueId,&flag,4, 0);
- printf("queue write ret = %dn",ret);
- }
- else
- {
- /* 如果没有数据,则多等待 */
- LOS_Msleep(100);
- }
- }
- }
复制代码
5.最终效果
最终效果如上面视频,可以看出对于上下左右的效果很容易测试出来,但是顺时针,逆时针,远,近相对比较难测出来,挥手效果更是难以测试出来,不过好在模块性能够好,最终还是出现了挥手的效果.
6.总结
本次调试板子的过程,不算太顺利,好在及时的解决了,再次给小凌派研发团队点赞.
后期准备制作菜单模块,利用手势拨动菜单项.
1
|
|
|
|