123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- ** Проект VAPC-meth **
- * Измеритель напряжения/тока/мощности/ёмкости *
- Немогу никак определиться с диапазонами.
- Думал сначал сделать по два диапозона на напряжение и ток, но что-то мне эта
- идея разонравилась. Опять же, измерять большие напряжения/токи не особо часто
- приходится. Напряжения в основном до 20 вольт, токи - до пары ампер.
- Тем более, так как это измеритель в конкретное устройство, то нужно под него и
- подстраиваться.
- Будет по одному диапазону на ток и напряжения.
- нужно сделать пару кнопок.
- сделать ввод Кд делителя напряжения умноженного на 1000,
- и сопротивление шунта * Ку услителя тока * 1000.
- Далее в программе при вычислениях - получили код ацп, перевели в напряжение,
- умножили на 1000 и поделили на коэффициент.
- Ох и здоровая (85х40мм) плата получилась...
- можно попробовать разбить на две -- на одной индикатор и кнопки, на второй всё
- остальное. получится две платы ~ 45х40 мм.
- вариант A -- поменял входной разъём.
- вариант B -- поменял компановку, плата стала 51х47 мм.
- вариант C -- убрал кварц, добавил двухцветный светодиод, плата стала 49.53 x 46.67 мм.
- думаю последний вариант вполне неплох -- мне даже нравится :-)
- можно использовать в качестве окончательного.
- только вот нормы 0.4/0.17 -- можно пробовать фоторезистом.
- по софту пока идей нету :-)
- SVN-инит 2014.12.29
- появилась мысль -- сделать транзисторный ОК выход, например для управления
- релюхой. хотя если брать ардуиновское реле -- то там нужен просто выход.
- реле для управления нагрузкой -- можно сделать тот-же зарядно-разрядный
- автомат.
- ===
- 2014.12.30
- вывел ещё два вывода на колодку.
- ---
- 2015.05.14
- добавил скелет проекта, makefile, C::B проект.
- ---
- 2015.05.15
- настройка SPI.
- должно вывести 0-7 на индикаторы.
- ---
- 2015.05.18
- добавил RTOS, перенёс туда timing_delay, задержка на 4-ом таймере 1 мс,
- обработчик таймера перенёс в RTOS.
- должно вывести 0-7, через 5 сек 8-f, и так по кругу.
- ---
- 2016.03.23
- Проект уже на git.
- Закончил паять (начал вчера), прошил.
- И тишина...
- Попутно исправил в схеме некоторые номиналы.
- Шунт на 0.1 -- не влезет по мощности, использовал 0.05 Ом.
- На плате есть мелкие огрехи, но самый конкретный косяк -- не те индикаторы.
- По факту использовал корпуса 3-х символьных 7.62 мм. Втулил свои 4-х символьне
- 9 мм. подогнув выводы, но кнопки и светодиод не влезли.
- Исправил дефайны индикаторов.
- Осцилом ничего не увидел на выводах SPI, нужно искать.
- Почитал даташит на тему SPI, поправил свой код.
- ---
- 2016.03.24
- Так-как по прежнему тишь и глухомань, поднял проект в IAR-е и полез в
- отладку. Всё застряло где-то в Delay - похоже на проблемы с таймером.
- Таки да, забыл включить тактирование таймера -- похоже потерялось при
- переносе инициализации то туда, то сюда...
- Повторяем заповедь -- "Часы, ноги, перефирия".
- Вобщем, SPI работает. Проблема была в том, что токозадающий резистор для
- MAX нужно подключать на +5В, а у меня он был на земле. Напаял навесом.
- Картинка появилась, но на индикаторах какой-то бред.
- Исправил коды символов. Исправил позиции индикаторов.
- Вылезло два момента -- неправильно запаял индикаторы, собирался красный
- вниз, под ток, а жёлтый вверх под напряжение. В итоге запаял наоборот. Так
- ещё и на схеме они местами попутаны, так как на плате DS1 внизу, а DS2
- вверху. Исправил схему и позиции индикаторов под факт.
- Добился картинки. Похоже тут какой-то бешенный оптимизатор -- выкинул нах
- похожую функцию. Нужно учесть на будущее.
- ---
- Пора браться за ADC.
- С учётом входного сопротивления канала напряжения в 100 кОм,
- на частоте 16 МГц нужно использовать 384 цикла измерений,
- а на частоте 8 МГц -- 192 цикла.
- Формула расчёта (AN2834 стр. 25) = (циклы / (f_adc * C_adc * ln(2^N+1)) - 1 кОм
- ln(2^13) = 9,01091334728
- C_adc = 16 * 10^-12, т.е.:
- циклы/(f_MHz * 0.00016 * 9,01091334728) - 1 == кОм
- С канала тока, по идее, можно мерять на любой скорости.
- ---
- 2016.03.25
- Factory_VREFINT у меня == 0x7E, т.е. полное значение 0x067E == 1662
- Если это мерялось при 3В, то получается -- 1.218 В
- Предварительный успех -- читаю три канала АЦП и ПДП складывает их в
- память, преобразовываю и вывожу на индикаторы. Запуск АЦП каждые 10 мсек
- тригером от Т2. Настройка Т2 пока заклинанием -- понимания нету.
- На очереди -- усреднение результатов, вычисление напряжения питания через
- опорное напряжение.
- Пока не сильно нравится -- завышает напругу, скачут показания.
- Мерял аккум - 4.219 В, мой точный показывал 4.207, DT-шка - 4.17-4.18 В.
- Канал внутреннего опорного напряжения показывает 1.219 - 1.223 В
- По каналу тока висит 4 мВ, мой 5-ти разрядный вольтметр показывал 3 мВ на
- выводе.
- По каналу напряжения постоянно висит 17-26-35 мВ, вольтметр показывет
- чёткий "0". Замыкание на землю ничего не даёт. Хз, что это такое.
- Если от итогового напряжения вычесть эти миливольты, то результат будет
- больше похож на правду.
- На тему усреднения, такая идея:
- - в прерывании ПДП данные перекладываются в быстрый кольцевой буфер
- на 10 значений. Можно мерять чаще, хоть каждую 1 мс.
- - в основном теле каждые 100 мсек отрабатывает процедура, которая
- усредняет данные из быстрого буфера, отбрасывая слишком мелкие/большие,
- и перекладывает в медленный кольцевой буфер. Тут же делать пересчёты
- значений из кода АЦП в реальные значения.
- - ещё одна процедура раз в секунду усредняет данные из медленного буфера
- и сохраняем в текущий секундный результат. Здесь же вычеслять мощности,
- ёмкости, время и т.д.
- ---
- 2016.03.25
- Причесал настройку Т2.
- Считаем среднее, зануляем младшие 4 бита, и потом сравниваем каждое
- значение со сброшенными 4-мя младшими битами:
- middle &= 0xFFF0;
- if ((value & 0xFFF0) == middle) { ... }
- таким образом отберём только те значения, которые отличаются от
- предварительного среднего не более чем на 1/16
- ---
- 2016.03.28
- Период измерений 1.25 мсек, быстрый буфер - на 16 значений.
- Фильтра нет, только усреднение.
- Понял, почему скачет опора -- при включеном светодиоде проседает
- напряжение питания и завышаются показания. Что за хрень в канале напруги
- всё равно не понятно.
- Нужно срочно увеличивать резисторы в цепи светодиодов.
- Без светодиодов канал внутренней опоры показывает 1.219 В.
- ---
- 2016.03.31
- Начитался AN3137. Краткие выводы:
- - конденсаторы по входу АЦП нужно поменять на 220 нФ,
- - период измерения сделать не менее 2 мсек по упрощённой формуле,
- или не менее 1,2 мсек по полной формуле,
- - всё остальное -- отталкиваясь от этих данных.
- Подробнее:
- 1. внешний конденсатор (правда в некоторых слачаях его не нужно ставить,
- только я не понял в каких) расчитывается по так:
- Cext ~= 1.58 * Csh * (Umax / Ulsb),
- где Csh -- внутрення ёмкость АЦП, 16 пФ,
- Umax -- максимальное входное напряжение, принимается 4096,
- Ulsb -- нужная точность, принимается 0.5 LSB.
- Итого, Cext ~= 1.58 * 0.000000000016 * (4096 / 0.5) >= 207 nF.
- Этот конденсатор должен держать входное напряжение, пока оно меряеться АЦП,
- при этом он должен разрядиться не больше чем на Ulsb.
- Интересно, а можно его использовать для оверсемплинга, расчитав на 1 LSB ?
- Конденсатор на 10 нФ успевает разрдится на 6-10 LSB.
- 2. Период времени между измерениями, за который должен успеть зарядиться
- входной конденсатор, расчитывается так:
- tc = - (Rin * Csh) * ln(1 - (Csh/Cext) * (Umax/Ulsb))
- или, упрощённая формула tc ~= (Rin * Csh)
- где Rin -- это внешнее сопротивление по отношению к АЦП (Rext)
- ln(1 - (Csh/Cext) * (Umax/Ulsb)) ~= 0.9058
- и в итоге, для канала вольтметра (как более высокоомного и медленного):
- tc = (Rin * Csh) * 0.9058 = 9090 * 0.000000000016 * 0.9058 ~= 1,2 мсек
- ---
- 2016.07.27
- Попытка "ADC2" провалилась -- там что-то не то в буфере от АЦП.
- Возвращаюсь на последнюю рабочую версию и пойду другим путём.
- План:
- - меряем два канала (напряжение и ток) каждые 1,5625 мсек;
- - DMA забирает данные, в прерывании перебрасываем два слова в первичный
- циклический буфер на 64 значения (два буфера под напряжение и ток?)
- в этом буфере сырые данные (код от ацп);
- - раз в 100 мсек усредняем/обрабатываем эти 64 значения и складываем во
- второй буфер на 10 значений;
- - раз в секунду усредняем и считаем данные из воторого буфера.
- Закончил.
- Получился слегка затянутым -- "фронт" изменения показаний около 3-х секунд.
- Шаг вольтметра в 1 мВ я получил, но смысла особого не вижу :-)
- Без "оверсэмплинга" показания более сабильны.
- Фильтрация по каналу тока -- её не заметно. хз куда смотреть.
- В канале тока постоянно "висит" 3-4 мА, когда-то я считал,
- это похоже на смещение "0" от ОУ. Хз, нужно ли вычитывать их из результата.
- Этот этап можно считать законченым.
- ---
- Убрал оверсэмплинг по напряжению, и фильтрацию по току.
- Идея по индикации:
- - разбить на режимы:
- * режим БП
- + вверху напряжение
- + внизу ток или мощность
- * режим заряд/разряд
- + вверху напряжение / время (по кнопке или таймеру)
- время мм.сс или чч.мм, тогда мигаем точкой синхронно с секундами.
- + внизу ток (заряд) / А*Ч (разряд) / Вт*Ч (по кнопке или таймеру)
- Если две кнопки -- то двумя выбирать режим, светодиодом можно отображать.
- Одиночое нажатие меняет выводимую инфу.
- Индикация выбранного режима (секунд 5, можно с морганием): "PSU", "CHAr", "DECH";
- текущего параметра: "-U-", "-I-", "-P-", "-t-", "-IH-", "-PH-"
- Или проще -- выбираем, что отображать в текущей строке:
- "-U-", "-I-", "-U-I-", "-P-", "-t-", "-IH-", "-PH-", "-U-t-", "-I-t-"
- В двойных режимах менять отображаемый параметр по таймеру.
- Обработка кнопок.
- Каждая кнопка коротким нажатием переключает отображаемую величину своей строки.
- Что повесить на длинное нажатие -- не могу придумать.
- Как я понимаю, на каждую строку нужен свой КА, состояния которого будет
- переключать соотвествующая кнопка.
- Получается, что для каждой строки нужна функция отображения каждого параметра.
- Как-то это накладно, но ничего умнее пока придумать не могу.
- хватило бы оперативки...
- ---
- 2016.07.28
- Сделал переключение режимов построчно.
- Пора подумать о сохранении настроек в eeprom.
|