Pages: [1]   Go Down
Author Topic: Heya, help for project coding much appreciated  (Read 686 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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(smiley-cool; //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 smiley-wink

Peace,
Atomicdog
 smiley
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 360
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey,

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

THANKS!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
#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
Logged

Pages: [1]   Go Up
Jump to: