Rc submarine need help

hello every one i need help with my code. i have my stepper motor which is a kp35fm2-035, following values 0 to 14000, but if i have it turning to say 10000 and the vales change to 300 while it is still turning it will go to 10000 fist and only then change direction. i need help on how to make the stepper change the destination and direction if applicable right away so i dont have to wait for it to go to say 10000 and only then to 300

#include <Stepper.h>

#define RCPin 2
#define STEPS 200
//#define turning  {int preei = i - 1; stepper.step(preei);}
//#define ever (int i = 0; i <= stepperMapped; i++)
Stepper stepper(STEPS, 8, 9, 10, 11);

const float smoothingFactor = 0.1;  // smoothing factor between 0 and 1

int servoMin = 1000;              // minimum input value
int servoMax = 2000;              // maximum input value
int servoValue = 0;               // variable to store the servo/PWM value
int stepperPos = 0;
int preStepperPos = 0;

void setup() {
  Serial.begin(9600);
  stepper.setSpeed(150);
  pinMode(RCPin, INPUT_PULLUP);
}

void loop() {
  servoValue = pulseIn(RCPin, HIGH, 25000);
  if (servoValue != 0) {

    int servoMapped = map(servoValue, servoMin, servoMax, 0, 1000);

    // Stabilize the stepper position using exponential moving average
    stepperPos = smoothingFactor * servoMapped + (1 - smoothingFactor) * stepperPos;
    stepperPos = constrain(stepperPos, 0, 1000);

    int stepperMapped = map(stepperPos, 0, 1000, 0, 14000);

    stepper.step(stepperMapped - preStepperPos);
    preStepperPos = stepperMapped;

    // Output the stabilized servo value and stepper position
    Serial.print("\tStepper Position: ");
    Serial.println(stepperMapped);
  }
  delay(20);  // Add a small delay to prevent excessive loop iterations
}

it is bipolar stepper. bipolar stepper need stepper driver.

@ivannobodye

Some of this motor's information:

Do you have a motor driver board like the A4988 or DRV8825? Have you set the current limit of the driver board? Here is a link to the DRV8825... scroll down to "Current Limit" and follow that procedure before running the motor.

im using l298n

Get away from the Stepper library. The step function blocks. You either have to wait till it reaches its commanded position or step the motor one step st a time. There are several stepper libraries that have non-blocking motion. AccelStepper and MobaTools are a couple. I like MobaTools.

I second the recommendations of @xfpd. The L298 is a totally inappropriate driver for that stepper. An A4988 or DRV8825 (or similar) step/dir current controlling type driver would be much better.

The coil current limit on the above drivers must be set properly before use.

The stepper motor basics tutorial may be of interest.

could you give me an example code pls thank you

Here is an example using the MobaTools library and methods and code from the Serial input basics tutorial to illustrate non-blocking stepper code. You can use the serial monitor to change the absolute position of the stepper, the relative position of the stepper and the speed of the stepper by serial command. You can tell the stepper to go to 10000, then while it is moving send a new position command or speed and the stepper will immediately obey. This code has been tested on real hardware. The hardware consists of an Uno with a CNC shield that holds a DRV8825 STEP/DIR type stepper driver. The motor is a NEMA 17 set to 1.0A coil current and a 12V motor supply.

#include <MobaTools.h>

const byte stepPin = 2;
const byte dirPin = 5;
const byte enablePin = 8;

const byte numChars = 32;
char receivedChars[numChars];

const unsigned int motorStepsPerRev = 200;
const unsigned int microstepMultiplier = 4;
const int STEPS_REVOLUTION = motorStepsPerRev * microstepMultiplier;

MoToStepper myStepper( STEPS_REVOLUTION, STEPDIR );

boolean newData = false;

void setup()
{
   Serial.begin(115200);

   myStepper.attach( stepPin, dirPin );
   myStepper.attachEnable(enablePin, 0, 1);
   myStepper.setSpeed(100);  // rpm /10, 100 = 10 RPM
   myStepper.setRampLen(10);
   myStepper.setZero();

   Serial.println("Enter p,x = absolute position (steps), t,x = relative positinon and s,x = speed (RPM)");
   Serial.println("Example p,3000 will move, absolute, to 3000 if already at 3000 nothing will happen");
   Serial.println("Example t,3000 will move, relative, 3000 steps,  if already at 3000 will move to 6000");   
}

void loop()
{
   recvWithEndMarker();
   //showNewData();
   if (newData)
   {
      parseData();
   }

} // ################4444444444444$$$$$$$$$$$$$&&&&&&&&&&&&&&&&

void moveStepsSerialRelative(long steps)
{
   Serial.print("moving steps >> ");
   Serial.println(steps);
   myStepper.move(steps);
}

void moveStepsSerialAbsolute(long steps)
{
   Serial.print("moving steps >> ");
   Serial.println(steps);
   myStepper.moveTo(steps);
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '\n';
   char rc;

   while (Serial.available() > 0 && newData == false)
   {
      rc = Serial.read();
      if (rc == '\r') // ignore carruage return
      {
         return;
      }
      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numChars)
         {
            ndx = numChars - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string
         ndx = 0;
         newData = true;
      }
   }
}

void showNewData()
{
   if (newData == true)
   {
      Serial.print("This just in ... ");
      Serial.println(receivedChars);
      //newData = false;
   }
}

void parseData()
{
   char *strings[3]; // an array of pointers to the pieces of the above array after strtok()
   char *ptr = NULL; byte index = 0;
   ptr = strtok(receivedChars, ",");  // delimiters, comma
   while (ptr != NULL)
   {
      strings[index] = ptr;
      index++;
      ptr = strtok(NULL, ",");
   }
   /*
      Serial.println("The Pieces separated by strtok()");
      for (int n = 0; n < index; n++)
      {
      Serial.print("piece ");
      Serial.print(n);
      Serial.print(" = ");
      Serial.println(strings[n]);
      }
   */

   if (tolower(receivedChars[0]) == 'p')
   {
      long s = atol(strings[1]);
      Serial.print("Steps >> ");
      Serial.println(s);
      moveStepsSerialAbsolute(s);
   }

   else if (tolower(receivedChars[0]) == 't')
   {
      long s = atol(strings[1]);
      Serial.print("Steps >> ");
      Serial.println(s);
      moveStepsSerialRelative(s);
   }

   else if (tolower(receivedChars[0]) == 's')
   {
      int a = atoi(strings[1]);
      Serial.print("Speed>> ");
      Serial.println(a);
      myStepper.setSpeed(a);
   }

   else
   {
      Serial.println("invalid input");
   }
   newData = false;
}

To see how fast the code will respond to a new command, send a long slow forward move like
s,200, enter // speed 20 RPM
then
p,10000, enter // to 10000 steps absolute
then
t, -200, enter // 200 steps in reverse
the motor should immediately reverse.

thank you very much for the code how would i incorporate my pulse in function that i am using to read signals from the rc recerver and then use those values to turn the stepper. could you help me out pls

Here you go. This compiles but is untested. I really dislike posting code that I cannot test so if it does not do what you want or messes something up I will bear no responsibility.

#include <MobaTools.h>

const byte RCPin = 2;  //I don't like define for variables
const byte stepPin = 8; // change to suit
const byte dirPin = 9;  // change to suit


#define STEPS 200
//#define turning  {int preei = i - 1; stepper.step(preei);}
//#define ever (int i = 0; i <= stepperMapped; i++)

const unsigned int STEPS_REVOLUTION = 200; // no microstepping

MoToStepper stepper( STEPS_REVOLUTION, STEPDIR );

const float smoothingFactor = 0.1;  // smoothing factor between 0 and 1

int servoMin = 1000;              // minimum input value
int servoMax = 2000;              // maximum input value
int servoValue = 0;               // variable to store the servo/PWM value
int stepperPos = 0;
int preStepperPos = 0;

void setup()
{
   Serial.begin(9600);

   pinMode(RCPin, INPUT_PULLUP);

   stepper.attach( stepPin, dirPin );
   stepper.setSpeed(100);  // rpm /10, 100 = 10 RPM
   stepper.setRampLen(10); // acceleration
   stepper.setZero(); // set reference position
}

void loop()
{
   static unsigned long timer = 0;
   unsigned interval = 20;
   if (millis() - timer >= interval)
   {
      timer = millis();
      servoValue = pulseIn(RCPin, HIGH, 25000);
      if (servoValue != 0)
      {

         int servoMapped = map(servoValue, servoMin, servoMax, 0, 1000);

         // Stabilize the stepper position using exponential moving average
         stepperPos = smoothingFactor * servoMapped + (1 - smoothingFactor) * stepperPos;
         stepperPos = constrain(stepperPos, 0, 1000);

         int stepperMapped = map(stepperPos, 0, 1000, 0, 14000);

         stepper.move(stepperMapped - preStepperPos);  
         preStepperPos = stepperMapped;

         // Output the stabilized servo value and stepper position
         Serial.print("\tStepper Position: ");
         Serial.println(stepperMapped);
      }
   }
 // I hate delay so use the blink without delay instead, this code doesn't block
//delay(20);  // Add a small delay to prevent excessive loop iterations
}

Non-blocking timing tutorials:
Blink without delay().
Blink without delay detailed explanation
Beginner's guide to millis().
Several things at a time.

Just a Q, how will the RC part work submerged? Not sure how far radio penetrates slightly conductive liquid? Any data?
I see kits, so I guess it must work. Who'da thunk it?

RC subs work fine... depending.
I made one many years ago, and the limitation was the murkiness of the pond water.

The main factors are salt water vs fresh water, as well as the signal frequency.
In fresh water, with the appropriate transmitter, one can get about 10' of depth. I added a failsafe to mine to make it surface if signal was lost.

Mind you, this was in the pre-historic days of 75 MHz transmitters. The current 2.4 GHz will have shallower depth, but I don't know exactly how deep.

thank you for the code

i am using 72 MHz so it should penetrate quite far defenetly farther than 2.4 GHz

would i need to add this or no?
myStepper.attachEnable(enablePin, 0, 1);

You can if you want to be able to write pin 8 (enablePin) HIGH to disable the driver output stage (turn off power to the stepper) to save power.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.