2017-02-04 2 views
0

Я пытаюсь записать аналоговые показания с потенциометра, подключенного к Arduino, и прочитать эти значения с использованием I2C из python на RPi. Я получил Arduino для Arduino, чтобы работать, используя приведенный ниже код. То, что я не могу сделать правильно, это записать два байта из Arduino и прочитать два байта из RPi.Как читать банк, подключенный к arduino из Rpi с использованием python и i2c

Arduino Мастер код:

#include <Wire.h> 
#define SLAVE_ADDRESS 0x2a 

void setup() 
{ 
    Wire.begin();  // join i2c bus (address optional for master) 
    Serial.begin(9600); // start serial for output 
} 

void loop() 
{ 
    Wire.requestFrom(SLAVE_ADDRESS, 2); // request 2 bytes from slave 
    byte loByte; 
    byte hiByte; 
    if(Wire.available() >= 2) // slave may send less than requested 
    { 
    hiByte = Wire.read(); 
    loByte = Wire.read(); 
    } 
    int val = (hiByte << 8) + loByte; 
    Serial.print("read value:"); 
    Serial.println(val); 
    delay(500); 
} 

Arduino Подчиненный код:

#include <Wire.h> 
#include <stdlib.h> 
#define SLAVE_ADDRESS 0x2a 
//#define potPin 0 
int readVal; 
byte hi; 
byte lo; 


void setup() 
{ 
// Communication I2C 
    Wire.begin(SLAVE_ADDRESS);     
    Wire.onRequest(requestEvent); // register event 

    Serial.begin(9600); 
} 

void loop() 
{ 

readVal = analogRead(A2); 
Serial.println(readVal); 
hi = highByte(readVal); 
lo = lowByte(readVal); 
} 

void requestEvent() 
{ 

byte buf [2]; 

    buf [0] = hi; 
    buf [1] = lo; 

    Wire.write(buf, sizeof buf); // send 2-byte response 

} 

Ближайший я получил чтение из ИРЦ:

RPi Мастер-код:

import smbus 
import time 
bus = smbus.SMBus(1) 
address = 0x2a 

while True: 
    bus.write_byte(address, 1) 
    number = bus.read_byte(address) 
    print(number) 
    time.sleep(1) 

Ard uino раб. код:

#include <Wire.h> 
#define SLAVE_ADDRESS 0x2a 
int number = 0; 
void setup() { 
    Wire.begin(SLAVE_ADDRESS); 
    Wire.onReceive(receiveData); 
    Wire.onRequest(sendData); 
    } 
void loop() { 
    } 
void receiveData(int byteCount){ 
    while(Wire.available()) { 
    number = Wire.read(); 
    number = analogRead(A2); 
    } 
} 
void sendData(){ 
    Wire.write(number); 
    } 

Кажется, что я могу получить 0-255, но после 255 значение начинается снова. Несомненно, есть более точный способ сказать, что я получаю только один байт данных или что-то в этом роде. В конечном счете, я хочу иметь 2 горшка, подключенных к показаниям подачи Ардуино в RPi.

+0

прощайте глупый вопрос, но в чем смысл того, чтобы ведомое устройство спланировало * int * в двух байтах, только для отправки обоих из них через * SPI *? не будет ли это работать, просто отправив * int *? –

ответ

1

На Arduino, analogRead возвращается значение int в диапазоне 0-1023. На этом оборудовании int - это два байта. Однако форма Wire.write, которую вы используете в функции sendData, записывает только байт, отбрасывая часть целого числа.

Существует в основном два решения.

Простейшим было бы принять возвращаемое значение analogRead, разделить его на 4 и бросить в байт. Отправьте это с помощью Wire.write. Это уменьшает разрешение значения счетчика, но это очень простое решение.

Другое должно было отправить целое значение по проводу. Поскольку вы читаете байты в RPi, вы не можете знать, читаете ли вы первый или второй байт целого числа. Поэтому вам, вероятно, придется использовать сигнал для указания начала двухбайтовой последовательности. Вы также должны принять во внимание концепцию обеих платформ. В общем, это намного сложнее.

0

Спасибо за отзыв. Это помогло мне продумать это немного больше и сделать больше копания. Это то, что я работаю.

Arduino сторона для записи:

#include <Wire.h> 
#define SLAVE_ADDRESS 0x2a 
#define pot1pin A2 
#define pot2pin A3 

byte pot1byte; 
byte pot2byte; 
void setup() 
{ 
    Wire.begin(SLAVE_ADDRESS); 
    Wire.onRequest(requestEvent); 
} 

void loop() { 
    int pot1int = analogRead(pot1pin); 
    int pot2int = analogRead(pot2pin); 
    pot1byte = map(pot1int, 0, 1024, 0, 255); 
    pot2byte = map(pot2int, 0, 1024, 0, 255); 
} 

void requestEvent() 
{ 
    Wire.write(pot1byte); 
    delay(30); 
    Wire.write(pot2byte); 
} 

RPi сторона для чтения:

import smbus 
bus = smbus.SMBus(1) 
address = 0x2a 
while (1): 
    block = bus.read_i2c_block_data(address, 0, 2) # Returned value is a list of 2 bytes 
    print(block) 

Как вы можете видеть, что я читаю 2 кастрюли, преобразования выходного сигнала в диапазоне 0-255, запись в I2C и затем чтение 2 байтов на стороне RPi. Мне пришлось изменить значение задержки Arduino во время тестирования, потому что через несколько минут я получил ошибку «IOError: [Errno 5] Ошибка ввода/вывода». Теперь, может быть, я вернусь и напишу 2 байта на банк и прочитаю 4 байта, чтобы не потерять и не разрешить.

Смежные вопросы