블로그 이미지
훅크선장

카테고리

분류 전체보기 (365)
사진이야기 (23)
펭귄컴퓨팅 (122)
컴퓨터보안 (85)
절름발이 프로그래머 (59)
하드웨어개조 (24)
멀알려줄까 (35)
잡다한것들 (15)
홈베이킹&홈쿠킹 (2)
Total
Today
Yesterday

달력

« » 2026.8
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31

공지사항

태그목록

최근에 올라온 글

'2026/08'에 해당되는 글 1건

  1. 2026.08.03 무아스 LED 벽시계의 IR 리모콘을 아두이노로 구현

잃어버린 IR 리모콘을 다시 구현하는 과정을 이미 정리한 적이 있었으나,

이번에 AI의 도움을 받아서, 확실하게 모든 리모콘 기능을 구현하였습니다.

 

IR 송신부 회로는 아래와 같이 구성하면 되는데,

아두이노 우노 또는 나노를 사용하고, 나중에 코드에서도 설명되겠지만, IR 송신핀은 코드와 맞춰서 사용한다.

아래 그림에는 D9로 되어 있지만, 실제 이후 코드에서는 D12를 사용하였다.

 

그리고, 사용한 IRed가 SI3317-H 이지만, 다른 제품을 사용한다면, R1 저항 33오옴을 적절하게 바꿔야만 한다.

IR 송신부 회로 구성

 

 

만약 IRed를 SI5315-DS로 바꿔서 사용하려면, R1 저항을 68오옴으로 교체해야만 한다.

 

데이터시트상에서 체크한 내용이 

순방향 전류 IF 정격입니다. 앞서 드린 33Ω은 SI3317-H의 IF = 100mA를 전제로 계산한 값입니다.

IF 정격R1 값비고
100mA 33Ω, 1/4W 그대로 사용
50mA 68Ω, 1/4W 저항만 교체

 

무아스 LED 시계 리모콘 설명서

 

 

그래서, 위의 조작법을 보고, SW1~SW8을 원래 리모콘 배치 그대로 매핑했습니다.

스위치                               짧게                                                                      길게 (0.7초)

 

SW1 전원
SW2 화면 전환 디스플레이 모드 설정
SW3 자동밝기 ON/OFF 페이드 인/아웃 ON/OFF
SW4 🔔 알람 ON/OFF
SW5 🕐 (확정 / OK) 시간설정
SW6 알람시간 확인 알람시간 설정
SW7 밝기 올림 / 숫자 올림 연속 증가
SW8 밝기 내림 / 숫자 내림 연속 감소

 

아두이노 코드 .ino 파일은 다음과 같습니다.

---------------------------------------------------------------------------------------------------------------

/*
 * 무아스 퓨어 슬림 LED 벽시계 IR 리모콘
 * 8버튼 · 짧게/길게 누름 / 아두이노 나노·우노 공통
 */

#define DISABLE_CODE_FOR_RECEIVER
#define IR_SEND_PIN 12

#include <IRremote.hpp>

#define HOLD_MS      700      // 700ms = 0.7초, 이 시간 이상 누르면 '길게'
#define LONG_REPS    24       // 길게 1회성 명령용 (SW2·3·5·6)
#define MAX_REPEAT  200       // 연속 증감 상한 (약 22초), 숫자 수정시에 연속된 증감을 위해,

const uint8_t NKEYS = 8;
const uint8_t keyPins[NKEYS] = {2, 3, 4, 5, 6, 7, 8, 9};  // 아두이노에 연결된 키들을 연결하는 곳은 D2~D9 까지 8개의 키에 각각 매핑, 그리고 GND 가 하나 더 꽂아져야 하겠지요!

//                              SW1   SW2   SW3   SW4   SW5   SW6   SW7   SW8
const uint8_t shortCmd[NKEYS]={0x1C, 0x40, 0x08, 0x44, 0x5E, 0x4A, 0x18, 0x52};  // 키에 할당되는 코드 값
const bool    hasLong[NKEYS] ={false,true, true, false,true, true, true, true};  // 길게 누르는 키의 존재 여부

// SW7, SW8만 연속 반복
const bool holdRepeat[NKEYS] = {false,false,false,false,false,false,true,true};

const char* names[NKEYS] = {
  "POWER", "DISPLAY", "AUTO BRIGHT", "ALARM",
  "CLOCK", "ALARM TIME", "UP +", "DOWN -"
};

bool     stable[NKEYS], raw[NKEYS];
uint32_t lastChange[NKEYS];
const uint16_t DEBOUNCE_MS = 25;

void setup() {
  Serial.begin(115200);
  for (uint8_t i = 0; i < NKEYS; i++) {
    pinMode(keyPins[i], INPUT_PULLUP);
    stable[i] = raw[i] = true;
    lastChange[i] = 0;
  }
  pinMode(LED_BUILTIN, OUTPUT);
  IrSender.begin(DISABLE_LED_FEEDBACK);
  Serial.println(F("--- Mooas remote ready (8 buttons) ---"));
}

// 눌린 채 유지되는지 확인 (디바운스 포함)
bool held(uint8_t i) {
  return (digitalRead(keyPins[i]) == LOW);
}

void fire(uint8_t i, bool isLong) {
  digitalWrite(LED_BUILTIN, HIGH);

  if (isLong && holdRepeat[i]) {
    IrSender.sendNEC(0x00, shortCmd[i], 0);      // 첫 프레임
    uint16_t n = 0;
    uint8_t miss = 0;
    while (n < MAX_REPEAT) {                      // 뗄 때까지 반복
      delay(n == 0 ? 42 : 98);
      if (!held(i)) { if (++miss >= 3) break; }
      else            miss = 0;
      IrSender.sendNECRepeat();
      n++;
    }
    Serial.print(F("  (repeat ")); Serial.print(n); Serial.print(F(")"));
  } else {
    IrSender.sendNEC(0x00, shortCmd[i], isLong ? LONG_REPS : 0);
  }

  digitalWrite(LED_BUILTIN, LOW);

  Serial.print(F("SW")); Serial.print(i + 1);
  Serial.print(F("  ")); Serial.print(names[i]);
  Serial.println(isLong ? F("  [LONG]") : F("  [short]"));
}

void loop() {
  uint32_t now = millis();

  for (uint8_t i = 0; i < NKEYS; i++) {
    bool r = digitalRead(keyPins[i]);
    if (r != raw[i]) { raw[i] = r; lastChange[i] = now; }
    if ((now - lastChange[i]) < DEBOUNCE_MS || stable[i] == r) continue;

    stable[i] = r;
    if (r != LOW) continue;               // 뗀 것은 무시

    if (!hasLong[i]) {                    // 길게가 없으면 즉시 전송
      fire(i, false);
    } else {
      uint32_t t0 = now;
      uint8_t miss = 0;
      while (millis() - t0 < HOLD_MS) {   // 계속 누르고 있나 관찰
        if (!held(i)) { if (++miss >= 3) break; }
        else            miss = 0;
        delay(10);
      }
      fire(i, (millis() - t0) >= HOLD_MS);
    }

    uint8_t rel = 0;                      // 손 뗄 때까지 대기
    while (rel < 5) {
      if (!held(i)) rel++; else rel = 0;
      delay(10);
    }
    stable[i] = raw[i] = true;
    lastChange[i] = millis();
  }
}

 

 

리모콘을 만들기 위한 긴 여정은 이제 여기서 끝마친다!

Posted by 훅크선장
, |