mirror of
https://github.com/EEVengers/ThunderScope.git
synced 2025-04-22 17:43:44 +00:00
commit
ec2caa0088
Software/waveview
@ -34,8 +34,8 @@ Prepend the name with `CMD_` to find it in the Electron and C++ code.
|
||||
Cmd | DataSize | Name | Description
|
||||
-----|-----------------|---------------|------------------------
|
||||
0x01 | 2 (useless) | GetData1 |
|
||||
0x05 | 2 | GetMin | Data has ch 1,2,3 or 4
|
||||
0x06 | 2 | GetMax | Data has ch 1,2,3 or 4
|
||||
0x05 | 4 | GetMin | Data: `[ch1, ch2, ch3, ch4]`, each 1 or 0
|
||||
0x06 | 4 | GetMax | Data: `[ch1, ch2, ch3, ch4]`, each 1 or 0
|
||||
0x11 | 2 | SetFile | Number mapped to filename by C++
|
||||
0x1F | 2 (useless) | RampDemo |
|
||||
0x21 | 2 (useless) | GetWindowSize |
|
||||
@ -63,8 +63,8 @@ Note that the encoding used by the protocol might not be same as the encoding us
|
||||
Cmd | DataSize | Name | Description
|
||||
-----|-----------------|---------------|------------------------
|
||||
0x01 | ch * windowSize | GetData1 | Data for all ch
|
||||
0x05 | 16 | GetMin | Data has x and y as uint64 and int64
|
||||
0x06 | 16 | GetMax | Data has x and y as uint64 and int64
|
||||
0x05 | 64 | GetMin | Data has `[x1, x2...]` and `[y1, y2..]` as uint64 and int64
|
||||
0x06 | 64 | GetMax | Data has `[x1, x2...]` and `[y1, y2..]` as uint64 and int64
|
||||
0x11 | 0 | SetFile | Set testdata filename
|
||||
0x1F | 4096 | RampDemo | 4 ch, simple waves
|
||||
0x21 | 4 | GetWindowSize | Data has window size as uint32
|
||||
@ -83,20 +83,29 @@ Cmd | DataSize | Name | Description
|
||||
|
||||
### Electron -> C++
|
||||
|
||||
Cmd | DataSize | Name | Description
|
||||
-----|-----------------|---------------|------------------------
|
||||
0x02 | 2 (useless) | GetData2 | Reserved, If we need 1 command/ch
|
||||
0x03 | 2 (useless) | GetData3 | Reserved, If we need 1 command/ch
|
||||
0x04 | 2 (useless) | GetData4 | Reserved, If we need 1 command/ch
|
||||
Cmd | DataSize | Name | Description
|
||||
-----|-----------------|---------------------|------------------------
|
||||
0x02 | 2 (useless) | GetData2 | Reserved, If we need 1 command/ch
|
||||
0x03 | 2 (useless) | GetData3 | Reserved, If we need 1 command/ch
|
||||
0x04 | 2 (useless) | GetData4 | Reserved, If we need 1 command/ch
|
||||
0x36 | 2? | SetBandwidth |
|
||||
0x37 | 2? | SetVerticalScaling |
|
||||
0x38 | 2 | SetVerticalOffset | Data\[0\] has offset
|
||||
0x39 | 2? | SetHorizontalOffset |
|
||||
0x3A | 2 | SetCoupling | Data\[0\] has 0\1 for AC\DC
|
||||
|
||||
### C++ -> Electron
|
||||
|
||||
Cmd | DataSize | Name | Description
|
||||
-----|-----------------|---------------|------------------------
|
||||
0x02 | windowSize | Reserved | If we need 1 command/ch
|
||||
0x03 | windowSize | Reserved | If we need 1 command/ch
|
||||
0x04 | windowSize | Reserved | If we need 1 command/ch
|
||||
Cmd | DataSize | Name | Description
|
||||
-----|-----------------|---------------------|------------------------
|
||||
0x02 | windowSize | Reserved | If we need 1 command/ch
|
||||
0x03 | windowSize | Reserved | If we need 1 command/ch
|
||||
0x04 | windowSize | Reserved | If we need 1 command/ch
|
||||
0x36 | 0 | SetBandwidth |
|
||||
0x37 | 0 | SetVerticalScaling |
|
||||
0x38 | 0 | SetVerticalOffset |
|
||||
0x39 | 0 | SetHorizontalOffset |
|
||||
0x3A | 0 | SetCoupling |
|
||||
|
||||
## Proposed But Not Allocated
|
||||
|
||||
+ (none)
|
||||
|
@ -90,6 +90,11 @@ enum CMD {
|
||||
CMD_SetLevel = 0x33,
|
||||
CMD_SetTriggerCh = 0x34,
|
||||
CMD_SetEdgeType = 0x35,
|
||||
CMD_SetBandwidth = 0x36,
|
||||
CMD_SetVerticalScaling = 0x37,
|
||||
CMD_SetVerticalOffset = 0x38,
|
||||
CMD_SetHorizontalOffset = 0x39,
|
||||
CMD_SetCoupling = 0x3A,
|
||||
CMD_SetMath = 0x3F
|
||||
};
|
||||
|
||||
|
@ -107,27 +107,29 @@ void controller::controllerLoop()
|
||||
break;
|
||||
case CMD_GetMin: {
|
||||
INFO << "Packet command: GetMin";
|
||||
const int incomingPacketSize = 2;
|
||||
int ch = 1;
|
||||
if(currentPacket->dataSize != incomingPacketSize) {
|
||||
const int maxCh = 4;
|
||||
const int incomingDataSize = maxCh;
|
||||
//calloc to ensure zero
|
||||
int8_t* outgoingData = (int8_t*) calloc(2*maxCh, sizeof(uint64_t));
|
||||
if(currentPacket->dataSize != incomingDataSize) {
|
||||
ERROR << "Unexpected size for GetMin packet";
|
||||
}
|
||||
else {
|
||||
ch = currentPacket->data[0];
|
||||
uint64_t* outgoingU = (uint64_t*) outgoingData;
|
||||
int64_t* outgoingS = (int64_t*) outgoingData;
|
||||
for(int ch = 0; ch < incomingDataSize; ch++) {
|
||||
if(currentPacket->data[ch]) {
|
||||
int8_t val;
|
||||
uint64_t pos;
|
||||
getMin(ch + 1, &val, &pos);
|
||||
outgoingU[ch] = pos;
|
||||
outgoingS[ch + maxCh] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
int8_t val;
|
||||
uint64_t pos;
|
||||
getMin(ch, &val, &pos);
|
||||
|
||||
const int outgoingPacketSize = 2*sizeof(uint64_t);
|
||||
uint64_t* outgoingU = (uint64_t*) malloc(outgoingPacketSize);
|
||||
int64_t* outgoingS = (int64_t*) outgoingU;
|
||||
outgoingU[0] = pos;
|
||||
outgoingS[1] = val;
|
||||
|
||||
EVPacket* tempPacket = (EVPacket*) malloc(sizeof(EVPacket));
|
||||
tempPacket->data = (int8_t*)outgoingU;
|
||||
tempPacket->dataSize = outgoingPacketSize;
|
||||
tempPacket->data = outgoingData;
|
||||
tempPacket->dataSize = 2*maxCh*sizeof(uint64_t);
|
||||
tempPacket->packetID = 0;
|
||||
tempPacket->command = CMD_GetMin;
|
||||
controllerQueue_tx.push(tempPacket);
|
||||
@ -135,31 +137,31 @@ void controller::controllerLoop()
|
||||
break;
|
||||
case CMD_GetMax: {
|
||||
INFO << "Packet command: GetMax";
|
||||
const int incomingPacketSize = 2;
|
||||
int ch = 1;
|
||||
if(currentPacket->dataSize != incomingPacketSize) {
|
||||
ERROR << "Unexpected size for GetMax packet";
|
||||
const int maxCh = 4;
|
||||
const int incomingDataSize = maxCh;
|
||||
//calloc to ensure zero
|
||||
int8_t* outgoingData = (int8_t*) calloc(2*maxCh, sizeof(uint64_t));
|
||||
if(currentPacket->dataSize != incomingDataSize) {
|
||||
ERROR << "Unexpected size for GetMin packet";
|
||||
}
|
||||
else {
|
||||
ch = currentPacket->data[0];
|
||||
uint64_t* outgoingU = (uint64_t*) outgoingData;
|
||||
int64_t* outgoingS = (int64_t*) outgoingData;
|
||||
for(int ch = 0; ch < incomingDataSize; ch++) {
|
||||
if(currentPacket->data[ch]) {
|
||||
int8_t val;
|
||||
uint64_t pos;
|
||||
getMax(ch + 1, &val, &pos);
|
||||
outgoingU[ch] = pos;
|
||||
outgoingS[ch + maxCh] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
int8_t val;
|
||||
uint64_t pos;
|
||||
getMax(ch, &val, &pos);
|
||||
|
||||
INFO << "val: " << convert_int(val) << ", pos: " << convert_int(pos);
|
||||
|
||||
const int outgoingPacketSize = 2*sizeof(uint64_t);
|
||||
uint64_t* outgoingU = (uint64_t*) malloc(outgoingPacketSize);
|
||||
int64_t* outgoingS = (int64_t*) outgoingU;
|
||||
outgoingU[0] = pos;
|
||||
outgoingS[1] = val;
|
||||
|
||||
EVPacket* tempPacket = (EVPacket*) malloc(sizeof(EVPacket));
|
||||
tempPacket->data = (int8_t*)outgoingU;
|
||||
tempPacket->dataSize = outgoingPacketSize;
|
||||
tempPacket->data = outgoingData;
|
||||
tempPacket->dataSize = 2*maxCh*sizeof(uint64_t);
|
||||
tempPacket->packetID = 0;
|
||||
tempPacket->command = CMD_GetMax;
|
||||
tempPacket->command = CMD_GetMin;
|
||||
controllerQueue_tx.push(tempPacket);
|
||||
}
|
||||
break;
|
||||
|
@ -19,8 +19,8 @@ Trigger::Trigger(boost::lockfree::queue<buffer*, boost::lockfree::fixed_sized<fa
|
||||
triggerLevel = level;
|
||||
clearCount();
|
||||
|
||||
stopTrigger.store(false);
|
||||
pauseTrigger.store(true);
|
||||
stopTrigger.store(false);
|
||||
pauseTrigger.store(true);
|
||||
triggerMet.store(false);
|
||||
|
||||
// start thread paused
|
||||
@ -54,7 +54,7 @@ void Trigger::checkTriggerFalling(buffer* currentBuffer)
|
||||
DEBUG << "Checking a Trigger with #ch: " << (int)numCh << " triggering on ch: " << (int)triggerCh;
|
||||
// Compute the trigger
|
||||
for (int i = 0; i < (BUFFER_SIZE/64)/numCh; i++) {
|
||||
currentBuffer->trigger[i] =
|
||||
currentBuffer->trigger[i] =
|
||||
((uint64_t)((currentBuffer->data[(i * 64 + 0) * numCh + triggerCh] > triggerLevel) &&
|
||||
(currentBuffer->data[(i * 64 + 0 + 1) * numCh + triggerCh] <= triggerLevel)) << 63) |
|
||||
((uint64_t)((currentBuffer->data[(i * 64 + 1) * numCh + triggerCh] > triggerLevel) &&
|
||||
@ -198,7 +198,7 @@ void Trigger::checkTriggerRising(buffer* currentBuffer)
|
||||
DEBUG << "Checking a Trigger with #ch: " << (int)numCh << " triggering on ch: " << (int)triggerCh;
|
||||
// Compute the trigger
|
||||
for (int i = 0; i < (BUFFER_SIZE/64)/numCh; i++) {
|
||||
currentBuffer->trigger[i] =
|
||||
currentBuffer->trigger[i] =
|
||||
((uint64_t)((currentBuffer->data[(i * 64 + 0) * numCh + triggerCh] < triggerLevel) &&
|
||||
(currentBuffer->data[(i * 64 + 0 + 1) * numCh + triggerCh] >= triggerLevel)) << 63) |
|
||||
((uint64_t)((currentBuffer->data[(i * 64 + 1) * numCh + triggerCh] < triggerLevel) &&
|
||||
@ -420,7 +420,7 @@ int8_t Trigger::getTriggerCh ()
|
||||
// Sets the channel to trigger off of
|
||||
void Trigger::setTriggerCh (int8_t newTriggerCh)
|
||||
{
|
||||
if (newTriggerCh == 1 || newTriggerCh == 2 || newTriggerCh == 4) {
|
||||
if (newTriggerCh == 1 || newTriggerCh == 2 || newTriggerCh == 3 || newTriggerCh == 4) {
|
||||
triggerCh = newTriggerCh - 1;
|
||||
} else {
|
||||
ERROR << "Invalid trigger channel: " << newTriggerCh;
|
||||
|
@ -3,62 +3,15 @@ import './App.css';
|
||||
import Graph from './components/graph/graph';
|
||||
import BottomBar from './components/bottombar/bottombar';
|
||||
import Sidebar from './components/sidebar/sidebar';
|
||||
import TestPoints from './util/testpoints';
|
||||
import TestConf from './util/testconf';
|
||||
|
||||
interface IAppState {
|
||||
tickCount: number;
|
||||
}
|
||||
|
||||
let initialState: IAppState = {tickCount: 0};
|
||||
|
||||
class App extends React.Component {
|
||||
state: IAppState;
|
||||
timerID: number = 0;
|
||||
generator: TestPoints;
|
||||
conf: TestConf;
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = initialState;
|
||||
this.generator = new TestPoints(50, 50);
|
||||
this.conf = new TestConf();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.timerID = window.setInterval(
|
||||
() => this.tick(),
|
||||
16.67
|
||||
);
|
||||
this.generator.mountCalls();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.timerID)
|
||||
}
|
||||
|
||||
tick() {
|
||||
let tickCount = this.state.tickCount + 1;
|
||||
this.generator.update();
|
||||
if(tickCount % 100 === 0) {
|
||||
console.log(tickCount);
|
||||
this.conf.update(tickCount % 500 !== 0);
|
||||
//this.conf.mathUpdate();
|
||||
}
|
||||
this.setState({tickCount: tickCount});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="App">
|
||||
<header
|
||||
className="App-header">
|
||||
</header>
|
||||
<Graph
|
||||
yDomain={this.generator.y.getDomain()}
|
||||
xDomain={this.generator.x.getDomain()}
|
||||
dataSeries={this.generator.getData()}
|
||||
/>
|
||||
<Graph />
|
||||
<BottomBar />
|
||||
<Sidebar />
|
||||
</div>
|
||||
|
@ -10,36 +10,62 @@ import {
|
||||
LineSeries
|
||||
} from 'react-vis';
|
||||
|
||||
class Graph extends React.Component<any, any> {
|
||||
import GraphStatus from '../../configuration/enums/graphStatus';
|
||||
import TestPoints from '../../util/testpoints';
|
||||
|
||||
class Graph extends React.Component<any, any> {
|
||||
static instanceList: Graph[] = [];
|
||||
timerID: number = 0;
|
||||
generator: TestPoints = new TestPoints(50, 50);
|
||||
|
||||
componentDidMount() {
|
||||
Graph.instanceList.push(this);
|
||||
this.timerID = window.setInterval(
|
||||
() => this.tick(),
|
||||
16.67
|
||||
);
|
||||
this.generator.mountCalls();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.timerID)
|
||||
}
|
||||
|
||||
tick() {
|
||||
if(this.props.graph.currentStatus === GraphStatus.On) {
|
||||
this.props.dispatch({type: 'graph/tick'});
|
||||
this.generator.update();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="graph_view">
|
||||
<div
|
||||
<div
|
||||
className="graph_sidebar"
|
||||
>
|
||||
<p
|
||||
<p
|
||||
className = "graph_arrow"
|
||||
>
|
||||
↳
|
||||
</p>
|
||||
</div>
|
||||
<FlexibleXYPlot
|
||||
yDomain={this.props.yDomain}
|
||||
xDomain={this.props.xDomain}
|
||||
yDomain={this.generator.y.getDomain()}
|
||||
xDomain={this.generator.x.getDomain()}
|
||||
margin={{right:0, bottom:0}}
|
||||
>
|
||||
<HorizontalGridLines
|
||||
<HorizontalGridLines
|
||||
style={{stroke: '#4D4D4D'}}
|
||||
left={0}
|
||||
left={0}
|
||||
top={0}
|
||||
width={10000}
|
||||
height={10000}
|
||||
tickTotal={12}
|
||||
/>
|
||||
<VerticalGridLines
|
||||
<VerticalGridLines
|
||||
style={{stroke: '#4D4D4D'}}
|
||||
left={0}
|
||||
left={0}
|
||||
top={0}
|
||||
width={10000}
|
||||
height={10000}
|
||||
@ -49,12 +75,12 @@ class Graph extends React.Component<any, any> {
|
||||
title=""
|
||||
hideTicks
|
||||
/>
|
||||
<YAxis
|
||||
title=""
|
||||
<YAxis
|
||||
title=""
|
||||
hideTicks
|
||||
/>
|
||||
{
|
||||
this.props.dataSeries.map((data: any, index: any) => {
|
||||
this.generator.getData().map((data: any, index: any) => {
|
||||
return <LineSeries
|
||||
className="data-series"
|
||||
data={data}
|
||||
|
@ -1,11 +1,16 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import './../../../css/sidebar/core/singleButton.css';
|
||||
import Graph from '../../graph/graph';
|
||||
|
||||
class SingleButton extends React.Component<any, any> {
|
||||
|
||||
toggleSingleMode = () => {
|
||||
this.props.dispatch({type: 'graph/singleMode'});
|
||||
//this.props.dispatch({type: 'graph/singleMode'}); //TODO: something about this
|
||||
if(Graph.instanceList.length > 0) {
|
||||
this.props.dispatch({type: 'graph/tick'});
|
||||
Graph.instanceList[0].generator.update();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -2,8 +2,60 @@ import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import MathType from '../../../configuration/enums/mathType';
|
||||
import './../../../css/sidebar/widgets/measurementsWidget.css';
|
||||
import GraphStatus from '../../../configuration/enums/graphStatus';
|
||||
|
||||
import CMD from '../../../configuration/enums/cmd';
|
||||
import {Plumber, PlumberArgs} from '../../../util/plumber';
|
||||
|
||||
class MeasurementsWidget extends React.Component<any, any> {
|
||||
timerID: number = 0;
|
||||
|
||||
componentDidMount() {
|
||||
this.timerID = window.setInterval(
|
||||
() => this.tick(),
|
||||
1000
|
||||
);
|
||||
}
|
||||
|
||||
tick() {
|
||||
if(this.props.graph.currentStatus === GraphStatus.On) {
|
||||
this.props.dispatch({type: 'measurements/tick'});
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
|
||||
update() {
|
||||
//TODO: unit analysis
|
||||
let channels = this.props.measurementsWidget.displayChannel as boolean[];
|
||||
let channelNum = channels.map(v => v ? 1 : 0) as number[];
|
||||
if(channelNum.reduce((a, b) => a + b) == 0) {
|
||||
return; //Don't bother C if we don't need to.
|
||||
}
|
||||
let maxArgs: PlumberArgs = {
|
||||
headCheck: () => true,
|
||||
bodyCheck: (args, bytesRead, body) => {
|
||||
let decoded = Plumber.getInstance().decodeGetMinMax(args, body);
|
||||
this.props.dispatch({type: 'measurements/setMax', payload: decoded });
|
||||
return true;
|
||||
},
|
||||
cmd: CMD.CMD_GetMax,
|
||||
id: 0,
|
||||
writeData: channelNum
|
||||
}
|
||||
let minArgs: PlumberArgs = {
|
||||
headCheck: () => true,
|
||||
bodyCheck: (args, bytesRead, body) => {
|
||||
let decoded = Plumber.getInstance().decodeGetMinMax(args, body);
|
||||
this.props.dispatch({type: 'measurements/setMin', payload: decoded });
|
||||
return true;
|
||||
},
|
||||
cmd: CMD.CMD_GetMin,
|
||||
id: 0,
|
||||
writeData: channelNum
|
||||
}
|
||||
Plumber.getInstance().cycle(maxArgs);
|
||||
Plumber.getInstance().cycle(minArgs);
|
||||
}
|
||||
|
||||
measureChannel = (channelNumber: number) => {
|
||||
this.props.dispatch({type: 'measurements/selectChannel', payload: channelNumber });
|
||||
@ -58,31 +110,31 @@ class MeasurementsWidget extends React.Component<any, any> {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{this.props.measurementsWidget.displayChannel[0] === true &&
|
||||
{this.props.measurementsWidget.displayChannel[0] === true &&
|
||||
<div className="Channel1Measurements-Title">
|
||||
CH1 Measurements
|
||||
</div>
|
||||
}
|
||||
{this.props.measurementsWidget.displayChannel[0] === true &&
|
||||
{this.props.measurementsWidget.displayChannel[0] === true &&
|
||||
<div className="Channel1Measurements">
|
||||
<label
|
||||
<label
|
||||
className="Channel1-MaxLabel"
|
||||
style={{color: this.props.settings.colors.channel[0]}}>
|
||||
{MathType.Max}
|
||||
</label>
|
||||
<label
|
||||
<label
|
||||
className="Channel1-MaxValue"
|
||||
style={{color: this.props.settings.colors.channel[0]}}>
|
||||
{this.props.measurementsWidget.max[0].value}
|
||||
{this.props.measurementsWidget.max[0].unit}
|
||||
</label>
|
||||
<div className="ClearBlock"></div>
|
||||
<label
|
||||
<label
|
||||
className="Channel1-MinLabel"
|
||||
style={{color: this.props.settings.colors.channel[0]}}>
|
||||
{MathType.Min}
|
||||
</label>
|
||||
<label
|
||||
<label
|
||||
className="Channel1-MinValue"
|
||||
style={{color: this.props.settings.colors.channel[0]}}>
|
||||
{this.props.measurementsWidget.min[0].value}
|
||||
@ -92,31 +144,31 @@ class MeasurementsWidget extends React.Component<any, any> {
|
||||
</div>
|
||||
}
|
||||
|
||||
{this.props.measurementsWidget.displayChannel[1] === true &&
|
||||
{this.props.measurementsWidget.displayChannel[1] === true &&
|
||||
<div className="Channel2Measurements-Title">
|
||||
CH2 Measurements
|
||||
</div>
|
||||
}
|
||||
{this.props.measurementsWidget.displayChannel[1] === true &&
|
||||
{this.props.measurementsWidget.displayChannel[1] === true &&
|
||||
<div className="Channel2Measurements">
|
||||
<label
|
||||
<label
|
||||
className="Channel2-MaxLabel"
|
||||
style={{color: this.props.settings.colors.channel[1]}}>
|
||||
{MathType.Max}
|
||||
</label>
|
||||
<label
|
||||
<label
|
||||
className="Channel2-MaxValue"
|
||||
style={{color: this.props.settings.colors.channel[1]}}>
|
||||
{this.props.measurementsWidget.max[1].value}
|
||||
{this.props.measurementsWidget.max[1].unit}
|
||||
</label>
|
||||
<div className="ClearBlock"></div>
|
||||
<label
|
||||
<label
|
||||
className="Channel2-MinLabel"
|
||||
style={{color: this.props.settings.colors.channel[1]}}>
|
||||
{MathType.Min}
|
||||
</label>
|
||||
<label
|
||||
<label
|
||||
className="Channel2-MinValue"
|
||||
style={{color: this.props.settings.colors.channel[1]}}>
|
||||
{this.props.measurementsWidget.min[1].value}
|
||||
@ -126,31 +178,31 @@ class MeasurementsWidget extends React.Component<any, any> {
|
||||
</div>
|
||||
}
|
||||
|
||||
{this.props.measurementsWidget.displayChannel[2] === true &&
|
||||
{this.props.measurementsWidget.displayChannel[2] === true &&
|
||||
<div className="Channel3Measurements-Title">
|
||||
CH3 Measurements
|
||||
</div>
|
||||
}
|
||||
{this.props.measurementsWidget.displayChannel[2] === true &&
|
||||
{this.props.measurementsWidget.displayChannel[2] === true &&
|
||||
<div className="Channel3Measurements">
|
||||
<label
|
||||
<label
|
||||
className="Channel3-MaxLabel"
|
||||
style={{color: this.props.settings.colors.channel[2]}}>
|
||||
{MathType.Max}
|
||||
</label>
|
||||
<label
|
||||
<label
|
||||
className="Channel3-MaxValue"
|
||||
style={{color: this.props.settings.colors.channel[2]}}>
|
||||
{this.props.measurementsWidget.max[2].value}
|
||||
{this.props.measurementsWidget.max[2].unit}
|
||||
</label>
|
||||
<div className="ClearBlock"></div>
|
||||
<label
|
||||
<label
|
||||
className="Channel3-MinLabel"
|
||||
style={{color: this.props.settings.colors.channel[2]}}>
|
||||
{MathType.Min}
|
||||
</label>
|
||||
<label
|
||||
<label
|
||||
className="Channel3-MinValue"
|
||||
style={{color: this.props.settings.colors.channel[2]}}>
|
||||
{this.props.measurementsWidget.min[2].value}
|
||||
@ -160,31 +212,31 @@ class MeasurementsWidget extends React.Component<any, any> {
|
||||
</div>
|
||||
}
|
||||
|
||||
{this.props.measurementsWidget.displayChannel[3] === true &&
|
||||
{this.props.measurementsWidget.displayChannel[3] === true &&
|
||||
<div className="Channel4Measurements-Title">
|
||||
CH4 Measurements
|
||||
</div>
|
||||
}
|
||||
{this.props.measurementsWidget.displayChannel[3] === true &&
|
||||
{this.props.measurementsWidget.displayChannel[3] === true &&
|
||||
<div className="Channel4Measurements">
|
||||
<label
|
||||
<label
|
||||
className="Channel4-MaxLabel"
|
||||
style={{color: this.props.settings.colors.channel[3]}}>
|
||||
{MathType.Max}
|
||||
</label>
|
||||
<label
|
||||
<label
|
||||
className="Channel4-MaxValue"
|
||||
style={{color: this.props.settings.colors.channel[3]}}>
|
||||
{this.props.measurementsWidget.max[3].value}
|
||||
{this.props.measurementsWidget.max[3].unit}
|
||||
</label>
|
||||
<div className="ClearBlock"></div>
|
||||
<label
|
||||
<label
|
||||
className="Channel4-MinLabel"
|
||||
style={{color: this.props.settings.colors.channel[3]}}>
|
||||
{MathType.Min}
|
||||
</label>
|
||||
<label
|
||||
<label
|
||||
className="Channel4-MinValue"
|
||||
style={{color: this.props.settings.colors.channel[3]}}>
|
||||
{this.props.measurementsWidget.min[3].value}
|
||||
@ -199,10 +251,11 @@ class MeasurementsWidget extends React.Component<any, any> {
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state: { measurementsWidget: any, settings: any }) {
|
||||
function mapStateToProps(state: { measurementsWidget: any, settings: any, graph: any }) {
|
||||
return {
|
||||
measurementsWidget: state.measurementsWidget,
|
||||
settings: state.settings
|
||||
settings: state.settings,
|
||||
graph: state.graph
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,9 @@ import './../../../css/sidebar/widgets/triggerWidget.css';
|
||||
import VoltageUnit from '../../../configuration/enums/voltageUnit';
|
||||
import TriggerType from '../../../configuration/enums/triggerType';
|
||||
|
||||
import CMD from '../../../configuration/enums/cmd';
|
||||
import {Plumber, PlumberArgs} from '../../../util/plumber';
|
||||
|
||||
class TriggerWidget extends React.Component<any, any> {
|
||||
|
||||
// Trigger Channel
|
||||
@ -16,25 +19,48 @@ class TriggerWidget extends React.Component<any, any> {
|
||||
}
|
||||
|
||||
changeChannel = (channelNumber: number) => {
|
||||
let args: PlumberArgs = {
|
||||
headCheck: () => true,
|
||||
bodyCheck: () => true,
|
||||
cmd: CMD.CMD_SetTriggerCh,
|
||||
id: 0,
|
||||
writeData: [channelNumber, 0]
|
||||
};
|
||||
Plumber.getInstance().cycle(args);
|
||||
this.props.dispatch({type: 'trigger/changeChannel', payload: channelNumber})
|
||||
}
|
||||
|
||||
// Trigger Type
|
||||
changeTriggerType = (triggerType: TriggerType) => {
|
||||
let edgeNum = (triggerType == TriggerType.RisingEdge) ? 1 : 2;
|
||||
let args: PlumberArgs = {
|
||||
headCheck: () => true,
|
||||
bodyCheck: () => true,
|
||||
cmd: CMD.CMD_SetEdgeType,
|
||||
id: 0,
|
||||
writeData: [edgeNum, 0]
|
||||
}
|
||||
Plumber.getInstance().cycle(args);
|
||||
this.props.dispatch({type: 'trigger/changeTriggerType', payload: triggerType});
|
||||
}
|
||||
|
||||
// Trigger Level
|
||||
increaseTriggerLevel = () => {
|
||||
//TODO: Plumber call
|
||||
//(TRIGGER LEVEL (V))/((VOLTAGE RANGExDIVISIONS)/256)
|
||||
this.props.dispatch({type: 'trigger/increaseTriggerLevelValue'});
|
||||
}
|
||||
|
||||
decreaseTriggerLevel = () => {
|
||||
//TODO: Plumber call
|
||||
//(TRIGGER LEVEL (V))/((VOLTAGE RANGExDIVISIONS)/256)
|
||||
this.props.dispatch({type: 'trigger/decreaseTriggerLevelValue'});
|
||||
}
|
||||
|
||||
// Trigger Level Unit
|
||||
changeTriggerLevelUnit = (voltageUnit: VoltageUnit) => {
|
||||
//TODO: unit analysis, plumber call
|
||||
//(TRIGGER LEVEL (V))/((VOLTAGE RANGExDIVISIONS)/256)
|
||||
this.props.dispatch({type: 'trigger/changeTriggerLevelUnit', payload: voltageUnit});
|
||||
}
|
||||
|
||||
@ -115,19 +141,19 @@ class TriggerWidget extends React.Component<any, any> {
|
||||
Trigger Level
|
||||
</div>
|
||||
<div className="TriggerWidgetAdjustTriggerLevelValue">
|
||||
<button
|
||||
<button
|
||||
className="MinusButton"
|
||||
onClick={() => this.decreaseTriggerLevel()}>
|
||||
-
|
||||
</button>
|
||||
<label
|
||||
<label
|
||||
className="AdjustChannelBlockValue"
|
||||
style={{color: this.props.settings.colors.channel[this.props.triggerWidget.triggerChannel-1]}}
|
||||
>
|
||||
{this.props.triggerWidget.triggerLevel[this.props.triggerWidget.triggerChannel-1].value.toString()}
|
||||
{this.props.triggerWidget.triggerLevel[this.props.triggerWidget.triggerChannel-1].unit}
|
||||
</label>
|
||||
<button
|
||||
<button
|
||||
className="PlusButton"
|
||||
onClick={() => this.increaseTriggerLevel()}>
|
||||
+
|
||||
@ -172,7 +198,7 @@ class TriggerWidget extends React.Component<any, any> {
|
||||
</label>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
35
Software/waveview/src/configuration/enums/cmd.tsx
Normal file
35
Software/waveview/src/configuration/enums/cmd.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
enum CMD {
|
||||
//Data commands
|
||||
CMD_GetData1 = 0x01,
|
||||
CMD_GetData2 = 0x02,
|
||||
CMD_GetData3 = 0x03,
|
||||
CMD_GetData4 = 0x04,
|
||||
CMD_GetMin = 0x05,
|
||||
CMD_GetMax = 0x06,
|
||||
|
||||
//Demo commands
|
||||
CMD_SetFile = 0x11,
|
||||
CMD_RampDemo = 0x1F,
|
||||
|
||||
//Get Config commands
|
||||
CMD_GetWindowSize = 0x21,
|
||||
CMD_GetCh = 0x22,
|
||||
CMD_GetLevel = 0x23,
|
||||
CMD_GetTriggerCh = 0x24,
|
||||
CMD_GetEdgeType = 0x25,
|
||||
|
||||
//Set Config commands
|
||||
CMD_SetWindowSize = 0x31,
|
||||
CMD_SetCh = 0x32,
|
||||
CMD_SetLevel = 0x33,
|
||||
CMD_SetTriggerCh = 0x34,
|
||||
CMD_SetEdgeType = 0x35,
|
||||
CMD_SetBandwidth = 0x36,
|
||||
CMD_SetVerticalScaling = 0x37,
|
||||
CMD_SetVerticalOffset = 0x38,
|
||||
CMD_SetHorizontalOffset = 0x39,
|
||||
CMD_SetCoupling = 0x3A,
|
||||
CMD_SetMath = 0x3F
|
||||
}
|
||||
|
||||
export default CMD;
|
@ -4,7 +4,8 @@ const GraphInitialState = {
|
||||
currentStatus: GraphStatus.On,
|
||||
singleMode: false,
|
||||
xDomain: [0,0],
|
||||
yDomain: [0,0]
|
||||
yDomain: [0,0],
|
||||
tickCount: 0
|
||||
};
|
||||
|
||||
export default GraphInitialState;
|
@ -30,27 +30,28 @@ const MeasurementsWidgetInitialState = {
|
||||
}
|
||||
],
|
||||
min: [
|
||||
{
|
||||
{
|
||||
value: 10,
|
||||
unit: VoltageUnit.MicroVolt,
|
||||
display: false
|
||||
},
|
||||
{
|
||||
{
|
||||
value: 20,
|
||||
unit: VoltageUnit.NanoVolt,
|
||||
display: false
|
||||
},
|
||||
{
|
||||
{
|
||||
value: 30,
|
||||
unit: VoltageUnit.MilliVolt,
|
||||
display: false
|
||||
},
|
||||
{
|
||||
{
|
||||
value: 40,
|
||||
unit: VoltageUnit.Volt,
|
||||
display: false
|
||||
}
|
||||
]
|
||||
],
|
||||
tickCount: 0
|
||||
};
|
||||
|
||||
export default MeasurementsWidgetInitialState;
|
||||
|
@ -16,6 +16,11 @@ export default function(state = GraphInitialState, action: {type: any, payload:
|
||||
currentStatus: GraphStatus.Off,
|
||||
singleMode: !state.singleMode
|
||||
};
|
||||
case "graph/tick":
|
||||
return {
|
||||
...state,
|
||||
tickCount: state.tickCount + 1
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import MeasurementsWidgetInitialState from '../../initialStates/measurementsWidgetInitialState';
|
||||
import { MaxMinResult } from '../../../util/plumber';
|
||||
|
||||
export default function(state = MeasurementsWidgetInitialState, action: {type: any, payload: any}) {
|
||||
export default function(state = MeasurementsWidgetInitialState, action: {type: any, payload: any}) {
|
||||
var tmp;
|
||||
|
||||
switch(action.type) {
|
||||
@ -12,6 +13,33 @@ export default function(state = MeasurementsWidgetInitialState, action: {type: a
|
||||
...state,
|
||||
displayChannel: tmp
|
||||
};
|
||||
case "measurements/setMax":
|
||||
//TODO: unit analysis
|
||||
let setMaxPayload = action.payload as MaxMinResult[];
|
||||
tmp = state.max
|
||||
for(let maxItem of setMaxPayload) {
|
||||
tmp[maxItem.ch - 1].value = maxItem.y;
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
max: tmp
|
||||
}
|
||||
case "measurements/setMin":
|
||||
//TODO: unit analysis
|
||||
let setMinPayload = action.payload as MaxMinResult[];
|
||||
tmp = state.min
|
||||
for(let minItem of setMinPayload) {
|
||||
tmp[minItem.ch - 1].value = minItem.y;
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
min: tmp
|
||||
}
|
||||
case "measurements/tick":
|
||||
return {
|
||||
...state,
|
||||
tickCount: state.tickCount + 1
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
24
Software/waveview/src/util/convert.ts
Normal file
24
Software/waveview/src/util/convert.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import VoltageUnit from '../configuration/enums/voltageUnit';
|
||||
import TimeUnit from '../configuration/enums/timeUnit';
|
||||
|
||||
function convertVoltage(x: number, from: VoltageUnit, to: VoltageUnit) {
|
||||
let power = {
|
||||
[VoltageUnit.NanoVolt]: -9,
|
||||
[VoltageUnit.MicroVolt]: -6,
|
||||
[VoltageUnit.MilliVolt]: -3,
|
||||
[VoltageUnit.Volt]: 0
|
||||
}
|
||||
return x * Math.pow(10, power[from] - power[to]);
|
||||
}
|
||||
|
||||
function convertTime(x: number, from: TimeUnit, to: TimeUnit) {
|
||||
let power = {
|
||||
[TimeUnit.NanoSecond]: -9,
|
||||
[TimeUnit.MicroSecond]: -6,
|
||||
[TimeUnit.MilliSecond]: -3,
|
||||
[TimeUnit.Second]: 0
|
||||
}
|
||||
return x * Math.pow(10, power[from] - power[to]);
|
||||
}
|
||||
|
||||
export {convertVoltage, convertTime}
|
@ -1,31 +1,4 @@
|
||||
export enum CMD {
|
||||
//Data commands
|
||||
CMD_GetData1 = 0x01,
|
||||
CMD_GetData2 = 0x02,
|
||||
CMD_GetData3 = 0x03,
|
||||
CMD_GetData4 = 0x04,
|
||||
CMD_GetMin = 0x05,
|
||||
CMD_GetMax = 0x06,
|
||||
|
||||
//Demo commands
|
||||
CMD_SetFile = 0x11,
|
||||
CMD_RampDemo = 0x1F,
|
||||
|
||||
//Get Config commands
|
||||
CMD_GetWindowSize = 0x21,
|
||||
CMD_GetCh = 0x22,
|
||||
CMD_GetLevel = 0x23,
|
||||
CMD_GetTriggerCh = 0x24,
|
||||
CMD_GetEdgeType = 0x25,
|
||||
|
||||
//Set Config commands
|
||||
CMD_SetWindowSize = 0x31,
|
||||
CMD_SetCh = 0x32,
|
||||
CMD_SetLevel = 0x33,
|
||||
CMD_SetTriggerCh = 0x34,
|
||||
CMD_SetEdgeType = 0x35,
|
||||
CMD_SetMath = 0x3F
|
||||
}
|
||||
import CMD from '../configuration/enums/cmd';
|
||||
|
||||
export enum SetMathOp {
|
||||
SetMath_None = 0,
|
||||
@ -33,6 +6,12 @@ export enum SetMathOp {
|
||||
SetMath_Minus = 2,
|
||||
}
|
||||
|
||||
export interface MaxMinResult {
|
||||
ch: number,
|
||||
x: number,
|
||||
y: number
|
||||
}
|
||||
|
||||
export interface PlumberArgs {
|
||||
headCheck: (args: PlumberArgs, head: Uint16Array) => boolean;
|
||||
bodyCheck: (args: PlumberArgs, bytesRead: number, body: Int8Array) => boolean;
|
||||
@ -132,9 +111,16 @@ export class Plumber {
|
||||
return [lhsChan, rhsChan, op, 0];
|
||||
}
|
||||
|
||||
public decodeGetMinMax(a: Int8Array) {
|
||||
var a64u = new BigUint64Array(a.buffer);
|
||||
var a64s = new BigInt64Array(a.buffer);
|
||||
return {x: Number(a64u[0]), y: Number(a64s[1])};
|
||||
public decodeGetMinMax(args: PlumberArgs, a: Int8Array) {
|
||||
let maxCh = 4;
|
||||
let a64u = new BigUint64Array(a.buffer);
|
||||
let a64s = new BigInt64Array(a.buffer);
|
||||
var res: MaxMinResult[] = [];
|
||||
for(var i = 0; i < args.writeData.length; i++) {
|
||||
if(args.writeData[i] != 0) {
|
||||
res.push({ch: i + 1, x: Number(a64u[i]), y: Number(a64s[i + maxCh])});
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
import { CMD, PlumberArgs, Plumber } from './plumber';
|
||||
|
||||
class TestConf {
|
||||
getEdgeArgs: PlumberArgs;
|
||||
setEdgeArgs: PlumberArgs;
|
||||
getWinArgs: PlumberArgs;
|
||||
setWinArgs: PlumberArgs;
|
||||
|
||||
getMinArgs: PlumberArgs;
|
||||
getMaxArgs: PlumberArgs;
|
||||
|
||||
constructor() {
|
||||
|
||||
this.getEdgeArgs = {
|
||||
headCheck: (a, head) => true,
|
||||
bodyCheck: (a, bytesRead, body) => {
|
||||
console.log("C++ edge type: " + body[0]);
|
||||
return true;
|
||||
},
|
||||
cmd: CMD.CMD_GetEdgeType,
|
||||
id: 0,
|
||||
writeData: [0, 0]
|
||||
}
|
||||
|
||||
this.setEdgeArgs = {
|
||||
headCheck: () => true,
|
||||
bodyCheck: () => true,
|
||||
cmd: CMD.CMD_SetEdgeType,
|
||||
id: 0,
|
||||
writeData: [2, 0]
|
||||
}
|
||||
|
||||
this.getWinArgs = {
|
||||
headCheck: () => true,
|
||||
bodyCheck: (args, bytesRead, body) => {
|
||||
var body32 = new Uint32Array(body.buffer);
|
||||
console.log(body32);
|
||||
return true;
|
||||
},
|
||||
cmd: CMD.CMD_GetWindowSize,
|
||||
id: 0,
|
||||
writeData: [0, 0]
|
||||
}
|
||||
|
||||
this.setWinArgs = {
|
||||
headCheck: () => {
|
||||
console.log("I set win");
|
||||
return true;
|
||||
},
|
||||
bodyCheck: () => true,
|
||||
cmd: CMD.CMD_SetWindowSize,
|
||||
id: 0,
|
||||
writeData: new Int8Array((new Uint32Array([20])).buffer)
|
||||
}
|
||||
|
||||
this.getMinArgs = {
|
||||
headCheck: () => true,
|
||||
bodyCheck: (args, bytesRead, body) => {
|
||||
console.log(Plumber.getInstance().decodeGetMinMax(body));
|
||||
return true;
|
||||
},
|
||||
cmd: CMD.CMD_GetMin,
|
||||
id: 0,
|
||||
writeData: [3, 0]
|
||||
}
|
||||
|
||||
this.getMaxArgs = {
|
||||
headCheck: () => true,
|
||||
bodyCheck: (args, bytesRead, body) => {
|
||||
console.log(Plumber.getInstance().decodeGetMinMax(body));
|
||||
return true;
|
||||
},
|
||||
cmd: CMD.CMD_GetMax,
|
||||
id: 0,
|
||||
writeData: [3, 0]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update(get: boolean) {
|
||||
/*if(get) {
|
||||
Plumber.getInstance().cycle(this.getWinArgs);
|
||||
}
|
||||
else {
|
||||
Plumber.getInstance().cycle(this.setWinArgs);
|
||||
}*/
|
||||
Plumber.getInstance().cycle(this.getMaxArgs);
|
||||
}
|
||||
}
|
||||
|
||||
export default TestConf;
|
@ -1,4 +1,5 @@
|
||||
import { CMD, PlumberArgs, Plumber, SetMathOp } from './plumber';
|
||||
import CMD from '../configuration/enums/cmd';
|
||||
import { PlumberArgs, Plumber, SetMathOp } from './plumber';
|
||||
|
||||
class Range {
|
||||
dataMin: number = 0;
|
||||
@ -111,6 +112,7 @@ class TestPoints {
|
||||
|
||||
getData() {
|
||||
var chMax = this.effectiveChCount();
|
||||
console.log(this.scope_data);
|
||||
return this.scope_data.slice(0, chMax);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user