当前位置: 首页 > 知识库问答 >
问题:

树莓通信

颛孙轩昂
2023-03-14

我试图建立RaspberryPI B(主)和Arduino Uno(从)之间的全双工SPI通信。

主机侧代码:

#include<sys/ioctl.h>
#include<linux/spi/spidev.h>
#include<fcntl.h>
#include<cstring>
#include<iostream>
#include<unistd.h>

using namespace std;

int fd;
unsigned int val;
unsigned int result;

int spiTxRx(unsigned int txDat);

int main(void){
    fd = open("/dev/spidev0.0",O_RDWR);
    unsigned int speed = 1000000;
    ioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,&speed);
    int ret = 0;
    while(ret <=5){
        ret++;      
        cout<<"input:";
        cin>>val;
        result=spiTxRx(val);
        cout<<result<<endl;
        usleep(10);
    }
    close(fd);
}

int spiTxRx(unsigned int txDat){
    unsigned char rxDat;
    struct spi_ioc_transfer spi;
    memset(&spi,0,sizeof(spi));

    spi.tx_buf = (unsigned long) &txDat;
    spi.rx_buf = (unsigned long) &rxDat;
    spi.len = 1;
    ioctl (fd, SPI_IOC_MESSAGE(1), &spi);

    return rxDat;
}

从机端码

byte clr;
int x = 0;
int readInput;
void setup (void){

  Serial.begin (9600);

  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);
  // turn on SPI in slave mode. SPCR determine Arduino SPI settings
  SPCR |= _BV(SPE);
  clr = SPSR;
  clr = SPDR;  
  delay(10);
}

void loop (void){

  if ((SPSR & _BV(SPIF)) !=0){ //if byte has been received 
      readInput = SPDR;
      if (readInput == 7){
        x++;
        SPDR = x;
      }
  }
} 

所以,简单地说,我希望如果我向throw MOSI行发送一个输入(在本例中为7),Arduino会增加var x,并用x的值回复我。

但是我的输出看起来像这样:

init: x = 0;
(1st input)
Master send 7, Slave add x (so, x=1) and send me back unusual value
(2nd input)
Master send 7, Slave add x (x=2) and send me back 1 (previous value of x)
(3rd input)
Master send 7, slave add x (x=3) and send me back 2 (previous value of x)
(Nth input)
Master send 7, slave add x (x = k) and send me back k-1

换句话说,如果我发送7,Arduino增量x,则在while行中循环并返回相同的输入值。如果我再次发送一个值,Arduino将以正确的响应回复我。

有人能帮我吗?

共有1个答案

孟昊空
2023-03-14

我找到了解决我问题的办法。

发送和接收的消息之间的差异是由Arduino SPI数据寄存器(SPDR)引起的。SPDR由8位移位寄存器和8位接收缓冲器定义。当主机发送一个字节时,它被存储在接收缓冲器中,移位寄存器中的字节被发送回主机。因此,我们需要发送另一条消息以获得正确的回复。

 类似资料:
  • 我想用Python在我的树莓派和Arduino之间进行交流。到目前为止,Arduino成功地向Raspberry Pi发送了一条串行消息,并使用Python中的ser.readline()函数读取消息。但是当我想用IF语句闪烁连接到树莓派的led时,它就不起作用了 这是我的Arduino代码: 这是在我的Raspberry Pi上运行的Python代码: 这是我在终端中看到的:终端图像 我已经找了

  • 我已经设法从我的arduino(Uno)到我的Raspberry Pi 3,通过串口进行了写操作。 如果我在pi端使用相同的python脚本,在arduino端使用相同的Sketch,但使用Teensy,我无法从Arduino读取任何输出。 根据串行通信,arduino Uno和teensy之间有什么区别吗? Arduino草图: 我的Pi上的Python脚本: 此代码适用于我的Arduino U

  • 我正在尝试通过串行通信来溜冰树莓皮和阿杜伊诺。我的目的是用户控制Raspberry Pi的Arduino LED。 我找到了一个串行通信的示例代码,它每2秒自动向Arduino发送一个字符串。但我想做两件事: 更改发送的值,而不是Hello。 用户可以随时发送值,而不是自动发送。 你能帮我吗?我不擅长节点。js。

  • 我试图让一个树莓派流到一个crtmpserver,并从那里到一个网页与JWplayer。 我可以用这个成功地将视频发送到crtmpserver: raspivid-t 0-w 960-h 540-fps 25-b 500000-vf-o-|ffmpeg-i--acodec aac-ac 2-严格实验-ab160k-vcodec libx264-预设慢速配置文件:v基线级别30-maxrate 10

  • Raspbian All-in-One 终端中登陆树莓派 停止正在运行的 Home Assistant 服务:sudo systemctl stop home-assistant.service 切换至 homeassistant 用户:sudo su -s /bin/bash homeassistant 切换至虚拟环境:source /srv/homeassistant/homeassistan

  • Linux 是使用最广泛的开源操作系统,而树莓派是新兴的开放硬件平台。两者相互结合,能激起很多有趣的火花。这一部分中,我将介绍树莓派的基本使用方法。