DFRobot专区
直播中

cszzlsw

9年用户 202经验值
擅长:嵌入式技术
私信 关注

【FireBeetle Board ESP32-E IoT 开发板试用体验】第二弹,点个OLED屏玩玩吧,带跑马灯哟

本帖最后由 cszzlsw 于 2021-8-29 18:34 编辑

继上次点灯贴之后,发现好多点灯贴,然后群里有同学就吐槽了说大家都是点灯贴,感觉没什么意义,今天我来点个OLED,不知道大家会不会认为也是在浪费时间
话不多说,进入正题吧!

一,建立工程
上次点灯用的是led例程,这次咱们进到i2c工程里,
~/esp/esp-idf/examples/peripherals/i2c/i2c_tools$

为什么用这个呢,因为这里面有i2c的代码示例,因为我要玩的OLED屏需要I2C来驱动,这也就跟各新手同学提示了,如果拿到一款芯片用某个功能不知道怎么使用的时候,去官方的例程里去找,然后看不懂的时候去看文档,最后就能搞出来了,建立工程后工程目录这样:
微信截图_20210829183322.png
二,写代码
这一步其实大家都会,其实挺枯燥无味的,主要跟大家说一下玩oled或者其他屏的时候会遇到的两个问题:图片和字模,
首先图片需要转换成数组,这里推荐大家用这个网站:图片转数组,如果所示,最后把转出来的数组拷到我们的代码里去就行:
微信截图_20210829182244.png
  1. // width: 64, height: 64  //for black
  2. const unsigned char picture_arr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0xf0, 0x1f, 0x80, 0x07, 0xff, 0xff, 0xc0, 0x01, 0xf8, 0x1f, 0x80, 0x0f, 0xff, 0xff, 0xf0, 0x01, 0xf8, 0x1f, 0x80, 0x3f, 0xff, 0xff, 0xfc, 0x03, 0xf8, 0x1f, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf8, 0x1f, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xf8, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x07, 0x70, 0x00, 0x00, 0x0e, 0xf8, 0x00, 0x00, 0x3f, 0x70, 0x00, 0x00, 0x0f, 0x9f, 0x80, 0x01, 0xf9, 0xf0, 0x00, 0x00, 0x0f, 0xf3, 0xf0, 0x0f, 0xcf, 0xf0, 0x00, 0x00, 0x0f, 0xfe, 0x7e, 0xfe, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xcf, 0xf7, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
第二样是取字模,用汉字取模程序,在这里贴上地址,大家自行下载:http://www.pc0359.cn/downinfo/110811.html
微信截图_20210829181907.png
把字模软件生成的数组拷到代码里去:
  1. unsigned char hope_arr[][32] = {
  2.         //当前汉字是:祝
  3.         {0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x18, 0x01, 0xFC, 0x0D, 0x98, 0x7C, 0xB0, 0x2C, 0xF0,
  4.          0x1E, 0xF0, 0x1E, 0xE0, 0x3D, 0xA1, 0x6D, 0x23, 0x0E, 0x3F, 0x08, 0x1E, 0x08, 0x00, 0x00, 0x00},

  5.         /*---------------电----------------*/
  6.         {0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0xF8, 0x3F, 0xB8, 0x1B, 0xB0, 0x1F, 0xF0,
  7.          0x1B, 0x30, 0x1F, 0xE0, 0x0F, 0x00, 0x03, 0x04, 0x03, 0x06, 0x01, 0xFE, 0x00, 0x78, 0x00, 0x00},

  8.         /*---------------子----------------*/
  9.         {0x00, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x0F, 0x70, 0x00, 0x60, 0x01, 0xC0, 0x01, 0xFE, 0x3F, 0xFE,
  10.          0x78, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x07, 0xC0, 0x03, 0x80, 0x01, 0x00},

  11.         /*---------------发----------------*/
  12.         {0x00, 0x00, 0x01, 0x80, 0x01, 0xF8, 0x05, 0x9C, 0x07, 0x90, 0x0D, 0xF8, 0x0F, 0x00, 0x0B, 0x60,
  13.          0x03, 0xF0, 0x07, 0x60, 0x06, 0xE0, 0x0C, 0xE0, 0x19, 0xF0, 0x33, 0xBC, 0x00, 0x1E, 0x00, 0x00},

  14.         /*---------------烧----------------*/
  15.         {0x00, 0x00, 0x00, 0x00, 0x09, 0x80, 0x0C, 0xF0, 0x0C, 0xF8, 0x0F, 0xF8, 0x6E, 0x74, 0x38, 0xFE,
  16.          0x09, 0x8E, 0x09, 0xF8, 0x0F, 0xE0, 0x1E, 0xA0, 0x11, 0xA2, 0x33, 0x3F, 0x46, 0x3E, 0x00, 0x00},

  17.         /*---------------友----------------*/
  18.         {0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x03, 0xF8, 0x1F, 0x80, 0x03, 0x00, 0x03, 0xF0,
  19.          0x07, 0xB0, 0x07, 0x60, 0x0D, 0xE0, 0x18, 0xE0, 0x30, 0xF0, 0x63, 0xBC, 0x0E, 0x1F, 0x00, 0x00},
然后就可以组织主程序了:
  1. void app_main(void)
  2. {
  3.     // esp_console_repl_t *repl = NULL;
  4.     // esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();

  5.     TaskHandle_t xHandle = xTaskCreateStatic(
  6.         oledTaskEntry,
  7.         "oled_th",
  8.         OLED_TASK_STACK_SIZE,
  9.         NULL,
  10.         tskIDLE_PRIORITY,
  11.         xStack,
  12.         &xTaskBuffer);

  13.     printf("create task %pn", xHandle);

  14.     // vTaskSuspend(xHandle);

  15.     while (1)
  16.     {
  17.         HAL_Delay(1000);
  18.     }
  1. void oledTaskEntry(void *arg)
  2. {
  3.     printf("oledTaskEntry-------------n");
  4.     HAL_Delay(100);

  5.     ssd1306_Init();

  6.     int text_area_width = 64;
  7.     int text_area_height = 64;

  8.     int text_per_line_num = text_area_height / font_width;

  9.     int mod = hope_num % text_per_line_num;
  10.     int text_line_num = hope_num / text_per_line_num;
  11.     if (mod)
  12.     {
  13.         text_line_num += 1;
  14.     }

  15.     printf("picture_arr size=%dn", sizeof(picture_arr));
  16.     int text_alredy_show = 0;

  17.     while (1)
  18.     {
  19.         ssd1306_Fill(Black);
  20.         ssd1306_SetCursor(0, 0);

  21.         int x = 0;
  22.         int y = 0;
  23.         printf("hope_num =%dn", hope_num);
  24.         // int start_num = text_alredy_show * text_per_line_num;
  25.         int showed_num = 0;
  26.         for (int i = text_alredy_show; i < hope_num; i++)
  27.         {

  28.             ssd1306_DrawRegion(x, y, font_height, font_width, hope_arr[i], sizeof(hope_arr[0]), 0);

  29.             x += font_width;
  30.             if (x >= text_area_width)
  31.             {
  32.                 y += font_height;
  33.                 x = 0;
  34.             }
  35.             showed_num++;
  36.             if (y >= text_area_height)
  37.             {

  38.                 break;
  39.             }
  40.         }

  41.         ssd1306_DrawRegion(64, 0, 64, 64, picture_arr, sizeof(picture_arr), 0);
  42.         ssd1306_UpdateScreen();
  43.         HAL_Delay(OLED_INTERVAL_TIME_MS);
  44.         text_alredy_show++;
  45.         if (text_alredy_show >= hope_num - text_alredy_show)
  46.         {
  47.             text_alredy_show = 0;
  48.             HAL_Delay(OLED_INTERVAL_TIME_MS * 3);
  49.         }
  50.     }
  51. }
三,编译,下载,运行
其实这一步挺枯燥的,不打算写比较多的内容,这里再贴一下i2c的初始化以及数据发送的代码把:

  1. #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
  2. #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
  3. #define WRITE_BIT I2C_MASTER_WRITE  /*!< I2C master write */
  4. #define READ_BIT I2C_MASTER_READ    /*!< I2C master read */
  5. #define ACK_CHECK_EN 0x1            /*!< I2C master will check ack from slave*/
  6. #define ACK_CHECK_DIS 0x0           /*!< I2C master will not check ack from slave */
  7. #define ACK_VAL 0x0                 /*!< I2C ack value */
  8. #define NACK_VAL 0x1                /*!< I2C nack value */

  9. static gpio_num_t i2c_gpio_sda = 21;
  10. static gpio_num_t i2c_gpio_scl = 22;
  11. static uint32_t i2c_frequency = 400000;
  12. static i2c_port_t i2c_port = I2C_NUM_0;

  13. static esp_err_t i2c_master_driver_initialize(void)
  14. {
  15.     i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
  16.     i2c_config_t conf = {
  17.         .mode = I2C_MODE_MASTER,
  18.         .sda_io_num = i2c_gpio_sda,
  19.         .sda_pullup_en = GPIO_PULLUP_ENABLE,
  20.         .scl_io_num = i2c_gpio_scl,
  21.         .scl_pullup_en = GPIO_PULLUP_ENABLE,
  22.         .master.clk_speed = i2c_frequency,
  23.         // .clk_flags = 0,          /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
  24.     };
  25.     return i2c_param_config(i2c_port, &conf);
  26. }

  27. static uint32_t ssd1306_SendData(uint8_t *data, size_t size)
  28. {
  29.     // WifiIotI2cIdx id = SSD1306_I2C_IDX;
  30.     // WifiIotI2cData i2cData = {0};
  31.     // i2cData.sendBuf = data;
  32.     // i2cData.sendLen = size;
  33.     i2c_cmd_handle_t g_i2c_cmd = NULL;
  34.     if (g_i2c_cmd == NULL)
  35.     {
  36.         g_i2c_cmd = i2c_cmd_link_create();
  37.     }
  38.     esp_err_t ret = 0;

  39.     i2c_master_start(g_i2c_cmd);
  40.     ret = i2c_master_write_byte(g_i2c_cmd, SSD1306_I2C_ADDR | WRITE_BIT, ACK_CHECK_EN);
  41.     // printf("i2c_master_write_byte ret = %dn", ret);
  42.     ret = i2c_master_write(g_i2c_cmd, data, size, ACK_CHECK_EN);
  43.     // printf("i2c_master_write ret = %dn", ret);
  44.     ret = i2c_master_stop(g_i2c_cmd);
  45.     // printf("i2c_master_stop ret = %dn", ret);
  46.     ret = i2c_master_cmd_begin(i2c_port, g_i2c_cmd, 50 / portTICK_RATE_MS);
  47.     // printf("i2c_master_cmd_begin ret = %dn", ret);
  48.     i2c_cmd_link_delete(g_i2c_cmd);

  49.     return ret; //i2c_master_write(id, SSD1306_I2C_ADDR, &i2cData);
  50. }
四,效果:
最初图片转数组没有用反色,效果是这样,感觉挺别扭:
微信图片_20210829180943.jpg
然后取个反色,舒服多了,
微信图片_20210829180952.jpg
最后再加个跑马灯效果,完美
OLED演示[00_00_06--00_00_26].gif

说个题外话,大家看这个logo像什么,
其实是我们这次活动供应商DFRobot的logo,因为尺寸关系,,就截了个图形过来,完整的logo在这:

60ebd99dd5461.jpg
这里再次感谢DFRobot和电子发烧友
五,下一步计划
下一步的计划把跑马等完善完善,有同学问了,还怎么完善,回答:必须的
比如用网络发送文字,速度等,或者用蓝牙也可以呀,期待一下吧
视频演示在下方

OLED演示

更多回帖

发帖
×
20
完善资料,
赚取积分