-
Notifications
You must be signed in to change notification settings - Fork 56
Description
I'm not sure how to propose edits to the wiki, but I have re-created the examples on the wiki in Kotlin, if you are interested in adding them. I haven't found a Kotlin-specific SerialPort library that isn't based on Android, so I figure all Kotlin users looking for a SerialPort will come here.
Following is my example code:
import jssc.*
import jssc.SerialPort.*
fun main() {
listPorts()
writeData()
readData()
eventListener()
}
// #List Ports
fun listPorts() {
val ports = SerialPortList.getPortNames()
ports.forEach { println(it) }
}
// #Write Data
fun writeData() {
val port = SerialPort("COM10")
port.openPort()
port.setParams(BAUDRATE_115200, DATABITS_8, STOPBITS_1, PARITY_NONE)
// port.setParams(9600, 8, 1, 0); // alternate technique
port.writeBytes("Testing serial from Kotlin".encodeToByteArray())
// The following shows up in the serial port (prettified for readability):
// 54 65 73 74 69 6E 67 20 73 65 72 69 61 6C 20 66 72 6F 6D 20 4B 6F 74 6C 69 6E
port.closePort()
}
// #Read Data
fun readData() {
val port = SerialPort("COM10")
port.openPort()
port.setParams(BAUDRATE_115200, DATABITS_8, STOPBITS_1, PARITY_NONE)
// port.setParams(9600, 8, 1, 0); // alternate technique
val buffer = port.readBytes(10 /* read the first 10 bytes */)
// Print the buffer but pretty, with spaces between bytes and padding to two characters with 0
// See below for implementation
println(buffer.fancyToString())
// Using the same bytes as used in the writeData() method above we get:
// 54 65 73 74 69 6E 67 20 73 65 72 69 61 6C 20 66 72 6F 6D 20 4B 6F 74 6C 69 6E
port.closePort()
}
// #Event Listener
fun eventListener() {
val port = SerialPort("COM10")
port.openPort()
port.setParams(BAUDRATE_115200, DATABITS_8, STOPBITS_1, PARITY_NONE)
// port.setParams(9600, 8, 1, 0); // alternate technique
val mask = MASK_RXCHAR + MASK_CTS + MASK_DSR
port.eventsMask = mask
port.addEventListener(MyPortListener(port))
}
/*
* In this class must implement the method serialEvent, through it we learn about
* events that happened to our port. But we will not report on all events but only
* those that we put in the mask. In this case the arrival of the data and change the
* status lines CTS and DSR
*/
internal class MyPortListener(private val port: SerialPort) :
SerialPortEventListener {
override fun serialEvent(event: SerialPortEvent) {
when {
event.isRXCHAR -> { // data is available
// read data, if 10 bytes available
if (event.eventValue == 10) {
try {
println(port.readBytes(10).fancyToString())
} catch (ex: SerialPortException) {
println(ex)
}
}
}
event.isCTS -> { // CTS line has changed state
if (event.eventValue == 1) { // line is ON
println("CTS - ON")
} else {
println("CTS - OFF")
}
}
event.isDSR -> { // DSR line has changed state
if (event.eventValue == 1) { // line is ON
println("DSR - ON")
} else {
println("DSR - OFF")
}
}
}
}
}
// Please note that Unsigned Integers are a stable feature in Kotlin version >= 1.5
// This is an extension function for ByteArrays to print them as unsigned hexadecimals
private fun ByteArray.fancyToString(): String {
var res = ""
// Converts each element from a signed byte to a unsigned byte
this.asUByteArray().forEach {
// Returns the bytes as two hexadecimals, separated by spaces per pair. Fills out the leading zero if necessary
res += it.toString(16).toUpperCase().padStart(2, '0').padEnd(3, ' ')
}
// And remove the trailing whitespace
return res.trim()
}I'm not sure how, in the original example, the MyPortListener class has access to the port, because I had to pass the port to it. It does work and prints reactively from the serial messages I'm sending to the relevant port. Otherwise, aside from the fancyToString method, this is basically an exact copy of the current examples on the wiki.
Feel free to disregard and/or close this issue if Kotlin is not applicable to this Repo, but I think there is at least some audience for SerialPorts in Kotlin, and this Repo seems the best/only option.