Browse Source

added code to transmit sample frequency along with sample data (more compatibility between arduino and PC, and possibility to change sampling rate at run-time)

timer1
Youen Toupin 9 years ago
parent
commit
ef01fe74bb
  1. 15
      OneWireIO.ino
  2. 28
      SerialChannel.cpp
  3. 3
      SerialChannel.h
  4. 3
      SerialMonitor/SerialMonitor/App.xaml.cs
  5. 26
      SerialMonitor/SerialMonitor/MainWindowContext.cs

15
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) // how many samples we want to skip between two samples we keep (can be used to lower the sampling frequency)
#define SkipSamples 0 #define SkipSamples 0
byte regularEncodedFrequency;
const int BufferSize = 512; const int BufferSize = 512;
byte buffer1[BufferSize]; byte buffer1[BufferSize];
@ -38,11 +39,19 @@ void setup()
ADMUX |= (1 << REFS0); //set reference voltage 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 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 << ADATE); //enabble auto trigger
ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); //enable ADC ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements ADCSRA |= (1 << ADSC); //start ADC measurements
regularEncodedFrequency = (byte)ADPS;
byte skipSamples = 0;
#if SkipSamples > 0
skipSamples = SkipSamples;
#endif
regularEncodedFrequency |= skipSamples << 3;
sei();//enable interrupts sei();//enable interrupts
@ -63,7 +72,9 @@ void loop()
digitalWrite(LEDPin, LOW); digitalWrite(LEDPin, LOW);
//Serial.write(currentBuffer, currentBufferSize); //Serial.write(currentBuffer, currentBufferSize);
oscilloscope.write(currentBuffer, currentBufferSize, currentBufferStartTime); oscilloscope.beginWrite(currentBufferSize + 1, currentBufferStartTime);
oscilloscope.continueWrite(&regularEncodedFrequency, 1);
oscilloscope.continueWrite(currentBuffer, currentBufferSize);
} }
ISR(ADC_vect) {//when new ADC value ready ISR(ADC_vect) {//when new ADC value ready

28
SerialChannel.cpp

@ -23,16 +23,26 @@ SerialChannel::SerialChannel(const char* name_)
void SerialChannel::write(byte* data, short byteCount, unsigned long time) void SerialChannel::write(byte* data, short byteCount, unsigned long time)
{ {
if (time == (unsigned long)-1) beginWrite(byteCount, time);
time = micros(); continueWrite(data, byteCount);
}
handleConnection();
void SerialChannel::beginWrite(short byteCount, unsigned long time)
{
if (time == (unsigned long)-1)
time = micros();
handleConnection();
Serial.write("START"); Serial.write("START");
Serial.write(id); Serial.write(id);
writeULong(time); writeULong(time);
writeShort(byteCount); writeShort(byteCount);
Serial.write(data, byteCount); }
void SerialChannel::continueWrite(byte* data, short byteCount)
{
Serial.write(data, byteCount);
} }
void SerialChannel::write(const char* text, unsigned long time) void SerialChannel::write(const char* text, unsigned long time)

3
SerialChannel.h

@ -17,6 +17,9 @@ public:
void write(byte* data, short byteCount, unsigned long time = (unsigned long)-1); void write(byte* data, short byteCount, unsigned long time = (unsigned long)-1);
void write(const char* text, 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: private:
void handleConnection(); void handleConnection();

3
SerialMonitor/SerialMonitor/App.xaml.cs

@ -85,7 +85,8 @@ namespace SerialMonitor
MainWindowContext.Get.WriteLine(text); MainWindowContext.Get.WriteLine(text);
break; break;
case "oscilloscope": 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; break;
} }
} }

26
SerialMonitor/SerialMonitor/MainWindowContext.cs

@ -35,13 +35,13 @@ namespace SerialMonitor
OnPropertyChanged("ConsoleText"); OnPropertyChanged("ConsoleText");
} }
public double SampleDelay { get { return 0.000026; } }
public int MaxSequenceSize { get { return 2048; } } public int MaxSequenceSize { get { return 2048; } }
private class Sequence 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 byte[] Data { get; set; }
public double Frequency { get; set; } // sampling rate (in samples per second)
public class Comparer : IComparer<Sequence> public class Comparer : IComparer<Sequence>
{ {
@ -67,7 +67,8 @@ namespace SerialMonitor
foreach (var sequence in Sequences) foreach (var sequence in Sequences)
{ {
double seqStartTime = (double)sequence.StartTime/1000000.0; 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)) foreach (var line in ConvertToLines(sequence))
yield return line; yield return line;
@ -82,6 +83,7 @@ namespace SerialMonitor
double scale = viewportWidth / ViewportTimeWidth; // in pixels per second double scale = viewportWidth / ViewportTimeWidth; // in pixels per second
ulong displayStartTime = (ulong)(viewportStartTime_ * 1000000.0); ulong displayStartTime = (ulong)(viewportStartTime_ * 1000000.0);
double sampleDelay = 1.0 / sequence.Frequency;
double pos = ((double)sequence.StartTime - (double)displayStartTime) / 1000000.0 * scale; double pos = ((double)sequence.StartTime - (double)displayStartTime) / 1000000.0 * scale;
if (pos > 1000) if (pos > 1000)
@ -94,7 +96,7 @@ namespace SerialMonitor
for (int idx = 1; idx < sequence.Data.Length; ++idx) for (int idx = 1; idx < sequence.Data.Length; ++idx)
{ {
byte value = sequence.Data[idx]; byte value = sequence.Data[idx];
pos += SampleDelay * scale; pos += sampleDelay * scale;
if (value > maxValue) maxValue = value; if (value > maxValue) maxValue = value;
if (value < minValue) minValue = value; if (value < minValue) minValue = value;
@ -110,7 +112,7 @@ namespace SerialMonitor
prevPos = pos; prevPos = pos;
line.X2 = 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); double lastHeight = ValueToHeight(time, value);
if (idx == prevIdx + 1) 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 // 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); Sequences.Add(sequence);
OnPropertyChanged("Oscilloscope"); OnPropertyChanged("Oscilloscope");
OnPropertyChanged("MinTime"); OnPropertyChanged("MinTime");

Loading…
Cancel
Save