Pages: 1 2 [3]   Go Down
Author Topic: SPI read write for 32bits data  (Read 6681 times)
0 Members and 1 Guest are viewing this topic.
Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 150
Posts: 6142
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Did you try my test code a few posts above? Reply #26. It did not work? What did the serial monitor say?

If it did not work, try lowering the SPI speed to 1M.
Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1729
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It looks like there is more to this than meets the eye. For example there are two types of write - one which writes commands, one which writes registers. As such there are now two write functions.

Secondly, it looks like you need to send a reset command before you can use it.

Thirdly you wanted continuous conversion mode, so that needs to be set.

As for which mode it is, the datasheet seems totally ambiguous. In the diagrams on page 12, compare SDI Write and SDO Read diagrams, in the first you will see the additional falling edge I mentioned, in the second you will see none. So who knows which mode it is - could be 0 could be 3 - try both.

Finally make sure that the MODE pin on the IC is connected to ground.

Code:
#include <SPI.h>

union FourByte{
    struct {
      unsigned long value:24; //24bit register values go in here
      byte command:8; //8bit command goes in here.
    };
    byte bit8[4]; //this is just used for efficient conversion of the above into 4 bytes.
};

void setup(){
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE3); //I believe it to be Mode3
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  pinMode(SS, OUTPUT); //not really necessary as it is done by the SPI library.
  digitalWrite(SS, HIGH);  
  
  Serial.begin(9600);
  
  unsigned long check = SPI_read(0x00); //read the config register.
  Serial.print("Config = ");
  Serial.println(check);
  
  //Software reset:
  SPI_writeCommand(0x80);
  
  unsigned long status;
  do {
    status = SPI_read(0b00011110); //read the status register
    status &= (1UL<<23);
  } while (!status); //keep checking until DRDY bit gets set.

  SPI_writeCommand(0xE8); //Set continuous conversion mode  
  
  
  check = SPI_read(0x00); //read the config register.
  Serial.print("Config = ");
  Serial.println(check);

/*
  //example of writing a register
  union FourByte data;
  data.command = 0b01000000; //Write to config register
  data.value = 1; //This is the default value from datasheet, just using it as an example.
  SPI_writeRegister(data);*/
}

void loop(){
  delay(1000);
    //example of reading data
  unsigned long voltage = SPI_read(4);//Instantaneous Voltage Channel 1
  Serial.print("Voltage = ");
  Serial.println(voltage);
}

void SPI_writeCommand(byte command) {
  digitalWrite(SS,LOW); //SS goes low to mark start of transmission
  union FourByte data = {0xFEFEFE,command}; //generate the data to be sent, i.e. your command plus the Sync bytes.
  for(char i = 3; i >= 0; i--){
    SPI.transfer(data.bit8[i]); //transfer all 4 bytes of data - command first, then Big Endian transfer of the 24bit value.
  }
  digitalWrite(SS,HIGH);
}
void SPI_writeRegister(union FourByte data) {
  digitalWrite(SS,LOW); //Using CS pin, so sync1/sync0 bytes not needed
  for(char i = 3; i >= 0; i--){
    SPI.transfer(data.bit8[i]); //transfer all 4 bytes of data - command first, then Big Endian transfer of the 24bit value.
  }
  digitalWrite(SS,HIGH);
}

unsigned long SPI_read(byte command){
  digitalWrite(SS,LOW); //SS goes low to mark start of transmission
  union FourByte data = {0xFEFEFE,command}; //generate the data to be sent, i.e. your command plus the Sync bytes.
  for(char i = 3; i >= 0; i--){
    data.bit8[i] = SPI.transfer(data.bit8[i]); //send the data whilst reading in the result
  }
  digitalWrite(SS,HIGH); //SS goes high to mark end of transmission
  return data.value; //return the 24bit value recieved.
}

Could you try running that with:
Code:
SPI.setDataMode(SPI_MODE3);

And with
Code:
SPI.setDataMode(SPI_MODE0);

In each case, what value is returned on the Serial Monitor for the line "Config = "
Logged

~Tom~

Offline Offline
Jr. Member
**
Karma: 0
Posts: 58
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Tom,

             Thanks a lot. The IC now works. I am able to get the voltage value now. Previously it was always 0. Now I can get some value. Long int. But it was not the actual reading. I think I had to just convert the value into voltage. As from the datasheet, the value is from -1 to 1 to represent the voltage.

             BTW, I am using Mode 3 and it works. I believe its the writecommand and writeregister that works. After initialisation and continous conversion setting, the IC can work now. I try other register like current and power and the value will change accordingly to represent current and power. Its just that all value are from -1 to 1 represented by 24bits. FFFFFF to 7FFFFF. I think I only get the positive value therefore max only 7FFFFF.
           
            SPI.setDataMode(SPI_MODE3); //I believe it to be Mode3
            SPI.setClockDivider(SPI_CLOCK_DIV8);

            I really appreicated your help throughout. Thanks a lot again. Have a nice day
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 58
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Tim,

              Thanks for your help alo. Have a nice day
Logged

Pages: 1 2 [3]   Go Up
Jump to: