Repository navigation
Add Kotlin examples #85
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.
Activity
tresf commentedon Apr 29, 2021
Thanks. Generally, the wiki can be directly edited and maintained by anyone. I'm not sure if the permissions are setup properly for this, so I've just committed them directly.
I've added your code verbatim via: https://github.com/java-native/jssc/wiki
I added a new page, then crosslinked to wiki/Home.
I didn't write this but rather copied it blindly from the upstream repo. We'll take a look and adjust accordingly.
Omnieboer commentedon Apr 29, 2021
Cool, thanks! If you need and/or want any further help, let me know ;)
tresf commentedon Apr 29, 2021
You're right, the example was wrong. I've fixed it here: https://github.com/java-native/jssc/wiki/Examples/_compare/c3412f125645151ad4378c32b5a8ae220ddda3c0...a1bb82fa756297846cf55d6c06fea8b2ac98e2c6.
It could technically work in the original example had
MyPortListenerbeen non-static AND if the package private variableportwere effectively final and internally referenced, but this is non-standard design. Your approach is much better. :)Omnieboer commentedon Apr 30, 2021
I have proposed another way to deal with this in #87 . I could also having an overload to allow for both options.