{"id":29190812,"url":"https://github.com/abratchik/upscore","last_synced_at":"2026-02-26T16:14:43.169Z","repository":{"id":281540425,"uuid":"912504595","full_name":"abratchik/UPSCore","owner":"abratchik","description":"This project is implementing core functions of a basic single-phase line-interactive UPS using Arduino. ","archived":false,"fork":false,"pushed_at":"2025-05-13T14:13:11.000Z","size":771,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-12T01:35:50.111Z","etag":null,"topics":["arduino","line-interactive","ups","voltronic"],"latest_commit_sha":null,"homepage":"https://projecthub.arduino.cc/abratchik/line-interactive-ups-on-arduino-part-1-bcd89b","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/abratchik.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,"zenodo":null}},"created_at":"2025-01-05T18:52:47.000Z","updated_at":"2025-07-06T12:25:58.000Z","dependencies_parsed_at":"2025-03-09T20:19:37.642Z","dependency_job_id":"e19aa384-06dd-4eb9-9ee7-7f55ee9ff30f","html_url":"https://github.com/abratchik/UPSCore","commit_stats":null,"previous_names":["abratchik/upscore"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/abratchik/UPSCore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abratchik%2FUPSCore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abratchik%2FUPSCore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abratchik%2FUPSCore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abratchik%2FUPSCore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abratchik","download_url":"https://codeload.github.com/abratchik/UPSCore/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abratchik%2FUPSCore/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279052233,"owners_count":26093894,"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","status":"online","status_checked_at":"2025-10-15T02:00:07.814Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["arduino","line-interactive","ups","voltronic"],"created_at":"2025-07-02T00:11:43.599Z","updated_at":"2025-10-15T05:09:36.453Z","avatar_url":"https://github.com/abratchik.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Line-interactive UPS on Arduino\nThis project is implementing core functions of a basic single-phase line-interactive UPS using Arduino. The main idea is to have a fully functional controller, which can manage display indication, relays, invertor and sensors and also support external communication based on the [Voltronic protocol](https://networkupstools.org/protocols/voltronic.html). \n\n## Introduction \n\nThe central part of a typical line-interactive UPS is a Big Iron Transformer, which plays the role of a back-boost voltage regulator with help of relays. \n\n\u003ccenter class=\"half\"\u003e\n    \u003cdiv style=\"background-color:#ffffff;\"\u003e\n    \u003cimg src=\"docs/line-interactive-ups-diagram.png\" title=\"Line Interactive UPS with the Back-Boost Transformer\"/\u003e\n\u003c/center\u003e\n\nIf the input voltage is within the acceptable limits (230V +/- 10%) then the UPS passes it to the load with no changes, just applying EMI/RFI and load filters. But once the voltage is deviating for more than 10%, the relays are switching to ensure voltage back or boost, depending on the sign of deviation. \n\nFinally, if the input voltage is beyond the limits of back/boost regulation then the input relay is disconnected and the invertor kicks in to ensure the uninterrupted power feed to the load.\n\nSince the invertor is taking power form the battery, the latter needs to be charged when the load is powered from the mains. There are different options how the charger can be implemented but the most recent ones involve some sort of fast-switching voltage convertors maintaining the required charging current by pulse-width modulation.\n\nThe line-interactive UPS controller features implemented in this project include:\n\n1. Manage UPS relays to ensure the back/boost regulation of the output voltage when on AC power.\n2. Automatically switch on the inverter once the AC power falls beyond the regulation limits and safely return to the AC once the mains power is restored back to normal.\n3. Support user-friendly display indication. There are numerous display options for the UPS so for this project. For this projects, 3 options are supported: a 1602 or 2003 LCD display based on HD44780 controller (the most common for Arduino community), or an LED indicator based on [TM1640 chip](https://www.alldatasheet.com/datasheet-pdf/pdf/1133630/TITAN/TM1640.html). The latter has been re-used from a broken commercial UPS. One can modify or amend the Display class (see **Display.h**) in case if different hardware is to be supported.   \n4. Display switch on/off and brightness regulation\n5. Support of pulse-width modulated output for driving the battery charging process.\n6. Support of the sensors: input/output AC voltage, output current (load), battery voltage and current. \n7. Support of the UPS sound indication (buzzer).\n8. Support of the self-test scenario \n9. Support of the standby/restore scenario\n10. Serial communication based on [Voltronic protocol](https://networkupstools.org/protocols/voltronic.html) implementation. See supported commands below:\n\n## Configuration\nMain parameters are set in the **config.h** and can be tweaked based on the Arduino board used. The solution is tested on the Arduino Nano board and 2x12V PbAc batteries. \n\n## Voltronic: supported commands\nThe solution supports most of the Voltronic commands. Some extensions are added to enable display and sensor management. Also, the default baud rate is set to 9600bps in order to minimize the blocking delays needed for the serial processing and allow more time for the main loop. However, the baud rate can be adjusted to the standard 2400bps in the **config.h**.\n\n\u003ctable\u003e\n\u003cthead\u003e\u003ctd\u003e\u003cb\u003eCommand\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003eDescription\u003c/b\u003e\u003c/td\u003e\u003c/th\u003e\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003eM\u003c/td\u003e\u003ctd\u003eReturns the Voltronic protocol. Currently only 'V' is supported\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eQ\u003c/td\u003e\u003ctd\u003eToggle the UPS buzzer.\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eQS\u003c/td\u003e\u003ctd\u003eQuery UPS for status (short) (old)\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eQMD\u003c/td\u003e\u003ctd\u003eQuery UPS for rated information #1\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eQRI\u003c/td\u003e\u003ctd\u003eQuery UPS for rated information #2\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eQMF\u003c/td\u003e\u003ctd\u003eQuery UPS for manufacturer\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eQBV\u003c/td\u003e\u003ctd\u003eQuery UPS for battery information\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eD\u003c/td\u003e\u003ctd\u003eToggle display on or off\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eDn\u003c/td\u003e\u003ctd\u003eSet the brightness level for the display where \u003cb\u003en\u003c/b\u003e is representing the brightness level and can be from 0 to 4\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eDM\u003c/td\u003e\u003ctd\u003eChange the display mode. The effect of this command depends on the type of the display used. For TM1640 it is showing the input and output frequency. Not supported for HD44780 with 20x04 screen\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eT\u003c/td\u003e\u003ctd\u003eInvoke a quick battery self-test\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTn\u003c/td\u003e\u003ctd\u003eInvoke a battery self-test lasting n (.2→.9, 01→99) minutes\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eCT\u003c/td\u003e\u003ctd\u003eCancel the self-test\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eSnRm\u003c/td\u003e\u003ctd\u003eDisconnect the load in n (.2→.9, 01→99) minutes and then connect again after m (0001..9999) minutes\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eCS\u003c/td\u003e\u003ctd\u003eRe-connect the load or cancel the previous S command\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eR\u003c/td\u003e\u003ctd\u003eReset the controller board\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eVN\u003c/td\u003e\u003ctd\u003ePrint the scale factor and the offset of the sensor specified by the index N\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eVNPMVK...K\u003c/td\u003e\u003ctd\u003eallows to tune or read sensor params, where:\u003cbr\u003e\nN - index of the sensor (1 digit). See the Sensors section below for the list of available indexes (0-4).\u003cbr\u003e\nM - can be 0 (scale) or 1 (offset).\u003cbr\u003e\nK...K - float value to be set (17 symbols, counting with the decimal dot).\u003cbr\u003e\nThe same command can also modify PID parameters of the charger regulator (index=5). Please see the Charger section for details.\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eW\u003c/td\u003e\u003ctd\u003eSave the sensor params in the EEPROM\u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\nCommands are posted through Serial  bus. Each command should be sent for execution followed by the `CR` symbol. \n\n## Sensors\nThe crucial part of line-interactive UPS is a set of sensors measuring input and output voltage and current as well as battery parameters. It is very important to ensure that these sensors are configured and tuned correctly so that the UPS could function properly.\n\nThe comprehensive list of sensors is represented in the table below. Each sensor is characterized by two parameters: \u003cI\u003escale factor\u003c/I\u003e and \u003cI\u003eoffset\u003c/I\u003e, both of the float type. The purpose of these parameters is to transform the integer reading from the Arduino analog input to the voltage, or amperage, or temperature in physical units. \n\n\u003ctable\u003e\n\u003cthead\u003e\n    \u003ctd\u003e\u003cb\u003eIndex\u003c/b\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cb\u003ePurpose\u003c/b\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cb\u003eLimits\u003c/b\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cb\u003eDefault scale\u003c/b\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cb\u003eDefault offset\u003c/b\u003e\u003c/td\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e0\u003c/td\u003e\n        \u003ctd\u003eInput voltage\u003c/td\u003e\n        \u003ctd\u003e0...300VAC\u003c/td\u003e\n        \u003ctd\u003e2.05\u003c/td\u003e\n        \u003ctd\u003e0\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e1\u003c/td\u003e\n        \u003ctd\u003eOutput voltage\u003c/td\u003e\n        \u003ctd\u003e0...300VAC\u003c/td\u003e\n        \u003ctd\u003e2.05\u003c/td\u003e\n        \u003ctd\u003e0\u003c/td\u003e\n    \u003c/tr\u003e \n    \u003ctr\u003e\n        \u003ctd\u003e2\u003c/td\u003e\n        \u003ctd\u003eOutput current\u003c/td\u003e\n        \u003ctd\u003e0...9A\u003c/td\u003e\n        \u003ctd\u003e0.007\u003c/td\u003e\n        \u003ctd\u003e0\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e3\u003c/td\u003e\n        \u003ctd\u003eBattery voltage\u003c/td\u003e\n        \u003ctd\u003e0...49.9V\u003c/td\u003e\n        \u003ctd\u003e0.05298\u003c/td\u003e\n        \u003ctd\u003e0\u003c/td\u003e\n    \u003c/tr\u003e     \n     \u003ctr\u003e\n        \u003ctd\u003e4\u003c/td\u003e\n        \u003ctd\u003eBattery current\u003c/td\u003e\n        \u003ctd\u003e-29.9...29.9A\u003c/td\u003e\n        \u003ctd\u003e0.07362\u003c/td\u003e\n        \u003ctd\u003e-37.61\u003c/td\u003e\n    \u003c/tr\u003e           \n\u003c/tbody\u003e\n\u003c/table\u003e\n\nTwo types of sensors are supported - Running Average (for non-periodic signal) and true RMS for AC voltage.  \n\n### AC voltage sensors\nAC voltage sensors can be implemented based on ZMPT101b signal transformer. The schema of the sensor is below. \n\n\u003ccenter class=\"half\"\u003e\n    \u003cdiv style=\"background-color:#ffffff;\"\u003e\n    \u003cimg src=\"docs/zmpt101b.png\" title=\"Line Interactive UPS with the Back-Boost Transformer\"/\u003e\n\u003c/center\u003e\n\nThe R1 is limiting the input current as required by the transformer module. The signal voltage is formed on R2. R5/C1 is forming the low-pass filter with approx 1kHz of the cutoff frequency. It is needed to filter out all the high-frequency noise.     \n\n### DC Current sensor\nMeasurement of the DC current through the battery can be done with help if the standard ACS712 module based on Hall effect. There are 5A, 20A and 30A modules available on the market. The schema of these modules is below:\n\n\u003ccenter class=\"half\"\u003e\n    \u003cdiv style=\"background-color:#ffffff;\"\u003e\n    \u003cimg src=\"docs/acs712.jpg\" title=\"Line Interactive UPS with the Back-Boost Transformer\"/\u003e\n\u003c/center\u003e\n\n## Charger\nBattery charging is kicking in 2 seconds when the input VAC is within the acceptable limits. The algorithm of charging is \"constant current-\u003econstant voltage-\u003estandby\":\n\n1. Constant Current. The charger is maintaining the battery current at 10% of the battery capacity till the voltage is reaching the maximum as defined for the cell per cycle use.\n2. Constant voltage. The charger is maintaining the maximum voltage per cell till the charging current become less than 2% of the battery capacity.\n3. Standby. The voltage is dropped to the standby level and kept at it thus maintaining the battery at the charged state.\n\nRegulation of the current and voltage is based on the PID regulator. Values of PID coefficients can be configured using the \"V\"/\"W\" commands with the index 5 (similar to a sensor):\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctd\u003e\u003cb\u003e#\u003c/b\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cb\u003eParameter\u003c/b\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cb\u003eDescription\u003c/b\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cb\u003eDefault value\u003c/b\u003e\u003c/td\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003eKp\u003c/td\u003e\u003ctd\u003eProportional\u003c/td\u003e\u003ctd\u003e400\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003eKi\u003c/td\u003e\u003ctd\u003eIntegral\u003c/td\u003e\u003ctd\u003e0.02\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003eKd\u003c/td\u003e\u003ctd\u003eDerivative\u003c/td\u003e\u003ctd\u003e50.0\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\nOutput of the charger is a PWM signal on the pin 10. \n\nCharger parameters can be changed similar to sensor parameters, by the command \u003cb\u003eVNPMVK...K\u003c/b\u003e where N=5, M is the index of the parameter and K...K is the new value. Dumping of parameters canbe invoked by \u003cb\u003eV5\u003c/b\u003e command, also similar to sensors. Example of the response is below:\n\n```\n(5 250.00 0.02 50.00 0.90 28.80 0.79 26.52 1 1 0.12 358\n```\nValues are space-delimited and come as follows:\n- index of the charger, always equal to 5\n- Kp PID parameter\n- Ki PID parameter\n- Kd PID parameter\n- target battery current during the 1st charging phase\n- target battery voltage during the 2nd charging phase\n- measured battery current \n- measured battery voltage \n- '1' if charging or '0' otherwise\n- phase of charging ('0' - constant current, '1' - constant voltage, '2' - standby). If the value is greater than 2, this indicates that some erroneous situation happened during the charging. Possible error codes are defined in the ChargingStatus enum in the Charger.h header.\n- relative deviation from the target (current or voltage)\n- output value of the charger regulator. Can be from 0 to 512. The maximum value corresponds to the 50% duty cycle.\n\n## Display\nIndication of the line-interactive modes and parameters can be done in many different ways. The Display class is supporting several options, which are defined in the **config.h** header by modifying corresponding macro as listed below.\n\n```\n// uncomment only one line for enabling display of the supported type\n// #define DISPLAY_TYPE_NONE                        // no display. Saves resources at the expense of real-time visual info on the UPS. \n// #define DISPLAY_TYPE_LED_TM1640                  // LED assembly display based on TM1640\n// #define DISPLAY_TYPE_LCD_HD44780                 // 16x2 or 20x4 LCD matrix display based on HD44780\n\n// allows to configure display I2C address and resolution for HD44780\n#ifdef DISPLAY_TYPE_LCD_HD44780\n#define DISPLAY_I2C_ADDRESS     0x27\n#define DISPLAY_SCREEN_WIDTH    20\n#define DISPLAY_SCREEN_HEIGHT   4\n#endif\n```\n\n  \n\n## License\n[GPLv3](/LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabratchik%2Fupscore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabratchik%2Fupscore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabratchik%2Fupscore/lists"}