#include "Arduino.h" #include "SerialChannel.h" #define LEDPin 13 #define OWPin 2 #define InterruptNumber 0 // Must correspond to the OWPin to correctly detect state changes. On Arduino Uno, interrupt 0 is for digital pin 2 // how many samples we want to skip between two samples we keep (can be used to lower the sampling frequency) #define SkipSamples 0 byte regularEncodedFrequency; byte burstEncodedFrequency; int regularADCSRA; int burstADCSRA; const int BufferSize = 128; const int BurstBufferSize = 1024; byte buffer1[BufferSize]; byte buffer2[BufferSize]; byte burstBuffer[BurstBufferSize]; volatile byte* backBuffer = buffer1; volatile short backBufferPos = 0; byte samplesSkipped = SkipSamples; volatile unsigned long backBufferStartTime = micros(); SerialChannel oscilloscope("oscilloscope"); SerialChannel debug("debug"); void setup() { pinMode(LEDPin, OUTPUT); pinMode(OWPin, INPUT); digitalWrite(LEDPin, LOW); //attachInterrupt(InterruptNumber,onewireInterrupt,CHANGE); cli();//disable interrupts //set up continuous sampling of analog pin 0 //clear ADCSRA and ADCSRB registers ADCSRA = 0; ADCSRB = 0; ADMUX |= (1 << REFS0); //set reference voltage ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only byte skipSamples = 0; #if SkipSamples > 0 skipSamples = SkipSamples; #endif int ADPS = (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); regularADCSRA = 0; regularADCSRA |= ADPS; //set ADC clock with 32 prescaler- 16mHz/32=500KHz ; 13 cycles for a conversion which means 38000 samples per second regularADCSRA |= (1 << ADATE); //enabble auto trigger regularADCSRA |= (1 << ADIE); //enable interrupts when measurement complete regularADCSRA |= (1 << ADEN); //enable ADC regularADCSRA |= (1 << ADSC); //start ADC measurements regularEncodedFrequency = (byte)ADPS; regularEncodedFrequency |= skipSamples << 3; ADCSRA = regularADCSRA; ADPS = (0 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); burstADCSRA = 0; burstADCSRA |= ADPS; //set ADC clock with 32 prescaler- 16mHz/32=500KHz ; 13 cycles for a conversion which means 38000 samples per second burstADCSRA |= (1 << ADATE); //enabble auto trigger burstADCSRA |= (1 << ADIE); //enable interrupts when measurement complete burstADCSRA |= (1 << ADEN); //enable ADC burstADCSRA |= (1 << ADSC); //start ADC measurements burstEncodedFrequency = (byte)ADPS; burstEncodedFrequency |= skipSamples << 3; sei();//enable interrupts Serial.begin(400000); } void loop() { while(backBufferPos < BufferSize / 2 || (backBuffer == burstBuffer && backBufferPos < BurstBufferSize - 1)) ; cli();//disable interrupts byte* currentBuffer = (byte*)backBuffer; short currentBufferSize = backBufferPos; backBuffer = (backBuffer == buffer1 ? buffer2 : buffer1); backBufferPos = 0; if(currentBuffer == burstBuffer) { ADCSRA = regularADCSRA; } sei();//enable interrupts unsigned long currentBufferStartTime = backBufferStartTime; backBufferStartTime = micros(); digitalWrite(LEDPin, LOW); byte encodedFrequency = currentBuffer == burstBuffer ? burstEncodedFrequency : regularEncodedFrequency; //Serial.write(currentBuffer, currentBufferSize); oscilloscope.beginWrite(currentBufferSize + 1, currentBufferStartTime); oscilloscope.continueWrite(&encodedFrequency, 1); oscilloscope.continueWrite(currentBuffer, currentBufferSize); } ISR(ADC_vect) {//when new ADC value ready byte sample = ADCH; //store 8 bit value from analog pin 0 #if SkipSamples > 0 if(samplesSkipped++ < SkipSamples) return; samplesSkipped = 0; #endif backBuffer[backBufferPos++] = sample; if(backBuffer == burstBuffer) { if(backBufferPos >= BurstBufferSize) { backBufferPos = BurstBufferSize - 1; } } else { if(backBufferPos >= BufferSize) { // overflow of back buffer, we loose the current sample digitalWrite(LEDPin, HIGH); backBufferPos = BufferSize - 1; } } // switch to burst mode if the trigger condition is met /*if(backBuffer != burstBuffer && sample < 127) { backBuffer = burstBuffer; ADCSRA = burstADCSRA; backBufferPos = 0; backBufferStartTime = micros(); }*/ } void onewireInterrupt(void) { //digitalWrite(LEDPin, digitalRead(OWPin)); }