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 |