// Auto CQ Caller // This project is based on portions of code from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1234149784 (Marcelo Shiniti Uchimura) // and ACP loading code from https://codebender.cc/sketch:247685#ISD1700.ino (Code Bender - Grimar) // The rest was kludged together by John Forrest (VK3JNF) #includeISD1700 chip(10); // Initialize chipcorder with SS at Arduino's digital pin 10 // The following pins are pre-defined // in ISD1700.h // SCK_PIN 13 // MISO_PIN 12 // MOSI_PIN 11 // Define Input pin numbers #define button_PTT 2 // PTT (Press to Talk) pushbutton (Interrupt) #define button_CQ 3 // CQ pushutton #define button_SETUP 4 // Message Setup pushutton #define buttonPlay 5 // Play pushbutton #define buttonStop 6 // Stop pushbutton #define buttonForward 7 // Forward pushbutton #define buttonRecord 8 // Record pushbutton #define buttonErase 9 // Erase pushbutton // Define Output pin numbers #define RXLED 14 // RX LED Pin #define TXLED 15 // Activate PTT, TX LED Pin #define RECLED 16 // Recorder Active LED pin #define CQLED 17 // CQ Caller Active LED Pin #define QSOLED 18 // QSO Active LED Pin // Variables int vol = 0; //volume 0=MAX, 7=min int volcon = false; // Volume Control true=Up, false=Down int APC_Reg_Play = 0; // APC CQ Configuration Bit Storage int APC_Reg_FT = 0; // APC QSO Configuration Bit Storage int APC_Reg_Rec = 0; // APC Record Configuration Bit Storage volatile int QSO_CQ_state; // QSO or CQ operation state (Interrupt variable) int sensorReading; // Storage for QRZ delay control pot reading unsigned long MAXdelay; // Maximum Listening Delay between CQ calls for QRZ response unsigned long MINdelay; // Minimum Listening Delay between CQ calls for QRZ responses unsigned long QRZdelay; // Listening Delay counter void setup() { Serial.begin(9600); // Load APC Register Bit Storage by OR masking in the appropriate bits // for each mode of operation. // Play Operation (Used in Recording and CQ modes) APC_Reg_Play = APC_Reg_Play | vol; // D0, D1, D2 APC_Reg_Play = APC_Reg_Play | 0x40; // D4=0; D6=1 MIC Reord, No Feed Through, Output on analogue + Speaker // APC_Reg_Play = APC_Reg_Play | 0x80; // D7=1; AUX ON APC_Reg_Play = APC_Reg_Play | 0x800; // D11=1; EOM ON // Feed Thru Operation (Used in QSO Mode) APC_Reg_FT = APC_Reg_FT | vol; // D0, D1, D2 // APC_Reg_FT = APC_Reg_FT | 0x80; // D7=1; AUX ON APC_Reg_FT = APC_Reg_FT | 0x100; // D8=1; Analogue input Feed Through, Speaker Disabled, Output on analogue APC_Reg_FT = APC_Reg_FT | 0x800; // D11=1; EOM ON // Record Operation (Used in Recording Mode) APC_Reg_Rec = APC_Reg_Rec | vol; // D0, D1, D2 APC_Reg_Rec = APC_Reg_Rec | 0x200; // D9=1; Analogue Input Record, Analogue input Feed Through, AUD/AUX OFF APC_Reg_Rec = APC_Reg_Rec | 0x800; // D11=1; EOM ON Serial.println(APC_Reg_Play,BIN); Serial.println(APC_Reg_FT,BIN); Serial.println(APC_Reg_Rec,BIN); //Configure pins as inputs and enable the internal pull-up resistors pinMode(buttonPlay, INPUT_PULLUP); pinMode(buttonStop, INPUT_PULLUP); pinMode(buttonErase, INPUT_PULLUP); pinMode(buttonRecord, INPUT_PULLUP); pinMode(buttonForward, INPUT_PULLUP); pinMode(button_CQ, INPUT_PULLUP); pinMode(button_SETUP, INPUT_PULLUP); pinMode(button_PTT, INPUT_PULLUP); //configure pins as outputs pinMode(RECLED, OUTPUT); pinMode(RXLED, OUTPUT); pinMode(TXLED, OUTPUT); pinMode(CQLED, OUTPUT); pinMode(QSOLED, OUTPUT); // Set up Interrupt Pin attachInterrupt(digitalPinToInterrupt(button_PTT), checkPTT, CHANGE); // Set variables QSO_CQ_state = 1; // Start up in QSO state MAXdelay = 1500000; // Set maximum listening delay between CQ calls. MINdelay = 100000; // Set minimum listening delay between CQ calls. // Power Up the chip chip.pu(); //Enable SPI Control while (!chip.RDY()) { // Wait for ready } } void loop() { checkState(); // Check all input buttons switch (QSO_CQ_state) { //********************************* QSO *************************************** case 1: digitalWrite(QSOLED, HIGH); // QSO LED On digitalWrite(TXLED, LOW); // Outgoing PTT inactve, TX LED Off digitalWrite(RXLED, HIGH); // RX LED On chip.wr_apc2(APC_Reg_FT); //Load APC Register with Feed Thru parameters while (QSO_CQ_state == 1) { // Wait for PTT if (digitalRead(button_PTT) == LOW){ digitalWrite(TXLED, HIGH); // Outgoing PTT actve, TX LED on digitalWrite(RXLED, LOW); // RX LED off while ((digitalRead(button_PTT) == LOW)) { // Wait here until QSO done } digitalWrite(TXLED, LOW); // Outgoing PTT inactive, TX LED off digitalWrite(RXLED, HIGH); // RX LED on } checkState(); // Check all input buttons } digitalWrite(RXLED, LOW); // RX LED off digitalWrite(QSOLED, LOW); // QSO LED Off break; //********************************* CQ *************************************** case 2: digitalWrite(CQLED, HIGH); // CQ LED On digitalWrite(RXLED, HIGH); // RX LED on chip.wr_apc2(APC_Reg_Play); //Load the APC Register with Play parameters while (QSO_CQ_state == 2) { // Keep Calling while in CQ state digitalWrite(TXLED, HIGH); // Outgoing PTT active, TX LED on digitalWrite(RXLED, LOW); // RX LED Off delay(300); // Short delay for PTT activation chip.play(); // Call CQ delay(500); while (!chip.RDY()) { // Wait for CQ Call to end if (digitalRead(button_CQ) == LOW){ // CQ Button volAdj(); chip.wr_apc2(APC_Reg_Play); //Load the APC Register with Play parameters delay(500); } } delay(300); // Short delay for PTT deactivation digitalWrite(TXLED, LOW); // Outgoing PTT inactive, TX LED off digitalWrite(RXLED, HIGH); // RX LED on // QRZ delay // read the sensor value: int sensorReading = analogRead(A5); // map it to a range from 0 to 100: QRZdelay = map(sensorReading, 0, 1023, MINdelay, MAXdelay); while(QRZdelay>0){ checkState(); // Check all input buttons if (QSO_CQ_state != 2) { // Check if still in CQ state delay(300); // Short delay QRZdelay=0; }else{ --QRZdelay; //Serial.println(QRZdelay); } } } digitalWrite(RXLED, LOW); // RX LED Off digitalWrite(CQLED, LOW); // CQ LED Off break; default: //************************************** Record/Playback Functions ************************** digitalWrite(RECLED, HIGH); // Setup LED on chip.wr_apc2(APC_Reg_Play); //Load the APC Register with Play parameters while (QSO_CQ_state == 3) { // Keep in Recording while in Recording state if (digitalRead(button_SETUP) == LOW) { // Setup Button Pressed again for Volume change volAdj(); chip.wr_apc2(APC_Reg_Play); //Load the APC Register with Play parameters delay(500); } if (digitalRead(buttonPlay) == LOW) { // Play current recording file chip.play(); delay(500); } if (digitalRead(buttonStop) == LOW) { // Stop Recording or Playing current File chip.stop(); chip.wr_apc2(APC_Reg_Play); //Load the APC Register with Play parameters } if (digitalRead(buttonErase) == LOW) { // Erase current Recording File chip.erase(); } if (digitalRead(buttonRecord) == LOW) { // Record to current file chip.wr_apc2(APC_Reg_Rec); //Load the APC Register with Record parameters chip.rec(); } if (digitalRead(buttonForward) == LOW) { // Step forward through recording files chip.fwd(); } checkState(); // Check system State } digitalWrite(RECLED, LOW); // Setup LED Off break; } } //********************************** Subroutines ************************* // Check PTT Button // void checkPTT(){ // PTT interrupt if (QSO_CQ_state != 1){ // Switch State to QSO State QSO_CQ_state = 1; // Switch State to QSO State chip.stop(); // Stop CQ Caller delay(500); } } // Check Other Buttons // void checkState() { if (digitalRead(button_CQ) == LOW){ // CQ Button QSO_CQ_state = 2; // Switch State to CQ Caller } if (digitalRead(button_SETUP) == LOW) { // Setup Button QSO_CQ_state = 3; // Switch state to Message Recording } } // Volume Adjust void volAdj() { if (volcon==true) { // Volume Up if (vol<7) { vol=++vol; }else { volcon=false; } } if (volcon==false) { // Volume Down if (vol>0) { vol=--vol; }else { volcon=true; vol=++vol; } } // Update Play Register APC_Reg_Play = APC_Reg_Play >> 3; // Shift data bits D0, D1, D2 out APC_Reg_Play = APC_Reg_Play << 3; // Shift databack 3 bits back APC_Reg_Play = APC_Reg_Play | vol; // OR data bits D0, D1, D2 // Update Feed Thru Register APC_Reg_FT = APC_Reg_FT >> 3; // Shift data bits D0, D1, D2 out APC_Reg_FT = APC_Reg_FT << 3; // Shift databack 3 bits back APC_Reg_FT = APC_Reg_FT | vol; // OR data bits D0, D1, D2 // Update Record Register APC_Reg_Rec = APC_Reg_Rec >> 3; // Shift data bits D0, D1, D2 out APC_Reg_Rec = APC_Reg_Rec << 3; // Shift databack 3 bits back APC_Reg_Rec = APC_Reg_Rec | vol; // OR data bits D0, D1, D2 }