Модуль - TDS/EC-метр, FLASH-I2C.
Техническое описание: Данная страница содержит подробное техническое описание модуля - TDS/EC-метр, FLASH-I2C и раскрывает работу с модулем через его регистры.
Ознакомиться с пользовательским описанием модуля и примерами работы с библиотекой iarduino_I2C_TDS можно на странице Wiki - TDS/EC-метр, FLASH-I2C.
Правила ухода: Перед измерениями подготовьте датчик модуля к работе. Протрите электроды датчика спиртом или дистиллированной водой, после чего дайте им высохнуть. Те же действия рекомендуется делать до калибровки модуля и после проведения измерений. Не касайтесь руками выводов датчика (измерительного щупа).
Назначение:
Модуль - TDS/EC-метр, FLASH-I2C - является устройством для измерения общего количества растворённых твердых веществ в воде и её удельной электрической проводимости. Модуль позволяет определять количество растворённых твёрдых веществ в диапазоне от 0 до 10'000 ppm (1ppm = 1мг/л воды), по этим показаниям можно судить об общей минерализации, жёсткости и солёности воды. Чувствительность модуля позволяет «заметить» 2-3 крупинки мелкозерновой пищевой соли (NaCl) растворённой в стакане дистиллированной воды. Модуль можно использовать для анализа качества дистиллированной воды, для контроля за оставшимся ресурсом мембранных фильтров воды, слежения за жёсткостью воды в аквариумах, бассейнах и системах водоснабжения. По изменениям показаний минерализации воды на входе и выходе из трубы, можно судить о степени износа этой трубы. Но модуль нельзя использовать для определения качества питьевой воды, так как питьевая вода может содержать и полезные для организма минералы.
Управление модулем осуществляется по шине I2C, а чтение показаний модуля можно осуществлять, либо по шине I2C, либо по аналоговому выходу модуля.
К одной шине I2C можно подключить более 100 модулей. Адрес модуля на шине I2C (по умолчанию 0x09) назначается программно и хранится в его энергонезависимой памяти.
Описание:
Модуль построен на базе микроконтроллера STM32F030F4 и двух операционных усилителях LMC7101, и LM358, снабжён кнопкой калибровки, светодиодами информирующими о стадии калибровки, и собственным стабилизатором напряжения. Модуль способен работать как TDS-метр (Total Dissolved Solids) для определения общего количества растворённых твердых веществ в воде от 0 до 10'000 ppm (1ppm = 1мг/л воды). Так и в качестве EC-метра (Electrical Conductivity) для определения удельной электрической проводимости жидкости от 0 до 20,000 мСм/см. Модуль способен работать с различными датчиками (щупами), подключаемыми к колодке в центре платы.
Принцип действия модуля основан на прямой зависимости электропроводности от количества растворенных в воде веществ, а электропроводность жидкости является величиной обратно пропорциональной её сопротивлению. Так как электропроводность и сопротивление жидкости сильно зависят от температуры, модулю нужно указывать реальную температуру жидкости в °С.
Модуль измеряет сопротивление жидкости, используя переменный ток, для снижения поляризации. Значение сопротивления определяется по напряжению считанному с выхода ОУ, которое преобразуется в электропроводность, после чего оно приводится от реальной температуры к опорной температуре и переводится в общее количество растворённых твердых веществ. Каждый измеренный в этом процессе показатель доступен для чтения из регистров модуля.
Измерительная часть схемы модуля построена следующим образом:
- На инвертирующий вход ОУ, через датчик (Rдатчика), подается меандр (Vin) с размахом потенциалов от 0,4Vcc до 0,6Vcc.
- На неинвертирующий вход ОУ подаётся постоянный потенциал (Vo) равный половине напряжения питания (0,5Vcc).
- Операционный усилитель (ОУ) будет устанавливать такое напряжение на своём выходе (Vout) при котором потенциал инвертирующего входа (центральная точка делителя Rдатчика+Rooc) будет равен потенциалу неинвертирующего входа (Vo).
- Так как на один вывод датчика подан меандр (Vin), а на другом выводе датчика ОУ установил потенциал (Vo) равный центру потенциалов меандра, то напряжение между выводами датчика является переменным:
- Vдатчика = разность потенциалов Vin и Vo:
- Vin-Vo = 0,6Vcc-0,5Vcc = +0,1Vcc.
- Vin-Vo = 0,4Vcc-0,5Vcc = -0,1Vcc.
- Rдатчика = Rоос * (Vin-Vo) / (Vo-Vout).
- Схема самостоятельно корректирует напряжение используемое для измерений. Чем выше сопротивление жидкости, тем больше напряжение используемое для измерений. Это достигается тем, что при снижении сопротивления Rдатчика, размах меандра Vin будет уменьшаться, стремясь к значению Vo.
Модуль следует калибровать, как в процессе эксплуатации, так и после каждой замены датчика (если таковые будут выполняться), или после изменения частоты переменного тока используемого для измерения сопротивления жидкости.
Запись и чтение данных модуля, осуществляется через его регистры. Доступ к регистрам модуля осуществляется по шине I2C.
С помощью регистров модуля можно выполнять следующие действия:
- Изменить адрес данного модуля на шине I2C. При изменении адреса, можно указать, что новый адрес должен сохраниться в flash память модуля, а значит адрес сохранится и после отключения питания.
- Включить / отключить внутреннюю подтяжку линий шины I2C (по умолчанию включена). Состояние подтяжки линий шины I2C автоматически сохраняется в flash память модуля, а значит состояние линий сохранится после отключения и включения питания.
- Узнать версию прошивки модуля.
- Указать частоту переменного тока используемую для измерения сопротивления жидкости.
- Указать количество растворённых веществ в жидкостях используемых для калибровки.
- Выполнить калибровку модуля (определить коэффициенты степенной функции).
- Указать или прочитать коэффициенты степенной функции.
- Указать или прочитать температурный коэффициент жидкости.
- Указать или прочитать коэффициент пересчёта (для перевода проводимости в ppm).
- Указать текущую температуру жидкости и опорную температуру к которой приводится EC.
- Узнать общее сопротивление между электродами датчика.
- Узнать удельную электрическую проводимость жидкости для текущей температуры.
- Узнать удельную электрическую проводимость приведённую к опорной температуре.
- Узнать количество растворённых твердых веществ в жидкости.
Выводы модуля:
У модуля имеются три колодки выводов: разъем I2C (GND, Vcc, SDA, SCL), разъем A (GND, Vcc, Signal) и разъем посередине платы используемый для подключения датчика.
- SCL - вход/выход линии тактирования шины I2C.
- SDA - вход/выход линии данных шины I2C.
- S (Signal) - аналоговый выход, для совместимости с проектами на аналоговых датчиках.
- Vcc - вход питания от 3,3 до 5 В.
- GND - общий вывод питания.
Вывод «Vcc» колодки «I2C» электрически соединён с выводом «V» колодки «A».
Вывод «GND» колодки «I2C» электрически соединён с выводом «G» колодки «A».
Характеристики:
- Напряжение питания: 3,3 В или 5 В, поддерживаются оба напряжения.
- Ток потребляемый модулем: до 10 мА.
- Интерфейс: I2C.
- Скорость шины I2C: 100 кбит/с.
- Адрес на шине I2C: устанавливается программно (по умолчанию 0x09).
- Уровень логической 1 на линиях шины I2C: Vcc (толерантны к 5В).
- Диапазон измерений TDS: от 0 до 10'000 ppm (мг/л воды).
- Диапазон измерений ЕС: от 0 до 20,000 мСм/см.
- Частота тока используемого для измерений: от 50Гц до 5кГц (по умолчанию 2кГц).
- Точность показаний: ±5% (для растворов NaCl до 3'000 ppm в дистиллированной воде).
- Рабочая температура: от 0 до +55 °С.
- Габариты: 30 х 30 мм.
- Вес: 5 г.
Калибровка модуля:
Для калибровки потребуется приготовить два калибровочных раствора хлорида натрия (NaCl) в концентрации 500 ppm и 1'500 ppm.
Нам понадобятся: хлорид калия (KCl), дистиллированная вода (H2O) - продаётся в универсальных и автомагазинах, 3 чистых стакана, шприц, и весы.
Если хлорида калия (KCl) нет, можно взять хлорид натрия (NaCl) - это обычная пищевая соль.
- Пронумеруйте стаканы цифрами «0», «1» и «2» соответственно.
- В стакане «0» приготовим эталонный раствор хлорида калия с концентрацией 10'000 ppm:
- В стакан «0» насыпьте 1 г (1'000 мг) калиевой соли (KCl).
- В стакан «0» налейте 50-70 мл дистиллированной воды.
Перемешайте содержимое стакана до полного растворения соли. - В стакан «0» долейте дистиллированной воды до получения 100 мл раствора.
Перемешайте содержимое стакана до полного растворения соли. - В итоге в стакане «0» мы получили эталонный раствор 10'000 ppm.
(1'000 мг / 100 мл = 10'000 мг/л = 10'000 ppm).
- В стакане «1» приготовим первую калибровочную жидкость 500 ppm:
- В стакан «1» перелейте 5 мл эталонного раствора из стакана «0» с помощью шприца.
Теперь в стакане «1» находится 5 мл начального раствора.
(1'000 мг / 100 мл = 50 мг / 5 мл). - В стакан «1» долейте дистиллированной воды до получения 100 мл раствора.
Перемешайте содержимое стакана. - В итоге в стакане «1» мы получили первую калибровочную жидкость 500 ppm.
(50 мг / 100 мл = 500 мг/л = 500 ppm).
- В стакан «1» перелейте 5 мл эталонного раствора из стакана «0» с помощью шприца.
- В стакане «2» приготовим вторую калибровочную жидкость 1'500 ppm:
- В стакан «2» перелейте 15 мл эталонного раствора из стакана «0» с помощью шприца.
Теперь в стакане «2» находится 15 мл начального раствора.
(1'000 мг / 100 мл = 150 мг / 15 мл). - В стакан «2» долейте дистиллированной воды до получения 100 мл раствора.
Перемешайте содержимое стакана. - В итоге в стакане «2» мы получили вторую калибровочную жидкость 1'500 ppm.
(150 мг / 100 мл = 1'500 мг/л = 1'500 ppm).
- В стакан «2» перелейте 15 мл эталонного раствора из стакана «0» с помощью шприца.
- Эталонный раствор в стакане «0» больше не понадобится. А калибровочные растворы в стаканах «1» и «2» должны настояться не менее 2 часов.
- Формула: ШПРИЦ = КОНЦЕНТРАЦИЯ * КОЛИЧЕСТВО / ЭТАЛОН
Эта формула позволяет определить, сколько эталонной жидкости (из стакана «0») нужно взять в шприц для приготовления калибровочной жидкости в любых концентрациях.
- Пример: Нужно создать 100 мл калибровочной жидкости 1'500 ppm из эталонной 10'000 ppm.
- КОНЦЕНТРАЦИЯ = 1'500 ppm.
- КОЛИЧЕСТВО = 100 мл.
- ЭТАЛОН = 10'000 ppm.
- ШПРИЦ = КОНЦЕНТРАЦИЯ * КОЛИЧЕСТВО / ЭТАЛОН = 1'500 * 100 / 10'000 = 15 мл.
Этот пример показывает почему на 4 пункте инструкции, для приготовления 100 мл жидкости с концентрацией 1'500 ppm, мы переливали шприцом именно 15 мл эталонного раствора.
Концентрации используемых калибровочных жидкостей хранятся в регистрах 0x0C-0x0D «KNOWN_TDS_1» (500ppm) и 0x0E-0x0F «KNOWN_TDS_2» (1'500ppm) соответственно. При желании вы можете перезаписать эти значения и использовать для калибровки иные жидкости. Записанные значения сохранятся в энергонезависимую память модуля.
Калибровку модуля можно выполнить кнопкой на плате модуля:
- Протрите электроды щупа спиртом или дистиллированной водой.
- Опустите щуп датчика в первую калибровочную жидкость (500 ppm).
- Подождите одну минуту.
- Нажмите кнопку «калибровка». Должен начать мигать светодиод «1».
- Подождите пока не начнут перемигиваться светодиоды «1» и «2».
- Вытащите щуп датчика из первой калибровочной жидкости.
- Протрите электроды щупа спиртом или дистиллированной водой.
- Опустите щуп датчика во вторую калибровочную жидкость (1500 ppm).
- Подождите одну минуту.
- Нажмите кнопку «калибровка». Должен начать мигать светодиод «2».
- Подождите пока светодиод «2» не перестанет мигать.
- Если светодиод «2» погас и светодиод «1» не включился, значит калибровка выполнена.
- Одновременное включение двух светодиодов информирует об ошибке калибровки.
Если по завершении калибровки, оба светодиода включились на 2 секунды, значит калибровка выполнена с ошибкой и результаты калибровки не сохранены. Об ошибке калибровки указывают не только светодиоды, но и биты CODE_CALC_SAVE[3-0] регистра 0x10 «CALIBRATION». Возможные причины ошибки: неправильно приготовлены калибровочные жидкости (концентрации жидкостей не соответствуют указанным в регистрах), перепутан порядок калибровочных жидкостей (на первой стадии использовали 1500ppm, а на второй 500ppm), плохой контакт модуля с щупом, неисправен модуль.
Калибровку можно проводить без нажатия кнопки на плате модуля, устанавливая биты BIT_CALC_1 и BIT_CALC_2 регистра 0x10 «CALIBRATION», тогда концентрация первой и второй калибровочной жидкости указывается в регистр 0x0A-0x0B «KNOWN_TDS» без сохранения в энергонезависимую память (см. описание регистров).
Установка адреса:
Модуль - TDS/EC-метр, 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 0x09 |
FREQUENCY[7-0] FREQUENCY[15-8] |
|||||||
0x0A 0x0B |
KNOWN_TDS[7-0] KNOWN_TDS[15-8] |
|||||||
0x0C 0x0D |
KNOWN_TDS_1[7-0] KNOWN_TDS_1[15-8] |
|||||||
0x0E 0x0F |
KNOWN_TDS_2[7-0] KNOWN_TDS_2[15-8] |
|||||||
0x10 | FLG_STAT_2 | FLG_STAT_1 | CODE_CALC_SAVE[3-0] | BIT_CALC_2 | BIT_CALC_1 | |||
0x11 0x12 0x13 |
Ka[7-0] Ka[15-8] Ka[23-16] |
|||||||
0x14 0x15 |
Кb[7-0] Кb[15-8] |
|||||||
0x16 0x17 |
Kt[7-0] Kt[15-8] |
|||||||
0x18 | Кp[7-0] | |||||||
0x19 | t[7-0] | |||||||
0x1A | T[7-0] | |||||||
0x1B 0x1C 0x1D |
Ro[7-0] Ro[15-8] Ro[23-16] |
|||||||
0x1E 0x1F |
Vout[7-0] Vout[15-8] |
|||||||
0x20 0x21 |
S[7-0] S[15-8] |
|||||||
0x22 0x23 |
EC[7-0] EC[15-8] |
|||||||
0x24 0x25 |
TDS[7-0] TDS[15-8] |
Регистры с адресами 0x02 и 0x03 зарезервированы, их биты сброшены в 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 память, или при обращении к любому регистру (кроме записи в 0x01 «REG_BITS_0» и 0x06 «ADDRESS»). Запись адреса выполняется следующим образом: нужно сбросить бит «BLOCK_ADR», установить бит «SAVE_ADR_EN», после чего записать новый адрес в регистр 0x06 «ADDRESS» с установленным битом «SAVE_FLASH».
Регистр 0x04 «MODEL» - содержит идентификатор типа модуля:
Регистр только для чтения.
- MODEL[7-0] - Для модуля - TDS/EC-метр, FLASH-I2C - идентификатор равен 0x19.
- Если установлен флаг «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] не будет установлен ни временно, ни постоянно. Так же адрес не будет установлен если это запрещено битом «BLOCK_ADR» регистра 0x01 «BITS_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».
Регистры 0x08-0x09 «FREQUENCY» - содержат частоту тока используемого для измерений:
Регистры для чтения и записи.
Значение регистров сохраняется после отключения питания.
Перед записью необходимо ввести код разрешения записи калибровочных значений.
- FREQUENCY[15-0] - Частота переменного тока используемого для измерения электрического сопротивления жидкости в диапазоне от 50 до 5000 Гц. Значение по умолчанию 0x07D0 = 2'000Гц. Частота записанная в регистры 0x08-0x09 «FREQUENCY» применяется после записи старшего байта «FREQUENCY[15-8]».
Если записать значение < 0x0032 то в регистрах появится 0x0032 и частота будет 50 Гц.
Если записать значение > 0x1388 то в регистрах появится 0x1388 и частота будет 5000 Гц. - Использование переменного тока снижает эффект поляризации при измерениях.
- В модулях версии 6 и выше, значение регистра может быть не только записано, но и рассчитано по завершении двух стадий калибровки. В процессе калибровки модуль подбирает частоту максимально согласованную с параметрами щупа, кабеля и входного каскада операционного усилителя.
- В модулях версии 5 и выше, новая частота не будет установлена и сохранена, если на момент её записи в регистры 0x08-0x09 «FREQUENCY» не указан код разрешения записи калибровочных значений CODE_CALC_SAVE[3-0] в регистре 0x10 «CALIBRATION».
Регистры 0x0A-0x0B «KNOWN_TDS» - получают TDS калибровочной жидкости:
Регистры только для записи.
- KNOWN_TDS[15-0] - Известное количество растворённых твёрдых веществ калибровочной жидкости используемой на первой или второй стадии калибровки модуля.
Значение в диапазоне от 0 до 10'000 ppm (мг/л воды) указывается перед установкой битов BIT_CALC_1 и BIT_CALC_2 регистра 0x10 «CALIBRATION».
Если калибровка осуществляется нажатием кнопки на плате, то для первой стадии значение регистра аппаратно установится в значение 0x0C-0x0D «KNOWN_TDS_1» ppm, а на второй в значение 0x0E-0x0F «KNOWN_TDS_2» ppm.
Регистры 0x0C-0x0D «KNOWN_TDS_1» - хранят значение TDS первой калибровочной жидкости:
Регистры 0x0E-0x0F «KNOWN_TDS_2» - хранят значение TDS второй калибровочной жидкости:
Регистры для чтения и записи.
Значение регистров сохраняется после отключения питания.
Перед записью необходимо ввести код разрешения записи калибровочных значений.
- KNOWN_TDS_1[15-0] - Значение аппаратно копируемое в регистр 0x0A-0x0B «KNOWN_TDS» при первом нажатии на кнопку калибровки. По умолчанию 0x01F4 = 500ppm.
- KNOWN_TDS_2[15-0] - Значение аппаратно копируемое в регистр 0x0A-0x0B «KNOWN_TDS» при втором нажатии на кнопку калибровки. По умолчанию 0x05DC = 1'500 ppm.
- Записываемые значения применяются после записи старшего байта.
- В модулях версии 5 и выше, новые значения TDS калибровочных жидкостей не будут применены и сохранены, если на момент записи в регистры 0x0C-0x0D «KNOWN_TDS_1» и 0x0E-0x0F «KNOWN_TDS_2» не указан код разрешения записи калибровочных значений CODE_CALC_SAVE[3-0] в регистре 0x10 «CALIBRATION».
Регистр 0x10 «CALIBRATION» - содержит биты калибровки модуля:
Регистр для чтения и записи.
Модуль аппаратно сбрасывает все биты по завершении вычислений, кроме кода ошибки в битах CODE_CALC_SAVE[3-0], если таковая возникла.
- FLG_STAT_1 - Флаг выполнении первой стадии калибровки модуля.
Флаг устанавливается и сбрасывается аппаратно, информируя о выполнении 1 стадии. - FLG_STAT_2 - Флаг выполнения второй стадии калибровки модуля.
Флаг устанавливается и сбрасывается аппаратно, информируя о выполнении 2 стадии. - BIT_CALC_1 - Бит запуска первой стадии калибровки модуля.
Устанавливать бит нужно не раньше чем через 20-30 секунд после опускания датчика в первую калибровочную жидкость. До установки бита требуется указать количество растворённых твердых веществ первой калибровочной жидкости в регистры 0x0B-0x0C «KNOWN_TDS» и точную температуру этой жидкости в регистр 0x19 «t».
В калибровке так же участвуют: коэффициент перевода 0x18 «Кp» = 0.5, температурный коэффициент жидкости 0x16-0x17 «Kt» = 0.02 и опорная температура 0x1A «T» = 25°С. Если указанные значения по умолчанию требуется изменить, то это надо сделать до установки бита запуска калибровки.
В модулях версии 5 и выше, бит устанавливается с указанием кода CODE_CALC_SAVE[3-0]. - BIT_CALC_2 - Бит запуска второй стадии калибровки модуля.
Устанавливать бит нужно не раньше чем через 20-30 секунд после опускания датчика во вторую калибровочную жидкость. До установки данного бита требуется указать количество растворённых твердых веществ второй калибровочной жидкости в регистры 0x0B-0x0C «KNOWN_TDS» и точную температуру этой жидкости в регистр 0x19 «t».
В калибровке так же участвуют: коэффициент перевода 0x18 «Кp» = 0.5, температурный коэффициент жидкости 0x16-0x17 «Kt» = 0.02 и опорная температура 0x1A «T» = 25°С. Если указанные значения по умолчанию требуется изменить, то это надо сделать до установки бита запуска калибровки.
В модулях версии 5 и выше, бит устанавливается с указанием кода CODE_CALC_SAVE[3-0]. - CODE_CALC_SAVE[3-0] - Биты разрешения записи калибровочных значений.
Перед записью данных в регистры 0x08-0x09 «FREQUENCY», 0x0C-0x0D «KNOWN_TDS_1», 0x0E-0x0F «KNOWN_TDS_2», 0x11-0x13 «Ka», 0x14-0x15 «Кb», необходимо записать код разрешения записи калибровочных значений (1001) в биты CODE_CALC_SAVE[3-0].
Тот же код указывается вместе с установкой битов BIT_CALC_1 или BIT_CALC_2.
Код защищает чип от ненамеренной записи калибровочных данных шумами на шине I2C, биты CODE_CALC_SAVE[3-0] используется в модулях версии 5 и выше.
Биты аппаратно сбрасываются после записи данных в указанные выше регистры.
В модулях версии 6 и выше, в процессе калибровки, биты CODE_CALC_SAVE[3-0] аппаратно принимают значения: - 0001 - при поиске частоты смены полярности щупа на первой стадии калибровки.
- 0010 - при накоплении данных о электропроводности на 1 или 2 стадии калибровки.
- 0011 - при ожидании запуска 2 стадии калибровки (после завершения 1 стадии).
- 0100 - при завершении калибровки с ошибкой (после завершения 2 стадии).
- 0000 - при успешном завершении калибровки (после завершения 2 стадии), а так же при записи в регистры хранящие калибровочные значения (0x08-0x09, 0x0C-0x15).
- Алгоритм калибровки модуля:
По завершении двух стадий известны следующие значения:
- Указаны или используются значения по умолчанию: T (°C), Kt и Kp.
- Указаны температуры двух жидкостей t1 и t2 (°С) во время измерений.
- Указаны количества растворённых веществ для двух жидкостей TDS1 и TDS2 (ppm).
- Измерены напряжения на выходе первого ОУ для двух жидкостей Vout1 и Vout2 (В).
- Преобразуем TDS1 и TDS2 в EC1 и EC2 по формуле: EC = TDS / Kp (мкСм/см).
- Преобразуем EC1 и EC2 в σ1 и σ2 по формуле: σ = EC * ( 1 + Kt * (t-T) ) (мкСм/см).
- Модуль вычисляет σ используя степенную функцию: σ = Ka * Vout^Kb.
- Для этой функции известны две точки: (σ1:Vout1) и (σ2:Vout2).
- Этого достаточно для поиска коэффициентов Ka и Kb степенной функции.
По завершении вычислений, будут определены новые значения множителя 0x11-0x13 «Ka» и степени 0x14-0x15 «Кb», а в модулях версии 6 и выше, будет определена новая частота смены полярности щупа 0x08-0x09 «FREQUENCY».
Регистры 0x11-0x13 «Ka» - содержат множитель степенной функции:
Регистры для чтения и записи.
Значение регистров сохраняется после отключения питания.
Перед записью необходимо ввести код разрешения записи калибровочных значений.
- Ka[23-0] - Множитель степенной функции в десятых долях.
- Регистры хранят значение от 1 = 0.1, до 16'777'215 = 1'677'721.5.
Значение по умолчанию 10'000 = 1000.0.
Записываемое значение применяется после записи старшего байта «Ka[23-16]».
Значение регистра может быть не только записано, но и рассчитано по завершении двух стадий калибровки модуля. - Множитель степенной функции Ka используется для преобразования напряжения Vout (В) считанного с первого ОУ модуля, в удельную электропроводность σ (мкСм/см).
σ = Ka * Vout^Kb. - В модулях версии 5 и ниже, значение Ka хранилось не в десятых, а в сотых долях.
- В модулях версии 5 и выше, новое значение Ka не будет применено и сохранено, если на момент записи в регистры 0x11-0x13 «Ka» не указан код разрешения записи калибровочных значений CODE_CALC_SAVE[3-0] в регистре 0x10 «CALIBRATION».
Регистры 0x14-0x15 «Кb» - содержат степень степенной функции:
Регистры для чтения и записи.
Значение регистров сохраняется после отключения питания.
Перед записью необходимо ввести код разрешения записи калибровочных значений.
- Kb[15-0] - Модуль степени степенной функции в тысячных долях.
Регистры хранят значение от 10 = -0.010, до 65'535 = -65.535.
Значение по умолчанию 5000 = -5.000.
Записываемое значение применяется после записи старшего байта «Kb[15-8]».
Значение регистра может быть не только записано, но и рассчитано по завершении двух стадий калибровки модуля. - Степень степенной функции Kb используется для преобразования напряжения Vout (В) считанного с первого ОУ модуля, в удельную электропроводность σ (мкСм/см).
σ = Ka * Vout^Kb. - В модулях версии 5 и выше, новое значение Kb не будет применено и сохранено, если на момент записи в регистры 0x14-0x13 «Kb» не указан код разрешения записи калибровочных значений CODE_CALC_SAVE[3-0] в регистре 0x10 «CALIBRATION».
Регистры 0x16-0x17 «Kt» - содержат температурный коэффициент жидкости:
Регистры для чтения и записи.
- Kt[15-0] - Температурный коэффициент жидкости в десятитысячных долях.
Регистры хранят значение от 0 = 0.0000 до 65'535 = 6.5535.
Значение по умолчанию 200 = 0.0200.
Температурный коэффициент жидкости зависит от её химического состава.
Записываемое значение применяется после записи старшего байта «Kt[15-8]». - Температурный коэффициент жидкости Kt используется для приведения удельной электрической проводимости жидкости σ (мкСм/см) измеренной при текущей температуре t (°C) к удельной электрической проводимости жидкости EC (мкСм/см) для опорной температуры T (по умолчанию 25°С).
EC = σ / ( 1 + Kt * (t-T) ).
Примечание: EC это значение σ, если бы оно было измерено при T °С, а не t °С.
Регистр 0x18 «Kp» - содержит коэффициент пересчёта:
Регистр для чтения и записи.
- Kp[7-0] - Коэффициент пересчёта в сотых долях.
Регистр хранит значение от 1 = 0.01, до 255 = 2.55.
Значение по умолчанию 50 = 0.5.
Коэффициент пересчёта зависит от химического состава жидкости. Чаще всего используют коэффициенты 0.5, 0.64, 0.7. - Коэффициент пересчёта Kp используется для преобразования удельной электрической проводимости жидкости EC (мкСм/см) приведённой к опорной температуре T (25°С) в количество растворённых твёрдых веществ TDS (ppm или мг/л воды).
TDS = EC * Kp.
Регистр 0x19 «t» - получает реальную температуру жидкости:
Регистр для чтения и записи.
- t[7-0] - Реальная температура жидкости в °С*4 (температура с шагом 0.25°С).
Регистр получает значения от 0 = 0°С, 1 = 0.25 °С, ..., до 255 = 63.75 °С.
Электрическая проводимость жидкости сильно зависит от её температуры. Чем выше температура жидкости, тем выше её электрическая проводимость. По этому модулю требуется постоянно отправлять реальную температуру жидкости. - Зная реальную температуру жидкости t (°С), температурный коэффициент жидкости Kt и измеренную удельную электрическую проводимость жидкости σ (мкСм/см), можно узнать какой будет удельная электрическая проводимость той же жидкости EC (мкСм/см) при опорной температуре T (по умолчанию 25°С).
EC = σ / ( 1 + Kt * (t-T) ).
Регистр 0x1A «T» - содержит опорную температуру жидкости:
Регистр для чтения и записи.
- T[7-0] - Опорная температура жидкости в °С*4 (температура с шагом 0.25°С).
Регистр хранит значения от 0 = 0°С, до 255 = 63.75 °С.
Значение по умолчанию 100 = 25.00°С. - Опорная температура жидкости, это та температура при которой её удельную электрическую проводимость ЕС (мкСм/см) можно умножить на коэффициент пересчёта Kp для получения точного количества растворённых твёрдых веществ TDS (ppm или мг/л воды) в этой жидкости.
TDS = EC * Kp.
На практике неудобно доводить жидкость до температуры T (°C) для проведения измерений, по этому удельную электрическую проводимость σ (мкСм/см) измеряют при любой температуре t (°С), а затем приводят результат к опорной температуре T (°С) получая EC (мкСм/см).
EC = σ / ( 1 + Kt * (t-T) ).
Регистры 0x1B-0x1D «Ro» - содержат общее сопротивление:
Регистры только для чтения.
- Ro[23-0] - Общее измеренное сопротивление в Ом.
Регистры хранят значение от 0 до 10'000'000 Ом.
Общее измеренное сопротивление является совокупностью активных Rd и реактивных Xc сопротивлений датчика (зависящих от его конструкции и частоты переменного тока), и сопротивления жидкости R.
Ro = (R+Rd)Xc / (R+Rd+Xc) Ом. - При подключении резистивного сопротивления к электродам датчика, его наминал будет совпадать с общим измеренным сопротивлением Ro (Ом).
Регистры 0x1E-0x1F «Vout» - содержат напряжение на выходе ОУ:
Регистры только для чтения.
- Vout[15-0] - Напряжение на выходе первого ОУ в десятитысячных долях В.
Регистры хранят значение, от 0 = 0.0000 В до 65'535 = 6.5535 В.
Напряжение на выходе первого ОУ отличается от напряжения на аналоговом выходе модуля, так как последнее проходит через ещё два ОУ и два RC фильтра модуля.
Напряжение на выходе первого ОУ используется модулем для определения удельной электропроводности жидкости, так как оно зависит от электрической проводимости G (мкСм) и постоянной датчика Kd (см-1).
σ = Ka * Vout^Kb. - Примечание: модуль отслеживает все напряжения на первом ОУ. При отклонении напряжений от нормы, включаются оба светодиода на плате модуля. Это можно наблюдать при подаче питания, светодиоды светятся пока не стабилизируется напряжение.
- Напряжение на выходе модуля Vm отличается от напряжения Vout на выходе первого ОУ.
Vm ≈ (3,3В - 0.85 Vout) / 2.
где 0.85 - коэффициент передачи ФВЧ+ФНЧ для измерений на частоте 2кГц (по умолчанию).
Регистры 0x20-0x21 «S» - содержат удельную электропроводность:
Регистры только для чтения.
- S[15-0] - Удельная электрическая проводимость в мкСм/см.
Регистры хранят значение, от 0 мкСм/см до 65'535 мкСм/см.
Удельная электрическая проводимость σ (мкСм/см) вычисляется степенной функцией от напряжения на выходе первого операционного усилителя Vout (В), которое зависит от электрической проводимости G (мкСм) и постоянной датчика Kd (см-1).
σ = Ka * Vout^Kb.
σ = G*Kd = Kd/R = 1/ρ. - Примечание: Регистр имеет имя «S», а не «σ» для совместимости с таблицей ASCII.
Регистры 0x22-0x23 «EC» - содержат приведённую удельную электропроводность:
Регистры только для чтения.
- EC[15-0] - Электрическая проводимость в мкСм/см приведённая к температуре T °C.
Регистры хранят значение, от 0 мкСм/см до 65'535 мкСм/см.
Измеряемая электрическая проводимость жидкости сильно зависит от её температуры. Чем выше температура жидкости, тем выше её электрическая проводимость. По этому удельную электрическую проводимость σ (мкСм/см) измеряют при любой температуре t (°С), а затем приводят результат к опорной температуре T (°С) получая EC (мкСм/см).
EC = σ / ( 1 + Kt * (t-T) ). - Примечание: EC это значение σ, если бы оно было измерено при T °С, а не t °С.
Регистры 0x24-0x25 «TDS» - содержат количество растворённых твёрдых веществ:
Регистры только для чтения.
- TDS[15-0] - Количество растворённых твёрдых веществ в ppm (мг/л воды).
Регистры хранят значение, от 0 ppm до 65'535 ppm.
Количество растворённых твёрдых веществ TDS (ppm) определяется умножением приведённой удельной электрической проводимости ЕС (мкСм/см) на коэффициент пересчёта Kp.
TDS = EC * Kp.
Регистры 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. В противном случае потребуется отключить питание при уже подключённом модуле.
Пример чтения концентрации раствора:
Следующий скетч выводит количество твёрдых растворённых веществ в монитор последовательного порта.
#include <Wire.h> // Подключаем библиотеку Wire для работы с шиной I2C. // const uint8_t ADDRESS = 0x09; // Определяем адрес модуля на шине I2C. const uint8_t REG_t = 0x19; // Определяем адрес регистра принимающего текущую температуру жидкости. const uint8_t REG_TDS = 0x24; // Определяем адрес регистра хранящего концентрацию раствора (мл. байт). float VAL_t = 21.5; // Определяем переменную для передачи текущей температуры жидкости (21.5°C). uint16_t VAL_TDS; // Объявляем переменную для получения концентрации раствора. // void setup(){ // Serial.begin(9600); // Инициируем связь с монитором последовательного порта на скорости 9600 бит/сек. while(!Serial){;} // Ждём готовность к работе аппаратной шины UART. Wire.setClock(100000L); // Устанавливаем скорость передачи данных по шине I2C. Wire.begin(); // Инициируем работу c шиной I2C в качестве мастера. delay(100); // } // // void loop(){ // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write(REG_t); // Функция write() помещает значение своего аргумента в буфер для передачи, в данном случае это адрес регистра REG_t. Wire.write((uint8_t)(VAL_t*4.0f)); // Функция write() помещает значение своего аргумента в буфер для передачи, в данном случае это байт данных для записи в указанный ранее регистр. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных с установкой состояние STOP после передачи. delay(10); // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write(REG_TDS); // Функция write() помещает значение своего аргумента в буфер для передачи, в данном случае это адрес регистра REG_TDS. Wire.endTransmission(false); // Выполняем инициированную ранее передачу данных (параметр false указывает что состояние STOP устанавливать не требуется). Wire.requestFrom(ADDRESS, 2); // Читаем из модуля с адресом ADDRESS, 2 байта данных в буфер библиотеки Wire. Так как предыдущая функция не установила состояние STOP, то состояние START установленное данной функцией будет расценено как RESTART. VAL_TDS = (uint16_t)Wire.read(); // Сохраняем первый байт полученных данных (мл.). VAL_TDS |= (uint16_t)Wire.read()<<8; // Добавляем второй байт полученных данных (ст.). Serial.print("Концентрация раствора "); // Выводим текст. Serial.print(VAL_TDS); // Выводим концентрацию раствора. Serial.print(" ppm.\r\n"); // Выводим текст. delay(500); // } //
- Действия выполняемые в коде setup():
- Инициализация работы с шиной UART на скорости 9'600 бит/сек.
- Инициализация работы с шиной I2C на скорости 100'000 бит/сек.
- Действия выполняемые в коде loop():
- Передача модулю с адресом ADDRESS температуры (VAL_t°С*4) в регистр REG_t.
- Получение от модуля с адресом ADDRESS данных из регистра REG_TDS в VAL_TDS.
- Вывод текста и значения переменной VAL_TDS в монитор последовательного порта.
- Пауза на пол секунды.
Габариты:
Все модули линейки "Trema" выполнены в одном формате:
Обсуждение