www.open-tager.ru http://www.open-tager.ru/forum/ |
|
LTAscetik http://www.open-tager.ru/forum/viewtopic.php?f=5&t=1565 |
Страница 256 из 532 |
Автор: | Pingvin [ 11 апр 2013, 06:11 ] |
Заголовок сообщения: | Re: LTAscetik |
hexFF писал(а): Pingvin писал(а): hexFF писал(а): не успевает прерывание отработать, тут гадать не надо. компилятор на прерывание минимум 70-80 тактов хоронит, на сохранение и восстановление РОН. на ассемблере- самое оно, тактов 25-30 вместе с уходом на вектор и возвратом. А помочь сможете? Я в AVR-овском ассемблере ни бум-бум... Как то же ещё значения из переменных в регистры передать надо. Вот, собственно, код прерывания Код: /************************************************************************************** * Обработчик прерываний таймера ***************************************************************************************/ ISR(TIMER2_COMP_vect){ static volatile uint8_t prt; prt = TSOP_IN&TSOP_PIN; if (prt==0) //На ножке ИК-приемника низкий уровень сигнала (пойман сигнал несущей) { low_level_counter++;//Увеличиваем счетчик длительности низкоуровнего сигнала на ножке ИК-приемника } else //На ножке ИК-приемника высокий уровень сигнала (пойман сигнал несущей) { high_level_counter++;///Увеличиваем счетчик длительности высокоуровнего сигнала на ножке ИК-приемника if((start_bit_received)&&(high_level_counter > IR_ZERO*8)) {//Фиксируем окончание приема по таймауту start_bit_received = false; //отменяем прием rx_event = RX_COMPLETE; //Генерим событие "принят пакет" receiver_on = false;//выключаем приемник if (ir_transmitter_on==false) TIMSK &=~_BV(OCIE2); //если передача не ведётся - выключаем прерывания } if((high_level_counter > IR_ZERO*8)&&(ir_transmitter_on==false)) { receiver_on = false;//выключаем приемник TIMSK &=~_BV(OCIE2); } } if (ir_transmitter_on==true) {//Если передача разрешена if (ir_pulse_counter > 0) //необходимая длительность пачки импульсов { //ещё не достигнута, "мигаем" дальше IR_LED_INVERT; //необходимая длительность пачки ir_pulse_counter--; } else //пачка импульсов была отправлена, { IR_LED_OFF; //тушим ИК-диод if ( ir_space_counter > 0) //проверим, выдержан ли промежуток между импульсами { //нет, промежуток не выдержан IR_LED_OFF; //тушим ИК-диод ir_space_counter--; //уменьшаем обратный счетчик паузы на один "тик" } else //Пакет импульсов и промежуток между битами переданы { //нужно формировать следующую пачку (передаваемый бит) if (data_packet.data[cursor_position]!=0) //если указатель указывает не на пустую ячейку { ir_pulse_counter =data_packet.data[cursor_position++] ; //передадим импульс указанной длительностью ir_space_counter = IR_SPACE; //и про паузу не забудем } else //Все данные переданы (элемент, на который ссылается указатель, равен 0) { ir_transmitter_on=false; //выключаем передатчик FIRE_LED_OFF; display_bullets_update_now++; // если if (!receiver_on) //если нет приема пакета { TIMSK &=~_BV(OCIE2); // Запрещаем прерывания по захвату/сравнению } } } } } else {//Если передача запрещена } } по коду едва ли, в Си я не бум-бум совершенно, но алгоритмом помогу. Так понял, что у вас ножка ИК- диода по прерыванию инвертируется. Думал над этим вариантом, выбрал другой подход. По порядку: у меня процессор ATmega328 (выбрал из-за маленького корпуса и 32 кб флеш- памяти- её больше половины уйдет на бинарники звуков), такт 8 МГц. алгоритм передачи "пули": таймер 1 настраивается в режим СТС по значению в OCR1A (подбираем так, чтоб прерывание выскакивало каждые 17,7 мкс - для частоты несущей 56 килогерц), в OCR1B закидываем значение OCR1A деленное на 2. Оба прерывания (по совпадению OCR1A и OCR1B) разрешаем. теперь самое интересное - обработчики. по совпадению OCR1B самый простой- только одно действие- выставить неактивный уровень на ножке ИК- светодиода. по совпадению OCR1А- тут вывод пачек импульсов- смотрим что нужно выводить, если нужно- выставляем высокий уровень на ножке, нет- не трогаем её. на ассемблере летает на ура, на Си не знаю, пойдет ли- там компилятор есть... таймер 2 будет для вывода звука, таймер 0- для приема пуль и как системный таймер. Спасибо, но проблема решена в рамках существующего алгоритма- проблема была в математике! Значение "количество тиков таймера" для СТАРТ-БИТА просто не влазило в переменную типа uint8_t - было больше, чем 255. Пришлось поменять тип переменной на uint16_t. Ну облегчил обработчик передающий - прием пакета перенес в другое прерывание частотой 8 КГц. Теперь передающий обработчик выглядит так Код: /************************************************************************************** * Обработчик прерываний таймера ***************************************************************************************/ ISR(TIMER2_COMP_vect){ if (ir_transmitter_on==true) {//Если передача разрешена if (ir_pulse_counter > 0) //необходимая длительность пачки импульсов { //ещё не достигнута, "мигаем" дальше IR_LED_INVERT; //необходимая длительность пачки ir_pulse_counter--; } else //пачка импульсов была отправлена, { IR_LED_OFF; //тушим ИК-диод if ( ir_space_counter > 0) //проверим, выдержан ли промежуток между импульсами { //нет, промежуток не выдержан ir_space_counter--; //уменьшаем обратный счетчик паузы на один "тик" } else //Пакет импульсов и промежуток между битами переданы { //нужно формировать следующую пачку (передаваемый бит) if (data_packet.data[cursor_position]!=0) //если указатель указывает не на пустую ячейку { ir_pulse_counter =data_packet.data[cursor_position++] ; //передадим импульс указанной длительностью ir_space_counter = IR_SPACE; //и про паузу не забудем } else //Все данные переданы (элемент, на который ссылается указатель, равен 0) { ir_transmitter_on=false; //выключаем передатчик FIRE_LED_OFF; display_bullets_update_now++; TIMSK &=~_BV(OCIE2); // Запрещаем прерывания по захвату/сравнению } } } } else {//Если передача запрещена } } Так что прошивка уже работает на 56000 Гц! Жду не дождусь реальных тестов с оборудованием LW. |
Автор: | Pingvin [ 11 апр 2013, 06:16 ] |
Заголовок сообщения: | Re: LTAscetik |
hexFF писал(а): можно, только есть одно НО- частоту несущей выстрела программно изменить труда не составит, а вот с TSOP- ами повязки как быть? На "родной" частоте они очень хороши, сместить её- чуствительность резко падает. Экспериментировал с TSOP4836, у них пик на частоте 36 кГц. Сигнал с несущей 56 кГц со 100 метров (ИК- диод + кусок канализационной трубы + длиннофокусная лупа диаметром 40 мм) кое- как принял. Кое- как- это неуверенно, плюс очень плавают (до 40%) тайминги. Протоколы MilesII и Laserwar4 предусматривают период Т сигнала 600 мкс, а на практике с TSOP4836 от 430 до 800 вышло. TSOP4856 - идеально, до муллиметра. Программно это можно победить, но делать ТАКОЕ не очень хочется. Самый очевидный выход- две повязки (просто подключить нужную), либо съемные датчики (как крепить? в бою не отвалятся?). Собственно - Вам уже ответили MidnightDreamer писал(а): Однозначно либо две повязки, либо повязку с двумя типами датчиков. А съемные датчики на липучках практикуются как за границей, так в Полигоне 64, так что ничего никуда не отваливается Сам так же свои повязи сделал ) Можно и три TSOPa поставить - 36,48,56 КГц. Можно даже три выстрела подряд на разных частотах передать. Тогда вообще таг будет "из коробки" совместим с любой несущей. Так что проблема аппаратной совместимости несколько преувеличена, ИМХО. hexFF писал(а): извиняюсь, а что за плату брали? Я ничего не брал! Это Jumpy выслал для тестов - спасибо ему огромное! Безумно рад, что проектом интересуются и принимают непосредственное участие и содействие в его развитии! |
Автор: | Pingvin [ 11 апр 2013, 08:30 ] |
Заголовок сообщения: | Re: LTAscetik |
Незадача! Распознавание принятых пакетов стало хуже... Начал свой собственный отраженный сигнал ловить и фиксировать поражение (ИД левые). Попробую с "толерантность" поиграть или опять вернуть прием в прерывание 56 КГц. |
Автор: | hexFF [ 11 апр 2013, 08:49 ] |
Заголовок сообщения: | Re: LTAscetik |
Pingvin писал(а): Можно и три TSOPa поставить - 36,48,56 КГц. думаю избыточно, 36 + 56 вполне. объединить выводы питания +Vcc и выходы, а -Gnd в одну группу 36- килогерцовые, в другую 56-ти. Выбирать просто подав питание на нужную группу. Pingvin писал(а): Собственно - Вам уже ответили да, теперь думаю повязку с 8-ю TSOP-ами делать, вместо 4-х. оффтоп- Смоленские HSL-щики на форуме есть? Pingvin писал(а): Незадача! Распознавание принятых пакетов стало хуже... Начал свой собственный отраженный сигнал ловить и фиксировать поражение (ИД левые). Попробую с "толерантность" поиграть или опять вернуть прием в прерывание 56 КГц. плохо... как алгоритм приема реализован, в двух словах? |
Автор: | Pingvin [ 11 апр 2013, 09:29 ] | ||
Заголовок сообщения: | Re: LTAscetik | ||
Видимо - 8000 Гц слишком низкое разрешение, чтобы отличить ошибку. Вернул прием обратно (в передающий обработчик). Теперь свои отраженные пакеты не принимает, а фиксирует ошибку. Вроде все четко. Замучил вас уже, но похоже - это действительно то, что надо (рабочий вариант) P.S. Знаю, где косяк может быть. В прошивке нет проверки количества принятых бит. Поэтому, даже если принят и распознан только СТАРТ-БИТ, а потом таймаут (нет приема в течение 8*ДлительностьПаузыМеждуБитами) то генерируется событие "пакет принят", а тем временем в приемном буфере может лежать чёрте чего!!! Будем работать! P.P.S. Допавил проверку количества принятых байт, на всякий случай. Цитата: if((start_bit_received)&&(high_level_counter > IR_ZERO*8))
{//Фиксируем окончание приема по таймауту start_bit_received = false; //отменяем прием if (bit_in_rx_buff>=13) rx_event = RX_COMPLETE; //Генерим событие "принят пакет" else rx_event = RX_ERROR; //генерируем событие - "ошибка приёма" receiver_on = false;//выключаем приемник if (ir_transmitter_on==false) TIMSK &=~_BV(OCIE2); //если передача не ведётся - выключаем прерывания }
|
Автор: | tommy [ 11 апр 2013, 11:52 ] |
Заголовок сообщения: | Re: LTAscetik |
Pingvin писал(а): Видимо - 8000 Гц слишком низкое разрешение, чтобы отличить ошибку. а почему вам так инт0 прерывание не нравится? нет ведь такой необходимости в прерываниях логику опроса датчика ставить, ещё и наверняка доступ к половине переменных из-за этой хрени компилятором не оптимизируется. вынести выстрел на шим, вход с датчиков на изменение инт0. ну и убрать многочисленные while юарта и i2c в прерывания.Вернул прием обратно (в передающий обработчик). hexFF писал(а): оффтоп- Смоленские HSL-щики на форуме есть? а это кто такие?
|
Автор: | Pingvin [ 11 апр 2013, 11:56 ] |
Заголовок сообщения: | Re: LTAscetik |
tommy писал(а): Pingvin писал(а): Видимо - 8000 Гц слишком низкое разрешение, чтобы отличить ошибку. а почему вам так инт0 прерывание не нравится? нет ведь такой необходимости в прерываниях логику опроса датчика ставить, ещё и наверняка доступ к половине переменных из-за этой хрени компилятором не оптимизируется. вынести выстрел на шим, вход с датчиков на изменение инт0. ну и убрать многочисленные while юарта и i2c в прерывания.Вернул прием обратно (в передающий обработчик). hexFF писал(а): оффтоп- Смоленские HSL-щики на форуме есть? а это кто такие?Так int0 работает, в таймере только длительнось низкоуровневого и высокоуровневого импульсов считаем. Про какие while при работе с UART и i2c Вы говорите? |
Автор: | kindats [ 11 апр 2013, 11:58 ] |
Заголовок сообщения: | Re: LTAscetik |
hexFF писал(а): оффтоп- Смоленские HSL-щики на форуме есть? Есть ли те, кто интегрировал Смоленскую электронику? Есть. Пример viewtopic.php?f=14&t=1951. Интеграция моя, подготовка макета - Gaspar, Zloy_man и я. |
Автор: | hexFF [ 11 апр 2013, 15:25 ] |
Заголовок сообщения: | Re: LTAscetik |
hexFF писал(а): оффтоп- Смоленские HSL-щики на форуме есть? ребята из Смоленска кто делал винтовку сам с платой HSL или LTAscetic |
Автор: | Pingvin [ 11 апр 2013, 15:33 ] |
Заголовок сообщения: | Re: LTAscetik |
Груз прибыл (смоленская плата)! Спасибо Jumpy! Распечатал, посмотрел. Приятный наборчик. Пошел искать руководство по сборке ... |
Страница 256 из 532 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |