Heya, help for project coding much appreciated

hey peeps,

im undergoing a project installation that requires the movement of two servos (180deg servo) , by a single infrared sensor (sharp analog infrared sensor).
In essence, two servos are attached to two different mechanical systems that both produce two different moving outcomes (done by each servo having different angle movements outcomes when the sensor is triggered). Instead of using two sensors, i was wondering if it is possible for the arduino to read a single analog infrared sensor then trigger each servo (with its own angle) at different promixities?

Through experimentation have made one servo move to its particular angle when activated by the sensor.
This is the code (for 1 servo, for 2nd servo the angles have been calibrated)


#include <Servo.h>
////servo layer 1-2////
Servo myservo;
int potPin = 0; //analog pin used to connect the sensor
int ledPin = 9; //select pin for the servo
int val = 0; //variable to read the value from the analog pin
void setup()
{
myservo.attach(9); //set up the servo as usual

pinMode(ledPin, OUTPUT); //variable to store the value coming from the sensor
Serial.begin(9600); //for watching the speeds in the serial monitor
}

void loop() {
val = analogRead(potPin); // read the value from the sensor
val = map(val,0,1023,0,179);
if (val>79) myservo.writeMicroseconds(1000);
else if (val<80) myservo.writeMicroseconds(1500);
//set servo to mid-point
Serial.println(val);
delay(1);

}


And furthermore, an attempt to implement the second servo


#include <Servo.h>

Servo myservo1; //first servo
Servo myservo2; //layer 2-3 servo

int potPin = 0; //analog pin ued to connect the sensor
int ledPin = 9; //select pin for the servo
int val = 0; //variable to read the value from the analog pin

void setup()
{
myservo1.attach(9); //set up the servo as usual first servo
myservo2.attach(8); //layer 2-3 servo

pinMode(ledPin, OUTPUT); //variable to store the value coming from the sensor

}

void loop() {

val = analogRead(potPin); // read the value from the sensor
val = map(val,0,200,0,179);
if (val>79) myservo1.writeMicroseconds(900); //set servo to mid-point
else if (val<80) myservo1.writeMicroseconds(2000);
delay(1);

val = analogRead(potPin); // read the value from the sensor
val = map(val,0,1023,0,179);
if (val>79) myservo2.writeMicroseconds(1000); //set servo to mid-point
else if (val<80) myservo2.writeMicroseconds(1500);
delay(1);

}


I have concerns that i may be heading in a totally wrong direction with regards to the coding (writeMicroseconds command), however
any suggestions would be appreciated, but please keep it in mind what it asked in the installation :wink:

Peace,
Atomicdog
:slight_smile:

Not too sure what you're trying to do here - the Sharp IR rangefinders have a nonlinear voltage response as compared to distance. If you give the model number we can give a generic function for converting analog readings to distances. You also only need to read the distance once.

In regards to your original question, something like this should suffice:

void loop() {
  uint16_t reading = analogRead(SHARP_IR_PIN);
  uint8_t distance = adc_to_cm(reading); // you will need to derive this function by measuring various distances and voltages and doing a regression analysis
  if (distance < 20) {
    myservo1.write(90);
  } else {
    myservo1.write(180);
  }
  if (distance < 15) {
    myservo2.write(90);
  } else {
    myservo2.write(0);
  }
}

Servo::writeMicroseconds(int) is a perfectly valid way to write positions to a servo, but is generally unnecessary and inconvenient if you're not using control loops that need the resolution. Servo::write(int) is much better, as it takes a parameter of an angle between 0 and 180 - significantly more intuitive.

Hey,

Thanks so much :wink:
I've got it working, but also understand the process whichi s quiet rewarding.

THANKS!

Here the solved code.
Enables different servos to move, independently, via different proximity readings with a single infrared sensor.

sharp infrared sensor found @ http://www.mindkits.co.nz/store/sensors/infrared-proximity-sensor-sharp-gp2y0a21yk

#include <Servo.h>

Servo myservo1; //first servo
Servo myservo2; //layer 2-3 servo

int SHARP_IR_PIN = 0; //analog pin used to connect the sensor
int ledPin = 9;  //select pin for the servo
int val = 0;  //variable to read the value from the analog pin
int adc_to_cm(int adc) {
  return 14251 * pow(adc,-1.17);
}

void setup()
{
  myservo1.attach(9); //set up the servo as usual first servo
  myservo2.attach(8); //layer 2-3 servo
  pinMode(ledPin, OUTPUT);  //variable to store the value coming from the sensor
  Serial.begin(9600);
}

void loop() {
  
  int reading = analogRead(SHARP_IR_PIN); // replace this pin with the analog pin your sensor is connected to
  int distance = adc_to_cm(reading);

  char buf[50];
  sprintf(buf, "Distance: %d, voltage: %.02f, adc: %d\r\n", distance, reading * 5.00 / 1024 , reading);
  Serial.print(buf);
  
  if (distance > 10) {
    myservo1.write(50);
  } else {
    myservo1.write(80);
  }
  if (distance < 50) {
    myservo2.write(150);
  } else {
    myservo2.write(45);
  }
  
delay(1);

}

Peace,
Atomicdog