目次
前
次
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。
コマンドは、'*'で終了すると決めたので
バッファに'*'を格納後、解読に着手。
解読は、次のアルゴリズムを適用。
- 2変数bx、fxに、配列サイズを格納
- 配列中に'#'があれば、位置を変数bxに保存。
- 配列中に'*'があれば、位置を変数fxに保存。
- bx>=fxであれば、コマンドではないと判定
- 変数bxが配列サイズ以上なら、コマンドではないと判定
- 変数fxが配列サイズ以上なら、コマンドではないと判定
- 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 ;
}
目次
前
次