Addressing SAMD21 Analog-Digital Converter ADC on Seeeduino LoRaWAN

How do I set parameters on the ADC of my Seeeduino LoRAWAN arduino board? I am trying to get as much precision as I can for my measurements and understand that I can set a number of constants to change the ADC operation.

I have the Atmel AT07627: ASF Manual (SAM D21), which gives enumerations for ADC settings but apparently I can’t just slap their code into the Arduino IDE because it doesn’t recognize the data objects.

I have seen some code examples that use things like:

ADC->ADC_CR = ADC_CR_SWRST; // Reset ADC

However, when I tried, for example:

ADC->ADC_ACCUMULATE_SAMPLES=ADC_ACCUMULATE_SAMPLES_16;

I got an error message that ‘struct Adc’ has no member named ‘ADC_ACCUMULATE_SAMPLES’

Where can I find the members for ADC and the constants to set? Is there a better way of doing this?

Thanks

@haresfur Are you using ASF? No Arduino?

I want to use the Arduino IDE. I hope I don’t need to deal with ASF, but I haven’t been successful in addressing the ADC chip. I thought I could use the structures ATM had defined in their documentation but that doesn’t seem to work and I haven’t been successful using the “ADC->” form either. Here is a cut-down version of my code that I am using for testing.

/*Code to read a Teros 10 capacitance soil moisture sensor, output reading to Serial
 * All LoRaWAN code removed for debugging
 * Written for Seeeduino so the serial port to the computer is SerialUSB
 * The current requirement of the sensor is 12 mA at 3VDC so can power from digital pin
 */

// millis timer global------------------------------------------------------------------

#include <millisDelay.h>	  //handy timing library
                            //https://www.forward.com.au/pfod/ArduinoProgramming/TimingDelaysInArduino.html
  millisDelay SensorDelay;  // the delay object

  // battery of Seeeduino LoRaWAN
  const short pin_battery_status  = A5;
  const short pin_battery_voltage = A4;   //note that this will read the USB voltage if plugged into computer
  boolean arStatus;               //not very useful
  int arVoltage;
  float bvoltage;                 

	const int Apin = A3;            //analog pin connected to sensor +
	const int ReadingTime = 20;     //time to read from Apin in ms 10 is minimum  
  int SensorBits = 0;             //variable to store sensor reading from 12 bit A/D converter
	double SensorMV = 0;		        //store sensor reading converted to mV	

// Setup readings global-----------------------------------------------------------

	const unsigned long DelayTime = 1000*60; 	// have const here so it is easy to find and change (in mS)

// end global----------------------------------------------------------------------

void setup() {
	// put your setup code here, to run once:

  pinMode(Apin, INPUT);  
  pinMode(LED_BUILTIN, OUTPUT);   	//During testing have the LED on when taking a reading
  SerialUSB.begin(19200);
  while (!SerialUSB) { 
    ;   // wait for serial port to connect
  }
  //analogReadResolution(12);         //will do this through direct addressing
	//analogReference(AR_INTERNAL);    	//2.23V SAMD Boards e.g. Zero/Seeeduino only has error

  //Read sensor once as throwaway value but print it out
  SerialUSB.println("Read in setup");
	digitalWrite(LED_BUILTIN, HIGH);
  delay(10);
	SensorBits = analogRead(Apin);
	digitalWrite(LED_BUILTIN, LOW);
	SerialUSB.print("SensorBits = ");
	SerialUSB.println(SensorBits);
	SensorMV = SensorBits/4096.0*3.3;	//Not sure if this should be 4095. Assumes 3.3 mV analog reference
	SerialUSB.print("SensorMV = ");
	SerialUSB.println(SensorMV);

  //Read sensor again after setting to 12 bit for testing as throwaway value but print it out
  SerialUSB.println("Set ADC to 12 Bit using direct addressing");
  configure_adc();
    
  digitalWrite(LED_BUILTIN, HIGH);
  delay(10);
  SensorBits = analogRead(Apin);
  digitalWrite(LED_BUILTIN, LOW);
  SerialUSB.print("SensorBits = ");
  SerialUSB.println(SensorBits);
  SensorMV = SensorBits/4096.0*3.3; //Not sure if this should be 4095. Assumes 3.3 mV analog reference
  SerialUSB.print("SensorMV = ");
  SerialUSB.println(SensorMV);

	SensorDelay.start(DelayTime);     //Start millis delay timer for sensor reading intervals

}     //end setup

void loop() {
	// put your main code here, to run repeatedly:
	if (SensorDelay.justFinished()) {		// repeat delay and take reading
		SensorDelay.repeat(); // repeat
		SerialUSB.print("millis() = ");
    SerialUSB.println(millis());
		ReadTeros10();
//    SendPayload();
	}
}     //end loop

void configure_adc(void){
  /* This routine uses commands that send instructions directly to the SAM-D21 chip
   *  so it is not portable to other systems
   *  they are taken from the AT07627: ASF Manual (SAM D21)
   *  not sure which commands are needed so trial and error
   */
    
  ADC->ADC_ACCUMULATE_SAMPLES=ADC_ACCUMULATE_SAMPLES_16;
} //end configure_adc

void ReadTeros10() {
	digitalWrite(LED_BUILTIN, HIGH);
  delay(10);
	SensorBits = analogRead(Apin);
	digitalWrite(LED_BUILTIN, LOW);
	SerialUSB.print("SensorBits = ");
	SerialUSB.println(SensorBits);
	SensorMV = SensorBits/4096.0*3.3;	//Not sure if this should be 4095. Assumes 3.3 mV analog reference
	SerialUSB.print("SensorMV = ");
	SerialUSB.println(SensorMV);
} //end ReadTeros10