Arduino как I2C раб разговаривает с RPi - PullRequest
2 голосов
/ 28 марта 2019

Я использую Arduino в качестве ведомого устройства I2C для обработки некоторых ультразвуковых датчиков и отправляю данные об Raspberry. Код, работающий на Arduino:

void setup() {
  // initialize i2c as slave
  Serial.begin(9600);
  Wire.begin(SLAVE_ADDRESS);
  // define callbacks for i2c communication
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);

  // useless
}

void loop() {
    // useless
} 

// callback for received data
void receiveData(int byteCount) {
  int i = 0;
  while (Wire.available()) {
    number[i] = (char) Wire.read();
    i++;
  }
  number[i] = '\0';
  Serial.println(atoi(number));
  if(atoi(number) != 0) { caseN = atoi(number); }
}  

int SonarSensor(int trigPin,int echoPin)
{
    // uselesss
}

// callback for sending data
void sendData() {
  if(caseN == 1) { Wire.write(distance1);}
  else if(caseN == 2) { Wire.write(distance2);}
  else if(caseN == 3) { Wire.write(distance3);}
  else if(caseN == 4) { Wire.write(distance4);}
  else if(caseN == 5)
  {
    if(state == 0)
    {
      state = 1;
      digitalWrite(ledPin, HIGH);
    }
    else
    {
      state = 0;
      digitalWrite(ledPin, LOW);
    }
  }
  else { Wire.write(0); }
}

Я делаю первую версию "чата" с Python, и он работает очень хорошо:

import smbus
import time

bus = smbus.SMBus(1)


address = 0x04

def writeNumber(value):
    bus.write_byte(address, value)
    return -1

def readNumber():
    number = bus.read_byte_data(address, 1)
    return number

while True:
    data = raw_input("Enter the data to be sent : ")
    data_list = list(data)
    for i in data_list:
        writeNumber(int(ord(i)))
        time.sleep(.1)

    writeNumber(int(0x0A))

Я пытаюсь сделать то же самое в C, но это выглядит немного сложнее:

#include "i2c-dev.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <string.h>

int main() {
    const int adapter_nr = 1;
    char filename[20];
    snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
    const int file = open(filename, O_RDWR);
    if (file < 0) {
        printf("Unable to connect to Atmega, I2C plugged ? DC ok ?");
        exit(EXIT_FAILURE);
    }

    // Atmega address
    const int addr = 0x04;

    if(ioctl(file, I2C_SLAVE, addr) < 0) 
    {
        printf("Fail to reach Atmega");
        exit(EXIT_FAILURE);
    }

    const __u8 add = 5; // Ask to "distance 5"
    i2c_smbus_write_byte_data(file, 0x04, add); // What is the adress ?


    const __u8 reg = 0x0A;
    const __s32 result = i2c_smbus_read_byte_data(file, reg);
    if(result < 0) 
    {
        printf("Fail to reach Atmega reg");
        exit(EXIT_FAILURE);
    } 
    else 
    {
        printf("Distance %d cm \n", result);
    }

    close(file);

    return(EXIT_SUCCESS);
}

Как я уже упоминал в коде, я не знаю, какой регистрационный адрес имеет мой раб Arduino. Я вижу в терминале Arduino COM много 0 и только 0.

Надеюсь, вы поймете мою проблему. Спасибо.

Ответы [ 2 ]

0 голосов
/ 16 июля 2019

Вам необходимо знать правильный адрес подчиненного устройства I2C, который использует ваш Arduino.

К счастью, Raspberry Pi может обнаружить любое подключенное устройство I2C и показать вам их адрес, используя следующую команду:

sudo i2cdetect -y 1

или

sudo i2cdetect -y 0

Примечание: первыйКоманда работает для всех последних Raspberry Pi3 и Pi2 (модели A, B, B +) и Pi Zero.Вторая команда только в том случае, если вы используете старые модели.

Для получения дополнительной информации вы можете посмотреть здесь (Включить I2C) или здесь (Настройка I2C).Оба схожи, и вы можете просто перейти к нижней части, где они объясняют, как использовать вышеуказанную команду.

0 голосов
/ 28 марта 2019

Почему бы не определить адрес подчиненного устройства, чтобы вы точно знали, что это такое. Кроме того, это позволит вам установить другой адрес, если в будущем вы будете использовать более 1 arduino.

Запустите эту строку кода перед установкой на Arduino. Вы можете изменить адрес на любой другой, если он не используется другой системой в соединении I2C.

#define  SLAVE_ADDRESS           0x29  //slave address,any number from 0x01 to 0x7F

Вот Учебник , обсуждающий использование Arduino в качестве раба

...