SPI communication with max 1300

There is 1 year old topic (already closed) regarding UNO to max 1301 spi communication. And the problem was not resolved.
I got max1300 working with Arduino UNO and decided to post here - maybe somebody still needs this.
Problem description from old topic:

The problem is that max1300 cannot receive commands correctly. Not sure which part is responsible - max1300 or arduino spi library, but it can be resolved by adding one line after command transmit.
Something like:
SPI.transfer(command byte);
SPI.transfer(0);

My code:

#include <SPI.h>
byte configByte = 0b10000011; // 3(0 - 3Vref/2)
byte modeByte = 0b10101000; // MAX1300 Mode = 2 (internal clock mode)
byte commandByte = 0b10000000; // read channel 0
const int ss = 10;
const int sstrb = 8;
unsigned int adcValue;
byte arange = 3;
byte channel = 0;
float voltage;


// returns mode byte for specific mode number (0,1,2,4,6,7)
byte mode_byte(byte mode){ 
  // mode 0: External clock (3.67MHz)  mode 1: External acquisition (4.39MHz)
  // mode 2: Internal clock (Up to 10 MHz)  mode 4: Reset (to default config)
  // mode 6: Partial power-down mode 7: Full power-down
  return 128 + 16*mode + 8; }
  
// returns configuration byte for specific channel number(0-7) and input range (1-7)
byte config_byte(byte channel, byte range){
// range 1(Plus-Minus 3Vref/4) 2(0 - -3Vref/2) 3(0 - 3Vref/2) 4(Plus-Minus 3Vref/2) 5(0 - -3Vref)  6(0 - 3Vref) 7(Plus-Minus 3Vref)
  return 128 + 16*channel + range; }

// returns start byte for cpecific channel number (0-7)
byte start_byte(byte channel){ return 128 + 16*channel; }

// translates adc data to voltage for specific input range
float translate(unsigned int data, byte range){
  float volt;
  switch(range){
    case 1: volt = (data-32768)*0.00009375; break; // (+- 3Vref/4)
    case 2: volt = (65536 - data)*0.00009375; break; // (0 - -3Vref/2)
    case 3: volt = data*0.00009375; break; // (0 - 3Vref/2)  2.187v
    case 4: volt = (data-32768)*0.0001875; break;  // (Plus-Minus 3Vref/2)
    case 5: volt = (65536 - data)*0.0001875; break;  // (0 - -3Vref)  12.287v
    case 6: volt = data*0.0001875; break;   // (0 - 3Vref)  2.188v
    case 7: volt = (data-32768)*0.000375; break;   // (Plus-Minus 3Vref)  7.239v
  }
  return volt;
}


void setup() {
  //==== Set channel number and Voltage range ====
  arange = 3; // input voltage range (1 - 7)
  channel = 0; // channel number to read (0 - 7)
  //----------------------------------------------
  modeByte = mode_byte(2); // max1300 internal clock mode
  configByte = config_byte(channel,arange); // input range for the channel
  commandByte = start_byte(channel); // adc convertion command for the channel
  //==============================================
  Serial.begin(115200);
  pinMode(ss,OUTPUT);
  pinMode(sstrb,INPUT_PULLUP);
  // ==== SPI settings ===========================
  SPI.begin();
  bitSet(SPCR, 4);  //UNO is Master 
  SPI.setBitOrder(MSBFIRST); //bit transmission order 
  SPI.setDataMode(SPI_MODE1); // Setup at RE and Saple at FE 
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  bitClear(SPCR, 7); //local SPI interrupt is disable 
  // ==== Reset MAX1300 ===========================
  digitalWrite(ss,LOW);
  SPI.transfer(mode_byte(4));
  SPI.transfer(0); // <<<=============
  digitalWrite(ss,HIGH);
  delay(10); 
  // ==== Send Channel Configuration ==============
  digitalWrite(ss,LOW);
  SPI.transfer(configByte);
  SPI.transfer(0); // <<<=============
  digitalWrite(ss,HIGH);
  delay(10); 
  // ==== Set MAX1300 mode ========================
  digitalWrite(ss,LOW);
  SPI.transfer(modeByte);
  SPI.transfer(0); // <<<=============
  digitalWrite(ss,HIGH);
  delay(10);
}

void loop() {
  byte low8 = 0;
  byte high8 = 0;
  // ==== Send start convertion command ====================
  digitalWrite(ss,LOW);
  SPI.transfer(commandByte);
  SPI.transfer(0);  // <<<=============  sstrb stays Low without this line
  digitalWrite(ss,HIGH);
  // ==== Wait for MAX1300 ready status ====================
  while(digitalRead(sstrb)==LOW){};
  // ==== Read MAX1300 data ================================
  digitalWrite(ss,LOW);
  high8 = SPI.transfer(0);
  low8 = SPI.transfer(0);
  digitalWrite(ss,HIGH);
  // ==== Convert adc data to voltage ======================
  adcValue = high8 << 8;
  adcValue = adcValue | low8;
  voltage = translate(adcValue,arange);
  Serial.print(adcValue, HEX);
  Serial.print(" - ");
  Serial.println(voltage);

  delay(500);
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.