• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

XT-ZB1 (Devkit) BL702C

pvvx

Активный участник сообщества
@volaltd - В каждый блок изначально заложена внешне настраиваемая конфигурация практически всех типовых отдаваемых/обрабатываемых переменных и подобие скриптов для выполнения циклических действий и т.д.. Для переноса необходимо переписать только драйвера периферии и учесть специфику очередного MCU/компилятора и всё. Отработать и протестировать дрова не составляет труда, а общие алгоритмы и функционирование не меняется. Это-же пром.автоматика – типа ПЛK совмещенный с драйверами…
 

pvvx

Активный участник сообщества
Дык вот эта “внешне настраиваемая конфигурация” не меняется десятилетиями и обычно используется заранее запрограммированная как “default”. Если внести изменения, то придется менять всё окружение и “программисты” (особенно в АСУ заводов-пароходах, а так-же и других внешних компонентов) туда никогда не лезут. А изменяю её только тогда, когда создается совершенно новая система в механической схеме. Внешнее железо составляет большую часть стоимости оборудования, только по весу металлолома. И такое не требуется миллионным тиражом, а только до сотни в месяц, тем более каждая система учитывает специфику заказчика – его завода-парохода и прочего бреда их маркетологов… Но это более относится к железкам, большим агрегатам, а не к электронике… И раз запустив установку, её останавливают только на обслуживание по расходникам. В итоге через дцать лет или при поломке легче заменить все блоки электроники на новые, а не путаться в номерах версий и т.д.

Применение каких-то готовых пром. блоков нам не подходит – есть множество специфики по датчикам, сертификации и т.д. И стронние “фирменные” блоки летят чаще – там нет расчета на непрерывную работу в десятилетия. И как пример – Siemens наконец-то сгинул из России, остальные так-же… В итоге промышленность в ауте, а у нас всё ok и увеличение спроса...
 

volaltd

Member
А по факту CI/CD именно что то, что вы описали: быстрое создание туевой кучи версий и тестирование их на конечном пользователе, причем в большинстве случаев вместо фиксов говорят "это чисто косметическое и никак не влияет на функционал, используйте ... вот таким образом", где вместо ... следует вставить воркараунд.
 

pvvx

Активный участник сообщества
По нужде ещё раз глянул работу ADC в XT-ZB1 Devkit. Нужно было что-то дешевое и с более 14 бит ENOD для подключения INA199A1.
В принципе, используя железные китайские проводки и разъемы к XT-ZB1 Devkit - всё на соплях, но вроде влезает, если до 20 ksps в USB-CDC.
1668495760964.png

Варианты ADC sps в BL702 от CLK_DIV и AVERAGE:

// ADC_CLOCK_DIV_32, ADC_DATA_WIDTH_16B_WITH_256_AVERAGE = 3906.25 sps # 32000000/256/32 = 3906.25
// ADC_CLOCK_DIV_24, ADC_DATA_WIDTH_16B_WITH_256_AVERAGE = 5208.33 sps # 32000000/256/24 = 5208.33
// ADC_CLOCK_DIV_20, ADC_DATA_WIDTH_16B_WITH_256_AVERAGE = 6250 sps # 32000000/256/20 = 6250
// ADC_CLOCK_DIV_16, ADC_DATA_WIDTH_16B_WITH_256_AVERAGE = 7812.5 sps # 32000000/256/20 = 7812.5
// ADC_CLOCK_DIV_12, ADC_DATA_WIDTH_16B_WITH_256_AVERAGE = 10416.66 sps # 32000000/256/12 = 10416.66

// ADC_CLOCK_DIV_32, ADC_DATA_WIDTH_16B_WITH_128_AVERAGE = 7812.5 sps # 32000000/128/32 = 7812.5
// ADC_CLOCK_DIV_24, ADC_DATA_WIDTH_16B_WITH_128_AVERAGE = 10416.66 sps # 32000000/128/24 = 10416.66
// ADC_CLOCK_DIV_20, ADC_DATA_WIDTH_16B_WITH_128_AVERAGE = 12500 sps # 32000000/128/20 = 12500
// ADC_CLOCK_DIV_16, ADC_DATA_WIDTH_16B_WITH_128_AVERAGE = 15625 sps # 32000000/128/16 = 15625
// ADC_CLOCK_DIV_12, ADC_DATA_WIDTH_16B_WITH_128_AVERAGE = 20833.33 sps # 32000000/128/12 = 20833.33

// ADC_CLOCK_DIV_32, ADC_DATA_WIDTH_14B_WITH_64_AVERAGE = 15625 sps # 32000000/64/32 = 15625
// ADC_CLOCK_DIV_24, ADC_DATA_WIDTH_14B_WITH_64_AVERAGE = 20833.33 sps # 32000000/64/24 = 20833.33
// ADC_CLOCK_DIV_20, ADC_DATA_WIDTH_14B_WITH_64_AVERAGE = 25000 sps # 32000000/64/20 = 25000
// ADC_CLOCK_DIV_16, ADC_DATA_WIDTH_14B_WITH_64_AVERAGE = 31250 sps # 32000000/64/16 = 31250
// ADC_CLOCK_DIV_12, ADC_DATA_WIDTH_14B_WITH_64_AVERAGE = 41666.66 sps # 32000000/64/12 = 41666.66

// ADC_CLOCK_DIV_32, ADC_DATA_WIDTH_14B_WITH_16_AVERAGE = 62500 sps # 32000000/16/32 = 62500
// ADC_CLOCK_DIV_24, ADC_DATA_WIDTH_14B_WITH_16_AVERAGE = 83333.33 sps # 32000000/16/24 = 83333.33
// ADC_CLOCK_DIV_20, ADC_DATA_WIDTH_14B_WITH_16_AVERAGE = 100000 sps # 32000000/16/20 = 100000
// ADC_CLOCK_DIV_16, ADC_DATA_WIDTH_14B_WITH_16_AVERAGE = 125000 sps # 32000000/16/16 = 125000
// ADC_CLOCK_DIV_12, ADC_DATA_WIDTH_14B_WITH_16_AVERAGE = 166666.66 sps # 32000000/16/12 = 166666.66

// ADC_CLOCK_DIV_32, ADC_DATA_WIDTH_12B = 100000 sps # 32000000/32 = 1000000
// ADC_CLOCK_DIV_24, ADC_DATA_WIDTH_12B = 1333333.33 sps # 32000000/24 = 1333333.33
// ADC_CLOCK_DIV_20, ADC_DATA_WIDTH_12B = 1600000 sps # 32000000/20 = 1600000
// ADC_CLOCK_DIV_16, ADC_DATA_WIDTH_12B = 2000000 sps # 32000000/16 = 2000000
// ADC_CLOCK_DIV_12, ADC_DATA_WIDTH_12B = 2666666.66 sps # 32000000/12 = 2666666.66

Использовал ADC_CLOCK_DIV_12, ADC_DATA_WIDTH_16B_WITH_128_AVERAGE = 20833.33 sps (более уверенно не лезет в USB без оптимизации исходников SDK)
 

pvvx

Активный участник сообщества
Подкрутил на 100 ksps. Но это уже 14 бит.
1668555910065.png
ADC на C(1uF)+R(7k5) к GND (100kHz) , C - электролит, чтобы шумел - имитация доп. схемы :)
Среднекв отклонение: 1,08 единиц АЦП
Max Bits 14 Bits
Max SNR 86,04 dB
ENOB 13,89 Bits
Test SNR 85,38 dB
 

pvvx

Активный участник сообщества
Сплошной бардак на https://github.com/bouffalolab/bl_mcu_sdk
Лепят новую версию v2.0, не совместимую со старой v1.4.5
Половины опций для конфигурации устройств нет... Циклической работы DMA нет, но это решается дописыванием своей процедурки...
Но, за счет более короткого кода скорость работы с периферией увеличилась... Трансфер с USB в комп уже достигает 1 Мбайта/сек и стало возможно гнать данные с ADC и на 166 ksps (следующий типовой шаг ADC - 1 Msps и не лезет).
 

pvvx

Активный участник сообщества
ADC к DAC (проводком, а не внутренним соединением) на XT-ZB1:
1668855262895.png
Все значения в единицах ADC (16bit 0...65535), real 15bit 100 ksps, Ref 3.2V.

Ref DAC - 2V, DAC 10-ти битный, но он не тянет до 0 и до полного Ref. Итог 180...1.8 V.
Ступени DAC (масштаб Y x10):
1668855438351.png
 

pvvx

Активный участник сообщества
Да просто копаясь в хламе, в самых дешевых ныне SoC, в этом BL702C ADC более менее и годится для некоторых поделок. Так-же наличие DAC дает возможность гнать Ref для диф. замеров при однополярном питании.
Но, есть малая неприятность - взаимовлияние каналов ADC. Т.е. при оцифровке в автомате по DMA с разных каналов они влияют друг на друга и достаточно сильно. Причина - не успевают зарядиться цепи измерения SAR-ADC - мало время заряда. Так настроили в SDK. На самой низкой скорости оцифровки - всё более менее, а на 100000 sps (50ksps на канал) выходит такое:
1668876581421.png
Это x10, один канал ADC вместе c DAC, второй на GND или на кондер. Каналы переключаются каждый замер.
Утягивает замер второго канала:
1668876770813.png

Два канала позволяют расширить динамический диапазон к 20 битам, но требуется авто-калибровка.
Т.е. возможно сделать более дешевый вариант PowerProfiler, чем "nRF PowerProfiler 2" ($99) поставив всего два чипа типа INA199A1 и INA199A3 и примерно уравновесить шунтом из двух делителей. Т.е. всего пару деталей (+калибровочные R и транзисторы).
Получается линейный диапазон - не будет стыков и выбросов от авто-переключения шунта, как это происходит у nRF. И диапазон измерения увеличивается до 26В (возможно до 60В - в зависимости от используемых INAxxx).
В данном случае влияние каналов контролируемо - при переключении один упирается в ограничение выхода INAxxx, а второй работает с большей амплитудой - т.е. получаем стабильное напряжение и влияние - корректируется программно.
Бесшовное переключение :)

+ https://pallavaggarwal.in/dc-current-analyzer-for-embedded-iot-product-development/
 

pvvx

Активный участник сообщества
Хотел прикрутить к данным чипам ADC с 24 бита по SPI безусловно...
Но чип не тянет стабильно и без пропусков дискретизацию более 12 кГц, а хочу 250 кГц, т.к. ADC может и USB в чипе может выплюнуть такой поток.
Но все ADC имеют странный протокол по SPI, где линия SDO (MISO) падает когда произведена оцифровка и можно читать значения.
На прямую на прерывание по пину это не повесить, т.к. ещё и выходные битики дергаются при чтении...
Приходится в IRQ по пину с фронта запрещать новое прерывание и ждать, пока SPI отработает свои 24-32 бита, потом сбрасывать флаг прерывания от пина и разрешать прерывание снова.
Это всё вроде укладывается в сотни нс, кроме транзакции по SPI.
И само прерывание возможно не всегда, т.к. надо переписывать SDK и убирать все запреты (но это пока не делал, т.к. и так видно что другое тоже тормозит).
1670179118075.png
Типичный интерфейс у ADC такой:
1670179238664.png
И пофиг какой ADC - всё пракnически едино...
Как слепить на 2-х SPI с DMA - это ещё понятно, но как получить данные с прерываниями в 250 и выше кГц если у чипа нет второго SPI?
 
  • Like
Реакции: mdx

pvvx

Активный участник сообщества
Всё-таки добил эти 24-х битные АЦП. Скормил BL702, пашут на 125 ksps и более в USB.
Но так и не разобрался, почему прерывание по GPIO в BL702 тормозное. Но там два режима прерываний по GPIO - один уж совсем-совсем тормозной, с защелкой и аппаратным счетом - типа реализовали аппаратный анти-дребезг.
Без GPIO обошлось, тупеньким подобием фапч - подстройкой таймера на ходу под CLK ADC по его сигналу готовности...
Теперь гляжу какую фигню выдают дешевые китайские генераторы типа
MHS-5200A Высокоточный цифровой двухканальный генератор сигналов DDS :) :) :)
DAC 8-мь бит (!), кусок его пилы, шум с него тоже есть - амплитудой пару тысяч единиц ADC, при максимальной амплитуде выхода и согласованию с максимумом к 24 битам ADC.
1671996231154.png
А это увеличение и сами битики :)
1671996240247.png
PS: есть нормальный ген с DDC и т.д. - в них пила строиться источниками тока и ступеней нет вообще.
 

pvvx

Активный участник сообщества
Т.е. BL702 запросто шурует в прерывании к 200 кГц с обработкой коррекции таймера, опросом и выводом в GPIO (72МГц), SPI и буферизацией. При этом вываливает всё в USB1.1 (USB2.0FS) в пределе к 1 Мегабайту в сек в CDC (COM порт).
 

cryptozoy

Member
Ясное дело, ядро-то у него 144МГц, и получается 720 тактов на один дискрет АЦП. Этого более чем достаточно для обработки прерываний.
 

pvvx

Активный участник сообщества
Ясное дело, ядро-то у него 144МГц, и получается 720 тактов на один дискрет АЦП. Этого более чем достаточно для обработки прерываний.
Но по прерыванию GPIO не достаточно. Что-то там намудрено в контроллере GPIO и прерываний.
А для таких ADC нужно прерывание по сигналу готовности, т.к. SPI не умеет стартовать по перепаду сигнала с SS и DMA к нему не подключить - приходиться всё делать софтом.
И не в каких доках не расписаны приоритеты прерываний :)
 

pvvx

Активный участник сообщества
К примеру с AD7176-2 дело усугубляется тем, что если попасть на сигнал занятости SPI то это сбивает весь прием навсегда. А окно возможности чтения регистров замера там в предел на максимальный CLK при максимальном sps, и ADC тактируется от своего генератора. А возможный синхро приводит к старту начального набора ADC и соответственно пропуску нескольких шагов непрерывного измерения.
Т.е. тупо по таймеру с ним нет возможности работать.
 

pvvx

Активный участник сообщества
Теперь необходимо обработать полученные потоки в нормальном живом виде графиков. Имеющиеся либы для компа не могут обрабатывать такие потоки в виде красивых графиков нормально. Все тормозят по черному и не важно платные они или нет.
Пока для рассмотрения остается один вариант - подглядеть и переписать исходники от nRF Power Profiler. Там их как раз адаптировали под такие задачи и благо они выложены на github. У других это выглядит как полный кошмар с кучей неудобств.
Но это уже другая задача и в другую тему…
 

pvvx

Активный участник сообщества
Наткнулся на проблему -
При включении I2S в режиме Slave Stereo нет синхронизации по каналам L и R в буфере DMA. Возникает зависимость от времени старта инициализации i2s и далее не понять какой канал будет приниматься по четному и нечетному адресу в буфер DMA. Отслеживать GPIO синхро сигнал каналов при старте инициализации i2s не прокатило. Частота синхро сигнала 96 или 192 кГц и если опрашивать вход синхро по GPIO и сразу стартовать пуск i2s, то это так-же не дает однозначности - чип думает о чем-то сам и плевал на это. В итоге неизвестно какой канал будет принят первым в буфер, а флагов номера принятого канала i2s не имеет.
При MONO режиме всё ok. Четко принимается L или R канал, в зависимости от настроек i2s. Попытка синхронизовать с помощью инициализации на MONO и по событию приема к примеру L канала переключить i2s на Stereo так-же не прокатила...
Какие могут быть предложения по синхронизации канального приема c i2s в режимах slave при приеме нескольких каналов (чип имеет возможность до 4-х каналов по i2s)?
 

nikolz

Well-known member
Наткнулся на проблему -
При включении I2S в режиме Slave Stereo нет синхронизации по каналам L и R в буфере DMA. Возникает зависимость от времени старта инициализации i2s и далее не понять какой канал будет приниматься по четному и нечетному адресу в буфер DMA. Отслеживать GPIO синхро сигнал каналов при старте инициализации i2s не прокатило. Частота синхро сигнала 96 или 192 кГц и если опрашивать вход синхро по GPIO и сразу стартовать пуск i2s, то это так-же не дает однозначности - чип думает о чем-то сам и плевал на это. В итоге неизвестно какой канал будет принят первым в буфер, а флагов номера принятого канала i2s не имеет.
При MONO режиме всё ok. Четко принимается L или R канал, в зависимости от настроек i2s. Попытка синхронизовать с помощью инициализации на MONO и по событию приема к примеру L канала переключить i2s на Stereo так-же не прокатила...
Какие могут быть предложения по синхронизации канального приема c i2s в режимах slave при приеме нескольких каналов (чип имеет возможность до 4-х каналов по i2s)?
24 бита - это на постоянном уровне сигнала на входе.
Если сигнал на входе синусоида, то какая ошибка?
А если ступенька на входе, то какое время установление кода на выходе?
--------------
Судя по более ранним Вашим данным у Вас точность измерения не более 14 бит, даже если на выходе 24 бита .
Можете показать динамическую ошибку?
 
Сверху Снизу