Радиолюбительский Маяк на arduino nano
- 1
- 2
- 3
- 4
- 5
- следующая ›
- последняя »
- Войдите на сайт для отправки комментариев
Чт, 18/04/2019 - 21:53
В разработке конструкция простого радиолюбительского маяка на три диапазона, планируется 144/430/1200Mhz/
За основу скетча планировался проект выполненный радиолюбителем из Италии Nicola Salsotto IN3GJH
Так как скетч был сильно раскритикован здешним сообществом с их помощью и попытаюсь реализовать.
Начиналось с этого скетча:
01
#define SPEED (20) //скорость в WPM
02
#define DOTLEN (1200/SPEED)
03
#define DASHLEN (4*(1200/SPEED))
04
//#define PAUSE (180000) //пауза между передачами маяка в милисекундах
05
#define PAUSE (10000) //пауза между передачами маяка в милисекундах
06
07
int
txPin=10;
//управление PTT
08
int
ledPin=13;
//мигать встроенным светодиодом или подключить внешний на пин 13
09
int
tonePin=5;
//выход звука
10
int
toneFreq=800;
//Частота звука (выбирайте между 800 - 1500Гц)
11
unsigned
long
old_millis;
12
13
char
thePhrase[] =
"UA6EM UA6EM BEACON QRA IS LN14AG LN14AG"
;
14
15
typedef
struct
{
16
char
letter;
17
uint8_t sequence;
18
} morseCode_t;
19
20
// B11101000
21
// ...-S <- S - start bit
22
morseCode_t morseCode[]= {
23
{
'A'
, B01100000}, {
'B'
, B11101000}, {
'C'
, B10101000},
24
{
'D'
, B11010000}, {
'E'
, B11000000}, {
'F'
, B10111000},
25
{
'G'
, B10010000}, {
'H'
, B11111000}, {
'I'
, B11100000},
26
{
'J'
, B00011000}, {
'K'
, B01010000}, {
'L'
, B11011000},
27
{
'M'
, B00100000}, {
'N'
, B10100000}, {
'O'
, B00010000},
28
{
'P'
, B10011000}, {
'Q'
, B01001000}, {
'R'
, B10110000},
29
{
'S'
, B11110000}, {
'T'
, B01000000}, {
'U'
, B01110000},
30
{
'V'
, B01111000}, {
'W'
, B00110000}, {
'X'
, B01101000},
31
{
'Y'
, B00101000}, {
'Z'
, B11001000}, {
'0'
, B00000100},
32
{
'1'
, B00001100}, {
'2'
, B00011100}, {
'3'
, B00111100},
33
{
'4'
, B01111100}, {
'5'
, B11111100}, {
'6'
, B11110100},
34
{
'7'
, B11100100}, {
'8'
, B11000100}, {
'9'
, B10000100},
35
{
' '
, B10000000},
36
};
37
38
void
setup
() {
39
pinMode(ledPin, OUTPUT);
40
pinMode(txPin, OUTPUT);
41
Serial
.begin(115200);
42
old_millis = millis();
43
}
44
45
//*** передаём тире ***
46
void
dash()
47
{
48
digitalWrite(ledPin, HIGH);
49
tone(tonePin, toneFreq);
50
delay(DASHLEN);
51
digitalWrite(ledPin, LOW);
52
noTone(tonePin);
53
delay(DOTLEN);
54
}
55
56
//*** передаём точку ***
57
void
dot()
58
{
59
digitalWrite(ledPin, HIGH) ;
60
tone(tonePin, toneFreq);
61
delay(DOTLEN);
62
digitalWrite(ledPin, LOW);
63
noTone(tonePin);
64
delay(DOTLEN);
65
}
66
67
//(c) sadman41 <a href="http://www.arduino.ru" title="www.arduino.ru" rel="nofollow">www.arduino.ru</a>
68
void
sendBeacon(
char
* _thePhrase) {
69
while
(*_thePhrase) {
70
for
(int8_t i=0; i<
sizeof
(thePhrase); i++)
71
{
//Serial.println(sizeof(thePhrase));
72
// длина определилась верно, проверить при изменении данных
73
if
(toupper(*_thePhrase) == morseCode[i].letter) {
74
uint8_t sequenceStarted =
false
;
75
for
(uint8_t l = 0; l < 8; l++) {
76
uint8_t currentBit = bitRead(morseCode[i].sequence, l);
77
if
(!sequenceStarted) {
78
sequenceStarted = currentBit;
79
continue
;
80
}
81
currentBit ? dot() : dash() ;
82
}
83
}
84
}
85
if
(toupper(*_thePhrase) ==
' '
) {
Serial
.println(
"Пробел"
); delay(3*DOTLEN);}
86
_thePhrase++;
87
delay(2*DOTLEN);
88
}
89
}
90
91
void
loop
() {
92
if
(millis() - old_millis >= PAUSE){
93
sendBeacon(thePhrase);
94
old_millis = millis();
95
}
96
}
Далее:
Вариант 1. (с изменениями от 20.04.2019 - введен режим программирования с консольного порта, вход в режим программирования отправка с консоли "P", далее следуем инструкциям выводимым в консоль, сначала позывной, далее локатор, изменения вступают в силу сразу же, так как функция передачи маяка блокирующая, вход в режим после окончания текущего сеанса
001
#include <EEPROM.h>
002
int
eeAddress = 0;
//EEPROM address to start reading from
003
int
eeFlag = 73;
// в ячейке 73 сохраняем флаг ==73, что структура сохранялась
004
int
eeData;
// сюда читаем байт из ячейки флага
005
#define DataFlag 73
006
007
struct
MyBeacon {
008
char
call_sign[20];
009
char
loc[7];
010
};
011
MyBeacon mb = {
"UA6EM"
,
"LN14AG"
};
012
013
String my_call;
014
String my_loc;
015
String my_null;
016
017
#define SPEED (20) //скорость в WPM
018
#define DOTLEN (1200/SPEED)
019
#define DASHLEN (4*(1200/SPEED))
020
//#define PAUSE (180000) //пауза между передачами маяка в милисекундах
021
#define PAUSE (10000) //пауза между передачами маяка в милисекундах
022
023
unsigned
long
old_millis;
024
unsigned
long
modeTime;
025
026
int
txPin=10;
//управление PTT
027
int
ledPin=13;
//мигать встроенным светодиодом или подключить внешний на пин 13
028
int
tonePin=5;
//выход звука
029
int
toneFreq=800;
//Частота звука (выбирайте между 800 - 1500Гц)
030
031
//char thePhrase[] = "ABCDEF GHIJK LMNOP QRSTU VWXYZ 01234 56789 .,:?\/ -()@=";
032
const
int8_t strSize;
033
volatile
char
str[50];
034
//char thePhrase[strSize];
035
036
// B11101000
037
// ...-S <- S - start bit
038
// (c) sadman41 дописал UA6EM <a href="http://www.arduino.ru" title="www.arduino.ru" rel="nofollow">www.arduino.ru</a>
039
typedef
struct
{
040
char
letter;
041
uint8_t sequence;
042
} morseCode_t;
043
// И само наполнение структуры
044
morseCode_t morseCode[]= {
045
{
'A'
, B01100000}, {
'B'
, B11101000}, {
'C'
, B10101000},
046
{
'D'
, B11010000}, {
'E'
, B11000000}, {
'F'
, B10111000},
047
{
'G'
, B10010000}, {
'H'
, B11111000}, {
'I'
, B11100000},
048
{
'J'
, B00011000}, {
'K'
, B01010000}, {
'L'
, B11011000},
049
{
'M'
, B00100000}, {
'N'
, B10100000}, {
'O'
, B00010000},
050
{
'P'
, B10011000}, {
'Q'
, B01001000}, {
'R'
, B10110000},
051
{
'S'
, B11110000}, {
'T'
, B01000000}, {
'U'
, B01110000},
052
{
'V'
, B01111000}, {
'W'
, B00110000}, {
'X'
, B01101000},
053
{
'Y'
, B00101000}, {
'Z'
, B11001000}, {
'0'
, B00000100},
054
{
'1'
, B00001100}, {
'2'
, B00011100}, {
'3'
, B00111100},
055
{
'4'
, B01111100}, {
'5'
, B11111100}, {
'6'
, B11110100},
056
{
'7'
, B11100100}, {
'8'
, B11000100}, {
'9'
, B10000100},
057
{
'.'
, B01010110}, {
','
, B00110010}, {
':'
, B11000100},
058
{
'?'
, B11001110}, {
'-'
, B01111010}, {
'\\'
, B10000110},
059
{
'/'
, B10110100}, {
'('
, B01001010}, {
')'
, B01001010},
060
{
'@'
, B10100110}, {
'='
, B01110100}, {
'"'
, B10110110},
061
};
062
063
064
//*** передаём тире ***
065
// (c) Nicola Salsotto IN3GJH
066
void
dash()
067
{
068
digitalWrite(ledPin, HIGH);
069
tone(tonePin, toneFreq);
070
delay(DASHLEN);
071
digitalWrite(ledPin, LOW);
072
noTone(tonePin);
073
delay(DOTLEN);
074
}
075
076
//*** передаём точку ***
077
// (c) Nicola Salsotto IN3GJH
078
void
dot()
079
{
080
digitalWrite(ledPin, HIGH) ;
081
tone(tonePin, toneFreq);
082
delay(DOTLEN);
083
digitalWrite(ledPin, LOW);
084
noTone(tonePin);
085
delay(DOTLEN);
086
}
087
088
089
// *** функция разбора и передачи строки ***
090
// (c) ЕвгенийП <a href="http://www.arduino.ru" title="www.arduino.ru" rel="nofollow">www.arduino.ru</a>
091
// void sendMsg(char *str){
092
// Строка для отправки сформируется внутри,
093
// а при выходе будет освобождена, (если не объявить глобально)
094
//
095
void
sendMsg(MyBeacon & mbStr) {
096
static
const
char
middle[] =
"BEACON QRA is"
;
// серёдка сообщения
097
static
const
int8_t sizeMiddle = strlen(middle);
// длина серёдки сообщения
098
static
const
int8_t repeatCounter = 2;
// сколько раз повторять позывной и ... тот хвост
099
//
100
// strSize - длина строки для отправки по sms, включая терминальный ноль.
101
const
int8_t strSize = sizeMiddle + (strlen(mbStr.call_sign) + strlen(mbStr.loc) + 2) * repeatCounter + 1;
102
// volatile char str[strSize];
103
//
104
// Заполняем строку
105
str[0] =
'\0'
;
106
for
(int8_t i = 0; i < repeatCounter; i++) {
107
strcat(str, mbStr.call_sign);
108
strcat(str,
" "
);
109
}
110
strcat(str, middle);
111
for
(int8_t i = 0; i < repeatCounter; i++) {
112
strcat(str,
" "
);
113
strcat(str, mbStr.loc);
// Собрали строку текста Маяка
114
}
115
}
116
117
// ***** (c) brokly arduino.ru *****
118
void
sendBeacon(
char
* _thePhrase) {
119
while
(*_thePhrase) {
120
if
(toupper(*_thePhrase)==
' '
){
121
delay(3*DOTLEN);
122
}
else
{
for
(int8_t i=0;i<
sizeof
(morseCode)/
sizeof
(morseCode[0]);i++){
123
if
(toupper(*_thePhrase) == morseCode[i].letter) {
124
uint8_t mask=1;
125
while
(!(morseCode[i].sequence & mask)){ mask<<=1; }
126
mask<<=1;
127
while
(mask){ (morseCode[i].sequence & mask) ? dot() : dash(); mask<<=1; }
128
break
; } } }
129
_thePhrase++; delay(2*DOTLEN);
130
} }
131
132
// Процедура инициализации текста Маяка (с) UA6EM
133
void
initBeacon(){
134
// MyBeacon mb = {"UA6EaM", "LN14Ae"}; // Данные для Маяка при первом включении
135
eeData = EEPROM.read(eeFlag);
136
if
(eeData == 73){
137
Serial
.println(eeData);
138
EEPROM.
get
(eeAddress, mb);
// получить данные из EEPROM
139
}
else
{
// первая запись в EEPROM
140
EEPROM.put(eeAddress,mb);
141
EEPROM.write(eeFlag, DataFlag);
142
}
143
}
144
145
146
void
setBeacon_Data(){
147
my_null=
Serial
.readString();
// Очистим буфер порта
148
modeTime = millis();
149
Serial
.println(
"Введите ваш позывной сигнал"
);
150
while
(!
Serial
.available()> 0 && millis() - modeTime <= 10000) { }
151
if
(
Serial
.available()>0) {
152
my_call =
Serial
.readString();
153
my_call.toCharArray(mb.call_sign,20);
154
}
155
my_call = mb.call_sign;
156
Serial
.print(
"Использую ваш позывной сигнал - "
);
157
Serial
.println(my_call);
158
159
my_null=
Serial
.readString();
// Очистим буфер порта
160
modeTime = millis();
161
Serial
.println(
"Введите ваш QRA локатор"
);
162
while
(!
Serial
.available()> 0 && millis() - modeTime <= 10000) { }
163
if
(
Serial
.available()>0) {
164
my_loc =
Serial
.readString();
165
my_loc.toCharArray(mb.loc,7);
166
}
167
my_loc = mb.loc;
168
Serial
.print(
"Использую QRA локатор - "
);
169
Serial
.println(my_loc);
170
EEPROM.put(eeAddress,mb);
// сохраним новые данные в EEPROM
171
EEPROM.write(eeFlag, DataFlag);
172
initBeacon();
173
sendMsg(mb);
174
}
// выход из режима программирования
175
176
177
void
setup
() {
178
pinMode(ledPin, OUTPUT);
179
pinMode(txPin, OUTPUT);
180
Serial
.begin(115200);
181
initBeacon();
182
sendMsg(mb);
183
old_millis = millis();
184
Serial
.println(
"Для входа в режим программирования введите P"
);
185
}
186
187
void
loop
() {
188
if
(millis() - old_millis >= PAUSE){
189
digitalWrite(txPin, HIGH);
190
delay(900);
//txdelay - задержка после нажатия PTT
191
// sendMsg(mb); //текст маяка - проба
192
delay(20);
193
// sendBeacon(thePhrase);
194
sendBeacon(str);
195
old_millis = millis();
196
digitalWrite(txPin, LOW);
197
}
198
// Serial.println("Для входа в режим программирования введите P");
199
if
(
Serial
.available()) {
200
int
inByte =
Serial
.read();
201
if
(inByte ==
'P'
){
202
setBeacon_Data();
203
}
204
}
205
}
Вариант 2
001
#include <EEPROM.h>
002
int
eeAddress = 0;
//EEPROM address to start reading from
003
int
eeFlag = 73;
// в ячейке 73 сохраняем флаг ==73, что структура сохранялась
004
int
eeData;
// сюда читаем байт из ячейки флага
005
#define DataFlag 73
006
007
struct
MyBeacon {
008
char
call_sign[20];
009
char
loc[7];
010
};
011
MyBeacon mb = {
"UA6EM"
,
"LN14AG"
};
012
String my_call;
013
String my_loc;
014
015
#define SPEED (20) //скорость в WPM
016
#define DOTLEN (1200/SPEED)
017
#define DASHLEN (4*(1200/SPEED))
018
//#define PAUSE (180000) //пауза между передачами маяка в милисекундах
019
#define PAUSE (10000) //пауза между передачами маяка в милисекундах
020
unsigned
long
old_millis;
021
int
txPin=10;
//управление PTT
022
int
ledPin=13;
//мигать встроенным светодиодом или подключить внешний на пин 13
023
int
tonePin=5;
//выход звука
024
int
toneFreq=800;
//Частота звука (выбирайте между 800 - 1500Гц)
025
026
const
int8_t strSize;
027
volatile
char
str[50];
028
029
//ТАБЛИЦА ГЕНЕРАЦИИ БУКВЫ АЗБУКИ МОРЗЕ
030
// ''
031
// 0 1 2 3 4 5 6 7 8 9
032
// A B C D E F G H I J
033
// K L M N O P Q R S T
034
// U V W X Y Z
035
// описание буквы 0-точка, 1 -тире
036
const
PROGMEM uint8_t morseCode[]={B00000000,
037
B00000100,B00001100,B00011100,B00111100,B01111100,B11111100,B11110100,B11100100,B11000100,B10000100,
038
B01100000,B11101000,B10101000,B11010000,B11000000,B10111000,B10010000,B11111000,B11100000,B00011000,
039
B01010000,B11011000,B00100000,B10100000,B00010000,B10011000,B01001000,B10110000,B11110000,B01000000,
040
B01110000,B01111000,B00110000,B01101000,B00101000,B11001000};
041
042
// секвенция по символу
043
uint8_t getMorzeSeq(
char
in
) {
044
uint8_t till = 0;
045
if
(
in
<
'0'
) {
046
return
0;
047
}
else
if
(
in
<=
'9'
) {
048
till =
in
- 0x2F;
// если цифра , то корректируем на 0x2F;
049
}
else
if
(
in
<
'A'
) {
050
return
0;
051
}
else
if
(
in
<=
'Z'
) {
052
till =
in
- 0x36;
// заглавные буквы до Z, в нашей таблице с 11 до 37
053
}
else
if
(
in
<
'a'
) {
054
return
0;
055
}
else
if
(
in
<=
'z'
) {
056
till =
in
- 0x56;
// маленькие, передаем как заглавные буквы до z, в нашей таблице с 11 до 37
057
}
058
if
(till>=
sizeof
(morseCode)) {
059
return
0;
060
}
061
return
pgm_read_byte_near(morseCode+till);
062
}
063
064
//*** передаём тире ***
065
// (c) Nicola Salsotto IN3GJH
066
void
dash()
067
{
068
digitalWrite(ledPin, HIGH);
069
tone(tonePin, toneFreq);
070
delay(DASHLEN);
071
digitalWrite(ledPin, LOW);
072
noTone(tonePin);
073
delay(DOTLEN);
074
}
075
076
//*** передаём точку ***
077
// (c) Nicola Salsotto IN3GJH
078
void
dot()
079
{
080
digitalWrite(ledPin, HIGH) ;
081
tone(tonePin, toneFreq);
082
delay(DOTLEN);
083
digitalWrite(ledPin, LOW);
084
noTone(tonePin);
085
delay(DOTLEN);
086
}
087
088
// *** функция разбора и передачи строки ***
089
// void sendMsg(char *str){
090
// Строка для отправки сформируется внутри,
091
// а при выходе будет освобождена
092
//
093
void
sendMsg(MyBeacon & mbStr) {
094
static
const
char
middle[] =
"BEACON QRA is"
;
// серёдка сообщения
095
static
const
int8_t sizeMiddle = strlen(middle);
// длина серёдки сообщения
096
static
const
int8_t repeatCounter = 2;
// сколько раз повторять позывной и ... тот хвост
097
//
098
// strSize - длина строки для отправки по sms, включая терминальный ноль.
099
const
int8_t strSize = sizeMiddle + (strlen(mbStr.call_sign) + strlen(mbStr.loc) + 2) * repeatCounter + 1;
100
//
101
// Заполняем строку
102
str[0] =
'\0'
;
103
for
(int8_t i = 0; i < repeatCounter; i++) {
104
strcat(str, mbStr.call_sign);
105
strcat(str,
" "
);
106
}
107
strcat(str, middle);
108
for
(int8_t i = 0; i < repeatCounter; i++) {
109
strcat(str,
" "
);
110
strcat(str, mbStr.loc);
// Собрали строку текста Маяка
111
}
112
}
113
114
115
// ***** (c) brokly <a href="http://www.arduino.ru" title="www.arduino.ru" rel="nofollow">www.arduino.ru</a> *****
116
void
sendBeacon(
char
* _thePhrase) {
117
while
(*_thePhrase) {
118
if
(*_thePhrase==
' '
){
119
delay(5*DOTLEN);
120
}
else
{
121
uint8_t buff=getMorzeSeq(*_thePhrase);
122
if
(buff){
123
uint8_t mask=1;
124
while
(!(buff & mask)){
125
mask<<=1;
126
}
127
mask<<=1;
128
while
(mask){
129
(buff & mask) ? dot() : dash();
130
mask<<=1;
131
}
132
delay(2*DOTLEN);
133
}
134
}
135
_thePhrase++;
136
}
137
}
138
139
// Процедура инициализации текста Маяка (с) UA6EM
140
void
initBeacon(){
141
eeData = EEPROM.read(eeFlag);
142
if
(eeData == 73){
// если надо перешить данные в EEPROM из IDE изменить на 74 )))
143
Serial
.println(eeData);
144
EEPROM.
get
(eeAddress, mb);
// получить данные из EEPROM
145
}
else
{
146
EEPROM.put(eeAddress, mb);
// сохраним позывной и локатор в EEPROM
147
EEPROM.write(eeFlag, eeFlag); }
// в ячейку с адресом 73 шьём адрес 73 )))
148
}
149
150
void
setBeacon_Data(){
151
Serial
.readString();
// Очистим буфер порта
152
unsigned
long
modeTime = millis();
153
Serial
.println(
"Введите ваш позывной сигнал"
);
154
while
(!
Serial
.available() && millis() - modeTime < 10000) { }
155
if
(
Serial
.available()>0) {
156
my_call =
Serial
.readString();
157
my_call.toCharArray(mb.call_sign,20);
158
}
159
my_call = mb.call_sign;
160
Serial
.print(
"Использую ваш позывной сигнал - "
);
161
Serial
.println(my_call);
162
163
Serial
.readString();
// Очистим буфер порта
164
modeTime = millis();
165
Serial
.println(
"Введите ваш QRA локатор"
);
166
while
(!
Serial
.available() && millis() - modeTime < 10000) { }
167
if
(
Serial
.available()>0) {
168
my_loc =
Serial
.readString();
169
my_loc.toCharArray(mb.loc,7);
170
}
171
my_loc = mb.loc;
172
Serial
.print(
"Использую QRA локатор - "
);
173
Serial
.println(my_loc);
174
EEPROM.put(eeAddress,mb);
// сохраним новые данные в EEPROM
175
EEPROM.write(eeFlag, DataFlag);
176
initBeacon();
177
sendMsg(mb);
178
}
// выход из режима программирования
179
180
181
void
setup
() {
182
pinMode(ledPin, OUTPUT);
183
pinMode(txPin, OUTPUT);
184
Serial
.begin(115200);
185
initBeacon();
186
sendMsg(mb);
187
old_millis = millis();
188
Serial
.println(
"Для входа в режим программирования введите P"
);
189
}
190
191
void
loop
() {
192
if
(millis() - old_millis >= PAUSE){
193
digitalWrite(txPin, HIGH);
194
delay(900);
//txdelay - задержка после нажатия PTT
195
// sendMsg(mb); //текст маяка - проба
196
delay(20);
197
// sendBeacon(thePhrase);
198
sendBeacon(str);
199
old_millis = millis();
200
digitalWrite(txPin, LOW);
201
}
202
// Serial.println("Для входа в режим программирования введите P");
203
if
(
Serial
.available()) {
204
int
inByte =
Serial
.read();
205
if
(inByte ==
'P'
){
206
setBeacon_Data();
207
}
208
}
209
}
Для варианта 2 можно конечно реализовать и обработку знаков, но код разрастется и экономия в 30 байт в таблице варианта 1 совсем потеряется

Деда Витя, это ж не маяк, это ж ключ :)
Вот маяк на 8 МГц:
01
// Arduino simply CW beacon
02
// (c) 2012 Max Klimenko
03
// emaster [at] mail.ru
04
// <a href="http://max-ter.livejournal.com/571.html" title="http://max-ter.livejournal.com/571.html" rel="nofollow">http://max-ter.livejournal.com/571.html</a>
05
06
// It sends beacon at 8 MHz from pin D9
07
08
// Beacon message
09
const
char
message[] =
"VVV CQ CQ CQ DX DE BEACON BAND 40M 8000KHZ"
;
10
11
// Period of single point (ms)
12
const
int
point_time = 80;
13
14
// Carrier frequency divider.
15
// Carrier freq. (MHz) = 16 / (2 * (1 + freq_div))
16
const
unsigned
char
freq_div = 1;
17
18
//////////////////////////////////////////////////////////////////
19
struct
s_abc
20
{
21
char
letter;
22
char
sign[7];
23
};
24
25
const
s_abc abc[] = {
26
'A'
,
".-"
,
'B'
,
"-..."
,
'W'
,
".--"
,
'G'
,
"--."
,
'D'
,
"-.."
,
27
'E'
,
"."
,
'V'
,
"...-"
,
'Z'
,
"--.."
,
'I'
,
".."
,
28
'J'
,
".---"
,
'K'
,
"-.-"
,
'L'
,
".-.."
,
'M'
,
"--"
,
'N'
,
"-."
,
29
'O'
,
"---"
,
'P'
,
".--."
,
'R'
,
".-."
,
'S'
,
"..."
,
30
'T'
,
"-"
,
'U'
,
"..-"
,
'F'
,
"..-."
,
'H'
,
"...."
,
'C'
,
"-.-."
,
31
'Q'
,
"--.-"
,
'Y'
,
"-.--"
,
'X'
,
"-..-"
,
'1'
,
".----"
,
32
'2'
,
"..---"
,
'3'
,
"...--"
,
'4'
,
"....-"
,
'5'
,
"....."
,
33
'6'
,
"-...."
,
'7'
,
"--..."
,
'8'
,
"---.."
,
'9'
,
"----."
,
34
'0'
,
"-----"
,
'.'
,
"......"
,
','
,
".-.-.-"
,
':'
,
"---..."
,
35
';'
,
"-.-.-."
,
'('
,
"-.--.-"
,
'`'
,
".----."
,
36
'"'
,".-..-.
", '-',"
-....-
", '/',"
-..-.
", '?',"
..--..",
37
'!'
,
"--..--"
,
'@'
,
".--.-."
,
'\\'
,
"..-.-"
};
38
39
unsigned
char
abc_size =
sizeof
(abc) /
sizeof
(abc[0]);
40
41
void
setup
()
42
{
43
PORTB = 0;
44
DDRB |= 1<<1;
45
46
OCR1A = freq_div;
47
TCCR1A = 0x48;
48
TCCR1B = 0x09;
49
50
pinMode(13, OUTPUT);
51
digitalWrite(13, HIGH);
// set the LED on
52
}
53
54
void
send_letter(
char
l)
55
{
56
if
(l ==
' '
)
57
{
58
delay(point_time * 7);
59
return
;
60
}
61
62
unsigned
char
idx = 255;
63
for
(unsigned
char
i = 0; i < abc_size; i++)
64
if
(abc[i].letter == l)
65
{
66
idx = i;
67
break
;
68
}
69
70
if
(idx == 255)
return
;
71
72
const
char
*s = abc[idx].sign;
73
74
for
(unsigned
char
c = 0; s[c] != 0; c++)
75
{
76
char
q = s[c];
77
78
DDRB |= 1<<1;
79
digitalWrite(13, HIGH);
// set the LED on
80
81
if
(q ==
'.'
) delay(point_time);
82
else
delay(point_time * 3);
83
84
DDRB &= ~(1<<1);
85
digitalWrite(13, LOW);
// set the LED off
86
87
delay(point_time);
88
}
89
90
delay(point_time * 2);
91
}
92
93
void
loop
()
94
{
95
for
(
int
n = 0; message[n] != 0; n++)
96
send_letter(message[n]);
97
98
delay(2000);
99
}
А вот маяк на 1337 кГц:
001
long
millisAtStart = 0;
002
long
millisAtEnd = 0;
003
004
//period of shortest broadcast (256 port changes)
005
const
long
period_broadcast = 8;
006
007
// number of period_broadcasts in one 'dit',
008
// all other lengths are scaled from this
009
#define LENGTH_DIT 64
010
011
const
int
length_dit = LENGTH_DIT;
//number of periods for dit
012
const
int
pause_dit = LENGTH_DIT;
//pause after dit
013
const
int
length_dah = 3 * LENGTH_DIT;
//number of persots for dah
014
const
int
pause_dah = LENGTH_DIT;
//pause after dah
015
const
int
length_pause = 7 * LENGTH_DIT;
//pause between words
016
017
void
dit(
void
);
018
void
dah(
void
);
019
void
pause(
void
);
020
void
broadcast(
int
N_cycles);
021
void
dontbroadcast(
int
N_cycles);
022
023
// ### INC ### Increment Register (reg = reg + 1)
024
#define ASM_INC(reg) asm volatile ("inc %0" : "=r" (reg) : "0" (reg))
025
026
void
setup
()
027
{
028
Serial
.begin(9600);
029
DDRB = 0xFF;
//Port B all outputs
030
// Do one dit to determine approximate frequency
031
millisAtStart = millis();
032
dit();
033
millisAtEnd = millis();
034
Serial
.print(millisAtEnd - millisAtStart);
035
Serial
.print(
" ms/dit, freq: "
);
036
Serial
.print( (length_dit + pause_dit) * period_broadcast * 256 / (millisAtEnd - millisAtStart) / 2 );
037
Serial
.print(
"kHz "
);
038
Serial
.println();
039
}
040
041
void
loop
()
042
{
043
dah();
044
dit();
045
dah();
046
dah();
047
pause();
048
dah();
049
dit();
050
dah();
051
dah();
052
pause();
053
dah();
054
dah();
055
dit();
056
dit();
057
pause();
058
pause();
059
}
060
061
void
dit(
void
)
062
{
063
for
(
int
i = 0; i < length_dit; i++)
064
{
065
broadcast(period_broadcast);
066
}
067
for
(
int
i = 0; i < pause_dit; i++)
068
{
069
dontbroadcast(period_broadcast);
070
}
071
}
072
073
074
void
dah(
void
)
075
{
076
for
(
int
i = 0; i < length_dah; i++)
077
{
078
broadcast(period_broadcast);
079
}
080
for
(
int
i = 0; i < pause_dah; i++)
081
{
082
dontbroadcast(period_broadcast);
083
}
084
}
085
086
void
pause(
void
)
087
{
088
for
(
int
i = 0; i < length_pause; i++)
089
{
090
dontbroadcast(period_broadcast);
091
}
092
}
093
094
void
broadcast(
int
N_cycles)
095
{
096
unsigned
int
portvalue;
097
for
(
int
i = 0; i < N_cycles; i++)
098
{
099
portvalue = 0;
100
do
101
{
102
PORTB = portvalue;
103
ASM_INC(portvalue);
104
}
105
while
(portvalue < 255);
106
}
107
}
108
109
void
dontbroadcast(
int
N_cycles)
110
{
111
unsigned
int
portvalue;
112
PORTB = 0x00;
113
for
(
int
i = 0; i < N_cycles; i++)
114
{
115
portvalue = 0;
116
do
117
{
118
ASM_INC(portvalue);
119
//add some assembly No OPerations to keep timing the same
120
asm volatile (
"NOP"
);
121
}
122
while
(portvalue < 255);
123
}
124
}
Оба полноценные, никакого больше оборудования, кроме ардуины и куска провода к пину, не требуется.
Деда Витя, это ж не маяк, это ж ключ :)
ай да Клименко! А, что, красивое решение, это по нашему )))
будет Маяк, а ключ у меня тока разводной и пару-тройку трубных (есть номер 4-ре) )))
Мда. Похоже скоро китайцы будут говорить, что все что Сделано в России можно сразу на помойку.
Несколько Маяков от UA6HJQ:
1.Простой телеграфный маяк на Arduino
001
/*
002
Простой телеграфный маяк для экспериментов
003
004
Исходный код:
005
Written by Nicola Salsotto IN3GJH
006
<a data-cke-saved-href="<a href="https://github.com/NicoVarg99" rel="nofollow">https://github.com/NicoVarg99</a>" href="<a href="https://github.com/NicoVarg99" rel="nofollow">https://github.com/NicoVarg99</a>" rel="nofollow"><a href="https://github.com/NicoVarg99" rel="nofollow">https://github.com/NicoVarg99</a></a>
007
008
Модификация сделана:
009
UA6HJQ 18.11.2018 (добавлено управление радиостанцией)
010
UA6EM 21.04.2019 (добавлена функция перевода в верхний регистр, теперь текст можно писать
011
в любом регистре, сделано для дальнешего развития скетча)
012
Интервал между передачей:
013
10мин= 600000 (передача примерно 20 секунд)
014
5мин = 300000
015
3мин = 180000
016
2мин = 120000
017
*/
018
019
#define SPEED (20) //скорость в WPM
020
#define DOTLEN (1200/SPEED)
021
#define DASHLEN (3*(1200/SPEED))
022
#define PAUSE (180000) //пауза между передачами маяка в милисекундах
023
024
int
txPin=10;
//управление PTT
025
int
ledPin=13;
//мигать встроенным светодиодом или подключить внешний на пин 13
026
int
tonePin=5;
//выход звука
027
int
toneFreq=800;
//Частота звука (выбирайте между 800 - 1500Гц)
028
029
void
sendMsg(
char
*);
030
void
dash();
031
void
dot();
032
033
034
void
setup
()
035
{
036
pinMode(ledPin, OUTPUT);
037
pinMode(txPin, OUTPUT);
038
}
039
040
041
void
loop
()
042
{
043
digitalWrite(txPin, HIGH);
044
delay(900);
//txdelay - задержка после нажатия PTT
045
046
sendMsg(
"UA6HJQ UA6HJQ BEACON LN14AX"
);
//текст маяка
047
048
delay(20);
049
digitalWrite(txPin, LOW);
050
051
delay(PAUSE);
052
}
053
054
055
void
dash()
056
{
057
digitalWrite(ledPin, HIGH);
058
tone(tonePin, toneFreq);
059
delay(DASHLEN);
060
digitalWrite(ledPin, LOW);
061
noTone(tonePin);
062
delay(DOTLEN);
063
}
064
065
066
void
dot()
067
{
068
digitalWrite(ledPin, HIGH) ;
069
tone(tonePin, toneFreq);
070
delay(DOTLEN);
071
digitalWrite(ledPin, LOW);
072
noTone(tonePin);
073
delay(DOTLEN);
074
}
075
076
077
void
sendMsg(
char
*str)
078
{
079
int
i;
080
081
delay(500);
082
083
for
(i=0;i<strlen(str);i++)
084
{
085
switch
(toupper(str[i]))
// добавлена функция перевода текста в верхний регистр
086
{
087
case
'A'
:
088
dot();dash();
break
;
089
case
'B'
:
090
dash();dot();dot();dot();
break
;
091
case
'C'
:
092
dash();dot();dash();dot();
break
;
093
case
'D'
:
094
dash();dot();dot();
break
;
095
case
'E'
:
096
dot();
break
;
097
case
'F'
:
098
dot();dot();dash();dot();
break
;
099
case
'G'
:
100
dash();dash();dot();
break
;
101
case
'H'
:
102
dot();dot();dot();dot();
break
;
103
case
'I'
:
104
dot();dot();
break
;
105
case
'J'
:
106
dot();dash();dash();dash();
break
;
107
case
'K'
:
108
dash();dot();dash();
break
;
109
case
'L'
:
110
dot();dash();dot();dot();
break
;
111
case
'M'
:
112
dash();dash();
break
;
113
case
'N'
:
114
dash();dot();
break
;
115
case
'O'
:
116
dash();dash();dash();
break
;
117
case
'P'
:
118
dot();dash();dash();dot();
break
;
119
case
'Q'
:
120
dash();dash();dot();dash();
break
;
121
case
'R'
:
122
dot();dash();dot();
break
;
123
case
'S'
:
124
dot();dot();dot();
break
;
125
case
'T'
:
126
dash();
break
;
127
case
'U'
:
128
dot();dot();dash();
break
;
129
case
'V'
:
130
dot();dot();dot();dash();
break
;
131
case
'W'
:
132
dot();dash();dash();
break
;
133
case
'X'
:
134
dash();dot();dot();dash();
break
;
135
case
'Y'
:
136
dash();dot();dash();dash();
break
;
137
case
'Z'
:
138
dash();dash();dot();dot();
break
;
139
case
' '
:
140
delay(DOTLEN*5);
break
;
141
case
'.'
:
142
dot();dash();dot();dash();dot();dash();
break
;
143
case
','
:
144
dash();dash();dot();dot();dash();dash();
break
;
145
case
':'
:
146
dash();dash();dash();dot();dot();
break
;
147
case
'?'
:
148
dot();dot();dash();dash();dot();dot();
break
;
149
case
'\''
:
150
dot();dash();dash();dash();dash();dot();
break
;
151
case
'-'
:
152
dash();dot();dot();dot();dot();dash();
break
;
153
case
'/'
:
154
dash();dot();dot();dash();dot();
break
;
155
case
'('
:
156
case
')'
:
157
dash();dot();dash();dash();dot();dash();
break
;
158
case
'\"'
:
159
dot();dash();dot();dot();dash();dot();
break
;
160
case
'@'
:
161
dot();dash();dash();dot();dash();dot();
break
;
162
case
'='
:
163
dash();dot();dot();dot();dash();
break
;
164
case
'0'
:
165
dash();dash();dash();dash();dash();
break
;
166
case
'1'
:
167
dot();dash();dash();dash();dash();
break
;
168
case
'2'
:
169
dot();dot();dash();dash();dash();
break
;
170
case
'3'
:
171
dot();dot();dot();dash();dash();
break
;
172
case
'4'
:
173
dot();dot();dot();dot();dash();
break
;
174
case
'5'
:
175
dot();dot();dot();dot();dot();
break
;
176
case
'6'
:
177
dash();dot();dot();dot();dot();
break
;
178
case
'7'
:
179
dash();dash();dot();dot();dot();
break
;
180
case
'8'
:
181
dash();dash();dash();dot();dot();
break
;
182
case
'9'
:
183
dash();dash();dash();dash();dot();
break
;
184
185
}
186
delay(2*DOTLEN);
187
}
188
189
}
2. Телеграфный маяк с автоответчиком
CW-BEACON-R7HJ
001
/*
002
* UA6HJQ 22.12.2018
003
* <a href="http://rlsk.ucoz.ru/" rel="nofollow">http://rlsk.ucoz.ru/</a>
004
* Радиолюбительский телеграфный маяк с автоответчиком
005
* с исправлениями UA6EM от 22.04.2019 скорректирована функция передачи по времени
006
* добавлена функция перевода теста для передачи
007
* в верхний регистр (для Маяка)
008
* Передачи маяка сразу после включения
009
* Управление DTMF кодами:
010
* 1 - версия прошивки
011
* 2 - непрерывный тон 1000Гц, длиной 15 секунд
012
* 3 - рингтон
013
* 4 - температура
014
* 5 - напряжение питания
015
* 6 - S-метр
016
* 7 - передача маяка не дожидаясь очереди
017
* 8 - реле включено
018
* 9 - реле выключено
019
* 0 - текст буквы и цифры
020
* * - текст только цифры
021
* # - текст только буквы
022
* A - не используется...
023
* B - не используется...
024
* C - не используется...
025
* D - не используется...
026
*/
027
028
#include "Config.h" // файл с настройками пользователя
029
#include "DTMF.h"
030
#include <OneWire.h>
031
#include <DallasTemperature.h>
032
033
#define DOTLEN (1200/SPEED)
034
#define DASHLEN (3*(1200/SPEED))
035
036
#define ONE_WIRE_BUS 2
037
OneWire oneWire(ONE_WIRE_BUS);
038
DallasTemperature sensors(&oneWire);
039
040
int
sensorPin = A0;
// сигнал из эфира
041
int
ledPin=13;
// загорается при приёме DTMF сигнала
042
int
rele1 = 3;
// реле 1
043
int
ptt = A2;
// PTT на корпус во время передачи
044
int
tonePin = A4;
// выход звука на радиостанцию
045
int
smetrPin = A1;
// S-метр, показания RSSI
046
int
smetrReading;
047
048
float
n = 128.0;
049
float
sampling_rate = 8926.0;
050
DTMF dtmf = DTMF(n, sampling_rate);
051
052
unsigned
long
previousMillis;
053
byte
flag_1 = 0;
054
055
int
nochar_count = 0;
056
float
d_mags[8];
057
058
#ifdef PAUSE_GO
059
byte
pause_go = 1;
060
#else
061
byte
pause_go = 0;
062
#endif
063
064
065
void
setup
()
066
{
067
Serial
.begin(115200);
068
pinMode(ptt, INPUT);
069
digitalWrite(ptt, LOW);
070
pinMode(rele1, OUTPUT);
071
pinMode(ledPin, OUTPUT);
072
sensors.begin();
// ds18b20
073
randomSeed(analogRead(10));
// для генерации случайных чисел указать неиспользуемый порт
074
075
Serial
.println(
"BEACON + Answering Machine\nver. 1.0 <a href="
mailto:ua6hjq@mail.ru
">ua6hjq@mail.ru</a> 22.12.2018"
);
076
Serial
.println(MYCALL);
077
Serial
.println(QTHLOC);
078
Serial
.print(
"CW speed "
);
Serial
.print(SPEED);
Serial
.println(
" WPM"
);
079
Serial
.print(
"CW tone "
);
Serial
.print(toneFreq);
Serial
.println(
" Hz"
);
080
Serial
.print(
"Beacon interval "
);
081
Serial
.print(interval);
082
Serial
.println(
" sec"
);
083
sendMsg(
"E"
);
// текст маяка при включении, без передачи в эфир
084
previousMillis = millis()- 1000UL*interval;
// устанавливаем время для передачи маяка сразу после включения
085
}
086
087
088
void
loop
()
089
{
090
char
thischar;
091
dtmf.sample(sensorPin);
092
dtmf.detect(d_mags, 506);
093
thischar = dtmf.button(d_mags, 1800.);
094
095
if
(thischar) {
096
Serial
.print(thischar);
097
nochar_count = 0;
098
099
if
(thischar ==
'1'
) {
Serial
.println(
" CODE version"
); txON(); sendMsg(
"VER 1 UA6HJQ"
); txOFF(); }
100
else
101
if
(thischar ==
'2'
) {
Serial
.println(
" CODE tone 15 sec"
); ton(); }
102
else
103
if
(thischar ==
'3'
) {
Serial
.println(
" CODE ring"
); ring(); }
104
else
105
if
(thischar ==
'4'
) {
Serial
.print(
" CODE temperatura "
); temp1(); }
106
else
107
if
(thischar ==
'5'
) {
Serial
.println(
" CODE beacon"
); voltemeter(); }
108
else
109
if
(thischar ==
'6'
) {
Serial
.print(
" CODE "
); smetr(); }
110
else
111
if
(thischar ==
'7'
) {
Serial
.print(
" CODE voltemeter "
); beacon(); }
112
else
113
if
(thischar ==
'8'
) {
Serial
.println(
" CODE rele on"
); digitalWrite(rele1, HIGH); txON(); sendMsg(
"R"
); txOFF(); }
114
else
115
if
(thischar ==
'9'
) {
Serial
.println(
" CODE rele off"
); digitalWrite(rele1, LOW); txON(); sendMsg(
"R"
); txOFF(); }
116
else
117
if
(thischar ==
'0'
) {
Serial
.println(
" CODE letters and digital text"
); text3(); }
118
else
119
if
(thischar ==
'*'
) {
Serial
.println(
" CODE digital text"
); text1(); }
120
else
121
if
(thischar ==
'#'
) {
Serial
.println(
" CODE letters text"
); text2(); }
122
else
123
if
(thischar ==
'A'
) {
Serial
.println(
" CODE"
); txON(); sendMsg(
"E"
); txOFF(); }
124
else
125
if
(thischar ==
'B'
) {
Serial
.println(
" CODE"
); txON(); sendMsg(
"E"
); txOFF(); }
126
else
127
if
(thischar ==
'C'
) {
Serial
.println(
" CODE"
); txON(); sendMsg(
"E"
); txOFF(); }
128
else
129
if
(thischar ==
'D'
) {
Serial
.println(
" CODE"
); txON(); sendMsg(
"E"
); txOFF(); }
130
}
131
132
else
{
133
if
(++nochar_count == 50)
Serial
.println(
""
);
134
if
(nochar_count > 30000)nochar_count = 51;
135
}
136
137
if
(millis() - previousMillis >= 1000UL*interval){
138
Serial
.println(
"sec - beacon transmiter"
);
139
if
(pause_go){
140
previousMillis = millis();
// временные отрезки от начала передачи
141
beacon();
142
}
else
{
143
beacon();
144
previousMillis = millis();
// временные отрезки от конца передачи
145
}
146
}
else
{}
147
}
//END
Config.h
01
/*
02
* UA6HJQ 25.11.2018
03
* ОСНОВНЫЕ НАСТРОЙКИ
04
* UA6EM 22.04.2019 отсчет времени от начала/конца передачи
05
*/
06
07
#define MYCALL "UA6EM/B" // ваш позывной
08
#define QTHLOC "LN14AE"// ваш локатор
09
10
#define SPEED (20) //скорость передачи телеграфа в WPM
11
12
#define toneFreq (800) //частота звука (выбирайте между 600 - 1000Гц)
13
14
#define interval (60) // интервал передачи маяка в секундах
15
// 180=3мин 300=5мин 600=10мин 900=15мин
16
// 1200=20мин 1800=30мин 3600=60мин
17
18
#define PAUSE_GO YES // если надо временные отрезки считать от конца
19
// передачи Маяка закомментируйте эту строку
20
//
21
// уровень модуляции регулируйте подстроечным резистором на плате!
22
//
DTMF.cpp
001
/*
002
Based on: <a href="https://github.com/jacobrosenthal/Goertzel" rel="nofollow">https://github.com/jacobrosenthal/Goertzel</a>
003
Heavily modified by Pete (El_Supremo on Arduino forums) to decode DTMF tones
004
It is also public domain and provided on an AS-IS basis. There's no warranty
005
or guarantee of ANY kind whatsoever.
006
This uses Digital Pin 4 to allow measurement of the sampling frequency
007
008
The Goertzel algorithm is long standing so see
009
<a href="http://en.wikipedia.org/wiki/Goertzel_algorithm" rel="nofollow">http://en.wikipedia.org/wiki/Goertzel_algorithm</a> for a full description.
010
It is often used in DTMF tone detection as an alternative to the Fast
011
Fourier Transform because it is quick with low overheard because it
012
is only searching for a single frequency rather than showing the
013
occurrence of all frequencies.
014
This work is entirely based on the Kevin Banks code found at
015
<a href="http://www.eetimes.com/design/embedded/4024443/The-Goertzel-Algorithm" rel="nofollow">http://www.eetimes.com/design/embedded/4024443/The-Goertzel-Algorithm</a>
016
so full credit to him for his generic implementation and breakdown. I've
017
simply massaged it into an Arduino library. I recommend reading his article
018
for a full description of whats going on behind the scenes.
019
020
Created by Jacob Rosenthal, June 20, 2012.
021
Released into the public domain.
022
023
*/
024
025
// include core Wiring API
026
#include "Arduino.h"
027
028
// include this library's description file
029
#include "DTMF.h"
030
031
float
SAMPLING_RATE;
032
float
TARGET;
033
int
N;
034
float
coeff[8];
035
float
Q1[8];
036
float
Q2[8];
037
float
cosine;
038
//PAH int
039
int
testData[160];
040
041
const
int
dtmf_tones[8] = {
042
697,
043
770,
044
852,
045
941,
046
1209,
047
1336,
048
1477,
049
1633
050
};
051
052
const
unsigned
char
dtmf_map[16] = {
053
0x11,
054
0x21,
055
0x41,
056
0x12,
057
0x22,
058
0x42,
059
0x14,
060
0x24,
061
0x44,
062
0x28,
063
0x81,
064
0x82,
065
0x84,
066
0x88,
067
0x18,
068
0x48
069
};
070
071
const
char
dtmf_char[16] = {
072
'1'
,
073
'2'
,
074
'3'
,
075
'4'
,
076
'5'
,
077
'6'
,
078
'7'
,
079
'8'
,
080
'9'
,
081
'0'
,
082
'A'
,
083
'B'
,
084
'C'
,
085
'D'
,
086
'*'
,
087
'#'
,
088
};
089
090
DTMF::DTMF(
float
BLOCK)
091
{
092
#if F_CPU == 16000000L
093
DTMF(BLOCK, 8928.0);
094
#else
095
DTMF(BLOCK, 4400.0);
096
#endif
097
}
098
099
DTMF::DTMF(
float
BLOCK,
float
SAMPLING_FREQ)
100
{
101
// El_Supremo Set pin 4 as output
102
DDRD |= B00010000;
103
// Set pin 4 LOW
104
PORTD &= B11101111;
105
106
SAMPLING_RATE=SAMPLING_FREQ;
//on 16mhz, ~8928.57142857143, on 8mhz ~44444
107
//>>> TARGET=TARGET_FREQUENCY; //must be integer of SAMPLING_RATE/N
108
N=BLOCK;
//Block size
109
110
float
omega;
111
// Calculate the coefficient for each DTMF tone
112
for
(
int
i = 0;i < 8;i++) {
113
omega = (2.0 * PI * dtmf_tones[i]) / SAMPLING_RATE;
114
// DTMF detection doesn't need the phase.
115
// Computation of the magnitudes (which DTMF does need) does not
116
// require the value of the sin.
117
// not needed sine = sin(omega);
118
coeff[i] = 2.0 * cos(omega);
119
}
120
ResetDTMF();
121
}
122
123
124
/* Call this routine before every "block" (size=N) of samples. */
125
void
DTMF::ResetDTMF(
void
)
126
{
127
for
(
int
i=0; i<8 ; i++) {
128
Q2[i] = 0;
129
Q1[i] = 0;
130
}
131
}
132
133
134
/* Call this routine for every sample. */
135
//El_Supremo - change to int (WHY was it byte??)
136
void
DTMF::ProcessSample(
int
sample,
int
adc_centre)
137
{
138
float
Q0;
139
//EL_Supremo subtract adc_centre to offset the sample correctly
140
for
(
int
i=0;i < 8;i++) {
141
Q0 = coeff[i] * Q1[i] - Q2[i] + (
float
) (sample - adc_centre);
142
Q2[i] = Q1[i];
143
Q1[i] = Q0;
144
}
145
}
146
147
/* Sample some test data. */
148
void
DTMF::sample(
int
sensorPin)
149
{
150
// El_Supremo
151
// To toggle the output on digital pin 4
152
const
unsigned
char
f_counter = 0x10;
153
154
for
(
int
index = 0; index < N; index++)
155
{
156
testData[index] = analogRead(sensorPin);
157
// El_Supremo
158
// toggle bit 4 for a frequency counter
159
PORTD ^= f_counter;
160
}
161
}
162
163
// return the magnitudes of the 8 DTMF frequencies
164
void
DTMF::detect(
float
dtmf_mag[],
int
adc_centre)
165
{
166
int
index;
167
float
d_tmp;
168
169
/* Process the samples. */
170
for
(index = 0; index < N; index++)
171
{
172
ProcessSample(testData[index],adc_centre);
173
}
174
// Calculate the magnitude of each tone.
175
for
(
int
i=0;i < 8;i++) {
176
// El_Supremo 150318 the compilers in Arduino verisons 1.6.0 and 1.6.1
177
// generated "unable to find a register to spill" error in the original statement
178
// here. Breaking it into pieces worked around the problem.
179
// dtmf_mag[i] = sqrt(Q1[i]*Q1[i] + Q2[i]*Q2[i] - coeff[i]*Q1[i]*Q2[i]);
180
181
// This is the equivalent of sqrt(real*real + imag*imag)
182
d_tmp = Q1[i]*Q1[i];
183
d_tmp += Q2[i]*Q2[i];
184
d_tmp -= coeff[i]*Q1[i]*Q2[i];
185
186
dtmf_mag[i] = sqrt(d_tmp);
187
}
188
ResetDTMF();
189
}
190
191
192
char
last_dtmf = 0;
193
// Detect which button was pressed using magnitude as the
194
// cutoff. Returns the character or a zero
195
char
DTMF::button(
float
mags[],
float
magnitude)
196
{
197
int
bit = 1;
198
int
j;
199
int
dtmf = 0;
200
201
202
203
for
(
int
i=0;i<8;i++) {
204
if
(mags[i] > magnitude) {
205
dtmf |= bit;
206
}
207
bit <<= 1;
208
}
209
for
(j=0;j<16;j++) {
210
if
(dtmf_map[j] == dtmf)
break
;
211
}
212
if
(j < 16) {
213
// wait for the button to be released
214
if
(dtmf_char[j] == last_dtmf)
return
((
char
) 0);
215
last_dtmf = dtmf_char[j];
216
return
(dtmf_char[j]);
217
}
218
last_dtmf = 0;
219
return
((
char
) 0);
220
}
DTMF.h
01
/*
02
Heavily modified by El_Supremo (Arduino forums) to decode DTMF tones
03
It is also public domain and provided on an AS-IS basis. There's no warranty
04
or guarantee of ANY kind whatsoever.
05
06
The Goertzel algorithm is long standing so see
07
<a href="http://en.wikipedia.org/wiki/Goertzel_algorithm" rel="nofollow">http://en.wikipedia.org/wiki/Goertzel_algorithm</a> for a full description.
08
It is often used in DTMF tone detection as an alternative to the Fast
09
Fourier Transform because it is quick with low overheard because it
10
is only searching for a single frequency rather than showing the
11
occurrence of all frequencies.
12
This work is entirely based on the Kevin Banks code found at
13
<a href="http://www.eetimes.com/design/embedded/4024443/The-Goertzel-Algorithm" rel="nofollow">http://www.eetimes.com/design/embedded/4024443/The-Goertzel-Algorithm</a>
14
so full credit to him for his generic implementation and breakdown. I've
15
simply massaged it into an Arduino library. I recommend reading his article
16
for a full description of whats going on behind the scenes.
17
18
Created by Jacob Rosenthal, June 20, 2012.
19
Released into the public domain.
20
*/
21
22
// ensure this library description is only included once
23
#ifndef DTMF_h
24
#define DTMF_h
25
26
// include types & constants of Wiring core API
27
#include "Arduino.h"
28
29
// library interface description
30
class
DTMF
31
{
32
// user-accessible "public" interface
33
public
:
34
DTMF(
float
,
float
);
35
DTMF(
float
);
36
void
sample(
int
);
37
void
detect(
float
dtmf_mag[],
int
adc_centre);
38
char
button(
float
mags[],
float
magnitude);
39
// library-accessible "private" interface
40
private
:
41
42
//El_Supremo change to int
43
void
ProcessSample(
int
,
int
);
44
void
ResetDTMF(
void
);
45
46
};
47
48
#endif
cw.ino
001
/*
002
* ФОРМИРОВАНИЕ ТЕЛЕГРАФНОГО СИГНАЛА
003
* Written by Nicola Salsotto IN3GJH
004
* <a href="https://github.com/NicoVarg99" rel="nofollow">https://github.com/NicoVarg99</a>
005
*/
006
007
void
dash()
008
{
009
digitalWrite(ledPin, HIGH);
010
tone(tonePin, toneFreq);
011
delay(DASHLEN);
012
digitalWrite(ledPin, LOW);
013
noTone(tonePin);
014
delay(DOTLEN);
015
}
016
017
018
void
dot()
019
{
020
digitalWrite(ledPin, HIGH) ;
021
tone(tonePin, toneFreq);
022
delay(DOTLEN);
023
digitalWrite(ledPin, LOW);
024
noTone(tonePin);
025
delay(DOTLEN);
026
}
027
028
029
void
sendMsg(
char
*str)
030
{
031
int
i;
032
033
delay(500);
034
035
for
(i=0;i<strlen(str);i++)
036
{
037
switch
(toupper(str[i]))
038
{
039
case
'A'
:
040
dot();dash();
break
;
041
case
'B'
:
042
dash();dot();dot();dot();
break
;
043
case
'C'
:
044
dash();dot();dash();dot();
break
;
045
case
'D'
:
046
dash();dot();dot();
break
;
047
case
'E'
:
048
dot();
break
;
049
case
'F'
:
050
dot();dot();dash();dot();
break
;
051
case
'G'
:
052
dash();dash();dot();
break
;
053
case
'H'
:
054
dot();dot();dot();dot();
break
;
055
case
'I'
:
056
dot();dot();
break
;
057
case
'J'
:
058
dot();dash();dash();dash();
break
;
059
case
'K'
:
060
dash();dot();dash();
break
;
061
case
'L'
:
062
dot();dash();dot();dot();
break
;
063
case
'M'
:
064
dash();dash();
break
;
065
case
'N'
:
066
dash();dot();
break
;
067
case
'O'
:
068
dash();dash();dash();
break
;
069
case
'P'
:
070
dot();dash();dash();dot();
break
;
071
case
'Q'
:
072
dash();dash();dot();dash();
break
;
073
case
'R'
:
074
dot();dash();dot();
break
;
075
case
'S'
:
076
dot();dot();dot();
break
;
077
case
'T'
:
078
dash();
break
;
079
case
'U'
:
080
dot();dot();dash();
break
;
081
case
'V'
:
082
dot();dot();dot();dash();
break
;
083
case
'W'
:
084
dot();dash();dash();
break
;
085
case
'X'
:
086
dash();dot();dot();dash();
break
;
087
case
'Y'
:
088
dash();dot();dash();dash();
break
;
089
case
'Z'
:
090
dash();dash();dot();dot();
break
;
091
case
' '
:
092
delay(DOTLEN*5);
break
;
093
case
'.'
:
094
dot();dash();dot();dash();dot();dash();
break
;
095
case
','
:
096
dash();dash();dot();dot();dash();dash();
break
;
097
case
':'
:
098
dash();dash();dash();dot();dot();
break
;
099
case
'?'
:
100
dot();dot();dash();dash();dot();dot();
break
;
101
case
'\''
:
102
dot();dash();dash();dash();dash();dot();
break
;
103
case
'-'
:
104
dash();dot();dot();dot();dot();dash();
break
;
105
case
'/'
:
106
dash();dot();dot();dash();dot();
break
;
107
case
'('
:
108
case
')'
:
109
dash();dot();dash();dash();dot();dash();
break
;
110
case
'\"'
:
111
dot();dash();dot();dot();dash();dot();
break
;
112
case
'@'
:
113
dot();dash();dash();dot();dash();dot();
break
;
114
case
'='
:
115
dash();dot();dot();dot();dash();
break
;
116
case
'0'
:
117
dash();dash();dash();dash();dash();
break
;
118
case
'1'
:
119
dot();dash();dash();dash();dash();
break
;
120
case
'2'
:
121
dot();dot();dash();dash();dash();
break
;
122
case
'3'
:
123
dot();dot();dot();dash();dash();
break
;
124
case
'4'
:
125
dot();dot();dot();dot();dash();
break
;
126
case
'5'
:
127
dot();dot();dot();dot();dot();
break
;
128
case
'6'
:
129
dash();dot();dot();dot();dot();
break
;
130
case
'7'
:
131
dash();dash();dot();dot();dot();
break
;
132
case
'8'
:
133
dash();dash();dash();dot();dot();
break
;
134
case
'9'
:
135
dash();dash();dash();dash();dot();
break
;
136
137
}
138
delay(2*DOTLEN);
139
}
140
141
}
func.ino
001
/*
002
* UA6HJQ 25.11.2018
003
* ФУНКЦИИ НЕОБХОДИМЫЕ ДЛЯ РАБОТЫ ВСЕХ РЕЖИМОВ ПРОГРАММЫ
004
*/
005
006
void
ring() {
007
txON();
008
tone(tonePin, 1000);delay(400);
009
tone(tonePin, 800);delay(400);
010
tone(tonePin, 600);delay(400);
011
tone(tonePin, 400);delay(600);
012
noTone(tonePin);
013
txOFF();
014
}
015
016
017
void
ton() {
018
txON();
019
tone(tonePin, 1000);
020
delay(15000);
021
noTone(tonePin);
022
txOFF();
023
}
024
025
026
void
beacon() {
027
txON();
028
sendMsg(MYCALL);
029
sendMsg(MYCALL);
030
sendMsg(
"BEACON"
);
031
sendMsg(QTHLOC);
032
txOFF();
033
}
034
035
void
txON() {
036
delay(1000);
037
pinMode(ptt, OUTPUT);
038
digitalWrite(ptt, LOW);
039
delay(600);
040
}
041
042
043
void
txOFF() {
044
pinMode(ptt, INPUT);
045
digitalWrite(ptt, LOW);
046
}
047
048
049
void
text1() {
050
txON();
051
052
for
(
int
i=0; i <= 9; i++){
053
int
randNumber = random(10000, 30000);
054
char
rcw[1];
055
itoa(randNumber, rcw, 10);
056
Serial
.print(rcw);
057
Serial
.print(
" "
);
058
sendMsg(rcw);
059
}
060
061
Serial
.println();
062
txOFF();
063
}
064
065
066
void
text2() {
067
txON();
068
char
Str1[ ] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
069
070
for
(
int
i=0; i <= 9; i++){
071
for
(
int
s = 1; s <= 5; s++){
072
073
int
randNumber = random(0, 26);
074
Serial
.print(Str1[randNumber]);
075
076
switch
(Str1[randNumber]) {
077
case
'A'
:
078
dot();dash();
break
;
079
case
'B'
:
080
dash();dot();dot();dot();
break
;
081
case
'C'
:
082
dash();dot();dash();dot();
break
;
083
case
'D'
:
084
dash();dot();dot();
break
;
085
case
'E'
:
086
dot();
break
;
087
case
'F'
:
088
dot();dot();dash();dot();
break
;
089
case
'G'
:
090
dash();dash();dot();
break
;
091
case
'H'
:
092
dot();dot();dot();dot();
break
;
093
case
'I'
:
094
dot();dot();
break
;
095
case
'J'
:
096
dot();dash();dash();dash();
break
;
097
case
'K'
:
098
dash();dot();dash();
break
;
099
case
'L'
:
100
dot();dash();dot();dot();
break
;
101
case
'M'
:
102
dash();dash();
break
;
103
case
'N'
:
104
dash();dot();
break
;
105
case
'O'
:
106
dash();dash();dash();
break
;
107
case
'P'
:
108
dot();dash();dash();dot();
break
;
109
case
'Q'
:
110
dash();dash();dot();dash();
break
;
111
case
'R'
:
112
dot();dash();dot();
break
;
113
case
'S'
:
114
dot();dot();dot();
break
;
115
case
'T'
:
116
dash();
break
;
117
case
'U'
:
118
dot();dot();dash();
break
;
119
case
'V'
:
120
dot();dot();dot();dash();
break
;
121
case
'W'
:
122
dot();dash();dash();
break
;
123
case
'X'
:
124
dash();dot();dot();dash();
break
;
125
case
'Y'
:
126
dash();dot();dash();dash();
break
;
127
case
'Z'
:
128
dash();dash();dot();dot();
break
;
129
case
' '
:
130
delay(DOTLEN*5);
break
;
131
}
132
delay(3*DOTLEN);
133
}
134
Serial
.print(
" "
);
135
136
delay(500);
137
}
138
Serial
.println();
139
txOFF();
140
}
141
142
143
void
text3() {
144
txON();
145
char
Str1[ ] =
"ABCDEFGHIJ0123456789KLMNOPQRST0123456789UVWXYZ"
;
146
147
for
(
int
i=0; i <= 9; i++){
148
for
(
int
s = 1; s <= 5; s++){
149
150
int
randNumber = random(0, 46);
151
Serial
.print(Str1[randNumber]);
152
153
switch
(Str1[randNumber]) {
154
case
'A'
:
155
dot();dash();
break
;
156
case
'B'
:
157
dash();dot();dot();dot();
break
;
158
case
'C'
:
159
dash();dot();dash();dot();
break
;
160
case
'D'
:
161
dash();dot();dot();
break
;
162
case
'E'
:
163
dot();
break
;
164
case
'F'
:
165
dot();dot();dash();dot();
break
;
166
case
'G'
:
167
dash();dash();dot();
break
;
168
case
'H'
:
169
dot();dot();dot();dot();
break
;
170
case
'I'
:
171
dot();dot();
break
;
172
case
'J'
:
173
dot();dash();dash();dash();
break
;
174
case
'K'
:
175
dash();dot();dash();
break
;
176
case
'L'
:
177
dot();dash();dot();dot();
break
;
178
case
'M'
:
179
dash();dash();
break
;
180
case
'N'
:
181
dash();dot();
break
;
182
case
'O'
:
183
dash();dash();dash();
break
;
184
case
'P'
:
185
dot();dash();dash();dot();
break
;
186
case
'Q'
:
187
dash();dash();dot();dash();
break
;
188
case
'R'
:
189
dot();dash();dot();
break
;
190
case
'S'
:
191
dot();dot();dot();
break
;
192
case
'T'
:
193
dash();
break
;
194
case
'U'
:
195
dot();dot();dash();
break
;
196
case
'V'
:
197
dot();dot();dot();dash();
break
;
198
case
'W'
:
199
dot();dash();dash();
break
;
200
case
'X'
:
201
dash();dot();dot();dash();
break
;
202
case
'Y'
:
203
dash();dot();dash();dash();
break
;
204
case
'Z'
:
205
dash();dash();dot();dot();
break
;
206
case
' '
:
207
delay(DOTLEN*5);
break
;
208
case
'0'
:
209
dash();dash();dash();dash();dash();
break
;
210
case
'1'
:
211
dot();dash();dash();dash();dash();
break
;
212
case
'2'
:
213
dot();dot();dash();dash();dash();
break
;
214
case
'3'
:
215
dot();dot();dot();dash();dash();
break
;
216
case
'4'
:
217
dot();dot();dot();dot();dash();
break
;
218
case
'5'
:
219
dot();dot();dot();dot();dot();
break
;
220
case
'6'
:
221
dash();dot();dot();dot();dot();
break
;
222
case
'7'
:
223
dash();dash();dot();dot();dot();
break
;
224
case
'8'
:
225
dash();dash();dash();dot();dot();
break
;
226
case
'9'
:
227
dash();dash();dash();dash();dot();
break
;
228
}
229
delay(3*DOTLEN);
230
}
231
Serial
.print(
" "
);
232
233
delay(500);
234
}
235
Serial
.println();
236
txOFF();
237
}
238
239
240
void
smetr() {
241
smetrReading = analogRead(smetrPin);
242
Serial
.print(
"S-metr "
);
243
Serial
.print(smetrReading);
244
txON();
245
if
(smetrReading < 80) {
Serial
.println(
" = S2"
); sendMsg(
"S 2 2"
); }
// калибровка уровня S-метра
246
else
if
(smetrReading < 90) {
Serial
.println(
" = S3"
); sendMsg(
"S 3 3"
); }
// 55-182 для GM-340 UHF
247
else
if
(smetrReading < 100) {
Serial
.println(
" = S4"
); sendMsg(
"S 4 4"
); }
248
else
if
(smetrReading < 110) {
Serial
.println(
" = S5"
); sendMsg(
"S 5 5"
); }
249
else
if
(smetrReading < 120) {
Serial
.println(
" = S6"
); sendMsg(
"S 6 6"
); }
250
else
if
(smetrReading < 130) {
Serial
.println(
" = S7"
); sendMsg(
"S 7 7"
); }
251
else
if
(smetrReading < 140) {
Serial
.println(
" = S8"
); sendMsg(
"S 8 8"
); }
252
else
{
Serial
.println(
" = S9"
); sendMsg(
"S 9 9"
); }
253
txOFF();
254
}
255
256
257
//вольтметр калибруем в зависимости от резисторов (у меня 15к и 1к)
258
// питаем он 5В и проверяем сколько на пине RAW/VCC должно быть примерно столько и в показаниях
259
// затем включаем внешнее питание через RAW/VCC должно быть сколько подано
260
261
void
voltemeter() {
//вольтметр на основе делителя из резисторов
262
float
U1;
263
float
U2;
264
265
float
Rs = 1000.0;
266
float
Rd = 15000.0;
267
float
Vo = 5.00;
268
U2 = Vo * analogRead(A3) / Rs;
269
U1 = U2 / ( Rs / ( Rd + Rs ));
270
Serial
.print(U1);
271
Serial
.println(
" V"
);
272
273
int
volt1 = U1;
274
char
volt[1];
275
itoa(volt1, volt, 10);
276
277
txON(); sendMsg(volt); sendMsg(volt); sendMsg(
"V"
); txOFF();
278
}
279
280
281
void
temp1() {
282
sensors.requestTemperatures();
283
284
char
temp[1];
285
itoa(sensors.getTempCByIndex(0), temp, 10);
286
Serial
.print(temp);
287
Serial
.println(
" C"
);
288
289
txON(); sendMsg(temp); sendMsg(temp); sendMsg(
"C"
); txOFF();
290
}
3.Простой маяк от K6HX (весьма оригинальный математический метод перевода в знаки морзе)
PS для тех, кто дружен с математикой
001
//
002
// Simple Arduino Morse Beacon
003
// Written by Mark VandeWettering K6HX
004
// Email: <a href="mailto:k6hx@arrl.net">k6hx@arrl.net</a>
005
//
006
// This code is so trivial that I'm releasing it completely without
007
// restrictions. If you find it useful, it would be nice if you dropped
008
// me an email, maybe plugged my blog @ <a href="http://brainwagon.org" title="http://brainwagon.org" rel="nofollow">http://brainwagon.org</a> or included
009
// a brief acknowledgement in whatever derivative you create, but that's
010
// just a courtesy. Feel free to do whatever.
011
//
012
013
014
struct
t_mtab {
char
c, pat; } ;
015
016
struct
t_mtab morsetab[] = {
017
{
'.'
, 106},
018
{
','
, 115},
019
{
'?'
, 76},
020
{
'/'
, 41},
021
{
'A'
, 6},
022
{
'B'
, 17},
023
{
'C'
, 21},
024
{
'D'
, 9},
025
{
'E'
, 2},
026
{
'F'
, 20},
027
{
'G'
, 11},
028
{
'H'
, 16},
029
{
'I'
, 4},
030
{
'J'
, 30},
031
{
'K'
, 13},
032
{
'L'
, 18},
033
{
'M'
, 7},
034
{
'N'
, 5},
035
{
'O'
, 15},
036
{
'P'
, 22},
037
{
'Q'
, 27},
038
{
'R'
, 10},
039
{
'S'
, 8},
040
{
'T'
, 3},
041
{
'U'
, 12},
042
{
'V'
, 24},
043
{
'W'
, 14},
044
{
'X'
, 25},
045
{
'Y'
, 29},
046
{
'Z'
, 19},
047
{
'1'
, 62},
048
{
'2'
, 60},
049
{
'3'
, 56},
050
{
'4'
, 48},
051
{
'5'
, 32},
052
{
'6'
, 33},
053
{
'7'
, 35},
054
{
'8'
, 39},
055
{
'9'
, 47},
056
{
'0'
, 63}
057
} ;
058
059
#define N_MORSE (sizeof(morsetab)/sizeof(morsetab[0]))
060
061
#define SPEED (12)
062
#define DOTLEN (1200/SPEED)
063
#define DASHLEN (3*(1200/SPEED))
064
065
int
LEDpin = 13 ;
066
067
void
068
dash()
069
{
070
digitalWrite(LEDpin, HIGH) ;
071
delay(DASHLEN);
072
digitalWrite(LEDpin, LOW) ;
073
delay(DOTLEN) ;
074
}
075
076
void
077
dit()
078
{
079
digitalWrite(LEDpin, HIGH) ;
080
delay(DOTLEN);
081
digitalWrite(LEDpin, LOW) ;
082
delay(DOTLEN);
083
}
084
085
void
086
send(
char
c)
087
{
088
int
i ;
089
if
(c ==
' '
) {
090
Serial
.print(c) ;
091
delay(7*DOTLEN) ;
092
return
;
093
}
094
for
(i=0; i<N_MORSE; i++) {
095
if
(morsetab[i].c == c) {
096
unsigned
char
p = morsetab[i].pat ;
097
Serial
.print(morsetab[i].c) ;
098
099
while
(p != 1) {
100
if
(p & 1)
101
dash() ;
102
else
103
dit() ;
104
p = p / 2 ;
105
}
106
delay(2*DOTLEN) ;
107
return
;
108
}
109
}
110
/* if we drop off the end, then we send a space */
111
Serial
.print(
"?"
) ;
112
}
113
114
void
115
sendmsg(
char
*str)
116
{
117
while
(*str)
118
send(*str++) ;
119
Serial
.println(
""
);
120
}
121
122
void
setup
() {
123
pinMode(LEDpin, OUTPUT) ;
124
Serial
.begin(9600) ;
125
Serial
.println(
"Simple Arduino Morse Beacon v0.0"
) ;
126
Serial
.println(
"Written by Mark VandeWettering <k6hx@arrl.net>"
) ;
127
Serial
.println(
"Check out my blog @ <a href="
http:
//brainwagon.org" title="http://brainwagon.org"" rel="nofollow">http://brainwagon.org"</a>) ;
128
Serial
.println(
""
) ;
129
}
130
131
void
loop
() {
132
sendmsg(
"K6HX/B CM87"
) ;
133
delay(3000) ;
134
}
Вот маяк на 8 МГц:
Оба полноценные, никакого больше оборудования, кроме ардуины и куска провода к пину, не требуется.
проверил первый, что на 8 мегагерц, CW сигнал просто великолепный!!!
Слышен на гармониках, на чётных похуже, на нечетных S9++ )))
Вплоть до 144mHz, на 432 нет даже присутствия
То-есть, можно просто поставить умножители, выделить нужные частоты и получить очень простой маячок ...
во. плод похмельной ночи, отоматический неблокирующий морзе-маяк с таймерами, очередью и блэкджэком.
https://youtu.be/5O44eD7DJaA
чо скормишь ему, то и будет передавать. Ннада?
во. плод похмельной ночи, отоматический неблокирующий морзе-маяк с таймерами, очередью и блэкджэком.
https://youtu.be/5O44eD7DJaA
чо скормишь ему, то и будет передавать. Ннада?
надо
ок. код причешу, описание набью и выкладу. В этой теме, или отдельную создать? тама код абъемный, аж 179 строк. Я помню, ты говорил, что код больше 200 строк ниасилишь, поэтому старался укласца в рамки.
ок. код причешу, описание набью и выкладу. В этой теме, или отдельную создать? тама код абъемный, аж 179 строк. Я помню, ты говорил, что код больше 200 строк ниасилишь, поэтому старался укласца в рамки.
В этой, я буду тут собирать все коды Маяков, что найду
Вы бы сам принцип работы ещё объяснили... И для чего/кого они нужны. Глядишь, люди и потянуться.)
Вы бы сам принцип работы ещё объяснили... И для чего/кого они нужны. Глядишь, люди и потянуться.)
Маяк, устройство подключаемое к радиопередатчику, работающему в автономном режиме, используется радиолюбителями при выезде в полевые условия, служит для точного определения азимута на корреспондента.
Частоты маяков перед выедом как правило озвучиваются на соответствующих сайтах. Так как маяк работает автономно, позволяет оценить прохождение радиоволн в конкретное время суток, отметить точные азимуты на корреспондентов, для последующего использования, в частности в соревнованиях.
Очень помогает при работе на высокочастотных диапазонах (5 - 10 Гигагерц и выше), где угол лепестка диаграммы антенны порядка 1-2 градуса.
Постоянно работающие маяки позволяют оценить прохождение радиосигнала на конкретных корреспондентов.
Попробовал маяк Клименко на WAVGAT nano, от внутреннего генератора сигнал просто ужасен, от внешнего кварца, а он на плате 12 мегацерцовый сигнал приемлемый, на атмеге ардуино нано всё же получше, там он кристально чистый.
Хочу попробовать сменить кварц на 28 мгц, тогда маяк будет работать на частоте 14 мегагерц и кратные этой частоте.
Да, уровень сигнала значительно ниже, сказывается питание камня от 3.3 вольта )))
Скетч здесь, аддоны брал из этой ветки форума
001
// Arduino simply CW beacon
002
// (c) 2012 Max Klimenko
003
// emaster [at] mail.ru
004
// <a href="<a href="http://max-ter.livejournal.com/571.html" rel="nofollow">http://max-ter.livejournal.com/571.html</a>" title="<a href="http://max-ter.livejournal.com/571.html" rel="nofollow">http://max-ter.livejournal.com/571.html</a>" rel="nofollow"><a href="http://max-ter.livejournal.com/571.html" rel="nofollow">http://max-ter.livejournal.com/571.html</a></a>
005
006
// It sends beacon at 8 MHz from pin D9
007
#include "lgtx8p.h"
008
009
// Beacon message
010
const
char
message[] =
"VVV CQ CQ CQ DX DE BEACON BAND 40M 8000KHZ"
;
011
012
// Period of single point (ms)
013
const
int
point_time = 80;
014
015
// Carrier frequency divider.
016
// Carrier freq. (MHz) = 16 / (2 * (1 + freq_div))
017
const
unsigned
char
freq_div = 1;
018
019
//////////////////////////////////////////////////////////////////
020
struct
s_abc
021
{
022
char
letter;
023
char
sign[7];
024
};
025
026
const
s_abc abc[] = {
027
'A'
,
".-"
,
'B'
,
"-..."
,
'W'
,
".--"
,
'G'
,
"--."
,
'D'
,
"-.."
,
028
'E'
,
"."
,
'V'
,
"...-"
,
'Z'
,
"--.."
,
'I'
,
".."
,
029
'J'
,
".---"
,
'K'
,
"-.-"
,
'L'
,
".-.."
,
'M'
,
"--"
,
'N'
,
"-."
,
030
'O'
,
"---"
,
'P'
,
".--."
,
'R'
,
".-."
,
'S'
,
"..."
,
031
'T'
,
"-"
,
'U'
,
"..-"
,
'F'
,
"..-."
,
'H'
,
"...."
,
'C'
,
"-.-."
,
032
'Q'
,
"--.-"
,
'Y'
,
"-.--"
,
'X'
,
"-..-"
,
'1'
,
".----"
,
033
'2'
,
"..---"
,
'3'
,
"...--"
,
'4'
,
"....-"
,
'5'
,
"....."
,
034
'6'
,
"-...."
,
'7'
,
"--..."
,
'8'
,
"---.."
,
'9'
,
"----."
,
035
'0'
,
"-----"
,
'.'
,
"......"
,
','
,
".-.-.-"
,
':'
,
"---..."
,
036
';'
,
"-.-.-."
,
'('
,
"-.--.-"
,
'`'
,
".----."
,
037
'"'
,".-..-.
", '-',"
-....-
", '/',"
-..-.
", '?',"
..--..",
038
'!'
,
"--..--"
,
'@'
,
".--.-."
,
'\\'
,
"..-.-"
};
039
040
unsigned
char
abc_size =
sizeof
(abc) /
sizeof
(abc[0]);
041
042
void
setup
()
043
{
044
// Затактироваться от OSC на плате, при 12 мГц кварце (частота около 6мгц)
045
/*
046
sysClock(EXT_OSC);
047
CLKPR = 1<<PMCE;//разрешить изменение
048
CLKPR = 1<<5; // вывод clk
049
*/
050
051
// Затактироваться от внутреннего генератора 32мГц (частота маяка 16 мегагерц)
052
CLKPR = 1<<PMCE;
//разрешить изменение
053
CLKPR = B00000000;
054
055
// Затактировать от внешнего генератора 32мГц
056
/* int main(){
057
PMCR=1<<PMCE; //разрешить выбор источника тактирования
058
PMCR= 1<<2 | 1<<5; //External high frequency crystal
059
PMX2= 1<<WCE;//разрешить изменения
060
PMX2= 1<<XIEN;//разрешить вход тактовой частоты от кварц. генератора
061
CLKPR = 1<<PMCE;//разрешить изменение
062
CLKPR = 1<<5; //делитель =1 и вывод clk
063
} */
064
065
PORTB = 0;
066
DDRB |= 1<<1;
067
068
OCR1A = freq_div;
069
TCCR1A = 0x48;
070
TCCR1B = 0x09;
071
072
pinMode(13, OUTPUT);
073
digitalWrite(13, HIGH);
// set the LED on
074
}
075
076
void
send_letter(
char
l)
077
{
078
if
(l ==
' '
)
079
{
080
delay(point_time * 7);
081
return
;
082
}
083
084
unsigned
char
idx = 255;
085
for
(unsigned
char
i = 0; i < abc_size; i++)
086
if
(abc[i].letter == l)
087
{
088
idx = i;
089
break
;
090
}
091
092
if
(idx == 255)
return
;
093
094
const
char
*s = abc[idx].sign;
095
096
for
(unsigned
char
c = 0; s[c] != 0; c++)
097
{
098
char
q = s[c];
099
100
DDRB |= 1<<1;
101
digitalWrite(13, HIGH);
// set the LED on
102
103
if
(q ==
'.'
) delay(point_time);
104
else
delay(point_time * 3);
105
106
DDRB &= ~(1<<1);
107
digitalWrite(13, LOW);
// set the LED off
108
109
delay(point_time);
110
}
111
112
delay(point_time * 2);
113
}
114
115
void
loop
()
116
{
117
for
(
int
n = 0; message[n] != 0; n++)
118
send_letter(message[n]);
119
120
delay(2000);
121
}
У Вас там в Черкесске ещё радиогубители осталися???
ок. код причешу, описание набью и выкладу.
Ан нет, быстро не выкладу. Там, аказываеца, думать надо. Крепко думать надо, и даже трезвым, а то хрень с налёту получица.
У Вас там в Черкесске ещё радиогубители осталися???
а то )))
ua6em, ты мне, кста, можешь существенно помочь, если набьешь пока недостающее.
01
const
TMorze MorzeArray[] PROGMEM = {
02
{
'A'
,0b101},
03
{
'B'
,0b11000},
04
{
'C'
,0b11010},
05
{
'D'
,0b1100},
06
{
'E'
,0b10},
07
// .
08
{
'K'
,0b1101},
09
// .
10
{
'S'
,0b1000},
11
// .
12
// .
13
{
'Q'
,0b11101},
14
// .
15
{
'Z'
,0b11100},
16
{
'1'
,0b101111},
17
{
'2'
,0b100111},
18
{
'3'
,0b100011 },
19
20
// .
21
{
'9'
,0b111110},
22
{
'0'
,0b111111},
23
// .
24
// .
25
{
'?'
,0b1001100}
26
};
символ и код морзе в бинарном виде (0bxxxx), для кода морзе правило простое, ведущая единица (мы ее пропустим потом), а потом сам код морзя, 1-тире, 0- точка
например 'Щ' ('Q') ..--.. = 0b1 001100 - пробелом я отделил ведущую единицу от собственно кода Морзе, в реальном коде пробел ставить не нужно
символ и код морзе в бинарном виде (0bxxxx), для кода морзе правило простое, ведущая единица (мы ее пропустим потом), а потом сам код морзя, 1-тире, 0- точка
например 'Щ' ('Q') ..--.. = 0b1 001100 - пробелом я отделил ведущую единицу от собственно кода Морзе, в реальном коде пробел ставить не нужно
сейчас на работу доеду и набью, точнее в течении часа сделаю
дак я не тороплю же, у мня часть есть, отлаживать можно и на этом. Потом, как сделаешь, подставим, и решение будет полным. С кириллицей потом чонить придумаем, мошт таблицу перекодировки какую.
01
const
TMorze MorzeArray[] PROGMEM = {
02
{
'A'
,0b101},
03
{
'B'
,0b11000},
04
{
'C'
,0b11010},
05
{
'D'
,0b1100},
06
{
'E'
,0b10},
07
{
'F'
,0b10010},
08
{
'G'
,0b1110},
09
{
'H'
,0b10000},
10
{
'I'
,0b100},
11
{
'J'
,0b10111},
12
{
'K'
,0b1101},
13
{
'L'
,0b10100},
14
{
'M'
,0b111},
15
{
'N'
,0b110},
16
{
'O'
,0b1111},
17
{
'P'
,0b10110},
18
{
'Q'
,0b11101},
19
{
'R'
,0b1010},
20
{
'S'
,0b1000},
21
{
'T'
,0b11},
22
{
'U'
,0b1001},
23
{
'V'
,0b10001},
24
{
'W'
,0b1011},
25
{
'X'
,0b11001},
26
{
'Y'
,0b11011},
27
{
'Z'
,0b11100},
28
{
'1'
,0b101111},
29
{
'2'
,0b100111},
30
{
'3'
,0b100011},
31
{
'4'
,0b100001},
32
{
'5'
,0b100000},
33
{
'6'
,0b110000},
34
{
'7'
,0b111000},
35
{
'8'
,0b111100},
36
{
'9'
,0b111110},
37
{
'0'
,0b111111},
38
{
'.'
,0b1010101},
39
{
','
,0b1110011},
40
{
':'
,0b1111000},
41
{
'\\'
,0b1011110},
42
{
'-'
,0b1100001},
43
{
'/'
,0b110010},
44
{
'('
,0b1101101},
45
{
')'
,0b1101101},
46
{
'@'
,0b1011010},
47
{
'='
,0b110001},
48
{
'"'
,0b1010010},
49
{
''
',0b1011110},
50
{
'?'
,0b1001100}
51
{
'!'
,0b1110011}
52
{
';'
,0b1101010}
53
54
};
Если ничего не пропустил )))
Спасибо, забрал
Восклецательный знак { '!',0b1110011 } забыл.
Как там с причёсыванием?
Жди. Или вдумчиво и надежно, или быстро. Хочешь, завтра выложу?
не думаю, что еслиф ты без маяка жил 50 лет, то не проживёшь еще 3-4 дня.
Жди. я же кроме писания программ от нечего делать, еще и таки немношко пью. :)
не думаю, что еслиф ты без маяка жил 50 лет, то не проживёшь еще 3-4 дня.
Жди. я же кроме писания программ от нечего делать, еще и таки немношко пью. :)
это другое дело ... да маяк в принципе работает, вот тут скетчик от UA6HJQ немного поправил, у него интересная задумка...
Гы. Очень сильно немношко. :-)
Именно поэтому я не беру заказов. Сегодня я здесь, а завтра в запое, и чем закащик виноват в такой ситуации? А такак у мня остались еще жалкие фрагменты совести, то мне неудобно подставлять непричастных людей. Тебе я ничего, сопсно, и не обещал, мне стала интересна задача, сиравно заняца нечем пока, я попробую сделать. Но уж, как смогу. Не получица - не обессудь, голова моя уже как в децтве работать не в состояньи. :-)
Можешь кидать в мня тапками, я ниабижусь. :-)
Моя задумка готова пока на 60%.
Я очень сильно сожалею, если вдруг обидел каво.
Тебе строку откуда брать? Из сериала или жоска заданную в тексте?
Пока сделал чтение из Сериала, что туда напишешь, то и будет по кругу передавать. Напишешь другое - через 2 секунды будет другое передавать.
В принципе, в АТМега8 код влазиит, даже, наерна, тиньку приспособить можно будет
мне интересен сам твой алгоритм, лучше из сериала, тогда можно клавиатуру притарачить, да я сам всё делаю из интереса )))
Ок. Сериал оставлю. Набираешь в сериале нужный текст. Отправляешь. когда прошло 2 секунды с момента приема последнего символа - передаваемая строка заменяется принятой из сериала и сразу начинает передаваца
Алгоритм простой, на таймерах и флагах. К вечеру выложу на гитхаб. Наерна.
К вечеру выложу на гитхаб. Наерна.
Хорошо!
А я тут небольшой тренер (по мотивам R7HJ) за это время насобирал, пока не оптимизировал, компилируется )))
01
/*
02
* 24.04.2019 (с) UA6EM <a href="mailto:ua6em@yandex.ru">ua6em@yandex.ru</a>, cтарт проекта
03
*
04
* Предлагается скетч простого телеграфного датчика кода Морзе.
05
* Для соревнований тексты формируются в трёх режимах: Цифры, Буквы,
06
* Смешанные тексты, время передачи радиограммы составляет 1 минуту
07
* с выравниваем текста до полной группы.
08
* Скорость передачи регулируется с шагом 10 знаков в минуту.
09
*
10
*
11
*/
12
#define DOTLEN (1200/SPEED)
13
#define DASHLEN (3*(1200/SPEED))
14
#define SEC 1000UL
15
#define SPEED (60) //скорость передачи телеграфа в WPM
16
#define toneFreq (800) //частота звука (выбирайте между 600 - 1000Гц)
17
18
byte
test_go = 1;
19
byte
test_mode = 1;
20
int
ledPin=13;
21
int
tonePin = A4;
// выход звука
22
unsigned
long
previousMillis;
23
unsigned
long
test_time = 60;
// время теста одна минута
24
25
26
void
setup
() {
27
Serial
.begin(115200);
28
previousMillis = millis();
29
}
30
31
void
loop
() {
32
33
if
(test_go){
34
while
(millis() - previousMillis <= test_time * SEC){
35
if
(test_mode == 1) {
Serial
.println();cw_digi();}
36
if
(test_mode == 2) {
Serial
.println();cw_char();}
37
if
(test_mode == 3) {
Serial
.println();cw_chdg();}
38
}
39
delay(10000);
40
previousMillis = millis();
41
test_mode++;
42
if
(test_mode == 4) test_mode=1;
43
}
44
}
И ...при нём
001
/*
002
* Библиотеки для CW
003
*/
004
005
//
006
// *** Генерация цифровых кодов ***
007
008
void
cw_digi() {
009
010
for
(
int
i=0; i <= 9; i++){
011
int
randNumber = random(10000, 30000);
012
char
rcw[1];
013
itoa(randNumber, rcw, 10);
014
Serial
.print(rcw);
015
Serial
.print(
" "
);
016
sendMsg(rcw);
017
}
018
019
Serial
.println();
020
}
021
022
023
//
024
// *** Генерация символьных кодов ***
025
026
void
cw_char() {
027
028
char
Str1[ ] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
029
030
for
(
int
i=0; i <= 9; i++){
031
for
(
int
s = 1; s <= 5; s++){
032
033
int
randNumber = random(0, 26);
034
Serial
.print(Str1[randNumber]);
035
036
switch
(Str1[randNumber]) {
037
case
'A'
:
038
dot();dash();
break
;
039
case
'B'
:
040
dash();dot();dot();dot();
break
;
041
case
'C'
:
042
dash();dot();dash();dot();
break
;
043
case
'D'
:
044
dash();dot();dot();
break
;
045
case
'E'
:
046
dot();
break
;
047
case
'F'
:
048
dot();dot();dash();dot();
break
;
049
case
'G'
:
050
dash();dash();dot();
break
;
051
case
'H'
:
052
dot();dot();dot();dot();
break
;
053
case
'I'
:
054
dot();dot();
break
;
055
case
'J'
:
056
dot();dash();dash();dash();
break
;
057
case
'K'
:
058
dash();dot();dash();
break
;
059
case
'L'
:
060
dot();dash();dot();dot();
break
;
061
case
'M'
:
062
dash();dash();
break
;
063
case
'N'
:
064
dash();dot();
break
;
065
case
'O'
:
066
dash();dash();dash();
break
;
067
case
'P'
:
068
dot();dash();dash();dot();
break
;
069
case
'Q'
:
070
dash();dash();dot();dash();
break
;
071
case
'R'
:
072
dot();dash();dot();
break
;
073
case
'S'
:
074
dot();dot();dot();
break
;
075
case
'T'
:
076
dash();
break
;
077
case
'U'
:
078
dot();dot();dash();
break
;
079
case
'V'
:
080
dot();dot();dot();dash();
break
;
081
case
'W'
:
082
dot();dash();dash();
break
;
083
case
'X'
:
084
dash();dot();dot();dash();
break
;
085
case
'Y'
:
086
dash();dot();dash();dash();
break
;
087
case
'Z'
:
088
dash();dash();dot();dot();
break
;
089
case
' '
:
090
delay(DOTLEN*5);
break
;
091
}
092
delay(3*DOTLEN);
093
}
094
Serial
.print(
" "
);
095
096
delay(500);
097
}
098
Serial
.println();
099
}
100
101
102
//
103
// *** Генерация смешанного текста ***
104
void
cw_chdg() {
105
char
Str1[ ] =
"ABCDEFGHIJ0123456789KLMNOPQRST0123456789UVWXYZ"
;
106
107
for
(
int
i=0; i <= 9; i++){
108
for
(
int
s = 1; s <= 5; s++){
109
110
int
randNumber = random(0, 46);
111
Serial
.print(Str1[randNumber]);
112
113
switch
(Str1[randNumber]) {
114
case
'A'
:
115
dot();dash();
break
;
116
case
'B'
:
117
dash();dot();dot();dot();
break
;
118
case
'C'
:
119
dash();dot();dash();dot();
break
;
120
case
'D'
:
121
dash();dot();dot();
break
;
122
case
'E'
:
123
dot();
break
;
124
case
'F'
:
125
dot();dot();dash();dot();
break
;
126
case
'G'
:
127
dash();dash();dot();
break
;
128
case
'H'
:
129
dot();dot();dot();dot();
break
;
130
case
'I'
:
131
dot();dot();
break
;
132
case
'J'
:
133
dot();dash();dash();dash();
break
;
134
case
'K'
:
135
dash();dot();dash();
break
;
136
case
'L'
:
137
dot();dash();dot();dot();
break
;
138
case
'M'
:
139
dash();dash();
break
;
140
case
'N'
:
141
dash();dot();
break
;
142
case
'O'
:
143
dash();dash();dash();
break
;
144
case
'P'
:
145
dot();dash();dash();dot();
break
;
146
case
'Q'
:
147
dash();dash();dot();dash();
break
;
148
case
'R'
:
149
dot();dash();dot();
break
;
150
case
'S'
:
151
dot();dot();dot();
break
;
152
case
'T'
:
153
dash();
break
;
154
case
'U'
:
155
dot();dot();dash();
break
;
156
case
'V'
:
157
dot();dot();dot();dash();
break
;
158
case
'W'
:
159
dot();dash();dash();
break
;
160
case
'X'
:
161
dash();dot();dot();dash();
break
;
162
case
'Y'
:
163
dash();dot();dash();dash();
break
;
164
case
'Z'
:
165
dash();dash();dot();dot();
break
;
166
case
' '
:
167
delay(DOTLEN*5);
break
;
168
case
'0'
:
169
dash();dash();dash();dash();dash();
break
;
170
case
'1'
:
171
dot();dash();dash();dash();dash();
break
;
172
case
'2'
:
173
dot();dot();dash();dash();dash();
break
;
174
case
'3'
:
175
dot();dot();dot();dash();dash();
break
;
176
case
'4'
:
177
dot();dot();dot();dot();dash();
break
;
178
case
'5'
:
179
dot();dot();dot();dot();dot();
break
;
180
case
'6'
:
181
dash();dot();dot();dot();dot();
break
;
182
case
'7'
:
183
dash();dash();dot();dot();dot();
break
;
184
case
'8'
:
185
dash();dash();dash();dot();dot();
break
;
186
case
'9'
:
187
dash();dash();dash();dash();dot();
break
;
188
}
189
delay(3*DOTLEN);
190
}
191
Serial
.print(
" "
);
192
193
delay(500);
194
}
195
Serial
.println();
196
}
197
198
199
void
dash()
200
{
201
digitalWrite(ledPin, HIGH);
202
tone(tonePin, toneFreq);
203
delay(DASHLEN);
204
digitalWrite(ledPin, LOW);
205
noTone(tonePin);
206
delay(DOTLEN);
207
}
208
209
210
void
dot()
211
{
212
digitalWrite(ledPin, HIGH) ;
213
tone(tonePin, toneFreq);
214
delay(DOTLEN);
215
digitalWrite(ledPin, LOW);
216
noTone(tonePin);
217
delay(DOTLEN);
218
}
219
220
221
void
sendMsg(
char
*str)
222
{
223
int
i;
224
225
delay(500);
226
227
for
(i=0;i<strlen(str);i++)
228
{
229
switch
(toupper(str[i]))
230
{
231
case
'A'
:
232
dot();dash();
break
;
233
case
'B'
:
234
dash();dot();dot();dot();
break
;
235
case
'C'
:
236
dash();dot();dash();dot();
break
;
237
case
'D'
:
238
dash();dot();dot();
break
;
239
case
'E'
:
240
dot();
break
;
241
case
'F'
:
242
dot();dot();dash();dot();
break
;
243
case
'G'
:
244
dash();dash();dot();
break
;
245
case
'H'
:
246
dot();dot();dot();dot();
break
;
247
case
'I'
:
248
dot();dot();
break
;
249
case
'J'
:
250
dot();dash();dash();dash();
break
;
251
case
'K'
:
252
dash();dot();dash();
break
;
253
case
'L'
:
254
dot();dash();dot();dot();
break
;
255
case
'M'
:
256
dash();dash();
break
;
257
case
'N'
:
258
dash();dot();
break
;
259
case
'O'
:
260
dash();dash();dash();
break
;
261
case
'P'
:
262
dot();dash();dash();dot();
break
;
263
case
'Q'
:
264
dash();dash();dot();dash();
break
;
265
case
'R'
:
266
dot();dash();dot();
break
;
267
case
'S'
:
268
dot();dot();dot();
break
;
269
case
'T'
:
270
dash();
break
;
271
case
'U'
:
272
dot();dot();dash();
break
;
273
case
'V'
:
274
dot();dot();dot();dash();
break
;
275
case
'W'
:
276
dot();dash();dash();
break
;
277
case
'X'
:
278
dash();dot();dot();dash();
break
;
279
case
'Y'
:
280
dash();dot();dash();dash();
break
;
281
case
'Z'
:
282
dash();dash();dot();dot();
break
;
283
case
' '
:
284
delay(DOTLEN*5);
break
;
285
case
'.'
:
286
dot();dash();dot();dash();dot();dash();
break
;
287
case
','
:
288
dash();dash();dot();dot();dash();dash();
break
;
289
case
':'
:
290
dash();dash();dash();dot();dot();
break
;
291
case
'?'
:
292
dot();dot();dash();dash();dot();dot();
break
;
293
case
'\''
:
294
dot();dash();dash();dash();dash();dot();
break
;
295
case
'-'
:
296
dash();dot();dot();dot();dot();dash();
break
;
297
case
'/'
:
298
dash();dot();dot();dash();dot();
break
;
299
case
'('
:
300
case
')'
:
301
dash();dot();dash();dash();dot();dash();
break
;
302
case
'\"'
:
303
dot();dash();dot();dot();dash();dot();
break
;
304
case
'@'
:
305
dot();dash();dash();dot();dash();dot();
break
;
306
case
'='
:
307
dash();dot();dot();dot();dash();
break
;
308
case
'0'
:
309
dash();dash();dash();dash();dash();
break
;
310
case
'1'
:
311
dot();dash();dash();dash();dash();
break
;
312
case
'2'
:
313
dot();dot();dash();dash();dash();
break
;
314
case
'3'
:
315
dot();dot();dot();dash();dash();
break
;
316
case
'4'
:
317
dot();dot();dot();dot();dash();
break
;
318
case
'5'
:
319
dot();dot();dot();dot();dot();
break
;
320
case
'6'
:
321
dash();dot();dot();dot();dot();
break
;
322
case
'7'
:
323
dash();dash();dot();dot();dot();
break
;
324
case
'8'
:
325
dash();dash();dash();dot();dot();
break
;
326
case
'9'
:
327
dash();dash();dash();dash();dot();
break
;
328
329
}
330
delay(2*DOTLEN);
331
}
332
333
}
тваюштымать. ну как не надоест то ватэтовотвсё
291
case
'?'
:
292
dot();dot();dash();dash();dot();dot();
break
;
293
case
'\''
:
294
dot();dash();dash();dash();dash();dot();
break
;
295
case
'-'
:
296
dash();dot();dot();dot();dot();dash();
break
;
Нет. Сегодня вряд ли успею. Жучков много.
Нет. Сегодня вряд ли успею. Жучков много.
Да не торопись! Я дед только вникать в твой код неделю буду...PS Скидывал там скетч вверху, две ошибки на 50 строк, лохматость уже совсем не та ...ЗЫ и это не синтаксис, можно было сослаться на незнание языка, а логика...)))
здоброй ночей.
Значить, берешь, лезешь вот сюда.
https://github.com/DetSimen/MorzeRepeater
скачиваешь оттудова Zip файл
В Zip файле есть директория DtS, просто скопируй всё ее содержимое к себе в %Arduino%\libraries\DtS. ПОСЛЕ ЭТОГО только запускай IDE и открывай Morze.ino. Канпилируй, матерись, спрашивай, наливай.
Для вопросов и обсуждения, воть файл Morze.ino (осторожна!!! Dead-o-code):
001
#include "Arduino.h"
002
#include "MorzeTable.h"
003
#include "TimerList.h"
004
#include "Messages.h"
005
006
static
uint8_t TXPin = 10;
// пин передаччика
007
008
extern
TTimerList TimerList;
// списой таймеров (до 10) паумолчанью
009
010
TMessageList MessageList(12);
// очереть на 12 сапщений
011
012
static
const
int
msg_ReadSerial = 0x100;
// сообщение "Читать Сериал"
013
static
const
int
msg_SendChar = 0x101;
// сообщение "Передать символ (букву)"
014
static
const
int
msg_SendNextBit = 0x102;
// сообщение "Передать следующий бит в букве"
015
016
static
const
uint32_t DOT_TIME = 75;
// основное время, длительность точки 75 мс, остальные производные
017
static
const
uint32_t DASH_TIME = 3 * DOT_TIME;
// длительность тире
018
019
static
const
uint16_t REPEAT_TIME = 5000;
// Задержка в мс между повторениями текста, по умолчанию 5 сек.
020
static
const
uint16_t SERIAL_TIMEOUT = 2000;
// если в течение 2000 мс не было данных с сериала, значит приняли всю строку
021
022
static
const
uint8_t MAX_STRING_LENGTH = 128;
// макс длина передаваемой строки
023
024
enum
class
enumTXState :
bool
{ Pause =
false
, Bit =
true
};
025
026
enumTXState TXState = enumTXState::Pause;
// что передаем в данный момент: или бит (точка/тире) или паузу
027
028
THandle hTXTimer = INVALID_HANDLE;
// таймер передаччика
029
THandle hSerialTimer = INVALID_HANDLE;
// таймер таймаута приема из Serial
030
THandle hRepeatTimer = INVALID_HANDLE;
// таймер повтора фразы
031
032
uint8_t TXCurrentMask = 0;
// маска текущего символа
033
uint8_t TXCurrentCode = 0;
// битовый код Морзе текущего символа
034
bool
TXBusy =
false
;
// идет передача бита или паузы
035
bool
TXStopped =
false
;
// передаччик остановлен нахрен. ничего не передаеца
036
037
String StringToTransmit;
// строка, которую будем слать
038
uint16_t TransmitCharIndex = 0;
// индекс текущего символа, в этой строке
039
040
void
TXOnOff(
const
bool
On) {
// передаччик вкл/выкл
041
digitalWrite(TXPin, On);
042
}
043
044
void
tmrTXTimer(
void
) {
// здесь кончился таймер передачи бита/паузы
045
SendMessage(msg_TimerEnd, hTXTimer);
046
TimerList.Stop(hTXTimer);
// остановим этот таймер
047
}
048
049
void
tmrSerialTimer(
void
) {
// строку приняли до конца
050
SendMessage(msg_TimerEnd, hSerialTimer);
051
TimerList.Stop(hSerialTimer);
// таймер больше не нужен
052
}
053
054
void
tmrRepeat(
void
) {
// таймер повтора кончился, начинаем передавать сначала
055
TransmitCharIndex = 0;
056
TXStopped =
false
;
057
TimerList.Stop(hRepeatTimer);
058
}
059
060
void
sendBit(
const
bool
aBit) {
// передать один бит (точку == false или тире == true)
061
062
TXState = enumTXState::Bit;
// признак: передаем бит
063
064
TXOnOff(
true
);
// ключ на старт!
065
066
TXBusy =
true
;
// передаччик теперя занят
067
068
TimerList.setNewInterval(hTXTimer, aBit ? DASH_TIME : DOT_TIME);
// длительность таймера разная для точки и тире
069
TimerList.Reset(hTXTimer);
// перезапустим его сначала интервала
070
071
}
072
073
void
sendPause(
const
uint8_t kf = 1) {
// передаем паузу длиной в 1 точку по умолчанию
074
TXState = enumTXState::Pause;
075
076
TXBusy =
true
;
// передаччик занят
077
078
TimerList.setNewInterval(hTXTimer, kf*DOT_TIME);
// либо длительность паузы кратна точке в kf раз
079
TimerList.Reset(hTXTimer);
// перезапустим таймер сначала
080
}
081
082
;
void
setup
()
083
{
084
Serial
.begin(115200);
085
086
delay(1000);
// чтоб всё устаканилось к старту
087
088
pinMode(TXPin, OUTPUT);
089
090
TXOnOff(
false
);
// ключ выключен
091
092
// все таймеры создаюца по умолчанию остановленными
093
//
094
hTXTimer = TimerList.AddStopped(DOT_TIME, tmrTXTimer);
// таймер передаччика бит
095
hSerialTimer = TimerList.AddStopped(SERIAL_TIMEOUT, tmrSerialTimer);
// таймер таймаута чтения из Serial
096
hRepeatTimer = TimerList.AddStopped(REPEAT_TIME, tmrRepeat);
// таймер повтора передачи строки
097
098
StringToTransmit.reserve(MAX_STRING_LENGTH);
// хапнем сразу место под строку, чтоб не перераспределять потом
099
StringToTransmit =
"CQ DX UA6EM CQ DX UA6EM QSA? 73! 73! 73! K"
;
// строка для передачи по умолчанию
100
TransmitCharIndex = 0;
101
}
102
103
void
loop
()
104
{
105
if
(
Serial
.available()) {
// если в сериал чота припрыгало
106
SendMessage(msg_ReadSerial);
// пошлем команду прочесть сериал
107
TXStopped =
true
;
// передачу остановим
108
TransmitCharIndex = 0;
// и все индексы и маски обнулим,
109
TXCurrentCode = 0;
// так как после приема будем передавать уже новую строку
110
TXCurrentMask = 0;
111
}
112
113
if
((not TXBusy) and (not TXStopped)) {
// если передаччик не остановлен и не занят передачей бита
114
115
if
(TXCurrentMask > 0)
// если маска еще до конца не сдвинулась
116
{
117
SendMessage(msg_SendNextBit);
// передать следующий бит знака
118
}
119
else
120
{
121
SendMessage(msg_SendChar);
// знак кончился, начать передавать след. символ
122
}
123
}
124
125
126
if
( not MessageList.Available())
return
;
// если сапщений в очереди нет, выходим
127
128
TMessage msg = MessageList.GetMessage();
129
130
switch
(msg.Message)
131
{
132
133
case
msg_TimerEnd: {
134
if
(msg.LoParam == hSerialTimer) {
// кончился таймер приёма по сериал
135
TXStopped =
false
;
// можно стартовать передаччик, есличо
136
break
;
137
}
138
if
(msg.LoParam == hTXTimer) {
// кончился таймер передачи бита/паузы
139
TXBusy =
false
;
// можно передавать следующий
140
141
if
(TXState == enumTXState::Bit) {
// если передавали бит, передадим 1 паузу
142
TXOnOff(
false
);
// выключим ключ
143
TXCurrentMask >>= 1;
144
if
(TXCurrentMask>0) sendPause();
else
sendPause(3);
// а если знак кончился, то 3 паузы
145
}
146
147
break
;
148
}
149
150
break
;
151
}
152
153
case
msg_SendNextBit: {
// передаем след. бит (точка/тире)
154
sendBit(TXCurrentCode & TXCurrentMask);
155
break
;
156
}
157
158
case
msg_ReadSerial: {
// чтение из сериала
159
if
(!TimerList.isActive(hSerialTimer)) {
// если таймер таймаута остановлен
160
StringToTransmit =
""
;
// значить читаем новую строку
161
TransmitCharIndex = 0;
162
}
163
StringToTransmit +=
char
(
Serial
.read());
// берем символ из сериал и вклеиваем в строку
164
TimerList.Reset(hSerialTimer);
// перезапускаем таймер таймаута (помнишь? 2 секунды после ПОСЛЕДНЕГО символа)
165
break
;
166
}
167
168
case
msg_SendChar: {
// послать знак
169
if
(TransmitCharIndex < StringToTransmit.length()) {
// если строка еще не кончиилась
170
char
c = StringToTransmit[TransmitCharIndex++];
// взять символ
171
if
(c !=
' '
) {
// если не пробел, то
172
TXCurrentCode = getMorzeCode(c);
// по нему взять код Морзя см. MorzeTable.cpp
173
TXCurrentMask = getSymbolMask(getMorzeCode(c));
// и маску см. MorzeTable.cpp
174
}
175
else
sendPause(7);
// пробел между словами - передаем паузу в 7 точек
176
}
177
else
{
// если строка кончилась
178
TXStopped =
true
;
// остановим передачу
179
TransmitCharIndex = 0;
// вернем указатель на 0 символ строки
180
TimerList.Reset(hRepeatTimer);
// и запустим таймер для REPEAT
181
}
182
break
;
183
}
184
185
default
:
186
Serial
.print(F(
"Unknown message code: 0x"
));
Serial
.println(msg.Message, HEX);
187
break
;
188
}
189
190
}
К 10 пину подключи светлодиот/бузер/ключ на полевике/Братскую ГЭС, всё чо хочешь, короче.
При старте начинает "передавать" фразу по умолчанию. Чтоб сменить, надо в Сериал отправить всё, что надо передавать. Через 2 секунды после приема ПОСЛЕДНЕГО символа, принятая фраза начинает передаваца. После окочания передачи всей фразы - пауза 5 секунд и передача сначала. Все тайминги настраиваюца в самом начале. Комментарии тоже есть. Разбирайся. Матерись. Спрашивай.
код морзе берется из таблицы в прогмем. Как получается код в бинарном виде:
Допустим, закодируем знак вопроса ..--..
ставим 1, это флаг, что после нее до конца байта будут значащие биты, 0-точка, 1-тире
0b1001100
из этого кода, пропусканием всех нулевых бит от начала байта и флага получаем маску символа
0b1001100 символ
0b0100000 - его маска, единичка стоит в первом значащем разряде
делаем маске и коду битовый AND, получаем 0 (точка) или не ноль (тире)
передаем этот бит
маску сдвигаем вправо на бит
пока маска не 0, т.е не сдвинулась до конца, передаем очередной бит.
символ 0b1001100
маски 0b0100000
0b0010000
0b0001000
.
0b0000001
и всё, символ кончился.
хорошо!
СКОМПИЛИРОВАЛ - ИЗУЧАЮ
И чо? скомпилировалось намайна?
у мня для Уно
ВСЁ НОРМАЛЬНО! у нас еще рано, хочу зуммер подключить послушать, разбужу тут всех )))
Работает!!!
Перезалил, уклался в 200 строк. Выкинул лишние сучности
теперь карикатура занимает 5272 байта PROGMEM и 280 АЗУ
Ой. Забыл про саафтара. Подтверждаю, понужал меня не спать изо всех сил.
ua6em, а я всё хотел спросить. Вот ваш маяк, подключили вы его к своему ТХ. Как я понимаю, сами при этом работать не можете - ведь маяк за вас работает... Или есть какие то иные правила?
Это ж как на рыбалке: приехал, удочки поставил, налил... Ну, иногда можно и дёрнуть, когда закусывать надоело ))
Нет, для своего позывного нужно же иметь разрешение с соответствующей категорией и пр. А так получается что вместо тебя работает робот и возможна ситуация когда твоих экземпляров класса может быть несколько.) С одинаковыми позывными! Что как то странненько.)
синглтон, аднака, нужен
Нет, для своего позывного нужно же иметь разрешение с соответствующей категорией и пр. А так получается что вместо тебя работает робот и возможна ситуация когда твоих экземпляров класса может быть несколько.) С одинаковыми позывными! Что как то странненько.)
РосЭфирЗапрет поймает роботов и разберётся, как полагается. Около робота же человек сидит обумаженный - следит, стало быть, за бездушной железякой. А этак ведь и обычный алко... партизан в тылу врага может отстучать под чужой фамилией - разницы нет ведь.
Не, ну это понятно. Хулиганить может каждый, только всё это ведь не законно. А мы же ж законопослушные граждане.)
Хотя раньше что бы выполнить норматив приходилось идти на обман. ЕМНИП, была категория один передатчик - несколько операторов, а категории несколько передатчиков - несколько опрераторов небыло. Однако, многие работали именно так, потому как конкуренция была большая.)
Законопослушные граждане по десять роботов не пускают в эфир под одним аккаунтом. Пока рука стакан держит - робот стучит. Освободилась рука - батарейку у робота отобрал и сам трели выдаёшь. Так что суть вопроса до сих пор неясна.
Ну вот и я о том же. Можно ли десяток роботов пускать под одним аккаунтом? Та даже одного робота и себя?