collapse

* Links de Robótica

* Posts Recentes

Ligar Células de Lithium por Hugu
[Hoje às 02:00]


Encomenda Colectiva N3-2016[@Mouser - Aberta a pedidos!] por Hugu
[Hoje às 01:53]


Printer 3D barata por xmatias
[Ontem às 03:56]


Servidor por almamater
[09 de Dezembro de 2016, 21:39]


mysql server error por andre_f_carvalho
[09 de Dezembro de 2016, 18:56]


Cortar plástico ABS por msr
[05 de Dezembro de 2016, 17:27]


MOVIDO: FPV Drone Racing? por metRo_
[05 de Dezembro de 2016, 10:49]


Módulo gsm por dio123
[04 de Dezembro de 2016, 23:06]


Procuro resistências 220 Ohm de 1% por brunus
[02 de Dezembro de 2016, 15:50]


Package de cond 10uF 35V smd? por KammutierSpule
[02 de Dezembro de 2016, 11:19]

Autor Tópico: Comunicação I2C com Arduino  (Lida 3992 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline marlon.tiedt

  • Mini Robot
  • *
  • Mensagens: 5
Comunicação I2C com Arduino
« em: 04 de Dezembro de 2014, 01:37 »
Pessoal estou estudando a comunicação I2C pelo Arduino. Estou querendo fazer a comunicação com o shield MPU-6050 e estou seguindo este tutorial http://playground.arduino.cc/Main/MPU-6050 para entender a comunicação I2C.

As coisas que já entendi, é que todo componente com I2C tem o seu próprio endereço e os seus próprios registradores.

Neste exemplo tem estas linhas de código:

Código: [Seleccione]
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);/

O código
Código: [Seleccione]
Wire.write(0x6B); indica que quero acessar o endereço 0x6B? Se sim, como o controlador sabe que o próximo byte é valor que vai ser escrito? Ou o I2C por padrão é assim, mando o endereço o componente, um registrador e depois o valor.

Como sei se é escrita ou leitura?

Outra coisa, se eu tiver um segundo parâmetro em seguida tenho que mandar o endereço e depois o valor, ou posso mandar o valor direto? Se o valor para setar for igual a 0x6B, como ele vai entender que é um valor e não para ir no endereço?

Se eu tiver no minha rede I2C um parâmetro igual a um endereço, como os slaves se comportam?

Neste código
Código: [Seleccione]
Wire.beginTransmission(address);
Wire.write(0x03);
Wire.endTransmission();
Wire.requestFrom(address, 6);


o requestFrom(address, 6); pede 6 próximos bytes a partir do 1 endereço?


Tentei colocar todas as dúvidas direto para não ficar perguntando por partes.
[/code]

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 2.843
    • Tróniquices
Re: Comunicação I2C com Arduino
« Responder #1 em: 04 de Dezembro de 2014, 02:08 »
Bom, assim por alto:

O bus I2C em si apenas define como se faz a communicação (transmissão de dados) entre dispositivos; o que cada dispositivo faz com esses dados "é lá com ele", ou seja, está escrito na sua datasheet.

Na verdade o I2C destingue entre dispositivos mestre e dispositivos escravo, ou seja, há 2 tipos de dispositivo, sendo que apenas os do tipo mestre podem iniciar uma leitura ou escrita de dados de um dispositivo escravo (se 2 mestres pretenderem comunicar, um deles tem que se transformar em escravo temporariamente). O mestre é quem sempre controla a linha de clock (SCL), que regula o ritmo de transmissão de dados (os dados viajam na linha de dados, SDA). Quando falamos em "escrever" e "ler", é do ponto de vista do mestre, o mestre escreve ou lê dados do escravo.

Uma consequência da forma como o bus funciona é que um escravo não tem maneira de iniciar uma transmissão de dados para o mestre (excepto se se tornar num mestre!); se ele quiser enviar algo ao mestre, tem que o avisar de outra maneira (por exemplo por uma linha dedicada de "interrupção") e então o mestre é que faz a leitura dos dados do escravo.

O mestre tipicamente é um microcontrolador/processador e o escravo é um periférico/memória/sensor/etc.

O bus funciona por transmissão de "mensagens". Uma mensagem transporta um conjunto de bytes entre 2 dispositivos (sempre 1 mestre e 1 escravo), e começa com um "sinal especial" (ao nível eléctrico, chamado START CONDITION) que marca o inicio e outro sinal especial que marca o fim (STOP CONDITION). Existe ainda um bit especial de confirmação de recepção (acknowlege, ACK) depois de cada byte transmitido (quem recebe o byte confirma a recepção a quem o enviou), e uma forma de controlo de fluxo, em que o escravo pode dizer ao mestre "ei, espera aí um bocadinho, tás a falar/pedir muito depressa!", o chamado CLOCK STRETCHING (consiste no escravo "segurar" a linha de clock (SCL) a zero durante o bit de ACK, impedindo o mestre de transmitir clocks).

O 1º byte de cada mensagem é uma escrita (o mestre escreve para o escravo) que indica o endereço do escravo (7 bits) e se a operação é de leitura ou de escrita (1 bit); depois o mestre escreve ou lê dados conforme o tipo de operação escolhida no 1º byte.

Entendendo "por alto" como funciona o bus, tens que consultar a datasheet do dispositivo mestre e a do dispositivo escravo para saberes:

1) do lado do mestre, como endereçar um escravo e como efectuar escritas e leituras (no teu caso, tens a documentação da API do arduino do site do arduino)

2) do lado do escravo, que mensagens ele está preparado para receber/enviar e qual a sua composição (no caso, na datasheet desse MPU6050 (não sei o que é, não fui ver))

Offline fergas

  • Mini Robot
  • *
  • Mensagens: 108
Re: Comunicação I2C com Arduino
« Responder #2 em: 04 de Dezembro de 2014, 08:55 »


Código: [Seleccione]

Wire.beginTransmission(MPU);



Aqui MPU deverá ser uma variável que tem o endereço do dispositivo com o qual o arduino vai comunicar.
A instrução Wire.write(x) envia valores para o dispositivo. Wire.write(0x6B) vai mandar o valor 0x68 para o dispositivo selecionado em Wire.beginTransmission(endereço); que já estará espera dele ou até de mais valores se fôr o caso.
Já a instrução Wire.requestFrom(address, x); indica ao dispositivo que tem o endereço "address" para enviar ao arduino x bytes, que serão colectados com as funções available() e read() .
Consulta a página do site do arduino que explica bem estas funções.

Offline marlon.tiedt

  • Mini Robot
  • *
  • Mensagens: 5
Re: Comunicação I2C com Arduino
« Responder #3 em: 04 de Dezembro de 2014, 09:54 »
Valeu pelas dicas. Se eu fazer o código abaixo, vai escrever 0 no endereço 0x00 e 2 no endereço 0x01 ou vai escrever 0 no endereço 0x00 e depois 2 no mesmo endereço.

Código: [Seleccione]
Wire.write(0x00);
Wire.write(0);
Wire.write(2);

Ou tenho que fazer isto, para escrever nos dois endereços:

Código: [Seleccione]
Wire.write(0x00);
Wire.write(0);
Wire.endTransmission();
Wire.write(0x01);
Wire.write(2);
Wire.endTransmission();

Offline Kristey

  • Mini Robot
  • *
  • Mensagens: 689
Re: Comunicação I2C com Arduino
« Responder #4 em: 04 de Dezembro de 2014, 11:00 »
Boa explicação Njay

Online jm_araujo

  • Mini Robot
  • *
  • Mensagens: 1.692
  • NERD!
Re: Comunicação I2C com Arduino
« Responder #5 em: 04 de Dezembro de 2014, 11:07 »
Valeu pelas dicas. Se eu fazer o código abaixo, vai escrever 0 no endereço 0x00 e 2 no endereço 0x01 ou vai escrever 0 no endereço 0x00 e depois 2 no mesmo endereço.

Código: [Seleccione]
Wire.write(0x00);
Wire.write(0);
Wire.write(2);

Ou tenho que fazer isto, para escrever nos dois endereços:

Código: [Seleccione]
Wire.write(0x00);
Wire.write(0);
Wire.endTransmission();
Wire.write(0x01);
Wire.write(2);
Wire.endTransmission();



RTFM!
Os engenheiros perdem tanto tempo a escrever datasheets e depois ninguém lhes liga nenhum :(

Tens a resposta nas páginas 35 e 36 da datasheet do MPU 6050 : http://www.invensense.com/mems/gyro/documents/PS-MPU-6000A-00v3.4.pdf




Offline marlon.tiedt

  • Mini Robot
  • *
  • Mensagens: 5
Re: Comunicação I2C com Arduino
« Responder #6 em: 04 de Dezembro de 2014, 11:49 »
Obrigado pela resposta jm_araujo.
Mas a minha dúvida é, o I2C se comporta assim ou depende do CI?


Online jm_araujo

  • Mini Robot
  • *
  • Mensagens: 1.692
  • NERD!
Re: Comunicação I2C com Arduino
« Responder #7 em: 04 de Dezembro de 2014, 12:08 »
Tens sempre de ler as datasheets (é para isso que elas servem), cada IC implementa as partes que lhes interessa, e há alguns com umas manias bem estranhas: Recordo-me de memórias que se fizeres leituras(ou eram escritas?) sequenciais não mudavam de página de ?256bytes?, ficavam sempre na mesma, para alterar tinha-se de iniciar nova leitura.

Como já foi muito bem dito:
O bus I2C em si apenas define como se faz a communicação (transmissão de dados) entre dispositivos; o que cada dispositivo faz com esses dados "é lá com ele", ou seja, está escrito na sua datasheet.

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 8.990
  • Helpdesk do sitio
Re: Comunicação I2C com Arduino
« Responder #8 em: 04 de Dezembro de 2014, 12:42 »
Só escreve num endereço novo se fizer incrementação automática do endereço, mas tambem pode estar á espera de receber um valor de 16bits, ou 24, ou 32, ou mais bits para um só endereço e terás de fazer várias escritas para o mesmo endereço.

Se não queres ler, sacas uma biblioteca para esse chip, escreves chip.begin e chip.read e está feito, continuas é sem entender como é que funciona, mas mesmo a biblioteca i2c do arduino não é das melhores, esconde algumas coisas(ack's e nak's, o bit read/write do endereço, entre outros).
Avr fanboy

Offline marlon.tiedt

  • Mini Robot
  • *
  • Mensagens: 5
Re: Comunicação I2C com Arduino
« Responder #9 em: 04 de Dezembro de 2014, 13:10 »
Só escreve num endereço novo se fizer incrementação automática do endereço, mas tambem pode estar á espera de receber um valor de 16bits, ou 24, ou 32, ou mais bits para um só endereço e terás de fazer várias escritas para o mesmo endereço.

Se não queres ler, sacas uma biblioteca para esse chip, escreves chip.begin e chip.read e está feito, continuas é sem entender como é que funciona, mas mesmo a biblioteca i2c do arduino não é das melhores, esconde algumas coisas(ack's e nak's, o bit read/write do endereço, entre outros).

Por isto estou tentando entender o padrão. Pois o Wire do Arduino esconde muita coisa mesmo. E vários post da internet, muitos são parecidos.

Offline dropes

  • Mini Robot
  • *
  • Mensagens: 1.876
Re: Comunicação I2C com Arduino
« Responder #10 em: 04 de Dezembro de 2014, 14:17 »
Não há nada melhor do que ler um pdf de uma memória da Philips para entender o protocolo I2C.
Entretanto já consigo ler e escrever neste tipo de ICs como nos RTCs, sensores, etc..., através da porta paralela do pc ou de um microcontrolador programado em assembler.

http://www.nxp.com/documents/data_sheet/PCF8582C_2.pdf

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 8.990
  • Helpdesk do sitio
Re: Comunicação I2C com Arduino
« Responder #11 em: 04 de Dezembro de 2014, 14:44 »
Podemos sempre ler o que uma das pessoas que criou o protocolo tem a dizer sobre o mesmo:
http://www.siliconvalleygarage.com/i2cfaq/i2cfaq_000_index.htm

Tambem conhecido como free_electron no eevblog.
Avr fanboy

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 2.843
    • Tróniquices
Re: Comunicação I2C com Arduino
« Responder #12 em: 04 de Dezembro de 2014, 18:56 »
Uma das pessoas que criou o protocolo? Com o que ele diz na FAQ, não me parece:

Citar
Who put this FAQ together?
I put this FAQ together in response to my own frustration in searching for information about I2C. (...)

O I2C parece catita no papel, mas quando vamos realmente usar a coisa, as implementações de chips (principalmente mestres) por esse mundo fora estão "cheias" de bugs, dos AVR ao RaspberryPI*. Já tive que lidar com I2C em pelo menos 3 ou 4 projectos profissionais mais 1 pessoal e em absolutamente *todos* encontrei problemas com bugs do hardware e implementações de sw, que especialmente se traduzem em problemas que ocorrem esporádicamente (portanto, mesmo dos bons; uma vez passei uma bela noite no laboratório, eu, um analizador lógico e uma placa com um bus I2C). E foram só sistemas de 1 mestre, nem quero imaginar sistemas multi-mestre. Os locks de bus são os mais giros, quando há 3 ou mais dispositivos pendurados no bus; em geral é difícil ou quase impossível descobrir quem é que está a prender o bus**. A verdade é que a implementação do I2C é complexa, não passa pela cabeça de ninguém a quantidade de estados e casos possíveis que isto tem, para ser bem implementado. Admito que é um bus só uso se for "obrigado", eventualmente posso usar para aceder só a uma EEPROM ou chip simples mas mesmo assim... cuidado na escolha do hw mestre.


*O (SoC do) RaspberryPi tem um bug no clock stretching; em certas condições simplesmente ignora o pedido de stretching do escravo, resultando em locks temporários do bus e corrupção de mensagens. Sim, também já fui "mordido" por este.

**Uma dica: num sistema complexo, deixem no PCB maneira de poder desligar qualquer um dos dispositivos escravo do bus, ponham 2 jumpers/resistências de 0 Ohm em série com as linhas à entrada do dispositivo. Desta forma podem isolar o dispositivo do bus se tiverem problemas.
« Última modificação: 04 de Dezembro de 2014, 19:05 por Njay »

Online KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 949
Re: Comunicação I2C com Arduino
« Responder #13 em: 04 de Dezembro de 2014, 20:06 »
Felizmente nunca tive que usar I2C :) Mas tenho encontrado testemunhos com o Njay dos problemas daquilo. Acho estranho principalmente porque ja devia ser um protocolo "maduro".
Tenho a impressão que a maior parte das erratas relacionadas com I2C, sao devido a novas expansões (plus plus plus...) ao protocolo original.
'E quando as leio que penso para mim "espero nunca vir a precisar disto!"  ???

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 8.990
  • Helpdesk do sitio
Re: Comunicação I2C com Arduino
« Responder #14 em: 04 de Dezembro de 2014, 20:52 »
Provavelmente estou a confundir com outro nome, sorry.

Até me sinto melhor ao saber que não é só comigo que sempre que há alguma coisa a falar i2c que há sempre algum problema inesperado, a ultima guerra foi com um PCA9685.

« Última modificação: 04 de Dezembro de 2014, 20:55 por senso »
Avr fanboy