SSブログ

CH552 で リモコン信号をシリアル送信 [Arduino]

CH552にも移植してみました。
Ch55xduinoで注意が必要なのは、、

・C++ではなくCである
・pulseIn()がない
・シリアル通信がいつものと異なる

pulseIn()については、100μ秒オーダー程度の精度で十分なので、micros()で自作。

ch552_ir_decoder.jpg
// IR Receive and Decode (CH55x ver.)

#define IR_IN    11          // IR Receiver pin

uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout) {
    uint32_t  usExp = micros();
    while( digitalRead( pin ) == state )  if( micros() - usExp > timeout ) return 0;
    while( digitalRead( pin ) != state )  if( micros() - usExp > timeout ) return 0;
    uint32_t  usOrg = micros(); 
    while( digitalRead( pin ) == state )  if( micros() - usExp > timeout ) return 0;
    return micros() - usOrg;
}

void setup() {
  pinMode( IR_IN , INPUT );                     // input  Vout(active low, negative logic)
  pinMode(  31 ,  OUTPUT ); digitalWrite( 31, LOW  );   // LOW  (*use as GND)
  pinMode(  30 ,  OUTPUT ); digitalWrite( 30, HIGH );   // HIGH (*use as Vcc)
}

void loop() {
  uint32_t  irData = 0;
  uint8_t   irProtocol = 0, irBit = 0;
  __xdata uint8_t   irArray[20] = {0};
  
  // ****** Receive and Decode IR signals ******
  uint16_t  us = pulseIn( IR_IN, LOW , 65535 ); // Judge the protocol by the length of the leader section (usec.)
  if      ( us > 2000 && us <  3000 ) {         //  *** SIRC ***
      irProtocol = 'S';                         //  T=600us, ON/OFF : leader= 4T/1T, 0=1T/1T, 1=2T/1T 
      for(;(us = pulseIn( IR_IN, LOW , 3000 )); irBit++)
        if( us > 1000 && us <  1500 ) irData |= (1UL << irBit);
  }else if( us > 3500 && us <  5000 ) {         //  *** AEHA ***
      irProtocol = 'A';                         //  T=425us, ON/OFF : leader= 8T/4T, 0=1T/1T, 1=1T/3T, stop=1T
      while( digitalRead( IR_IN ) );
      for(;(us = pulseIn( IR_IN, HIGH, 4000 )); irBit++)
        if( us > 1050 && us <  1500 ) irArray[ irBit / 8 ] |= (1 << (irBit % 8) );
  }else if( us > 7200 && us < 11000 ) {         //  *** NEC ***
      irProtocol = 'N';                         //  T=560us, ON/OFF : leader=16T/8T, 0=1T/1T, 1=1T/3T, stop=1T
      while( digitalRead( IR_IN ) );
      for(;(us = pulseIn( IR_IN, HIGH, 3000 )); irBit++)
        if( us > 1350 && us <  2000 ) irData |= (1UL << irBit);
  }else return;

  // ****** Display results by protocol ******
  USBSerial_print( irProtocol == 'S' ? "SIRC: " : irProtocol == 'A' ? "AEHA: " : "NEC : " );
  if( !irBit ) { 
    USBSerial_println( " (repeat code) " );
    return;
  }
  USBSerial_print( irBit );
  USBSerial_print( "bit" ); 
  if( irProtocol == 'A' ) {
    for( uint8_t i = 0; i < ( (irBit + 7) / 8 ); i++ ) {
      USBSerial_print((irArray[i] < 0x10) ? " 0x0" : " 0x" );
      USBSerial_print( irArray[i], HEX );
    }
  } else {
      USBSerial_print( " 0x" );
      USBSerial_print( irData, HEX );
      USBSerial_print( "\t0b" );
      USBSerial_print( irData, BIN );
  }
  USBSerial_println("");
}

ちなみに、CH552 のピン P1.0~P1.7, P3.0~P3.7 のうち、CH552 mini coreでは、P1.2, P1.3 は外部クリスタル、P3.6, P3.7 はそれぞれUDP, UDMで、USBとつながっているためI/Oピンには使えません。
ちょっとこれで嵌りました。

nice!(0)  コメント(0)