Variable question - way to code 'all variables except' ? (using []?) [Solved]

Howdy,

I have a ping distance sensor, and I'm simply (ha?) trying to have a RED led light up if X distance away, YELLOW led light up if another distance, and a GREEN led if another distance away. So far, I have this code:

// Example 45.1 - tronixstuff.com - CC by-sa-nc
// Connect Ping))) signal pin to Arduino digital 8

const int signal = 3;
const int redLED = 8;
const int yellowLED = 9;
const int greenLED = 10;

int whichLED;

int distance, indistance;
unsigned long pulseduration=0;
void setup()
{
// pinMode(signal, OUTPUT);
 Serial.begin(9600);
 pinMode(redLED,OUTPUT);
 pinMode(yellowLED, OUTPUT);
 pinMode(greenLED, OUTPUT);
 
}
void measureDistance()
{
 // set pin as output so we can send a pulse
 pinMode(signal, OUTPUT);
 digitalWrite(signal, LOW);
 delayMicroseconds(5);

 digitalWrite(signal, HIGH);
 delayMicroseconds(5);
 digitalWrite(signal, LOW);

 pinMode(signal, INPUT);

 pulseduration=pulseIn(signal, HIGH);
}
void loop()
{
 measureDistance();

 pulseduration=pulseduration/2; 

 distance = int(pulseduration/29);
 indistance = distance*.39;
 
  if (indistance < 10){
   whichLED = redLED;
 }
  if (indistance >11 && indistance < 30){
   whichLED = yellowLED;
 } 
 if (indistance > 31){
   whichLED = greenLED;
 }

  digitalWrite(whichLED, HIGH);
//  digitalWrite([the other two LEDs], LOW);   THIS IS WHAT I'M TRYING TO FIGURE OUT ....

 // Display on serial monitor  
   Serial.print("Distance - ");
   Serial.print(distance);
   Serial.print(" cm ");
   Serial.print(indistance);
   Serial.print(" in.    LED lit up is ");
   Serial.println(whichLED);

 delay(500);
}

This works - almost. When it starts, I have my green one lit up, since the distance to the nearest object is greater than 31 inches. However, when I put something in the YELLOW and RED range, the LEDs stay lit up.

How would I code it so the other two LEDs go LOW? I have seen code before using variables like
int specialVar[3]; but am not sure what to look up to learn about that - would that work?

Does my question make sense? I am basically looking for a way to do

digitalWrite(whichLED, HIGH);
digitalWrite(the other inputs that aren't whichLED, LOW);

so if whichLED is 'redLED' (or 8 ),
digitalWrite([9,10], LOW);

Thanks for any help or ideas!

[Edit: Solved, thanks to BulldogLowell and here for code using "variable pass"]

I don't read the post with to much care, but from what I understand, you need to make that array:

int specialVar[3];

and then inside a for loop you may turn ON or OFF the outputs that you like.

int turnON = 2;

for (int i=0; i<3; i++) {
   if (i==turnON) {
      digitalWrite(specialVar[i], HIGH);
   }
   else {
      digitalWrite(specialVar[i], LOW);
   }
}

Just turn off all three and then turn on whichled

It will happen so fast you won't be able to tell

also, what colour do you want when the distance returns 10, 11, 30 or 31?

look at this alternate approach, I used an array and the ternary operator...

compiles but not tested

const int ledPin[3] = {8,9,10};
const int signal = 3;
int whichLED;

int distance, indistance;
unsigned long pulseduration=0;
void setup()
{
  // pinMode(signal, OUTPUT);
  Serial.begin(9600);
  for(int i = 0; i < 3; i++)
  {
    pinMode(ledPin[i],OUTPUT);
  }
}
//
void measureDistance()
{
  // set pin as output so we can send a pulse
  pinMode(signal, OUTPUT);
  digitalWrite(signal, LOW);
  delayMicroseconds(5);
  digitalWrite(signal, HIGH);
  delayMicroseconds(5);
  digitalWrite(signal, LOW);
  pinMode(signal, INPUT);
  pulseduration=pulseIn(signal, HIGH);
}
//
void loop()
{
  measureDistance();
  pulseduration=pulseduration/2; 
  distance = int(pulseduration/29);
  indistance = distance*.39;//<<<<<<<<<<< you want a float here?  you initialized as an int 
  if (indistance <= 10)
  {
    whichLED = ledPin[0];
  }
  else if (indistance >= 11 && indistance <= 30)//<<<<<<<<< note the changes to capture the distances you missed
  {
    whichLED = ledPin[1];
  } 
  else if (indistance >= 31)
  {
    whichLED = ledPin[2];
  }
  for (int i = 0; i < 3; i++)
  {
    digitalWrite(ledPin[i], (ledPin[i] == whichLED)? HIGH: LOW);
  }
  Serial.print("Distance - ");
  Serial.print(distance);
  Serial.print(" cm ");
  Serial.print(indistance);
  Serial.print(" in.    LED lit up is ");
  Serial.println(whichLED);
  delay(500);
}

BulldogLowell:
also, what colour do you want when the distance returns 10, 11, 30 or 31?

look at this alternate approach, I used an array and the ternary operator...

compiles but not tested

const int ledPin[3] = {8,9,10};

const int signal = 3;
int whichLED;

int distance, indistance;
unsigned long pulseduration=0;
void setup()
{
  // pinMode(signal, OUTPUT);
  Serial.begin(9600);
  for(int i = 0; i < 3; i++)
  {
    pinMode(ledPin[i],OUTPUT);
  }
}
//
void measureDistance()
{
  // set pin as output so we can send a pulse
  pinMode(signal, OUTPUT);
  digitalWrite(signal, LOW);
  delayMicroseconds(5);
  digitalWrite(signal, HIGH);
  delayMicroseconds(5);
  digitalWrite(signal, LOW);
  pinMode(signal, INPUT);
  pulseduration=pulseIn(signal, HIGH);
}
//
void loop()
{
  measureDistance();
  pulseduration=pulseduration/2;
  distance = int(pulseduration/29);
  indistance = distance*.39;//<<<<<<<<<<< you want a float here?  you initialized as an int
  if (indistance <= 10)
  {
    whichLED = ledPin[0];
  }
  else if (indistance >= 11 && indistance <= 30)//<<<<<<<<< note the changes to capture the distances you missed
  {
    whichLED = ledPin[1];
  }
  else if (indistance >= 31)
  {
    whichLED = ledPin[2];
  }
  for (int i = 0; i < 3; i++)
  {
    digitalWrite(ledPin[i], (ledPin[i] == whichLED)? HIGH: LOW);
  }
  Serial.print("Distance - ");
  Serial.print(distance);
  Serial.print(" cm ");
  Serial.print(indistance);
  Serial.print(" in.    LED lit up is ");
  Serial.println(whichLED);
  delay(500);
}

That works! Thanks so much - I'll review what you have there and learn about the array variables. Thanks a lot :grin:

Now that it works you could tidy up your program a bit more by making the measureDistance() function do what its name implies. Put all of the code that calculates distance in the function so that by the time it has run distance is set to the target distance.

For extra points have the function calculate the distance and return it to the main program rather than setting a global variable. Not strictly necessary but good to learn the technique.

On a similar note, save space by changing several variables from ints to bytes when you know that there value cannot exceed 255.

UKHeliBob:
Now that it works you could tidy up your program a bit more by making the measureDistance() function do what its name implies. Put all of the code that calculates distance in the function so that by the time it has run distance is set to the target distance.

For extra points have the function calculate the distance and return it to the main program rather than setting a global variable. Not strictly necessary but good to learn the technique.

On a similar note, save space by changing several variables from ints to bytes when you know that there value cannot exceed 255.

Thanks for the ideas - I'll get into working this out tomorrow and post any results/questions I have. Thanks!

UKHeliBob:
Now that it works you could tidy up your program a bit more by making the measureDistance() function do what its name implies. Put all of the code that calculates distance in the function so that by the time it has run distance is set to the target distance.

For extra points have the function calculate the distance and return it to the main program rather than setting a global variable. Not strictly necessary but good to learn the technique.

On a similar note, save space by changing several variables from ints to bytes when you know that there value cannot exceed 255.

Okay - I have made some changes to my code and if you have a second, I appreciate any thoughts!

First, I added the Serial print part to its own function, to more easily turn on/off.

Second, I changed the 'indistance' variable to a Float variable. You noted I could change those variables which won't exceed 255 to bytes. Can you have a FLOAT variable also be a BYTE to save space? (Does that make sense?) Also, did you suggest FLOAT since the FLOAT type is more precise than INT?

Third, I believe I did what you were saying by "Put all of the code that calculates distance in the function so that by the time it has run distance is set to the target distance. ", if you/someone could confirm.

Here's the code:

const int ledPin[3] = {9,10,11};
const int signal = 3;
int whichLED;

int distance;
float indistance;
unsigned long pulseduration=0;

void setup() {
  // pinMode(signal, OUTPUT);
  Serial.begin(9600);
  for(int i = 0; i < 3; i++) {
    pinMode(ledPin[i],OUTPUT);
  }
}
//
void measureDistance()
{
  // set pin as output so we can send a pulse
  pinMode(signal, OUTPUT);
  digitalWrite(signal, LOW);
  delayMicroseconds(5);
  digitalWrite(signal, HIGH);
  delayMicroseconds(5);
  digitalWrite(signal, LOW);
  pinMode(signal, INPUT);
  pulseduration=pulseIn(signal, HIGH) / 2;
  // pulseduration=pulseduration/2; 
  distance = int(pulseduration/29);
  indistance = distance*.39;   //<<<<<<<<<<< changed 'indistance' to FLOAT 
}

void printDistances(){
  Serial.print("Distance - ");
  Serial.print(distance);
  Serial.print(" cm / ");
  Serial.print(indistance);
  Serial.print(" in.    LED lit up is ");
  Serial.println(whichLED);
}

void loop() {
  measureDistance();
  
  if (indistance <= 10) {
    whichLED = ledPin[0];
  }
  else if (indistance >= 11 && indistance <= 30) {
    whichLED = ledPin[1];
  } 
  else if (indistance >= 31) {
    whichLED = ledPin[2];
  }
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPin[i], (ledPin[i] == whichLED)? HIGH: LOW);
  }
  
  printDistances();
  delay(500);
}

What I couldn't figure out is how to do the "extra points" by returning a value to main program, instead of setting a global variable. Thanks for any more hints/advice!

Piethon:
Can you have a FLOAT variable also be a BYTE to save space?

No. An 8 bit float would hardly be usable in just about any application.

Piethon:
What I couldn't figure out is how to do the "extra points" by returning a value to main program, instead of setting a global variable. Thanks for any more hints/advice!

Hint... it will end up looking like this...

void setup()
{
  Serial.begin(9600);
  int distance = measureDistance();// you are telling it to go get a value and assign it to distance, an int 
  Serial.print(distance);
}

void loop()
{
  
}

int measureDistance()  // you will return what???  yes, an int
{
  // calculate your distance
  // come up with an answer
  int theAnswer = 431; // my example
  // and return the answer
  return theAnswer; // and here is the int you will return!!!
}

BulldogLowell:

Piethon:
What I couldn't figure out is how to do the "extra points" by returning a value to main program, instead of setting a global variable. Thanks for any more hints/advice!

Hint... it will end up looking like this...

void setup()

{
  Serial.begin(9600);
  int distance = measureDistance();// you are telling it to go get a value and assign it to distance, an int
  Serial.print(distance);
}
...

Hm, I think I am on the path, but get an error:

const int ledPin[3] = {9,10,11};
const int signal = 3;
int whichLED;

int distance;
unsigned long pulseduration=0;

void setup() {
  // pinMode(signal, OUTPUT);
  Serial.begin(9600);
  for(int i = 0; i < 3; i++) {
    pinMode(ledPin[i],OUTPUT);
  }
  
}


void loop() {
  int indistance = measureDistance();  // added this in the loop, because if I do so in setup, it'll only get indistance once, correct?
  if (indistance <= 10) {
    whichLED = ledPin[0];
  }
  else if (indistance >= 11 && indistance <= 30) {
    whichLED = ledPin[1];
  } 
  else if (indistance >= 31) {
    whichLED = ledPin[2];
  }
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPin[i], (ledPin[i] == whichLED)? HIGH: LOW);
  }
  
  printDistances();
  delay(500);
}

int measureDistance(){
  // set pin as output so we can send a pulse
  pinMode(signal, OUTPUT);
  digitalWrite(signal, LOW);
  delayMicroseconds(5);
  digitalWrite(signal, HIGH);
  delayMicroseconds(5);
  digitalWrite(signal, LOW);
  pinMode(signal, INPUT);
  pulseduration=pulseIn(signal, HIGH) / 2;
  // pulseduration=pulseduration/2; 
  distance = int(pulseduration/29);
  int inches = distance*.39;  // EDITED THIS PART 
  return inches;
}

void printDistances(){
  Serial.print("Distance - ");
  Serial.print(distance);
  Serial.print(" cm / ");
  Serial.print(indistance);  // ERROR: 'indistance' was not declared in this scope
  Serial.print(" in.    LED lit up is ");
  Serial.println(whichLED);
}

If I comment out the line "Serial.print(indistance);" then it works. But how come that variable isn't defined, when distance is? They both come from the 'int measureDistance' part...

I think I'm missing some understanding....

now you get to learn how to pass a variable into a function!!!

const int ledPin[3] = {9,10,11};
const int signal = 3;
int whichLED;

int distance;
unsigned long pulseduration=0;

void setup() {
  // pinMode(signal, OUTPUT);
  Serial.begin(9600);
  for(int i = 0; i < 3; i++) {
    pinMode(ledPin[i],OUTPUT);
  }
  
}


void loop() {
  int indistance = measureDistance();  // added this in the loop, because if I do so in setup, it'll only get indistance once, correct?
  if (indistance <= 10) {
    whichLED = ledPin[0];
  }
  else if (indistance >= 11 && indistance <= 30) {
    whichLED = ledPin[1];
  } 
  else if (indistance >= 31) {
    whichLED = ledPin[2];
  }
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPin[i], (ledPin[i] == whichLED)? HIGH: LOW);
  }
  
  printDistances(indistance);
  delay(500);
}

int measureDistance(){
  // set pin as output so we can send a pulse
  pinMode(signal, OUTPUT);
  digitalWrite(signal, LOW);
  delayMicroseconds(5);
  digitalWrite(signal, HIGH);
  delayMicroseconds(5);
  digitalWrite(signal, LOW);
  pinMode(signal, INPUT);
  pulseduration=pulseIn(signal, HIGH) / 2;
  // pulseduration=pulseduration/2; 
  distance = int(pulseduration/29);
  int inches = distance*.39;  // EDITED THIS PART 
  return inches;
}

void printDistances(int myDistance){
  Serial.print("Distance - ");
  Serial.print(distance);
  Serial.print(" cm / ");
  Serial.print(myDistance);  // ERROR: 'indistance' was not declared in this scope
  Serial.print(" in.    LED lit up is ");
  Serial.println(whichLED);
}

EDIT: whoops, I use a variable you declared as global...

BulldogLowell:
now you get to learn how to pass a variable into a function!!!

const int ledPin[3] = {9,10,11};

const int signal = 3;
int whichLED;

int distance;
unsigned long pulseduration=0;

void setup() {
 // pinMode(signal, OUTPUT);
 Serial.begin(9600);
 for(int i = 0; i < 3; i++) {
   pinMode(ledPin[i],OUTPUT);
 }
 
}

void loop() {
 int indistance = measureDistance();  // added this in the loop, because if I do so in setup, it'll only get indistance once, correct?
 if (indistance <= 10) {
   whichLED = ledPin[0];
 }
 else if (indistance >= 11 && indistance <= 30) {
   whichLED = ledPin[1];
 }
 else if (indistance >= 31) {
   whichLED = ledPin[2];
 }
 for (int i = 0; i < 3; i++) {
   digitalWrite(ledPin[i], (ledPin[i] == whichLED)? HIGH: LOW);
 }
 
 printDistances(indistance);
 delay(500);
}

...

void printDistances(int myDistance){
...
 Serial.print(myDistance);  // ERROR: 'indistance' was not declared in this scope
 Serial.print(" in.    LED lit up is ");
 Serial.println(whichLED);
}

YES! I knew I was forgetting something - I have seen that before, and only briefly used/learned about it. Passing variables is still a little confusing to me, but will have to spend more time with it. Thanks so much!

Why though, briefly, would it be better to use the above code, instead of a global variable (which I was using at the beginning)? Is it because it makes the code more easily "portable" or easier to read? Is it so I don't have the same variable "hanging out all over the place", so if I want to edit the stuff later, I have fewer places to edit?

Thanks again for all of your help and guidance! :grin: :grin:

Piethon:
Why though, briefly, would it be better to use the above code, instead of a global variable (which I was using at the beginning)? Is it because it makes the code more easily "portable" or easier to read? Is it so I don't have the same variable "hanging out all over the place", so if I want to edit the stuff later, I have fewer places to edit?

yes, yes, yes and yes.

once you have your own library of functions, you will use them over and over and over (many thousands of times per second in many cases!)

plus Functions start with Fun! :blush:

BulldogLowell:

Piethon:
Why though, briefly, would it be better to use the above code, instead of a global variable (which I was using at the beginning)? Is it because it makes the code more easily "portable" or easier to read? Is it so I don't have the same variable "hanging out all over the place", so if I want to edit the stuff later, I have fewer places to edit?

yes, yes, yes and yes.

once you have your own library of functions, you will use them over and over and over (many thousands of times per second in many cases!)

plus Functions start with Fun! :blush:

Hahaha :smiley:

Thanks again for your help!

Okay - I have made some changes to my code and if you have a second, I appreciate any thoughts!

I think that everything I would have commented on has been covered.

For a simple program using functions and passing variables back and forth is an overhead but they are good tools to have in the locker for larger projects in the future. Functions provide a method of avoiding the need to repeat common code and judicious naming of functions and variables can help enormously in understanding a program especially when you go back to it after a period of time.

Now, I wonder, can we find a reason to use pointers in your program and really up the ante ? :slight_smile:

UKHeliBob:

Okay - I have made some changes to my code and if you have a second, I appreciate any thoughts!

I think that everything I would have commented on has been covered.

For a simple program using functions and passing variables back and forth is an overhead but they are good tools to have in the locker for larger projects in the future. Functions provide a method of avoiding the need to repeat common code and judicious naming of functions and variables can help enormously in understanding a program especially when you go back to it after a period of time.

Now, I wonder, can we find a reason to use pointers in your program and really up the ante ? :slight_smile:

I looked up pointers, and apparently they can be tough to learn for the beginner programmer. However, I want to learn as much as I can and am going to jump in. However, to help guide me - what would pointers do in this case to help? Are they just further good practice/good code to help clarify things? Or are there some more powerful aspects I should be keen on learning?

I haven't found too much, so would be open to any websites/lessons on pointers. I am starting here for now...

However, to help guide me - what would pointers do in this case to help?

Nothing as far as I can see. It was my little joke, hence the :slight_smile:

UKHeliBob:

However, to help guide me - what would pointers do in this case to help?

Nothing as far as I can see. It was my little joke, hence the :slight_smile:

Haha, and I got all excited to learn something new =(

...but I'll learn it anyways! :smiley: