public static double[] DecodeTelemetrySamples(string bits) { // Each packet contains a 16 bit timestamp, followed by 4, 16-bit values representing battery, "fuel_gauge?", adc voltage, and temperature. double[] samples = new double[Constants.MUSE_TELEMETRY_CHANNEL_COUNT]; for (int i = 0; i < Constants.MUSE_TELEMETRY_CHANNEL_COUNT; i++) { samples[i] = PacketConversion.ToUInt16(bits, 16 + (i * 16)); // Initial offset by 16 bits for the timestamp. } // The following conversion are from muse-lsl (inside muse.py). Not sure how accurate this info is. 2/13/2020. // Battery. samples[0] = samples[0] / 512; // Fuel guage... samples[1] = samples[1] * 2.2d; return(samples); }
private async void Channel_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args) { if (isStreaming) { string bits = GetBits(args.CharacteristicValue); ushort museTimestamp = PacketConversion.ToUInt16(bits, 0); // Zero bit offset, since first 16 bits represent Muse timestamp. MuseSample sample; lock (sampleBuffer) { if (!sampleBuffer.ContainsKey(museTimestamp)) { sample = new MuseSample(); sampleBuffer.Add(museTimestamp, sample); sample.BaseTimestamp = TimestampFormat.GetNow(); // This is the real timestamp, not the Muse timestamp which we use to group channel data. sample.BasetimeStamp2 = TimestampFormat.GetType() != TimestampFormat2.GetType() ? TimestampFormat2.GetNow() // This is the real timestamp (format 2), not the Muse timestamp which we use to group channel data. : sample.BasetimeStamp2 = sample.BaseTimestamp; // Ensures they are equal if using same timestamp format. } else { sample = sampleBuffer[museTimestamp]; } // Get time samples. sample.ChannelData[sender.Uuid] = GetTimeSamples(bits); } // If we have all 5 channels, we can push the 12 samples for each channel. if (sample.ChannelData.Count == channelCount) { await LSLPushChunk(sample); lock (sampleBuffer) sampleBuffer.Remove(museTimestamp); } } }