# tcp module | Status | Last Update | API Version | | ------ | ----------- | ----------- | | Active | 2020-10-17 | V1.00.00 | After firmware version `V1.00.45`, we provide a TCP port for user's PC applications to communicate with his Lua scripts. This is ideal for: Production line automation, customized data querying, etc. ## Scheme Connect the meter to PC, open Shizuku Toolbox application. When you open your multimeter, Shizuku Tool application will act as a TCP server, forwarding data flows from and into the meter. Your application communicates with your lua script with this TCP port. ![image-20201017193259272](vcp_inplementation_en.png) ## What can user TCP do? While other lua APIs provide access to hardware resources of the meter, the TCP API provides a way to establish connection with your host application on your PC. ## Loopback test Before you make use of this feature, we should make sure TCP forwarding functions normally: If you haven't installed Shizuku host App yet, download it [here](https://yk-lab.org:666/index.php/shizuku-pc-software/). Connect the multimeter and your PC with a micro USB cable, run Shizuku Toolbox, and double-click your multimeter's name to open the multimeter: ![loopback1](loopback1_en.png) Click`Lua Script`panel,and find`Lua TCP`: ![loopback2](loopback2_en.png) Set a proper local TCP port number, and click start button. ![loopback3](loopback3_en.png) Copy the following code into code panel on the right side ```lua function tcp_callback() tcp.write(tcp.readAll()) end tcp.open() tcp.onReceived(tcp_callback) ``` ![loopback4](loopback10_en.png) Open PuTTY,config it as following, and click open button: ![loopback4](loopback4.png) After this, when you type anything into the session, you should be able to read an echo, which means the loopback test works well: ![loopback5](loopback5.png) You might think to launch an application for TCP forwarding is too cumbersome, you may use `UserTCPUtils` instead, which is installed in the same directory with Shizuku toolbox. Usage and example: ```bat Usage: UserTCPUtils.exe -s -t Example: UserTCPUtils.exe -s COM1 -t 10000 ``` ## tcp.open() ### Description Open user TCP port and allocate Rx/Tx buffer. If no size is specified, both Rx and Tx buffer is 64 bytes. ### Parameters | Name | Type | Range | Usage | | ---------------- | ------ | -------- | ------------------ | | [rx_buffer_size] | number | 1~2^32-1 | Specify Rx buffer size | | [tx_buffer_size] | number| 1~2^32-1 | Specify Tx buffer size| ### Return Value nil ### Example call ```lua tcp.open() --Open user TCP ``` ## tcp.close() ### Description Close user TCP port. ### Parameters nil ### Return Value nil ### Example call ```lua tcp.close() --Close user TCP ``` ## tcp.read() ### Description Read n bytes from user TCP port. ### Parameters | Name | Type | Range | Usage | | ---------------- | ------ | -------- | ------------------ | | bytesToRead | number | 1~2^32-1 | Number of bytes that you want to read | ### Behaviour If existing data in Rx buffer is equal or greater than `bytesToRead`, the function fetch `bytesToRead` bytes of data from the buffer and return immediately. Otherwise the function waits until `bytesToRead` of data is received and return it. If the time waited is greater than the timeout (You can specify the timeout with `vcp.setTimeout()`), the function returns with all the data available. ### Return Value | Name | Type | Range | Usage | | ---------------- | ------ | -------- | ------------------ | | content | string | | Data received. | | actual_size | number | 1~2^32-1 | Length of data received. | ### Example call ```lua packet = tcp.read(20) --Read a packet with length 20. ``` ## tcp.readAll() ### Description Read all the data in the Rx buffer. ### Parameters nil ### Behaviour Read all existing data in the Rx buffer, the function returns immediately after calling. If the Rx buffer is empty, an empty `string` and a `number` 0 is returned. ### Return Value | Name | Type | Range | Usage | | ---------- | ------ | -------- | ------------ | | content | string | | Data received. | | bytesCount | number | 1~2^32-1 | Length of data received. | ### Example call ```lua packet,actual_size = tcp.readAll() --Read all if(actual_size == 0) begin print("We got nothing.") end ``` ## tcp.write() ### Description Write content to Tx buffer. ### Parameters | Name | Type | Range | Usage | | ---------------- | ------ | -------- | ------------------ | | content | string | 1~2^32-1 | Content to send | ### Behaviour If there is enough empty space in the Tx buffer, the function write content into the Tx buffer and return immediately. If there is not enough space in the Tx buffer, the function write the Tx buffer to full, and wait for the data to be sent out, and write again until all the data is sent. If the tx buffer is full more than the timeout specified(You can specify the timeout with `vcp.setTimeout()`), the function returns. ### Return value | Name | Type | Range | Usage | | ---------------- | ------ | -------- | ------------------ | | actual_size | number | 1~2^32-1 | Number of bytes actually sent. | ### Example call ```lua tcp.write("Hello World!!") ``` ## tcp.bytesToRead() ### Description Get number of bytes in the Rx buffer. ### Parameters nil ### Return value | Name | Type | Range | Usage | | ----------- | ------ | -------- | ------------------------ | | bytesToRead | number | 1~2^32-1 | Number of bytes in the Rx buffer | ### Example call ```lua byteCount = tcp.bytesToRead() --Get size of data in rx FIFO data = tcp.read(byteCount) --Read out data ``` ## tcp.bytesToWrite() ### Description Get number of bytes of data which is still in the Tx buffer. ### Parameters nil ### Return value | Name | Type | Range | Usage | | ------------ | ------ | -------- | -------------------------------------- | | bytesToWrite | number | 1~2^32-1 | Number of bytes of data which is still in the Tx buffer | ### Example call ```lua if(tcp.bytesToWrite() > 0) then tcp.flushTx() end ``` ## tcp.rxOverflow() ### Description Check if an overflow event happened in the Rx buffer. ### Parameters nil ### Return value | Name | Type | Range | Usage | | ---------- | ------- | ---- | ------------------ | | overflowed | boolean | | Overflowed | ### Example call ```lua if(tcp.rxOverflow()) then print("Oh shit, we are in trouble.") end ``` ## tcp.setTimeout() ### Description Set timeout of a write or read operation. The default Rx/Tx timeout is 500ms. ### Parameters | Name | Type | Range | Usage | | ------------- | ------ | -------- | ---------------------- | | read_timeout | number | 1~2^32-1 | Rx timeout (In milliseconds) | | write_timeout | number | 1~2^32-1 | Tx timeout (In milliseconds) | ### Return value nil ### Example call ```lua tcp.setTimeout(1000,1000) --Set read & write timeout to 1000ms. ``` ## tcp.flushTx() ### Description Flush data in the Tx buffer. ### Parameters nil ### Return value nil ### Example call ```lua tcp.flushTx() ``` ## tcp.flushRx() ### Description Flush data in the Rx buffer. ### Parameters nil ### Return value nil ### Example call ```lua tcp.flushRx() ``` ## tcp.isOpen() ### Description Check if TCP port is allocated (This has nothing to do with the connection status of your host machine, it just makes sure you have opened the TCP module inside the meter). ### Parameters nil ### Return value | Name | Type | Range | Usage | | ---- | ------- | ---- | ---------- | | open | boolean | | Opened | ### Example call ```lua if(~tcp.isOpen()) then tcp.open() end ``` ## tcp.onReceived() ### Description Set the callback function when there is any data in the Rx buffer. ### Parameters | Name | Type | Range | Usage | | -------- | -------- | ---- | ------------ | | callback | function | | Specify the callback function | | [threshold] | number | | Specify the threshold on which the callback function should be called | ### Behaviour Set the callback function when there is any data in the Rx buffer. After which, once the data in the Rx buffer is equal or more than the `threshold`, the callback function is called. If no threshold is specified, the threshold is 1 byte as default. ### Hint You must call `tcp.read()` or `tcp.readAll()` somewhere in your callback function, or the callback function is called again and agian as the trigger condition always satisfies. ### Return value nil ### Example call ```lua function tcp_callback() tcp.write(tcp.readAll()) end tcp.open() tcp.onReceived(tcp_callback) ```