Second button fine in test, flaky in action

I'm attempting to move a Sun Oven to follow the sun with a motor (12v - .6A - 50rpm) and an actuator (12v - 256:1 - 1A max) driven by a L293D Dual H-Bridge (Adafruit #807) using a UNO v3 and two Tactile Button Switches (Adafruit #1009).

When I test the buttons with a simple print to the monitor they work perfectly. However, as soon as I allow the button presses to call their respective functions (#1 = Motor, #2 = Actuator), #1 runs the motor perfectly, but the #2 button it is erratic.

The simple, single press SHOULD run the actuator for 60 seconds, shut off, and lock up in an endless loop until reset. However, pressing button #2 can get you .5 sec run time, another press, nothing, another press, another .5 sec run time, another press, 3 secs run time, another, THE MOTOR RUNS! What the heck is going on here? You shouldn't be allowed to press button #2 a second time, let alone several, let alone run the motor!

(The UNO in the black box is not currently used during testing)




  #include <toneAC.h>                                             // This library is HARD WIRED to use pins 9 and 10.
  #include <Debounce.h>

  int button1 = 4;
  int button2 = 5;
  int acturE = 6;                                                 // Truns actuator ON (Enable)(EN2 - P09) PWM.
  int actur1 = 7;                                                 // Actuator lead + (or -)    (IN4 - P15).
  int actur2 = 8;                                                 // Actuator lead - (or +)    (IN3 - P10).
  int tonePin1 = 9;                                               // Piezo possitive (+) pin (toneAC library REQUIRES pin 9 and 10).
  int tonePin2 = 10;                                              // Piezo negative  (-) pin (toneAC library REQUIRES pin 9 and 10).
  int motorE = 11;                                                // Truns motor ON (Enable)   (EN1 - P01) PWM.
  int motor2 = 12;                                                // Motor lead + (or -)       (IN2 - P07).
  int motor1 = 13;                                                // Motor lead - (or +)       (IN1 - P02).
  int limit = 36000;                                              // Motor spent too much time (36 sec = 360°) trying to find sun!
  int dir = 0;                                                    // Direction, 0 = Left or Up, 1 = Right or Down.

  unsigned long timeIn = 0;                                       // Time count to stop potential endless loop.
  unsigned long MotTime = 0;                                      // Motor can't find sun, bail and alarm!
  unsigned long ActTime = 0;                                      // Actuator can't find sun, bail and alarm!
  bool moved = false;                                             // All is well.

  int photoCellVal;                                               // Analog reading from current phtocell.
  int photoCellNorm[4];                                           // Normalized results for easy differencial.
  const int cellTR = 0;                                           // (A0) Orange - Top Right.
  const int cellTL = 1;                                           // (A1) Yellow - Top Left.
  const int cellBR = 2;                                           // (A2) Green  - Bottom Right.
  const int cellBL = 3;                                           // (A3) Blue   - Bottom Left.
                                                                  // Red = 5V.
                                                                  // Brown = Gnd.
  Debounce Button1(4, 50, true);                                  // Use default 50ms delay and INPUT_PULLUP.
  Debounce Button2(5, 50, true);

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {

  pinMode(motorE, OUTPUT);                                        // Turns motor ON.
  pinMode(motor1, OUTPUT);                                        // Motor lead + (or -).
  pinMode(motor2, OUTPUT);                                        // Motor lead - (or +).
  pinMode(acturE, OUTPUT);                                        // Turns actuator ON.
  pinMode(actur1, OUTPUT);                                        // Actuator lead + (or -).
  pinMode(actur2, OUTPUT);                                        // Actuator lead - (or +).
  pinMode(tonePin1, OUTPUT);                                      // Piezo possitive (+) pin.
  pinMode(tonePin2, OUTPUT);                                      // Piezo negative (-) pin.
  pinMode(button1, INPUT_PULLUP);                                 // Motor run button.
  pinMode(button2, INPUT_PULLUP);                                 // Actuator park button.

  digitalWrite(motor1, 0);                                        // Start with all motors off.
  digitalWrite(motor2, 0);
  digitalWrite(actur1, 0);
  digitalWrite(actur2, 0);
  digitalWrite(motorE, HIGH);                                     // Only one "speed", 0% or 100%.
  digitalWrite(acturE, HIGH);                                     // set them perminently to 100%.

  for (int i = 0; i < 3; i++) {
    toneAC(3136, 5, 250);                                         // Starup warning.
    delay(250);
  }
  // Serial.begin(9600);
}

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {

  if (Button1.read()) {
    ManualMotor();
    // Serial.println("Motor");
  }
  delay(50);                                                      // Reading two buttons too quickly seems to cause problems.
  if (Button2.read()) {
    Park();
    // Serial.println("Actuator"):
  }
}

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ReadPhotocells() {

  for (int i = 0; i < 4; i++) {                                   // Normalize photochell values.
    photoCellVal = analogRead(i);
    photoCellNorm[i] = abs(photoCellVal /100) *100;               // All reads stripped to even 100s. (121 = 100. 387 = 300 etc.)
  }
}

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ManualMotor() {

  static bool motorDir = LOW;

  int i = 0;
  timeIn = millis();
  runMotor(motorDir);                                             // Run motor in last used direction until button is pressed again.
  while (true) {
    if (!Button1.read()) {                                        // Button released, switfch directions...
      motorDir = !motorDir;
      break;                                                      // ...bail.
    }
    if (millis() >= timeIn + limit) {                             // 360°...
      stopMotor();
      while (i < 10) {                                            // ...signal done (10 quick beeps)...
        i++;
        toneAC(3136, 10, 10);
        delay(50);
      }
      toneAC();
      break;                                                      // ...bail.
    }
  }
  stopMotor();
}

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Park() {

  int i = 0;
  runActuator(LOW);                                               // Run actuator UP until in park position.
  delay(60000);                                                   // Max time to go full range. (or hit Actuator's built-in limit switch)
  stopActuator();
  while (i < 10) {                                                // Signal "parked" with 10 quick beeps.
    i++;
    toneAC(3136, 10, 10);
    delay(50);
  }
  toneAC();
  while(true) {
    // Endless loop until reset!
  }
}

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void runMotor(int power) {

  digitalWrite(motor1, !power);
  digitalWrite(motor2, power);
}

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void stopMotor() {

  digitalWrite(motor1, LOW);
  digitalWrite(motor2, LOW);
}

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void runActuator(int power) {

  digitalWrite(actur1, !power);
  digitalWrite(actur2, power);
}

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void stopActuator() {

  digitalWrite(actur1, LOW);
  digitalWrite(actur2, LOW);
}

Thanks in advance.
Dan

Hi
on this line you call the function with a boolean value.

But the function takes int values.

I think that "!power" is diferent for boolean or int.

Modify and see if this solves the problem;

Eagle eye ruilviana! Thanks for your time and thought.

Alas, the the system admin of Arduino.cc said,
"HIGH and LOW are defined as 1 and 0 which match the definitions of true and false. "
But, of course, I tried it anyway. Sorry. No difference.

...not to mention running the motor, which is controlled by a different switch on a different pin.

Hi
I will test here, are you using a UNO?

Yes. Rev 3.

Hi
As I don't have this driver, I will use LEDs on the outputs to the driver.

int has the range of -32,768 to 32,767


We need to see a schematic.

Hi
In my test it worked OK, but in this piece of code you "block" processing. (Endless loop)

Is it to "block" it?

 while (true) {
    // Endless loop until reset!
  }

The test working just fine is the originally stated problem.

The endless loop is a software switch. It's in a function called Park() because the machine is solar powered and the user needs to stop it from moving (following the sun) in order to service the food in the Sun Oven. The reset button will get it moving normally again.

This morning I replaced both switches and the board they are mounted on. (first pic)

Previously I replaced the L293D chip and Screw Shield, thinking it could be the chip or even shield. (second pic) without remedy. (first shield, blue, Adafruit #196, second, red, is Anonymous Chinese)

So far I have replaced the UNO, Screw Shield, L293D, switches, mount and wiring, in addition to power supply (solar panel, 12v battery and bench power supply). Both the motor (which has also been replaced, 10rpm with 50rpm) work perfectly when powered directly. I even tried sticking my tongue out the other side of my mouth.

Any clues as to where/what this gremlin is would be greatly appreciated.

Thanks,
Dan


1 Like

It sounds like the Uno is getting reset. Possibly due to a power brownout.

Add some serial prints to the park routine to see what it's doing.

We need to see a schematic.

I have serial printed all function calls. As noted above, everything works perfectly in test. It's the real world that raises the gremlin.

There is a voltage drop (bench power supply) from12v to 11, 10.5 and occasionally as low as the high 8's. Is that enough to reset the UNO?

That would be suggested if the Park() button simply failed. However, as noted above, it works intermittently with actuator movement of .5 seconds, 3 seconds, 10 seconds but not the full 60 seconds. Not to mention (which has been noted above) RUNNING THE MOTOR!

I don't have a schematic. You can see all connections in the photo above. Schematics for the UNO, L293D and the momentary switches are available on line.

Could my sloppy soldering be the culprit? Baring in mind that both shields act the same, that is they are equally flaky. Also, plugging the motor into the actuator circuit caused the motor to be intermittent and/or non-functional.



Not sure why you cannot draw one with pencil :thinking: .


You supply the information, we try to help you once we get all pertinent information.


Little information = little help. :woozy_face:


Crystal ball says you might be trying to power an external load with the Arduino 5V pin.

If so, do not do this, but we will never know as we are left guessing . . .

The photos clearly show 12v at 400mA supply through the barrel jack.

Please explain the discrepancy.


What is the resistance of your load(s) ?


BTW, Add decoupling to the motor driver.


Please show your current sketch.

I'm working on it.

If you are seeing your Siglent 0-30V @ 0-5A power supply acting up like this, you have either a power supply current limiting problem or your loads are drawing too much current, i.e. more than the 400mA mentioned.

Powering your loads thru the Vin pin (which has a series diode to the power jack) should be avoided, do it directly.


To double check the switch wiring, write a simple sketch than monitors the two switches.


What is the motor resistance ?
What is the actuator resistance ?

The mentioned power drop is only when the actuator is activated by the switch, and of course, operates sporadically or not at all. When it's powered directly, both the motor and the actuator only drop about 1 volt for only an instant and both run properly.

Good to know. Arduino gave me the impression that the Barrel Jack can safely use 7-12 volts to power the UNO and peripheral devices such as motors. And the L293D states that one can supply up to 18 volts through it's pin 8 from the VIN of the UNO.

So I guess you are suggesting that I need to split my power supply into two, one limited to 5V to the UNO (into the Barrel or USB I presume) and a second one for 12V to pin 8 of the L293D. Is that right?

What is VIN to be properly used for then?

The motor came from Amazon with no data sheet. https://www.amazon.com/Greartisan-Electric-Reduction-Centric-Diameter/dp/B07K9KPDNV?th=1

The only info is:
Rated Voltage: DC 12V
Reduction Ratio: 1:95
No-Load Speed: 50RPM
Rated Torque: 3.97Kg.cm
Rated Current: 0.6Amp
D Shaped Output Shaft Size: 614mm (0.24" x 0.55") (DL)
Gearbox Size: 37 x 27mm (1.46" x 1.06") (DL)
Motor Size: 36.2 x 33.3mm (1.43" x 1.31") (D
L)
Mounting Hole Size: M3 (not included)

The actuator is a Actuonix P16-200-256-12S

I don't see any mention of resistance.

I have tested the switches by putting them in-line with the Bench Power Supply. That is, nothing but power, switch, actuator and ground. As mentioned above, I have switched both switches, replaced both switches and even replaced the perf board that they are mounted on.

And here's your schematic. A bit crude probably, but it's the first one I have ever made. It wasn't easy, took a long time and I am dying to find out what you are going to glean from it that you can't see in the photos. But since you say you can't help without it, here it is.

Schematic.pdf (11.8 KB)