Controllare i PWM

Forum relativo alle schede FLEX, ERIKA Enterprise, RT-Druid, ScicosLab, ...

Moderator: paolo.gai

Locked
steo82fi
Newbie
Posts: 15
Joined: Fri Aug 06, 2010 3:33 pm

Controllare i PWM

Post by steo82fi » Fri Feb 11, 2011 11:31 am

Salve, sto cercando di sviluppuare un sistema di controllo per un robot mobile utilizzando la motion board senza utlizzare la generazione di codice scicos.
Come primo passo ho provato a utilizzare i pwm tramite le funzioni di EE che si trovano all'interno dei file contenuti in rt druid.
Nel main dopo l'inizializzazione dei pwm (EE_pwm_init( 1 , 20000 , 0 );) e del timer T1 richiamo il mio task con SetRelAlarm(myAlarm, 1, 1000); .
Nel task non faccio altro che settare il duty cicle con EE_pwm_set_duty_f( 1 , 0.5); .
Ora il comportamento che osservo è un movimento dei motori a singhiozzo in base al duty cicle (quindi duty al 100% i motori e quindi le ruote si muovono costantemente alla massima velocità mentre con valori intermedi vanno sempre alla massima velocità ma per intervalli di tempo dovuti al duty io credo), e mi chiedevo come posso invece controllare la velocità di rotazione?
Grazie

erikadds
Newbie
Posts: 45
Joined: Wed May 12, 2010 9:41 am

Re: Controllare i PWM

Post by erikadds » Fri Feb 11, 2011 3:32 pm

Ciao,
per pilotare i motori Dc serve sul lato hardware:
- una scheda Flex + DemoII (Motion board) + il plugin per i motori DC
(il plugin non è quello dei servomotori che usa l'Amazing Ball...ma quello specifico
per i motori DC in grado di pilotare fino a 2 motori).
mentre sul lato software:
- un'applicazione che riesca a configurare i driver per la lettura degli encoder e le periferiche per la
generazione dei segnali pwm, e che implementi un algoritmo di controllo.

Immagino che tu abbia già l'hardware corretto, simile a quello descritto, in caso contrario puoi acquistarlo
direttamente da noi.
Per quanto riguarda il software hai a disposizione due set di funzioni. Le funzioni EE_pwm... e le funzioni EE_dcm_pwm...
Il secondo set di funzioni serve per generare un segnale pwm da inviare ad un motore DC e compatibile
con il plugin a cui ho accennato prima.
Le funzioni le puoi trovare nel file:
pkg\board\ee_flex\src\ee_flex_motionboard.c
Un esempio su come tali funzioni possono essere utilizzate lo puoi trovare invece nel file:
contrib\scicos\src\pic30\flex_daughter_dcm_pwm.c
Le funzioni che hai usato invece sono nate per il controllo dei servomotori dell'Amazing Ball ma
possono anche essere usate per il tuo scopo.
Devi però stare attento al fatto che la funzione EE_pwm_set_duty_f effettua un'inversione del duty-cycle
(cioè a 0% corrisponde 100% e viceversa...).

Il duty-cycle serve per stabilire quanto tempo deve stare alta la tensione all'interno del periodo.
Ciò che dovresti vedere è che il motore si porta sempre ad una velocità costante e proporzionale al duty-cycle
e non un comportamento a singhiozzo e questo perchè il motore ha una risposta in frequenza simile a quella di
un filtro passa-basso.
Per controllare la velocità in anello aperto basta modificare ad hoc il duty-cycle.
Per il controllo di velocità in ciclo chiuso sono necessarie competenze nel campo dei controlli automatici.

Un comportamento diverso può essere legato ad un utilizzo errato delle funzioni o all'utilizzzo di un
alimentatore poco potente...

Spero di esserti stato utile.
Saluti,
Dario

steo82fi
Newbie
Posts: 15
Joined: Fri Aug 06, 2010 3:33 pm

Re: Controllare i PWM

Post by steo82fi » Sat Feb 12, 2011 11:00 am

Ciao Dario, grazie della risposta.
Il robot che ho a disposizione fa uso della demo2 però non utilizza il plugin ma ha i motori sono direttamente collegati ai CON della motion board(tra il motore e la scheda c'è un ponte H) per questo ho pensato di usare il set di funzioni EE_pwm.
Mi ero accorto dell'inversione del duty cicle leggendo il dodice della funzione e il comportamento che mi aspettavo è esattamente quello che mi hai descritto te, per cui credo ci sia un qualche errore a livello di utilizzo delle funzioni (la bassa alimentazione la scarterei perchè con un .cof generato tramite scicos tutto funziona normalmente). Potrebbe essere un qualcosa dovuto al timer che va a resettare i motori?
Ti scrivo qui sotto le poche righe di codice che vado a compilare, data l'inesperienza è sicuro che sbaglio qualcosa.

/* ********************************************************** */
/* Code C */
/* ********************************************************** */
#include "ee.h"
#include "cpu/pic30/inc/ee_irqstub.h"

// Primary (XT, HS, EC) Oscillator without PLL
_FOSCSEL(FNOSC_PRI);
// OSC2 Pin Function: OSC2 is Clock Output - Primary Oscillator Mode: XT Crystanl
_FOSC(OSCIOFNC_ON & POSCMD_XT);
// Watchdog Timer Enabled/disabled by user software
_FWDT(FWDTEN_OFF);
// Disable Code Protection
_FGS(GCP_OFF);
/* insert a stub for the functions not directly supported by __FP__ */

/* Program the Timer1 peripheral to raise interrupts */
void T1_program(void)
{
T1CON = 0; /* Stops the Timer1 and reset control reg */
TMR1 = 0; /* Clear contents of the timer register */
PR1 = 0x9c40; /* Load the Period register with the value 0x9c40 (1ms @ 40MIPS) */
IPC0bits.T1IP = 5; /* Set Timer1 priority to 1 */
IFS0bits.T1IF = 0; /* Clear the Timer1 interrupt status flag */
IEC0bits.T1IE = 1; /* Enable Timer1 interrupts */
T1CONbits.TON = 1; /* Start Timer1 with prescaler settings at 1:1
* and clock source set to the internal
* instruction cycle */
}

/* Clear the Timer1 interrupt status flag */
void T1_clear(void)
{
IFS0bits.T1IF = 0;
}

/* This is an ISR Type 2 which is attached to the Timer 1 peripheral IRQ pin
* The ISR simply calls CounterTick to implement the timing reference
*/
ISR2(_T1Interrupt)
{
/* clear the interrupt source */
T1_clear();

/* count the interrupts, waking up expired alarms */
CounterTick(myCounter);

}
TASK(myTask){
EE_pwm_set_duty_f( 1 , 0.5);

EE_pwm_set_duty_f( 2 , 0.5);
}

int main(void)
{
EE_pwm_init( 1 , 20000 , 0 );
EE_pwm_init( 2 , 20000 , 0 );
/* Program Timer 1 to raise interrupts */
T1_program();

SetRelAlarm(myAlarm, 1, 10000);

/* Forever loop: background activities (if any) should go here.
Please note that in this example the code never reach this point... */
for (;;);

return 0;
}

/*
* conf.oil
*/
CPU mySystem {

OS myOs {
//EE_OPT = "VERBOSE";
EE_OPT = "DEBUG";
EE_OPT = "NODEPS";
EE_OPT = "__dsPIC33F__";
EE_OPT = "__C30__";

CFLAGS = "-I $(PIC30_GCCDIR)/support/h";
CFLAGS = "-I ../.";
CFLAGS = "-Os";
ASFLAGS = "";

CPU_DATA = PIC30 {
APP_SRC = "code.c";
MULTI_STACK = FALSE;
ICD2 = TRUE;
};

MCU_DATA = PIC30 {
MODEL = PIC33FJ256MC710;
};

BOARD_DATA = EE_FLEX {
USELEDS = TRUE;
};

KERNEL_TYPE = FP;
/* ********************************************************** */
/* Contrib Library Inlcusion */
/* ********************************************************** */
EE_OPT = "__ADD_LIBS__";
CFLAGS = "-DYOUR_BOARD";
EE_OPT = "__USE_MOTIONBOARD__";
EE_OPT = "__USE_ENCODER__";
EE_OPT = "__USE_PWM__";
//LIB = ENABLE { NAME = "SCICOS"; };
};

/* User section */
TASK myTask {
PRIORITY = 2;
STACK = SHARED;
SCHEDULE = FULL;
};

COUNTER myCounter;

ALARM myAlarm {
COUNTER = "myCounter";
ACTION = ACTIVATETASK { TASK = "myTask"; };
};
};

Grazie per l'aiuto.
Stefano

paolo.gai
Administrator
Posts: 875
Joined: Thu Dec 07, 2006 12:11 pm

Re: Controllare i PWM

Post by paolo.gai » Sat Feb 12, 2011 6:28 pm

Ciao,

Il periodo del PWM è 20ms.
Il duty cycle è 0,5, ovvero 10ms alto e 10ms basso. (o viceversa).
Il task è periodico a 1ms.
ogni periodo il PWM viene riprogrammato. 99 su 100 quando il PWM viene riprogrammato il contatore riparte da capo, per cui l'uscita rimane fissa...

Prova ad abbassare la frequenza del task o ad alzare la frequenza del PWM...

PJ

steo82fi
Newbie
Posts: 15
Joined: Fri Aug 06, 2010 3:33 pm

Re: Controllare i PWM

Post by steo82fi » Mon Feb 14, 2011 5:09 pm

Ho risolto. Il problema credo stesse nel fatto che non usavo il PLL.
Avrei un altro paio di domande. Come posso invertire il senso di rotazione? C'è una qualche guida per implementare del codice che simuli il blocco l'udp_send di scicos? Mi farebbe molto comodo monitorare alcune cose da scicoslab.
grazie

paolo.gai
Administrator
Posts: 875
Joined: Thu Dec 07, 2006 12:11 pm

Re: Controllare i PWM

Post by paolo.gai » Mon Feb 14, 2011 7:25 pm

simulare il comportamento del blocco scicos è abbastanza semplice. In particolare, ti consiglio per prima cosa di crearti un progetto scicos con ilblocco UDP.
Poi generi il codice, e prendi i settaggi dell'OIL generato.

Infine, replichi quanto viene fatto nel corpo del blocco scicos UDP. Il codice lo trovi su

http://svn.tuxfamily.org/viewvc.cgi/eri ... iew=markup

e su

http://svn.tuxfamily.org/viewvc.cgi/eri ... iew=markup

bye

PJ

steo82fi
Newbie
Posts: 15
Joined: Fri Aug 06, 2010 3:33 pm

Re: Controllare i PWM

Post by steo82fi » Tue Feb 15, 2011 11:09 am

Ho provato a compilare un progettino in cui prendo il valore dall'encoder e lo rimando in udp. Solo che durante la compilazione ricevo questo errore:
/************************************************************************************************************************************************/
C:\cygwin\bin\bash found!
MAKE_DIRECTORIES (after a clean)
CPP ARP.c
In file included from c:/Evidence/Evidence/eclipse/plugins/CO8163~1.201/ee_base/contrib/microchip/tcpip_510/inc/TCPIP_Stack/TCPIP.h:283,
from c:\Evidence\Evidence\eclipse\plugins\CO8163~1.201\ee_base\contrib\microchip\tcpip_510\libsrc\ARP.c:64:
c:/Evidence/Evidence/eclipse/plugins/CO8163~1.201/ee_base/contrib/microchip/tcpip_510/inc/TCPIP_Stack/MAC.h:88:3: error: #error No Ethernet/WiFi controller defined in HardwareProfile.h. Defines for an ENC28J60, ENC424J600/624J600, or ZeroG ZG2100 must be present.
In file included from c:/Evidence/Evidence/eclipse/plugins/CO8163~1.201/ee_base/contrib/microchip/tcpip_510/inc/TCPIP_Stack/TCPIP.h:283,
from c:\Evidence\Evidence\eclipse\plugins\CO8163~1.201\ee_base\contrib\microchip\tcpip_510\libsrc\ARP.c:64:
c:/Evidence/Evidence/eclipse/plugins/CO8163~1.201/ee_base/contrib/microchip/tcpip_510/inc/TCPIP_Stack/MAC.h:167: error: syntax error before 'ReadPHYReg'
c:/Evidence/Evidence/eclipse/plugins/CO8163~1.201/ee_base/contrib/microchip/tcpip_510/inc/TCPIP_Stack/MAC.h:167: warning: type defaults to 'int' in declaration of 'ReadPHYReg'
c:/Evidence/Evidence/eclipse/plugins/CO8163~1.201/ee_base/contrib/microchip/tcpip_510/inc/TCPIP_Stack/MAC.h:167: warning: data definition has no type or storage class
make: *** [obj//cygdrive/c/Evidence/Evidence/eclipse/plugins/CO8163~1.201/ee_base/contrib/microchip/tcpip_510/libsrc/ARP.o] Error 1

/************************************************************************************************************************************************/
Il file OIL è quello generato da scicos tranne per il campo APP_SRC del CPU_DATA.

CPU mySystem {

OS myOs {

EE_OPT = "DEBUG";
EE_OPT = "NODEPS";

EE_OPT = "__ADD_LIBS__";

EE_OPT = "__C30__";
EE_OPT = "__dsPIC33F__";
CFLAGS = "-I $(PIC30_GCCDIR)/support/h";
LIB = ENABLE { NAME = "TCPIP"; };
CFLAGS = "-mlarge-data";

CPU_DATA = PIC30 {
APP_SRC = "code.c";
MULTI_STACK = FALSE;
ICD2 = TRUE;
};

MCU_DATA = PIC30 {
MODEL = PIC33FJ256MC710;
};

BOARD_DATA = EE_FLEX {
};

KERNEL_TYPE = FP;

LIB = ENABLE {
NAME = "SCICOS";
};
};
TASK myTask {
PRIORITY = 100;
STACK = SHARED;
SCHEDULE = FULL;
};

TASK UDP_TASK {
PRIORITY = 1;
STACK = SHARED;
SCHEDULE = FULL;
};

COUNTER myCounter;

ALARM myAlarm {
COUNTER = "myCounter";
ACTION = ACTIVATETASK { TASK = "myTask"; };
};

};

Qualche idea?
Grazie

erikadds
Newbie
Posts: 45
Joined: Wed May 12, 2010 9:41 am

Re: Controllare i PWM

Post by erikadds » Fri Feb 18, 2011 12:06 pm

Ciao,
l'errore è dovuto al fatto che manca la macro della board.
Questa macro insieme ad altre macro e ad altre informazioni utili per la compilazione
possono essere trovate nel file "app.mk". Questo makefile viene creato nella cartella di
progetto quando si usa il generatore di codice di scicos.
Quando generi la cartella Debug con il druido all'interno di Eclipse ricordati di stoppare la compilazione
e di modificare il makefile generato aggiungendo il comando per l'inclusione del file "app.mk".
Devi aggiungere:
include ../app.mk
alla fine del makefile prima di "rules.mk".

Esempio:
...
...
...
############################################################################
#
# end
#
############################################################################
include ../app.mk
include $(EEBASE)/pkg/cfg/rules.mk

Dopo aver fatto questa modifica cancella la cartella "obj" e fai ripartire la compilazione
senza modificare il "conf.oil", altrimenti sarà creato un nuovo makefile e perderai le modifiche.

Fammi sapere se funziona.
Ciao,
Dario

steo82fi
Newbie
Posts: 15
Joined: Fri Aug 06, 2010 3:33 pm

Re: Controllare i PWM

Post by steo82fi » Sat Feb 19, 2011 11:17 am

Allora ho aperto un file app.mk generato da un progetto scicos con l'udp e ho preso i campi EE_OPT che mancavano nel mio file oil ( EE_OPT = "__USE_MOTIONBOARD__"; EE_OPT = "__USE_UDP__";) ho preferito fare cosi in modo che poi non sono dipendente dal file app.mk. E ora compila tutta la parte di librerie per il tcp/ip ecc.
Ora però mi da un errore nella mia parte di codice quando vado ad attivare il task UDP_SEND.
Dal dspic_main.c che ho generato tramite scicos ho visto che lui richiama prima il task rti_sci e dopo attiva il task dell'udp.
Questo è l'errore che ottengo
CPP code.c
c:\DOCUME~1\Steo\DOCUME~1\WORKSP~1\UDP_test\code.c: In function 'main':
c:\DOCUME~1\Steo\DOCUME~1\WORKSP~1\UDP_test\code.c:133: error: 'UPD_TASK' undeclared (first use in this function)
c:\DOCUME~1\Steo\DOCUME~1\WORKSP~1\UDP_test\code.c:133: error: (Each undeclared identifier is reported only once
c:\DOCUME~1\Steo\DOCUME~1\WORKSP~1\UDP_test\code.c:133: error: for each function it appears in.)
make: *** [obj/code.o] Error 1
ho provato anche a aggiungere il campo APP_SRC= "flex_udp.c" all'interno del task ma niente.
In allegato invece ci sono il file .oil e il .c
Grazie
Attachments
UDP_test.rar
(2.18 KiB) Downloaded 294 times

paolo.gai
Administrator
Posts: 875
Joined: Thu Dec 07, 2006 12:11 pm

Re: Controllare i PWM

Post by paolo.gai » Sat Feb 19, 2011 12:12 pm

il file code.c contiene la stringa "UPD_TASK". Se non sbaglio originariamente quelal stringa era poi processata con il rpeprocessore GCC per generare il nome giusto.

Come hai chiamato il task UDP nel file .OIL? usa lo stesso nome...

(può darsi poi che UPD_TASK sia UDP_TASK...)

PJ

steo82fi
Newbie
Posts: 15
Joined: Fri Aug 06, 2010 3:33 pm

Re: Controllare i PWM

Post by steo82fi » Sun Feb 20, 2011 10:37 am

Mi era sfuggito l'errore di battitura...eppure avevo controllato...
Adesso mi da questo errore:
CPP eecfg.c
CPP code.c
LD
.\libtcpip.a(Tick.o)(.text+0xca): In function `_T1Interrupt':
c:\Evidence\Evidence\eclipse\plugins\CO8163~1.201\ee_base\contrib\microchip\tcpip_525\libsrc\Tick.c:433: multiple definition of `_T1Interrupt'
obj/code.o(.text+0x26):c:\DOCUME~1\Steo\DOCUME~1\WORKSP~1\UDP_test\code.c:100: first defined here
c:\PROGRA~1\MICROC~1\MPLABC~1\bin\bin\pic30-coff-ld.exe: Link terminated due to previous error(s).
make: *** [pic30.cof] Error 1

dovrei forse utilizzare un altro timer? come posso fare?
Grazie

paolo.gai
Administrator
Posts: 875
Joined: Thu Dec 07, 2006 12:11 pm

Re: Controllare i PWM

Post by paolo.gai » Sun Feb 20, 2011 11:46 am

L'errore dice che hai definito due volte lo stesso interrupt.

2 possibilità:
- metti tutto in un interrupt solo
- usi un altro interrupt (ce ne sono fino a 9 sul dsPIC!)

PJ

Locked