Connecting two programs into one

I have two sketches and each one of them are used for controlling the robotic arm. One of the programs is for automatic control and second for hand control by potentiometers. I am using two drivers. L298N and PCA9685. I want to make one program and be able to switch between them by using a 2 position switch. I used a function switch but it dont work well. If the robot is in automatic control I cant switch it to hand control. Below I attach the code. I dont know what I can do else?


#include <LedControl.h> 
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <AccelStepper.h>
#include <Stepper.h>

#define MIN_PULSE_WIDTH       650
#define MAX_PULSE_WIDTH       2350
#define FREQUENCY             50
#define STEPS 200

#define SERVOMIN  130 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  575 // this is the 'maximum' pulse length count (out of 4096)
#define Motor 4

byte button = 2;
byte programToRun;

uint8_t servonum = 0;

AccelStepper stepper = AccelStepper(Motor, 8, 9, 10, 11);
Stepper stepper_reczny(STEPS, 8, 9, 10, 11);
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();


int DIN = 5;
int CS = 6;
int CLK = 7;


//int state= digitalRead(button);

int controlservo1 = A1;
int controlservo2 = A2;
int controlservo3 = A0;
int controlservo4 = A4;
int controlservo5 = A3;

int previous = 0;
int bit1;

int motor1 = 0;
int motor2 = 4;
int motor3 = 8;
int motor4 = 12;
int motor5 = 15;

int mtrDegreeServo1;
int mtrDegreeServo2;
int mtrDegreeServo3;
int mtrDegreeServo4;
int mtrDegreeServo5;

LedControl screen = LedControl(DIN, CLK, CS, 0);


void setup() {

  screen.shutdown(0, false);
  screen.setIntensity(0, 15);
  screen.clearDisplay(0);

  pinMode(button, INPUT_PULLUP);

  pwm.begin();
  pwm.setPWMFreq(FREQUENCY);

  stepper.setSpeed(30);
  Serial.begin(115200);
  Serial.begin(9600);
  //Serial.println("16 channel Servo test!");
  stepper.setMaxSpeed(200);

  pwm.begin();
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates

  pwm.setPWM(0, 0, angleToPulse(50));
  delay(500);
  pwm.setPWM(4, 0, angleToPulse(90));
  delay(500);
  pwm.setPWM(8, 0, angleToPulse(60));//jest na równo człon 3
  delay(500);
  pwm.setPWM(12, 0, angleToPulse(60));//narzędzie
  delay(500);
  pwm.setPWM(15, 0, angleToPulse(130));


  delay(5000);

}



// Function to move motor to specific position
void moveMotorDeg(int moveDegree, int motorOut)
{
  int pulse_wide, pulse_width;

  // Convert to pulse width
  pulse_wide = map(moveDegree, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
  pulse_width = int(float(pulse_wide) / 1000000 * FREQUENCY * 4096);

  //Control Motor
  pwm.setPWM(motorOut, 0, pulse_width);
}

// Function to convert potentiometer position into servo angle
int getDegree(int controlIn)
{
  int potVal, srvDegree;

  // Read values from potentiometer
  potVal = analogRead(controlIn);

  // Calculate angle in degrees
  srvDegree = map(potVal, 0, 1023, 0, 180);

  // Return angle in degrees
  return srvDegree;

}



void loop() {

  //int state= digitalRead(button);

  if (digitalRead(button) == HIGH) {
    bit1 = 1;
    Serial.println("1");
  }
  else {
    bit1 = 0;
    Serial.println("0");
  }

  programToRun = bit1;

  switch (programToRun) {

    case 1:

      byte a[8] =

      {
        B00011000,
        B00111100,
        B01100110,
        B11000011,
        B11111111,
        B11111111,
        B11000011,
        B11000011
      };

      printByte(a);
      delay(1000);



      delay(200);

      stepper.setCurrentPosition(0);

      delay(1000);

      // Run the motor forward at 200 steps/second until the motor reaches 400 steps (2 revolutions):
      while (stepper.currentPosition() != -49)  {
        stepper.setSpeed(-20);
        stepper.runSpeed();
      }

      delay(1000);



      for ( int angle = 50; angle < 120; angle += 2) {
        delay(50);
        pwm.setPWM(0, 0, angleToPulse(angle));

      }

      delay(1000);

      for ( int angle = 90; angle > 60; angle -= 1.8) {
        delay(50);
        // Pozycja wyjścjowa
        pwm.setPWM(4, 0, angleToPulse(angle));

      }

      delay(1500);


      for ( int angle = 60; angle > 0; angle -= 1.8) {
        delay(50);
        pwm.setPWM(12, 0, angleToPulse(angle));

      }

      delay(1500);

      for ( int angle = 60; angle < 120; angle += 2) {
        delay(50);
        // Pozycja wyjścjowa
        pwm.setPWM(8, 0, angleToPulse(angle));

      }

      delay(1500);


      for ( int angle = 120; angle < 155; angle += 1.8) {
        delay(50);
        pwm.setPWM(0, 0, angleToPulse(angle));

      }

      // Run the motor forward at 200 steps/second until the motor reaches 400 steps (2 revolutions):
      while (stepper.currentPosition() != 5)  {
        stepper.setSpeed(10);
        stepper.runSpeed();
      }

      delay(1500);

      for ( int angle = 130; angle > 50; angle -= 1.8) {
        delay(50);
        pwm.setPWM(15, 0, angleToPulse(angle));
      }

      delay(1500);

      for ( int angle = 155; angle > 120; angle -= 1.8) {
        delay(50);
        pwm.setPWM(0, 0, angleToPulse(angle));

      }


      delay(1500);


      for ( int angle = 120; angle > 60; angle -= 2) {
        delay(50);
        // Pozycja wyjścjowa
        pwm.setPWM(8, 0, angleToPulse(angle));

      }

      delay(1000);

      // Run the motor backwards at 600 steps/second until the motor reaches -200 steps (1 revolution):
      while (stepper.currentPosition() != 40)   {
        stepper.setSpeed(20);//dla (-)silnik wzgledem osi pionowej jedzie w prawo
        stepper.runSpeed();
      }


      delay(500);

      break;


    case 0:

      byte b[8] =

      {
        B11111111,
        B11111111,
        B00011000,
        B00011000,
        B00011000,
        B00011000,
        B00011000,
        B00011000
      };

      printByte(b);

      // get the sensor value
      int val = analogRead(0);
      int step = map(val, 0, 1023, 0, STEPS);

      // move a number of steps equal to the change in the
      // sensor reading
      stepper_reczny.step(step - previous);

      // remember the previous value of the sensor
      previous = step;


      //Control Base Motor

      // Get desired position
      mtrDegreeServo1 = getDegree(controlservo1);
      // Move motor
      moveMotorDeg(mtrDegreeServo1, motor1);


      //Control Elbow Motor

      // Get desired position
      mtrDegreeServo2 = getDegree(controlservo2);
      // Move motor
      moveMotorDeg(mtrDegreeServo2, motor2);


      //Control Wrist Motor

      // Get desired position
      mtrDegreeServo3 = getDegree(controlservo3);
      // Move motor
      moveMotorDeg(mtrDegreeServo3, motor3);

      //Control Pivot Motor

      // Get desired position
      mtrDegreeServo4 = getDegree(controlservo4);
      // Move motor
      moveMotorDeg(mtrDegreeServo4, motor4);

      //Control Pivot 2 Motor

      // Get desired position
      mtrDegreeServo5 = getDegree(controlservo5);
      // Move motor
      moveMotorDeg(mtrDegreeServo5, motor5);

      break;


  }
}



int angleToPulse(int ang) {
  int pulse = map(ang, 0, 180, SERVOMIN, SERVOMAX); // map angle of 0 to 180 to Servo min and Servo max
  Serial.print("Angle: "); Serial.print(ang);
  Serial.print(" pulse: "); Serial.println(pulse);
  return pulse;
}

void printByte(byte character[])
{
  int i = 0;
  for (i = 0; i < 8; i++)
  {
    screen.setRow(0, i, character[i]);
  }
}

Welcome to the Forum!
Please insert your code using the code tags. You can go back and fix your original post.
Read the forum guidelines to see how to properly insert the code and some other good information on making a good post.

Regarding the problem - as far I see your codes contains a lot of delay() operators - it means that this codes can't be merged together.
You need to rewrite the codes first, getting rid all the delays.

Your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advice on) your project :wink: See About the Installation & Troubleshooting category.

Is Millis function will be correct for replacing delays?

Yes, but you have to restructure your code too so that it isn't blocking. Otherwise you could end up with something that just uses millis to create the same blocking delays.

Declaring variables inside a case is not a good idea:

    case 0:

      byte b[8] =

      {
        B11111111,
        B11111111,
        B00011000,
        B00011000,
        B00011000,
        B00011000,
        B00011000,
        B00011000
      };

For now it'd be easier for you to just declare the two instances as globals. Also, do yourself a favor and get in the habit of using more descriptive variable names than stuff like 'a'.

So can I instead of switch function, use if function and just check the button?

This is caused by the many many delay()s

I guess with writing

you mean only if the complete sequence of the automatic mode has been running through it switches to manual mode

Yes you can but this is the ugly way of doing it

The ugly way to get a fast response to the switch beeing changed is to add code

if (switch is in manual-mode) {
 break;
}

right before each and every single delay()

This will take maybe two or three hours including testing it

The elegant way is to take 5 to 10 hours time to

  • learn
    how millis() is used to code non-blocking timing

if beginners start using millis() they write blocking code again.

  • learn how state-machines based on switch-case-break work

  • learn how all looping can be done and
    MUST be done for non-blocking coding by void loop()

which means to rewrite almost all lines of code

Which way do you want to go?

best regards Stefan

additionally you should start learning how to define your own functions.
This is pretty simple.

Then your code will become much much easier to develop the code further and to maintain the code

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