вторник, 29 ноября 2022 г.

Пацифисты, смерть несущие.

В очередной раз выбесили удивили меня все эти защитники прав кошечек, ежиков и собак. Не скажу, что пост именно про них, но такие люди стали причиной, почему это сообщение вообще появилось.
Начну издалека.
Рассмотрим какой-нибудь не топовый айфон, например, Apple iPhone 13. Модель айфона взята произвольно. Стоимость покупки, про информации из сети, составляет 62530 рублей.
Себестоимость айфона составляет около 570 долларов, что в пересчете на рубли (при курсе в 61 рубль за доллар) будет 34770 рублей. Прибыль, соответственно, 27760.
Смотрим, какой процент отдают производители в виде налогов в бюджет.
"Федеральная ставка корпоративного налога в США для Корпораций С/S в настоящее время составляет 21% (net income).
Ставка штатного корпоративного налога: 0-9%"
Т.е. максимально, производитель отдает 30% в виде налогов. Ну, не будем отрицать наличие разума у руководства известной компании и будем считать, что они каким-то легальным образом уходят от штатного налога и отдают всего 21% от прибыли. И это будет 5800 рублей.
За 2021 год бюджет Америки составил $4,8 трлн. Военный бюджет у той же страны за тот же период составил 740 миллиардов долларов, т.е. 15% от общей сумы бюджета.
15% от суммы, полученной в виде налогов за наш айфон - 870 рублей.
К сожалению, не знаю, с каким оружием бегают доблестные американские парни и какое оружие другие доблестные американские мужики поставляют за пределы США. Возьму для сравнения патрон к нашему калашу, калибра 5.45. Думаю, что у американцев наиболее распространенные патроны не сильно отличаются по цене.
Смотрим наши магазины. Патрон 5,45x39 FMJ 3,85 лакированный - стоит в районе 20 рублей за патрон.

И финальная часть статьи.
870 рублей делим на 20 и получаем 43 патрона.
Допустим, что стрелять будет рукожопый стрелок, который попадает в ростовую живую мишень хотя бы один раз из 10.
Да хотя бы один раз из 40!
И получается, что следуя моде и покупая замечательные американские смартфоны, каждый покупатель спонсирует убийство от одного до четырех человек в каком-либо военном конфликте, где у американцев есть какой-то интерес.

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

А так, в целом, я тоже не одобряю неоправданное насилие по отношению к животным. Но... это что, самая большая наша проблема?

понедельник, 29 октября 2018 г.

Московский мусор в регионы!

Добрый день!
Хочу обратить Ваше внимание на одно из сообщений на сайте roi.ru, о запрете создания мусорного полигона в Архангельской области.
Информация подана совершенно дико, но сути проблемы это не меняет - в Архангельской области хотят сделать полигон для хранения Московского мусора. Казалось бы - где та Архангельская область, а где мы... но что, если завтра около Вашего дома начнут строить такой полигон? Это даже если не думать о том, что на Севере находится значительный запас пресной питьевой воды, в которую может попадать разная гадость с полигона. Не Байкал, конечно, но тем не менее...
Да, чиновники утверждают, что там будет налажено абсолютно безопасное производство по переработке отходов. Казалось бы - здорово! Но... если все так замечательно, почему полигон не строят под Москвой? Переработка мусора - это огромные деньги. Лично я не верю что москвичи отдали бы такой жирный куш кому-то в регионы.
Проголосовать против строительства можно просто. Авторизуйтесь на госуслугах, затем в сообщении на сайт найдите в разделе Решение строку "Для голосования вы должны быть авторизованы через ЕСИА", нажмите на ссылку. И проголосуйте за решение проблемы путем запрета строительства полигона.
Спасибо!

среда, 1 ноября 2017 г.

Гимнастические кольца

Очень долго не доходили руки до блога. То мысли грустные, то веселые, но не для распространения... Одним слово - никак. :о)

Небольшая предыстория. У детей в комплекте с гимнастической стенкой были кольца на шнурах. Долго висели в кладовке, пока мне не приспичило попробовать сделать на них некоторые упражнения. Повесил на турник, поболтался на них... И был впечатлен количеством мышц, вовлеченных в простейшие тяги и жимы а так же нагрузками. Для понимающих - нагрузка шла даже на внутреннюю верхнюю часть грудной мышцы. Из минусов - радиус колец мелкий (детские же) и кольца давят на запястья. Не смертельно, но болезненно.

-Неужели и гимнасты так маются с руками, - думал я. Полез в Интернет. Оказалось, что для взрослых кольца делают немного побольше размером. После изучения вопроса и непродолжительных поисков и заказал кольца с ремнями на Алиэкспрессе. Нашел комплект из двух колец и регулируемых ремней за 1450 рублей. Толщина кольца 28 мм. Внутренний/внешний диаметры - 17.5/23.5. Длина ремня 4.8 м. Ширина 2.5 см. Заказал. Примерно через месяц посылка пришла.

В интернете можно найти массу упражнений по работе с кольцами. Кроме ног и шеи, кажется, можно тренировать все. :о)

P.S. Да, я в курсе, что если сделать так (23.5-17.5)/2=3. 3!=2.8 Но толщина колец совпала с заявленной, а разницу в диаметрах в 2 мм решил оставить на совести продавца. :о)

P.P.S. Повесил. Очень доволен. :о)))


четверг, 20 августа 2015 г.

live-vk.com - мошенники? Скорее всего - да.

   Небольшое вступление.
   На сайте Avito.ru мелькнуло объявление о продаже фототехники за половину цены. Конечно же, не смог оставить его без внимания и закинул в избранное, чтобы на досуге более подробно изучить предложение. Заодно закинул в избранное ссылку на страницу, указанную продавцом как торговую площадку, чтобы посмотреть, что еще человек предлагает.
   На следующий день объявление на авито было заблокировано. Взгрустнул, но недолго - у меня же была ссылка на торговую площадку! Пошел туда. Выяснил, что некто "Виктор", работая на оптовом складе "М.Видео", продает технику с существенной уценкой. Заинтересовавший меня Canon 70D предлагает не за 54 т.р., как указано на сайте магазина, а за 30! Шикарный фотоаппарат, на который как раз хватило бы, если продать всю имеющуюся у меня фотоаппаратуру... Конечно же, желание стать обладателем такой чудесной машинки подтолкнуло меня на дальнейшие шаги. :)
   Связался с продавцом, чтобы уточнить, каким образом можно купить заинтересовавший меня фотоаппарат. Вот тут началось самое интересное. Выяснилось, что "Виктор" не встречается с покупателями лично, а направляет курьера с товаром, при условии ПРЕДВАРИТЕЛЬНОЙ оплаты. На мои предложения оплатить после осмотра фотоаппарата ответил, что у курьеров, якобы, отбирают товар, производят подмены товара или платят фальшивыми деньгами, поэтому он настаивает на предварительной оплате через системы qiwi или wallet.
   Предлагаю встретиться с курьером в общественном месте, например, торговом центре, где есть охрана. И оплатить через терминал на его счет, чтобы исключить вероятность оплаты фальшивыми купюрами. Продавец не соглашается и настаивает "хотя бы" оплате половины стоимости вперед. Как вариант, предлагает использовать "гарант сервис" на том же сайте live-vk.com.
   Полез на сайт изучать разделы про этот "гарант-сервис" ну и вообще поближе познакомиться с ресурсом. Суть сервиса в том, что человек перечисляет некоему пользователю сайта стоимость товара + 10% комиссии сверху и в случае, если сделка состоится, этот гарант перечисляет деньги продавцу или возвращает их покупателю. Гы. Гарантом выступает другой пользователь сайта, которого я тоже не знаю. Т.е. ситуация еще смешнее стала - заплати +10% сверху стоимости для обеспечения "безопасной" сделки.
   Да и сам сайт начал вызывать вопросы. Однообразные комментарии "довольных покупателей", небольшое количество сообщений и тем, связанных с продажами... Никаких отзывов о работе сайта в инете не нашел - ни отрицательных, ни положительных. Заглянул на сайт 2ip.ru чтобы проверить, что за сайт-то такой и выяснил, что имя live-vk.com было зарегистрировано 11 августа 2015 года. Вспомнил, что объявление на авито от "Виктора" появилось то-ли 13, то-ли 14-го августа.. Интересно, да? Сообщения в форуме начинают датироваться с 2010 года, но это тоже легко фальсифицируется - разворачиваем форум на локальной машине, ставим системную дату на любой нужный нам год и вперед.. плодим юзеров, сообщения, меняем дату на более свежую и так далее. Месяц работы, затем заливаем базу форума на арендуемый сервер и вуаля! Имеем форум с сообщениями, датируемыми любым временным интервалом.
   В общем, решил, что скорее всего - это мошенники. Нормальный продавец согласился бы на оплату после осмотра, либо же осуществлял бы торговлю через площадки molotok или ebay. Нормальная торговая площадка имеет длительную историю в виде отзывов пользователей на других ресурсах, например, в тех же блогах. Или в виде обзоров на новостных сайтах. Нормальный продавец не будет кидать объявление на авито с интригующим заголовком "любая фототехника за полцены" а потом в личке говорить, что он не очень заинтересован в привлечении новых клиентов и готов работать со старыми по удобной ему схеме.
   В общем, берегите свои деньги и нервы, уважаемые. :) По возможности проверяйте продавца и не платите вперед, даже если вам предлагают... э-эх... новенький Canon 70D всего за 30 тысяч рублей. :)

воскресенье, 2 августа 2015 г.

Тестируем матрицу зеркального фотоаппарата - PSD и PHP

   Выкладываю обещанный скрипт для проверки наличия битых пикселей на матрице. Да кому он нужен, когда можно глазками все посмотреть? Он может пригодиться при покупке б/у фотоаппаратов через интернет, или для выбора лучшего фотоаппарата из нескольких, например, в магазине
   Для начала надо заполучить RAW'ки, сделанные в максимальном разрешении, в режиме приоритета выдержки, в режиме ручной фокусировки с закрытым объективом (крышечку с объектива не снимаем). Чтобы было какое-то единообразие, пусть ISO пусть будет 100. В интернете встречаются рекомендации по установке выдержки в 3-5 секунд... Я-перфекционист, хочу, чтобы выдержка была 10 секунд.
   Полученный "черный" кадр, конечно, можно и глазками посмотреть, но на дворе 21-й век! Поэтому немного схитрим.
   Открываем RAW-файл любом подходящем графическом редакторе. В моем случае любым подходящим оказался Lightroom. RAW-файл экспортируем в PSD в формате 16-битного sRGB.
   Теперь пару слов о том, что делает скрипт.
   В конце PSD файла в формате RRR GGG BBB находятся данные нашей картинки. Помним, что мы конвертировали наш файл в формате 16-битного sRGB. Обращаем внимание на то, что у нас структура файла не RGBRGBRGB... а RRRRRR...GGGGG...BBBBB. Я не обратил на это в первый раз внимания, за что и поплатился... :о)
   Скрипт читает заголовок файла, откуда получает информацию о размерах картинки и расположении блока Image Data Section, и начинает читать по два байта данные, пробегая массив данных RRRRR, затем GGGGG и наконец BBBBB, попутно "запоминая" элементы, яркость которых превышает указанный нами порог и выводит данные об обнаруженных точках в файл. Выводятся данные о координатах точек и яркости каналов, позволивших себе выделиться на общем фоне. :о).
   На моем ноуте первоначальный вариант скрипта разбирал 12 миллионов пикселей более чем за 340 секунд. Сейчас 17 миллионов пикселей скрипт разбирает чуть более чем за 90 чекунд. Но мне кажется, что и 90 секунд - не предел.
   Ну а теперь, собственно, сам скрипт.



//Каждый цвет может иметь интенсивность от 0 до 65535 и кодируется 2 байтами.
//Блок с данными находится в конце файла. 
//Перед ним блоки переменной длины, читаем заголовки.
//Ищем точки, в которых одна из компонент R,G или B превышает порог, 
//заданный в параметрах при запуске скрипта.
//Пороговое значение задается в процентах.
//
$reshandle=fopen($argv[1]."-".$argv[2].".res",'w');  //Открываем файл для резудбтатов
$start_time=time();     //Фиксируем время старта скрипта.
$header=array();
$handle=fopen($argv[1],'r');    //Открываем файл формата PSD, указанный в параметрах
$resarr=array();
$width=0;      //Длина картинки 
$height=0;      //Высота картинки
$pixcnt=0;
$limit=(int)((65535*$argv[2])/100);   //Рассчитываем пороговое значение
$cur_pos=0;      //Текущая позиция в файле
$content;      //А сюда будем читать байты (2 шт), отвечающие за один пиксель
$shine_num=0;      //Счетчик "битых" пикселей 

//В этом блоке читаем заголовок PSD файла и вытаскиваем оттуда размеры картинки
for ($i=0;$i<26;$i++)    
    {$byte = fread($handle,1);
     $header[$i]=$byte;
    }
$bh=array($header[14],$header[15],$header[16],$header[17]);
$bw=array($header[18],$header[19],$header[20],$header[21]);
$height=HEX_DEC_CONVERT($bh);
$width=HEX_DEC_CONVERT($bw);
$pixcnt=$height*$width;
//Выводим полученную информацию в файл
fwrite($reshandle,"Width (pxl): ".$width."\r\n");
fwrite($reshandle,"Height (pxl): ".$height."\r\n");
fwrite($reshandle,"Size (pxl): ".$pixcnt."\r\n=====================\r\n");


//Пойдем по-взрослому, с начала файла, читая заголовки блоков файла
$cur_pos=$cur_pos+26;
echo $cur_pos."\r\n";

//Color Mode Data Section
fseek($handle,$cur_pos);
for ($i=0;$i<4;$i++)    
    {$byte = fread($handle,1);
     $farr[$i]=$byte;
    }
$cur_pos=ftell($handle)+HEX_DEC_CONVERT($farr);
echo $cur_pos."\r\n";
fseek($handle,$cur_pos);

//Image Resources Section
fseek($handle,$cur_pos);
for ($i=0;$i<4;$i++)    
    {$byte = fread($handle,1);
     $farr[$i]=$byte;
    }
$cur_pos=ftell($handle)+HEX_DEC_CONVERT($farr);
echo $cur_pos."\r\n";
fseek($handle,$cur_pos);

//Layer and Mask Information Section
fseek($handle,$cur_pos);
for ($i=0;$i<4;$i++)    
    {$byte = fread($handle,1);
     $sarr[$i]=$byte;
    }
$cur_pos=ftell($handle)+HEX_DEC_CONVERT($sarr)+2;
echo $cur_pos."\r\n";
fseek($handle,$cur_pos);


$tmp_arr=array();
//====================
$i=0;
for($y=0;$y<$height;$y++)
   {for($x=0;$x<$width;$x++)     
      {
//читаем данные по одной точке - 2 байт. 
    $content=fread($handle,2);
    $tmp_arr[0]=$content[0];
    $tmp_arr[1]=$content[1];
    $R=HEX_DEC_CONVERT($tmp_arr);
//Сравниваем с пороговым значением. 
//Если есть необходимость - сохраняем в массиве
// координаты и значения компоненты RGB
    if ( ($R>$limit) )    
       {$resarr[$x][$y]['R']=$R;        
        $resarr[$x][$y]['G']=null;        
        $resarr[$x][$y]['B']=null;        
       }       
      }
   }

for($y=0;$y<$height;$y++)
   {for($x=0;$x<$width;$x++)     
      {
//читаем данные по одной точке - 2 байт. 
    $content=fread($handle,2);
    $tmp_arr[0]=$content[0];
    $tmp_arr[1]=$content[1];
    $G=HEX_DEC_CONVERT($tmp_arr);

    if ( ($G>$limit) )    
       {$resarr[$x][$y]['R']=null;        
        $resarr[$x][$y]['G']=$G;        
        $resarr[$x][$y]['B']=null;        
       }       
      }
   }

for($y=0;$y<$height;$y++)
   {for($x=0;$x<$width;$x++)     
      {
//читаем данные по одной точке - 2 байт. 
    $content=fread($handle,2);
    $tmp_arr[0]=$content[0];
    $tmp_arr[1]=$content[1];
    $B=HEX_DEC_CONVERT($tmp_arr);

    if ( ($B>$limit) )    
       {$resarr[$x][$y]['R']=null;        
        $resarr[$x][$y]['G']=null;        
        $resarr[$x][$y]['B']=$B;        
       }       
      }
   }
//Разбор массива и вывод результатов в файл
reset($resarr);
$R="";
$G="";
$B="";
while (list($key,$val)=each($resarr))
  {
   while (list($skey,$sval)=each($resarr[$key]))
     {if (!is_null($sval['R'])) {$R="  RED: ".$sval['R'];}
      if (!is_null($sval['G'])) {$G="  GREEN: ".$sval['G'];}
      if (!is_null($sval['B'])) {$B="  BLUE: ".$sval['B'];}
      
      fwrite($reshandle,"\r\nX: ".$key."; Y: ".$skey."    ".$R.$G.$B);
      $shine_num++;
     }


  }


//Цикл обработки закончился, выводим результаты работы
fwrite($reshandle,"\r\n================================\r\n");
fwrite($reshandle,"\r\nBrightness: ".$argv[2]."%");
fwrite($reshandle,"\r\nNumber of shine pixels :".$shine_num);
fwrite($reshandle,"\r\nWorking time (sec):".(time()-$start_time));

//echo ftell($handle)."\r\n";

fclose($handle);
fclose($reshandle);


//===================================================
//Переводим значения из двухбайтного HEX в DEC
function HEX_DEC_CONVERT(array $arg)
   {$result=0;
    $cnt=count($arg);
//echo $cnt."\r\n";
    for ($f=$cnt;$f>0;$f--)
       {$result=$result+ord($arg[$f-1])*pow(256,$cnt-$f);
   
       }
    return $result;
   }


   Чуть не забыл. Запускаем скрипт с параметрами. Первый параметр - имя файла. Второй параметр - процент.
php.exe shinepxl.php 5d.psd 5

На выходе получим файл с именем 5d.psd-5.res

Содержимое файла:

Width (pxl): 5184
Height (pxl): 3456
Size (pxl): 17915904
===============================================================

X: 24; Y: 2105      RED: 64646
===============================================================

Brightness: 40%
Number of shine pixels :1
Working time (sec):93

   В файле ширина, высота, общее количество точек. Потом перечисляются точки, у которых хотя бы одна составляющая R,G или B превышает заданное значение. Начало координатных осей - верхний левый угол.
   В конце - пороговое значение, число найденных точек и время обработки.
Как видим, в примере имеем один битый пиксель, светящийся красным.
   Вот, собственно, и все.


Canon EOS 5D. Full frame мне в руки! Первые впечатления.

По случаю купил подержанную тушку фотоаппарата Canon EOS 5D - полнокадровую зеркалку. В инете можно встретить и другое название фотоаппарата - "первый пятак".

Первые впечатления - он ОГРОМНЫЙ. По сравнению с мои Canon EOS 1100D - 5D ощутимо больше и тяжелее. Сверху на корпусе у пятерки присутствует ЖК экранчик, отображающий почти все необходимые для съемки параметры. И множество кнопочек, позволяющих быстро менять параметры съемки. Удобно, черт возьми.

Небольшое лирическое отступление про экранчик - по тому же случаю, в комплекте шел Canon EOS 40D - отдал его старшему ребенку. У 40D тоже есть сверху аналогичный экранчик и кнопочки - ребенок просто тихо млеет от удовольствия, почувствовав, как можно быстро менять любые настройки фотоаппарата. Почти год пытался подтолкнуть его к использованию домашнего Canon EOS 1100D и как-то без особого результата. А тут он как взял в руки 40D и все... Ковыряется в нем, изучает документацию, таскает фотик на улицу фотографировать одноклассниц и просто знакомых девчонок. Зацепила человека удобная, качественная техника. :) Чему я рад безмерно. :)

Но, вернемся к 5D. ISO у фотоаппарата - от 100 до 3200. Мало? Нормально! Обычно уже на ISO 400 начинают чувствоваться шумы, после ISO 600 шумы становятся просто неприличными. Для меня обычно рабочие ISO не выше 300, поэтому тут ничего не смутило.

Выдержка - 1/8000! Кстати, на 40D такая же выдержка. :) Короткая выдержка очень выручала при съемке движущихся объектов.

Малая ГРИП (глубина резко изображаемого пространства) делает портреты ощутимо выразительнее.

Имеются следующие режимы съемки: авто, ручной, приоритет диафрагмы (мой любимый), приоритет выдержки, пользовательский, программный.

Довольно быстрая серийная съемка - чуть больше 3 кадров в секунду. И серия в RAW до 17 кадров.Приятно.


Теперь немного о "минусах", или , точнее - особенностях, которые обратили на себя мое внимание.

Довольно быстро почувствовал отсутствие встроенной вспышки. Вроде, ерундовая вспышечка была у 1100D, но совсем без встроенной вспышки - ни тени смягчить при съемке в солнечную погоду, ни в сумерках подсветить... Понимаю, что на серьезной технике встроенных вспышек нет, но осадочек остался, да и расходы в будущем предстоят дополнительные.

Объективы. У меня не оказалось ни одного объектива с автофокусом, который встал бы на байонет EF. Только мануальные советские стекла с чипованным переходником. Похоже, меня ждет очередной приступ болезни покупки объективов. (Деньги!!! Куда вы?!!) :)

Малая ГРИП очень ощутима. Фокусироваться стало сложнее. Хотя даже на кропе со светосильной оптикой проблема ручной фокусировки будет присутствовать, поэтому оценил малую ГРИП как техническую особенность, к которой надо привыкнуть.

Нет видео. Я покупал фотоаппарат, чтобы фотографировать, поэтому отсутствие видео меня не расстроило, но для кого-то это может показаться недостатком.

Нет Live View - это ощутимо усложняет точную фокусировку. Думаю о приобретении насадки на видоискатель, увеличивающей картинку. В инете народ говорит, что отчасти помогает решать проблему.

12 мегапикселей - меня не смутили. Я отлично помню, какие замечательные фотографии делались на старенькую мыльницу с 4(!) мегапикселями.


В целом - доволен фотоаппаратом. Canon EOS 5D добротный фотоаппарат, который, на мой взгляд, не потерял актуальности и сможет еще не один год радовать хорошим качеством снимков. Если есть желание попробовать ФФ камеру, но имеются финансовые ограничения - Canon EOS 5D отличный вариант. Б/У камеру можно взять за 25-30 тысяч рублей. Но будьте готовы к расходам на объективы! Либо смотрите в сторону старых советских объективов, которые ставятся на зеркалку через адаптер и которые при отличном качестве оптики стоят в разы дешевле современной оптики. Кстати, светосильные объективы на 5D - рулят! Они позволяют раскрыться камере в полной мере и получать снимки, качество которых наполнит сердце радостью, а голову мыслями о том, что... хм... чем черт не шутит... может быть, в глубине души живет ВЕЛИКИЙ фотограф?! ;)

Для начинающих фотографов порекомендовал бы все-таки брать б/у Canon EOS 40D - на него встают объективы с байонетом EF-S, он чуть полегче, есть Live View, экранчик и дополнительные кнопки для быстрого доступа к настройкам, творческие режимы. Можно купить старенький но вполне еще актуальный фотоаппарат с полупрофессиональным управлением менее чем за 10 т.р.


У 5D и у 40D есть какой-то свой шарм. Приятные машинки, с душой. Рекомендую. :)


P.S.

Чуть позже выложу скрипт, позволяющий проверять матрицу на наличие "битых" пикселей. Да, автоматизировал процесс. Это болезнь. Я знаю. :))


среда, 26 ноября 2014 г.

Суровая правда жизни

#С Юрой пообщался
Я могучий, как джин – все на свете могу!
Строить замки, сносить города!
Но задач по плечу не найти… и грущу…
И картошку копаю тогда.


#Просто так
А снежинки ажурные с неба спускаются
И тихонько ложатся под ноги они
С тихим звоном о землю они разбиваются
Заполняя собою все зимние дни…

Ёжики

А чумазые ежики ходят по комнатам
В одинаковых синих трусах
И грызут эти ежики булки пшеничные
И варенье у них на усах.

Только самый малюсенький, в угол забившийся
что оберткою тихо шурша
Тихо чавкает изредка маленьким ротиком
Он конфетку жует не спеша

вторник, 25 ноября 2014 г.

Arduino. Собираем своего робота из компектующих

Ранее упоминал о приобретенном на dx.com наборе для сборки робота. В какой-то момент число замененных комплектующих стало существенным и решил уточнить, во что обойдется аналогичный робот, приобретенный врассыпуху, а не готовым комплектом.

Полный набор сейчас стоит 86.6$.

Если брать все по отдельности, то получим:

КомплектующиеЦена
Платформа с двигателями 26$
4-канальный контроллер двигателей 3.54$
Аналог Arduino Uno R3 8.82$
Сервопривод и ультразвуковой датчик 5.9$
Модуль Bluetooth 4.68$
Стекируемые разъемы 1.98$
Набор соединительных проводов 1.58$
Итого - 52,5$.

Разница получается 34.1$. Но есть нюанс - предлагаемый мной контроллер для управления двигателями одевается СВЕРХУ на ардуинку и закрывает все пины, даже те, которые ему не нужны ля работы. Поэтому надо приложить немного руки и перепаять контактные площадки с дефолтовых на предлагаемые мной в списке (последняя позиция).

Паяльник с регулируемой температурой нагрева жала, подставкой и отсосом для припоя можно приобрести на том же aliexpress.com за 12$. Те, кому лень паять, могут сразу купить вместо клона Arduino Uno R3 - клон Arduino Mega 2560 R3, которая имеет значительно больше свободных портов и которая стоит около 16$ - мы все равно выигрываем около 20$. :о)

Толковый мануал по сборке можно найти на сайте http://chingachgook.net

Управлять роботом можно по Bluetooth с компа или с телефона.

Вот и все. Удачи в разработке скетчей! Да пребудет с вами Сила! ;о)


пятница, 23 мая 2014 г.

Травма сустава. Чем мазать?

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

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

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

Взял тюбик и под напутственные слова доктора отправился в каюту обрабатывать поврежденную конечность. Намазал. Никакого эффекта. Ну, думаю, может пока впитается... Прошел час, в течении которого довольно много бегал по рабочим помещениям. Мази как будто и не было, а плечо болит - ни обезбаливающего, ни согревающего эффекта не наблюдается. Смыл остатки мази и снова зашел к доктору. На этот раз взял мазь "Капсикам".

На счет обезбаливающего - не знаю, но греть стало почти сразу. Особенно хорошо стало припекать когда разогрелся немного. УХ! Хорошо! :о)

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

Вернул доктору мазь, обсудили лечебный эффект от использованных препаратов. Доктору тоже "Фастум гель" не очень нравится. С "Капсикамом" он лично не сталкивался, а по опыту использования очень хвалил "Кетонал".

Резюмируя. "Фастум гель" - ерунда, не достойная чести занимать место в аптечке приличного спортсмена. "Капсикам" - прошел полевые испытания и показал неплохие результаты. "Кетонал" - то, что доктор прописал.

P.S. Может возникнуть вопрос, почему доктор изначально не предложил "Кетанол". А за время, пока я лечился у нас успели врачи поменяться. :о)


вторник, 20 мая 2014 г.

Arduino. Работаем с часами DS3231 по i2C через Wire.

Копнул более основательно часики.

Для начала запустил сканер устройств на шине i2C. Рекомендую сохранить этот скетч в свою библиотеку, чтобы он был под руками - очень полезная штука!

Сканер обнаруживает два устройства на шине i2C по следующим адресам:
1. 0x57 - это адрес микросхемы памяти AT24C32
2. 0x68 - адрес микросхемы DS3231SN

Cтоит учитывать - сканер возвращает адреса в формате шестнадцатеричной системы. Т.е в привычном нам десятичном формате получим адреса 87 и 104. Нас интересует адрес 0x68 (104). Сделал себе первую пометочку.

Следующий шаг - скачать даташит к микросхеме. Найти его можно, например, по этой ссылке
Читаю, радуюсь большому количеству английских букв и разнообразных таблиц. :)

Самое интересное началось на странице 11, где присутствует следующая таблица:

Figure 1. Timekeeing Registers

Addressbit 7
MSB
bit 6bit 5bit 4bit 3bit 2bit 1bit 0
LSB
FunctionRange
00H010 secondssecondsSeconds00-59
01H010 minutesminutesMinutes00-59
02H012/24AM/PM
10 hour
10 hourhourHours1-12+AM/PM
00-23
03H00000dayDay1-7
04H0010 datedateDate00-31
05HCentury0010 monthmonthMonth/Century01-12+Century
06H10 yearyearYear00-99
07HA1M110 secondssecondsAlarm 1
seconds
00-59
08HA1M210 minutesminutesAlarm 1
minutes
00-59
09HA1M312/24AM/PM
10 hour
10 hourhourAlarm 1
hours
1-12+AM/PM
00-23
0AHA1M4DY/DT10 datedayAlarm 1 day1-7
dateAlarm 1 date1-31
0BHA2M210 minutesminutesAlarm 2 minutes00-59
0CHA2M312/24AM/PM
10 hour
10 hourhourAlarm 2 hours1-12+AM/PM
00-23
0DHA2M4DY/DT10 datedayAlarm 2 day1-7
dateAlarm 2 date1-31
0EHEOSCBBSQWCONVRS2RS1INTCNA2IEA1IEControl---
0FHOSF000EN32kHzBSYA2FA1FControl/status---
10HSIGNDATADATADATADATADATADATADATAAgign Offset---
11HSIGNDATADATADATADATADATADATADATAMSB of Temp---
12HDATADATA000000LSB of Temp---
Рекомендую все-таки скачать даташит - там есть такие замечательные отметочки в оригинальной таблице - крышечки. Как я понял, обозначают, какое состояние бита отвечает за состояние AM/PM или DY/DT, например. В моей таблице этого нет.

Первоначально интерес тут представляют строки с 00H до 06H и c 0EH до 12H. Блок с алармами (07H-0DH) пока пропущу - им займусь позже.

Далее приведен скетч, работающий напрямую с данными на DS3231.

#include <Wire.h>
 #define DS3231_I2C_ADDRESS 0x68
  
 byte seconds, minutes, hours, day, date, month, year;
 char weekDay[4];  
 byte tMSB, tLSB;
 float temp3231;
  
 void setup()
 {
   Wire.begin();
   Serial.begin(9600);
   //set control register to output square wave on pin 3 at 1Hz
   Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
   Wire.write(0x0E); //выставляемся в 14й байт 
   Wire.write(B00000000); //сбрасываем контрольные регистры 
   Wire.write(B10001000); //выставляем 1 на статус OSF и En32kHz
   Wire.endTransmission();
 }
  
 void loop() {    
   watchConsole(); //читаем консоль. Если нажата "T" читаем из консоли следующий 7 байт и устанавливаем время.    
   get3231Date(); //получаем данные 

          //и потом их выводим через Serial.print()    
   Serial.print(weekDay); Serial.print(", "); Serial.print(month, DEC); Serial.print("/"); Serial.print(date, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" - ");
   Serial.print(hours, DEC); Serial.print(":"); Serial.print(minutes, DEC); Serial.print(":"); Serial.print(seconds, DEC);    
   Serial.print("   Temperature: "); Serial.print(get3231Temp());Serial.print("; ");
          Serial.println(get3231Register(0x0F)); //получаем и выводим статусовый регистр
   delay(1000);
 }
  
 // Convert normal decimal numbers to binary coded decimal
 byte decToBcd(byte val)
 {
   return ( (val/10*16) + (val%10) );
 }
  
 void watchConsole()
 {
   if (Serial.available()) {      // Look for char in serial queue and process if found
     if (Serial.read() == 84) {      //If command = "T" Set Date
       set3231Date();
       get3231Date();
       Serial.println(" ");
     }
   }
 }
    
 void set3231Date()
 {
 //T(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year)
 //T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99)
 //Example: 02-Feb-09 @ 19:57:11 for the 3rd day of the week -> T1157193020209
  
   seconds = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result. 
   minutes = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   hours   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   day     = (byte) (Serial.read() - 48);
   date    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   month   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   year    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));

   Wire.beginTransmission(DS3231_I2C_ADDRESS); //начали сессию
   Wire.write(0x00); //поставляемся в нулевой байт для чтения данных
   Wire.write(decToBcd(seconds));
   Wire.write(decToBcd(minutes));
   Wire.write(decToBcd(hours));
   Wire.write(decToBcd(day));
   Wire.write(decToBcd(date));
   Wire.write(decToBcd(month));
   Wire.write(decToBcd(year));
   Wire.endTransmission();//закрыли сессию
 }
  
 byte get3231Register(byte regNo) {
   // send request to receive data starting at register regNo
   Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
   Wire.write(regNo); // start at register regNo
   Wire.endTransmission();
   Wire.requestFrom(DS3231_I2C_ADDRESS, 1); // request one byte
   if(Wire.available()) return  Wire.read();
 }
  
 void set3231Register(byte regNo, byte value) {
   Wire.beginTransmission(DS3231_I2C_ADDRESS);
   Wire.write(regNo);
   Wire.write(value);
   Wire.endTransmission();
 }
  
 void get3231Date()
 {
   // send request to receive data starting at register 0
   Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
   Wire.write(0x00); // start at register 0
   Wire.endTransmission();
   Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes
  
   if(Wire.available()) {
     seconds = Wire.read(); // get seconds
     minutes = Wire.read(); // get minutes
     hours   = Wire.read();   // get hours
     day     = Wire.read();
     date    = Wire.read();
     month   = Wire.read(); //temp month
     year    = Wire.read();

//Конвертация происходит очень просто - битовым оператором & мы очищаем МЛАДШИЕ (0,1,2,3) четыре бита , сдвигаем все вправо на 4 позиции (очищенные биты
//вылезут при этом с левой стороны и результат умножаем на 10, т.к. в старших битах хранится информация о десятках секунд.
//После этого битовым оператором & очищаем СТАРШИЕ (4,5,6,7)четыре бита и получаем секунды. Затем суммируем десятки секунд и единиц.
     seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111));
     minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111));
     hours   = (((hours & B00110000)>>4)*10 + (hours & B00001111)); 
     day     = (day & B00000111); // 1-7
     date    = (((date & B00110000)>>4)*10 + (date & B00001111)); // 1-31
     month   = (((month & B00010000)>>4)*10 + (month & B00001111)); //msb7 is century overflow
     year    = (((year & B11110000)>>4)*10 + (year & B00001111));
   }
   else {
     //oh noes, no data!
   }
    
   switch (day) {     
     case 1:
       strcpy(weekDay, "Mon");
       break;
     case 2:
       strcpy(weekDay, "Tue");
       break;
     case 3:
       strcpy(weekDay, "Wed");
       break;
     case 4:
       strcpy(weekDay, "Thu");
       break;
     case 5:
       strcpy(weekDay, "Fri");
       break;
     case 6:
       strcpy(weekDay, "Sat");
       break;
            case 7:
       strcpy(weekDay, "Sun");
       break;
   }
 }
  
 float get3231Temp()
 {
   //temp registers (11h-12h) get updated automatically every 64s
   Wire.beginTransmission(DS3231_I2C_ADDRESS);
   Wire.write(0x11);
   Wire.endTransmission();
   Wire.requestFrom(DS3231_I2C_ADDRESS, 2);
    
   if(Wire.available()) {
     tMSB = Wire.read(); //2's complement int portion
     tLSB = Wire.read(); //fraction portion      
     temp3231 = (tMSB & B01111111); //do 2's math on Tmsb
     temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8
   }
   else {
     //oh noes, no data!
   }
      
   return temp3231;
 }

Вот как-то так. Непонятно пока, что произойдет при совпадении текущего времени с установленным в байтах 07h-0Ah и в 0Bh-0Dh, но этим займусь завтра.


понедельник, 19 мая 2014 г.

Arduino. Программирование

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

Еще раз напомню о замечательной подборке материалов по Arduino, датчикам и библиотекам на robocraft.ru


воскресенье, 18 мая 2014 г.

Arduino. Звук - пищим динамиком

В коробке остался 8Ом-ный динамик, 0,5W. Порылся в закромах, нашел ссылку на статью о подключении динамика к Arduino.

Схема подключения

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

Простейший скетч

void setup() {
}

void loop() {
tone(8, 311,300);
delay(500);
noTone(8);
}
}


суббота, 17 мая 2014 г.

Arduino. HC-SR04 - ультразвуковой модуль измерения расстояния

Имеющихся в наличии датчиков все меньше и меньше и выбора особого уже не остается. :о) Сегодня подключаем датчик HC-SR04 - ультразвуковой датчик измерения расстояния.

Дополнительных библиотек к нему не надо, что существенно упрощает нам жизнь. ;о) Немного дополнительной информации можно почерпнуть отсюда или отсюда.

Схема подключения самая простая.

Скетч для работы с датчиком
#define Trig 9
#define Echo 8

void setup()
{
pinMode(Trig, OUTPUT); //инициируем как выход
pinMode(Echo, INPUT); //инициируем как вход
Serial.begin(9600);
/* задаем скорость общения. В нашем случае с компьютером */
}
unsigned int impulseTime=0;
unsigned int distance_sm=0;

void loop()
{
digitalWrite(Trig, HIGH);
/* Подаем импульс на вход trig дальномера */
delayMicroseconds(10); // равный 10 микросекундам
digitalWrite(Trig, LOW); // Отключаем
impulseTime=pulseIn(Echo, HIGH); // Замеряем длину импульса
distance_sm=impulseTime/58; // Пересчитываем в сантиметры
Serial.println(distance_sm); // Выводим на порт
delay(100);
/* ждем 0.1 секунды, Следующий импульс может быть излучён, только после исчезновения эха от предыдущего. Это время называется периодом цикла (cycle period).
Рекомендованный период между импульсами должен быть не менее 50 мс. */
}

Думаю, как подключить дальномер к УСТРОЙСТВУ и как изменить скетч - понятно. Только стоит обратить внимание на то, что Digital 8 у нас занят датчиком HC-SR501. Поэтому предлагаю Echo подключить к Digital 7, и внести необходимые изменения в блоке определения пинов.

На этом имеющиеся в наличии датчики закончились - остались только два двигателя и контроллер к ним. И еще нашел динамик 8 Ом-ный. Так что впереди борьба с колесами и музыка. :о)

При тестировании выявился такой неприятный момент - на дистанции более 2 метров расстояние фиксируется не стабильно. Т.е. и 201 покажет и 203, но может и 820 показать или 930. Причем чем дальше от приемника, тем реже на экране возникают правильные цифры. До двух метров меня дальномер "ловил" хорошо. Как вариант может попробовать сделать трубку из бумаги на излучатель, чтобы сузить сектор? Должно быть меньше помех и проще будет определять, куда излучение "полетело". Хотя, если все так просто, почему производители изначально не делают трубки более длинными? Непонятно...

Трубка не помогла. На расстоянии до 150 см фиксация четкая. Выше - начинают выскакивать 875 и другие "неправильные" числа. Вывод - датчик стабильно работает на полтора метра. Дальше - сложно будет отсеять достоверные результаты от помех.


пятница, 16 мая 2014 г.

Arduino. Датчик движения HC-SR501

Дело было вечером, делать было нечего... Решил пересмотреть свою копилку материалов по датчикам к Arduino. Наткнулся на схему проверки работоспособности датчика движения HC-SR501

Вместо рекомендуемого 4.5 кОм резистра воткнул 15 кОм (ну, что нашел). Датчик весело замигал светодиодом при движении. Много интересного про датчик можно прочитать, например, на этом ресурсе.

До подключения к плате осталось пара шагов - подключил выход Out к 8 разъему (Digital) на плате микроконтроллера. По совету, увиденному в одном из форумов подвязал Out резистором к земле. Номинал резистора оставил 15 кОм. Питание (+5В) и землю взял с платы.

Простейший скетч для проверки работы датчика с Arduino

int pirPin = 8;
int val;

void setup() {
    pinMode(pirPin,INPUT);
    Serial.begin(9600);
}

void loop() {
    val = digitalRead(pirPin); //read state of the PIR
    if (val == LOW) {
      Serial.println("No motion"); //if the value read is low, there was no motion
    }
    else {
      Serial.println("Motion!"); //if the value read was high, there was motion
    }
    delay(1000);
}

Когда все заработало, перецепил все на схему к уже собранному УСТРОЙСТВУ. Модифицировал скетч - при появлении сигнала от датчика включается подсветка экрана и горит 5 секунд.

#include Wire.h
#include DS3231.h
#include LiquidCrystal.h
/*
The circuit:
* 5V to Arduino 5V pin
* GND to Arduino GND pin
* SDA (data) to Analog #4
* SCL (clock) to Analog #5
*/

// Connect via i2c, default address #0 (A0-A2 not jumpered)
LiquidCrystal lcd(0);
DS3231 Clock;
bool h12=false;//True is 12-h, false is 24-hour.;
bool PM;
bool Century=false;

int pirPin = 8;
int val;
int msec;

void setup() {
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
lcd.clear();
lcd.setBacklight(LOW);
Wire.begin();
pinMode(pirPin,INPUT);
}

void loop() {
int second,minute,hour,date,month,year,temperature;

val = digitalRead(pirPin); //read state of the PIR
if (val == LOW){
lcd.setBacklight(LOW); //if the value read is low, there was no motion
}
else {
lcd.setBacklight(HIGH);
msec=millis()/1000;
}
if (millis()/1000-msec<5) lcd.setBacklight(HIGH);

year=Clock.getYear();
month=Clock.getMonth(Century);
date=Clock.getDate();
hour=Clock.getHour(h12,PM);
minute=Clock.getMinute();
second=Clock.getSecond();
temperature=Clock.getTemperature();

lcd.print("20");
lcd.print(year,DEC);
lcd.print('-');
if (month<10) lcd.print('0');
lcd.print(month,DEC);
lcd.print('-');
if (date<10) lcd.print('0');
lcd.print(date,DEC);

// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
if (hour<10) lcd.print('0');
lcd.print(hour,DEC);
lcd.print(':');
if (minute<10) lcd.print('0');
lcd.print(minute,DEC);
lcd.print(':');
if (second<10) lcd.print('0');
lcd.print(second,DEC);
lcd.print(' ');
lcd.print("Temp:");
lcd.print(temperature);
delay(500);
lcd.setCursor(0,0);
}

тут завтра будет фотография УСТРОЙСТВА


Arduino. DS3231 и I2C/SPI LCD1602 в одном флаконе

Сегодня мне удалось собрать первый функциональный прибор, который может работать без компьютера. Ранее, я уже писал о подключении высокоточных часов и I2C LCD 1602 по шине I2C. Следующей стояла задача совместного использования этих устройств.

В интернете нашел несколько статей по использованию шины I2C. Есть более развернутые статьи, есть менее. Интересующимся рекомендую вот эту статью. Или вот эту. В статье рекомендуют привязывать разъемы SDA и SCL к +5 вольтам. Номинал резисторов от 1кОм до 10 кОм. Я поставил 1кОм (других не нашлось).

Схема сборкиФотография

Скетч просто собрал из двух, использовавшихся ранее для часов и экрана

#include Wire.h
#include DS3231.h
#include LiquidCrystal.h
/**
The circuit:
* 5V to Arduino 5V pin
* GND to Arduino GND pin
* SDA (data) to Analog #4
* SCL (clock) to Analog #5
**/

// Connect via i2c, default address #0 (A0-A2 not jumpered)
LiquidCrystal lcd(0);
DS3231 Clock;
bool h12=false;//True is 12-h, false is 24-hour.;
bool PM;
bool Century=false;

void setup() {
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
lcd.clear();
lcd.setBacklight(LOW);
Wire.begin();
}

void loop() {
int second,minute,hour,date,month,year,temperature;

year=Clock.getYear();
month=Clock.getMonth(Century);
date=Clock.getDate();
hour=Clock.getHour(h12,PM);
minute=Clock.getMinute();
second=Clock.getSecond();
temperature=Clock.getTemperature();

lcd.print("20");
lcd.print(year,DEC);
lcd.print('-');
if (month<10) lcd.print('0');
lcd.print(month,DEC);
lcd.print('-');
if (date<10) lcd.print('0');
lcd.print(date,DEC);

// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
if (hour<10) lcd.print('0');
lcd.print(hour,DEC);
lcd.print(':');
if (minute<10) lcd.print('0');
lcd.print(minute,DEC);
lcd.print(':');
if (second<10) lcd.print('0');
lcd.print(second,DEC);
lcd.print(' ');
lcd.print("Temp:");
lcd.print(temperature);
delay(500);
lcd.setCursor(0,0);
}


Вот такие вот часы у меня получились. ;о)


Arduino. DS3231 - высокоточные часы реального времени

Иду дальше по плану. Высокоточные часы. Тут все было предельно просто - на странице интернет-магазина сразу имелась ссылка на библиотеки. Распаковал, установил файлы из папки DS3231_TEST, запустил скетч из примера... Замечательный девайс! Показывает время и температуру. А наличие батарейки позволяет таймеру работать и без подключения к компьютеру.

Вот упрощенный текст скетча
#include DS3231.h
#include Wire.h

DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte year, month, date, DoW, hour, minute, second;

void setup() {
// Start the I2C interface
Wire.begin();
Clock.setSecond(50);//Set the second
Clock.setMinute(59);//Set the minute
Clock.setHour(11); //Set the hour
Clock.setDoW(5); //Set the day of the week
Clock.setDate(31); //Set the date of the month
Clock.setMonth(5); //Set the month of the year
Clock.setYear(13); //Set the year (Last two digits of the year)
// Start the serial interface
Serial.begin(9600);
}

void loop() {
int second,minute,hour,date,month,year,temperature;
second=Clock.getSecond();
minute=Clock.getMinute();
hour=Clock.getHour(h12, PM);
date=Clock.getDate();
month=Clock.getMonth(Century);
year=Clock.getYear();
temperature=Clock.getTemperature();

Serial.print("20");
Serial.print(year,DEC);
Serial.print('-');
Serial.print(month,DEC);
Serial.print('-');
Serial.print(date,DEC);
Serial.print(' ');
Serial.print(hour,DEC);
Serial.print(':');
Serial.print(minute,DEC);
Serial.print(':');
Serial.print(second,DEC);
Serial.print('\n');
Serial.print("Temperature=");
Serial.print(temperature);
Serial.print('\n');
delay(1000);
}

И схема подключения. Аналогична схеме подключения LCD.

Следующий шаг - заставить работать два устройства I2C на одной паре проводов. Т.е. чтобы часы выводили данные на LCD, а не через виртуальный COM-порт в среду разработки. Как разберусь - напишу. ;)


Arduino. I2C/SPI LCD1602 Module

Вчера почти весь день боролся с модулем IIC/I2C/TWI SPI Serial LCD 1602.

И так его уговаривал, и так... В конце концов решил подойти к решению вопроса системно - для начала узнать, какой адрес имеет подключаемый модуль. Скачал скетч сканера I2C, запустил его при подключенном экране. Узнал, что устройство имеет адрес 0х20. Отлично! Казалось бы, вот оно, счастье.. Но знание адреса не помогло. Перепробовал кучу разных библиотек для I2C LCD, и все никак. Менял провода, платы с микроконтроллером... Тоже без толку.

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

В конце концов наткнулся на страничку производителя модуля. И там, помимо схемы устройства оказались еще и библиотеки для модуля. Заработала вот эта библиотека SPI_IIC_LCD library for Arduino 1.0. Причем заработал код из примера, при выставленном адресе не 0х20, а просто 0! Почему так получилось - не понял. Будет время - покопаюсь. Но сейчас модуль исправно выводит надписи, мигает подсветкой и вообще ведет себя образцово.

Вот текст скетча

#include Wire.h
#include LiquidCrystal.h

// Connect via i2c, default address #0 (A0-A2 not jumpered)
LiquidCrystal lcd(0);

void setup() {
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
lcd.print("hello, world!");
}

void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis()/1000);
lcd.setBacklight(HIGH);
delay(500);
lcd.setBacklight(LOW);
delay(500);
}

И схема подключения, на всякий пожарный. :о)


среда, 14 мая 2014 г.

Arduino. Первое включение. Мигаем светодиодом.

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

Когда открывал посылку, был удивлен размерами деталей. Ну, вот как такую фот финтифлюшку брать моими пальцами! :о)

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

IDE качал с официального сайта. Единственно, скачивал релиз Arduino 1.5.6-r2 BETA (with support for Arduino Yún and Arduino Due boards Кстати, развернутая из архива, а не проинсталлированная, среда отлично работает.

И еще нюанс. На микроконтроллер изначально был прошил скетч blink, который просто периодически мигает светодиодом на плате. Т.е. даже залив скетч blink из примеров, идущих в комплекте, я не был на 100% уверен, что это мигает мой скетч, а не изначально залитый на микроконтроллер. Поэтому внес небольшие поправки.


/* Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This example code is in the public domain.
*/
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second

digitalWrite(led, HIGH);
delay(500);
digitalWrite(led, LOW);
delay(1000);

digitalWrite(led, HIGH);
delay(100);
digitalWrite(led, LOW);
delay(1000);

}

Теперь светодиод мигает, как и раньше через равные промежутки времени, но время свечения различается. Вот после этого я поверил, что это заработал залитый мной скетч! :о)

Обе платы пока работают идентично. Завтра попробую цеплять сенсоры.


четверг, 3 апреля 2014 г.

Arduino есть. Что дальше?

На следующей неделе, наконец-то, смогу начать разбираться с заказанным ранее клоном Arduino. В качестве памятки для себя накидаю перечень имеющихся компонентов, компонентов планируемых к покупке и предполагаемый функционал устройства. По мере реализации задумок буду выкладывать статьи. Ну, понеслась.

Компонент Описание Функционал
Плата микроконтроллера Собственно, сама по себе плата может только мигать светодиодом и слать на ПК запрограммированные сигналы. Пока не очень интересно. Но перспективы есть - контроллер-то программируемый!.:о)
2,6" ЖК-дисплей Можно будет снимать какие-то данные без подключения к компьютеру. УСТРОЙСТВО начинает обретать автономность. ;о) Кстати, данный экран имеет маркировку 1602, что подсказывает нам о возможности вывода на экран двух строк по 16 символов.
Высокоточные часы реального времени Чтобы было что выводить на экран. Ну и полезный функционал появляется. Так ведь веселее. :о)
Пироэлектрический датчик Теперь УСТРОЙСТВО сможет узнавать, когда к нему кто-то подходит. Зачем? Ну, хотя бы для того, чтобы начать что-то выводить на экран. Предполагается, что в отсутствии зрителей на экран не будет ничего выводиться.
Ультразвуковой модуль измерения расстояния Ну как же без измерителя расстояния! Очень нужный датчик. Пригодится потом, когда УСТРОЙСТВО обзаведется колесами и будет учиться избегать столкновений с препятствиями.
Зуммер У нас есть часы. Почему бы не сделать их будильником? Пусть напоминает о событиях звуковым сигналом. А можно еще и на экран выводить напоминалку. Кроме того видел схемы с подключением 8-омных динамиков. Можно будет попробовать не простые Би-и-и или Дз-з-з реализовывать, а какие-нибудь простенькие мелодии выводить.
Выходной сдвиговый регистр 8 бит - 74HC595 Зачем? Даже себе не смог объяснить. Но так звучит красиво: "Сдвиговый регистр"! В принципе, позволит получить +7 выходных портов, каскадами регистров можно получать еще более значительное увеличение выходных портов. Может быть полезно при управлении большим числом внешних устройств. Например - диодной матрицей.
Входной сдвиговый регистр 8 бит - 74HC165N Вообще без понятия. Но раз уж буду брать выходной регистр, то с входным тоже надо разобраться. До кучи. :о)
10-ти сегментный индикатор А это мой подопытный "кролик", для тестирования 74HC595
Модуль памяти Micro SD Лучше поздно, но задуматься о ведении логов событий. SD-карта - вполне удобный вариант.
Цифровой датчик температуры и влажности Вот представим себе - гуляю я вечером по улице. Подходят ко мне ребята и спрашивают время. Я достаю из кармана УСТРОЙСТВО и говорю им, который час. Ребята слегка офигевают. А если самые ушлые спросят про температуру, я им тоже смогу ответить! Ну, не бить же людей каждый раз за то, что они расстроились, не получив ответ на вопрос о времени! :о)) А если серьезно - это начало блока контроля за растениями. :о) Есть у меня такая задумка на перспективу. Да и в быту, думаю, такая информация может быть не лишней.
Датчик влажности почвы Втыкаем щуп в землю и считываем информацию о влажности грунта. ИМХО, штука полезная. Когда-нибудь можно будет к системе еще и автополив прикрутить, но на первом этапе с лейкой, думаю, я и сам справлюсь. ;о) Датчиков влажности много - указанный тут лишь один из них. Я пока еще предметно вопрос не изучал. Может есть и более качественные. Кстати, большое количество датчиков можно будет прикрутить к ардуине с помощью входного сдвигового регистра. Т.е. контролировать несколько десятков саженцев - не проблема.
Датчик освещенности Штука нужная для подключения дополнительного освещения растениям. Пока это просто памятка о необходимости изучения данного вопроса. Есть фоторезисторы и фотодиоды. Кто-то из них дает более приятные сигналы на выходе, подходящие к моей задаче. Ближе к реализации разберусь и в статье напишу.
Датчик звука Интересно, а можно ли будет управлять УСТРОЙСТВОМ посредством дискретных звуковых сигналов? Разработать набор звуковых кодов (стуков) и использовать для управления. Потом надо будет разобраться с компонентами.
Компас Надеюсь, растения оценят мою заботу о них и начнут активно расти. Вот тогда мне и пригодится компас, чтобы выбираться из зарослей с огорода! :о)) И для навигации УСТРОЙСТВА в будущем пригодится. Вопрос нуждается в дополнительном изучении.
Bluetooth Буду ли по блютусу управлять УСТРОЙСТВОМ - не знаю. Но как вариант, можно использовать датчик для привязки к хозяину. Уровень сигнала падает быстро и используя это, УСТРОЙСТВО сможет определять направление, в котором хозяин от него удаляется. Или оно удаляется от хозяина. :о)

Собственно, на этом немобильная версия УСТРОЙСТВА закончится. К моменту реализации всего вышеуказанного, надеюсь, старшему ребенку надоест его игрушка и удастся задействовать ее в качестве мобильной платформы.

Вот такие вот скромные планы. А еще в планах закончить ремонт в туалете, сменить пол в коридоре и обшить балкон. Но это уже не так интересно, думаю все с этим сталкивались. ;о)