#include <Wire.h>
#define SSD1306_I2C_ADDRESS 0x3C // Change if your display has a different I2C address
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define BUFFER_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 8)
uint8_t buffer[BUFFER_SIZE];
// I2C pins
//#define SDA_PIN 4
//#define SCL_PIN 5
// Standard ASCII 5x8 font
const uint8_t font5x8[96][5] PROGMEM = {
{0x00, 0x00, 0x00, 0x00, 0x00}, // 32 - Space
{0x00, 0x00, 0x5F, 0x00, 0x00}, // 33 - !
{0x00, 0x07, 0x00, 0x07, 0x00}, // 34 - "
{0x14, 0x7F, 0x14, 0x7F, 0x14}, // 35 - #
{0x24, 0x2A, 0x7F, 0x2A, 0x12}, // 36 - $
{0x23, 0x13, 0x08, 0x64, 0x62}, // 37 - %
{0x36, 0x49, 0x55, 0x22, 0x50}, // 38 - &
{0x00, 0x05, 0x03, 0x00, 0x00}, // 39 - '
{0x00, 0x1C, 0x22, 0x41, 0x00}, // 40 - (
{0x00, 0x41, 0x22, 0x1C, 0x00}, // 41 - )
{0x14, 0x08, 0x3E, 0x08, 0x14}, // 42 - *
{0x08, 0x08, 0x3E, 0x08, 0x08}, // 43 - +
{0x00, 0x50, 0x30, 0x00, 0x00}, // 44 - ,
{0x08, 0x08, 0x08, 0x08, 0x08}, // 45 - -
{0x00, 0x60, 0x60, 0x00, 0x00}, // 46 - .
{0x20, 0x10, 0x08, 0x04, 0x02}, // 47 - /
{0x3E, 0x51, 0x49, 0x45, 0x3E}, // 48 - 0
{0x00, 0x42, 0x7F, 0x40, 0x00}, // 49 - 1
{0x42, 0x61, 0x51, 0x49, 0x46}, // 50 - 2
{0x21, 0x41, 0x45, 0x4B, 0x31}, // 51 - 3
{0x18, 0x14, 0x12, 0x7F, 0x10}, // 52 - 4
{0x27, 0x45, 0x45, 0x45, 0x39}, // 53 - 5
{0x3C, 0x4A, 0x49, 0x49, 0x30}, // 54 - 6
{0x01, 0x71, 0x09, 0x05, 0x03}, // 55 - 7
{0x36, 0x49, 0x49, 0x49, 0x36}, // 56 - 8
{0x06, 0x49, 0x49, 0x29, 0x1E}, // 57 - 9
{0x00, 0x36, 0x36, 0x00, 0x00}, // 58 - :
{0x00, 0x56, 0x36, 0x00, 0x00}, // 59 - ;
{0x08, 0x14, 0x22, 0x41, 0x00}, // 60 - <
{0x14, 0x14, 0x14, 0x14, 0x14}, // 61 - =
{0x00, 0x41, 0x22, 0x14, 0x08}, // 62 - >
{0x02, 0x01, 0x51, 0x09, 0x06}, // 63 - ?
{0x32, 0x49, 0x79, 0x41, 0x3E}, // 64 - @
{0x7E, 0x11, 0x11, 0x11, 0x7E}, // 65 - A
{0x7F, 0x49, 0x49, 0x49, 0x36}, // 66 - B
{0x3E, 0x41, 0x41, 0x41, 0x22}, // 67 - C
{0x7F, 0x41, 0x41, 0x22, 0x1C}, // 68 - D
{0x7F, 0x49, 0x49, 0x49, 0x41}, // 69 - E
{0x7F, 0x09, 0x09, 0x09, 0x01}, // 70 - F
{0x3E, 0x41, 0x49, 0x49, 0x7A}, // 71 - G
{0x7F, 0x08, 0x08, 0x08, 0x7F}, // 72 - H
{0x00, 0x41, 0x7F, 0x41, 0x00}, // 73 - I
{0x20, 0x40, 0x41, 0x3F, 0x01}, // 74 - J
{0x7F, 0x08, 0x14, 0x22, 0x41}, // 75 - K
{0x7F, 0x40, 0x40, 0x40, 0x40}, // 76 - L
{0x7F, 0x02, 0x04, 0x02, 0x7F}, // 77 - M
{0x7F, 0x04, 0x08, 0x10, 0x7F}, // 78 - N
{0x3E, 0x41, 0x41, 0x41, 0x3E}, // 79 - O
{0x7F, 0x09, 0x09, 0x09, 0x06}, // 80 - P
{0x3E, 0x41, 0x51, 0x21, 0x5E}, // 81 - Q
{0x7F, 0x09, 0x19, 0x29, 0x46}, // 82 - R
{0x46, 0x49, 0x49, 0x49, 0x31}, // 83 - S
{0x01, 0x01, 0x7F, 0x01, 0x01}, // 84 - T
{0x3F, 0x40, 0x40, 0x40, 0x3F}, // 85 - U
{0x1F, 0x20, 0x40, 0x20, 0x1F}, // 86 - V
{0x3F, 0x40, 0x38, 0x40, 0x3F}, // 87 - W
{0x63, 0x14, 0x08, 0x14, 0x63}, // 88 - X
{0x07, 0x08, 0x70, 0x08, 0x07}, // 89 - Y
{0x61, 0x51, 0x49, 0x45, 0x43}, // 90 - Z
{0x00, 0x7F, 0x41, 0x41, 0x00}, // 91 - [
{0x02, 0x04, 0x08, 0x10, 0x20}, // 92 - Backslash
{0x00, 0x41, 0x41, 0x7F, 0x00}, // 93 - ]
{0x04, 0x02, 0x01, 0x02, 0x04}, // 94 - ^
{0x40, 0x40, 0x40, 0x40, 0x40}, // 95 - _
{0x00, 0x03, 0x05, 0x00, 0x00}, // 96 - `
{0x20, 0x54, 0x54, 0x54, 0x78}, // 97 - a
{0x7F, 0x48, 0x48, 0x48, 0x30}, // 98 - b
{0x38, 0x44, 0x44, 0x44, 0x28}, // 99 - c
{0x30, 0x48, 0x48, 0x48, 0x7F}, // 100 - d
{0x38, 0x54, 0x54, 0x54, 0x18}, // 101 - e
{0x08, 0x7E, 0x09, 0x01, 0x02}, // 102 - f
{0x18, 0xA4, 0xA4, 0xA4, 0x78}, // 103 - g
{0x7F, 0x08, 0x04, 0x04, 0x78}, // 104 - h
{0x00, 0x44, 0x7D, 0x40, 0x00}, // 105 - i
{0x40, 0x80, 0x84, 0x7D, 0x00}, // 106 - j
{0x7F, 0x10, 0x28, 0x44, 0x00}, // 107 - k
{0x00, 0x41, 0x7F, 0x40, 0x00}, // 108 - l
{0x7C, 0x04, 0x78, 0x04, 0x78}, // 109 - m
{0x7C, 0x08, 0x04, 0x04, 0x78}, // 110 - n
{0x38, 0x44, 0x44, 0x44, 0x38}, // 111 - o
{0xFC, 0x18, 0x24, 0x24, 0x18}, // 112 - p
{0x18, 0x24, 0x24, 0x18, 0xFC}, // 113 - q
{0x7C, 0x08, 0x04, 0x04, 0x08}, // 114 - r
{0x48, 0x54, 0x54, 0x54, 0x24}, // 115 - s
{0x04, 0x3F, 0x44, 0x40, 0x20}, // 116 - t
{0x3C, 0x40, 0x40, 0x20, 0x7C}, // 117 - u
{0x1C, 0x20, 0x40, 0x20, 0x1C}, // 118 - v
{0x3C, 0x40, 0x30, 0x40, 0x3C}, // 119 - w
{0x44, 0x28, 0x10, 0x28, 0x44}, // 120 - x
{0x0C, 0x50, 0x50, 0x50, 0x3C}, // 121 - y
{0x44, 0x64, 0x54, 0x4C, 0x44}, // 122 - z
{0x00, 0x08, 0x36, 0x41, 0x00}, // 123 - {
{0x00, 0x00, 0x7F, 0x00, 0x00}, // 124 - |
{0x00, 0x41, 0x36, 0x08, 0x00}, // 125 - }
{0x10, 0x08, 0x08, 0x10, 0x08}, // 126 - ~
};
#define ENCODER_CLK 6
#define ENCODER_DT 7
int lastClk = HIGH;
int count=0;
void setup() {
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
Serial1.begin(9600);
// Initialize I2C (use default I2C pins)
Wire.begin();
Wire.setClock(400000); // Set I2C clock to 400kHz
// Initialize the display
initDisplay();
//clearDisplay();
clearDisplay();
updateDisplay();
// Set cursor to top-left corner
setCursor(0, 0);
// Write text to the display
writeText("Hello, Pi Pico!");
setCursor(0, 1);
writeNumber(22);
}
void loop() {
// Your main code here
int newClk = digitalRead(ENCODER_CLK);
if (newClk != lastClk) {
// There was a change on the CLK pin
lastClk = newClk;
int dtValue = digitalRead(ENCODER_DT);
if (newClk == LOW && dtValue == HIGH) {
Serial1.println("Rotated clockwise ⏩");
clearDisplay();
updateDisplay();
setCursor(0, 1);
writeNumber(++count);
Serial1.print(count);
}
if (newClk == LOW && dtValue == LOW) {
Serial1.println("Rotated counterclockwise ⏪");
clearDisplay();
updateDisplay();
setCursor(0, 1);
writeNumber(--count);
Serial1.print(count);
}
}
}
void initDisplay() {
// Send initialization commands to the display
sendCommand(0xAE); // Display off
sendCommand(0x20); // Set Memory Addressing Mode
sendCommand(0x10); // 00,Horizontal Addressing Mode; 01,Vertical Addressing Mode; 10,Page Addressing Mode (RESET); 11,Invalid
sendCommand(0xB0); // Set Page Start Address for Page Addressing Mode, 0-7
sendCommand(0xC8); // Set COM Output Scan Direction
sendCommand(0x00); // Set low column address
sendCommand(0x10); // Set high column address
sendCommand(0x40); // Set start line address
sendCommand(0x81); // Set contrast control register
sendCommand(0xFF);
sendCommand(0xA1); // Set segment re-map 0 to 127
sendCommand(0xA6); // Set normal display
sendCommand(0xA8); // Set multiplex ratio (1 to 64)
sendCommand(0x3F); //
sendCommand(0xA4); // 0xa4,Output follows RAM content; 0xa5,Output ignores RAM content
sendCommand(0xD3); // Set display offset
sendCommand(0x00); // No offset
sendCommand(0xD5); // Set display clock divide ratio/oscillator frequency
sendCommand(0xF0); // Set divide ratio
sendCommand(0xD9); // Set pre-charge period
sendCommand(0x22); //
sendCommand(0xDA); // Set com pins hardware configuration
sendCommand(0x12);
sendCommand(0xDB); // Set vcomh
sendCommand(0x20); // 0x20,0.77xVcc
sendCommand(0x8D); // Set DC-DC enable
sendCommand(0x14);
sendCommand(0xAF); // Turn on OLED panel
}
void sendCommand(uint8_t command) {
Wire.beginTransmission(SSD1306_I2C_ADDRESS);
Wire.write(0x00); // Co = 0, D/C = 0
Wire.write(command);
Wire.endTransmission();
}
void setCursor(uint8_t col, uint8_t row) {
sendCommand(0xB0 + row); // Set page start address
sendCommand(0x00 + (col & 0x0F)); // Set lower column start address
sendCommand(0x10 + ((col >> 4) & 0x0F)); // Set higher column start address
}
void writeChar(char c) {
if (c < 32 || c > 127) {
c = '?'; // Replace non-printable characters with '?'
}
for (uint8_t i = 0; i < 5; i++) {
sendData(pgm_read_byte(&font5x8[c - 32][i]));
}
sendData(0x00); // Space between characters
}
void sendData(uint8_t data) {
Wire.beginTransmission(SSD1306_I2C_ADDRESS);
Wire.write(0x40); // Co = 0, D/C = 1
Wire.write(data);
Wire.endTransmission();
}
void writeText(const char* text) {
while (*text) {
writeChar(*text++);
}
}
void writeNumber(int32_t num) {
// Handle negative numbers
if (num < 0) {
writeChar('-'); // Write the negative sign
num = -num; // Convert number to positive
}
// Convert number to string
char buf[11]; // Assuming maximum 10 digits + null terminator
sprintf(buf, "%ld", num); // Convert number to string
writeText(buf); // Write the string to the display
}
void clearDisplay() {
memset(buffer, 0, BUFFER_SIZE); // Clear buffer
}
void updateDisplay() {
for (uint8_t page = 0; page < 8; page++) {
setCursor(0, page);
Wire.beginTransmission(SSD1306_I2C_ADDRESS);
Wire.write(0x40);
for (uint8_t col = 0; col < 128; col++) {
Wire.write(buffer[page * 128 + col]);
}
Wire.endTransmission();
}
}