CNCzone.com-The Largest Machinist Community on the net!



Home Page Mark Forums Read Today's Posts My Replies Classifieds Reviews Photo Gallery Web Links Share Files Advertise With Us Ad List
Go Back   CNCzone.com-The Largest Machinist Community on the net! > OpenSource CNC Design Center > Open Source Controller Boards


Open Source Controller Boards Discussion for Open Source CNC type Controller Boards and other related items. (for personal use only)


This forum is sponsored by:

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1  
Old 03-30-2009, 08:23 PM
*Registered User*
 
Join Date: Jan 2009
Location: Sweden
Posts: 81
Zoidberg is on a distinguished road
Cool DIY autotuning servo driver

Anyone up for a collaboration project? The best open source servo driver ever!

Let's talk specifications:
Written in C/C++.
Based on Amtel AVR ATmega48, 88, 168 (differ only in memory sizes).
Easily portable to other models by using port/pin defines.
Minimalistic board design.
Programmed on board with ISP.

Inputs/outputs:
Enable input.
Step/dir or quadrature input.
Encoder input 1x, 2x or 4x.
Current sensing with A/D converter.
Fault output.
Auto tuning button.
Reset button.

Control:
2 PID loops, torque loop controls output PWM, position loop controls torque.
Autotuning with Ziegler Nichols method.

Settings:
Max current limit (over the limit = fault).
Max continuous current limit (over the limit for 1? second = fault).
Max error limit (over the limit = fault).
Max PWM output.
Step multiplier 1-10.

Safety:
Missing encoder check (Max? PWM output for x loops without any encoder interrupt = fault).



Because the driver is open source and built for a specific use by each user, the settings is set at compile time by defines, and therefore you would not need any RS232, only 1 button to initialize the autotuning and 1 button for reset! It would reduce the size and cost of the driver a bit, as you don't need DB9 connector, the MAX232 ic and the supporting components! It also reduces the memory requirement for the µC as you don't need a communication protocol.

Comments?
Reply With Quote

  #2  
Old 03-30-2009, 08:33 PM
*Registered User*
 
Join Date: Jan 2009
Location: Sweden
Posts: 81
Zoidberg is on a distinguished road

I have written the encoder input earlier!

It works by setting interrupts for the 2 encoder input pins:
Rising edge on pin A, nothing on pin B = 1X
Logical change on pin A, nothing on pin B = 2X
Logical change on pin A, logical change on pin B = 4X

Code:
ISR(INT0_vect)
{
  if(bit_is_set(PIND, PD2))
  {
    if(bit_is_set(PIND, PD3))
    {
      ProcessVariable--;
    } else {
      ProcessVariable++;
    }
  } else {
    if(bit_is_set(PIND, PD3))
    {
      ProcessVariable++;
    } else {
      ProcessVariable--;
    }
  }
}

ISR(INT1_vect)
{
  if(bit_is_set(PIND, PD3))
  {
    if(bit_is_set(PIND, PD2))
    {
      ProcessVariable++;
    } else {
      ProcessVariable--;
    }
  } else {
    if(bit_is_set(PIND, PD2))
    {
      ProcessVariable--;
    } else {
      ProcessVariable++;
    }
  }
}
Reply With Quote

  #3  
Old 03-31-2009, 12:43 AM
*Registered User*
 
Join Date: Jan 2009
Location: Sweden
Posts: 81
Zoidberg is on a distinguished road

I have done some coding now. I dropped the quadrature input, enable input and PORT/PIN defines.

Implemented:
Save and Load PID parameters from eeprom.
Step/Dir input with step multiplier.
Encoder input, 1X, 2X and quadrature.

I have only used notepad so i don't know if it will compile!

Code:
#define F_CPU 20000000U //20 MHz External Oscillator

#include 
#include 
#include 

#define sbi(port, bit) (port |=  (1 << bit))
#define cbi(port, bit) (port &= ~(1 << bit))

//////////////
// SETTINGS //
//////////////

#define MaxCurrent 255
#define MaxContinuousCurrent 127
#define MaxContinuousCurrentTime 1000

#define MaxError 1000

#define MaxPWM 255

#define StepMultiplier 1

//#define EncoderMode1
//#define EncoderMode2
#define EncoderModeQuadrature

//////////////////
// DECLARATIONS //
//////////////////

typedef struct
{
  short int PTorque;
  short int ITorque;
  short int DTorque; 

  short int PPosition;
  short int IPosition;
  short int DPosition;
} pss //PID Setting Structure

pss EEMEM EEPROM_Data;
pss PidSettings = {0,0,0,0,0,0};

long int SetPoint = 0;
long int ProcessVariable = 0;

void Initialization();

void AutoTune();
void TorqueLoop();
void PositionLoop();

void LoadSettings();
void SaveSettings();

//////////
// MAIN //
//////////

int main(void)
{
  LoadSettings();
  Initialization();
}

///////////////
// FUNCTIONS //
///////////////

void Initialization()
{
  cbi(DDRC, DDC0); //Enable Step input - Pin 23
  cbi(DDRC, DDC1); //Enable Dir input - Pin 24

  sbi(PCICR, PCIE1); //Enable pin change interrupt
  sbi(PCMSK1, PCINT8); //Enable PCINT8 - Step input

  cbi(DDRD, DDD2); //Enable encoder A input - Pin 4
  cbi(DDRD, DDD3); //Enable encoder B input - Pin 5

  cbi(EIMSK, INT0); //Clear registers
  cbi(EIMSK, INT1);
  cbi(EICRA, ISC00);
  cbi(EICRA, ISC01);
  cbi(EICRA, ISC10);

#ifdef EncoderMode1
  sbi(EIMSK, INT0); //Enable interrupt A
  sbi(EICRA, ISC01); //Set rising edge A
#endif

#ifdef EncoderMode2
  sbi(EIMSK, INT0); //Enable interrupt A
  sbi(EICRA, ISC00); //Set logical change A
#endif

#ifdef EncoderModeQuadrature
  sbi(EIMSK, INT0); //Enable interrupt A
  sbi(EICRA, ISC00); //Set logical change A
  sbi(EIMSK, INT1); //Enable interrupt B
  sbi(EICRA, ISC10); //Set logical change B
#endif
}

void AutoTune()
{ 
}

void TorqueLoop()
{
}

void PositionLoop()
{
}

void LoadSettings()
{
  eeprom_read_block((void*)&PidSettings, (const void*)&EEPROM_Data, sizeof(pss));
}

void SaveSettings()
{
  eeprom_write_block((const void*)&PidSettings, (void*)&EEPROM_Data, sizeof(pss));
}

////////////////
// INTERRUPTS //
////////////////

ISR(PCINT1_vect) //Step Dir input
{
  if(bit_is_set(PINC, PC0))
  {
    if(bit_is_set(PINC, PC1))
    {
      SetPoint -= StepMultiplier;
    } else {
      SetPoint += StepMultiplier;
    }
  }
}

ISR(INT0_vect) //Encoder input A
{
  if(bit_is_set(PIND, PD2))
  {
    if(bit_is_set(PIND, PD3))
    {
      ProcessVariable--;
    } else {
      ProcessVariable++;
    }
  } else {
    if(bit_is_set(PIND, PD3))
    {
      ProcessVariable++;
    } else {
      ProcessVariable--;
    }
  }
}

#ifdef EncoderModeQuadrature
ISR(INT1_vect) //Encoder input B
{
  if(bit_is_set(PIND, PD3))
  {
    if(bit_is_set(PIND, PD2))
    {
      ProcessVariable++;
    } else {
      ProcessVariable--;
    }
  } else {
    if(bit_is_set(PIND, PD2))
    {
      ProcessVariable--;
    } else {
      ProcessVariable++;
    }
  }
}
#endif
Reply With Quote

  #4   Ban this user!
Old 03-31-2009, 11:20 AM
 
Join Date: Jul 2003
Location: Holmen, WI
Posts: 1,082
samco is on a distinguished road

I think you may want to look at a different autotuning method than ZN. I have used ZN manually and within emc there is a PID with ZN tuning built in. It gets you sort of close - but in the end a bit of manual tuining is required.

(I don't know what is out there)

Good luck
sam
Reply With Quote

Reply




Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
servo driver for yaskawa chriswp Servo Motors and Drives 5 02-11-2009 04:17 AM
Phelps CNC Servo Driver dgoddard General Electronics Discussion 0 08-28-2008 03:05 PM
Servo driver karl1 General Electronics Discussion 21 03-21-2007 08:51 AM
Basic driver for an AC servo phantomcow2 Servo Motors and Drives 1 12-18-2005 11:57 PM
have anybody making servo driver? masaV Servo Motors and Drives 0 06-20-2005 03:10 AM




All times are GMT -5. The time now is 12:58 AM.





Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2012, vBulletin Solutions, Inc.
Content Relevant URLs by vBSEO
Template-Modifications by TMS

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361