Raspberry Pi 和 I2C in c++ with wiringPi for PCF8591
Raspberry Pi and I2C in c++ with wiringPi for PCF8591
我正在尝试了解用于控制 PCF8591 D/A 转换器的 I2C 总线以及我 Raspberry Pi B+ 上的 wiringPi C 库。
我写了一个测试代码(用 c++),工作正常,但我不知道我做的是否正确。程序每 0.5 秒读取并显示 4 个模拟输入值,并将输出相应地设置为 4 个输入引脚的平均值。
#include <iostream>
#include <wiringPi.h>
#include <wiringPiI2C.h>
using namespace std;
int readInput(int fd, int reg)
{
wiringPiI2CReadReg8(fd, reg);
return wiringPiI2CReadReg8(fd, reg);
}
int main()
{
wiringPiSetupGpio();
int dacModule = wiringPiI2CSetup(0x48);
if (dacModule < 0)
{
cout << "I2C Setup Error" << endl;
return 0;
}
int i;
int A[4] = {0, 0, 0, 0};
int A_Reg[4] = {0x40, 0x41, 0x42, 0x43};
while (1)
{
for (i=0;i<4;i++) A[i] = readInput(dacModule, A_Reg[i]);
wiringPiI2CWriteReg8(dacModule, 0x40, (A[0]+A[1]+A[2]+A[3])/4);
cout << endl;
for (i=0;i<4;i++) cout << i << " : " << A[i] << endl;
delay(500);
}
return 0;
}
我的问题是:
- 我注意到我需要调用 wiringPiI2CReadReg8 函数两次才能读取正确的输入值,为什么? (如果我不这样做,函数 return 之前的输入值)。
- 我读到 wiringPi 库中有一个专门为 PCF8591 制作的特殊模块 (This one),这两种方法(特殊库与通用 I2C 库)之间是否存在任何性能差异?
非常感谢您的帮助/反馈。
回答您的第一个问题:是的,这很正常。如果您查看数据表(可以找到 here),您将在第 8 页的图 8 中看到读取操作正在触发新的转换,但会输出 previous[ 的结果=17=]转换。所以,如果想知道current的转换,通过"forcing"两个连续的读操作一个接一个,确实需要读出2个字节。
下一页第二段也再次提到了它。
关于你的第二个问题,我还没有使用过那个库。但源代码是免费提供的,因此您可以检查并比较您的 code/method 与您在其中找到的内容。
我用C语言为PCF8591写了如下代码。
这条线很好用。
#include <wiringPi.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
/*
cc -o test1 test1.c -lwiringPi
*/
int main (void)
{
int fd;
int i;
int a2dChannel = 0; // analog channel
int a2dVal;
float a2dVol;
float Vref = 3.3;
if ((fd = wiringPiI2CSetup(0x48)) < 0) {
printf("wiringPiI2CSetup failed:\n");
}
for(i=0;i<20;i++) {
wiringPiI2CWrite(fd,0x40 | a2dChannel);
a2dVal = wiringPiI2CRead(fd); // Previously byte
a2dVal = wiringPiI2CRead(fd);
a2dVol = a2dVal * Vref / 255;
printf("a2dVal=%d\n",a2dVal);
printf("a2dVol=%f[V]\n",a2dVol);
sleep(1);
}
}
你可以使用 analogRead()。
#include <wiringPi.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pcf8591.h>
#define PINBASE 100
/*
cc -o test2 test2.c -lwiringPi
*/
int main (void)
{
int i;
int a2dChannel = 0; // analog channel
int a2dVal;
float a2dVol;
float Vref = 3.3;
if (pcf8591Setup(PINBASE, 0x48) < 0)
{
printf("pcf8591Setup failed:\n");
}
for(i=0;i<20;i++) {
a2dVal = analogRead(PINBASE + a2dChannel);
a2dVol = a2dVal * Vref / 255;
printf("a2dVal=%d\n",a2dVal);
printf("a2dVol=%f[V]\n",a2dVol);
sleep(1);
}
}
我正在尝试了解用于控制 PCF8591 D/A 转换器的 I2C 总线以及我 Raspberry Pi B+ 上的 wiringPi C 库。
我写了一个测试代码(用 c++),工作正常,但我不知道我做的是否正确。程序每 0.5 秒读取并显示 4 个模拟输入值,并将输出相应地设置为 4 个输入引脚的平均值。
#include <iostream>
#include <wiringPi.h>
#include <wiringPiI2C.h>
using namespace std;
int readInput(int fd, int reg)
{
wiringPiI2CReadReg8(fd, reg);
return wiringPiI2CReadReg8(fd, reg);
}
int main()
{
wiringPiSetupGpio();
int dacModule = wiringPiI2CSetup(0x48);
if (dacModule < 0)
{
cout << "I2C Setup Error" << endl;
return 0;
}
int i;
int A[4] = {0, 0, 0, 0};
int A_Reg[4] = {0x40, 0x41, 0x42, 0x43};
while (1)
{
for (i=0;i<4;i++) A[i] = readInput(dacModule, A_Reg[i]);
wiringPiI2CWriteReg8(dacModule, 0x40, (A[0]+A[1]+A[2]+A[3])/4);
cout << endl;
for (i=0;i<4;i++) cout << i << " : " << A[i] << endl;
delay(500);
}
return 0;
}
我的问题是:
- 我注意到我需要调用 wiringPiI2CReadReg8 函数两次才能读取正确的输入值,为什么? (如果我不这样做,函数 return 之前的输入值)。
- 我读到 wiringPi 库中有一个专门为 PCF8591 制作的特殊模块 (This one),这两种方法(特殊库与通用 I2C 库)之间是否存在任何性能差异?
非常感谢您的帮助/反馈。
回答您的第一个问题:是的,这很正常。如果您查看数据表(可以找到 here),您将在第 8 页的图 8 中看到读取操作正在触发新的转换,但会输出 previous[ 的结果=17=]转换。所以,如果想知道current的转换,通过"forcing"两个连续的读操作一个接一个,确实需要读出2个字节。 下一页第二段也再次提到了它。
关于你的第二个问题,我还没有使用过那个库。但源代码是免费提供的,因此您可以检查并比较您的 code/method 与您在其中找到的内容。
我用C语言为PCF8591写了如下代码。 这条线很好用。
#include <wiringPi.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
/*
cc -o test1 test1.c -lwiringPi
*/
int main (void)
{
int fd;
int i;
int a2dChannel = 0; // analog channel
int a2dVal;
float a2dVol;
float Vref = 3.3;
if ((fd = wiringPiI2CSetup(0x48)) < 0) {
printf("wiringPiI2CSetup failed:\n");
}
for(i=0;i<20;i++) {
wiringPiI2CWrite(fd,0x40 | a2dChannel);
a2dVal = wiringPiI2CRead(fd); // Previously byte
a2dVal = wiringPiI2CRead(fd);
a2dVol = a2dVal * Vref / 255;
printf("a2dVal=%d\n",a2dVal);
printf("a2dVol=%f[V]\n",a2dVol);
sleep(1);
}
}
你可以使用 analogRead()。
#include <wiringPi.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pcf8591.h>
#define PINBASE 100
/*
cc -o test2 test2.c -lwiringPi
*/
int main (void)
{
int i;
int a2dChannel = 0; // analog channel
int a2dVal;
float a2dVol;
float Vref = 3.3;
if (pcf8591Setup(PINBASE, 0x48) < 0)
{
printf("pcf8591Setup failed:\n");
}
for(i=0;i<20;i++) {
a2dVal = analogRead(PINBASE + a2dChannel);
a2dVol = a2dVal * Vref / 255;
printf("a2dVal=%d\n",a2dVal);
printf("a2dVol=%f[V]\n",a2dVol);
sleep(1);
}
}