Go Down

Topic: Servo object inside custom class not working (Read 217 times) previous topic - next topic

GreenOlive

Ah yeah sorry i hadn't seen that i was looking through the library folder of the IDE 0023, but you should take the AVR though the write() function is exactly the same in all versions, easiest should be to just add a version taking a float as an argument, i might not even bother about renaming the library for now (though be careful when updating the IDE) something like this would do
Code: [Select]
void Servo::writeFloat(float value)
{
  // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
  if (value < MIN_PULSE_WIDTH)
  {
    if (value < 0)
      value = 0;
    else if (value > 180)
      value = 180;
    value = (SERVO_MIN()+ (value * (SERVO_MAX() - SERVO_MIN()) ) / 180) ;
  }
  writeMicroseconds((int) value);
}

 and add the prototype to servo.h  hmm strange how they have identical functions in different files.
Or does the map() function takes floats as arguments (i rarely use it)
ok thanks ill try this. The map function takes a long as an argument, unless there is an overlaoded version they dont mention in the refrence.

well 1 degree is fairly accurate and usually already beyond what most people can manufacture for things that can be controlled. Anyway writing the pulse directly without the use of timers is still the most accurate. (and gives you the processors undivided attention for the rest of the time.)
by directly writing the pulse width do you mean this that you posted earlier?
Code: [Select]

digitalWrite(pin,HIGH);delayMicroseconds(500+pulselength);
digitalWrite(pin,LOW);
delay(20);


If you have any ideas why my class didnt work as id still like to know why in case i ever run into a similar problem.

Thanks for your help

Deva_Rishi

Quote
by directly writing the pulse width do you mean this that you posted earlier?
Yes i do, though this was a rather crude version of it. Normally you'd just check to see if 20ms have elapsed at least (rather than the delay(20) ) and you should send a pulse out through all your pins within the same section of code as to not hold up your program any longer than necessary (though doing it 1 at a time is fine as well and you can use that for testing)) and you should probably disable interrupts while you are measuring the pulselength  .
Quote
If you have any ideas why my class didnt work as id still like to know why in case i ever run into a similar problem.
nope sorry, it'ss not my specialty, but initiating an object that uses many other resources and doing that from within another class, it should be possible, but...
To 'Correct' you have to be Correct. (and not be condescending..)

GreenOlive

I have tried to edit the servo class but I am getting compile errors.

I added this to servo.cpp in the avr file:
Code: [Select]

void Servo::writeFloat(float value) {
if (value < MIN_PULSE_WIDTH)
{  // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
if (value < 0) value = 0;
if (value > 180) value = 180;
value = (SERVO_MIN() + (value * (SERVO_MAX() - SERVO_MIN())) / 180);
}
this->writeMicroseconds((int)value);
}


I defined the function in the servo.h file:

Code: [Select]

class Servo
{
public:
  Servo();
  uint8_t attach(int pin);           // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure
  uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes.
  void detach();
  void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
  void writeFloat(float value); //excepts a float value instead of integer
  void writeMicroseconds(int value); // Write pulse width in microseconds
  int read();                        // returns current pulse width as an angle between 0 and 180 degrees
  int readMicroseconds();            // returns current pulse width in microseconds for this servo (was read_us() in first release)
  bool attached();                   // return true if this servo is attached, otherwise false
private:
   uint8_t servoIndex;               // index into the channel data for this servo
   int8_t min;                       // minimum is this value times 4 added to MIN_PULSE_WIDTH   
   int8_t max;                       // maximum is this value times 4 added to MAX_PULSE_WIDTH   
};


And i tried to use it in my main program:

Code: [Select]

void setServos(float pos1, float pos2, float pos3, float pos4, float pos5 = 90, float pos6 = 90) {
shoulderIn.writeFloat(pos1);
shoulderOut.writeFloat(pos2);
upperArm.writeFloat(pos3);
elbow.writeFloat(pos4);
wristIn.writeFloat(pos5);
wristOut.writeFloat(pos6);

}


these were the errors i got

Compiling 'RobotArmControlV0.2' for 'Arduino/Genuino Uno'
 
cchP9XR8.ltrans0.ltrans.o*: In function setServos
RobotArmControlV0.2.ino:13: undefined reference to Servo  writeFloat(float)

Error linking for board Arduino/Genuino Uno
RobotArmControlV0.2.ino:14: undefined reference to Servo  writeFloat(float)
Build failed for project 'RobotArmControlV0.2'
RobotArmControlV0.2.ino:15: undefined reference to Servo  writeFloat(float)
RobotArmControlV0.2.ino:16: undefined reference to Servo  writeFloat(float)
RobotArmControlV0.2.ino:17: undefined reference to Servo  writeFloat(float)
cchP9XR8.ltrans0.ltrans.o*: C:\Users\olive\Documents\Arduino\RobotArmControlV0.1 - Copy\RobotArmControlV0.2\RobotArmControlV0.2.ino:18: more undefined references to Servo::writeFloat(float) follow
 
collect2.exe*: error: ld returned 1 exit status


I get the feeling i didnt define it properly but im not sure how.
thanks

Deva_Rishi

hmm maybe it's not the AVR file, i added to all servo.cpp 's and then this
Code: [Select]
#include <Servo.h>

Servo servo;

float var;

void setup() {

}

void loop() {
  servo.writeFloat(var);

}
compiles
To 'Correct' you have to be Correct. (and not be condescending..)

GreenOlive

aha! I found my problem, for some reason the Arduino IDE and visual studio cant access the default libraries so a while back I copied over the servo library to the 'client?' libraries. I was changing it the library that the compiler wasn't using. so I just updated the library in the right place. by then I had already put it in all the .cpp files so it might have been the avr one, but I don't feel like removing it from the others to find out.

Again thank you for your help, I really appreciate it.

Deva_Rishi

You're welcome ! yeah about running into a similar issue again, this i think is usually the best approach. Modify the existing library by adding a function. And better than just adding to the existing one, copy and rename the original (and it's references) and modify that one, so that when you update the IDE, your changes do not get overwritten.
To 'Correct' you have to be Correct. (and not be condescending..)

Go Up