Главная > MSP430 > Touch-candle

Touch-candle

Все началось с того, что примерно полгода назад я по ошибке заказал три штуки MSP430G2121. В этих МК мало памяти и нет почти ничего. Присутствуют только один таймер и USI — полуфабрикат, из которого не сделать даже UART. И потому я долго думал, куда бы их применить. По зрелом размышлении мне показалось, что лучше всего будет произвести что-нибудь сувенирного толка; и в конце концов я сделал электронную свечу, управляемую касанием.

Вот она какая, свеча XXI века:

 

Очевидно, для реализации заявленного в заголовке функционала нужен светодиод и емкостной сенсор. Светодиод, конечно, управляется ШИМом, который MSP430G2121, слава Богу, умеет генерировать аппаратно. Вообще ШИМ, пожалуй, единственная роскошь этого совершенно спартанского кристалла.

Исходя из изложенных соображений я нарисовал такую схему:

Кроме этого, я вывел P1.1 — изначально были планы использовать для отладки UART, а моя софтовая реализация (аппаратного, как я уже говорил, тут нет) использует эту ножку как передающую. Впрочем, она так и осталась неиспользованной. Элементы R3/Q1 — опциональный выход сигнала на что-то внешнее: P2.6 — второй выход ШИМ-канала таймера. Нет, не второй канал, а именно второй выход того же канала, который можно включить программно. В текущей версии прошивки эта функция тоже не используется, и эти детали не запаяны, хотя и разведены.

Итак, теперь о прошивке.

Имитация бликов пламени.

Я провел долгие часы в медитации и размышлениях о том, как же лучше всего имитировать мерцание огня. К слову, я нигде не смог найти ничего удобоваримого на этот счет. Единственное, что попалось — проект тов. ARV. Однако алгоритм, использованный в его устройстве, показался мне слишком упрощенным. Свой алгоритм я создал на основе следующих идей:

1. В отсутствие внешних возмущений свеча стремится установить определенную стабильную яркость.
2. Внешнее возмущение может притушить ее, а может разжечь ярче.
3. Внешние возмущения случайны.
4. Все происходит относительно плавно (ибо природа не любит резких скачков), но хаотично.

Сразу встает вопрос — где же брать энтропию для случайных воздействий? Лучше всего, конечно, было бы поставить микрофон и анализировать поток с него (тогда свечу можно было бы даже задуть). Но в MSP430G2121 нет ни АЦП, ни даже компаратора. И потому я ограничился обычным регстром с линейной обратной связью (LFSR).

Имитируемый отблеск описывается тремя параметрами: текущая яркость, целевая яркость и нормальная яркость. Алгоритм может находиться в двух состояниях. В первом происходит плавная (за один шаг яркость меняется на единицу) установка нормальной яркости и случайный выбор целевой в момент окончания этого процесса; во втором — плавный переход к целевой яркости. Режимы чередуются. Скорость установки каждого уровня яркости также выбирается случайно.

Такой алгоритм, как мне кажется, дает неплохое приближение к мерцанию пламени.

Сенсорное управление

Девайс надо как-то включать и выключать. Однако включать свечу выключателем уж как-то совсем по-постмодернистски. Прикосновение — куда ни шло, подумал я, и прикрутил тач-сенсор (про то, как работают такие сенсоры, хорошо писал Elm Chan). При подаче питания свеча выключена. Если коснуться сенсора, огонек начинает «разгораться». Чтобы было интереснее, реализована следующая логика: если убрать руку слишком рано, свеча «не успеет разгореться» и плавно потухнет. Прикосновение к сенсору при работающей свече приводит к ее плавному затуханию.

Энергопотребление

Поскольку проект делался «just for fun», оптимизация по энергопотреблению не проводилась. В состоянии покоя устройство потребляет около 3.8 мА. В принципе, этот показатель можно снизить, уменьшив тактовую частоту МК. Но тогда могут возникнуть проблемы с определением касания. Да и, в общем, ~4мА тоже не так много.

Заключение

В приложенных файлах есть схема, разводка платы и проект прошивки для IAR. В первой версии платы/схемы была ошибка — я не учел, что в MSP430G2121 нет встроенной подтяжки на выводе сброса, и потому ее пришлось добавлять навесом. В файлах, приложенных к статье, это уже поправлено.

Видео работы (спасибо dcoder):

По многочисленным просьбам почтенной публики я дописал прошивку до версии 1.1. Теперь в режиме ожидания МК потребляет 60мкА, ибо переводится на тактирование от внутреннего генератора частотой 120КГц. Тактирование 15МГц включается раз в секунду для проверки сенсора.

P.S.

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

***

Приложение. Подробное описание алгоритма имитации бликов пламени.

Весь процесс имитации бликов происходит в функции HandleLight(), которая вызывается через промежутки времени upd_interval:

void HandleLight(void)
{
  static uint8_t pwm_value=0,pwm_target=0,set_def=1;
  //pwm_value - текущая яркость
  //pwm_target - устанавливаемая яркость
  //set_def - переключатель режима
  
  if (set_def)
  {
    //Фаза "1" на графике, set_def==1
    //смысл этой фазы - возвратить яркость
    //к значению DEF_BRIGHTNESS
        
    if (pwm_valueDEF_BRIGHTNESS)
      pwm_value--;

    if (pwm_value==DEF_BRIGHTNESS)
    {
      //Как только возвратили - выбираем 
      //новое случайное значение,
      //которого будем достигать во 
      //второй фазе, и переходим
      //ко второй фазе, устанавливая set_def в 0

      set_def=0;
      pwm_target=LFSR_Random();
    }
  }
  else
  { 
    //Фаза "2" на графике, set_def==0
    //Смысл - установить новую яркость, выбранную в фазе "1". 
        
    if (pwm_valuepwm_target)
      pwm_value--;

    //Как только установили - переходим к первой фазе,
    //устанавливая set_def в 1

    if (pwm_value==pwm_target)
      set_def=1;
  }


  //Функция вызывается через промежутки времени upd_interval.
  //Устанавливаем это значение случаным. Т.е., каждый последующий
  //вызов функции выполняется через случайное время.
  
  upd_interval=(LFSR_Random()/2)+10;


  //Обновляем яркость светодиода.
  //TACCR1 - это типа OCR0A в AVR.  
      
  TACCR1=pwm_value;
}

Ее работу можно пояснить следующим графиком:

Таким образом, для портирования нужно подставить вместо TACCR1 регистр, управляющий яркостью диода на целевой архитектуре, и организовать вызов описываемой функции через интервалы upd_interval. Опционально — поменять LFSR_Random() на любой другой источник случайных значений.

Рубрики:MSP430
  1. Комментариев нет.
  1. No trackbacks yet.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s