Ola pessoal. Boa tarde

Eu estou montando um projeto porém em alguns momentos um recurso utilizado acaba atrapalhando o desempenho do controlador.

Pensei em colocar outro controlador mas será preciso que esse segundo receba informações do primeiro.. Alguém saberia me informar como fazer eles conversarem?

Não pode ser i2c pois já tenho um sensor conectado nos pinos i2c.

obrigado desde já...

Exibições: 1489

Responder esta

Respostas a este tópico

Ola. Bom dia.

mas se os numeros que eu tenho tem casas decimais, como fazer?

lembrei o que eu fiz, eu multiplico por 100 no mestre e mando como int, e no slave eu divido por 100

union INT_tag {byte INT_b[2]; int INT_val;} INT_Union;

INT_Union.INT_val = (int)((variavel float) * 100);

Wire.beginTransmission(Dispositivo); // Transmite para o ID do dispositivo
Wire.write((byte*)INT_Union.INT_B, 2); // Manda os Bytes do union.
Wire.endTransmission();

Acho que seria algo do tipo...

recomendo nunca usar float no código uma vez que isto implicará em um aumento consideravel do programa resultante. eu faço sempre o seguinte, se quero duas casas de precisão preparo meu programa para tratat 0,25 como 25 se preciso de mais casa de precisão aumento o fator, uma vez que consigo trabalhar com pseudos ponto flutuante sem perder uma área considerável de flash.

outra coisa uma maneira muito fácil de transformar qualquer tipo de dado em byte é assim:

int c = 6;

unsigned char * intc;

intc = &c;

// neste momento intc aponta para o enderenço de memoria de c;

for(int i = 0; i < sizeof(int); i++)

    write(intc[i]);

resumindo sizeof(int) = 2 

Tive um problema parecido, mas eu precisava enviar um long int (4 bytes) sendo que o tamanho maximo tambem era byte.

Eh só "desmontar" float, no arduino um float sao 4 bytes

float phi = 1.61803398875;

char byte0 = phi && 0xff

char byte1 = phi && 0xff00

char byte2 = phi && 0xff0000

char byte3 = phi && 0xff000000

No outro lado tem que remontar com cuidado, para garantir que o numero obtido eh o mesmo enviado.

No meu caso acrescentei tambem um checksum so para garantir a integridade dos dados.

Conclusao: a menos que REALMENTE seja necessario, evite transferir float, pois isso significa mais custo computacional e menor eficiencia da comunicacao.

Rodrigo , encontrei uma outra biblioteca I2C que permite o uso dos "fios" SDA e SCL em outros pinos diferentes de A4 e A5, Ela é mais rápida pois foi construida em assembler.

SoftI2CMaster

http://playground.arduino.cc/Main/SoftwareI2CLibrary#.UzNYffldWa8

https://github.com/felias-fogg/SoftI2CMaster

Rodrigo eu também estou pesquisando como transferir bytes (no meu caso 6)  de um Arduino para outro.

Acho que encontrei a solução - (não sei se é a melhor)

https://sites.google.com/site/adifferentlemming/Home/projects/arduino

Multiple I2C Masters and Slaves with Arduino

Anexei o aquivo Multi I2C.zip

Mas antes deverá converter a sua variável  para uma string :

http://arduino.cc/en/Tutorial/StringConstructors

exemplos:

String stringOne = "Hello String";                  // using a constant String
String stringOne =  String('a');                    // converting a constant char into a String
String stringTwo =  String("This is a string");    // converting a constant string into a String object
String stringOne =  String(stringTwo + " with more");// concatenating two strings
String stringOne =  String(13);                     // using a constant integer
String stringOne =  String(analogRead(0), DEC);     // using an int and a base
String stringOne =  String(45, HEX);                // using an int and a base (hexadecimal)
String stringOne =  String(255, BIN);               // using an int and a base (binary)
String stringOne =  String(millis(), DEC);          // using a long and a base

Acho que vai dar certo...

Anexos

Transmitir como string eh bem pratico, mas em termos de eficiencia, existem alguns aspectos a serem considerados:

A cada caractere corresponde 1 byte. Por exemplo, no caso de um unsigned int (tamanho de 2 bytes) ao enviar como string seria necessario enviar enviar entre 1 e 5 bytes (valor maximo 65535).

Podemos supor que a maioria dos numeros enviados teria entre 3 e 5 caracteres (99,998% se considerarmos uma distribuicao uniforme).

Ou seja, em 99,998% dos casos seria mais eficiente "quebrar" o unsigned int em bytes, remontar, e ainda enviar um byte checksum.

Isso sem contar o tempo de processamento para converter/desconverter valor<->string.

Eh claro que essa escolha depende dos requisitos do projeto.

Olá, boa tarde!


Valeu a todos pela resposta... eu tentei de várias maneiras e a que foi relativamente fácil de fazer.. vou usando como String mesmo.

Mesmo não sendo recomendado, achei que foi a melhor maneira de eu conseguir e deu certo.


.....

exemplo:
variavel_monta_post_i2c = "23.4,3,0,4"

Wire.beginTransmission(7); 
Wire.write(variavel_monta_post_i2c.c_str()); 
Wire.endTransmission(); // stop transmitting



Um detalhe interessante..

como o segundo chip controla um beep, sempre que uma informação chegava, fazia um ruido no beep.

como se a cada chegada de informação, havesse uma interrupção momentânea...


Para resolver isso, ao invés de recuperar as informações, dentro da função receiveEvent, eu apenas marquei como true se tivessem novos dados..

void receiveEvent(int howMany)
{

haveData = true;
}


E recuperei no loop.

if (haveData)
{
   String vmonta_string_para_envio_i2c;
   vmonta_string_para_envio_i2c = "";
   while(Wire.available()) // loop through all but the last
   {
   char c = Wire.read(); // receive byte as a character
   vmonta_string_para_envio_i2c = vmonta_string_para_envio_i2c + c;
   }

}

Deu certo e funcionando 100%.  Depois que terminar o projeto eu publico aqui.


Desde já, muito Obrigado

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço