Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Неверный результат измерения потреблённой энергии
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
Motion
Добрый день.

Есть регулятор мощности (диммер). В самом устройстве есть возможность измерения потребляемой энергии в кВт*ч. Но результат измерения не является истинным.

Мощность нагрузки (лампы накаливания) - 150Вт.

Схема устройства - Нажмите для просмотра прикрепленного файла (вообше сделана в Visio, но можно открыть и через Internet Explorer)


Схема состоит из:

- Блока защиты (FU1, R1) - защита от перенапряжения и сверх тока
- Входного фильтра (C1, L1, C3, C4, C5) - для подавления помех исходящих из сети и помех, которые генерирует само устройство
- Блок синхронизации (R3, R4, R5, VD2, VD3, R8) на выходе генерирует меандр. Используется для сигнализации МК (ATMega 16) о пересечении нуля.
- Ключевой элемент (VS1, DA2, R6, R18) - ключ и драйвер к нему для управления мощностью нагрузки
- Датчик напряжения (R7=10КОм, R9=1360КОм, R10=10КОм). При 0В на входе - 1,28В на выходе датчика. Таким образом возможно измерения напряжения как положительной так и отрицательной полуволны.
- Датчик тока (R11=40кОм, R12=40кОм, R13=10кОм, R14=0.1Ом, R16=10кОм, R17=20кОм, DA3 ) - происходит усиление сигнала с шунта R14 в 2 раза. При токе 0А - на выходе датчика 1,28В.
- Внутренний источник питания (DA1) - AC/DC конвертер на +5В.
- МК ATmega 16 (DD1) - для управления симистором и измерения потребляемой энергии

X2 - разъём для подключения нагрузки
Vref=2.56В

Результаты измерения такие:

0% 10 сек 5.8343192677057230e-7 кВт*ч
0% 20 сек 8.0240965871780650e-7 кВт*ч
0% 30 сек 1.1658407856884878e-6 кВт*ч

10% 10 сек 2.3212598989630350e-6 кВт*ч
10% 20 сек 4.5253750613483135e-6 кВт*ч
10% 30 сек 6.8126664700685070e-6 кВт*ч

30% 10 сек 5.3651533562515400e-6 кВт*ч
30% 20 сек 1.0688728252716828e-5 кВт*ч
30% 30 сек 1.5965944839990698e-5 кВт*ч

60% 10 сек 1.1322937098157126e-5 кВт*ч
60% 20 сек 2.3698581571807154e-5 кВт*ч
60% 30 сек 3.6179320886731150e-5 кВт*ч

90% 10 сек 8.4226830949774010e-6 кВт*ч
90% 20 сек 1.6873924323590472e-5 кВт*ч
90% 30 сек 2.5354749595862813e-5 кВт*ч



60% 60 сек 1.0975133045576513e-4 кВт*ч
60% 300 сек 5.5118359159678220e-4 кВт*ч
60% 600 сек 1.0919348569586873e-3 кВт*ч

90% 60 сек 1.1617362179094926e-4 кВт*ч
90% 300 сек 5.8644410455599430e-4 кВт*ч
90% 600 сек 1.1541526764631271e-3 кВт*ч

Результат может отличаться на порядок и даже больше от теоретически расчитаного. Например для 60% 10 сек теоретически результат должен получиться E=P*t= (0.150/100)*60 кВт * (10/3600)ч = 0.09 кВт * 0.0027 ч = 0.00025 кВт*ч = 2.5 * е-4 кВт*ч. А результат измерения получился - 1.1322937098157126e-5

А если к примеру сравнить результат измерения 60% 30 сек и 90% 30 сек. Теоретически во втором случае количество потреблимой энергии должно быть на 30% больше. Но согласно результату измерения - при 90% киловат-часов получилось меньше.

Не могу понять почему так получается.

Программа - Нажмите для просмотра прикрепленного файла

В работе самого регулятора я уверен. Так как при изменении мощности можно визуально это отследить.
Есть пару осцилограмм. Смотрел работу устройства в реальном времени с помощью осцилографа. Всё чётко отрабатывается. Сначала плавный пуск - площадь синусоиды плавно растёт до номинального значения. Потом происходит само регулирование. Есть даже пару осцилограмм на нагрузке:

Нажмите для просмотра прикрепленного файла для 90% мощности

Нажмите для просмотра прикрепленного файла для 50% мощности

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

В ближайшее время возможности посмотреть осцилограммы нет.

То есть проблем с железом вроде не должно быть. Значит скорее всего что-то с программой.

Это мой первый проэкт. Другого опыта не имею.

Прошу помощи у вас, участников форума. Так как сам уже несколько недель безрезультатно не могу ничего сделать.

В чём может быть ошибка/ошибки?
Flasher
Можно для начала схему в удобоваримом формате для общей конструктивной критики?
Dog Pawlowa
Цитата(Flasher @ Apr 29 2008, 23:09) *
Можно для начала схему в удобоваримом формате для общей конструктивной критики?

Еще лучше для начала узнать используемые принципы измерения мощности.
rezident
Цитата(Dog Pawlowa @ Apr 30 2008, 02:19) *
Еще лучше для начала узнать используемые принципы измерения мощности.
+1. И вообще алгоритмы подсчета электроэнергии можно проверить отдельно от алгоритмов измерения и преобразования физ. величин.
_Pasha
Не нашел, где Вы считаете RMS для тока и напряжения smile.gif
MaslovVG
1. Каким прибором измеряете мощность и годится ли он для измерения мощности несинусоидалного тока.
2. Нельзя забывать что мощность есть функция времени. Если речь идет о средней мощности то
Pср. = {(интеграл от U*I*dT)в интервале от 0 до T} / T.
где U и I МГНОВЕННЫЕ значения тока и напряжения.
и средняя мощность не равна произведению среднего тока на среднее напряжение. (для сигналов произвольной формы.)
MrYuran
Интересно, а что подразумевается под "90% мощности"?
Если считать, что на лампочке сдвига фазы нет (вполне вероятно), то мощность - это квадрат площади под синусоидой (с точностью до коэффициента)
Если подразумевается, что 90% мощности соответствует углу включения симистора, равному 10% от полуволны, то это в корне неверно. Сравните площадь отсечённого кусочка и площадь оставшейся синусоиды - вряд ли они соотносятся как 1/9

частный случай - 50%.
Там мощность делится пополам, как ни крути
Motion
Цитата
Можно для начала схему в удобоваримом формате для общей конструктивной критики?

Нажмите для просмотра прикрепленного файла

Цитата
Еще лучше для начала узнать используемые принципы измерения мощности.


Мне необходимо померять работу или энергию.

А (работа)=P (мощность) * t (время)

Нажмите для просмотра прикрепленного файла

То есть я измеряю площадь подкривой, которая равна энергии. На рисунке нарисована синусоида. На самом же деле, график изменения мгновенной мощности будет пропорционален квадрату напряжения или квадрату тока.

Общий принцип такой - периодически (200 раз за период сетевого напряжения) меряю мгновенное значение тока и напряжения, перемножаю их и домножаю на дельта t. Это и есть количество энергии(площадь) за определённый промежуток времени.


Цитата
Не нашел, где Вы считаете RMS для тока и напряжения

Я считаю среднеквадратические значения тока и напряжения. А зачем их считать?

Цитата
1. Каким прибором измеряете мощность и годится ли он для измерения мощности несинусоидалного тока.

В моём устройстве есть МК и датчики тока и напряжения. Я меряю мощность с их помощью. Проверяю измерянную мощность с теоретическим расчётом.

Цитата
Нельзя забывать что мощность есть функция времени. Если речь идет о средней мощности то
Pср. = {(интеграл от U*I*dT)в интервале от 0 до T} / T.
где U и I МГНОВЕННЫЕ значения тока и напряжения.

Я меряю ту мощность, что меряет обычный бытовой счётчик. То есть киловатт-часы. По-моему это и есть средняя мощность.

Цитата
Интересно, а что подразумевается под "90% мощности"?

У меня устройство регулятор мощности. Он регулирует мощность на нагрузке. Если написано 90% мощности, то это значит, что к нагрузке прилаживается 90% от полной возможной мощности.

Цитата
Если подразумевается, что 90% мощности соответствует углу включения симистора, равному 10% от полуволны, то это в корне неверно. Сравните площадь отсечённого кусочка и площадь оставшейся синусоиды - вряд ли они соотносятся как 1/9

Мощность регулируется с помощью фазового регулирования (времени отпирания симистора после пересечения синусоиды 0). Это время рассчитывалось так, чтобы при 90% мощности на нагрузке было приложено 90% площади синусоиды. И здесь время открытого состояния симистора не равно 1/10 полупериода синусоиды.
tyro
Цитата(Владимир_КПИ @ Apr 30 2008, 11:55) *
Я меряю ту мощность, что меряет обычный бытовой счётчик. То есть киловатт-часы. По-моему это и есть средняя мощность.

Обычный бытовой счетчик считает потребленную энергию, а не мощность. Киловат-часы - и естественно никак не средную мощность. Наверное стоит вспонить свой диплом диплом, который Вы недавно писали. smile.gif
MrYuran
попробуйте подключить снаружи какой-нибудь мощиметр и сравните результаты ваших теоретических изысков с показаниями прибора
MaslovVG
Цитата
Общий принцип такой - периодически (200 раз за период сетевого напряжения) меряю мгновенное значение тока и напряжения, перемножаю их и домножаю на дельта t. Это и есть количество энергии(площадь) за определённый промежуток времени.


Теперь сложи их все и подели на период

Цитата
Я считаю среднеквадратические значения тока и напряжения.


А это зачем? Мощность не есть произведение средне квадратичных значений.

Цитата
В моём устройстве есть МК и датчики тока и напряжения. Я меряю мощность с их помощью.


А как ты обеспечиваешь что ток и напряжение измерены в один и тотже момент времени Двумя АЦП?
Motion
Цитата
Обычный бытовой счетчик считает потребленную энергию, а не мощность.

Точно, а я такой бред понаписывал.

Цитата
В моём устройстве есть МК и датчики тока и напряжения. Я меряю мощность с их помощью. Проверяю измерянную мощность с теоретическим расчётом.


Нужно - В моём устройстве есть МК и датчики тока и напряжения. Я меряю энергию с их помощью. Проверяю измерянную энергию с теоретическим расчётом.

Цитата
Я меряю ту мощность, что меряет обычный бытовой счётчик. То есть киловатт-часы. По-моему это и есть средняя мощность.


Нужно - Я меряю энергию, которую меряет счётчик. Единица измерения - киловатт-часы.


Цитата
Наверное стоит вспонить свой диплом диплом, который Вы недавно писали.

Что вы хотите этим сказать? Что диплом писали вы? Я благодарен вам и другим участникам форума за огромную помощь при написании диплома (объяснения, части рабочих схем). Из всего потока (30 человек) лишь 3 человека что-то собирали по своему диплому. И я сомневаюсь, что я бы что-то собрал и оно реально заработало без посторонней помощи. Вы так написали, как будь-то подразумевали, что диплом писал не я , а кто-то другой.

Диплом был успешно сдан. Но разработанное устройство планируется использоваться. Но чтобы оно полностью работало согласно ТЗ, необходимо реализовать программную часть измерения энергии. Что на данный момент я и пытаюсь сделать.


Цитата
А это зачем? Мощность не есть произведение средне квадратичных значений.


Я имел ввиду "я не считаю среднеквадратические значения тока и напряжения. А зачем их считать? ". Спешил и пропустил "не".

Цитата
А как ты обеспечиваешь что ток и напряжение измерены в один и тотже момент времени Двумя АЦП?

Я меряю одним АЦП, но в разное время. Сначала ток, потом напряжение. Время между двумя измерениями пренебрежительно мало. Не один из сигналов за это время значительно не измениться.

Цитата
Теперь сложи их все и подели на период

А зачем делить на период? Ведь мне нужна площадь, а не среднее значение.

Цитата
попробуйте подключить снаружи какой-нибудь мощиметр и сравните результаты ваших теоретических изысков с показаниями прибора

У меня нет такой возможности
bzx
2 Владимир_КПИ
А каналы I & U откалиброваны?
Dog Pawlowa
Цитата(Владимир_КПИ @ Apr 30 2008, 13:20) *
Похоже, проблема с измерениями или расчетами. Может, переполнение происходит или еще что. Вообще-то мне казалось, что AVR не тянет по быстродействию/точности АЦП для таких измерений.
Motion
Цитата
А каналы I & U откалиброваны?


Нет, а что это значит?

Цитата
Вообще-то мне казалось, что AVR не тянет по быстродействию/точности АЦП для таких измерений.


Почему нет?
demaven
Уважаемые, из всего выше прочитанного я так и не понял, уловил ли автор топика разницу между МОЩНОСТЬЮ и ЭНЕРГИЕЙ, между показаниями "мощометра" и счетчика. Или я не прав?
Motion
Цитата
Уважаемые, из всего выше прочитанного я так и не понял, уловил ли автор топика разницу между МОЩНОСТЬЮ и ЭНЕРГИЕЙ, между показаниями "мощометра" и счетчика. Или я не прав?


P=A/t (количество работы за единицу времени)

E=P*t=A/t*t=A (работа)
galjoen
'Владимир_КПИ', а если ток =0, а напряжение имеется, или наоборот - ваш счётчик ничего не считает? Это я к тому, что нули-то верно выставлены? И как вы нули тока и напряжения настраивали?
bzx
Бардак в голове у Вас Владимир, Вы не понимаете что делаете, а отсюда и не срастается Ваша ”теория” c практикой. Вы пишите
Цитата(Владимир_КПИ @ Apr 30 2008, 12:55) *
Я считаю среднеквадратические значения тока и напряжения. А зачем их считать?

В ступор такие вопросы ставят после утверждения, что считается rms. Ради интереса посмотрел исходник. Да, действительно берётся выборка мгновенных токов и напряжений и далее делается совсем непонятная манипуляция
Код
per=(((current*voltage)/1000)*(t/3600));

это не мощьность.

По поводу калибровки.
Цитата(Владимир_КПИ @ Apr 30 2008, 15:02) *
Нет, а что это значит?

А с чего Вы взяли, что измеренным токам и напряжениям можно верить? В коде у Вас есть место
Код
voltage=(u-1.28)*136;

если кратно, то 1,28 - смешение 0, а 136 масштабный коэффициент, то бишь, калибровочный коэффициент, и естественно, он будет свой для каждой вашей железки. Как калибровать - подать эталон, для тока - эталон тока, для напряжения - эталон напряжения, для мощности - эталон мощности, для энергии - эталон энергии.
В общем, почитайте что-нибудь по метрологии, хотя бы парочку статей.
Motion
Цитата
'Владимир_КПИ', а если ток =0, а напряжение имеется, или наоборот - ваш счётчик ничего не считает? Это я к тому, что нули-то верно выставлены? И как вы нули тока и напряжения настраивали?


Решил проверить с помощью тестера что же у меня на ножках МК, отвечающих за измерения тока и напряжения. Удивился результату. Во первых при касании к земляному выводу (земля АЦП, вывод 31 для ATmega 16) щупом тестера у меня как бы произошла перезагрузка МК. На мгновение свет погас, произошёл плавный пуск и установился заданый угол регулирования. Но не при каждом касании такое происходит.

Потом проверил всё же напряжение - показывает по 2В на каждой из ножек в не зависимости от % мощности. Странно... Тестером мерял в режиме "переменка".
Если мерять в режиме "постоянка" - меряет 1,23 для тока и 1,28В для напряжения.

Следавательно, "виртуальный ноль" выставлен правильно. А вот почему при разных значениях мощности сигнал на датчиках не меняется, пока не понял. Тот же датчик напряжения (обычный делитель) просто обязан менять выходное значение в зависимости от входного напряжения.

Буду проверять электрические связи и само "железо".

Цитата
Бардак в голове у Вас Владимир, Вы не понимаете что делаете, а отсюда и не срастается Ваша ”теория” c практикой. Вы пишите


Я уже писал выше, что я не считаю rms. Я пропустил "не" перед словом считаю. Да и можно было догадаться по смыслу следующего предложения, что я не измеряю rms.

Цитата
per=(((current*voltage)/1000)*(t/3600));

Это не мощность, а энергия в киловатт-часах.

Цитата
Как калибровать - подать эталон, для тока - эталон тока, для напряжения - эталон напряжения, для мощности - эталон мощности, для энергии - эталон энергии.
В общем, почитайте что-нибудь по метрологии, хотя бы парочку статей.


Я когда-то ещё не подключая устройство к сети запитывал МК и ОУ напряжением +5В от батареек. В итоге запустился МК, на ножке Vref получилось 2,56В, которые появились в нужных местах на датчике тока и напряжения. В итоге на ножках МК измерения тока и напряжения с датчиков у меня получилось по 1,28В. Я и решил, что так как входное напряжение отсутствует, что эквивалентно 0% мощности значит "виртуальный ноль" выставлен у меня верно и точно.


Вообщем нужно мне тщательно проверить "железо", отвечающее за измерение. Что-то там не так.
tyro
Цитата(Владимир_КПИ @ Apr 30 2008, 13:20) *
Что вы хотите этим сказать? Что диплом писали вы?

Мне почему-то все время кажется, что диплом Вы писали не для себя, а например для своей подруги. smile.gif
Motion
Цитата
Мне почему-то все время кажется, что диплом Вы писали не для себя, а например для своей подруги.


smile.gif

На самом деле диплом писался для себя, а устройство разрабатывалось для кафедры.
demaven
на токе-напряжении сложной формы, имеющем место быть в Вашей схеме, делать выводы по ОДНОМУ замеру тока и напряжения нельзя, необходимо, по крайней мере за один период замерить достаточно много раз ток и напряжение с помощью АЦП, а затем призвать на помощь математику и обсчитать полученные результаты. Делать измерения с помощью тестера не есть правильно
Motion
Цитата
на токе-напряжении сложной формы, имеющем место быть в Вашей схеме, делать выводы по ОДНОМУ замеру тока и напряжения нельзя, необходимо, по крайней мере за один период замерить достаточно много раз ток и напряжение с помощью АЦП, а затем призвать на помощь математику и обсчитать полученные результаты. Делать измерения с помощью тестера не есть правильно


1. Я вспомнил - я точно смотрел осцилограмы на измерительных выводах МК и они были правильны - при изменении мощности нагрузки, сигналы на них пропорционально менялись. Значит что-то я не то тестером меряю.

2. Я не знаю как меряет тестер. По-идее у него внутри есть АЦП. Он ведь показывает действующее значение. А оно должно меняться при изменении формы сигнала(мощности нагрузки).
Alex11
Тестер, если на нем не написано TrueRMS, при не синусоидальной форме сигнала измеряет температуру воздуха в Лондоне. А если написано, то как повезет, в зависимости от производителя. То, что у Вас при отсутствии тока в нагрузке растет показание с увеличением времени, означает, что нули выставлены не совсем верно. Далее, как Вам уже писали, откалибруйте каналы измерения. Отключите симистор, подайте регулируемое постоянное напряжение от внешнего источника (его можно измерить приличным вольтметром с хорошей точностью), установите несколько значений и сравните показания своего АЦП и действительные значения тока и напряжения.
И еще. Я не смотрел Вашу схему - замечание для профилактики - есть ли у Вас на входе АЦП RC-цепочка? Дело в том, что там могут быть довольно большие помехи на фронтах включения симистора, АЦП будет показывать все что угодно, потом это сильно скажется на результате.
Motion
Цитата
Тестер, если на нем не написано TrueRMS, при не синусоидальной форме сигнала измеряет температуру воздуха в Лондоне.



На нём такой записи не нашёл. Тестер Goldtool GSM-880.

Цитата
есть ли у Вас на входе АЦП RC-цепочка?

Да, на выходе каждого датчика стоит RC-фильтр(1 кОм, 1 нФ). Когда смотрел осцилограмы, обращал внимание на помехи. Есть небольшие, но явных выбросов нет.


Цитата
Далее, как Вам уже писали, откалибруйте каналы измерения. Отключите симистор, подайте регулируемое постоянное напряжение от внешнего источника (его можно измерить приличным вольтметром с хорошей точностью), установите несколько значений и сравните показания своего АЦП и действительные значения тока и напряжения.


Так и поступлю. О результатах отпишусь.
Stanislav_S
Прежде чем что то мерять и вычислять, неплохо бы что -нибудь почитать из теории. Вот например для начала вот это http://www.analog.com/UploadedFiles/Data_Sheets/ADE7753.pdf, там с картинками и с теорией довольно все понятно разжевано, как мерять и чего вычислять smile.gif
Motion
А можно подать постоянное напряжение 9В с батареек?

Дело в том, что это напряжение пойдёт на нагрузку. Сопротивление лампочки в холодном состоянии 26Ом. Почти к.з. Не взорвутся ли у меня, например, батарейки при включении?
Stanislav_S
Цитата(Владимир_КПИ @ May 1 2008, 19:06) *
А можно подать постоянное напряжение 9В с батареек?

Дело в том, что это напряжение пойдёт на нагрузку. Сопротивление лампочки в холодном состоянии 26Ом. Почти к.з. Не взорвутся ли у меня, например, батарейки при включении?

нет не взорвутся smile.gif
singlskv
Цитата(Владимир_КПИ @ May 1 2008, 18:06) *
А можно подать постоянное напряжение 9В с батареек?

Дело в том, что это напряжение пойдёт на нагрузку. Сопротивление лампочки в холодном состоянии 26Ом. Почти к.з. Не взорвутся ли у меня, например, батарейки при включении?
Обычно, когда Вы например включаете фонарик, никто не взрывается smile.gif
Хотя наверное фонарики разные бывают... smile.gif


Ну а для затравки глянул ваш код:
Цитата
unsigned char EEPROM_read(unsigned int uiAddress) //описание функции чтения из EEPROM
{
#asm("cli");
/* Wait for completion of previous write */
while(EECR & (1<<EEWE))
;
/* Set up address register */
EEAR = uiAddress;
/* Start eeprom read by writing EERE */
EECR |= (1<<EERE);
/* Return data from data register */
return EEDR;
#asm("sei");
}

очень порадовался вот этому:
#asm("cli");
.........
return EEDR;
#asm("sei");

Угадайте что будет после возврата из этой функции...
прерывания будут разрешены ?
Motion
Цитата
Угадайте что будет после возврата из этой функции...
прерывания будут разрешены ?


Верно, прерывания не будут разрешены. Спасибо.

Правильнее будет так:

#asm("cli");
EEPROM_read(....);
#asm("sei");
Motion
Откалибровал таким образом:

Так как регулируемого источника питания у меня нет, в качестве постоянного напряжения использовал напряжение блока питания сканера (около 12В, максимальный ток 1.2А). Входной разъём (220В) к сети я не подключал. В качестве нагрузки использовал резистор номиналом 1кОм. Подал +12В на нагрузку и через 78L05 на питание МК (+5В). В итоге на нагрузке у меня +12В, на питании МК и ОУ +5В, на ножке МК Vref - 2.56В. На измерительных каналах - 1,23В(ADC1 - измерение тока) и 1,28В(ADC2 - измерение напряжения). Все напряжения мерял с помощью тестера. Далее померял с помощью МК "нули". Напряжение получилось 1.2749В. Ток получился - 1.2224В (подправил значение тока в программе, так как ранее считал, что оно должно равняться 1.28В). Потом нашёл ещё одну ошибку - при расчёте напряжения нужно домножать на 272, а не на 136 (там как в схеме не обычный делитель).

После этого померял ток и напряжение на нагрузке. По напряжению я получил 10.9В (при 12.1В входном), а значение тока получилось ещё точнее(сейчас не помню значения).

В итоге могу утверждать, что "нули" выставлены верно (с определённой погрешностью).


Снова провёл серию измерений при разной мощности. Вот что получил:
Нажмите для просмотра прикрепленного файла


Обновлённая версия программы:
Нажмите для просмотра прикрепленного файла

Результат измерения (то, что получаю в ЕЕPROM) декодирую с помощью этой страницы

Ещё лампочка заметно мерцает. Когда устройство ещё ничего не меряло, а просто регулировало мощность - замерных мерцаний не было. Скорее всего мерцания за счёт того, что 200 раз в период меряю значения.

Вот так вот. Что делать дальше - не знаю.
singlskv
Цитата(Владимир_КПИ @ May 6 2008, 15:57) *
Откалибровал таким образом:
Калибровка это конечно хорошо, но обычно, если необходимо, это завершающая
стадия проекта.
Владимир_КПИ,
прога которая у Вас написана выглядит ужасающе...
Эээ, ну просто там и проэктированием в принципе не пахнет, все написано
в стиле "что вижу то и пою..."

Количество принципиальных ошибок при проектировании просто зашкаливает,
видимо поэтому никто и не может/сможет дать Вам рекомендации что с этим делать...

Можно конечно начать дисскусию по конкретным проблемам в Вашем коде, тока
это скорее всего будет малорезультативно, если Вы реально хотите разобраться как это все
нужно делать - упрощайте задачку(на первое время).
В качестве упрощенной задачки могу предложить Вам такое:
по одному каналу АЦП(подключенному к просто делителю) считаем скользящее среднее
показаний АЦП и раз в секунду пишем его в EEPROM.
Тока сделать это нужно так чтобы на время записи(много милисекунд) считывание показаний
АЦП не прекращалось...
После решения подобной задачки, многие вопросы отпадут, а те которые появятся, ну
мы Вам с ними попробуем помочь.

Удачи!
Motion
Цитата
по одному каналу АЦП(подключенному к просто делителю) считаем скользящее среднее
показаний АЦП и раз в секунду пишем его в EEPROM.


Насколько я понял, необходимо постоянно измерять напряжение на канале ADC2 (измерение напряжения нагрузки). Но с какой частотой? И что такое "скользящее среднее
показаний АЦП"? Если это среднее значение, то оно будет приблизительно равно 0.

Сейчас у меня в программе частота измерения 200 раз за период. Может быть это много и из-за этого у меня проблемы. Возможно время измерения постоянно перекрывается с каким-то другим временем. И может из-за этого и мерцает лампочка...

Запись в EEPROM занимает 8.5мс (согласно документации). То есть почти полупериод.

Цитата
Тока сделать это нужно так чтобы на время записи(много милисекунд) считывание показаний
АЦП не прекращалось

Как такое возможно? Если я пишу в EEPROM, я никак в это же время не могу делать что-то другое.
vet
Цитата(Владимир_КПИ @ May 7 2008, 08:57) *
Как такое возможно? Если я пишу в EEPROM, я никак в это же время не могу делать что-то другое.

почему бы нет? есть флаг готовности EEPROM, есть прерывание по завершению записи в EEPROM.
Motion
Цитата
почему бы нет? есть флаг готовности EEPROM, есть прерывание по завершению записи в EEPROM.


Запись будет происходить почти полупериод. За это время нужно провести минимум десяток измерений. Прерывать запись нельзя. Можно измерить одно значение и ждать пока закончиться запись и по завершению записи сохранить результат. Но только 1 результат измерения, а не несколько.
Stanislav_S
Цитата(Владимир_КПИ @ May 7 2008, 12:26) *
Запись будет происходить почти полупериод. За это время нужно провести минимум десяток измерений. Прерывать запись нельзя. Можно измерить одно значение и ждать пока закончиться запись и по завершению записи сохранить результат. Но только 1 результат измерения, а не несколько.

"скользящее среднее" это когда у вас отсчеты АЦП записываются в кольцевой буфер, таким образом у вас в буфере хранится предистория отсчетов на длину буфера а среднее вычисляется для каждого отсчета, путем суммирования всех отсчетов и делением на число N - где N количество элементов в буфере. Кстати какой смысл в том что вы записываете данные в ЕЕПРОМ?
Motion
Скользящее среднее - это среднее арифметическое?


Смысл записи в EEPROM - сохранение результата в случае выключения питания. Запись будет происходить лишь при понижении питании ниже, например, 4В. А так всё будет храниться в ОЗУ.

Сейчас я пишу в EEPROM, чтобы узнать, правильно ли всё подсчитывается.


По поводу кольцевого буфера - мозможна ли независимая работа АЦП и самого МК? То есть АЦП себе меряет и сохраняет результат, а в этот же момент времени происходит запись в EEPROM. Помню читал, что у АЦП существуют 2 режима работы - одиночное измерение и непрерывное. Вы имеете ввиду непрерывный режим измерения АЦП?
Stanislav_S
Цитата(Владимир_КПИ @ May 7 2008, 13:57) *
Скользящее среднее - это среднее арифметическое?
Смысл записи в EEPROM - сохранение результата в случае выключения питания. Запись будет происходить лишь при понижении питании ниже, например, 4В. А так всё будет храниться в ОЗУ.

Да среднее, только оно считается для каждого отсчета, а не для скажем 8. Ну так и записывайте в ЕЕПРОМ, только в случае пропадания питания, это легко отлавливать.
Цитата
Сейчас я пишу в EEPROM, чтобы узнать, правильно ли всё подсчитывается.
По поводу кольцевого буфера - мозможна ли независимая работа АЦП и самого МК? То есть АЦП себе меряет и сохраняет результат, а в этот же момент времени происходит запись в EEPROM. Помню читал, что у АЦП существуют 2 режима работы - одиночное измерение и непрерывное. Вы имеете ввиду непрерывный режим измерения АЦП?

Да возможно, запускайте АЦП в режиме непрерывного преобразования, а в прерывании считайте результат, потом при достижении нужного числа осчетов, выставляйте флаг и уже в фоновой программе производите вычисление мощности.
Motion
Цитата
Да среднее, только оно считается для каждого отсчета, а не для скажем 8.


Не могу понять как это? У меня есть непрерывний меняющийся сигнал напряжения. И я должен периодически измерять мгновенные значения. С какой частотой? И что дальше с ними делать?
vet
я бы предложил при понижении напряжения питания ниже некоторого порога не дожидаться, пока сработает brownout detector, а приостанавливать работу с корректным сохранением всего необходимого.
Motion
Всё-таки я попробовал измерять мгновенные значения не 200 раз за период, а 20 и 40 раз за период. Вот что получил:
Нажмите для просмотра прикрепленного файла

Из результатов видно, что при измерении 20 раз за период результат измерения мощности максимально приближён к истинному результату. Ещё реже проводить измерения нет смысла, так как погрешность будет слишком велика(>10%).

К тому же лампочка перестала мерцать при измерении 20 раз за период(1кГц).

То есть получается, что если слишком часто мерять значения тока и напряжения - что-то происходит, что приводит к мерцанию лампочки и искажению результата.

Теперь нужно понять, почему так происходит.
bzx
Цитата(Владимир_КПИ @ May 7 2008, 15:59) *
Теперь нужно понять, почему так происходит.

Ещё не надоело фигнёй страдать? Начните с малого, как Вам советовали.
Motion
Цитата
Начните с малого, как Вам советовали.

Я не понял сути, что мне нужно делать.
galjoen
Цитата(Владимир_КПИ @ May 7 2008, 17:18) *
Я не понял сути, что мне нужно делать.

1. Почитайте теорию. Хотя-бы соседнюю тему про измерение RMS.
2. Разберитесь с временами. Узнайте чем занимается процессор в каждый момент времени. На что времени уходит больше всего и т.д. Вы пишите на C, поэтому это вам далеко не очевидно. Поставте на неспользуемые выходы процессора светодиоды и, например, в каждой задаче включайте свой и выключайте остальные (кроме обработчиков прерываний). Можно и без светодиодов - осциллографом. Но светодиоды нагляднее. Вообще светодиод очень мощное средство отладки, а у вас на схеме ни одного!
3. Задавайте конкретные вопросы.
Stanislav_S
Цитата(Владимир_КПИ @ May 7 2008, 14:31) *
Не могу понять как это? У меня есть непрерывний меняющийся сигнал напряжения. И я должен периодически измерять мгновенные значения. С какой частотой? И что дальше с ними делать?

Поскольку у вас два канала измерения, то логично будет установить делитель для АЦП на 128, таким образом на канал у вас будет примерно по 6кГц. Заводите АЦП на непрерывный режим работы в прерывании вычисляете скользящее среднее, для начала сделайте это.
singlskv
Цитата(Владимир_КПИ @ May 7 2008, 08:57) *
Как такое возможно? Если я пишу в EEPROM, я никак в это же время не могу делать что-то другое.
когда Вы пишите в EEPROM Вы можете делать все что угодно кроме
второй записи/чтения в EEPROM, запрещать прерывания нужно только на 2 команды запуска
записи в EEPROM.
Ваша основная проблема в том что Вы не можете правильно спроектировать прогу так
что бы все операции работали параллельно, поэтому я и предложил Вам написать тестовую
прогу с чтением/рассчетом данных с АЦП и параллельной записью в EEPROM,
Вам это просто необходимо для того чтобы понять основы проектирования прог в реалтайме,
когда много разных процессов должны работать одновременно(почти одновременно).

Ну а по Вашему коду можно тоже слегка пройтись, раз уж Вы настаиваете... smile.gif
Код
void EEPROM_write(unsigned int addr, unsigned char val) //описание функции записи в EEPROM
{  
#asm("cli");
/* Wait for completion of previous write */
while(EECR & (1<<EEWE))
;
/* Set up address and data registers */
EEAR = addr;
EEDR = val;
/* Write logical one to EEMWE */
EECR |= (1<<EEMWE);
/* Start eeprom write by setting EEWE */
EECR |= (1<<EEWE);
#asm("sei");
}
Это конечно здорово запрещать прерывания перед записью в EEPROM,
НО, учитывая то что запись в EEPROM у Вас вызывается только из прерывания,
очень интересным является #asm("sei"); в конце функции который просто разрешает
нам вложенные прерывания.... 07.gif
Обычно в начале критической части сохраняют текущий статус разрешения прерываний а
потом его восстанавливают, те если было запрещенно то так и должно остаться.

Код
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)      //функция обработки внешнего прерываня по переднему фронту INT0
{
..........................
...........................
  if (count==3000)   //время через которое происходит запись значения мощности в EEPROM (через определённое количество периодов синусоиды)
  {
.......    
  EEPROM_write(addr, *pntr); //пишем в текущую ячейку EEPROM первый байт 32-битного числа float
.......
  EEPROM_write(addr, *pntr); // повторили еще 3 раза
......
  EEPROM_write(addr, *pntr);
......
  EEPROM_write(addr, *pntr);
......
  }
......
как Вы думаете, успеет отработать эта запись 4 байтов (по 8,5мс) до прихода следующего
переднего фронта(20мс)?
А что будет происходить если в функции EEPROM_write мы разрешили вложенные прерывания ?
Код
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
..........
i=(adc_data*2.56)/1024;
.........
u=(adc_data*2.56)/1024;               //сохраниение результата измерения напряжения                
.........
current=((1.2224-i)/2)/0.1;
........
Вы хотя бы примерно представляете сколько времени занимает 1 оперция деления
просто целочисленных 32бит/32бит ? А деление float ?

Ну и в остальных частях проги тоже много чего можно нарыть
- чтение кнопок без фильтрации
- 3 прерывания вместо 1-2 достаточных для такой проги
- все рассчеты только в прерываниях вместо основного цикла
....................

Начинайте с чего-нить попроще, потратите куда как меньше времени на освоение в целом (с) smile.gif
Motion
Цитата
очень интересным является #asm("sei"); в конце функции который просто разрешает
нам вложенные прерывания

Когда я запрещал или разрешал прерывания, я подразумевал, что эти 2 команды разрешают/запрещают глобальное разрешение прерываний (то есть изменение флага I в регистре SREG). Посмотрел в книге - там команда sei, например, означает общее разрешение прерываний. Это ведь ассемблерные вставки. А вы говорите про разрешение/запрешение вложеных прерываний... Что это значит?


Цитата
как Вы думаете, успеет отработать эта запись 4 байтов (по 8,5мс) до прихода следующего
переднего фронта(20мс)?


Это уже не важно, что будет потом. Запись в ЕЕPROM будет происходить лишь при пропадании питания. Сейчас я записывал в EEPROM лишь чтобы узнать правильно ли считается мощность. То есть периодической записи в EEPROM происходить не будет.


Цитата
Вы хотя бы примерно представляете сколько времени занимает 1 оперция деления
просто целочисленных 32бит/32бит ? А деление float ?

Нет, а где можно почитать?


Цитата
А что будет происходить если в функции EEPROM_write мы разрешили вложенные прерывания ?

Получается вложеные прерывания будут разрешины, а общие запрещины? И тогда устройство не сможет нормально работать из-за общего запрета прерываний?


Цитата
чтение кнопок без фильтрации

А что за фильтрация? Вы имеете ввиду антидребезг? Или возможность ложного срабатывания в случае помехи?

Цитата
3 прерывания вместо 1-2 достаточных для такой проги

1 прерывание для синхронизации (INT0)
1 прерывание для таймера0 (для измерения значений)
1 прерывание для таймера1 (для отсчёта угла отпирания)

Кака же можно обойтись одним-двумя?


Цитата
все рассчеты только в прерываниях вместо основного цикла

Если вызвана подпрограмма обработки прерывания, она будет выполняться до конца или её в любой момент может прервать другое прерывание или только прерывание с более высоким приоритетом?


Цитата
Ваша основная проблема в том что Вы не можете правильно спроектировать прогу так
что бы все операции работали параллельно, поэтому я и предложил Вам написать тестовую
прогу с чтением/рассчетом данных с АЦП и параллельной записью в EEPROM,
Вам это просто необходимо для того чтобы понять основы проектирования прог в реалтайме,
когда много разных процессов должны работать одновременно(почти одновременно).

Да, наверное так и есть. Значит буду начинать с более простого(то, что вы предложили).

Но я так и не понял сути, что мне нужно сделать. Нужно паралельно мерять значения напряжения, их каким-то образом обрабатывать (так называемое скольжение) и паралельно со всем этим записывать результат в EEPROM?
singlskv
Уффф... бум отвечать по пунктам:
Цитата(Владимир_КПИ @ May 7 2008, 23:38) *
Когда я запрещал или разрешал прерывания, я подразумевал, что эти 2 команды разрешают/запрещают глобальное разрешение прерываний (то есть изменение флага I в регистре SREG). Посмотрел в книге - там команда sei, например, означает общее разрешение прерываний. Это ведь ассемблерные вставки. А вы говорите про разрешение/запрешение вложеных прерываний... Что это значит?
когда я говорил про 2 команды я имел в виду вот это:
EECR |= (1<<EEMWE);
EECR |= (1<<EEWE);

только эта спецпоследовательность должна выполняться при запрещенных прерываниях,
когда Вы в своей функции EEPROM_write в конце ставите #asm("sei"); Вы разрешаете ВСЕ прерывания...
Цитата
Это уже не важно, что будет потом. Запись в ЕЕPROM будет происходить лишь при пропадании питания. Сейчас я записывал в EEPROM лишь чтобы узнать правильно ли считается мощность. То есть периодической записи в EEPROM происходить не будет.
Про потом это конечно хорошо, но при таком коде Вы никогда не перейдете
к этой самой стадии "потом", Ваш код записи в EEPROM просто мешает фунициклировать правильно
всем прерываниям....
Ну и уже чисто мое ИМХО, это неправильно уповать только на то что Вы успеете записать
многобайтовую переменную в случае пропадания питания, должно быть 2 механизма записи,
1 это привязанное ко времени(типа раз в XXX) второе при пропадании питания, ну
и механизм который разруливает это при старте...
Цитата
Нет, а где можно почитать?
Можно не прочитать а посчитать/просимулировать.
Ваша проблема в том что Вы пытаетесь сразу все посчитать в float и сразу все поделить,
а это нужно делать в самый последний момент, те пока можем, считаем все в целых и
желательно без делений, перевод в float или деления только перед выдачей на экран или
сохранением, хотя если еще чуть подумать, для сохранения это тоже не нужно,
какая разница в каких единицах будет все храниться в EEPROM ?
Цитата
Получается вложеные прерывания будут разрешины, а общие запрещины? И тогда устройство не сможет нормально работать из-за общего запрета прерываний?
выше ответил, будут разрешены ВСЕ прерывания и вложенные в том числе,
и при рассчетах с float прямо в прерывании АЦП Вы явно не всегда будете успевать...

Цитата
А что за фильтрация? Вы имеете ввиду антидребезг? Или возможность ложного срабатывания в случае помехи?
Антидребезг конечно, фильтрация это просто общее название.
Цитата
1 прерывание для синхронизации (INT0)
1 прерывание для таймера0 (для измерения значений)
1 прерывание для таймера1 (для отсчёта угла отпирания)
Кака же можно обойтись одним-двумя?
Если вызвана подпрограмма обработки прерывания, она будет выполняться до конца или её в любой момент может прервать другое прерывание или только прерывание с более высоким приоритетом?
Да, наверное так и есть. Значит буду начинать с более простого(то, что вы предложили).

Ну как минимум 2 из этих задач можно совместить,
ну и еще, подумайте, может чего-нить из этого можно делать и в основной проге ?
про прерывания Вы неправильно поняли, Вы сами разрешаете им быть вложенными,
НО, если Вы им запретите быть вложенными при том софте который есть, станет тока хуже...

Цитата
Но я так и не понял сути, что мне нужно сделать. Нужно паралельно мерять значения напряжения, их каким-то образом обрабатывать (так называемое скольжение) и паралельно со всем этим записывать результат в EEPROM?
Скользящее среднее это очень простая штука, это просто сумма
последних N отсчетов какой-нить меняющейся величины(например показаний АЦП) поделенная на
количество отсчетов N. То есть при получении каждого нового отсчета, мы просто суммируем
последние N отсчетов и делим сумму на N. Нужно просто грамотно организовать хранение
отсчетов и иметь это скользящее среднее в любой момент времени.
Так же нужно раз в секунду записать текущее значение скользящего среднего в EEPROM при этом
не прерывая рассчет скользящего среднего...

Это просто задачка такая, но после того как Вы с ней справитесь, Вам будет намного проще
написать более сложный вариант...

P.S. про кольцевые буферы Вам уже намекнули, ну и делить не всегда необходимо(для хранения)...
_Pasha
Цитата(singlskv @ May 8 2008, 00:30) *
То есть при получении каждого нового отсчета, мы просто суммируем
последние N отсчетов и делим сумму на N.
P.S. про кольцевые буферы Вам уже намекнули, ну и делить не всегда необходимо(для хранения)...


И каждый раз суммировать тоже не обязательно, достаточно при поступлении нового отсчета вычесть из результата скользящего среднего элемент, на который указывает указатель кольцевого буфера, затем записать в буфер новый отсчет и прибавить его к результату. А потом передвинуть указатель. В начальный момент времени у Вас все будет ==0, поэтому до заполнения буфера ничего эдакого делать не надо - все само устаканится.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.