Shop OBEX P1 Docs P2 Docs Learn Events
The function "servo_get" can't stored more than 7 servo's degree — Parallax Forums

The function "servo_get" can't stored more than 7 servo's degree

bsnatubsnatu Posts: 7
edited 2013-09-14 10:52 in Learn with BlocklyProp
I write the program with Propeller C to control the Hexapod robot.
But it still can't work...
Is this function just only can store 7 servos' degree?
https://code.google.com/p/propsideworkspace/source/browse/Learn/Simple Libraries/Motor/libservo/servo.c?r=4718b5a6c19f4be616a801772b1f43d896c82544&spec=svn4718b5a6c19f4be616a801772b1f43d896c82544

servo 7.png
servo 8.png


How could I slove it?
1015 x 568 - 55K
947 x 564 - 53K

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2013-09-05 23:33
    The program listed only provides for 7 slots you can control. This may be an arbitrary limitation or something which is imposed by the underlying servo cog. Checking the documentation we find:
    Control servos in other cog. Currently up to 7, but more should be coming soon.
  • bsnatubsnatu Posts: 7
    edited 2013-09-05 23:44
    Thank you very much!!
  • edited 2013-09-06 21:35
    Hi bsnatu,

    Here is a test library that runs up to 14 servos, and you can use it with the existing library to get up to 21. It should be pretty easy to modify it for 28, but I'm out of time until later next week. The one bug I know of is that the servo14_ servos need to be initialized before the servo_ servos. Please let me know if you find any more. Aside from changing servo to servo14 at the beginning of function names, the rest of the API is the same for both libraries.

    These instructions assume you have SimpleIDE v0.9.43. If you have an older version, update at http://learn.parallax.com/propeller-c-set-simpleide. Before running the installer, make sure to rename your existing .../Documents/SimpleIDE folder so that when you run SimpleIDE, it'll copy the latest SimpleIDE folder into documents. If you have a Mac, you may also want to Tools -> Properties -> General -> Clear Settings -> OK then restart SimpleIDE.

    Next, just copy the libservo14 folder from the attached zip to Documents\SimpleIDE\Learn\Simple Libraries\Motor. If SimpleIDE is open, you'll need to restart it. Then, make sure you are in Simple View (default view), click New Project, name & save, paste code below in, and run. It's controlling 20 servos.
    #include "simpletools.h"
    #include "servo.h"
    #include "servo14.h"
    
    int main()
    {
      servo14_set(0, 700);
      servo14_set(1, 800);
      servo14_set(2, 900);
      servo14_set(3, 1000);
      servo14_set(4, 1100);
      servo14_set(5, 1200);
      servo14_set(6, 1300);
      servo14_set(7, 1400);
      servo14_set(8, 1500);
      servo14_set(9, 1600);
      servo14_set(10, 1700);
      servo14_set(11, 1800);
      servo14_set(12, 1900);
      servo14_set(13, 2000);
    
      servo_set(14, 2100);
      servo_set(15, 2200);
      servo_set(16, 2300);
      servo_set(17, 650);
      servo_set(26, 750);
      servo_set(27, 850);
    
      pause(2000);
    
      int pulse;
      while(1)
      {
        for(int i = 0; i < 14; i++)
        {
          pulse = servo14_get(i);
          pulse += 100;
          if(pulse > 2300) pulse = 700;
          servo14_set(i, pulse);
        }
    
        for(int i = 14; i < 17; i++)
        {
          pulse = servo_get(i);
          pulse += 100;
          if(pulse > 2300) pulse = 700;
          servo_set(i, pulse);
        }
        pause(100);
      }
    }
    

    Regards, Andy
  • kuronekokuroneko Posts: 3,623
    edited 2013-09-07 19:33
    Here is a test library that runs up to 14 servos, and you can use it with the existing library to get up to 21.
    In servo14.c function servo14_set we find this:
    [COLOR="#FFA500"]if(i == s)[/COLOR]                                  // Not existing servo14?
      [COLOR="#FFA500"]{[/COLOR]
        for(i= 0; i < s; i++)                     // Look for empty slot
        {
          if(p[i]==-1)                            // Found one?
          {
            break;                                // Exit for loop, keep index
          }
        }
        [COLOR="#FF0000"]if(i <= s)[/COLOR]                                // Found empty slot?
        {
          p[i] = pin;                             // Set up pin and pulse durations
          t[i] = time;
          tp[i] = time;
          lockclr(lockID);                        // Clear the lock 
          return 1;                               // Return success 
        }
        else                                      // servo14 not found, no empty slots?
        {
          lockclr(lockID);                        // Clear lock
          return 0;                               // Return, set not completed
        }
      [COLOR="#FFA500"]}[/COLOR]
    
    we only get there when i equals s so the outer if is redundant. What's more worrying is the i <= s expression. When no empty slot is found then i equals s which would access an out of range array element (s == 14, index 0..13). I'd put the found slot code inside the loop (instead of the break), i.e. same style as pin match above (not shown).
  • bsnatubsnatu Posts: 7
    edited 2013-09-08 19:53
    The "servo14.h" is useful.
    But I have other question, in this example http://learn.parallax.com/propeller-c-functions/multicore-example
    When I first time call the function "cogstart", it will use "cog2" not "cog1."
    So, it means in the main function the chip use 2cogs, "cog0" & "cog1", right?
    what's reason will cause that?
  • kuronekokuroneko Posts: 3,623
    edited 2013-09-08 20:32
  • bsnatubsnatu Posts: 7
    edited 2013-09-08 22:27
    So, I can't use the print & float point...it is not a good news.
    But when I use that the cog will start on cog3, 4....for six legs, the 6th leg cog=-1, so it can't work.
    If I cancel the print & float point the cog will start on 2 or 1?
    #include "simpletools.h"                      // Include simpletools header
    #include "servo.h"
    #include "servo14.h"
    void R1servo (void *par);
    void R2servo (void *par);
    void R3servo (void *par);
    void L1servo (void *par);
    void L2servo (void *par);
    void L3servo (void *par);
    static volatile int R1_SS, R1_RD, R1_VA, R1_S1, R1_S2;
    static volatile int R2_SS, R2_RD, R2_VA, R2_S1, R2_S2;
    static volatile int R3_SS, R3_RD, R3_VA, R3_S1, R3_S2;
    static volatile int L1_SS, L1_RD, L1_VA, L1_S1, L1_S2;
    static volatile int L2_SS, L2_RD, L2_VA, L2_S1, L2_S2;
    static volatile int L3_SS, L3_RD, L3_VA, L3_S1, L3_S2;
    static volatile int Velocity, Tp, Tr, PowerRa, ReturnRa, PowerSpeed, ReturnSpeed;
    //static volatile float Velocity, Tp, Tr, PowerRa, ReturnRa, PowerSpeed, ReturnSpeed;
    static volatile int Gait;
    unsigned int R1servoarr[40 + 200];
    unsigned int R2servoarr[40 + 200];
    unsigned int R3servoarr[40 + 200];
    unsigned int L1servoarr[40 + 200];
    unsigned int L2servoarr[40 + 200];
    unsigned int L3servoarr[40 + 200];
    int main()                                    // main function
    {
      R1_SS=1, R1_RD=1, R1_VA=1;
      R2_SS=0, R2_RD=0, R2_VA=0;
      R3_SS=1, R3_RD=1, R3_VA=1;
      L1_SS=0, L1_RD=0, L1_VA=0;
      L2_SS=1, L2_RD=1, L2_VA=1;
      L3_SS=0, L3_RD=0, L3_VA=0;
      Gait=1;
      Velocity=8;     //Velocity=7.707;
      Tp=16/Velocity;     //Tp=15.17/Velocity;
      Tr=Tp/Gait;
      PowerRa=1000*Tp/4;
      ReturnRa=100*Tr/2;
      PowerSpeed=(22500/PowerRa)/5;
      ReturnSpeed=(22500/ReturnRa)/5;
    
    
      servo14_angle(0, 1800);    //pin 0=>UP/DOWN
      servo14_angle(1, 450);    //pin 1=>FORWARD/BACK
      R1_S1 = servo14_get(0);
      R1_S2 = servo14_get(1);
       
      pause(2000);
       cogstart(&R1servo, NULL, R1servoarr, sizeof(R1servoarr));   
       cogstart(&R2servo, NULL, R2servoarr, sizeof(R2servoarr));
       cogstart(&R3servo, NULL, R3servoarr, sizeof(R3servoarr));
       cogstart(&L1servo, NULL, L1servoarr, sizeof(L1servoarr));
       cogstart(&L2servo, NULL, L2servoarr, sizeof(L2servoarr));
       cogstart(&L3servo, NULL, L3servoarr, sizeof(L3servoarr));
      
    while(1)
    {
      /*print("R1S1 position = %d\n",R1_S1);
      print("R1S2 position = %d\n",R1_S2);
      print("\n");*/
      pause(2000);
    }
    }
    
  • kuronekokuroneko Posts: 3,623
    edited 2013-09-09 00:15
    bsnatu wrote: »
    So, I can't use the print & float point...it is not a good news.
    But when I use that the cog will start on cog3, 4....for six legs, the 6th leg cog=-1, so it can't work.
    Why do you think you need one cog per servo? The servo library can control more than one servo per cog so it would seem wasteful not to use this feature.
  • bsnatubsnatu Posts: 7
    edited 2013-09-09 02:06
    kuroneko wrote: »
    Why do you think you need one cog per servo? The servo library can control more than one servo per cog so it would seem wasteful not to use this feature.

    Oh...My advisor hope me can try what different between 1 cog and 6 cogs, which is better when the hexapod robot walking.
    It seem like I don't need 6 cogs for the robot.
  • edited 2013-09-11 17:18
    Since we have a working example that controls 20 servos with three cogs, and only 18 are needed for hexapod control, I'm going to mark this "solved".

    @bsnatu,

    The current solution uses a total of three cogs, one for executing the main function (orchestrating motions) and two for controlling the 18 servos. That's because servo14 and servo each use one cog apiece. If your adviser is suggesting that you develop a single cog implementation and compare to the three cog implementation, it is doable and sounds like an interesting project.

    @kuroneko,

    Thank you very much for pointing out the out of range bug. I'll fix it and post the update soon.

    Andy
  • edited 2013-09-14 10:52
    Alright, let's try these. In addition to kuroneko's fixes (thanks kuroneko!) the servo library now controls up to 14 servos, and the servoAux library can be used to control up to 14 more servos for a total of 28.

    To run the 28 servo signal example below, make sure to remove the libsrevo and libservo14 (if you have it) folders from ...Documents/SimpleIDE/Learn/Simple Libraries/Motor. Then, copy the libservo and libservoAux folders from the attached zips into that folder. If you have SimpleIDE running, make sure to restart it. Then, click New Project, name and save it, paste this code in, and click Load EEPROM & Run:
    /*
      Control 28 Servos.c
    */
    
    #include "simpletools.h"
    #include "servo.h"
    #include "servoAux.h"
    
    static int pin, pulse;
    
    int main()
    {
      for(pin = 0; pin < 14; pin++)
      {
        pulse = 500 + (pin * 100);
        servo_set(pin, pulse);
      }
    
      for(pin = 15; pin < 28; pin++)
      {
        pulse = 500 + (pin * 100);
        servoAux_set(pin, pulse);
      }
    
      pause(2000);
    
      while(1)
      {
        for(pin = 0; pin < 14; pin++)
        {
          pulse = servo_get(pin);
          pulse += 100;
          if(pulse > 2300) pulse = 700;
          servo_set(pin, pulse);
        }
    
        for(int pin = 14; pin < 28; pin++)
        {
          pulse = servoAux_get(pin);
          pulse -= 100;
          if(pulse < 600) pulse = 2300;
          servoAux_set(pin, pulse);
        }
        pause(100);
      }
    }
    
Sign In or Register to comment.