wagiminator / ATtiny85-PhoneChargeGuard

USB Phone Charge Guard
https://oshwlab.com/wagiminator/attiny85-phone-charge-guard
Other
19 stars 5 forks source link

How exactly are these fonts made? #1

Open parthbhat13 opened 11 months ago

parthbhat13 commented 11 months ago

Hi, im so sorry to create a issue, i could not find any direct way to contact you. ive been a big fan of your projects and mainly how you play with the OLED displays and optimize the code. i was trying to use some fonts of yours in my code, but i saw that you have mostly stripped down a lot of things to save the memory. My most favouraite have been the 7 Segment style font. now i was wanting to use some letters like "I" , "A" or even in the big font. but i am so confused on how exactly have you made those fonts that i just was forced to contact you here as an issue. again sorry for that. but can you guide me how can i actually make more alphabets of the following fonts from your different codes.

// OLED 6x16 font
const uint8_t OLED_FONT_BIG[] = {
  0x7C, 0x1F, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x7C, 0x1F, //  0 0
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x1F, //  1 1
  0x00, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x00, //  2 2
  0x00, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, //  3 3
  0x7C, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7C, 0x1F, //  4 4
  0x7C, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x00, 0x1F, //  5 5
  0x7C, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x00, 0x1F, //  6 6
  0x7C, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7C, 0x1F, //  7 7
  0x7C, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, //  8 8
  0x7C, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, //  9 9
  0x00, 0x00, 0xF0, 0x3F, 0x8C, 0x00, 0x82, 0x00, 0x8C, 0x00, 0xF0, 0x3F, // 10 A
  0x00, 0x00, 0xFE, 0x07, 0x00, 0x18, 0x00, 0x20, 0x00, 0x18, 0xFE, 0x07, // 11 V
  0x00, 0x00, 0xFE, 0x1F, 0x00, 0x20, 0x00, 0x1F, 0x00, 0x20, 0xFE, 0x1F, // 12 W
  0x00, 0x00, 0xFE, 0x3F, 0x00, 0x01, 0x80, 0x00, 0x80, 0x00, 0x00, 0x3F, // 13 h
  0x00, 0x00, 0x80, 0x3F, 0x80, 0x00, 0x80, 0x3F, 0x80, 0x00, 0x00, 0x3F, // 14 m
  0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, // 15 :
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 16 SPACE
};

another one is for the 7 segment style

// OLED 5x16 font 7 Segment
const uint8_t OLED_FONT[] = {
  0x7C, 0x1F, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x7C, 0x1F, // 0  0
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x1F, // 1  1
  0x00, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x00, // 2  2
  0x00, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, // 3  3
  0x7C, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7C, 0x1F, // 4  4
  0x7C, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x00, 0x1F, // 5  5
  0x7C, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x00, 0x1F, // 6  6
  0x0C, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7C, 0x1F, // 7  7
  0x7C, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, // 8  8
  0x7C, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, // 9  9
  0xF0, 0x3F, 0x8C, 0x00, 0x82, 0x00, 0x8C, 0x00, 0xF0, 0x3F, // A 10
  0xFE, 0x07, 0x00, 0x18, 0x00, 0x20, 0x00, 0x18, 0xFE, 0x07, // V 11
  0x00, 0x00, 0x30, 0x06, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, // : 12
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //   13
  0x02, 0x00, 0x02, 0x00, 0x7E, 0x3F, 0x02, 0x00, 0x02, 0x00, // T 14
};

can you please give some guidance? or am i totally missing something? as well these fonts are taking from different projects of yours, im trying to implement this on STM32G030F6P6TR, i do have memory restrictions too. heres the C code attached.

/*
 * SSD1306.c
 *
 *  Created on: Dec 2, 2023
 *      Author: parthasus
 */

#include "stm32g0xx_hal.h"
#include "SSD1306.h"

// extern the i2c handler
extern I2C_HandleTypeDef hi2c2;
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))

// Oled definitions
#define OLED_CMD_MODE   0x00    // set command mode
#define OLED_DAT_MODE   0x40    // set data mode
#define OLED_INIT_LEN   11      // 9: no screen flip, 11: screen flip

// OLED init settings
const uint8_t OLED_INIT_CMD[] = {
  0xA8, 0x1F,                   // set multiplex for 128x32
  0x20, 0x01,                   // set vertical memory addressing mode
  0xDA, 0x02,                   // set COM pins hardware configuration to sequential
  0x8D, 0x14,                   // enable charge pump
  0xAF,                         // switch on OLED
  0xA1, 0xC8                    // flip the screen
};

// OLED current page
uint8_t OLED_page;

// OLED 5x8 font (adapted from Neven Boyanov and Stephen Denne)
const uint8_t OLED_FONT_SMALL[]  = {
  0x3E, 0x51, 0x49, 0x45, 0x3E, //  0 0
  0x00, 0x42, 0x7F, 0x40, 0x00, //  1 1
  0x42, 0x61, 0x51, 0x49, 0x46, //  2 2
  0x21, 0x41, 0x45, 0x4B, 0x31, //  3 3
  0x18, 0x14, 0x12, 0x7F, 0x10, //  4 4
  0x27, 0x45, 0x45, 0x45, 0x39, //  5 5
  0x3C, 0x4A, 0x49, 0x49, 0x30, //  6 6
  0x01, 0x71, 0x09, 0x05, 0x03, //  7 7
  0x36, 0x49, 0x49, 0x49, 0x36, //  8 8
  0x06, 0x49, 0x49, 0x29, 0x1E, //  9 9
  0x7C, 0x12, 0x11, 0x12, 0x7C, // 10 A
  0x1F, 0x20, 0x40, 0x20, 0x1F, // 11 V
  0x3F, 0x40, 0x38, 0x40, 0x3F, // 12 W
  0x7F, 0x08, 0x04, 0x04, 0x78, // 13 h
  0x7C, 0x04, 0x18, 0x04, 0x78, // 14 m
  0x00, 0x36, 0x36, 0x00, 0x00, // 15 :
  0x00, 0x00, 0x00, 0x00, 0x00, // 16 SPACE
  0x3E, 0x41, 0x41, 0x41, 0x22, // 17 C
  0x7F, 0x49, 0x49, 0x49, 0x41, // 18 E
  0x3E, 0x41, 0x49, 0x49, 0x7A, // 19 G
  0x7F, 0x08, 0x08, 0x08, 0x7F, // 20 H
  0x00, 0x41, 0x7F, 0x41, 0x00, // 21 I
  0x7F, 0x40, 0x40, 0x40, 0x40, // 22 L
  0x7F, 0x02, 0x0C, 0x02, 0x7F, // 23 M
  0x7F, 0x09, 0x09, 0x09, 0x06, // 24 P
  0x7F, 0x09, 0x19, 0x29, 0x46, // 25 R
  0x46, 0x49, 0x49, 0x49, 0x31, // 26 S
  0x01, 0x01, 0x7F, 0x01, 0x01, // 27 T
  0x3F, 0x40, 0x40, 0x40, 0x3F, // 28 U
  0x00, 0x44, 0x7D, 0x40, 0x00, // 29 i
  0x7C, 0x08, 0x04, 0x04, 0x78,  // 30 n
  0x7F, 0x41, 0x41, 0x22, 0x1C, // D 31
  0x00, 0x60, 0x60, 0x00, 0x00, // . 32
};
// OLED 6x16 font
const uint8_t OLED_FONT_BIG[] = {
  0x7C, 0x1F, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x7C, 0x1F, //  0 0
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x1F, //  1 1
  0x00, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x00, //  2 2
  0x00, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, //  3 3
  0x7C, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7C, 0x1F, //  4 4
  0x7C, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x00, 0x1F, //  5 5
  0x7C, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x00, 0x1F, //  6 6
  0x7C, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7C, 0x1F, //  7 7
  0x7C, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, //  8 8
  0x7C, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, //  9 9
  0x00, 0x00, 0xF0, 0x3F, 0x8C, 0x00, 0x82, 0x00, 0x8C, 0x00, 0xF0, 0x3F, // 10 A
  0x00, 0x00, 0xFE, 0x07, 0x00, 0x18, 0x00, 0x20, 0x00, 0x18, 0xFE, 0x07, // 11 V
  0x00, 0x00, 0xFE, 0x1F, 0x00, 0x20, 0x00, 0x1F, 0x00, 0x20, 0xFE, 0x1F, // 12 W
  0x00, 0x00, 0xFE, 0x3F, 0x00, 0x01, 0x80, 0x00, 0x80, 0x00, 0x00, 0x3F, // 13 h
  0x00, 0x00, 0x80, 0x3F, 0x80, 0x00, 0x80, 0x3F, 0x80, 0x00, 0x00, 0x3F, // 14 m
  0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, // 15 :
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 16 SPACE

};

// OLED 5x16 font 7 Segment
const uint8_t OLED_FONT[] = {
  0x7C, 0x1F, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x7C, 0x1F, // 0  0
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x1F, // 1  1
  0x00, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x00, // 2  2
  0x00, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, // 3  3
  0x7C, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7C, 0x1F, // 4  4
  0x7C, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x00, 0x1F, // 5  5
  0x7C, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x00, 0x1F, // 6  6
  0x0C, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7C, 0x1F, // 7  7
  0x7C, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, // 8  8
  0x7C, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, // 9  9
  0xF0, 0x3F, 0x8C, 0x00, 0x82, 0x00, 0x8C, 0x00, 0xF0, 0x3F, // A 10
  0xFE, 0x07, 0x00, 0x18, 0x00, 0x20, 0x00, 0x18, 0xFE, 0x07, // V 11
  0x00, 0x00, 0x30, 0x06, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, // : 12
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //   13
  0x02, 0x00, 0x02, 0x00, 0x7E, 0x3F, 0x02, 0x00, 0x02, 0x00, // T 14
};

// Internal Function Prototype
void i2cWrite(uint8_t oledAddr, uint8_t oledReg, uint8_t oledData);

// global functions
uint8_t dispInit()
{
    if(HAL_I2C_IsDeviceReady(&hi2c2, OLED_ADDR, 2, 2000) != HAL_OK)
    {
        return 0;
    }

    for(uint8_t i = 0; i < OLED_INIT_LEN; i++)
    {
        i2cWrite(OLED_ADDR, OLED_CMD_MODE, OLED_INIT_CMD[i]);
    }

    return 1;
}

void dispSetCursor(uint8_t xPos, uint8_t yPos)
{
    i2cWrite(OLED_ADDR, OLED_CMD_MODE, 0x22);
    i2cWrite(OLED_ADDR, OLED_CMD_MODE, yPos);

    (yPos > 1) ? (i2cWrite(OLED_ADDR, OLED_CMD_MODE, 3)) : (i2cWrite(OLED_ADDR, OLED_CMD_MODE, yPos));

    i2cWrite(OLED_ADDR, OLED_CMD_MODE, xPos & 0x0F);
    i2cWrite(OLED_ADDR, OLED_CMD_MODE, 0x10 | (xPos >> 4));
    i2cWrite(OLED_ADDR, OLED_CMD_MODE, 0xB0 | (yPos));
    OLED_page = yPos;
}

void dispClearScreen(void)
{
    uint8_t i;
    dispSetCursor(0, 0);
    for(i = OLED_WIDTH; i; i--) i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00);

    dispSetCursor(0, 1);
    for(i = OLED_WIDTH; i; i--) i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x02);

    dispSetCursor(0, 2);
    do { i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00); } while (--i);
}

void dispPlotChar(uint8_t ch)
{
    if(OLED_page)
    {
        ch = (ch << 3) + (ch << 2);
        i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00);
        i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00);
        for(uint8_t i = 12; i; i--)
            i2cWrite(OLED_ADDR, OLED_DAT_MODE, pgm_read_byte(&OLED_FONT_BIG[ch++]));
        i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00);
        i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00);
    }
    else
    {
        ch += (ch << 2);
        i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00);
        for(uint8_t i = 5; i; i--)
            i2cWrite(OLED_ADDR, OLED_DAT_MODE, pgm_read_byte(&OLED_FONT_SMALL[ch++]));
        //i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00);
        //i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00);
    }
}

void dispPlotSevenSegment(uint8_t xPos, uint8_t yPos, uint8_t ch)
{
    i2cWrite(OLED_ADDR, OLED_CMD_MODE, 0x22);
    i2cWrite(OLED_ADDR, OLED_CMD_MODE, yPos);

    (yPos > 1) ? (i2cWrite(OLED_ADDR, OLED_CMD_MODE, 3)) : (i2cWrite(OLED_ADDR, OLED_CMD_MODE, yPos));

    i2cWrite(OLED_ADDR, OLED_CMD_MODE, xPos & 0x0F);
    i2cWrite(OLED_ADDR, OLED_CMD_MODE, 0x10 | (xPos >> 4));
    i2cWrite(OLED_ADDR, OLED_CMD_MODE, 0xB0 | (yPos));

    ch = (ch << 1) + (ch << 3);
    i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00);
    i2cWrite(OLED_ADDR, OLED_DAT_MODE, 0x00);
    for(uint8_t i = 10; i; i--)
        i2cWrite(OLED_ADDR, OLED_DAT_MODE, pgm_read_byte(&OLED_FONT[ch++]));
}

void dispPrintChar(uint8_t ch)
{
    dispPlotChar(ch);
}

void dispPrint(const uint8_t *p)
{
    uint8_t ch = pgm_read_byte(p);
    while(ch < 255)
    {
        dispPlotChar(ch);
         ch = pgm_read_byte(++p);
    }
}

// internal functions
void i2cWrite(uint8_t oledAddr, uint8_t oledReg, uint8_t oledData)
{
    uint8_t data[2];
    data[0] = oledReg;
    data[1] = oledData;

    HAL_I2C_Master_Transmit(&hi2c2, oledAddr, data, 2, 20);
}
wagiminator commented 11 months ago

Hi, I actually drew these fonts in the old school way on graph paper and then calculated the individual bytes in my head. Of course you can use an OLED font editor, such as this one: https://sourpuss.net/projects/fontedit/

parthbhat13 commented 11 months ago

Hi, Thanks for your response. I was running away from going deep into the whole oled and screen things but I guess I eventually have to haha. Thanks for the website. I guess I better start from scratch and learn rather than to copy paste.

Thanks again.

wagiminator commented 10 months ago

You can use the Arduino IDE. There are certainly a lot of ready-made libraries for different displays, many fonts to choose from and certainly tools for font creation.