Skip to content

Commit

Permalink
Merge pull request #5 from Pi4J/release/2.3.0
Browse files Browse the repository at this point in the history
Release/2.3.0
  • Loading branch information
mhashim6 authored Dec 28, 2022
2 parents 7880cac + 7072cab commit ed1be0e
Show file tree
Hide file tree
Showing 12 changed files with 503 additions and 3 deletions.
79 changes: 79 additions & 0 deletions .run/Test.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!--
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<!--
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<!--
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<!--
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName"/>
<option name="externalProjectPath" value="$PROJECT_DIR$"/>
<option name="externalSystemIdString" value="GRADLE"/>
<option name="scriptParameters" value=""/>
<option name="taskDescriptions">
<list/>
</option>
<option name="taskNames">
<list>
<option value=":lib:check"/>
</list>
</option>
<option name="vmOptions"/>
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2"/>
</configuration>
</component>
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
}

val libVersion by extra("2.2.1.2")
val libVersion by extra("2.3.0")

group = "com.pi4j"
version = libVersion
Expand Down
4 changes: 3 additions & 1 deletion example/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ repositories {

dependencies {
// implementation(project(":lib"))
implementation("com.pi4j:pi4j-ktx:2.2.1.2")
implementation("com.pi4j:pi4j-ktx:2.3.0")
implementation("com.pi4j:pi4j-core:2.2.1")
implementation("com.pi4j:pi4j-plugin-raspberrypi:2.2.1")
implementation("com.pi4j:pi4j-plugin-pigpio:2.2.1")
implementation("com.pi4j:pi4j-plugin-linuxfs:2.2.1")
implementation("com.pi4j:pi4j-plugin-mock:2.2.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
implementation("org.slf4j:slf4j-api:1.7.32")
implementation("org.slf4j:slf4j-simple:1.7.32")
testImplementation(kotlin("test"))
Expand Down
66 changes: 66 additions & 0 deletions example/src/main/kotlin/CoroutinesExample.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import com.pi4j.io.gpio.digital.DigitalState
import com.pi4j.io.gpio.digital.PullResistance
import com.pi4j.ktx.console
import com.pi4j.ktx.io.digital.digitalInput
import com.pi4j.ktx.io.digital.digitalOutput
import com.pi4j.ktx.io.digital.onLow
import com.pi4j.ktx.io.digital.piGpioProvider
import com.pi4j.ktx.pi4jAsync
import kotlinx.coroutines.delay

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

private const val PIN_BUTTON = 24 // PIN 18 = BCM 24
private const val PIN_LED = 22 // PIN 15 = BCM 22
private var pressCount = 0

/**
* This application blinks a led and counts the number the button is pressed. The blink speed increases with each
* button press, and after 5 presses the application finishes.
*
* This example fully describes the basic usage of Pi4J-Kotlin + Coroutines
*
* @author Muhammad Hashim (mhashim6) (<a href="https://mhashim6.me">https://mhashim6.me</a>)
*/
fun main() {
pi4jAsync {
console {
digitalInput(PIN_BUTTON) {
id("button")
name("Press button")
pull(PullResistance.PULL_DOWN)
debounce(3000L)
piGpioProvider()
}.onLow {
pressCount++
+"Button was pressed for the ${pressCount}th time"
}

digitalOutput(PIN_LED) {
id("led")
name("LED Flasher")
shutdown(DigitalState.LOW)
initial(DigitalState.LOW)
piGpioProvider()
}.run {
while (pressCount < 5) {
+"LED ${state()}"
toggle()
delay(500L / (pressCount + 1))
}
}
}
}
}
85 changes: 85 additions & 0 deletions example/src/main/kotlin/I2CExample.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import com.pi4j.ktx.console
import com.pi4j.ktx.io.i2c
import com.pi4j.ktx.io.linuxFsI2CProvider
import com.pi4j.ktx.io.setPin
import com.pi4j.ktx.pi4j
import com.pi4j.ktx.utils.binStr
import java.lang.Thread.sleep

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


private const val TCA9534_REG_ADDR_OUT_PORT: Int = 0x01
private const val TCA9534_REG_ADDR_CFG: Int = 0x03

/**
* @author Muhammad Hashim (mhashim6) (<a href="https://mhashim6.me">https://mhashim6.me</a>) on 28/12/2022
*/
fun main() {
pi4j {
i2c(1, 0x3f) {
id("TCA9534")
linuxFsI2CProvider()
}.use { tca9534Dev ->
val config = tca9534Dev.readRegister(TCA9534_REG_ADDR_CFG)
check(config >= 0) {
"Failed to read configuration from address 0x${"%02x".format(TCA9534_REG_ADDR_CFG)}"
}

var currentState = tca9534Dev.readRegister(TCA9534_REG_ADDR_OUT_PORT)
if (config != 0x00) {
println(
"TCA9534 is not configured as OUTPUT, setting register 0x${"%02x".format(TCA9534_REG_ADDR_CFG)} to 0x00"
)
currentState = 0x00
tca9534Dev.writeRegister(TCA9534_REG_ADDR_OUT_PORT, currentState)
tca9534Dev.writeRegister(TCA9534_REG_ADDR_CFG, 0x00)
}

tca9534Dev.run {
// bit 8, is pin 1 on the board itself, so set pins in reverse:
console {
currentState = setPin(currentState, 8, TCA9534_REG_ADDR_OUT_PORT)
+"Setting TCA9534 to new state ${currentState.binStr()}"
sleep(500L)
currentState = setPin(currentState, 8, TCA9534_REG_ADDR_OUT_PORT, false)
+"Setting TCA9534 to new state ${currentState.binStr()}"
sleep(500L)
currentState = setPin(currentState, 7, TCA9534_REG_ADDR_OUT_PORT)
+"Setting TCA9534 to new state ${currentState.binStr()}"
sleep(500L)
currentState = setPin(currentState, 7, TCA9534_REG_ADDR_OUT_PORT, false)
+"Setting TCA9534 to new state ${currentState.binStr()}"
sleep(500L)
}
}
}
}

}
1 change: 1 addition & 0 deletions lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies {
compileOnly("org.slf4j:slf4j-api:1.7.32")
testImplementation("org.slf4j:slf4j-api:1.7.32")
compileOnly("org.slf4j:slf4j-simple:1.7.32")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
testImplementation("org.slf4j:slf4j-simple:1.7.32")
testImplementation(kotlin("test"))
}
Expand Down
29 changes: 28 additions & 1 deletion lib/src/main/kotlin/com/pi4j/ktx/Context.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import com.pi4j.context.ContextBuilder
import com.pi4j.io.IO
import com.pi4j.platform.Platform
import com.pi4j.provider.Provider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import java.io.File
import java.io.InputStream
import java.io.Reader
Expand All @@ -33,26 +37,31 @@ import java.util.*
annotation class ContextBuilderMarker

@ContextBuilderMarker
class KontextBuilder: ContextBuilder by ContextBuilder.newInstance() {
class KontextBuilder : ContextBuilder by ContextBuilder.newInstance() {
operator fun Platform.unaryPlus() {
add(this)
}

operator fun Provider<out Provider<*, *, *>, out IO<*, *, *>, out Config<*>>?.unaryPlus() {
add(this)
}

operator fun Properties.unaryPlus() {
add(this)
}

operator fun Pair<String, String>.unaryPlus() {
addProperty(this.first, this.second)
}

operator fun File.unaryPlus() {
addProperties(this)
}

operator fun Reader.unaryPlus() {
addProperties(this)
}

operator fun InputStream.unaryPlus() {
addProperties(this)
}
Expand All @@ -70,6 +79,24 @@ inline fun pi4j(block: Context.() -> Unit): Context {
return context
}

/**
* Coroutine variant of [pi4j]
*
* Creates a new [Context] using [Pi4J.newAutoContext] and uses it in execution.
* Automatically calls [Context.shutdown] after [block] execution
* @param scope within which the coroutines will run
* @param block runs on a [Context] Receiver
*/
fun pi4jAsync(scope: CoroutineScope = CoroutineScope(Dispatchers.IO), block: suspend Context.() -> Unit): Context {
return runBlocking {
pi4j {
scope.async {
block()
}.await()
}
}
}

inline fun buildContext(builder: KontextBuilder.() -> Unit): Context {
return KontextBuilder().run {
builder.invoke(this)
Expand Down
Loading

0 comments on commit ed1be0e

Please sign in to comment.