#define sketchname "Pico_SSD1306Ascii"
/*-----------------------------------------------------------------------------------
Autor : Reinhold Wenzl, August 2022
Board : RaspberryPi Pico
Display : SSD1306, I2C
Encoder : KY-040
Pico Display Encoder
GP2 DT
GP3 CLK
GP4 SDA
GP5 SCL
GP6 SW
-----------------------------------------------------------------------------------
https://github.com/mathertel/RotaryEncoder
https://github.com/greiman/SSD1306Ascii
+--------------------------+ +---------------+
| 0 | | 0 font 12x16 |
| 8 | | 16 123456789# |
| 16 font 6x8 | | 32 1 |
| 24 | | 48 123467890 |
| 32 123456789#123456789#1 | | 0246802468 |
| 40 | +---------------+
| 48 1111 |
| 56 1123344566778990012 |
| 062840628406284062840 |
+--------------------------+
*/
#define accelerator
// https://github.com/greiman/SSD1306Ascii
//#include <Wire.h>
//#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
// https://github.com/mathertel/RotaryEncoder
#include <RotaryEncoder.h>
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
#define PIN_IN1 2
#define PIN_IN2 3
#define SW 6
/*------------------------------------------------------------------------------*/
/*----- RotaryEncoder ----------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);
// the maximum acceleration is 10 times.
constexpr float m = 10;
// at 200ms or slower, there should be no acceleration. (factor 1)
constexpr float longCutoff = 50;
// at 5 ms, we want to have maximum acceleration (factor m)
constexpr float shortCutoff = 5;
// To derive the calc. constants, compute as follows:
// On an x(ms) - y(factor) plane resolve a linear formular factor(ms) = a * ms + b;
// where f(4)=10 and f(200)=1
constexpr float a = (m - 1) / (shortCutoff - longCutoff);
constexpr float b = 1 - longCutoff * a;
// a global variables to hold the last position
static int lastPos = 0;
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
SSD1306AsciiWire oled;
/*------------------------------------------------------------------------------*/
/*----- S E T U P --------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
void setup() {
Serial1.begin(9600);
Wire.begin();
Wire.setClock(400000L);
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.setFont(Adafruit5x7); // 8 Zeilen je 21 Zeichen
//oled.setFont(font5x7); // 8 Zeilen je 21 Zeichen
//oled.setFont(ZevvPeep8x16); // 4 Zeilen je 16 Zeichen
oled.clear();
#ifdef accelerator
// ---------------------- nur Test
oled.println("0....5....0....5....0.");
oled.println("0....5....0....5....0.");
oled.println("0....5....0....5....0.");
oled.println("0....5....0....5....0.");
oled.println("0....5....0....5....0.");
oled.println("0....5....0....5....0.");
oled.println("0....5....0....5....0.");
oled.println("0....5....0....5....0.");
delay(2000);
oled.clear(60, 90, 1, 3); // Spalte, Zeile, Anzahl Zeichen
delay(5000);
// end ---------------------- nur Test
oled.clear();
oled.set2X(); // die folgenden Anzeigen in set2X
oled.print("Pos: "); // Text in Spalte 0-4
Serial1.println("Accelerated example");
Serial1.print("a=");
Serial1.println(a);
Serial1.print("b=");
Serial1.println(b);
#else //#ifdef accelerator
#endif //#ifdef accelerator
}
/*------------------------------------------------------------------------------*/
/*----- L O O P ----------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
void loop()
{
encoder.tick();
#ifdef accelerator
int newPos = encoder.getPosition();
if (lastPos != newPos) {
// accelerate when there was a previous rotation in the same direction.
unsigned long ms = encoder.getMillisBetweenRotations();
if (ms < longCutoff) {
// do some acceleration using factors a and b
// limit to maximum acceleration
if (ms < shortCutoff) {
ms = shortCutoff;
}
float ticksActual_float = a * ms + b;
Serial1.print(" f= ");
Serial1.println(ticksActual_float);
long deltaTicks = (long)ticksActual_float * (newPos - lastPos);
Serial1.print(" d= ");
Serial1.println(deltaTicks);
newPos = newPos + deltaTicks;
encoder.setPosition(newPos);
}
oled.setCursor(60, 0);
// 5 Zeichen *6 pixel *2 bei einem 5x7 font in doublesize (set2X)
// in Zeile 0
oled.clearToEOL();
oled.print(newPos);
Serial1.print(newPos);
Serial1.print(" ms: ");
Serial1.println(ms);
lastPos = newPos;
}
#else //#ifdef accelerator
int newPos = encoder.getPosition();
if (lastPos != newPos)
{
oled.setCursor(60, 0);
oled.clearToEOL();
oled.print(newPos);
lastPos = newPos;
}
#endif //#ifdef accelerator
}