Sida 2 av 4

Postat: 26 mars 2007, 00:43:39
av $tiff
Chribbe76 skrev:Din motor kommer helt enkelt få PWM (spänning), Strömbegränsningen är bara ett skydd.

I mina servo-tester har PID'en bara styrt motor-strömmen (linjär-regleras med opamp) vilket ger ett korrekt resultat.
Enligt mina personliga teorier krävs det ett beräknings-steg mellan PID'en och motorns PWM-värde om man ska köra med PWM, har man ingen beräkning mellan så kommer regleringen bli väldigt dålig.
Det ska bli mycket intressant att se resultatet när du styr motorn utan denna extra beräkning.

Det är helt rätt att börja "basic" och höja ribban senare.
Det är inte bara dina egna teorier som säger att en motor inte går att reglera speciellt bra med en enkel PID-regulator med avseende på varvtal (eller position). Eftersom hela kedjan (vartalsreferens -> vridmoment(rotorström) -> rotorspänning) innehåller två integratorer blir det svårt att få till en stabil regulator med vettiga prestanda enbart med den konventionella PID-regulatorn.

För att lösa detta bättre kan man antingen använda en mer avancerad (tillståndsåterkopplad) regulator eller så kaskadkopplar man flera P(I)-regulatorer. Mao bör man ha en relativt enkel men snabb regulator för att hantera ett börvärde i rotorströmm med rotorspäning som styrsignal. Utanpå denna lägger man en regulator med varvtal som börvärde och rotorström som styrsignal.

Men, jag håller med Chribbe76 om att det är bäst att börja på lagom nivå. När man trimmat sig till vanvett vet man att det är dags att använda en annan regulator och försöka igen.

Postat: 4 april 2007, 00:02:26
av JBV
Nu har jag börjat experimentera och koda lite!!

Hittade just lite intressant info!
http://bestune.50megs.com/typeABC.htm
Typ C kanske vore det man ska satsa på!?

Postat: 4 april 2007, 23:46:10
av JBV
Synpunkter på min enkoder input?

Kod: Markera allt

void ENCODER_Init()
{
  cbi(DDRD, DDD2);
  cbi(DDRD, DDD3);;
 
  EIMSK |= _BV(INT0) | _BV(INT1);
  EICRA |= _BV(ISC00);
  EICRA |= _BV(ISC10);
}

ISR(INT0_vect) //A
{
  if(bit_is_set(PIND, PD2)) //rising edge
  {
    if(bit_is_set(PIND, PD3))
	{
	  ProcessVariable--;
	} else {
	  ProcessVariable++;
	}
  } else { //falling edge
    if(bit_is_set(PIND, PD3))
	{
	  ProcessVariable++;
	} else {
	  ProcessVariable--;
	}
  }
}

ISR(INT1_vect) //B
{
  if(bit_is_set(PIND, PD3)) //rising edge
  {
    if(bit_is_set(PIND, PD2))
	{
	  ProcessVariable++;
	} else {
	  ProcessVariable--;
	}
  } else { //falling edge
    if(bit_is_set(PIND, PD2))
	{
	  ProcessVariable--;
	} else { //Else increment
	  ProcessVariable++;
	}
  }
}
Det fungerar sådär, tappar steg om jag vrider för fort, men det beror förhoppningsvis på att jag använder en mekanisk pulsgivare i stil med dennna: http://www.elfa.se/elfa-bin/dyndok.pl?dok=2030.htm

Postat: 4 april 2007, 23:53:48
av strombom
Små avkopplingskondensatorer kanske behövs?

Så här såg koden ut när jag använde exakt en sådan enkoder du visade bild på (kommer inte ihåg varför det är en delay där i koden):

Kod: Markera allt

u08 navigatorState;
#define navigatorStateMax 2

void initNavigator()
{
	SFIOR &= ~(1<<PUD);

	// Set Nav-ports to input w/ pullup
	DDRD &= ~(1<<NAV_A) & ~(1<<NAV_B) & ~(1<<NAV_BTN);
	PORTD |= (1<<NAV_A) | (1<<NAV_B) | (1<<NAV_BTN);
	
	// Trig on falling edge
	cbi(EICRA, ISC00);
	sbi(EICRA, ISC01);
	cbi(EICRA, ISC10);
	sbi(EICRA, ISC11);
	
	//Enable interrupts
	sbi(EIMSK, INT1);
}

ISR(SIG_INTERRUPT1)
{
	u16 delay, a;
	for(delay=0;delay<550;delay++)
		for(a=0;a<10;a++);
	
	if((EICRA & (1<<ISC10)) == 0)
	{
		sbi(EICRA, ISC10);
		
		if((PIND & (1<<NAV_B)) != 0) {
			if(navigatorState == navigatorStateMax)
				navigatorState =0;
			else
				navigatorState++;
		} else {
			if(navigatorState == 0)
				navigatorState = navigatorStateMax;
			else
				navigatorState--;
		}
	}
	else	
	{
		cbi(EICRA, ISC10);
	
		if((PIND & (1<<NAV_B)) == 0) {
			if(navigatorState == navigatorStateMax)
				navigatorState =0;
			else
				navigatorState++;
		} else {
			if(navigatorState == 0)
				navigatorState = navigatorStateMax;
			else
				navigatorState--;
		}	
	}
	
	updateLedDrivers();
}

Postat: 5 april 2007, 00:01:28
av JBV
Ska testa imorrn! Jag skulle ju iofs även kunna pröva simulera AB genom datorn! då märks det ju snabbt om man tappar pulser!

Vet någon var man kan få tag på vinklade läsgafflar (så dom läser i samma plan som kretskortet)? Tänkte pröva bygga en egen enkoder! :)

Btw så triggar jag på logical change!

Postat: 5 april 2007, 12:00:09
av Nihilim
Jag kanske kan låna ut en encoder om det finns intresse. Har tillgång till ett gäng relativt högupplösta optiska varianter.

Postat: 5 april 2007, 12:30:44
av $tiff
JBV skrev:Nu har jag börjat experimentera och koda lite!!

Hittade just lite intressant info!
http://bestune.50megs.com/typeABC.htm
Typ C kanske vore det man ska satsa på!?
Exakt vad jag svamlade om i mitt förra inlägg! Välj typ C och slipp många problem från början! :tumupp: (Å andra sidan missar du kanske nöjet att uppleva och åtgärda problemen)

Postat: 5 april 2007, 13:00:18
av JBV
Hehe känns lite baklänges att välja en sämre variant när man har informationen serverad ;) Jag lär väl pröva en P regulator först bara för att få nånting att snurra :D

Nihilim: Tack för erbjudandet, men jag tror jag ska försöka bygga en själv! Hade jag bara haft en schmitt trigger hemma hade jag offrat en gammal datormus! :)

Jag försöker få igång pin change interrupt för Step ingången men det händer inget! Har jag missat något? :S

Kod: Markera allt

void INPUT_Init()
{
  cbi(DDRC, DDC0); //Step
  cbi(DDRC, DDC1); //Dir
  cbi(DDRC, DDC2); //Enable

  PCMSK1 |= _BV(PCINT8);
}

ISR(PCINT1_vect) //Step
{
  USART_Transmit('x'); //Debug

  if(bit_is_set(PINC, PC0)) //Step
  {
    if(bit_is_set(PINC, PC1)) //Dir
    {
      SetPoint++;
    } else {
      SetPoint--;
    }
  }
}

Postat: 5 april 2007, 13:17:05
av JBV
Nu löste jag problemet! Hade missat PCICR |= _BV(PCIE1);

Postat: 5 april 2007, 21:23:26
av JBV
Nu blev det för mycket på experimentplattan så jag ritade ihop ett kretskort! Det är bara för lite experiment så jag har inte lagt ner allt för mycket tid!

Skulle jag få igång allt ska jag försöka få ner det på ett 100*75 mm kretskort med ytmonterade komponenter!

Stor bild!

Postat: 11 april 2007, 02:00:10
av JBV
Kretskortet är klart och verkar fungera som tänkt! Har testkört lite med den här koden:

Kod: Markera allt

void PID_Init()
{
  sbi(TCCR0B, CS00);
  sbi(TCCR0A, WGM00);  

  sbi(TCCR0A, COM0A1); //Output A
  sbi(DDRD, PD6);
  OCR0A = 0x00;

  sbi(TCCR0A, COM0B1); //Output B
  sbi(DDRD, PD5);
  OCR0B = 0x00;
}

void PID()
{
  OCR0A = 0x00;
  OCR0B = 0x00;

  int PWM = 0;
  int Error = SetPoint - ProcessVariable;
  PWM = Error * 4;

  if(PWM < 0) //Output A, negative error
  {
    PWM = abs(PWM);
    if(PWM > 200) PWM = 200;
    OCR0A = PWM;
  } else if(PWM > 0) //Output B, positive error
  {
    if(PWM > 200) PWM = 200;
    OCR0B = PWM;
  }
}
Har testat med lysdioder på µC utgångarna och det fungerar som väntat efter koden! Har även testat med gate driver kretsarna ikopplade men då fungerar bara utgång B! Jag har även bytt plats på dom och även då fungerar bara utgång B, så jag tvingas löda lös och byta FET:arna imorrn! Vet inte vad som gick fel :evil:

Postat: 11 april 2007, 02:17:44
av Andax
JBV och Strombom, den mekaniska enkodern som ni körde med (den som ELFA hade) hur är friktionen i den? Snurrar den lätt? (gissar/hoppas att ni körde med den utan distinkta lägen)

Postat: 11 april 2007, 02:35:39
av JBV
Den jag har är med distinkta lägen och passar verkligen inte för det här! Det är bara för att experimentera lite tills jag orkar bygga nå vettigare :)

Postat: 11 april 2007, 07:30:39
av strombom
Jag har testat två från elfa, en som är grön tror jag, den har distinkta lägen, en som var helt metallfärgad, den hade inte lika tydliga lägen men var lite "seg".

Jag har även sett ett instrument som hade en: http://www.elfa.se/elfa-bin/dyndok.pl?l ... 130152.htm
Den användes till en stor ratt, extremt lättsnurrad och bra känsla... och dyr :)

Postat: 11 april 2007, 11:35:59
av Andax
Hittade en enkoder från Bourns modell ECW1J-B24-AC0024 med distinkta steg. Öppnade den för att se hur den funkade...
Det var en mycket enkel konstruktion. Ska se om jag kan få upp några bilder om någon är intresserad.
Ska försöka modda den så att jag kan använda den för positionsåtermatningen av min inverterade pendel.
Att få bort de distinkta stegen var lätt... Det var bara att vända bladfjädern i enkodern 180 grader eftersom stegen alstrades av ett litet veck på fjädern.