Arduino Pro Mini with magnetic encoder

Hey guys,

I have a problem with getting correct data of the “AETA-6600-T16” magnetic encoder from “Avago Technologies”, which uses SSI communication. I want to read the data with the intern SPI from Arduino Pro Mini (Atmega 328p 3V3 8MHz).
Magnetic encoder attitude:
16bit mode, absolute mode (this means it uses SSI).
The problem is, that I have a 200ns delay between “data” and “clock”, so that I get wrong values.
First bit is always “1” and last bit is missing.

For example:
The correct value is: 0111
The value which is read is: 1010 or 1011

I have tried different clock speeds, but without success.

Hope someone can help me with this.

Here is the code and pictures of the oscilloscope:

#include <SPI.h>

uint16_t raw_response = 0;
unsigned int result = 0;
uint16_t finalresult = 0;

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
SPI.begin();
digitalWrite(SS, HIGH);
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
}

void loop() {

digitalWrite(SS, LOW); //start communication
delayMicroseconds(1);

raw_response = SPI.transfer16(0xFF); // shift in the data

delayMicroseconds(1);
digitalWrite(SS, HIGH); //end communication
//raw_response = (raw_response << 1) | 0;
Serial.println(raw_response, BIN);
Serial.println(raw_response, DEC);
delay(1000);

}

Are you certain that the SPI mode is MODE3? There are three other possibilities.

Study the SSI timing diagram in the data sheet very carefully.

I do not see how SPI can be correct for the first and last byte from this device, as the data lines (MOSI, MISO) are changed before the clock triggers the reading. http://www.gammon.com.au/spi

Most of the solutions for these SSI devices which have appeared on this forum, involve bit banging the clock with digitalWrite() and assembling the digitalRead() values which are in response.

Thanks for the quick answers.

I'm sure that MODE3 is correct.

I tried digitalWrite and digitalRead too, there is the problem "speed". The clock via digitalWrite is not fast enough -> magnetic encoder timeout. Same problem with shiftIn().

I'm not sure if I'm able to measure with a 200ns delay. Maybe to slow down the rising edge with some hardware?

I've got the Avago HED - 8937 programmer kit and if I analyse the bits via oscilloscope, I get with "MODE2" or "MODE3" the value 43337. If I shift the bits with 200ns I get 21668, which is the correct value indicated by the programmer.

The clock via digitalWrite is not fast enough → magnetic encoder timeout. Same problem with shiftIn().

The data sheet shows the timeout between falling edges as 20 microseconds. digitalRead and digitalWrite take about 4 microseconds. A reading routine like this should not time out. .

stream[16] = {0};
for (int i = 0; i < 16; i++) 
{
  digitalWrite(PIN_CLOCK, HIGH);   
  digitalWrite(PIN_CLOCK, LOW);
  stream[i] = digitalRead(PIN_DATA);
}

Can you post the code with the clock which failed because it was too slow, and did not get you the results you wanted. Why do you think the clock was too slow?

You can always use port manipulation and some NOPs for faster commands that meet the 500 ns min pulse width if indeed you need to be faster than digitalWrite().

My code was equal to yours.

I get a 30us between the falling edges to much for the timeout.

Now, I have used port manipulation, which is much faster and get correct results.

Solved!

Thank you!

My code was equal to yours. I get a 30us between the falling edges to much for the timeout.

Arduino Pro Mini (Atmega 328p 3V3 8MHz).

Ahhh! I just noticed that you were using an 8Mhz promini. :)