diff --git a/GB3TX/GB3TX.ino b/GB3TX/GB3TX.ino index 1af4be8..ccff043 100644 --- a/GB3TX/GB3TX.ino +++ b/GB3TX/GB3TX.ino @@ -23,14 +23,15 @@ void loop() { /* Setup params */ myrpt->params.cw_speed = 1200 / CW_SPEED; + myrpt->params.close_down = CLOSEDOWN; myrpt->params.pip_length = RFPIPLEN; myrpt->params.pip_pitch = RFPIP; + myrpt->params.pip_gw_pitch = RFPIP; myrpt->params.pip_gw_length = GWPIPLEN; - myrpt->params.pip_gw_pitch = GWPIP; myrpt->params.courtesy = COURTESY; - myrpt->params.pip_speed = 1200 / PIP_SPEED; myrpt->params.pip_letter = PIP_LETTER; myrpt->params.pip_gw_letter = PIP_GW_LETTER; + myrpt->params.start_up = START; delay(1000); myrpt->transmitter.tx = true; @@ -40,13 +41,17 @@ void loop() { unsigned long ht = millis(); unsigned long tot = ht; unsigned long kc; - unsigned long id = ht; + myrpt->id_time = 0; serial_writer(&myrpt->serial, "READY"); digitalWrite(PIP_ATT, LOW); + myrpt->stats.gw_time = 0; + myrpt->stats.tx_time = 0; + myrpt->stats.rx_time = 0; while (1) { + serial_command(&myrpt->serial, myrpt); rx(myrpt); - if (((!myrpt->receiver.rx || !myrpt->gateway.receiver.rx)) && myrpt->state < KEYCHUNK) { + if (busy(myrpt) && myrpt->state < KEYCHUNK) { myrpt->state = KEYCHUNK; serial_writer(&myrpt->serial, "KEYCHUNK"); kc = millis(); @@ -59,8 +64,11 @@ void loop() { } else { myrpt->state = GW; serial_writer(&myrpt->serial, "RX: GATEWAY"); + myrpt->timer.gw_start = millis(); } tot = millis(); + if (myrpt->params.start_up) + sendID(myrpt); } if ((myrpt->receiver.rx && myrpt->gateway.receiver.rx) && myrpt->state == KEYCHUNK) { @@ -70,7 +78,9 @@ void loop() { if ((myrpt->receiver.rx && myrpt->gateway.receiver.rx) && myrpt->state > HANG) { serial_writer(&myrpt->serial, "HANG"); - delay(350); + if (myrpt->state == GW) + myrpt->stats.gw_time += millis() - myrpt->timer.gw_start; + delay(500); myrpt->last = myrpt->state; myrpt->state = HANG; ht = millis(); @@ -99,11 +109,6 @@ void loop() { tot = millis(); } - if (myrpt->state == HANG && millis() - ht > HANGTIME) { - serial_writer(&myrpt->serial, "REPEATER: IDLE"); - myrpt->state = IDLE; - } - if (millis() - tot >= TIMEOUT && (myrpt->state == TT || myrpt->state == GW)) { serial_writer(&myrpt->serial, "REPEATER: TIMEOUT"); myrpt->state = TIMEOUT; @@ -111,6 +116,17 @@ void loop() { delay(1000); } + if (myrpt->state == HANG && millis() - ht > HANGTIME) { + if (myrpt->params.close_down) { + serial_writer(&myrpt->serial, "REPEATER: CLOSEDOWN ID"); + myrpt->state = SLEEP; + sendID(myrpt); + continue; + } + serial_writer(&myrpt->serial, "REPEATER: IDLE"); + myrpt->state = IDLE; + } + if (myrpt->state == TIMEOUT) { myrpt->state = IDLE; tx(myrpt); @@ -122,13 +138,13 @@ void loop() { serial_writer(&myrpt->serial, "REPEATER: TIMEOUT RESET"); } - if (myrpt->state > SLEEP && millis() - id >= (IDTIME - 60000)) { + if (myrpt->state > SLEEP && millis() - myrpt->id_time >= (IDTIME - 60000)) { /* Check if the repeater is in use * wait the full ID time */ - if (myrpt->state > IDLE && millis() - id < IDTIME) { + if (myrpt->state > IDLE && millis() - myrpt->id_time < IDTIME) { continue; } @@ -139,8 +155,8 @@ void loop() { myrpt->state = SLEEP; } serial_writer(&myrpt->serial, "REPEATER: ID"); + delay(250); sendID(myrpt); - id = millis(); } tx(myrpt); diff --git a/GB3TX/config.h b/GB3TX/config.h index 04859d7..52650ec 100644 --- a/GB3TX/config.h +++ b/GB3TX/config.h @@ -10,21 +10,21 @@ #define PIP 3 /* CW ID SETTINGS */ -#define ID "M0ZAH/R" -#define CW_SPEED 22 -#define CW_PITCH 875 +#define ID "MX0WVV" +#define CW_SPEED 25 +#define CW_PITCH 950 /* PARAMS */ #define COURTESY CW -#define GWPIP 1200 -#define GWPIPLEN 120 -#define PIP_LETTER 'R' -#define PIP_GW_LETTER 'E' -#define PIP_SPEED 20 -#define RFPIP 1200 -#define RFPIPLEN 80 +#define CLOSEDOWN 1 +#define GWPIPLEN 1200 / CW_SPEED +#define PIP_LETTER 'W' +#define PIP_GW_LETTER 'X' +#define RFPIP 950 +#define RFPIPLEN 1200 / CW_SPEED +#define START 0 #define TAILPIPS true -#define TAILPIP_PITCH 500 +#define TAILPIP_PITCH 950 /* SERIAL */ #define SERIAL true @@ -32,9 +32,10 @@ /* TIMERS */ #define HANGTIME 5000 -#define KEYCHUNK_TIME 1000 +#define KEYCHUNK_TIME 2500 #define TIMEOUT 300000 #define IDTIME 300000 -#define PIP_KEYCHUNK 1500 +#define PIP_KEYCHUNK 2000 +#define TAIL_PIP_DELAY 1000 #endif \ No newline at end of file diff --git a/GB3TX/cw.ino b/GB3TX/cw.ino index 6b6b794..4be4ea3 100644 --- a/GB3TX/cw.ino +++ b/GB3TX/cw.ino @@ -1,8 +1,8 @@ #include "cw.h" -void sendChar(int speed, int pitch, char c) { +void sendChar(repeater* myrpt, char c) { if (c < 47 || c > 90) { - delay(speed * 3 * 2); + delay(myrpt->params.cw_speed * 3 * 2); return; } @@ -20,35 +20,42 @@ void sendChar(int speed, int pitch, char c) { int dd = morse[index]; + if (digitalRead(PIP_ATT) && myrpt->state != SLEEP) + digitalWrite(PIP_ATT, LOW); for (int i=0; i < 8; i++) { if (dd == 1) { return; } - tone(PIP, pitch); + /* + * attenuate pips in active T/T + */ + if (busy(myrpt) && !digitalRead(PIP_ATT)) + digitalWrite(PIP_ATT, HIGH); + tone(PIP, myrpt->params.cw_pitch); if (dd&1) { - delay(speed * 3); + delay(myrpt->params.cw_speed * 3); } else { - delay(speed); + delay(myrpt->params.cw_speed); } dd >>= 1; noTone(PIP); - delay(speed); + delay(myrpt->params.cw_speed); } } void sendID(repeater* myrpt) { + myrpt->id_time = millis(); if (myrpt->callsign == NULL) { return; } + + delay(500); + + if (myrpt->state == SLEEP) + digitalWrite(PIP_ATT, HIGH); for (int i=0; i < sizeof ID/sizeof ID[0]; i++) { - /* attenuate pips in active T/T - * unless first ID from sleep - */ - if (busy(myrpt) && !digitalRead(PIP_ATT)) - digitalWrite(PIP_ATT, HIGH); - - sendChar(myrpt->params.cw_speed, myrpt->params.cw_pitch, myrpt->callsign[i]); + sendChar(myrpt, myrpt->callsign[i]); delay(myrpt->params.cw_speed * 3); } if (digitalRead(PIP_ATT)) diff --git a/GB3TX/repeater.h b/GB3TX/repeater.h index 5270e3b..7c1a8d6 100644 --- a/GB3TX/repeater.h +++ b/GB3TX/repeater.h @@ -14,10 +14,12 @@ typedef enum { typedef enum { TONE, CW, + NONE, }c_type; typedef struct { c_type courtesy; + int close_down; int cw_pitch; int cw_speed; int pip_length; @@ -27,8 +29,21 @@ typedef struct { int pip_gw_length; char pip_gw_letter; int pip_gw_pitch; + int start_up; }params; +typedef struct { + unsigned long tx_start; + unsigned long rx_start; + unsigned long gw_start; +}timer; + +typedef struct { + unsigned long tx_time; + unsigned long rx_time; + unsigned long gw_time; +}stats; + typedef struct { bool tx; unsigned long long tx_time; @@ -59,9 +74,19 @@ typedef struct { params params; receiver receiver; serial serial; + stats stats; state state; + timer timer; transmitter transmitter; unsigned long tail; }repeater; +typedef struct { + byte type; + stats* stats; + bool transmitter; + bool receiver; + bool gateway; +}info; + #endif \ No newline at end of file diff --git a/GB3TX/repeater.ino b/GB3TX/repeater.ino index 5f4f090..d859866 100644 --- a/GB3TX/repeater.ino +++ b/GB3TX/repeater.ino @@ -4,12 +4,14 @@ void tx(repeater* myrpt) { myrpt->transmitter.tx = true; digitalWrite(PTT,LOW); delay(100); + myrpt->timer.tx_start = millis(); return; } if (myrpt->state < KEYCHUNK && myrpt->transmitter.tx) { serial_writer(&myrpt->serial, "REPEATER: TX OFF"); myrpt->transmitter.tx = false; + myrpt->stats.tx_time += millis() - myrpt->timer.tx_start; digitalWrite(PTT,HIGH); } } @@ -22,12 +24,14 @@ void rx(repeater* myrpt) { serial_writer(&myrpt->serial, "REPEATER: COS"); digitalWrite(GWPTT, true); myrpt->gateway.transmitter.tx = true; + myrpt->timer.rx_start = millis(); return; } if (myrpt->receiver.rx && myrpt->gateway.transmitter.tx) { digitalWrite(GWPTT, false); myrpt->gateway.transmitter.tx = false; + myrpt->stats.rx_time += millis() - myrpt->timer.rx_start; } } @@ -42,13 +46,68 @@ void courtesyTone(repeater* myrpt) { myrpt->last == TT ? tone(PIP, myrpt->params.pip_pitch, myrpt->params.pip_length) : tone(PIP, myrpt->params.pip_gw_pitch, myrpt->params.pip_gw_length); break; case CW: - myrpt->last == TT ? sendChar(myrpt->params.pip_speed,myrpt->params.pip_pitch,myrpt->params.pip_letter) : sendChar(myrpt->params.pip_speed,myrpt->params.pip_gw_pitch, myrpt->params.pip_gw_letter); + myrpt->last == TT ? sendChar(myrpt, myrpt->params.pip_letter) : sendChar(myrpt, myrpt->params.pip_gw_letter); + break; + default: break; } if (TAILPIPS) delay(myrpt->params.pip_length); } +void serial_command(serial* s, repeater* myrpt) { + char cmd[5]; + if (Serial.available() > 0) { + Serial.readBytes(cmd, 5); + switch (cmd[0]) { + case '0': + serial_writer(s, "SEND STATS"); + break; + case '1': + tone(PIP, 1000, 100); + break; + case '2': + serial_writer(s, "CONFIG: Set tone | (0) OFF | (1) CW | (2) TONE |"); + serial_writer(s, "Entered"); + switch (cmd[1]) { + case '0': + serial_writer(s, "Courtesy OFF"); + myrpt->params.courtesy = NONE; + break; + case '1': + serial_writer(s, "Courtesy CW"); + myrpt->params.courtesy = CW; + break; + case '2': + serial_writer(s, "Courtesy TONE"); + myrpt->params.courtesy = TONE; + break; + default: + break; + } + break; + case '3': + Serial.print("RX: "); Serial.println((myrpt->stats.rx_time /1000)); + Serial.print("TX: "); Serial.println((myrpt->stats.tx_time /1000)); + Serial.print("GW: "); Serial.println((myrpt->stats.gw_time /1000)); + Serial.print("RX Status: "); Serial.println(!myrpt->receiver.rx); + Serial.print("TX Status: "); Serial.println(myrpt->transmitter.tx); + Serial.print("GW Status: "); Serial.println(!myrpt->gateway.receiver.rx); + break; + case '4': + info inf; + inf.type = 254; + inf.stats = &myrpt->stats; + inf.receiver = !myrpt->receiver.rx; + inf.transmitter = myrpt->transmitter.tx; + inf.gateway = !myrpt->gateway.receiver.rx; + Serial.write((byte*)&inf, sizeof(info) + sizeof(stats) - 4); + default: + break; + } + } +} + void serial_writer(serial* s, char* buff) { if (!s->enable) return;