简体   繁体   English

如何使用python和i2c从Rpi读取连接到arduino的pot

[英]How to read pot connected to arduino from Rpi using python and i2c

I'm trying to write analog readings from a potentiometer connected to an Arduino and read those values using I2C from python on an RPi. 我正在尝试从连接到Arduino的电位计中写入模拟读数,并使用RPi上的python使用I2C读取这些值。 I have gotten Arduino to Arduino to work using the code below. 我已经将Arduino转到Arduino,以使用下面的代码工作。 What I cannot seem to do correctly is write two bytes from the Arduino and read two bytes from the RPi. 我似乎无法正确执行的操作是从Arduino写入两个字节,并从RPi读取两个字节。

Arduino Master code: 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 Slave code: 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

}

The closest I have gotten reading from an RPi is: 我从RPi读取的最接近的是:

RPi Master code: 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)   

Arduino slave code: Arduino从属代码:

#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);
  }

I seem to be able to get 0-255, but after 255 the value starts again. 我似乎能够获得0-255,但在255之后,该值再次开始。 No doubt there is a more precise way to say I am only getting one byte of data or something along those lines. 毫无疑问,有一种更精确的方法可以说我仅沿这些行获取一个字节的数据或其他内容。 Ultimately I want to have 2 pots connected to the Arduino feeding readings into the RPi. 最终,我想将2个电位器连接到Arduino,将读数馈送到RPi。

On Arduino, analogRead returns an int value in the range 0-1023. 在Arduino上, analogRead返回的int值在0-1023范围内。 On this hardware, an int is two bytes. 在此硬件上,一个int是两个字节。 However, the form of Wire.write that you use in the sendData function only writes a single byte, discarding part of the integer. 然而,形式Wire.write您在使用sendData功能只写一个字节,丢弃的整数部分。

There are basically two solutions. 基本上有两种解决方案。

The simplest would be to take the return value of analogRead , divide it by 4 and cast it into a byte. 最简单的方法是取analogRead的返回值,将其除以4,然后将其转换为一个字节。 Send that out with Wire.write . 使用Wire.write发送出去。 This does reduce the resolution of the value of the pot-meter, but is it a very simple solution. 这确实降低了电位计值的分辨率,但这是一个非常简单的解决方案。

The other was is to send an integer value over the wire. 另一个是通过电线发送一个整数值。 Since you're reading bytes on the RPi, you cannot know if you are reading the first or second byte of an integer. 由于您正在读取RPi上的字节,因此您不知道要读取整数的第一个还是第二个字节。 So you would probably have to use a signal to indicate the start of a two-byte sequence. 因此,您可能必须使用信号来指示两个字节序列的开始。 You would also have to take the endian-ness of both platform into account. 您还必须考虑两个平台的字节序。 All in all, this is much more complicated. 总而言之,这要复杂得多。

Thanks for the feedback. 感谢您的反馈。 It helped me think through this a bit more and do more digging. 它帮助我进行了更多思考,并进行了更多挖掘。 This is what I have working. 这就是我的工作。

Arduino side for writing: 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 side for reading: 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)

As you can see I am reading 2 pots, converting the output to 0-255, writing to the I2C bus and then reading the 2 bytes on the RPi side. 如您所见,我正在读取2个电位器,将输出转换为0-255,写入I2C总线,然后在RPi侧读取2个字节。 I did have to change the Arduino delay value during testing because I was getting the error "IOError: [Errno 5] Input/output error" after a few minutes. 我确实必须在测试期间更改Arduino延迟值,因为几分钟后出现错误“ IOError:[Errno 5]输入/输出错误”。 Now maybe I will go back and write 2 bytes per pot and read 4 bytes so I don't lose and resolution. 现在也许我会回去为每个锅写入2个字节并读取4个字节,这样我就不会丢失和解析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何通过I2C使用Raspberry pi从Arduino读取数据 - How to Read Data from Arduino with Raspberry pi via I2C 使用I2C从arduino上的模拟引脚读取值并将其发送到raspberry pi。 它返回奇怪的数字,如122或255 - Using I2C to read value from analog pin on arduino and sending it to raspberry pi. It returns weird numbers like 122 or 255 如何使用 python I2C TCA9548A 从多路复用器读取 - How to read from multiplexer with python I2C TCA9548A 如何使用Python在Raspberry Pi上列出I2C地址? - How to list I2C address on Raspberry Pi using Python? 使用 i2c 和 Python 中断 - Interrupts using i2c and Python 我如何使用连接到 Arduino UNO 的 Arduino 超声波传感器来使用 Pyfirmata 或 Python 通常测量距离? - How can I use an Arduino Ultrasonic Sensor connected to an Arduino UNO to measure distance using Pyfirmata or Python Generally? 我可以使用Python(带有pyfirmata)从连接到Arduino的陀螺仪读取和使用数据吗? - Can I use Python (with pyfirmata) to read and use data from a gyroscope connected to an Arduino? i2c LCD 连接到互联网 - i2c LCD connected to the internet 在处理来自主设备的请求时,如何从从设备 I2C 读取一个字节? - How do I read a byte from a Slave I2C Device while handling a request from the Master? 使用I2c协议从Raspberry pi向Arduino发送2Dimensional Listarray - send 2Dimensional Listarray From Raspberry pi to the Arduino with I2c protocol
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM