Week 15. Nov 26.30 2018 - michelle-qin/Portfolio GitHub Wiki

To clarify, the problem with the beam timer is this: When a user interrupts the beam timer (i.e. while the beam is on, a user presses the button to turn the beam off), the timer does NOT restart. This leads to an error because the next time a user turns the light on, the timer will be inconsistent (i.e. timer is currently set to 10 seconds. When a user interrupts the beam timer, the timer is not reset to 10 and will change to a different value).

The beam timer alone (i.e. without any user interruption whatsoever) works. When the beam turns on, 10 seconds will pass and then it will turn off automatically.

I worked with a mentor, Joe, to figure this out today. We specifically looked at the method for the timer, pasted below:

void timerIsr() { Serial.print("[debug] time "); Serial.println(i);

i++;

if (!(--tick_count)) // Count to 10S { tick_count = TICK_COUNTS; // Reload tick_2s_isr(); // Call the 2s routine }

if (!(--tick_count1)) // Count to 30S { tick_count1 = TICK_COUNTS1; // Reload tick_3s_isr(); // Call the 3s routine } }

When the beam light is turned on with method "TurnOnBeam()", it calls "Timer1.initialize(timerIsr)."

What we realized was that this part of the if loop if (!(--tick_count)) decrements. tick_count is initialized to 100 as a global variable and it is the time that the timer is set for Thus, the first time it reaches that if loop, it will read if (!(99)), then ...

So, when a user interrupts the beam light when it's on, it doesn't end up going through that if loop, and it doesn't end up reading that statement, tick_count = TICK_COUNTS; So, tick_count doesn't initialize to 10 seconds, and that's why it becomes inconsistent. To fix this, I simply added that statement to turnOnBeam(), so that each time the beam is turned on, it resets the timer to 10 seconds.

I implemented the same timer for the motor, following similar structure and logic.

Also, each time the encoder is moved while the motor or beam is moved, I want to restart the timer. To do this, I added the statements tick_count = TICK_COUNTS; tick_count1 = TICK_COUNTS1; to the method that updates or checks the potentiometer value, filterPotVal(). Implemented as follows:

void filterPotVal() { // allows the limitless potentiometer to work without "overflowing" back to zero int newPotVal = analogRead(A0);

if (abs(newPotVal - prevPotVal) > overflowThreshold) { if (prevPotVal > overflowThreshold) outputVal = min(outputVal + 1, maxOutputVal); else outputVal = max(outputVal - 1, 0); }

else if (abs(newPotVal - prevPotVal) > filterThreshold) { Serial.println("[debug] potentiometer2"); tick_count = TICK_COUNTS; tick_count1 = TICK_COUNTS1; i = 0; if (newPotVal > prevPotVal) outputVal = min(outputVal + 1, maxOutputVal); else outputVal = max(outputVal - 1, 0);

`prevPotVal = newPotVal;`

}

Finally, another feature that I wanted to implement was resetting the encoder. Each time the motor is turned off, I want to reset the encoder/potentiometer value to 0 so it starts back at the slowest pace, instead of picking up on the last value.

To fix this, I added statements in turnOffMotor() to reset the potentiometer value. Essentially, I took the statements that were declared globally to initialize the potentiometer and wrote them into turnOffMotor(), see below:

void turnOffMotor() { digitalWrite(MOTOR_BUTTON_LIGHT, LOW); stepper.disableStepper(); Serial.println("[debug] turnOffMotor() off"); Timer1.stop(); Serial.println("[debug] timer motor stops"); turnOffBeam(); beamState = LOW; beamCount = false; i = 0; potVal = 0; lastPotVal = 0; outputVal = 0; }

Noticed that with this setup, overlapping timers causes a problem. Since there is only 1 timer, and it is used for both beam and motor, when both the beam and motor and turned on, it causes issues (e.g. motor could stop at the 30 second mark as it's supposed to, but the beam would stay on forever).

To fix this, I worked with Mr. Harlow and Ken to try to implement a second timer. After some research, we realized that there is no "Timer2", but there is a "Timer3" that we can use with arduino. Thus, we downloaded a zip file similar to Timer1 (the initial timer that we have currently implemented) for Timer3 that has the same methods and such. I included the TimerThree.h library into the arduino file. I changed some of the print lines to differentiate "timer for motor" and "timer for beam" rather than simply "timer". Also, included a new variable that resets the new timer. Now, it seems to be working. When motor is turned on, any button press from the beam will reset the timer for both timers so they can work together. When motor is turned off, the beam will turn off after its timer.

Began documenting the code, and pushed new version of code to GitHub.