Groups
You can work in groups of two on this assignment.
Pair Programming
It is strongly recommended that you use formal “pair programming”, where one person (the driver) types/creates and the other (the navigator) observes/assists. Moreover, you should alternate roles so each person takes on each role for a roughly equal amount of time. Remember that a spokesperson will be designated at checkout time, so both group members need to be comfortable presenting the work.
Repositories
Before configuring a repository, decide if you will be working in a group or not. If you will be working in a group, decide who will create the GitHub group and who will join it.
Follow the same basic process used in studios and previous assignments to create/join a group, download the resulting repository (with GitHub Desktop), and import it using the Particle Desktop IDE.
The GitHub Link is: https://classroom.github.com/g/FiS6UK9u
Files in your repository:
The repository currently contains a few files:
src/GarageController.ino
should be filled to include the main logic and state machine to control the garage door.
lib/GarageHardware/src/GarageHardwareProxy.cpp
contains empty functions that you will need to fill in according to the comments preceding each function and their TODO statements
- You should not add any extra functions in this file, but only edit the contents of the existing functions, leaving the function signature unchanged.
lib/GarageHardware/src/GarageHardware.h
: This contains the declarations for the Hardware API used by the real hardware. These represent a contract between the hardware team and you. DO NOT MODIFY THEM.
lib/GarageHardware/src/GarageHardwareReal.cpp
: This contains the definitions for the Hardware API for real hardware. DO NOT MODIFY THEM.
README.md
contains some questions you need to complete when you are done with the assignment
lib/GarageHardware/HardwareCheckoutSteps.md
: This contains the directions you need to follow to switch between the hardware checkout with the mini-garage and using your proxy hardware.
documentation/contents.md
: This contains a description of the files that should be included in the documentation
directory when you’re done.
Finite State Machine Review
This assignment will require you to design a state machine to control the behavior of a garage door. This should be review from CSE132. If you need a refresher, see the CSE132 Prep Material on Finite State Machines, which actually includes a FSM diagram of a simpler garage door opener and/or the CSE132 “Introduction to Finite State Machines”. If you carefully design the state machine first, the actual implementation of it should be relatively straightforward.
Circuit Diagrams
This assignment will also require you to build your circuit virtually in an application called Fritzing (download here). Once you open the application, you can go to the Breadboard tab and start assembling your circuit. You can find the Photon if you use the search tool on the right sidebar labeled Parts.
- Once you’ve finished building your circuit on Fritzing, please print out a screenshot of it and draw arrows to specify which buttons and LEDs correspond with specific functionality (i.e. show which button is the fault button, etc.)
- Please bring this with you to your demo
Your (Third) Assignment
DBI has decided on the basic elements of the hardware and has specified a set of routines you can use to interact with it. As long as you develop your work using identical stubs, you should be able to control a real door. The basic door system will have a number of inputs and outputs:
Inputs
- Button: a wall-mounted push button. If the door is open, it should start to close. If the door is closed, it should start to open. If the door is opening/closing and the button is pressed again, the door should stop. If the door is stopped in an intermediate state and the button is pressed, the door should start either opening or closing (the opposite of whatever it was doing last).
- Closed Switch: This switch is triggered when the door is all the way closed (down).
- Open Switch: This switch is triggered when the door is all the way open (up).
- Fault Signal: This is an indicator that something has gone wrong. It could indicate a problem with the motor or something/someone obstructing the door.
Outputs
- Motor: There will be a motor that moves the door.
- Light: The door has a light bulb. This can be used for both illumination of the garage and to indicate an error or problem with the door.
The hardware team has developed an API and they will ensure that all their systems work well with the API. You will have to create your own implementations within stubs of these functions to demonstrate your work. When the hardware team has completed their work, you will compile your code other code with implementations that work with the actual hardware.
Implementation Requirements
- You should use hardware to provide a satisfying demonstration that your code works. It should provide a clear understanding of the door’s behavior.
- Required Hardware:
- Four buttons (or use of wires to
3V
/ GND
to simulate button)
- One to mimic the button to open and close the garage door (described above)
- One to mimic the Open Switch (described above)
- One to mimic the Closed Switch (described above)
- One to mimic a Fault Signal (described above)
- Three LEDs
- One to represent the door opening
- One to represent the door closing
- One as the garage light (described above)
- Door Behavior:
- When the door is down, the open/close button makes the door go up.
- When the door is up, the open/close button makes the door go down.
- Pressing the open/close button while the door is in motion should stop the door within 200ms of the button being pressed. The next press should make the door go in the opposite direction.
- If a fault is detected, all motion to the door should be stopped within 200ms from when the fault occurred (from when the fault button was pressed).
- When the door starts moving, it should only stop if:
- there is a fault (the fault button is pressed)
- it encounters one of the sensors that indicates it has hit the end of its motion (open switch button or closed switch button), or
- the open/close button has been pressed again
- Light Behavior:
- The garage light should come on whenever the door moves and should stay on until the door has fully opened, fully closed, or stopped in the middle due to pressing of the open/close button.
- Once the door is in one of these three states, the garage light will gently fade out over the course of 5s. You should use the function
setLightPWM()
to implement this part (not setLight()
).
- When a fault is detected, the light should not only fade out over 5s, but a call should be made to
sendDebug(String)
with the message “fault”.
- Miscellaneous:
- The open/close button needs to be held for more than 100ms before the door responds to it (i.e. debounced). The door should start responding by 150ms.
- i.e. it should not do anything for at least 100ms, but should then start moving within 50ms more. Continuing to hold the button should have no additional impact. So, it isn’t necessary to release the button to impact the door’s action.
- The door has hard limits on its motion. If either the open or closed switch is activated, the door’s motion should stop within 200ms from when the switch was triggered, otherwise either the motor or mechanical components of the door will be damaged.
- You should use
const int
to define constants for any pins used, and all pin references should be grouped together immediately above the setupHardware()
function.
- Nothing from your
GarageController.ino
should be directly interacting with the hardware, but instead you should be calling functions declared in GarageHardware.h
(and defined in GarageHardwareProxy.cpp
), which will interact with the hardware.
Suggested Work Flow
- Design and revise a state machine diagram.
- Consider testing your state machine without hardware or possibly on another platform that is easier to deploy code to and/or has better debugging facilities than the Photon. For example, you could test your work on an Arduino or write a Java version to verify your logic.
- Plan your circuit (perhaps using paper or just rearranging parts via Fritzing).
- When you start building your circuit, carefully test each piece of hardware independently, either by using a different program to test each or by gradually adding in new hardware support one at a time to test your program. Implement and test the required Hardware API.
- Integrate your State Machine with the hardware.
- Think carefully about ways to test and demonstrate that you meet the various timing constraints.
- Make or complete your Fritzing diagram, print it out, and label it.
Hints
- Think very carefully about how you can test the timing constraints. A constraint like “within Xms of Y” does not mean “within Xms of code detecting Y”. Think about way you can prove that you meet the requirements.
- Debouncing can be important, but it isn’t always required. Think carefully about whether inputs really require debouncing.
- When using the normal, default settings, blocking code will cause the Photon to disconnect from Wi-Fi, which also causes the code to freeze and will require a reset to be able to reprogram the Photon. Avoid blocking code!
- Eventually your code will be tested on a real mini garage.
- Take a look at the actual garage design to understand how things will look and how the mechanics work behind the scenes
Artifacts that are Due
- State Machine Diagram. This can be drawn with the tool of your choice. Some free options include Draw.io and the Finite State Machine Designer.
- Include a png, jpg, or pdf in the
documentation
folder of your repository.
- Fritzing circuit diagram
- Include the
.fzz
file in the documentation
folder of your repository.
- Include a PNG of the breadboard view in the
documentation
folder of your repository (File > Export > as Image > PNG
).
- A working circuit to demonstrate behavior.
- Completed versions of
GarageController.ino
and GarageHardwareProxy.cpp
.
- Completed
README.md
.
Tentative Rubric
Door Behavior (42 points)
- door closes until closed sensor/button is hit (6 points)
- door opens until opened sensor/button is hit (6 points)
- door stops when a fault is detected while opening (6 points)
- door stops when a fault is detected while closing (6 points)
- pressing open/close button while door is in motion stops the door (6 points)
- pressing open/close button while door is stopped from opening closes the door (3 points)
- pressing open/close button while door is stopped from closing opens the door (3 points)
- pressing fault while door is opened does not do anything (2 points)
- pressing fault while door is closed does not do anything (2 points)
- pressing fault while door is stopped does not do anything (2 points)
Light Behavior (12 points)
- light comes on whenever door starts opening or closing (even from stopped state) (4 points)
- light stays on until the door is fully opened, fully closed, or stopped in the middle by fault or button press (2 points)
- once door is fully opened, fully closed, or stopped in the middle from fault or open/close button press, the light fades off over the course of 5s (6 points)
Miscellaneous (32 points)
- Finite State Machine corresponds to implementation (4 points)
- Finite State Machine Diagram is clear and well explained (5 points)
- Fritzing circuit diagram is clear and corresponds to actual circuit (2 points)
- the required hardware was used (4 buttons/wires & 3 LEDs) (2 points)
- all Input/Output functionality is contained within
GarageHardwareProxy.cpp
(3 points)
GarageController.ino
does not directly interact with the hardware
GarageHardwareProxy.cpp
functions follow the original specifications (3 points)
- debounce the open/close button for 100ms (5 points)
- this deals with the
isButtonPressed()
function
- other buttons are not debounced (2 points)
- the other buttons besides the open/close button do not need to be debounced
- continuing to hold button after open/close doesn’t have any further effect (6 points)
Best Practices (14 points)
- quality of code organization (5 points)
- code is non blocking (4 points)
- uses Timer instead of
delay()
- completion of
README.md
(5 points)
Demo
The video below shows an example of the behavior of the simulated garage door (includes audio narration).
Submission & Checkout
As outlined in the course policies, you must commit work to GitHub and demo it by class time on the due date for full credit.
You need to be prepared to demo and explain your work during your checkout as well as answer the questions in the README.md
. (The final checklist may help verify that you are ready to demo)
Checkout and review will be done on a first-come-first-serve basis. If you aren’t done before class, you risk not being able to check out during class time. Work demoed after class time is considered late and will either not count as a grade or will consume late day coupons.