Hello all, this is my first time posting but I am completely perplexed. I have a project involving a Teensy 3.6 and an encoder. It's a wheel which mounts on a car bumper and records the vehicle's position to the microSD card. The encoder never outputs more than about 400 hz. I'm noticing an apparent delay of up to 96 microseconds per sample in the data.
Here's a link to the data file:https://drive.google.com/open?id=1T_qQJ6P6mnl2qhEdIbuD69vT4ytKL-w3 Below is the code I've used to sample for 10 seconds on controller startup. It interrupts when the A channel changes, and buffers a time stamp if A is high. After 10 seconds it writes the buffer to the microSD card.
The issue is in the time difference from one time stamp to the next (t1 - t0), there appears to be certain values occurring much more often than the rest. Specifically, every 96th value has a much greater frequency than the rest (eg. 2798 microseconds, 2894 microseconds, 2990 microseconds, etc. appear very often). You can see this on the graph below. The only explanation I have is that the controller will often ignore the interrupts for up to 96 microseconds, but I don't understand why. Can anyone explain what causes this anomaly? Thanks!!!
Here's a link to the data file:https://drive.google.com/open?id=1T_qQJ6P6mnl2qhEdIbuD69vT4ytKL-w3 Below is the code I've used to sample for 10 seconds on controller startup. It interrupts when the A channel changes, and buffers a time stamp if A is high. After 10 seconds it writes the buffer to the microSD card.
The issue is in the time difference from one time stamp to the next (t1 - t0), there appears to be certain values occurring much more often than the rest. Specifically, every 96th value has a much greater frequency than the rest (eg. 2798 microseconds, 2894 microseconds, 2990 microseconds, etc. appear very often). You can see this on the graph below. The only explanation I have is that the controller will often ignore the interrupts for up to 96 microseconds, but I don't understand why. Can anyone explain what causes this anomaly? Thanks!!!
Code:
#define ENCODER_PPR 128
#define ENCODER_PPM 103.8
#define FILE_BASE_NAME "Data"
#include "SdFat.h"
//uSD Card
SdFatSdioEX sdEx;
File file;
boolean sdAvailable = false;
boolean recording = false;
//Encoder
#define ENCODER_INDEX_BUFFER_SIZE ENCODER_BUFFER_SIZE/ENCODER_PPR
volatile uint32_t encoderBuffer[ENCODER_BUFFER_SIZE];
volatile uint32_t encoderIndexBuffer[ENCODER_INDEX_BUFFER_SIZE]; //Not used in this test code
volatile long encoderPosition;
//Pins
const byte aPin = 11;
const byte bPin = 10;
//Battery Voltage
#define VOLTAGE_DIVISOR 20.43
float voltIn;
void setup() {
//Set pin modes
pinMode(aPin, INPUT);
pinMode(bPin, INPUT);
//Set interrupt
attachInterrupt(aPin, aISR, CHANGE); // Calls ISR when encoder pin A changes state
//Sample for 10 seconds then stop
recording = true;
while (millis() < 10000){};
if (sdEx.begin()) sdAvailable = true; //Check if SD card is inserted
sdEx.chvol();
recordData(); //Copy data to MicroSD Card
recording = false;
recordData();
}
void loop() {
}
void aISR(){
static uint32_t _bufPos;
uint8_t dir;
if (digitalRead(bPin)){
encoderBuffer[_bufPos] = micros() & 0b01111111111111111111111111111111;
if (!digitalRead(aPin)){
dir = 0b10000000000000000000000000000000;
encoderPosition++;
}
else {
dir = 0;
encoderPosition--;
}
if (recording){ //Copy data to buffer, will be moved onto card by recordData function
encoderBuffer[_bufPos] += dir; //Round to nearest 2 microseconds, save directionality bit in LSB
_bufPos++;
_bufPos %= ENCODER_BUFFER_SIZE;
}
else encoderBuffer[_bufPos] = 0;
}
}
void recordData(){
static uint32_t _bufPos;
static uint32_t _bufIndexPos;
static uint8_t _fileOpen = false;
static uint32_t _fStartTime;
if (recording && !_fileOpen){
char fileName[13] = FILE_BASE_NAME "00.csv";
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
while (sdEx.exists(fileName)) {
if (fileName[BASE_NAME_SIZE + 1] != '9') {
fileName[BASE_NAME_SIZE + 1]++;
}
else if (fileName[BASE_NAME_SIZE] != '9') {
fileName[BASE_NAME_SIZE + 1] = '0';
fileName[BASE_NAME_SIZE]++;
}
else break;
}
if (!sdEx.exists(fileName)){
if(file.open(fileName, O_RDWR | O_CREAT)){
_fStartTime = micros();
file.print(F("Calibration Factor (pulses per metre): "));
file.println(ENCODER_PPM);
file.print(F("Encoder Precision (pulses per revolution: "));
file.println(ENCODER_PPR);
file.println(F("Time (us), Dir (+1/-1),Special Flags"));
file.println(F("0,0"));
_fileOpen = true;
}
}
if (!_fileOpen) {
recording = 0;
}
}
while (encoderBuffer[_bufPos]){
file.print((encoderBuffer[_bufPos] & 0b01111111111111111111111111111111) - _fStartTime, DEC);
file.print(F(","));
if (encoderBuffer[_bufPos] & 0b10000000000000000000000000000000) file.print(F("1"));
else file.print(F("-1"));
if (encoderIndexBuffer[_bufIndexPos]){ //Not used in this test code
file.print(F(",INDEX:"));
file.print(encoderIndexBuffer[_bufIndexPos]);
encoderIndexBuffer[_bufIndexPos] = 0;
_bufIndexPos++;
_bufIndexPos %= ENCODER_INDEX_BUFFER_SIZE;
}
else file.print(",");
if(!file.println())
{
recording = 0;
}
encoderBuffer[_bufPos] = 0;
_bufPos++;
_bufPos %=ENCODER_BUFFER_SIZE;
}
if (!recording) {
file.print(micros() - _fStartTime);
file.print(F(",0,end"));
file.close();
_fileOpen = false;
}
}