Igual es algo obvio para muchos, pero al mismo tiempo para gente como yo que ha empezado a programar hace mas bien poco no lo es tanto y cosas que pueden ser de cajón o simplemente automáticas para muchos, se convierte en toda una odisea para otros.
Os pido si puede ser, ejemplos de como desglosar, trocear o separar enteros o longs en bytes para luego por separado meterlos en un array, enviarlos por serial, meterlos en memoria o simplemente, tratar los datos por separado.
DRicote:
Igual es algo obvio para muchos, pero al mismo tiempo para gente como yo que ha empezado a programar hace mas bien poco no lo es tanto y cosas que pueden ser de cajón o simplemente automáticas para muchos, se convierte en toda una odisea para otros.
Os pido si puede ser, ejemplos de como desglosar, trocear o separar enteros o longs en bytes para luego por separado meterlos en un array, enviarlos por serial, meterlos en memoria o simplemente, tratar los datos por separado.
Saludos
Yo lo haría más o menos así:
long l;
byte b[4];
.... a toma algun valor
b[0]=l & 0xff; // hago and con 0xff para que quede solo el ultimo byte
b[1]=(l>>8) & 0xff; // roto los bits 8 veces a la derecha y de nuevo me quedo con el ultimo byte
b[2]=(l>>16) & 0xff;
b[3]=(l>>24) & 0xff;
Si el valor de l se puede perder, se puede if haciendo >>8 sobre l varias veces en lugar de hacerlo dentro de la asignacion. También se podría copiar l a una variable auxiliar. Todo depende de si en tu programa ahorrar algunos microsegundos es importante o no.
Lo del 3 en el array se me ha debido colar, como he estado inicializando el array de varias maneras...pero gracias por la aclaración que siempre viene bien! XD
Acabo de hacer lo siguiente para ver si consigo verlos al imprimirlos pero nada, creo que no me queda claro el concepto...
También lo he leído con el RealTerm y me saca 02,34,30,30 en HEX y debería sacar 31,32,33,34 no?
1º un número en arduino son 2 bytes.
2º estás dividiendo el número en bytes, no en caracteres ascii. El número 1234 está formado por los bytes 0x04 y 0xd2. Si lo que quieres hacer es dividirlo en los número 1, 2, 3 y 4 prueba esto:
Ok muchas gracias!!! No había tenido en cuenta la comprobación de signo pero si me puede hacer falta, y saber los limites del int y del long también.
La verdad que me está siendo muy instructivo este hilo
Hola a todos,hace unas semanas abrí un hilo titulado "Enviar un dato float via serial" el cual me contesto Xlopez ofreciéndome una solución (gracias Xlopez) pero que yo no he sido capaz de adaptarla.Ahora veo esto que parece se acerca mas a lo que necesito.Os explico: tengo un Arduino "B" que lee los datos de un anemómetro,lee las revoluciones y calcula cada 10 segundos el dato "float speedwind", desde un Arduino "A" le envío a través de un xbee una orden y el Arduino "B" obedece y "Serial.print (windspeed); me envía la lectura y yo en el Arduino "A" lo visualizo en un lcd , hasta aquí sin problemas, pero, aquí viene mi problema, necesito que aparte de visualizarlo en el lcd actualice el valor "windspeed" en el Arduino A.Tengo que descomponer el dato en "B" y enviarlo a "A" y aquí volverlo a armar para actualizarlo y almacenarlo . He probado mil cosas y no he dado con la solución.¿Alguna idea?, actualmente estoy bloqueado con esto.
Muchas gracias y un saludo
Mandas el dato en "raw", es decir, tal cual lo lees sin hacer ninguna operacion. A ver si me explico mejor.... XD
Si estas midiento pulsos, imagino que estaras usando una variable de tipo byte o unsigned int (2 bytes) como contador, no?
Puedes enviar este byte o estos dos, y en el otro lado haces la operacion de dividir entre el tiempo y el numero de pulsos por vuelta, etc.
Mandas el float tal cual (4 bytes).
Para mandar el dato en ambas opciones, descompones en bytes (depende del tipo de variable que quieras descomponer) con las operaciones bitwise que han explicado mas arriba y usa Serial.print(mibyte,BYTE).
En el otro lado, tienes que "componerlo" consecuentemente a como lo has "descompuesto".
Imaginemos un unsigned int (ocupa dos bytes):
unsigned int micontadorpulsos; //la variable que aumento cada vez que recibo un pulso nuevo
byte byte_bajo;
byte byte_alto;
byte_bajo=micontadorpulsos & 255;
byte_alto=(micontadorpulsos >> 8 ) & 255;
En el otro Arduino, ya sabes que primero te va a llegar la parte baja, y luego la alta.
Por lo cual tienes que hacer (asumo que has leido los dos bytes con Serial.read() ):
unsigned int mivariablerecepcion;
mivariablerecepcion=(byte alto << 8 ) ¦ (byte_bajo);
Nota.- Cuando escribo un post largo, el textbox de crear el mensaje se me sube siempre hacia arriba, por lo que tengo que andar bajando con el scroll.... alguien sabe como evitar esto???
Hola a todos: parece que veo luz al final del tunel,o no....He sido capaz de descomponer el dato enviarlo y volverlo a montar al otro lado pero en... I2c , no en Serial.
Vamos a ver el la parte del emisor:
unsigned int micontadorpulsos=1550; //la variable que aumento cada vez que recibo un pulso nuevo
byte byte_bajo;
byte byte_alto;
void setup() {
Pero tengo problemas a la hora de recepcionarlo.Esta linea me da error al compilar"mivariablerecepcion =((byte_alto << 8 )| (byte_bajo));"no acabo de dar con la solución.
Hola Juantreras, intenta probar con el siguiente código en el emisor:
unsigned int micontadorpulsos=1550; //la variable que aumento cada vez que recibo un pulso nuevo
byte byte_bajo;
byte byte_alto;
void setup() {
Serial.begin(9600);
}
void loop(){
byte_bajo=micontadorpulsos & 255;
byte_alto=(micontadorpulsos >> 8 ) & 255;
Serial.print('S', BYTE);
Serial.print(byte_bajo,BYTE);
Serial.print(byte_alto,BYTE);
Serial.print('F', BYTE);
delay (2000);
}
Y el siguiente en el lado del receptor:
byte byte_bajo;
byte byte_alto;
unsigned int contadorPulsos;
void setup() {
Serial.begin(9600);
}
void loop() {
//Compruebo si han llegado datos por el puerto serie
if (Serial.available() > 0) {
//Si el dato que ha llegado es S significa que comienza la transmisión
//del contador de pulsos.
if (Serial.read() == 'S') {
byte_bajo = Serial.read(); //Leo el byte_bajo del puerto serie
byte_alto = Serial.read(); //Leo el byte_alto del puerto serie
contadorPulsos = ((byte_alto << 8) && (byte_bajo)); //Junto todo en una variable
Serial.read(); //Como el protocolo envia una F la leo y en este caso la
//desecho porque no la necesito para nada
}
}
}
En este caso las tramas se envían con un protocolo como ha dicho Igor_R que es Sbyte_bajobyte_altoF.
Lo unico que:
contadorPulsos = ((byte_alto << 8 ) && (byte_bajo));
deberia ser una OR, no una AND. Y de operaciones bitwise => & - Arduino Reference (quieres sumar la parte alta a la baja).
&& devuelve true or false (es una operacion logica que devuelve boolean). Es diferente "&" que "&&".
Y es bueno comprobar que llegaba una F a lo ultimo ( para eso te "curras" el protocolo... ) y asi validar que puedes "confiar" que has recibido bien los datos.
Bueno chicos ,primero un saludo para todos,disculpar la tardanza en contestar, he estado muy liado.Bueno al lío ,efectivamente, Igor, el código funciono perfectamente pero no con && si no con | como decías , además el implementar ese sencillo protocolo da un control "total" sobre el flujo de datos, me ha venido de perlas para otra parte del proyecto que se dedica a recopilar datos y que no acababa de ir como debiera, así es que ha sido un "math" en toda regla.
Bien ahora , ya solo por culturilla general ¿que diferencia hay entre esta expresión? :RPM = ( Wire.receive()<<8) +Wire.receive(); y esta otra: RPM = ((byte_alto << 8) | (byte_bajo)); por supuesto a parte de que una es usada en comunicación I2c y la otra en Serial.
Gracias a todos