#include <RotaryEncoder.h>
#include <Tone.h>
#include <LiquidCrystal_I2C.h>
#include "Button.hpp"
constexpr byte MAX_HERTZ {15};
constexpr byte MIN_HERTZ {1};
constexpr byte pin_in1 {2};
constexpr byte pin_in2 {3};
constexpr byte pin_btn {4};
constexpr byte pin_led {13};
constexpr byte I2C_ADDR {0x27};
constexpr byte LCD_COLUMNS {16};
constexpr byte LCD_LINES {2};
enum class ProgState : byte {adjust = 0, start, running, stop, idle};
struct EncoderData {
byte pos;
byte newPos;
byte value;
};
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
// RotaryEncoder encoder(pin_in1, pin_in2, RotaryEncoder::LatchMode::FOUR0);
RotaryEncoder encoder(pin_in1, pin_in2, RotaryEncoder::LatchMode::FOUR3);
//RotaryEncoder encoder(pin_in1, pin_in2, RotaryEncoder::LatchMode::TWO03);
Btn::Button btn{pin_btn};
EncoderData encData {0, 0, MIN_HERTZ};
Tone Generator;
void askEncoder(EncoderData& );
void setup()
{
//Serial.begin(115200);
//Serial.println("Start");
btn.begin();
btn.setDebounceTime_ms(150);
lcd.init();
lcd.backlight();
Generator.begin(pin_led);
}
void loop()
{
static byte oldValue {1};
static ProgState state {ProgState::adjust};
askEncoder(encData);
if (encData.value != oldValue) {
oldValue = encData.value;
state = ProgState::adjust;
}
switch (state) {
case ProgState::adjust:
Generator.stop();
char buffer[10]; // Achtung: buffer an Textlänge + 1 anpassen. Sonst gibt es komische Effekte.
sprintf(buffer, "%d Hz", encData.value);
lcd.clear();
lcd.setCursor(4, 0);
lcd.print(buffer);
lcd.setCursor(0, 1);
lcd.print("Aus...");
state = ProgState::idle;
break;
case ProgState::start:
lcd.setCursor(0, 1);
lcd.print("Ein...");
state = ProgState::running;
[[fallthrough]]
case ProgState::running:
Generator.play(encData.value);
break;
default:
break;
}
if (btn.tick()) { // Tasterabfrage
state = ProgState::start;
//Serial.println("Hertz übernommen");
}
}
void askEncoder(EncoderData& data) {
encoder.tick();
data.newPos = encoder.getPosition();
if (data.pos != data.newPos) {
data.pos = data.newPos;
int dir = static_cast<int>(encoder.getDirection());
if (dir >= 0) {
data.value = (++data.value > MAX_HERTZ) ? MIN_HERTZ : data.value;
}
if (dir < 0) {
data.value = (--data.value < MIN_HERTZ) ? MAX_HERTZ : data.value;
}
}
}