Me obligas a leerme el pdf, y es precisamente lo que uno trata de evitar, porque ir al detalle fino, requiere mucho más tiempo en responder y sale un mensaje más largo.
Es definitiva es como te señalaba en mi mensaje anterior...
En ese incluí el ejemplo para decodificar un supuesto comando de la bateria (que existe se llama B (Battery), pero con sus valores específicos).
El comando X27, viene explicado también en el pdf, recibe '#' con 6 bytes, un cóoodigo de error viene en la forma: "#- loque sea".
Lo más sencillo al caso una vez leído por encima en pdf, es hacer un parsing genérico y luego especifico para cada comando... es más o menos el pseudocódigo previo que puse en mi mensaje anterior... la parte del preparsing, sería algo como:
enumeracion PartesResultado
COMANDO_INICIO = 35 // el ASCII de '#'
COMANDO_FIN = 13 // el ASCII de 'retorno de carro
//COMANDO_MEDIO = 1 // referencia al medio, luego se explica mejor.
fin enumeracion
Ahora una funcion que preprocesa el comando recibido:
funcion ParsingComando(string comando, string valor)
entero inicio, cantidad
si ((valor comienza con COMANDO_INICIO) y (termina con COMANDO_FIN))
Si (valor.charat(1) = "-") // parece ser un código de error. "#- loquesea"
llamada a InterpetarCodigoError(substring(valor, 2,1)) //enviamos el carácter 3 de los 4 que tiene
// (ignoro si tienen más de 1 byte-char como codigo de error.
Sino // el resultado tiene valores interpretables:
// enviamos ya 'recortdo' el string, sin los caracteres inicial y final
inicio = 1
cantidad = valor.length -2
llamada a ProcesarComandos(comando, valor.Substring(inicio, cantidad))
fin si
sino
mensaje = "Error, el valor del comando recibido, tiene un formato desconocido..."
fin si
fin funcion
Como decía conviene tener una enumeracion que represente cada comando:
Hay todos estos comandos: "The I, O, L, B, V, T, F, H, R, C, Q, S, W, X are single uppercase
enumeracion ComandosSAI
SAI_COMANDO_BATERIA = 66 // ASCII de 'B'
SAI_COMANDO_UTILITY_VOLT = 73 // ASCII de 'I' (una 'i').
//
//
...
SAI_COMANDO_STATUS_FLAG = 83 //ASCII de 'S'.
SAI_COMANDO_W... = 87 // idem de 'W'
SAI_COMANDO_X... = 88 // " 'X'
character"
La funcion procesar comando, tendrá en selector de casos, con un caso para cada comando que te interese y un 'else', para el resto...
Esto viene a ser equivalente al código de más arriba, solo que allí se recibía 1 solo byte y se ejemplificaba solo el comando 'B' de batería.
Algunos comandos como el X, tienen 'subcomandos' en la forma Xn, donde 'n' es un numero...
Estos comandos dento de su 'caso', examina precisamente el 'subcomando', y lo gestiona a su vez con otro 'selector de casos'.
Como los comandos al final tienen varos bytes, interesa más hacer una llamada en esta funcion para dedicar una funcion exclusiva para procesar cada comando o subcomando, incluso aunque haya partes comunes entre ellos, será m
ás fácil de implementar y de mantener aunque sea a costa de más código:
funcion ProcesarComandos(string comando, string valor) //valor ya viene filtrado de # y 'cr'
ComandosSAI SaiComando = comando.left(1).ToByte
seleccionar caso para SaiComando
caso SAI_COMANDO_BATERIA
llamada a ProcesarBateria(valor)
caso SAI_COMANDO_UTILITY_VOLT
llamada a ProcesarUtilityVolt(valor)
....
caso SAI_COMANDO_STATUS_FLAG
llamada a ProcesarStatusFlag(valor)
caso SAI_COMANDO_W...
llamada a ProcesarW(valor)
caso SAI_COMANDO_X...
comando = comando.substring(1, comando.length-1)
llamada a ProcesarX(comando, valor) // <-------- ejemplo de un comando que tiee subcomandos
otros casos
mensaje "Actualmente no procesamos el comando: " + comando + nuevalinea + valor
fin casos
fin funcion
funcion ProcesarX(string comando, string valor)
byte servico = comando.Tobyte
seleccionar caso para servicio
caso 5
caso 15
...
caso 27 // tiene 6 chars
llamada a ProcesarX27(valor)
caso 28
...
otros casos
mensaje "Actualmente noe staos procesando el subcomando '" servicio.Tostring + "' del comando 'X', con valor: " + valor
fin seleccionar casos
fin funcion
// Según el pdf: #output_voltage,high_transfer_voltage,low_transfer_voltage, battery_threshold,runtime_threshold<cr>
funcion ProcesarX27(string valor)
llamada a procesarOutputVoltage(valor.charat(0).tobyte)
llamada a procesarHighTransferV(valor.charat(1).tobyte)
llamada a procesarLowTransferV(valor.charat(2).tobyte)
llamada a procesarBatteryThreshold(valor.charat(3).tobyte)
llamada a procesarThreshold(valor.substring(4,2)) // este parametro ocupa creo que 2 bytes.
fin funcion
Y bueno, este es el esqueleto para decodificar todo... fíjate que es un simple parsing, donde primero se verifica si el resultado es un codigo de erro o no... sino, luego se verifica que comando se trata, luego cada comando si tiene subcomandos, deriva a otra funcion que identifique de qué subcomando se trata, al final cada comando final, tiene que ser procesado individualmente, porque los bits de cada uno tendran un significado unico y específico...
El caso de error, igualmente en su llamada debe derivar descendeidno e comandos y subcomandos, segun sea el caso, para que al final procesar el error. Ignoro si cuando es un código de error, se compone de un unico byte o más... si es solo uno, una unica funcion (a nivel de comandos y subcomandos) podría ser suficiente, en cambio si tiene varios bytes, y el codigo puede ser excesivo (generaría una función muy larga), convendría en ese caso, tener una etapa más donde se procese cada byte (si cada bit tiene un significado propio, si cada byte tiene un significado propio es lo mismo que recibir 1 solo byte con significado propio a nivel de bit (o más de 1).
En fin, el trabajo no es complicado, solo largo y algo tedioso, porque son más de una docena de comandos y algunos tienen subcomandos, y luego cada caso se procesa a nivel de bit, por lo que necesitas constantes a mogollon...
pd.: Olvidaba adjuntar una captura que hice, para que veas que viene explicado, tienes que leerlo primero entero, para tener una idea global y luego ocn más detenimiento en el apartado que más te interese, si te interesan todos, pués paciencia, hoy uno y mañana otro.
