Skip to content

Commit

Permalink
Commenting
Browse files Browse the repository at this point in the history
  • Loading branch information
tscholze committed Mar 21, 2024
1 parent 9bafd46 commit 99cbeb5
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 238 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ Green: 918.0
Press any key to quit server
```

## Scheme

![Scheme](__docs/scheme.png)

## Keep in mind

### Calculations may be incorrect
Expand Down
Binary file added __docs/scheme.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 53 additions & 48 deletions src/nativeMain/kotlin/io/github/tscholze/kenviro/Enviro.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,64 +10,69 @@ import io.ktgp.use
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking


/**
* Pirmoroni Enviro pHAT wrapper class to start
* reading values from and writing values to
* [BMP280], [TCS3472] and [LEDs].
*/
class Enviro {
/**
* Runs the life cycle of the pHAT
*/
fun run() = runBlocking {

// Print greeting
println("""
# ------------------------------------------ #
# Kotlin Native + Raspberry Pi + Enviro pHAT #
# ------------------------------------------ #
""".trimIndent())

// Launch sensor readings
launch {
fun run() =
runBlocking {
// Print greeting
println(
"""
# ------------------------------------------ #
# Kotlin Native + Raspberry Pi + Enviro pHAT #
# ------------------------------------------ #
""".trimIndent(),
)

// Open GPIO connections
Gpio().use { gpio ->
// Create and access to the LEDs
val leds = LEDs(gpio)
// Launch sensor readings
launch {
// Open GPIO connections
Gpio().use { gpio ->
// Create and access to the LEDs
val leds = LEDs(gpio)

// Open I2c connection
I2c(1).use { i2c ->
// Create and access the BMP280
val bmp280 = BMP280(i2c)
val tcs3472 = TCS3472(i2c)
// Open I2c connection
I2c(1).use { i2c ->
// Create and access the BMP280
val bmp280 = BMP280(i2c)
val tcs3472 = TCS3472(i2c)

// Start server
val server = runServer(leds, bmp280, tcs3472)
// Start server
val server = runServer(leds, bmp280, tcs3472)

println("")
println("--- Environment reading START --")
println("Temperature (C°): ${bmp280.readTemperature()}")
println("Pressure (hPa): ${bmp280.readPressure()}")
println("Altitude (m): ${bmp280.readAltitude()}")
println("--- Sample reading END ----")
println("")
println("--- Ambient reading START --")
println("")
println("--- Environment reading START --")
println("Temperature (C°): ${bmp280.readTemperature()}")
println("Pressure (hPa): ${bmp280.readPressure()}")
println("Altitude (m): ${bmp280.readAltitude()}")
println("--- Sample reading END ----")
println("")
println("--- Ambient reading START --")

val rgb = tcs3472.readRGB()
println("Values in range of 0 to 255")
println("Red: ${rgb.red}")
println("Blue: ${rgb.blue}")
println("Green: ${rgb.clear}")
println("--- Ambient reading END ----")
println("")
// Present a closable action
println("Press any key to quit server")
readln()
val rgb = tcs3472.readRGB()
println("Values in range of 0 to 255")
println("Red: ${rgb.red}")
println("Blue: ${rgb.blue}")
println("Green: ${rgb.clear}")
println("--- Ambient reading END ----")
println("")
// Present a closable action
println("Press any key to quit server")
readln()

// Stop gracefully
server.stop()
bmp280.shutdown()
leds.shutdown()
println("Bye bye.")
// Stop gracefully
server.stop()
i2c.close()
gpio.close()
println("Bye bye.")
}
}
}
}
}
}
}
48 changes: 21 additions & 27 deletions src/nativeMain/kotlin/io/github/tscholze/kenviro/bmp280/BMP280.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import kotlin.math.pow

/**
* Represents an BMP280 chip manager.
* It allows the read temperature and pressure sensors
* It allows the read sensors for:
* - Temperature
* - Pressure
* - Altitude
*
*
* After usage the method [close] shall be called to clean up I2C usage.
*
* @param i2c I2C Controller to access pins.
* @param i2c I2C manager to access pins.
*/
class BMP280(private var i2c: I2c) {
// MARK: - Private properties -
Expand All @@ -32,20 +32,21 @@ class BMP280(private var i2c: I2c) {
}

// Get calibration information for sensors
calibration = CalibrationInformation(
device.read(REGISTER_DIGIT_TEMPERATURE_1, 2U).toInt() and 0xffff,
device.read(REGISTER_DIGIT_TEMPERATURE_2, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_TEMPERATURE_3, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_1, 2U).toInt() and 0xffff,
device.read(REGISTER_DIGIT_PRESSURE_2, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_3, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_4, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_5, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_6, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_7, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_8, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_9, 2U).toInt().toShort()
)
calibration =
CalibrationInformation(
device.read(REGISTER_DIGIT_TEMPERATURE_1, 2U).toInt() and 0xffff,
device.read(REGISTER_DIGIT_TEMPERATURE_2, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_TEMPERATURE_3, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_1, 2U).toInt() and 0xffff,
device.read(REGISTER_DIGIT_PRESSURE_2, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_3, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_4, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_5, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_6, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_7, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_8, 2U).toInt().toShort(),
device.read(REGISTER_DIGIT_PRESSURE_9, 2U).toInt().toShort(),
)
}

// MARK: - Getters -
Expand Down Expand Up @@ -115,13 +116,6 @@ class BMP280(private var i2c: I2c) {
return part1 * part2
}

// MARK: - System -

fun shutdown() {
print("Shutting down BMP280")
i2c.close()
}

// MARK: - Companion -

companion object {
Expand Down Expand Up @@ -191,4 +185,4 @@ class BMP280(private var i2c: I2c) {
/** QNH value of Munich, Bavaria, Germany. */
private const val QNH_MUNICH = 1018
}
}
}
14 changes: 2 additions & 12 deletions src/nativeMain/kotlin/io/github/tscholze/kenviro/led/LEDs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@ import io.ktgp.gpio.PinState
* Represents two LEDs besides the tcs3472 sensor.
* It allows to illuminate the environment.
*
*
* After usage the method [close] shall be called to clean up I2C usage.
*
* @param gpio Gpio Controller to access pins.
* @param gpio Gpio manager to access pins.
*/
class LEDs(gpio: Gpio) {

// MARK: - Private properties -

private val output = gpio.output(4)
Expand All @@ -33,10 +29,4 @@ class LEDs(gpio: Gpio) {
fun turnOff() {
output.setState(PinState.LOW)
}

// MARK: - System -

fun shutdown() {
output.close()
}
}
}
117 changes: 13 additions & 104 deletions src/nativeMain/kotlin/io/github/tscholze/kenviro/server/Server.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("ktlint:standard:no-wildcard-imports")

package io.github.tscholze.kenviro.server

import io.github.tscholze.kenviro.bmp280.BMP280
Expand All @@ -11,23 +13,26 @@ import io.ktor.server.response.*
import io.ktor.server.routing.*
import platform.posix.exit


/**
* Starts and runs the embedded server.
*
* @param leds LEDs manager
* @param bmp280 BMP280 chip manager
* @param tcs3472 TCS3472 chip manager
*/
fun runServer(leds: LEDs, bmp280: BMP280, tcs3472: TCS3472): ApplicationEngine {
fun runServer(
leds: LEDs,
bmp280: BMP280,
tcs3472: TCS3472,
): ApplicationEngine {
return embeddedServer(CIO, port = 8080) {
routing {
// Listen to GET requests on root
get("/") {
println("Request: Index")
call.respondText(
contentType = ContentType.Text.Html,
text = generateIndexContent(bmp280, tcs3472)
text = generateIndexContent(bmp280, tcs3472),
)
}

Expand All @@ -47,9 +52,6 @@ fun runServer(leds: LEDs, bmp280: BMP280, tcs3472: TCS3472): ApplicationEngine {

post("shutdown") {
println("Request: Shutdown")
leds.shutdown()
bmp280.shutdown()

call.respond(HttpStatusCode.OK)
exit(0)
}
Expand All @@ -63,12 +65,15 @@ fun runServer(leds: LEDs, bmp280: BMP280, tcs3472: TCS3472): ApplicationEngine {
* @param bmp280 BMP280 manager to render it's values.
* @return Populated html template string.
*/
private fun generateIndexContent(bmp280: BMP280, tcs3472: TCS3472): String {
private fun generateIndexContent(
bmp280: BMP280,
tcs3472: TCS3472,
): String {
val temperature = bmp280.readTemperature()
val pressure = bmp280.readPressure()
val altitude = bmp280.readAltitude()
val rgb = tcs3472.readRGB()
val bright = if(rgb.clear > 215) "Yes" else "No"
val bright = if (rgb.clear > 215) "Yes" else "No"

return template
.replace("{{temperature}}", temperature.toString().cutToTwoDecimals())
Expand Down Expand Up @@ -96,99 +101,3 @@ private fun String.cutToTwoDecimals(): String {

return substring(0, endIndex)
}

/**
* In Kotlin Native, you cannot load Ktor content from
* `resources`, to have a simple template string was the
* best of the worse.
*/
private val template = """
<html lang="en">
<head>
<title>KPi - Enviro</title>
<script>
let xhr = new XMLHttpRequest();
function turnOn() {
xhr.open("POST", "/ledon");
xhr.send()
}
function turnOff() {
xhr.open("POST", "/ledoff");
xhr.send()
}
function shutdown() {
xhr.open("POST", "/shutdown");
xhr.send()
}
</script>
</head>
<body>
<h1>Kotlin Native Enviro</h1>
<div style="width: 300px">
<fieldset>
<legend>Light switch</legend>
<button onclick="turnOn()">On</button>
<button onclick="turnOff()">Off</button>
</fieldset>
<fieldset>
<legend>Environment properties</legend>
<table>
<tr>
<td>Temperature</td>
<td>{{temperature}} C°</td>
</tr>
<tr>
<td>Pressure</td>
<td>{{pressure}} hPa</td>
</tr>
<tr>
<td>Altitude</td>
<td>{{altitude}} m</td>
</tr>
</table>
</fieldset>
<fieldset>
<legend>Ambient</legend>
<table>
<tr>
<td>Red</td>
<td>{{Red}}</td>
<td>Clear</td>
<td>{{Clear}}</td>
</tr>
<tr>
<td>Green</td>
<td>{{Red}}</td>
<td>Is bright?</td>
<td>{{Bright}}</td>
</tr>
<tr>
<td>Blue</td>
<td>{{Blue}}</td>
<td>Color</td>
<td>
<div style='background-color: rgb({{Red}},{{Green}},{{Blue}}); height:14px; width:14px;'>
&nbsp;
</div>
</td>
</tr>
</table>
</fieldset>
<fieldset>
<legend>System</legend>
<button onclick="shutdown()">Shutdown</button>
</fieldset>
</div>
<p>Try it, maybe it will explode.</p>
</body>
</html>
""".trimIndent()
Loading

0 comments on commit 99cbeb5

Please sign in to comment.