State Modelling Homework
We now have a Yakindu License server. Many of you probably use the free trial. This will expire before the exam, so please try to get the license before doing this homework!
Acknowledgements: This project is adapted from this assignment by Hans Vangheluwe.
In this assignment, you will specify a statechart capturing the behavior of a digital watch, inspired by the 1981 Texas Instruments LCD Alarm Chronograph. The statechart must be designed and tested using Yakindu SCT. You are not required to write Java code, for this assignment is provided to you in a zip file containing an initial Yakindu project. In this project, the GUI code is ready to be plugged to the statechart. You are allowed to add only internal events and variables but not to modify the interfaces “Buttons”, “Display” or “LogicUnit”.
Requirements
- The time value should be updated every second, even when it is not displayed (as for example, when the chrono is running).
- Pressing the top right button turns on the background light. The light stays on for as long as the button remains pressed. From the moment the button is released, the light stays on for 2 more seconds, after which it is turned off.
- Pressing the top left button alternates between the chrono and the time display modes. The system starts in the time display mode. In this mode, the time (HH:MM:SS) and date (MM/DD/YY) are displayed.
- When in chrono display mode, the elapsed time is displayed MM:SS:FF (with FF hundredths of a second). Initially, the chrono starts at 00:00:00. The bottom right button is used to start the chrono. The running chrono updates in 1/100 second increments.
- Subsequently pressing the bottom right button will pause/resume the chrono.
- Pressing the bottom left button when the chrono is paused will reset the chrono to 00:00:00.
- Pressing the bottom left button when the chrono is running will reset the chrono to 00:00:00 and immediately restart it.
- The chrono will keep running (when in running mode) or keep its value (when in paused mode), even when the watch is in a different display mode (for example, when the time is displayed).
- Note: interactive simulation of a model containing time increments of 1/100 second is possible, but it is difficult to manually insert other events. Hence, while you are simulating your model, it is advisable to use larger increments (such as 1/4 second) for simulation purposes.
- When in time display mode, the watch will go into time editing mode when the bottom right button is held pressed for at least 1 second. In this mode, one of the fields of the time or the date is marked as “selected”. The currently selected field blinks while in edit mode (e.g. if the “hour” field is selected, it blinks).
- Initially, when the editing mode is entered, the “hour” field is selected.
- Briefly pressing the bottom-left button increases the value of the currently selected field (e.g. if the currently selected field is the “hour”, and the current value of the hour is 10, the value changes to 11). It is only possible to increase the value of the currently selected field; there is no way to decrease it – but when the value reaches its maximum value (e.g. hour = 23), then it moves back to the smallest value (i.e. hour = 0).
- If the bottom-left button is held down, the value of the currently selected field is incremented automatically every 0.25 seconds.
- The editing mode is exited if neither the bottom-left nor the bottom-right buttons are pressed during an interval of 5 seconds.
- Pressing the bottom-right button will change the “selected field” to the next one in the following order: from the “hour”, to the “minute” to the “second”, to the “month”, to the day, to the year and back to the “hour”.
- Time value should be increasing and updated every second even during editing.
- The selected field should blink with 250ms interval, i.e. it is hidden for 250ms and then displayed for 250ms, repeated.
To help clarify the requirements, you can find a working solution here: dwatch.jar (to run the demo use java -jar dwatch.jar
).
What to submit?
A zip file containing the Yakindu statechart digitalwatch.sct
as well as a document solution.pdf
explaining your solution.
- It must be possible to take your file and place it into my project and Yakindu should build it. This means that you may not change the public (non-internal) interface and the framework GUI code that we provide. (Students retaking this course must update their solutions to build against this year's interface.) If this requirement fails, you will get zero points (or very close to zero as we still give up to two points subjectively).
- The document must be a PDF file (Word is also accepted), describing your solution. The document should indicate the set of satisfied requirements, open issues, known bugs, etc. and the list of names of the team members. Ideally, this is a very short document because your design is clean and self-explanatory.
Grading
If your submission satisfies the above submission requirements, the solution will be graded as follows:
- One point for each of the following requirements: 1 and 2.
- Three points for chrono mode (requirement 4).
- Three points for time editing (requirement 5).
The grade for the above will based (almost) directly on the unit tests. We do not grade requirement 3 independently because changing mode is implicit in the rest of the requirements.
Additionally, we award two points for simplicity and readability of the overall solution. My solution has less than 20 states and uses only one internal variable (as in the stub). If you use significantly more states or variables, your solution is probably overly complicated.
Starting point
The dwatch.zip file provided to you contains a Yakindu project that implements the GUI. You can either run or test your project as follows:
- As the entry point for starting to launch the application, you must use the class
dwatch.Main
. The latter class sets up all the elements in the application (State machine, Timer Service, GUI controllers and views, etc.) and launches the simulation. - The Yakindu project also contains jUnit tests in the class
dwatch.DigitalWatchTest
. To run the tests, right click on the file DigitalWatchTest.java and select Run As → JUnit Test. If asked what tests to run, select the first option "DigitalWatchTest" to run all the tests.
The GUI and tests both assume an event-driven statechart (@EventDriven
), which is needed for accurate timekeeping and cycle-independent testing. The stub statechart file contains some silly logic, but it also contains some useful idioms that may come in handy for the real solution. We'll be using the Yakindu timer service, so this part of the docs may be useful.
The code provided to you is decomposed into three components exposing the following interfaces.
Interface Buttons:
This interface give a hook for the simulation to generate the events associated with the buttons in the watch. We distinguish the following events:
topRightPressed
andtopRightReleased
for the light switch.topLeftPressed
andtopLeftReleased
for the mode button.botRightPressed
andbotRightReleased
for start/paus chron) and time editing next.botLeftPressed
andbotRightReleased
for lap/reset chrono and time editing increment.
We follow Java terminology, so when you run the GUI, a mouse click triggers the press event when you push the mouse button down and release events when you let go.
Interface Display:
This interface exposes the functions associated with the watch display. Not that this interface defines only operations and no event. The list of operations supported is the following:
refreshTimeDisplay()
redraws the time with the current internal time and date values. The display does not need to be cleaned before calling this function. For instance, if the chrono is currently displayed, it will be deleted before drawing the time.refreshChronoDisplay()
. See refreshTimeDisplay()setIndiglo()
turns on the display background light.unsetIndiglo()
turns off the display background light.hidePos(pos: integer)
. This method allows you to hide a position (the positions range from 0 to 5, indicating hours, minutes, seconds, months, days, years). You will implement the blinking animation for the time editing mode by alternating between calls to this operation and refreshTimeDisplay.
Interface LogicUnit:
This interface exposes the behavior internal to the digital watch (e.g., time counting, date counting, etc.). The set of operations and their descriptions follows:
increaseTimeByOne()
increases the time by one second. Note how minutes, hours, days, month and year will be modified appropriately, if needed (for example, when increaseTimeByOne() is called at time 11:59:59, the new time will be 12:00:00).increaseChronoByOne()
increases the chrono time by 10 milliseconds. All the other parts, i.e., seconds, minutes, and hours will be updated accordingly.resetChrono()
resets the time count for the chrono.increasePos(pos: integer)
increases the given digit group's value by one (positions are the same as in hidePos above). This is what you will use to set the date and time!