Hola a todos.
A partir de una librería de string en Librerías para JAL (http://www.ucontrol.com.ar/forosmf/jal-y-jalv2/librerias-para-jal/msg60409/#msg60409), y con el ejemplo que me dio NESTORIANO (http://www.ucontrol.com.ar/forosmf/jal-y-jalv2/librerias-para-jal/msg86100/#msg86100) sobre una consulta de buscar una frase dentro de un string (buscar un string dentro de otro string), intenté hacer una función general; ya que mi ejemplo y el de Nestoriano, es sobre una frase en particular; cuando en realidad, el string que voy a recibir, cambia constantemente.
Viendo las funciones que hay en dicha librería llamada jtring.jal, vi que utilizan una función que está integrada en el "motor" de jal, y es count. La misma cuenta los caracteres que hay dentro de un string (cadena); o al menos, es es lo que entendí.
Por lo tanto, la función que escribí devuelve 1, si se encontró la frase o palabra que se busca, o de lo contrario devuelve 0.
La estrategia fue:
1) Contar los carateres que hay en la cadena recibida (se llama cadena) para saber hasta donde hay que buscar.
2) Contar los caracteres que hay en la cadena frase (se llama frase) que, justamente es lo que queremos buscar dentro del string cadena[]. Se cuenta por el mismo tema anterior.
3) Comparar caracter por caracter. Si hay coincidencia, sumamos 1 a la variable coincidencia. De lo contrario lo ponemos a 0.
4) Ir comparando el valor de coincidencia con el tamaño o cantidad de la cadena frase[]. Si coinciden, ya encontramos la frase; de lo contrario seguimos buscando.
5) Al mismo tiempo, ver que no excedamos la cantidad cadena[]. Si al cazamos ese valor y coincidencia no tiene el mismo tamaño de frase, quiere decir que no lo encontramos y devuelve 0
-- ----------------------------------------------------------------------------
-- Encuentra una palabra o frase dentro de una cadena.
-- ----------------------------------------------------------------------------
function EncPalCad (byte in cadena[], byte in frase[]) return bit is
var byte i
var byte x
var byte pos_cadena = 0
var byte pos_frase = 0
var byte control
var byte coincidencia
i = StrLen (cadena[])
x = count (frase[])
control = 0
while control != i loop
if control == i then
if coincidencia == x then
return true
else if
return false
end if
else if
if cadena[pos_cadena] == frase[pos_frase]
coincidencia = coincidencia + 1
if coincidencia == x then
return true
else if
pos_cadena = pos_cadena + 1
pos_frase = pos_frase + 1
control = control + 1
end if
else if
coincidencia = 0
control = control + 1
pos_frase = 0
pos_cadena = pos_cadena + 1
end if
end if
end loop
end function
El problema es que me tira los siguiente errores:
generating p-code
basico.jal:168: constant expression expected
basico.jal:168: warning: assignment to smaller type; truncation possible
basico.jal:169: constant expression expected
basico.jal:169: warning: assignment to smaller type; truncation possible
basico.jal:176: warning: boolean expression expected
basico.jal:176: 'then' expected (got 'return')
basico.jal:184: warning: boolean expression expected
basico.jal:184: 'then' expected (got '=')
basico.jal:216: constant expression expected
basico.jal:216: constant expression expected
basico.jal:218: 'then' expected (got '=')
basico.jal:221: 'end' expected (got '')
basico.jal:221: {IF starts at basico.jal:218}
basico.jal:221: 'end' expected (got '')
basico.jal:221: {IF starts at basico.jal:216}
basico.jal:221: 'end' expected (got '')
basico.jal:221: {IF starts at basico.jal:176}
basico.jal:221: 'end' expected (got '')
basico.jal:221: {IF starts at basico.jal:174}
basico.jal:221: 'end' expected (got '')
basico.jal:221: {IF starts at basico.jal:173}
basico.jal:221: 'end' expected (got '')
basico.jal:221: {WHILE starts at basico.jal:172}
basico.jal:221: 'end' expected (got '')
basico.jal:221: {function starts at basico.jal:160}
21 errors, 4 warnings
El que más me preocupa es 168 y 169 que corresponde a:
i = count (cadena[])
x = count (frase[])
¿Alguien sabe a que se debe eso, o como solucionarlo?
Hola David!
Probá así:
var byte i = StrLen (cadena[])
var byte x = count (frase[])
Lo que te tira como mensaje es igual a cuando no tenés determinada la variable, y sería conveniente que la declares fuera de la función (como variable general) para que la tome de cualquier lado.
Espero te sirva
Lamentablemente, mismo error; tanto como tu ejemplo como declararlas fuera de la función. >:[[
Sería más fácil ayudarte si estuviese el código completo, incluso lo podría compilar desde acá y ver que onda, pero como los errores o precauciones te los tira por número de línea de programa y esos números no aparecen en el código, estoy desubicado sin saber por donde buscar, por ejemplo:
basico.jal:168: constant expression expected
Cuando me pasaba esto era porque no tenía declarada la constante que usaba en algún punto del programa.
basico.jal:168: warning: assignment to smaller type; truncation possible
Esto era cuando le asignaba a una variable o constante un valor chico Ej: ponía byte y debía ser word.
basico.jal:176: warning: boolean expression expected
Acá era cuando quería hacer una cuenta y no tenía bien los datos de como lo quería hacer.
Muchas veces corrigiendo algún error o warning citado antes, el resto se acomodaba solo y tenía sentido el resto, entonces dejaba de haber más errores.
basico.jal:184: 'then' expected (got '=')
Ésto quiere decir que te comiste otro = debió ser == Ej.: else if coincidencia = 0 (te faltó ponerle otro = Debió ser else if coincidencia == 0
Acá me parece que tenes otro error:
else if
if cadena[pos_cadena] == frase[pos_frase]
Si pongo else if , no le gusta porque sería else o elsif nunca me deja else if , lo toma como que a ese if suelto le falta la condición, por lo tanto todo lo que vá después no tiene sentido para el compilador.
Fijate que hasta te cuestiona el end final porque tenes algo que te quedó sin resolver (abierto)
Tal vez mejore con :
elsif cadena[pos_cadena] == frase[pos_frase] then
o tal vez asi : else cadena[pos_cadena] = frase[pos_frase]
Ojalá te sirva
¿Sabes que no me había percatado de esos else if y luego if nuevamente? Ya los corregí y decayeron muchísimos los errores.
Aquí va el código completo:
-- ------------------------------------------------------------------------------------------------
-- ------------------------------------------------------------------------------------------------
-- Servidor web básico.
-- ------------------------------------------------------------------------------------------------
-- ------------------------------------------------------------------------------------------------
-- Creado por Leo Persi
--
-- Iniciado el 12 de junio de 2.015
--
-- ------------------------------------------------------------------------------------------------
-- TÍTULO: Servidor web básico.
-- VERSIÓN: 1.0.0.
-- AUTOR: Leo D. Persi.
-- PROGRAMA PARA PIC: Leo D. Persi.
-- PROGRAMA PARA PC:
-- FECHA DE LA ÚLTIMA ACTUALIZACIÓN: 12 de junio de 2.015.
--
-- DESCRIPCIÓN:
-- ------------
-- El presente programa, realiza un servidor web básico para ser usado con el módulo
-- ESP8266.
--
-- ------------------------------------------------------------------------------------------------
--
-- Este programa ha sido generado por jallib.py
-- Plataforma entrenadora Felixls.
--
-- ------------------------------------------------------------------------------------------------
-- 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 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
-- ------------------------------------------------------------------------------------------------
-- CONFIGURACIÓN GENERAL DEL PIC:
-- ------------------------------
--
-- ------------------------------------------------------------------------------------------------
var volatile bit usb_en_uso = 0 -- Ver en la descripción de la interrupción.
var volatile bit usb_iniciado = 0
include usb_serial -- Incluímos la librería para emular el puerto serial por USB.
usb_iniciado = 0
usb_serial_init()
usb_iniciado = 1
-- ------------------------------------------------------------------------------------------------
-- VARIABLES:
-- -----------
var byte ch -- Recupera el valor recibido por USB
var byte i
var byte x
-- ------------------------------------------------------------------------------------------------
-- INCLUIMOS LIBRERÍAS:
-- --------------------
include print
;include jstring
-- ------------------------------------------------------------------------------------------------
-- CONFIGURACIÓN DEL TMR0:
-- -----------------------
INTCON=0b10100000
T0CON=0b10000000
tmr0=64000
-- ------------------------------------------------------------------------------------------------
-- Iniciamos la conexión USB y el adc.
-- -----------------------------------
-- ------------------------------------------------------------------------------------------------
-- TRATAMIENTO DE LAS INTERRUPCIONES:
-- ----------------------------------
-- Descripción:
-- ------------
-- La interrupción ocurre cada 250useg. En la interrupción, se analiza el estado del bit usb_en_uso
-- para saber si hay que mantener viva la conexión USB o no.
-- Si usb_en_uso es 1; indica que se está transmitiendo datos por USB y no es necesario mantener viva
-- la conexión. Por lo tanto no se ejecuta la función usb_serial_flush().
-- En caso de que el bit usb_en_uso valga 0; quiere decir que no se está transmitiendo ningún dato,
-- por lo tanto, es necesario mantener viva la conexión y se tendrá que ejecutar la funsión usb_serial_flush()
-- ----------------------------------
procedure interrupcion() is
pragma interrupt
if (INTCON_TMR0IF) then
if usb_iniciado == 1 then
if usb_en_uso == 0 then
usb_serial_flush()
end if
end if
tmr0=64000
INTCON_TMR0IF=0
end if
end procedure
-- ------------------------------------------------------------------------------------------------
-- PROCEDIMIENTOS Y FUNCIONES TOTALES.
-- -----------------------------------
--
--
const byte STRING_MAX = 255
function StrLen (byte in str[]) return byte is
var byte i
for STRING_MAX using i loop
if str[i] == 0 then
return i
end if
end loop
return STRING_MAX
end function
-- ----------------------------------------------------------------------------
-- Encuentra una palabra o frase dentro de una cadena.
-- ----------------------------------------------------------------------------
function EncPalCad (byte in cadena[], byte in frase[]) return bit is
var byte pos_cadena = 0
var byte pos_frase = 0
var byte control
var byte coincidencia
i = count (cadena[])
x = count (frase[])
control = 0
while control != i loop
if control == i then
if coincidencia == x then
return true
else
return false
end if
else
if cadena[pos_cadena] == frase[pos_frase] then
coincidencia = coincidencia + 1
if coincidencia == x then
return true
else
pos_cadena = pos_cadena + 1
pos_frase = pos_frase + 1
control = control + 1
end if
else
coincidencia = 0
control = control + 1
pos_frase = 0
pos_cadena = pos_cadena + 1
end if
end if
end loop
end function
-- ------------------------------------------------------------------------------------------------
-- MENU PRINCIPAL.
-- ---------------
var byte cadena[] = "MI MAMA ME MIMA"
var byte frase[] = "MAMA"
forever loop
;
usb_en_uso = 0 -- Indicamos que no vamos a transmitir por USB.
if usb_serial_read(ch) then
usb_en_uso = 0
end if
if EncPalCad(cadena[],frase[])== 1 then
usb_en_uso = 1
else
usb_en_uso = 0
end if
end loop
Lo que está en for ever loop, realmente no me interesa mucho. Mi idea era simularlo y ver los estados de las memorias RAM para ver como se comportaba. Luego me iba a disponer de hacerlo funcionar en el PIC conectado al PC por USB.
A mi me desconcierta que espera una constante. Si la declaro como constante, también me tira error.
Bueno, lo acabo de hacer andar.
Era lo más evidente. Lo estaba usando mal. La función count, es solo para constantes. >:[|
Para ello, utilicé una función que trae la librería jstring.jal que busca un caracter. No salió andando de una. Tuve el problema de que contaba mal la cantidad de caracteres, y se debía que la función que cuenta la cantidad de caracteres en una cadena, contaba hasta encontrar un 0 al final de la cadena. Es por ello que le tuve que agregar, al final de la cadena \x00 que significa un valor en hexadecimal, que en este caso es 0
-- ------------------------------------------------------------------------------------------------
-- ------------------------------------------------------------------------------------------------
-- Servidor web básico.
-- ------------------------------------------------------------------------------------------------
-- ------------------------------------------------------------------------------------------------
-- Creado por Leo Persi
--
-- Iniciado el 12 de junio de 2.015
--
-- ------------------------------------------------------------------------------------------------
-- TÍTULO: Servidor web básico.
-- VERSIÓN: 1.0.0.
-- AUTOR: Leo D. Persi.
-- PROGRAMA PARA PIC: Leo D. Persi.
-- PROGRAMA PARA PC:
-- FECHA DE LA ÚLTIMA ACTUALIZACIÓN: 12 de junio de 2.015.
--
-- DESCRIPCIÓN:
-- ------------
-- El presente programa, realiza un servidor web básico para ser usado con el módulo
-- ESP8266.
--
-- ------------------------------------------------------------------------------------------------
--
-- Este programa ha sido generado por jallib.py
-- Plataforma entrenadora Felixls.
--
-- ------------------------------------------------------------------------------------------------
-- 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 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
-- ------------------------------------------------------------------------------------------------
-- CONFIGURACIÓN GENERAL DEL PIC:
-- ------------------------------
--
-- ------------------------------------------------------------------------------------------------
var volatile bit usb_en_uso = 0 -- Ver en la descripción de la interrupción.
var volatile bit usb_iniciado = 0
include usb_serial -- Incluímos la librería para emular el puerto serial por USB.
usb_iniciado = 0
usb_serial_init()
usb_iniciado = 1
-- ------------------------------------------------------------------------------------------------
-- VARIABLES:
-- -----------
var byte ch -- Recupera el valor recibido por USB
var byte i
var byte x
-- ------------------------------------------------------------------------------------------------
-- INCLUIMOS LIBRERÍAS:
-- --------------------
include print
;include jstring
-- ------------------------------------------------------------------------------------------------
-- CONFIGURACIÓN DEL TMR0:
-- -----------------------
INTCON=0b10100000
T0CON=0b10000000
tmr0=64000
-- ------------------------------------------------------------------------------------------------
-- Iniciamos la conexión USB y el adc.
-- -----------------------------------
-- ------------------------------------------------------------------------------------------------
-- TRATAMIENTO DE LAS INTERRUPCIONES:
-- ----------------------------------
-- Descripción:
-- ------------
-- La interrupción ocurre cada 250useg. En la interrupción, se analiza el estado del bit usb_en_uso
-- para saber si hay que mantener viva la conexión USB o no.
-- Si usb_en_uso es 1; indica que se está transmitiendo datos por USB y no es necesario mantener viva
-- la conexión. Por lo tanto no se ejecuta la función usb_serial_flush().
-- En caso de que el bit usb_en_uso valga 0; quiere decir que no se está transmitiendo ningún dato,
-- por lo tanto, es necesario mantener viva la conexión y se tendrá que ejecutar la funsión usb_serial_flush()
-- ----------------------------------
procedure interrupcion() is
pragma interrupt
if (INTCON_TMR0IF) then
if usb_iniciado == 1 then
if usb_en_uso == 0 then
usb_serial_flush()
end if
end if
tmr0=64000
INTCON_TMR0IF=0
end if
end procedure
-- ------------------------------------------------------------------------------------------------
-- PROCEDIMIENTOS Y FUNCIONES TOTALES.
-- -----------------------------------
--
--
const byte STRING_MAX = 255
function StrLen (byte in str[]) return byte is
var byte i
for STRING_MAX using i loop
if str[i] == 0 then
return i
end if
end loop
return STRING_MAX
end function
-- ----------------------------------------------------------------------------
-- Encuentra una palabra o frase dentro de una cadena.
-- ----------------------------------------------------------------------------
function EncPalCad (byte in cadena[], byte in frase[]) return bit is
var byte pos_cadena = 0
var byte pos_frase = 0
var word control = 0
var byte coincidencia = 0
var word i = StrLen (cadena)
var word x = StrLen (frase)
while control != i loop
if control == i then
if coincidencia == x then
return true
else
return false
end if
else
if cadena[pos_cadena] == frase[pos_frase] then
coincidencia = coincidencia + 1
if coincidencia == x then
return true
else
pos_cadena = pos_cadena + 1
pos_frase = pos_frase + 1
control = control + 1
end if
else
coincidencia = 0
control = control + 1
pos_frase = 0
pos_cadena = pos_cadena + 1
end if
end if
end loop
end function
-- ------------------------------------------------------------------------------------------------
-- MENU PRINCIPAL.
-- ---------------
var byte cadena[] = "MI MAMA ME MIMA\x00"
var byte frase[] = "MAMA\x00"
forever loop
;
usb_en_uso = 0 -- Indicamos que no vamos a transmitir por USB.
if usb_serial_read(ch) then
usb_en_uso = 0
end if
if EncPalCad(cadena,frase) == 1 then
usb_en_uso = 1
else
usb_en_uso = 0
end if
end loop
Siguiente paso, encontrar la manera de agregar, al final de la cadena, el valor 0. Me refiero a que yo voy a recibir una cadena, y al final no va a tener un valor 0. Por ahora tengo que analizar como me llega la cadena, ya que sospecho que me llega con \n y/o con \r
Hola.
No conocía el modulo 8266 y parece bastante interesante, pero un lío procesar los datos.
Desconozco el código de la parte de recepción datos, pero si necesitas agregar un 0 al final de la cadena lo que se me ocurre es inicializar todos datos con ceros antes de comenzar a recibir.
Los datos van reemplazando los ceros a medida que vayan entrando.
Si lo que necesitas es una comunicación inalámbrica entre PICs, yo te recomendaría los módulos NRF24L01+ y te olvidas de los string.
Podes mandar máximo de a 32 bytes pero te los manda a 2Mbit/s y cuestan casi lo mismo que el par de módulos 433.
Saludos.
Si, son excelentes estos módulos pero complicado de hacerlos andar.
Ahora lo dejé pro falta de tiempo. De echo hasta cree una función para buscar cadena dentro de una cadena; pero está en versión beta. Aún no lo probé como es debido.
Lamentablemente JAL me está desilucionando, y seguramente iré a otro lenguaje.