Skip to content

Add support for SH110X #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ I like to use the SSD1306-based displays in Particle projects. They're small and
- 128 x 32 short
- 128 x 64 yellow and blue, with the top 16 pixels yellow and the rest blue

There's also support for SH110X OLED displays:
- 128 x 128 white (1.5")

They're available with I2C and SPI interfaces. I recommend I2C; it's fewer pins (D0 and D1 only) and the added speed of SPI is not worth the effort in my opinion.

On Particle devices, the [Adafruit GFX library](https://github.com/adafruit/Adafruit-GFX-Library) is typically used to draw to the display. It works great, but it's kind of a pain to have to adjust a pixel or two, recompile and flash your code, and repeat the process over and over.
Expand Down Expand Up @@ -87,6 +90,12 @@ It also generates the C++ display code, including the GFX calls, any additional

The Javascript code takes the display bitmap and renders it on a HTML5 canvas in normal and zoomed size.

## Running Locally:
Run the following command and open `http://localhost:8000/public/` in your browser:

```
python -m http.server 8000
```

## Releases

Expand Down
28 changes: 13 additions & 15 deletions public/editor.css
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
body
{
background-color:#ffffff;
max-width:800;
body {
background-color:#ffffff;
max-width:800;
margin: auto;
padding-top: 1rem;
}

p,h1,h2,h3,li,td,div
{
font-family: helvetica, sans-serif;
color:#000000;
font-size: medium;
p, h1, h2, h3, li, td, div {
font-family: helvetica, sans-serif;
color:#000000;
font-size: medium;
}

div.selectedCommand
{
background-color:#ffee67;
div.selectedCommand {
background-color:#ffee67;
}

textarea.code
{
font-family: monospace;
textarea.code {
font-family: monospace;
}
57 changes: 33 additions & 24 deletions public/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// Repository: https://github.com/rickkas7/DisplayGenerator
// License: MIT

var screenx = 128;
var screeny = 64;
var maxScreenX = 128;
var maxScreenY = 128;
var currentScreenX = 128;
var currentScreenY = 64;
var zoom = 3;
var margin = 4;
var showMini = true;
Expand All @@ -23,10 +25,10 @@ var Module = {
onRuntimeInitialized: function() {
// console.log('Enscripten loaded!');

// Create an Adafruit GFX 1-bit deep bitmap of screenx x screeny pixels
// Create an Adafruit GFX 1-bit deep bitmap of maxScreenX and maxScreenY pixels
// Note: when using the short display the GFX screen size is still set at
// 128x64, it's just the bottom half isn't rendered to the screen.
gfx = new Module.TestGFX(screenx, screeny);
gfx = new Module.TestGFX(maxScreenX, maxScreenY);

initializeVue();
}
Expand Down Expand Up @@ -229,7 +231,7 @@ function initializeVue() {
},
moveUpCommand: function() {
if (this.selectedCommandId > 0) {
for(var ii = 1; ii < mainApp.commands.length - 1; ii++) {
for(var ii = 1; ii < mainApp.commands.length; ii++) {
var cmd = mainApp.commands[ii];
if (cmd.id == this.selectedCommandId) {
mainApp.commands[ii] = mainApp.commands[ii - 1];
Expand Down Expand Up @@ -386,15 +388,15 @@ function initializeVue() {
if (cx < 0) {
cx = 0;
}
if (cx > screenx) {
cx = screenx;
if (cx > currentScreenX) {
cx = currentScreenX;
}
var cy = Math.round((y - margin) / zoom);
if (cy < 0) {
cy = 0;
}
if (cy > screeny) {
cy = screeny;
if (cy > currentScreenY) {
cy = currentScreenY;
}

this.coordinates = '(' + cx + ', ' + cy + ')';
Expand Down Expand Up @@ -425,11 +427,16 @@ function initializeVue() {
handler(val) {
if (val === 'short') {
// 128x32
screeny = 32;
currentScreenY = 32;
}
else if (val === 'SH110X_large') {
// 128x128
currentScreenX = 128;
currentScreenY = 128;
}
else {
// 128x64
screeny = 64;
currentScreenY = 64;
}

document.getElementById('mainCanvas').height = mainCanvasHeight();
Expand Down Expand Up @@ -837,23 +844,23 @@ function initializeVue() {
switch(this.standardLogoSelect) {
case 'p128x32':
selectedCmd.x = 0;
selectedCmd.y = (screeny == 32) ? 0 : 16;
selectedCmd.y = (currentScreenY == 32) ? 0 : 16;
selectedCmd.width = 128;
selectedCmd.height = 32;
selectedCmd.bitmap = particle128x32;
break;

case 'p32x32':
selectedCmd.x = 48;
selectedCmd.y = (screeny == 32) ? 0 : 16;
selectedCmd.y = (currentScreenY == 32) ? 0 : 16;
selectedCmd.width = 32;
selectedCmd.height = 32;
selectedCmd.bitmap = particle32x32;
break;

case 'p48x48':
selectedCmd.x = 40;
selectedCmd.y = (screeny == 32) ? -8 : 8;
selectedCmd.y = (currentScreenY == 32) ? -8 : 8;
selectedCmd.width = 48;
selectedCmd.height = 48;
selectedCmd.bitmap = particle48x48;
Expand Down Expand Up @@ -1069,13 +1076,15 @@ function processCommands() {


case 'setTextColor':
const colorPrex = mainApp.displayType === 'SH110X_large' ? 'SH110X_' : '';

if (!cmd.invert) {
gfx.setTextColor(1);
codeImpl += indent + gfxClass + 'setTextColor(WHITE);\n';
codeImpl += indent + gfxClass + `setTextColor(${colorPrex}WHITE);\n`;
}
else {
gfx.setTextColor2(0, 1);
codeImpl += indent + gfxClass + 'setTextColor(BLACK, WHITE);\n';
codeImpl += indent + gfxClass + `setTextColor(${colorPrex}BLACK, ${colorPrex}WHITE);\n`;
}
break;

Expand Down Expand Up @@ -1106,7 +1115,7 @@ function processCommands() {

var cursorY = gfx.getCursorY();
cmd.width = gfx.measureTextX(cmd.text);
var cursorX = Math.floor((screenx / 2) - (cmd.width / 2));
var cursorX = Math.floor((currentScreenX / 2) - (cmd.width / 2));

gfx.setCursor(cursorX, cursorY);
codeImpl += indent + gfxClass + 'setCursor(' + cursorX + ', ' + cursorY + ');\n';
Expand Down Expand Up @@ -1161,13 +1170,13 @@ function mainCanvasY(y) {
return margin + y * zoom + ((mainApp.displayType === 'yellow' && y >= yellowTopSize) ? zoom : 0);
}
function mainCanvasWidth() {
return (2 * margin) + (screenx * zoom);
return (2 * margin) + (currentScreenX * zoom);
}
function mainCanvasHeight() {
return (2 * margin) + (screeny * zoom) + ((mainApp.displayType === 'yellow') ? zoom : 0);
return (2 * margin) + (currentScreenY * zoom) + ((mainApp.displayType === 'yellow') ? zoom : 0);
}
function miniCanvasLeft() {
return (screenx * zoom) + (2 * margin) + miniSeparator;
return (currentScreenX * zoom) + (2 * margin) + miniSeparator;
}
function miniCanvasX(x) {
return miniCanvasLeft() + miniMargin + x;
Expand All @@ -1176,10 +1185,10 @@ function miniCanvasY(y) {
return miniMargin + y + ((mainApp.displayType === 'yellow' && y >= yellowTopSize) ? 1 : 0);
}
function miniCanvasWidth() {
return (2 * miniMargin) + screenx;
return (2 * miniMargin) + currentScreenX;
}
function miniCanvasHeight() {
return (2 * miniMargin) + screeny + ((mainApp.displayType === 'yellow') ? 1 : 0);
return (2 * miniMargin) + currentScreenY + ((mainApp.displayType === 'yellow') ? 1 : 0);
}

function render() {
Expand All @@ -1204,7 +1213,7 @@ function render() {


var byteIndex = 0;
for(var yy = 0; yy < screeny; yy++) {
for(var yy = 0; yy < currentScreenY; yy++) {
if (yellow) {
if (yy < yellowTopSize) {
ctx.fillStyle = displayYellow;
Expand All @@ -1213,7 +1222,7 @@ function render() {
ctx.fillStyle = displayBlue;
}
}
for(var xx = 0; xx < screenx; xx += 8) {
for(var xx = 0; xx < currentScreenX; xx += 8) {
var pixel8 = bytes[byteIndex++];

for(var ii = 0; ii < 8; ii++) {
Expand Down
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<option value="normal">128 x 64 (normal)</option>
<option value="short">128 x 32 (short)</option>
<option value="yellow">128 x 64 (yellow and blue)</option>
<option value="SH110X_large">128 x 128 (normal) (SH110X)</option>
</select>

<input type="checkbox" v-model="invertDisplay" id="invertCheckbox"/><label for="invertCheckbox">Invert Display</label>
Expand Down