SPI with Intan RHS2116

I'm trying to use Arduino to control IC with SPI. This is my first time using Arduino, so I just tried SPI library.

Thanks to many other examples, now I'm able to send and receive 32 bits data which is necessary to control IC named RHS2116.

However, there are some questions because of the method I'm using.

Right now, I'm using modified method came from Tom Carpenter's code at "SPI read write for 32bits data - Microcontrollers - Arduino Forum".

The IC is on delivery now, so I'm using additional Arduino as slave. I attached codes.

It seems that SPI.transfer() reads slave's data first and then sends message according to the result of Serial.print() function.

I think I can make the replies in proper order by shifting using SPI.transfer(msg.bit8[0]) at the front and SPI.transfer(0).

The questions is

the shifting will also work well for RHS2116?

or, in other words, do additional 8 bits after 32 bits affect the operation of IC?

Sorry for my bad English :sob:

SPI_step2_master.ino (1.04 KB)

SPI_step2_slave.ino (483 Bytes)

RHS2116.h (917 Bytes)

How did you connect the two Arduinos? Post a wiring diagram.

If I understood you correctly you're trying to emulate the RHS2116 with a second Arduino. As the slave code is incomplete (it won't compile) I don't know what exactly your problem is.

One problem you probably might run into is that the SS pin has to be put in output mode, this is missing in your code (master).
Remove the delayMicroseconds() call, it's not necessary and simply slows down your sketch.

pylon:
How did you connect the two Arduinos? Post a wiring diagram.

If I understood you correctly you're trying to emulate the RHS2116 with a second Arduino. As the slave code is incomplete (it won't compile) I don't know what exactly your problem is.

One problem you probably might run into is that the SS pin has to be put in output mode, this is missing in your code (master).
Remove the delayMicroseconds() call, it's not necessary and simply slows down your sketch.

Sorry for uploading wrong code :sweat_smile: The working version of slave is this,

#include <SPI.h>

byte num;

void setup()
{
	pinMode(MISO, OUTPUT);
	pinMode(MOSI, INPUT);
	pinMode(SCK, INPUT);
	pinMode(SS, INPUT);

	SPI.setClockDivider(SPI_CLOCK_DIV16);

  // Set SPI Control Register to make arduino as slave.
	SPCR |= _BV(SPE);
	SPCR &= ~_BV(MSTR);
	SPCR |= _BV(SPIE);
	Serial.begin(9600);

  num = 0;
}

ISR(SPI_STC_vect) {
  switch (SPDR){
    case B11110000 :
      SPDR = B10100000;
      break;
    case B00001111 :
      SPDR = B00001010;
      break;
    default :
      SPDR = num;
  }

}

void loop()
{
  num += 5;
  if (num>255) {
    num = 0;
  }
	delay(1000);
}

SPI.h defined pin number of MOSI, MISO, SCK, SS and I wired like this

My problem is return value of SPI.transfer() is shifted. For example, if Master sends data by

  return[0] = SPI.transfer(data[0]);
  return[1] = SPI.transfer(data[1]);
  return[2] = SPI.transfer(data[2]);
  return[3] = SPI.transfer(data[3]);

Expected value of return[] is

[ response for data[0], response for data[1], response for data[2], response for data[3] ]

but what I found is

[ response for data[3'], response for data[0], response for data[1], response for data[2] ]

where data[3'] is something sent before data[0].

Meanwhile, delayMicroseconds() call was necessary as slave need time to read SPDR. The codes were not worked when the delay not existed.

I get the impression that you think of SPI as a faster version of standard (UART) serial interface. It isn't.

if you call

byte rv = SPI.transfer(cmd);

the rv byte is not the response of the slave to the cmd byte sent but it's the value that is received at the same time as the cmd byte is sent. So bit 7 of cmd is sent while bit 7 of rv is received and so on. That's why you need the delayMicroseconds() call (although 5µs would be probably enough to react on the received value and fill the data register).

pylon:
I get the impression that you think of SPI as a faster version of standard (UART) serial interface. It isn't.

if you call

byte rv = SPI.transfer(cmd);

the rv byte is not the response of the slave to the cmd byte sent but it's the value that is received at the same time as the cmd byte is sent. So bit 7 of cmd is sent while bit 7 of rv is received and so on. That's why you need the delayMicroseconds() call (although 5µs would be probably enough to react on the received value and fill the data register).

Then, how can I get 32 bits data of RHS2116 with Arduino Uno? Its register is only 8 bits...

Then, how can I get 32 bits data of RHS2116 with Arduino Uno? Its register is only 8 bits...

By calling SPI.tansfer() four times in a sequence. You might have to send the command byte first, so you end with 5 calls of SPI.transfer() for one 32bit value from the device.

pylon:
By calling SPI.tansfer() four times in a sequence. You might have to send the command byte first, so you end with 5 calls of SPI.transfer() for one 32bit value from the device.

I'm trying inconvenient method now, but I'll try it soon. Thanks!

Long time no see. I was debugging circuit as the IC arrived.

Here I attach arduino code used for testing the chip operation.

It is not fancy, but maybe useful to someone... I hope...

Arduino_SPI.ino (1.17 KB)