Pull to refresh

Система автоматического подсчета кругов и времени для RC-автомоделей

Reading time 6 min
Views 20K
Не так давно я собрал свой аналог AMB, она же MyLaps. Для тех кто не знает — это сильно навороченная система для подсчета кругов радиоуправляемых моделей, картингов и даже автоспорт. Стоимость готового комплекта от MyLaps просто космическая. Моя задача была создать либо клон, либо максимально совместимое. Что же у меня получилось на данный момент.

Предыстория


Не так давно я активно занялся автомодельным спортом. Периодически начал ездить на более-менее крупные соревнования в ближайшие города (Владимир, Заречный, хочется еще Тюмень летом посетить конечно), даже пересел на более мене нормальную модель и обзавелся понтовыми девайсами для настройки шасси. Немного фото, прошу прощение за качество:



Короче говоря — этот спорт затянул очень сильно.

Сразу начал обдумывать как сделать собственную систему подсчета кругов (дальше в тексте ее зову «засечка»). Первые потуги были реализованы на базе RFID меток, которые я переделывал в активные. Задумка так себе. Для покрытия всей ширины трассы и исключения коллизий требовалось несколько декодеров и несколько петель:

Сама метка:

Увеличивал частоту несущий со 125 до 500кгц, но особого результата не было.
После активных гуглений нашел пост на rctech.net. Howard тоже начал что-то делать. Даже выложил схемы детектора и усилителя, которыми я и воспользовался.

Вот уже здесь я начал делать декодер, который работает с оригинальными транспондерами AMB и самопальные. И даже делал свой интерфейс на основе WiFi, но проект пока что загнил:



Что я сейчас имею на данный момент


Вот такую черную коробочку-декодер:

Внутри такая платка:

Усилитель петли:

Сама петля детектирования:

И транспондеры:


Сегодня хочу рассмотреть подробнее как работает транспондер и как он умудряется так быстро передавать 13 байт идентификатора за 100мкс.

Транспондер


Вот так выглядят оригинальные транспондеры:
AMBrc dp

MRT (клоны AMB)

AMB RC4 Hybrid

Вот так выглядят транспондеры Howard'а:


И схема:

Более подробная тема про них на rctech.net. Если интересно — прошу ознакомиться.

Начну со схемы своих поделок:

и фотографии:


Первое что бросается в глаза — катушка вокруг платы. Это можно назвать антенной. На схеме это L1. Для резонанса к ней подключен конденсатор на 100пФ. Напоминаю, что несущая в оригинальных AMB транспондеров — 5мгц. Способ передачи данных — BPSK, то бишь сдвиг фазы. Пожалуй покажу пару осциллограмм для наглядности:




и немного осциллограмм Howard'а:




p.s. на последних осциллограммах Howard тестирует детектор сдвига фазы, еще аналоговый, судя по всему.

По поводу питания схемы — можно использовать 200 Ом резистор и стабилитрон на 5.1В, ибо 5в LDO стабилизаторы дорогие.

В качестве контроллера используем Attiny25 по нескольким причинам:

1. Встроенный генератор на 64мгц, который не пригодился
2. Программирование по debugWire
3. Работает на 20мгц.
4. Есть интересный режим работы ШИМ, который мне и пригодился.

Начну с интересного режима ШИМ:



Мы можем заставить 5 и 6 ногу работать в противофазе, а это убирает часть внешней ненужной обвязки.
Инициализация таймера:

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 20000,000 kHz
// Mode: PWMA top=OCR1C
// OC1A output: Non-Inv., /OC1A connected
// OC1B output: Disconnected
// Timer1 Overflow Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
PLLCSR=0x00;

TCCR1=0x51;
GTCCR=0x00;
TCNT1=0x00;
OCR1A=2;
OCR1B=0x00;
OCR1C=3;


Это даст нашему таймеру работать на 5мгц и выдавать прямоугольные импульсы на выходах PWM.

Каждый бит информации передается раз в 800нс, а это 16 машинных тактов при 20мгц. Что бы реализовать такую быструю передачу мне пришлось перед передачей кода записывать каждый бит в отдельный байт памяти. Другого более легкого способа я не придумал.

Из 13 передаваемых байт первые 2 байта всегда 0x79 0x16. Howard называет их преамбулой. Эти байты в дальнейшем нам пригодятся. По этим байтам FPGA выдает сигнал VALID, который говорит котороллеру о том, что над петлей прошла метка.

Итак, перед передачей остальных 11 байт, их нужно раскидать в 88 байт ОЗУ:

do                       
        {                
        if (RFID_Buffer_ee[RFIDBufferPtr]&mask)  
            {       
            buffer[RFIDBit_Count]=1;
            } 
            else 
            {
            buffer[RFIDBit_Count]=0;
            }   
        mask>>=1;
        if (!mask)
            {
            mask=0x80;
            RFIDBufferPtr++;
            }                                      
        RFIDBit_Count++;
        }
      while (RFIDBit_Count<TransBuffSize);


Особо мудрить с передачей первых двух байт я не стал и сделал так:

      //Включаем таймер
      TCCR1=0x51; 
      //Ждем 8мкс
      delay_us(8);  
      //transmit 0x79 0x16
      NoPhaseChange
      NOP
      PhaseChange
      NOP
      PhaseChange
      NOP
      PhaseChange
      NOP
      PhaseChange
      NOP        
      NoPhaseChange
      NOP        
      NoPhaseChange
      NOP        
      PhaseChange
      NOP        
      NoPhaseChange
      NOP        
      NoPhaseChange
      NOP        
      NoPhaseChange
      NOP        
      PhaseChange
      NOP        
      NoPhaseChange
      NOP        
      PhaseChange
      NOP        
      PhaseChange
      NOP
      NoPhaseChange     
      #asm("nop");
      #asm("nop");


А вот сами PhaseChange и NoPhaseChange. Что бы сменить фазу нужно выключить и включить таймер на 4 такта. Как раз каждая запись значения в регистр таймера занимает по два такта. Ну а что бы ничего не делать нужно просто подождать 4 такта.

#define PhaseChange TCCR1=0x50; TCCR1=0x51;
#define NoPhaseChange #asm("nop"); #asm("nop"); #asm("nop"); #asm("nop"); 
#define NOP #asm("nop"); #asm("nop"); #asm("nop"); #asm("nop"); #asm("nop"); #asm("nop"); #asm("nop"); #asm("nop"); #asm("nop"); #asm("nop"); #asm("nop"); #asm("nop"); 


Так что передача первых двух байт довольно таки тупорылая.

И собственно передача остальных 11 байт:

for (i=0;i<TransBuffSize;i++)
        {
        if (!buffer[i]) 
            {
            #asm("nop");
            #asm("nop");
            #asm("nop");}
        else
            {
            TCCR1=0x50; 
            TCCR1=0x51;
            }; 
        }


Тут один машинный такт отнимает if else.

Примерно так выглядит сигнал после детектора BPSK:



Кстати, время между передачами каждого кода варьируется рандомом от 1мс до 2мс

Встает логичный вопрос, что же нам нужно передавать. О своем протоколе я напишу позже, а пока дам коды тех оригинальных транспондеров, что у меня есть:

//flash char RFID_Buffer_ee[BuffSize]={0xEF,0xD4,0xFE,0xF6,0xE1,0xD1,0x22,0xCD,0xCC,0x3C,0}; //9887001:
//flash char RFID_Buffer_ee[BuffSize]={0x3B,0x21,0xC7,0x1F,0xF7,0xFE,0x3E,0xFE,0xC3,0x3F,0}; //9577130:
flash char RFID_Buffer_ee[BuffSize]={0x0D,0xAE,0xAD,0xB2,0x49,0x89,0xB9,0x64,0xB3,0x33,0x48};  //8087916:
//flash char RFID_Buffer_ee[BuffSize]={0x00,0xEF,0x35,0xEF,0x0E,0x26,0x0A,0xD8,0x3F,0xCF,0x48}; //8110984:
//flash char RFID_Buffer_ee[BuffSize]={0xE1,0x2A,0xD9,0xE1,0xEE,0xD9,0x4E,0x07,0x83,0x0F,0x40}; //5495805:
//flash char RFID_Buffer_ee[BuffSize]={0x35,0xD1,0x1E,0x21,0x2A,0x10,0x5D,0xd0,0x7F,0xCF,0x40}; //3472238:
//flash char RFID_Buffer_ee[BuffSize]={0xDA,0xE4,0x2B,0x24,0x27,0xEF,0x87,0x31,0x4F,0x33,0x00}; //8959711:
//flash char RFID_Buffer_ee[BuffSize]={0xD4,0x14,0xC7,0xCB,0xDF,0xD6,0x9A,0x17,0xBF,0xF0,0x40}; //8361115
//flash char RFID_Buffer_ee[BuffSize]={0xDA,0x0B,0x2B,0x14,0xFC,0xC7,0x2C,0xC2,0xF3,0x03,0x04}; //8718039:


Вот найти взаимосвязь передаваемого кода и номера транспондера мне не удалось. Мои клоны транспондеров с оригинальной засечкой AMBrc3 работают так: один раз увидится, потом перестает. Подозреваю, что проблема все таки кроется в дополнительно передаваемой информации:

EC84418105A6B5BD70CF0000
E12AD9E1EED94E07830F4001
E12AD9E7EED94E07C30F4002
E12AD9E1EED94E07830F4002
38A8F9C1ECA67A7E4FCC4002
E12AD9E1EED94E07830F4002
E12AD9E1EED9CE07830F4000
E12BDBE1EED94E07830F4000
E12AD9E1EED94E07830F4000
E12AD9E1EED94E07830F4001
E27B5E0BC356B9B98CC24001
E12BD9E1EED94E07830F4001
F12AD9E1EED94E07830F4000
E12AD9E1EED94E07830F4002
E12AD9E1EED94E07830F4002
E242145FC145858D4CCF0023
E12AD9E1EED94E07830F4000
E12AD9E1EED94E07830F4004
D417A27CD8B9BA4E40CC4002
E12AD9E1EED94E07830F4002
E12AD9E1EED94E07830F4023
E12AD9E1EED94E07830F4000
E12AD9E1EED94E07830F4000
E12AD9E1EED94E07830F4000
E12AD9E1EED94E07830F4000
E12BD9E1EED94E07830F4001
E12AD9E1EED94E07830F4002
E12AD9E1EED94E07830F4002
E12AD9E1EED94E07830F4000
3B14155CCA79B54D73000002
E12AD9E1EED94E07830F4002
E243145FC145858D4CCF0000
E12AD9E1EED94E07830F4000
E12A58E1EED94E07830F4002
E12AD9E1EED94E07830FC000

Плохо видно из-за помех, но через каждые три посылки с идентификатором (E12AD9E1EED94E07830F40) шлется еще посылка с дополнительной информацией (D417A27CD8B9BA4E40CC40).
Все осложняется тем, что проверить транспондеры я могу только на соревнованиях. Засечку стоимость порядка 4000 евро мне никто поиграться не даст.

Все осложняется тем, что проверить транспондеры я могу только на соревнованиях. Засечку стоимость порядка 4000 евро мне никто поиграться не даст.

Файлы для эмуляции


Тем кто хочет посмотреть как это работает в Proteus, прошу сюда


Вместо заключения


Хочу сказать что в следующей статье расскажу немного о детекторе BPSK (там половина схемы взята с rctech.net и запихана в ПЛИС), но больше расскажу о программной части декодера. Расскажу о протоколах AMB20 и AMBRc работающих на Rs-232, о том как реализовал совместимость с оригинальными транспондерами AMB
Tags:
Hubs:
+19
Comments 3
Comments Comments 3

Articles