Pages: [1] 2   Go Down
Author Topic: SOLVED: Devantech SD21 servo contr. and desperate programmer, after one year...  (Read 3662 times)
0 Members and 1 Guest are viewing this topic.
Espoo, Finland
Offline Offline
God Member
*****
Karma: 6
Posts: 586
"Oops, try again..."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all!

This is almost ridiculous, but I have to ask for help.

Our robot is getting close to a point, where the Madam of the house is ready to consider it as member of a family. Well, new born child is smarter and cuter, but hey, beauty is in the eye of the beholder, right?

Anyway, here's the problem.
SD21 takes the value for the servo position in to bytes. I have tested that it works both ways, so the mathematic is probably right.

What happens, is that when I increase the value by one on each round, servo jumps MUCH TOO MUCH when the value goes from 1529 to 1530, an daround 1540-1544 it jumps back to where it actually should be. We have to controllers, same thing. Maybe firmware problem, maybe something that I can't see in this code.

Here is my old faithful test code, this time even shorter, but functioning.

EDIT. Corrected 255 to 256
Code:
#include <Wire.h>
#define SD21 0x61 //SD21 I2C Address, shifted by one bit from original 0xC2:sta

byte ServoHigh, ServoLow;
int Pos_ms=1400;
int ServoNro=0;
int Luku;


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

void loop()
{
  Pos_ms=Pos_ms+1;

  if (Pos_ms > 1600)
  {
    Pos_ms=1400;
  }

  ServoHigh   =  byte(Pos_ms / 256);
  ServoLow    =  byte(Pos_ms - ServoHigh);

  Wire.beginTransmission(SD21);
  Wire.send(0);                 //Speed Servo 0
  Wire.send(30);
  Wire.endTransmission();

  Wire.beginTransmission(SD21);
  Wire.send(1);                 // Servo 0, Low Byte to Register 1
  Wire.send(ServoLow);          
  Wire.endTransmission();

  Wire.beginTransmission(SD21);
  Wire.send(2);                 // Servo 0, High Byte to Register 2
  Wire.send(ServoHigh);
  Wire.endTransmission();

  delay(100);
}


Electric is ok, Arduino only controls this module through I2C, controller's power is guarantee. But all servo channels do this.

Problem appears today when we started to fine tune arm positions, step by step incremental with the servo positioning.

As usual, any advice is welcome!
Thanks!

Cheers,
Kari
« Last Edit: January 15, 2012, 03:59:04 am by GaryP » Logged


The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"

Offline Offline
Full Member
***
Karma: 1
Posts: 152
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Change 255 to 256
Logged

Espoo, Finland
Offline Offline
God Member
*****
Karma: 6
Posts: 586
"Oops, try again..."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh sh...!!!!

Thank you, that was too obvious, and very typical mistakes I do all the time!
And my co-pilot needs to some lecturing too! He is supposed to watch after my coding!!!!

Thank you once more!

Cheers,
Kari
Logged


The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"

Espoo, Finland
Offline Offline
God Member
*****
Karma: 6
Posts: 586
"Oops, try again..."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Justone,
It was a good advice, but only thing that changed was the point where the error appears, it is now from 1535 to 1536 moves ahead, and from 1541 to 1542 brings back.

That's not funny... I just need to sleep over the night and try to figure it out again.
 smiley-confuse

Cheers,
Kari
Logged


The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"

Offline Offline
Full Member
***
Karma: 1
Posts: 152
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just did a quick glance at first but now I see you are extracting the low and high bytes from Pos_ms. Why not just use the lowbyte and highbyte functions on your Pos_ms integer.
Logged

Espoo, Finland
Offline Offline
God Member
*****
Karma: 6
Posts: 586
"Oops, try again..."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

justone,

Still learning. Tried shifting 8 bit to right, and it did the same thing.

Now I have tested all points where it goes wrong, and there is a pattern. I just can not see what causes it.
It jumps every time in two pairs. Something really simple?
The first number is right, then from second to third wrong, and right again. After every set the second pair is +1 further.


Code:
511  0000 0001 1111 1111
512  0000 0010 0000 0000
513  0000 0010 0000 0001
514  0000 0010 0000 0010

767  0000 0010 1111 1111
768  0000 0011 0000 0000
770  0000 0011 0000 0010
771  0000 0011 0000 0011

1023 0000 0011 1111 1111
1024 0000 0100 0000 0000
1027 0000 0100 0000 0011
1028 0000 0100 0000 0100

1279 0000 0100 1111 1111
1280 0000 0101 0000 0000
1284 0000 0101 0000 0100
1285 0000 0101 0000 0101

1535 0000 0101 1111 1111
1536 0000 0110 0000 0000
1541 0000 0110 0000 0101
1542 0000 0110 0000 0110

1791 0000 0110 1111 1111
1792 0000 0111 0000 0000
1798 0000 0111 0000 0110
1799 0000 0111 0000 0111

2047 0000 0111 1111 1111
2048 0000 1000 0000 0000
2055 0000 1000 0000 0111
2056 0000 1000 0000 1000

2303 0000 1000 1111 1111
2304 0000 1001 0000 0000
2312 0000 1001 0000 1000
2313 0000 1001 0000 1001

Cheers,
Kari
Logged


The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"

Espoo, Finland
Offline Offline
God Member
*****
Karma: 6
Posts: 586
"Oops, try again..."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

justone,

That did it. No I can finally go to sleep.
My math sucks...

Code:
  ServoHigh   =  highByte(Pos_ms);
  ServoLow    =  lowByte(Pos_ms);

Thanks man!

Cheers,
Kari
Logged


The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"

Espoo, Finland
Offline Offline
God Member
*****
Karma: 6
Posts: 586
"Oops, try again..."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After night everything is clear(er)...

That original code was from one year back, when I had even more problems with coding C. I haven't altered the code, so I have had the problem from the beginning.
We are starting to rewrite some of the code again, just to see what we didn't see in the beginning. From VB-programmer to C-programmer, it's not a long way if you think logically, but syntax is like hell to learn.

Original code had two mistakes, at least, but in this part

Code:
ServoHigh   =  byte(Pos_ms / 255);
 ServoLow    =  byte(Pos_ms - ServoHigh);

Should be:
Code:
ServoHigh   =  byte(Pos_ms / 256);
 ServoLow    =  byte(Pos_ms - (ServoHigh*256));

But nobody does it like this, I just did for some reason, can't remember what was in my thoughts a year back. Must have been terrible hurry to just do something that moves... well, no more.

Time to try find more flaws from three different codes that works with each other, I2C communication and home brewed "protocol", PITA.

Cheers,
Kari
Logged


The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"

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

Just this solved an issue for me too, thanks.
Logged

Espoo, Finland
Offline Offline
God Member
*****
Karma: 6
Posts: 586
"Oops, try again..."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just this solved an issue for me too, thanks.

Weel, that is great! What exactly was your problem?
We've had so many brain farts so far, I can't even remember all stupid mistakes found and corrected, by try and learn method.

Cheers,
Kari
Logged


The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"

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

I was having issues with the high/low byte as well, turned out I found the worlds worst example of interfacing the SD21 and Arduino.
 If I could remember where I found it I would post a warning.   This post and quick test program had my servos working perfectly, in about 15 minutes, well except for speed but I can figure that out.

I am trying to build a graceful start and end leg positioning for a hexapod, basically an unfold from storage to start and a refold to finish. 

Servo speed is a key component, as well as battery life to know when to shutdown once it is autonomous.
Logged

Espoo, Finland
Offline Offline
God Member
*****
Karma: 6
Posts: 586
"Oops, try again..."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok!
Have you been playing with SD21 a lot? We seem to have some problems with getting
absolute positions for servos, one day middle position is not where it was yesterday.

We have to recalibrate some servos every now and then to get them where they belong
at the start, to get safe combination for the joints of the robots arms. One thing that
is still to do, is the change of the source voltage.

If you experience any similar symptoms, it would great if you tell us about that.
I don't know how widely this board is used, but it's quite hard to believe that the problem
lies in it.

Cheers,
Kari
Logged


The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"

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

I have not noticed that so far, but  I will pay attention.  For power I am using a 7.4 Volt 2500 Lipo, with a 15c discharge rate.

But you can have 2 different issues the servos themselves, poorly made or cheap servos do not always get to the same point every time.

If it is power, you should be able to isolate it by raising your bot, removing all but 1 leg, actually remove the servos from the board. Run a few cycles and see where you end up.  If all is good keep adding legs back, until things start going off, at that point isolate just that leg.

If it all works ok in isolation then you have a power issue.

It is a pain in the but though.
Logged

Espoo, Finland
Offline Offline
God Member
*****
Karma: 6
Posts: 586
"Oops, try again..."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

We tested it with single servo only, and the position didn't change with less power consumption. We have probably 5 kind of different servos at this moment used, quite cheap models all.

When our big picture is ready, we start to check the problem, now our hands are full with combining  all four arduinos to work with each other.

I promise to tell if any progress happens with SD21.

Cheers,
Kari
Logged


The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"

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

Just a small up date, I have a little routine that pops all 6 legs of my hexapod to neutral positions, works fine in it's own little sketch.

Move it over to a larger sketch to be used as servo initialization it it does not always function correctly, similar to your issue with servos not returning to the exact same point.    I have a little more debugging to do, but I will keep this updated.
Logged

Pages: [1] 2   Go Up
Jump to: