目次

HamShield Mini利用

 HamShield MiniをArduinoProMiniに接続して
 DTMF信号の送受信ができるかを試験してみました。

 使ったHamShield Miniは、以下。



 ArduinoProMiniは、手持ちの次のボードを利用。




 電源、シリアルインタフェースには、L型ピン
 ヘッダを切り離して、半田付けしておきました。





 他のピンは、40ピンのピンヘッダを12ピン
 ごとに切り離して、半田付け。

 HamShield Miniと電波のやりとりをするために
 YAESUのFT-70Dを利用。



 HamShield MiniとArduinoProMiniを接続するための
 プリント基板を作成して、楽に実験ができるように
 しました。




 HamShield MiniとArduinoProMiniの接続は
 7ピンのピンヘッダとコネクタを利用。

 プリント基板の回路図は、以下。



 ArduinoIDEで、HamShieldのサンプルコードDTMFを
 一部変更して、ArduinoProMiniに転送しました。

#include <HamShield.h>

// create object for radio
HamShield radio(8,19,18,9);//HamShield radio;

#define LED_PIN    13

#define MIC_PIN    3
#define RESET_PIN  A3
#define FET_PIN    2 //#define SWITCH_PIN 2

uint32_t freq;

void setup()
{
  // NOTE: if not using PWM out, it should be held low to avoid tx noise
  pinMode(MIC_PIN, OUTPUT);
  digitalWrite(MIC_PIN, LOW);

  // prep the switch
  //pinMode(SWITCH_PIN, INPUT_PULLUP);
  pinMode(FET_PIN,OUTPUT);
  digitalWrite(FET_PIN,LOW);

  // set up the reset control pin
  // NOTE: HamShieldMini doesn't have a reset pin, so this has no effect
  pinMode(RESET_PIN, OUTPUT);
  digitalWrite(RESET_PIN, LOW);

  // initialize serial communication
  Serial.begin(9600);
  Serial.println("press the switch to begin...");

  //while (digitalRead(SWITCH_PIN));
  delay(1000);

  // now we let the AU ot of reset
  digitalWrite(RESET_PIN, HIGH);
  delay(5); // wait for device to come up

  Serial.println("beginning radio setup");

  // verify connection
  Serial.println("Testing device connections...");
  Serial.println(radio.testConnection() ? "HamShield connection successful" : "HamShield connection failed");

  // initialize device
  radio.initialize();

  Serial.println("setting default Radio configuration");
  Serial.println("setting squelch");

  radio.setSQHiThresh(-10);
  radio.setSQLoThresh(-30);
  Serial.print("sq hi: ");
  Serial.println(radio.getSQHiThresh());
  Serial.print("sq lo: ");
  Serial.println(radio.getSQLoThresh());
  radio.setSQOn();

  Serial.println("setting frequency to: ");
  freq = 432100; // 70cm calling frequency
  radio.frequency(freq);
  Serial.print(radio.getFrequency());
  Serial.println("kHz");

  // set RX volume to minimum to reduce false positives on DTMF rx
  radio.setVolume1(6);
  radio.setVolume2(0);

  // set to receive
  radio.setModeReceive();

  radio.setRfPower(0);

  // configure Arduino LED for
  pinMode(LED_PIN, OUTPUT);

  // set up DTMF
  radio.enableDTMFReceive();

  /* DTMF timing settings are optional.
   * These times are set to default values when the device is started.
   * You may want to change them if you're DTMF receiver isn't detecting
   * codes from the HamShield (or vice versa).
   */
  radio.setDTMFDetectTime(24); // time to detect a DTMF code, units are 2.5ms
  radio.setDTMFIdleTime(50);   // time between transmitted DTMF codes, units are 2.5ms
  radio.setDTMFTxTime(60);     // duration of transmitted DTMF codes, units are 2.5ms

  Serial.println("ready");
}

void loop()
{
  // look for tone
  char m = radio.DTMFRxLoop();
  m = radio.DTMFRxLoop();
  if ( m != 0 ) {
    Serial.print(m);
  }

  // Is it time to send tone?
  if ( Serial.available() ) {
    // get first code
    uint8_t code = radio.DTMFchar2code(Serial.read());

    // start transmitting
    radio.setDTMFCode(code); // set first
    radio.setTxSourceTones();
    radio.setModeTransmit();
    delay(300); // wait for TX to come to full power

    bool dtmf_to_tx = true;
    while (dtmf_to_tx) {
      // wait until ready
      while ( radio.getDTMFTxActive() != 1 ) {
        // wait until we're ready for a new code
        delay(10);
      }
      if (Serial.available()) {
        code = radio.DTMFchar2code(Serial.read());
        if ( code == 255 ) code = 0xE; // throw a * in there so we don't break things with an invalid code
        radio.setDTMFCode(code); // set first
      } else {
        dtmf_to_tx = false;
        break;
      }

      while (radio.getDTMFTxActive() != 0) {
        // wait until this code is done
        delay(10);
      }

    }
    // done with tone
    radio.setModeReceive();
    radio.setTxSourceMic();
  }
}

 シリアルインタフェースで、DTMF信号の
 やりとりをすると、次のようになりました。



 端末ソフトの設定は、以下。

  データ転送速度 9600bps
  データ長    8ビット
  ストップビット 1ビット
  パリティ    なし
  フロー制御   なし

  ローカルエコーあり

 DTMF信号を、MOSFETに接続したLEDの点灯
 消灯に使うように、スケッチを改造すると
 以下。

#include <HamShield.h>

// create object for radio
HamShield radio(8,19,18,9);

#define LED_PIN    13

#define MIC_PIN    3
#define RESET_PIN  A3

#define FET_PIN 2

uint32_t freq;

#define DCMDBUFSIZE 16

char m ;
char dcmd[DCMDBUFSIZE];
byte dindex ;
int  cmd_entry ;
byte car ;
byte cdr ;
byte handle ;

void device_handling(byte x);
void init_dbuf();
int  get_cmd_loc();

void setup()
{
  // NOTE: if not using PWM out, it should be held low to avoid tx noise
  pinMode(MIC_PIN, OUTPUT);
  digitalWrite(MIC_PIN, LOW);

  // prep the FET switch
  pinMode(FET_PIN,OUTPUT);
  digitalWrite(FET_PIN,LOW);

  // set up the reset control pin
  // NOTE: HamShieldMini doesn't have a reset pin, so this has no effect
  pinMode(RESET_PIN, OUTPUT);
  digitalWrite(RESET_PIN, LOW);

  // initialize serial communication
  Serial.begin(9600);
  Serial.println("press the switch to begin...");

  //while (digitalRead(SWITCH_PIN));
  delay(1000);

  // now we let the AU ot of reset
  digitalWrite(RESET_PIN, HIGH);
  delay(5); // wait for device to come up

  Serial.println("beginning radio setup");

  // verify connection
  Serial.println("Testing device connections...");
  Serial.println(radio.testConnection() ? "HamShield connection successful" : "HamShield connection failed");

  // initialize device
  radio.initialize();

  Serial.println("setting default Radio configuration");
  Serial.println("setting squelch");

  radio.setSQHiThresh(-10);
  radio.setSQLoThresh(-30);
  Serial.print("sq hi: ");
  Serial.println(radio.getSQHiThresh());
  Serial.print("sq lo: ");
  Serial.println(radio.getSQLoThresh());
  radio.setSQOn();

  Serial.println("setting frequency to: ");
  freq = 432100; // 70cm calling frequency
  radio.frequency(freq);
  Serial.print(radio.getFrequency());
  Serial.println("kHz");

  // set RX volume to minimum to reduce false positives on DTMF rx
  radio.setVolume1(6);
  radio.setVolume2(0);

  // set to receive
  radio.setModeReceive();

  radio.setRfPower(0);

  // configure Arduino LED for
  pinMode(LED_PIN, OUTPUT);

  // set up DTMF
  radio.enableDTMFReceive();

  /* DTMF timing settings are optional.
   * These times are set to default values when the device is started.
   * You may want to change them if you're DTMF receiver isn't detecting
   * codes from the HamShield (or vice versa).
   */
  radio.setDTMFDetectTime(24); // time to detect a DTMF code, units are 2.5ms
  radio.setDTMFIdleTime(50);   // time between transmitted DTMF codes, units are 2.5ms
  radio.setDTMFTxTime(60);     // duration of transmitted DTMF codes, units are 2.5ms

  Serial.println("ready");

  // clear buffer 
  init_dbuf();
}

void loop()
{
  // look for tone
  m = radio.DTMFRxLoop();
  if ( m != 0 ) {
    // store character
    *(dcmd+dindex) = m ;
    // update index
    dindex++ ;
    dindex &= 15 ;
    // monitor
    Serial.print(m);
    // command terminate
    if ( m == '*' ) {
      // clear index
      dindex = 0 ;
      // get command entry
      cmd_entry = get_cmd_loc();
      // perform command
      if ( cmd_entry >= 2 ) {
        // get digit value
        car = *(dcmd+cmd_entry)   - '0' ;
        cdr = *(dcmd+cmd_entry+1) - '0' ;
        // generate command code
        handle = car * 10 + cdr ;
        // execute
        if ( handle == 0  ) { device_handling(LOW) ; }
        if ( handle == 99 ) { device_handling(HIGH); }
        // monitor
        Serial.println( handle );
      }
    }
  }

  // Is it time to send tone?
  if ( Serial.available() ) {
    // get first code
    uint8_t code = radio.DTMFchar2code(Serial.read());

    // start transmitting
    radio.setDTMFCode(code); // set first
    radio.setTxSourceTones();
    radio.setModeTransmit();
    delay(300); // wait for TX to come to full power

    bool dtmf_to_tx = true;
    while (dtmf_to_tx) {
      // wait until ready
      while ( radio.getDTMFTxActive() != 1 ) {
        // wait until we're ready for a new code
        delay(10);
      }
      if (Serial.available()) {
        code = radio.DTMFchar2code(Serial.read());
        if ( code == 255 ) code = 0xE; // throw a * in there so we don't break things with an invalid code
        radio.setDTMFCode(code); // set first
      } else {
        dtmf_to_tx = false;
        break;
      }

      while (radio.getDTMFTxActive() != 0) {
        // wait until this code is done
        delay(10);
      }

    }
    // done with tone
    radio.setModeReceive();
    radio.setTxSourceMic();
  }
}

void device_handling(byte x)
{
  digitalWrite(FET_PIN, x);
}

void init_dbuf()
{
  byte ii ;
  for ( ii = 0 ; ii < DCMDBUFSIZE ; ii++ ) {
    *(dcmd+ii);
  }
  dindex = 0 ;
}

int  get_cmd_loc()
{
  byte bx ;
  byte fx ;
  byte ii ;
  // default
  bx = DCMDBUFSIZE ;
  fx = DCMDBUFSIZE ;
  // search
  for ( ii = 0 ; ii < DCMDBUFSIZE ; ii++ ) {
    // #
    if ( *(dcmd+ii) == '#' ) { bx = ii ; }
    // *
    if ( *(dcmd+ii) == '*' ) { fx = ii ; }
  }
  // judge
  if ( bx >= fx ) return -1 ;
  if ( bx >= DCMDBUFSIZE ) return -1 ;
  if ( fx >= DCMDBUFSIZE ) return -1 ;
  // command entry
  return( fx - 2 );
}

 MOSFETは、外部に接続した電流制限抵抗とLEDに
 電流を流すか、流さないかを決めるスイッチと
 なっています。

 コマンドは、次のように決めました。

 #D99* ← LED点灯
 #D00* ← LED消灯

 このDTMFで送付されてくる文字を、配列で構成した
 受信バッファに格納し、解読する処理を用意。

 受信バッファに文字列を格納し、解読してから
 LEDの点灯、消灯を決定するまでは、次のコード
 にまとめました。

  m = radio.DTMFRxLoop();
  if ( m != 0 ) {
    // store character
    *(dcmd+dindex) = m ;
    // update index
    dindex++ ;
    dindex &= 15 ;
    // monitor
    Serial.print(m);
    // command terminate
    if ( m == '*' ) {
      // clear index
      dindex = 0 ;
      // get command entry
      cmd_entry = get_cmd_loc();
      // perform command
      if ( cmd_entry >= 2 ) {
        // get digit value
        car = *(dcmd+cmd_entry)   - '0' ;
        cdr = *(dcmd+cmd_entry+1) - '0' ;
        // generate command code
        handle = car * 10 + cdr ;
        // execute
        if ( handle == 0  ) { device_handling(LOW) ; }
        if ( handle == 99 ) { device_handling(HIGH); }
        // monitor
        Serial.println( handle );
      }
    }
  }

 受信バッファを構成する配列は、dcmd。

 コマンドは、'*'で終了すると決めたので
 バッファに'*'を格納後、解読に着手。

 解読は、次のアルゴリズムを適用。
  1. 2変数bx、fxに、配列サイズを格納
  2. 配列中に'#'があれば、位置を変数bxに保存。
  3. 配列中に'*'があれば、位置を変数fxに保存。
  4. bx>=fxであれば、コマンドではないと判定
  5. 変数bxが配列サイズ以上なら、コマンドではないと判定
  6. 変数fxが配列サイズ以上なら、コマンドではないと判定
  7. 4から6をパスしたなら、fx-2がコマンド開始位置になる
 解読処理は、関数にまとめて使い勝手をよくします。 int get_cmd_loc() { byte bx ; byte fx ; byte ii ; // default bx = DCMDBUFSIZE ; fx = DCMDBUFSIZE ; // search for ( ii = 0 ; ii < DCMDBUFSIZE ; ii++ ) { // # if ( *(dcmd+ii) == '#' ) { bx = ii ; } // * if ( *(dcmd+ii) == '*' ) { fx = ii ; } } // judge if ( bx >= fx ) return -1 ; if ( bx >= DCMDBUFSIZE ) return -1 ; if ( fx >= DCMDBUFSIZE ) return -1 ; // command entry return( fx - 2 ); }  関数get_cmd_locの返値が、−1ならコマンドとは  見なさず、2以上ならば書式に合致していると判定  できる仕様にまとめました。  配列からコマンドに相当する2文字を取り出し  数字から数値に変換後、10進数の値を求めて  コマンドを実行。  コマンドを構成する2文字は、ASCIIとして  数字から数値への変換は、'0'を減算。  2つの数値を、10進数の10の位、1の位として  10進数に変換。  この10進数が、コマンドに相当する値。  コマンドに相当する10進数の値を求めるのは  次のように単純な処理でまとめられます。 // get digit value car = *(dcmd+cmd_entry) - '0' ; cdr = *(dcmd+cmd_entry+1) - '0' ; // generate command code handle = car * 10 + cdr ;  変数handleの値で、LEDの点灯、消灯を処理。 // execute if ( handle == 0 ) { device_handling(LOW) ; } if ( handle == 99 ) { device_handling(HIGH); }  LEDの点灯、消灯は、次の関数にまとめて  使い勝手をよくします。 void device_handling(byte x) { digitalWrite(FET_PIN, x); }  関数device_handlingは、回路ではMOSFETのドレインと  電源の間に、抵抗とLEDを接続して点灯、消灯を  扱います。  LEDの点灯、消灯を関数に任せると、ピン番号に  頭を使わずに済みます。  外部基板に、電流制限抵抗とLED、ACアダプタから  ArduinoProMiniに電源を供給できるようにコネクタ  その他を半田付けして使いました。  HamShield MiniとArduinoProMiniを実装した基板と  LEDを載せた外部基板を接続すると、以下。  DTMF信号のコマンドを受信バッファに入力してから  解釈するのは、C言語では定番のstrcmpで比較して  処理すればよいと気がつきました。  受信バッファに、文字列転送するには、loopの中の  文字受信処理を、以下に変更。 xmsg = hs_radio.DTMFRxLoop(); if ( xmsg != 0 ) { *(dcmd+dindex) = xmsg ; /* store character */ /* update index */ dindex++ ; dindex &= 15 ;  文字列からコマンドを判定して、数値で実行すべき  内容を決定するには、次の関数で対応。 byte check_cmd() { byte result ; /* default */ result = 0 ; /* turn off red LED */ if ( strcmp( dcmd , "#D100*" ) == 0 ) { result = 10 ; } /* turn on red LED */ if ( strcmp( dcmd , "#D101*" ) == 0 ) { result = 11 ; } /* blink red LED */ if ( strcmp( dcmd , "#D102*" ) == 0 ) { result = 12 ; } /* turn off green LED */ if ( strcmp( dcmd , "#D200*" ) == 0 ) { result = 20 ; } /* turn on green LED */ if ( strcmp( dcmd , "#D201*" ) == 0 ) { result = 21 ; } /* blink green LED */ if ( strcmp( dcmd , "#D202*" ) == 0 ) { result = 22 ; } /* servo motor 0 degree */ if ( strcmp( dcmd , "#D300*" ) == 0 ) { result = 30 ; } /* servo motor 15 degree */ if ( strcmp( dcmd , "#D301*" ) == 0 ) { result = 31 ; } /* servo motor 30 degree */ if ( strcmp( dcmd , "#D302*" ) == 0 ) { result = 32 ; } /* servo motor 45 degree */ if ( strcmp( dcmd , "#D303*" ) == 0 ) { result = 33 ; } /* servo motor 60 degree */ if ( strcmp( dcmd , "#D304*" ) == 0 ) { result = 34 ; } /* servo motor 75 degree */ if ( strcmp( dcmd , "#D305*" ) == 0 ) { result = 35 ; } /* servo motor 90 degree */ if ( strcmp( dcmd , "#D306*" ) == 0 ) { result = 36 ; } return result ; }  ArduinoProMiniに接続している2個のLEDと  1個のサーボモータを動かすためのコマンド  を数値にしているだけ。  関数check_cmd()からの返値で、動作を振り分け  して、希望する処理を実行させます。  それをloop()の中に記述。 if ( xmsg == '*' ) { /* store delimiter */ *(dcmd+dindex) = '\0' ; /* clear index */ dindex = 0 ; /* get command value */ cval = check_cmd(); /* judge */ switch ( cval ) { /* turn off red LED */ case 10 : gv[0] = gv[1] = LOW ; break ; /* turn on red LED */ case 11 : gv[0] = gv[1] = HIGH ; break ; /* blink red LED */ case 12 : gv[0] = HIGH ; gv[1] = LOW ; break ; /* turn off green LED */ case 20 : rv[0] = rv[1] = LOW ; break ; /* turn on green LED */ case 21 : rv[0] = rv[1] = HIGH ; break ; /* blink green LED */ case 22 : rv[0] = HIGH ; rv[1] = LOW ; break ; /* servo motor 0 degree */ case 30 : myservo.write(0) ; break ; /* servo motor 15 degree */ case 31 : myservo.write(15) ; break ; /* servo motor 30 degree */ case 32 : myservo.write(30) ; break ; /* servo motor 45 degree */ case 33 : myservo.write(45) ; break ; /* servo motor 60 degree */ case 34 : myservo.write(60) ; break ; /* servo motor 75 degree */ case 35 : myservo.write(75) ; break ; /* servo motor 90 degree */ case 36 : myservo.write(90) ; break ; } } }  2個のLEDの消灯、点灯、点滅は、ステートマシン  を利用して記述すれば簡単。 byte rstate ; byte rv[2] ; unsigned long rlast ; void gled_init() { gstate = 0 ; gv[0] = gv[1] = LOW ; } void gled_loop() { switch ( gstate ) { case 0 : digitalWrite( GLED , gv[0] ); glast = millis() + 500 ; gstate = 1 ; break ; case 1 : gstate = 1 ; if ( millis() > glast ) { gstate = 2 ; } break ; case 2 : digitalWrite( GLED , gv[0] ); glast = millis() + 500 ; gstate = 3 ; break ; case 3 : gstate = 3 ; if ( millis() > glast ) { gstate = 4 ; } break ; default : gstate = 0; break ; } } void rled_init() { rstate = 0 ; rv[0] = rv[1] = LOW ; } void rled_loop() { switch ( rstate ) { case 0 : digitalWrite( RLED , rv[0] ); rlast = millis() + 500 ; rstate = 1 ; break ; case 1 : rstate = 1 ; if ( millis() > rlast ) { rstate = 2 ; } break ; case 2 : digitalWrite( RLED , rv[0] ); rlast = millis() + 500 ; rstate = 3 ; break ; case 3 : rstate = 3 ; if ( millis() > glast ) { rstate = 4 ; } break ; default : rstate = 0; break ; } }  ステートマシンには、ステート(状態)を扱う  変数が必要なので、緑、赤のLEDに各々変数の  gstate、rstateを与えて、それが変化するよう  に記述。  消灯、点灯、点滅は、ステートマシンに与える  パラメータで変更できるように工夫。  ステートマシンを初期化するのは、setup()の中で  実際のステートマシンの処理は、loop()の中に記述。  ステートマシンを使うメリットは、パラメータを  変更すると、モードを可変させられること。  全体のソースコードは、次のようになりました。 #include <stdio.h> #include <string.h> #include <HamShield.h> #include <Servo.h> /* create object for hs_radio */ HamShield hs_radio(8,19,18,9); Servo myservo; #define LED_PIN 13 #define GLED 10 #define RLED 11 #define MIC_PIN 3 #define RESET_PIN A3 #define FET_PIN 2 #define ServoPin 9 uint32_t freq; #define DCMDBUFSIZE 16 char xmsg ; char dcmd[DCMDBUFSIZE]; byte dindex ; byte dtmf_to_tx; byte cval ; void device_handling(byte x); void init_dbuf(); byte check_cmd(); byte gstate ; byte gv[2] ; unsigned long glast ; byte rstate ; byte rv[2] ; unsigned long rlast ; void gled_init() { gstate = 0 ; gv[0] = gv[1] = LOW ; } void gled_loop() { switch ( gstate ) { case 0 : digitalWrite( GLED , gv[0] ); glast = millis() + 500 ; gstate = 1 ; break ; case 1 : gstate = 1 ; if ( millis() > glast ) { gstate = 2 ; } break ; case 2 : digitalWrite( GLED , gv[0] ); glast = millis() + 500 ; gstate = 3 ; break ; case 3 : gstate = 3 ; if ( millis() > glast ) { gstate = 4 ; } break ; default : gstate = 0; break ; } } void rled_init() { rstate = 0 ; rv[0] = rv[1] = LOW ; } void rled_loop() { switch ( rstate ) { case 0 : digitalWrite( RLED , rv[0] ); rlast = millis() + 500 ; rstate = 1 ; break ; case 1 : rstate = 1 ; if ( millis() > rlast ) { rstate = 2 ; } break ; case 2 : digitalWrite( RLED , rv[0] ); rlast = millis() + 500 ; rstate = 3 ; break ; case 3 : rstate = 3 ; if ( millis() > glast ) { rstate = 4 ; } break ; default : rstate = 0; break ; } } void setup() { /* NOTE: if not using PWM out, it should be held low to avoid tx noise */ pinMode(MIC_PIN, OUTPUT); /* prep the FET switch */ digitalWrite(FET_PIN,LOW); pinMode(FET_PIN,OUTPUT); /* set up the reset control pin NOTE: HamShieldMini doesn't have a reset pin, so this has no effect */ digitalWrite(RESET_PIN, LOW); pinMode(RESET_PIN, OUTPUT); /* initialize serial communication */ Serial.begin(9600); Serial.println("press the switch to begin..."); /* while (digitalRead(SWITCH_PIN)); */ delay(1000); /* now we let the AU ot of reset */ digitalWrite(RESET_PIN, HIGH); delay(5); // wait for device to come up Serial.println("beginning hs_radio setup"); /* verify connection */ Serial.println("Testing device connections..."); Serial.print("HamShield connection "); if ( hs_radio.testConnection() ) { Serial.println("successful"); } else { Serial.println("failed"); } /* initialize device */ hs_radio.initialize(); Serial.println("setting default Radio configuration"); Serial.println("setting squelch"); hs_radio.setSQHiThresh(-10); hs_radio.setSQLoThresh(-30); Serial.print("sq hi: "); Serial.println(hs_radio.getSQHiThresh()); Serial.print("sq lo: "); Serial.println(hs_radio.getSQLoThresh()); hs_radio.setSQOn(); Serial.println("setting frequency to: "); /* 70cm calling frequency */ freq = 432100; hs_radio.frequency(freq); Serial.print(hs_radio.getFrequency()); Serial.println("kHz"); /* set RX volume to minimum to reduce false positives on DTMF rx */ hs_radio.setVolume1(6); hs_radio.setVolume2(0); /* set to receive */ hs_radio.setModeReceive(); hs_radio.setRfPower(0); /* configure Arduino LED for */ pinMode(LED_PIN, OUTPUT); /* set up DTMF */ hs_radio.enableDTMFReceive(); /* DTMF timing settings are optional. * These times are set to default values when the device is started. * You may want to change them if you're DTMF receiver isn't detecting * codes from the HamShield (or vice versa). */ hs_radio.setDTMFDetectTime(24); // time to detect a DTMF code, units are 2.5ms hs_radio.setDTMFIdleTime(50); // time between transmitted DTMF codes, units are 2.5ms hs_radio.setDTMFTxTime(60); // duration of transmitted DTMF codes, units are 2.5ms Serial.println("ready"); /* clear buffer */ init_dbuf(); gled_init(); rled_init(); myservo.attach(ServoPin); } void loop() { /* look for tone */ xmsg = hs_radio.DTMFRxLoop(); if ( xmsg != 0 ) { *(dcmd+dindex) = xmsg ; /* store character */ /* update index */ dindex++ ; dindex &= 15 ; Serial.print(xmsg); /* monitor */ /* command terminate */ if ( xmsg == '*' ) { /* store delimiter */ *(dcmd+dindex) = '\0' ; /* clear index */ dindex = 0 ; /* get command value */ cval = check_cmd(); /* judge */ switch ( cval ) { /* turn off red LED */ case 10 : gv[0] = gv[1] = LOW ; break ; /* turn on red LED */ case 11 : gv[0] = gv[1] = HIGH ; break ; /* blink red LED */ case 12 : gv[0] = HIGH ; gv[1] = LOW ; break ; /* turn off green LED */ case 20 : rv[0] = rv[1] = LOW ; break ; /* turn on green LED */ case 21 : rv[0] = rv[1] = HIGH ; break ; /* blink green LED */ case 22 : rv[0] = HIGH ; rv[1] = LOW ; break ; /* servo motor 0 degree */ case 30 : myservo.write(0) ; break ; /* servo motor 15 degree */ case 31 : myservo.write(15) ; break ; /* servo motor 30 degree */ case 32 : myservo.write(30) ; break ; /* servo motor 45 degree */ case 33 : myservo.write(45) ; break ; /* servo motor 60 degree */ case 34 : myservo.write(60) ; break ; /* servo motor 75 degree */ case 35 : myservo.write(75) ; break ; /* servo motor 90 degree */ case 36 : myservo.write(90) ; break ; } } } gled_loop(); rled_loop(); /* Is it time to send tone? */ if ( Serial.available() ) { /* get first code */ uint8_t code = hs_radio.DTMFchar2code(Serial.read()); /* start transmitting */ hs_radio.setDTMFCode(code); /* set first */ hs_radio.setTxSourceTones(); hs_radio.setModeTransmit(); /* wait for TX to come to full power */ delay(300); dtmf_to_tx = HIGH ; while (dtmf_to_tx) { /* wait until we're ready for a new code */ while ( hs_radio.getDTMFTxActive() != 1 ) { delay(10); } if (Serial.available()) { code = hs_radio.DTMFchar2code(Serial.read()); if ( code == 255 ) code = 0xE; /* throw a * in there so we don't break things with an invalid code */ hs_radio.setDTMFCode(code); /* set first */ } else { dtmf_to_tx = LOW; break; } /* wait until this code is done */ while ( hs_radio.getDTMFTxActive() != 0 ) { delay(10); } } /* done with tone */ hs_radio.setModeReceive(); hs_radio.setTxSourceMic(); } } void device_handling(byte x) { digitalWrite(FET_PIN, x); } void init_dbuf() { byte ii ; for ( ii = 0 ; ii < DCMDBUFSIZE ; ii++ ) { *(dcmd+ii); } dindex = 0 ; } byte check_cmd() { byte result ; /* default */ result = 0 ; /* turn off red LED */ if ( strcmp( dcmd , "#D100*" ) == 0 ) { result = 10 ; } /* turn on red LED */ if ( strcmp( dcmd , "#D101*" ) == 0 ) { result = 11 ; } /* blink red LED */ if ( strcmp( dcmd , "#D102*" ) == 0 ) { result = 12 ; } /* turn off green LED */ if ( strcmp( dcmd , "#D200*" ) == 0 ) { result = 20 ; } /* turn on green LED */ if ( strcmp( dcmd , "#D201*" ) == 0 ) { result = 21 ; } /* blink green LED */ if ( strcmp( dcmd , "#D202*" ) == 0 ) { result = 22 ; } /* servo motor 0 degree */ if ( strcmp( dcmd , "#D300*" ) == 0 ) { result = 30 ; } /* servo motor 15 degree */ if ( strcmp( dcmd , "#D301*" ) == 0 ) { result = 31 ; } /* servo motor 30 degree */ if ( strcmp( dcmd , "#D302*" ) == 0 ) { result = 32 ; } /* servo motor 45 degree */ if ( strcmp( dcmd , "#D303*" ) == 0 ) { result = 33 ; } /* servo motor 60 degree */ if ( strcmp( dcmd , "#D304*" ) == 0 ) { result = 34 ; } /* servo motor 75 degree */ if ( strcmp( dcmd , "#D305*" ) == 0 ) { result = 35 ; } /* servo motor 90 degree */ if ( strcmp( dcmd , "#D306*" ) == 0 ) { result = 36 ; } return result ; }

目次

inserted by FC2 system