Ik zit hier zo een beetje te experimenteren met een AtMEGA 163. Werkt allemaal natuurlijk harstikke mooi, maar ik zou nu graag een motorregeling willen gaan maken.

Deze regeling houd in dat ik zo'n 6 DC motoren onafhankelijk van elkaar wil regelen. Het ligt voor de hand om dit met PWM te doen.

Helaas heeft de 163 maar 2 PWM outputs, weet iemand hoe ik dit probleem moet oplossen?

Ik programmeer in C.

Je kunt de PWM natuurlijk softwarematig in de AVR bouwen. Zo heeft een stagiair van mij een PWM regeling gebouwd voor een 20A motor, met een Tiny15L

Op 7 november 2003 20:31:40 schreef Antoine:
Je kunt de PWM natuurlijk softwarematig in de AVR bouwen. Zo heeft een stagiair van mij een PWM regeling gebouwd voor een 20A motor, met een Tiny15L

Voor 1 of 2 uitgangen is dit inderdaad eenvoudig te realiseren. Echter, als ik gebruik maak van 6 outputs dan wordt de timing wel erg ingewikkeld.

Stel ik zet uitgang 1 op 80%, dan heb ik nog maar 20% processortijd over voor de andere outputs. Ik zal waarschijnlijk wel verkeerd beredeneren, dus als je een oplossing hebt zou ik dat graag van je willen weten.

Alvast bedankt :)

Toverstaf in 6 PWM outputs op AtMEGA 163Stel ik zet uitgang 1 op 80%, dan heb ik nog maar 20% processortijd over voor de andere outputs. Ik zal waarschijnlijk wel verkeerd beredeneren, dus als je een oplossing hebt zou ik dat graag van je willen weten.
[/quote]
Gewoon een loopje maken welke de status van die 6 timers afvraagd en aan de hand daarvan doorgaat met scannen of even actie onderneemt en daarna dan weer doorgaat met de loop.

Op 8 november 2003 19:26:33 schreef Atlantis:

[...]

Gewoon een loopje maken welke de status van die 6 timers afvraagd en aan de hand daarvan doorgaat met scannen of even actie onderneemt en daarna dan weer doorgaat met de loop.

Maar dat 'doorgaan' is dus het softwarematig PWM aandrijven van de motors, en dat vreet denk ik wel van zn resources :) (of ik begrijp je verkeerd kan ook)

Meerdere PWMs aansturen begrijp ik al langere tijd niet. Stel ik stuur 1 PWM softwarematig aan, frequentie van 30khz. Als ik nu een 2e software matige PWM erbij programmeer dan zal de 1e toch nooit op 30khz meer kunnen draaien? :? (de controller moet toch tussen een 'aan/uit' en 'aan/uit' van de 1e PWM zn aandacht vestigen op de 2e PWM, en dus bij de 1e PWM er een vertraging is?)

Op 8 november 2003 19:36:02 schreef Nofri:

[...]

Maar dat 'doorgaan' is dus het softwarematig PWM aandrijven van de motors, en dat vreet denk ik wel van zn resources :) (of ik begrijp je verkeerd kan ook)

Meerdere PWMs aansturen begrijp ik al langere tijd niet. Stel ik stuur 1 PWM softwarematig aan, frequentie van 30khz. Als ik nu een 2e software matige PWM erbij programmeer dan zal de 1e toch nooit op 30khz meer kunnen draaien? :? (de controller moet toch tussen een 'aan/uit' en 'aan/uit' van de 1e PWM zn aandacht vestigen op de 2e PWM, en dus bij de 1e PWM er een vertraging is?)

Jij snapt mijn probleem :)

Ik kan voor de aansturing van de 6 poorten natuurlijk een extra (kleine) controller gebruiken. Ik heb namelijk een 163 met daarop een grafisch display, 4 knopjes (polling) en een seriële interface. Als ik ook nog eens 6 PWM signalen ga "emuleren" denk ik dat het geheel nogal traag werkt, recources kan ik echt goed gebruiken in dit project ;)

Maar dan zit ik inderdaad nog met het probleem wat ik ook al bedoelde. Als ik 1 output op 50% wil zetten betekent dat dat hij 50% "uit zijn neus staat te eten". Maar als ik dan nog een 2de pwm output op 100% wil hebben kan dat dus nooit omdat 50% van de recources al weg zijn.

Ik weet dat het moet kunnen, ik bedoel... het kan toch niet zo zijn dat ik de eerste ben die tegen dit probleem aanloopt ;)

Heeft iemand hier misschien ervaring mee?

al eens gedacht aan interrupts? gebruik een timer + zijn interrupt, waarbij de timer de minimum periode die je nodig hebt aangeeft. Met een teller per uitgang kan je dan eventueel deze minimum periode vermenigvuldigen met een factor 2/3/4/...
Je serieele comm. kan je trouwens ook nog afhandelen met irq.
Zo kan je dan de tijd tussen de interrupts gebruiken om je display aan te sturen & toetsen te pollen.

ik heb nu deze code gemaakt:



int	iTeller,
		iPWM1 = 95,
		iPWM2 = 0,
		iPWM3 = 0,
		iPWM4 = 0,
		iPWM5 = 0,
		iPWM6 = 0;
    
	
void main(void)
{
	DDRB=0xFF;
	PORTB=0x00;

	 	while (1)
  		{
      		delay_ms(1);
      		for(iTeller = 1; iTeller < 100; iTeller++)
      		{
      			if(iTeller <= iPWM1)
      			{
      				PORTB = 0xFF;
      			}
      			else
      			{
      				PORTB = 0x00;     			
      			}
      		}

      	};
}

Ik heb nog een oude scoop, dus ik kan het signaal niet helemaal bekijken. De ledjes gaan nu wel zwakker en feller branden, maar ik weet niet of dit een goed PWM signaal afgeeft. Weet iemand dit?

Geen idee of het werkt... Ben niet zo'n C gebruiker/liefhebber.

Wat ik meestal doe is gewoon 1 hardware teller laten lopen. Elke keer vergelijk ik elke PWM waarde met die teller. Als de waarde groter is dan de tellerstand dan laat je de uitgang hoog zijn en anders laag. Zo kan je dus makkelijk 32 PWM uitgangen sturen en heb je nog zat tijd over voor andere dingen. :)

Als je het geheel met timerinterupts laat werken, dan is het trouwens veel stabieler.

Op 10 november 2003 13:55:59 schreef Benadski:
Geen idee of het werkt... Ben niet zo'n C gebruiker/liefhebber.

Wat ik meestal doe is gewoon 1 hardware teller laten lopen. Elke keer vergelijk ik elke PWM waarde met die teller. Als de waarde groter is dan de tellerstand dan laat je de uitgang hoog zijn en anders laag. Zo kan je dus makkelijk 32 PWM uitgangen sturen en heb je nog zat tijd over voor andere dingen. :)

Als je het geheel met timerinterupts laat werken, dan is het trouwens veel stabieler.

Dat is dus bijna hetzelfde als wat ik doe, alleen dan andersom omdat mijn poorten niet inverse zijn. Ik zal alleen een teller moeten gaan gebruiken in plaats van een delay van 10ms?

Zoja, op hoeveel ms laat jij die teller aflopen?

Alvast bedankt :)

De clock van de teller laat ik meestal op ongeveer 50kHz lopen als ik LEDs gebruik. Dan knipperen de LEDs ongeveer op 200Hz, dat ziet het oog niet meer. Voor motoren kun je dit ook wel gebruiken denk ik...

De totale tellertijd (wanneer een overflow interrupt word gegeven) is ongeveer 5ms, de tijd per tel is ongeveer 20us.

EDIT: Ik laat meestal de teller tot 255 lopen, dan heb je meer stapjes. Het kan natuurlijk ook gewoon tot 100 of lager, dat is een keuze die je zelf maakt.

[Bericht gewijzigd door Benadski op ]

Nu snap ik er helemaal niets meer van. Ik snap wel hoe PWM werkt, maar zoals julie hem aansturen niet (niet meer thans :)) PWM = pulse width modulation = duty cycly laten veranderen, correct?
(frequentie blijft gelijk)

Maar hoe veranderen julie de pulse width dan adh van de timer? (dat stukkie raak ik even kwijt)

Op 10 november 2003 21:14:53 schreef Nofri:
Nu snap ik er helemaal niets meer van. Ik snap wel hoe PWM werkt, maar zoals julie hem aansturen niet (niet meer thans :)) PWM = pulse width modulation = duty cycly laten veranderen, correct?
(frequentie blijft gelijk)

Maar hoe veranderen julie de pulse width dan adh van de timer? (dat stukkie raak ik even kwijt)

Het is niet zo heel moeilijk hoor :) Ik ben ook maar een beginneling.

Als je een beetje C kunt is het makkelijk te zien, maar ik zal een toelichting geven. Je hebt een bereik van 0 - 100% in stapjes van 1%. Stel je wilt 60% schakelen, dan doet de code het volgende:

- stel teller in op 0
- is de teller kleiner dan 60?
- zo ja, zet dan de output hoog
- verhoog de teller met 1

- is de teller kleiner dan 60?
- zo nee, zet dan de output laag
- verhoog teller met 1 en tel door tot 100.

zo zorg je ervoor dat je 60% van de tijd een hoog signaal afgeeft.

Ik heb alleen 2 vragen,

- volgens de multimeter schakel ik met 652 Hz, dit zou toch veeeeel hoger moeten zijn als ik die delay van 1ms weghaal?

- mijn ventilatoren piepen enorm, hoe haal ik die piep weg?

Waarschijnlijk heeft je multimeter ongeveer gelijk en schakel je in het hoorbare gebied. 625 Hz geeft al een naar piepje. Op welke kloksnelheid draait die AT?

[Bericht gewijzigd door A vd Linden op ]

Op 10 november 2003 23:53:56 schreef A vd Linden:
Waarschijnlijk heeft je multimeter ongeveer gelijk en schakel je in het hoorbare gebied. 625 Hz geeft al een naar piepje. Op welke kloksnelheid draait die AT?

Met deze code:


#include <mega163.h>

int	iTeller,
	iPWM1 = 60,
 
void main(void)
{

	PORTB=0x00;
	DDRB=0xFF;

		while (1)
  		{
      		for(iTeller = 0; iTeller <= 100; iTeller++)
      		{
      			if(iTeller <= iPWM1)
      				PORTB.1 = 1;
      			else
      				PORTB.1 = 0;      			
      		}

      	};
}

schakelt hij met zo'n 625 Mhz. En inderdaad, daarom hoor ik die pieptoon.

Het rare is alleen dat de controller op 4Mhz werkt, je zou dan toch verwachten dat hij deze code hierboven dan veel vaker zou moeten uitvoeren?

Op 11 november 2003 08:18:00 schreef Toverstaf:
schakelt hij met zo'n 625 Mhz. En inderdaad, daarom hoor ik die pieptoon.

Het rare is alleen dat de controller op 4Mhz werkt

1. Jij hebt goeie oren
2. Moet die 4 MHz geen 4 GHz zijn ;)

Ja, het zou wel moeten... Maak eens een assemblerfile van die C code? O, en hoort die komma na de 60 (zal ie wel negeren, maar je weet het nooit).

Volgens mij moet het wel wat sneller gaan inderdaad. Staat de interne klok niet aan?

Ik weet dat je bij assemblercode je stackpointer moet vastleggen, hoeft dat bij C niet?

Aaahaaa, nu snap ik em! :)

Moet er geen ';' achter de 60? (en in C moet je toch ook nog volgende regel aangeven? (met \ of \\ geloof ik)

igg zoiets :
int itimer, ipwm = 60;

En nog een vraagje. Moet bij je If....Then statement geen accolades? {} (weet het niet zeker hoor, ik begin ook maar net met C)
:)

[Bericht gewijzigd door Nofri op ]

Op 11 november 2003 15:53:37 schreef Nofri:
Aaahaaa, nu snap ik em! :)

Moet er geen ';' achter de 60? (en in C moet je toch ook nog volgende regel aangeven? (met \ of \\ geloof ik)

igg zoiets :
int itimer, ipwm = 60;

En nog een vraagje. Moet bij je If....Then statement geen accolades? {} (weet het niet zeker hoor, ik begin ook maar net met C)
:)

er hoeft geen ';' erachter omdat het een opsomming van integers is, de laatste van de reeks moet dus wel een ';' hebben, de rest kun je scheiden met ','.

Zolang de if-statement niet uit meerdere regels bestaat heb je geen accolades nodig.

Maargoed, ik heb eens navraag gedaan en de if-statement is de boosdoener. Deze vraagt namelijk heel veel processorload. Er is dus weinig wat aan te doen.

Weet iemand of ik dit via hardware kan oplossen? Ik wil alleen die irritante piep kwijt :)

Kun je niets met assembler dan? Dat vind ik een stuk makkelijker dan C, maarja, da's misschien heel persoonlijk.

Op 11 november 2003 16:59:41 schreef Benadski:
Kun je niets met assembler dan? Dat vind ik een stuk makkelijker dan C, maarja, da's misschien heel persoonlijk.

Eigenlijk niet nee :)

Ik doe alles al jaren in C, en op zich zou het niets uit mogen maken. Als ik compileer krijg ik gewoon assembler terug. Dit is de assembler code die de compiler ervan maakt:

http://members.chello.nl/~bjhm.velthuis/pwm_test.asm

met deze c-code:

http://members.chello.nl/~bjhm.velthuis/pwm_test.c

Dubbelpost...

[Bericht gewijzigd door Benadski op ]

Dat kan nooit dat kleine stukje code zijn wat je hierboven geeft of wel?!? Zou wel erg inefficient gaan dan...

O, en maak eens van die int een char!!!

[Bericht gewijzigd door Benadski op ]

Op 11 november 2003 17:10:25 schreef Benadski:
Dat kan nooit dat kleine stukje code zijn wat je hierboven geeft of wel?!? Zou wel erg inefficient gaan dan...

O, en maak eens van die int een char!!!

Toch is dat wel de code :)
Als ik de int verander in een char stijgt hij van 625 Hz naar 1030 Hz, een behoorlijke verbetering maar nog niet genoeg.

Ik denk echt dat het met de software niet gaat werken. Wat zou er gebeuren als ik een condensator over de ventilator zet?

Ik denk dat je dan veel kwijt bent aan koppel en dus luchtstuwkracht. Je zet dan PWM om naar DC met een beetje kortsluiting... :P

Of gebruik je een open collector uitgang aan je fan? Geef je schema eens?