Как стать автором
Обновить

Комментарии 27

Вместо про мини, на макетной плате можно было разместить ATmega328 в DIP, 3-4 кондера и кварц.
Согласен, но тогда уже разводить и травить всю плату целиком.
В ATmega328 есть же встроенный кварц. Правда он менее точен, чем внешний. Може кто подскажет, для каких задач его может не хватить? Скажем генерация ШИМ и подключение по UART или SIP?
Кварца там нет, есть задающая RC-цепочка.
Да, погорячился. Подчерпнул знания из этой статьи:
http://mysku.ru/blog/aliexpress/22070.html
Все-таки хотелось бы знать, когда можно применять встроенный генератор, а когда без внешнего кварца не обойтись. Или лучше экспериментально проверить?
Применять встроенный генератор можно всегда, когда вас устраивает его НЕ стабильность в условиях работы вашего устройства (в документации есть графики зависимости его частоты от температуры и напряжения питания). А ещё есть разбег от экземпляра к экземпляру и есть процедура калибровки этого генератора.
Но есть и плюсы. Например, от встроенного генератора микроконтроллер стартует быстрее, чем от внешнего кварца (его ещё надо раскачать)
Когда нужны стабильные и точные временные интервалы в широком диапазоне температур — использовать только кварц. Встроенный генератор, он хоть и откалиброван но без температурной компенсации(большинство контроллеров) не буде обеспечивать стабильность частоты, и она порой будет гулять +-20% — если устроит такой разгул(для асинхронного UART максимальная ошибка должна быть не более +-2%) тогда МОЖНО использовать встроенный генератор.
Но сейчас как-то даже микросхемы работающие с USB умудряются обходится без кварцевой стабилизации — в основном это происходит за счет постоянной следящей подстройки «по образцу» с хоста.
Спасибо за ответы. Вы меня разубедили использовать встроенный генератор. 20% разброс это как-то многовато, да и откалибровать все и настроить у меня опыта не хватит. Тем более про мини не намного больше места занимает чем голый контроллер в DIP корпусе (ну может раза в 2 шире).
Встроенный, безо всякой калибровки работает «как первый советский трактор», в т.ч. и с UART. Много страхов. Особенно у начинающих, наслушавшихся советов от таких же начинающих.
Не знаю, у меня даже с калибровкой последний бит искажается. и вообще работает нестабильно. А если взять расширенные условия эксплуатации не в комнатных условиях работы то где-то точно работать не будет.
Из 10 штук ATTINY13 из одной партии при питании от 5В разброс был -2% +5% это при том что они откалиброваны на заводе при 20 градусах и +3.3В. Если вот так взять и сделать на них 10-к устройств без дополнительной калибровки то минимум 3 из них не заработают правильно с UART, а 2 из них будут на грани. Изменится температура, и лажающих резко станет больше.
Да, в широком диапазоне температур возможно, но при комнатной проблем не наблюдал. При том что постоянно использую int rc и UART. А если есть возможность калибровки, то какие вообще могут быть проблемы — путей возникновения нестабильности не видно.
А их всего два… напряжение питания и температура, если в даташите не заявлено что генератор термокомпенсированный — например в ATTINY85.
К тому же калибровка очень грубая — один шаг соответствует примерно 1% и его величина сильно зависит от величины калибровки, к тому же меняется не монотонно а пилами. Калибровать можно, но есть проблема — новую калибровочную константу должна использовать прошивка, т.е. это должно быть предусмотрено специально. Для одного экземпляра это не сложно, десяток уже напрягает а когда речь пойдёт о сотне то всё больше посещает мысль о том что дешевле было использовать кварцевый резонатор чем решать эти проблемы. Можно не кварц использовать а пьезокерамику, дешевле но стабильность на уровне всего 3-х знаков.
Ну естественно, тут уже самому нужно решать что проще, что менее затратно/хлопотно. И естественно нужно учитывать область применения. Но говорить однозначно о том что встроенный генератор для УАРТ использовать нельзя, я бы не стал. Ибо практика показывает обратное, моя в т.ч.
Практика показывает, что работает скорей вопреки чем благодаря. Если в схеме есть асинхронный UART то обязательно должен быть кварц(или на худой конец керамический резонатор), одна деталька способна сэкономить кучу времени на поиск «неисправности» в будущем.
По цене DIP с кварцем и прочим дороже встанет, чем PRO MINI. Экономия в месте, если это не SMD монтаж, тоже особая не получится.
А как схемотехнически реализована цепь измерения напряжения на аккумуляторе? Сейчас занимаюсь именно данным моментом и не знаю как сделать так, чтобы через рез. делитель, на выходе которого напруга меньше 1.1В, не утекало больше 10мкА.
Если правильно понимаю вашу задачу, то нужно идти другим путем.
В исходнике эта функция readVcc(). Оригинальная статья недоступна, поэтому под спойлером подробнее.
подробнее
http://blog.unlimite.net/?p=25
Секретный вольтметр в Arduino — измерение напряжения батареи средствами микроконтроллера
Posted on 2014-11-03 by freeman
В основном перевод статьи Secret Arduino Voltmeter – Measure Battery Voltage с некоторыми дополнениями.

Мало известная фишка Ардуино и многих других AVR чипов это возможность измерить внутренний источник опорного напряжения 1.1 В. Эта функция может быть использована для повышения точности функции Arduino — analogRead () при использовании стандартного опорного напряжения 5 В (на платформах с напряжением питания 5 В) или 3.3 В (на платформах с напряжением питания 3.3 В). Она также может быть использована для измерения Vcc, поданного на чип, обеспечивая средство контроля напряжения батареи без использования драгоценных аналоговый выводов.

Мотивация

Есть, по крайней мере, две причины для измерения напряжения, питающего наш Arduino (Vcc). Одним из них является наш проект, питающийся от батареи, если мы хотим следить за уровнем напряжения батареи. Кроме того, когда питание от батареи (Vcc) не может быть 5,0 вольт(например питание от 3-х элементов 1.5 В), а мы хотим сделать аналоговые измерения более точными — мы должны использовать либо внутренний источник опорного напряжения 1,1 В либо внешний источник опорного напряжения. Почему?

Обычно предполагают при использовании analogRead () то, что аналоговое напряжение питания контроллера составляет 5.0 вольт, когда в действительности это может быть совсем не так(например питание от 3-х элементов 1.5 В). Официальная документация Arduino даже может привести нас к этому неправильному предположению. Дело в том, что питание не обязательно 5,0 вольт, независимо от текущего уровня это питание подано на Vcc чипа. Если наше питание не стабилизировано или если мы работаем от аккумулятора, это напряжение может меняться совсем немного. Вот пример кода, иллюстрирующий эту проблему:

double Vcc = 5.0; // не обязательно правда
int value = analogRead(0); / читаем показания с А0
double volt = (value / 1023.0) * Vcc; // верно только если Vcc = 5.0 вольт

Для того чтобы измерить напряжение точно, необходимо точное опорное напряжение. Большинство чипов AVR обеспечивает три источника опорного напряжения:
1,1 в от внутреннего источника, в документации он проходит как bandgap reference (некоторые из них 2,56 В, например ATMega 2560). Выбор осуществляется функцией analogReference() с параметром INTERNAL: analogReference(INTERNAL);
внешний источник опорного наптяжения, на ардуинке подписан AREF. Выбор: analogReference(EXTERNAL);
Vcc — источник питания самого контроллера. Выбор: analogReference(DEFAULT).
В Arduino нельзя просто взять и подключить Vcc к аналоговому пину напрямую — по умолчанию AREF связан с Vcc и вы всегда будете получать максимальное значение 1023, от какого бы напряжения вы не питались. Спасает подключение к AREF источника напряжения с заранее известным, стабильным напряжением, но это — лишний элемент в схеме.

Еще можно соединить Vcc с AREF через диод: падение напряжение на диоде заранее известно, поэтому вычислить Vcc не составит труда. Однако, при такой схеме через диод постоянно протекает ток, сокращая жизнь батареи, что тоже не очень удачно.

Источник внешнего опорного напряжения является наиболее точным, но требует дополнительных аппаратных средств. Внутренний ИОН стабильным, но не точен + / — 10% отклонение. Vcc является абсолютно ненадежен в большинстве случаев. Выбор внутреннего источника опорного напряжения является недорогим и стабильным, но большую часть времени, мы хотели бы измеряет большее напряжение чем 1.1 В, так что использование Vcc является наиболее практичным, но потенциально наименее точным. В некоторых случаях оно может быть очень ненадежным!

Как это сделать

Многие чипы AVR включая серию ATmega и ATtiny обеспечивают средства для измерения внутреннего опорного напряжения. Зачем это нужно? Причина проста — путем измерения внутреннего напряжения, мы можем определить значение Vcc. Вот как:

Установить источник опорного напряжения по умолчанию: analogReference(DEFAULT);. Используем как источник — Vcc.
Снять показания АЦП для внутреннего источника 1.1 В.
Расчитать значение Vcc основываясь на измерении 1.1 В по формуле:
Vcc * (Показания АЦП) / 1023 = 1.1 В

Из чего следует:

Vcc = 1,1 В * 1023 / (Показания АЦП)

Собираем все вместе и получаем код:

long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif

delay(75); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring

uint8_t low = ADCL; // must read ADCL first — it then locks ADCH
uint8_t high = ADCH; // unlocks both

long result = (high<<8) | low;

result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
Использование
Проверка напряжения Vcc или батареи

Вы можете назвать эту функцию – readVcc(), если Вы хотите мониторить Vcc. Примером может служить для проверка уровня заряда батареи. Вы также можете использовать её для определения подключены ли Вы к источнику питания или работаете от батареи.

Измерение Vcc для опорного напряжения

Вы также можете использовать её, чтобы получить правильное значение Vcc для использования с analogRead (), когда вы используете опорное напряжение (Vcc). Пока Вы не используете стабилизированный источник питания, Вы не можете быть уверенны, что Vcc = 5.0 вольт. Эта функция позволяет получить правильное значение. Хотя есть один нюанс….

В одной из статей я сделал заявление, что эта функция может использоваться, чтобы улучшить точность аналоговых измерений в тех случаях, когда Vcc было не совсем 5.0 вольт. К сожалению, эта процедура не будет давать точный результат. Почему? Это зависит от точности внутреннего источника опорного напряжения. Спецификация дает номинальное напряжение 1.1 вольт, но говорится, что оно может отличаться до 10%. Такие измерения могут быть менее точными, чем наш источник питания Arduino!

Повышаем точность

Пока большие допуски внутреннего источника питания 1.1 В. значительно ограничивают точность измерений при использовании в серийном производстве, для индивидуальных проэктов мы можем добиться большей точности. Сделать это просто, просто измерив Vcc с помощью вольтметра и нашей функции readVcc(). Далее заменяем константу 1125300L новой переменной:

scale_constant = internal1.1Ref * 1023 * 1000

где

internal1.1Ref = 1.1 * Vcc1 (показания_вольтметра) / Vcc2 (показания_функции_readVcc())

Это калиброванное значение будет хорошим показателем для измерений AVR чипом, но может зависеть от изменений температуры. Не стесняйтесь экспериментировать с вашим собственным измерениям.

Вывод
С этой маленькой функцией можно сделать многее. Вы можете использовать стабильное опорное напряжение близкое к 5.0 В не имея на самом деле 5.0 В на Vcc. Вы можете измерять напряжение вашей батареи или даже увидеть на каком вы питание от батареи или от стационарного источника питания.

И наконец, код будет поддерживать все Arduino, включая новый Leonardo, а также чипы ATtinyX4 и ATtinyX5 серий.
Отлично! Благодарю.
> на библиотеку TimeLord.h
А с какой точностью она считает время восхода/захода?
В свое время портировал на Atmega2560 библиотеку с диска-приложения к книге Оливера Монтенбрука и Томаса Пфлегера «Астрономия на персональном компьютере».
Так из-за того, что для контроллеров Atmega double=float, погрешность получилась до двух минут.
Я не знаю с какой точностью она считает. В тоже время я не знаю где вообще взять эталонные значения и есть ли они. Все равно для каждой местности все индивидуально, любая возвышенность легко изменит время. Поэтому минута-две вообще роли не играет.
Сравнил значения для моей местности с трех источников
image
Всё ничего, но провода у вас… Это что то. Прям, шланги какие то. Есть же МГТФ тонкий или ему подобные. Ну, просто порнография какая то, ей богу.
Какое энергопотребление? Я не увидел какой либо функции отключения девайса. Было бы логично переводить его в power_down по таймауту, и потому выводить, или idle. А то мне кажется аккумулятора на долго не хватит так.
Пока наблюдаю, 5 дней живет точно. Затем можно и с энергосбережением поиграться.
~9 мА, а с подсветкой ~16 мА
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории