Last active
September 8, 2025 05:19
-
-
Save tomasen/913694611507c334e991a72808124055 to your computer and use it in GitHub Desktop.
IR bridge that maps Samsung TV Vol+/Vol−/Mute to Integra/Onkyo AVR commands using an Adafruit Metro Mini 328 V2 and IRremote.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Metro Mini 328 V2 / Arduino Uno | |
| // Wiring: | |
| // PIN2 → TSOP38238 OUT | |
| // GND → TSOP38238 GND | |
| // 5V → TSOP38238 VCC | |
| // 5V → 0.1µF capacitor → TSOP38238 VCC | |
| // PIN3 → 1kΩ → PN2222 base | |
| // GND → PN2222 emitter | |
| // PN2222 collector → IR LED cathode (short lead) | |
| // IR LED anode (long lead) → 50Ω → 5V | |
| #include <IRremote.hpp> | |
| const uint8_t IR_RECEIVE_PIN = 2; // TSOP38238 OUT | |
| const uint8_t IR_SEND_PIN = 3; // -> 1k -> PN2222 base | |
| const uint8_t LED_PIN = LED_BUILTIN; // On-board LED (D13 on Metro Mini/Uno) | |
| // Samsung 32-bit raw values (as seen in ReceiveDump) | |
| const uint32_t SAMSUNG_VOL_UP_RAW = 0xF8070707; | |
| const uint32_t SAMSUNG_VOL_DOWN_RAW = 0xF40B0707; | |
| const uint32_t SAMSUNG_MUTE = 0xF00F0707; | |
| // Integra / Onkyo (NEC) address + commands | |
| const uint16_t ONKYO_ADDR = 0x6DD2; | |
| const uint8_t CMD_VOL_UP = 0x02; | |
| const uint8_t CMD_VOL_DOWN = 0x03; | |
| const uint8_t CMD_MUTE = 0x05; | |
| // Rate limit so we don't spam the AVR (ms between transmissions). | |
| // NEC frames are ~67 ms; 70–90 ms feels natural for volume ramp. | |
| const uint16_t MIN_SEND_INTERVAL_MS = 800; | |
| uint32_t lastSendMs = 0; | |
| // Tiny, non-blocking LED pulse | |
| inline void pulseLED(uint8_t ms = 10) { | |
| digitalWrite(LED_PIN, HIGH); | |
| delay(ms); // 10 ms is short; safe here | |
| digitalWrite(LED_PIN, LOW); | |
| } | |
| inline bool canSendNow() { | |
| uint32_t now = millis(); | |
| if (now - lastSendMs >= MIN_SEND_INTERVAL_MS) { | |
| lastSendMs = now; | |
| return true; | |
| } | |
| return false; | |
| } | |
| void setup() { | |
| pinMode(LED_PIN, OUTPUT); | |
| digitalWrite(LED_PIN, LOW); | |
| // Start IR without library LED feedback; we control LED ourselves | |
| IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); | |
| IrSender.begin(IR_SEND_PIN); | |
| IrSender.enableIROut(38); // NEC uses 38 kHz | |
| Serial.begin(115200); | |
| Serial.println(F("Samsung -> Integra volume translator with LED blinks")); | |
| Serial.println(F("Blink 1x = received any IR; Blink + another 1x = matched & re-sent")); | |
| } | |
| void loop() { | |
| // blinkOnce(); | |
| if (!IrReceiver.decode()) return; | |
| Serial.println(F("Received Signal")); | |
| // Copy out what we need, then resume ASAP to keep receiver ready | |
| auto d = IrReceiver.decodedIRData; | |
| bool isSamsung = (d.protocol == SAMSUNG); | |
| uint32_t raw = d.decodedRawData; | |
| bool held = d.flags & IRDATA_FLAGS_IS_REPEAT; | |
| if (isSamsung) { | |
| bool matched = true; | |
| uint16_t command = 0; | |
| uint8_t repeats = held ? 2 : 1; // ramp when holding | |
| switch (raw) { | |
| case SAMSUNG_VOL_UP_RAW: | |
| // send Onkyo/Integra VOL+ | |
| command = CMD_VOL_UP; | |
| Serial.println(F("Matched: SAMSUNG VOL+ -> Sent ONKYO VOL+")); | |
| break; | |
| case SAMSUNG_VOL_DOWN_RAW: | |
| // send Onkyo/Integra VOL- | |
| command = CMD_VOL_DOWN; | |
| Serial.println(F("Matched: SAMSUNG VOL- -> Sent ONKYO VOL-")); | |
| break; | |
| case SAMSUNG_MUTE: | |
| command = CMD_MUTE; | |
| Serial.println(F("Matched: SAMSUNG MUTE -> Sent ONKYO MUTE")); | |
| break; | |
| default: | |
| // Not a key we care about; ignore. | |
| matched = false; | |
| break; | |
| } | |
| if (matched && canSendNow()) { | |
| // avoid IR interference | |
| delay(100); | |
| IrSender.sendNEC(ONKYO_ADDR, command, 0); | |
| delay(200); | |
| Serial.println(F("Signal Sent")); | |
| } | |
| } | |
| IrReceiver.resume(); // free the receiver quickly | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment