i'm trying to build a SSI-interace with the Arduino Board, i.e. one has a clock signal and synchorn to that signal one gets the data out of the device one is interfaceing.
The problem ist that the frequency of the Clock signal has to be above 100kHz, and during one tick one has to read the signal from a I/O-port.
After trying the "normal" Code, which means at last a "for Loop": - "togle the clock"- "read the port" - "togle the clock" and again....
seems not quick engouh.
Then i started to look at Forums, for the inbuild timer routine and code samples, finding this
unluckiely the mantioned snipped is not compileable becaus of the missing function "timerAttach" which is located in "timer.h". Including this header results in another error ("avrlibtypes.h: 70: error: expected unqualified-id before numeric constant"; which has some thing in common with typedefs...).....
So what I like to know is if it is possible to realise an Interface described above, with the usage of inbuild timers?
Or is the arduino Board not quick enough for this kind of task?
I guess what you're trying to build is an SPI interface.
have you looked at the example for the Qt401? http://www.arduino.cc/en/Tutorial/Qt401
there is an SPI routine written in the arduino language that has been working quite well.
otherwise you need to look into "Hardware SPI"
here is some c code from Peter Fleury that uses the SPI master built-in the atmega8
#define SPI_CHIP_SELECT PB2 // SS pin is used here, but any pin can be used
#define SPI_MOSI PB3 // SPI MOSI pin
#define SPI_SCK PB5 // SPI SCK pin
#define SPI_DDR DDRB // port used by SPI
uint8_t led = 2;
/* SPI port initialization (/SS, MOSI, SCK output, MISO input) */
SPI_DDR = _BV(SPI_CHIP_SELECT) + _BV(SPI_MOSI) + _BV(SPI_SCK);
/* SPI interrupt disabled, SPI port enabled, master mode, MSB first, SPI mode 3, SPI Clock = XTAL/4 */
SPCR = _BV(SPE) +_BV(MSTR) + _BV(CPOL) + _BV(CPHA);
PORTB &= ~_BV(SPI_CHIP_SELECT); // enable SPI device
SPDR = led; // send data to SPI device (turn LED on/off)
while (!(SPSR & _BV(SPIF))); // wait until write complets
PORTB |= _BV(SPI_CHIP_SELECT); // disable SPI device
led ^= 2; // toggle LED
delay(65535); // delay 0.1 seconds
consider that the clock used by this code will be in the region of 4 MHZ (the code mentions clock/4...)
let me know if this works for you
Thanks for this fast reply,
luckily i'm really trying to make an SSI-Interface (which means Serial Synchron Interface), which is much simpler than an SPI one. I don't have to pass an address to the device, just toggle the clock and get the (synchron comming) output.
I guess i have to make my homework now and digg me thru to code, to get the relevant parts.....
I gonna let you know
finaly i got it working. Give me a few days to clean up my code. I'll then post it here.
To describe the project: The SSI is needed to get the absolute position of an rotary absolute enconder, then transfere the Position to MAX/MSP/Jitter, and play a video synchron to the read Position of the encoder.
Right now i'm only hassling with the HF-electronics, but in principle it works right now.
Thanks a lot,
what kind of rotary encoder do you use? i need to read the position of a hand crank.
(actually Stephan too
its form Kübler GmbH and its a rotary absolute multiturn encoder 5862 series, see www.kuebler.com for details. Its not cheap but its relieable industial optical encoder.
You don't have to take this one because the SSI is used as an industrial standart, so have a look at other companies for the best encoder that fits your needs.
here is the code, i promised weeks ago.....
SSI (Serial Synchron Interface) for the Kübler GmbH rotary absolute multiturn encoder 5862 series, see www.kuebler.com.
* 25-bit rotary absolute multiturn encoder
* Interface: SSI (with RS485 line definitions)
* encoded as: Gray-Code
- SSI-Clock TicTac must be equal or less 10µs.
- 26 Clock TicTac are needed for the whole Position consiting of a 25 Bit word, the first TicTac is needed for he status bit, which enconde the status of the device, (0) for not clear.
- After the the 26 TicTacs a puse of max. 80µs is needed for a new Position to be available.
* This Program:
- emulates a SSI with the Arduino Ports 12 (clock) and 11 (data).
- transform the gray encoded Position to binary encoded Position
- send the Position to Max/MSP/Jitter via USB
* Electronics needed:
- 2 RS485 line drivers (e.g. sn75176) are needed, if you want to save ports and clean up the ignals.
- for the start-sequence and the reset a uln 2803 could used (not implemented yet).
- a few resitors for cleaning the singnals....
byte getByte; //dummy Byte for serialAvailable
byte grayArray; //Array reseved for the recieved Gray Code
byte binaryArray; //Array reserved for the binary transformed Code
byte dummy; //dummy
int i = 0; //loop counter
int j = 0; //loop counter
void getPosition(); // saves the status bit and the 25 position bits in the grayArray, read from the register as PINB. The only time-critical process.
void condensePosition(); // condenses the recieved Byte (PINB) in grayArray to the only intersting bit (PB3) in PINB.
void transformPosition(); // transforms the 25 postion bits to binary and saves them in binaryArray
void sendPosition(); // sends the binarayArray - enclosed in '255' - via USB to Max/MSP/Jitter
//void resetRoutine(); // external Reset of the encoder, to select rotary direction and define zero Position.
DDRB = (1<<PB4); //PB4 is digital pin No 12
if(PINB & (1<<PB3))
// delay for device to become ready again
if(Serial.available()) // check if a request form max is there. To avoid a buffer overrun, MAX/MSP/Jitter is playing PingPong with the arduino Board, if max send any via sierial, arduino responds with the newest Position
while(Serial.available() > 0) // reads all the data send to the arduino board
dummy = Serial.read();
} // and finaly sends the Position
for(j = 0;j < 26; j++) // Untested yet
grayArray[j] = 0;
binaryArray[j] = 0;
for(j = 0;j < 26; j++)
PORTB = (0<<PB4);
grayArray[j]= PINB; //delayMicroseconds(3) fits a 10us tictac
PORTB = (1<<PB4);
for(i = 0;i < 26; i++)
if(grayArray[i] & (1<<PB3))
grayArray[i] = 1;
grayArray[i] = 0;
binaryArray= grayArray; // transfer status bit
binaryArray = grayArray; // gray to binary, transfer the MSB
for(i = 2; i < 26; i++) // all other bits are transformed according to: binaryArray[i] = XOR(grayArray[i], binaryArray[i - 1]), cf. http://www.faqs.org/faqs/ai-faq/genetic/part6/section-1.html
binaryArray[i]= grayArray[i] ^ binaryArray[i - 1];
void sendPosition() //This function just sends the raw data (not packed in 4 bytes)- encolsed in a '255'-masking - to the serial Object of MAX/MSP/Jitter
for(i = 0; i < 26; i++)
binaryArray[i] = 0;
grayArray[i] = 0;
void resetRoutine() //to be filled for external reset via max/msp
unfortunally this code/device/max produces false position data abou every 100 requests...which should be filtered by an mean-filtern on the max/msp side.....