Страница 1 из 6 123456 ПоследняяПоследняя
Показано с 1 по 10 из 51
  1. #1
    Пользователь
    Регистрация
    25.01.2011
    Сообщений
    24
    Вес репутации
    167

    По умолчанию Помогите. Не могу понять тянет ли ардуино проект.

    Добрый день.

    Я тут решил нагрузить Arduino Nano v5 практической задачей и не могу понять - то ли я делаю что-то не так, то ли ардуино просто не справляется с задачей физически.

    Что мы имеем? Имеем сигнал, показанный на картинке желтым цветом. Его амплитуда +20В - -20В. Сигнал преобразовывается оптроном и получается то, что показано голубым цветом. Амплитуда полученного сигнала +5В.

    Вот этот сигнал я хочу считать с помощью ардуино и понять, что же именно закодировано. Кодирование 0 и 1 происходит длительностью импульса - на картинке видно.

    И вот тут-то у меня затык. Как не бьюсь - ничего не выходит.

    Алгоритм вроде бы простой:
    1) контролируем состояние ноги - ноль там или единица
    2) как только на ноге появился ноль, засекаем системное время
    3) ждем, пока появится единица, второй раз засекаем время
    4) ждем, пока появится ноль, третья засечка времени.

    Потом определяем продолжительность нуля и продолжительность единицы. В теории, время должно приблизительно совпасть. И по значению определяем - ноль это был, или единица.

    Так вот - НИФИГА НЕ ВЫХОДИТ. Замеренные значения интервалов пляшут как им угодно. Совершенно хаотично и без системы. Как бы я ни извращался - ни в лоб, ни через прерывания. Если нужен программный код - скажите, напишу. И значения могу тоже дать.....

    Что я делаю не так? В чем проблема? У меня в руках, или просто ардуино не успевает обработать сигнал и поэтому выдает ошметки того, что успело "ухватить"?

    Заранее спасибо.
    Миниатюры Миниатюры Нажмите на изображение для увеличения. 

Название:	NewFile0.jpg 
Просмотров:	1131 
Размер:	38.0 Кб 
ID:	10925  

  2. #2
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,376
    Вес репутации
    10

    По умолчанию Re: Помогите. Не могу понять тянет ли ардуино проект.

    Сигнал имеет очень короткую длительность меньше 100мкс.
    Нужно во первых принимать сигнал выводом D2 или D3 , настроить один нужный из этих входов на прерывание по перепаду сигнала .
    В обработчике прерывания написать код с минимумом инструкций желательно на ассемблере.
    Вот пример работы на ассемблере:
    PHP код:
    //http://compcar.ru 
    #include <avr/pgmspace.h>
    #include <Spi.h>
    //-----------------------------------------------------------------------------------------------------------------------------------------
     //                        ' '  A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z  */
    const byte ltrs[189PROGMEM = {255,231,131,195,135,129,129,195,189,131,129,189,191,125,125,195,131,195,131,195,131,189,189,125,125,125,  1,
                   
    255,219,189,189,187,191,191,189,189,239,247,187,1915761,189,189,189,189,189,239,189,189,125,187,187,251,
                   
    255,189,189,191,189,191,191,191,189,239,247,183,1918593,189,189,189,189,191,239,189,189,109,215,215,247,
                   
    255,189,131,191,189,131,131,177,129,239,247,143,191,109,109,189,131,189,131,195,239,189,219,109,239,239,239,
                   
    255,129,189,191,189,191,191,189,189,239,247,183,191,125,117,189,191,179,183,253,239,189,219,109,215,239,223,
                   
    255,189,189,189,187,191,191,189,189,239,183,187,129,125,121,189,191,185,187,189,239,189,219,147,187,239,191,
                   
    255,189,131,195,135,129,191,195,189,131,207,189,129,125,125,195,191,205,189,195,239,195,231,147,125,239,  1    };
    //------------------------------------------------------------------------------------------------------------------------------------------
    /*                 -   .   /   0   1   2   3   4   5   6   7   8   9   :  */
    byte nums[98]=             {255,255,207,131,239,131,131,227,  1,131,  1,131,131,255,
                    
    255,255,187,125,207,125,125,219,127,127,253,125,125,239,
                    
    255,255,187,125,239,253,253,187,127,127,251,125,125,255,
                    
    131,255,207,125,239,243,227,123,131,  3,247,131,129,255,
                    
    255,255,255,125,239,207,253,  1,253,125,239,125,251,255,
                    
    255,231,255,125,239,191,125,251,125,125,239,125,247,239,
                    
    255,231,255,131,199,  1,131,251,131,131,239,131,207,255};

    byte i=0
    byte reg 8;   
    byte result 25;
    word *ptr=0
    word addr ;

    //----------------------------------------------------------------
    void setup()  

    //ptr = &ltrs[0]; // младший байт адреса
    //addr = ltrs[*ptr]; // полный 16 бит адрес
    //addr = &ltrs[0]; // полный 16 бит адрес
    //word paddr = ltrs[0];

    pinMode(8INPUT); // portb0
    pinMode(9INPUT); // portb1
    Spi.mode((1<<MSTR) | (1<<CPHA));  //mode 0, clock/4, SPI Enable, DORD старший первый, MSTR Master Enable
    Serial.begin(115200);  

    //----------------------------------------------------------------
    void loop()  
    {  

    //i=i+1;
    //Spi.transfer(ltrs[i]);

    addr ltrs[*ptr];
    //addr = *ltrs;
    //result=checkline(addr);

    Serial.println( *ptrDEC );
    Serial.printlnaddrDEC );
    Serial.println( *ltrsDEC );
    //Serial.println( result, DEC );
    Serial.println(' ');
    delay(500);
    }
    //--------------------------------------------------------------
    byte checklineunsigned char in_char )
    {
    asm volatile
                  
    "cli       \n" // отключить прерывания
                  
    "push r26   \n"
                  
    //  "mov r30, %A[ADDR16]       \n"   // загрузить младший 16 бит адрес
                  //  "mov r31, %B[ADDR16]        \n"   //
                   
    "label_1%=:  \n"
                  "sbic %[PIN_B], 1   \n"  
    // ловим  кадровый импульс
    "rjmp label_1%=  \n" 

    "label_1e%=:  \n"
                  "sbis %[PIN_B], 1   \n"  
    // ждем начала кадра
    "rjmp label_1e%=  \n" 

    "rcall Wait_Line%=  \n"              
    // отступ с верху (переднее гашение)

    "label_2%=:  \n"
                  "sbic %[PIN_B], 0   \n"  
    // ловим строчный импульс
    "rjmp label_2%=  \n"

    "label_2e%=:  \n"
                  "sbis %[PIN_B], 0   \n"  
    // ждем начала строки
    "rjmp label_2e%=  \n"

    "rcall Step_Line%=  \n"            
    //отступаем  слева xx пикселей

    //--------------------выводим изображение------------------------------------ 
     
    "Transmit%=:  \n"               
                    "ld  r26, %a[ADDR]+       \n"   
    // загрузка данных из памяти программ с постинкрементом 
                   // "ldi  r26, 170                \n"
                     
    "out %[SPI_DATA], r26  \n"
                     "sbic %[PIN_B], 0             \n"    
    // ловим  строчный импульс  
    "rjmp Transmit%=  \n"                                 // переходим на вывод следующего байта
                  
    "sbic %[PIN_B], 1               \n"        // ловим  кадровый импульс
    "rjmp label_2e%=  \n"                                 // продолжаем вывод данных если не конец кадра

    "rjmp label_1e%=  \n"    // переходим на навый кадр

    "mov %[RESULT], r30  \n" // возвращаем адрес в переменную result
    "pop r26  \n"
    "sei  \n"        
    // включить прерывания 
    "rjmp data%=  \n" // на выход
    //-------------------------------------------------
    "Data_seg%=:  \n"
    //-----------------------подпрограмма отступа сверху--------------------------
    "Wait_Line%=:  \n"
                    "ldi r26, 30  \n"    
    // чило пропускаемых строк , отступ сверху
                    
    "label_str%=:  \n"
                  "sbic %[PIN_B], 0   \n"  
    // ловим строчный импульс
    "rjmp label_str%=  \n"

    "label_new%=:  \n"
                  "sbis %[PIN_B], 0   \n"  
    // ждем начала строки
    "rjmp label_new%=  \n"

    "dec r26 \n"
    "brne label_str%=  \n"              
    // считаем строки

    "ret  \n"
    //-----------------------подпрограмма отступа слева--------------------------
    "Step_Line%=:  \n"
             "ldi r26, 35  \n"    
    // чило пропускаемых пикселей в начале строки , отступ слева
     
    "label_step%=:  \n"                 
    "dec r26 \n"
    "brne label_step%=  \n"              
    // считаем пропуски
    "ret  \n"
    //---------------------------------------------------------------------------
    "data%=: \n" 
    //".EQU 200 \n"
    //".db    12, 34, 45, 23 \n"
    // "sbi ADCSR, 6 \n" //включить бит преобразования
    // "sbi r38, 6 \n" //включить бит преобразования
    //"mov %0, r4  \n"  // прочитать из младшего регистра АЦП ADCL
    //"ret  \n"
    //---------------------------------------------------------------------------                     
                
    : [RESULT]  "=&r" (result)               // Список выходных операндов
                
    : [PORT_B]    "I" (_SFR_IO_ADDR(PORTB)), 
                  [
    SPI_DATA]  "I" (_SFR_IO_ADDR(SPDR)), 
                  [
    PIN_B]     "I" (_SFR_IO_ADDR(PINB)), 
                  [
    SPI_STAT]  "I" (_SFR_IO_ADDR(SPSR)), 
              
    //    [REG_IN] "r" (in_char),
                  
    [ADDR"e" (ltrs),              
                 
    // [ADDR] "m" (ltrs[*ptr]),
                  
    [ADDR16"e" (addr)
       
                :  
    "memory""r30""r31" ); //       //резервируем регистры   
    return (result);
     } 

  3. #3
    Пользователь
    Регистрация
    25.01.2011
    Сообщений
    24
    Вес репутации
    167

    По умолчанию Re: Помогите. Не могу понять тянет ли ардуино проект.

    Цитата Сообщение от Chip Посмотреть сообщение
    Сигнал имеет очень короткую длительность меньше 100мкс.
    Нужно во первых принимать сигнал выводом D2 или D3 , настроить один нужный из этих входов на прерывание по перепаду сигнала .
    В обработчике прерывания написать код с минимумом инструкций желательно на ассемблере.
    Спасибо.

    А вообще, потянет ли ардуино это или нет? Мне же помимо того, что принять данные, надо их обработать, да и еще кое-какие действия сделать.

    Если уж простой сигнал она не в состоянии принять без ассемблерных подпорок....

    Я же делал через прерывания - там кода полстроки:

    void setup() {
    pinMode(2, INPUT);
    attachInterrupt(1, blink, FALLING);
    Serial.begin(38400);
    }

    void loop() { }

    void blink(){
    time2 = micros(); time3=time2-time1;
    Serial.print(" time="); Serial.println(time3);
    time1=time2;
    }

    Может сменить платформу и не мучиться? Хотя уж больно приятно с ардуино работать...

  4. #4
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,376
    Вес репутации
    10

    По умолчанию Re: Помогите. Не могу понять тянет ли ардуино проект.

    Не могу ничего сказать нужно хотябы понимать что за задача.
    Serial.print убери из обработки прерывания, данная функция будет вносить большие задержки

  5. #5
    Пользователь
    Регистрация
    25.01.2011
    Сообщений
    24
    Вес репутации
    167

    По умолчанию Re: Помогите. Не могу понять тянет ли ардуино проект.

    Цитата Сообщение от Chip Посмотреть сообщение
    Не могу ничего сказать нужно хотябы понимать что за задача.
    Serial.print убери из обработки прерывания, данная функция будет вносить большие задержки
    Задача читать сигнал DCC с рельс на жд-макете. Построение стрелочного (аксессуарного) декодера. DCC сигнал (пример) есть на осциллограмме.

    Если я уберу из прерывания печать в основную программу, то проц может 10 раз проколбасить прерывания и только один раз вывести мне что-то на печать.

  6. #6
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,376
    Вес репутации
    10

    По умолчанию Re: Помогите. Не могу понять тянет ли ардуино проект.

    Так ты в массив считывай , а потом отправляй данные из массива функцией Serial.write(buf, len) ; иначе ничего не получится.
    Скорость порта измени Serial.begin(115200); побыстрей будет
    У DCC сигнала есть разрыв или он без остановки шлет данные?
    Последний раз редактировалось Chip; 26.01.2011 в 02:01.

  7. #7
    Модератор
    Регистрация
    06.07.2008
    Возраст
    45
    Сообщений
    414
    Вес репутации
    435

    По умолчанию Re: Помогите. Не могу понять тянет ли ардуино проект.

    Согласен с Chip.
    1. Убрать запись в uart сразу после измерения. Это очень длительная операция и выполнять ее надо в фоне.
    2. Прикинуть длительность записи в uart нужных данных. Если длительность около 100мкс, то ни о каком тексте в uart речь вообще идти не может, ибо это 10000 записей в секунду.
    3. 100 мкс - это до фига с точки зрения простой обработки, это порядка 1600 тактов, в такое время можно слона печеного уместить и без ассемблера.

    Нужна информация о минимальной, максимальной длительности и о необходимой точности измерения длительности. От этого и придется плясать.

    Можно, к примеру, сделать таймер, который будет опрашиваться каждые n микросекунд. И в нем будет анализироваться состояние ноги и если оно не изменилось - увеличивать счетчик, а если изменилось - переписывать счетчик куда-либо и очищать его.

  8. #8
    Модератор
    Регистрация
    06.07.2008
    Возраст
    45
    Сообщений
    414
    Вес репутации
    435

    По умолчанию Re: Помогите. Не могу понять тянет ли ардуино проект.

    я когда делал анализ посылки сигнализации, делал подобную феню. Сделал там очень просто - пока идет нужный импульс - считаю до 255. Досчитал, отправил 255, обнулил счетчик и считаю дальше. Импульс кончился - послал сколько было. Если 255, то послал 255 и 0.

    Все. Никаких более прерываний. Ибо в AVR по умолчанию пока программа находится в прерывании, другие прерывания вызваться не могут.

  9. #9
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,376
    Вес репутации
    10

    По умолчанию Re: Помогите. Не могу понять тянет ли ардуино проект.

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

  10. #10
    Пользователь
    Регистрация
    25.01.2011
    Сообщений
    24
    Вес репутации
    167

    По умолчанию Re: Помогите. Не могу понять тянет ли ардуино проект.

    Вот выписка из стандарта по DCC:

    А: Принципы кодирования битов
    Основной сигнал цифрового управления согласно NMRA состоит из потока переходов между двумя уровнями напряжения, которые имеют противоположную полярность (Существенный момент заключается именно в переходах между уровнями напряжения, т.к. с точки зрения декодера, подключенного к ДСС шине невозможно определить полярность присутствующего на конкретный момент напряжения, потому что локомотив с декодером может быть, например установлен на рельсы как в прямом, так и в обратном направлениях). Переходом с одного уровня на другой определяется раздел между двумя битами, последующим за ним переходом в первоначальное состояние бит делится на две части – первую и вторую. Цифровая командная станция должна кодировать биты путем подачи на выход потока из изменения уровней, причем в зависимости от значения бита временной интервал между изменениями уровней должен изменяться, или другими словами должна изменяться частота изменений уровней.



    Для передачи бита «1» первая и вторая части бита должны иметь одинаковые длительности, которые номинально должны быть равны 58мкс (все временные измерения производятся на уровне перехода через ноль). Т.о. общая длительность «1» бита составляет 116мкс. Компоненты цифровой командной станции должны передавать «1» бит с длительностями первой и второй частей в пределах от 55 до 61мкс. Декодер должен корректно распознавать «1» бит если длительность между переходами составляет от 52 до 64мкс.



    Для передачи «0» бита длительность первой и второй частей бита между переходами должна номинально быть больше или равна 100мкс. Для сохранения постоянной составляющей всего ДСС сигнала на уровне 0В обе части «0» бита должны быть идентичны по длительности между переходами. Компоненты цифровой командной станции должны передавать «0» биты с длительностью каждой их части от 95 до 9900мкс, с общей длительностью «0» бита не превышающей 12000мкс. Цифровой декодер должен корректно распознавать первую и вторую части «0» бита, если их длительности находятся в интервале времен от 90 до 10000мкс. Рис. 1 демонстрирует наглядно принцип кодирования битов.



    Цифровой декодер должен достоверно распознавать «1» бит, если длительности его первой и второй частей отличаются не более чем на 6мкс.

Страница 1 из 6 123456 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •