Простой поисковый радио маячок.

artrue
Vladimir_N:

Только если сами напишете под них прошивку.

Уже пишу, только нужно разобраться с функцией вызова по тону 1750Hz. Есть кусок кода 3 писка с разной мощьностью.

#include <SPI.h>
#define ssPin 10       // SS  Chip select pin for reading/writing to the rf69 registers with SPI

///////////////////////////////////////////////////////////////////////////////////
void setup() {
   Serial.begin(9600);             // baud speed for sending to the arduino serial monitor
  Serial.println("Starting up");  // print to the serial monitor
  pinMode(ssPin, OUTPUT);         // define
  pinMode(9, OUTPUT);
  setupSPI();
  writeReg(0x02,0x34);            // Modulation for OOK, Continuous w.o bit synch, OOK, no shaping
  printReg(0x02);

// multiply desired frequency(MHz) by 16384; convert to HEX; split into 3 blocks with 2 char each
// sample: 432.395*16384=7084359[.68]; 7084359 in dec = 6C1947 in hex; split into 3 hex blocks: 0x6C, 0x19, 0x47

  writeReg(0x07,0x6C);  // 6C,19,47 defaults to a frequency of approximately 432.395 MHZ with crystal tolerance ~  MHz
  writeReg(0x08,0x19);  //
  writeReg(0x09,0x47);  //

//  writeReg(0x07,0x6C);  // 6C,19,19 defaults to a frequency of approximately 432.475 MHZ with crystal tolerance ~  MHz
//  writeReg(0x08,0x19);  //
//  writeReg(0x09,0x19);  //

  printReg(0x07);
  printReg(0x08);
  printReg(0x09);
  // writeReg(0x26,0x07); // CLK off to save power by not enableing an external clock signal on a DIO port.
  // printReg(0x26);
  writeReg(0x01,0x0C);  // Set mode to Transmitter TX mode
  printReg(0x01);
}
////////////////////////////////////////////////////////////////////////////////
void loop() {
beacon(1000);
}

//////////////////////////////////////////////////////////////////////////////////
void printReg(byte data) {
  Serial.print("Register ");
  Serial.print(data);
  Serial.print(" = ");
  Serial.println(readReg(data), HEX);
}

//////////////////////////////////////////////////////////////////////////////////
void writeReg(uint8_t addr, uint8_t value) {
  digitalWrite(ssPin,LOW);
  SPI.transfer(addr | 0x80);
  SPI.transfer(value);
  digitalWrite(ssPin, HIGH);
}

/////////////////////////////////////////////////////////////////////////////////
uint8_t readReg(uint8_t addr) {
  digitalWrite(ssPin, LOW);
  SPI.transfer(addr & 0x7F);
  uint8_t regval = SPI.transfer(0);
  digitalWrite(ssPin, HIGH);
  return regval;
}

/////////////////////////////////////////////////////////////////////////////////
void setupSPI() {
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
}

/////////////////////////////////////////////////////////////////////////////////

void beacon(int timer) {
  // Тон с мин мощьностью
  writeReg(0x11,0x50);
  digitalWrite(9, HIGH);
  delay(timer);
  writeReg(0x11,0x00);
  digitalWrite(9, LOW);
  delay(timer);

  //Средняя мощьность
  writeReg(0x11,0x5F);
  digitalWrite(9, HIGH);
  delay((timer)+1000);
  writeReg(0x11,0x00);
  digitalWrite(9, LOW);
  delay(timer);
  // Максимум
  writeReg(0x11,0x5F);
//writeReg(0x13,0x0F);
  writeReg(0x5A,0x5D);
  writeReg(0x5C,0x7C);
  digitalWrite(9, HIGH);
  delay(timer+2000);
  writeReg(0x11,0x00);
  //writeReg(0x13,0x00);
  writeReg(0x5A,0x00);
  writeReg(0x5C,0x00);
  digitalWrite(9, LOW);
  delay(timer);
}
artrue

Павел помогите разобраться, хочу повторить маяк на модулях RFM69HW. Помогите написать код вызова маяка через тон 1750Hz. Какой алгоритм действий? Что добавить вышеуказанный код?

Pavel_liev:

Там главное разобраться с протоколом чтения/записи, ну писать/читать его регистры, а дальше оно не сложно. Эти модули умеют передавать цифровую информацию, чем ниже скорость тем дальше, но настройка скорости отдельная телега, блок передатчика задается в килогерцах, когда блок приема в специальной генеративной кодовой шняге, там на сайте разработчиков есть даже спец. файл екселя, чтобы считать верные значения для реальной скорости, хотя надежнее не заморачиваться, и взять настройки с маяка. Радиомодуль умеет подавать на ногу уровень, когда случилось какое-то прерывание, удобно ставить на прием валидного пакета, но еще быстрее на прием “префикса”, там в каждой передаче есть технический кусок - префикс, если он “ловится”, модуль думает что дальше будет “дата”, при этом это не гарантирует что сама дата будет точно целой, и чем длиннее инфа, тем больше мусора. Но можно ловить голый префикс, вообще без даты, сработка получается четче. К примеру режим пробуждения маяка сделан на приеме префикса “0b10101010”, на частоте обмена 1.75кГц, ну тон радейки 1.75кГц в узкополосном ЧМ как раз дает непрерывный поток “10101010”(для GFSK с шагом 10КГц лог.0 это наличие несущей на частоте “Х”, и лог.1 такое же наличие несущей на частоте “Х+10КГц”), а модуль тупо выбирает первые попавшиеся что пришли “чистыми”, и дает сигнал прерывания на лапу МК, если прерывание настроено только на это событие, то кода как бы больше нет.

Pavel_liev

artrue какие отличия у RFM69HW мне не известно, а у Si4432 согласно мануалу настаивается скорость работы под частоту передачу бод, которая совпадает с тоном 1750Гц радейки, ширина канала под узкополосный ЧМ, радиомодуль “видит” такой вызывной тон, как постоянный сигнал 0xAA, ну чередование лог. 1 и 0, ведь вызов у радейки занимает обе полосы при ЧМ, а для GFSK это полосы 1 и 0 уровней данных.
Радиомодуль с таким сигналом отлично ловит преамбулу данных, но у звука нет стоповых и префикса, из-за чего дальше он выдаст ошибку пакета, но это не важно, по приему преамбулы можно отследить прерывание внутри модуля, что является сигналом к выходу из сна и начала передачи тонов на нужное нам время.
Алгоритм там такой, МК и модуль спят, раз в сработку таймера вачдог, у меня это 8 секунд, МК будит модуль и мониторит эфир на преамбулу, если ее нет, снова все в сон, а радейка для надежного пробуждения тон должна передавать чуть дольше чем таймер пробуждения вачдог.

Конкретно сами настройки для Si4432, ассемблер, пересылка пакетов конфига, читабельно:

;***настройки частоты***
...
;***модуляция передачи***
ldi R16,0x70
ldi R17,0x80	;активация низкой скорости
rcall spi_write	;подпрограмма пересылки по SPI
ldi R16,0x71
ldi R17,0b00010010;fsk,Direct Mode using TX_Data function via the SDI pin
rcall spi_write	;R16-адрес,R17-дата
;ширина канала передачи
ldi R16,0x72
ldi R17,3		;x625Hz=ширина канала
rcall spi_write


;***настройки приема***
ldi R16,0x1c	;фильтр ширины канала
ldi R17,0b11000001	;4.9КГц
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x20
ldi R17,0xd6
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x21
ldi R17,0x00
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x22
ldi R17,0x98
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x23
ldi R17,0xeb
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x24
ldi R17,0x00
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x25
ldi R17,0x9b
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x2A
ldi R17,0x20
rcall spi_write	;R16-адрес,R17-дата


;преамбула с радейки 1750Гц
ldi R16,0x33
ldi R17,0b00001010;выкл. заголовки
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x35
ldi R17,0x7A	;длина преамблы
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x36
ldi R17,0b01010101
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x37
ldi R17,0b01010101
rcall spi_write	;R16-адрес,R17-дата


;настройки gpio, переключатель антенны, без этого не будет дальности
ldi R16,0x0b
ldi R17,0x12
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x0c
ldi R17,0x15
rcall spi_write	;R16-адрес,R17-дата


;***откл.прерывания радиомодуля,чтобы не тупил***
ldi R16,0x05
ldi R17,0x00
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x06
ldi R17,0x00	;преамбула радейки
rcall spi_write	;R16-адрес,R17-дата
ldi R16,0x03
rcall spi_read	;R16-адрес,R17-дата
ldi R16,0x04
rcall spi_read	;R16-адрес,R17-дата


;***вкл.прием, 0x07="4"***(t=5.6мс)
ldi R16,0x07
ldi R17,0x04
rcall spi_write	;R16-адрес,R17-дата


;проверка на преамбуду радейки для пробуждения
;минимальное определение 16мс
;время spi_read-210мкс, spi_write-226мкс
clr R21
c_metr:
inc R21			;+1
cpi R21,60		;время определения, 60 прогонов, 25мс
brlo no_pream	;если не было преамбулы
rjmp off_beacon	;время вышло,спать
no_pream:
;читаем оба статуса
ldi R16,0x03
rcall spi_read	;R16-адрес,R17-дата
ldi R16,0x04
rcall spi_read	;R16-адрес,R17-дата
sbrs R17, 6	;выполнить если бит байта равен нулю
rjmp c_metr	;нет преамбулы,цикл
;код ниже только если пойман тон вызова

Еще момент, регистры 0х71 и 0х72 нужны для ТХ, и в режиме манипуляции пином с МК мощность ТХ получается чуть выше чем при передаче пакета, почему так не знаю, но максималка у Si4432 именно при конфиге на “Direct Mode using TX_Data function via the SDI pin”. Для Si4432 есть здоровенный отличный фирменный мануал на сайте производителя, там описаны регистры и протокол передачи, даже примеры есть.

1 month later
Pavel_liev

Добавил второй GPS модуль в приемник, теперь программка получила возможность считать расстояние по теореме Пифагора, получили расстояние в метрах, а с направлением, стрелочкой на ЖКИ засада, сам GPS толком не определяет стороны света, использовать еще и модуль компаса не хочется.

Vladimir_N
Pavel_liev:

Добавил второй GPS модуль в приемник, теперь программка получила возможность считать расстояние по теореме Пифагора, получили расстояние в метрах, а с направлением, стрелочкой на ЖКИ засада, сам GPS толком не определяет стороны света, использовать еще и модуль компаса не хочется.

Стрелочку сделать можно, но при этом нужно чтобы приемник двигался тогда можно определить стороны света по разности показаний GPS приемника и направление движения всегда совпадало с одной из сторон приемника. Если приемник стоит или крутится на месте, то только дополнительный модуль и лучше не просто компас, а полный набор датчиков чтобы исключить погрешности от наклона корпуса приемника.

Pavel_liev

Смотрел видео работы таких компасов+гиро, точность низкая, до уровня телефона далеко, стрелка гуляет на треть оборота, больше нравится вариант по GPS, более того у него есть своя софтварная строка угла до севера, стоит попробовать, но точность будет зависеть от количества спутников и скорости перемещения.

Vladimir_N

Нужно гиро+аксель+компас+GPS . Тогда будет нормально. Можно даже без компаса гиро+аксель и поправку делать по GPS. Пример, платы гоночных квадратиков у них как правило не используют компас, но ось Z держат с минимальным дрейфом.
Подобная проблема также неплохо решена в головных трекерах для камер (очков, шлема), там используется полный комплект датчиков.

1 month later
Feruz

Всем привет! Я пришел на форум с ютуб видео Pavel_liev. Пытался на ютубе в комментариях отписаться по этому проекту, но ютуб безжалостно блокировал попытки.

У меня есть комментарий по существу вот к этой проблеме:

Pavel_liev:

получили расстояние в метрах, а с направлением, стрелочкой на ЖКИ засада, сам GPS толком не определяет стороны света

Дело в том, что я занимаюсь похожим проектом, в котором я уже решил задачу относительной навигации между двумя географическими координатами. Я использовал формулу гаверсинусов и азимут по локсодромии. Используя вычисления с двойной точностью можно достичь погрешности меньше 1% при расстояниях между точками до 300 км.
Формулы следующие:

    distance = twice_mean_earth_radius *
               asin( sqrt( pow(sin((lat2 - lat1) / 2), 2) +
                           cos(lat2) * cos(lat1) * pow(sin((lon2 - lon1) / 2), 2)));

    heading = atan((lon2 - lon1) /
                    log(tan(pi_div_by_4 + lat2 / 2) / tan(pi_div_by_4 + lat1 / 2)));

Здесь twice_mean_earth_radius = 12742016, pi_div_by_4 = 0.7853981633974483, lat/lon - координаты точек в радианах

Подробнее можно посмотреть в файле /Firmware/CubeIDE/Code/src/lrns.c проекта на гитхабе: github.com/FeruzTopalov/eleph

По поводу определения сторон света. Современные GPS модули определяют COG (курс относительно земли) достаточно быстро и точно, надо лишь сделать несколько шагов в некотором направлении. При этом они определяют курс относительно истинного севера, а не магнитного как это делает любой компас.

Pavel_liev

Feruz спасибо за пост, не знаю что с ютубом, через раз порой отображает комменты.
Задачу определения расстояния между двумя точками решил с помощью Декарта, путем поиска гипотенузы прямоугольного треугольника: разность долготы в квадрате минус разность широты точек в квадрате будет гипотенузой, дальше корень и имеем расстояние.
В списке параметров GPS видел показчик скорости и курса, но еще не тестировал их, и по специфике работы они должны выдать корректные данные только в движении.
От показчика высоты по GPS отказался, большая погрешность, еще испытывал несколько модулей: Neo6m, atgm336h и Quectel L70-R. Выяснилось что чуйка у Neo6m самая плохая, по быстродействию самым резвым при холодном старте вышел atgm336h, и самым экономичным по питанию L70-R, среднее потребление с пассивной антенной 19мА.
Так же все модули хорошо работают без 3.3в стабилизации, на передатчике радиомодуль и GPS запитываются от литиевого АКБ, его напряжение полного заряда 4.2в ничему не навредило.

Pavel_liev

произвел тест курса и скорости, и по показаниям строки $GPVTG с 9’ю спутниками получилось, что курс GPS вменяемо определяет уже с 0.5км/ч, скорость так же отлично мониторится.

Feruz

Интересный подход с Пифагором. Если не ошибаюсь вы пишите на ассемблере, поэтому такое упрощение? Оценивали погрешность такого расчета?
Согласен насчет Neo6m, впечатления от него самые грустные. Все-таки 2009 год выпуска если не ошибаюсь. Я в своем проекте выпаивал стабилизатор с платы Neo6m чтобы напрямую от 3.3В питать.
Сейчас на али можно купить 8е поколение Ublox, с ним достижимо потребление около 10 мА и это при связке GPS+GLONASS. И кстати как упоминалось выше новое поколение умеет и трек писать, и относительное положение рассчитывать до нужных точек, назначать geo fence и много других плюшек.

Pavel_liev

Только ассемблер, только хардкор! 😃
Погрешность математически по Пифагору отсутствует, а так узкое место корень квадратный, использовал код с радиокота, при сверении с гуглокартой отклонений не заметил. Ассемблер хорош для AVR, если делать на STM32 то конечно проще на Си.

Pavel_liev

Хотя погрешность есть, вспомнил в чем дело, пересчитывал под местную систему координат, а долгота в разных частях света разная, и считается по более сложной формуле. Точно будет только дома, но я же не собираюсь на экватор 😒

А так для правильного расчета: долгота экватора * cos(широты) = долгота местная. Пример: 1° широты = 111км, долгота на экваторе тоже 111км, но у меня 50°N, cos(50°)=0.64, 111km*0.64=71km, значит 1° местной долготы это 71км.

Геннадий10

Маленький вопрос- какую ATTINY нужно использовать для маяка, ATTINY 13, или можно использовать и ATTINY 13A? Сейчас не вспомню,но у них, есть какая то разница.

Pavel_liev

Как пишут в великом гугле, 13’х тинек без “А” не выпускают уже очень долго, отличия были по питанию и каком-то регистре. Для маячка подходит любая.

Vladimir_N
Геннадий10:

Маленький вопрос- какую ATTINY нужно использовать для маяка, ATTINY 13, или можно использовать и ATTINY 13A? Сейчас не вспомню,но у них, есть какая то разница.

Для Вас тини13 не подойдут. Все зависит от версии прошивки. Читайте фаилы сборочной документации (которые я выслал) там есть перечень деталей.

Геннадий10

Владимир, Ваше отправление я еще не получил, поэтому с документацией еще не успел познакомиться. Буду ждать и разбираться. Как всегда, моя проклятая спешка.

Vladimir_N

Геннадий, Вам вся документация отправлена на эл. почту открывайте и изучайте.

Геннадий10

Владимир, только сейчас перепроверяя почту, обнаружил отправленную Вами документацию. Пропустил, замотался. Да… Спасибо.

Feruz
Pavel_liev:

Проведя ряд испытаний, перешел на 3’х элементную ягу. На практике получилось что яга из книги Ротхаммеля давала преимущество над 3’х элементной антенны из симулятора mmanagal всего на несколько процентов, теоретическое преимущество на местности типа лес 50 метров, в замерах на местности разница не была замечена вовсе. Таким образом отдал предпочтение более компактной антенне.
Конструкция 3х элементной яги - результат работы симулятора mmanagal и данных книги Ротхаммеля: “Антенны”, настройками симулятору ограничил длину конструкции, отдавая предпочтение компактности. Антенна имеет немного менее остро выраженный центр, но лучшее соотношение перед/зад, усиление примерно на том же уровне.
Анализатора типа NanoVNA к сожалению нет, и подгонку в реале проверял двигая и подкусывая элементы, смотря сигнал работающего маячка, как оказалось симулятор mmanagal все выдал верно.
Практические испытания в лесу прошли успешно, дальность та же, но компактнее на 6см.

Смоделировал эту антенну интереса ради. Отмечу очень хороший F/B и хорошее усиление. Сопротивление при резонансе низковато, но это Уда-Яги, здесь без ухищрений никак. Тем не менее КСВ 1.6 приемлемый. 😃

Pavel_liev

Feruz значит MMANAGAL не наврал, эту ягу брал из Ротхаммеля, затем подгонял в софте, после чего натурные двиганья элементов и подкусывания по уровню силы сигнала в режиме приема, после чего снова MMANAGAL, и вышло то что вышло 😃
F/B в софте регулировал по максимуму, этот критерий для аналогового поиска по уровню сигнала самый важный, плюс размеры старался уменьшать. На практике 20-30° по центру одинаковы, но далее хорошо заметно ослабевание, и зад вовсе нереально спутать, там большущий спад, такой 3х элементной ягой хорошо ощущается где передатчик.
Вот только у Si4432 всего 0.1Вт, и чуйка так себе, если передатчик упал в траву и ловить на сам радиомодуль расстояние будет менее 200м., в лесу до пол км, а в поле 2-3км, если брать для дальнего радейку китайскую, за счет ее большей чуйки, дальность в полтора-два раза больше. Поэтому начал заниматься с LoRa, она обходит на тестах рацию, при тех же 0.1Вт