Open SSI7210153 opened 3 years ago
Hi - sorry for the delayed response!
CSV export We do not provide CSV export functionality within MSCL, you'll need to implement that yourself, but if you run into any issues streaming or accessing data we'd be happy to help!
Histogram MSCL does not have any visualization functionality. The Histogram isn't so much a function as a specific data format that is output by our SHM-Link nodes. I suppose you could use the Histogram class to build your own histogram data over time, but we don't have any examples of this. Let me know if you're using an SHM-Link and I can provide more direction for interpreting the output histogram data.
DatalogDownloader Unfortunately we don't currently have published examples for this, but I do have a code snippet in C++ that should be pretty straightforward to switch over. There is one known outstanding issue in this workflow for Python in accessing the calibration coefficients of the datalog sessions. We're working on resolving this, but in the mean time the issue and a workaround is documented in Issue 136 here. The workaround assumes that the calibration configuration has not changed since the time of data collection. The C++ snippet is below - let us know if you run into any issues in implementation!
void datalogDownload(mscl::WirelessNode& node)
{
mscl::DatalogDownloader downloader(node);
mscl::SampleRate currentSampleRate;
mscl::ChannelCalMap currentCalCoefs;
while (!downloader.complete())
{
// get next sweep
mscl::LoggedDataSweep sweep = downloader.getNextData();
// check if sample rate or cal coefficients have changed
if (downloader.metaDataUpdated())
{
currentSampleRate = downloader.sampleRate();
currentCalCoefs = downloader.calCoefficients();
}
// access data
for (mscl::WirelessDataPoint data : sweep.data())
{
// access timestamp
sweep.timestamp();
// access channel name, id, number
data.channelName();
data.channelId();
data.channelNumber();
// can access actual type based on storedAs but will convert to float fine regardless
mscl::ValueType storedAs = data.storedAs();
float val = data.as_float();
// if cals not already applied to sweep, apply them (optional)
if (!sweep.calApplied())
{
// get cal for this data point channel
mscl::CalCoefficients calCoef = currentCalCoefs.at(data.channelId());
// apply coef, access unit
val = (val * calCoef.linearEquation().slope()) + calCoef.linearEquation().offset();
mscl::WirelessTypes::CalCoef_Unit unit = calCoef.unit();
}
}
}
}
Thank you very much. The information is clear now. I try to graphic data, and this is what I made.
import time from time import sleep import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np import mscl import re import csv import threading IP = "xxx.xxx.xxx" #WSDA-2000 PORT = xxxx NODE_ADDRESS1 = xxxxx #G-LINK-200-OEM NODE_ADDRESS2 = xxxxx data= [] data.append([0.0]) data.append([0.0]) data.append([0.0]) data.append([0.0]) saveData={}
`
def readingData(baseStation): archive= open('datos.txt','a') while True:
sweeps = baseStation.getData(500)
for sweep in sweeps:
# print out information about the sweep
# print("Packet Received", end=' ')
# print("Node", sweep.nodeAddress(), end=' ')
# print("Timestamp", sweep.timestamp(), end=' ')
# print("Tick", sweep.tick(), end=' ')
# print("Sample Rate", sweep.sampleRate().prettyStr(), end=' ')
# print("Base RSSI: ", sweep.baseRssi(), end=' ')
# print("Node RSSI: ", sweep.nodeRssi(), end=' ')
# print("DATA: ", end=' ')
# iterate over each point in the sweep
for dataPoint in sweep.data():
#print out the channel data
match = re.match('^ch\d', dataPoint.channelName())
if match != None:
archive.write(dataPoint.as_string()+'\n')
# print(dataPoint.channelName(), ":", dataPoint.as_float(), end=' ')
# print("")
def graphicData(data, baseStation):
while True:
# if flag:
# print('wait, starting acquisition...')
# time.sleep(0.1)
time.sleep(0.03)
#######################################################
sweeps = baseStation.getData(500)
flag= False
for sweep in sweeps:
# print('Node', sweep.nodeAddress())
# iterate over each point in the sweep
for dataPoint in sweep.data():
#print out the channel data
match = re.match('^ch\d', dataPoint.channelName())
if match != None:
if dataPoint.channelName() == 'ch1':
# print('ch1: ',dataPoint.as_float())
data[1].append(np.round(dataPoint.as_float(),5))
if len(data[1])>100:
data[1].pop(0)
if dataPoint.channelName() == 'ch2':
# print('ch1: ',dataPoint.as_float())
data[2].append(np.round(dataPoint.as_float(),5))
if len(data[2])>100:
data[2].pop(0)
if dataPoint.channelName() == 'ch3':
# print('ch1: ',dataPoint.as_float())
data[3].append(np.round(dataPoint.as_float(),5))
if len(data[3])>100:
data[3].pop(0)
def update_line(num, hl1, hl2, hl3, data):
dx = np.array(range(len(data[1]))) #Funca con el len de data[1 o 2 o 3] ya que solo nos interesa generar el mismo tamaño de datos que se guardan en las posiciones 1, 2 o 3
dy1 = np.array(data[1])
dy2 = np.array(data[2])
dy3 = np.array(data[3])
hl1.set_data(dx, dy1)
hl2.set_data(dx, dy2)
hl3.set_data(dx, dy3)
return hl1, hl2, hl3,
try:
baseStation = connectBaseStation(IP, PORT)
node1 = createWirelessNode(NODE_ADDRESS1, baseStation)
# getCurrentConfig(node1)
# setCurrentConfig(node1)
#node2 = createWirelessNode(NODE_ADDRESS2, baseStation)
#getCurrentConfig(node2)
#setCurrentConfig(node2)
network = createModeSamplingNet(baseStation)
addNode(node1, network)
#addNode(node2, network)
configNetwork(network)
startSamplingNetwork(network)
fig = plt.figure(figsize=(10,8))
ax = fig.gca()
plt.ylim(-2.00, 2.00)
plt.xlim(0, 100)
hl1, = plt.plot(data[0], data[1], label='Canal 1')
hl2, = plt.plot(data[0], data[2], label='Canal 2')
hl3, = plt.plot(data[0], data[3], label='Canal 3')
plt.legend(loc='upper left')
dataCollector = threading.Thread(target=graphicData, args= (data,baseStation,))
dataSaving = threading.Thread(target=readingData, args= (baseStation,))
dataCollector.start()
dataSaving.start()
line_ani = animation.FuncAnimation(fig, update_line, fargs= (hl1, hl2, hl3, data), interval = 25, blit= False) #repeat= False,
plt.show()
dataSaving.join()
dataCollector.join()
except Exception as e:
print("Error:", e)
`
I got it, this code to print a graphic of the data and save data. But this runs very slow, any idea why? If I remove the thread and the save data function, the graph is fluid, as long as I do not remove the 30 ms wait in the graphicData function, because if I remove it, the graph freezes.
I also want to configure the node as an inclinometer. For this, I have used the function sensorOutputMode_tilt, but channels 4 and 5 are not actives, I try to use activeChannels, but so far I have not managed to use the functions well, it always gets me error:
config = mscl.WirelessNodeConfig() config.activeChannels.(4).enable()
I also tried with ChannelType, but it does not work:
config = mscl.WirelessNodeConfig() config.ChannelType(mscl.WirelessTypes.chType_tilt)
Thank you for the help, and looking forward to your reply.
I realized that the code to graph is not well appreciated, so I better attach the script.
Hi.
I'm new to programming and I work with the mscl library for python and LORD Wireless Sensors. I want to know if there is a function of the library that exporting data in CSV or if I have to make a step for step. Also, I like to know examples with the following functions, please:
- DatalogDownloader
- Histogram
¿The Histogram function makes graphics of the data?
Thank you for the help, and looking forward to your reply.
Hi, were you able to implement a csv conversion function? I have the same need.
Hi.
I'm new to programming and I work with the mscl library for python and LORD Wireless Sensors. I want to know if there is a function of the library that exporting data in CSV or if I have to make a step for step. Also, I like to know examples with the following functions, please:
DatalogDownloader
Histogram
¿The Histogram function makes graphics of the data?
Thank you for the help, and looking forward to your reply.