Forum Rule: Always post complete source code & details to reproduce any issue!
Page 4 of 17 FirstFirst ... 2 3 4 5 6 14 ... LastLast
Results 76 to 100 of 420

Thread: ADC library update, now with support for Teensy 3.1

  1. #76
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,574
    It is supports differential mode, negative numbers would be needed for the case where the negative ADC channel is higher than the positive one.

  2. #77
    That's quite a sensible idea. Thanks for the clarification!

  3. #78

    ADC library and teensy 2???

    my goal is to use the ADC library with a teensy 3.1 and i have compiled an example sketch successfully. however it will be a while before i can get various PC board changes to allow the use of the 3.1 in my project. therefore i would like to test with the teensy 2 but i get all sorts of compile errors.

    is it possible to use the ADC library with the teensy 2? any suggestions as to settings options or other magic needed to get it to work?

  4. #79
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    This library only works with Teensy 3.0 & 3.1. Teensy 2.0 is a very different kind of micro-processor.

    About the singed integer return values: The standard arduino analogRead returns an int, so I kept it that way. Then I started returning negative values as error codes. Finally I started using error flags, so that void functions can also signal errors to the user, but analogRead still returns negative error codes.
    Last edited by Pedvide; 08-05-2014 at 09:56 AM.

  5. #80
    Junior Member
    Join Date
    Aug 2014
    Posts
    2
    Hello,
    I am helping design a card to read 16 piezo sensors.
    I see ADC0-13 here
    http://www.pjrc.com/teensy/schematic.html
    but 2 look to be tied up with SCL/SDA, so only 12 free. And one sort of tied up with an activity LED, which I can remove.
    Are there other pins that can be routed for single input ADC use?
    Thanks

  6. #81
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,256
    The Teensy 3.1 actually has 20 pins that can do analog input: http://www.pjrc.com/teensy/pinout.html

    • Pins A0..A9 are available as through holes on the right side (with the usb adapter pointing up). As you mention, A4/A5 (or alternatively A2/A3) are used for i2c (SDA/SCL), but if you aren't using i2c, you can use them for analog inputs;
    • Pins A10..A11 are available as through holes on the right inside of the chip;
    • Pins A12 and A15-A17 are available as solder pads on the right side underneath the Teensy 3.1;
    • Pins A13 and A18-A20 are available as solder pads on the left side underneath the Teensy 3.1;
    • Pin A14 is available as a through hole on the back of the Teensy 3.1;
    • A18/A19 can be used for the second i2c bus if needed on the Teensy 3.1;
    • Teensy 3.0 did not have analog pins A14-A20. The A14 pin in Teensy 3.1 is the reset pin in Teensy 3.0, and pins A15-A20 are just digital pins.
    Last edited by MichaelMeissner; 08-13-2014 at 02:38 PM.

  7. #82
    Junior Member
    Join Date
    Aug 2014
    Posts
    2
    Thanks Mike, I hadn't noticed the other inputs marked A14 to A20 in the bottom picture before. Those pics could really stand to be rotated 90 degrees for easier reading.
    Click image for larger version. 

Name:	Teensy3.1.jpg 
Views:	3201 
Size:	94.0 KB 
ID:	2545

  8. #83
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,256
    There are two 'shields' to allow you to get access to the bottom pins in a shield or breadboard setup:


    Note, pin 33 is special, in that at present, it can through you into EZ Port mode on power up, if it is connected.

  9. #84
    Junior Member
    Join Date
    Jul 2014
    Posts
    8
    hi,


    my gift for christmas:

    teensy-3.1-l with/onClick image for larger version. 

Name:	teensy_31_LCD_SSD1289_board_back.JPG 
Views:	283 
Size:	215.2 KB 
ID:	2546Click image for larger version. 

Name:	teensy_31_LCD_SSD1289_22kHz_10bit.JPG 
Views:	319 
Size:	99.1 KB 
ID:	2547Click image for larger version. 

Name:	teensy_31_LCD_SSD1289_board_top.JPG 
Views:	342 
Size:	116.2 KB 
ID:	2548 DIL-48 socket and nearly ? all signals on a pin.

  10. #85
    Senior Member
    Join Date
    Sep 2013
    Location
    Hamburg, Germany
    Posts
    891
    It seems like it's not possible to use the differential pairs without accessing the bottom pads - is that correct?

  11. #86
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    One differential pair is connected to the A10-A11 pins which can be accessed from above (you can solder two pin headers so they stick out from above), the second pair is connected to A12-A13 and as you say can only be accessed from below.

  12. #87
    Senior Member
    Join Date
    Sep 2013
    Location
    Hamburg, Germany
    Posts
    891
    I didn't think of adding extra pin headers to be accessed from above, thanks for the heads-up. Maybe I was just too lazy to walk to the basement where the soldering iron is...

  13. #88

    Ring buffer with DMA

    I have a sketch working quite well using continuous analog read and ring buffer from this library. Definitely works better than just continuous read. I would like to take advantage of DMA and used the example as a guide to changing my sketch to use DMA ring buffer. The example runs fine but seems to read 0 every second read and I can not get the DMA version to work at all in my sketch.

    Can someone tell me the exact sequence of steps that are necessary to use DMA ring buffer for continuous ADC ? A sample sketch would be helpful. I don't think that timer interrupts are suitable for my application but am willing to try that as well. Would like to get DMA ring buffer working first and I think it might be all I need.

  14. #89
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    So you took the example "ringBufferDMA.ino" and added continuous conversions and every second read is 0?
    What do you mean by the DMA example runs fine, but the DMA version doesn't work? Which examples work and which don't and what modifications have you made, and if you have problems with a sketch, please post it!

  15. #90
    I did not modify the DMA ring buffer example other than to change input pin from A9 to A2 and every second read is 0. i guess i should not have said it runs fine. I pared the sketch down to the minimum? I wanted to include stuff such as the encoder reading in case there is a conflict between libraries. I think there must be some basic misunderstanding as to how the DMA buffer works thta is hopefully easy to find in the code. I can add a bunch of comments to explain what I am trying to do but here is a summary.
    I record pulses to audio using a hardware encoder. A quadrature encoder is the input device to initiate pulses. I read pulses from audio analog input and use sines to trigger a motor step in one direction and cosines to trigger a step in the other direction.



    Code:
    #define ENCODER_DO_NOT_USE_INTERRUPTS
    //#define ENCODER_OPTIMIZE_INTERRUPTS
    
    #include <Encoder.h>
    
    #include <ADC.h>
    ADC *adc = new ADC(); // adc object
    //RingBuffer *buffer = new RingBuffer;
    RingBufferDMA *dmaBuffer = new RingBufferDMA(2,ADC_0); // use dma channel 2 and ADC0
      
    //#include <Encoder.h>
    Encoder readEnc(5, 6);
    
    const int numReadings = 2500;
    const int readAudio = A2; // ADC0
    int encoder_scale;
    int minus_encoder_scale;
    
    int count = 0;
    int encoder_step_count;
    
    int newRead;
    int min_time;
    
    int up_thresh;
    int down_thresh;
    int up_zero;
    int down_zero;
    int inter_pulse;
    int max_pulse_width;
    int max_position;
    int pause_loops;
    int pause_loop_threshold;
    
    int diff;
    int center;
    int zero_diff;
    int zero_check;
    int audio_min = 1000;   // initialize at high number
    int audio_max = 0;   // initialize at low number :)
    boolean sent_pulse = false;
    boolean pause_begin;
    boolean got_pause;
    boolean playback = false;
    
    // see setup for decoder variables
    
    int audio_in;
    int read_in;
    
    int reading_index = 0;              // the index of the current reading
    
    int readings[numReadings];  // the readings from the analog input
    long total = 0;              // the running total
    int average = 0;            // the average
    
    long countloops;
    
    void setup() {
    //  digitalWriteFast(13, HIGH);
      digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
      delay(2000);  // this is needed for some fucking reason to let voltage stabilize???
      pinMode(1, OUTPUT); // step out clockwise  (used to drive audio encoder)
      pinMode(2, OUTPUT); // step out counterclockwise  (used to drive audio encoder)  
      pinMode(3, OUTPUT); // step
      pinMode(4, OUTPUT); // direction 
      pinMode(5, INPUT); // encoder, no pullup
      pinMode(6, INPUT); // encoder, no pullup  
      pinMode(9, INPUT_PULLUP); // limit CW
      pinMode(10, INPUT_PULLUP); // limit CCW 
      pinMode(13, OUTPUT);
      pinMode(A2, INPUT);
      pinMode(A4, INPUT);
      pinMode(21, INPUT_PULLUP); // switch for record/playback
      
      encoder_scale = 6;  // 
      minus_encoder_scale = encoder_scale * -1;
      
      diff = 300;  // 200 to 300? and is terrible 400 too high
      zero_diff = 80;  // was 80
      zero_check = 25;  // was 50 anything from about 7 to 150 probably fine keep it short to allow fast motion
      pause_loop_threshold = 3;
      max_pulse_width = 50;  // 50 seems right, do not change?
      inter_pulse = 2;  // time between multiple ticks from pulse sub should vary this in playback to smooth playing
      pause_loops = 0;
      
      adc->enableDMA(ADC_0);
      adc->enableInterrupts(ADC_0);  
      
    // set parameters for ADC0
      adc->setAveraging(1); // needs to be maybe 5 to 10?
      adc->setResolution(10); // set bits of resolution seems to need to be 10 
      adc->setConversionSpeed(ADC_VERY_HIGH_SPEED); // change the conversion speed
      adc->setSamplingSpeed(ADC_VERY_HIGH_SPEED); // change the sampling speed  
      adc->startContinuous(readAudio, ADC_0);  // must be continuous read   
        
      int cal_count = 1000;
      for (int thisReading = 0; thisReading < cal_count; thisReading++){
        total += adc->analogReadContinuous(ADC_0);
        delayMicroseconds(100);
      }
      center = int (total / cal_count);
      up_thresh = center + diff; 
      down_thresh = center - diff;
      up_zero = center + zero_diff;
      down_zero = center - zero_diff;     
    }
    
    void loop() {
      int read_in;
    //  buffer->write(adc->analogReadContinuous(ADC_0));  // comment this out if using DMA buffer
      newRead = readEnc.read(); 
      
      // the following could miss a step but the loop is fast enought that it probably won't if it does WTF
      if ((newRead > 0 ) and (digitalReadFast(10)== HIGH)){ 
        encoder_step_count ++;
      }
      if ((newRead < 0 ) and (digitalReadFast(9)== HIGH)){
        encoder_step_count --;
      }  
      readEnc.write(0);  // reset encodereach loop so it just reads direction single pulses
      if (encoder_step_count == encoder_scale){
        digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN)); 
        encoder_step_count = 0;  // might need to move this to next loop level
        if (!playback){
          record_cw();      
        }  
        digitalWriteFast(4, LOW); 
        for (int i=0; i < encoder_scale; i++){  
          delayMicroseconds(2);   // this delay is critical do not remove it but try 1 us      
          digitalWriteFast(3, HIGH);
          delayMicroseconds(1);
          digitalWriteFast(3, LOW);
        }
      }
      if (encoder_step_count == minus_encoder_scale){
        digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
        encoder_step_count = 0; 
        if (!playback){
          record_ccw();       
        }
        digitalWriteFast(4, HIGH); 
        for (int i=0; i < encoder_scale; i++){   
          delayMicroseconds(2);   // this delay is critical do not remove it but try 1 us
          digitalWriteFast(3, HIGH);
          delayMicroseconds(1); 
          digitalWriteFast(3, LOW);
        }
      }              
      pause_loops ++; // increments each loops is reset at pause begin  
    //  read_in = buffer->read();
      read_in = dmaBuffer->read();
      if (! pause_begin){
        if ((read_in > down_zero) && (read_in < up_zero)){ // might want && this with above if statement
          pause_begin = true;
          pause_loops = 0;
        }
      }
      if ((pause_begin) && ((read_in < down_zero) || (read_in > up_zero))){ // just left a pause
         if (pause_loops > pause_loop_threshold){  
           inter_pulse =  max(pause_loops/(encoder_scale * 4),max_pulse_width);  // need to figure out how ong the loop time is to get this right
           if (read_in > up_thresh){
             cwpulse();
           }
           if (read_in < down_thresh){
             ccwpulse();
           }
        pause_begin = false;  // reset  
        }
      }   
    }
    void dma_ch2_isr(void) {
        //int t = micros();
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
    
    //    Serial.println("DMA_CH2_ISR"); //Serial.println(t);
    
        DMA_CINT = 2; // clear interrupt
    
        // call write to tell the buffer that we wrote a new value
        dmaBuffer->write();
    
        //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
    
    }
    void adc0_isr(void) {
        //int t = micros();
    //    Serial.println("ADC0_ISR"); //Serial.println(t);
        ADC0_RA; // clear interrupt
    }
    
    void record_cw(void){ // output cw pulse to encoder
        digitalWriteFast(1, HIGH); // pin 1 high CW step this was 2 by mistake might be reason for jitter
        delayMicroseconds(2);  // might need to make this longer was 1 trying 2
        digitalWriteFast(1, LOW); // pin 1 low CW step    
    } 
    void record_ccw(void){ // output ccw pulse to encoder
        digitalWriteFast(2, HIGH); // pin 2 high CCW step
        delayMicroseconds(2);
        digitalWriteFast(2, LOW); // pin 2 low CCW step   
    } 
    
    void cwpulse(void){ // interrupt code for input CW step (not using interrupt now)
      digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
      if (digitalReadFast(10)== HIGH){ // pin 10 limit open
        digitalWriteFast(4, LOW); // pin 4 low for CW 
        for (int i=0; i < encoder_scale; i++){
          delayMicroseconds(inter_pulse);      
          digitalWriteFast(3, HIGH); // pin 3 high
          delayMicroseconds(1);
          digitalWriteFast(3, LOW); // pin 3 low
        }    
      } 
    } 
    void ccwpulse(void){ // interrupt code for input CCW step (not using interrupt now)
      digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
      if (digitalReadFast(9)== HIGH){ // pin 9 limit open
        digitalWriteFast(4, HIGH); // pin 4 high for CCW
        for (int i=0; i < encoder_scale; i++){  
          delayMicroseconds(inter_pulse);   // needed for time to read the analog input  
          digitalWriteFast(3, HIGH); // pin 3 high      
          delayMicroseconds(1);
          digitalWriteFast(3, LOW); // pin 3 low      
        }    
      }  
    }

  16. #91
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    Can you try switching the adc interrupt off? I think that might be the problem.
    Originally I included the DMA stuff more as a test than as a finished thing, but I haven't really worked on that much.

  17. #92
    no difference with adc interrupt off. i think there is some sort of conflict with encoder.

  18. #93

    Compiling using this Library

    Hello!

    I appreciate all of the hard work to create this post. I am trying to include this library to run the two ADC simultaneously to read in two different voltages, however, I cant seem to get the library to load properly. I've followed the instructions but I get the following error. Compiling the examples gives the same error.

    Code:
    C:\Users\Somniare\Documents\Arduino\libraries\ADC/ADC.h:52:24: fatal error: DMAChannel.h: No such file or directory
    compilation terminated.
    I am using TeensyDuino 1.19 and Arduino 1.0.5-r2

  19. #94
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    Mmm, I compiled the library with the latest release of Teensyduino (1.20), it's possible that it doesn't work with the 1.19 version.
    Can you update your Teensyduino and see if it works?

  20. #95
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,574
    Yes, indeed DMAChannel.h is one of the new features in 1.20. It's so much better than the old, conflict-prone way used with 1.19 and older, so you should definitely install 1.20-rc5.

  21. #96
    Senior Member
    Join Date
    Mar 2013
    Posts
    651
    When using the 1.2V scale does that also mean the max safe voltage on the analog pins is 1.2V or can they still be driven to 3.3V even if they cant read it any higher then 1.2v?
    A project im working on will be sending analog voltages to several pins, I plan to use the 1.2V internal ref but im not sure if I should install 1.2V protection Zener's or if 3-3.3V will be ok.

    Im using several op amps to buffer the analog voltages but I like to have some protections in place.

  22. #97
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    The manual doesn't say much about this:
    For proper conversion, the input voltage must fall between VREFH and VREFL. If the input is equal to or exceeds VREFH, the converter circuit converts the signal to 0xFFF (full scale 12-bit representation), 0x3FF (full scale 10-bit representation) or 0xFF (full scale 8-bit representation). If the input is equal to or less than VREFL, the converter circuit converts it to 0x000.
    The datasheet says that in operating conditions, Vin should be between VREFH and VREFL.

    The pins are of course safe until 3.3 V (or 5.0 V for Teensy 3.1 analog and digital pins), but I guess it's possible that the ADC gets damaged. I can't give you a definite answer, sorry.

  23. #98
    Quote Originally Posted by PaulStoffregen View Post
    Yes, indeed DMAChannel.h is one of the new features in 1.20. It's so much better than the old, conflict-prone way used with 1.19 and older, so you should definitely install 1.20-rc5.
    I am using the TAR download rather than the installer as I am using Eclipse. Is there a new version of that TAR file with DMAChannel in it, the one I downloaded a few days ago (teensy_1.15_mac_1.14.tar.gz) does not seem to have it.

  24. #99
    Senior Member
    Join Date
    Jul 2013
    Posts
    272
    Update: Now it works with the Audio library:
    Teensy 3.0 is compatible, except if you try to use the Audio library ADC input (AudioInputAnalog), because there's only one ADC module so you can't use it for two things.
    Teensy 3.1 is compatible. If you want to use AudioInputAnalog and the ADC you have to use the ADC_1 module, the Audio library uses ADC_0. Any calls to functions that use ADC_0 will most likely crash the program. Note: make sure that you're using pins that ADC_1 can read (see pictures above)! Otherwise the library will try to use ADC_0 and it won't work!!

    It's important to create the ADC object before the Audio objects, for example:

    Code:
    // FFT Test
    //
    // Compute a 1024 point Fast Fourier Transform (spectrum analysis)
    // on audio connected to the Left Line-In pin.  By changing code,
    // a synthetic sine wave can be input instead.
    //
    // The first 40 (of 512) frequency analysis bins are printed to
    // the Arduino Serial Monitor.  Viewing the raw data can help you
    // understand how the FFT works and what results to expect when
    // using the data to control LEDs, motors, or other fun things!
    //
    // This example code is in the public domain.
    
    
    
    
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    
    #include <ADC.h>
    
    // CREATE THE ADC OBJECT FIRST, BEFORE ALL AUDIO STUFF!!
    ADC *adc = new ADC(); // adc object
    const int readPin = A3; // ADC0
    
    // Create the Audio components.  These should be created in the
    // order data flows, inputs/sources -> processing -> outputs
    // Using adafruit mic-amp, edit library to turn-off internal voltage reference in 
    // inputAnalog.cpp 
    
    AudioInputAnalog       adc1(15);
    AudioSynthWaveformSine sinewave;
    AudioAnalyzeFFT1024    myFFT;
    
    
    
    // Connect either the live input or synthesized sine wave
    AudioConnection patchCord1(adc1, 0, myFFT, 0);
    //AudioConnection patchCord1(sinewave, 0, myFFT, 0);
    
    
    
    
    void setup() {
      // Audio connections require memory to work.  For more
      // detailed information, see the MemoryAndCpuUsage example
      AudioMemory(12);
      
      pinMode(15, INPUT);
      pinMode(14, INPUT);
      
      // Configure the window algorithm to use
      //myFFT.windowFunction(AudioWindowHanning1024);
      myFFT.windowFunction(NULL);
    
      // Create a synthetic sine wave, for testing
      // To use this, edit the connections above
      sinewave.amplitude(0.8);
      sinewave.frequency(1034.007);
    
    
      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
    
    }
    
    int value = 0;
    
    void loop() {
      float n;
      int i;
      
      value = adc->analogRead(readPin, ADC_1); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    
      if (myFFT.available()) {
        // each time new FFT data is available
        // print it all to the Arduino Serial Monitor
        //Serial.print("T: "); //Testing touchRead
        //Serial.print(touchRead(0));
        Serial.print("\t FFT: ");
        for (i=0; i<40; i++) {
          n = myFFT.read(i);
          if (n >= 0.005) {
            Serial.print(n);
            Serial.print(" ");
          } else {
            Serial.print("  -  "); // don't print "0.00"
          }
        }
        Serial.println();   
    
        Serial.print("Pin: ");
        Serial.print(readPin);
        Serial.print(", value ADC1: ");
        Serial.println(value*3.3/adc->getMaxValue(ADC_1), DEC);
      }
    }
    Last edited by Pedvide; 10-31-2014 at 09:22 PM.

  25. #100
    Senior Member
    Join Date
    Mar 2013
    Posts
    651
    Pedvide,
    just looking at some of the library, mainly synchronized reads. I had planned to read 5 pins but may add 1 more so I don't have to jump between 2 different read modes. Sadly I am traveling all week so reading up and making some hopefully working test software is as far as I can go.

    I have to say some of the library goes right over my head.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •