Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: attachInterrupt issue - function seems to be called twice

Threaded View

  1. #1

    Question attachInterrupt issue - function seems to be called twice

    I've been playing around with some analog devices ADCs (SPI parts). One that I'm fairly familiar with is the AD7794. However, I've never used it in continuous read mode. (Teensy 3.0, Teensyduino 1.18)

    In continuous read, the part uses its DOUT to indicate conversion complete and ready to read by pulling it low. You then clock in 24 bits of 0 to read the 24 bit data register, and DOUT is pulled high as soon as the last bit is clocked out. I'm just using the SPI.h library for this.

    The problem I'm having is that the interrupt routine runs twice, resulting in valid data the first time, and 0xFFFFFF the second, since it's just reading the DOUT line pulled high. I'm new to the world of Arduino/Teensy, so I'm not sure if I'm misunderstanding how attachInterrupt works, and how it masks the interrupt its processing. Anyway, here is what I see on the scope: DOUT is pulled low, three bytes of 0 are clocked in, all good, but then it clocks in another 3 bytes of 0's for no apparent reason (DOUT is high). I've tried putting a delay inside the interrupt function in case it was catching the last 0 on the data line, but it makes no difference.

    What am I missing?

    Click image for larger version. 

Name:	DS1Z_QucikPrint1.png 
Views:	471 
Size:	52.3 KB 
ID:	1642

    Code:
    #include <SPI.h>
    
    volatile long adcValue;  // AD7794 continuous read value 
    
    // attachInterrupt function for AD7794 continuous read
    
    void readADC() {
       adcValue = SPI.transfer(0x00) << 16 | SPI.transfer(0x00) << 8 | SPI.transfer(0x00); // clock in 24 0's to read AD7794 data register
    }
    
    void setup() {
      
      Serial.begin(9600);
    
      // setup _CS_ AD7794
      pinMode(6, OUTPUT); digitalWrite(6, HIGH);
      
      // setup interrupt pin (wired to pin 12 - was originally attaching interrupt to pin 12, but moved in case of SPI library conflict - but no difference)
      pinMode(9, INPUT);
    
      SPI.begin();
      delay(3000);
      
      digitalWrite(6, LOW); // select AD7794
      
      for (int i = 0; i < 8; i++) { // reset AD7794
        SPI.transfer(0xFF);
      }
      delay(1); // settle time only 10uS actually needed
      
    // *** this is just set and readback code for the configuration registers on the AD7794 while I'm testing the part ***
    
      Serial.println(); Serial.println("...............<<<<>>>>................."); Serial.println();
      
    // **** STATUS REGISTER ****
    
      SPI.transfer(0b01000000); // set to read the Status register - 8 bits
      long response = SPI.transfer(0x80);
      Serial.print("Status Register: "); Serial.println(response);
      delay(1);
      
    // ***** CONFIGURATION REGISTER ****
    
      SPI.transfer(0b01010000); // set to read the register - 16 bits
      response = SPI.transfer(0x80) << 8 | SPI.transfer(0x80);
      Serial.print("Configuration Register: "); Serial.println(response);
      
      SPI.transfer(0b00010000); // set to write the register - 16 bits
      SPI.transfer(0b00010000); SPI.transfer(0b00100000);
      delay(1);
      
      SPI.transfer(0b01010000); // set to read back the configuration - 16 bits
      response = SPI.transfer(0x80) << 8 | SPI.transfer(0x80);
      Serial.print("Configuration Register: "); Serial.println(response);
      delay(1);
      
    // ***** MODE REGISTER ****  
    
      SPI.transfer(0b01001000);  // set to read the mode register - 16 bits
      response = SPI.transfer(0x80) << 8 | SPI.transfer(0x80);
      Serial.print("Mode Register: "); Serial.println(response);
      delay(1);
      
    // Internal Calibration: zero scale
      SPI.transfer(0b00001000); //select mode register for write
      SPI.transfer(0b10000000); SPI.transfer(0b00001000); //write configuration bits to calibrate
      delay(1); //wait a moment
      SPI.transfer(0b01001000); //select mode register for read
      response = SPI.transfer(0x80) << 8 | SPI.transfer(0x80); //read new configuration
      Serial.print("Mode Register: "); Serial.println(response);
      delay(1);
      
    // Internal Calibration: full scale
      SPI.transfer(0b00001000); //select mode register for write
      SPI.transfer(0b10100000); SPI.transfer(0b00001000); //write configuration bits
      delay(1); //wait a moment
      SPI.transfer(0b01001000); //select mode register for read
      response = SPI.transfer(0x80) << 8 | SPI.transfer(0x80); //read new configuration
      Serial.print("Mode Register: "); Serial.println(response);
      delay(1);
      
    // Return to continuous conversion mode
      SPI.transfer(0b00001000); //select mode register for write
      SPI.transfer(0b00000000); SPI.transfer(0b00001000); //write configuration bits
      delay(1); //wait a moment
      SPI.transfer(0b01001000); //select mode register for read
      response = SPI.transfer(0x80) << 8 | SPI.transfer(0x80); //read new configuration
      Serial.print("Mode Register: "); Serial.println(response);
      delay(500);
    
    
    // enable interrupt on pin 6 and initiate continuous read
      
      attachInterrupt(9, readADC, LOW);
      SPI.transfer(0x5C);
      
    }
    
    
    void loop() {
    
    }
    Last edited by adeptrc; 03-16-2014 at 08:06 PM. Reason: Clarify platform

Tags for this Thread

Posting Permissions

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