#include <Arduino.h>
// Hardware setup:
// Attach a rotary encoder with output pins to A2 and A3.
// The common contact should be attached to ground.
#include <RotaryEncoder.h>
#include <U8g2lib.h>
//#define UPPER_LIMIT 100
#define UPPER_LIMIT 255
#if(UPPER_LIMIT == 255)
#define USE_PWM_MULTIPLIER 0
#else
#define USE_PWM_MULTIPLIER 1
#endif
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
// Setup a RoraryEncoder for pins A2 and A3:
RotaryEncoder encoder(A3, A2);
U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
int pwmpin = 3;
uint8_t buttonpin = 2;
uint8_t ledpin = 7;
uint32_t frequency = 50000;
bool running = true;
uint8_t newButton = HIGH;
uint8_t oldButton = HIGH;
void UpdateDisplay(long newPos, long pos);
void setup()
{
// You may have to modify the next 2 lines if using other pins than A2 and A3
PCICR |= (1 << PCIE1); // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
PCMSK1 |= (1 << PCINT10) | (1 << PCINT11); // This enables the interrupt for pin 2 and 3 of Port C.
pinMode(buttonpin, INPUT_PULLUP);
pinMode(ledpin, OUTPUT);
digitalWrite(ledpin, running);
#if 0
InitTimersSafe(frequency - 10);
bool success = SetPinFrequencySafe(pwmpin, frequency);
if(success)
{
pinMode(pwmpin, OUTPUT);
digitalWrite(pwmpin, LOW);
}
#endif
u8g2.begin();
u8g2.enableUTF8Print();
u8g2.setFontMode(0);
u8g2.setDrawColor(1);
u8g2.firstPage();
do
{
u8g2.setFont(u8g2_font_logisoso32_tn);
uint8_t wid = u8g2.getStrWidth("0");
u8g2.setCursor(64 - wid/2, 63); //bottom, centered
u8g2.print(0);
u8g2.drawFrame(12, 2, 104, 19);
} while (u8g2.nextPage() );
}
/* The Interrupt Service Routine for Pin Change Interrupt 1
This routine will only be called on any signal change on A2 and A3: exactly where we need to check. */
ISR(PCINT1_vect)
{
encoder.tick(); // just call tick() to check the state.
}
// Read the current position of the encoder and print out when changed.
void loop()
{
static long pos = 0;
static RotaryEncoder::Direction direction = RotaryEncoder::Direction::NOROTATION;
unsigned char pwmvalue = 0;
newButton = digitalRead(buttonpin);
if(newButton != oldButton)
{
oldButton = newButton;
if(newButton == LOW)
{
running = !running;
}
}
digitalWrite(ledpin, running);
long newPos = encoder.getPosition();
direction = encoder.getDirection();
if(pos != newPos)
{
if(newPos < 0)
{
newPos = 0;
encoder.setPosition(newPos);
}
if(newPos > UPPER_LIMIT)
{
newPos = UPPER_LIMIT;
encoder.setPosition(newPos);
}
pos = newPos;
#if 0
#if(USE_PWM_MULTIPLIER == 1)
pwmvalue = map(newPos, 0, UPPER_LIMIT, 0, 255);
#else
pwmvalue = newPos;
#endif
if(newPos == 0)
{
digitalWrite(pwmpin, LOW);
}
else if(newPos == UPPER_LIMIT)
{
digitalWrite(pwmpin, HIGH);
}
else
{
pwmWrite(pwmpin, pwmvalue);
}
#endif
}
UpdateDisplay(newPos, pos);
}
void UpdateDisplay(long newPos, long pos)
{
char theStr[10];
memset(theStr, 0, sizeof(theStr));
u8g2.firstPage();
do
{
u8g2.setFont(u8g2_font_logisoso32_tn);
uint8_t wid = u8g2.getStrWidth(itoa(newPos, theStr, 10));
u8g2.setCursor(64 - wid/2, 63 ); // bottom, centered
u8g2.setDrawColor(1);
u8g2.print(newPos);
u8g2.drawFrame(12, 2, 104, 19);
u8g2.setDrawColor(0);
u8g2.drawBox(13, 3, 102, 17);
u8g2.setDrawColor(1);
u8g2.drawBox(14, 4, pos, 15);
u8g2.setFont(u8g2_font_7x13B_tf);
u8g2.setCursor(0,63);
if(!running)
{
u8g2.print("OFF");
}
else
{
u8g2.setDrawColor(0);
u8g2.drawBox(0,63,20,56);
}
} while(u8g2.nextPage());
}