• Система автоматизации с открытым исходным кодом на базе 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)
 
Сверху Снизу