Игрушечный осциллограф на Arduino Uno - 200 ksamp/sec

Тема в разделе "Глядите, что я сделал", создана пользователем Андрей Хохлов, 3 апр 2016.

  1. Не все еще готово, но похоже, что делать 200 тыс. выборок в секунду возможно.

    https://sourceforge.net/projects/inoscope

    На картинке колебания в LC-контуре 1 мГн / 47 нФ + 560 Ом нагрузка:
    [​IMG]
    Можно увидеть, что на одном 20us делении происходит четыре отсчета.

    P.S. Как хранить картинку прямо здесь не понял.
     
    Последнее редактирование: 12 апр 2016
  2. Okmor

    Okmor Нерд

    Вы хоть что то выложите, а то кроме картинки ничего нет.
     
  3. На данный момент код для avr (arduino) ~1000 строк, для ПК (java) ~700 строк. По хорошему все это надо аккуратно переписать. И исключить немногочисленные вызовы библиотечных функций Arduino.

    По существу:

    Прерывания используются только для запуска АЦП (используется запуск по совпадению TIMER1/B, но без разрешенного прерывания он почему-то не происходит) и работы с клавиатурой, Выборка - в основном цикле. В нем же передача данных на ПК. Прерывания от TIMER0 запрещены - если этого не делать, картинка немного дергается.

    АЦП работает далеко за декларируемым пределом быстродействия - ADC Clock freq. 4 МГц при допустимой 1 МГц. При 8 МГц АЦП неработоспособен.

    Аналоговая часть - два или один (переключается) инвертирующий усилитель с закрытым входом на транзисторе BC547B с обратной связью и нагрузкой в виде источника тока (два транзистора BC557B), питание от +5В.

    Возможно стоит попробовать операционный усилитель вроде AD8041 или MCP601/602.
     
    Последнее редактирование: 5 апр 2016
  4. ostrov

    ostrov Гуру

    Не понятно что это вообще? Как работает, как выглядит? Какой софт на ПК?
     
  5. ostrov

    ostrov Гуру

    Круто, интересно, необычно. Но хотелось бы побольше инфо. А еще попробуйте сделать логический анализатор хотя бы канала на 4.
     
  6. Okmor

    Okmor Нерд

    Можете конкретизировать как вы запукаете АЦП. Я пробовал АЦП в режиме автоматического перезапуска и больше 300 000 выборок не получилось. При делителе 1/2 уже не работает, тоесть работает как 1/4 :-(.
    Как вы смогли достигнуть 8 000 000 выборок на АЦП?!! У вас на плате Atmega328 или Atmega8?
     
  7. Информация будет [https://sourceforge.net/projects/inoscope], но мне нужно некоторое время.

    2 ostrov В плате ничего особенного нет и не факт, что ее следует повторять. На попробовать достаточно усилителя на одном транзисторе, обеспечивающего в покое 2.5 вольта на выходе. Ну и кнопок с диодами конечно. Возможно, стоит смотреть в сторону rail-to-rail операционных усилителей, о существовании которых я до недавнего времени не догадывался. Но никакого опыта их использования у меня нет.

    2 Okmor Я нигде не писал о 8 млн. выборок. Если я правильно понимаю datasheet время преобразования 2 + 13.5 периодов ADC Clock freq. При 4 МГц это 3.875 мкс. 300 000 уже не получается. Насчет 1/2 сильно сомневаюсь. Пробовал на двух контроллерах - результат либо 0 либо 255, т.е. чушь.

    Запуск АЦП автоматический:
    Код (C++):

      ADCSRA |=  (1 << ADATE);

      ADCSRB  = ((1 << ADTS2) | // Sets Auto Trigger source - Timer/Counter1 Compare Match B
                 (0 << ADTS1) |
                 (1 << ADTS0));
     
    Плюс к этому нужно пустое прерывание (только iret):
    Код (C++):

    EMPTY_INTERRUPT(TIMER1_COMPB_vect)
     
    Его нужно разрешить:
    Код (C++):

      TIMSK1 |= (1 << OCIE1B);
     
     
  8. Okmor

    Okmor Нерд

    У меня больше

    uint8_t MyBuff[255];
    ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | (0 << ADIF) | (1 << ADIE) | (0 << ADPS2) | (1 << ADPS1) | (0 << ADPS0);
    ADMUX = (0 << REFS1) | (0 << REFS0) | (1 << ADLAR) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (0 << MUX0) ;

    ISR(ADC_vect)
    {
    MyBuff[N++] = ADCH;
    }
    Использовано arduinoNano 16мГц
    Безымянный.jpg
     
  9. Okmor

    Okmor Нерд

  10. ADC_vect я тоже использовал, 100 ksamp/sec получить удалось сразу, а вот 200 - не удалось. Может быть, если писать на ассемблере это и возможно, но gcc вставляет в обработчик больше десятка push/pop - одно это требует микросекунду с четвертью. (В обработчике надо ведь не только записывать данные в массив, но еще и определять момент запуска).

    Надо с ARM'ом разбираться...
     
    Последнее редактирование: 5 апр 2016
  11. Okmor

    Okmor Нерд

    Для получения 320 ksamp/sec в прерывании должно быть только
    Код (C++):
    ISR(ADC_vect)
    {
    MyBuff[N++] = ADCH;
    }
    Даже простое if.. then и for приводит к увеличению времени выборки на 1/3.
    N у нас типа byte и при переполнении переходит на 0.
    Здесь я использовал ефект переполнения переменной, что позволило достичь высокого быстродействия.
    Синхронизацию делаю потом программным путем.
     
  12. Посмотрите на дизассемблированный код.

    И не понимаю я как получается 320 ksamp/sec. 4 МГц / 15.5 = 258 064.5
     
  13. Okmor

    Okmor Нерд

    16 000 000 /4 /13,5=296296 (при автозапуске будет 13,5)
    Откуда 320 000 ? А хрен его знает. Возможно кварц не точный.
    Опыт можете повторить сами. Ссылка выше по тексту. Там и скетч и программа.
     
  14. Возможно, кварц 20МГц: 20 000 000 / 4 / 15.5 = 322 580.6 (15.5 = 2(Sample & Hold) + 13.5(Conversion))
     
  15. Как говорится as is: [https://sourceforge.net/projects/inoscope]. Можно либо загрузить код из svn, либо скачать snapshot.

    В принципе можно не собирать никакой схемы, на третьем пине тестовый сигнал 3906 Гц, скорость развертки 100 мкс/дел.

    Компиляция:
    Код (Text):
    javac -cp .:../../lib/RXTXcomm-2.2pre2.jar net/sf/inoscope/InoScope.java
    Запуск:
    Код (C++):
    java -cp .:../../lib/RXTXcomm-2.2pre2.jar net.sf.inoscope.InoScope
    Предполагается, что текущий каталог - java.

    В Windows разделитель classpath - точка с запятой (-cp.;...). Для работы нужна библиотека librxtxSerial.so/rxtxSerial.dll.

    java нужна 1.7, 1.6 тоже может использоваться, но придется немного изменить программу.

    Возможно, придется менять в программе имя порта.

    В Windows проверял только компиляцию и запуск, на данный момент не знаю, что достаточно сделать. На вопросы постараюсь ответить.
     
    Последнее редактирование: 6 апр 2016
  16. Okmor

    Okmor Нерд

    Не думаю, что на столько.
    Возможно я фигово считаю, или генератор не точный (аудиовыход ПК).
    Если кто то проверит с нормальным генератором, буду очень благодарен.
     
  17. Аудиовыход не должен быть неточным. Изменение частоты на несколько процентов заметно на слух.
    Если только ошибка в программе генератора.
     
  18. Попробовал в Windows. Пока не сделано нормально нужно в программе закомментировать строку
    Код (C++):
    System.setProperty("gnu.io.rxtx.SerialPorts", "/dev/ttyACM0");
    и заменить элемент массива PORT_NAMES "COM3" на назначенное имя порта (у меня он "COM7"). На P4/1600 скорость рисования совершенно недостаточна (тестовый сигнал - до 63 мсек, реальный может быть много хуже), с этим тоже надо что-то делать, как вариант - пропускать кадры и/или снизить скорость передачи и кадры будет пропускать сама Arduino.
     
    Последнее редактирование: 8 апр 2016
  19. Изменил программу для STM32 (Nucleo F411/100МГц) - 2 млн выборок в секунду, 8 бит. По крайней мере для звуковых частот все выглядит намного лучше. Но помехи от Nucleo заметно больше, чем от Arduino.