Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <LiquidCrystal.h>
- LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
- int lcd_key = 0;
- int adc_key_in = 0;
- #define btnRIGHT 0
- #define btnUP 1
- #define btnDOWN 2
- #define btnLEFT 3
- #define btnSELECT 4
- #define btnNONE 5
- int read_LCD_buttons()
- {
- adc_key_in = analogRead(0);
- if (adc_key_in > 1000) return btnNONE;
- if (adc_key_in < 50) return btnRIGHT;
- if (adc_key_in < 250) return btnUP;
- if (adc_key_in < 450) return btnDOWN;
- if (adc_key_in < 650) return btnLEFT;
- if (adc_key_in < 850) return btnSELECT;
- return btnNONE;
- }
- void setup()
- {
- Serial.begin (115200);
- lcd.begin(16, 2);
- lcd.setCursor(0,0);
- lcd.print("Push the buttons");
- }
- int repeat, lastButton = 0;
- unsigned long nextCheck = 0;
- static byte pml009State[17] = {
- 0x0B, 0x58, 0x58, 0x00,
- 0x00, 0x00, 0xB0, 0x00,
- 0x00, 0x10, 0x00, 0x40,
- 0x40, 0xC0, 0x86, 0xC0,
- 0x86
- };
- byte readState(byte byteIdx, byte bitShift, byte mask)
- {
- return (byte)((pml009State[byteIdx] & mask) >> bitShift);
- }
- void writeState(int value, byte byteIdx, byte bitShift, byte mask)
- {
- pml009State[byteIdx] = (byte)(pml009State[byteIdx] & ~mask | (value << bitShift));
- }
- const byte
- byteEqHigh = 3,
- byteEqMid = 4,
- byteEqLow = 5,
- byteLoudness = 6,
- byteEqTreble = 7,
- byteEqBass = 8,
- byteSubwoofer = 9;
- class Menu {
- public:
- virtual void processButton(int key, int repeat) = 0;
- virtual void show() = 0;
- protected:
- printSignedInteger(int value) {
- if (value > 0) lcd.write('+');
- else if (value == 0) lcd.write(' ');
- lcd.print(value);
- }
- };
- class EqMenu : public Menu {
- private:
- byte bandByte = byteEqLow;
- int getCurrentValue() {
- return
- (readState(bandByte, 3, 0b00001000) ? -1 : +1) *
- readState(bandByte, 0, 0b00000111);
- }
- void processButton(int key, int repeat) override {
- int delta = 0;
- if (key == btnRIGHT) bandByte = max(byteEqHigh, bandByte - 1);
- else if (key == btnLEFT) bandByte = min(byteEqLow, bandByte + 1);
- else if (key == btnUP) delta = +1;
- else if (key == btnDOWN) delta = -1;
- if (delta != 0) {
- int newValue = min(+6, max(-6, getCurrentValue() + delta));
- writeState(abs(newValue), bandByte, 0, 0b00000111);
- writeState(newValue >= 0 ? 0 : 1, bandByte, 3, 0b00001000);
- }
- }
- void show() override {
- switch (bandByte) {
- case byteEqLow:
- lcd.print("EQ Low: ");
- break;
- case byteEqMid:
- lcd.print("EQ Mid: ");
- break;
- case byteEqHigh:
- lcd.print("EQ High: ");
- break;
- }
- printSignedInteger(getCurrentValue());
- }
- };
- class BassTrebleMenu : public Menu {
- private:
- byte bandByte = byteEqBass;
- int getCurrentValue(int shift) {
- return
- (readState(bandByte, shift + 3, 0b00001000 << shift) ? -1 : +1) *
- readState(bandByte, shift, 0b00000111 << shift);
- }
- void processButton(int key, int repeat) override {
- int delta = 0;
- if (key == btnRIGHT) bandByte = max(byteEqTreble, bandByte - 1);
- else if (key == btnLEFT) bandByte = min(byteEqBass, bandByte + 1);
- else if (key == btnUP) delta = +1;
- else if (key == btnDOWN) delta = -1;
- if (delta != 0) {
- auto shift = (bandByte == byteEqBass ? 1 : 2);
- int newValue = min(+6, max(-6, getCurrentValue(shift) + delta));
- writeState(abs(newValue), bandByte, shift, 0b00000111 << shift);
- writeState(newValue >= 0 ? 0 : 1, bandByte, shift + 3, 0b00001000 << shift);
- }
- }
- void show() override {
- switch (bandByte) {
- case byteEqBass:
- lcd.print("Bass: ");
- break;
- case byteEqTreble:
- lcd.print("Treble: ");
- break;
- }
- printSignedInteger(getCurrentValue(bandByte == byteEqBass ? 1 : 2));
- }
- };
- class LoudnessMenu : public Menu {
- private:
- int lastActiveMode = 1;
- const byte modes[3] = { 4, 11, 15 };
- public:
- void processButton(int key, int repeat) override {
- if (key == btnUP) writeState(modes[lastActiveMode], 6, 4, 0b11110000);
- else if (key == btnDOWN) writeState(0, 6, 4, 0b11110000);
- else if (key == btnLEFT) lastActiveMode = max(0, lastActiveMode - 1 );
- else if (key == btnRIGHT) lastActiveMode = min(2, lastActiveMode + 1 );
- if (readState(6, 4, 0b11110000)) writeState(modes[lastActiveMode], 6, 4, 0b11110000);
- }
- void show() override {
- lcd.print("Loudness: ");
- switch(readState(6, 4, 0b11110000)) {
- case 0:
- lcd.print("OFF");
- break;
- case 4:
- lcd.print("LOW");
- break;
- case 11:
- lcd.print("MID");
- break;
- case 15:
- lcd.print("HIGH");
- break;
- }
- }
- };
- class SubSwitchMenu : public Menu {
- private:
- int lastActiveMode = 1;
- public:
- void processButton(int key, int repeat) override {
- auto state = readState(9, 3, 0b111000);
- if (state & 0b11) lastActiveMode = state;
- if (key == btnUP) writeState(lastActiveMode, 9, 3, 0b111000);
- else if (key == btnDOWN) writeState(0, 9, 3, 0b11000);
- else if (key == btnLEFT && (state & 0b11)) writeState(0, 9, 5, 0b100000);
- else if (key == btnRIGHT && (state & 0b11)) writeState(1, 9, 5, 0b100000);
- }
- void show() override {
- lcd.print("Sub: ");
- if (readState(9, 3, 0b11000)) {
- lcd.print(readState(9, 3, 0b100000) ? "REVERSE" : "NORMAL");
- } else {
- lcd.print("OFF");
- }
- }
- };
- class SubLevelsMenu : public Menu {
- private:
- int level;
- public:
- void processButton(int key, int repeat) override {
- auto cutoff = readState(9, 3, 0b11000);
- if (key == btnUP) level = min(+6, level + 1);
- else if (key == btnDOWN) level = max(-6, level - 1);
- else if (key == btnLEFT) writeState(max(1, cutoff - 1), 9, 3, 0b11000);
- else if (key == btnRIGHT) writeState(min(3, cutoff + 1), 9, 3, 0b11000);
- }
- void show() override {
- lcd.print("Sub: ");
- switch(readState(9, 3, 0b11000)) {
- case 0:
- lcd.print("off ");
- break;
- case 1:
- lcd.print("50 Hz ");
- break;
- case 2:
- lcd.print("80 Hz ");
- break;
- case 3:
- lcd.print("125 Hz ");
- break;
- }
- printSignedInteger(level);
- }
- };
- class HighpassMenu : public Menu {
- public:
- void processButton(int key, int repeat) override {
- auto cutoff = readState(9, 6, 0b11000000);
- if (key == btnLEFT) writeState(max(0, cutoff - 1), 9, 6, 0b11000000);
- else if (key == btnRIGHT) writeState(min(3, cutoff + 1), 9, 6, 0b11000000);
- }
- void show() override {
- lcd.print("HPF: ");
- switch(readState(9, 6, 0b11000000)) {
- case 0:
- lcd.print("off ");
- break;
- case 1:
- lcd.print("50 Hz ");
- break;
- case 2:
- lcd.print("80 Hz ");
- break;
- case 3:
- lcd.print("125 Hz ");
- break;
- }
- }
- };
- class MainMenu : public Menu {
- private:
- Menu* menus[6] = { new EqMenu(), new BassTrebleMenu(), new LoudnessMenu(), new SubSwitchMenu(), new SubLevelsMenu(), new HighpassMenu() };
- int currentMenu = 0;
- public:
- void processButton(int key, int repeat) override {
- if (key == btnSELECT && repeat == 0) {
- currentMenu = (currentMenu + 1) % 6;
- } else {
- menus[currentMenu]->processButton(key, repeat);
- }
- }
- void show() override {
- menus[currentMenu]->show();
- }
- };
- class FreqMenu : public Menu {
- private:
- int bandByte = byteEqLow;
- public:
- void processButton(int key, int repeat) override {
- if (key == btnSELECT && repeat == 0) {
- switch (bandByte) {
- case byteEqLow: bandByte = byteEqMid; break;
- case byteEqMid: bandByte = byteEqHigh; break;
- case byteEqHigh: bandByte = byteEqBass; break;
- case byteEqBass: bandByte = byteEqTreble; break;
- case byteEqTreble: bandByte = byteEqLow; break;
- }
- }
- if (key == btnUP && bandByte <= byteEqBass) {
- auto q = readState(bandByte, 6, 0b11000000);
- writeState(min(3, q + 1), bandByte, 6, 0b11000000);
- }
- else if (key == btnDOWN && bandByte <= byteEqBass) {
- auto q = readState(bandByte, 6, 0b11000000);
- writeState(max(0, q - 1), bandByte, 6, 0b11000000);
- }
- byte shift, mask;
- switch (bandByte) {
- case byteEqLow:
- case byteEqMid:
- case byteEqHigh:
- shift = 4; mask = 0b110000;
- break;
- case byteEqBass:
- shift = 5; mask = 0b1100000;
- break;
- case byteEqTreble:
- shift = 6; mask = 0b11000000;
- break;
- }
- if (key == btnLEFT) {
- auto center = readState(bandByte, shift, mask);
- writeState(max(0, center - 1), bandByte, shift, mask);
- }
- else if (key == btnRIGHT) {
- auto center = readState(bandByte, shift, mask);
- writeState(min(3, center + 1), bandByte, shift, mask);
- }
- }
- void show() override {
- switch (bandByte) {
- case byteEqLow:
- lcd.print("L: ");
- switch(readState(bandByte, 4, 0b110000)) {
- case 0: lcd.print("40"); break;
- case 1: lcd.print("80"); break;
- case 2: lcd.print("100"); break;
- case 3: lcd.print("160"); break;
- }
- break;
- case byteEqMid:
- lcd.print("M: ");
- switch(readState(bandByte, 4, 0b110000)) {
- case 0: lcd.print("200"); break;
- case 1: lcd.print("500"); break;
- case 2: lcd.print("1k"); break;
- case 3: lcd.print("2k"); break;
- }
- break;
- case byteEqHigh:
- lcd.print("H: ");
- switch(readState(bandByte, 4, 0b110000)) {
- case 0: lcd.print("3k"); break;
- case 1: lcd.print("8k"); break;
- case 2: lcd.print("10k"); break;
- case 3: lcd.print("12k"); break;
- }
- break;
- case byteEqBass:
- lcd.print("B: ");
- switch(readState(bandByte, 5, 0b1100000)) {
- case 0: lcd.print("160"); break;
- case 1: lcd.print("100"); break;
- case 2: lcd.print("63"); break;
- case 3: lcd.print("40"); break;
- }
- break;
- case byteEqTreble:
- lcd.print("T: ");
- switch(readState(bandByte, 6, 0b11000000)) {
- case 0: lcd.print("10k"); break;
- case 1: lcd.print("6k"); break;
- case 2: lcd.print("4k"); break;
- case 3: lcd.print("2k"); break;
- }
- break;
- }
- if (bandByte <= byteEqLow) {
- lcd.write('/');
- switch (readState(bandByte, 6, 0b11000000)){
- case 0: lcd.print("2W"); break;
- case 1: lcd.print("1W"); break;
- case 2: lcd.print("1N"); break;
- case 3: lcd.print("2N"); break;
- }
- }
- }
- };
- class RootMenu : public Menu {
- private:
- Menu* menus[2] = { new MainMenu(), new FreqMenu() };
- int currentMenu = 0;
- public:
- void processButton(int key, int repeat) override {
- if (key == btnSELECT && repeat == 2) {
- currentMenu = (currentMenu + 1) % 2;
- } else {
- menus[currentMenu]->processButton(key, repeat);
- }
- show();
- Serial.write(0xFF);
- Serial.write(pml009State + 3, 7);
- }
- void show() override {
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print(currentMenu == 0 ? "> " : " ");
- menus[0]->show();
- lcd.setCursor(0,1);
- lcd.print(currentMenu == 1 ? "> " : " ");
- menus[1]->show();
- lcd.setCursor(13,1);
- lcd.print(pml009State[1]);
- }
- };
- RootMenu root;
- // filter by:
- // repeat==2 is long press (use greater number for longer delay)
- // repeat==0 is short single press
- // repeat>=1 is repeated action
- int inputPos = 0;
- unsigned long inputTimer = 0;
- void loop()
- {
- while(Serial.available()) {
- if (millis() - inputTimer < 100 && inputPos > 0) {
- pml009State[inputPos++] = Serial.read();
- if (inputPos > 9) {
- inputPos = 0;
- inputTimer = 0;
- root.show();
- }
- }
- else if (Serial.read() == 0xFF) { // sync
- inputPos = 3;
- inputTimer = millis();
- }
- }
- lcd_key = read_LCD_buttons();
- if (lcd_key < btnNONE && millis() >= nextCheck) {
- ++repeat;
- lastButton = lcd_key;
- if (repeat > 1) {
- root.processButton(lcd_key, repeat);
- }
- nextCheck = millis() + (repeat > 1 ? 150 : 500);
- }
- else if (lcd_key == btnNONE && nextCheck > millis()) {
- if (repeat == 1) {
- root.processButton(lastButton, repeat = 0);
- }
- nextCheck = 0;
- repeat = 0;
- }
- }
Add Comment
Please, Sign In to add comment