TODOPIC
Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: Enner en 01 de Julio de 2016, 06:04:57
-
Hola,
Tengo un Problema con un manillar que tiene integrado un acelerador con efecto Hall (ver imagen),
Este acelerador va alimentado a 5V, al poner el voltimetro en la salida tiene por defecto un voltage residual (offset) 0,8V permanente.
Cuando de doy a todo gas en la salida entrega 4,3V máximos todo cuadra +/-(5V-0,8V).
Este acelerador regula un PWM de un motor, pero no va de una forma gradual va atrompicones.
El Acelerador efecto Hall tiene 3 Pines (VCC,GND,Out)
Cogi por separado el acelerador y regula bien de una forma progresiva, por otra parte cogi la placa del driver y el motor lo regula perfecto.
Al poner el tester en la salida del PWM los volatges pasan de 7V a medida que le vas dando gas pasa a 10V 17V,21V... hasta llegar a los 24V que esl el máximo.
Pero no lo hace de una manera lineal ... Aqui os dejo todo el código.
Device = 18F26K22
Xtal = 16
Config_Start
FOSC = INTIO67
PLLCFG = On 'On ' Oscillator multiplied by 4
PRICLKEN = On ' Primary clock enabled
FCMEN = OFF ' Fail-Safe Clock Monitor disabled
IESO = Off ' Internal/External Oscillator Switchover mode disabled
PWRTEN = On ' Power up timer enabled
BOREN = SBORDIS ' Brown-out Reset enabled in hardware only (SBOREN is disabled)
BORV = 190 ' Brown Out Reset Voltage set to 1.90 V nominal
WDTEN = Off ' Watch dog timer is always disabled. SWDTEN has no effect.
WDTPS = 128 ' Watchdog Timer Postscale 1:128
CCP2MX = PORTC1 ' CCP2 input/output is multiplexed with RC1
PBADEN = Off ' PORTB<5:0> pins are configured as digital I/O on Reset
CCP3MX = PORTC6 ' P3A/CCP3 input/output is multiplexed with RC6
HFOFST = On ' HFINTOSC output and ready status are not delayed by the oscillator stable status
T3CMX = PORTC0 ' Timer3 Clock Input (T3CKI) is on RC0
P2BMX = PORTB5 ' ECCP2 B (P2B) is on RB5 (EXTMCLR = Enable MCLR/Disable RE Input)
MCLRE = INTMCLR ' MCLR pin enabled, RE3 input pin disabled (INTMCLR = Disable MCLR/Enabled RE Input)
STVREN = Off ' Stack full/underflow will not cause Reset
LVP = Off ' Single-Supply ICSP disabled
XINST = Off ' Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
Debug = Off ' Disabled
Cp0 = Off ' Block 0 (000800-001FFFh) not code-protected
CP1 = Off ' Block 1 (002000-003FFFh) not code-protected
CP2 = Off ' Block 2 (004000-005FFFh) not code-protected
CP3 = Off ' Block 3 (006000-007FFFh) not code-protected
CPB = Off ' Boot block (000000-0007FFh) not code-protected
CPD = Off ' Data EEPROM not code-protected
WRT0 = Off ' Block 0 (000800-001FFFh) not write-protected
WRT1 = Off ' Block 1 (002000-003FFFh) not write-protected
WRT2 = Off ' Block 2 (004000-005FFFh) not write-protected
WRT3 = Off ' Block 3 (006000-007FFFh) not write-protected
WRTC = Off ' Configuration registers (300000-3000FFh) not write-protected
WRTB = Off ' Boot Block (000000-0007FFh) not write-protected
WRTD = Off ' Data EEPROM not write-protected
EBTR0 = Off ' Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
EBTR1 = Off ' Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
EBTR2 = Off ' Block 2 (004000-005FFFh) not protected from table reads executed in other blocks
EBTR3 = Off ' Block 3 (006000-007FFFh) not protected from table reads executed in other blocks
EBTRB = Off ' Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End
Declare Adin_Res = 10 ' Resolucion 10 BITS
Declare Adin_Tad = FRC ' Oscilator RC AD
Declare Adin_Stime = 100 ' AD 100uS
Declare CCP1_Pin = PORTC.2 ' Pin para PWM CCP1
ANSELA = %00001111 ' Port A4-A7 Digital=0 / A0-A3 Analog
TRISA = %11101111 ' Port A I/O
ADCON1 = %10000000 ' Puerto Analogico
ADCON2 = %10000000 ' Right justified
Dim DUTY As Byte ' Ciclo Duty PWM
Dim AD_TENSION As ADRESL.Word ' Señal Conversol AD
Dim AD_TMP as Word ' Valor Temporal
Dim VALOR_GAS As Float ' Calculo voltage
Dim VOLT As Float ' En Voltios
Dim A as Byte
DUTY=0
VOLT=0
AD_TENSION =0
AD_TMP=0
VALOR_GAS=0
CLS
Main:
GoSub ADC_Gas_Manillar
Print At 4,6,Dec2 VOLT ," - ", Dec DUTY 'Display
HPWM 1,DUTY,20000
DelayMs 5
Goto Main
ADC_Gas_Manillar:
For A=1 to 15
AD_TENSION = ADIn 1 ' Conversor AD
AD_TMP=AD_TMP+AD_TENSION 'Temporal para la Media de AD
Next
AD_TMP=AD_TMP/15 'Calcula la Media
VALOR_GAS = (489 *(AD_TMP/ 10) )-0.8 ' 489 = (5V/1023) 10Bits / Vref 5V
VOLT = (VALOR_GAS / 10000) ' Valor en Voltios
DUTY=(255/4.3)*VOLT ' 4.3V el voltage Maximos Gas al Ma´ximo (no los 5V)
Return
END
Ver Imagen http://es.aliexpress.com/store/product/Free-Shipping-High-Quality-Wuxing-Brand-48V-E-bike-Twist-Throttle-with-Battery-Indicator-only-right/313864_526345570.html (http://es.aliexpress.com/store/product/Free-Shipping-High-Quality-Wuxing-Brand-48V-E-bike-Twist-Throttle-with-Battery-Indicator-only-right/313864_526345570.html)
Gracias.
-
No uso tu lenguaje pero si la frecuencia que programaste es de 20000Hz bajo una frecuencia de reloj de 64Mhz, la resolución que consigues en el modulo CCP es de 10bits con dos posibles prescaler: 4 y 16. Con el prescaler 4 el duty cycle máximo es de solo 799 puntos y con el prescaler 16 el duty cycle máximo es de 99. Esto implica que no puedes cargar valores mayores a los que expongo o el PWM es posible que haga cosas raras. De todas maneras hace tiempo que no uso este modulo, si alguien puede echar un vistazo para a ver que le parece.
-
He echado otro vistazo y me sale que para los siguientes valores de AN1:
AN1=0, duty = 0
AN1=510, duty = 158
AN1=854, duty = 255 'Maximo
AN1 = 1023, duty = 61
Define CONFIG = 0x2f50
Define CONFIG2 = 0x3ffc
Define CLOCK_FREQUENCY = 8
'device = 18f26k22
'xtal = 16
'config_start
'fosc = intio67
'pllcfg = On 'On ' Oscillator multiplied by 4
'priclken = On 'Primary clock enabled
'fcmen = off 'Fail-Safe Clock Monitor disabled
'ieso = off 'Internal/External Oscillator Switchover mode disabled
'pwrten = On 'Power up timer enabled
'boren = sbordis 'Brown-out Reset enabled in hardware only (SBOREN is disabled)
'borv = 190 'Brown Out Reset Voltage set to 1.90 V nominal
'wdten = off 'Watch dog timer is always disabled. SWDTEN has no effect.
'wdtps = 128 'Watchdog Timer Postscale 1:128
'ccp2mx = portc1 'CCP2 input/output is multiplexed with RC1
'pbaden = off 'PORTB<5:0> pins are configured as digital I/O on Reset
'ccp3mx = portc6 'P3A/CCP3 input/output is multiplexed with RC6
'hfofst = On 'HFINTOSC output and ready status are not delayed by the oscillator stable status
't3cmx = portc0 'Timer3 Clock Input (T3CKI) is on RC0
'p2bmx = portb5 'ECCP2 B (P2B) is on RB5 (EXTMCLR = Enable MCLR/Disable RE Input)
'mclre = intmclr 'MCLR pin enabled, RE3 input pin disabled (INTMCLR = Disable MCLR/Enabled RE Input)
'stvren = off 'Stack full/underflow will not cause Reset
'lvp = off 'Single-Supply ICSP disabled
'xinst = off 'Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
'debug = off 'Disabled
'cp0 = off 'Block 0 (000800-001FFFh) not code-protected
'cp1 = off 'Block 1 (002000-003FFFh) not code-protected
'cp2 = off 'Block 2 (004000-005FFFh) not code-protected
'cp3 = off 'Block 3 (006000-007FFFh) not code-protected
'cpb = off 'Boot block (000000-0007FFh) not code-protected
'cpd = off 'Data EEPROM not code-protected
'wrt0 = off 'Block 0 (000800-001FFFh) not write-protected
'wrt1 = off 'Block 1 (002000-003FFFh) not write-protected
'wrt2 = off 'Block 2 (004000-005FFFh) not write-protected
'wrt3 = off 'Block 3 (006000-007FFFh) not write-protected
'wrtc = off 'Configuration registers (300000-3000FFh) not write-protected
'wrtb = off 'Boot Block (000000-0007FFh) not write-protected
'wrtd = off 'Data EEPROM not write-protected
'ebtr0 = off 'Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
'ebtr1 = off 'Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
'ebtr2 = off 'Block 2 (004000-005FFFh) not protected from table reads executed in other blocks
'ebtr3 = off 'Block 3 (006000-007FFFh) not protected from table reads executed in other blocks
'ebtrb = off 'Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
'config_end
'declare adin_res = 10 'Resolucion 10 BITS
'declare adin_tad = frc 'Oscilator RC AD
'declare adin_stime = 100 'AD 100uS
Define SINGLE_DECIMAL_PLACES = 2
Define ADC_SAMPLEUS = 10
Define ADC_CLOCK = 5 'Tad 2uSeg a 8Mhz
Define SIMULATION_WAITMS_VALUE = 1
'declare ccp1_pin = portc.2 'Pin para PWM CCP1
'ansela = %00001111 'Port A4-A7 Digital=0 / A0-A3 Analog
ANSEL = %00001111
TRISA = %11101111 'Port A I/O
TRISB = ffh
ADCON1 = %10000000 'Puerto Analogico
TRISB.3 = 0 'PWM
'adcon2 = %10000000 'Right justified
Hseropen 4800
Dim duty As Byte 'Ciclo Duty PWM
Dim ad_tension As Word 'adresl.Word 'Señal Conversol AD
Dim ad_tmp As Word 'Valor Temporal
Dim valor_gas As Single 'float 'Calculo voltage
Dim volt As Single 'float 'En Voltios
Dim a As Byte
Dim aux As Single
duty = 0
volt = 0
ad_tension = 0
ad_tmp = 0
valor_gas = 0
'pwm
'cls
PWMon 1, 9
main:
Gosub adc_gas_manillar
Hserout #volt, " -", #duty 'print at 4, 6, dec2 volt, " - ", dec duty 'Display
PWMduty 1, duty 'hpwm 1, duty, 20000
'WaitMs 5 'delayms 5
Goto main
End
adc_gas_manillar:
For a = 1 To 15
Adcin 1, ad_tension '= adin 1 'Conversor AD
ad_tmp = ad_tmp + ad_tension 'Temporal para la Media de AD
Next a
ad_tmp = ad_tmp / 15 'Calcula la Media
valor_gas = (489 * (ad_tmp / 10)) - 0.8 '489 = (5V/1023) 10Bits / Vref 5V
volt = valor_gas / 10000 'Valor en Voltios
aux = (255 / 4.3) * volt '4.3V el voltage Maximos Gas al Ma´ximo (no los 5V)
duty = aux
Return
-
Hey,
Siento por la demora a responderte, ya monté la placa porque de la protoboard con tanto cable no me fiaba.
Probé tu código y va muy bien.
Lo único que haber como lo podemos hacer si se puede hacer...
El manillar como ya dije está equipado con un variador efecto hall. a la hora de dar más gas o velocidad, el motor empieza arrancar cuando llevo unos 1.8 o 2V casi un 41% de duty.
y tengo que ir girando el manillar muy muy lentamente para que no se disparé y es muy molesto porque vas con miedo.
Si restamos los 4.3 a plena potencia - los 0.8 de offset residual, quedan 3.8V de trabajo para un duty 100%.
Como puedo hacer que esto vaya mucho más suave sin tener que preocuparme de ir lentamente dando gas.
El comado HPWM trabaja a 8bits =0 a 255) que pasaria si fuese 10bits (0 a 1023) aunqe no se llega a 1023 son unos 881 +/-, esto influiria en algo.!!
o que otras soluciones pueden haber.
Gracias.
-
No te puedes pasar del máximo permitido, de otro modo puedes tener problemas.
Mediante una formula muy simple se puede acotar el máximo y el mínimo, de hecho ya la utilizas en tu programa.
Yo te recomiendo que utilices el modulo CCP directamente, sin usar el comando o función del sistema, creo que todos los problemas te vienen por ese lado y de esta manera sales de dudas.
De todas formas buscaré un ejemplo para trabajar con el modulo ccp de forma directa.
-
Gracias dogflu66,
Respecto PWM de 8bits y 10bits se notaria alguna mejoria.
Lo de poder arrancar apartir de los 2V (41% duty +/-) que es cuando el motor empieza arrancar hasta el máximo se puede hacer algo.
Es decir que el Duty del 41% (2V) fuese el 0% hasta el Máximo de los 4.3V que seria el 100% del Duty.
Saludos.
-
Cuanto mayor es la resolución los tránsitos de potencia son más suaves y por lo tanto mayor control.
Con una formulita con limite superior e inferior:
V = ((v / 4.3v) * (4.3v - 2v)) + 2v
Limite superior = 4.3v
Limite inferior = 2v
De todas maneras si el 0v = 2v = 41%, puede que no se mueva el motor pero tiene consumo, por lo que tienes que dejar una zona muerta inicial que suministre potencia 0.
Por ejemplo:
V = ((v / 4.3v) * (4.3v - 1.5v)) + 1.5v
If v<2 then pwm=0
-
Osea para no perder el hilo con lo anterior...
El código quedaria de esta manera:
adc_gas_manillar:
For a = 1 To 15
Adcin 1, ad_tension '= adin 1 'Conversor AD
ad_tmp = ad_tmp + ad_tension 'Temporal para la Media de AD
Next a
ad_tmp = ad_tmp / 15 'Calcula la Media
valor_gas = (489 * (ad_tmp / 10)) - 0.8 '489 = (5V/1023) 10Bits / Vref 5V
volt = valor_gas / 10000 'Valor en Voltios
Duty = ((volt / 4.3) * (4.3 - 1.5)) + 1.5
If Duty <2 Then Duty=0
Return
-
Bueno, eso es la idea, ahora tendrás que probar con distintos valores. Una vez que obtengas una mejoría real tendrás otros problemas, posiblemente menores. En fin, pasito a pasito.
-
Otro tema es la media aritmetica, no es exactamente así, luego veré de mejorarla para esta aplicación.
-
Hay algo va mal..
en Duty: Duty = ((volt / 4.3) * (4.3 - 1.5)) + 1.5
la variable Duty no da los valores del 0 al 255, si no da exactamente los voltajes del 2V al 4.3V
ahora como se hace para que el voltaje se ha del 0 al 255 Duty.
Saludos.
-
Cuanto mayor es la resolución los tránsitos de potencia son más suaves y por lo tanto mayor control.
Con una formulita con limite superior e inferior:
V = ((v / 4.3v) * (4.3v - 2v)) + 2v
Limite superior = 4.3v
Limite inferior = 2v
De todas maneras si el 0v = 2v = 41%, puede que no se mueva el motor pero tiene consumo, por lo que tienes que dejar una zona muerta inicial que suministre potencia 0.
Por ejemplo:
V = ((v / 4.3v) * (4.3v - 1.5v)) + 1.5v
If V<2 then pwm=0
De una forma rápida podría ser:
V = ((v / 4.3v) * (4.3v - 1.5v)) + 1.5v
Duty = (V x 255PwmMax.) / 4.3v
-
Solo comentario, porque no usar las referencias para suprimir el voltaje residual.
Colocando dos potenciómetros, uno ajustado a 0.8 V que iría a Ref- y otro ajustado a 4.3 a Ref+, asi el ADC hace la conversión entre ese rango, claro solo hay que configurar esa opción en el PIC.
-
Agregando màs info sobre lo comentado anteriormente, adjunto los archivos de ISIS y Proton Ide para un PWM de 10 bits de resolución, la verdad me tomé la molestia de realizar el código porque estoy realizando un proyecto parecido para uno de mis brazos robóticos con un Joystick: http://www.farnell.com/datasheets/30691.pdf
Cualquier duda o aclaración no duden en plantearlo.
Saludos
-
Antes de todas gracias por aportar información.
Poco a poco vamos mejorando...
Lo que dices sobre suprimir el valor 0.8V con -ref seria lo ideal, pues la placa ya estaba hecha y no sabía que estos aceleradores efecto hall tuviesen ese voltaje residual ya que me lo trajeron a última hora.
Ahora probare junto con el código de dogflu66 y el tuyo en PWM ya que utilizaba la instrucción HPWM a ver cómo funciona.
Una duda que tengo para modificar la frecuencia en PR2 para que sea 10Bits tiene que ser 255.
PR2= 255 es una frecuencia de unos 15Khz y yo necesitaría unos 24Khz esto sería PR2=165 y el T2CON = %00000101 (Prescaler 4:4)
Gracias.
-
Aqui tines un calculador, no puedes elegir la frecuencia que quieras porque es un multiplo del cristal usado.
Si necesitas una frecuencia determinada necesitas un cristal especial.
http://www.micro-examples.com/public/microex-navig/doc/097-pwm-calculator.html
Recuerda que el duty-cycle tiene que ser el 100% para tu aplicación.
-
Hola,
He encontrado un Código por internet, para el problema de la aceleración rápida pero este emplea un Joystick analogico de la PS3 en vez el acelerador con Efecto Hall.
pero la mayoria del código no se que significa.
a ver si podeis ayudarme.
Este es el Video: https://www.youtube.com/watch?v=zaTskMjpXtA (https://www.youtube.com/watch?v=zaTskMjpXtA)
void loop() {
potval=analogRead(potentiometer);
potval=map(potval,0,1023,0,180);
while(curval<potval){
potval=analogRead(potentiometer);
potval=map(potval,0,1023,0,180);
curval=curval+1;
ESC.write(curval);
SoftwareServo::refresh();
Serial.println(curval);
delay(50);}
Saludos.
-
Podrás adjuntar el código completo para analizarlo?. Y tendrás el circuito del motor para ir analizando también?. Solo me gustaría entender el problema, lo que necesitas es que cuando alcanzas el tope máximo del acelerador, independientemente que velocidad tenga el motor, necesitas que incremente proporcionalmente hasta llegar al máximo. Porque al parecer es lo que hace el pequeño código adjunto.
Saludos
-
Hey,
Efectivamente casi todo va bien lo que no logro es que valla suave y voy aplicando retardos o delays pero no logro que tenga algo lineal .
Saludos.
-
Lo que puedes hacer es no mandar directo la conversión al duty del pwm, mejor usarlo solo como referencia y crear otra variable que vayas incrementando hasta alcanzar el duty destino. Ahora, solo te interesa controlar el incremento o también el decremento??
-
Otro detalle es si ya decidiste si usar el módulo CCP del pic para usar los 10 bits de resolución, o manejar el comando HPWM de basic con 8 bits de resolución. Sobre la frecuencia de trabajo del PWM depende mucho del Oscilador, y solo ten en cuenta que el incremento de la frecuencia del PWM decrementa la resolución, esto usando el CCP.