ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

spi_ioc_message

asked 2018-02-20 01:22:45 -0500

NRottmann gravatar image

Hi,

I have a problem sending a SPI message with ROS using ioctl. In general, i can connect to the SPI port using ROS and I am able to send one byte at a time. The problem is, when I am trying to send more then one byte (length > 1) with the ROS node, I get a error from the ioctl. The exact same program (except the ROS part) running as a normal C-program works fine even by sending more then one bytes at a time. Has anyone any idea how to fix this issue in ROS?

Here is the code i use:

void SpiWriteRead(int length, const char *device, uint8_t *msg)
{
// Initialize parameters
uint8_t mode = 0;
uint8_t bits = 8;
uint32_t speed = 32000;

// Open device
int fd = open(device, O_RDWR);
if (fd < 0) { 
    ROS_ERROR("Can't open device"); 
    exit(1);
}
// SPI mode
int ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret < 0) { 
    ROS_ERROR("Can't set spi mode");
    exit(1);
}
// Bits per word
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret < 0) { 
    ROS_ERROR("Can't set bits per word");
    exit(1);
}
// Max speed, 1ms per 32bit command --> 32kHz
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret < 0) { 
    ROS_ERROR("Can't set max speed"); 
    exit(1);
}

unsigned char tx[256];
unsigned char rx[256];
for (int i = 0; i < length; i++) {
    tx[i] = 0x00;
    rx[i] = 0x00;
}
struct spi_ioc_transfer tr[256];
for (int i = 0; i < length; i++) {
    tr[i].tx_buf = (unsigned long)&tx[i];
    tr[i].rx_buf = (unsigned long)&rx[i];
    tr[i].len = 1;
    tr[i].delay_usecs = 1000;
    tr[i].speed_hz = speed;
    tr[i].bits_per_word = 8;
}
ret = ioctl(fd, SPI_IOC_MESSAGE(length), tr);
if (ret < 1)
{
    ROS_ERROR("Error read or write - ioctl");
    exit(1);
}
// Close device
close(fd);
}


int main(int argc, char **argv)
{
ros::init(argc, argv, "spiInterface");
ros::NodeHandle nh;
ros::Duration duration(1. / 24.);
// Length of byte stream
int length = 2;
sleep(2);
while (ros::ok())
{
  unsigned char rightMsg[] = { 0x00, 0x77, 0x00, 0x77, 0x00, 0x77, 0x00 };
  const char *dev0 = "/dev/spidev1.0";
  SpiWriteRead(length, dev0, rightMsg);
  duration.sleep();
  }
  return 0;
 }
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2018-02-20 02:38:58 -0500

NRottmann gravatar image

Funny thing, today with a bit luck I solved the problem by myself. The

struct spi_ioc_transfer tr[256];

has to be defined as a global variable. Then we can send as many bytes as we require.

Best, Nils

edit flag offensive delete link more

Question Tools

Stats

Asked: 2018-02-20 01:22:45 -0500

Seen: 2,336 times

Last updated: Feb 20 '18