Blinking diodes

hello
i am pretty green and a newbie in arduino coding, and most of this code is written with the help of google, so i really hope you can help me out here.
i have an arduino project with 2 diodes, an infrared distance sensor and a toggle switch. When i have the system in a mode where the diodes should light up, instead of turning on, they blink quite fast. i can see on the serial monitor that it changes between ex. mode 1 and 2 or 3 and 4. mode 1 makes the "upPin" led turn on until the distance sensor feels an obstacle, when the obstacle sensor feels an obstacle that is mode 2. when the switch is activated it goes to mode 3 and 4. when the obstacle sensor feels an obstacle it turns "downPin" led. when the obstacle is gone the led turns of.
the code looks like this.


#define SWITCH_PIN 13 // this is the toggle switch i use
int upPin = 9; // this is led no.1
int downPin = 10; // this is led no.2
int obstaclePin = 3; // this is the obstacle sensor

void setup() {
  pinMode(SWITCH_PIN, INPUT_PULLUP);
  Serial.begin(9600);
  pinMode(upPin, OUTPUT);
  pinMode(downPin, OUTPUT);
  pinMode(obstaclePin, INPUT);
}

void loop() {
  digitalRead(SWITCH_PIN) ? doModeOneStuff() : doModeTwoStuff();
 int hasObstacle = digitalRead(obstaclePin);
}

void doModeOneStuff() {
  int hasObstacle = digitalRead(obstaclePin);
  if (hasObstacle == HIGH){
  Serial.println("Mode 1, kører op");
  digitalWrite(upPin, HIGH);
  digitalWrite(downPin, LOW);
  }
  if (hasObstacle == LOW);
  Serial.println("Mode 2, stopper bord");
  digitalWrite(upPin, LOW);
  digitalWrite(downPin, LOW);
  
}
void doModeTwoStuff() {
  int hasObstacle = digitalRead(obstaclePin);
  if (hasObstacle == LOW) {
  Serial.println("Mode 3, kører ned");
  digitalWrite(upPin, LOW);
  digitalWrite(downPin, HIGH);
  }
  if (hasObstacle == HIGH);
  Serial.println("Mode 4, stopper bord");
  digitalWrite(upPin, LOW);
  digitalWrite(downPin, LOW);
  
}

it's time to read about scope

(not your issue though - just a thought)

1 Like

thanks, i'll read about it.
you say that the line of code you included in your answer needs this scope thing?

well the line I included from the loop is useless. You'll see why if you read about scope.

how does your distance sensor work ? does it need a pullup ?
how is you switch wired?

Read about scope of variables then count how many different variables named hasObstacle are in your sketch and what the scope of each is

i've read about scope, but i dont really understand how to incoperate it in my code, or why the line is useless. any help, tips or tricks?
the distance sensor is like the one in this link. i dont think it needs a pullup, but it worked fine on another code i used. Infrared Obstacle Avoidance Sensor Module - FC-51
my switch is wired between 5v power and pin 13. the switch is working correctly i would say, because i can change

i've read about scope. i guess i have 4 different variables. what do you mean about "what the scope of each is"?

As you will have read, each variable has a scope in which its value is available

So, when you declare a variable like this

   int hasObstacle = digitalRead(obstaclePin);

in a function then its value is only available in that function, ie in its scope. Declaring a variable with the same name in a different function, which is what you do, creates a different variable with a different scope and value that is unrelated to the first one

One way round this is to declare the variable just once near the start of the sketch but outside of a function, much as you do with the obstaclePin variable, for instance. This makes the variable and its value available anywhere in the sketch. It is said to have global scope.

Then, later in the sketch you use the already declared variable like this

    hasObstacle = digitalRead(obstaclePin);

Note that as the variable name is not preceded by a type declaration such as int, then a new variable is not being declared and the global variable will be used

Summary
Declare a global variable named hasObstacle and use it throughout the sketch

There may well be other problems but this will solve some of teh major ones

okay, so to be sure. i delete the lines where the

int hasObstacle = digitalRead(obstaclePin);

is, is that correct? and then just keep the one at the top of void loop?
and do i keep the

if (hasObstacle == HIGH)

or not?

thank you

No

Declare hasObstacle as a global variable at the start of the sketch

int hasObstacle;

Then anywhere in the sketch that you need to save its value do this

hasObstacle = digitalRead(obstaclePin);

Anywhere that you want to test its value do this

if (hasObstacle == HIGH)

i have declared it as a global variable
i have a

has0bstacle = digitalread(obstaclePin);

in each of the modes like before, just without the "int"
then i have

if (has0bstacle == HIGH)

right after the digitalRead.
there is no difference in the way the circuit is working. so im doubting that i did it how you mean?

Hello fklauber

Welcome to the worldbest Arduino forum ever.

I assume that you have written the programme by yourself, then it is quite easy to find the error.

There's a trick to figuring out why something isn't working:

Use a logic analyzer to see what happens.
Put Serial.print statements at various places in the code to see the values of variables, especially ones that control the LEDs, and determine whether they meet your expectations.

Hello
thank you
i have written the programme by myself, but with a bit of help from google.
i have Serial.print statements together with my 4 modes. when it is in mode 1 or 3, it blinks the led, and i can see in the serial monitor that it just changes extremely fast between mode 1 and 2, or mode 3 and 4. but when i activate it in such a way that it is in mode 2 or 4 it works as expected.
i have posted a youtube video about it now, to clarify what i mean. if you look in the beginning when i record the serial monitor, you can see it jumping between the modes. and mode 1 turns on the led, mode 2 turns off the led

Please post your sketch as it is now

ohh hey, i figured out why it didn't work as i wanted it. i was missing some { } between some parts of the code. so now the code looks like this

#define SWITCH_PIN 13
int upPin = 9;
int downPin = 10;
int obstaclePin = 3;
 
void setup() {
  pinMode(SWITCH_PIN, INPUT_PULLUP);
  Serial.begin(9600);
  pinMode(upPin, OUTPUT);
  pinMode(downPin, OUTPUT);
  pinMode(obstaclePin, INPUT);
}
 
void loop() {
  digitalRead(SWITCH_PIN) ? doModeOneStuff() : doModeTwoStuff();
  int hasObstacle = digitalRead(obstaclePin);
}
 
void doModeOneStuff() {
  int hasObstacle = digitalRead(obstaclePin);
  if (hasObstacle == HIGH) {
    Serial.println("Mode 1, kører op");
    digitalWrite(upPin, HIGH);
    digitalWrite(downPin, LOW);
  }
  if (hasObstacle == LOW) {
 
    Serial.println("Mode 2, stopper bord");
    digitalWrite(upPin, LOW);
    digitalWrite(downPin, LOW);
  }
}
void doModeTwoStuff() {
  int hasObstacle = digitalRead(obstaclePin);
  if (hasObstacle == LOW) {
    Serial.println("Mode 3, kører ned");
    digitalWrite(upPin, LOW);
    digitalWrite(downPin, HIGH);
  }
  if (hasObstacle == HIGH) {
    Serial.println("Mode 4, stopper bord");
    digitalWrite(upPin, LOW);
    digitalWrite(downPin, LOW);
  }
}

thank you all for your help

I see that you decided not to take the advice about creating a global variable. This is good news and bad news

Good news : it is good programming practice to declare variables in the scope of say a function, which is what you have done, but only if their value is only needed in that scope, which in this case it is

Bad news : by using the same variable name with different scopes it can become confusing as to which variable is being used. Take for instance the hasObstacle variable declared in loop(). Why did you do that ?

If you have problems with curly brackets (which can also limit the scope of a variable) then you may find it useful to format your code with each of them on its own line like this

#define SWITCH_PIN 13
int upPin = 9;
int downPin = 10;
int obstaclePin = 3;

void setup()
{
    pinMode(SWITCH_PIN, INPUT_PULLUP);
    Serial.begin(9600);
    pinMode(upPin, OUTPUT);
    pinMode(downPin, OUTPUT);
    pinMode(obstaclePin, INPUT);
}

void loop()
{
    digitalRead(SWITCH_PIN) ? doModeOneStuff() : doModeTwoStuff();
    int hasObstacle = digitalRead(obstaclePin);
}

void doModeOneStuff()
{
    int hasObstacle = digitalRead(obstaclePin);
    if (hasObstacle == HIGH)
    {
        Serial.println("Mode 1, kører op");
        digitalWrite(upPin, HIGH);
        digitalWrite(downPin, LOW);
    }
    if (hasObstacle == LOW)
    {
        Serial.println("Mode 2, stopper bord");
        digitalWrite(upPin, LOW);
        digitalWrite(downPin, LOW);
    }
}
void doModeTwoStuff()
{
    int hasObstacle = digitalRead(obstaclePin);
    if (hasObstacle == LOW)
    {
        Serial.println("Mode 3, kører ned");
        digitalWrite(upPin, LOW);
        digitalWrite(downPin, HIGH);
    }
    if (hasObstacle == HIGH)
    {
        Serial.println("Mode 4, stopper bord");
        digitalWrite(upPin, LOW);
        digitalWrite(downPin, LOW);
    }
}

Note how each code block stands out when formatted like this

Incidentally, instead of

void doModeOneStuff()
{
    int hasObstacle = digitalRead(obstaclePin);
    if (hasObstacle == HIGH)
    {
        Serial.println("Mode 1, kører op");
        digitalWrite(upPin, HIGH);
        digitalWrite(downPin, LOW);
    }
    if (hasObstacle == LOW)
    {
        Serial.println("Mode 2, stopper bord");
        digitalWrite(upPin, LOW);
        digitalWrite(downPin, LOW);
    }
}

you could do this

void doModeOneStuff()
{
    if (digitalRead(obstaclePin) == HIGH)
    {
        Serial.println("Mode 1, kører op");
        digitalWrite(upPin, HIGH);
        digitalWrite(downPin, LOW);
    }
    else  //if it is not HIGH then it must be LOW so no need to test it
    {
        Serial.println("Mode 2, stopper bord");
        digitalWrite(upPin, LOW);
        digitalWrite(downPin, LOW);
    }
}

There is nothing wrong with assigning the result of digitalRead() to a variable but the function is neater written like this and in any case you do not need the else. There are ways of making the function even neater but going too far can obscure how it works if you are not careful

3 Likes

that semi colon was an issue indeed !

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.