/* Copyright (C) Paul Falstad and Iain Sharp This file is part of CircuitJS1. CircuitJS1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. CircuitJS1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CircuitJS1. If not, see <http://www.gnu.org/licenses/>. */ package com.lushprojects.circuitjs1.client; //import java.awt.*; //import java.util.StringTokenizer; // much of this was adapted from Bill Collis's code in TestPointElm.java class ProbeElm extends CircuitElm { static final int FLAG_SHOWVOLTAGE = 1; int meter; final int TP_VOL = 0; final int TP_RMS = 1; final int TP_MAX = 2; final int TP_MIN = 3; final int TP_P2P = 4; final int TP_BIN = 5; final int TP_FRQ = 6; final int TP_PER = 7; final int TP_PWI = 8; final int TP_DUT = 9; //mark to space ratio public ProbeElm(int xx, int yy) { super(xx, yy); meter = TP_VOL; // default for new elements flags = FLAG_SHOWVOLTAGE; } public ProbeElm(int xa, int ya, int xb, int yb, int f, StringTokenizer st) { super(xa, ya, xb, yb, f); meter = TP_VOL; try { meter = new Integer(st.nextToken()).intValue(); //get meter type from saved dump } catch (Exception e) {} } int getDumpType() { return 'p'; } String dump() { return super.dump() + " " + meter ; } String getMeter(){ switch (meter) { case TP_VOL: return "V"; case TP_RMS: return "V(rms)"; case TP_MAX: return "Vmax"; case TP_MIN: return "Vmin"; case TP_P2P: return "Peak to peak"; case TP_BIN: return "Binary"; case TP_FRQ: return "Frequency"; case TP_PER: return "Period"; case TP_PWI: return "Pulse width"; case TP_DUT: return "Duty cycle"; } return ""; } double rmsV=0, total, count; double binaryLevel=0;//0 or 1 - double because we only pass doubles back to the web page int zerocount=0; double maxV=0, lastMaxV; double minV=0, lastMinV; double frequency=0; double period=0; double pulseWidth=0; double dutyCycle=0; double selectedValue=0; boolean increasingV=true, decreasingV=true; long periodStart, periodLength, pulseStart;//time between consecutive max values Point center; void setPoints() { super.setPoints(); center = interpPoint(point1, point2, .5); } void draw(Graphics g) { int hs = 8; setBbox(point1, point2, hs); boolean selected = needsHighlight(); double len = (selected || sim.dragElm == this || mustShowVoltage()) ? 16 : dn-32; calcLeads((int) len); setVoltageColor(g, volts[0]); if (selected) g.setColor(selectColor); drawThickLine(g, point1, lead1); setVoltageColor(g, volts[1]); if (selected) g.setColor(selectColor); drawThickLine(g, lead2, point2); Font f = new Font("SansSerif", Font.BOLD, 14); g.setFont(f); if (this == sim.plotXElm) drawCenteredText(g, "X", center.x, center.y, true); if (this == sim.plotYElm) drawCenteredText(g, "Y", center.x, center.y, true); if (mustShowVoltage()) { String s = ""; switch (meter) { case TP_VOL: s = myGetUnitText(getVoltageDiff(),"V",false); break; case TP_RMS: s = myGetUnitText(rmsV,"V(rms)",false); break; case TP_MAX: s = myGetUnitText(lastMaxV,"Vpk",false); break; case TP_MIN: s = myGetUnitText(lastMinV,"Vmin",false); break; case TP_P2P: s = myGetUnitText(lastMaxV-lastMinV,"Vp2p",false); break; case TP_BIN: s= binaryLevel + ""; break; case TP_FRQ: s = myGetUnitText(frequency, "Hz", false); break; case TP_PER: // s = "percent:"+period + " " + sim.timeStep + " " + sim.simTime + " " + sim.getIterCount(); break; case TP_PWI: s = myGetUnitText(pulseWidth, "S", false); break; case TP_DUT: s = showFormat.format(dutyCycle); break; } drawValues(g, s, 4); } g.setColor(Color.white); g.setFont(unitsFont); Point plusPoint = interpPoint(point1, point2, (dn/2-len/2-4)/dn, -10*dsign ); if (y2 > y) plusPoint.y += 4; if (y > y2) plusPoint.y += 3; int w = (int)g.context.measureText("+").getWidth();; g.drawString("+", plusPoint.x-w/2, plusPoint.y); drawPosts(g); } boolean mustShowVoltage() { return (flags & FLAG_SHOWVOLTAGE) != 0; } void stepFinished(){ count++;//how many counts are in a cycle double v = getVoltageDiff(); total += v*v; //sum of squares if (v<2.5) binaryLevel = 0; else binaryLevel = 1; //V going up, track maximum value with if (v>maxV && increasingV){ maxV = v; increasingV = true; decreasingV = false; } if (v<maxV && increasingV){//change of direction V now going down - at start of waveform lastMaxV=maxV; //capture last maximum //capture time between periodLength = System.currentTimeMillis() - periodStart; periodStart = System.currentTimeMillis(); period = periodLength; pulseWidth = System.currentTimeMillis() - pulseStart; dutyCycle = pulseWidth / periodLength; minV=v; //track minimum value with V increasingV=false; decreasingV=true; //rms data total = total/count; rmsV = Math.sqrt(total); if (Double.isNaN(rmsV)) rmsV=0; count=0; total=0; } if (v<minV && decreasingV){ //V going down, track minimum value with V minV=v; increasingV=false; decreasingV=true; } if (v>minV && decreasingV){ //change of direction V now going up lastMinV=minV; //capture last minimum pulseStart = System.currentTimeMillis(); maxV = v; increasingV = true; decreasingV = false; //rms data total = total/count; rmsV = Math.sqrt(total); if (Double.isNaN(rmsV)) rmsV=0; count=0; total=0; } //need to zero the rms value if it stays at 0 for a while if (v==0){ zerocount++; if (zerocount > 5){ total=0; rmsV=0; maxV=0; minV=0; } }else{ zerocount=0; } } void getInfo(String arr[]) { arr[0] = "voltmeter"; arr[1] = "Vd = " + getVoltageText(getVoltageDiff()); } boolean getConnection(int n1, int n2) { return false; } public EditInfo getEditInfo(int n) { if (n == 0) { EditInfo ei = new EditInfo("", 0, -1, -1); ei.checkbox = new Checkbox("Show Value", mustShowVoltage()); return ei; } if (n==1){ EditInfo ei = new EditInfo("Value", selectedValue, -1, -1); ei.choice = new Choice(); ei.choice.add("Voltage"); ei.choice.add("RMS Voltage"); ei.choice.add("Max Voltage"); ei.choice.add("Min Voltage"); ei.choice.add("P2P Voltage"); ei.choice.add("Binary Value"); //ei.choice.add("Frequency"); //ei.choice.add("Period"); //ei.choice.add("Pulse Width"); //ei.choice.add("Duty Cycle"); ei.choice.select(meter); return ei; } return null; } public void setEditValue(int n, EditInfo ei) { if (n == 0) { if (ei.checkbox.getState()) flags = FLAG_SHOWVOLTAGE; else flags &= ~FLAG_SHOWVOLTAGE; } if (n==1){ meter = ei.choice.getSelectedIndex(); } } }