Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature currently requires accessing the site using the built-in Safari browser.
Bueno, te lo agradeceria... no tanto el codigo sino la explicacion. hay algo está fallando en mi código... aparte que al no usar interrupciónes hay que usar bits para indicar que el incremento o decremento ya se envió y no lo haga en cada comparación...Bueno, nada más que pueda te hago el código, que es simple.
Interrupcion: '-------- Decodificador de Encoder --------------
Context SAVE ' Salva en contexto de los registros antes de operar con la
' interrupción.
If PORTB.0 = 1 Then ' Si RB0 se ha puesto a 1 (flanco de subida),
INTEDG = 0 ' entonces activar la siguiente interrupción por flanco de
' bajada.
If PORTB.1 = 1 Then ' Si RB1 está a 1,
Inc x ' entonces incrementar el contador X.
EndIf
Else ' Si RB0 se ha puesto a 0 (flanco de bajada),
INTEDG = 1 ' entonces activar la siguiente interrupción por flanco de
' subida.
If PORTB.1 = 1 Then ' Si RB1 está 1,
Dec x ' entonces decrementar el contador X.
EndIf
EndIf
INTF = 0 ' Borra el "flag" de la interrupción RB0/INT para poder permitir
' la siguiente interrupción cuando ocurra.
Context Restore ' Restablece el contexto de los registros tal como estaban antes
' de la interrupción.
[LEFT]
x=0;
for(;;){
pos2=pos;
if(bit_test(PORTB,0)){
if(bit_test(PORTB,1)) pos=3;
else pos=2;
}
if(!(bit_test(PORTB,0))){
if(bit_test(PORTB,1)) pos=4;
else pos=1;
}
if (pos2!=pos){
switch(pos){
case 1: if(pos2==4) x++;
else x--;
break;
case 2: if(pos2==1) x++;
else x--;
break;
case 3: if(pos2==2) x++;
else x--;
break;
case 4: if(pos2==3) x++;
else x--;
break;
}
}
}
'****************************************************************
'* Name : Conexion usb *
'* Author : FERNANDOAE *
'****************************************************************
Config_Start
PLLDIV = 1 ; No prescale (4 MHz oscillator input drives PLL directly)
CPUDIV = OSC1_PLL2 ; [OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
USBDIV = 2 ; USB clock source comes from the 96 MHz PLL divided by 2
FOSC = XTPLL_XT ; XT oscillator, PLL enabled, XT used by USB
PWRT = On ; PWRT enabled
BOR = OFF ; Brown-out Reset disabled in hardware and software
VREGEN = On ; USB voltage regulator enabled
WDT = OFF ; HW Disabled - SW Controlled
MCLRE = OFF ; RE3 input pin enabled; MCLR disabled
PBADEN = OFF ; PORTB<4:0> pins are configured as digital I/O on Reset
LVP = OFF ; Single-Supply ICSP disabled
Debug = OFF ; Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
Config_End
'SELECCIONAMOS EL PIC Y LA FRECUENCIA DE TRABAJO (48Mhz PARA USB)
Device = 18F2550
Xtal = 48
All_Digital= 1
'ESTA FILA LA GENERA EL MISMO "EASYHID USB WIZARD" Y LA COLOCA
'JUNTO A ESTE ARCHIVO .BAS DONDE TRABAJAREMOS LA APLICACIÓN
'(EN LA MISMA CARPETA)
USB_Descriptor = "DESCRIPTOR.inc"
'LOS TAMAÑOS DEL BUFFER USB
Symbol USBBufferSizeMax = 8
Symbol USBBufferSizeTX = 8
Symbol USBBufferSizeRX = 8
Dim USBBuffer[USBBufferSizeMax] As Byte
'REGISTROS Y BANDERAS
Dim PP0 As Byte System ' REGISTRO DENTRO DEL PIC USBPOLL STATUS
Symbol CARRY_FLAG = STATUS.0 ' EN ESTADO ALTO SI EL PIC NO TIENE
' EL CONTROL SOBRE EL BUFFER
Symbol ATTACHED_STATE = 6 ' SI USB ESTÁ CONECTADO
Clear 'LIMPIO LA RAM AL INICIAR
TRISA = %11111111
TRISB = %11111111
GoSub AttachToUSB 'ME VOY A VER SI ESTÀ CONECTADO
'AL INICIAR EL PROGRAMA
' *****************************************************************
' *****************************************************************
' * LAZO PRINCIPAL DEL PROGRAMA MIENTRAS SE ESTÁ CONECTADO A USB; *
' * RECUERDA QUE DEBES MANTENER LA CONEXIÓN "VIVA" CON LLAMADOS *
' * CONSTANTES A LAS RUTINAS USBPoll, USBIn or USBOut CADA ALGUNOS*
' * MILISEGUNDOS O MÁS *
' *****************************************************************
' *****************************************************************
Dim x As Byte
Dim viejo As Byte
Dim actual As Byte
viejo=0
actual=0
INICIO:
viejo=actual
actual = ~PORTA & 3
If viejo= 0 And actual= 2 Then
GoSub incremento
EndIf
If viejo= 2 And actual= 3 Then
GoSub incremento
EndIf
If viejo= 3 And actual= 1 Then
GoSub incremento
EndIf
If viejo= 1 And actual= 0 Then
GoSub incremento
EndIf
If viejo= 1 And actual= 3 Then
GoSub decremento
EndIf
If viejo= 3 And actual= 2 Then
GoSub decremento
EndIf
If viejo= 2 And actual= 0 Then
GoSub decremento
EndIf
If viejo= 0 And actual= 1 Then
GoSub decremento
EndIf
USBIn 1, USBBuffer, USBBufferSizeRX,norecibi
norecibi:
GoTo INICIO 'CIERRO EL LAZO DESPUÉS DE TODO EL TRABAJO
' ************************************************************
' * RUTINA DE RECEPCIÓN DE DATOS *
' ************************************************************
DoUSBIn:
USBIn 1, USBBuffer, USBBufferSizeRX, DoUSBIn
Return
' ************************************************************
' * RUTINA DE TRANSMISIÓN DE DATOS *
' ************************************************************
DoUSBOut:
USBOut 1, USBBuffer, USBBufferSizeTX, DoUSBOut
Return
' ************************************************************
' * ESPERA HASTA QUE EL USB SE CONECTE *
' ************************************************************
AttachToUSB:
Repeat
USBPoll
Until PP0 = ATTACHED_STATE
Return
decremento:
USBBuffer[0]= %00000000
USBBuffer[1]= %00000010
GoSub DoUSBOut
USBBuffer[0]= %00000000
USBBuffer[1]= %00000000
GoSub DoUSBOut
Return
incremento:
USBBuffer[0]= %00000000
USBBuffer[1]= %00000001
GoSub DoUSBOut
USBBuffer[0]= %00000000
USBBuffer[1]= %00000000
GoSub DoUSBOut
Return
actual = ~PORTA & 3
Es el de Proton, si no me equivoco se llama Proton Basic.¡Buen trabajo! Este lenguaje no lo entiendo muy bien, ¿cual es?
"~" Es para invertir los bits del puerto A(porque el encoder en reposo me da 11), o sea, no cambia el valor del puerto... solamente toma el valor invertido. Calculo que en CCS seria algo como "not porta"¿Me puedes decir que siginifica esta instrucción? : Código:
actual = ~PORTA & 3
O también podés venderlaA mi me pasa como a tí, que no se si le daré uso a la consola, pero es un placer verlo funcionar, jejej
Pero si los leds los hice funcionar, fijate.La mia definitivamente la voy a dejar en Midi, porque es compatible con mas software, y no me sigo comiendo la cabeza con los leds, que los dejo por imposible.
Si, es lo mejor. Queda con muy buena sensibilidad, incluso girandolo MUUUUY lento detecta todo.pero para los motores paso a paso del disco duro, mejor utilizar todas las transiciones para tener más sensibilidad, ¿no?
De todas formas, y no es por ser cabezón
Eso tambien quiero probar, de hacerlo con interrupciones. Perooo, y cuando tengo dos encoders y se mueven en simultaneo?, prefiero utilizar interrupciones para no estar millones de ciclos esperando por algo que no llega, porque cuando no se mueve el jogwhell estás perdiendo tiempo en escanear unas entradas que no cambian.
#device ADC=8
setup_adc_ports(AN0_TO_AN1);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(30);
tempoA1=read_adc();
tempoA11=tempoA1/2; //convierte del rango 0xFF a 0x7F para Midi
//comprueba si ha cambiado el pitch para enviarlo
if(tempoA11!=tempoA2)
{ tempA[1]=0xB0;
tempA[0]=tempA[1]>>4;
tempA[2]=0x00;
tempA[3]=tempoA11;
usb_put_packet(1,tempA,4,USB_DTS_TOGGLE);
tempoA2=tempoA11;
}
Device=16F876A
REMINDERS = FALSE
Config XT_OSC, PWRTE_ON, CPD_OFF, WDT_OFF, BODEN_OFF, LVP_OFF
REMINDERS = TRUE
Symbol INTF = INTCON.1 ' RB0 External Interrupt Flag
Symbol INTE = INTCON.4 ' RB0 External Interrupt Enable
Symbol GIE = INTCON.7 ' Global Interrupt Enable
Symbol INTEDG = OPTION_REG.6 ' Flag = 0 Flanco bajada. Flag = 1 Flanco subida.
On_INTERRUPT GoTo Interrupcion ' Interrupción por hardware (es la más rápida).
GIE = 1 ' Activa interrupciones generales.
INTE = 1 ' Activa la interrupción externa RB0/INT.
INTEDG = 1 ' Hace que inicialmente la interrupción se dispare
' por flanco de subida.
ALL_DIGITAL = TRUE ' Todas las entradas y salidas son digitales.
TRISA = %111111
TRISB = %11111111 ' Puerto A y B todo entradas.
TRISC = %00000000 ' Puerto C como salida para visualizar a través de los LED.
Dim x As Byte ' Variable X ---> contador de posición actual.
x=0
While 1=1 ' |------ Programa Principal ------|
PORTC = x ' El contenido de X se visualiza en el Puerto C a través de los LED.
Wend ' |--------------------------------|
End
Interrupcion: '-------- Decodificador de Encoder --------------
Context SAVE ' Salva en contexto de los registros antes de operar con la interrupción.
If PORTB.0 = 1 Then ' Si RB0 se ha puesto a 1 (flanco de subida),
INTEDG = 0 ' entonces activar la siguiente interrupción por flanco de bajada.
If PORTB.1 = 1 Then ' Si RB1 está a 1
Inc x ' entonces incrementar el contador X.
EndIf
EndIf
If PORTB.0 = 0 Then ' Si RB0 se ha puesto a 0 (flanco de bajada),
INTEDG = 1 ' entonces activar la siguiente interrupción por flanco de subida.
If PORTB.1 = 1 Then ' Si RB1 está 1
Dec x ' entonces decrementar el contador X.
EndIf
EndIf
INTF = 0 ' Borra el "flag" de la interrupción RB0/INT
' para poder permitir la siguiente interrupción.
Context Restore ' Restablece el contexto de los registros tal como estaban antes de la
' interrupción.
[LEFT]Device = 18F4550 ' Usamos el PIC 18F4550, pero puedes declarar cualquiera de los 18Fxx5x.
REMINDERS = 1 ' Comunicar todos los avisos de compilación.
XTAL = 4 ' Pon el cristal que quieras; en principio usamos un cristal de 4MHz.
Symbol INTF = INTCON.1 ' RB0 External Interrupt Flag
Symbol INTE = INTCON.4 ' RB0 External Interrupt Enable
Symbol GIE = INTCON.7 ' Global Interrupt Enable
Symbol INTEDG = INTCON2.6 ' Flag = 0 int. por flanco bajada. Flag = 1 int. por flanco subida.
On_INTERRUPT GoTo Interrupcion ' Interrupción por Hardware (es la más rápida).
GIE = 1 ' Activa interrupciones generales.
INTE = 1 ' Activa la interrupción externa RB0/INT.
INTEDG = 1 ' Hace que inicialmente la interrupción se habilite
' por flanco de subida.
ALL_DIGITAL = TRUE ' Todas las entradas y salidas son digitales.
TRISA = %11111111 ' Puerto A todo entradas, en este caso no usamos el Puerto A.
TRISB = %11111111 ' Puerto B todo entradas, sólo usamos las entradas RB0 y RB1.
TRISC = %11111111 ' Puerto C todo entradas, en este caso no usamos el Puerto C.
TRISD = %00000000 ' Puerto D todo salidas (8 bits que irán a los LEDs).
TRISE = %11111111 ' Puerto E todo entradas, en este caso no usamos el Puerto E.
Dim x As Byte ' Variable X ---> contador de posición actual con resolución
' 0..255
x=0
While 1=1 ' |------ Programa Principal ------|
PORTD = x ' El contenido de X se visualiza en el Puerto D a través de
' los LED.
Wend ' |--------------------------------|
End
Interrupcion: '-------- Decodificador de Encoder --------------
Context SAVE ' Salva en contexto de los registros antes de operar con la
' interrupción.
If PORTB.0 = 1 Then ' Si RB0 se ha puesto a 1 (flanco de subida),
INTEDG = 0 ' entonces activar la siguiente interrupción por flanco de
' bajada.
If PORTB.1 = 1 Then ' Si RB1 está a 1,
Inc x ' entonces incrementar el contador X.
EndIf
Else ' Si RB0 se ha puesto a 0 (flanco de bajada),
INTEDG = 1 ' entonces activar la siguiente interrupción por flanco de
' subida.
If PORTB.1 = 1 Then ' Si RB1 está 1,
Dec x ' entonces decrementar el contador X.
EndIf
EndIf
INTF = 0 ' Borra el "flag" de la interrupción RB0/INT para poder permitir
' la siguiente interrupción cuando ocurra.
Context Restore ' Restablece el contexto de los registros tal como estaban antes
' de la interrupción.
[/LEFT]
Yo cuando tenga tiempo voy a ver si hago algo asi, busca en google, con un pin y una resistencia se puede hacer, creo que hay que poner el pin a 1, esperar 5 useg y leer la entrada...P.D. Los jogwheel estaría bueno hacerlos con ruedas capacitivas, no?
En cuanto a la lectura e interpretación del Quadrature, lo mejor sería utilizar dos pines de entre los [RB4-RB7] ya que ellos permiten configurar una interrupción de cambio de estado(sin importar el flanco). Por ende interrumpirían ante cualquier cambio, y sólo habría que manipular una interrupción en lugar de 2.