Модуль - ИК-приёмник/передатчик, FLASH-I2C.
Техническое описание: Данная страница содержит подробное техническое описание модуля - ИК-приемник/передатчик, FLASH-I2C и раскрывает работу с модулем через его регистры.
Ознакомиться с пользовательским описанием модуля и примерами работы с библиотекой iarduino_I2C_IR можно на странице Wiki - ИК-приемник/передатчик, FLASH-I2C.
Назначение:
Модуль - ИК-приемник/передатчик, FLASH-I2C - является устройством для беспроводного обмена данными по ИК-каналу. Модуль позволяет передавать данные на устройства с управлением от ИК пультов ДУ, обмениваться данными с подобными себе модулями и получать данные от ИК пультов ДУ, и модулей линейки «Дорожное движение». Управление модулем ИК-приёмопередатчика осуществляется по шине I2C.
К одной шине I2C можно подключить более 100 модулей. Адрес модуля на шине I2C (по умолчанию 0x09) назначается программно и хранится в его энергонезависимой памяти.
Описание:
Модуль построен на базе, микроконтроллера STM32F030F4, снабжён ИК-приёмником, двумя ИК-светодиодами для передачи данных, светодиодами информирующими о приёме и передаче данных по ИК-каналу, регулятором дальности ИК-передатчика, и собственным стабилизатором напряжения. Модуль способен принимать и передавать данные по ИК-каналу в соответствии с протоколами: NEC, SAMSUNG, SHARP, SIRC12, SIRC15, RC5, RC5X, RC6 и IARDUINO. Все перечисленные протоколы используют пакетную передачу данных, данные в пакете представлены в виде адреса ИК-устройства (не путать с адресом устройства на шине I2C) и команды для него. При получении данных по ИК-каналу, модуль способен самостоятельно определить протокол который был использован для их отправки.
Настройка модуля, запись и чтение данных, осуществляется через его регистры. Доступ к регистрам модуля осуществляется по шине I2C.
С помощью регистров модуля можно выполнять следующие действия:
- Изменить адрес данного модуля на шине I2C. При изменении адреса, можно указать, что новый адрес должен сохраниться в flash память модуля, а значит адрес сохранится и после отключения питания.
- Включить / отключить внутреннюю подтяжку линий шины I2C (по умолчанию включена). Состояние подтяжки линий шины I2C автоматически сохраняется в flash память модуля, а значит состояние линий сохранится после отключения и включения питания.
- Узнать версию прошивки модуля.
- Указать данные для передачи по ИК-каналу (адрес устройства и команду).
- Прочитать принятые по ИК-каналу данные (адрес устройства и команду).
- Задать автоматическую отправку данных по ИК-каналу с заданным интервалом.
- При автоматической отправке данных, можно задать режим хаотичной смены интервалов между пакетами (в диапазоне ±50% от заданного), что позволит передавать данные по ИК-каналу от нескольких модулей, в одном направлении, одновременно.
- Определить факт получения по ИК-каналу данных отправляемых в автоматическом режиме (факт получения пакетов повторов, как при удержании кнопки ИК-пульта ДУ).
- Выбрать один из 9 доступных протоколов для передачи данных по ИК-каналу.
- Выбрать один из 9 доступных протоколов для получения данных по ИК-каналу.
- Включить/отключить ИК-передатчик.
- Включить/отключить ИК-приёмник.
- Включить/отключить режим автоопределения кодировки ИК-приёмником.
Выводы модуля:
Модуль подключается по шине I2C, все выводы которой (GND, Vcc, SDA, SCL) размещены на одной колодке.
- SCL - вход/выход линии тактирования шины I2C.
- SDA - вход/выход линии данных шины I2C.
- Vcc - вход питания от 3,3 до 5 В.
- GND - общий вывод питания.
Характеристики:
- Напряжение питания: 3,3 В или 5 В, поддерживаются оба напряжения.
- Ток потребляемый модулем: до 15 мА.
- Интерфейс: I2C.
- Скорость шины I2C: 100 кбит/с.
- Адрес на шине I2C: устанавливается программно (по умолчанию 0x09).
- Уровень логической 1 на линиях шины I2C: Vcc.
- Рабочая температура: от -20 до +70 °С.
- Габариты: 30 х 30 мм.
- Вес: 5 г.
Установка адреса:
Модуль - ИК-приемник/передатчик, FLASH-I2C относится к серии «Flash» модулей. Все модули данной серии позволяют назначать себе адрес для шины I2C, как временно (новый адрес действует пока есть питание), так и постоянно (новый адрес сохраняется в энергонезависимую память и действует даже после отключения питания). По умолчанию все модули серии «Flash» поставляются с адресом 0x09.
Допускается указывать адреса в диапазоне: 7 < адрес < 127.
Установка адреса (без сохранения):
Если в регистр 0x06 «ADDRESS» записать значение из 7 бит адреса и младшим битом «SAVE_FLASH» равным 0, то указанный адрес станет адресом модуля на шине I2C, но он не сохранится во FLASH памяти, а значит после отключения питания или перезагрузки, установится прежний адрес модуля.
Установка адреса может быть заблокирована, если в регистре 0x01 «BITS_0» установлен бит «BLOCK_ADR». Этот бит по умолчанию сброшен, но он самостоятельно устанавливается при попытке записи данных в регистры предназначенные только для чтения. Бит «BLOCK_ADR» используется в модулях версии 5 и выше. Версия модуля хранится в регистре 0x05 «VERSION».
Установка адреса (с сохранением):
Для установки адреса с его сохранением в FLASH память модуля необходимо выполнить два действия:
- Установить бит «SAVE_ADR_EN» в регистре 0x01 «BITS_0» (при этом адрес модуля останется прежним).
- Записать в регистр 0x06 «ADDRESS» значение из 7 бит адреса и младшим битом «SAVE_FLASH» равным 1.
Если не выполнить первое действие (не установить бит «SAVE_ADR_EN»), то новый адрес будет проигнорирован и у модуля останется старый адрес. Бит «SAVE_ADR_EN» самостоятельно сбрасывается после сохранения адреса во FLASH память, а так же при обращении к любому регистру модуля (кроме записи в 0x01 «BITS_0» и 0x06 «ADDRESS»).
Установка адреса может быть заблокирована, если в регистре 0x01 «BITS_0» установлен бит «BLOCK_ADR». Этот бит по умолчанию сброшен, но он самостоятельно устанавливается при попытке записи данных в регистры предназначенные только для чтения. Бит «BLOCK_ADR» используется в модулях версии 5 и выше. Версия модуля хранится в регистре 0x05 «VERSION».
ВАЖНО: запись адреса занимает не менее 30 мс.
Регистры:
Карта регистров модуля:
адрес | РЕГИСТРЫ ОБЩЕГО НАЗНАЧЕНИЯ: | |||||||
---|---|---|---|---|---|---|---|---|
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0x00 | FLG_RESET | FLG_SELF_TEST | - | FLG_GET_NAME | RAND_ADR | FLG_I2C_UP | RESERVED | RESERVED |
0x01 | SET_RESET | SET_SELF_TEST | - | SET_GET_NAME | BLOCK_ADR | SET_I2C_UP | SAVE_ADR_EN | RESERVED |
0x02 0x03 |
RESERVED |
|||||||
0x04 | MODEL[7-0] | |||||||
0x05 | VERSION[7-0] | |||||||
0x06 | ADDRESS[6-0] | SAVE_FLASH | ||||||
0x07 | CHIP_ID[7-0] | |||||||
0x08 --- 0x0F |
RESERVED | |||||||
адрес | РЕГИСТРЫ УПРАВЛЕНИЯ ИК-ПЕРЕДАТЧИКОМ: | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0x10 | SEND_REPEAT[7-1] | REPEAT | ||||||
0x11 | SEND_ADR[7-0] | |||||||
0x12 | SEND_COM[7-0] | |||||||
0x13 | RC6_MODE[2-0] | NUM_CODING[5-0] | ||||||
адрес | РЕГИСТРЫ УПРАВЛЕНИЯ ИК-ПРИЁМНИКОМ: | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0x14 | WAIT_REPEAT[7-1] | REPEAT | ||||||
0x15 | READ_ADR[7-0] | |||||||
0x16 | READ_COM[7-0] | |||||||
0x17 | RC6_MODE[2-0] | NUM_CODING[5-0] | ||||||
адрес | РЕГИСТРЫ УПРАВЛЕНИЯ МОДУЛЕМ: | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0x18 | RESERVED | RESERVED | BIT_TX_BUSY | RESERVED | TX_SHIFT | DETECT | RX_EN | TX_EN |
Регистры с адресами 0x02, 0x03 и 0x08 - 0x0F зарезервированы, их биты сброшены в 0. Попытка записи данных в эти регистры будет проигнорирована модулем.
Регистр 0x00 «FLAGS_0» - содержит флаги чтения состояния модуля:
Регистр только для чтения.
- FLG_RESET - Флаг указывает на факт выполнения успешной перезагрузки модуля. Флаг самостоятельно сбрасывается после чтения регистра 0x00 «FLAGS_0».
- FLG_SELF_TEST - Флаг указывает на результат выполнения самотестирования модуля (0-провал, 1-успех). Не поддерживается данным модулем.
- FLG_GET_NAME - Если флаг установлен, значит модуль поддерживает вывод своего названия установкой бита «SET_GET_NAME» в регистре 0x01 «BITS_0».
- RAND_ADR - Если флаг установлен, значит модуль поддерживает генерацию случайного адреса для шины I2C регистрами 0x64 «RANDOM_NUM», «RANDOM_ADR», «BUN_ADR».
- FLG_I2C_UP - Если флаг установлен, значит модуль позволяет управлять подтяжкой линий шины I2C при помощи бита «SET_I2C_UP» регистра 0x01 «BITS_0».
Регистр 0x01 «BITS_0» - содержит биты установки состояния модуля:
Регистр для записи и чтения.
- SET_RESET - Бит запускает программную перезагрузку модуля. О завершении перезагрузки свидетельствует установка флага «FLG_RESET» регистра 0x00 «FLAGS_0».
- SET_SELF_TEST - Бит запускает самотестирование модуля. При успешном завершении самотестирования устанавливается флаг «FLG_SELF_TEST » регистра 0x00 «FLAGS_0». Не поддерживается данным модулем.
- SET_GET_NAME - Бит указывает использовать регистр 0x04 «MODEL» для посимвольного вывода названия модуля. Бит сбрасывается автоматически через 300 мс после его установки. Если флаг «FLG_GET_NAME» регистра 0x00 «FLAGS_0» сброшен, значит модуль не поддерживает посимвольный вывод своего названия.
- BLOCK_ADR - Бит блокирует смену и сохранение адреса для шины I2C. Бит устанавливается автоматически при попытке записи данных в регистры предназначенные только для чтения. Это защищает чип от ненамеренной смены адреса шумами на шине I2C, бит используется в модулях версии 5 и выше. Версия модуля хранится в регистре 0x05 «VERSION».
- SET_I2C_UP - Бит управляет внутрисхемной подтяжкой линий шины I2C. Значение бита сохраняется в FLASH память модуля. Установка бита в «1» приведёт к подтяжке линий SDA и SCL до уровня 3,3 В. На линии I2C допускается устанавливать внешние подтягивающие резисторы и иные модули с подтяжкой до уровня 3,3 В или 5 В, вне зависимости от состояния текущего бита. Если флаг «FLG_I2C_UP» регистра 0x00 «FLAGS_0» сброшен, значит управление подтяжкой не поддерживается модулем.
- SAVE_ADR_EN - Бит разрешает записать новый адрес модуля для шины I2C в FLASH память. Бит самостоятельно сбрасывается после сохранения адреса во FLASH память. Запись адреса выполняется следующим образом: нужно установить бит «SAVE_ADR_EN», после чего записать новый адрес в регистр 0x06 «ADDRESS» с установленным битом «SAVE_FLASH».
Регистр 0x04 «MODEL» - содержит идентификатор типа модуля:
Регистр только для чтения.
- MODEL[7-0] - Для модуля - ИК-приемник/передатчик, FLASH-I2C - идентификатор равен 0x17.
- Если установлен флаг «FLG_GET_NAME» регистра 0x00 «FLAGS_0» значит модуль поддерживает посимвольный вывод своего названия.
- Установка бита «SET_GET_NAME» регистра 0x01 «BITS_0» включает режим посимвольного вывода названия модуля. При этом в регистре 0x04 «MODEL» появится первый символ названия модуля. В процессе чтения регистра 0x04 «MODEL» он будет возвращать очередной символ названия, вплоть до символа конца строки имеющего код 0x00. Далее цикл повторится.
- Сброс бита «SET_GET_NAME» регистра 0x01 «BITS_0» отключает режим посимвольного вывода названия модуля. Регистр 0x04 «MODEL» вновь будет содержать идентификатор.
Регистр 0x05 «VERSION» - содержит версию прошивки модуля:
Регистр только для чтения.
- VERSION[7-0] - Версия прошивки (от 0x01 до 0xFF).
Регистр 0x06 «ADDRESS» - отвечает за чтение/установку адреса модуля на шине I2C:
Регистр для чтения и записи.
- ADDRESS[6-0] - 7 бит адреса модуля на шине I2C. При чтении возвращается текущий адрес модуля, при записи устанавливается указанный адрес модулю. Допускается указывать адреса в диапазоне: 7 < адрес < 127.
- SAVE_FLASH - Флаг записи адреса в FLASH память модуля.
Флаг имеет значение только при записи данных в регистр.
Если флаг сброшен, то адрес в битах ADDRESS[6-0] будет установлен временно (до отключения питания, или сброса/записи нового адреса). Если флаг установлен, то адрес в битах ADDRESS[6-0] будет сохранён в FLASH память модуля (останется и после отключения питания), но только если в бите «SAVE_ADR_EN» регистра 0x01 «BITS_0» установлена логическая 1. Если флаг «SAVE_FLASH» установлен, а бит «SAVE_ADR_EN» сброшен, то адрес в битах ADDRESS[6-0] не будет установлен ни временно, ни постоянно.
Регистр 0x07 «CHIP_ID» - содержит идентификатор общий для всех модулей серии «Flash»:
Регистр только для чтения.
У всех модулей серии «Flash» в регистре «CHIP_ID» содержится значение 0x3C. Если требуется отличить модули серии «Flash» на шине I2C от сторонних модулей, то достаточно прочитать значение регистров 0x06 «ADDRESS» и 0x07 «CHIP_ID» всех модулей на шине I2C. Если 7 старших битов регистра 0x06 «ADDRESS» хранят адрес совпадающий с адресом модуля, а в регистре 0x07 «CHIP_ID» хранится значение 0x3C, то можно с большой долей вероятности утверждать, что данный модуль является модулем серии «Flash».
Регистр 0x10 «SEND_RPT» - содержит интервал и разрешение отправки пакетов повторов:
Регистр для чтения и записи.
- SEND_REPEAT[7-1] - Биты определяют интервал между отправляемыми пакетами повторов. Интервал = SEND_REPEAT[7-0] = SEND_REPEAT[7-1]<<1 миллисекунд. Если интервал равен 0, то пакеты повторов будут отправляться с интервалом предусмотренным используемым ИК протоколом передачи данных.
- REPEAT - Бит указывает модулю отправлять пакеты повтора после отправки любых данных, до тех пор, пока бит «REPEAT» не будет сброшен.
Регистр 0x11 «SEND_ADR» - принимает байт адреса ИК-устройства для передачи:
Регистр 0x12 «SEND_COM» - принимает байт команды ИК-устройству для передачи:
Регистры для чтения и записи.
Данные передаваемые по ИК-каналу состоят из адреса ИК-устройства и команды для него. Отправка пакета с данными по ИК-каналу из регистров 0x11 и 0x12 осуществляется после записи в регистр 0x12.
Если в регистре 0x10 «SEND_RPT» установлен бит «REPEAT», то сразу после отправки пакета с данными начнут автоматически отправляться пакеты повтора (как при удержании кнопки ИК-пульта), до тех пор пока бит «REPEAT» не будет сброшен. Интервал между пакетами повторов можно задать битами «SEND_REPEAT[7-1]» регистра 0x10 «SEND_RPT».
Регистр 0x13 «SEND_COD» - содержит номер ИК протокола передачи данных:
Регистр для чтения и записи.
- NUM_CODING[5-0] - Биты хранят число определяющее используемый ИК протокол передачи данных:
- 1 - NEC (передаёт байт адреса и байт команды, с проверкой на ошибки).
- 2 - SAMSUNG (передаёт байт адреса и байт команды, с проверкой на ошибки).
- 3 - SHARP (передаёт 5 младших бит адреса и байт команды, с проверкой на ошибки).
- 4 - SIRC12 (передаёт 5 младших бит адреса и 7 бит команды, без проверки ошибок).
- 5 - SIRC15 (передаёт 5 младших бит адреса и 10 бит команды, без проверки ошибок).
- 6 - RC5 (передаёт 5 младших бит адреса и 6 бит команды, без проверки ошибок).
- 7 - RC5X (передаёт 5 младших бит адреса и 7 бит команды, без проверки ошибок).
- 8 - RC6 (передаёт байт адреса и байт команды, без проверки ошибок).
- 9 - IARDUINO (передаёт байт адреса и байт команды, с проверкой на ошибки).
- Иные значения в битах «NUM_CODING[5-0]» приведут к тому, что данные не будут отправляться по ИК-каналу.
- RC6_MODE[2-0] - Биты хранят режим используемый протоколом RC-6 для передачи данных. Значение «RC6_MODE[2-0]» игнорируется при использовании иных ИК протоколов.
Регистр 0x14 «READ_RPT» - содержит время ожидания и бит получения пакета повтора:
Регистр для чтения и записи.
- WAIT_REPEAT[7-1] - Биты определяют максимальное время ожидания пакета повтора.
Время ожидания = WAIT_REPEAT[7-0] = WAIT_REPEAT[7-1]<<1 миллисекунд.
Если время между принимаемыми по ИК-каналу пакетами превышает время ожидания пакета повтора, то бит «REPEAT» данного регистра будет автоматически сброшен.
Если в биты «WAIT_REPEAT[7-1]» записать нулевое значение, то модуль будет использовать время ожидания пакета повтора определённое выбранным ИК-протоколом + 20мс.
Рекомендуется указывать время ожидания пакетов повторов на 10-20 мс больше, чем интервал используемый передатчиком для отправки этих пакетов повторов по ИК-каналу. - REPEAT - Бит информирует о получении пакета повтора.
- Бит самостоятельно устанавливается при получении пакета повтора.
- Бит самостоятельно сбрасывается при получении нового пакета данных или по истечении максимального времени ожидания пакета повтора.
Регистр 0x15 «READ_ADR» - содержит принятый байт адреса ИК-устройства:
Регистр 0x16 «READ_COM» - содержит принятый байт команды ИК-устройства:
Регистры только для чтения.
Данные в указанных регистрах обновляются после каждого полученного по ИК-каналу пакета. Чтение данных из этих регистров по шине I2C можно выполнять в любой последовательности. Значение каждого регистра обнуляется после его чтения.
О наличии полученных по ИК-каналу данных свидетельствует не нулевое значение в любом из двух регистров. Это накладывает одно ограничение, модуль не способен принять пакет по ИК-каналу с нулевым адресом и нулевой командой.
Регистр 0x17 «READ_COD» - содержит номер ИК протокола для приёма данных:
Регистр для чтения и записи.
- NUM_CODING[5-0] - Биты хранят число определяющее ИК протокол используемый для приёма данных:
- 1 - NEC (с проверкой на ошибки).
- 2 - SAMSUNG (с проверкой на ошибки).
- 3 - SHARP (с проверкой на ошибки).
- 4 - SIRC12.
- 5 - SIRC15 .
- 6 - RC5.
- 7 - RC5X.
- 8 - RC6.
- 9 - IARDUINO (с проверкой на ошибки).
- Иные значения в битах «NUM_CODING[5-0]» приведут к тому, что данные не будут приниматься по ИК-каналу.
- Если ИК-приёмник получит данные отправленные с использованием ИК-протокола отличного от указанного в данном регистре, то эти данные будут проигнорированы модулем и не повлияют на состояние регистров 0x15 «READ_ADR» и 0x16 «READ_COM».
- Если ИК-приёмник получил данные отправленные с использованием ИК-протокола позволяющего проверить полученные данные на наличие ошибок, то такая проверка будет выполнена модулем автоматически, а состояние регистров 0x15 «READ_ADR» и 0x16 «READ_COM» изменится только в том случае, если данные прошли проверку.
- Если установить бит «DETECT» регистра 0x18 «BIT», то модуль самостоятельно определит ИК-протокол принятых данных и сохранит его номер в битах «NUM_CODING[5-0]».
- RC6_MODE[2-0] - Биты хранят режим используемый протоколом RC-6 для приёма данных. Значение «RC6_MODE[2-0]» игнорируется при использовании иных ИК протоколов.
Регистр 0x18 «BIT» - содержит биты управления ИК-каналом:
Регистр для чтения и записи.
- BIT_TX_BUSY - Бит информирует о занятости ИК-передатчика. Бит самостоятельно устанавливается при передаче данных по ИК-каналу и сбрасывается по окончанию передачи.
- TX_SHIFT - Бит меняющегося интервала между пакетами повторов. Если данный бит установлен и установлен бит «REPEAT» регистра 0x10 «SEND_RPT», то интервал между отправляемыми пакетами повторов будет хаотично меняться в диапазоне ±50% от заданного битами SEND_REPEAT[7-1] регистра 0x10 «SEND_RPT». Это позволит установить несколько модулей рядом и постоянно передавать данные по ИК-каналу в одном направлении, вне зависимости от используемого ИК-протокола.
- DETECT - Бит разрешает автоопределение ИК-протокола.
Установка бита приведёт к переходу приёмника в режим автоопределения ИК-протокола.
Как только ИК-протокол будет определён, установленный бит «DETECT» будет автоматически сброшен, а в биты «NUM_CODING[5-0]» регистра 0x17 «READ_COD» будет сохранён номер протокола определённого модулем. При определении протокола RC-6, дополнительно сохраняется его режим в биты «RC6_MODE[2-0]» регистра 0x17 «READ_COD».
Для автоопределения протокола приёмник должен получить по ИК-каналу пакет данных и пакет повтора. Для автоопределения протокола используемого ИК-пультом ДУ, достаточно нажать и удерживать любую его кнопку не менее 1 секунды. Для автоопределения протокола используемого другим модулем ИК-приемник/передатчик, FLASH-I2C или модулей линейки «Дорожное движение» достаточно отправить с этих модулей любые данные с пакетами повтора (отправить данные при установленном бите «REPEAT» регистра 0x10 «SEND_RPT» модуля передающего данные). - RX_EN - Бит разрешает работу ИК-приёмника.
- TX_EN - Бит разрешает работу ИК-передатчика.
- ПРИМЕЧАНИЕ: Если на одном модуле разрешена работа ИК-приёмника и ИК-передатчика, а ИК-протокол передатчика совпадает с ИК-протоколом приёмника, то данные переданные передатчиком, будут приняты приёмником по ИК-каналу. Это обусловлено расположением на плате модуля и направлением ИК-светодиодов передающих данные, и ИК-приёмника принимающего их.
Регистры 100+:
У младших версий модулей линейки «FLASH-I2C» нет блока регистров «100+», так же этого блока нет у модулей линейки «Metro», о его наличии свидетельствует установленный флаг «RAND_ADR» в регистре 0x00 «FLAGS_0».
Блок регистров «100+» с адресами от 0x64 (100)10 до 0x75 (117)10 не участвует в работе модуля, он предназначен только для обнаружения модулей с одинаковыми адресами и назначения этим модулям разных адресов, не отключая их от шины I2C.
Карта регистров 100+:
Регистры 0x64-0x65 «RANDOM_NUM» - содержат случайное число:
Регистры только для чтения.
- RANDOM_NUM[15-0] - Содержит двухбайтное случайное число позволяющее определить наличие нескольких устройств с одинаковым адресом.
- Значение из регистров читается одним пакетом (младший и старший байт). После чтения старшего байта, модуль на 5мс перейдёт в режим «молчания». В этом режиме модуль будет отправлять NACK мастеру после получения номера регистра в любых запросах.
- Если прочитать регистры 0x64-0x65 «RANDOM_NUM» дважды, с промежутком между чтениями менее 5мс, то первый раз мы получим два байта случайного числа, а второй раз модуль откажет в чтении, так как отправит NACK. Но это только в том случае, если адрес модуля уникален.
- Если адрес принадлежит нескольким устройствам, то и отвечать на запрос чтения будут несколько устройств. При первом чтении регистров 0x64-0x65 «RANDOM_NUM», биты случайного числа у разных модулей не совпадут, в результате чего один модуль передаст оба байта случайного числа и перейдёт в режим «молчания», а другой модуль (или модули) зафиксирует потерю арбитража и не передаст старший байт, следовательно, и не перейдёт в режим «молчания». Значит при повторном чтении регистров, мы опять получим два байта случайного числа от того модуля который не перешёл в режим «молчания», что будет свидетельствовать о наличии нескольких устройств на одном адресе.
Регистр 0x66 «RANDOM_ADR» - случайный адрес:
Регистр для чтения и записи.
- RANDOM_ADR[7-0] - Позволяет задавать модулю случайный временный адрес, подтверждать временный адрес и получать информацию о состоянии временного адреса.
- Запись 0x0F - Назначить модулю случайный временный адрес на 50 мс.
В регистре 0x06 «ADDRESS» останется значение постоянного адреса. - Запись 0xF0 - Подтвердить назначенный временный адрес до отключения питания.
В регистре 0x06 «ADDRESS» появится назначенный временный адрес. - Чтение 0x55 - Назначен временный случайный адрес на 50 мс.
- Чтение 0xFF - Назначенный временный адрес подтверждён до отключения питания.
- Чтение 0x00 - Временный адрес не назначался или отменён по истечении 50 мс.
- Если на шине несколько устройств имеют одинаковый адрес, то запись значения 0x0F в регистр 0x66 «RANDOM_ADR» этих устройств, приведёт к тому, что каждый модуль сам себе назначит временный случайный адрес на 50 мс. За указанное время следует найти все новые временные адреса устройств и подтвердить их отправив в регистр 0x66 «RANDOM_ADR» значение 0xF0.
- Примечание: Случайный адрес модуль выбирает сам из диапазона от 0x08 до 0x7E включительно, кроме адресов запрещённых регистрами 0x67-0x75 «BUN_ADR».
Регистры 0x67-0x75 «BUN_ADR» - запрещают назначать адреса:
Регистры для чтения и записи.
- BUN_ADR_08 - Бит запрещает назначать адрес 0x08 регистром 0x66 «RANDOM_ADR».
- BUN_ADR_09 - Бит запрещает назначать адрес 0x09 регистром 0x66 «RANDOM_ADR».
- ...
- BUN_ADR_7D - Бит запрещает назначать адрес 0x7D регистром 0x66 «RANDOM_ADR».
- BUN_ADR_7E - Бит запрещает назначать адрес 0x7E регистром 0x66 «RANDOM_ADR».
- Если бит регистров 0x67-0x75 «BUN_ADR» установлен, то модуль не назначит себе случайный временный адрес соответствующий установленному биту.
- Если на шине есть несколько устройств с одинаковым адресом, то отправка команды 0x0F в регистр 0x66 «RANDOM_ADR» этих устройств, приведёт к тому, что каждый модуль сам себе назначит временный случайный адрес на 50 мс. Но вновь назначенный адрес может совпасть с адресом другого модуля на шине I2C, особенно если их много. По этому перед назначением случайного временного адреса рекомендуется записать в регистры 0x67-0x75 «BUN_ADR» все найденные на шине I2C уникальные адреса.
Доступ к данным регистров:
Каждый регистр модуля хранит 1 байт данных. Так как модуль использует интерфейс передачи данных I2C, то и доступ к данным охарактеризован им.
Обмен данными по шине I2C происходит по одному биту за один такт, после каждых переданных 8 бит (1 байта) принимающее устройство отвечает передающему одним битом: «ACK» в случае успешного приёма, или «NACK» в случае ошибки. Пакет приёма/передачи данных начинается сигналом «START» и завершается сигналом «STOP». Первый байт пакета всегда состоит из 7 бит адреса устройства и одного (младшего) бита R/W.
Сигналы интерфейса передачи данных I2C:
- Для удобства восприятия сигналов они выполнены в следующих цветах:
- Зелёный - сигналы формируемые мастером.
- Красный - данные отправляемые мастером.
- Синий - данные отправляемые модулем.
- Фиолетовый - данные отправляемые мастером или модулем.
- «START» - отправляется мастером в начале пакета приема/передачи данных. Сигнал представляет переход уровня линии «SDA» из «1» в «0» при наличии «1» на линии «SCL».
- «STOP» - отправляется мастером в конце пакета приёма/передачи данных. Сигнал представляет переход уровня линии «SDA» из «0» в «1» при наличии «1» на линии «SCL».
- БИТ - значение бита считывается с линии «SDA» по фронту импульса на линии «SCL».
- «ACK» - бит равный 0, отправляется после успешного приёма байта данных.
- «NACK» - бит равный 1, отправляется после байта данных в случае ошибки.
- ПЕРВЫЙ БАЙТ - отправляется мастером, состоит из 7 бит адреса и бита «RW».
- «R/W» - младший бит первого байта данных указывает направление передачи данных пакета, 1 - прием (от модуля к мастеру), 0 - передача (от мастера в модуль).
- «RESTART» - повторный старт, отправляется мастером внутри пакета. Сигнал представляет из себя «START» отправленный не на свободной шине, а внутри пакета.
ВАЖНО: Все изменения на линии «SDA» должны происходить только при наличии «0» на линии «SCL» за исключением сигналов «START», «STOP» и «RESTART».
Запись данных в регистры:
- Отправляем сигнал «START».
- Отправляем первый байт: 7 бит адреса модуля и бит «R/W» равный 0 (запись).
Получаем ответ от модуля в виде одного бита «ACK». - Отправляем второй байт: адрес регистра в который будет произведена запись.
Получаем ответ от модуля в виде одного бита «ACK». - Отправляем третий байт: данные для записи в регистр.
Получаем ответ от модуля в виде одного бита «ACK». - Далее можно отправить четвёртый байт данных для записи в следующий по порядку регистр и т.д.
- Отправляем сигнал «STOP».
Пример записи в один регистр:
Запись значения 0x2A в регистр 0x06 модуля с адресом 0x09:
// Запись в регистр методами библиотеки Wire.h Wire.beginTransmission(0x09); // Инициируем передачу данных в устройство с адресом 0x09. Wire.write(0x06); // Записываем в буфер байт адреса регистра. Wire.write(0x26); // Записываем в буфер байт который будет записан в регистр. Wire.endTransmission(); // Выполняем передачу адреса и байтов из буфера. Функция возвращает: 0-передача успешна / 1 - переполнен буфер для передачи / 2 - получен NACK при передаче адреса / 3 - получен NACK при передаче данных / 4 - другая ошибка.
Пример записи в несколько регистров подряд:
Запись в модуль с адресом 0x09 нескольких значений начиная с регистра 0x12:
В регистр 0x12 запишется значение 0x0F, в следующий по порядку регистр (0x13) запишется значение 0x30 и в следующий по порядку регистр (0x14) запишется значение 0xB1.
// Запись в регистры методами библиотеки Wire.h byte data[3] = {0x0F,0x30,0xB1}; // Определяем массив с данными для передачи. Wire.beginTransmission(0x09); // Инициируем передачу данных в устройство с адресом 0x09. Wire.write(0x12); // Записываем в буфер байт адреса первого регистра. Wire.write(data, 3); // Записываем в буфер 3 байта из массива data. Wire.endTransmission(); // Выполняем передачу адреса и байт из буфера. Функция возвращает: 0-передача успешна / 1 - переполнен буфер для передачи / 2 - получен NACK при передаче адреса / 3 - получен NACK при передаче данных / 4 - другая ошибка.
Чтение данных из регистров:
- При чтении пакет делится на 2 части: запись № регистра и чтение его данных.
- Отправляем сигнал «START».
- Отправляем первый байт: 7 бит адреса модуля и бит «R/W» равный 0 (запись).
Получаем ответ от модуля в виде одного бита «ACK». - Отправляем второй байт: адрес регистра из которого нужно прочитать данные.
Получаем ответ от модуля в виде одного бита «ACK». - Отправляем сигнал «RESTART».
- Отправляем первый байт после «RESTART»: 7 бит адреса и бит «R/W» равный 1 (чтение).
Получаем ответ от модуля в виде одного бита «ACK». - Получаем байт данных из регистра модуля.
Отвечаем битом «ACK» если хотим прочитать следующий регистр, иначе отвечаем «NACK». - Отправляем сигнал «STOP».
Пример чтения одного регистра:
Чтение из модуля с адресом 0x09 байта данных регистра 0x05:
(в примере модуль вернул значение 0x01).
// Чтение регистра методами библиотеки Wire.h byte data; // Объявляем переменную для чтения байта данных. Wire.beginTransmission(0x09); // Инициируем передачу данных в устройство с адресом 0x09. Wire.write(0x05); // Записываем в буфер байт адреса регистра. Wire.endTransmission(false); // Выполняем передачу без установки состояния STOP. Wire.requestFrom(0x09, 1); // Читаем 1 байт из устройства с адресом 0x09. Функция возвращает количество реально принятых байтов. Так как предыдущая функция не установила состояние STOP, то состояние START установленное данной функцией будет расценено как RESTART. data=wire.read(); // Сохраняем прочитанный байт в переменную data.
Пример чтения нескольких регистров подряд:
Чтение из модуля с адресом 0x09 нескольких регистров начиная с регистра 0x05:
(в примере модуль вернул значения: 0x01 из рег. 0x05, 0x13 из рег. 0x06, 0xC3 из рег. 0x07).
// Чтение регистров методами библиотеки Wire.h byte data[3]; // Объявляем массив для чтения данных. Wire.beginTransmission(0x09); // Инициируем передачу данных в устройство с адресом 0x09. Wire.write(0x05); // Записываем в буфер байт адреса регистра. Wire.endTransmission(false); // Выполняем передачу без установки состояния STOP. Wire.requestFrom(0x09, 3); // Читаем 3 байта из устройства с адресом 0x09. Функция возвращает количество реально принятых байтов. Так как предыдущая функция не установила состояние STOP, то состояние START установленное данной функцией будет расценено как RESTART. int i=0; // Определяем счётчик номера прочитанного байта. while( Wire.available() ){ // Выполняем цикл while пока есть что читать из буфера. if(i<3){ // Лучше делать такую проверку, чтоб не записать данные за пределы массива data! data[i] = wire.read(); i++; // Читаем очередной байт из буфера в массив data. } // } //
Примечание:
- Если на линии I2C только один мастер, то сигнал «RESTART» можно заменить на сигналы «STOP» и «START».
- Рекомендуется не выполнять чтение или запись данных чаще 200 раз в секунду.
- Обратите внимание на сигналы «RESTART» и «STOP» в пакетах чтения данных:
- Между фронтом и спадом сигнала «RESTART» проходит фронт импульса на линии «SCL», что расценивается как передача бита равного 1.
- Между сигналом «NACK» и сигналом «STOP» проходит фронт импульса на линии «SCL», что расценивается как передача бита равного 0.
- Эти биты не сохраняются в модулях и не расцениваются как ошибки.
Модуль не поддерживает горячее подключение: Подключайте модуль только при отсутствии питания и данных на шине I2C. В противном случае потребуется отключить питание при уже подключённом модуле.
Алгоритм получения данных от модулей линейки «Дорожное движение»:
О получении любых данных модулем - ИК-приемник/передатчик, FLASH-I2C по ИК-каналу, свидетельствует ненулевое значение в регистре 0x15 «READ_ADR» (адрес ИК-устройства) или 0x16 «READ_COM» (команда ИК-устройства).
Получение состояния светофора:
Если значение регистра 0x15 «READ_ADR» изменилось на число от 0x04 до 0x1F, значит модуль получил данные по ИК-каналу от модуля светофор.
Байт ИК-адреса светофора информирует о типе перекрёстка и наличии у светофора секций поворота:
ЗНАЧЕНИЕ РЕГИСТРА 0x15 «READ_ADR» ПРИ ПОЛУЧЕНИИ ДАННЫХ ОТ СВЕТОФОРА: | |||||||
---|---|---|---|---|---|---|---|
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | 0 | 0 | TRACK_L | TRACK_F | TRACK_R | SECTION_L | SECTION_R |
- Три старших бита адреса имеют значение 000, что позволяет отличить светофор от знака.
- TRACK_L - бит указывает, что перекрёсток светофора имеет поворот налево.
- TRACK_F - бит указывает, что перекрёсток светофора имеет прямое направление.
- TRACK_R - бит указывает, что перекрёсток светофора имеет поворот направо.
- SECTION_L - бит указывает что светофор оснащён секцией поворота налево.
- SECTION_R - бит указывает что светофор оснащён секцией поворота направо.
Состояние светофора можно прочитать из регистра 0x16 «READ_COM» каждый бит которого несёт информацию о принятом состоянии соответствующего цвета светофора или состояния шлагбаума:
ЗНАЧЕНИЕ РЕГИСТРА 0x16 «READ_COM» ПРИ ПОЛУЧЕНИИ ДАННЫХ ОТ СВЕТОФОРА: | |||||||
---|---|---|---|---|---|---|---|
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
GATE | RED | YELLOW_BLINK | YELLOW | GREEN_BLINK | GREEN | GREEN_L | GREEN_R |
- GATE - бит указывает на закрытое состояние шлагбаума.
- RED - бит указывает на свечение красного сигнала светофора.
- YELLOW_BLINK - бит указывает на мигание жёлтого сигнала светофора.
- YELLOW - бит указывает на свечение жёлтого сигнала светофора.
- GREEN_BLINK - бит указывает на мигание зелёного сигнала светофора.
- GREEN - бит указывает на свечение зелёного сигнала светофора.
- GREEN_L - бит указывает на свечение или мигание стрелки налево.
- GREEN_R - бит указывает на свечение или мигание стрелки направо.
ПРИМЕР: Если в регистре 0x15 «READ_ADR» появилось значение 0x0D, а в регистре 0x16 «READ_COM» значение 0x51 = (01010001)2 значит модуль принял состояние светофора оснащённого секцией правого поворота, который регулирует перекрёсток с движением прямо и направо, и в данный момент у светофора светятся красный и жёлтый сигналы, а так же светится или мигает стрелка направо.
Получение информации от автомобиля трассы:
Если значение регистра 0x15 «READ_ADR» изменилось на число 0x01, значит модуль получил данные по ИК-каналу от модуля являющегося автомобилем.
Команду отправленную автомобилем можно прочитать из регистра 0x16 «READ_COM».
Вы сами можете придумать, какие команды должен отправлять автомобиль (внимание, уступи дорогу, остановись, уступаю дорогу, поворачиваю влево, еду прямо и т.д.). Это может помочь при маневрировании на перекрёстках трассы.
Получение информации о знаке:
По состоянию на 4 апреля 2017 г. дорожные знаки ПДД пронумерованы и разделены на 8 групп. Для обозначения конкретного знака указывается номер группы, номер знака и в некоторых случаях пункт.
- 1.22 - Пешеходный переход (знак относится к 1 группе и имеет номер 22).
- 3.24 - Ограничение максимальной скорости (знак относится к 3 группе и имеет номер 24).
- 6.3.1 - Место для разворота (знак относится к 6 группе, имеет номер 3 и пункт 1).
Если значение регистра 0x15 «READ_ADR» изменилось на число от 0x20 до 0xFF, значит модуль получил данные по ИК-каналу от модуля - Дорожный знак, а его обозначение можно извлечь из битов регистров 0x15 «READ_ADR» и 0x16 «READ_COM».
БАЙТ АДРЕСА (0x15 «READ_ADR»): | БАЙТ КОМАНДЫ (0x16 «READ_COM»): | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ГРУППА | НОМЕР | ПУНКТ | ТАБЛИЧКА |
Для извлечения данных о знаке из регистров 0x15 «READ_ADR» и 0x16 «READ_COM», нужно выполнить следующие действия:
uint16_t data = ( (uint16_t)READ_ADR << 8 ) | READ_COM; // Определяем двухбайтную переменную, присвоив её старшему байту значение из регистра READ_ADR, а младшему биту значение из регистра READ_COM. uint8_t ГРУППА = ( data >> 13 ) & 0b00000111; // Извлекаем группу знака. Число состоит из 3 бит и может принимать значение от 1 до 7 (в ПДД нет знаков с группой 0). uint8_t НОМЕР = ( data >> 7 ) & 0b00111111; // Извлекаем номер знака. Число состоит из 6 бит и может принимать значение от 1 до 63 (в ПДД нет знаков с номером 0). uint8_t ПУНКТ = ( data >> 3 ) & 0b00001111; // Извлекаем пункт знака. Число состоит из 4 бит и может принимать значение от 0 до 15 (если 0 значит у знака нет пункта). uint8_t ТАБЛИЧКА = data & 0b00000111; // Извлекаем информацию о табличке под знаком.
ПРИМЕР: Если значение регистра 0x15 «READ_ADR» изменилось на число 0xС1, а в регистре 0x16 «READ_COM» появилось значение 0x88, значит по ИК-каналу принята информация от модуля - Дорожный знак 6.3.1 ПДД, без таблички под знаком.
0xС188 = 0b11000001100010000 => 110.000011.0001.000 => 6.3.1.0
Если ПУНКТ=0, значит знак обозначен в ПДД только 2 числами: группой и номером.
Некоторые знаки имеют картинку с числовыми обозначениями, например, ограничение скорости 60 км/ч, или рекомендуемая скорость 50 км/ч, ограничение массы и т.д. В таких случаях вместо пункта знака передаётся число кратное изображённому на знаке. Пример: для передачи знака 3.24 "ограничение максимальной скорости", по ИК-каналу передаётся группа 3, номер 24 и пункт от 1 (для 10 км/ч) до 15 (для 150 км/ч).
Помимо группы, номера и пункта, модуль - Дорожный знак передаёт информацию о табличке под знаком, уточняющей или ограничивающей его действие, это значение от 0 до 7:
- 0 - Под знаком нет таблички уточняющей или ограничивающей его действие.
- 1 - Действие знака распространяется только на грузовые автомобили.
- 2 - Действие знака распространяется только на легковые автомобили.
- 3 - Расстояние до объекта или зона действия знака равна 50 метрам.
- 4 - Расстояние до объекта или зона действия знака равна 100 метрам.
- 5 - Расстояние до объекта или зона действия знака равна 150 метрам.
- 6 - Расстояние до объекта или зона действия знака равна 200 метрам.
- 7 - Расстояние до объекта или зона действия знака равна 250 метрам.
Остальные таблички (знаки 8 группы ПДД) не поддерживаются модулями - Дорожные знаки.
Пример настройки модуля на получение данных по протоколу IARDUINO:
Следующий скетч настраивает модуль на получение данных по ИК-каналу с использованием протокола IARDUINO и выводит получаемые модулем по ИК-каналу данные в монитор последовательного порта.
#define REG_READ_RPT 0x14 // Регистр повтора. Младший бит устанавливается при получении пакетов повторов. Старшие 7 бит определяют максимальное время ожидания пакета повтора в мс. #define REG_READ_ADR 0x15 // Регистр номера устройства. Байт принимается по ИК-каналу. #define REG_READ_COM 0x16 // Регистр номера команды. Байт принимается по ИК-каналу. #define REG_READ_COD 0x17 // Регистр номера протокола. Старшие 3 бита определяют режим для протокола RC6, а младшие 5 бит определяют номер протокола. #define REG_BIT 0x18 // Регистр битов управления. Содержит биты BIT_TX_SHIFT, BIT_DETECT, BIT_RX_EN, BIT_TX_EN. // #include <Wire.h> // Подключаем библиотеку Wire для работы с шиной I2C. // const uint8_t ADDRESS = 0x09; // Определяем адрес модуля. uint8_t GET_DEVICE = 0x00; // Определяем переменную для хранения адреса ИК-устройства. uint8_t GET_COMMAND = 0x00; // Определяем переменную для хранения номера команды. // void setup(){ // // Инициируем работу с шинами: // Serial.begin(9600); // Инициируем работу c шиной UART на скорость 9600 бит/сек. Wire.setClock(100000L); // Устанавливаем скорость передачи данных по шине I2C. Wire.begin(); // Инициируем работу c шиной I2C в качестве мастера. delay(500); // // Разрешаем работу приёмника: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write( REG_BIT ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра. Wire.write( 0b00000010 ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это байт с одним установленным битом разрешающим работу приёмника. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. // Указываем ИК-протокол: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write( REG_READ_COD ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра. Wire.write( 9 ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер ИК-протокола IARDUINO. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. } // // void loop(){ // // Читаем данные приёмника: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write(REG_READ_ADR); // Функция write() помещает значение своего аргумента в буфер для передачи. Wire.endTransmission(false); // Выполняем инициированную ранее передачу данных (параметр false указывает что состояние STOP устанавливать не требуется). Wire.requestFrom(ADDRESS, 2); // Читаем из модуля с адресом ADDRESS, 2 байта данных в буфер библиотеки Wire. Так как предыдущая функция не установила состояние STOP, то состояние START установленное данной функцией будет расценено как RESTART. GET_DEVICE = Wire.read(); // Помещаем 1 прочитанный байт в переменную GET_DEVICE. GET_COMMAND = Wire.read(); // Помещаем 2 прочитанный байт в переменную GET_COMMAND. while(Wire.available()){Wire.read();} // Если в буфере библиотеки Wire есть еще данные, то читаем их в никуда (чистим буфер). // Если данные приняты: // if( GET_DEVICE || GET_COMMAND ){ // Если в переменной GET_DEVICE или GET_COMMAND есть значение отличное от 0. // Выводим полученные данные: // Serial.print(GET_DEVICE); // Выводим адрес ИК-устройства. Serial.print(' '); // Serial.print(GET_COMMAND); // Выводим команду ИК-устройства. Serial.print("\r\n"); // } // GET_DEVICE = 0; // Сбрасываем адрес ИК-устройства. GET_COMMAND = 0; // Сбрасываем команду ИК-устройства. delay(50); // } //
- Действия выполняемые в коде setup():
- Инициализация работы с шинами UART (скорость 9600 бит/сек) и I2C (100'000 бит/сек).
- Включение приёмника установкой бита «BIT_RX_EN» в регистре «REG_BIT».
- Указание ИК-протокола, записью номера протокола в регистр «REG_READ_COD». Можно указать значения от 1 до 9, где 9 - указывает использовать протокол «IARDUINO».
- Действия выполняемые в коде loop():
- Получение данных приёмника чтением 2 байт из регистров «REG_READ_ADR» и «REG_READ_COM» в переменные «GET_DEVICE» и «GET_COMMAND».
- Если данные приняты, о чем свидетельствует не нулевое значение в переменной «GET_DEVICE» или «GET_COMMAND», то выводим полученные данные.
- Обнуление значений переменных «GET_DEVICE» и «GET_COMMAND» для проверки принятия данных при следующем проходе цикла loop().
Пример настройки модуля на передачу данных по протоколу IARDUINO:
Следующий скетч настраивает модуль на передачу данных по ИК-каналу с использованием протокола IARDUINO и выполняет передачу данных каждые 200 мс.
#define REG_SEND_RPT 0x10 // Регистр повтора. Младший бит указывает отправлять пакеты повторов. Старшие 7 бит определяют интервал между пакетами повторов в мс. #define REG_SEND_ADR 0x11 // Регистр номера устройства. Байт передаётся по ИК-каналу. #define REG_SEND_COM 0x12 // Регистр номера команды. Байт передаётся по ИК-каналу. #define REG_SEND_COD 0x13 // Регистр номера протокола. Старшие 3 бита определяют режим для протокола RC6, а младшие 5 бит определяют номер протокола. #define REG_BIT 0x18 // Регистр битов управления. Содержит биты BIT_TX_SHIFT, BIT_DETECT, BIT_RX_EN, BIT_TX_EN. // #include <Wire.h> // Подключаем библиотеку Wire для работы с шиной I2C. // const uint8_t ADDRESS = 0x09; // Определяем адрес модуля. uint8_t SET_DEVICE = 0x01; // Определяем переменную для отправки адреса ИК-устройства. uint8_t SET_COMMAND = 0x00; // Определяем переменную для отправки команды. // void setup(){ // // Инициируем работу с шиной I2C: // Wire.setClock(100000L); // Устанавливаем скорость передачи данных по шине I2C. Wire.begin(); // Инициируем работу c шиной I2C в качестве мастера. // Разрешаем работу передатчика: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write( REG_BIT ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра. Wire.write( 0b00000001 ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это значение для регистра. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. // Указываем ИК-протокол: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write( REG_SEND_COD ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра. Wire.write( 9 ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер ИК-протокола IARDUINO. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. // Запрещаем отправлять пакеты повторов: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write( REG_SEND_RPT ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра. Wire.write( 0 ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это значение для регистра. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. } // // void loop(){ // // Отправляем данные: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write( REG_SEND_ADR ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра. Wire.write( SET_DEVICE ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это значение для регистра. Wire.write( SET_COMMAND ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это значение для регистра. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. delay(200); // Ждём 200 мс. // Меняем данные для следующей передачи: // SET_COMMAND++; // Увеличиваем значение ИК-команды. if( SET_COMMAND==0 ){SET_DEVICE++;} // Увеличиваем значение ИК-адреса. if( SET_DEVICE ==0 ){SET_DEVICE=1;} // Не позволяем отправлять данные с ИК-адресом равным 0. } //
- Действия выполняемые в коде setup():
- Инициализация работы с шиной I2C на скорости 100'000 бит/сек.
- Включение передатчика установкой бита «BIT_TX_EN» в регистре «REG_BIT».
- Указание ИК-протокола, записью номера протокола в регистр «REG_SEND_COD». Можно указать значения от 1 до 9, где 9 - указывает использовать протокол «IARDUINO».
- Запрет отправки пакетов повторов, сбросом бита «REPEAT» в регистре «REG_SEND_RPT».
- Действия выполняемые в коде loop():
- Передача данных по ИК-каналу, путем записи адреса ИК-устройства и команды для него в регистры «REG_SEND_ADR» и «REG_SEND_COM». В скетче в качестве адреса ИК-устройства используется значение переменной «SET_DEVICE», а в качестве команды выступает значение переменной «SET_COMMAND».
- Меняем значение передаваемых данных. С каждым проходом цикла loop() увеличивается значение «SET_COMMAND». А с каждым сбросом значения «SET_COMMAND» увеличивается значение «SET_DEVICE».
Пример настройки модуля на постоянную передачу данных:
Следующий скетч настраивает модуль на передачу данных по ИК-каналу с отправкой пакетов повторов и использованием протокола IARDUINO. Передача данных выполняется однократно, далее модуль самостоятельно отправляет пакеты повтора содержащие те же данные.
#define REG_SEND_RPT 0x10 // Регистр повтора. Младший бит указывает отправлять пакеты повторов. Старшие 7 бит определяют интервал между пакетами повторов в мс. #define REG_SEND_ADR 0x11 // Регистр номера устройства. Байт передаётся по ИК-каналу. #define REG_SEND_COM 0x12 // Регистр номера команды. Байт передаётся по ИК-каналу. #define REG_SEND_COD 0x13 // Регистр номера протокола. Старшие 3 бита определяют режим для протокола RC6, а младшие 5 бит определяют номер протокола. #define REG_BIT 0x18 // Регистр битов управления. Содержит биты BIT_TX_SHIFT, BIT_DETECT, BIT_RX_EN, BIT_TX_EN. // #include <Wire.h> // Подключаем библиотеку Wire для работы с шиной I2C. // const uint8_t ADDRESS = 0x09; // Определяем адрес модуля. uint8_t SET_DEVICE = 0x01; // Определяем переменную для отправки адреса ИК-устройства. uint8_t SET_COMMAND = 0x02; // Определяем переменную для отправки команды. // void setup(){ // // Инициируем работу с шиной I2C: // Wire.setClock(100000L); // Устанавливаем скорость передачи данных по шине I2C. Wire.begin(); // Инициируем работу c шиной I2C в качестве мастера. // Разрешаем работу передатчика: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write( REG_BIT ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра. Wire.write( 0b00000001 ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это значение для регистра. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. // Указываем ИК-протокол: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write( REG_SEND_COD ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра. Wire.write( 9 ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер ИК-протокола IARDUINO. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. // Указываем интервал между пакетами: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write( REG_SEND_RPT ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра. Wire.write( 0|1 ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это значение для регистра. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. // Запускаем передачу данных: // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write( REG_SEND_ADR ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра. Wire.write( SET_DEVICE ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это значение для регистра. Wire.write( SET_COMMAND ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это значение для регистра. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. } // // void loop(){ // } //
- Действия выполняемые в коде setup():
- Инициализация работы с шиной I2C на скорости 100'000 бит/сек.
- Включение передатчика установкой бита «BIT_TX_EN» в регистре «REG_BIT».
- Указание ИК-протокола, записью номера протокола в регистр «REG_SEND_COD». Можно указать значения от 1 до 9, где 9 - указывает использовать протокол «IARDUINO».
- Указание интервала между пакетами повторов и управление отправкой пакетов повторов, записью значения в регистр «REG_SEND_RPT». В скетче интервал равен 0, что указывает модулю использовать интервал определённый выбранным протоколом, а бит «REPEAT» равен 1, что указывает модулю начать отправку повторов сразу после отправки любых данных.
- Запуск передачи данных, путем записи адреса ИК-устройства и команды для него в регистры «REG_SEND_ADR» и «REG_SEND_COM». В скетче в качестве адреса используется значение 0x01, а в качестве команды значение 0x02.
- Действия выполняемые в коде loop():
- В коде loop() нет команд, так как модуль будет самостоятельно, постоянно, отправлять адрес 0x01 и команду 0x02 пока не будет сброшен бит «REPEAT» в регистре «REG_SEND_RPT».
Габариты:
Все модули линейки "Trema" выполнены в одном формате:
Ссылки:
- Все модули линейки «Дорожное движение».
- Модуль - Дорожный знак «Главная дорога».
- Модуль - Дорожный знак «Уступи дорогу».
- Модуль - Дорожный знак «Квадратный».
- Модуль - Дорожный знак «Круглый».
- Модуль - Дорожный знак «Треугольный».
- Модуль - Светофор.
- Модуль - Шлагбаум для светофора.
- Модуль - ИК-приемник/передатчик, FLASH-I2C.
- Wiki - Дорожный знак.
- Wiki - Светофор и шлагбаум.
- Wiki - Основание дорожных знаков и светофора, FLASH-I2C - Datasheet.
- Wiki - ИК-приемник/передатчик, FLASH-I2C.
- Библиотека iarduino_I2C_IR.
- Wiki - Расширенные возможности библиотек iarduino для шины I2C.
- Wiki - Установка библиотек в Arduino IDE.
Обсуждение