#include "ssd1366.h" #include "font8x8_basic.h" #include #include "driver/gpio.h" #define SSD1366_RST_PIN GPIO_NUM_16 #define SSD1366_VEXT_PIN GPIO_NUM_21 #define I2C_NUM I2C_NUM_0 static const char *tag = "oled"; void ssd1306_init() { esp_err_t espRc; gpio_set_direction(SSD1366_RST_PIN, GPIO_MODE_OUTPUT); gpio_set_direction(SSD1366_VEXT_PIN, GPIO_MODE_OUTPUT); gpio_set_level(SSD1366_VEXT_PIN, 0); //enable power to oled gpio_set_level(SSD1366_RST_PIN, 0); vTaskDelay(50 / portTICK_PERIOD_MS); gpio_set_level(SSD1366_RST_PIN, 1); i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_OFF, true); // AE i2c_master_write_byte(cmd, OLED_CMD_SET_MUX_RATIO, true); // A8 i2c_master_write_byte(cmd, 0x3F, true); i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_OFFSET, true); // D3 i2c_master_write_byte(cmd, 0x00, true); i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_START_LINE, true); // 40 i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP, true); // reverse left-right mapping i2c_master_write_byte(cmd, OLED_CMD_SET_COM_SCAN_MODE, true); // reverse up-bottom mapping i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_CLK_DIV, true); // D5 i2c_master_write_byte(cmd, 0x80, true); i2c_master_write_byte(cmd, OLED_CMD_SET_COM_PIN_MAP, true); // DA i2c_master_write_byte(cmd, 0x12, true); i2c_master_write_byte(cmd, OLED_CMD_SET_CONTRAST, true); // 81 i2c_master_write_byte(cmd, 0xFF, true); i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_RAM, true); // A4 i2c_master_write_byte(cmd, OLED_CMD_SET_VCOMH_DESELCT, true); // DB i2c_master_write_byte(cmd, 0x40, true); i2c_master_write_byte(cmd, OLED_CMD_SET_MEMORY_ADDR_MODE, true); // 20 //i2c_master_write_byte(cmd, OLED_CMD_SET_HORI_ADDR_MODE, true); // 00 i2c_master_write_byte(cmd, OLED_CMD_SET_PAGE_ADDR_MODE, true); // 02 // Set Lower Column Start Address for Page Addressing Mode i2c_master_write_byte(cmd, 0x00, true); // Set Higher Column Start Address for Page Addressing Mode i2c_master_write_byte(cmd, 0x10, true); i2c_master_write_byte(cmd, OLED_CMD_SET_CHARGE_PUMP, true); // 8D i2c_master_write_byte(cmd, 0x14, true); i2c_master_write_byte(cmd, OLED_CMD_DEACTIVE_SCROLL, true); // 2E i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_NORMAL, true); // A6 i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true); i2c_master_stop(cmd); espRc = i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); if (espRc == ESP_OK) { ESP_LOGI(tag, "OLED configured successfully"); } else { ESP_LOGE(tag, "OLED configuration failed. code: 0x%.2X", espRc); } i2c_cmd_link_delete(cmd); } void i2c_contrast( int contrast) { i2c_cmd_handle_t cmd; int _contrast = contrast; if (contrast < 0x0) _contrast = 0; if (contrast > 0xFF) _contrast = 0xFF; cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); i2c_master_write_byte(cmd, OLED_CMD_SET_CONTRAST, true); // 81 i2c_master_write_byte(cmd, _contrast, true); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } void ssd1306_display_clear(void) { i2c_cmd_handle_t cmd; uint8_t zero[128] = {0}; for (uint8_t i = 0; i < 8; i++) { cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_SINGLE, true); i2c_master_write_byte(cmd, 0xB0 | i, true); // Set GDDRAM page start address i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); i2c_master_write(cmd, zero, 128, true); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } } void ssd1306_display_text(char* text, uint16_t text_len) { i2c_cmd_handle_t cmd; uint8_t cur_page = 0; cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); i2c_master_write_byte(cmd, 0x00, true); // reset column i2c_master_write_byte(cmd, 0x10, true); i2c_master_write_byte(cmd, 0xB0 | cur_page, true); // reset page i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); for (uint8_t i = 0; i < text_len; i++) { if (text[i] == '\n') { cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true); i2c_master_write_byte(cmd, 0x00, true); // reset column i2c_master_write_byte(cmd, 0x10, true); i2c_master_write_byte(cmd, 0xB0 | ++cur_page, true); // increment page i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } else { cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); i2c_master_write(cmd, font8x8_basic_tr[(uint8_t)text[i]], 8, true); i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM, cmd, 10/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } } } void task_ssd1306_display_text(void *pvParameters) { char *pcTaskName; pcTaskName = (char *) pvParameters; //char text[13] = "Hello world!"; //uint8_t text_len = strlen(text); ssd1306_display_text(pcTaskName, strlen(pcTaskName)); vTaskDelete(NULL); }