Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADC_Module::checkDifferentialPins(uint8_t pinP, uint8_t pinN) always fails on Teensy 3.6 #17

Closed
kgeorge1student opened this issue Nov 2, 2016 · 4 comments
Labels

Comments

@kgeorge1student
Copy link

The bool ADC_Module::checkDifferentialPins(uint8_t pinP, uint8_t pinN) always sets error flag ADC_ERROR_WRONG_PIN on Teensy 3.6. I tried every combination of pin numbers and ADCs and this function always sets this error. I commented out all the returns and error flag setting and it now reads a voltage just fine.

@pedvide
Copy link
Owner

pedvide commented Nov 2, 2016

I'll have a look at it on the weekend. Can you post an example of that problem? Also what versions of the ADC library, Teensyduino and Arduino are you using?

@kgeorge1student
Copy link
Author

Arduino-1.6.11
Teensyduino version=1.6.7

From ADC_Module.cpp (I suspect the issue is with ADC_MAX_PIN check in checkDifferentialPins as differential pin numbers do exceed the limit its trying to enforce despite the fact they are valid pins on the Teensy 3.6:

//////////////// INFORMATION ABOUT VALID PINS //////////////////

// check whether the pin is a valid analog pin
bool ADC_Module::checkPin(uint8_t pin) {

if(pin>ADC_MAX_PIN) {
    return false;   // all others are invalid
}

// translate pin number to SC1A number, that also contains MUX a or b info.
const uint8_t sc1a_pin = channel2sc1a[pin];

// check for valid pin
if( (sc1a_pin&ADC_SC1A_CHANNELS) == ADC_SC1A_PIN_INVALID ) {
    return false;   // all others are invalid
}

return true;

}

// check whether the pins are a valid analog differential pins (including PGA if enabled)
bool ADC_Module::checkDifferentialPins(uint8_t pinP, uint8_t pinN) {
if(pinP>ADC_MAX_PIN) {
// return false; // all others are invalid
}

// translate pinP number to SC1A number, to make sure it's differential
uint8_t sc1a_pin = channel2sc1a[pinP];

if( !(sc1a_pin&ADC_SC1A_PIN_DIFF) ) {

// return false; // all others are invalid
}

// get SC1A number, also whether it can do PGA
sc1a_pin = getDifferentialPair(pinP);

// the pair can't be measured with this ADC
if( (sc1a_pin&ADC_SC1A_CHANNELS) == ADC_SC1A_PIN_INVALID ) {

// fail_flag |= ADC_ERROR_WRONG_PIN;
// return false; // all others are invalid
}

#if ADC_USE_PGA
// check if PGA is enabled, and whether the pin has access to it in this ADC module
if( isPGAEnabled() && !(sc1a_pin&ADC_SC1A_PIN_PGA) ) {

// return false;
}
#endif // ADC_USE_PGA

return true;

}

/##################################################
The Program:
##################################################
/
/* Example for analogReadDifferential

  • You can change the number of averages, bits of resolution and also the comparison value or range.
    */

#include <ADC.h>

ADC *adc = new ADC(); // adc object

void setup() {

pinMode(LED_BUILTIN, OUTPUT);
pinMode(A10, INPUT); //Diff Channel 0 Positive
pinMode(A11, INPUT); //Diff Channel 0 Negative

Serial.begin(115200);
while(!Serial);

///// ADC0 ////
// reference can be ADC_REF_3V3, ADC_REF_1V2 (not for Teensy LC) or ADC_REF_EXT.
//adc->setReference(ADC_REF_1V2, ADC_0); // change all 3.3 to 1.2 if you change the reference to 1V2

adc->setAveraging(32, ADC_1); // set number of averages
adc->setResolution(16, ADC_1); // set bits of resolution
adc->setConversionSpeed(ADC_VERY_LOW_SPEED, ADC_1); // change the conversion speed
adc->setSamplingSpeed(ADC_VERY_LOW_SPEED, ADC_1); // change the sampling speed

// always call the compare functions after changing the resolution!
//adc->enableCompare(1.0/3.3*adc->getMaxValue(ADC_1), 0, ADC_1); // measurement will be ready if value < 1.0V
//adc->enableCompareRange(-1.0*adc->getMaxValue(ADC_1)/3.3, 2.0*adc->getMaxValue(ADC_1)/3.3, 0, 1, ADC_1); // ready if value lies out of [-1.0,2.0] V

Serial.println("End setup");
delay(500);

}

int value2 = ADC_ERROR_VALUE;

void loop() {
value2 = adc->analogReadDifferential(A10,A11, ADC_1);
/* fail_flag contains all possible errors,
They are defined in ADC_Module.h as

      ADC_ERROR_OTHER
      ADC_ERROR_CALIB
      ADC_ERROR_WRONG_PIN
      ADC_ERROR_ANALOG_READ
      ADC_ERROR_COMPARISON
      ADC_ERROR_ANALOG_DIFF_READ
      ADC_ERROR_CONT
      ADC_ERROR_CONT_DIFF
      ADC_ERROR_WRONG_ADC
      ADC_ERROR_SYNCH

      You can compare the value of the flag with those masks to know what's the error.
  */
  if(adc->adc1->fail_flag) {
      Serial.print("ADC1 error flags: 0x");
      Serial.println(adc->adc1->fail_flag, HEX);
      if(adc->adc1->fail_flag == ADC_ERROR_COMPARISON) {
          adc->adc1->fail_flag &= ~ADC_ERROR_COMPARISON; // clear that error
          Serial.println("Comparison error in ADC1");
      }
  } else {
      Serial.print("Success: ");
      Serial.print(" Value ADC1: ");
      Serial.println(value2*3.3/adc->getPGA(ADC_1)/adc->getMaxValue(ADC_1), 4);
  }
  adc->adc1->fail_flag = 0;
delay(6000);

}

@pedvide pedvide added the bug label Nov 19, 2016
@pedvide
Copy link
Owner

pedvide commented Nov 19, 2016

I just pushed an update in the dev branch. I think tt fixes these problems, however my Teensy 3.6 board is an early prototype and doesn't have access to the A10, A11 pins (and hence no differential).
Can you check that they work? Use the sketch readAllPins.ino in the examples.
Connect A10 and A11 to GND and 3.3V and make sure that their values are correct, including the differential. Teensy 3.6 only has that one diff pair.

@pedvide
Copy link
Owner

pedvide commented Dec 9, 2016

Fixed with the last commit.

@pedvide pedvide closed this as completed Dec 9, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants