Hallo mede-collega-electronica-ict-mensen (;D),
Ik moet voor mijn eind project een gestabiliseerde voeding maken. Alleen moet ik data van de accellerometer (adxl345) om gaan zetten in een soort PWM signaal om dan mijn (2) servo motoren te kunnen aansturen. Ik ben redelijk nieuw in dit mileu en het zou al mogelijk zijn om de data te lezen maar ik heb geen flauw idee deze ruwe data (dus X0 lsb, X1 msb, Y0 lsb, Y1 msb) om te gaan zetten in PWM.
Heeft iemand hiervoor een gedacht of oplossing of code voor? Eventueel ook een idee hoe ik deze dat moet integreren in de PWM?
Ik werk in MPLAB C18 en de code vliegt in de PIC18f4550
Alvast bedankt
Het is me niet helemaal duidelijk hoe de onderdelen die je noemt (accellerometer en servo motoren) een gestabiliseerde voeding kunnen vormen.
Heb je iets meer uitleg van wat je zoekt?
Met een arduino en een wii-mote is dit heel makkelijk te doen. Maar als eindwerk zal je misschien zelf wat moeten leren?
Da_Vinci: Ik heb al heel wat bijgeleerd maar vindt heel weinig om met een PIC deze data om te zetten.. :s We mogen geen modules gebruiken dus moeten echt alles zelf doen <_<. Anders is het niet zo heel ingewikkeld te maken
Drieske: Wel de accelerometer kijkt of er verandering is in de ruimte en dan moet de servomotoren zo gaan bij geschakeld worden zodat deze eigenlijk horizontaal blijft met de grond.
Met de waarde van een accelerometer kan je heel eenvoudig een idee krijgen van de oriëntatie van het object waar deze aan verbonden is. Dit kan je doen door de oriëntatie van de zwaartekracht-vector (die je altijd kan zien op een accelerometer, g-force) te bepalen d.m.v. een tan2 operatie. Hiervoor zou het wel handig zijn ook een 3e accelerometer in de z-richting te hebben (of moet je maar één as bijregelen??). Je moet je MSB en je LSB gewoon achter elkaar hangen uiteraard indien je volledige precisie wilt.
Something like this:
hoekX = tan2(accDataY, accDataZ); // Draaien om x-as zal een vector op y-as veroorzaken
hoekY = tan2(accDataX, accDataZ);
Dit zou goed te doen moeten zijn voor een PIC18F. Indien je toch in de problemen komt met processing power kan je gaan gebruik maken van de small-angle approximation voor de tangens. Aangezien je toch continu bijregelt zullen je hoeken namelijk nooit groot worden en is er geen grote precisie vereist.
Belangrijk is ook dat je er rekening mee houdt dat accelerometer-data heel susceptibel is voor ruis. Elke kracht die op je object inwerkt zal je meting verstoren (ook de trillingen etc. van je eigen servo's). Daarom moet je uitmiddelen over veel waarden en extreme metingen uitsluiten. Mechanische processen zijn enorm traag in vgl met elektronica. Dit mag dus geen probleem zijn.
Voor de stabilisatie kan je dan een poging doen om een regelaar te ontwerpen die de hoeken om de x en y assen op 0 probeert te houden door de actuatoren aan te sturen. Dit zal redelijk wat prutswerk (trial/error) zijn aangezien je van een hoekwaarde naar een PWM waarde moet gaan. Het eenvoudigste is iig de frequentie van je PWM signaal constant te houden (bv. 100 Hz) en de duty cycle te gaan bijregelen met je regelaar. Begin met een gewone P-regeling:
duty_cycle_X = hoekX*P;
en regel zo je P af. Eventueel kan je je regelaar dan gaat uibreiden naar een volledige PID maar dat zal je dan wel zien. Zo'n PWM signaal generen op een PIC moet redelijk easy zijn. (pinnetje hoog zetten, delay1, pinnetje laag brengen, delay2, etc.)
Pieter-Jan: Wow je hebt wel veel duidelijkheid gebracht in men redenering die ik al hele tijd probeerde te maken. Ik heb 2 servomotoren dus 2 assen bijregelen.
Met msb en lsb aan elkaar hangen bedoelje dan toch
accDataX = Xdata0 + Xdata1;
en die formule van die hoeken zal ik eens proberen integreren (kan wel nog niet testen omdat mijn collega zijn hardware faalt)
Ook dacht ik dat de frequentie vooral zou moeten aanpassen ipv de duty cycle waardoor er constant verschil zou zijn in het zetten van de registers en dergelijken.
Ik heb onlangs ook nog een code gevonden in de PWM.h methode om via deze formule een PWM te maken :
void OpenPWM2 ( char period);
void SetDCPWM2( unsigned int duty_cycle);
het geeft me wel niet veel uitleg daarvoor dus das wel minder.
(en eventueel excuses voor mijn vele vragen, ik wil veel zelf doen maar soms reikt mijn kennis niet ver genoeg en google ook nie)
Alvast bedankt
Je moet oppassen bij het combineren van die MSB en LSB hé. Je moet ze combineren op bit niveau dus MSB en LSB achter elkaar zetten. Indien je MSB 11111111 is en je LSB 00000000 dna moet je dus:
1111111100000000 krijgen.
Om dit te implementeren in software moet je je MSB dus 8 bits shiften naar links:
accDataX = X_MSB << 8 + X_LSB;
Agree?
Die formule voor de hoek kan je rechtstreeks op een PIC schrijven. De tan2 zit normaal in de compiler inbegrepen (als ik mij goed herriner).
Bij PWM heb je 2 variabelen en dus 1 vrijheidsgraad indien je wilt gaan regelen. Ik zou écht wel de frequentie constant laten en enkel de duty cycle aanpassen. Dit is redelijk gebruikelijk en ook simpeler om over na denken (vind ik).
Die PWM methodes zou ik laten voor wat ze zijn. Zo'n dingen brengen alleen maar verwarring in het begin. En het implementeren van een PWM op een microcontroller kan leerrijk zijn. Probeer eens gewoon door een pin hoog en laag te brengen en delay functies te gebruiken een PWM signaal te generen. Meet dit. Komt de duty cycle overeen met wat je dacht? Komt de frequentie overeen? Goed. Nu kan je verder ... Dit moet iig je eerste stap zijn.
Had ooit is lang geleden een artikel geschreven op mijn website over het genereren van 4 verschillende PWM's met een PIC. Het is wel niet zo goed geschreven maar misschien ben je er iets mee:
http://www.pieter-jan.com/node/6
Indien je toch een extra IC mag gebruiken kan de PCA9685 héél handig zijn.
Ok sorry ik heb net is naar de datsheet van de PIC18f4550 gekeken en ik zie dat die een PWM module aan boord heeft. Het is véél gemakkelijker en sneller om die te gebruiken. Succes!
[Bericht gewijzigd door Henry S. op (6%)]
Met dat pin hoog en weer laag te doen en die delay functies vind ik raar om te gebruiken aangezien ik er dan niet veel meer mee ben? of vergis ik me?
Mijn leerkracht heeft me wel aangeraden om zo'n PWM methode te gaan implementeren ze eigenlijk dan alles automatisch regelt..
Alhoewel het idd niet zo gemakkelijk is de PWM.h te ontcijferen..
void OpenPWM2 ( char period);
void SetDCPWM2( unsigned int duty_cycle);
Het is een interessant artikel en zeker wel uitgebreid!!
Een extra IC is nu niet meer mogelijk aangezien de print al gemaakt is.
En met PWM module bedoel je de registers datje kan instellen?
(even terugkeren op eerder posts)
Het achter elkaar hangen van de MSB en LSB lukt.
De code:
"hoekX = tan2(accDataY, accDataZ); "
Geeft een fout maar als ik de tan2 verander in "atan2" dan lukt dit wel, ze geeft wel een error maar ik kan builden.
("Warning [2058] call of function without prototype")
met deze code:
"duty_cycle_X = hoekX*P; "
begrijp ik dan ook om P te regelen tot de juiste waarde is bereikt, maar in welke zin bedoelje dan om te gaan voor een PID?
(Ik vind het best wel genant dat ik zoveel vragen heb..)
Echt bedankt Pieter-Jan!
[Bericht gewijzigd door eldude op (34%)]