** Проект 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-"
В двойных режимах менять отображаемый параметр по таймеру.

Обработка кнопок.
Каждая кнопка коротким нажатием переключает отображаемую величину своей строки.
Что повесить на длинное нажатие -- не могу придумать.
Как я понимаю, на каждую строку нужен свой КА, состояния которого будет
переключать соотвествующая кнопка.
Получается, что для каждой строки нужна функция отображения каждого параметра.
Как-то это накладно, но ничего умнее пока придумать не могу.
хватило бы оперативки...
