0
Offline
Newbie
Karma: 0
Posts: 14
Arduino rocks
|
 |
« on: September 09, 2011, 04:12:37 pm » |
Hello i have problem with reading data from senzor ADIS 16354 (datasheet http://www.analog.com/static/imported-files/data_sheets/ADIS16354.pdf) I have Arduino Duemilanove I try read data from X accelerometer for this example. Here is mi code pin 10 CS - SS - voľba SPI zariadenia pin 11 DIN - MOSI - Master-out, Slave-in - digitálny vstup, slúži na zápis dát z Arduina do senzora pin 12 DOUT - MISO - Master-in, Slave out - digitálny výstup, slúži na čítanie dát zo senzora do Arduina pin 13 SCK - SCLK - Serial clock - nastavenie hodín a frekvencie #define SUPPLY_OUT 0X02 #define XGYRO_OUT 0X04 #define YGYRO_OUT 0X06 #define ZGYRO_OUT 0X08 #define XACCL_OUT 0X0A #define YACCL_OUT 0X0C #define ZACCL_OUT 0X0E #define XTEMP_OUT 0X10 #define YTEMP_OUT 0X12 #define ZTEMP_OUT 0X14 #define AUX_ADC 0X16 // tieto adresy registrov slúžia na čítanie hodnôt z jednotlivých senzorov
#define XGYRO_OFF 0X1A #define YGYRO_OFF 0X1C #define ZGYRO_OFF 0X1E #define XACCL_OFF 0X20 #define YACCL_OFF 0X22 #define ZACCL_OFF 0X24 #define ALM_MAG1 0X26 #define ALM_MAG2 0X28 #define ALM_SMPL1 0X2A #define ALM_SMPL2 0X2C #define ALM_CTRL 0X2E #define AUX_DAC 0X30 // nastavenie a kalibrácia senzora, po zápise hodnôt (pozri datasheet senzora) sa zmenia nastavenia senzora
#define GPIO_CTRL 0X32 #define MSC_CTRL 0X34 #define SMPL_PRD 0X36 // TS = TB × (NS + 1)
#define SENS/AVG 0X38 #define SLP_CNT 0X3A #define STATUS 0X3C #define COMMAND 0X3E */
#include <SPI.h>
int ss=10; // vyberieme SPI zariadenie, kedže sa používa iba jedno bude stále táto hodnota nastavená na 10 byte hi; byte lo; word data;
void setup() { pinMode(ss, LOW); // používa sa pin 10 SPI.begin(); // inicialuzuje sa SPI
SPI.setBitOrder(MSBFIRST); // senzor posle najskor MSB (most significant byte) bit ako prvý }
void loop() {
//read x digitalWrite(ss,LOW); hi=SPI.transfer(0x0b); lo=SPI.transfer(0x0a); digitalWrite(ss,HIGH); data=((hi<8)+lo); data &= 0b0011111111111111; data<<=2; data>>=2; double xacc=data*0.4672;
Serial.begin (9600); Serial.print("X Accel: "); Serial.print(xacc); Serial.println("mg");
delay(100);
}
Here is data from serial monitor, almost all the same, even if the sensor moves X Accel: 0.47mg X Accel: 0.47mg X Accel: 0.47mg X Accel: 29.43mg X Accel: 0.47mg X Accel: 29.43mg X Accel: 0.47mg X Accel: 27.10mg X Accel: 4.67mg X Accel: 4.67mg X Accel: 4.67mg X Accel: 0.47mg
Change vary wildly. What's wrong?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14097
Lua rocks!
|
 |
« Reply #1 on: September 09, 2011, 04:56:40 pm » |
hi < 8 ? data=((hi<<8) | lo); perhaps.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 14
Arduino rocks
|
 |
« Reply #2 on: September 10, 2011, 01:42:31 am » |
I changed specific line. Here is result: X Accel: 0.00mg X Accel: 4549.13mg X Accel: 0.00mg X Accel: 4549.59mg X Accel: 0.00mg X Accel: 4549.13mg X Accel: 0.00mg X Accel: 4548.66mg X Accel: 0.00mg X Accel: 4549.13mg X Accel: 0.00mg
I dont move with senzor and data still flowing. It is another way to read this address and then print its value through serial.print? Here is example read cycle from datasheet:
|
|
|
|
« Last Edit: September 10, 2011, 01:44:37 am by mmichalll »
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 75
Posts: 6969
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #3 on: September 10, 2011, 05:34:54 am » |
Put Serial.begin (9600); in setup not loop. I don't know if that has any bad effect but it ain't right where it is.
BTW, what does
data<<=2; data>>=2;
do? _____ Rob
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 75
Posts: 6969
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #4 on: September 10, 2011, 05:40:00 am » |
I've had a further look
hi=SPI.transfer(0x0b); lo=SPI.transfer(0x0a);
hi will be crap because at this point the device hasn't received an address. My guess is that then you do the 0x0a transfer you get the data for 0x0b. I'd have to look at the IMU data sheet to get a better idea.
______ Rob
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 75
Posts: 6969
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #5 on: September 10, 2011, 05:50:02 am » |
Based on a very quick look I think you do this
lo=SPI.transfer(0x0b); // get whatever crap is there from last transfer lo=SPI.transfer(0x0a); // get low byte hi=SPI.transfer(0x0); // get high byte, data sent doesn't matter
Normally with SPI unless the slave has preloaded the output reg the first transfer returns any old crap.
I'll continue to look at the data sheet though. _____ Rob
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 75
Posts: 6969
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #6 on: September 10, 2011, 06:41:23 am » |
I've had a better look and basically I think you were doing the right thing, each reading would have got data from the preceeding command but that doesn't matter. There was one possible other error though pinMode(ss, LOW); is wrong but may have worked depending on the values for LOW and OUTPUT Here's a slightly modified version of your code, I've removed stuff that doesn't help like xacc=data*0.4672 so we can see raw data for the time being. #include <SPI.h>
int ss=10; // vyberieme SPI zariadenie, kedže sa používa iba jedno bude stále táto hodnota nastavená na 10 byte hi; byte lo; word data;
void setup() { Serial.begin (9600); pinMode(ss, LOW); // používa sa pin 10 SPI.begin(); // inicialuzuje sa SPI
SPI.setBitOrder(MSBFIRST); // is MSBFIRST correct ?? // senzor posle najskor MSB (most significant byte) bit ako prvý hi=SPI.transfer(0x0a); // set the IMU to read so the next command will get valid data lo=SPI.transfer(0x0); }
void loop() {
//read x digitalWrite(ss,LOW); hi=SPI.transfer(0x0a); lo=SPI.transfer(0x0); // this value doesn't matter digitalWrite(ss,HIGH); data=((hi<<8)+lo); //data &= 0b0011111111111111; // this shouldn't be needed, leave it out for the moment //data<<=2; // don't know what this does //data>>=2; //double xacc=data*0.4672; // let's just work with raw data for starters
Serial.print("X Accel: "); Serial.print(((hi<<8)+lo), HEX); //Serial.println("mg");
delay(100);
} Try this and see what happens. ______ Rob
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 14
Arduino rocks
|
 |
« Reply #7 on: September 10, 2011, 10:12:21 am » |
Hello I use your code and here is result : X Accel: FFFFE7FE X Accel: 0 X Accel: FFFFE7FD X Accel: 0 X Accel: FFFFE7FD X Accel: 0 X Accel: FFFFE7FD X Accel: 0 X Accel: FFFFE7FD X Accel: 0 X Accel: FFFFE7FD X Accel: 0 X Accel: FFFFE7FE X Accel: 0 X Accel: FFFFE7FE X Accel: 0
No change, same value repeating When the sensor moves, the data is changed somewhere X Accel: FFFFC017 X Accel: A1F X Accel: A3F X Accel: 0 X Accel: A3F X Accel: 0 X Accel: 0 X Accel: A3F X Accel: 0 X Accel: 0
|
|
|
|
« Last Edit: September 10, 2011, 10:19:01 am by mmichalll »
|
Logged
|
|
|
|
|
Greenville, IL
Offline
Edison Member
Karma: 11
Posts: 1290
Warning Novice on board! 0 to 1 chance of errors!
|
 |
« Reply #8 on: September 10, 2011, 12:31:41 pm » |
Would it be possible that you need more time after?: digitalWrite(ss,LOW); Before you request: hi=SPI.transfer(0x0a); You could try adding a small delay to see if that helps.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 14
Arduino rocks
|
 |
« Reply #9 on: September 10, 2011, 06:10:58 pm » |
I added: delayMicroseconds(160); - 160micro s is in datasheet at normal mode (i use normal mode) Sensor sends almost the same values. Any ideas?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14097
Lua rocks!
|
 |
« Reply #10 on: September 10, 2011, 06:24:52 pm » |
This doesn't look right: digitalWrite(ss,LOW); hi=SPI.transfer(0x0a); lo=SPI.transfer(0x0); // this value doesn't matter digitalWrite(ss,HIGH); Rob seemed to realize this, but then posted the code above. Using SPI, you can't request and receive in the same transfer. That is because each bit is sent and received at the same time. So at the very least (and without reading the data sheet at great length, and checking timings) you would need: digitalWrite(ss,LOW); SPI.transfer(0x0a); // request register 0x0A hi=SPI.transfer(0x0b); // receive 0x0A, request 0x0B lo=SPI.transfer(0x0); // receive 0x0B digitalWrite(ss,HIGH); However after reading page 13 of the datasheet it says: Reading the contents of a register requires a modification to the sequence illustrated in Figure 27. In this case, the first two bits in the DIN sequence are 0, followed by the address of the register. Each register has two addresses (an upper address and a lower address), but either one can be used to access the entire 16 bits of data. The final eight bits of the DIN sequence are irrelevant and can be counted as don’t cares during a read command. Based on that, and the diagram, it looks like you send 16 bits, and then receive 16 bits, more like this: digitalWrite(ss,LOW); SPI.transfer(0x0a); // request register 0x0A SPI.transfer (0); // don't care hi=SPI.transfer(0x0a); // request again, receive high lo=SPI.transfer(0x0); // receive low, send don't care digitalWrite(ss,HIGH); Because of this design, for each two bytes, you request something (which you receive two bytes later) and receive something (which you requested two bytes back).
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 75
Posts: 6969
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #11 on: September 10, 2011, 07:07:23 pm » |
I think the after the first two transfers everything works in pairs, send two, get two from the last send. So I did two in setup() then two in every loop(). But that obviously isn't working so I'll have another look at the DS, I still think it's right though  EDIT: How fast are you allowed to read this IMU, maybe 10x a second is too fast, try changing delay(100) to delay(1000). _____ Confused
|
|
|
|
« Last Edit: September 10, 2011, 07:14:30 pm by Graynomad »
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14097
Lua rocks!
|
 |
« Reply #12 on: September 10, 2011, 07:44:42 pm » |
I think the after the first two transfers everything works in pairs, send two, get two from the last send. So I did two in setup() then two in every loop().
You might be right about doing that in setup. But you need to bring SS low if you are, otherwise it will ignore the attempt to do the first address setup. The ~CS line enables the ADIS16354 SPI port and frames each SPI event. When this signal is high, the DOUT line is in a high impedance state and the signals on DIN and SCLK have no impact on operation.
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 75
Posts: 6969
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #13 on: September 10, 2011, 08:00:03 pm » |
But you need to bring SS low if you are, otherwise it will ignore the attempt to do the first address setup. Correct. Just looking deaper into the data sheet CONVERSION RATE Maximum Sample Rate SMPL_PRD = 0x01 819.2 SPS Minimum Sample Rate SMPL_PRD = 0xFF 0.413 SPS That implies to me that the best you can do is one reading every 413mS, that doesn't explain why every second one seems to work though, if it had been every 4th one I'd be happier that that is the problem, but maybe it just works better than advertised. ______ Rob
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 14
Arduino rocks
|
 |
« Reply #14 on: September 11, 2011, 02:05:23 am » |
I do not have where or how to check if it works correctly. I'm learning to read values from one register, I will read the data from the X, Y, Z accelerometer, and X Y Z gyroscope. And view them in serial monitor, or save in file to HDD. When I read the temperature (address 0x10 XTEMP_OUT) with my program ,doing the same as reading accel addresses. I found the source code in C, the sensor is on the higher range (ADIS16355) for lower (ADIS16350). If it helped someone, I do not know much about at that.
|
|
|
|
« Last Edit: September 11, 2011, 02:07:45 am by mmichalll »
|
Logged
|
|
|
|
|
|