I am struggling to successfully write a program to get a LEDs to light up once a particular line tracker senses darkness. I have multiple LEDs on a board that I want to light up once the line tracker associated with it is triggered. Background: I have students who have made a skee ball game. When the ball falls through the hole the line tracker is triggered, and they want the LED above that hole to light up for 2 seconds and turn off. They want this is happen continuously each time the line trackers sense darkness. I’m new to teaching this, so helping them has been a struggle.
this is what I have so far for two of the lights, but it’s not working. Using VexCode Pro V5.
#include “vex.h”
using namespace vex;
int main() {
// Initializing Robot Configuration. DO NOT REMOVE!
int threshold=65;
vexcodeInit();
Use indents! I found a syntax error in your code just by adding the proper indents. Please look for it.
Code
#include “vex.h”
using namespace vex;
int main() {
// Initializing Robot Configuration. DO NOT REMOVE!
int threshold = 65;
vexcodeInit();
while (true) {
waitUntil(LineTrackerC.value(pct) < threshold);
LEDred.on();
wait(2, sec);
LEDred.off();
waitUntil(LineTrackerD.value(pct) < threshold);
LEDgreen.on();
wait(2,sec);
LEDgreen.off();
}
}
}
“It’s not working” does not help us help you. It doesn’t describe the problem in any way. We don’t know what errors to look for unless you give us some symtoms.
The LEDs will alternate which one lights up, which I think you don’t want. You see, it says
Yes, you are correct “not working is not helpful” and what you mention on #4 is correct. Any ideas on how to get the LED to light up only when the line tracker senses darkness, regardless of the order of which line trackers is sensed? Since its a game, the ball would fall in each hole randomly.
int greenCallback() { // Has to be int
while (true) {
// whatever
wait(20, msec);
}
}
int main() {
vex::task somethingRandom(greenCallback);
while (true) {
// whatever
wait(20, msec);
}
}
In general, you want to avoid blocking calls. No “waitUntil”.
The biggest problem with your task is this “happen continuously” requirement. There is no “continuously” in the digital world. Your sensors are sampled at limited rate and if that rate is too slow, you might easily miss the event.
For further discussion, it’s instrumental to look under the hood of waitUntil():
#define waitUntil(condition) \
do { \
wait(5, msec); \
} while (!(condition))
It doesn’t continuously monitor the sensor, but still samples it every 5ms.
You would need to do something similar, but with all sensors in parallel. No wait, everything somewhat event driven. What are you limited most on is the actual sample rate of the sensors. I don’t know off-hand what is the rate of the 3-wire port expander (that is how you attach your line trackers, right? The 8 3-ports on the brain are in fact presented by an expander, just onboard), but it certainly won’t be any faster than 200Hz.
So your code could be structured like this:
int main() {
// local variables describing the state:
// [...]
for(;;) {
// capture a timestap:
uint32_t now = vex::timer::system();
// evaluate the state of each line tracker. Like 8x:
// bool state1 = LineTrackerA.value(pct) < threshold;
// [...]
// decide which sensors were newly covered, turn on their LEDs and take a timestamp
// [...]
// like:
if (state1 && !state1_old) {LED1.on(); time1=now;}
// For sensors no longer covered, decide if the 2s has passed
// like:
if (!state1 && (now - time1 > 2000) { LED1.off(); }
// save the old state
state1_old = state1;
// the only wait in there
wait (5, msec);
}
}
You could simplify it if you don’t really care about the edges. Perhaps you want to do 2s from when it was uncovered again (so when it is continuously covered, the LED stays lit. But you’ll still need some state information to measure the 2s LED on time.
You should also better implement this with arrays and inner loop(s) over those many sensors (instead of copying the code N times).