Week 13. Nov 13.17 2018 - michelle-qin/Portfolio GitHub Wiki
Working on making the beam turn off after 5 seconds AND having a user be able to turn it off anytime in between (i.e. user control overrides timer).
As for first part, I implemented a timer that worked for this purpose. See code below:
void timerIsr()
{
Serial.println("[debug] timer");
`if (!(--tick_count)) // Count to 2S`
`{`
`tick_count = TICK_COUNTS; // Reload`
`tick_2s_isr(); // Call the 2S routine`
`}`
`if (!(--tick_count1)) // Count to 2S`
`{`
`tick_count1 = TICK_COUNTS1; // Reload`
`tick_3s_isr(); // Call the 2S routine`
`}`
}
void tick_2s_isr()
{
Serial.println("[debug] timer 2s");
if (in_long_isr)
return;
in_long_isr = true;
volatile long i;
interrupts();
if (motorCount == false) {
turnOffBeam();
beamState = LOW;
beamCount = false;
}
noInterrupts();
in_long_isr = false;
}
void tick_3s_isr()
{
Serial.println("[debug] timer 3s");
if (in_long_isr)
return;
in_long_isr = true;
volatile long i;
interrupts();
if (motorCount == true) {
turnOffMotor();
motorState = LOW;
motorCount = false;
}
noInterrupts();
in_long_isr = false;
}
However, I noticed a problem with this code: it starts the timer irrelevant of the beam button. Say you want the beam to turn off at second 5. If you turn the beam on at second 4, it will only stay on for a second. We want the timer to be based off of the beam - i.e. timer initiated when beam is turned on.
To fix that, I worked with Wade to implement the code below:
if (beamState == HIGH)
{
startTime = millis();
endTime = startTime + 5000;
buttonPressed = true;
while (millis() < endTime)
{
`}`
`turnOffBeam();`
`beamState = LOW;`
`beamCount = false;`
}
That code works. Now, onto the second part of our goal - having the user control override the timer. This is a little bit trickier. Work in progress . . . Also noticed that the motor is kinda wonky now with the above implementation
Talked with Mr. Harlow and reorganized the project goals:
1. When the Motor Button is Pressed to turn ON
-turn on the motor
-start the timer
-check encoder - if moved, restart timer at new speed
-check user control - if motor button is pressed, turn off motor, reset encoder speed to 0, and stop timer
2. When the Beam Button is Pressed to turn ON
-turn on the beam
-start the timer
-check user control - if beam button is pressed, turn off beam and stop timer
3. Reset Encoder
-when motor is turned OFF, reset encoder to 0
There are some difficulties with step 2 part 3... A part of that is due to my lack of understanding of timers and timer interrupts. Proposed new approach: use external interrupts.
With the 11/9 version of Zoetrope pushed to GitHub, the code works in that:
- it allows user to control when to turn on/off button regardless of timer
- has a timer that turns off beam after a certain amount of time
Issue: 3) the timer does not start & end according to button press
Now, the timer works with the following features: turns on the beam, starts the timer, checks the user control, turns off timer when user control overrides
However, currently encountering some difficulties with encoder. It seems that as the encoder is being moved, it's possible the timer can go off and close the timer. This is clearly not ideal. I'm thinking about implementing code to turn off the timer and restart it each time the encoder is moved.