here's an easy one

...for someone, but perhaps not for me.

I have been working on a program for a system that is very close to projects i've sorted out before, but i can't seem to get this one. The system is:

Arduino mega; three inputs (one optocoupler as input, two rocker switches), one DC motor through h bridge.

The basic steps to the program are:

upon first input of Signal A, motor runs forward until input from limiting switch 1.
upon second input of signal A, motor runs backward until input from limiting switch 2.

repeat.

Signal A will always come in pairs, so at the end of each paired set of motor actions, the device will be back at the starting position.

Here is the code I have so far. Currently, once the first signal A is received (main_val) it will not stop the motor with input from the limiting switch. I have used very similar code in the past, but for projects with five or six sequenced actions. Don't know why it isn't working here.

(cleaned up the code a little, but still not working right)

int motor1 = 26;           //declares the first pin for the motor 
int motor2 = 27;           //declares the other pin for the motor
int motorpmw = 9;     // this is the pmw that will set how much battery power the motor is getting (speed)
 
int soundPin = 22;
int stop1 = 24;
int stop2 = 25;
int main_val = 0;
int val1 = 0;
int val2 = 0;
int ctrl = 0;
int ctrl2 = 0;
void setup()
{
pinMode(motor1, OUTPUT);           //
pinMode(motor2, OUTPUT);           // these simply are declaring them as outputs
pinMode(soundPin, INPUT);
pinMode(stop1, INPUT);
pinMode(stop2, INPUT);
}
 
void loop()
{
 main_val = digitalRead(soundPin);
 val1 = digitalRead(stop1);
 val2 = digitalRead(stop2);
 delay(10);
  
  if (main_val == HIGH) 
  {
   ctrl = ctrl+1;
  }
 

  if (ctrl == 1)
  {
    digitalWrite(motor1, HIGH);         
     digitalWrite(motor2, LOW);
     
    if (val1 == HIGH)
      {
      digitalWrite(motor1, LOW);         
      digitalWrite(motor2, LOW);
      ctrl = 2;
      }
  
  }
  
  if (ctrl == 3)
  {
      digitalWrite(motor1, LOW);         
      digitalWrite(motor2, HIGH);
      
    if (val2 == HIGH)
      {
      digitalWrite(motor1, LOW);         
      digitalWrite(motor2, LOW);
      ctrl = 0;
      }
   
  }
}

I have already achieved the right functions here by losing the two rocker switches and using a stepper instead, but i would like a smoother motion. If there is a completely different code structure i need here please let me know.

All switch/motor physical functions, pin assignments, etc., have been troubleshot.

thanks!

I'd create two boolean values - goingForward and goingBackward.

Set goingForward to true and goingBackward to false when main_val is HIGH and ctrl == 0. Increment ctrl at the same time.

Set goingBackward to true and goingBackward to false when main_val is HIGH and ctrl == 1. Decrement ctrl at the same time.

Then, decide what to do if goingForward is true, and what to do if goingBackward is true.

There is not much point in checking the backwards limit switch when going forward or stopped, and not much point in checking the forwards limit switch when going backwards or stopped.

I imagine this loop runs so fast that when soundPin goes HIGH, ctrl increments a lot.
I expect you'll want to add two things. 1) Debounce the digital inputs, and 2) look for a transition from low to high rather than the state

fixed it. dropped the incremental values in favor of double conditionals. it looks like this:

void loop()
{
 main_val = digitalRead(soundPin);
 val1 = digitalRead(stop1);
 val2 = digitalRead(stop2);

  
  if (main_val == HIGH) 
  {
   ctrl = 1;
  }
 if (ctrl == 1 && ctrl2 ==0)
  {    
    if (val1==HIGH)
      {
      digitalWrite(motor1, LOW);         
      digitalWrite(motor2, LOW);
      ctrl = 2;
      ctrl2 = 1;
   
      }
      else
      {
        digitalWrite(motor1, HIGH);         
        digitalWrite(motor2, LOW);
      }
      
  }

  if (ctrl ==1 && ctrl2 ==1)
    {
     if (val2==HIGH)
     {
       digitalWrite(motor1, LOW);         
      digitalWrite(motor2, LOW);
      ctrl2 = 0;
      ctrl = 0;
   
      }
      else
      {
        digitalWrite(motor1, LOW);         
        digitalWrite(motor2, HIGH);
      }
  }
  
 
}

thanks for your help! i know it's probably not the prettiest way to set this up, but being a maker and not strong on the code side, i am always happy just to get it working!

The only reason I suggested boolean variables is to make the code easier to read.

if(goingForward)
{
   // whatever...
}

is easier to understand at a glance than

if(cntrl1 == 1)
{
   // whatever...
}

But, if it works, and you understand it, that's all that matters.

no you're right pauls, i often have a hard time following my own syntax a couple of months later and i would like to work on a little more transparency in how i set these things up.

i haven't worked with booleans in a long time, so this project would be a good refresher.

to provide a little closure (which seems to be rare around here) i've posted the nearly-finished reality of this project over in the Exhibition forum: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1262997480/0#0