HOMEMADE NUMBER STATION
The circuit is just an Arduino connected to an SD card reader. The supply voltage for the SD is obtained using a zener regulator. The audio synthesis is carried out on a PWM pin either via 8 or 16 bit sampling and an RC high pass filter. The white and red wires are the audio output (signal+ground), while the strip connector is used for ISP and power supply. The system is able to read out vocal messages stored on the SD card using NATO alphabet at set time intervals or when a specific trigger pin in pulled low.
The SD contains the following items:
Also, the transmission channel can be kept occupied even when a message is not being sent by playing a user selected sound at short intervals (the BUZZER). The code is able to autoreset the arduino in case of fault.
#include <MemoryFree.h>
#include <avr/pgmspace.h>
#include <EEPROM.h>
#include <Sleep_n0m1.h>
#include <SD.h>
#include <TMRpcm.h>
#include <SPI.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#define Reset_AVR() wdt_enable(WDTO_500MS); while(1) {}
#define SD_ChipSelectPin 10
#define audiopin 9
#define pttpin 4
#define triggerpin 2
#define letterdelay 80
#define numberdelay 190
#define spacedelay 500
#define warmup 100
uint8_t telemetryflag;
uint8_t interval;
uint8_t occupyflag;
uint8_t opmode;
uint8_t s=0;
char buf[8];
char buff[9];
char msg[200];
const char string_1[] PROGMEM = "a/sa.wav";
const char string_0[] PROGMEM = "a/a.wav";
const char* const string_table[] PROGMEM = {string_0, string_1};
TMRpcm audio;
File myFile;
Sleep sleep;
void setup(){
// Serial.begin(9600);
if(opmode!=2){pinMode(triggerpin,INPUT_PULLUP);}
audio.speakerPin = audiopin;
audio.quality(1);
audio.volume(5);
if (!SD.begin(SD_ChipSelectPin)) {
Reset_AVR();}
recallsettings();
strcpy_P(buf,(char*)pgm_read_word(&(string_table[0])));
strcpy_P(buff,(char*)pgm_read_word(&(string_table[1])));
tone();
delay(300);
tone();
}
void loop(){
if(opmode==1){
sleep.pwrDownMode();
sleep.sleepInterrupt(triggerpin, FALLING);
if(telemetryflag==1){s = collectdata();}
transmission();
}
if(opmode==2){
tsleep(interval);
if(telemetryflag==1){s = collectdata();}
transmission();
}
if(opmode==3){
trsleep();
}
if(opmode==4){
delay(interval);
}
}
uint8_t collectdata() {
pinMode(A0,INPUT);
analogReference(INTERNAL);
delay(500);
uint8_t v=0;
for (uint8_t l = 0; l < 5; l++){
v = v + analogRead(A0);
delay(200);
}
uint8_t tempC = round (10*( v /( 5* 9.31)));
return tempC;
}
void senddata(){
send('t');
send(char(((s/100)%10)+48));
send(char(((s/10)%10)+48));
send(char(((s)%10)+48));
playtone('_');
}
void send(char c) {
if (c == '_'){
playtone(c);
return;}
if (c == ' '){
delay(spacedelay);
return;}
buf[2]=c;
audio.play(buf);
while (audio.isPlaying() == 1){delay(5);}
if (uint8_t(c)>47 && uint8_t(c)<58){
delay(numberdelay);
return;}
delay(letterdelay);
}
void sendmsg(char *str)
{
while (*str) {
send(*str++);
// Serial.print(F("Free RAM: ")); Serial.println(FreeRam());
}}
void recallsettings(){
myFile = SD.open("settings.txt");
if (!myFile) {Reset_AVR();}
interval = myFile.parseInt();
telemetryflag = myFile.parseInt();
occupyflag = myFile.parseInt();
opmode = myFile.parseInt();
int i=0;
char a;
while (myFile.read() != '[') {delay(1);}
msg[i] = myFile.read();
i++;
a= myFile.read();
while (a!=']') {
msg[i]=a;
i++;
a = myFile.read();}
msg[i]='\0';
myFile.close();
}
void txcount(){
long w =0;
myFile = SD.open("txcount.txt");
if (myFile) {
w = myFile.parseInt();
}
myFile.close();
w++;
SD.remove("txcount.txt");
myFile = SD.open("txcount.txt", FILE_WRITE);
if (myFile) {
myFile.print(F("Transmissions counter ["));
myFile.print(w);
myFile.print(F("]"));
myFile.close();
}
}
void tsleep(uint8_t t){
for (uint8_t i=0; i < (t*60000)/2000; i++){
sleep.pwrDownMode();
sleep.sleepDelay(2000);
if (occupyflag==1) {tone();}
}}
void trsleep(){
while(1){
sleep.pwrDownMode();
sleep.sleepDelay(2000);
if (occupyflag==1) {tone();}
if (digitalRead(triggerpin)==LOW){
delay(50);
if (digitalRead(triggerpin)==LOW){
if(telemetryflag==1){s = collectdata();}
transmission();}}
}}
void playtone(char t) {
if (t=='_'){
delay(300);
buff[3]='h';
audio.play(buff);
delay(500);
audio.disable();
delay(600);
return;}
buff[3]=t;
audio.play(buff);
}
void tone(){
digitalWrite(pttpin,HIGH);
delay(warmup);
playtone('l');
delay(500);
playtone('h');
delay(250);
audio.disable();
digitalWrite(pttpin,LOW);
}
void transmission(){
digitalWrite(pttpin,HIGH);
delay(warmup);
playtone('m');
while (audio.isPlaying() == 1){delay(5);}
playtone('_');
playtone('_');
playtone('_');
sendmsg(msg);
playtone('_');
if (telemetryflag==1) senddata();
playtone('_');
playtone('_');
txcount();
digitalWrite(pttpin,LOW);
}