Skip to content
This repository has been archived by the owner on May 5, 2024. It is now read-only.

Commit

Permalink
Oled fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Galzai committed Sep 7, 2018
1 parent 95c7706 commit 3d37fdb
Show file tree
Hide file tree
Showing 11 changed files with 147 additions and 86 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ In order to define your keyboard:

### OLED Display:
- You can add an OLED display to your keyboard by defining ENABLE_OLED in keyboard_config.h and setting the correct i2c pins.
- The graphics are currently configured for an SSD1306 128x64 OLED but can be modified by changing your display in oled_tasks.c. please refer to the u8g2 wiki
for additional information: https://github.com/olikraus/u8g2/wiki
- The graphics are currently configured for an SSD1306 128x64 OLED but can be modified by changing your display in oled_tasks.c. please refer to the u8g2 wiki for additional information: https://github.com/olikraus/u8g2/wiki
- The oled currently responds relativley slowly (probably an issue with i2c over 100khz on the esp32).

### Battery Monitoring:
- Battery level indication is by approximate values (you can look at LiPo voltage discharge graphs and adjust using an appropriate voltage-discharge capacity table)
Expand Down
21 changes: 19 additions & 2 deletions components/battery_monitor/battery_monitor.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
/*
* This battery monitoring code is based on reading the voltage
* after after a voltage divider and checking the level on an analog pin
* Based on the adc example from Espressif
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* Copyright 2018 Gal Zaidenstein.
*/


Expand All @@ -19,7 +36,7 @@
#include "battery_monitor.h"

#define DEFAULT_VREF 1100 //Use adc2_vref_to_gpio() to obtain a better estimate
#define NO_OF_SAMPLES 64 //Multisampling
#define NO_OF_SAMPLES 500 //Multisampling

static const adc_channel_t channel = BATT_PIN;
static const adc_atten_t atten = ADC_ATTEN_DB_2_5;
Expand All @@ -44,7 +61,7 @@ uint32_t get_battery_level(void){
//Convert adc_reading to voltage in mV
voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
uint32_t battery_percent = ((voltage-Vout_min)*100/(Vout_max-Vout_min));
printf("Raw: %d\tVoltage: %dmV\tPercent: %d\n", adc_reading, voltage, battery_percent);
// printf("Raw: %d\tVoltage: %dmV\tPercent: %d\n", adc_reading, voltage, battery_percent);
return battery_percent;

}
Expand Down
4 changes: 2 additions & 2 deletions components/battery_monitor/battery_monitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ extern "C" {

/*These are approximate values,
* battery voltage isn't completely linear, it would be better to use a table for specific battery
* in the future.
* For now this is an ok approximation.
*/
#define Vin_max 4200 //Charging Battery voltage [mV]
#define Vin_max 4200 //Max Battery voltage [mV]
#define Vin_min 3400 //Battery discharge Voltage[mV]

#define Vout_max Vin_max*R_2/(R_1+R_2) //Max voltage on analog pin [mV]
Expand Down
4 changes: 4 additions & 0 deletions components/nkolban_BLE/HID_kbdmousejoystick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

#include "sdkconfig.h"
#include "keyboard_config.h"
#include "oled_tasks.h"

static char LOG_TAG[] = "HAL_BLE";

Expand Down Expand Up @@ -271,6 +272,9 @@ class kbdOutputCB : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic* me){
uint8_t* value = (uint8_t*)(me->getValue().c_str());
curr_led = *value;
#ifdef OLED_ENABLE
xQueueSend(led_recieve_q,&curr_led, (TickType_t) 0);
#endif
ESP_LOGI(LOG_TAG, "special keys: %d", *value);
}
};
Expand Down
153 changes: 84 additions & 69 deletions components/u8g2_OLED/oled_tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,107 +44,91 @@ static const char *TAG = " OLED";
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

u8g2_t u8g2; // a structure which will contain all the data for one display
uint8_t prev_layout = 0;
uint8_t prev_led = 0;

QueueHandle_t layer_recieve_q;
QueueHandle_t led_recieve_q;

uint32_t battery_percent = 0;
uint32_t prev_battery_percent= 0;

uint8_t curr_layout = 0;
uint8_t current_led = 0;

int BATT_FLAG =0;
int DROP_H=0;

#define BT_ICON 0x5e
#define BATT_ICON 0x5b
#define LOCK_ICON 0xca


//Function for updating the OLED
void erase_area(uint8_t x,uint8_t y,uint8_t w,uint8_t h){
u8g2_SetDrawColor(&u8g2,0);
u8g2_DrawBox(&u8g2,x,y,w,h);
u8g2_SetDrawColor(&u8g2,1);
}

void update_oled(void){
#ifdef BATT_STAT
battery_percent = get_battery_level();
#endif

if(current_layout!=prev_layout){
u8g2_ClearBuffer(&u8g2);
if(xQueueReceive(layer_recieve_q,&curr_layout,1)){
erase_area(0,7,45,7);
u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
u8g2_DrawStr(&u8g2, 0,6,GATTS_TAG);
u8g2_DrawStr(&u8g2, 0,14,layout_names[current_layout]);
u8g2_SetFont(&u8g2, u8g2_font_open_iconic_all_1x_t );
u8g2_DrawGlyph(&u8g2, 110,8,BATT_ICON);
u8g2_DrawGlyph(&u8g2, 120,8,BT_ICON);

if(CHECK_BIT(curr_led,0)!=0){
u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
u8g2_DrawStr(&u8g2, 0,31,"NUM");
u8g2_SetFont(&u8g2, u8g2_font_open_iconic_all_1x_t );
u8g2_DrawGlyph(&u8g2, 16,32,LOCK_ICON);
}

if(CHECK_BIT(curr_led,1)!=0){
u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
u8g2_DrawStr(&u8g2, 27,31,"CAPS");
u8g2_SetFont(&u8g2, u8g2_font_open_iconic_all_1x_t );
u8g2_DrawGlyph(&u8g2,48,32,LOCK_ICON);
}
if(CHECK_BIT(curr_led,2)!=0){
u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
u8g2_DrawStr(&u8g2, 57,31,"SCROLL");
u8g2_SetFont(&u8g2, u8g2_font_open_iconic_all_1x_t );
u8g2_DrawGlyph(&u8g2,88,32,LOCK_ICON);
}

u8g2_DrawStr(&u8g2, 0,14,layout_names[curr_layout]);
u8g2_SendBuffer(&u8g2);
prev_layout = current_layout;
}

if(curr_led!=prev_led){
u8g2_ClearBuffer(&u8g2);
u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
u8g2_DrawStr(&u8g2, 0,6,GATTS_TAG);
u8g2_DrawStr(&u8g2, 0,14,layout_names[current_layout]);
u8g2_SetFont(&u8g2, u8g2_font_open_iconic_all_1x_t );
u8g2_DrawGlyph(&u8g2, 110,8,BATT_ICON);
u8g2_DrawGlyph(&u8g2, 120,8,BT_ICON);

if(CHECK_BIT(curr_led,0)!=0){
if(xQueueReceive(led_recieve_q,&current_led,1)){
erase_area(0,24,127,8);
if(CHECK_BIT(current_led,0)!=0){
u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
u8g2_DrawStr(&u8g2, 0,31,"NUM");
u8g2_SetFont(&u8g2, u8g2_font_open_iconic_all_1x_t );
u8g2_DrawGlyph(&u8g2, 16,32,LOCK_ICON);
}

if(CHECK_BIT(curr_led,1)!=0){
if(CHECK_BIT(current_led,1)!=0){
u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
u8g2_DrawStr(&u8g2, 27,31,"CAPS");
u8g2_SetFont(&u8g2, u8g2_font_open_iconic_all_1x_t );
u8g2_DrawGlyph(&u8g2,48,32,LOCK_ICON);
}
if(CHECK_BIT(curr_led,2)!=0){
if(CHECK_BIT(current_led,2)!=0){
u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
u8g2_DrawStr(&u8g2, 57,31,"SCROLL");
u8g2_SetFont(&u8g2, u8g2_font_open_iconic_all_1x_t );
u8g2_DrawGlyph(&u8g2,88,32,LOCK_ICON);
}
u8g2_SendBuffer(&u8g2);
prev_led = curr_led;
}

if(battery_percent!=prev_battery_percent){
u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
char buf[sizeof(uint32_t)];
snprintf (buf, sizeof(uint32_t), "%d", battery_percent);
u8g2_DrawStr(&u8g2, 103,7,"%");
if(battery_percent<100){
if((battery_percent<100)&&(battery_percent-prev_battery_percent>=2)){
erase_area(85,0,15,7);
u8g2_DrawStr(&u8g2, 90,7,buf);
}else{
u8g2_DrawStr(&u8g2, 85,7,buf);
u8g2_SendBuffer(&u8g2);
}
if((battery_percent>100)&&(BATT_FLAG = 0)){
erase_area(85,0,15,7);
u8g2_DrawStr(&u8g2, 85,7,"100");
BATT_FLAG =1;
u8g2_SendBuffer(&u8g2);
}
if(battery_percent==100){
erase_area(85,0,15,7);
u8g2_DrawStr(&u8g2, 85,7,"100");
u8g2_SendBuffer(&u8g2);
}
u8g2_SendBuffer(&u8g2);
prev_battery_percent = battery_percent;
}






}
}

void ble_connected_oled(void){
Expand Down Expand Up @@ -178,6 +162,15 @@ void ble_connected_oled(void){
u8g2_DrawGlyph(&u8g2,88,32,LOCK_ICON);
}

u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
char buf[sizeof(uint32_t)];
snprintf (buf, sizeof(uint32_t), "%d", battery_percent);
u8g2_DrawStr(&u8g2, 103,7,"%");
if(battery_percent<100){
u8g2_DrawStr(&u8g2, 90,7,buf);
}else{
u8g2_DrawStr(&u8g2, 85,7,"100");
}
u8g2_SendBuffer(&u8g2);
}

Expand All @@ -198,12 +191,29 @@ void ble_slave_oled(void){
char buf[sizeof(uint32_t)];
snprintf (buf, sizeof(uint32_t), "%d", battery_percent);
u8g2_DrawStr(&u8g2, 103,7,"%");
if(battery_percent<100){
if((battery_percent<100)&&(battery_percent-prev_battery_percent>=2)){
u8g2_SetDrawColor(&u8g2,0);
u8g2_DrawBox(&u8g2,85,90,0,7);
u8g2_SetDrawColor(&u8g2,1);
u8g2_DrawStr(&u8g2, 90,7,buf);
}else{
u8g2_DrawStr(&u8g2, 85,7,buf);
u8g2_SendBuffer(&u8g2);
}
if((battery_percent<100)&&(battery_percent-prev_battery_percent>=2)){
erase_area(85,0,15,7);
u8g2_DrawStr(&u8g2, 90,7,buf);
u8g2_SendBuffer(&u8g2);
}
if((battery_percent>100)&&(BATT_FLAG = 0)){
erase_area(85,0,15,7);
u8g2_DrawStr(&u8g2, 85,7,"100");
BATT_FLAG =1;
u8g2_SendBuffer(&u8g2);
}
if(battery_percent==100){
erase_area(85,0,15,7);
u8g2_DrawStr(&u8g2, 85,7,"100");
u8g2_SendBuffer(&u8g2);
}
u8g2_SendBuffer(&u8g2);
prev_battery_percent = battery_percent;
}

Expand All @@ -227,15 +237,19 @@ void waiting_oled(void){
u8g2_DrawStr(&u8g2,0,6,GATTS_TAG);


u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
char buf[sizeof(uint32_t)];
snprintf (buf, sizeof(uint32_t), "%d", battery_percent);
u8g2_DrawStr(&u8g2, 103,7,"%");
if(battery_percent<100){
u8g2_DrawStr(&u8g2, 90,7,buf);
}else{
u8g2_DrawStr(&u8g2, 85,7,buf);
}
u8g2_SetFont(&u8g2, u8g2_font_5x7_tf );
char buf[sizeof(uint32_t)];
snprintf (buf, sizeof(uint32_t), "%d", battery_percent);
u8g2_DrawStr(&u8g2, 103,7,"%");
if((battery_percent<100)&&(battery_percent-prev_battery_percent>=2)){
u8g2_DrawStr(&u8g2, 90,7,buf);
u8g2_SendBuffer(&u8g2);
}
if(battery_percent<100){
u8g2_DrawStr(&u8g2, 90,7,buf);
}else{
u8g2_DrawStr(&u8g2, 85,7,"100");
}

for(int i=0; i<3; i++){
u8g2_DrawStr(&u8g2, 0,26,waiting_conn);
Expand Down Expand Up @@ -264,16 +278,17 @@ void deinit_oled(void) {

//initialize oled
void init_oled(void) {
layer_recieve_q = xQueueCreate(32,sizeof(uint8_t));
led_recieve_q = xQueueCreate(32,sizeof(uint8_t));
ESP_LOGI(TAG, "Setting up oled");
u8g2_esp32_hal_t u8g2_esp32_hal = U8G2_ESP32_HAL_DEFAULT;
u8g2_esp32_hal.sda = OLED_SDA_PIN;
u8g2_esp32_hal.scl = OLED_SCL_PIN;
u8g2_esp32_hal_init(u8g2_esp32_hal);

u8g2_Setup_ssd1306_i2c_128x32_univision_f(
u8g2_Setup_ssd1306_i2c_128x64_noname_f(
&u8g2,
U8G2_R0,
//u8x8_byte_sw_i2c,
u8g2_esp32_i2c_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
u8x8_SetI2CAddress(&u8g2.u8x8,0x78);
Expand Down
9 changes: 9 additions & 0 deletions components/u8g2_OLED/oled_tasks.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
#ifndef OLED_TASKS_H_
#define OLED_TASKS_H_

#include <freertos/FreeRTOS.h>
#include <freertos/event_groups.h>
#include <freertos/queue.h>
#include <esp_log.h>

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -37,6 +42,10 @@ void ble_slave_oled(void);
* */
void update_oled(void);

/** @brief Queue for sending mouse reports
**/
extern QueueHandle_t layer_recieve_q;
extern QueueHandle_t led_recieve_q;

#ifdef __cplusplus
}
Expand Down
4 changes: 2 additions & 2 deletions components/u8g2_OLED/u8g2_esp32_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

#define U8G2_ESP32_HAL_UNDEFINED (-1)

#define I2C_MASTER_NUM I2C_NUM_1 // I2C port number for master dev
#define I2C_MASTER_NUM I2C_NUM_0 // I2C port number for master dev
#define I2C_MASTER_TX_BUF_DISABLE 0 // I2C master do not need buffer
#define I2C_MASTER_RX_BUF_DISABLE 0 // I2C master do not need buffer
#define I2C_MASTER_FREQ_HZ 50000 // I2C master clock frequency
#define I2C_MASTER_FREQ_HZ 1000000 // I2C master clock frequency
#define ACK_CHECK_EN 0x1 // I2C master will check ack from slave
#define ACK_CHECK_DIS 0x0 // I2C master will not check ack from slave

Expand Down
2 changes: 1 addition & 1 deletion components/u8g2_OLED/u8x8_d_ssd1306_128x64_noname.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ static const u8x8_display_info_t u8x8_sh1106_128x64_noname_display_info =
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
/* spi_mode = */ 3, /* active low (clock is high by default), rising edge, this seems to be a difference to the ssd1306 */
/* i2c_bus_clock_100kHz = */ 4,
/* i2c_bus_clock_100kHz = */ 1,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16,
Expand Down
6 changes: 5 additions & 1 deletion main/keypress_handles.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "keymap.c"
#include "matrix.c"
#include "HID_kbdmousejoystick.h"
#include "oled_tasks.h"

#define KEY_PRESS_TAG "KEY_PRESS"

Expand Down Expand Up @@ -161,7 +162,10 @@ void layer_adjust( uint16_t keycode ){
current_layout++;
break;
}
vTaskDelay(3);
#ifdef OLED_ENABLE
xQueueSend(layer_recieve_q,&current_layout, (TickType_t) 0);
#endif
vTaskDelay(10);
ESP_LOGI(KEY_PRESS_TAG,"Layer modified!, Current layer: %d ",current_layout);
}

Expand Down
Loading

0 comments on commit 3d37fdb

Please sign in to comment.