OpenServo.com Forum Index OpenServo.com
Discussion of the OpenServo project
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

OpenServo V4 (was OpenServo V3.x hardware update)
Goto page Previous  1, 2, 3 ... 12, 13, 14, 15  Next
 
Post new topic   Reply to topic    OpenServo.com Forum Index -> Hardware
View previous topic :: View next topic  
Author Message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Thu Oct 10, 2013 9:34 am    Post subject: Reply with quote

Status Update:

I have designed new encoder boards that do not use any through holes for the wire connections, rather SMD pads as there is no room under the board for the bottom of these and they will otherwise short out to the metal of the potentiometer housing. This means I no longer need a mylar (polyester) sheet below the PCB to prevent short circuits!!!

I have also changed the encoder to run in fast mode and I am getting much better readings (more accurate), but I need to move the polling of the encoder from a thread in the RTOS to a timer driver interrupt as the thread is only sampling 205 times per second and this is too slow and generates over-shoot in the servo.

Before I do this I will re-read the RTOS documenation to see if I can set the speed at which the threads swap (noting I already have the encoder reading thread at the highest priority).

When this is sorted I can:
(1) complete the code for the servo,
(2) Modify the bootloader to enable it to be called from application itself so a user can replace the application and / or the bootloader.
(3) Write the code for the 3-axis accelerometer (which initially will simply allow the host to read it)
(4) complete the interface (perhaps move it to a binary only, or ASII/human usable + switchable to a binay interface.
(5) Minaturise the board to preferably a single board that will squeeze into a standard servo.
Cheers
Douglas
Back to top
View user's profile Send private message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Sat Oct 12, 2013 3:17 am    Post subject: Reply with quote

I have reduced the Timer Tick for RTX and this has significantly sped up the number of times a thread is executed in a second (in RTX_Conf_CM.c which is a configuration file for RTX):

Code:

// <h>RTX Kernel Timer Tick Configuration
// ======================================
// <q> Use Cortex-M SysTick timer as RTX Kernel Timer
// <i> Use the Cortex-M SysTick timer as a time-base for RTX.
#ifndef OS_SYSTICK
 #define OS_SYSTICK     1
#endif
//
//   <o>Timer clock value [Hz] <1-1000000000>
//   <i> Defines the timer clock value.
//   <i> Default: 12000000  (12MHz)
#ifndef OS_CLOCK
 #define OS_CLOCK    48000000
#endif

//   <o>Timer tick value [us] <1-1000000>
//   <i> Defines the timer tick value.
//   <i> Default: 1000  (1ms)
#ifndef OS_TICK
// #define OS_TICK    (32 * 1000000 / 32768)
#define OS_TICK    (32 * 1000000 / 32768 / 32) //Speed up threads
#endif


Now to fine tune the PID to reduce the overshoot!

Cheers
Douglas
Back to top
View user's profile Send private message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Sun Oct 13, 2013 3:20 am    Post subject: Reply with quote

My fine tuning of the PID algorithm is still underway:



As you can see, the motor is driven hard (+/- 4800 is the limits of the PWM for full-scale) right to the point it should stop, and over shoots).

Still more tuning work to be done!

Cheers
Douglas
Back to top
View user's profile Send private message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Tue Oct 15, 2013 10:42 pm    Post subject: Reply with quote

More tuning of the algorithm performed, it now seems that the D Component of the PID seems to 'wind-up' and I need to fix that.


image ru
Back to top
View user's profile Send private message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Wed Oct 16, 2013 8:29 am    Post subject: Reply with quote

I found the logic problem and now get:


image hosting


Note the Encoder goes from 0-4095 and I had set the travel limits to 100 <-> 3000 inclusive.

So I am happy at this point, I wil not perform further tuning until I have the servo in a real-world situation (in my robot).

But then again I may try the braking feature of the MC33926 motor driver chip ...

Now I am working on the code for the 3-Axis accelerometer.

Cheers
Douglas
Back to top
View user's profile Send private message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Wed Oct 16, 2013 9:24 am    Post subject: Reply with quote

Further update,

I am getting accuracy of about 0.35 degrees or less under varying loads (which is 4/4096 * 360) which seems to be good enough for alpha code.

Later I will add some code to allow the servo (or the calling software) to vary the deadband (which is current 0x4) so that under heavy and wildy variable loads it will be possible to tune the servo on-the-fly to minimise oscillations.

Cheers
Douglas
Back to top
View user's profile Send private message
ginge
Site Admin


Joined: 14 Jan 2006
Posts: 1030
Location: Manchester, UK

PostPosted: Sat Nov 02, 2013 3:01 pm    Post subject: Reply with quote

Nice progress Douglas.

I look forward to seeing more!
_________________
http://www.headfuzz.co.uk/
http://www.robotfuzz.co.uk/
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Tue Nov 05, 2013 1:22 am    Post subject: Reply with quote

Here is a picture of the latest iteration of the servo with the electronics hanging out. You can also see the Energy Micro (now part of Silicon Labs) STK3600 to enable JTAG/SWD and SWO debugging and the ribbon cable going off to a logic analyser (not visible).



I am having to debug some errors in the code, relating to the servo reacting if it overshoots beyond its limits. Ah such fun!

Cheers
Douglas
Back to top
View user's profile Send private message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Tue Jan 21, 2014 7:48 am    Post subject: January 2014 Update Reply with quote

Well I had to redesign the magnetic encoder board and these arrived back from manufacturing in China last week and I have been testing these.

They work really well.

I now have the code to read the current the motor driver is using, as well as the temperature of the CPU.

I also have the code written to read the accelerometer (X, Y and Z).

I have the following bug, the logic to determine the travel within the software set travel limits can sometimes go wrong, I need to carefully go through all of the logic to figure that one out. **BUG SQUASHED 2014-02-02**

Then I have the boot loader to re-write so the CPU can be flashed in-circuit.

Lastly I need to decide on the external protocol for this servo and write that up.

I am having interesting issues getting all of the circuits into a 1/4 scale servo as there is a lot to fit in (the circuit boards only just fit in). I have been contemplating having the entire servo custom made in China using a form factor similar to existing Robot Servos (i.e. have a die made for injection moulding the case, using standard existing motor and gears plus the custom design).

This means that I can use a single double sided PCB, but there is the tooling cost and I am not sure how many of these I would sell Sad

Ah well, a bug to squash and extra code to write.

Cheers
Douglas
Back to top
View user's profile Send private message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Sat Feb 01, 2014 6:32 am    Post subject: Reply with quote

Update:
You can now set the CW_Limit (clockwise limit) and the CCW_Limit (counter clockwise limit) of travel dynamically and the servo will automatically adjust itself and the PID controller.

If, after dynamically changing the travel limits, the position is outside of that range, then the servo will move to the closet of the new limits set.

One thing I need to understand is how to set the torque of the controller, say from 0..1023 and how that works with a PID controller, does anyone have any pointers or thoughts?

Cheers
Douglas
Back to top
View user's profile Send private message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Sun Feb 02, 2014 4:41 am    Post subject: Reply with quote

Typical,

I have a few logic bugs I need a second pair of eyes, I would appreciate if someone could desk check my code.

Basically you have 0-4095 (going Counter Clock Wise) for the encoder with a negative current_velocity drives the motor Counter Clock Wise (CCW) and 0 stops it and a positive current_velocity drives it Clock Wise (CW).
CW_Limit and CCW_Limit can be any values 0..4095

I have issues where CW_Limit and CCW_Limit are close together, especially where on of these is '0';

The code:

Code:

if (
        ((CW_Limit < CCW_Limit) && ((seek_position < CW_Limit) || (seek_position > CCW_Limit))) ||
        ((CCW_Limit < CW_Limit) && ((seek_position < CW_Limit) && (seek_position > CCW_Limit)))
        )
    {
     //ERROR OUTSIDE OF THE BOUNDS, so fix this by chosing the closest limit
      c = seek_position - CW_Limit;
      d = seek_position - CCW_Limit;
      if (c < 0) c = c*-1;
      if (d < 0) d = d*-1;
     
      if (c>d)
        seek_position = CCW_Limit;
      else
        seek_position = CW_Limit;
    }
   

   //Now lets calculate the distance and direction of travel
  sum_previous_movements += previous_position - current_position; //what is the difference, sum it.
                                                                  //but this seems to fail near the 0 position
 
  if (CW_Limit == CCW_Limit) {  //Continuous rotation
    if ((current_position - seek_position) > HALF_TRAVEL)
      current_velocity = (4096 - current_position + seek_position) * -1; //swapped to -1
    else if ((current_position - seek_position) < (-1* HALF_TRAVEL))
        current_velocity = 4096 - seek_position + current_position;
      else
        current_velocity = current_position - seek_position;
  } else if ((CW_Limit < CCW_Limit)||(CW_Limit==0)||(CCW_Limit==0)) {  // Scenario A - '0' position is not in our permitted range of travel
  if (( current_position <= CCW_Limit) && ( current_position >= CW_Limit )) { //Zone_A?
       current_velocity = current_position - seek_position;      //we are in permitted range of travel
       sum_previous_movements = 0;              //so reset the sum of travels
    } else if (current_position < CW_Limit) {
       if (sum_previous_movements < 0)
         current_velocity = current_position + 4096 - seek_position;
       else
         current_velocity = (seek_position - current_position) * -1;
    } else if (CW_Limit == 0) {
       current_velocity = current_position - 4096 - seek_position;
    } else if (CCW_Limit ==0) {
      if (seek_position ==0)
        current_velocity = (4096-current_position)* -1;
      else
        current_velocity = (seek_position - current_position) *-1;
    } else if (sum_previous_movements < 0 )
           current_velocity = current_position - seek_position;
         else
           current_velocity = current_position + seek_position;
    } else {                          //Scenario B '0' position is in permitted range of travel
       if ((current_position <= CCW_Limit) || (current_position >= CW_Limit))
         sum_previous_movements = 0; //in correct range so reset sum of movements;
       if ((current_position <= CCW_Limit) && ( seek_position <= CCW_Limit)) {
         current_velocity = current_position - seek_position; //swapped
       } else if ((current_position <= CCW_Limit) && (seek_position >= CW_Limit)) {
          current_velocity = 4096 + current_position - seek_position;
       } else if ((current_position >= CW_Limit) && (seek_position >= CW_Limit)) {
          current_velocity = current_position - seek_position;
       } else if (current_position < CCW_Limit) {
          if (sum_previous_movements < 0)
            current_velocity = current_position + 4096 - seek_position;
          else
            current_velocity = (seek_position - current_position) * -1;
         } else //if (current_position >= CW_Limit) {
           if ( sum_previous_movements >= 0 ) {
             current_velocity = (4096 - current_position + seek_position) * -1;
           } else {
             current_velocity = current_position - seek_position;
           }
    }
    if (current_velocity > 4095) current_velocity -= 4096; //make sure we   
Back to top
View user's profile Send private message
Neon22



Joined: 06 Feb 2014
Posts: 4

PostPosted: Thu Feb 06, 2014 11:04 pm    Post subject: Reply with quote

Is seek position signed ?
The initial test might not work if one of borders is zero.
Also - is this the test you want ? The second case seems like it might not be right.
I made an image of the test conditions but can't post image.. yet


Last edited by Neon22 on Fri Feb 07, 2014 1:11 am; edited 1 time in total
Back to top
View user's profile Send private message
Neon22



Joined: 06 Feb 2014
Posts: 4

PostPosted: Thu Feb 06, 2014 11:17 pm    Post subject: Reply with quote

I also wanted to say great work. Thanks so much for reviving this.

In case its useful STM just released a new chip which is very parsimonious on power and has a float capability and 10 timers. 2 of which are 16 bit up/down as well as two other timers that can count quadrature inputs directly. It seems well designed for this kind of thing.

Its in a 64pin QFP also - but they unusually also have a 49pin version.
Its cheap too - but rare right now as just released.

Its the STM32F401

    84MHz top speed.
    Comes in 49, 64, 100 pin packages
    Current consumption in run mode (from Flash) can be as low as 128 ľA/MHz. In Stop mode, the power consumption can be as low as 9 ľA.
    single 12bit ADC
    4x SPI, 3x I2C, 1x USB, 3x USART
    128-512K Flash ROM, 96kB RAM
    10 Timers (2 advanced)
    96bit unique ID


On the st website you can find it under
web/en/catalog/mmc/FM141/SC1169/SS1577/LN1810

The power consumption of 128ľA/MHz is lower than the TinyGecko chip's 160ľA/MHz. The stop mode is much the same. And its an M4 not an M3.

The model STM32F401RE has 512K Flash in a 64 pin package (totally diff pinouts to your current device Sad )
Back to top
View user's profile Send private message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Fri Feb 07, 2014 4:30 am    Post subject: Reply with quote

Hi,

Thanks for the info.

Seek_position is 0..4095.

The first test seems to work ok.

I will keep testing the second test.

I will post a simple program I have been using if you want to look at the code in more depth.

The new chip may be too large, I will have a look at it.

I have designed a replacement bottom part of the servo case and am looking to replace the processor and motor board with a single board. I am waiting to get this back from the 3D printer next week.

This new part integrates a thrust bearing and a normal bearing to absorb and external shock / forces too.

It also has additional mounting bracket to make it more robust.



The means that you simply replace the pot with my new encoder and the new bottom of the case which has the main board integrated with a micro USB connector, and power connector, I may also bring the JTAG outside of the case too.

Cheers
Douglas
Back to top
View user's profile Send private message
douglas



Joined: 01 Nov 2012
Posts: 66

PostPosted: Fri Feb 07, 2014 8:14 am    Post subject: Reply with quote

Also, I have implemented a very simple command interface:

Code:
help
Available commands:

g   cw <n>     : get clockwise limit 0..4095
g   ccw <n>    : get counter-clockwise limit 0..4095
g   temp       : get internal CPU temp in celcius
g   current    : get motor current in mA
g   deadband   : get deadband
g   position   : get position of the servo output shaft 0..4095
g   status     : get a string representing the internal status
g   version    : display OpenServo version
s   cw <n>     : set clockwise limit 0..4095
s   ccw <n>    : set counter-clockwise limit 0..4095
s   deadband   : set deadband
s   seek <n>   : set seek position 0..4095
help           : display this help

>
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OpenServo.com Forum Index -> Hardware All times are GMT
Goto page Previous  1, 2, 3 ... 12, 13, 14, 15  Next
Page 13 of 15

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group