Initial commit

This commit is contained in:
Robin Müller 2022-02-17 14:47:56 +01:00
commit 0c7a0f042f
3 changed files with 474 additions and 0 deletions

323
MAX122x.cpp Normal file
View File

@ -0,0 +1,323 @@
#include "MAX122x.h"
#include <SPI.h>
MAX122x_library::MAX122x_library(bool displayMsg) {
// Anything you need when instantiating your object goes here
}
// Reads out MAX122x internal temperature sensor
float MAX122x_library::max122xreadTemp(uint8_t Chipselect_Pin){
// Utilise SPI bus with appropriate settings
SPI.beginTransaction(SPI_SETTINGS);
// Write Setup register
digitalWrite(Chipselect_Pin,LOW);
// Write in setup register
SPI.transfer(MAX122x_SETUP_0);
delayMicroseconds(SPI_delay_commandSkip);
// Write conversion register to get temperature
SPI.transfer(MAX122x_CONVERT_TMP);
// Wait for conversion to be finished (incl. int. ref. wake-up time)
delayMicroseconds(SPI_delay_conversionTime);
// Write 24-2 byte of zeros on bus
for (byte i=0;i<=21;i++){
SPI.transfer(0x00);
}
// Fetch temperature from last 2 bytes of the 24 bytes sent
byte tmp_msb=SPI.transfer(0x00); // MSB of conversion
byte tmp_lsb=SPI.transfer(0x00); // LSB of conversion
// end ADC sampling
digitalWrite(Chipselect_Pin,HIGH);
// Clear bus
SPI.endTransaction();
// recover 12 bit value into 16 bit/2byte/uint16_t
//adc_msb = adc_msb & 0x0F;
uint16_t tmp_comb=((uint16_t)tmp_msb << 8) | tmp_lsb;
// Convert to celsius
float tmp_result = (float)tmp_comb/8;
// Return result
return tmp_result;
} // end of max122xreadTMP()
// Reads out single MAX122x ADC channnel
uint16_t MAX122x_library::max122xreadADCsingle(uint8_t Chipselect_Pin, byte channel){
// Utilise SPI bus with appropriate settings
SPI.beginTransaction(SPI_SETTINGS);
// Write Setup register
digitalWrite(Chipselect_Pin,LOW);
// Write in setup register
SPI.transfer(MAX122x_SETUP_0);
delayMicroseconds(SPI_delay_commandSkip);
// Select channel
switch(channel){
case 0 : SPI.transfer(MAX122x_CONVERT_CH0);
break;
case 1 : SPI.transfer(MAX122x_CONVERT_CH1);
break;
case 2 : SPI.transfer(MAX122x_CONVERT_CH2);
break;
case 3 : SPI.transfer(MAX122x_CONVERT_CH3);
break;
case 4 : SPI.transfer(MAX122x_CONVERT_CH4);
break;
case 5 : SPI.transfer(MAX122x_CONVERT_CH5);
break;
case 6 : SPI.transfer(MAX122x_CONVERT_CH6);
break;
case 7 : SPI.transfer(MAX122x_CONVERT_CH7);
break;
case 8 : SPI.transfer(MAX122x_CONVERT_CH7);
break;
case 9 : SPI.transfer(MAX122x_CONVERT_CH7);
break;
case 10 : SPI.transfer(MAX122x_CONVERT_CH7);
break;
case 11 : SPI.transfer(MAX122x_CONVERT_CH7);
break;
default: break;
}
// Wait for conversion to be finished (incl. int. ref. wake-up time)
delayMicroseconds(SPI_delay_conversionTime);
byte data[16]={0};
byte adc_msb=SPI.transfer(0x00); // MSB of conversion
byte adc_lsb=SPI.transfer(0x00); // LSB of conversion
// end ADC sampling
digitalWrite(Chipselect_Pin,HIGH);
// Clear bus
SPI.endTransaction();
// recover 12 bit value into 16 bit/2byte/uint16_t
//adc_msb = adc_msb & 0x0F;
uint16_t adc_result=((uint16_t)adc_msb << 8) | adc_lsb;
// Return result
return adc_result;
} // end of max122xreadADCsingle()
// Reads out MAX122x ADC channel 0 through 3 (MAX1227 and MAX1229)
struct ADCresults0to3 MAX122x_library::max122xReadADC0to3(uint8_t Chipselect_Pin){
// Instantiate struct
struct ADCresults0to3 adcresult0to3_instance;
// Initialise function variables
uint16_t results_concat;
// Utilise SPI bus with appropriate settings
SPI.beginTransaction(SPI_SETTINGS);
// Write Setup register
digitalWrite(Chipselect_Pin,LOW);
// Write in setup register
SPI.transfer(MAX122x_SETUP_0);
delayMicroseconds(SPI_delay_commandSkip);
// Loop over all channels
for(uint8_t i=0; i<=3; i++){
switch(i){
case 0 : SPI.transfer(MAX122x_CONVERT_CH0);
break;
case 1 : SPI.transfer(MAX122x_CONVERT_CH1);
break;
case 2 : SPI.transfer(MAX122x_CONVERT_CH2);
break;
case 3 : SPI.transfer(MAX122x_CONVERT_CH3);
break;
default: break;
}
// Wait for conversion to be finished (incl. int. ref. wake-up time)
if(i==0){
delayMicroseconds(SPI_delay_conversionTime);
}else{
delayMicroseconds(SPI_delay_commandSkip);
}
byte adc_msb=SPI.transfer(0x00); // MSB of conversion
byte adc_lsb=SPI.transfer(0x00); // LSB of conversion
// End ADC sampling
// Recover 12 bit value into 16 bit/2byte/uint16_t
//adc_msb = adc_msb & 0x0F;
results_concat=((uint16_t)adc_msb << 8) | adc_lsb;
// Write into instantiated struct
switch(i){
case 0 : adcresult0to3_instance.result_ch0=results_concat;
break;
case 1 : adcresult0to3_instance.result_ch1=results_concat;
break;
case 2 : adcresult0to3_instance.result_ch2=results_concat;
break;
case 3 : adcresult0to3_instance.result_ch3=results_concat;
break;
default: break;
}
}
// Clear bus
digitalWrite(Chipselect_Pin,HIGH);
SPI.endTransaction();
// Return result
return adcresult0to3_instance;
} // end of max122xReadADC0to3()
// Reads out MAX122x ADC channel 0 through 7 (MAX1227 and MAX1229)
struct ADCresults0to7 MAX122x_library::max122xReadADC0to7(uint8_t Chipselect_Pin){
// Instantiate struct
struct ADCresults0to7 adcresult0to7_instance;
// Initialise function variables
uint16_t results_concat;
// Utilise SPI bus with appropriate settings
SPI.beginTransaction(SPI_SETTINGS);
// Write Setup register
digitalWrite(Chipselect_Pin,LOW);
// Write in setup register
SPI.transfer(MAX122x_SETUP_0);
delayMicroseconds(SPI_delay_commandSkip);
// Loop over all channels
for(uint8_t i=0; i<=7; i++){
switch(i){
case 0 : SPI.transfer(MAX122x_CONVERT_CH0);
break;
case 1 : SPI.transfer(MAX122x_CONVERT_CH1);
break;
case 2 : SPI.transfer(MAX122x_CONVERT_CH2);
break;
case 3 : SPI.transfer(MAX122x_CONVERT_CH3);
break;
case 4 : SPI.transfer(MAX122x_CONVERT_CH4);
break;
case 5 : SPI.transfer(MAX122x_CONVERT_CH5);
break;
case 6 : SPI.transfer(MAX122x_CONVERT_CH6);
break;
case 7 : SPI.transfer(MAX122x_CONVERT_CH7);
break;
default: break;
}
// Wait for conversion to be finished (incl. int. ref. wake-up time)
if(i==0){
delayMicroseconds(SPI_delay_conversionTime);
}else{
delayMicroseconds(SPI_delay_commandSkip);
}
byte adc_msb=SPI.transfer(0x00); // MSB of conversion
byte adc_lsb=SPI.transfer(0x00); // LSB of conversion
// End ADC sampling
// Recover 12 bit value into 16 bit/2byte/uint16_t
//adc_msb = adc_msb & 0x0F;
results_concat=((uint16_t)adc_msb << 8) | adc_lsb;
// Write into instantiated struct
switch(i){
case 0 : adcresult0to7_instance.result_ch0=results_concat;
break;
case 1 : adcresult0to7_instance.result_ch1=results_concat;
break;
case 2 : adcresult0to7_instance.result_ch2=results_concat;
break;
case 3 : adcresult0to7_instance.result_ch3=results_concat;
break;
case 4 : adcresult0to7_instance.result_ch4=results_concat;
break;
case 5 : adcresult0to7_instance.result_ch5=results_concat;
break;
case 6 : adcresult0to7_instance.result_ch6=results_concat;
break;
case 7 : adcresult0to7_instance.result_ch7=results_concat;
break;
default: break;
}
}
// Clear bus
digitalWrite(Chipselect_Pin,HIGH);
SPI.endTransaction();
// Return result
return adcresult0to7_instance;
} // end of max122xReadADC0to7()
// Reads out MAX122x ADC channel 0 through 11 (only MAX1229!)
struct ADCresults0to11 MAX122x_library::max122xReadADC0to11(uint8_t Chipselect_Pin){
// Instantiate struct
struct ADCresults0to11 adcresult0to11_instance;
// Initialise function variables
uint16_t results_concat;
// Utilise SPI bus with appropriate settings
SPI.beginTransaction(SPI_SETTINGS);
// Write Setup register
digitalWrite(Chipselect_Pin,LOW);
// Write in setup register
SPI.transfer(MAX122x_SETUP_0);
delayMicroseconds(SPI_delay_commandSkip);
// Loop over all channels
for(uint8_t i=0; i<=11; i++){
switch(i){
case 0 : SPI.transfer(MAX122x_CONVERT_CH0);
break;
case 1 : SPI.transfer(MAX122x_CONVERT_CH1);
break;
case 2 : SPI.transfer(MAX122x_CONVERT_CH2);
break;
case 3 : SPI.transfer(MAX122x_CONVERT_CH3);
break;
case 4 : SPI.transfer(MAX122x_CONVERT_CH4);
break;
case 5 : SPI.transfer(MAX122x_CONVERT_CH5);
break;
case 6 : SPI.transfer(MAX122x_CONVERT_CH6);
break;
case 7 : SPI.transfer(MAX122x_CONVERT_CH7);
break;
case 8 : SPI.transfer(MAX122x_CONVERT_CH8);
break;
case 9 : SPI.transfer(MAX122x_CONVERT_CH9);
break;
case 10 : SPI.transfer(MAX122x_CONVERT_CH10);
break;
case 11 : SPI.transfer(MAX122x_CONVERT_CH11);
break;
default: break;
}
// Wait for conversion to be finished (incl. int. ref. wake-up time)
if(i==0){
delayMicroseconds(SPI_delay_conversionTime);
}else{
delayMicroseconds(SPI_delay_commandSkip);
}
byte adc_msb=SPI.transfer(0x00); // MSB of conversion
byte adc_lsb=SPI.transfer(0x00); // LSB of conversion
// End ADC sampling
// Recover 12 bit value into 16 bit/2byte/uint16_t
//adc_msb = adc_msb & 0x0F;
results_concat=((uint16_t)adc_msb << 8) | adc_lsb;
// Write into instantiated struct
switch(i){
case 0 : adcresult0to11_instance.result_ch0=results_concat;
break;
case 1 : adcresult0to11_instance.result_ch1=results_concat;
break;
case 2 : adcresult0to11_instance.result_ch2=results_concat;
break;
case 3 : adcresult0to11_instance.result_ch3=results_concat;
break;
case 4 : adcresult0to11_instance.result_ch4=results_concat;
break;
case 5 : adcresult0to11_instance.result_ch5=results_concat;
break;
case 6 : adcresult0to11_instance.result_ch6=results_concat;
break;
case 7 : adcresult0to11_instance.result_ch7=results_concat;
break;
case 8 : adcresult0to11_instance.result_ch8=results_concat;
break;
case 9 : adcresult0to11_instance.result_ch9=results_concat;
break;
case 10 : adcresult0to11_instance.result_ch10=results_concat;
break;
case 11 : adcresult0to11_instance.result_ch11=results_concat;
break;
default: break;
}
}
// Clear bus
digitalWrite(Chipselect_Pin,HIGH);
SPI.endTransaction();
// Return result
return adcresult0to11_instance;
} // end of max122xReadADC0to11()
float MAX122x_library::max122xFloatToVoltage(uint16_t adc_raw_value){
static float v_ref = 2.5; // [V] ADC internal voltage reference
static uint16_t adc_bit = 4095; // [bit] 2^12 bit resolution
return (float(adc_raw_value)*v_ref/adc_bit);
} // End of max122xFloatToVoltage

76
MAX122x.h Normal file
View File

@ -0,0 +1,76 @@
#ifndef _MAX122x_H_
#define _MAX122x_H_
// SPI communication settings
#define SPI_SETTINGS SPISettings(4000000, MSBFIRST, SPI_MODE0) // max 4.8MHz readout clock speed on MAX122x
// MAX122x Mode 11 registers
// Conversion MSBFirst: BIT7:1|BIT6:CHSEL3|BIT5:CHSEL2|BIT4:CHSEL1|BIT3:CHSEL0|BIT2:SCAN1|BIT1:SCAN0|BIT0:TEMP
#define MAX122x_CONVERT_CH0 0b10000110 // Initiates single ADC conversion on Ch0
#define MAX122x_CONVERT_CH1 0b10001110 // Initiates single ADC conversion on Ch1
#define MAX122x_CONVERT_CH2 0b10010110 // Initiates single ADC conversion on Ch2
#define MAX122x_CONVERT_CH3 0b10011110 // Initiates single ADC conversion on Ch3
#define MAX122x_CONVERT_CH4 0b10100110 // Initiates single ADC conversion on Ch4
#define MAX122x_CONVERT_CH5 0b10101110 // Initiates single ADC conversion on Ch5
#define MAX122x_CONVERT_CH6 0b10110110 // Initiates single ADC conversion on Ch6
#define MAX122x_CONVERT_CH7 0b10111110 // Initiates single ADC conversion on Ch7
#define MAX122x_CONVERT_CH8 0b11000110 // Initiates single ADC conversion on Ch8
#define MAX122x_CONVERT_CH9 0b11001110 // Initiates single ADC conversion on Ch9
#define MAX122x_CONVERT_CH10 0b11010110 // Initiates single ADC conversion on Ch10
#define MAX122x_CONVERT_CH11 0b11011110 // Initiates single ADC conversion on Ch11
#define MAX122x_CONVERT_TMP 0b10000001 // Initiates single TMP conversion
// Setup MSB first: BIT7:0|BIT6:1|BIT5:CKSEL1|BIT4:CKSEL0|BIT3:REFSEL1|BIT2:REFSEL0|BIT1:DIFFSEL1|BIT0:DIFFSEL0
#define MAX122x_SETUP_0 0b01110000 // External Timed by SCLK, Internal Reference w/ wakeup time, no unipolar/bipolar register write
#define MAX122x_SETUP_1 0b01111000 // External Timed by SCLK, Internal Reference w/o wakeup time, no unipolar/bipolar register write
#define MAX122x_SETUP_2 0b01100000 // Internally timed, use of EOC signal, Internal Reference w/ wakeup time, no unipolar/bipolar register write
#define MAX122x_SETUP_3 0b01101000 // Internally timed, use of EOC signal, Internal Reference w/o wakeup time, no unipolar/bipolar register write
// Averaging
// Not implemented because Mode 11 does not allow averaging and scanning
// Reset (all registers to 0)
#define MAX122x_RESET_ALL 0b00011000 // Resets all registers
#define MAX122x_RESET_FIFO 0b00010000 // Clears FIFO only
// Unipolar mode setup & bipolar mode setup
// Not implemented since unipolar, single ended is default case
// May be needed depending on Arduino version
#if (ARDUINO >=100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
struct ADCresults0to3{
uint16_t result_ch0,result_ch1,result_ch2,result_ch3;
};
struct ADCresults0to7{
uint16_t result_ch0,result_ch1,result_ch2,result_ch3,result_ch4,result_ch5,result_ch6,result_ch7;
};
struct ADCresults0to11{
uint16_t result_ch0,result_ch1,result_ch2,result_ch3,result_ch4,result_ch5,result_ch6,result_ch7,result_ch8,result_ch9,result_ch10,result_ch11;
};
// Create class for MAX122x ADC
class MAX122x_library {
public:
// Constructor
MAX122x_library(bool displayMsg=false);
// Methods
float max122xreadTemp(uint8_t Chipselect_Pin);
uint16_t max122xreadADCsingle(uint8_t Chipselect_Pin, byte channel);
struct ADCresults0to3 max122xReadADC0to3(uint8_t Chipselect_Pin);
struct ADCresults0to7 max122xReadADC0to7(uint8_t Chipselect_Pin);
struct ADCresults0to11 max122xReadADC0to11(uint8_t Chipselect_Pin);
float max122xFloatToVoltage(uint16_t adc_raw_value);
private:
uint8_t SPI_delay_commandSkip = 8; // in microseconds
uint8_t SPI_delay_conversionTime = 65; // in microseconds
};
#endif // _MAX122x_H_

View File

@ -0,0 +1,75 @@
#include<math.h>
#include <SPI.h>
#define SCLK 13
#define MOSI 11
#define MISO 12
#define CS_ADC 10
#include "MAX122x.h"
MAX122x_library max122x_library(true);
// SPISettings MAX1229_SETTINGS(4000000, MSBFIRST, SPI_MODE0); // max 4.8MHz readout clock speed on MAX1229
uint16_t ch0_bit,ch1_bit,ch2_bit,ch3_bit,ch4_bit,ch5_bit;
float ch0_volt,ch1_volt,ch2_volt,ch3_volt,ch4_volt,ch5_volt;
float temperature;
struct ADCresults0to3;
void setup() {
// Initiate console
Serial.begin(9600);
Serial.setTimeout(1000000);
// Initialise SPI pins and SPI protocol
pinMode(CS_ADC, OUTPUT); // declare SS output
pinMode(MOSI, OUTPUT); // declare MOSI output
pinMode(MISO, INPUT); // declare MISO input (not stricly necessary)
pinMode(SCLK, OUTPUT); // declare SCLK output
SPI.begin();
//SPI.setClockDivider(SPI_CLOCK_DIV8);
digitalWrite(CS_ADC,HIGH);
}// end of setup()
void loop() {
// Readout values
temperature = max122x_library.max122xreadTemp(CS_ADC);
ch0_bit = max122x_library.max122xreadADCsingle(CS_ADC,0);
ch1_bit = max122x_library.max122xreadADCsingle(CS_ADC,1);
ch2_bit = max122x_library.max122xreadADCsingle(CS_ADC,2);
ch3_bit = max122x_library.max122xreadADCsingle(CS_ADC,3);
ch4_bit = max122x_library.max122xreadADCsingle(CS_ADC,4);
ch5_bit = max122x_library.max122xreadADCsingle(CS_ADC,5);
ch0_volt = max122x_library.max122xFloatToVoltage(ch0_bit);
ch1_volt = max122x_library.max122xFloatToVoltage(ch1_bit);
ch2_volt = max122x_library.max122xFloatToVoltage(ch2_bit);
ch3_volt = max122x_library.max122xFloatToVoltage(ch3_bit);
ch4_volt = max122x_library.max122xFloatToVoltage(ch4_bit);
ch5_volt = max122x_library.max122xFloatToVoltage(ch5_bit);
// Print out results on serial monitor
if(true){
Serial.println(ch0_volt);
Serial.println(ch1_volt);
Serial.println(ch2_volt);
Serial.println(ch3_volt);
Serial.println(ch4_volt);
Serial.println(ch5_volt);
Serial.println(temperature);
Serial.println();
}
if(false){
Serial.println(ch0_bit);
Serial.println(ch1_bit);
Serial.println(ch2_bit);
Serial.println(ch3_bit);
Serial.println(ch4_bit);
Serial.println(ch5_bit);
Serial.println(temperature);
Serial.println();
}
} // end of loop()