Поиск

Резюме и био автора Несколько статей, связанных с моим хобби - робототехника
Мои впечатления об иммиграции в Австралию. В русском языке. Рецепты для ежедневного решения проблем
Linux должности, связанные с Windows, должности, связанные с
Программное обеспечение должности, связанные с Большое количество информации об аппаратном
Различные инструменты могут оказаться полезными Сообщения о различных веб-технологий
Все, что не вписывается в остальной части меню RSS лента этого блога

Облако тегов

Архив

Связи

Андрей Михальчук Блог

English flagItalian flagKorean flagChinese (Simplified) flagPortuguese flagGerman flagFrench flagSpanish flagJapanese flagRussian flagDanish flagFinnish flagHebrew flag

Technoblog о жизни

20 июня 2011 Чтение ATtiny85/45/25 Внутренний датчик температуры

ATtiny85 has internal temperature sensor

Attiny85 имеет встроенный датчик температуры

Я работаю на одном из моих проектов RTFMs видеоблоге (проверьте http://rtfms.com ), что требует измерения температуры в очень маленькой упаковке. Естественно, мой выбор Attiny85 - удивительный маленький чип с AVR, что помимо других товаров (например, 6-канальный ШИМ, последовательный интерфейс и т.д.), имеет встроенный датчик температуры. Поэтому я решил использовать один. Это было не легко, но после нескольких часов копания форумов и таблицы, я пришел с классом, который делает работу с весьма впечатляющим надежность и точность.


Прежде всего, чтобы выполнить этот код нужно Arduino-Tiny ( http://code.google.com/p/arduino-tiny/ ) основные и некоторые виды услуг Интернета. Я использую Arduino Duemilanove в качестве провайдера. Смотрите мой блог RTFMs для более подробной информации о том, как заставить ее работать так, как загрузить ядро ​​правильный и т.д. Насколько мне известно все популярные ядер будет нормально работать с этим кодом. Я только рекомендую Arduino-Tiny из-за своей богатой функциональности, которая может быть использована для развязывания более силы Attiny85.
Решение состоит из двух файлов, которые вы можете скопировать в свой проект. Просто CopyPaste их с этой страницы:

InternalTemperatureSensor.h

# IFNDEF _INTERNAL_TEMPERATURE_SENSOR_H_
# Define _INTERNAL_TEMPERATURE_SENSOR_H_

# Define TEMPERATURE_SAMPLES 30
# Define TEMPERATURE_ADJUSTMENT -13
# Define EXTREMES_RATIO 5

# Define MAXINT 32767
# Define MININT -32767

/ *
* На основе образцов:
* - Внутренний датчик температуры имеет ужасные отклонения. Его выход колеблется много (+ / -10 градусов / сек), поэтому требуется
* Некоторое "сглаживание". Я удаления экстремальных значений и работает прокатки ср на все остальное. Это возвращает нормально
* Результаты на 20 образцов и многое другое. Вы можете уменьшить количество проб, уменьшить время отклика, но это
* Снизит точность.
* - Линейность в порядке и примерно 1.0 в качестве таблицы обещал
* - Смещение необходимо рассчитать для каждого чипа в отдельности и представлены в c'tor
*
* Для того, чтобы компенсировать calaculate подключению терминала к контакту 2 (Serial TX) 9600 8N1 и использовать
* Temperature.print () вызова метода. Это выведет показания температуры. Матч его от вашего
* Калиброванный термометр прилагается к чипу. Отрегулируйте Тос в c'tor если это необходимо.
* См. главу 17,12 в Attiny85 данные для немного более подробной информации
* /

Класс InternalTemperatureSensor {
int offset;
плавать коэффициент;
Int чтений [TEMPERATURE_SAMPLES];
Int POS;

общественности:
InternalTemperatureSensor (флоат-к, Int п): смещение (о), коэффициент (К), POS (0) {}
/ / Вызываем его каждый раз, когда вам нужно подготовить чип читать датчиков (например, в настройках)
/ / Если вы используете другой АЦП, кроме температуры называют его перед каждым показания температуры
недействительными инициализации ();
/ / Возвращает текущую средняя температура в LSB
Int in_lsb ();
/ / Возвращает текущую средняя температура в градусах Цельсия
Int in_c ();
/ / Возвращает текущую средняя температура в градусах по Фаренгейту
Int in_f ();
/ / Возвращает текущую средняя температура в градусах Кельвина
Int in_k ();
/ / Возвращает текущую температуру сырого чтения из датчика
Int сырье ();
/ / Выводит текущие показания температуры в различных форматах
аннулировать печати ();
};
# ENDIF / / _INTERNAL_TEMPERATURE_SENSOR_H_

InternalTemperatureSensor.pde

# Include "InternalTemperatureSensor.h"

пустота InternalTemperatureSensor :: Init () {
/ / AnalogReference (INTERNAL1V1);
/ / Attiny85 данные P140 (17.13.2), Р137 (17.12)
/ / Настройка ADMUX
ADMUX = B1111 / / Выбор датчика температуры
ADMUX & = ~ _BV (Adlar) / / Правой кнопкой регулировки результат
ADMUX | = _BV (REFS1) / / Set работе напряжение
ADMUX & = ~ (_BV (REFS0) | _BV (REFS2)) / / в 1,1
/ / Настройка ADCSRA
ADCSRA & = ~ (_BV (ADATE) | _BV (АРЭИ)) / / Отключить autotrigger, отключение прерываний
ADCSRA | = _BV (Аден) / / Включение АЦП
ADCSRA | = _BV (ADSC); / / Начало первого преобразования
/ / Образцов семян
Int raw_temp;
в то время как (((= raw_temp сырье ()) <0));
для (INT = 0; я <TEMPERATURE_SAMPLES, я + +) {
показания [г] = raw_temp;
}
}

Int InternalTemperatureSensor :: in_lsb () {
Int readings_dup [TEMPERATURE_SAMPLES];
Int raw_temp;
/ / Запомним образец
если ((= raw_temp сырье ())> 0) {
показания [поз] = raw_temp;
POS + +;
POS% = TEMPERATURE_SAMPLES;
}
/ / Копировать образцы
для (INT = 0; я <TEMPERATURE_SAMPLES, я + +) {
readings_dup [я] = показания [г];
}
/ / Пузырь крайности конца массива
Int extremes_count = TEMPERATURE_SAMPLES / EXTREMES_RATIO;
Int подкачки;
для (INT = 0; я <extremes_count; + + я) {/ / процентов итераций пузырьковой сортировки на малых N работает быстрее, чем Q-рода
для (INT = 0; у <TEMPERATURE_SAMPLES - 1, J + +) {
если (readings_dup [я]> readings_dup [+1]) {/ / может быть сделано с 3 операцию XOR и не подкачки, если вы хотите фантазии
поменять = readings_dup [г];
readings_dup [я] = readings_dup [+1];
readings_dup [+1] = поменять;
}
}
}
/ / Средняя середине массива
Int sum_temp = 0;
для (INT I = extremes_count, я <TEMPERATURE_SAMPLES - extremes_count, я + +) {
sum_temp + = readings_dup [г];
}
вернуться sum_temp / (TEMPERATURE_SAMPLES - extremes_count * 2);
}

Int InternalTemperatureSensor :: in_c () {
вернуться in_k () - 273;
}

Int InternalTemperatureSensor :: in_f () {
вернуться in_c () * 9/5 + 32;
}

Int InternalTemperatureSensor :: in_k () {
вернуться in_lsb () + смещение;! / / для simplicty я использую = 1, используйте следующую строку, если вы хотите К = 1,0
/ / Возврат (INT) (in_lsb () * коэффициент) + смещение;
}

Int InternalTemperatureSensor :: сырье () {
если (ADCSRA и _BV (ADSC)) {
возвращается -1;
{} Другое
Int отставке = ADCL | (ADCH << 8) / / получить прежний результат преобразования
ADCSRA | = _BV (ADSC) / / Начать новую преобразования
вернуться в отставке;
}
}

пустота InternalTemperatureSensor :: Print () {
Serial.print ("> R");
Serial.print (сырье (), DEC);
Serial.print ("L");
Serial.print (in_lsb (), DEC);
Serial.print ("K");
Serial.print (in_k (), DEC);
Serial.print ("C:");
Serial.print (in_c (), DEC);
Serial.print ("F");
Serial.print (in_f (), DEC);
Serial.println ("#");
}

Использование

InternalTemperatureSensor температуры (1,0 TEMPERATURE_ADJUSTMENT) / / Аргументы 1.0 игнорируется по умолчанию, см. комментарии c'tor
пустота установки () {
temperature.init (); / / Вызов инициализации () в настройках или каждый раз после изменения ADCSRA или ADMUX
}

пустота цикла () {
/ / Temperature.print (); / / раскомментируйте для отладки датчика выход через последовательный порт
Int war_sensor_data = temperature.raw (); / / Это возвращает только использовать выходной сигнал датчика
Int temperature_in_celsius = temperature.in_c (); / / Это возвращает более удобным температуры в градусах Цельсия
}

Объяснение

ATtinyX5 использует ADC4 для чтения данных из внутреннего датчика. В инициализации () метод все необходимые магии с регистрами делается, чтобы подготовить систему для чтения этих данных. Вы должны вызывать этот метод каждый раз, когда вы хотите настроить ADMUX и ADCSRA для получения данных температурного датчика. Если единственный канал АЦП вы используете в своей программе ADC4 температура датчика, то вы должны вызывать только его настройки (), т.е. один раз. Это снижает температуру процедура чтения времени по крайней мере, фактор два.

Метод InternalTemperatureSensor :: сырье () возвращает необработанные данные от датчика. К сожалению, эти данные едва ли использовать. Чтобы проиллюстрировать эту проблему взглянем на выходе из InternalTemperatureSensor :: Print () метод отладки. В первой колонке то, что возвращается датчика. Выходной уровень составляет около 5 строк в секунду, так что в течение 2 секунд датчик возвращаемых значений на 18 градусов разницы.

ATtiny85 Internal Temperature Sensor Readouts

Attiny85 внутренних Показания датчика температуры


Для того чтобы сделать эти данные более удобным методом InternalTemperatureSensor :: in_lsb это скользящее среднее и устраняет крайности от входа. Результат вы можете видеть на картинке выше: in_lsb выход помечены как L: это способ более удобным. Это более точно также. Вы можете настроить параметры скользящего среднего, но в целом я не рекомендую делать TEMPERATURE_SAMPLES менее 20 и больше 50. Если она меньше 20, то отклонение существенно возрастает. Создание TEMPERATURE_SAMPLES больше 50 не улучшает точность, но отходы памяти и замедляет вычисления. Также EXTREMES_RATIO определяет, сколько крайние значения будут рубится, не делает ее менее чем за 2 (что позволит устранить все значения). Что делает его более эффективным будет TEMPERATURE_SAMPLES предотвратить удаление из крайности образцов.
В дополнение к этим 3 метода ядро ​​несколько вспомогательных методов in_c (), in_k (), in_f () предоставляются. Они возвращают температуру в градусах Цельсия, Фаренгейта и Кельвина.

Еще одна проблема, с внутренним датчиком, что он не откалиброван, поэтому для каждого чипа необходимо использовать печать () для вывода данных и настроить второй параметр конструктора, чтобы соответствовать этим ценностям с помощью калиброванного термометра. Значение -13 в исходный код работает только для одного из моих ATtinies, нет никакой гарантии, он будет работать для других.
Общий внутренний датчик можно использовать, но не ожидайте многого от него. Внешние датчики все еще намного лучше.

Это сообщение опубликовано в оборудование , робототехника .

Нет комментариев

Комментариев пока нет

Оставить комментарий

Карта сайта (С) Андрей Михальчук, 2005-2008