3

I have a circuit connected as follows enter image description here

my limit switches which are attached to my structure sometimes gets falsely triggered, so I wrote this code to address it. My motor is supposed to go down skip the up limit switch at first hit the down one then go back to the up one. is this a good way to implement it? https://pastebin.com/qVU1Gp0q

//Switch pressed ->  reading HIGH
//Switch not pressed -> reading LOW
//Motor direction 0 is down, 1 is up

const int uplimit = 32;
const int downlimit = 34;
const int motorspeed = 9;
const int motordirection = 28;
//const int pumpspeed=5;
//const int pumpdirection=6;
const int motorenable = 26;
//const int pumpenable=;
int Finishedcleaning = 0;
int Reachedup = 0;
int Motorinitialsetup = 0;
int Motorsecondsetup = 0;
int downfiltered = 0;
int upfiltered = 0;
void setup() {
  // put your setup code here, to run once:

  pinMode(motorspeed, OUTPUT);
  pinMode(motordirection, OUTPUT);
  pinMode(motorenable, OUTPUT);
  //pinMode(pumpspeed, OUTPUT);
  //pinMode(pumpenable, OUTPUT);
  pinMode(uplimit, INPUT);
  pinMode(downlimit, INPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
  int average1 = 0;
  int average2 = 0;
  if (Motorinitialsetup == 0 ) // to be run before hitting initial switch
  { digitalWrite(motorenable, HIGH);
    analogWrite(motorspeed, 190);
    digitalWrite(motordirection, 0); // Bring motor down
    //   digitalWrite(pumpenable,HIGH);
    //  digitalWrite(pumpdirection,1);
    // analogWrite(pumpspeed,240);
    Motorinitialsetup = 1; //so this if statement does not run again

  }

  for (int i = 1; i < 100; i++)
  { downfiltered = digitalRead(downlimit);
    average1 = average1 + downfiltered;
  }
  average1 = average1 / 100;

  if ((average1 > 0.9) && Finishedcleaning == 0 ) // Function after hitting down switch
  {
    delay(1000); // wait until motor cross switch
    analogWrite(motorspeed, 0); // stop motor
    Finishedcleaning = 1; //indicate cleaning is over for next loop
    delay(500); // wait until motor cross switch
  }

  if ( (Finishedcleaning == 1) &&   (Reachedup == 0)  && (Motorsecondsetup == 0))
  {
    digitalWrite(motordirection, 1); // reverse motor direction
    analogWrite(motorspeed, 190); // start motor again
    Motorsecondsetup = 1;
  }


  if ( Motorsecondsetup == 1) // only checks switch up switch after motors comes back
  {

    for (int i = 1; i < 300; i++)
    { upfiltered = digitalRead(downlimit);
      average2 = average2 + downfiltered;

    }
    average2 = average2 / 300;
    if ((average2 > 0.9) && (Finishedcleaning == 1)) // Stop Motor after returning
    { analogWrite(motorspeed, 0);
      delay(1000);
      Reachedup = 1; // indicate finished returning after cleaning cycle
    }
  }
}


hamad
  • 31
  • 2

1 Answers1

1

Hardware:

You have the switch at 5V with a pull down resistor.
When using longer wires or when everything is put into a box, it might be safer to have a GND wire to the switch (with a pull up resistor) instead of a 5V wire. When a switch or button is connected with a shielded cable, it can also be better to connect one pin of the switch to GND.

If you change the switch and connect one pin to GND with pullup resistor, then you have to change the sketch as well, because the pin will become LOW when the switch is pressed.

You may add a capacitor of 1 nF to 100 nF between the digital input and GND. That will help against spikes and noise.

The pull down resistors of 4k7 is a high value for a noisy environment. I suggest to use 470 Ω or 1k resistors.

The ground path is very important. You have the GND of the motor driver connected to the breadboard and that is also where the switches are connected. That means the input (switches) and the output (motor driver) share a piece of ground wire. Always avoid such situations.
Breadboards have often bad contacts. If the GND to the breadboard is not very solid, then you are injecting the input pins with noise from the output pins of the Arduino board.
Use two seperate breadboards for input and output. Or connect the GND of the motor driver directly to the Arduino board.

Software:

An integer can not be 0.9, therefor your filter does not work.

The function digitalRead() returns HIGH or LOW. You add those values, but I prefer to stick with HIGH or LOW.

Taking multiple samples and have a threshold is a good idea. Do you really need 100 or 300 samples? A button may bounce for 10 ms, so I suggest to use about 20 samples during 20 ms.

int digitalReadFiltered(int pin) {
  int result;
  const int n = 20;                // maximum 30
  int count = 0;                   // an integer can hold 30 analog samples

  for (int i = 0; i < n; i++) {
    if (digitalRead(pin) == HIGH) {
      count++;
    }
    delay(1);        // 1 ms for sampling during 20 ms with 20 samples
  }

  if (count > (n / 2)) {
    result = HIGH;   // counted enough HIGH values
  } else {
    result = LOW;
  }

  return(result);
}

In short, a pull down (or pull up) resistor with a low value makes the circuit low impedance, and the electrical noise will have less influence.

When a button is pressed, that connects the digital input pin of the Arduino board directly to 5V (or GND). Then it is almost impossible that electrical noise can get to that pin.

When a button is not pressed, then the resistor keeps the input pin low (or high). Then electrical noise can cause spikes.

A circuit with low impedance is less influenced by the electrical noise. The lower the value of the resistor, the less troubles with noise.

It is not something that can be calculated, see it as electrical/capacitive/electromagnetic/radio-noise combined with bad ground currents from a wrong ground path. What is the best way to receive that? With a high impedance circuit of course.

A pull down (or pull up) resistor with a value of 10k can be used when there are no wires connected to it that are going outside the circuit board. When there is a button with wires, then I would suggest a lower value, for example 2k2 or 4k7. Since you have troubles with noise, I suggest a value of 470 Ω or 1k.

Jot
  • 3,276
  • 1
  • 14
  • 21