{"id":13805571,"url":"https://github.com/erdetn/vserialport","last_synced_at":"2026-01-16T15:10:57.722Z","repository":{"id":53568942,"uuid":"426509484","full_name":"erdetn/vserialport","owner":"erdetn","description":"Wrapper of libserialport written in V","archived":false,"fork":false,"pushed_at":"2021-11-21T14:43:26.000Z","size":31,"stargazers_count":12,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-18T21:48:10.553Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"V","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erdetn.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}},"created_at":"2021-11-10T06:29:17.000Z","updated_at":"2024-02-02T06:43:09.000Z","dependencies_parsed_at":"2022-08-26T14:24:29.894Z","dependency_job_id":null,"html_url":"https://github.com/erdetn/vserialport","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erdetn%2Fvserialport","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erdetn%2Fvserialport/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erdetn%2Fvserialport/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erdetn%2Fvserialport/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erdetn","download_url":"https://codeload.github.com/erdetn/vserialport/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254012971,"owners_count":21999346,"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":[],"created_at":"2024-08-04T01:01:02.476Z","updated_at":"2026-01-16T15:10:57.710Z","avatar_url":"https://github.com/erdetn.png","language":"V","funding_links":[],"categories":["Libraries"],"sub_categories":["Serial Communications"],"readme":"# vserialport\nThis is a wrapper of [`libserialport`](https://sigrok.org/wiki/Libserialport) written in V. `vserialport` consists of the main datatype `Port`, and `Configuration`, `EventSet`, `UsbBus` and `UsbID` as secondary datatypes.\n\n\n## Construct and deconstruct the serial `Port`\nCreate a `Port` object by calling `new_port`. `new_port` requires `port_name` argument as string (such as `devttyUSB0` or `/dev/ttyS0`) and returns optionally `Port` object. Use `or` to handle the error, in case it failes to create the `Port` object.\n```V\nmut p1 := vserialport.new_port('/dev/ttyUSB1') or {\n\tcode := vserialport.error_code()\n\tmsg  := vserialport.error_message()\n\tprintln('\u003e\u003e [${code}]: ${msg}')\n\tprintln('Failed to open:\\n\\t${err.msg}')\n\treturn\n}\n```\nIn case the object is created, make sure to call the *destructor* function `free()` to deallocate the `Port` object. A safer approach is to use [defer](https://github.com/vlang/v/blob/master/doc/docs.md#defer).\n```V\np1.free()\n```\n\n## Open and close the connection with serial port\nUse `p1.open()` and `p1.close()` to open the connection with serial port and to disconnect the serial port. `open(mode)` requires `vserialport.Mode` argument and returns a boolean if it is connected or not. The other way to check if the `Port` is connected or not, use `p1.is_connected()` function.\n```v\nenum Mode {\n\tread\n\twrite\n\tread_write\n}\n```\nSuch as:\n```v\nmut rc := int(0)\nif p1.open(vserialport.Mode.read_write) == false {\n\tcode := vserialport.error_code()\n\tmsg  := vserialport.error_message()\n\tprintln('\u003e\u003e [${code}]: ${msg}')\n\tp1.free()\n}\nprintln('p1 port is connected = ${p1.is_connected()}')\n```\n\n## Read / write functions\n`libserialport` supports non-blocking and blocking read/write functions. The same approach is reflected on `vserialport` as well. `write` function requires the first argument of boolean type to be set, if the write function is blocking or non-blocking write to serial port, respectively - that is, `block bool`: `true` for blocking write function, and `false` for non blocking write function. If it is non-blocking write function, the third argument - the `timeout_ms` argument is not going to be taken into consideration. It is useful only for blocking write function. The second argument is the byte array to be sent. In case you have to send `string`, `string` provides the `bytes()` function, which returns the byte array of that string. The `write` functions returns optional integer - that is, either number of bytes that are written to the serial port or the error that needs to be handled with `or` operator.\n\n### Example 1:\n```v\n// Use non-blocking write to sent string AT+R\nrc := p1.write(false, 'AT+R\\r'.bytes(), 0) or {\n\tprintln('faild to write')\n\treturn\n}\nprintln('${rc} bytes are sent.)\n```\n### Example 2\n```v\n// Use blocking write (and wait 1000 ms) to send this byte array [0x01, 0x31, 0x31, 0x04]\nrc := p1.write(true, [byte(0x01), 0x31, 0x31, 0x04], 1000) or {\n\tprintln('faild to write')\n\treturn\n}\nprintln('${rc} bytes are sent.)\n```\n\nFunction prototype for read/write.\n```v\nwrite(block bool, buffer []byte, timeout_ms u32) ?int\nread(mode ReaderMode, max_length u32, timeout_ms u32) []byte\n```\nIn contrast with `write` function, the first argument of `read` function, instead of bool, requires `mode` as `enum ReaderMode` which has following three options:\n```v\nenum ReaderMode{\n\tblocking    = 0\n\tnext        = 1\n\tnonblocking = 2\n}\n```\n\n\n## Configuration functions\nUse `set_baudrate()`, `set_bits()`, `set_parity()`, `set_stopbits()`, `set_rts(vserialport.Rts)`, `set_cts(vserialport.Cts)`, `set_dtr(vserialport.Dtr)`, `set_dsr(vserialport.Dsr)`, `set_xon_xoff(vserialport.XonXoff)` and `set_flowcontrol(vserialport.FlowControl)` to configure baudrate, bits, parity, stop bits, rts, cts, dtr, dsr, xon_xoff and flowcontrol, respectively.\n\nSome other helping functions are: \n| function | return type | description |\n| -- | -- | -- |\n| `Port.name()` | `string` | returns the name of serial port.|\n| `Port.description()`| `string` | returns the description of serial port. |\n| `Port.transport()` | `enum Transport` | returns the transport type of serial port. `enum Transport {native, usb, bluetooth}`|\n| `Port.usb_bus()` | `struct UsbBus` | returns the usb bus and usb address. |\n| `Port.usb_id()` | `struct UsbId` | returns the USB vendor ID and USB product ID. |\n| `Port.usb_manufacturer()` | `string` | returns the USB manufacturer. |\n| `Port.usb_product()` | `string` | returns the USB product. |\n| `Port.bluetooth_adress()` | `string` | returns the bluetooth address as string. |\n\n## Other functions\n|Function name | Return type | Description |\n| -- | -- | -- |\n| `Port.bytes_to_read()` | `int` | Return the number of bytes waiting in the input buffer. |\n| `Port.bytes_to_write()` | `int` |  Return the number of bytes waiting in the output buffer. |\n| `Port.flush(Buffer)` | `bool` | Flushes the `Buffer.input`, `Buffer.output` or `Buffer.both` and returns `true` if the selected buffer is flushed, otherwise `false`.|\n| `Port.drain()` | `false` | Waits for the buffered data to be transmitted. | \n| `Port.signal()` | `enum Signal` | Returns the status of control signal. This depends from the control signals that the serial port is configured. This may trigger as output `Signal.cts`, `Signal.dsr`, `Signal.dcd` or `Signal.ri`. If it failes to get the control signal, error needs to be handled with `or` operator.|\n| `Port.start_break` | `bool` | Puts the serial port transmission line into the break state. |\n| `Port.end_break` | `bool` | Takes the serial port tranmission line out of the break state. |\n\nOther helping function from `vserialport`:\n|Function name | Return type | Description |\n| -- | -- | -- |\n| `error_code()` | `int` | Returns the last error code. |\n| `error_message()` | `string` | Returns the last error message. |\n| `major_version()` | `int` | Returns the major package version of `libserialport`. |\n| `minor_version()` | `int` | Returns the minor package version of `libserialport`. |\n| `micro_version()` | `int` | Returns the micro package version of `libserialport`. |\n| `package_version()` | `string` | Returns the full package version of `libserialport` |\n\n## Depedencies\n- [libserialport](https://github.com/sigrokproject/libserialport)\n## Bugfix\nIf you install the `libserialport` using `apt-get install libserialport*`, you may have to deal with following error: **\"Inappropriate ioctl for device\"**. To avoid this error, make sure to install the `libserialport` from the github [repository](https://github.com/sigrokproject/libserialport). More specifically, make sure that the following patch is applied ([patch](https://sigrok.org/bugzilla/attachment.cgi?id=733)):\n```\nconfigure.ac | 2 +-\n1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/configure.ac b/configure.ac\nindex b1af16f..a26b851 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -112,7 +112,7 @@ AC_SYS_LARGEFILE\n AC_TYPE_SIZE_T\n \n # Check for specific termios structures.\n-AC_CHECK_TYPES([struct termios2, struct termiox],,,\n+AC_CHECK_TYPES([struct termios2],,,\n \t[[#include \u003clinux/termios.h\u003e]])\n AC_CHECK_MEMBERS([struct termios.c_ispeed, struct termios.c_ospeed,\n \t\tstruct termios2.c_ispeed, struct termios2.c_ospeed],,,\n```\n\n## Roadmap\n- [x] Writing the wrapper.\n- [x] Testing main functions of `Port` struct.\n- [ ] Testing other function of `Port` struct.\n- [ ] Full testing of `Configuration` struct.\n- [ ] Full testing of `EventSet` struct.\n- [ ] Multithreading/concurrency.\n- [ ] Testing on Windows OS.\n- [ ] Testing on Linux OS.\n\n## WARNING\nThis wrapper is not yet fully validated enough to be implemented in the application industry. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferdetn%2Fvserialport","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferdetn%2Fvserialport","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferdetn%2Fvserialport/lists"}