Как правильно осуществить передачу данных по I2C

valdemar
Offline
Зарегистрирован: 31.05.2015

Доброе время суток!

Подскажите пожалусто как будет правельно передать данные по I2C. Есть две ардуинки одно ведущая другая ведомая. Есть три переменных a,b,c они имеют числовое значение.

Вопрос заключается в следущем как правельно передать и как ведомая должна понять какую переменную я ей передаю.

Составил небольшую программу, но думаю что мой код не верен так как скорее всего какая нибудь переменная может не прейти или потеряться, может есть способ проверки, что отправленная переменная пришла,  может кто подскажет что да как?

Ведущая:

#include <Wire.h>
void setup()
{  Wire.begin(); }
 
byte a = 0;
byte b = 20;
byte c = 30;
 
void loop()
{
  Wire.beginTransmission(4); 
  Wire.write("a");
  Wire.write(a);
  Wire.endTransmission();    
 
  a++;
 
  delay(500);
  Wire.beginTransmission(4); 
  Wire.write("b");
  Wire.write(b);
  Wire.endTransmission();    
 
  b++;
  delay(500);
 
  Wire.beginTransmission(4); 
  Wire.write("c");
  Wire.write(c);
  Wire.endTransmission();    
 
  c++;
  delay(500);

 

}
 
Ведомая:
 
#include <Wire.h>
 
void setup()
{
  Wire.begin(4);                
  Wire.onReceive(receiveEvent); 
  Serial.begin(9600);         
}
 
byte a,b,с = 0;
 
void loop()
{
  delay(500);
  Serial.print("a = ");
  Serial.println(a); 
  Serial.print("b = ");
  Serial.println(b);
  Serial.print("с = ");
  Serial.println(с);
}
 
void receiveEvent(int howMany)
{
  while (Wire.available()) 
  {
    char f = Wire.read(); 
    if (f == 97){
   byte per = Wire.read();
    a = red;
  }
    if (f == 98){
    byte per = Wire.read();
    b = red;
 }    
        if (f == 99){
    byte per = Wire.read();
    c = red;
 }   
}    
 
}
 

 

nikolaki
nikolaki аватар
Offline
Зарегистрирован: 14.02.2013

почитайте тута. И тута . При моих минимальных знаниях мне это очень помогло.

valdemar
Offline
Зарегистрирован: 31.05.2015

Спасибо!

Sergeyevd
Sergeyevd аватар
Offline
Зарегистрирован: 25.03.2014

Здравствуйте. Помогите разобраться с получением данных по i2c в Nodemcu с Arduino

Код ардуино:

#include <Wire.h>
#include <iarduino_I2C_connect.h>
iarduino_I2C_connect I2C2;
const byte PIN_Potentiometer = 0;
int  VAR_Potentiometer = 0;
byte REG_Massive[3];
void setup(){
Wire.begin(0x02);
I2C2.begin(REG_Massive);
}
void loop(){
  VAR_Potentiometer = analogRead(PIN_Potentiometer);
  REG_Massive[1]    = VAR_Potentiometer>>8;
  REG_Massive[2]    = VAR_Potentiometer;
//Почему значение потенциометра содержит 2 байта?
}

Код Lua

id=0
sda=2--Uno A4--Node D2--IO4
scl=1--Uno A5--Node D1--IO5
i2c.setup(id, sda, scl, i2c.SLOW)
function read_reg(dev_addr, reg_addr)
    i2c.start(id)
    i2c.address(id, dev_addr, i2c.TRANSMITTER)
    i2c.write(id, reg_addr)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id, dev_addr, i2c.RECEIVER)
    c = i2c.read(id, 1)
    i2c.stop(id)
    return c
end
-- get content of register 0xAA of device 0x77
--Как я понял из примера на github.com
--таким способом получаю содержимое регистра 2 адреса 0х02
reg = read_reg(0x2, 0x02)
print(string.byte(reg))

Поворачивая ручку потенциометра получаю числа от 0 до 255

Как получить то, что отправляет ардуино? (0-1023)

Sergeyevd
Sergeyevd аватар
Offline
Зарегистрирован: 25.03.2014

У меня получилось принять данные, но...

Ардуино выступает в качестве slave

#include <Wire.h>

void setup() {
  Wire.begin(8);
  Wire.onRequest(requestEvent);
}

void loop() {

}

void requestEvent() {
  Wire.write("hello");
}

LUA Nodemcu master

i2c.setup(0, 2, 1, i2c.SLOW)

function read_reg()
    i2c.start(id)
    i2c.address(id, 0x08, i2c.RECEIVER)
    c = i2c.read(id, 9)
    i2c.stop(id)
    return c
end
tmr.alarm(0, 1000, 1, function() read_reg()
print(c)
end )

В nodemcu получаю как и должно быть, helloяяяя  (так как принимаю 9 байт, а не 5)

но если так:

char text="hello""
Wire.write(text);

то получаю:

яяяяяяяя
яяяяяяяя
яяяяяяяя
яяяяяяяя
яяяяяяяя
 
 
Sergeyevd
Sergeyevd аватар
Offline
Зарегистрирован: 25.03.2014

Решил

//char*text="error";
//String data="123456";
Potentiometer = analogRead(0);
String data =  String(Potentiometer, DEC);
Wire.write(data.c_str());

 

liftoman
liftoman аватар
Offline
Зарегистрирован: 15.03.2017

Уважаемые форумчане, подскажите плз - Можно ли понизить (строго задать) скорость i2c, не меняя частоту камня? Пытаюсь соединить ардуину со старым устройством 80-х годов и по осциллу скорость i2c ардуины в разы выше чем у устройства. Ни оно ардуину не видит ни она его. Заранее Спасибо!

______________________________________________________________________________

Нашёл функцию Wire.setClock();, поставил Wire.setClock(1); - скорость понизилась, но этого недостаточно, хорошо бы ещё раза в 3 уменьшить.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

liftoman, напиши свою I2c медленную

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

liftoman пишет:

Нашёл функцию Wire.setClock();, поставил Wire.setClock(1); - скорость понизилась, но этого недостаточно, хорошо бы ещё раза в 3 уменьшить.

А не пробовали ставить 10000?

(hint: при числах менее 245 Вы получаете переполнение с потерей старших разрядов)