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

Разработка ‘библиотеки’ малого webсервера на esp8266.

nikolz

Well-known member
pvvx,
Добрый день,
Хотел бы узнать Ваше мнение, почему ADC в ESP работает так медленно.
Если схема поразрядного уравновешивания, то на 10 разрядов при 50 мкс (Ваши результаты) получаем 5 мкс на разряд,
т е скорость очень низкая .
Возможно Вы измеряли время преобразования разряда.
В документации сказано, что при работе WIFI теряется 20% скорости процессора.
Возможно, что для ацп еще больше?
Возможно подскажите какую-либо документацию по ADC в ESP
Спасибо
 

pvvx

Активный участник сообщества
Хотел бы узнать Ваше мнение, почему ADC в ESP работает так медленно.
Спасибо
20 кГц на отсчет и баста. ADC полу-программный, набор сумм с коррекциями из 8 регистров сумматоров.
Определение типа ADC: http://esp8266.ru/forum/threads/tochnost-adc.598/#post-10617
Возможно подскажите какую-либо документацию по ADC в ESP
Нет никакой документации по ADC, кроме моих собственных похождений и замеров с ним.
Данная прошивка выводит в UDP поток с ADC до 20кГц 14 бит. Что ещё надо?
 
Последнее редактирование:

nikolz

Well-known member
pvvx,
Благодарю за информацию.
-----------------------------
Просьба ответить на следующие вопросы:
--------------------
1) Если я правильно понял Вашу осциллограмму,
то время коммутации 8 сумматоров 10 мкс.
Т е без учета времени считывания их получаем скорость 100 кгц.
-------------------
2) Число разрядов результата не влияет на скорость преобразования а определяется лишь алгоритмом суммирования.
----------------
3) Можно ли управлять скоростью коммутации сумматоров.
-----------------
4) Если у нас 8 шагов, то каким образом получаем 14 разрядов
Верно?
Спасибо.
 
Последнее редактирование:

pvvx

Активный участник сообщества
1) Если я правильно понял Вашу осциллограмму,
то время коммутации 8 сумматоров 10 мкс.
Там писано - 20 мкс клетка, а "зубцы" чуть более. Далее открывайте как работает SAR...
Потом смотрите код и видите, что начало замера (заряд) включается в конце цикла обслуживания прерывания чтения регистров. Т.е. следующее прерывание считывает готовый результат и снова заряжает SAR
И прерывание с 12-ю i/o низко-скоростной шины не обслужить быстрее 1.5 us.
 
Последнее редактирование:

pvvx

Активный участник сообщества
4) Если у нас 8 шагов, то каким образом получаем 14 разрядов
Верно?
Значит 12. Перепутано с ~sys_adc~ - там ещё сумма. Но точно я не помню - очень давно это уже было. Запустите WDRV и считайте показания при установке у максимум ADC.
 
Последнее редактирование:

nikolz

Well-known member
pvvx,
Пардон,действительно 20 мкс+2 мкс, т е примерно 40 кгц . Это понятно.
----------------------
Но как за 8 тактов получаем 10 или 12 бит. Это не понятно.
В SAR число разрядов равно числу тактов.
или здесь такт - это несколько разрядов?
Ваше мнение?
Спасибо
 

pvvx

Активный участник сообщества
pvvx,
Пардон,действительно 20 мкс+2 мкс, т е примерно 40 кгц . Это понятно.
----------------------
Но как за 8 тактов получаем 10 или 12 бит. Это не понятно.
Не помню, что содержат сумматоры. Смотрите китайский код. Там вроде сдвиг результата суммы на 2 и выходит 10 бит.
Код:
    read_sar_dout(sardata);
    for (i = 0; i < 8; i++) {
        sar_dout += sardata[i];
        ADC_DBG("%d, ", sardata[i]);
    }
    tout = (sar_dout + 8) >> 4;   // tout is 10 bits fraction
Пример ещё https://github.com/mattcallow/esp8266-sdk/blob/master/apps/07switch/driver/adc.c
Сморите тип китайской коррекции - это что-то типа линеаризации простого RC спада.
Код:
; =============== S U B R O U T I N E =======================================


read_sar_dout:                          ; CODE XREF: readvdd33+125p
                                        ; test_tout+B0p ...
                l32r            a9, dw0x60000A00
                l32r            a8, dw0xF00_0
                movi.n          a11, 0
                addi            a1, a1, 0xF0
                s32i.n          a12, a1, 4
                s32i.n          a0, a1, 0
                s32i.n          a13, a1, 8
                movi.n          a0, 0
                movi            a13, 0xFF
                movi.n          a12, 0x7F

loc_4024EF84:                           ; CODE XREF: read_sar_dout+55j
                addx4           a6, a0, a9
                addx2           a7, a0, a2
                mov.n           a5, a13
                mov.n           a10, a11
                memw
                movi            a3, 0x117
                l32i            a6, a6, 0x380
                addi.n          a0, a0, 1
                extui           a0, a0, 0, 8
                xor             a6, a6, a12
                extui           a4, a6, 0, 8
                addi            a4, a4, 0xEB
                extui           a6, a6, 0, 0xB
                s16i            a6, a7, 0
                movgez          a10, a4, a4
                mull            a10, a10, a3
                and             a3, a6, a8
                srai            a10, a10, 8
                blt             a13, a10, loc_4024EFBC
                mov.n           a5, a10

loc_4024EFBC:                           ; CODE XREF: read_sar_dout+4Bj
                add.n           a3, a5, a3
                s16i            a3, a7, 0
                bnei            a0, 8, loc_4024EF84
                l32i.n          a12, a1, 4
                l32i.n          a13, a1, 8
                l32i.n          a0, a1, 0
                addi            a1, a1, 0x10
                ret.n
; End of function read_sar_dout
Эта функция переведена мной на Cи как mread_sar_dout() - https://github.com/pvvx/esp8266web/blob/master/app/driver/adc.c

По поводу readvdd33() - там, в самой функции, стоят задержки ets_delay_us(25) перед чтением регистров "сумматоров" read_sar_dout(), чтобы не опрашивать их готовность:
while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0
Время после "заряда" измерения и выставлением битов готовности у данного SAR где-то дает предел опроса чуть более 22 кГц (22 тысяч опросов в секунду). С учетом времени считывания "сумматоров" и выходит предел к 20кГц. При другой тактовой потребуются другие коррекции и токи...

PS: Объяснять и капаться снова там не вижу смыслу - вы всё равно не напишите инструкции для всех.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Переехало на SDK 1.5.0 (размер кода в flash немного увеличился, heap стало немного больше).
Ошибка с deep_sleep в китай-либах запатчена.
 

auara2

New member
pvvx, 26 ноя 2015
Эта функция переведена мной на Cи как mread_sar_dout() - https://github.com/pvvx/esp8266web/blob/master/app/driver/adc.c
Кажись, потеряно ограничение z на уровне 255 перед суммированием с x.
Сморите тип китайской коррекции - это что-то типа линеаризации простого RC спада.
Код:
...
                      blt             a13, a10, loc_4024EFBC    ;jmp if(aD < aA)
                       mov.n           a5, a10        ;a5 = aA
      
      loc_4024EFBC:                           ; CODE XREF: read_sar_dout+4Bj
                      add.n           a3, a5, a3    ;a3 += a5
...
Надо где-то так:
Код:
void ICACHE_FLASH_ATTR mread_sar_dout(uint16 * buf)
{
  volatile uint32 * sar_regs = &SAR_BASE[32]; // 8 шт. с адреса 0x60000D80
  int i;
  for(i = 0; i < 8; i++) {
    int x = ~(*sar_regs++);
    int z = (x & 0xFF) - 21;
    if(z < 0)  z = 0;
    z = (z * 279) >> 8;  // == (z * 279) / 256 == z * 1.08984375
    if(z > 255)  z = 255;
    buf[i] = (x & 0x700) + z;
  }
}
 

auara2

New member
Как я понял про АЦП из документаций:
  1. Рабочее напряжение чипа (самой микросхемы): 1.8В - 3.6В .
  2. В файле "esp_init_data_default.bin", длиной 128 байт, надо
    прописывать значение "vdd33_const" (по адресу 0x6B = 107) равное реальному
    напряжению питания чипа в единицах 0.1В (т.е. от 18 до 36, по умолчанию 33).
  3. Разрядность АЦП: 10 бит .
  4. АЦП не желательно использовать, когда чип передает. Иначе напряжение, может быть неточным.
  5. Диапазон измеряемых напряжений АЦП: 0.0В - 1.0В .
    Следовательно, внутреннее опорное напряжение д.б. в районе 1.0В (желательно 1.024В).
 
Последнее редактирование:

pvvx

Активный участник сообщества
из данного кода следует что АЦП имеет 8 разрядов. 11 получаем суммированием 8 отсчетов.
Кто больше?
& 0x700 + младшие 8 бит не есть 8 разрядов.
3+8=12 и так по 8.
Как я понял про АЦП из документаций
"Не читайте перед обедом китайских газет."
 
Последнее редактирование:

pvvx

Активный участник сообщества
вот они восемь разрядов:
if(z > 255) z = 255;
-----------------------------------
Не запивайте свежие огурцы молоком
WDRV из прошивки F=1000, прием по WiFi:
ADC14Bits.gif
ADC_no_k.gif
ADC_xx.gif
Это контроль, принятый на ADC 24 бита тестового сигнала (DAC = полные 16 бит 0..1.2В):
ADC-DAC_gen_test.gif
 
Последнее редактирование:

nikolz

Well-known member
WDRV из прошивки F=1000, прием по WiFi:
Посмотреть вложение 1135
Посмотреть вложение 1138
Посмотреть вложение 1137
Это контроль, принятый на ADC 24 бита тестового сигнала (DAC = полные 16 бит 0..1.2В):
Посмотреть вложение 1136
-------------------------
Я Вам верю. Это замечательно.
---------------------------
Согласен,что разрядов больше восьми, их одиннадцать.

----------------------------
Картинки хорошие,
но не ясно, как они должны выглядеть если разрядов будет 11,10,9,8.
Что на них доказывает, что разрядов 14, а АЦП имеет 16?
---------------------------
Для доказательства разрядности нужна таблица цифрового кода на выходе ацп для нескольких шагов входного напряжения. Пока получить эту таблицу не могу, вся надежда на Вас.
---------------------------
Есть еще программы, которые могут прояснить логику (возможно и число разрядов)
--------------------------
У меня получается следующая логика этой прогаммы
void ICACHE_FLASH_ATTR mread_sar_dout(uint16 * buf)
{
volatile uint32 * sar_regs = &SAR_BASE[32]; // 8 шт. с адреса 0x60000D80
int i;
for(i = 0; i < 8; i++) {
int x = ~(*sar_regs++);
int z = (x & 0xFF) - 21;
if(z < 0) z = 0;
z = (z * 279) >> 8; // == (z * 279) / 256 == z * 1.08984375
if(z > 255) z = 255;
buf = (x & 0x700) + z;
}

--------------------------
1) В цикле выполняются некоторые преобразования восьми равноценных значений , полученных с АЦП
Почему восемь ? -понятно.
Почему равноценных? - потому, что выполнение действий не зависит от номера значения
-------------
2) С каждым из значений выполняются следующие действия:
int x = ~(*sar_regs++); - х присваивается очередное инверсное значение из массива sar_regs
int z = (x & 0xFF) - 21; - z присваивается младший байт (8 бит) значения x уменьшенное на 21 ( для SAR вполне правдоподобно так как требуется вычитать остаток)
if(z < 0) z = 0; -- если z <21 то ноль. Предположительно, что это отсечка шума
z = (z * 279) >> 8; -- предположительно - это коррекция нелинейности младших разрядов результата
if(z > 255) z = 255; Предположительно, что это отсечка шума
buf = (x & 0x700) + z; -- т е получаем
buf=x & 111 0000 0000 + z & 1111 1111
из x выделяются старшие 9,10,11 разряды и к ним дописываются 8 младших разрядов из z
------------------------
Таким образом, эта программа корректирует нелинейность в выходном 11-ти разрядном коде 8 значений АЦП
Согласны?
---------------------
Из этого следует, что при каждом обращении к АЦП, мы обрабатывает не одно преобразование АЦП а восемь.
Поэтому скорость преобразования АЦП не 20 кгц , а в восемь раз больше.
--------------------------
Согласны?
 
Последнее редактирование:

nikolz

Well-known member
Вот еще разбор Вашей проги:
-------------------
read_sar_dout(&sar_x[0]);
z=0;
for(y=0;y<8;y++)z+=sar_x[y];
z+=8;
z>>=4;
*ptr++=z;
};
Здесь происходит суммирование 8 значений АЦП, т е добавляем еще 3 разряда к полученным ранее 11
после суммирования прибавляем константу 8 - зачем? не знаю.
Затем сдвигаем вправо на 4 разряда. В результате остается 10 бит.
--------------------------------
Резюме:
Программа получения данных с ацп
При каждом обращении выполняет 8 раз запуск ацп и сохранение этих значений
затем у 8 значений исправляется нелинейность в младших битах и формируется 11 бит
затем эти восемь значений суммируются (результат уже 14 бит) и сдвигаются на 4 бита - результат 10бит
---------------------------------
А хотелось бы при обращении к ацп выполнялось лишь одно преобразование.
Может подскажите как запустить однократно АЦП ( пуск, готовность чтение данных) - один раз, а не восемь.
 

pvvx

Активный участник сообщества
-------------------------
Согласен,что разрядов больше восьми, их одиннадцать.
Ну наконец-то подсчитали :)
но не ясно, как они должны выглядеть если разрядов будет 11,10,9,8.
Никак - у ADC ESP8266 шум за 5-тым битом, с выбросами от работы WiFi.
Что на них доказывает, что разрядов 14, а АЦП имеет 16?
Совместно с шумом, усреднение дает уточнение.
WDRV берет только 8 значений из регистров и суммирует - итого 14 бит (от 0 до 16383).
Запрос у HTTP сервера значения ADC делает дополнительно ещё 4 суммы, и выводит значение в 16 бит (0..65535)
 

nikolz

Well-known member
Ну наконец-то подсчитали :)

Никак - у ADC ESP8266 шум за 5-тым битом, с выбросами от работы WiFi.
Совместно с шумом, усреднение дает уточнение.
WDRV берет только 8 значений из регистров и суммирует - итого 14 бит (от 0 до 16383).
Запрос у HTTP сервера значения ADC делает дополнительно ещё 4 суммы, и выводит значение в 16 бит (0..65535)
--------------------------------------------------
Вы согласны с тем, что это 8 независимых значений АЦП ?
Полагаю, если для ввода c АЦП вырубить WIFI
кроме того вводить по одному значению за раз а не по восемь
кроме того коррекцию нелинейности вынести за цикл ввода массива данных
то получим 11 бит АЦП со скоростью 200 кгц и погрешностью в пределах 1 бита.
Вот за это будем бороться
Согласны?
------------------------------
Можете подсказать регистр и биты отвечающие за однократный запуск ацп проверку готовности и регистр данных?
Спасибо
 

pvvx

Активный участник сообщества
Вы согласны с тем, что это 8 независимых значений АЦП ?
Нет.
Полагаю, если для ввода c АЦП вырубить WIFI
кроме того вводить по одному значению за раз а не по восемь
кроме того коррекцию нелинейности вынести за цикл ввода массива данных
то получим 11 бит АЦП со скоростью 200 кгц и погрешностью в пределах 1 бита.
Нет. 20*8=160 - это раз, а второе что там сплошной шум.
Вот за это будем бороться
Согласны?
Нет.
Сказано уже - ничего из этого хорошего не выйдет.
С выключенным WiFi и не работающей Flash (исполнение из IRAM), вывод в UART:
ADC_ESP8266.gif
Всё равно наблюдается кривизна и нелинейности (пол шкалы и полная отличаются).
Вход ADC ESP напрямую включен на выход ОУ у ЦАП-а на 16 бит с REF=1.200В. За цикл в 10000 c копейкой замеров (прием 10 точек в секунду). Стандартная коррекция - код брался из WDRV прошивки (там есть отличия от китайского).
Вложен файл ADC_ESP8266.xlsx, с пересчетом - множитель 0,0612 чтобы примерно совпало с тестовым генератором (до 4-го знака на максимуме), введено Z0= - 9 mV, т.к. ADC ESP нуль не показывает. Старт генератора и запись запущена руками, т.е. начало не с начала, а где-то секунда :)
Одновременно при данном замере снятый на другой ADC тот-же выход (разница всего в длине проводков к ОУ DAC на 4 см короче, прием на Eval-ADuC7061MK плату):
Test_GEN.gif
Можете подсказать регистр и биты отвечающие за однократный запуск ацп проверку готовности и регистр данных?
Спасибо
Всё подписано в исходниках.
 

Вложения

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

nikolz

Well-known member
pvvx,
А как запустить SAR на одно преобразование, а не на восемь?
Судя по исходникам, даже Вам это неизвестно.
---------------------
Правильно я понял, что 16 бит Вы получаете путем суммирования еще 4 значений. Т е усреднением по 32 значениям.
Не пробовали применить медианный фильтр для удаления помех?
Будет более эффективно.
-----------------------
 
Последнее редактирование:

pvvx

Активный участник сообщества
Правильно я понял, что 16 бит Вы получаете путем суммирования еще 4 значений. Т е усреднением по 32 значениям.
Да.
Не пробовали применить медианный фильтр для удаления помех?
Будет более эффективно.
Больному это не поможет - зачем АЦП с линейностью не более 5 бит и опорным источником тоже не точнее 5 бит?
 

nikolz

Well-known member
Да.
Больному это не поможет - зачем АЦП с линейностью не более 5 бит и опорным источником тоже не точнее 5 бит?
Очень даже поможет.
Есть задачи в которых источник аналогового сигнала имеет нелинейную характеристику и приходится ее корректировать.
Нет никакой разницы корректировать лишь источник или суммарную характеристику источника и ацп.
Поэтому главное это -скорость преобразования, повторяемость и число разрядов - для максимального динамического диапазона.
А остальное можно скорректировать в цифре.
 
Сверху Снизу