diff --git a/GB3TX/GB3TX.ino b/GB3TX/GB3TX.ino index ccff043..4887cef 100644 --- a/GB3TX/GB3TX.ino +++ b/GB3TX/GB3TX.ino @@ -2,12 +2,9 @@ #include "repeater.h" void setup() { - pinMode(3, OUTPUT); - pinMode(8, OUTPUT); - pinMode(9, OUTPUT); - pinMode(7, INPUT_PULLUP); - pinMode(6, INPUT_PULLUP); - pinMode(PIP_ATT, OUTPUT); + for (int i=0; icallsign = ID; myrpt->params.cw_pitch = CW_PITCH; - myrpt->serial.enable = SERIAL; - myrpt->serial.speed = 115200; - if (myrpt->serial.enable) - Serial.begin(myrpt->serial.speed); /* Setup params */ myrpt->params.cw_speed = 1200 / CW_SPEED; @@ -33,100 +26,95 @@ void loop() { myrpt->params.pip_gw_letter = PIP_GW_LETTER; myrpt->params.start_up = START; + myrpt->receiver.id = 0; + myrpt->gateway.receiver.id = 1; + delay(1000); myrpt->transmitter.tx = true; - sendID(myrpt); + send_id(myrpt); myrpt->state = SLEEP; unsigned long ht = millis(); unsigned long tot = ht; - unsigned long kc; 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 (busy(myrpt) && myrpt->state < KEYCHUNK) { myrpt->state = KEYCHUNK; - serial_writer(&myrpt->serial, "KEYCHUNK"); - kc = millis(); } - if (myrpt->state == KEYCHUNK && millis() - kc > KEYCHUNK_TIME) { + if (myrpt->state == KEYCHUNK && cmp_keychunk(myrpt, KEYCHUNK_TIME)) { if (!myrpt->receiver.rx) { myrpt->state = TT; - serial_writer(&myrpt->serial, "RX: RF"); } 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->params.start_up && millis() - myrpt->last_id >= LAST_ID_HOLD) + send_id(myrpt); } if ((myrpt->receiver.rx && myrpt->gateway.receiver.rx) && myrpt->state == KEYCHUNK) { - serial_writer(&myrpt->serial, "SHORT SIGNAL"); myrpt->state = IDLE; } if ((myrpt->receiver.rx && myrpt->gateway.receiver.rx) && myrpt->state > HANG) { - serial_writer(&myrpt->serial, "HANG"); - if (myrpt->state == GW) - myrpt->stats.gw_time += millis() - myrpt->timer.gw_start; - delay(500); myrpt->last = myrpt->state; myrpt->state = HANG; ht = millis(); myrpt->tail = ht; - if (ht - tot < PIP_KEYCHUNK || busy(myrpt)) - continue; - courtesyTone(myrpt); + courtesy_tone(myrpt); } if (myrpt->state == HANG && TAILPIPS) { if (millis() - myrpt->tail >= TAIL_PIP_DELAY && !busy(myrpt)) { myrpt->tail = millis(); - tone(PIP, TAILPIP_PITCH, myrpt->params.pip_length); + tone(PIP, TAILPIP_PITCH, TAIL_LEN); } } if (!myrpt->receiver.rx && myrpt->state == HANG) { - serial_writer(&myrpt->serial, "RX: RF"); myrpt->state = TT; tot = millis(); } if (!myrpt->gateway.receiver.rx && myrpt->state == HANG) { - serial_writer(&myrpt->serial, "RX: GATEWAY"); myrpt->state = GW; tot = millis(); } - if (millis() - tot >= TIMEOUT && (myrpt->state == TT || myrpt->state == GW)) { - serial_writer(&myrpt->serial, "REPEATER: TIMEOUT"); - myrpt->state = TIMEOUT; - tone(PIP, 440, 1000); - delay(1000); + if (cmp_start(&myrpt->receiver.timestamp, TOTIME) && myrpt->state == TT ) { + myrpt->state = PEN_T; } if (myrpt->state == HANG && millis() - ht > HANGTIME) { - if (myrpt->params.close_down) { - serial_writer(&myrpt->serial, "REPEATER: CLOSEDOWN ID"); + if (myrpt->params.close_down && millis() - myrpt->last_id >= LAST_ID_HOLD) { myrpt->state = SLEEP; - sendID(myrpt); + send_id(myrpt); continue; } - serial_writer(&myrpt->serial, "REPEATER: IDLE"); myrpt->state = IDLE; } + if (myrpt->state == PEN_T) { + if (!busy(myrpt)) + myrpt->state = HANG; + static unsigned long pc; + static int c = 0; + unsigned long tick = millis(); + if (tick - pc < 1000) + continue; + + pc = tick; + tone(PIP, 1750, 50); + c++; + if (c >= 10) { + myrpt->state = TIMEOUT; + } + } + if (myrpt->state == TIMEOUT) { myrpt->state = IDLE; tx(myrpt); @@ -135,7 +123,6 @@ void loop() { if (myrpt->receiver.rx && myrpt->gateway.receiver.rx) break; } - serial_writer(&myrpt->serial, "REPEATER: TIMEOUT RESET"); } if (myrpt->state > SLEEP && millis() - myrpt->id_time >= (IDTIME - 60000)) { @@ -154,9 +141,8 @@ void loop() { tx(myrpt); myrpt->state = SLEEP; } - serial_writer(&myrpt->serial, "REPEATER: ID"); delay(250); - sendID(myrpt); + send_id(myrpt); } tx(myrpt); diff --git a/GB3TX/config.h b/GB3TX/config.h index 52650ec..04c2f9d 100644 --- a/GB3TX/config.h +++ b/GB3TX/config.h @@ -9,33 +9,44 @@ #define GWPTT 9 #define PIP 3 +uint8_t io[6][2] = { + {PIP_ATT, OUTPUT}, + {GW_COS, INPUT_PULLUP}, + {COS, INPUT_PULLUP}, + {PTT, OUTPUT}, + {GWPTT, OUTPUT}, + {PIP, OUTPUT} +}; + /* CW ID SETTINGS */ -#define ID "MX0WVV" -#define CW_SPEED 25 -#define CW_PITCH 950 +#define ID "GB3DL H" +#define CW_SPEED 18 +#define CW_PITCH 1200 /* PARAMS */ #define COURTESY CW -#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 CLOSEDOWN 0 +#define GWPIPLEN 150 +#define PIP_LETTER 'E' +#define PIP_GW_LETTER 'S' +#define RFPIP CW_PITCH +#define RFPIPLEN 300 #define START 0 #define TAILPIPS true -#define TAILPIP_PITCH 950 +#define TAILPIP_PITCH CW_PITCH - 225 /* SERIAL */ -#define SERIAL true +#define SERIAL false #define SERIAL_SPEED 115200 /* TIMERS */ -#define HANGTIME 5000 -#define KEYCHUNK_TIME 2500 -#define TIMEOUT 300000 -#define IDTIME 300000 +#define HANGTIME 7000 +#define KEYCHUNK_TIME 3000 +#define TOTIME 300000 +#define IDTIME 500000 +#define LAST_ID_HOLD 60000 #define PIP_KEYCHUNK 2000 #define TAIL_PIP_DELAY 1000 +#define TAIL_LEN 70 #endif \ No newline at end of file diff --git a/GB3TX/cw.ino b/GB3TX/cw.ino index 4be4ea3..d6e8940 100644 --- a/GB3TX/cw.ino +++ b/GB3TX/cw.ino @@ -1,6 +1,6 @@ #include "cw.h" -void sendChar(repeater* myrpt, char c) { +void send_char(repeater* myrpt, char c) { if (c < 47 || c > 90) { delay(myrpt->params.cw_speed * 3 * 2); return; @@ -43,19 +43,15 @@ void sendChar(repeater* myrpt, char c) { } } -void sendID(repeater* myrpt) { +void send_id(repeater* myrpt) { myrpt->id_time = millis(); + myrpt->last_id = myrpt->id_time; 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++) { - sendChar(myrpt, myrpt->callsign[i]); + send_char(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 7c1a8d6..b691889 100644 --- a/GB3TX/repeater.h +++ b/GB3TX/repeater.h @@ -8,7 +8,8 @@ typedef enum { HANG, GW, TT, - TOT, + PEN_T, + TIMEOUT, }state; typedef enum { @@ -33,60 +34,37 @@ typedef struct { }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; + unsigned long start; + unsigned long end; +}t_stamp; typedef struct { bool tx; - unsigned long long tx_time; }transmitter; typedef struct { int id; bool rx; - unsigned long long rx_time; + t_stamp timestamp; }receiver; typedef struct { - bool enable; - unsigned long speed; -}serial; - -typedef struct { - bool enable; receiver receiver; transmitter transmitter; }gateway; typedef struct { char* callsign; + int last_caller; gateway gateway; unsigned long id_time; + unsigned long last_id; state last; 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 d859866..8af4735 100644 --- a/GB3TX/repeater.ino +++ b/GB3TX/repeater.ino @@ -1,38 +1,51 @@ void tx(repeater* myrpt) { if (myrpt->state > IDLE && !myrpt->transmitter.tx) { - serial_writer(&myrpt->serial, "REPEATER: TX ON"); 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); } } void rx(repeater* myrpt) { - myrpt->receiver.rx = digitalRead(COS); - myrpt->gateway.receiver.rx = digitalRead(GW_COS); - - if (!myrpt->receiver.rx && !myrpt->gateway.transmitter.tx) { - serial_writer(&myrpt->serial, "REPEATER: COS"); + + /* TODO: This is terrible and needs cleaning! */ + if (myrpt->receiver.rx && !digitalRead(COS)) { + myrpt->receiver.rx = digitalRead(COS); + myrpt->receiver.timestamp.start = millis(); digitalWrite(GWPTT, true); myrpt->gateway.transmitter.tx = true; - myrpt->timer.rx_start = millis(); + myrpt->last_caller = myrpt->receiver.id; 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; + if (!myrpt->receiver.rx && digitalRead(COS)) { + myrpt->receiver.rx = digitalRead(COS); + myrpt->receiver.timestamp.end = millis(); + if (myrpt->gateway.transmitter.tx) { + digitalWrite(GWPTT, false); + myrpt->gateway.transmitter.tx = false; + } } + + if (myrpt->gateway.receiver.rx && !digitalRead(GW_COS)) { + myrpt->gateway.receiver.rx = digitalRead(GW_COS); + myrpt->last_caller = myrpt->gateway.receiver.id; + myrpt->gateway.receiver.timestamp.start = millis(); + } + + if (!myrpt->gateway.receiver.rx && digitalRead(GW_COS)) { + myrpt->gateway.receiver.rx = digitalRead(GW_COS); + myrpt->last_caller = myrpt->gateway.receiver.id; + myrpt->gateway.receiver.timestamp.end = millis(); + } + + } bool busy(repeater* myrpt) { @@ -40,77 +53,34 @@ bool busy(repeater* myrpt) { return (!myrpt->receiver.rx || !myrpt->gateway.receiver.rx); } -void courtesyTone(repeater* myrpt) { +bool cmp_keychunk(repeater* myrpt, unsigned long cmp) { + if (myrpt->last_caller == 0) { + return (cmp_start(&myrpt->receiver.timestamp, cmp)); + } else { + return (cmp_start(&myrpt->gateway.receiver.timestamp, cmp)); + } +} + +bool cmp_start(t_stamp* ts, unsigned long cmp) { + return millis() - ts->start > cmp; +} + +void courtesy_tone(repeater* myrpt) { + delay(500); + /* Did the last caller beat the timer? */ + if (!cmp_keychunk(myrpt, PIP_KEYCHUNK) || busy(myrpt)) + return; + switch(myrpt->params.courtesy) { case TONE: 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, myrpt->params.pip_letter) : sendChar(myrpt, myrpt->params.pip_gw_letter); + myrpt->last == TT ? send_char(myrpt, myrpt->params.pip_letter) : send_char(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; - Serial.write(buff); - Serial.write('\n'); } \ No newline at end of file