Noticias:

Grupo en telegram, del foro de meteorología fácil: https://t.me/meteorologiafacil

Para mas detalles, puedes visitar el siguiente tema http://www.meteorologiafacil.com.ar/foros/index.php?topic=1608.0

Espero que les sea de mucha utilidad.

Menú Principal

USB-serial

Iniciado por David Met, Abril 02, 2015, 02:49:33 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

David Met

Hola a todos chicos.

Cuando uso el programa de ejemplo que trae JAL, la conexión anda muy bien. Incluso si la modifico y le voy agregando algunas tareas, la comunicación anda muy bien también. Pero cuando necesito agregarle más trabajo, la PC deja de reconocerme al PIC. Me he dado cuenta de que es por culpa de la función usb_serial_flush(). Si la llamo seguido, no tengo problema; pero si por algún problema el PIC se demora más de lo habitual para llamar a la función antes mencionada, la comunicación falla.
Para ello decidí usar la interrupción por TMR0 usando la librería, pero no he tenido buenos resultados. A fin de evitar problemas, decidí hacer mi propia configuración del TMR0; haciendo una interrupción cada 15useg (emulado en el MPLAB). Adivinen, no funcionó.

Sinceramente, ya no se porqué es la falla. Desde que retomé con este proyecto, me he estado volviendo loco. A continuación, pego el código completo para ver si ustedes ven mi error:

-- ------------------------------------------------------------------------------------------------
--
-- Este programa ha sido generado por jallib.py
-- Plataforma Invernadero.
--
-- ------------------------------------------------------------------------------------------------
-- INICIO DEL PROGRAMA.
-- --------------------

include 18f4550 -- Incluímos la librería para controlar nuestro PIC.

-- Aunque el cristal externo es 20 MHz, la configuración es tal que el reloj de la CPU
-- se deriva de reloj PLL 96 Mhz (div2),
-- por lo tanto, establecer la frecuencia de destino para 20 MHz
pragma target clock       20_000_000


-- FUSIBLES:
-- ---------
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBPLL        F48MHZ      -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       MINIMUM     -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- no watchdog
pragma target CCP2MUX       ENABLED     -- CCP2 pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           DISABLED    -- no low-voltage programming
pragma target XINST         ENABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected
-- ------------------------------------------------------------------------------------------------
-- INCLUIMOS LIBRERÍAS:
-- --------------------
include usb_serial -- Incluímos la librería para emular el puerto serial por USB.
include delay -- Incluímos la librería para las demoras.
-- ------------------------------------------------------------------------------------------------
-- CONFIGURACIÓN GENERAL DEL PIC:
-- ------------------------------

enable_digital_io() -- Por seguridad, configuraremos a los pines análogos
-- como digitales. Luego, cuando inicializemos el ADC,
-- se autoconfigurará analógicas las entradas a utilizar.
INTCON_GIE = false -- Deshabilitamos las interrupciones. Las habilitaremos
-- mas adelante.

portb_direction = output -- Todo el puerto B como salida.
portc_direction = output -- Todo el puerto C como salida.
portd_direction = output -- Todo el puerto D como salida.
pin_a4_direction = output -- Solo el RA4 como salida.

-- ------------------------------------------------------------------------------------------------
-- CONFIGURACIÓN DEL TMR0:
-- -----------------------
var byte tempori = 200
T0CON = 0b11000000 -- Habilitamos el TMR0, 8 Bit, Reloj del PIC; Prescaler 1:2
TMR0L = tempori -- A 48Mhz 15useg
INTCON_TMR0IF = 0 -- Por seguridad, limpiamos la bandera.
INTCON_TMR0IE = 1 -- Habilitamos individualmente la interrupción de TMR0
-- INTCON_GIE = 1 -- Habilitamos las interrupciones.
---------------------------------------------------------------------------------------------------
-- CONFIGURACIÓN DEL ADC:
-------------------------
;const bit ADC_HIGH_RESOLUTION = false
-- we said we want 1 analog channel...
;const byte ADC_NCHANNEL = 1
-- and no voltage reference
;const byte ADC_NVREF = 0
-- now we can include the library
-- note it's now named "adc", not "adc_hardware" anymore
;include adc
-- and run the initialization step
;adc_init()

-- ------------------------------------------------------------------------------------------------
-- VARIABLES:
-- -----------
var byte ch
var byte temp_hongo_1
var byte hum_hongo_1
var byte temp_hongo_2
var byte hum_hongo_2
var byte temp_hongo_3
var byte hum_hongo_3
var byte temp_hongo_4
var byte hum_hongo_4
var byte canal
var byte temperatura
var byte humedad
var word temp
var dword hum
-- ------------------------------------------------------------------------------------------------


-- setup the USB serial library
usb_serial_init()
INTCON_GIE = 1 -- Habilitamos las interrupciones.
-- ------------------------------------------------------------------------------------------------
-- TRATAMIENTO DE LAS INTERRUPCIONES:
-- ----------------------------------
procedure temporizador0() is
pragma interrupt NORMAL
if INTCON_TMR0IF == 1 then
usb_serial_flush()
end if
TMR0L = tempori
INTCON_TMR0IF = 0
end procedure



-- ----------------------------------------------------------------------------
-- PROCEDIMIENTOS Y FUNCIONES TOTALES.
-- -----------------------------------

-- ----------------------------------------------------------------------------
-- PROCEDIMIENTOS PARA EL CAD:
-- ---------------------------
function leer_cad(byte in canal)return byte is
var byte resultado_cad
ADCON0_CHS = canal
ADCON0_ADON = 1
_usec_delay(4) -- 20uS
ADCON0_GO = 1
while ADCON0_GO loop end loop -- Esperamos hasta que la conversión finalice.
resultado_cad = ADRESH
ADCON0_ADON = 0
return resultado_cad
end function

procedure sensar_temperatura() is
temp = BYTE(leer_cad(canal)) -- Iniciamos la conversión
temp = temp * 195 -- Multiplicamos por 195 para pasarlo a tensión
temp = temp / 100 -- Dividimos por 100 para quedarnos con la parte entera. Tamaño máximo 8 bit.
temperatura = BYTE(temp) -- El resultado de 8 bit, lo pasamos a otra variable de tamaño de 8 bit
end procedure
;
;**********************************************************************
;MEDIMOS LA HUMEDAD.
;------------------
;PASOS A SEGUIR.
;
;1- CONFIGURAR EL CANAL A SENSAR.
;2- MEDIR EL ADC DE LA HUMEDAD Y GUARDAMOS EL VALOR EN RAM
;   TENEMOS QUE APLICAR LA FÓRMULA SIGUIENTE PARA OBTENER LA HUMEDAD HR = (Vout - 0,8) / 0,031
;3- PARA ELLO, DEVEMOS MULTIPLICAR EL ADC POR 196 PARA PASARLO A TENSIÓN (EN REALIDAD DEBERÍA SER 195 PERO CON ESTE, EL ERROR ES MAS GRANDE).
;4- LUEGO LO VOLVEMOS A MULTIPLICAR POR 1.000 PARA TRABAJAR CON LA SIGUIENTE FÓRMULA HR = (Vout - 800) / 31
;5- APLICAMOS LA FORMULA HR = (Vout - 800) / 31,
;5- EL RESULTADO LO DIVIDIMOS POR 10.000 PARA OBETENER LA HUMEDAD RELATIVA EN 2 DÍGITOS (O 1.000 PARA OBTENER 3 DÍGITOS, ANALIZAMOS MAS ADELANTE ESTO)
;6- LO GUARDAMOS EN LA RAM
;7- TOMAMOS 42 MUESTRAS
;8- HACEMOS EL PROMEDIO, PARA ELLO SUMAMOS LAS 42 MUESTRAS ENTRE SI Y LUEGO LA DIVIDIMOS POR 42
;9- EL RESULTADO DEL PROMEDIO LO GUARDAMOS EN LA RAM humedad
;10- SENSAMOS EL VIENTO.
;**********************************************************************
procedure sensar_humedad() is
hum = BYTE(leer_cad(canal)) -- Iniciamos la conversión
hum = hum * 196 -- Lo pasamos a tensión
hum = hum * 1000 -- Lo multiplicamos por 1000
hum = hum - 800 -- Le restamos 800
hum = hum / 31 -- Lo dividimos por 31
hum = hum / 10000 -- Lo dividimos por 10000 para obtener 3 dígitos
humedad = BYTE(hum) -- El resultado de 8 bit, lo pasamos a otra variable de tamaño de 8 bit
end procedure

-- main loop
forever loop

;

canal = 0 -- Temperatura hongo 1 (AN0).
sensar_temperatura()
-- usb_serial_flush()
temp_hongo_1 = temperatura -- Recuperamos el valor de la temperatura sensado.
-- usb_serial_flush()
;
canal = 1 -- Humedad hongo 1 (AN1).
sensar_humedad()
-- usb_serial_flush()
hum_hongo_1 = humedad -- Recuperasmos el valor de la humedad sensada.
-- usb_serial_flush()
;
canal = 2 -- Temperatura hongo 2 (AN2).
sensar_temperatura()
-- usb_serial_flush()
temp_hongo_2 = temperatura -- Recuperamos el valor de la temperatura sensado.
-- usb_serial_flush()
;
canal = 3 -- Humedad hongo 2 (AN3).
sensar_humedad()
-- usb_serial_flush()
hum_hongo_2 = humedad -- Recuperasmos el valor de la humedad sensada.
-- usb_serial_flush()
;
canal = 4 -- Temperatura hongo 3 (AN4).
sensar_temperatura()
-- usb_serial_flush()
temp_hongo_3 = temperatura -- Recuperamos el valor de la temperatura sensado.
-- usb_serial_flush()
;
canal = 5 -- Humedad hongo 3 (AN5).
sensar_humedad()
-- usb_serial_flush()
hum_hongo_3 = humedad -- Recuperasmos el valor de la humedad sensada.
-- usb_serial_flush()
;
canal = 6 -- Temperatura hongo 4 (AN6).
sensar_temperatura()
-- usb_serial_flush()
temp_hongo_4 = temperatura -- Recuperamos el valor de la temperatura sensado.
-- usb_serial_flush()
;
canal = 7 -- Humedad hongo 4 (AN7).
sensar_humedad()
-- usb_serial_flush()
hum_hongo_4 = humedad -- Recuperasmos el valor de la humedad sensada.
-- usb_serial_flush()

if ( usb_cdc_line_status() !=  0x00 )  then
ch = 0
if usb_serial_read(ch) then -- leo el puerto usb
-- usb_serial_flush() -- mantengo viva la conexion usb   
case ch of -- manipulación de salidas digitales                           
            "A": pin_b7 = on -- Ventilador encendido
"B": pin_b7 = off -- Ventilador apagado
"C": pin_b6 = on -- Calefación encendido
"D": pin_b6 = off -- Calefacción apagado
"E": pin_b5 = on -- Refrigeración encendido
"F": pin_b5 = off -- Refrigeración apagado
"G": pin_b4 = on -- Luz encendido
"H": pin_b4 = off -- Luz apagado
"I": pin_b3 = on -- Humificador encendido
"J": pin_b3 = off -- Humificador apagado
;
"0": usb_serial_write(temp_hongo_1) -- Mostrar el valor de la tempereatura actual.
"1": usb_serial_write(hum_hongo_1) -- Mostrar el valor de la humedad actual.
"2": usb_serial_write(pin_b7) -- Mostrar el estado del ventilador.
"3": usb_serial_write(pin_b6) -- Mostrar el estado del calefacción.
"4": usb_serial_write(pin_b5) -- Mostrar el estado de la refrigeración.
"5": usb_serial_write(pin_b4) -- Mostrar el estado de la luz.
"6": usb_serial_write(pin_b3) -- Mostrar el estado del humificador.
;
"K": pin_b2 = on -- Vantilador 2 encendido
"L": pin_b2 = off -- Ventilador 2 apagado
"M": pin_d7 = on -- Calefacción 2 encendido
"N": pin_d7 = off -- Calefacción 2 apagado
"O": pin_d6 = on -- Refrigeración 2 encendido
"P": pin_d6 = off -- Refrigeración 2 apagado
"Q": pin_d5 = on -- Luz 2 ecendido
"R": pin_d5 = off -- Luz 2 apagado
"S": pin_d4 = on -- Humificador 2 encendido
"T": pin_d4 = off -- Humificador 2 apagado
;
"7": usb_serial_write(temp_hongo_2) -- Muestra la temperatura del hongo 2
"8": usb_serial_write(hum_hongo_2) -- Muestra la humedad del hongo 2
"9": usb_serial_write(pin_b2) -- Muestra el estado del ventilador 2
":": usb_serial_write(pin_d7) -- Muestra el estado de la calefacción 2
";": usb_serial_write(pin_d6) -- Muestra el estado de la refrigeración 2
"<": usb_serial_write(pin_d5) -- Muestra el estado de la luz 2
"=": usb_serial_write(pin_d4) -- Muestra el estado del humuficador 2
;
"a": pin_c7 = on -- Ventilador 3 encendido
"b": pin_c7 = off -- Ventilador 3 apagado
"c": pin_c6 = on -- Calefacción 3 encendido
"d": pin_c6 = off -- Calefacción 3 apagado
"e": pin_d3 = on -- Refrigeración 3 encendido
"f": pin_d3 = off -- Refrigeración 3 apagado
"g": pin_d2 = on -- Luz 3 encendido
"h": pin_d2 = off -- Luz 3 apagado
"i": pin_c0 = on -- Humificador 3 encendido
"j": pin_c0 = off -- Humificador 3 apagado
;
">": usb_serial_write(temp_hongo_3) -- Muestra la temperatura del hongo 3
"?": usb_serial_write(hum_hongo_3) -- Muestra la humedad del hongo 3
"@": usb_serial_write(pin_c7) -- Muestra el estado del ventilador 3
"(": usb_serial_write(pin_c6) -- Muestra el estado de la calefacción 3
")": usb_serial_write(pin_d3) -- Muestra el estado de la refrigeración 3
"+": usb_serial_write(pin_d2) -- Muestra el estado de la luz 3
"^": usb_serial_write(pin_c0) -- Muestra el estado del humificador 3
;
"k": pin_c1 = on -- Ventilador 4 encendido
"l": pin_c1 = off -- Ventilador 4 apagado
"m": pin_c2 = on -- Calefacción 4 encendido
"n": pin_c2 = off -- Calefacción 4 apagado
"o": pin_d0 = on -- Refrigeración 4 encendido
"p": pin_d0 = off -- Refrigeración 4 apagado
"q": pin_d1 = on -- Luz 4 encendido
"r": pin_d1 = off -- Luz 4 apagado
"s": pin_a4 = on -- Humificador 4 encendido
"t": pin_a4 = off -- Humificador 4 apagado
;
"_": usb_serial_write(temp_hongo_4) -- Muestra la temperatura del hongo 4
"!": usb_serial_write(hum_hongo_4) -- Muestra la humedad del hongo 4
" ": usb_serial_write(pin_c1) -- Muesttra el estado del ventilador 4
"#": usb_serial_write(pin_c2) -- Muestra el estado de la calefacción 4
"$": usb_serial_write(pin_d0) -- Muestra el estado de la refrigeración 4
"%": usb_serial_write(pin_d1) -- Muestra el estado de la luz 4
"&": usb_serial_write(pin_a4) -- Muestra el estado del humificador 4
;
end case
end if
end if
end loop


Como notarán, es una máquina de estado. Aún falta terminar ya que faltan funciones, que no las quiero agregar hasta tanto solucione este problema de comunicación.

Notarán que hay muchas llamadas de la función usb_serial_flush()    pero que están comentada (con --) para ver si logro funcionar con la interrupción por TMR0.
Hasta tomé la precaución de activar la interrupción después de inicializar el puerto USB, para que usb_serial_flush() no sea llamado primero.

Desde ya, cualquier ayuda se los agradeceré muchísimo.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

David Met

Por cierto, he probado con 2mseg y con 6mseg y nada.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Ricber

Hola David, no conozco el lenguaje Jal pero tratare de ayudar si puedo, te pregunto
cual es la función  de la  función usb_serial_flush().

David Met

Esta función, mantiene viva la conexión entre el PIC y el USB.
Si el puerto USB se mantiene inactivo por un cierto tiempo (hasta donde se de unos 10ms), el host (la PC, en mi caso) corta la conexión.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Ricber

La opcion del timer me parece acertada, seguis haciendo pruebas.

David Met

#5
En el foro de Ucontrol, un usuario llamado nestoriano, me dio un programa que funciona y utiliza la interrupción para poder mantener viva la comunicación.

Este es el código

--;@main
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000


-- FUSIBLES:
-- ---------
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBPLL        F48MHZ      -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       MINIMUM     -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- no watchdog
pragma target CCP2MUX       ENABLED     -- CCP2 pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           DISABLED    -- no low-voltage programming
pragma target XINST         ENABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

include delay
include usb_serial
include print

include random
var word dato

const  byte str_welcome[] = "JALLIB USB Serial Demo app\n"




-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
procedure interrupcion() is
pragma interrupt

if (INTCON_TMR0IF) then
usb_serial_flush()
tmr0=64000
INTCON_TMR0IF=0

end if

if (PIR1_TMR1IF==1) then
tmr1=3038
dato=random_word
PIR1_TMR1IF=0
end if


end procedure
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------

--TMR0
INTCON=0b10100000
T0CON=0b10000000
tmr0=64000

--TMR1
PIR1_TMR1IF=0
INTCON_PEIE=1
T1CON=0b11000001


usb_serial_init()


forever loop

print_string(usb_serial_data,str_welcome)
print_word_dec(usb_serial_data,dato)
print_crlf(usb_serial_data)

delay_1ms(1000)

end loop


El utilizó el PIC 18F2550. Yo solo respeté los fuses de mi pic, el resto es obra de él.
Ahora tenemos un punto de donde salir.

Nestoriano cree que alguna librería no está tratando bien la interrupción, mas precisamente en el tratamiento de la del bit GIE.
Ahora veremos si puedo adaptarlo a mis necesidades.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

David Met

#6
He creado una mejora del programa para no ejecutar la función USB_SERIAL_FUSH() mientras se mantenía una comunicación al enviar un dato. Esto es para no generar procedimiento recursivo.
Intenté con el chequeo del bit ACTVIF del registro UIR pero no funcionó. Para ello, cree una propia bandera llamado usb_en_uso donde 1 indica que está en uso, y 0 indica que no se está transmitiendo ningún dato. El programa funciona muy bien. Lo copio y pego:

--;@main
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000


-- FUSIBLES:
-- ---------
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBPLL        F48MHZ      -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       MINIMUM     -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- no watchdog
pragma target CCP2MUX       ENABLED     -- CCP2 pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           DISABLED    -- no low-voltage programming
pragma target XINST         ENABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected


var volatile bit usb_en_uso
include delay
include usb_serial
include print

include random
var word dato

const  byte str_welcome[] = "JALLIB USB Serial Demo app\n"




-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
procedure interrupcion() is
pragma interrupt

if (INTCON_TMR0IF) then
if usb_en_uso == 0 then
usb_serial_flush()
end if
tmr0=64000
INTCON_TMR0IF=0

end if

if (PIR1_TMR1IF==1) then
tmr1=3038
dato=random_word
PIR1_TMR1IF=0
end if


end procedure
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------

--TMR0
INTCON=0b10100000
T0CON=0b10000000
tmr0=64000

--TMR1
PIR1_TMR1IF=0
INTCON_PEIE=1
T1CON=0b11000001


usb_serial_init()

forever loop

        usb_en_uso = 1
print_string(usb_serial_data,str_welcome)
print_word_dec(usb_serial_data,dato)
print_crlf(usb_serial_data)
        usb_en_uso = 0

delay_1ms(1000)

end loop


De todas maneras está en prueba. Por ahora lleva funcionando por más de 15 minutos sin ningún problema.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

David Met

He estado haciendo algunas pruebas de poder leer al puerto USB. Por supuesto que las primeras pruebas fueron fallidas; pero no me llevó mucho tiempo descubrir que la función usb_serial_read([byte]) no mantiene vivo la comunicación. Esto es muy importante saberlo porque es uno de los problemas que hace que nuestro dispositivo no sea reconocido.

Pongo el siguiente programa que funciona:

-- ------------------------------------------------------------------------------------------------
--
-- Este programa ha sido generado por jallib.py
--;@main
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000


-- FUSIBLES:
-- ---------
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBPLL        F48MHZ      -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       MINIMUM     -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- no watchdog
pragma target CCP2MUX       ENABLED     -- CCP2 pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           DISABLED    -- no low-voltage programming
pragma target XINST         ENABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected


var volatile bit usb_en_uso
include delay
include usb_serial
include print

include random
var word dato

const  byte str_welcome[] = "Prueba comunicación PIC-PC por USB.\n"
const byte mensaje1[] = "Ingrese un dato\n"
const byte mensaje2[] = "Ahora tiene que esperar\n"




-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
procedure interrupcion() is
pragma interrupt

if (INTCON_TMR0IF) then
if usb_en_uso == 0 then
usb_serial_flush()
end if
tmr0=64000
INTCON_TMR0IF=0

end if

if (PIR1_TMR1IF==1) then
tmr1=3038
dato=random_word
PIR1_TMR1IF=0
end if


end procedure
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------

--TMR0
INTCON=0b10100000
T0CON=0b10000000


--TMR1
PIR1_TMR1IF=0
INTCON_PEIE=1
T1CON=0b11000001


usb_serial_init()
tmr0=4000
var byte ch

forever loop

usb_en_uso = 0
ch = 0
print_string(usb_serial_data,mensaje1)
for 783647 loop
if usb_serial_read(ch) then -- leo el puerto usb
print_byte_dec(usb_serial_data,ch)
end if
end loop
usb_en_uso = 1
print_crlf(usb_serial_data)
print_string(usb_serial_data,mensaje2)
print_crlf(usb_serial_data)
print_string(usb_serial_data,str_welcome)
print_word_dec(usb_serial_data,dato)
print_crlf(usb_serial_data)
usb_en_uso = 0

delay_1ms(1000)

end loop


El for 783647 loop está creado para que me de 3 segundos, aproximadamente, para ingresar datos por el teclado de la PC.
Noten que, al momento de leer al puerto USB, es necesario mantener viva la comunicación por medio de la función que está en la interrupción.

Lamento ir colocando los avances por cuenta gotas, pero me sirve para saber hasta donde llegué; si por algún motivo tengo que dejarlo y luego retomar otro día.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

David Met

Logré escribir un programa que lee y escribe por USB y no se corta. Hace más de una hora que lo tengo funcionando sin problema.
Me parece que es una excelente base como guía para cualquier proyecto USB-SERIAL.

Más adelante, trataré de escribir una librería para no tener dolores de cabeza. Les agradezco a todos por la ayuda, en especial de nestoriano y rubial69 (de Ucontrol) que hicieron que se llegara a buen puerto.

-- ------------------------------------------------------------------------------------------------
--
-- Este programa ha sido generado por jallib.py
--;@main
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000


-- FUSIBLES:
-- ---------
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBPLL        F48MHZ      -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       MINIMUM     -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- no watchdog
pragma target CCP2MUX       ENABLED     -- CCP2 pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           DISABLED    -- no low-voltage programming
pragma target XINST         ENABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected


var volatile bit usb_en_uso
include delay
include usb_serial
include print

include random
var word dato

const  byte str_welcome[] = "Prueba comunicación PIC-PC por USB.\n"
const byte mensaje1[] = "Ingrese un dato\a" --\a emite un tono de alerta a la PC para ser
-- reproducido por los parlantes.
const byte mensaje2[] = "Ahora tiene que esperar\n"
const byte mensaje3[] = "Usted presionó la tecla A\n"
const byte mensaje4[] = "Usted presionó la tecla B\n"
const byte mensaje5[] = "Usted presionó la tecla C\n"
const byte mensaje6[] = "Usted presionó la tecla D\n"
const byte mensaje7[] = "Usted presionó la tecla E\n"
const byte mensaje8[] = "Usted presionó la tecla F\n"
const byte mensaje9[] = "Usted presionó la tecla G\n"
const byte mensaje10[] = "Usted presionó la tecla H\n"
const byte mensaje11[] = "Usted presionó la tecla I\n"
const byte mensaje12[] = "Usted presionó la tecla J\n"
const byte mensaje13[] = "Buscando un número aleatorio. Por favor espere.\n"
const byte mensaje14[] = "Imprimiento número aleatorio: "

-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
procedure interrupcion() is
pragma interrupt

if (INTCON_TMR0IF) then
if usb_en_uso == 0 then
usb_serial_flush()
end if
tmr0=64000
INTCON_TMR0IF=0

end if

if (PIR1_TMR1IF==1) then
tmr1=3038
dato=random_word
PIR1_TMR1IF=0
end if


end procedure
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------

--TMR0
INTCON=0b10100000
T0CON=0b10000000


--TMR1
PIR1_TMR1IF=0
INTCON_PEIE=1
T1CON=0b11000001


usb_serial_init()
tmr0=4000
var byte ch

forever loop

ch = 0 -- Borro la variable CH
usb_en_uso = 1 -- Indico que voy a transmitir. No es necesario ejecutar la función
-- para mantener viva la comunicación USB.
print_string(usb_serial_data,mensaje1) -- Imprimo mensaje número 1. El mismo envía un tono de alerta por parlantes.
print_crlf(usb_serial_data) -- Borro una línea. Esto deja un espacio entre texto y texto.
usb_en_uso = 0 -- Indico que no voy a transmitir. Es necesario ejecutar la función
-- que mantiene viva la comunicación USB.
for 783647 loop -- Con dicho valor, voy a repetir el for por 3 segundos aproximadamente.
if usb_serial_read(ch) then -- Leo el puerto usb y lo guardo en CH
usb_en_uso = 1 -- Indico que voy a transmitir.
case ch of -- Según tecla presionada, imprimo el mensaje correspondiente.                           
            "A": print_string(usb_serial_data,mensaje3) -- Imprime mensaje número 3 si la tecla es A
"B": print_string(usb_serial_data,mensaje4) -- Imprime mensaje número 3 si la tecla es B
"C": print_string(usb_serial_data,mensaje5) -- Imprime mensaje número 3 si la tecla es C
"D": print_string(usb_serial_data,mensaje6) -- Imprime mensaje número 3 si la tecla es D
"E": print_string(usb_serial_data,mensaje7) -- Imprime mensaje número 3 si la tecla es E
"F": print_string(usb_serial_data,mensaje8) -- Imprime mensaje número 3 si la tecla es F
"G": print_string(usb_serial_data,mensaje9) -- Imprime mensaje número 3 si la tecla es G
"H": print_string(usb_serial_data,mensaje10)-- Imprime mensaje número 3 si la tecla es H
"I": print_string(usb_serial_data,mensaje11) -- Imprime mensaje número 3 si la tecla es I
"J": print_string(usb_serial_data,mensaje12) -- Imprime mensaje número 3 si la tecla es J
end case
print_crlf(usb_serial_data) -- Borro una línea.
usb_en_uso = 0 -- Indico que no voy a transmitir por USB
end if
end loop
usb_en_uso = 1 -- Indico que voy a transmitir.
print_crlf(usb_serial_data) -- Borro una línea
print_string(usb_serial_data,mensaje2) -- Imprimo mensaje 2
print_crlf(usb_serial_data) -- Borro una línea.
print_string(usb_serial_data,str_welcome) -- Imprimo mensaje de "prueba de comunicación PIC-PC por USB.
print_crlf(usb_serial_data) -- Borro una línea.
print_string(usb_serial_data,mensaje13) -- Imprimo mensaje 13
print_crlf(usb_serial_data) -- Borro una línea.
usb_en_uso = 0 -- Indico que no voy a transmitir por USB.
delay_1ms(1000) -- Realizo un tiempo de 1s para hacerlo más realista (leer mensaje número 13)
usb_en_uso = 1 -- Indico que voy a transmitir.
print_string(usb_serial_data,mensaje14) -- Imprimo mensaje número 14.
print_word_dec(usb_serial_data,dato) -- Imprimo el número aleatorio.
print_crlf(usb_serial_data) -- Borro una línea.
usb_en_uso = 0 -- Indico que no voy a transmitir,

delay_1ms(1000) -- Espero 1 segundo y vuelvo a comenzar todo de nuevo.

end loop


Cualquier cosa pregunten.

PD: De tanto en probar, el pic dejó de ser reconocido. Lo solucioné borrando por completo al PIC y luego regrabarlo. No se si será casualidad, pero es bueno tenerlo presente.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Ricber


YO

Hola muchachos!!
Recien me conecto y veo que David volvió a practicar con Jal
Si mal no recuerdo, ¿no te habias comunicado antes por el puerto serie con el simulador 232 / USB y tenias el mismo problema?, según recuerdo ya lo tenias resuelto la vez pasada cuando publicaste los videos
O esto es otra cosa o recuerdo mal?  dudo:
Sin saber que era imposible El fue y lo hizo

David Met

Ya había tenido problema y no lo había logrado solucionar. Luego tuve que dejarlo y quedó toda en la nada.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

David Met

Anoche, luego de varios intentos fracasados, pude hacer andar la máquina de estado que estaba desarrollando para un invernadero en que estoy trabajando.
Resulta que, después de haber logrado (con personas que me ayudaron) que el PIC se mantuviera en actividad por medio de la interrupción, volví a lo mismo. La pc no me reconocía al dispositivo.
Resultó que el problema era culpa de una función llamada usb_serial_write(dato_a_enviar) Cambié esta función por la de print_byte_dec(usb_serial_data,dato_a_enviar) y salió andando de maravillas.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.