Por fin...
ya consegui lo que queria hacer.este es mi primer programa en java.que no he tenido que copiar de ningun sitio.que trabajito me ha costado.
este programa que he realizado consiste en coger un String y separar los caracteres ASCII en parejas.estos caracteres solo pueden contener los valores
0 al 9 y letras A al la F.en mayusculas.las letras en minusculas darian errores en los calculos.aunque podria usar minusculas he preferido las mayusculas.
si alquien quisiera minusculas.solo tendria que modificar el programa.
bueno.el programa convierte una cadena ejem. "A1FE0543" en un array de valores int. ejem-> 161,254,5,67. siempre el array tiene que contener
un numero de caracteres par.en este ejemplo seria de 4 parejas.no he querido poner ningun tipo de proteccion ante errores de cantidad de caracteres para
no relentizar el programa.esto lo realizaremos en el layout del android.
este es el programa al que llamaremos con:
String trama="A1FE0543";
variableX=NombreDeLaClase.CRC16int(trama);
y este es el programa:
//se toman los caracteres ASCII del string de dos en dos.para obtener un valor entre 0 y 255.y asi crear un array de valores decimales
//a partir de un array de valores Hexagesimales.
public static int[] hexStringToIntArray(String cadenaDec) {
int len = cadenaDec.length();//longitud de la cadena
if (len <= 2){ len=2;};//para la obtencion del CRC de un solo valor hexagesimal.
int[] data = new int[len/2];//asignar indices del array.un indice por cada dos caracteres.
for (int i = 0; i < len; i += 2) {
int data1=cadenaDec.codePointAt(i)-48;//tomar valor int de caracter ASCII de valores entre (0-9)
if (data1 > 9) {data1=data1-7;};//modificar valor int para valores int de caracteres ASCI de valores entre (A-F)en mayusculas.
int data2 = cadenaDec.codePointAt(i+1)-48;//lo mismo que lo anterior pero para las unidades "ya que lo anterior es para las decenas"
if (data2 > 9) {data2=data2-7;};//lo mismo que lo anterior pero para las unidades "ya que lo anterior es para las decenas"
data[i/2]=(int) ((data1*16)+data2);//obtener el valor int del Hex string de dos cifras.
}
return data;
}
Con la llamada a este programa hemos conseguido transformar una cadena de caracteres Hexagesimales.en un array de enteros decimales.
los cuales vamos a usar en el siguiente programa para extraerles el CRC.
el programa que hize en anteriores respuestas hera para generar el CRC de una cadena de caracteres ASCII.el problema es que se usa un array de Bytes.
y estos tienen valores entre 0-127 y -0 a -127.y no nos sirven para valores entre 0 y 255 decimal.o entre 00h y FFh
asi que he creado el siguiente generador de CRC con polinomio A001.para un array de enteros.
// Calculo del CRC para protocolo MODBUS (polinomial 0xA001) para un array de valores integer.
public static String CRC16int(int[] cadenaDec) {
int crc = 0xFFFF; // valor inicial
int[]bytes=cadenaDec;
for (int b : bytes) {//ir tomando los bytes del string desde el primero al ultimo.
crc^=(b);//xor de crc con primer dato
for (int i = 8; i != 0; i--) { // bucle de 8 movimientos como maximo para crear el crc por cada byte
if ((crc & 0x0001) != 0) { //si el ultimo bit esta a 1,
if (DEBUG)Log.e(LOG_TAG, "bytes3 "+ crc);
crc >>= 1; // desplaza a la derecha
crc ^= 0xA001; //xor con valor polinomial 0xA001(MODBUS)
}
else // si el ultimo bit no esta a cero;
crc >>= 1; // rota a la derecha
}
// crc &= 0xffff;
}
String strCRC = Integer.toHexString(crc);
for (int i=strCRC.length();i<4;i++){strCRC= "0"+strCRC;};//asegura que el CRC sea de 4 caracteres.rellenar con ceros por la izquierda hasta obtener 4 cifras.
return strCRC;
}
Este programa en conjuncion con el anterior.genera el CRC del array introducido. en formato string.asi que lo podemos visualizar en un TextView.
o enviarlo atraves del bluetooth de la aplicacion que estoy desarroyando.
asi que junto a las lineas anteriores.
String cadenaHex7="A1FE0543";
cadenaHex18=ModBus.hexStringToIntArray(cadenaHex7);//debuelbe un array de bytes
cadenaHex3=NombreDeLaClase.CRC16int(cadenaHex18);
podemos unir las siguientes:
EditTextCRC.setText(cadenaHex3); // para visualizarlo en un textView.
cadenaHex2=ModBus.hexStringToByteArray(cadenaHex3);// o para extraer los bytes y..
mSerialService.write(cadenaHex2);// enviarlos atraves de
y de esta forma enviariamos el CRC de la trama "A1FE0543" en formato hexagesimal.que lo uniremos a la trama para transmitirla por bluetooth.
ya mismo pondre la aplicacion de envio de tramas con CRC incorporado.
PD: por cierto el CRC de la trama "A1FE0543" es 8900 segun mi programa.
y tambien lo podeis comprobar aqui:
http://www.lammertbies.nl/comm/info/crc-calculation.html