95% working, can't figure this out

I’ve been working on a project for a few weeks now with the help of a programmer and we are totally stumped. We have almost everything working except for two things. The project is a camera slider controlled via an arduino. I am using a stepper motor, an arduino pro Mini 5v, a potentiometer, a 2 way toggle switch, and a 3 way toggle switch along with two limit switches. The issue is with the 2 way toggle switch and the limit switches.

The 2 way toggle switch selects a set of speeds, pretty much a low speed and high speed this way I can control the set using the potentiometer. The 3 way toggle picks the drive mode, straight or looped (middle position is no movement) in Straight mode EVERYTHING works. Speed selector toggle works great, when the carriage hits an end stop the motor stops until the potentiometer is turned.

In loop mode we have issues, the 2 way toggle switch (speed selector) is doing nothing, I cannot pick the lower set of speeds to use. Also, when it is currently set to the slowest via the potentiometer when it hits an end stop instead of reversing direction it simply locks up. I also have no clue if the person who was programming this did things in a more complicated way then what was necessary.
Attached is the wiring diagram he provided as well as the code its self. Any help would be great

combined_5.ino (10.4 KB)

You attachment are much to large to read easily, but I see no pull-up resistors being used on your switch input pins. Where you set the pinMode for both switch pins in your setup function (three input pins I see) you should enable the internal pull-up resistors as such:

pinMode(pin#, INPUT_PULLUP); // enable pin's internal pull-up resistor.

Hello mdifilippo

when it is currently set to the slowest via the potentiometer when it hits an end stop instead of reversing direction it simply locks up.

What happens when it hits an end stop if you run it at faster speed? Does it then reverse correctly?

And what happens if you press the limit switch by hand before the slider reaches it?

Regards

Ray

Hey Ray, at fast speeds it briefly pauses and then reverses direction. At the slowest speed if I press the limit switch and keep my finger on it (like the carriage would) it doesn't do anything, if I quickly press the limit switch and release it, it then reverses.

thanks Mike

Thanks, Mike.

Sounds like that part of the code is responding (maybe repeatedly) to the limit switch being in the pressed state, instead of responding to the event of the switch going from not pressed to pressed. At the higher slider speeds (or quick finger press), the slider has time to reverse and un-press the switch.

I'll take another look at the code with this in mind.

Regards

Ray

Hi Mike

attachInterrupt(0, limit_switch, LOW);

In the code, there is an interrupt service routine (ISR) attached to Interrupt 0, which on the Uno is pin 2. Looks like you have the limit switches connected to that?

The above statement means that, when pin 2 is LOW, a function called limit_switch is called. This function (temporarily) detaches the interrupt and sets a flag to say limit switch reached.

When the code in the main loop spots this flag, it stops the motor, waits 1s, flips round a different flag which controls direction of travel, restarts the motor for a bit and then re-attaches the interrupt (ready for when the slider gets to the other end).

The problem could be the “LOW” in the statement above. LOW means that the interrupt will be triggered whenever the pin is low. I think you may want it triggered only when the switch has just gone from high to low. Try changing LOW to FALLING in the above statement and all the other attachInterrupt() statements.

I’m not sure why the system wasn’t designed with each limit switch on separate interrupt pins (there are two on the Uno).

Regards

Ray

Mike

In loop mode we have issues,

Can you clarify required behaviour in straight and loop modes?

In loop mode, the slider is meant to alternate going left and right, and automatically change direction when it hits the limit switch?

How is it meant to work in straight mode? How does it know which direction you want it to go in? And what does it do when it hits end stop?

Sorry for all the questions. But they will help to get to the bottom of the problems.

Thanks

Ray

I really appreciate it Ray! So replacing the "low" with "Falling" didn't help, now it actually only reverses for a few rotations, then returns back in the original direction, and on the lowest speed it never reverses.

Loop mode - the potentiometer controls the speed in one direction. When a limit switch it triggered it then reverses the direction. Straight mode- the potentiometer controls speed AND direction. If I sweep it from centered to counter clockwise, the carriage moves to the left, if I sweep it from center to clockwise the carriage moves right. Once a limit switch is engaged the carriage stops moving until the potentiometer is swept PAST the zero point and to the opposite direction.

The limit switches are indeed connected to pin 2.

Thank you thank you thank you!

OK, not sure what to suggest next about the “not reversing at slow speed”. Will have to think about that.

On the other problem “unable to select high vs low speed range” in the straight mode …

Does MODESWITCH 1 == LOW mean loop mode, and MODESWITCH2 == LOW mean straight mode?

And MODESWITCH3 == LOW means select other speed range?

This is the code in your main loop() after deleting all the if statements that handle the limit switches.

    if( digitalRead(MODESWITCH1) == LOW && digitalRead(MODESWITCH2) == HIGH && digitalRead(MODESWITCH3) == HIGH)      //if mode 1 selected  
    {
        runMotor_mode_1();
    }
    if( digitalRead(MODESWITCH1) == HIGH && digitalRead(MODESWITCH2) == LOW && digitalRead(MODESWITCH3) == HIGH) 
    {
        if(potentio_value() < 500)
        {
            set_left();
            if(potentio_value() < 450)
            {
                stepper_speed = map( potentio_value(), 0, 450, MOD1HIGHSPEED, MOD1LOWSPEED);
                stepper_run_delay(stepper_speed);
            }
            else
                stop_motor(); 
            //    Serial.println("Motor Direction L");
        }
        else
        { 
            set_right();
            if(potentio_value() > 550)
            {
                stepper_speed = map( potentio_value(), 550, 1023, MOD1LOWSPEED, MOD1HIGHSPEED);
                stepper_run_delay(stepper_speed);
            }
            else
                stop_motor();
            //     Serial.println("Motor Direction R");
        }   
    } 
    /**************************************************************************************/
    if( digitalRead(MODESWITCH1) == LOW && digitalRead(MODESWITCH2) == HIGH && digitalRead(MODESWITCH3) == LOW)      //if mode 1 selected  
    {
        runMotor_mode_1();
    }
    if( digitalRead(MODESWITCH1) == HIGH && digitalRead(MODESWITCH2) == LOW && digitalRead(MODESWITCH3) == LOW) 
    {
       // SEE COMMENTS IN POST
    } 
    ///********************************************************************************/ 
    if( digitalRead(MODESWITCH1) == HIGH && digitalRead(MODESWITCH2) == HIGH ); 
    {
        stop_motor();
    }

There is a block of code that starts “if(potentio_value() < 500)” and includes map statements. Looks like code to convert pot value into speed.

This block is under the MODESWITCH3 == HIGH condition.

There isn’t a similar block of code for MODESWITCH3 == LOW.

Or rather there was, but I deleted it :slight_smile: because it was inside an if statement that handles hitting the limit switch (it was where I have put the comment SEE COMMENTS IN POST). I think it may well be the right code but at the wrong nesting level.

Might be worth getting the programmer to have a look at this.

Regards

Ray

A suggestion to help generally with debugging and maintenance of the program. There is a lot of identical or similar code repeated a number of times. It would help to make more use of functions (there are some already) to reduce duplication and make it easier to understand the flow of the logic through the program :)

now it actually only reverses for a few rotations, then returns back in the original direction

Mike, does it reverse enough to be clear of the limit switch before it then goes back the wrong way?

And does it oscillate ... hits switch, reverses a bit,but reverses again, hits switch, reverses, etc?