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_value<DEF_BRIGHTNESS)
      pwm_value++;
    if (pwm_value>DEF_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_value<pwm_target)
      pwm_value++;
    if (pwm_value>pwm_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() на любой другой источник случайных значений.
  • +4
  • 06 ноября 2011, 17:40
  • _YS_
  • 1
Файлы в топике: cdl11.zip

Комментарии (75)

RSS свернуть / развернуть
Переделай схему, тексты на ней совершенно нечитабельны. Ну и настолько простую схему в 700рх уложить мона и без масштабирования.

3.8мА — слишком много. Даже если питать от двух щелочных АА — сожрет за месяц.

Алсо приведи чуть более подробные характеристики камня, количество памяти в частности. Алсо, где и за сколько ты его заказал?
0
  • avatar
  • Vga
  • 06 ноября 2011, 17:51
Переделай схему, тексты на ней совершенно нечитабельны.

ОК. Просто у DipTrace экспорт в картинку — слабое место…

3.8мА — слишком много.

Чтобы уменьшить, уже надо напрягать мозг. А это — конструкция выходного дня.

Алсо приведи чуть более подробные характеристики камня

Самое первое упоминание камня — ссыль на даташит.
0
А это — конструкция выходного дня.
И тем не менее надо довести до конца. Да и вообще, этот камень такой спартанский для минимального энергопотребления. А ты этим-то и не воспользовался.
Самое первое упоминание камня — ссыль на даташит.
Ну, его еще качать и открывать надо...)
0
И тем не менее надо довести до конца.

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

Ну, его еще качать и открывать надо...

1Kb FLASH, 128b RAM, USI, TimerA
0
И ты забыл сказать цену камушка.
0
Алсо, где и за сколько ты его заказал?
И ты забыл сказать цену камушка.

Заказывал в КОМПЭЛ, на тот момент стоил ~40р. Хотел заказать MSP430G2131, но мне по ошибке выписали 2121. Когда разобрался, было уже поздно. :) Тогда еще с AVR проблемы были. А теперь MSP430G2121 стоит ~90р, а ATmega48 44р. :DD Так что я опять использую AVR.
0
Так что этот проект — просто утилизация лишнего камня. :)
0
Щито? в компеле при заказе от 80 шт стоит 24.40 рубля. А один нет смысла заказывать, так как их шлет TI нахаляву 3 шт.
0
Понравилась музыка испанки Maya Filipic :)
Одного не пойму — неужели так сложно завести гугловский аккаунт, чтобы самому заливать видео? Интересная идея со свечой, надо бы попробовать…
0
неужели так сложно завести гугловский аккаунт, чтобы самому заливать видео

Хм… А там аккаунт GMail прокатит?
0
Должен :) Попробуй
0
И таки прокатил!
0
Интересно получилось, но выглядит как-то недоделано. Можно ведь было корпус смастерить и светодиод правильного цвета воткнуть.

Вот www.youtube.com/watch?v=ijpIIxdmRkk

PS Девушка Марина, если вы это читаете — скажите автору, чтоб уменьшил потребление девайса. Нас он не слушает :)
0
Интересно получилось, но выглядит как-то недоделано.

Просто это пробный макет для тестирования алгоритма + утилизация лишнего камня. Потом этот алгоритм пойдет в мой RGB-контроллер линейки диодов. Может, когда нибудь и про него напишу.

чтоб уменьшил потребление девайса

Кардинально уменьшить потребление тут можно только понизив частоту проца. А если ее понизить, будет невозможно опрашивать сенсор — там и так предельное значение около двадцати циклов, и это на 15МГц.
0
Можно, конечно, в idle-режиме переконфигурировать таймер и уходить в SLEEP. а по таймеру просыпаться и глядеть чего там с сенсором. Но это нужно глобально переконфигурировать камень, памяти не хватит. LFSR много занимает.
0
А корпус — это дело наживное. Запаять транзистор, поставить внешний диод вместо вкрученного в плату, поместить все в цилиндр.
0
Когда читал комменты к статьям вида:
«как раз в тему!»
«только об этом думал»
думал вот чешут, а теперь понял сам, что совпадения бывают :)
Второй день просматриваю сетку по данному предмету, только я хочу
большую гирлянду сделать свеч на сто-двести.
— Странный камушек, внутри пусто, а цена от 95 рэ у нас :(
0
  • avatar
  • ZiB
  • 06 ноября 2011, 18:23
Второй день просматриваю сетку по данному предмету

А там ничего нету, да? :D Вот и у меня такая проблема была. Пришлось самому решать… В общем, я рад, что кому-то пригодилось.

хочу
большую гирлянду сделать свеч на сто-двести.

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

Странный камушек, внутри пусто, а цена от 95 рэ у нас

В ближайшем ко мне магазине тоже около того. Просто я его покупал, когда шла маркетинговая компания TI, он был по 40р.

Там профит есть, если заказывать от 1000шт. Тогда он по $0.5 идет.
0
У меня идея. Сделать две такие свечи. Поставить по краям от монитора. А сенсор под обшивку стула или щё куда. Получится, когда садишься за комп начинаю гореть «свечи». А лучше взять нерабочие радиолампы и использовать накальную нить.
0
А Вы шутник. xDDD
0
Кстати, не будет работать. ;) Если посмотрите прошивку, там алгоритм мерцания не запускается, пока руку не убрали. :)
0
Ник обязывает))
0
Лишние источники света отвлекают от происходящего по ту сторону монитора
0
Нормалек, но надо запихать в матовый стакан какой-нибудь.
+1
Таки да, в стакан лучше всего. Ибо пламени-то нет, и потому электронные свечи в «стандартном» форм-факторе выглядят убого.
0
Понравилось. Для пущего реализьму можно яркость иногда изменять с большей скоростью (когда пламя начинает трепетать от движения воздуха) и может добавить пару градаций яркости в ту и в другую стороону.
0
когда пламя начинает трепетать от движения воздуха

Микрофон бы туда, микрофон. :) А так, если долго наболюдать, она иногда трепыхается подобным образом. Когда — зависит от seed-а ГПСЧ.
0
Ликуйте, друзья мои! С новой прошивкой девайс потребляет 60мкА в ждущем режиме!
0
  • avatar
  • _YS_
  • 07 ноября 2011, 21:31
Ну вот, это другое дело. А что он делает в этом ждущем режиме?
0
Ничего. Считает такты до опроса сенсора.

Нет, LPMx тут не катит, с ним будет сильно сложнее. Во-первых, даже умозрительно, ничего кроме LPM0 тут не подойдет — во всех остальных Low-Power режимах выключается DCO, а другого генератора там просто нет. А если мы посмотрим на потребление в LPM0 и при 120КГц, то увидим, что они почти равны (55мкА против измеренных 60мкА). Так что заморачиваться с переконфигурированием таймера я не вижу смысла — проще считать такты.
0
Следующую свечку делай на STM8L :)
0
Ну, это Вы у нас тут специалист по STM8[L]. :) Портируйте мой код, если хотите. :)
0
Я тут как-то делал на MSP430 сенсор прикосновения, к нему достаточно поднести руку и он срабатывает (расстояние ~15-20см). Получается если сделать как я, то можно задуть свечу просто «махнув на нее рукой».
0
Ну, чую, тут есть опасность переборщить с чувствительностью и сделать девайс нестабильным.
0
У меня работало вполне неплохо. Хотя возможно такая чувствительность это не совсем хорошо :)
Например кладу «сенсор» на стол и провожу рукой по другую его сторону — диодик загорается.
0
Красивая идея и красивая визуализация. Можно развить идею – сделать «столбик» из светодиодов и менять высоту «огонька». Можно подключить акселерометр и правдоподобно реагировать на перемещение «свечи». Не понятно, почему топик ушел в минуса.
+1
Не понятно, почему топик ушел в минуса.

Так это, плюсаните. ;)
0
Увы, но я уже «воздержался» :) Приношу свои извинения в ЛС :)
+1
О, спасибо, спасибо!
0
Как это, «воздержался»?
0
Щелкнул между стрелочками UP и DOWN :)
0
Я думал, это шутка, оказывается, нет))) Говорят — «вы воздержались, чтобы увидеть рейтинг топика».
0
А вот еще советик… Так ради прикола. Ведт свечу может и совсем задуть? Или она может погаснуть. И кстати тоже случайным образом. Причем погаснуть она может от ветра тогда, как правило, она перед погосание резко вспыхнет. Или просто потому что по каким-то, например что-то попало в пламя или фитить как-то неправильно загнулся, пламя стало очень маленьким.
Так может еще эти параметр контролировать. Я имею ввиду яркость. И гасить свечу ежли что не так…
0
  • avatar
  • kos
  • 10 ноября 2011, 15:12
Ну, тут большой простор для фантазии. :) Только я бы все же взял процессор пожирнее и вкрутил бы микрофон.
0
ну или оставить этот и прикрутить к нему… Скажем BlackFin… :-)
0
Лампа накаливания по моему лучше бы смотрелась, и спектр покрасивее у нее.
0
Ставил что было, честное слово. :) Но Вы же видите, там предусмотрена разводка под SMD транзистор. Можно поставить IRLML2803 — у него максимальный ток до ампера, чего вполне хватит для лампочки. Так что возможность есть.
0
Есть СИДы теплого белого цвета. Весьма на лампочку похоже. Можно поставить их.
0
Прямо-таки захотелось себе такое чудо сделать =) Правда алгоритм я не до конца поняла, чип незнакомый.
0
Ну, вообще я пытался сделать сам алгоритм мерцания максимально независимым от собственно чипа — он весь уложен в одну функцию. Если чего, спрашивайте.
0
Можете его в виде блок-схемы выложить?
0
Только алгоритм мерцания? ОК, попробую.
0
Думал я думал, и в конце концов мне показалось, что все таки лучше будет выложить кусок кода с подробными комментариями и графиком. Сейчас впилю в статью. Просто блок-схема у меня получилась какой-то запутанной. Но если будет непонятно — говорите, и я попытаюсь запилить и ее.
0
Ммм, прикольный алгоритм! По видео я подумал, что он будет посложнее, выглядит вполне реалистично. А тут всё оказалось настолько элементарно. Молодец!
0
Месяцы созерцания и медитации… :)
0
Только его, портировать ж придется.
0
Обновил статью.
0
LFSR_Random возвращает значение от 0 до 255 или значение в некотором промежутке min-max pwm_target?
0
По идее 0..255.
Кстати, а чем обычный rand не угодил? Он тоже довольно равномерное распределение дает, при этом заметно проще, компактней и быстрее.
0
Кстати, а чем обычный rand не угодил?

ХЗ. Что-то захотелось экзотики.
0
Да, [0;255]. Причем, естесственно, pwm_target тоже может принимать любое значение от 0 до 255.
0
Поэтому, кстати, пришлось писать так:

upd_interval=(LFSR_Random()/2)+10;


Все коэффициенты — чистая эмпирика, естесственно. Подбирал по наибольшему правдоподобию.
0
Повторил на stm32-vldiscovery (Cortex-M3). Замечания/переделки:
1. Непонятно, почему переменные объявляются в теле функции. Т.е. мы при каждом вызове функции заново инициализируем переменную?!?! (все, пошел в гугл и тот мне секунд за 10 объяснил все, вопрос снимается)
2. обычный rand() прекрасно работает
3. Непонятно, зачем делать разный интервал. Ведь каждый вызов rand() не только определяет яркость свечения, но и «расстояние» до цели, т.е. несмотря на то, что к цели оно всегда стремится с одинаковой скоростью, расстояние до нее меняется и время мерцания тоже меняется.

Ну и под конец — спасибо большое!
0
Непонятно, почему переменные объявляются в теле функции. Т.е. мы при каждом вызове функции заново инициализируем переменную?!

static не заметили, да? :)

обычный rand() прекрасно работает

Да я и не сомневался. Просто я люблю экзотику. :)

Непонятно, зачем делать разный интервал.

Ну, после экспериментов мне показалось, что так реалистичнее. Хотя это уже на вкус и цвет.

спасибо большое!

Да не за что. :)
0
www.youtube.com/watch?v=K5fW3JwdB1k&feature=player_embedded способ включения особенно понравился
0
Ха, у них алгоритм мерцания, имхо, менее реалистичен! :)
0
надо продать им свой за стопицот денег. :)
0
А мне понравилось. Портировал на PIC. Правда, немного поигрался с константами и переменными (4МГц это не 15МГц, хотелось бы более широкий диапазон скоростей, но...), прикольно получилось. LFSR — оригинально. Встроенный RAND() не айс… На мой взгляд, резковато.
З.Ы. Появилась мысль зарядить штук 20 УФ-диодов и на елку на НГ. Засада. Пакет с диодами потерялся… Куда-то заныкал, найти не могу :)
0
а можно по подробней о сенсоре?
на страничке Elm Chanа как то непонятно.
собираюсь реализовать на attiny13 точнее реализовал само мерцание а хочу добавить сенсор.
я так понял нужно использовать таймер для сенсора?
0
  • avatar
  • z80
  • 10 января 2012, 21:14
С сенсором все просто. Таймер — один из вариантов реализации.

Идея состоит в измерении времени, за которое зарядится емкость проводящей площадки сенсора. Сначала площадка заземляется, потом на нее подается питание через высокоомный резистор, и замеряется время ее заряда (ножки МК обладают пороговым эффектом, так что достаточно просто ждать появления лог. «1»). Время можно замерять таймером, а можно просто считать такты, как делал я (предварительно запретив прерывания, естесственно).

Если что, могу запилить статью на эту тему. Не стесняйтесь, говорите, если надо.
0
вообще статью желательно, так как думаю не только меня это интересует. точнее интересует именно програмная реализация какие есть методы.дело в том, что таймер у меня использован под програмный ШИМ. так, что либо мне переделать под аппаратный и использовать таймер либо считать такты но как их считать?
0
  • avatar
  • z80
  • 10 января 2012, 22:36
Ну, вообще эта тема уже достаточно хорошо освещена. Но таки я постараюсь запилить статью, если Вам это интересно.

как их считать?


O_O странный вопрос.


while (!(PORTn & PnX))
  i++;
0
а еще хочу прикрутить микрофон но пока не представляю как его использовать. по идее надо на АЦП его повесить. но задувать свечу это само собой но что еще можно реализовать не знаю. надо ведь использовать всю мощь тиньки
0
  • avatar
  • z80
  • 10 января 2012, 22:42
по поводу тактов я имел ввиду порядок. т е я имел ввиду время какое считается, что к сенсору прикоснулись?

что то не соображу как использовать аппаратный ШИМ не используя таймер
чувствую прийдется считать такты
0
время какое считается, что к сенсору прикоснулись?


Ну, это только экспериментально. Конкретно в этой конструкции у меня получалось порядка двенадцати тактов. Для другого сенсора будет по-другому.

что то не соображу как использовать аппаратный ШИМ не используя таймер


Это как? o_O Так нельзя, мил человек. :)

Ладно, скоро я освобожусь и запилю статью. Или уже разобрались?
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.