Проект не закончен, я весьма плох в этой теме и у меня пока вопросы. Хочется получше познакомиться с RTLSDR и NanoVNA в ходе их решения. Поэтому если кто-то будет читать и сможет помочь, буду очень рад советам. Сейчас я пытаюсь разнести радиоканалы двух идентичных игрушек, попутно получая какой-то опыт с радиоприемом и передачей, все в режиме хобби. Заменить все на NRF или ESP задача не стоит, это слишком просто.
Купил в фикспрайсе два кораблика на радиоуправлении, для детей. Вначале хотел печатать, но увидел эту игрушку и решил что она стоит своих денег. За 300 рублей там пульт на тактовых кнопках, два мотора, пластиковый корпус судна, танковое управление, руль бутафорский, его устанавливают в фиксированное положение для «триммирования» тяги, если выражаться по-самолетному.
Установка моторов довольно странная, они прикрепляются к днищу снизу и находятся в пластиковых кожухах. По лужам уже не погоняешь, или нужно найти глубокую лужу. Они здесь явно сэкономили на трубках Дейдвуда - своеобразных трубчатых подшипниках, в которые забивается консистентная смазка и устанавливается вал. Без таких трубок не достичь герметизации корпуса. Но раз тут моторы снаружи, даже если и нахлебаются, вода не попадет внутрь и корабль не потонет.
Взяв кораблики разных цветов, я надеялся, что можно будет рулить по-отдельности. Но радиоканал там настроен одинаково, без какой-либо быстрой возможности развести по частотам.
Приемник состоит из радиочастотной части (регенеративный приемник на одном транзисторе, с возможностью подстройки катушки), потом пассивные фильтры и микросхема дешифратора TXM8D423C, совмещенного с H-мостом. Микросхема китайская, информации на нее нет. Осциллографом потыкал в H-мост, там нет ШИМ, поэтому если поставить мощную батарейку, то она без контроля тока с большой вероятностью убьет и микросхему, и мотор.
Схему приемника удалось найти, она вроде похожая, тщательно не проверял, что-то скорее всего не совпадает, тут может быть 27 МГц, а у меня может быть 40 - я еще не выяснил, да и у меня нет светодиодов.
TXM8D423C приемник сигнала
Ткнул осциллограф в контакт 14 - увидел PWM на 1 кГц при работе пульта. Уже хорошо. Прежде чем дальше продолжать приключение, покопал передатчик - YX4116, есть скудная документация на китайском с возможностью перевода -
https://www.chinahao.com/product/559732132610/ Данные передаются на частоте 1 кГц, формат состоит из двух типов пакетов - W1 и W2, первый тип имеет заполнение 50%, про второй забыли написать. Признак конца передачи - 4 пакета W2 подряд, а количество пакетов W1 кодирует тип команды (левый мотор вперед, левый мотор назад, правый мотор вперед, правый мотор назад, оба мотора вперед, оба мотора назад, один вперед и второй назад и наоборот).
Глядя на схему приемника, конечно не полностью понятно что делает микросхема. Но раз уж команды завязаны на подсчет пакетов, то внутри микросхемы компаратор и автомат на триггерах или что-то вроде того. Похоже, после цепочки R3-C9, происходит процесс заряда и конденсатора C6, замедленный параллельным резистором R4, напряжение на этом конденсаторе считывается на VI1, и внутри микросхемы как-то с чем-то сравнивается, в результате чего формируется управление мостом для первого мотора - вперед или назад. Микросхема может и разрядить конденсатор, если обнаружит признак конца передачи. Но это все мои догадки - надо проверять. Вряд ли эта микросхема жестко завязана на фиксированное число пакетов от передатчика, а значит RC-цепочки как-то задают отсчет времени посылки пакетов, по которому определяется тип поступающих команд.
После тыканья осциллографом в ногу 14 приемника, стало понятно про недостающий в документации пакет W2, и можно по-быстрому написать такую программу для проверки всех команд:
void setup() {
pinMode(8, OUTPUT); // Output to r6 on rc car
}
void loop() {
rcLeft(5);
rcRight(5);
rcFWD(20); //Send forward signal 20 times;
rcFWDLeft(20); // forward left 20 times and so on.
rcFWDRight(20);
rcREV(20);
rcREVLeft(20);
rcREVRight(20);
rcLeft(2);
rcRight(2);
rcLeft(2);
rcRight(2);
delay(500);
}
void rcRight (int loops) {
for (int f = 0; f < loops; f++) { //left
for (int i = 0; i < 58; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(640);
digitalWrite(8, LOW);
delayMicroseconds(750);
}
for (int i = 0; i < 4; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(2000);
digitalWrite(8, LOW);
delayMicroseconds(740);
}
}
}
void rcLeft (int loops) {
for (int f = 0; f < loops; f++) { //left
for (int i = 0; i < 64; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(640);
digitalWrite(8, LOW);
delayMicroseconds(750);
}
for (int i = 0; i < 4; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(2000);
digitalWrite(8, LOW);
delayMicroseconds(740);
}
}
}
void rcFWD (int loops) {
for (int f = 0; f < loops; f++) { //forward
for (int i = 0; i < 10; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(640);
digitalWrite(8, LOW);
delayMicroseconds(750);
}
for (int i = 0; i < 4; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(2000);
digitalWrite(8, LOW);
delayMicroseconds(740);
}
}
}
void rcREV (int loops) {
for (int f = 0; f < loops; f++) { //Reverse
for (int i = 0; i < 40; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(640);
digitalWrite(8, LOW);
delayMicroseconds(750);
}
for (int i = 0; i < 4; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(2000);
digitalWrite(8, LOW);
delayMicroseconds(740);
}
}
}
void rcFWDRight (int loops) {
for (int f = 0; f < loops; f++) { //FR
for (int i = 0; i < 28; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(640);
digitalWrite(8, LOW);
delayMicroseconds(750);
}
for (int i = 0; i < 4; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(2000);
digitalWrite(8, LOW);
delayMicroseconds(740);
}
}
}
void rcFWDLeft (int loops) {
for (int f = 0; f < loops; f++) { //FL
for (int i = 0; i < 34; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(640);
digitalWrite(8, LOW);
delayMicroseconds(750);
}
for (int i = 0; i < 4; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(2000);
digitalWrite(8, LOW);
delayMicroseconds(740);
}
}
}
void rcREVRight (int loops) {
for (int f = 0; f < loops; f++) { //RR
for (int i = 0; i < 52; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(640);
digitalWrite(8, LOW);
delayMicroseconds(750);
}
for (int i = 0; i < 4; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(2000);
digitalWrite(8, LOW);
delayMicroseconds(740);
}
}
}
void rcREVLeft (int loops) {
for (int f = 0; f < loops; f++) { //RL
for (int i = 0; i < 46; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(640);
digitalWrite(8, LOW);
delayMicroseconds(750);
}
for (int i = 0; i < 4; i++) {
digitalWrite(8, HIGH);
delayMicroseconds(2000);
digitalWrite(8, LOW);
delayMicroseconds(740);
}
}
}
Схема передатчика простая, транзистор T1 приоткрывается через R2 и запускает колебания кварцевого резонатора, к которым через R1 добавляется модулирующий PWM-сигнал на 1 кГц. Колебания модулированного сигнала управляют открытием T2, который работает на антенну. C2, C5 - удаляют постоянную составляющую, L3-C6 - цепь согласования импеданса антенны и характеристического сопротивления выходного каскада передатчика.
YX4116 передатчик
На упаковке написано 27 МГц, антенна выполнена в виде струны длиной около 23 см, внутри корпуса она соединяется с проводом около 5 см. На плате нанесены режимы работы 27 и 40 МГц, отметка стоит возле 40 МГц. Думаю мне тут поможет RTLSDR - как найду, посмотрю насколько сильно передатчик гадит в эфир и на какой частоте работает. Несущая модулируется с помощью ШИМ, так что будут гармоники.
Такой передатчик просто так не перестроить на другую частоту - придется менять кварц и по-новой согласовывать антенну на такой частоте, а потом то же самое для приемника. Я пока это не умею, ни теоретически, ни практически.
Я так понимаю, для передатчика, надо определить комплексное сопротивление (импеданс) линии передачи сигнала от T2 до антенны. Если вместо антенны подключить известный высокочастотный резистор и сравнить амплитуду падения напряжения на нем с напряжением разомкнутой цепи, и все это на нужной частоте, то можно понять, какая у линии реактивная составляющая импеданса (но это не точно). И как тут может помочь VNA? Или вообще не очень важно вымерять импеданс короткого участка линии на печатной плате при частотах до 50 МГц...
А потом измерить импеданс антенны. Кстати как? Коннектора у нее нет - это просто кусок струны. Попробую просто припаять к SMA-разъему и подключить к VNA. А уже потом думать как изменить сопротивление линии передачи так, чтобы оно согласовалось с антенной. На схеме передатчика это элементы L3, C6. Только я не знаю под какое значение импеданса они подбирались.
Для приемника, надо попробовать сделать то же самое. Измерить его характеристическое сопротивление, вместо антенны подключив VNA, возможно понадобится аттенюатор, потом согласовывать его с антенной. Длина антенны какая-то странная, что не соответствует ни 27, ни 40 МГц.
NanoVNA можно применить в режиме спектроанализатора. Это может быть полезно при настройке катушки в радиоприемной части - чтобы максимизировать амплитуду усиленного сигнала.