​Fala galera, tudo certo? Eu estou tendo ploblemas pra transmitir dados estruturados via I2C com o ESP8266. Fiz vários testes e li tudo que encontrei... estou usando um Wemos D1 Mini (ESP8266) como mestre de uma rede I2C com vários arduinos pro mini. Fiz a interface de 3V3 - 5V usando MOSFETS 2N7000 e os resistores pull up, tudo bonitinho..
Inicializo a biblioteca wire.h no ESP e limito o clock para 1500 (pois o arduino eh lento comparado ao ESP)... tudo certo!
Se eu requisito 1 byte de um escravo, ok! Ou mesmo se requisitar um conjunto de até 32 char (char*), ok!
Mas se eu tentar enviar mais bytes (testei com 8 ou mais) os valores bagunçam...
De arduino pra arduino isso não acontece.
 
Eu preciso enviar dados estruturados, como por exemplo:
struct dados
{
double valor1;
double valor2;
int valor 3;
}
 
Pra isso eu "quebro em bytes" e envio e na outra ponta eu "remonto"... Estou seguindo o exemplo do Nicki Gammon (http://www.gammon.com.au/forum/?id=10896&reply=8#reply8)
 
Aqui como eu faço para ler e escrever:
template <typename T> int ler(T& valor)
{
auto * p = (byte*)&valor;
unsigned int i;
for (i = 0; i < sizeof valor; i++)
*p++ = Wire.read();
return i;
}
 
template <typename T> int escrever(const T& valor)
{
auto p = (const byte*)&valor;
unsigned int i;
for (i = 0; i < sizeof valor; i++)
Wire.write(*p++);
return i;
}
 
Como eu disse.... No arduino com arduino vai bem.
 
Alguém tem alguma sugestão? Ou fez algo similar?

Exibições: 671

Responder esta

Respostas a este tópico

Não tenho ideia, mas alguns chutes:

1) Vc está usando os pull ups necessários na fiação e colocou mesmo no local correto ? 

2) Vc já mediu com o osciloscópio o aspecto dos sinais, se estão satisfatoriamente quadrados ?

3) Sua fonte é boa e tem uma boa interligação de terras ? Exemplo de fonte ruim: Porta USB de micro ruim, de painel frontal ou de motherboard ruim (positivo, sem marca, chines, etc) ou Porta USB com cabo USB ruim ou usa um hub chines daqueles... As vezes os hubs tem diodos que derrubam a tensão. Só isso já faz tudo trabalhar no limite. Pra perder bit fica super fácil.

4) O arduino tem alguma interrupção ativa ? Se sim, ela é absolutamente curta e imediata ou fica usando floats, bibliotecas ou coisas assim?

Pq as vezes quando tudo parece certo e as soluções complexas não fezem mais sentido as coisas podem estar ocorrendo por motivos simples. Já perdi um bom tempo por cabos USB vagabundos que vem de brinde com a placa. 

Sobre interrupção. Microcontroladores tem um buffer de 1 bit para acumular pendencia de cada interrupção. Se vc se enrola atendendo uma e outra acontece ok, ele vai atender assim que retornar. Mas se vc receber duas perdeu uma. O flag de interrupção estava ativo e é ativado. A primeira ativação foi ignorada, atende só a segunda. Perda de bits na certa.

ref:

http://www.ti.com/lit/an/slva689/slva689.pdf

Bom dia, 

Com a minha experiência eu faria isso :

1) Faria um teste de um ESp8266 com somente um Arduino !

2) medir os sinais da interface I2C com osciloscópio

3) medir os sinais da interface I2C com analisador lógico

http://pedrominatel.com.br/pt/arduino/comunicando-o-arduino-com-o-e...

Obrigado pelas respostas Eduardo e José Gustavo.


Estou fazendo diversos testes individuais e analisando passos simples.
Como falei antes, usando 2 Arduinos, tudo funciona muito bem. O problema começa quando adiciono o ESP8266 na jogada.


Mas estou validando testes simples e aumentando a complexidade aos poucos.
Com uma análise mais calma da própria arquitetura dos microcontroladores (32bits no ESP e 8bits no Arduino) desconfiei que os tipos primitivos teriam tamanhos diferentes e constatei que realmente, no ESP8266 o sizeof(int) é 4 e o sizeof(double) é 8, enquanto no ATmega328 o sizeof(int) é 2 e o sizeof(double) é 4. Mas nos dois o sizeof(float) é 4... então, a princípio padronizei float nos tipos numéricos nos meus testes.


Infelizmente estou sem Osciloscópio/ Analisador Lógico por enquanto.


Constatei também que se eu enviar uma cadeia de até 32 char, vai sem problemas. Mas se mandar mais que 14 bytes começa a aparecer vários 255 na outra ponta. Estou até considerando em utilizar uma método pra fazer o envio dos bytes (0~255) convertidos em char (-128~127), mas me parece muita gambiarra...
Vou buscar algo mais elegante primeiro.


Sigo avançando passo a passo, mas ainda não tenho confiança de utilizar o ESP8266 neste projeto como controlador principal, então estou usando um ATMega2560 + o ESP-01 via comandos AT afim de atender o prazo de entrega. Até porque o escopo do projeto demanda ainda várias coisas de análise de negócio, backend, frontend, Data Analytics, etc...


Mas como priorizei deixar funcionando e agora estou melhorando (hardware e firmware), vamos ver se consigo mudar isso.


Caso consiga um resultado satisfatório publicarei um artigo. Obrigado novamente.

Outra constatação interessante...

Estou usando eventos OnRequest do mestre pro escravo.

E no trecho de código do escravo que envia os dados, faz uma GRANDE diferença na estabilidade não usar comandos para printar na Serial, caso contrário a comunicação se perde e bagunça tudo.

Mas independente de ser gambiarra nao eh valido para detectar o problema?

osciloscopio eh seu melhor amigo, pelo visto vc eh programador (com dominio da arte) e jah esta vendo um osciloscopio, numa bancada de uso profissional isso eh iimprescindivel, todo hobista deseja um. No final vc entrega um produto que foi testado em todos os sentidos quando tem as ferramentas.
As vezes onde vc esta roda tudo legal, mas no cliente interferencia acontece, testando antes vc nao perde tempo. 



Obrigado pelas contribuições Akira :)

Concordo com tudo!

No caso do evitar a "gambiarra" é mais pra melhorar o conhecimento mesmo e cada vez mais fazer do jeito certo.

E acho mesmo importante o teste e as validações e prezo por eles. Só não tenho as ferramentas ainda pois a empresa está investindo no laboratório conforme vamos mostrando retorno... sabe como é!?

IoT ainda é muita novidade lá no nosso meio...

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço