{"id":15011978,"url":"https://github.com/gmasse/esp-modbus-mqtt","last_synced_at":"2025-04-11T14:43:53.232Z","repository":{"id":98659582,"uuid":"245639143","full_name":"gmasse/esp-modbus-mqtt","owner":"gmasse","description":"A Modbus RTU (RS-485) to MQTT Gateway (based on ESP32)","archived":false,"fork":false,"pushed_at":"2024-05-07T23:46:23.000Z","size":464,"stargazers_count":87,"open_issues_count":0,"forks_count":29,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-25T10:51:11.655Z","etag":null,"topics":["esp32","home-automation","iot","modbus","mqtt","platformio"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gmasse.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-07T13:37:42.000Z","updated_at":"2025-03-08T22:22:01.000Z","dependencies_parsed_at":"2024-05-08T00:43:27.099Z","dependency_job_id":null,"html_url":"https://github.com/gmasse/esp-modbus-mqtt","commit_stats":{"total_commits":22,"total_committers":2,"mean_commits":11.0,"dds":0.4545454545454546,"last_synced_commit":"3b40d27a4b5e009e65fc5cdee6fa1c3a16e056cd"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gmasse%2Fesp-modbus-mqtt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gmasse%2Fesp-modbus-mqtt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gmasse%2Fesp-modbus-mqtt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gmasse%2Fesp-modbus-mqtt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gmasse","download_url":"https://codeload.github.com/gmasse/esp-modbus-mqtt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248420649,"owners_count":21100441,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["esp32","home-automation","iot","modbus","mqtt","platformio"],"created_at":"2024-09-24T19:41:58.242Z","updated_at":"2025-04-11T14:43:53.207Z","avatar_url":"https://github.com/gmasse.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"![esp-modbus-mqtt: A Modbus RTU (RS-485) to MQTT Gateway (based on ESP32)](./assets/banner.png)\n\n![CI workflow](https://github.com/gmasse/esp-modbus-mqtt/actions/workflows/ci.yml/badge.svg)\n\n## Circuit\n\nAuto-switching UART-to-RS485 converter:\n```\n\n                   VCC ---------------+\n                                      |\n                              +-------x-------+\n        (PIN27)    RXD \u003c------| RX            |\n                              |      UART    B|----------\u003c\u003e B\n        (PIN26)    TXD ------\u003e| TX    TO      |\nESP32                         |     RS-485    |     RS485 bus side\n                              |               |\n                              |              A|----------\u003c\u003e A\n                              |               |\n                              +-------x-------+\n                                      |\n                                     GND\n```\nManual switching UART-to-RS485 converter:\n```\n                   VCC ---------------+\n                                      |\n                              +-------x-------+\n        (PIN27)    RXD \u003c------| R             |\n                              |      UART    B|----------\u003c\u003e B\n        (PIN26)    TXD ------\u003e| D     TO      |\nESP32                         |     RS-485    |     RS485 bus side\n        (PIN25)    RTS --+---\u003e| DE            |\n                         |    |              A|----------\u003c\u003e A\n                         +----| /RE           |\n                              +-------x-------+\n                                      |\n                                     GND\n```\nNB: ESP32 pins are configurable at compilation time.\n\n## Modbus\n\nDevice acts as Modbus Master, regurlaly polling a list of registers from a Modbus Slave.\n\nList of Modbus parameters (in `platformio.ini` file):\n - `modbus_rxd`: RX/R pin number (default: `27`)\n - `modbus_txd`: TX/D pin number (default: `26`)\n - `modbus_rts`: DE/RE pin number (default: `25`). If you don't need RTS, use `NOT_A_PIN` value.\n - `modbus_baudrate` (default: `9600`)\n - `modbus_unit`: Modbus Slave ID (default: `10`);\n - `modbus_retries`: if a Modbus request fails, number of retries before passing to the next register (default: `2`)\n - `modbus_scanrate`: the device will attempt to poll the slave every XX seconds (default: `30`)\n\nRegisters list is defined by the array `registers[]` in `src/modbus_registers.h`.\nA very simple example would be:\n```\nconst modbus_register_t registers[] = {\n    { 123, MODBUS_TYPE_HOLDING, REGISTER_TYPE_U16, \"value_123\" },\n    { 124, MODBUS_TYPE_HOLDING, REGISTER_TYPE_U16, \"value_124\" }\n};\n```\nWhere:\n - `123` and `124` are register address to read,\n - `MODBUS_TYPE_HOLDING` is the Modbus object type to read,\n - `REGISTER_TYPE_U16` is the expected format of the returned value,\n - `value_123` and `value_124` are the name in the JSON MQTT message\n\n#### Supported Modbus objects:\n - `HOLDING` type is supported and has been tested\n - `INPUT`, `COIL`, `DISCRETE` and `COUNT` has not been tested but should work\n\n#### Supported returned Value:\n - `REGISTER_TYPE_U16`: unsigned 16-bit integer\n - `REGISTER_TYPE_BITFIELD`: a sequence of 16 (or less) single bits; the first item maps the least significant bit\n - `REGISTER_TYPE_DIEMATIC_ONE_DECIMAL`: a specific De-Dietrich signed decimal implementation\n - `REGISTER_TYPE_DEBUG`: hexadecimal value only visible in INFO logs (not sent in MQTT message)\n - other types are not supported (TODO src/modbus_base.cpp:readModbusRegisterToJson)\n\n## MQTT\n\nMQTT parameters are passed through environment variables:\n - `PIO_MQTT_HOST_IP`: MQTT broker IPv4\n - `PIO_MQTT_PORT`: MQTT broker port\n - `PIO_MQTT_TOPIC`: root prefix of the published topic\n\nWith `PIO_MQTT_TOPIC=MyTopic`, based on the register list example above, the published MQTT message will be:\n```\nTopic: MyTopic/ESP-MM-ABCDEF012345/data\nMessage: {\"value_123\":0,\"value_124\":65536}\n```\nWhere `ABCDEF012345` is the ESP unique Chip ID.\n\n## Compilation\n\n```\ngit clone https://github.com/gmasse/esp-modbus-mqtt.git\ncd esp-modbus-mqtt\npython3 -m venv venv\nsource venv/bin/activate\npip install -U platformio\nhash -r\ncp platformio.ini.dist platformio.ini\n(edit platformio.ini if needed)\nexport PIO_FIRMWARE_URL=\"http://domain.com/firmware.bin\"\nexport PIO_MQTT_HOST_IP=11.22.33.44\nexport PIO_MQTT_PORT=1883\nexport PIO_MQTT_TOPIC=mytopic\nplatformio run\n```\n\nBuilt firmware will be at `.pio/build/fm-devkit/firmware.bin`\nYou can upload to ESP with: `platformio run upload`\n\n## TODO\n\n- [ ] Configuration (Wifi credentials) Reset\n- [ ] Factory Firmware (https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/bootloader.html)\n- [ ] Secure Boot\n- [ ] Moving to ESP-IDF Framework\n- [ ] Log level update at runtime\n\n## FAQ\n#### Passing environment variables via VS Code\nEdit `.vscode/settings.json` and add the following lines:\n```\n  \"terminal.integrated.env.osx\": {\n    \"PIO_FIRMWARE_URL\": \"https://url/firmware.bin\",\n    \"PIO_MQTT_HOST_IP\": \"11.22.33.44\",\n    \"PIO_MQTT_PORT\": \"1883\",\n    \"PIO_MQTT_TOPIC\": \"mytopic\"\n  },\n```\n\n#### Flashing firmware\n```\ncp .plateformio/packages/framework-arduinoespressif32/tools/sdk/bin/bootloader_dio_40m.bin .\ncp .platformio/packages/framework-arduinoespressif32/tools/partitions/default.bin .\n\nesptool.py --chip esp32 --port /dev/ttyUSB1 --baud 460800 \\\n --before default_reset --after hard_reset write_flash -z \\\n --flash_mode dio --flash_freq 40m --flash_size detect \\\n 0x1000 bootloader_dio_40m.bin 0x8000 default.bin 0x10000 firmware.bin\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgmasse%2Fesp-modbus-mqtt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgmasse%2Fesp-modbus-mqtt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgmasse%2Fesp-modbus-mqtt/lists"}