CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Практическое программирование Arduino/CraftDuino - протокол 1-Wire и iButton

Сегодня мы познакомимся с интересным протоколом 1-Wire и даже сразу попробуем поработать с устройством, использующим этот протокол. «Как?» — спросите Вы – «мне не нужно будет покупать детали в радиомагазине?»
«Нет» — отвечу я :) С большой долей вероятности, Вы пользуетесь устройством 1-Wire и, возможно, даже не догадываетесь об этом :) Это всего-навсего – ключ-таблетка от домофона (iButton)!
iButton
Неужели?
Достанем ключи из кармана и примемся их пристально разглядывать :)
У меня контактная площадка сильно затёрта, но какие-то надписи проглядывают.
iButton
Потёр площадку фломастером и становится видна заветная надпись:

iButton.com
00000F67CE41
1-Wire
0744 UB1 DS1990A#F5


Ага! 1-Wire!
Так что же это за интерфейс?
Это однопроводной интерфейс, разработан фирмой Dallas Semiconductor (ныне MAXIM) в конце 90-х годов.

Этот интерфейс интересен тем, что для двустороннего обмена требуется всего одна линия! (отсюда и название :)

Подробнее об интерфейсе здесь.

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

DS1990A – это и есть название нашего устройства.

Смотрим варианты iButton-ов на сайте производителя
Наш ключ — это самая первая модель в списке :)
DS1990A — 64 Bit ID — уникальный серийный номер-ключ
Страничка этого ключика здесь, а здесь можно скачать датащит ;)

Число после # определяет форм-фактор ключа – у меня F5.

Итак, наш ключ хранит 64 бита уникальной информации
Питается от 2.8V до 6.0V
К центральной контактной площадке подключается линия данных, а к боковой каёмке – землю.
Ключ может работать в диапазоне температур от -40°C до +85°C – впрочем, это нам не нужно :)

Читаем датащит далее :)

Величина подтягивающего резистора рекомендуется в 2.2k
Так… запомним :)

Каждый DS1990A прошивается уникальным 64-битным номером

первые 8 бит — номер серии устройства (01h)
следующие 48 бит — уникальный серийный номер
последние 8 бит — CRC-код предыдущих 56 бит информации :)

(Cyclic redundancy code, CRC — циклический избыточный код) — способ цифровой идентификации некоторой последовательности данных, который заключается в вычислении контрольного значения её циклического избыточного кода.


Далее в датащите перечислены команды, которые понимает ключ:
33h — считать ROM — команда позволяет считать заветные 64-бита данных ключа
F0h — поиск ROM — т.к. к сети 1-wire может быть подключено несколько устройств данная команда используется для идентификации подключённых устройств.
55h — соответствие ROM / CCh — пропуск ROM
— данные команды входят в минимальный набор необходимых команд 1-wire-устройств. Т.к. в ключе DS1990A эти команды не требуются — он на них не отвечает.

Arduino/CraftDuino/Freeduino может работать с 1-Wire, используя библиотеку Jim Studt-а – OneWire.

Настало время пообщаться с нашим ключиком! :)

Схема подключения – крайне проста (это ведь 1-Wire! :)

Далее нужно скачать библиотеку OneWire и поместить её в свою директорию libraries.

Код скетча:
#include <OneWire.h>

/* 
 * тестируем работу по 1-Wire с ключём-таблеткой DS1990A
 */

OneWire  ds(10);  // на  digital pin 10

void setup(void) {
  Serial.begin(9600);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  
  if ( !ds.search(addr)) {
      Serial.print("No more addresses.\n");
      ds.reset_search();
      return;
  }
  
  Serial.print("R=");
  for( i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX);
    Serial.print(" ");
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.print("CRC is not valid!\n");
      return;
  }
  
  if ( addr[0] != 0x01) {
      Serial.print("Device is not a DS1990A family device.\n");
      return;
  }
  Serial.println();
  ds.reset();
  
  delay(1000);
}

Происходит постоянный поиск устройств на линии 1-Wire. Пока ключ не подключён – выдаётся:
No more addresses.
При подключении ключа-таблетки – считывается её номер и выдаётся в COM-порт.
Например, вот что выдаётся при подключении ключа-таблетки, с которого начиналась эта статья:

Первая цифра – номер серии – 01h
Далее, как видим, действительно ключ хранит номер, нанесённый на своём корпусе ;)
Только этот номер выведен наоборот – как и положено по протоколу 1-Wire – начиная с младшего байта ;)
Последний байт –B6h — CRC-код предыдущих байт.

Ура! Вот мы и считали наш ключ :)

Теперь можно самостоятельно сделать замок для комнаты или разблокировать свой компьютер по ключу :) Фантазируем :)

Читать далее: Arduino/CraftDuino и эмулятор iButton.

Cсылки:
Интерфейс 1-Wire — данная замечательная статья использовалась при написании заметки об интерфейсе 1-Wire

iButton
варианты iButton
Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products

внутренности iButton

http://en.wikipedia.org/wiki/1-Wire
http://ru.wikipedia.org/wiki/Фантомное_питание
http://ru.wikipedia.org/wiki/Порядок_байтов
http://ru.wikipedia.org/wiki/CRC
библиотека Jim Studt-аOneWire для Arduino
  • +4
  • 6 декабря 2009, 16:10
  • admin

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

RSS свернуть / развернуть
+
+1
ага, т.е. таким образом можно и сделать обратную операцию? сообщить в домофон код ключа посредством ардуино?
avatar

jbrain

  • 7 декабря 2009, 01:30
+
0
разумеется :) про это в следующей статье ;)
avatar

admin

  • 7 декабря 2009, 10:11
+
0
И сколько времени понадобится для подбора неизвестного ключа?)
avatar

Oboroten

  • 12 декабря 2009, 12:53
+
0
я об этом напишу в следующей статье :) но сразу хочу анонсировать, что обычный брут-форс не получится :(
однако, на некоторых домофонах есть другая возможность ;)
avatar

admin

  • 12 декабря 2009, 14:39
+
0
Почемуто после создания папки libraries и копирования в неё папки с библиотекой OneWire выдает ошибку
21: error: OneWire.h: No such file or directory In function 'void loop()':
Если же в #include прописать полный путь #include <C:\\arduino-0017\lib\OneWire\OneWire.h>
Выдает ошибку
C:\DOCUME~1\snk\LOCALS~1\Temp\build2355.tmp/_1wire.cpp:46: undefined reference to `OneWire::reset()'

Подскажите что делать?

avatar

snicksnk

  • 13 июля 2010, 14:26
+
0
в Вашем случае библиотеку нужно поместить в каталог
arduino-0017\hardware\libraries\
avatar

noonv

  • 13 июля 2010, 14:36
+
0
Ещё вопрос почему в serial monitor пишет чтото вроде
R=0 0 0 0 0 0 0 0 Device is not a DS1990A family device.
R=0 0 0 0 0 0 0 80 CRC is not valid!
R=0 0 0 0 0 8 0 40 CRC is not valid!

Причина может быть в том, что вместо 2,2 ком взял 2 ком?
В какое именно зазмление на плане arduino нужно втыкать провод?
avatar

snicksnk

  • 14 июля 2010, 00:20
+
0
резистор 2-2.2к, по идее, не должен так сильно влиять.
В землю — в любую — они гальванически связаны.
avatar

noonv

  • 14 июля 2010, 09:59
+
0
У меня почти также пишет:
R=1 5D 9B 9 B 0 0 CC Device is not a DS18S20 family device.
R=1 5D 9B 9 B 0 0 CC Device is not a DS18S20 family device.
R=1 5D 9B 9 B 0 0 CC Device is not a DS18S20 family device.

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

mogalkov

  • 14 июля 2010, 21:46
+
0
Есть хорошее описание протокола 1-Wire. Там же есть код для микроконтроллеров PIC — пример проекта для включения компьютера от кнопки iButton. Кстати, разобравшись в особенностях работы протокола, можно создавать небольшие (или большие — кому как) сети 1-Wire устройств — сети Microwire — а это уже интересней.
avatar

PICengine

  • 12 января 2011, 18:21
+
0
Использовал резистор 2.7 ком. Всё хорошо читается, но заметил такую особенность: на монитор выводятся
не все нули. На таблетке написано 3A 00 00 12 A1 A3 03 01, а на монитор выводится 13 A3 A1 12 00 3A.
Почему так?
avatar

sambor

  • 18 января 2011, 21:58
+
0
а если так?
1 3 A3 A1 12 0 0 3A

Обратите внимание на скриншот, приведённый в статье ;)
просто print не дополняет нулями слева :)
avatar

noonv

  • 18 января 2011, 22:06
+
0
А можно ли сделать, чтоб выводиллись все нули?
avatar

sambor

  • 18 января 2011, 22:26
+
0
всё в ваших руках ;) можете просто проверять, что текущий элемент массива меньше 16 и выводить дополнительный 0.
avatar

noonv

  • 18 января 2011, 22:29
+
0
Дополнить можно, но ноль может стоять в любом месте и чё куда дополнять.
Так или иначе спасибо за совет.
avatar

sambor

  • 18 января 2011, 22:39
+
0
Забыл сказать, данные я вывожу не на СОМ порт, а на LCD дисплей, подключенный к Arduino,
без промежутков между байтами, командой LCD.print. И именно по этому отсутствие ноликов удручает.
avatar

sambor

  • 18 января 2011, 22:57
+
0
А почему в данном примере считывается и выводится не содержание ПЗУ, а его адрес? Разве читать сам ROM не нужно?
Кстати, у моего ключа, CRC8 почему-то равна последнему байту адреса. (Возможно, совпадение...)

Ogogon.
avatar

ogogon

  • 8 мая 2011, 20:30
+
0
Помогите не могу никак разобраться! У меня Ардиуно Мега 1280 и ни одна из двух библиотек OneWire не работает! — все отлично компилируется и записывает в ардуину, но ключи не считываются! Все время повторяется надпись No more addresses. Кто знает в чем может быть дело? может есть какое то несоостветствие в номерах выводов на плате, но как узнать что чему соовтетсвтует???
avatar

Alec

  • 16 июля 2011, 13:05
+
0
Та же история, в одном источнике было указано на необходимость обновления библиотеки.Где ее взять?
avatar

Vladis

  • 21 августа 2011, 15:08
+
0
А какой ключик использовали? Ключи от домофонов Цифрал и Визит не подходят. У них собственный протокол, отличный от DS1990A! Если пробовать их, то как раз и будет постоянно надпись No more addresses. Хотя иногда может и прочитать все нули и выдать ошибку. Нужно использовать только оригинальные ключи DS1990A или их ПОЛНЫЙ аналог…
avatar

TrueNow

  • 8 октября 2011, 08:38
комментарий был удален

+
0
Товарищи, собираю схему, код читается только с одного «неопознанного» ключа и то постоянно выдает разные коды.
Работает только с резистром на 1ком.
Со вторым ключом TM01A не работает ни как.
avatar

StemTi

  • 7 ноября 2016, 11:32
+
0
Если нету вообще никаких резисторов (как было у меня), то у меня сработал следующий вариант.
В секцию setup добавляем
pinMode(10,INPUT_PULLUP);
pinMode(11,INPUT_PULLUP);
И объединяем 10 и 11 пины перемычкой. Тогда ваш iButton ключ будет питаться через встроенные в микроконтроллер резисторы. Если не работает — можно попробовать добавить ещё несколько пинов, у которых включены подтягивающие резисторы.
avatar

Lop

  • 6 ноября 2017, 16:07

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.