acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
TunerButtons.ino (5269B)
1 /* 2 * Emulate the buttons of a car radio: 3 * 4 * - 3 preset buttons 5 * - 1 tune-up button 6 * - 1 tune-down button 7 * 8 * LongPress of a preset button stores the station. 9 * LongPress of a tune-up or tune-down button scans the radio frequency. 10 */ 11 12 #include <AceButton.h> 13 14 using namespace ace_button; 15 16 const int NUM_PRESETS = 3; 17 18 const int PRESET_1_PIN = 6; 19 const int PRESET_2_PIN = 5; 20 const int PRESET_3_PIN = 4; 21 const int TUNE_DOWN_PIN = 3; 22 const int TUNE_UP_PIN = 2; 23 24 // Frequency range of the FM radio. 25 const uint16_t FM_FREQ_MIN = 879; // 87.9 MHz 26 const uint16_t FM_FREQ_MAX = 1079; // 107.9 MHz 27 const uint16_t FM_FREQ_DELTA = 2; // 0.2 MHz increments in USA 28 29 // Preset buttons use the SystemButtonConfig. 30 AceButton presetButton1; 31 AceButton presetButton2; 32 AceButton presetButton3; 33 34 // Tune up or down buttons use a different ButtonConfig. 35 ButtonConfig tuneConfig; 36 AceButton tuneDownButton(&tuneConfig); 37 AceButton tuneUpButton(&tuneConfig); 38 39 // Array to hold the stations associated with the button whose id is an 40 // index into this array. The value is the 10 * station_frequency (e.g. 88.5 MHz 41 // is stored as 885). 42 // 43 // NOTE: It might be tempting to subclass the AceButton to hold this information 44 // but it's cleaner to keep this info separated from the AceButton class 45 // hierarchy. 46 uint16_t stations[NUM_PRESETS]; 47 48 // The current station frequency. 49 uint16_t currentStation = FM_FREQ_MIN; 50 51 void handlePresetEvent(AceButton*, uint8_t, uint8_t); 52 void handleTuneEvent(AceButton*, uint8_t, uint8_t); 53 54 void setup() { 55 delay(1000); // some boards reboot twice 56 Serial.begin(115200); 57 while (! Serial); // Wait until Serial is ready - Leonardo/Micro 58 Serial.println(F("setup(): begin()")); 59 60 // Configs for the preset buttons. Need Released event to change the station, 61 // and LongPressed to memorize the current station. Don't need Clicked. 62 ButtonConfig* presetConfig = ButtonConfig::getSystemButtonConfig(); 63 presetConfig->setEventHandler(handlePresetEvent); 64 presetConfig->setFeature(ButtonConfig::kFeatureLongPress); 65 presetConfig->setFeature(ButtonConfig::kFeatureSuppressAfterLongPress); 66 67 // Configs for the tune-up and tune-down buttons. Need RepeatPress instead of 68 // LongPress. 69 tuneConfig.setEventHandler(handleTuneEvent); 70 tuneConfig.setFeature(ButtonConfig::kFeatureClick); 71 tuneConfig.setFeature(ButtonConfig::kFeatureRepeatPress); 72 // These suppressions not really necessary but cleaner. 73 tuneConfig.setFeature(ButtonConfig::kFeatureSuppressAfterClick); 74 tuneConfig.setFeature(ButtonConfig::kFeatureSuppressAfterRepeatPress); 75 76 // Preset Button 1 77 pinMode(PRESET_1_PIN, INPUT_PULLUP); 78 presetButton1.init(PRESET_1_PIN, HIGH, 0 /* id */); 79 80 // Preset Button 2 81 pinMode(PRESET_2_PIN, INPUT_PULLUP); 82 presetButton2.init(PRESET_2_PIN, HIGH, 1 /* id */); 83 84 // Preset Button 3 85 pinMode(PRESET_3_PIN, INPUT_PULLUP); 86 presetButton3.init(PRESET_3_PIN, HIGH, 2 /* id */); 87 88 // Tune Down Button 89 pinMode(TUNE_DOWN_PIN, INPUT_PULLUP); 90 tuneDownButton.init(TUNE_DOWN_PIN); 91 92 // Tune Up Button 93 pinMode(TUNE_UP_PIN, INPUT_PULLUP); 94 tuneUpButton.init(TUNE_UP_PIN); 95 96 // init the stations associated with each button 97 initStations(); 98 99 Serial.println(F("setup(): tuner buttons ready")); 100 printStation(currentStation); 101 } 102 103 void loop() { 104 presetButton1.check(); 105 presetButton2.check(); 106 presetButton3.check(); 107 tuneUpButton.check(); 108 tuneDownButton.check(); 109 } 110 111 void initStations() { 112 for (int i = 0; i < NUM_PRESETS; i++) { 113 stations[i] = FM_FREQ_MIN; 114 } 115 } 116 117 void printStation(uint16_t frequency) { 118 Serial.print(F("station: ")); 119 Serial.print(frequency / 10); 120 Serial.print('.'); 121 Serial.println(frequency % 10); 122 } 123 124 void handlePresetEvent(AceButton* button, uint8_t eventType, 125 uint8_t /* buttonState */) { 126 switch (eventType) { 127 case AceButton::kEventReleased: 128 // We trigger on the Released event not the Pressed event to distinguish 129 // this event from the LongPressed event. 130 retrievePreset(button->getId()); 131 break; 132 case AceButton::kEventLongPressed: 133 setPreset(button->getId()); 134 break; 135 } 136 } 137 138 void handleTuneEvent(AceButton* button, uint8_t eventType, 139 uint8_t /* buttonState */) { 140 switch (eventType) { 141 case AceButton::kEventPressed: 142 case AceButton::kEventRepeatPressed: { 143 uint8_t pin = button->getPin(); 144 switch (pin) { 145 case TUNE_UP_PIN: 146 tuneUp(); 147 break; 148 case TUNE_DOWN_PIN: 149 tuneDown(); 150 break; 151 } 152 } 153 } 154 } 155 156 void retrievePreset(uint8_t id) { 157 if (id < NUM_PRESETS) { 158 currentStation = stations[id]; 159 Serial.print(F("memory ")); 160 Serial.print(id + 1); 161 Serial.print(F(": ")); 162 printStation(currentStation); 163 } 164 } 165 166 void setPreset(uint8_t id) { 167 if (id < NUM_PRESETS) { 168 stations[id] = currentStation; 169 170 Serial.print(F("memory ")); 171 Serial.print(id + 1); 172 Serial.print(F(" set: ")); 173 printStation(currentStation); 174 } 175 } 176 177 void tuneUp() { 178 currentStation += FM_FREQ_DELTA; 179 if (currentStation > FM_FREQ_MAX) { 180 currentStation = FM_FREQ_MIN; 181 } 182 printStation(currentStation); 183 } 184 185 void tuneDown() { 186 currentStation -= FM_FREQ_DELTA; 187 if (currentStation < FM_FREQ_MIN) { 188 currentStation = FM_FREQ_MAX; 189 } 190 printStation(currentStation); 191 }