0

this is my first time dealing with arduinos and I have a school assignment. I have a servo and a force sensor. When "1" (a character, not an integer) is typed in the serial monitor, the servo needs to rotate 180 degrees but can be interrupted when the force sensor sends a value over let's say 300. And when "0" is typed in, the servo goes back to its initial position. I have been trying really hard figuring this out.

I basically need to exit a loop when the analog value exceeds 300.

here's my code:

#include <Servo.h>
Servo myservo;

int initpos; //initial position of the servo before the sweep (this doesn't change) 
int angle; //used to store the servo angle value (this changes)
char code; //the value entered in the serial monitor
int force; //value of the analog force sensor

void setup() 
{
  initpos = 10;
  Serial.begin(9600);
  myservo.attach(4);

  myservo.write(170); // makes the servo sweep(absolutelly useless for my project but I left it there)
  delay(500);         //
  myservo.write(10);  //
  delay(500);         //

  code = Serial.read(); 


}

void loop() 
{

  if(Serial.available())
  {


    angle = initpos;
    force = analogRead(A1);
    Serial.println(force);

    for(angle = 0; angle < 180; angle += 1)
    {
      if (code == "1" and force <= 300)
      {
        angle += 1;
        Serial.print(code);
        myservo.write(angle);
      }

      else if(code == "0")
      {
        myservo.write(initpos);
      }
    }

  }
}

any help is deeply appreciated and if there is already a topic on this please redirect me to it

  • ask yourself this when is code in setup() executed? and when is code in loop() executed? – jsotola Mar 15 at 18:26
0

I've written this code without access to a compiler, so there might be errors. Use it as an idea how to solve the quest. Hopefully the comments are helpful. Don't hesitate to ask if you do not understand or correct me if you see an error.

#include <Servo.h>

Servo myservo;

// end positions of the servo    
// declared as constant values
const int minPos = 10; 
const int maxPos = 180; 

int servoAngle;

int force;
char code;

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

  myservo.attach(4);
  // move the servo to minPos
  // or whatever you want/need
  servoAngle = minPos;
  myservo.write( servoAngle ); 

  // PPK: keep code as simple as possible -> sweep removed

  // PPK: removed - this makes no sense here
  // code = Serial.read(); 
}

void loop() 
{
  // PPK: here you check if data is available (I added "> 0")
  if( Serial.available() > 0 )
  {
    // PPK: but you did not read the data
    // Let's do it
    char newCode = Serial.read(); 
    If ( newCode == '0' || newCode == '1' )
    {
      // only "0" and "1" are valid codes
      code = newCode;
    }
  }

  if ( code == '0' && servoAngle > minPos )      
  {
    servoAngle--;
    myservo.write( servoAngle );
  }
  else if ( code == '1' && servoAngle < maxPos )
  {
    force = analogRead( A1 );
    Serial.println( force );
    if ( force > 300 )
    {
      servoAngle--;

      // PPK: the next line is only necessary if you want the
      // servo to go towards the min position
      // if a force > 300 is detected
      // remove the line if you wish to 
      // hold the servo at the position where 
      // the force exceeds 300
      code = '0':
    }
    else
    {
      servoAngle++;
    }
    myservo.write( servoAngle );
  }
  // a little delay to slow down the servo
  // remove it if you want
  delay( 10 );
}

EDIT

If you intend to stop the servo if force > 300, you can add a flag that indicates the exceptional state.

#include <Servo.h>

Servo myservo;

const int minPos = 10; 
const int maxPos = 180; 

int servoAngle;

int force;
char code;
int flagServoStopped = 0;

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

  myservo.attach(4);
  servoAngle = minPos;
  myservo.write( servoAngle ); 
}

void loop() 
{
  if( Serial.available() > 0 )
  {
    char newCode = Serial.read(); 
    If ( newCode == '0' || newCode == '1' )
    {
      code = newCode;
    }
  }

  if ( flagServoStopped == 1 && code == '1' )
  {
    // The servo is frozen as long as the stop flag is set and
    // you have not entered a '0'.
    // leave the loop
    return;
  }

  // in case `code = '0'`, reset the flag if it is set.
  flagServoStopped = 0;

  if ( code == '0' && servoAngle > minPos )      
  {
    servoAngle--;
    myservo.write( servoAngle );
  }
  else if ( code == '1' && servoAngle < maxPos )
  {
    force = analogRead( A1 );
    Serial.println( force );
    if ( force > 300 )
    {
      flagServoStopped = 1;
    }
    else
    {
      servoAngle++;
      myservo.write( servoAngle );
    }
  }
  delay( 10 );
}
| improve this answer | |
  • Hi thanks for your help this is great! (idk if you saw my previous comment it was missleading). Unfortunately the servo is expected to stop when force > 300 and wait for 0 – Kiz0 Mar 15 at 21:06
  • @Kiz0 I've changed the code according to your last comment. – Peter Paul Kiefer Mar 16 at 9:19
  • Thank you for your help! This works perfectly and has saved me hours in my project! :) – Kiz0 Mar 16 at 14:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.