Driving a stepper fitted with a FB pot in turn drives another stepper

Hi I am new to arduino and need some help please.
My project is as follows:

  1. 2 button switches as inputs (digital inputs), when either is switched will drive stepper via big easy driver one way, the other sw drives stepper the opposite
    (This simulates slow movement of a rudder reference unit which has a feedback signal from it (2k pot).

  2. Now the feedback signal (pot input) is fed back on A0 to drive another stepper via a L298 h-bridge driver. (This simulates ships head provided by an electronic heading sensor unit. So this stepper stops when pot is in the (midship) and run CW & CCW on either way of the pot. Stepper also accelerates the further away it is from the center.

  3. both sketches work as expected when tested separately but not when I merged them into one. Will attach sketches sometime tomorrow cheers

Hi everyone I am re- posting this in the hope of someone could shine me a light on my problem :frowning: in putting the 2 sketch in sync. cheers

My project is as follows:

  1. 2 button switches as inputs (digital inputs), when either is switched will drive stepper via big easy driver one way, the other sw drives stepper the opposite
    (This simulates slow movement of a rudder reference unit which has a feedback signal from it (2k pot).

  2. Now the feedback signal (pot input) is fed back on A0 to drive another stepper via a L298 h-bridge driver. (This simulates ships head provided by an electronic heading sensor unit. So this stepper stops when pot is in the (midship) and run CW & CCW on either way of the pot. Stepper also accelerates the further away it is from the center.

  3. both sketches work as expected when tested separately but not when I merged them into one. Will attach sketches sometime tomorrow cheers

Below is the sketch to drive stepper that’s attached with feedback pot. And the last one is for stepper fitted to the heading sensor(flux gate) that will simulates direction of a ship is headed. Will post some diagrams and schematic shortly.

[c#include <Wire.h>

#include <Stepper.h>

void setup() {
  
  //configure pin2 as an input and enable the internal pull-up resistor
  
  pinMode(2, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, OUTPUT);    // set pin 5 dir output
  pinMode(7, OUTPUT);    // set pin 7 step output
  digitalWrite(5, LOW);  // set pin 5 initially to LOW
  digitalWrite(7, LOW);  // set pin 7 initially to LOW

Serial.begin(9600);
}

void loop() {
   //read the pushbutton value into a variable
  
  
  int switch_A = digitalRead(2);
  int switch_B = digitalRead(4);
   
  
  if (switch_A == LOW){
    digitalWrite(5, LOW);
    digitalWrite(7, HIGH);   // Toggle pin 7 to HIgh
    delayMicroseconds(800);                // Wait 1ms
    digitalWrite(7, LOW);    // Toggle pin 7 to LOW
    delayMicroseconds(800);                // Wait 1ms
  }
  
    else if (switch_B == LOW){
      digitalWrite(5, HIGH);
      digitalWrite(7, HIGH);
      delayMicroseconds(800);
      digitalWrite(7, LOW);
      delayMicroseconds(800);
    }
} 
 ode]
#include <Stepper.h>

const int stepsPerRevolution = 400;  // change this to fit the number of steps per revolution
// for your motor


// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

int stepCount = 0;  // number of steps the motor has taken
int motorSpeed = 0;
int port = 0;
int stbd = 0;

void setup() {
  
Serial.begin(9600);  
  // nothing to do inside the setup
}

void loop() {
 
  // read the sensor value:
  int sensorReading = analogRead(A0);
  
  // map it to a range from 0 to 100:
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
   port = motorSpeed - 50 ; 
      
   Serial.println(port);
   
   // set the motor speed:
   if (port >0) {
      myStepper.setSpeed(port);
    
    // step 1/100 of a revolution:
    myStepper.step(-stepsPerRevolution / 100);
    delay(1);
   }
   
    if (port <0) {
     port = abs(port);
     stbd = port;
     myStepper.setSpeed(stbd);
     myStepper.step(stepsPerRevolution / 100);
     delay(1);
 }
    
}

[/code]

Don’t split the project across different Threads. I have asked the Moderator to merge this with your earlier Thread

When you add a new post to an existing Thread it will automatically return to the top of the list.

Please modify your post and use the code button </> so your code looks like this and is easier to read and copy to a text editor

…R

Is this better now?

Puno:
Is this better now?

No, your code is outside the

[code]Put code here[/code]

tags and it should be between them. (One pair of tags required per sketch.)

So you've shown us what does work. Now whatabout the version which doesn't work?

I'm still not sure what you're trying to do. Perhaps a schematic might be helpful. A cellphone photo of a pencil drawing is usually sufficient.

Ok sorry will modify sketch again on my post and also attach some sketches to what my project is all about. See soon guys

ok this is a rough schematic and its operation and my sketch for the 2 steppers.

[#include <Wire.h>
#include <Stepper.h>

  const int stepsPerRevolution = 400;


// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

int stepCount = 0;  // number of steps the motor has taken
int motorSpeed = 0;
int port = 0;
int stbd = 0;
int sensorReading;
int sensorReadingb;

void setup() {

   //configure pin2 as an input and enable the internal pull-up resistor
 
 Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, OUTPUT);    // set pin 5 dir output
  pinMode(7, OUTPUT);    // set pin 7 step output
  digitalWrite(5, LOW);  // set pin 5 initially to LOW
  digitalWrite(7, LOW);  // set pin 7 initially to LOW

 }

void loop() {
  
   //read the pushbutton value into a variable
    int switch_A = digitalRead(4);      
    int switch_B = digitalRead(2);
     
    if (switch_A == LOW){
       digitalWrite(5, LOW);
       digitalWrite(7, HIGH);   // Toggle pin 7 to HIgh
       delayMicroseconds(500);                // Wait 1ms
       digitalWrite(7, LOW);    // Toggle pin 7 to LOW
       delayMicroseconds(500);                // Wait 1ms
  
     shipsHead();  
      
  }
   
   if (switch_B == LOW){
      digitalWrite(5, HIGH);
      digitalWrite(7, HIGH);   // Toggle pin 7 to HIgh
      delayMicroseconds(500);                // Wait 1ms
      digitalWrite(7, LOW);    // Toggle pin 7 to LOW
      delayMicroseconds(500);                // Wait 1ms
  
     shipsHead(); 
   }
}

void shipsHead() {
 
  // read the sensor value:
  int sensorReading = analogRead(A0);
  
  // map it to a range from 0 to 100:
   motorSpeed = map(sensorReading, 0, 1023, 0, 100);
   port = motorSpeed - 50 ; 
      
   Serial.println(port);
   
   // set the motor speed:
   if (port >0) {
      myStepper.setSpeed(port);
    
    // step 1/100 of a revolution:
    myStepper.step(-stepsPerRevolution / 100);
    
   }
   
    if (port <0) {
     port = abs(port);
     stbd = port;
     myStepper.setSpeed(stbd);
     myStepper.step(stepsPerRevolution / 100);
     
   }
    
}
 /code]

AutopilotSim1.pdf (63.6 KB)

Your diagram (and your description) suggests that the rudder is physically separate from the fluxgate sensor.

I don't understand why you have all the "stuff" (Easydriver, stepper motor and FB pot) just to generate some slowly changing numbers for the Arduino. Why not just do that in code ? But that probably does not affect your questions.

I suspect it is the delayMicroseconds() that is screwing things up. Look at how millis() is used for timing without blocking in several things at a time. The technique also works with micros().

I would also restructure your code so that loop() looks like this

void loop() {
   readButtons();
   moveRudder();
   shipsHead();
}

as it puts the different parts in a more obvious relation with each other and makes it easier to spot problems.

Each function should be designed to take the shortest possible time so loop() can repeat frequently.

...R

I have all that many set ups as u know it is a simulation of a real ship except of course this one sits on the bench. I had a prototype type built from old dc motors and junk and it worked the problem was the accuracy and precise of the turning of the flux gate heading sensor.

I have tried Robins sketch one using Millis and I found sometimes the stepper squeals or start fast and then slowed down to the right motion and every time starts after that the time delay gets longer and longer.

I will right up another one using Robins sketch and in micros and see what happens

Appreciate your input cheers

Puno:
I will right up another one using Robins sketch and in micros and see what happens

When you have it done post your latest code if you need more advice.

It is almost impossible to answer questions without seeing the code (e.g. why is the motor squealing or starting fast). My guess is it squeals because sometimes it can't start as fast as the code requires.

...R

This is the sketch with millis. Whole thing hung up and the second stepper (shipsHead) is running because (rudder with pot ) did move with the buttons and then stops responding to buttons.

If the sketch is right I start to think the timing of things are not in sync. Not sure

#include <Stepper.h>

const int stepsPerRevolution = 400;  // change this to fit the number of steps per revolution
// for your motor


// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

int stepCount = 0;  // number of steps the motor has taken
int motorSpeed = 0;
int port = 0;
int stbd = 0;


byte directionPin = 5;
byte stepPin = 7;

byte buttonCWpin = 2;
byte buttonCCWpin = 4;

boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 2; // milliseconds


 

void setup() { 

  Serial.begin(9600);
 
  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  
  pinMode(buttonCWpin, INPUT_PULLUP);
  pinMode(buttonCCWpin, INPUT_PULLUP);
  
}

void loop() { 
	
	curMillis = millis();
	readButtons();
	actOnButtons();
        shipsHead();
}

void readButtons() {
	
	buttonCCWpressed = false;
	buttonCWpressed = false;
	
        if (digitalRead(buttonCWpin) == LOW) {
		buttonCWpressed = true;
	}
	if (digitalRead(buttonCCWpin) == LOW) {
		buttonCCWpressed = true;
	}
}

void actOnButtons() {
	if (buttonCWpressed == true) {
		digitalWrite(directionPin, LOW);
		singleStep();
	}
	if (buttonCCWpressed == true) {
		digitalWrite(directionPin, HIGH);
		singleStep();
	}
}

void singleStep() {
	if (curMillis - prevStepMillis >= millisBetweenSteps) {
		prevStepMillis += millisBetweenSteps;
		digitalWrite(stepPin, HIGH);
		digitalWrite(stepPin, LOW);
	}
}
    


void shipsHead() {
 
       // read the sensor value:
          int sensorReading = analogRead(A0);
  
      // map it to a range from 0 to 100:
          motorSpeed = map(sensorReading, 0, 1023, 0, 100);
          port = motorSpeed - 50 ; 
      
          
   
     // set the motor speed:
          if (port >0) {
           myStepper.setSpeed(port);
    
    // step 1/100 of a revolution:
            myStepper.step(-stepsPerRevolution / 100);
    
    }
   
          if (port <0) {
            port = abs(port);
            stbd = port;
            myStepper.setSpeed(stbd);
            myStepper.step(stepsPerRevolution / 100);
     
   }
    
}

Puno:
This is the sketch with millis. Whole thing hung up and the second stepper (shipsHead) is running because (rudder with pot ) did move with the buttons and then stops responding to buttons.

I will have a look at the code later, but can you give a much more detailed description of what happens. "Whole thing hung up" is what you do with an overcoat.

...R

ok I press one of the button the stepper that drives the pot start moving and as soon the readout from the pot is higher or lower than zero the other kicks in. And any further pressing of any buttons nothing happens except this second stepper keeps going round and round. And when I reset it nothing happens anymore. If there isn't any solution to this one I think it will only work if I run 2 unos. Will see if you come with anything. cheers.

Puno:
I think it will only work if I run 2 unos.

That is completely unnecessary - and will just make the project more complicated.

I will look at the code now. Thanks for the additional description.

…R

I suspect the problem is that in your shipsHead() function you are using the Pot position to set the speed rather than the position of the second stepper.

The way your code is written I think it would only work if the second motor was moving the potentiometer back to the central position. Conceivably the first motor would move the shaft of the pot and the second motor would move the body.

However I think it would be simpler just to treat the pot reading as an absolute position and have the second motor move an appropriate number of steps.

You don’t seem to have any code to establish the HOME position of the second stepper motor

…R

Thanks for your comment. I see where you coming from.
To get the ships head or the pot to home(Central) is by the action of the switches.

Therefore the second stepper is only running when there is a feedback signal from the pot. And the speed it rotates is equal to the signal level received from the pot.

When is all set up the switches will be replaced by optocouplers as the autopilot processor outputs 24v(currently set up like that except I included switches for port and starboard as I am just using a 24vdc pwr supply.

The second stepper(shipsHead) drives a fluxgate heading sensor this sensor has its own feedback signal to the autopilot to updates shipsHead in relation to demanded course so if there is a difference(course error), the autopilot activates either the port or starboard signal to adjust the first stepper position so thus the rudder(pot) until no more course error signals from the fluxgate when this happens the rudder(pot) is at home in the centre position.

Sorry for the long explanation I hope you get a clear picture now.

That's the set up has to be in. So by going of what you are saying, I am gonna need another controller.

Thanks for your time looking over my code and suggestions.

Puno:
Sorry for the long explanation I hope you get a clear picture now.

No, still clear as mud, I'm afraid.

So by going of what you are saying, I am gonna need another controller.

I don't know what you mean by "another controller".

If you mean another Arduino then I don't see any evidence for your conclusion.

...R

I have been thinking some more about this, I have looked back over the Thread and I still don't understand the overall intention of your poject. I think you are focusing too much on HOW to do things rather than WHAT needs to be done.

I had a sailboat so I have some knowledge of an autopilot. My sense of the thing is that the fluxgate compass is fixed relative to the boat and the autopilot is told to steer (say) 89deg. If the compass is not showing 89deg it will operate the rudder so as to return the boat (and, indirectly) the compass to the desired heading.

I cannot relate your descriptions or your code to that concept. I don't even know what part of the system you are trying to test or exercise.

I guess one interpretation is that the second stepper motor is pretending to be a platform on which the boat rotates (and brings the compass with it). But the problem I have with that is that the autopilot must move the rudder, not spin the boat on its axis. And an important aspect of an autopilot is the time that is allowed for the boat to regain its course and the damping to prevent hunting.

Maybe if you try to describe how your tests would work if you actually had a boat it would be easier to understand.

...R

I have been thinking some more about this, I have looked back over the Thread and I still don't understand the overall intention of your poject. I think you are focusing too much on HOW to do things rather than WHAT needs to be done.

As I have mentioned earlier this project is for simulation of the nav. autopilot automation and demonstration (training purposes for students), so they be able to see what is actually going on in autopilot mode and in nav mode, in relation to the navigational autopilot processor handles signals from the heading sensor(fluxgate) and outputs the correct signal to the rudder to correct the shipshead.

[iI had a sailboat so I have some knowledge of an autopilot. My sense of the thing is that the fluxgate compass is fixed relative to the boat and the autopilot is told to steer (say) 89deg. If the compass is not showing 89deg it will operate the rudder so as to return the boat (and, indirectly) the compass to the desired heading.
][/i]

Exactly right there, the boat is the fluxgate in this case, and keeps updating the autopilot processor with the shipshead.

I cannot relate your descriptions or your code to that concept. I don't even know what part of the system you are trying to test or exercise.

You are right the description of the codes I think it's only me that really knows what's going on. The codes are just to tell the first stepper to move rudder port or starboard that' it. And second stepper is just to turn the fluxgate once there is a readout on the pot that is built in inside the rudder reference unit.

I guess one interpretation is that the second stepper motor is pretending to be a platform on which the boat rotates (and brings the compass with it). But the problem I have with that is that the autopilot must move the rudder, not spin the boat on its axis. And an important aspect of an autopilot is the time that is allowed for the boat to regain its course and the damping to prevent hunting.

Yes fluxgate is the boat and will be fixed or drive by the second stepper on its axis. That's why the codes for the second stepper, it's speed is dependent how far the rudder is from 0, the more rudder the quicker the boat(fluxgate turnaround). And the codes can be manipulated to meet the specs of the autopilot processor unit and so thus the rate of change of the rudder. The autopilot can tell you if the rudder is too slow or too fast likewise with the fluxgate. Then you can fine tune your codes to meet all this.

Ok to sum this up I have proved it, it worked in my prototype but not very precise with dc motors and lots gear reduction involved to reduce the speed. Whereas with steppers they can go really slow with lots of torque and precise.

So I will get an ELEVEN and just use that to drive the second stepper and post you the results.
I thank you again for your response and in depth discussions with my project and I will post the results when I included another controller, cheers man.

Puno:
Yes fluxgate is the boat and will be fixed or drive by the second stepper on its axis. That's why the codes for the second stepper, it's speed is dependent how far the rudder is from 0, the more rudder the quicker the boat(fluxgate turnaround).

At the moment your mechanical system does not restore the rudder towards 0 as the compass moves towards the desired heading. There is a piece of your feedback system missing - unless you intend the human operator to fulfil that role.

So I will get an ELEVEN

What is an "ELEVEN" - please try to keep us in the loop :slight_smile:

...R