adjustable frequency

master
Ondřej Hruška 8 years ago
parent 5bb7a303b3
commit b183ab7868
  1. 2
      esp_meas.pro.user
  2. 2
      html/css/app.css
  3. 4
      html/js/all.js
  4. 17
      html/pages/waveform.html
  5. 1231
      html_src/css/app.css
  6. 2
      html_src/css/app.css.map
  7. 269
      html_src/js-src/lib/chartist.js
  8. 24
      html_src/js-src/page_waveform.js
  9. 2
      html_src/js-src/page_wifi.js
  10. 8
      html_src/js-src/utils.js
  11. 5519
      html_src/js/all.js
  12. 2
      html_src/js/all.js.map
  13. 17
      html_src/page_waveform.php
  14. 2
      html_src/sass/_grid-settings.scss
  15. 27
      html_src/sass/app.scss
  16. 4
      html_src/sass/lib/chartist/_chartist.scss
  17. 29
      html_src/sass/pages/_wfm.scss
  18. 6
      libesphttpd/util/cgiwifi.c
  19. 18
      user/page_waveform.c
  20. 17
      user/sampling.c
  21. 2
      user/sampling.h

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.6.0, 2016-03-28T13:51:48. -->
<!-- Written by QtCreator 3.6.1, 2016-03-29T02:35:32. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -21,10 +21,19 @@
<h1>Waveform</h1>
<div class="Box center">
<label for="count">Samples:</label>
<input id="count" type="number" value="100" style="width:100px">&nbsp;
<a id="load" class="button btn-green">Load</a>
<div class="Box center" id="samp-ctrl">
<div>
<label for="count">Samples</label>
<input id="count" type="number" value="500">
</div>
<div>
<label for="freq">Freq. <span class="mq-tablet-max" style="font-weight:normal;">(Hz)</span></label>
<input id="freq" type="number" value="4000">
<span class="mq-normal-min">Hz</span>
</div>
<div>
<a id="load" class="button btn-green">Load</a>
</div>
</div>
<div class="Box medium">

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1148,39 +1148,176 @@ var Chartist = {
};
};
/**
* Cardinal / Catmull-Rome spline interpolation is the default smoothing function in Chartist. It produces nice results where the splines will always meet the points. It produces some artifacts though when data values are increased or decreased rapidly. The line may not follow a very accurate path and if the line should be accurate this smoothing function does not produce the best results.
*
* Cardinal splines can only be created if there are more than two data points. If this is not the case this smoothing will fallback to `Chartist.Smoothing.none`.
*
* All smoothing functions within Chartist are factory functions that accept an options parameter. The cardinal interpolation function accepts one configuration parameter `tension`, between 0 and 1, which controls the smoothing intensity.
// /**
// * Cardinal / Catmull-Rome spline interpolation is the default smoothing function in Chartist. It produces nice results where the splines will always meet the points. It produces some artifacts though when data values are increased or decreased rapidly. The line may not follow a very accurate path and if the line should be accurate this smoothing function does not produce the best results.
// *
// * Cardinal splines can only be created if there are more than two data points. If this is not the case this smoothing will fallback to `Chartist.Smoothing.none`.
// *
// * All smoothing functions within Chartist are factory functions that accept an options parameter. The cardinal interpolation function accepts one configuration parameter `tension`, between 0 and 1, which controls the smoothing intensity.
// *
// * @example
// * var chart = new Chartist.Line('.ct-chart', {
// * labels: [1, 2, 3, 4, 5],
// * series: [[1, 2, 8, 1, 7]]
// * }, {
// * lineSmooth: Chartist.Interpolation.cardinal({
// * tension: 1,
// * fillHoles: false
// * })
// * });
// *
// * @memberof Chartist.Interpolation
// * @param {Object} options The options of the cardinal factory function.
// * @return {Function}
// */
// Chartist.Interpolation.cardinal = function(options) {
// var defaultOptions = {
// tension: 1,
// fillHoles: false
// };
//
// options = Chartist.extend({}, defaultOptions, options);
//
// var t = Math.min(1, Math.max(0, options.tension)),
// c = 1 - t;
//
// // This function will help us to split pathCoordinates and valueData into segments that also contain pathCoordinates
// // and valueData. This way the existing functions can be reused and the segment paths can be joined afterwards.
// // This functionality is necessary to treat "holes" in the line charts
// function splitIntoSegments(pathCoordinates, valueData) {
// var segments = [];
// var hole = true;
//
// for(var i = 0; i < pathCoordinates.length; i += 2) {
// // If this value is a "hole" we set the hole flag
// if(valueData[i / 2].value === undefined) {
// if(!options.fillHoles) {
// hole = true;
// }
// } else {
// // If it's a valid value we need to check if we're coming out of a hole and create a new empty segment
// if(hole) {
// segments.push({
// pathCoordinates: [],
// valueData: []
// });
// // As we have a valid value now, we are not in a "hole" anymore
// hole = false;
// }
//
// // Add to the segment pathCoordinates and valueData
// segments[segments.length - 1].pathCoordinates.push(pathCoordinates[i], pathCoordinates[i + 1]);
// segments[segments.length - 1].valueData.push(valueData[i / 2]);
// }
// }
//
// return segments;
// }
//
// return function cardinal(pathCoordinates, valueData) {
// // First we try to split the coordinates into segments
// // This is necessary to treat "holes" in line charts
// var segments = splitIntoSegments(pathCoordinates, valueData);
//
// if(!segments.length) {
// // If there were no segments return 'Chartist.Interpolation.none'
// return Chartist.Interpolation.none()([]);
// } else if(segments.length > 1) {
// // If the split resulted in more that one segment we need to interpolate each segment individually and join them
// // afterwards together into a single path.
// var paths = [];
// // For each segment we will recurse the cardinal function
// segments.forEach(function(segment) {
// paths.push(cardinal(segment.pathCoordinates, segment.valueData));
// });
// // Join the segment path data into a single path and return
// return Chartist.Svg.Path.join(paths);
// } else {
// // If there was only one segment we can proceed regularly by using pathCoordinates and valueData from the first
// // segment
// pathCoordinates = segments[0].pathCoordinates;
// valueData = segments[0].valueData;
//
// // If less than two points we need to fallback to no smoothing
// if(pathCoordinates.length <= 4) {
// return Chartist.Interpolation.none()(pathCoordinates, valueData);
// }
//
// var path = new Chartist.Svg.Path().move(pathCoordinates[0], pathCoordinates[1], false, valueData[0]),
// z;
//
// for (var i = 0, iLen = pathCoordinates.length; iLen - 2 * !z > i; i += 2) {
// var p = [
// {x: +pathCoordinates[i - 2], y: +pathCoordinates[i - 1]},
// {x: +pathCoordinates[i], y: +pathCoordinates[i + 1]},
// {x: +pathCoordinates[i + 2], y: +pathCoordinates[i + 3]},
// {x: +pathCoordinates[i + 4], y: +pathCoordinates[i + 5]}
// ];
// if (z) {
// if (!i) {
// p[0] = {x: +pathCoordinates[iLen - 2], y: +pathCoordinates[iLen - 1]};
// } else if (iLen - 4 === i) {
// p[3] = {x: +pathCoordinates[0], y: +pathCoordinates[1]};
// } else if (iLen - 2 === i) {
// p[2] = {x: +pathCoordinates[0], y: +pathCoordinates[1]};
// p[3] = {x: +pathCoordinates[2], y: +pathCoordinates[3]};
// }
// } else {
// if (iLen - 4 === i) {
// p[3] = p[2];
// } else if (!i) {
// p[0] = {x: +pathCoordinates[i], y: +pathCoordinates[i + 1]};
// }
// }
//
// path.curve(
// (t * (-p[0].x + 6 * p[1].x + p[2].x) / 6) + (c * p[2].x),
// (t * (-p[0].y + 6 * p[1].y + p[2].y) / 6) + (c * p[2].y),
// (t * (p[1].x + 6 * p[2].x - p[3].x) / 6) + (c * p[2].x),
// (t * (p[1].y + 6 * p[2].y - p[3].y) / 6) + (c * p[2].y),
// p[2].x,
// p[2].y,
// false,
// valueData[(i + 2) / 2]
// );
// }
//
// return path;
// }
// };
// };
/**
* Monotone Cubic spline interpolation produces a smooth curve which preserves monotonicity. Unlike cardinal splines, the curve will not extend beyond the range of y-values of the original data points.
*
* Monotone Cubic splines can only be created if there are more than two data points. If this is not the case this smoothing will fallback to `Chartist.Smoothing.none`.
*
* The x-values of subsequent points must be increasing to fit a Monotone Cubic spline. If this condition is not met for a pair of adjacent points, then there will be a break in the curve between those data points.
*
* All smoothing functions within Chartist are factory functions that accept an options parameter.
*
* @example
* var chart = new Chartist.Line('.ct-chart', {
* labels: [1, 2, 3, 4, 5],
* series: [[1, 2, 8, 1, 7]]
* }, {
* lineSmooth: Chartist.Interpolation.cardinal({
* tension: 1,
* lineSmooth: Chartist.Interpolation.monotoneCubic({
* fillHoles: false
* })
* });
*
* @memberof Chartist.Interpolation
* @param {Object} options The options of the cardinal factory function.
* @param {Object} options The options of the monotoneCubic factory function.
* @return {Function}
*/
Chartist.Interpolation.cardinal = function(options) {
Chartist.Interpolation.monotoneCubic = function(options) {
var defaultOptions = {
tension: 1,
fillHoles: false
};
options = Chartist.extend({}, defaultOptions, options);
var t = Math.min(1, Math.max(0, options.tension)),
c = 1 - t;
// This function will help us to split pathCoordinates and valueData into segments that also contain pathCoordinates
// and valueData. This way the existing functions can be reused and the segment paths can be joined afterwards.
// This functionality is necessary to treat "holes" in the line charts
@ -1194,6 +1331,13 @@ var Chartist = {
if(!options.fillHoles) {
hole = true;
}
} else if(i >= 2 && pathCoordinates[i] <= pathCoordinates[i-2]) {
// Because we are doing monotone interpolation, curve fitting only makes sense for
// increasing x values. Therefore if two subsequent points have the same x value, or
// the x value is decreasing, then we create a hole at this point. (Which cannot be
// filled in even with the 'fillHoles' option)
hole = true;
} else {
// If it's a valid value we need to check if we're coming out of a hole and create a new empty segment
if(hole) {
@ -1214,7 +1358,7 @@ var Chartist = {
return segments;
}
return function cardinal(pathCoordinates, valueData) {
return function monotoneCubic(pathCoordinates, valueData) {
// First we try to split the coordinates into segments
// This is necessary to treat "holes" in line charts
var segments = splitIntoSegments(pathCoordinates, valueData);
@ -1225,10 +1369,10 @@ var Chartist = {
} else if(segments.length > 1) {
// If the split resulted in more that one segment we need to interpolate each segment individually and join them
// afterwards together into a single path.
var paths = [];
// For each segment we will recurse the cardinal function
var paths = [];
// For each segment we will recurse the monotoneCubic fn function
segments.forEach(function(segment) {
paths.push(cardinal(segment.pathCoordinates, segment.valueData));
paths.push(monotoneCubic(segment.pathCoordinates, segment.valueData));
});
// Join the segment path data into a single path and return
return Chartist.Svg.Path.join(paths);
@ -1238,47 +1382,72 @@ var Chartist = {
pathCoordinates = segments[0].pathCoordinates;
valueData = segments[0].valueData;
// If less than two points we need to fallback to no smoothing
// If less than three points we need to fallback to no smoothing
if(pathCoordinates.length <= 4) {
return Chartist.Interpolation.none()(pathCoordinates, valueData);
}
var path = new Chartist.Svg.Path().move(pathCoordinates[0], pathCoordinates[1], false, valueData[0]),
z;
for (var i = 0, iLen = pathCoordinates.length; iLen - 2 * !z > i; i += 2) {
var p = [
{x: +pathCoordinates[i - 2], y: +pathCoordinates[i - 1]},
{x: +pathCoordinates[i], y: +pathCoordinates[i + 1]},
{x: +pathCoordinates[i + 2], y: +pathCoordinates[i + 3]},
{x: +pathCoordinates[i + 4], y: +pathCoordinates[i + 5]}
];
if (z) {
if (!i) {
p[0] = {x: +pathCoordinates[iLen - 2], y: +pathCoordinates[iLen - 1]};
} else if (iLen - 4 === i) {
p[3] = {x: +pathCoordinates[0], y: +pathCoordinates[1]};
} else if (iLen - 2 === i) {
p[2] = {x: +pathCoordinates[0], y: +pathCoordinates[1]};
p[3] = {x: +pathCoordinates[2], y: +pathCoordinates[3]};
}
var xs = [],
ys = [],
i,
n = pathCoordinates.length / 2,
ms = [],
ds = [], dys = [], dxs = [],
path;
// Populate x and y coordinates into separate arrays, for readability
for(i = 0; i < n; i++) {
xs[i] = pathCoordinates[i * 2];
ys[i] = pathCoordinates[i * 2 + 1];
}
// Calculate deltas and derivative
for(i = 0; i < n - 1; i++) {
dys[i] = ys[i + 1] - ys[i];
dxs[i] = xs[i + 1] - xs[i];
ds[i] = dys[i] / dxs[i];
}
// Determine desired slope (m) at each point using Fritsch-Carlson method
// See: http://math.stackexchange.com/questions/45218/implementation-of-monotone-cubic-interpolation
ms[0] = ds[0];
ms[n - 1] = ds[n - 2];
for(i = 1; i < n - 1; i++) {
if(ds[i] === 0 || ds[i - 1] === 0 || (ds[i - 1] > 0) !== (ds[i] > 0)) {
ms[i] = 0;
} else {
if (iLen - 4 === i) {
p[3] = p[2];
} else if (!i) {
p[0] = {x: +pathCoordinates[i], y: +pathCoordinates[i + 1]};
ms[i] = 3 * (dxs[i - 1] + dxs[i]) / (
(2 * dxs[i] + dxs[i - 1]) / ds[i - 1] +
(dxs[i] + 2 * dxs[i - 1]) / ds[i]);
if(!isFinite(ms[i])) {
ms[i] = 0;
}
}
}
// Now build a path from the slopes
path = new Chartist.Svg.Path().move(xs[0], ys[0], false, valueData[0]);
for(i = 0; i < n - 1; i++) {
path.curve(
(t * (-p[0].x + 6 * p[1].x + p[2].x) / 6) + (c * p[2].x),
(t * (-p[0].y + 6 * p[1].y + p[2].y) / 6) + (c * p[2].y),
(t * (p[1].x + 6 * p[2].x - p[3].x) / 6) + (c * p[2].x),
(t * (p[1].y + 6 * p[2].y - p[3].y) / 6) + (c * p[2].y),
p[2].x,
p[2].y,
false,
valueData[(i + 2) / 2]
// First control point
xs[i] + dxs[i] / 3,
ys[i] + ms[i] * dxs[i] / 3,
// Second control point
xs[i + 1] - dxs[i] / 3,
ys[i + 1] - ms[i + 1] * dxs[i] / 3,
// End point
xs[i + 1],
ys[i + 1],
false,
valueData[i]
);
}

@ -1,6 +1,8 @@
var page_waveform = (function () {
var wfm = {};
var zoomResetFn;
function buildChart(samples, xlabel, ylabel) {
var data = [];
samples.forEach(function (a, i) {
@ -35,6 +37,14 @@ var page_waveform = (function () {
);
}
// zoom
plugins.push(Chartist.plugins.zoom({
resetOnRightMouseBtn:true,
onZoom: function(chart, reset) {
zoomResetFn = reset;
}
}));
new Chartist.Line('#chart', {
series: [
{
@ -49,7 +59,7 @@ var page_waveform = (function () {
chartPadding: (isPhone ? {right: 20, bottom: 5, left: 0} : {right: 25, bottom: 30, left: 25}),
series: {
'a': {
lineSmooth: Chartist.Interpolation.none()
lineSmooth: Chartist.Interpolation.monotoneCubic()
}
},
axisX: {
@ -88,18 +98,26 @@ var page_waveform = (function () {
function clickHdl() {
var samples = $('#count').val();
var freq = $('#freq').val();
//http://192.168.1.13
$().get('/api/raw.json?n='+samples, onRxData, true, true);
$().get('http://192.168.1.13/api/raw.json?n='+samples+'&fs='+freq, onRxData, true, true);
}
$('#load').on('click', clickHdl);
$('#count').on('keyup', function(e) {
$('#count,#freq').on('keyup', function(e) {
if (e.which == 13) {
clickHdl();
}
});
$('#chart').on('contextmenu', function(e) {
zoomResetFn && zoomResetFn();
zoomResetFn = null;
e.preventDefault();
return false;
});
};
return wfm;

@ -49,7 +49,7 @@ var page_wifi = (function () {
var inner = document.createElement('div');
var $inner = $(inner).addClass('inner')
.htmlAppend('<div class="rssi">{0}</div>'.format(rssiPerc(ap.rssi)))
.htmlAppend('<div class="rssi">{0}</div>'.format(ap.rssi_perc))
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format(e(ap.essid)))
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));

@ -27,14 +27,6 @@ function regexEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
/** Convert RSSI 0-255 to % */
function rssiPerc(rssi) {
var r = parseInt(rssi);
if (r > -50) return 100; // 100%
if (r < -100) return 0; // 0%
return Math.round(2 * (r + 100)); // approximation
}
/** Perform a substitution in the given string.
*
* Arguments - array or list of replacements.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -3,10 +3,19 @@ include "_start.php"; ?>
<h1>Waveform</h1>
<div class="Box center">
<label for="count">Samples:</label>
<input id="count" type="number" value="100" style="width:100px">&nbsp;
<a id="load" class="button btn-green">Load</a>
<div class="Box center" id="samp-ctrl">
<div>
<label for="count">Samples</label>
<input id="count" type="number" value="500">
</div>
<div>
<label for="freq">Freq. <span class="mq-tablet-max" style="font-weight:normal;">(Hz)</span></label>
<input id="freq" type="number" value="4000">
<span class="mq-normal-min">Hz</span>
</div>
<div>
<a id="load" class="button btn-green">Load</a>
</div>
</div>
<div class="Box medium">

@ -13,3 +13,5 @@ $large: new-breakpoint(min-width 1377px);
$tablet-max: new-breakpoint(max-width 1000px);
$normal-max: new-breakpoint(max-width 1376px);
$tablet-min: new-breakpoint(min-width 545px);
$normal-min: new-breakpoint(min-width 1001px);

@ -36,3 +36,30 @@ $c-form-highlight-a: #28bc65;
// import all our pages
@import "pages/wifi";
@import "pages/home";
@import "pages/wfm";
/*
@include media($tablet-min) {
.mq-phone {
display: none;
}
}
@include media($phone) {
.mq-tablet-min {
display: none;
}
}
*/
@include media($normal-min) {
.mq-tablet-max {
display: none;
}
}
@include media($tablet-max) {
.mq-normal-min {
display: none;
}
}

@ -113,6 +113,10 @@
$ct-series-names: $ct-series-names,
$ct-series-colors: $ct-series-colors) {
.ct-zoom-rect {
fill: rgba(200, 100, 100, 0.3);
stroke: red;
}
.ct-axis-title {
fill: $ct-axis-label-color;

@ -0,0 +1,29 @@
#samp-ctrl {
display: flex;
padding: dist(-2);
flex-direction: row;
@include media($phone) {
flex-direction: column;
}
justify-content: center;
align-items: stretch;
> div {
margin: dist(-2);
}
label {
line-height: 1.8;
font-weight: bold;
}
input {
width: 150px;
@include media($phone) {
width: 100%;
}
}
}

@ -120,11 +120,13 @@ int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) {
if (!cgiWifiAps.scanInProgress && pos!=0) {
//Fill in json code for an access point
if (pos-1<cgiWifiAps.noAps) {
int rssi = cgiWifiAps.apData[pos-1]->rssi;
len=sprintf(buff, "{\"essid\":\"%s\",\"bssid\":\""MACSTR"\",\"rssi\":%d,\"enc\":%d,\"channel\":%d}%s",
len=sprintf(buff, "{\"essid\": \"%s\", \"bssid\": \""MACSTR"\", \"rssi\": %d, \"rssi_perc\": %d, \"enc\": %d, \"channel\": %d}%s",
cgiWifiAps.apData[pos-1]->ssid,
MAC2STR(cgiWifiAps.apData[pos-1]->bssid),
cgiWifiAps.apData[pos-1]->rssi,
rssi,
rssi2perc(rssi),
cgiWifiAps.apData[pos-1]->enc,
cgiWifiAps.apData[pos-1]->channel,
(pos-1==cgiWifiAps.noAps-1) ? "" : ","); //<-terminator

@ -20,6 +20,7 @@ typedef struct {
int FLASH_FN tplWaveformJSON(HttpdConnData *connData, char *token, void **arg)
{
char buff20[20];
int len;
tplReadSamplesJSON_state *st = *arg;
@ -36,18 +37,31 @@ int FLASH_FN tplWaveformJSON(HttpdConnData *connData, char *token, void **arg)
// check how many samples are requested
uint16_t count = 1;
int len = httpdFindArg(connData->getArgs, "n", buff20, sizeof(buff20));
len = httpdFindArg(connData->getArgs, "n", buff20, sizeof(buff20));
if (len != -1) count = (uint16_t)atoi(buff20);
if (count > 4096) {
warn("Requested %d samples, capping at 4096.", count);
count = 4096;
}
uint32_t freq = 4096;
len = httpdFindArg(connData->getArgs, "fs", buff20, sizeof(buff20));
if (len != -1) freq = (uint32_t)atoi(buff20);
if (freq > 5000000) {
warn("Requested fs %d Hz, capping at 5 MHz.", freq);
freq = 5000000;
}
if (freq == 0) {
error("Requested fs 0 Hz, using 1 Hz");
freq = 1;
}
st->total_count = count;
st->done_count = 0;
st->success = true; // success true by default
// REQUEST THE DATA
meas_request_data(st->total_count);
meas_request_data(count, freq);
}
// the "success" field is after the data,

@ -11,6 +11,8 @@
// the FIFO has 128 bytes, and should accomodate ideally the whole frame.
#define CHUNK_LEN 100
#define SAMPLING_TMEO 10000
#define READOUT_TMEO 100
// Only one readout can happen at a time.
@ -138,7 +140,7 @@ static void FLASH_FN request_data_sesn_listener(SBMP_Endpoint *ep, SBMP_Datagram
// dbg("Total bytes avail: %d", rd.total);
// renew the timeout
setReadoutTmeoTimer(1000);
setReadoutTmeoTimer(READOUT_TMEO);
// request first chunk
sbmp_bulk_request(ep, rd.pos, CHUNK_LEN, dg->session);
@ -156,7 +158,7 @@ static void FLASH_FN request_data_sesn_listener(SBMP_Endpoint *ep, SBMP_Datagram
// move the pointer for next request
rd.pos += dg->length;
setReadoutTmeoTimer(1000); // timeout to retrieve the data & ask for more
setReadoutTmeoTimer(READOUT_TMEO); // timeout to retrieve the data & ask for more
if (rd.pos >= rd.total) {
info("Transfer is complete.");
@ -181,11 +183,11 @@ cleanup:
}
bool FLASH_FN meas_request_data(uint16_t count)
bool FLASH_FN meas_request_data(uint16_t count, uint32_t freq)
{
bool suc = false;
info("Requesting data capture - %d samples.", count);
info("Requesting data capture - %d samples @ %d Hz.", count, freq);
if (rd.pending) {
error("Acquire request already in progress.");
@ -203,11 +205,11 @@ bool FLASH_FN meas_request_data(uint16_t count)
rd.pending = true;
// start the abort timer - timeout
setReadoutTmeoTimer(6000);
setReadoutTmeoTimer(SAMPLING_TMEO);
// start a message
uint16_t sesn = 0;
suc = sbmp_ep_start_message(dlnk_ep, DG_REQUEST_CAPTURE, sizeof(uint16_t), &sesn);
suc = sbmp_ep_start_message(dlnk_ep, DG_REQUEST_CAPTURE, sizeof(uint16_t)+sizeof(uint32_t), &sesn);
if (!suc) goto fail;
// register the session listener
@ -223,6 +225,9 @@ bool FLASH_FN meas_request_data(uint16_t count)
// request N values
sbmp_ep_send_u16(dlnk_ep, count);
// at freq F
sbmp_ep_send_u32(dlnk_ep, freq);
dbg("Request sent, session nr %d", sesn);
return true;

@ -18,7 +18,7 @@
*/
/** Request data from the sampling module. Count - number of samples. */
bool meas_request_data(uint16_t count); // TODO specify what kind of data - currently direct samples.
bool meas_request_data(uint16_t count, uint32_t freq); // TODO specify what kind of data - currently direct samples.
/** request next chunk */
void meas_request_next_chunk(void);

Loading…
Cancel
Save