diff --git a/OneWireIO.ino b/OneWireIO.ino index c6bf7b7..5ee71f9 100644 --- a/OneWireIO.ino +++ b/OneWireIO.ino @@ -7,6 +7,7 @@ // 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; const int BufferSize = 512; byte buffer1[BufferSize]; @@ -38,11 +39,19 @@ void setup() 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 - ADCSRA |= (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500KHz ; 13 cycles for a conversion which means 38000 samples per second + int ADPS = (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); + ADCSRA |= ADPS; //set ADC clock with 32 prescaler- 16mHz/32=500KHz ; 13 cycles for a conversion which means 38000 samples per second ADCSRA |= (1 << ADATE); //enabble auto trigger ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete ADCSRA |= (1 << ADEN); //enable ADC ADCSRA |= (1 << ADSC); //start ADC measurements + + regularEncodedFrequency = (byte)ADPS; + byte skipSamples = 0; + #if SkipSamples > 0 + skipSamples = SkipSamples; + #endif + regularEncodedFrequency |= skipSamples << 3; sei();//enable interrupts @@ -63,7 +72,9 @@ void loop() digitalWrite(LEDPin, LOW); //Serial.write(currentBuffer, currentBufferSize); - oscilloscope.write(currentBuffer, currentBufferSize, currentBufferStartTime); + oscilloscope.beginWrite(currentBufferSize + 1, currentBufferStartTime); + oscilloscope.continueWrite(®ularEncodedFrequency, 1); + oscilloscope.continueWrite(currentBuffer, currentBufferSize); } ISR(ADC_vect) {//when new ADC value ready diff --git a/SerialChannel.cpp b/SerialChannel.cpp index 51c716e..4c8c51d 100644 --- a/SerialChannel.cpp +++ b/SerialChannel.cpp @@ -23,16 +23,26 @@ SerialChannel::SerialChannel(const char* name_) void SerialChannel::write(byte* data, short byteCount, unsigned long time) { - if (time == (unsigned long)-1) - time = micros(); - - handleConnection(); + beginWrite(byteCount, time); + continueWrite(data, byteCount); +} + +void SerialChannel::beginWrite(short byteCount, unsigned long time) +{ + if (time == (unsigned long)-1) + time = micros(); + + handleConnection(); - Serial.write("START"); - Serial.write(id); - writeULong(time); - writeShort(byteCount); - Serial.write(data, byteCount); + Serial.write("START"); + Serial.write(id); + writeULong(time); + writeShort(byteCount); +} + +void SerialChannel::continueWrite(byte* data, short byteCount) +{ + Serial.write(data, byteCount); } void SerialChannel::write(const char* text, unsigned long time) diff --git a/SerialChannel.h b/SerialChannel.h index 7a2d5f8..c58aa4c 100644 --- a/SerialChannel.h +++ b/SerialChannel.h @@ -17,6 +17,9 @@ public: void write(byte* data, short byteCount, unsigned long time = (unsigned long)-1); void write(const char* text, unsigned long time = (unsigned long)-1); + + void beginWrite(short byteCount, unsigned long time = (unsigned long)-1); + void continueWrite(byte* data, short byteCount); private: void handleConnection(); diff --git a/SerialMonitor/SerialMonitor/App.xaml.cs b/SerialMonitor/SerialMonitor/App.xaml.cs index 74db570..bd2b9f2 100644 --- a/SerialMonitor/SerialMonitor/App.xaml.cs +++ b/SerialMonitor/SerialMonitor/App.xaml.cs @@ -85,7 +85,8 @@ namespace SerialMonitor MainWindowContext.Get.WriteLine(text); break; case "oscilloscope": - MainWindowContext.Get.AddSequence(message.SendTime, message.Data); + byte frequency = message.Data[0]; + MainWindowContext.Get.AddSequence(message.SendTime, frequency, message.Data.Skip(1).ToArray()); break; } } diff --git a/SerialMonitor/SerialMonitor/MainWindowContext.cs b/SerialMonitor/SerialMonitor/MainWindowContext.cs index 33d40ec..1c34255 100644 --- a/SerialMonitor/SerialMonitor/MainWindowContext.cs +++ b/SerialMonitor/SerialMonitor/MainWindowContext.cs @@ -35,13 +35,13 @@ namespace SerialMonitor OnPropertyChanged("ConsoleText"); } - public double SampleDelay { get { return 0.000026; } } public int MaxSequenceSize { get { return 2048; } } private class Sequence { - public ulong StartTime { get; set; } + public ulong StartTime { get; set; } // time in microseconds of the first sample public byte[] Data { get; set; } + public double Frequency { get; set; } // sampling rate (in samples per second) public class Comparer : IComparer { @@ -67,7 +67,8 @@ namespace SerialMonitor foreach (var sequence in Sequences) { double seqStartTime = (double)sequence.StartTime/1000000.0; - if (seqStartTime + (double)sequence.Data.Length * SampleDelay > ViewportStartTime && seqStartTime < ViewportStartTime + ViewportTimeWidth) + double sampleDelay = 1.0 / sequence.Frequency; + if (seqStartTime + (double)sequence.Data.Length * sampleDelay > ViewportStartTime && seqStartTime < ViewportStartTime + ViewportTimeWidth) { foreach (var line in ConvertToLines(sequence)) yield return line; @@ -82,6 +83,7 @@ namespace SerialMonitor double scale = viewportWidth / ViewportTimeWidth; // in pixels per second ulong displayStartTime = (ulong)(viewportStartTime_ * 1000000.0); + double sampleDelay = 1.0 / sequence.Frequency; double pos = ((double)sequence.StartTime - (double)displayStartTime) / 1000000.0 * scale; if (pos > 1000) @@ -94,7 +96,7 @@ namespace SerialMonitor for (int idx = 1; idx < sequence.Data.Length; ++idx) { byte value = sequence.Data[idx]; - pos += SampleDelay * scale; + pos += sampleDelay * scale; if (value > maxValue) maxValue = value; if (value < minValue) minValue = value; @@ -110,7 +112,7 @@ namespace SerialMonitor prevPos = pos; line.X2 = pos; - double time = (double)sequence.StartTime / 1000000.0 + (double)idx * SampleDelay; + double time = (double)sequence.StartTime / 1000000.0 + (double)idx * sampleDelay; double lastHeight = ValueToHeight(time, value); if (idx == prevIdx + 1) @@ -142,10 +144,20 @@ namespace SerialMonitor } } - public void AddSequence(ulong startTime, byte[] data) + public void AddSequence(ulong startTime, byte frequency, byte[] data) { // TODO: merge sequences if total size is lower than MaxSequenceSize - var sequence = new Sequence { StartTime = startTime, Data = data }; + double cpuClock = 16000000.0; + int adsp0 = (frequency & (1 << 0)) != 0 ? 1 : 0; + int adsp1 = (frequency & (1 << 1)) != 0 ? 1 : 0; + int adsp2 = (frequency & (1 << 2)) != 0 ? 1 : 0; + int skipBit0 = (frequency & (1 << 3)) != 0 ? 1 : 0; + int skipBit1 = (frequency & (1 << 4)) != 0 ? 1 : 0; + int skipBit2 = (frequency & (1 << 5)) != 0 ? 1 : 0; + int adcDivider = 1 << Math.Max(1, adsp0 + adsp1*2 + adsp2*4); + int skip = skipBit0 + skipBit1 * 2 + skipBit2 * 4; + double freq = cpuClock / (double)adcDivider / 13.0 / (double)(1 + skip); + var sequence = new Sequence { StartTime = startTime, Frequency = freq, Data = data }; Sequences.Add(sequence); OnPropertyChanged("Oscilloscope"); OnPropertyChanged("MinTime");