Working on what is one of my first 'proper' projects, having done most of the beginner tutorial projects that come with the UNO kit; the aim is to create the foundations for a device that takes user bearing in relation to multiple locations around them (currently all hard-coded to check it works), and displays it through two LED's as a sortof 'warmer-colder' compass that blinks faster on their respective sides dependent on distance, and stronger dependant on the user's bearing.
Thus far I've managed to get one of the LED's working as expected: huzzah!
Punch in any coordinates into the array of three locationDistance[] & locationBearing[] variables, and the LED will blink to any three seperate inputs between 0 and 180 degrees similtanously, and with different strengths depdendent on how close it is to North(0).
const int locationNumber = 3; //the number of locations being tracked
int locationDistance[] = {712, 104, 1107}; //an array of distances between the user and the location
float locationBearing[] = {203, 172, 5}; //an array of bearings relative to the user
int userBearing = 0; //the hardcoded bearing of the user, which currently is set to North
int locationDelay[locationNumber]; //an array declaring the location distances as delays, not required but will be useful when substituting figures in future
int pulseTime = 100; //the amount of time to turn on per pulse
unsigned long previousMillis[locationNumber]; //the amount of time that has passed since the previous timed event
bool pulseLeftLED[locationNumber]; //stating whether the LED is currently pulsing for the given location
bool pulseRightLED[locationNumber]; //stating whether the LED is currently pulsing for the given location
int bearingStrengthLeft[locationNumber]; //an array declaring the strengths of the PWM outputs in the left pin
int bearingStrengthRight[locationNumber]; //an array declaring the strengths of the PWM outputs in the right pin
int bearingStrengthTotalLeft; //a variable declaring the aggregate strengths of all PWM outputs in the left pin array
int bearingStrengthTotalRight; //a variable declaring the aggregate strengths of all PWM outputs in the right pin array
void setup() {
Serial.begin (9600);
for (int thisLocation = 0; thisLocation < locationNumber; thisLocation++) {
pulseLeftLED[thisLocation] = false;
pulseRightLED[thisLocation] = false;
}
}
void loop() {
for (int thisLocation = 0; thisLocation < locationNumber; thisLocation++) { //creates the PWM signals per location in the right pin
bearingStrengthRight[thisLocation] = ((float(255) / 100) * (100 - (locationBearing[thisLocation] / 180) * 100));
if (bearingStrengthRight[thisLocation] <= 0) {
bearingStrengthRight[thisLocation] = 0;
}
bearingStrengthLeft[thisLocation] = ((float(255) / 100) * ((((locationBearing[thisLocation]) - 180) / 180) * 100)); //creates the PWM signals per location in each left pin
if (bearingStrengthLeft[thisLocation] <= 0) {
bearingStrengthLeft[thisLocation] = 0;
}
}
for (int thisLocation = 0; thisLocation < locationNumber; thisLocation++) {
unsigned long currentMillis = millis();
locationDelay[thisLocation] = locationDistance[thisLocation]; //currently a bit redundant, but will be added to in future
if ((currentMillis - previousMillis[thisLocation] >= pulseTime) && (pulseRightLED[thisLocation] == true)) { //check if its time to turn that particular pulse off
pulseRightLED[thisLocation] = !pulseRightLED[thisLocation]; //make the state of the pulse 'off'
bearingStrengthTotalRight = bearingStrengthTotalRight - bearingStrengthRight[thisLocation]; //minus the PWM value of that location from the aggregate, therby turning the pulse off
if (bearingStrengthTotalRight <= 0) { //stop the LED from going below 0
bearingStrengthTotalRight = 0;
}
previousMillis[thisLocation] = currentMillis; //remember the current time
analogWrite(9, bearingStrengthTotalRight); //write whatever aggregate value created from all the locations to the right pin
}
else if ((currentMillis - previousMillis[thisLocation] >= locationDelay[thisLocation]) && (pulseRightLED[thisLocation] == false)) { //check if its time to turn that particular pulse on
pulseRightLED[thisLocation] = !pulseRightLED[thisLocation]; //make the state of the pulse 'on'
bearingStrengthTotalRight = bearingStrengthTotalRight + bearingStrengthRight[thisLocation]; //add the PWM value of the location from the aggregate, thereby turning that pulse on
if (bearingStrengthTotalRight >= 255) { //stop the LED from going above 255
bearingStrengthTotalRight = 255;
}
previousMillis[thisLocation] = currentMillis; //remember the current time
analogWrite(9, bearingStrengthTotalRight); //write whatever aggregate value created from all the locations to the right pin
}
Serial.println (bearingStrengthTotalRight); //read the current PWM value in the right pin out
}
}
Here's the code if you wanted to have a look, its just an LED + resistor to Pin9.
Currently you should see two of the three bearings are within the 0-180 bracket, so you'd see two independent blinks of different strengths: indicating one location is close but behind you, and another is directly ahead but very far away!
However, as the code shows there's another LED for the left side, so for locations with a bearing of 180-360 degrees.
The script already has the PWM values figured out so that's fine, and I assume the code won't differ wildly from what I already have... but I've spent HOURS trying to figure out what order to logically shoehorn this other data in so that it doesn't mess up the counting or anything else in the sequence... thus far they all attempts totally cock up my current program (my guess is that I'm getting the 'for' & 'if' statement ordering wrong) and just copying the 'for' statement for the whole thing and replacing 'right' with 'left' causes all sorts of timing issues... which I suppose serves me right for doing it one LED at a time -_-
Everything's there, all the data is available but if anyone has any ideas on how I'd go about efficiently doing this for the leftLED I'd be tremendously grateful! (because my brain is F R I E D.)
All working well with the current locations, the rightLED should stay blinking as it is, but the leftLED should now also be blinking once every 700 millis with a PWM value of 28ish.
Many thanks and apologies if this is a bit of a slog, this is deep-end for a novice like me. ![]()