Используйте Arduino Mega в качестве I2C Slave с RPi3 - PullRequest
0 голосов
/ 17 февраля 2019

Я пытаюсь использовать Arduino Mega 2560 для расширения входов / выходов RPi3 с ШИМ и аналоговыми входами.Фактически я вообще не использую выводы GPi RPi3, так как сложно поддерживать два напряжения для входов 3,3 и 5 В.

В основном я пытаюсь:

    1. отправьте массив из RPi3 для установки выходов в Arduino и
  • отправка массива из Arduino в RPi3 с указанием статуса входов.

Некоторые значения в массиве могут достигать 10000.

Iсмогли достичь вышеуказанного числа 1 без значений выше 255.

Код Python

bus = smbus.SMBus(1)
address = 0x06

def writeNumber(value):
    bus.write_i2c_block_data(address, 1, [5,0,1,255, 6]) #dummy array as of now. This can go upto 50 values
    return -1


def readNumber():
    # number = bus.read_byte(address)
    data_received_from_Arduino = bus.read_byte(address)
    for i in data_received_from_Arduino:
       print(i)

    return number

while i1:
    writeNumber(1)
    readNumber()

Код Arduino

#include <Wire.h>

#define SLAVE_ADDRESS 0x06
int number[50] = {0};
int inputs[100] = {0};

int state = 0;
int p=0; 

void setup() {
pinMode(13, OUTPUT);

Serial.begin(9600); // start serial for output
// initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);

// define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(sendData);

Serial.println('Ready!');
}

void loop() {

//delay(1);
}

// callback for received data
void receiveData(int byteCount){
  Serial.println(byteCount);
  int p=0;
  while(Wire.available()) {
      number[p] = Wire.read();
      p++;
  }
    for(int k=0; k < 5; k++)  { 
    Serial.print( k);
    Serial.print( ":");
    Serial.println(number[k]); 
  }

}


// callback for sending data
void sendData(){  
  for(int k=0; k < 56;k++) {
  inputs[k] = digitalRead(k);
  Serial.print( k ); Serial.print(" : "); Serial.print(inputs[k]); 
  Serial.println(digitalRead(k));
  }
  Wire.write( inputs,56);
}

Может кто-нибудь руководить?Кто-нибудь знает образец Git для достижения вышеуказанного.Я могу создать его для своего приложения, даже если образец для небольшого массива.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Я экспериментировал с экспериментированием с отправкой и получением четырех 16-битных чисел от Raspberry Pi на Arduino через I2C и получил следующую работу.

Помните, что я не специалист по SMBus или I2C, и я не знаю, есть ли более простые способы сделать это.Я рад отозвать свой ответ, если кто-нибудь знает лучше!

Вот код Raspberry Pi, он просто отправляет четыре 16-битных числа 100, 200, 1000, 10000 и затем читает их обратно.

#!/usr/bin/env python3
from smbus import SMBus
from time import sleep

bus = SMBus(1)
address = 0x08

def split(v):
    """Split 16-bit value into low and high bytes"""
    lobyte = v & 0xff
    hibyte = (v >> 8) & 0xff
    return lobyte, hibyte

def join(lo,hi):
    return lo | (hi << 8)

def Transmit():
    """Send 100, 200, 1000, 10000 on I2C"""
    a,b = split(100)
    c,d = split(200)
    e,f = split(1000)
    g,h = split(10000)
    bus.write_i2c_block_data(address, a,[b, c, d, e, f, g, h])

def Receive():
    block = bus.read_i2c_block_data(address, 0)
    i = join(block[0],block[1])
    j = join(block[2],block[3])
    k = join(block[4],block[5])
    l = join(block[6],block[7])
    print("{} {} {} {}".format(i,j,k,l))

Transmit()
sleep(1)
Receive()

На стороне Arduino я просто читаю четыре 16-битных числа из I2C, сохраняю их в массив и увеличиваю каждое.Когда приходит запрос на чтение, я отправляю обратно четыре приращенных числа:

#include <Wire.h>

const int address= 8;

#define N 4

// Last four 16-bit values we received
int16_t values[N];

void setup() {
  Serial.begin(9600);
  Serial.print("Starting on i2c address:");
  Serial.println(address,DEC);
  Wire.begin(address);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
}

void loop() {
  delay(100);
}

// callback for when data are received
void receiveEvent(int nBytes) {
  Serial.print("Received: ");
  Serial.println(nBytes);

  if(nBytes != 2 *N){
     Serial.print("I was expecting 8 bytes");

     return;
  }
  unsigned char *p = (unsigned char *)&values;
  for(int i=0;i<2*N;i++){
    *p++ = Wire.read();
  }
  // Increment all the values we received
  for(int i=0;i<N;i++){
    values[i]++;
  }

}

// Callback for when data are read
void requestEvent() {

  Serial.println("Data requested");
  // Send back
 Wire.write((const uint8_t*)&values, N*2);
}

Когда я запускаю код Python на Raspberry Pi, я получаю:

./i2c.py 
101 201 1001 10001
0 голосов
/ 18 февраля 2019

Самый простой способ связи с Raspberry Pi и Arduino - использовать последовательный протокол.Я использовал это все время.

В Python есть модуль для последовательной связи pyserial.

https://www.electronicwings.com/raspberry-pi/raspberry-pi-uart-communication-using-python-and-c

...