Co-authored-by: Jim Colderwood <jim.colderwood@pnsol.com>
Reviewed-on: #2
This commit is contained in:
jimzah 2024-04-06 19:10:18 +01:00
parent d78d3c11c9
commit aab8ebd76c
5 changed files with 98 additions and 44 deletions

View File

@ -1,14 +1,13 @@
#include "config.h"
#include "repeater.h"
#define PIP_OUT 13
void setup() {
pinMode(3, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(7, INPUT);
pinMode(7, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(PIP_ATT, OUTPUT);
}
void loop() {
@ -17,6 +16,10 @@ void loop() {
myrpt = &rpt;
myrpt->callsign = 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;
@ -38,28 +41,35 @@ void loop() {
unsigned long tot = ht;
unsigned long kc;
unsigned long id = ht;
serial_writer(&myrpt->serial, "READY");
digitalWrite(PIP_ATT, LOW);
while (1) {
rx(myrpt);
if (((!myrpt->receiver.rx || !myrpt->gateway.receiver.rx)) && myrpt->state < 2) {
if (((!myrpt->receiver.rx || !myrpt->gateway.receiver.rx)) && myrpt->state < KEYCHUNK) {
myrpt->state = KEYCHUNK;
serial_writer(&myrpt->serial, "KEYCHUNK");
kc = millis();
}
if (myrpt->state == KEYCHUNK && millis() - kc > 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");
}
tot = millis();
}
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");
delay(350);
myrpt->last = myrpt->state;
myrpt->state = HANG;
@ -78,20 +88,24 @@ void loop() {
}
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 (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;
tone(3, 440, 1000);
delay(1000);
@ -105,20 +119,31 @@ void loop() {
if (myrpt->receiver.rx && myrpt->gateway.receiver.rx)
break;
}
serial_writer(&myrpt->serial, "REPEATER: TIMEOUT RESET");
}
tx(myrpt);
if (myrpt->state > SLEEP && millis() - id >= (IDTIME - 60000)) {
/* Check if the repeater is in use
* wait the full ID time
*/
if (myrpt->state > IDLE && millis() - id < IDTIME) {
continue;
}
if (myrpt->state > SLEEP && millis() - id >= IDTIME) {
/* Repeater is IDLE, bring the transmitter up */
if (!myrpt->transmitter.tx) {
myrpt->state = HANG;
tx(myrpt);
myrpt->state = SLEEP;
}
serial_writer(&myrpt->serial, "REPEATER: ID");
sendID(myrpt);
id = millis();
}
tx(myrpt);
}
}

View File

@ -2,6 +2,7 @@
#define CONFIG_H
/* IO */
#define PIP_ATT 13
#define GW_COS 6
#define COS 7
#define PTT 8
@ -15,21 +16,25 @@
/* PARAMS */
#define COURTESY CW
#define GWPIP 875
#define GWPIP 1200
#define GWPIPLEN 120
#define PIP_LETTER 'R'
#define PIP_GW_LETTER 'I'
#define PIP_SPEED 18
#define PIP_GW_LETTER 'E'
#define PIP_SPEED 20
#define RFPIP 1200
#define RFPIPLEN 80
#define TAILPIPS true
#define TAILPIP_PITCH 500
/* SERIAL */
#define SERIAL true
#define SERIAL_SPEED 115200
/* TIMERS */
#define HANGTIME 3000
#define HANGTIME 5000
#define KEYCHUNK_TIME 1000
#define TIMEOUT 300000
#define IDTIME 300000
#define PIP_KEYCHUNK 1500
#define PIP_KEYCHUNK 1500
#endif

View File

@ -37,14 +37,25 @@ void sendChar(int speed, int pitch, char c) {
}
void sendID(repeater* myrpt) {
bool pip_att = false;
if (myrpt->callsign == NULL) {
return;
}
for (int i=0; i < sizeof ID/sizeof ID[0]; i++) {
/* attenuate pips in active T/T
* unless first ID from sleep
*/
if (myrpt->state != KEYCHUNK && busy(myrpt) && !pip_att) {
pip_att = true;
digitalWrite(PIP_ATT, HIGH);
}
sendChar(myrpt->params.cw_speed, myrpt->params.cw_pitch, myrpt->callsign[i]);
delay(myrpt->params.cw_speed * 3);
}
if (pip_att) {
digitalWrite(PIP_ATT, LOW);
}
}

View File

@ -18,45 +18,49 @@ typedef enum {
typedef struct {
c_type courtesy;
int cw_pitch;
int cw_speed;
int pip_length;
char pip_letter;
int pip_pitch;
int pip_speed;
int pip_gw_length;
char pip_gw_letter;
int pip_gw_pitch;
int cw_pitch;
int cw_speed;
int pip_length;
char pip_letter;
int pip_pitch;
int pip_speed;
int pip_gw_length;
char pip_gw_letter;
int pip_gw_pitch;
}params;
typedef struct {
bool tx;
bool tx;
unsigned long long tx_time;
}transmitter;
typedef struct {
int id;
bool rx;
int id;
bool rx;
unsigned long long rx_time;
}receiver;
typedef struct {
bool enable;
receiver receiver;
bool enable;
unsigned long speed;
}serial;
typedef struct {
bool enable;
receiver receiver;
transmitter transmitter;
}gateway;
typedef struct {
char* callsign;
int cw_pitch;
gateway gateway;
int hangtime;
char* callsign;
gateway gateway;
unsigned long id_time;
state last;
params params;
receiver receiver;
state state;
transmitter transmitter;
state last;
params params;
receiver receiver;
serial serial;
state state;
transmitter transmitter;
}repeater;
#endif

View File

@ -1,16 +1,17 @@
void tx(repeater* myrpt) {
if (myrpt->state > 1 && !myrpt->transmitter.tx) {
if (myrpt->state > IDLE && !myrpt->transmitter.tx) {
serial_writer(&myrpt->serial, "REPEATER: TX ON");
myrpt->transmitter.tx = true;
digitalWrite(PTT,LOW);
delay(100);
return;
}
if (!myrpt->transmitter.tx)
return;
myrpt->transmitter.tx = false;
digitalWrite(PTT,HIGH);
if (myrpt->state < KEYCHUNK && myrpt->transmitter.tx) {
serial_writer(&myrpt->serial, "REPEATER: TX OFF");
myrpt->transmitter.tx = false;
digitalWrite(PTT,HIGH);
}
}
void rx(repeater* myrpt) {
@ -18,12 +19,13 @@ void rx(repeater* myrpt) {
myrpt->gateway.receiver.rx = digitalRead(GW_COS);
if (!myrpt->receiver.rx && !myrpt->gateway.transmitter.tx) {
serial_writer(&myrpt->serial, "REPEATER: COS");
digitalWrite(GWPTT, true);
myrpt->gateway.transmitter.tx = true;
return;
}
if (myrpt->gateway.transmitter.tx) {
if (myrpt->receiver.rx && myrpt->gateway.transmitter.tx) {
digitalWrite(GWPTT, false);
myrpt->gateway.transmitter.tx = false;
}
@ -38,11 +40,18 @@ void courtesyTone(repeater* myrpt) {
switch(myrpt->params.courtesy) {
case TONE:
myrpt->last == TT ? tone(3, myrpt->params.pip_pitch, myrpt->params.pip_length) : tone(3, myrpt->params.pip_gw_pitch, myrpt->params.pip_gw_length);
if (TAILPIPS)
delay(150);
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);
break;
}
if (TAILPIPS)
delay(myrpt->params.pip_length);
}
void serial_writer(serial* s, char* buff) {
if (!s->enable)
return;
Serial.write(buff);
Serial.write('\n');
}