# PY32F002B PCHTemperature+Modbus Module
Прога для PY32F002B которая будет считывать датчики температуры в ПЧ и сохранять их в модбас регистры.
Конверсия идет непрерывно и после каждой конверсии считываются все датчики и записываются в модбас регистры.


## **Чтение температуры**
Для считывания температуры необходимо:
- выставить коил `RunConvertion` (`№0`)
- считывать инпут регистры `№0-29` для получения температуры [***Цельсий x 100***]

После выставления коила модуль будет непрерывно запускать конверсию и по её завершении обновлять инпут регистры. 

После каждого завершения конверсии выставляется коил `ConvertionDone` (`№16`), который сбрасывается при чтении инпут регистров температуры. Поэтому имеет смысл дополнительно проверить этот коил, обновились ли значения температуры с прошлого считывания.

Если какой-то датчик был потерян, в инпут регистры на его место записывается `0x0` и выставляется коил `LostedSensors` (`№17`)

## Управление датчиками
Взаимодействие с датчиком строится по следующему принципу:
- заполнение холдинг регистров (`№0-5`) для параметров датчика для обращения к нему
- выставление коила для взаимодействия с датчиком (поиск, чтение, инит, деинит)
- чтение инпут регистров (`№30-36`) содержащих ответ от датчика и [статус взаимодействия](#статус-общения-с-датчиком)

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

### Адреса всех датчиков
Для получения ROM всех датчиков необходимо:
- считать инпут регистры `№38-158`

В них записаны ROM всех найденных датчиков (максимум 30 датчиков на линии), каждый ROM занимает 4 регистра Modbus. Т.е. ROM первого датчика находится в регистрах `№38-41`, ROM второго - в регистрах `№42-45` и так далее. 

### Считывание параметров датчика 
Для считывания параметров конкретного датчика необходимо:
- выставить холдинг регистры:
    - `Location` (`№0`), где находится датчик
    - `ROM` (`№1-4`), адрес датчика
    - Выставляется что-то одно из `Location`/`ROM`, а второе должно быть в нуле
- выставить коил `ReadSensor` (`№1`)
- считать ответ в инпут регистры:
    - `Location` (`№30`), где находится датчик
    - `ROM` (`№31-34`), адрес датчика
    - `Config` (`№35`), конфиг регистр датчика
    - `Status` (`№36`), [статус общения с датчиком](#статус-общения-с-датчиком)

После выставления коила, происходит чтение скратчпада датчика и заполнение им инпут регистров. Если чтение по локации не прошло успешно статус выставляется в `0xF0`. Если чтение по ROM не прошло успешно статус выставляется в `0xF0`

### Инициализация датчика 
Для инициализации датчика необходимо:
- выставить холдинг регистры:
    - `Location` (`№0`), где находится датчик
    - `ROM` (`№1-4`), адрес датчика
    - `Config` (`№5`), конфиг регистр датчика
- выставить коил `InitSensor` (`№2`)
- считать ответ в инпут регистры:
    - `Location` (`№30`), где находится датчик
    - `ROM` (`№31-34`), адрес датчика
    - `Config` (`№35`), конфиг регистр датчика
    - `Status` (`№36`), [статус общения с датчиком](#статус-общения-с-датчиком)

После выставления коила в `UserByte` выбранного по ROM датчика записывается его локация и он включается в структуру датчиков микроконтроллера. Если инициализация не прошла успешно статус выставляется в `0xAA`

### Деинициализация датчика 
Для деинициализации датчика необходимо:
- выставить холдинг регистр `Location` (`№0`), где находится датчик
- выставить коил `DeInitSensor` (`№3`)
- считать ответ в инпут регистры:
    - `Location` (`№30`), где находится датчик
    - `ROM` (`№31-34`), адрес датчика
    - `Config` (`№35`), конфиг регистр датчика
    - `Status` (`№36`), [статус общения с датчиком](#статус-общения-с-датчиком)

После выставления коила в `UserByte` выбранного по `ROM` датчика записываются нули и он выключается из структуры датчиков микроконтроллера. Если деинициализация не прошла успешно статус выставляется в `0x55`

### Статус общения с датчиком
Статус сигнализирует о следующих событиях:
- `0x01`- без ошибок, все ок
- `0x11` - конец скана
- `0xF0` - ошибка при чтении по выбранной локации
- `0x0F` - ошибка при чтении по выбранному ROM
- `0xAA` - ошибка инициализации выбранного датчика
- `0x55` - ошибка деинициализации выбранного датчика
- `0xBB` - ошибка при сканировании (в МК хранится адрес несуществующего датчика например)


## Структура данных
**Coils**: адреса для управления работой модуля
- 0: `RunConvertion` - [запуск преобразований всех датчиков](#чтение-температуры)
- 1: `ReadSensor` - [считать параметры датчика](#считывание-параметров-датчика)
- 2: `InitSensor` - [инициализация датчика](#инициализация-датчика)
- 3: `DeInitSensor` - [деинициализировать датчик](#деинициализация-датчика)
- 4: `ScanSensors` - включить режим [поиска датчиков](#сканирование-датчиков)

**Coils**: адреса для флагов модуля
- 16: `ConvertionDone` - флаг окончания конверсии. Сбрасывается после считывания температуры из регистров
- 17: `LostedSensors` - флаг есть ли потерянные сенсоры. Сбрасывается по модбас

**Hodling Registers**: адреса для передачи параметров датчика и для инициализации/деинициализации.
- 0: `Location` - локация датчика
- 1-4: `ROM` - ROM датчика
- 5: `Config` - разрешение датчика
- 6: `Enable` - считывать напряжение с этого датчика или нет

**Input Registers**: адреса для хранения температуры и параметров датчика
Температура храниться в первых 30 инпут регистрах
- 0-29: `SensTemperature` - температура n-го датчика в [***Цельсий x 100***]
Параметры храняться в рестрах N+1. Хранятся параметры последнего датчика к которому было совершнео обращение (коилы №1-3)
- 30: `Location` - локация датчика, к которому было совершено обращение
- 31-34: `ROM` - ROM датчика, к которому было совершено обращение
- 35: `Config` - конфигурационный регистр датчика, к которому было совершено обращение
- 36: `Status` - статус работы датчика, к которому было совершено обращение