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);
}