Skip to content

Instantly share code, notes, and snippets.

@tobozo
Created November 12, 2017 18:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tobozo/14e6b8e605d500caa9dfbfb1548c71a1 to your computer and use it in GitHub Desktop.
Save tobozo/14e6b8e605d500caa9dfbfb1548c71a1 to your computer and use it in GitHub Desktop.
3 Way button + OLED UI test as seen at https://youtu.be/q8qFv8Y6cdM
/*
* 3 Way button + OLED UI test as seen at https://youtu.be/q8qFv8Y6cdM
*
* Copyleft (c+) tobozo Nov 2017
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the “Software”), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* The Software is provided “as is”, without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability, fitness
* for a particular purpose and noninfringement. In no event shall the authors or
* copyright holders be liable for any claim, damages or other liability, whether
* in an action of contract, tort or otherwise, arising from, out of or in
* connection with the software or the use or other dealings in the Software.
*
*
* Button Panel (A.K.A. "5-Pin 3-Way Momentary Push Button SMD/SMT Mini Tactile Switch")
* -------------------------------------------------------------------------------------
*
* _=/\\=_
* _//=-----=\\_
* SWIN <--|A] [X|
* | |
* | _ _ _ |
* | [B] [C] [D] |
* \--|---|---|--/
* | | |
* R100K | R1K
* | R10K |
* SWOUT <----+---+---+
*
*
*
* Arduino Nano PINOUT:
* --------------------
*
* UI PANEL | Arduino NANO
* -----------+--------------
* OLED SDA | A4
* OLED SCL | A5
* OLED VCC | 3.3v
* OLED GND | GND
* SWOUT | A2
* SWIN | A1
*
*
*
*/
#include "TimerOne.h"
#include <Wire.h>
#include "U8g2lib.h"
// Scrolling #defines (from https://github.com/adafruit/Adafruit_SSD1306/blob/master/Adafruit_SSD1306.h#L135)
#define SSD1306_ACTIVATE_SCROLL 0x2F
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
// button states (may be adjusted)
#define BUTTON_RIGHT 0
#define BUTTON_NEUTRAL 4
#define BUTTON_LEFT 3
#define BUTTON_CLICK 1
#define SWIN A1 // OUTPUT
#define SWOUT A2 // INPUT_PULLUP
/* hackerzvoice logo */
const uint8_t hzv_logo[] PROGMEM {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x03, 0x40, 0x00, 0x00, 0x02,
0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x78, 0x00, 0x00, 0x1e,
0x08, 0x00, 0xfc, 0x11, 0x08, 0x00, 0xfc, 0x11, 0x08, 0x00, 0xfc, 0x11,
0x88, 0x3f, 0xfc, 0x11, 0x88, 0x3f, 0xfc, 0x11, 0x88, 0x3f, 0xfc, 0x11,
0x88, 0x3f, 0xfc, 0x11, 0x08, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x10,
0x08, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x10, 0x78, 0x00, 0x00, 0x1e,
0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x3c, 0x3c, 0x02,
0x40, 0x24, 0x24, 0x02, 0x40, 0x24, 0x24, 0x02, 0x40, 0x24, 0x24, 0x02,
0xc0, 0xe7, 0xe7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* a pumpkin */
const uint8_t halloween_bits[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00,
0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xff, 0xff, 0x01,
0xc0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x1f,
0xf8, 0xff, 0xff, 0x3f, 0xf8, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xcf, 0x3f,
0xfc, 0xff, 0xc7, 0x7f, 0xfc, 0xc7, 0xc3, 0x73, 0xfc, 0x87, 0xc1, 0x73,
0xfc, 0x8f, 0xf1, 0x71, 0xfc, 0xff, 0xff, 0x70, 0xfc, 0xff, 0x7f, 0x60,
0x3c, 0xff, 0x3f, 0x60, 0x3c, 0xfe, 0x0f, 0x60, 0x3c, 0x30, 0x00, 0x70,
0x3c, 0x00, 0x00, 0x30, 0x78, 0xf8, 0xff, 0x39, 0x70, 0xfe, 0xff, 0x1f,
0xf0, 0xff, 0xff, 0x1f, 0xe0, 0xff, 0xff, 0x0f, 0x80, 0xff, 0xff, 0x03,
0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00
};
// U8G2 does not require to mess with the library settings to get the 128x32 OLED to work
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C display(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
byte pos, lastpos;
bool changed = false;
bool hacktheplanet = true; // toggle between two states
void buttonScan() {
int val2 = analogRead( SWOUT );
pos = map(val2, 0, 1024, 0, 5); // adjust the last value this to fit your resistors
if(pos!=lastpos) {
changed = true;
lastpos = pos;
} else {
changed = false;
}
}
void screenDrawIntro() {
hacktheplanet = !hacktheplanet;
display.clearDisplay();
display.setFont(u8g_font_7x13);
display.firstPage();
do {
display.drawStr(10, 14, hacktheplanet ? "Hack" : " Eat");
display.drawStr(9, 27, hacktheplanet ? " The" : "More");
display.drawStr(76, 20, hacktheplanet ? "Planet!" : "Chicken");
display.drawXBMP(40, 0, 32, 32, hacktheplanet ? hzv_logo : halloween_bits);
} while(display.nextPage() );
delay(500);
}
void screenScroll(uint8_t scrollDirection, uint8_t start, uint8_t stop) {
// I wonder why u8g2lib does not handle SSD1306's native scrolling
u8x8_cad_SendCmd( display.getU8x8(), scrollDirection);
u8x8_cad_SendCmd( display.getU8x8(), 0X00);
u8x8_cad_SendCmd( display.getU8x8(), start);
u8x8_cad_SendCmd( display.getU8x8(), 0X00);
u8x8_cad_SendCmd( display.getU8x8(), stop);
u8x8_cad_SendCmd( display.getU8x8(), 0X00);
u8x8_cad_SendCmd( display.getU8x8(), 0XFF);
u8x8_cad_SendCmd( display.getU8x8(), SSD1306_ACTIVATE_SCROLL);
}
void screenStopScroll() {
u8x8_cad_SendCmd( display.getU8x8(), SSD1306_DEACTIVATE_SCROLL);
}
void setup() {
pinMode(SWIN, OUTPUT);
pinMode(SWOUT, INPUT_PULLUP);
Timer1.initialize(50000); // initialize timer1, and set a 1/20th second period
Timer1.attachInterrupt(buttonScan); // attaches buttonScan as a timer overflow interrupt
display.begin();
screenDrawIntro();
}
void loop() {
switch(pos) {
case BUTTON_RIGHT:
screenScroll(SSD1306_RIGHT_HORIZONTAL_SCROLL, 0x00, 0x0F);
delay(100);
screenStopScroll();
break;
case BUTTON_LEFT:
screenScroll(SSD1306_LEFT_HORIZONTAL_SCROLL, 0x00, 0x0F);
delay(100);
screenStopScroll();
break;
case BUTTON_CLICK:
screenDrawIntro();
break;
default:
// Serial.println(pos); // uncomment this when calibrating
break;
case BUTTON_NEUTRAL:
// nothing to do
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment