Open foxjonesx7 opened 1 year ago
Any updates on this?
Sorry for the delayed response. Once the node is configured to output the derived channels, those data points are read in from the base station through the same BaseStation::getData()
function - any data points the base station receives are included in the sweeps returned from this function.
I've included some sample code below for configuring a node to output derived channels as well as retrieving and printing out different properties of derived channels (channel name, value, derived algorithm type, etc.). The data retrieval code will work for both regular and derived data, regular data just won't print out any of the derived data-specific properties.
The examples are in C++ but hopefully it's pretty straightforward to convert them over. Let us know if you run into any trouble or you need clarification on anything!
Setup and Configure
///////// Setup BaseStation and Node objects /////////
mscl::BaseStation baseStation(connection);
mscl::WirelessNode node(201, baseStation);
///////// Set node to idle /////////
// Note: recommend replacing this with something more robust that cannot hang indefinitely
mscl::SetToIdleStatus idleStatus = node.setToIdle();
while (!idleStatus.complete())
{
continue;
}
///////// Configure Node /////////
mscl::WirelessNodeConfig config;
// channel mask: enable derived data for chs 1, 2, and 3
mscl::ChannelMask chs;
chs.enable(1);
chs.enable(2);
chs.enable(3);
// specify derived data type and channels
config.derivedChannelMask(mscl::WirelessTypes::DerivedCategory::derivedCategory_peakToPeak, chs);
// specify derived data sample rate (max 1 Hz)
config.derivedDataRate(mscl::WirelessTypes::sampleRate_1Hz);
// enable both derived and regular (raw) data streaming
config.dataMode(mscl::WirelessTypes::DataMode::dataMode_raw_derived);
// apply config to device
node.applyConfig(config);
Setup Network and Start Sampling
///////// Start Sampling /////////
mscl::SyncSamplingNetwork network(baseStation);
network.addNode(node);
// checks for and applies any pending configurations
network.applyConfiguration();
// start sampling network if there are no bandwidth or configuration issues
if (network.ok())
{
network.startSampling();
}
Collect and Print data
// map to get human-readable labels from derived algorithm type IDs
const std::map<mscl::WirelessTypes::DerivedDataPacketAlgorithmId, std::string> DERIVED_TYPE_LABELS = {
{ mscl::WirelessTypes::DerivedDataPacketAlgorithmId::derivedAlgId_crestFactor, "Crest Factor" },
{ mscl::WirelessTypes::DerivedDataPacketAlgorithmId::derivedAlgId_ips, "IPS" },
{ mscl::WirelessTypes::DerivedDataPacketAlgorithmId::derivedAlgId_mean, "Mean" },
{ mscl::WirelessTypes::DerivedDataPacketAlgorithmId::derivedAlgId_mmps, "mmps" },
{ mscl::WirelessTypes::DerivedDataPacketAlgorithmId::derivedAlgId_peakToPeak, "Peak to Peak" },
{ mscl::WirelessTypes::DerivedDataPacketAlgorithmId::derivedAlgId_rms, "RMS" },
};
// continuously collect data
while (true)
{
// all data retrieved via getData() function - both derived and regular (raw)
mscl::DataSweeps sweeps = baseStation.getData();
// loop through retreived sweeps
for (int i = 0; i < sweeps.size(); i++)
{
mscl::DataSweep s = sweeps[i];
mscl::ChannelData data = s.data();
// print node address
cout << endl << "Sweep: " << s.nodeAddress() << ", " << s.tick();
for (int j = 0; j < data.size(); j++)
{
// print channel name and data value
mscl::WirelessDataPoint point = data[j];
cout << endl << " " << point.channelName()
<< endl << " Value: " << point.as_string();
// check if this data point has a derived algorithm ID channel property and print it
try
{
mscl::WirelessTypes::DerivedDataPacketAlgorithmId derivedTypeId = (mscl::WirelessTypes::DerivedDataPacketAlgorithmId)point.channelProperty(mscl::DataPoint::channelPropertyId_derivedAlgorithmId).as_uint8();
cout << endl << " Derived Type: " << DERIVED_TYPE_LABELS.at(derivedTypeId) << " (" << derivedTypeId << ")";
}
catch(...){/*ignore*/}
// check if this data point has a derived from channel propery and print it
try
{
mscl::ChannelMask derivedChMask = point.channelProperty(mscl::DataPoint::channelPropertyId_derivedFrom).as_ChannelMask();
cout << endl << " Derived From: chs ";
// loop through each possible channel in the channel mask and print all enabled
for (uint16_t i = 1; i <= derivedChMask.lastChEnabled(); i++)
{
if (derivedChMask.enabled(i))
{
cout << i << ", ";
}
}
}
catch (...) {/*ignore*/ }
}
}
}
Thank you so much for your time working on this. I was able to get this up and running in Python 3.6. You are amazing!
Hi,
I have had no luck importing the "Derived Output Channels" such as RMS, Peak-to-Peak, Crest Factor, Velocity, and Mean. For example, the following works great for the regular channels in the Python 3.6 version of the MSCL (Note: I used '#' to replace my actual node addresses):
Import libraries
import mscl
Set COM port and Node Addresses
COM_PORT = "COM3" NODE_ADDRESSES = [####, #####, #####]
Define the channels to display for each node
CHANNELS_TO_DISPLAY = {
: ["ch1", "ch2", "ch3"],
}
However, I cannot figure out how to call in the derived output channels. I have read through all of the supporting documentation and I cannot find anything that helps with this. Is this even possible? If so, can you please provide guidance.
Thank you!