![]() | ![]() | ![]() | LCD display and clock |
### ### ### ### ### ### ### ###
# # # # # # # # # # # # # #
# # # # # # # # # # # # # #
# # # # # # # # # # # # # #
### ### ### ### ### ### ###
# # # # # # # # # # # # #
# # # # # # # # # # # # #
# # # # # # # # # # # # #
### ### ### ### ### ### ###
In this project we want to implement a clock that displays the time in LCD-format.
We will build up the project in small steps, one function at a time.
Let us number the seven segments from 0 to 6 as follows:
555 4 0 4 0 4 0 666 3 1 3 1 3 1 222
I have made a table which tells us which segment to turn on for each digit:
val digits = listOf(listOf(true, true, true, true, true, true, false), // 0 listOf(true, true, false, false, false, false, false), // 1 listOf(true, false, true, true, false, true, true), // 2 listOf(true, true, true, false, false, true, true), // 3 listOf(true, true, false, false, true, false, true), // 4 listOf(false, true, true, false, true, true, true), // 5 listOf(false, true, true, true, true, true, true), // 6 listOf(true, true, false, false, false, true, false), // 7 listOf(true, true, true, true, true, true, true), // 8 listOf(true, true, true, false, true, true, true), // 9 listOf(false, false, false, false, false, false, false)) // BlankFor example, digits(5) is a list of 7 Boolean's, telling us to switch on segments 1, 2, 4, 5, 6. Note the entry with index 10, which simply displays a blank.
Your first task is to write a function
fun lcdDigit(digit: Char, k: Int, c: Char): String {
// ...
}
This function takes a character digit and returns a string that
represents this character in LCD-format. k is the size of the
LCD-display, c is the character to be used for the LCD-display.
When digit is not a digit, the function should simply return a blank string. You can use the following code to convert digit to an index for the digits table:
val d = if ('0' <= digit && digit <= '9') digit - '0' else 10
Here are some examples for the output:
$ ktc
Welcome to Kotlin version 1.0.1-2 (JRE 1.7.0_101-b00)
Type :help for help, :quit for quit
>>> :load lcd1.kts
>>> lcdDigit('0', 2, '*')
**
* *
* *
* *
* *
**
>>> lcdDigit('4', 3, '&')
& &
& &
& &
&&&
&
&
&
>>> lcdDigit('9', 5, 'M')
MMMMM
M M
M M
M M
M M
M M
MMMMM
M
M
M
M
M
MMMMM
>>> lcdDigit('a', 3, 'M')
Note that the character 'a' is simply displayed as a blank.
Note that the function does not print the digit itself. It only returns a string. Since this string goes over several lines, it needs to contain the "new-line" character, which you can enter as \n. There should be no new-line character at the beginning and at the end of the output string.
Next we need a function that combines two digits:
fun combine(left: String, sep: String, right: String): String {
// ...
}
This function needs to split both left and right into pieces at the new-line characters. It then adds the pieces together, and finally generates a new string.
You can use s.split("\n") to split a string into a list of strings, and r.joinToString(separator = "\n") to compose a list of strings into a single long string.
Here are some examples:
>>> combine("This\nis\nfun", "&", "Hello\nCS109\nStudents!")
This&Hello
is&CS109
fun&Students!
>>> combine(lcdDigit('0', 3, '*'), " # ", lcdDigit('9', 3, '@'))
*** # @@@
* * # @ @
* * # @ @
* * # @ @
# @@@
* * # @
* * # @
* * # @
*** # @@@
Next, we need a function that takes a string and changes it to LCD-format. To save you some typing, here it is:
fun lcd(s: String, k: Int, c: Char, sep: String): String {
var result = lcdDigit(s[0], k, c)
for (i in 1 until s.length)
result = combine(result, sep, lcdDigit(s[i], k, c))
return result
}
Test the function and check that it works well:
>>> lcd("12:45:99", 4, '@', ":")
: @@@@ : : : @@@@ : : @@@@ : @@@@
@: @: :@ @:@ : :@ @:@ @
@: @: :@ @:@ : :@ @:@ @
@: @: :@ @:@ : :@ @:@ @
@: @: :@ @:@ : :@ @:@ @
: @@@@ : : @@@@ : @@@@ : : @@@@ : @@@@
@:@ : : @: @: : @: @
@:@ : : @: @: : @: @
@:@ : : @: @: : @: @
@:@ : : @: @: : @: @
: @@@@ : : : @@@@ : : @@@@ : @@@@
If you got the lcd-function working, there is nothing to stop us from implementing our clock. Since it's mostly special functions for obtaining and formatting the current time, I wrote it for you:
fun clearScreen() {
println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
}
fun clock() {
val form = java.text.SimpleDateFormat("HH mm ss")
var current = form.format(java.util.Calendar.getInstance().getTime())
clearScreen()
println(lcd(current, 4, '#', " "))
while (true) {
Thread.sleep(100)
val ntime = form.format(java.util.Calendar.getInstance().getTime())
if (ntime != current) {
current = ntime
clearScreen()
println(lcd(current, 4, '#', " "))
}
}
}
Note that it runs forever. You can stop it by typing Ctrl+C.
![]() | ![]() | ![]() | LCD display and clock |