2018-06-17 02:14:13 +00:00
|
|
|
/* Hamshield
|
2018-06-25 00:12:04 +00:00
|
|
|
* Example: DTMF
|
2018-12-09 17:43:41 +00:00
|
|
|
* This is a simple example to demonstrate how to use DTMF.
|
2018-06-25 00:12:04 +00:00
|
|
|
*
|
2018-06-17 02:14:13 +00:00
|
|
|
* Connect the HamShield to your Arduino. Screw the antenna
|
2018-06-25 00:12:04 +00:00
|
|
|
* into the HamShield RF jack.
|
|
|
|
* Connect the Arduino to wall power and then to your computer
|
|
|
|
* via USB. After uploading this program to your Arduino, open
|
2018-12-09 17:43:41 +00:00
|
|
|
* the Serial Monitor. Press the switch on the HamShield to
|
2018-06-25 00:12:04 +00:00
|
|
|
* begin setup. After setup is complete, type in a DTMF value
|
|
|
|
* (0-9, A, B, C, D, *, #) and hit enter. The corresponding
|
|
|
|
* DTMF tones will be transmitted. The sketch will also print
|
|
|
|
* any received DTMF tones to the screen.
|
|
|
|
**/
|
2018-06-17 02:14:13 +00:00
|
|
|
|
|
|
|
#include <HamShield.h>
|
|
|
|
|
|
|
|
// create object for radio
|
|
|
|
HamShield radio;
|
|
|
|
|
|
|
|
#define LED_PIN 13
|
|
|
|
|
2019-03-15 17:43:15 +00:00
|
|
|
#define MIC_PIN 3
|
2018-06-17 02:14:13 +00:00
|
|
|
#define RESET_PIN A3
|
|
|
|
#define SWITCH_PIN 2
|
|
|
|
|
|
|
|
uint32_t freq;
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
// NOTE: if not using PWM out, it should be held low to avoid tx noise
|
2019-03-15 17:43:15 +00:00
|
|
|
pinMode(MIC_PIN, OUTPUT);
|
|
|
|
digitalWrite(MIC_PIN, LOW);
|
2018-06-17 02:14:13 +00:00
|
|
|
|
|
|
|
// prep the switch
|
|
|
|
pinMode(SWITCH_PIN, INPUT_PULLUP);
|
|
|
|
|
|
|
|
// set up the reset control pin
|
|
|
|
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));
|
|
|
|
|
2018-12-09 17:43:41 +00:00
|
|
|
// now we let the AU ot of reset
|
2018-06-17 02:14:13 +00:00
|
|
|
digitalWrite(RESET_PIN, HIGH);
|
2018-08-05 02:31:53 +00:00
|
|
|
delay(5); // wait for device to come up
|
2018-06-17 02:14:13 +00:00
|
|
|
|
|
|
|
Serial.println("beginning radio setup");
|
|
|
|
|
|
|
|
// verify connection
|
|
|
|
Serial.println("Testing device connections...");
|
2018-06-25 00:12:04 +00:00
|
|
|
Serial.println(radio.testConnection() ? "HamShield connection successful" : "HamShield connection failed");
|
2018-06-17 02:14:13 +00:00
|
|
|
|
|
|
|
// initialize device
|
2018-12-09 17:43:41 +00:00
|
|
|
radio.initialize();
|
2018-06-17 02:14:13 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
//radio.setSQOff();
|
|
|
|
|
2018-12-09 17:43:41 +00:00
|
|
|
Serial.println("setting frequency to: ");
|
2018-06-25 00:12:04 +00:00
|
|
|
freq = 420000;
|
2018-06-17 02:14:13 +00:00
|
|
|
radio.frequency(freq);
|
2018-12-09 17:43:41 +00:00
|
|
|
Serial.print(radio.getFrequency());
|
|
|
|
Serial.println("kHz");
|
2018-06-17 02:14:13 +00:00
|
|
|
|
|
|
|
// set RX volume to minimum to reduce false positives on DTMF rx
|
2018-07-03 22:32:05 +00:00
|
|
|
radio.setVolume1(6);
|
2018-06-17 02:14:13 +00:00
|
|
|
radio.setVolume2(0);
|
|
|
|
|
|
|
|
// set to receive
|
|
|
|
radio.setModeReceive();
|
|
|
|
|
|
|
|
radio.setRfPower(0);
|
|
|
|
|
|
|
|
// configure Arduino LED for
|
|
|
|
pinMode(LED_PIN, OUTPUT);
|
|
|
|
|
|
|
|
// set up DTMF
|
2018-06-25 00:12:04 +00:00
|
|
|
radio.enableDTMFReceive();
|
2018-08-05 02:31:53 +00:00
|
|
|
|
|
|
|
/* 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
|
|
|
|
|
2018-06-17 02:14:13 +00:00
|
|
|
Serial.println("ready");
|
|
|
|
}
|
|
|
|
|
2018-07-03 22:32:05 +00:00
|
|
|
char rx_dtmf_buf[255];
|
|
|
|
int rx_dtmf_idx = 0;
|
2018-06-17 02:14:13 +00:00
|
|
|
void loop() {
|
|
|
|
|
|
|
|
// look for tone
|
|
|
|
if (radio.getDTMFSample() != 0) {
|
|
|
|
uint16_t code = radio.getDTMFCode();
|
2018-07-03 22:32:05 +00:00
|
|
|
|
|
|
|
rx_dtmf_buf[rx_dtmf_idx++] = code2char(code);
|
|
|
|
|
|
|
|
// reset after this tone
|
2018-06-25 00:12:04 +00:00
|
|
|
int j = 0;
|
|
|
|
while (j < 4) {
|
|
|
|
if (radio.getDTMFSample() == 0) {
|
|
|
|
j++;
|
|
|
|
}
|
2018-06-17 02:14:13 +00:00
|
|
|
delay(10);
|
|
|
|
}
|
2018-07-03 22:32:05 +00:00
|
|
|
} else if (rx_dtmf_idx > 0) {
|
|
|
|
rx_dtmf_buf[rx_dtmf_idx] = '\0'; // NULL terminate the string
|
|
|
|
Serial.println(rx_dtmf_buf);
|
|
|
|
rx_dtmf_idx = 0;
|
2018-06-17 02:14:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Is it time to send tone?
|
|
|
|
if (Serial.available()) {
|
2018-07-03 22:32:05 +00:00
|
|
|
uint8_t code = char2code(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);
|
|
|
|
}
|
|
|
|
while (radio.getDTMFTxActive() != 0) {
|
|
|
|
// wait until this code is done
|
|
|
|
delay(10);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Serial.available()) {
|
|
|
|
code = char2code(Serial.read());
|
2018-07-03 23:02:21 +00:00
|
|
|
if (code == 255) code = 0xE; // throw a * in there so we don't break things with an invalid code
|
2018-07-03 22:32:05 +00:00
|
|
|
radio.setDTMFCode(code); // set first
|
|
|
|
} else {
|
|
|
|
dtmf_to_tx = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// done with tone
|
|
|
|
radio.setModeReceive();
|
|
|
|
radio.setTxSourceMic();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t char2code(char c) {
|
2018-06-17 02:14:13 +00:00
|
|
|
uint8_t code;
|
|
|
|
if (c == '#') {
|
|
|
|
code = 0xF;
|
|
|
|
} else if (c=='*') {
|
2018-06-25 00:12:04 +00:00
|
|
|
code = 0xE;
|
2018-06-17 02:14:13 +00:00
|
|
|
} else if (c >= 'A' && c <= 'D') {
|
|
|
|
code = c - 'A' + 0xA;
|
|
|
|
} else if (c >= '0' && c <= '9') {
|
|
|
|
code = c - '0';
|
|
|
|
} else {
|
|
|
|
// invalid code, skip it
|
2018-07-03 22:32:05 +00:00
|
|
|
code = 255;
|
2018-06-25 00:12:04 +00:00
|
|
|
}
|
2018-06-17 02:14:13 +00:00
|
|
|
|
2018-07-03 22:32:05 +00:00
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
|
|
|
char code2char(uint16_t code) {
|
|
|
|
char c;
|
|
|
|
if (code < 10) {
|
|
|
|
c = '0' + code;
|
|
|
|
} else if (code < 0xE) {
|
|
|
|
c = 'A' + code - 10;
|
|
|
|
} else if (code == 0xE) {
|
|
|
|
c = '*';
|
|
|
|
} else if (code == 0xF) {
|
|
|
|
c = '#';
|
|
|
|
} else {
|
|
|
|
c = '?'; // invalid code
|
2018-06-17 02:14:13 +00:00
|
|
|
}
|
2018-07-03 22:32:05 +00:00
|
|
|
|
|
|
|
return c;
|
2018-08-05 02:31:53 +00:00
|
|
|
}
|