• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

высокоскоростной ввод аналоговых данных

nikolz

Well-known member
Помещаю две библиотеки -
Phy_OS для RTOS SDK;
Phy_No_os для non-RTOS SDK ,
предоставленные мне китайскими товарищами на мой запрос о возможности высокоскоростного ввода.
------------------------
void phy_adc_read_fast(uint16 *adc_addr, uint16 adc_num, uint8 adc_clk_div)
uint16 *adc_addr: ADC sample output address
uint16 adc_num: ADC sample count, range [1, 65535]。
uint8 adc_clk_div: ADC sample collection clock=80M/adc_clk_div, range[2, 32]。
  • Example(Continue to collect 100 ADC samples):
uint16 adc_out[100];
phy_adc_read_fast(&adc_out[0], 100, 8);
---------------
Выкладываю как есть.
 

Вложения

Последнее редактирование:

pvvx

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

pvvx

Активный участник сообщества
К сожалению вот это: uint8 adc_clk_div: ADC sample collection clock=80M/adc_clk_div, range[2, 32] у меня не работает как написано.
Исправьте.
 

pvvx

Активный участник сообщества
Я исправить не могу, так как получил это в том виде в каком выложил.
Попробую сам, потом напишу ошибки китайским товарищам.[/QUOTE]
Вы говорили что вы профессор...
Нам бы побыстрее. Постарайтесь. Заранее спасибо.
 

pvvx

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

pvvx

Активный участник сообщества
Я ничего не принимал.
Всего попросил исправить, а вы зажидились. :(
Объявили себя ученым, а исправить не можете и оказалось, что только копировать - копи-пастить умеете...
Сейчас приступаю к сборке спектрометра и отладки программы.
Сейчас уже давно кончилось. Ныне уже 2-ое суток с сейчас. Уже сеть готовые и проверенные данные с ADC?
Такой долгострой всегда у людей с ученой степенью (не проверив работу ADC начинают строить проект)?
 
Последнее редактирование:

A_D

Active member
-------------------
«Дядя Петя, ты дурак»
Великолепный аргумент!! Тем более от лектора с 20 летним стажем. Браво.

Почитывал эту Санта Барбару....в целом же я не понимаю Вас, чего вы добиваетесь - больше всего на тролля теперь похожи, не очень хорошего притом, хотя начало было нормальным и ничего такого не предвещало, вроде как...

А если Вам отвечают с резкими комментариями и Вас это задело - возможно дело таки в Вас. Я редко, но спрашивал порой у pvvx что либо, да иногда посмеётся, но зачастую поможет, бывало и вообще не ответит на детские вопросы, что и правильно - я потом сам в них успешно разбираюсь, а в ответ я всего то просто Благодарю человека за его не малые труды. Все просто.
 

Alex

Member
ТС напоминает мне одного типа с kazus.ru с ником "selevo". Может это один и тоже человек. Там его уже забанили.
pvvx по идее надо забить на этого "профессора". Игнорировать просто. Чего на троля нервы и время тратить.
 

pvvx

Активный участник сообщества
Например, Вы согласны с тем, что человек считает Вас попрошайкой,
Нет. Я считаю именно nikolz попрошайкой.
Ему на вопрос ответишь, а он не слышит и опять тут-же задает тот-же вопрос, требуя наиподробнейшее объяснение и только на его условиях. Вот это и есть попрошайничество.
унижает Вас т к смеется он обычно унижая собеседника.
Извините, но невозможно унизить желающего разбираться самому. Это как невозможно научить. Можно только учиться! Т.е. самому. И если дают ответ с заковыркой, то это обычно означает, что вопрос поставлен неверно или на общие темы...
Умный -поймет, глупый - обидится.
Вот я и здесь - разбираю по вашему прошению ADC, но используя ваши манеры "с ученой степенью". Но не вижу вашего участия. Вы наверно глупы и обиделись? :)
Может мне захотелось сделать эксперимент - всем плясать по методу nikolz :) Хочу узнать результаты и продуктивность такой методики. Всё познается в сравнении. :p

И о китай-либе с ADC - в описании к функции (phy_adc_read_fast) вы дали ошибки (впрочем это стандартно у nikolz - притащить что-то нерабочее и попрошайничать чтобы исправили) ... Функция выдает ужасные данные, если её как-то запустить... Джиттер, разрывы в приеме, скорости никакой... Без правок не годится. Впрочем она уже давно переведена в СИ, всё что надо выдрано, переделано и лежит в "свалке", пока вы тут поёте о "ученой степени".:(
 

A_D

Active member
Вы совершенно правы, дело именно в Вас ( Нас)
Например, Вы согласны с тем, что человек считает Вас попрошайкой,
Не перевирайте Мои слова, то что Вы написали - это Ваши домыслы. Я вполне нормально общаюсь с человеком без задних мыслей и додумок (как это прекрасно видно на Вашем примере).

унижает Вас т к смеется он обычно унижая собеседника.
это вполне нормально, если задаются бредовые вопросы или человек не слишком разбирается в чем то, а лезет куда глаза глядят. А если вопросы вполне здравые и ответы воспринимаются нормально - то и не возникает каких либо подобных ситуаций. (как в Вашем случае)
Да, тут не могу не согласится, что у pvvx конечно чсв завышено, но т.к. он один разбирается во многом больше чем команда разработчиков чипа в плане SDK - то я сичтаю это вполне нормальным и допустимым.

Вопрос не в том, какое у человека образование, а в том как он относится к другим.
В интернете много таких умников-хамов.
Сначала пытаешься говорить с ними корректно, но им же важно самоутверждение.
В результате приходится просвещать цитатами из классики.
Все дело в НАС (ВАС).
т.е. сначала Вы упирали на то, что Вы такой умный и образованный, а Вашему собеседнику этого не хватает - мол это вот сразу видно, а теперь сьехали с этой темы, упирая на то, что воооот Вам нахамили и плак плак плак.... а за Ваш проект теперь и не слова - только обсуждение "хамства".
 

pvvx

Активный участник сообщества
А можете писать лишь технические моменты, без Ваших оценок людей?
У меня тоже не будет повода разбирать Ваши высказывания.
И будет просто технический форум.
Как Вам такое предложение?
Извините, но правила задали вы. :p
Теперь - "мы подумаем"...
-------------------
"Нет, не возьму. - Но почему вы отказываетесь? - Не хочу. - Вы не сочувствуете детям Германии?- Сочувствую. - А, полтинника жалко? - Нет. - Так почему же? - Не хочу…"
-------------------
Время исполнения в мкс 10 000 опросов старта с ожиданием готовности ADC, без считывания данных из регистров. Замер чисто для определения времени отработки старт-готово работы ADC, но с кратностью цикла частоте CPU (180 MHz) и периферийной шины. Замер сделан без SDK, весь код грузилсяв IRAM, Flash не подключалась.
SAR_T135.gif

Цикл опроса из теста:

Код:
uint32_t t1, t2;
int i = 10000;
t1 = system_get_time();
while(i--) {
// запуск нового замера SAR
uint32 x = SAR_CFG & (~(1 << 1));
SAR_CFG = x;
SAR_CFG = x | (1 << 1);
// ожидание готовности SAR
while((SAR_CFG >> 24) & 0x07);
}
t2 = system_get_time();
ets_printf(" Wait 10k samples = %u us\n", t2-t1);
Если сможете со своей "ученой степенью" определить формулу частоты опроса - будем думать, на счет вашего поведения... :)
У меня уже сосчитано... а данные в таблице ещё с пятницы... уже забыл где вычисленную формулу записал :) Последний раз был занят приемом в ESP по SDIO c DMA от внешнего MCU и забыл уже всё про ADC. Всё равно он кривой.

PS: Вы где последний раз видели эмбедовский форум без политики и ... ? :confused: Выпали из реальности? :eek:
 
Последнее редактирование:

pvvx

Активный участник сообщества
Со своей ученой степенью могу определить,
но для этого мне надо сначала разобраться в условиях Вашего эксперимента, либо поставить свой.
Для Вас условия очевидны , Так как это ваш эксперимент.
Все данные для вычисления даны. Вопросов быть не должно. Попробуйте повнимательнее вчитаться и исправить ошибку - пробел выпал перед буквой "и" :oops:
Числа из таблицы надо поделить на 10000 и получите время одиночного цикла опроса готовности ADC. У ADC задается частота - делитель от 1 до 23 включительно и кол-во замеров в буфере - от 1 до 8. Соответственно всё разложено в таблице по столбцам и стокам. Это всё описано в прошлом соо.
Могу уточнить только то, что другие варианты делителей и кол-ва обработки в буфер из 8 регистров невозможны по причине технической реализации данного ADC.
Проще прикрутить внешний STM32F103xxxT6 и лить в ESP по SDIO DMA блоками по 512 байт на одно прерывание на дикой скорости...
На это есть привет от ваших друзей - китайцев -> 8H-ESP8266__Interface_SDIO_SPI_Mode__EN_v0.1-2.pdf :)
Там как раз всё как у вас - нет ничего, только общие слова... :) По тому надо попрашайничать заново - это как раз работа для вас - требуется ученая степень по пресмыканию. :p
Конкретно нет кода для STM, но к нему даны описания... Остальное уже есть.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Просьба не писать ответы на мои вопросы,
если я их не адресую Вам лично.Спасибо
Вам это было давно предложено. Но ... теперь задано действовать по вашей методике, иначе вы не понимаете. Скорее всего вам не хватает ученой степени, или она не в том. :)
Во время линейного китай-опроса, в выданным вами их либе, происходят прерывания и цикл опроса у них зависит от результатов замеров...
В моём тесте это всё исключено - нет никаких прерываний и операционок, а принятые данные даже не рассматриваются между опросами...
Попрошайничайте у них сразу как настроить источник в SCL регистрах (DMA) для чтения ADC...
 

nikolz

Well-known member
pvvx,
может быть так быстрее будет:
-----------------------
uint32 x = SAR_CFG & (~(1 << 1));
SAR_CFG = x;
while(i--) {
SAR_CFG = x | 2; // запуск нового замера SAR
while(SAR_CFG &( 0x07<<24)); // ожидание готовности SAR
}
 

pvvx

Активный участник сообщества
-----------------------------------------
1) Из таблицы следует, что время готовности 10 000 отсчетов при 1/1 равно 83750.
Верно?
Да, при описанном алгоритме запуске и ожидания готовности.
2)Делим на 10000 получаем 8.375 мкс,
что дает максимальную частоту дискретизации 119 кгц.
Верно?
Нет. Туда не входит опрос регистров данных и их обработка. Это ещё замедлит цикл. Ну ещё надо учесть кратность и биение частот опроса с шиной доступа к регистрам ADC в примерно 26МГц...
И таким методом работают только на Arduino, или Lua, или китайцы в своем SDK.
Тогда каким образом у Вас получилась частота дискретизации 192 кГц?
цитата:
"В WDRV сделал скорость ADC от 1Гц до 192кГц:
0..48кГц = 14 бит, далее убывает каждый интервал до 12 бит при 192кГц.:"

----------------------------
Можете объяснить?
Спасибо.
У меня другой алгоритм. Он построен по другому принципу, для минимизации джиттера.
Я не смотрю готовность ADC, т.к. она и так нормирована от времени подачи сигнала старта.
Подав сигнал старта, через фиксированную паузу по таймерному прерыванию считываю готовые данные, без обработки, в буфер. Затем даю новый сигнал старта. А уже потом пересчитываю значения и прочее. По этому первый цикл считывания в буфер и задание нового сигнала старта всегда фиксировано по времени исполнения и ещё стробирован частотой шины доступа к регистрам и с прерыванием от аппаратного таймера. Кол-во регистров данных тоже задано фиксировано и вычислено заранее, чтобы время их накопления ADC вписывалось в паузу между прерываниями таймера.
Прерывание от таймера могут быть и по NMI, если мешают другие процедуры в SDK.
 

pvvx

Активный участник сообщества
может быть так быстрее будет:
-----------------------
uint32 x = SAR_CFG & (~(1 << 1));
SAR_CFG = x;
while(i--) {
SAR_CFG = x | 2; // запуск нового замера SAR
while(SAR_CFG &( 0x07<<24)); // ожидание готовности SAR
}
Нет не будет. У меня не используется сигнал готовности. А ADC запускается по перепаду/смене бита и это влияет на буфер готовых данных... Даже если в моем алго ещё не все данные приняты (задан прием 8-ми значений), а мы считываем и обрабатываем к примеру всего 3 значения из 8-ми, то всё будет хорошо. По новому старту буфер 8 регистров начнет набираться с начала.
В тесте кодов где-то я описал примерную формулу расчета скорости обработки одного замера ADC... Примерную, т.к. она зависит от нескольких переменных (более 4 значений регистров данного ADC точно), включая кол-во наборов готовых данных в регистры буфера и времен коммутаций зарядной цепи (они тоже указываются в регистрах ADC).

Так-же, если вы смотрели, как задается частота работы ADC, то должны были видеть, что задается 6 делителей в двух регистрах по 32 бита. А как влияют эти делители на коррекцию значений ADC у китайцев не описано. По этому я использую фиксированную частоту SAR, для которой коррекция известна, а частота общего опроса определяет кол-во сумм регистров данных -> разрядность готовых данных.

nikolz - если вы будите такими темпами это разгребать, то я уже многое забуду и буду путать, т.к. с данным ADC у меня всё закончено - признан невменяемым и кривым, годящимся только для баловства.

Примерный расчет времен работы ADC к выложенной ранее таблице:
SAR_TAB_BUFX.gif

Добиться не кривых данных с данного SAR при работе других программ не удалось.
Проще поставить какой STM32F1xx. Пример:
STLH-OSC-TEST.gif
Вывод 2-х каналов встроенных в STM32F103T8C6 ADC, но обрезанных до 8-ми бит, да ещё источник осцилки кривой (на резистивной матрице до 8 бит = MHS-5200-25M) - видно его нелинейности и выбросы - китайская дешевка.
Полный проект осцилла 2 канала по 460кГц :) из STM32F1xxx, для заинтересовавшихся :) тут STM32F103T8C6-OSC.zip
 
Последнее редактирование:

nikolz

Well-known member
pvvx,
благодарю за подробный ответ.
------------------
В моей задаче не все так просто, как кажется с первого взгляда.
Дело в том, что, перед тем как ввести значение, мне надо выдать управляющие сигналы.
Т е постановка внешнего АЦП не позволит увеличить скорость ввода по этой причине.
Если взять STM то ситуация не очень изменится.
Скорость ввода 192 кгц и 14 или 12 бит - это уже хорошо.
--------------------------
Единственно, что пока смущает это шумы.
Но в Ваших последних испытаниях они (шумы) существенно меньше.
кроме того, по самой природе обрабатываемого сигнала, мне надо удалять шумы других источников.
Т е получаемые массивы данных будут усредняться, либо фильтроваться (это еще надо исследовать).
Но фильтрация (усреднение) у меня производится не по 8 значениям , а по значительно большему кол-ву (до 1000).
----------------------
Относительно регистров.
Вы опередили мой вопрос относительно логики их загрузки.
Не мог понять как Вы это все разгребли.
-------------------
Возможно, что когда испытаю прибор,
то откажусь от данного решения,
но этот момент еще в будущем.
-------------------------------------
Нам не дано знать будущее ,
но мы можем его придумать.
 

pvvx

Активный участник сообщества
Но в Ваших последних испытаниях они (шумы) существенно меньше.
Угу - с выключенной частью WiFi и всё в IRAM (без всяких SDK), т.е. никаких внешних коммутационных сигналов из чипа на Flash не идет....
Ваша задача решится только на внешнем ADC и проще встроенном, объединенном с MCU.
Если я правильно понял, то Вы проверяете наличие второго значения в буфере данных.
если там не ноль, то начинаете чтение буфера.
Но если это так, то минимальное время преобразования в Вашем алгоритме будет равно 2*(Tsar+Tbuf)
т е удвоенному времени преобразования и записи в буфер.
Что-то попутали. Там смотрится есть ли выделенный буфер в RAM. Если его нет, то и писать данные вообще некуда и не требуется.
Если мы проверяем готовность флага SAR, то минимальное время будет равно Tsar+Tready
время преобразования+время проверки готовности.
По Вашей формуле получается, что время преобразования составляет
y=0.3865*x+0.4734. Для 1 отсчета и x=1 получаем 0.47 мкс. Пусть даже x=5 получим 2.4 мкс
это очень хорошо.
Опять что-то не так считаете. Минимум же выйдет 0.3865+0.4734 = 0.8599. "+ константа" получается от цикла опроса и обработки чипом функции записи SAR отсчетов в регистр данных буфера. У вас она будет больше - вам надо ещё считать данные и обработать их.
Правильно я понял, что если установить X=1, то скорость дискретизации SAR будет 1/0.47=2.1 мгц.
Неа. Будет больше. Это мин. цикл опроса процессором такой. А вот работает ли он на таких частотах (данный китай-SAR) и что показывает я и не собираюсь проверять :) И так всё с него кривое при 8 на 8.
Но если я буду запускать SAR каждые 10 мкс, то получим 100 кгц.Верно?
да
 
Последнее редактирование:

pvvx

Активный участник сообщества
pvvx,
1)Очевидно,я нe понял, что именно Вы проверяете здесь:
if((wdrv_buf_wr_idx >> 31) == 0) { // если второе и последующее прерывание, данные в SAR готовы
------------------------
я так понял, что Вы пропускаете первый вход в прерывание, т е когда ацп еще не запущено.Верно?
Но непонятно зачем сдвиг на 31 разряд содержимого счетчика введенных данных
Потому, что там задается флаг пропуска в wdrv_start():
wdrv_buf_wr_idx = 1<<31; // флаг для пропуска считывания SAR при первом прерывания
Он всё равно сброситься далее:
if(wdrv_buf_wr_idx >= WDRV_OUT_BUF_SIZE) wdrv_buf_wr_idx = 0;
Это всё чтобы не задействовать лишней памяти и времени CPU = "оптимаза" и не по тому как вас учили писать с ученой степенью забивая все ресурсы...
Изучите СИ и как транслирует команды СИ компилятор под ESP8266, тогда будет понятно, почему такими командами и т.д. :(
 
Последнее редактирование:

pvvx

Активный участник сообщества
Могу еще сообщить что у меня 25 изобретений и полсотни научных работ.( это чтобы не только про степень Вы вспоминали, но и другие мои достижения упоминали )
А я всё что сделал уже не помню :p Это просто нереально запомнить. Да и по жизни работаю с людьми у которых тысячи научных работ... так вышло. Так что ваш опыт не показателен.

Я бы сделал иначе.
Не ставил этот if, а просто отбросил первый отсчет в выходном массиве.
В результате время работы колбек уменьшится на этот if
кроме того, я бы просуммировал без устранения нелинейности (а еще лучше поставил бы медианный фильтр), а потом учел нелинейность после ввода всего массива данных.
В результате время колбека уменьшилось на величину времени коррекции отсчетов
А меня не интересует это, т.к. это демонстрация работы с SAR в ESP8266, а не готовый проект. Для готового проекта данный ADC можно использовать только как градусник на 5 бит, не более. Сколько раз это говорить...
Вот у китайцев 2 таймера в SAR.
Можете пояснить как Вы их заполняете в Вашей функции ввода с SAR.
Каких таймера?
Код инициализации SAR приведен в git. Дублирую:
Код:
/* Инициализация SAR */
void ICACHE_FLASH_ATTR sar_init(uint32 clk_div, uint32 win_cnt)
{
    tout_dis_txpwr_track = 1;
    if(win_cnt > 8 || win_cnt == 0) win_cnt = 8;
    wdrv_bufn = win_cnt;
    if(clk_div > 23 || clk_div < 2) clk_div = 8;
    SAR_CFG = (SAR_CFG & 0xFFFF00E3) | ((wdrv_bufn-1) << 2) | (clk_div << 8);
    SAR_TIM1 = (SAR_TIM1 & 0xFF000000) | (clk_div * 5 + ((clk_div - 1) << 16) + ((clk_div - 1) << 8) - 1);
    SAR_TIM2 = (SAR_TIM2 & 0xFF000000) | (clk_div * 11 + ((clk_div * 3 - 1) << 8) + ((clk_div * 10 - 1) << 16) - 1);
    // включить SAR
    rom_i2c_writeReg_Mask(108,2,0,5,5,1);
    SAR_CFG1 |= 1 << 21;
    while((SAR_CFG >> 24) & 0x07); // wait r_state == 0
}
Вот я назвал регистры: SAR_TIM1 и SAR_TIM2. В них 6 по 8 бит счетчиков и число (clk_div * 11) не лезет в 8 бит, при указанных параметрах китайцами делителя до 32, т.к. : 32*11=352. Китайцы считать и писать не умеют. Предел делителя = 23.
Эти таймеры?

Или аппаратные таймеры для прерываний CPU? Они в примере не используются. Подключайте сами, хоть по NMI - всё в проекте есть. А для демки используется софтовый таймер, чтобы не перегружать лишним "свалку web" - у неё другие цели.

Для полной инициализации SAR, с нуля, без SDK код тоже был дан мной где-то :) дублю:
Код:
    IO_RTC_4 = 0; // отключить WiFi
    GPIO0_MUX = 0; // отключить вывод Q_CLK
    // CLK CPU 160 MHz
    rom_i2c_writeReg(103, 4, 1, 136);
    rom_i2c_writeReg(103, 4, 2, 145);
    CLK_PRE_PORT |= 1;
    ets_update_cpu_frequency(80 * 2);
    IO_RTC_4 |= 0x06000000; // переключить источник тактирования (частоту) для SAR // SET_PERI_REG_MASK(0x60000710,0x06000000);
    rom_sar_init();
/******* rom_sar_init() в ROM:
    IO_RTC_4 |= 0x02000000;
    i2c_writeReg_Mask(108,2,0,4,4,1);
    i2c_writeReg_Mask(108,2,1,1,0,2); ********/
    rom_i2c_writeReg_Mask(98,1,3,7,4,15);  
    DPORT_BASE[0x18>>2] |= 0x038f0000; // SET_PERI_REG_MASK(0x3FF00018,0x038f0000);
    HDRF_BASE[0x0e8>>2] |= 0x01800000; // SET_PERI_REG_MASK(0x600005e8,0x01800000);
далее sar_init(x,x)
 
Сверху Снизу