pySerial revisited. Some Jason Mraz would be appreciated.

[ newline ] [ Arduino begin: parity ]

[ pySerial API ]

[ eLinux serial ] [ struct unpack ]

[ embeddedrelated ]

Intermittent failures. This is a screenshot of the txt file when things do seem to work.

Most of today went on fixing the serial communication. Earlier, I was trying to use pySerial’s readline(), and was changing the last two bytes of the packet to get \r and \n. Then, I come across one answer on stack exchange encouraging using read() instead.

That didn’t work out for quite a while, possibly because I wasn’t thoroughly updating Arduino’s firmware.

Anyway, it seems to work now (most of the time). Turns out that I can change the parity, stop bits, and number of bits in a byte for serial – but the default configuration works.

The main culprit, besides correcting the firmware, was probably not waiting for the serial buffer (4096 bytes?) to be filled. Sleep, being so good as it is, seems to fix that.



import serial
import time
from time import gmtime, strftime
import datetime

ser = serial.Serial(
    port='/dev/ttyACM0',
    baudrate=57600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout=1
    )

f = open('dataFile.txt','w')
f.write(strftime("%Y-%m-%d %H:%M:%S", gmtime())+'\n')

l = ['p', 'l', 'e', 'a', 's', 'e', ' ', 'w', 'o', 'r', 'k']

i = 0
while(i<10):
    time.sleep(1) #for filling up the buffer?
    if ser.inWaiting():
        data = ser.read(ser.inWaiting())
        f.write(data)
    #else: reset Uno...
    #    print("waiting\n")
    #print struct.unpack('BBBBBBBBBBBBBBBB', data)
    
    print i
    #print l[i]
    i = i+1

f.close()
ser.close()
/////////////////////////////////////////////
// Team UMAR-VARS                          //
// Arduino code for grabbing               //
// - ECG/EMG data (A0, A1)                 //
// - PPG data     (A2)                     //
// - acc data     (A5, A6) - I2C - raw     //
////////////////////////////////////////////////////////////////////////////////////////////
// Links:
// - User manual
// https://www.olimex.com/Products/Duino/Shields/SHIELD-EKG-EMG/resources/SHIELD-EKG-EMG.pdf
// - ECG code from Stan12's code (which is adapted from Olimex's sample code)
// https://www.olimex.com/forum/index.php?topic=572.0
// - MPU-6050 code from JohnChi's example sketch
////////////////////////////////////////////*BEGIN*/////////////////////////////////////////

  #include<FlexiTimer2.h>  //http://playground.arduino.cc/Main/FlexiTimer2 for interrupts (timing)
  //#include <compat/deprecated.h> //seems to be outdated
  #include<Wire.h>                 //for I2C

  // MPU-6050:
      const int MPU=0x68;  // I2C address of the MPU-6050. Max 7 bits.
      //int16_t AcX,AcY,AcZ; //,Tmp,GyX,GyY,GyZ;  
  // ECG shield:
      volatile unsigned char CurrentCh = 0;       // Current channel being sampled.
      volatile unsigned int  ADC_Value = 0;	  // ADC current value, 2 byte value (16 bits total)
      volatile unsigned char TXBuf[2+1+2*3+2*3];  // sync + packetNum + heartData + accData
      volatile unsigned char TXIndex;             // Next byte to write in the transmission packet.

  void setup() {
      //pinMode(13, OUTPUT);
      
  // MPU-6050:   
      //do NOT place noInterrupts() here. Seems to affect I2C?
      Wire.begin();                               // as master
      Wire.beginTransmission(MPU);                // "queue bytes for transmission with write(), transmit by calling endTransmission()"
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);
      
  // ECG shield:
      noInterrupts();  // Disable all interrupts before initialization
   
      //Packet | units?
      TXBuf[0] = 0xa5;    //Sync 0 -- could help with parsing -- unchanged for legacy
      TXBuf[1] = 0xa5;
      TXBuf[2] = 0x0;     //Packet counter -- helps to see what we might miss
      TXBuf[3] = 0x02;    //ECG-1 | A0 High Byte
      TXBuf[4] = 0x00;    //ECG-1 | A0 Low Byte
      TXBuf[5] = 0x02;    //ECG-2 | A1 High Byte
      TXBuf[6] = 0x00;    //ECG-2 | A1 Low Byte
      TXBuf[7] = 0x02;    //PPG   | A2 High Byte
      TXBuf[8] = 0x00;    //PPG   | A2 Low Byte
      TXBuf[9] = 0x02;    //AccX  | I2C High Byte
      TXBuf[10] = 0x00;    //AccX  | I2C Low Byte
      TXBuf[11] = 0x02;   //AccY  | I2C High Byte
      TXBuf[12] = 0x00;   //AccY  | I2C Low Byte
      TXBuf[13] = 0x02;   //AccZ  | I2C High Byte
      TXBuf[14] = 0x00;   //AccZ  | I2C Low Byte
   
      FlexiTimer2::set(4, 1.0/1000, Timer2_Overflow_ISR); //4 units of 1 ms resolution => sampling at FS
      // FlexiTimer2::set(unsigned long units, double resolution, void (*f)())

      FlexiTimer2::start();
      //enables the interrupt.
 
      // Serial Port
      Serial.begin(57600, SERIAL_8N1);       //why this baud rate? too slow vs too many errors

      interrupts();              // Enable all interrupts after initialization has been completed
  }

  void Timer2_Overflow_ISR() {

  // ECG/PPG:
    //Read the ADC channels (ECG-1, ECG-2, PPG)
    for(CurrentCh=0; CurrentCh<3; CurrentCh++) {
      ADC_Value = analogRead(CurrentCh); //first two channels reserved for I2C
      TXBuf[2*CurrentCh + 3] = ((unsigned char)((ADC_Value & 0xFF00) >> 8));// Write High Byte
      TXBuf[2*CurrentCh + 4] = ((unsigned char) (ADC_Value & 0x00FF));	    // Write Low Byte
    }

    // Send Packet
    for(TXIndex=0;TXIndex<15;TXIndex++){
      Serial.write(TXBuf[TXIndex]);
      //delay(100);
    }
    Serial.println("");


    //Serial.println(TXBuf[1], HEX);
    TXBuf[2]++;	                         // Increment the packet counter
    //digitalWrite(13, LOW);

  }

  void loop() {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);                    // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU,6,true);        // request 6 (consecutive?) registers
    
    int i = 0;
    while(Wire.available() && i<6) {     // Reads the following 6 registers:
      TXBuf[9+i]=Wire.read();            // 0x3B (ACCEL_XOUT_H), 0x3C (ACCEL_XOUT_L)
      i++;                               // 0x3D (ACCEL_YOUT_H), 0x3E (ACCEL_YOUT_L)
    } 
    //__asm__ __volatile__ ("sleep");
  }

Flexitimer: can we go from 250 Hz to 2kHz?

Why would we need a higher sampling rate? Our BME expert’s understanding is that a higher rate would make his signal processing less computationally intensive (although more memory resources would be called in.)

The second question is, can we do that?

It takes about 100 microseconds (0.0001 s) to read an analog input, so the maximum reading rate is about 10,000 times a second.

[analogread]

And, we’re sampling 5 channels. So it could be possible to sample at 2 kHz. But can we do that, and get readings over I2C, and communicate over serial?

The answer depends on:

  • How much data we want to transmit between each sampling event (packet size and baud rate)
    • a 15 byte packet at 115200 baud rate seems to take about 1/850 seconds.
    • I2C reads seem to be very fast compared to serial (kHz)
  • What range of arguments FlexiTimer2 supports
    • 1 unit of 1/1000 seconds seems to fail. 2, 3 and 4 ms units do work.
  • How timers on the Arduino work
    • Potential workaround, not using FlexiTimer at all.

The easiest thing to do is to just sending 15 byte packets over serial, with interrupts every 2 ms (487.427 Hz), and serial baud rate set to 115200.

Here are some scope captures to visualize what’s happening. In the first set, the yellow channel is driven high whenever the Uno reads accelerometer data over I2C. The blue channel goes high over the execution of the function called by FlexiTimer’s interrupts. Over different captures, I change the timing between interrupts from 4 ms, to 3, to 2, to 1 ms. I also switch the baud rates between 57600 and 115200.

In the next set of captures, I change the interrupt timing from 4 ms to 2 ms while showing the data packets sent over Tx. It is clear that for the 2 ms interrupts, we need to bump up the baud rate to make sure that all of our 15 bytes get sent in time!

The final set of captures for the day (night) showing different packets sizes, and what bytes look like on serial:

  



/////////////////////////////////////////////
// Team UMAR-VARS                          //
// Arduino code for grabbing               //
// - ECG/EMG data (A0, A1)                 //
// - PPG data     (A2)                     //
// - acc data     (A5, A6) - I2C - raw     //
////////////////////////////////////////////////////////////////////////////////////////////
// Links:
// - User manual
// https://www.olimex.com/Products/Duino/Shields/SHIELD-EKG-EMG/resources/SHIELD-EKG-EMG.pdf
// - ECG code from Stan12's code (which is adapted from Olimex's sample code)
// https://www.olimex.com/forum/index.php?topic=572.0
// - MPU-6050 code from JohnChi's example sketch
////////////////////////////////////////////*BEGIN*/////////////////////////////////////////

  #include<FlexiTimer2.h>  //http://playground.arduino.cc/Main/FlexiTimer2 for interrupts (timing)
  //#include <compat/deprecated.h> //seems to be outdated
  #include<Wire.h>                 //for I2C

  // MPU-6050:
      const int MPU=0x68;  // I2C address of the MPU-6050. Max 7 bits.
      //int16_t AcX,AcY,AcZ; //,Tmp,GyX,GyY,GyZ;  
  // ECG shield:
      volatile unsigned char CurrentCh = 0;       // Current channel being sampled.
      volatile unsigned int  ADC_Value = 0;	  // ADC current value, 2 byte value (16 bits total)
      volatile unsigned char TXBuf[1+1+2*3+2*3];  // sync + packetNum + heartData + accData
      volatile unsigned char TXIndex;             // Next byte to write in the transmission packet.

  void setup() {
      pinMode(11, OUTPUT);
      pinMode(10, OUTPUT);
      
  // MPU-6050:   
      //do NOT place noInterrupts() here. Seems to affect I2C?
      Wire.begin();                               // as master
      Wire.beginTransmission(MPU);                // "queue bytes for transmission with write(), transmit by calling endTransmission()"
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);
      
  // ECG shield:
      noInterrupts();  // Disable all interrupts before initialization
   
      //Packet | units?
      TXBuf[0] = 0xFF;    //Sync 0 -- could help with parsing -- unchanged for legacy
      TXBuf[1] = 0x0;     //Packet counter -- helps to see what we might miss
      TXBuf[2] = 0x02;    //ECG-1 | A0 High Byte
      TXBuf[3] = 0x00;    //ECG-1 | A0 Low Byte
      TXBuf[4] = 0x02;    //ECG-2 | A1 High Byte
      TXBuf[5] = 0x00;    //ECG-2 | A1 Low Byte
      TXBuf[6] = 0x02;    //PPG   | A2 High Byte
      TXBuf[7] = 0x00;    //PPG   | A2 Low Byte
      TXBuf[8] = 0x02;    //AccX  | I2C High Byte
      TXBuf[9] = 0x00;    //AccX  | I2C Low Byte
      TXBuf[10] = 0x02;   //AccY  | I2C High Byte
      TXBuf[11] = 0x00;   //AccY  | I2C Low Byte
      TXBuf[12] = 0x02;   //AccZ  | I2C High Byte
      TXBuf[13] = 0x00;   //AccZ  | I2C Low Byte
      TXBuf[14] = 0x5a;   //end packet
      
      FlexiTimer2::set(2, 1/1000, Timer2_Overflow_ISR); //4 units of 1 ms resolution => sampling at FS
      // FlexiTimer2::set(unsigned long units, double resolution, void (*f)())
      // E.g. units=1, resolution = 1.0/3000 will call f 3000 times per second, 
      // whereas it would be called only 1500 times per second when units=2.

      //serial prints seem to freeze for certain rates. Data might still be coming through.

      FlexiTimer2::start();
      //enables the interrupt.
 
      // Serial Port
      Serial.begin(115200);       //why this baud rate? too slow vs too many errors

      interrupts();              // Enable all interrupts after initialization has been completed
  }

  void Timer2_Overflow_ISR() {
        digitalWrite(11, HIGH);

    // Serial.println("Hey!");   //use for experimenting with interrupt frequency
  
  // ECG/PPG:
    //Read the ADC channels (ECG-1, ECG-2, PPG)
    for(CurrentCh=0; CurrentCh<3; CurrentCh++) {
      ADC_Value = analogRead(CurrentCh); //first two channels reserved for I2C
      TXBuf[2*CurrentCh + 2] = ((unsigned char)((ADC_Value & 0xFF00) >> 8));// Write High Byte
      TXBuf[2*CurrentCh + 3] = ((unsigned char) (ADC_Value & 0x00FF));	    // Write Low Byte
    }
    // http://arduino.cc/en/Reference/analogRead
    // 10-bit ADC, mapping input voltages 0-5V -> 0-1023 => resolution = 4.9 mV
    // The input range and resolution can be changed using analogReference().
    // It takes about (0.0001s to read an analog input => max rate is about 10,000 Hz.
 
  // MPU-6050 (I2C routine):
    //couldn't get it to work here. Moved to void loop().
    //MPU_I2C_read();
    //delay(100);
    
    //Serial.print(TXBuf[1], HEX);
    // Send Packet
    
    
    for(TXIndex=0;TXIndex<15;TXIndex++){//14
      Serial.write(TXBuf[TXIndex]);
      //delay(100);
    }
    
    //Serial.println("");


    //Serial.println(TXBuf[1], HEX);
    TXBuf[1]++;	                         // Increment the packet counter
    digitalWrite(11, LOW);

  }
/*
  void MPU_I2C_read(){
    //digitalWrite(13, HIGH);    
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);                    // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU,6,true);        // request 6 (consecutive?) registers
    
    int i = 0;
    while(Wire.available() && i<6) {     // Reads the following 6 registers:
      TXBuf[8+i]=Wire.read();            // 0x3B (ACCEL_XOUT_H), 0x3C (ACCEL_XOUT_L)
      i++;                               // 0x3D (ACCEL_YOUT_H), 0x3E (ACCEL_YOUT_L)
    }                                    // 0x3F (ACCEL_ZOUT_H), 0x40 (ACCEL_ZOUT_L)
    //digitalWrite(13, LOW);
  }
 */ 
  void loop() {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);                    // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU,6,true);        // request 6 (consecutive?) registers
    
    digitalWrite(10, HIGH);
    int i = 0;
    while(Wire.available() && i<6) {     // Reads the following 6 registers:
      TXBuf[8+i]=Wire.read();            // 0x3B (ACCEL_XOUT_H), 0x3C (ACCEL_XOUT_L)
      i++;                               // 0x3D (ACCEL_YOUT_H), 0x3E (ACCEL_YOUT_L)
    } 
    digitalWrite(10, LOW);
    //__asm__ __volatile__ ("sleep");
  }

ADC is working, atleast for a 1 Hz sine wave…

[ Thiyagarajan’s e2e code ]

Using GPAIN0 (channel 1)

Capture

The signal generator doesn’t work single ended. Need both GPAIN0 and GND. Also, negative voltages just get clipped (a fine diode in the system!)

Now to figure out a way for actually sampling at the rates the SAR ADC is capable of. These samples are way too slow because I’m printing to console. fprintf() doesn’t seem to work. DMA events are probably the way to go, and we have to use the LCD on the board!

#include <usbstk5515.h>
#include <stdio.h>
#include <sar.h> //defines the register addresses (pointer stuff!)

void adc_init2() {
	*SARCTRL= 0
			| ( 0 << 15 ) 	// ADC conversion start (0 is no conversion)
			| ( 1 << 12 ) 	// select Channel 1 (try 0, 2, and 4)
			| ( 0 << 11 )	// 0 - Normal mode, 1 - multi channel mode
			| ( 0 << 10 ); 	// back to back conversions

	*SARCLKCTRL = 149; 		// 1Mhz Clock

	*SARPINCTRL = 0
			| ( 1 << 14 ) 	// 12-15 always of data register
			| ( 1 << 13 ) 	// power up bias
			| ( 1 << 12 ) 	// analog power to sar
			| ( 1 << 8 ) 	// Ref V set to VDD_ANA (not bandgap)
			| ( 1 << 1 ); 	// 1: ch0 grounded , 0 ch0 is not grounded GNDON

	*SARGPOCTRL = 0; /*
		        | ( 1 << 3 ) // GPAIN3 Driven high
			| ( 1 << 2 ) // GPAIN2 Driven high
			| ( 1 << 1 ) // GPAIN1 Driven high
			| ( 1 << 0 ); // GPAIN0 Driven high
		 */
}

void main (void)
 {
	int i;

	USBSTK5515_init();
	adc_init2();

	*SARCTRL |= 0x8000; // start ADC conversion

	for(i=0;i<=100000;i++) {
		//printf("we see...");
		if((*SARDATA & 0x8000)==1){
			printf("ADCbusy: %d\n", 0x8000 & *SARDATA);
		} else printf("%d\n", 0x3FF & *SARDATA); //DATA is bits 0-9
	}
}

FlexiTimer2 under the scope!

To see how consistent our data sampling is, I made Pin 13 (blue channel) go HIGH whenever the interrupt function started executing, and drove it LOW again when the function ended. Pin 12 (yellow channel) goes HIGH right before we start reading the acceleration data on the I2C bus, and is driven it LOW when the reading completes.

The code is provided after the screenshots.

Observations:

  • We get a (reasonably?) consistent sampling rate of around 249 Hz with the FlexiTimer2, quite close to the desired 250 Hz.
  • I2C reading happens at about 920 Hz.
  • Interesting things happen when the two events come close, but does it throw the sampling off?
  • Using noInterrupts() and interrupts() to enclose the I2C reading doesn’t seem to affect much.
  • A digital pin driven high (hiZ on load?) gets pulled to about 680 mV (on pin 12), but only 580 mV on pin 13. That means that the drop across the on-board LED 13 is about a 100 mV!

Scope captures, without having I2C reads within no/interrupts():

TEK00026

zoomed in:

TEK00027

Now, I2C reads are enclosed within no/Interrupts():

TEK00028

Zoomed in:

TEK00029

Trigger on I2C’s LED for getting a rough sampling rate (~920 Hz):TEK00030 TEK00031 TEK00032

/////////////////////////////////////////////
// Team UMAR-VARS                          //
// Arduino code for grabbing               //
// - ECG/EMG data (A0, A1)                 //
// - PPG data     (A2)                     //
// - acc data     (A5, A6) - I2C - raw     //
////////////////////////////////////////////////////////////////////////////////////////////
// Links/Credits:
// - User manual
// https://www.olimex.com/Products/Duino/Shields/SHIELD-EKG-EMG/resources/SHIELD-EKG-EMG.pdf
// - ECG code from Stan12's code (which is adapted from Olimex's sample code)
// https://www.olimex.com/forum/index.php?topic=572.0
// - MPU-6050 code from JohnChi's example sketch
////////////////////////////////////////////*BEGIN*/////////////////////////////////////////
 
  #include&amp;lt;FlexiTimer2.h&amp;gt;;  //http://playground.arduino.cc/Main/FlexiTimer2 for interrupts (timing)
  //#include&amp;lt;compat/deprecated.h&amp;gt;; //seems to be outdated
  #include&amp;lt;Wire.h&amp;gt;;                 //for I2C
 
  // MPU-6050:
      const int MPU=0x68;  // I2C address of the MPU-6050
      int i=0;
      //int16_t AcX,AcY,AcZ; //,Tmp,GyX,GyY,GyZ;  
  // ECG shield:
      volatile unsigned char CurrentCh = 0;       // Current channel being sampled.
      volatile unsigned int  ADC_Value = 0;   // ADC current value, 2 byte value (16 bits total)
      volatile unsigned char TXBuf[1+1+2*3+2*3];  // sync + packetNum + heartData + accData
      volatile unsigned char TXIndex;             // Next byte to write in the transmission packet.
 
  void setup() {
    pinMode(13, OUTPUT);
    pinMode(12, OUTPUT);
  // MPU-6050:   
      //do NOT place noInterrupts() here. Seems to affect I2C?
      Wire.begin();
      Wire.beginTransmission(MPU);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);
       
  // ECG shield:
      noInterrupts();  // Disable all interrupts before initialization
    
      //Packet | units?
      TXBuf[0] = 0xa5;    //Sync 0 -- could help with parsing -- unchanged for legacy
      TXBuf[1] = 0x0;     //Packet counter -- helps to see what we might miss
      TXBuf[2] = 0x02;    //ECG-1 | A0 High Byte
      TXBuf[3] = 0x00;    //ECG-1 | A0 Low Byte
      TXBuf[4] = 0x02;    //ECG-2 | A1 High Byte
      TXBuf[5] = 0x00;    //ECG-2 | A1 Low Byte
      TXBuf[6] = 0x02;    //PPG   | A2 High Byte
      TXBuf[7] = 0x00;    //PPG   | A2 Low Byte
      TXBuf[8] = 0x02;    //AccX  | I2C High Byte
      TXBuf[9] = 0x00;    //AccX  | I2C Low Byte
      TXBuf[10] = 0x02;   //AccY  | I2C High Byte
      TXBuf[11] = 0x00;   //AccY  | I2C Low Byte
      TXBuf[12] = 0x02;   //AccZ  | I2C High Byte
      TXBuf[13] = 0x00;   //AccZ  | I2C Low Byte
       
      FlexiTimer2::set(4, 1.0/1000, Timer2_Overflow_ISR); //4 units of 1 ms resolution =&amp;gt; sampling at FS
      // FlexiTimer2::set(unsigned long units, double resolution, void (*f)())
      // E.g. units=1, resolution = 1.0/3000 will call f 3000 times per second, 
      // whereas it would be called only 1500 times per second when units=2.
 
      //serial prints seem to freeze for certain rates. Data might still be coming through.
 
      FlexiTimer2::start();
      //enables the interrupt.
  
      // Serial Port
      Serial.begin(57600);       //why this baud rate? too slow vs too many errors
 
      interrupts();              // Enable all interrupts after initialization has been completed
  }
 
  void Timer2_Overflow_ISR() {
    digitalWrite(13, HIGH);
    // Serial.println(&amp;quot;Hey!&amp;quot;);   //use for experimenting with interrupt frequency
   
  // ECG/PPG:
    //Read the ADC channels (ECG-1, ECG-2, PPG)
    for(CurrentCh=0; CurrentCh&amp;lt;3; CurrentCh++) {
      ADC_Value = analogRead(CurrentCh); //first two channels reserved for I2C
      TXBuf[2*CurrentCh + 2] = ((unsigned char)((ADC_Value &amp;amp; 0xFF00) &amp;gt;&amp;gt; 8));// Write High Byte
      TXBuf[2*CurrentCh + 3] = ((unsigned char) (ADC_Value &amp;amp; 0x00FF));      // Write Low Byte
    }
    // http://arduino.cc/en/Reference/analogRead
    // 10-bit ADC, mapping input voltages 0-5V -&amp;gt; 0-1023 =&amp;gt; resolution = 4.9 mV
    // The input range and resolution can be changed using analogReference().
    // It takes about (0.0001s to read an analog input =&amp;amp;amp;amp;amp;gt; max rate is about 10,000 Hz.
  
  // MPU-6050 (I2C routine):
    //couldn't get it to work here. Moved to void loop().
     
    //Serial.print(TXBuf[1], HEX);
    // Send Packet
    for(TXIndex=0;TXIndex&amp;lt;13;TXIndex++){
      Serial.write(TXBuf[TXIndex]);
    }
    Serial.println(&amp;quot;&amp;quot;);
 
 
    //Serial.println(TXBuf[1], HEX);
    TXBuf[1]++;                          // Increment the packet counter
 digitalWrite(13, LOW);
  }
 
  void loop() {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);                    // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU,6,true);        // request 6 (consecutive?) registers
    
    digitalWrite(12, HIGH);
 
    i = 0;
    noInterrupts();   // commented out for captures 1 and 2 (26, 27)
    

    while(Wire.available() &amp;amp;&amp;amp; i&amp;lt;6) {     // Reads the following 6 registers:
      TXBuf[8+i]=Wire.read();            // 0x3B (ACCEL_XOUT_H), 0x3C (ACCEL_XOUT_L)
      i++;                               // 0x3D (ACCEL_YOUT_H), 0x3E (ACCEL_YOUT_L)
    }                                    // 0x3F (ACCEL_ZOUT_H), 0x40 (ACCEL_ZOUT_L)
    interrupts(); // commented out for captures 1 and 2 (26, 27)
    //delay(2);                          // occasionally helps with serial.print()
 
    //__asm__ __volatile__ (&amp;quot;sleep&amp;quot;);
    digitalWrite(12, LOW);
  }

Redoing the codec breakout

Schematics from [ TLV320AIC3101EVM (PDF) ] | [ electret mics ]

Screen Shot 2015-03-22 at 1.06.43 AMScreen Shot 2015-03-22 at 1.07.13 AMUpdate March 23:

[ pin jumpers ]

SMD parts are numbered by size, not R/C values.

PWM -> cap -> analog signal

http://en.wikipedia.org/wiki/Reconstruction_filter

s = tf(‘s’);
C1 = 47e-12;
C2 = 47e-6;
R = 33;
H = C2 / (C1 + C2 + s*R*C1*C2);
bode(H)

response