Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

Grand Central, analog inputs 0-7 work ok, but analog inputs
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Grand Central, analog inputs 0-7 work ok, but analog inputs

by dj_lambert on Fri Oct 04, 2019 5:11 am

Hi
I have searched for a solution but not found one, i assume that i have not set a Parameter somewhere.
The following produces useable values for A0-A7, but A8-A15 are always 0

Code: Select all | TOGGLE FULL SIZE
#define ledPin 13
unsigned long prevMillis = 0;
unsigned long startLedMillis;
unsigned long clockMillis = 0;
unsigned long loopCount = 0;

int readADC(int Channel){
  return analogRead(Channel);
}


void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(9600);
}

void loop() {
unsigned long currMillis = millis();
   
if (currMillis - prevMillis >= 5000){
  Serial.println("Start of Loop " + String(loopCount) + ":");
  digitalWrite(ledPin,HIGH);
  for (int t = 0; t<16; t++){
    delay(5);
    Serial.println(readADC(t));
  }
  Serial.println("End of Loop " + String(loopCount) + ".");
  digitalWrite(ledPin,LOW);
  loopCount++;
  prevMillis = currMillis;
}



}

Please any ideas on what i have missed would be good..

Thanks and regards
DJL

dj_lambert
 
Posts: 4
Joined: Fri Oct 04, 2019 4:55 am

Re: Grand Central, analog inputs 0-7 work ok, but analog inp

by dastels on Fri Oct 04, 2019 10:14 am

Starting with the basics:
- Are you using an up to date version of the Arduino environment?
- Are all your board packages and libraries up to date?
- Do you have the correct board selected? I.e. Adafruit Grand Central M4

Dave

dastels
 
Posts: 3549
Joined: Tue Oct 20, 2015 3:22 pm

Re: Grand Central, analog inputs 0-7 work ok, but analog inp

by dj_lambert on Fri Oct 04, 2019 2:09 pm

Thanks for the reply..
yes updated all a few days ago..
have since found that 0-7 work ok as analogRead(0) - analogRead(7), but 8-15 only work as analogRead(A8) - analogRead(A15).
just got to workout how to include the "A" in the read call...

dj_lambert
 
Posts: 4
Joined: Fri Oct 04, 2019 4:55 am

Re: Grand Central, analog inputs 0-7 work ok, but analog inp

by stratosfear on Fri Oct 04, 2019 6:12 pm

I'll confirm dj_lambert's findings since I discovered it a few weeks ago. There's no need to try inserting the "A" and I doubt that would work, anyway. Here's a function I wrote that lets you use only Arduino pin numbers. Still, it would be nice to eliminate the function.

Code: Select all | TOGGLE FULL SIZE
//eliminates 'A' preface for analog input pins
uint32_t anaPinXlate(uint32_t inputPin)  {
  return (inputPin + 67 - ((inputPin / 8) * 21));  // (inputPin / 8) will be either 0 or 1
}

stratosfear
 
Posts: 10
Joined: Tue Dec 31, 2013 8:21 am

Re: Grand Central, analog inputs 0-7 work ok, but analog inp

by adafruit2 on Fri Oct 04, 2019 11:21 pm

use 'A' notation always, please! the old integer-only technique is not good for modern boards

adafruit2
Site Admin
 
Posts: 19383
Joined: Fri Mar 11, 2005 7:36 pm

Re: Grand Central, analog inputs 0-7 work ok, but analog inp

by dj_lambert on Sat Oct 05, 2019 3:14 pm

Hi all
Thanks for your replies,
Stratosfear, your Function works well thanks all 16 ADC pins provide useful results!
Adafruit2, not sure how to merge a char into a uint? tried a few methods excluding defines for all A0-A15 and a select to call them..

Thanks again

dj_lambert
 
Posts: 4
Joined: Fri Oct 04, 2019 4:55 am

Re: Grand Central, analog inputs 0-7 work ok, but analog inp

by stratosfear on Sun Oct 06, 2019 7:27 am

You're welcome, dj_lambert.

Lets take a look at the critical lines in \arduino-1.8.10\portable\packages\adafruit\hardware\samd\1.5.3\variants\grand_central_m4\variant.h.

Code: Select all | TOGGLE FULL SIZE
/*
 * Analog pins
 */
#define PIN_A0              (67)
#define PIN_A1              (PIN_A0 + 1)
#define PIN_A2              (PIN_A0 + 2)
#define PIN_A3              (PIN_A0 + 3)
#define PIN_A4              (PIN_A0 + 4)
#define PIN_A5              (PIN_A0 + 5)
#define PIN_A6              (PIN_A0 + 6)
#define PIN_A7              (PIN_A0 + 7)

#define PIN_A8              (54)
#define PIN_A9              (PIN_A8 + 1)
#define PIN_A10             (PIN_A8 + 2)
#define PIN_A11             (PIN_A8 + 3)
#define PIN_A12             (PIN_A8 + 4)
#define PIN_A13             (PIN_A8 + 5)
#define PIN_A14             (PIN_A8 + 6)
#define PIN_A15             (PIN_A8 + 7)

#define PIN_DAC0            PIN_A0
#define PIN_DAC1            PIN_A1

static const uint8_t A0   = PIN_A0;
static const uint8_t A1   = PIN_A1;
static const uint8_t A2   = PIN_A2;
static const uint8_t A3   = PIN_A3;
static const uint8_t A4   = PIN_A4;
static const uint8_t A5   = PIN_A5;
static const uint8_t A6   = PIN_A6;
static const uint8_t A7   = PIN_A7;

static const uint8_t A8   = PIN_A8;
static const uint8_t A9   = PIN_A9;
static const uint8_t A10  = PIN_A10;
static const uint8_t A11  = PIN_A11;
static const uint8_t A12  = PIN_A12;
static const uint8_t A13  = PIN_A13;
static const uint8_t A14  = PIN_A14;
static const uint8_t A15  = PIN_A15;

static const uint8_t DAC0 = PIN_DAC0;
static const uint8_t DAC1 = PIN_DAC1;


The defined values will vary for different boards/processors, so my function above is only valid for the Grand Central. This is likely why Adafruit state the integer pin numbers are "not good for modern boards."

In my project, I will be reading all sixteen analog inputs into an array (actually an array of structs), so nothing would be simpler than the following, yet we know it falls apart above analog input 7.

Code: Select all | TOGGLE FULL SIZE
void setup() {
  uint32_t aRead[16];  //specify array

  //read values into array
  for (byte n = 0; n <= 0x0f; n++)  {
    aRead[n] = analogRead(n);
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}



If Adafruit recommend always using the “A” preface, I can imagine a few options, each bulkier than a simple for loop and probably invalid for different boards. The first passes the number to a function with switch/case that determines which “A” pin to read. The drawback I see is the additional processing time to filter down to the larger cases. Maybe that's insignificant when running at 120MHz.

Code: Select all | TOGGLE FULL SIZE
void setup() {
  uint32_t aRead[16];  //my array to hold analog values

  //fill array
  for (byte n = 0; n <= 0x0f; n++) {
    aRead[n] = A_read(n);
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

//Uses "A" preface to read analog pins as recommended by Adafruit
uint32_t A_read (byte ardPin) {
    switch (ardPin)  {
      case 0:
        return analogRead(A0);
        break;
      case 1:
        return analogRead(A1);
        break;
      case 2:
        return analogRead(A2);
        break;
      case 3:
        return analogRead(A3);
        break;
      case 4:
        return analogRead(A4);
        break;
      case 5:
        return analogRead(A5);
        break;
      case 6:
        return analogRead(A6);
        break;
      case 7:
        return analogRead(A7);
        break;
      case 8:
        return analogRead(A8);
        break;
      case 9:
        return analogRead(A9);
        break;
      case 10:
        return analogRead(A10);
        break;
      case 11:
        return analogRead(A11);
        break;
      case 12:
        return analogRead(A12);
        break;
      case 13:
        return analogRead(A13);
        break;
      case 14:
        return analogRead(A14);
        break;
      case 15:
        return analogRead(A15);
        break;
    }
}


A second method “de-translates” the lines in variant.h and holds them in a global array. This is essentially what my function posted above calculates.

Code: Select all | TOGGLE FULL SIZE
byte anaPin[16];  //array to hold de-translated A pin numbers

void setup() {

  uint32_t anaRead[16];  //my array to hold analog values
 
  //fill the de-translated array
  anaPin[0] = A0;
  anaPin[1] = A1;
  anaPin[2] = A2;
  anaPin[3] = A3;
  anaPin[4] = A4;
  anaPin[5] = A5;
  anaPin[6] = A6;
  anaPin[7] = A7;
  anaPin[8] = A8;
  anaPin[9] = A9;
  anaPin[10] = A10;
  anaPin[11] = A11;
  anaPin[12] = A12;
  anaPin[13] = A13;
  anaPin[14] = A14;
  anaPin[15] = A15;

  //read analog values into my array
  for(byte n = 0; n <= 0x0f; n++) {
    anaRead[n] = analogRead(anaPin[n]);
  }
 
}

void loop() {
  // put your main code here, to run repeatedly:

}


I could imagine using an array of function pointers, but then you'd have sixteen different functions. Perhaps someone from Adafruit will have a better idea.

Jon

stratosfear
 
Posts: 10
Joined: Tue Dec 31, 2013 8:21 am

Re: Grand Central, analog inputs 0-7 work ok, but analog inp

by adafruit_support_bill on Sun Oct 06, 2019 8:16 am

The array approach is going to be the most efficient. You have the one-time overhead of initializing it in setup. The array-indexing overhead at run-time will be pretty minimal.

adafruit_support_bill
 
Posts: 78774
Joined: Sat Feb 07, 2009 10:11 am

Re: Grand Central, analog inputs 0-7 work ok, but analog inp

by dj_lambert on Mon Oct 07, 2019 2:52 am

Hi All
Thanks again for your replies.
Stratosfear as previously stated your function works well (also on an Arduino Mega), i was leaning toward the Switch Version, but i will probably implement the Array Version.
Adafruit maybe it is worth mentioning that the 'Ax' is required in the documentation for the Grand central? Other than this small (easily rectified with help) bump, Great board by the way.

Thanks again and Regards

dj_lambert
 
Posts: 4
Joined: Fri Oct 04, 2019 4:55 am

Re: Grand Central, analog inputs 0-7 work ok, but analog inp

by westfw on Fri Jul 17, 2020 10:43 pm


westfw
 
Posts: 1725
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Please be positive and constructive with your questions and comments.