updates
This commit is contained in:
Binary file not shown.
@@ -208,7 +208,7 @@ def run_analysis(last: int = 10) -> None:
|
|||||||
client = anthropic.Anthropic()
|
client = anthropic.Anthropic()
|
||||||
message = client.messages.create(
|
message = client.messages.create(
|
||||||
model = CLAUDE_MODEL,
|
model = CLAUDE_MODEL,
|
||||||
max_tokens = 1024,
|
max_tokens = 3072,
|
||||||
system = SYSTEM_PROMPT,
|
system = SYSTEM_PROMPT,
|
||||||
messages = [{"role": "user", "content": prompt}],
|
messages = [{"role": "user", "content": prompt}],
|
||||||
)
|
)
|
||||||
@@ -282,7 +282,7 @@ def main() -> None:
|
|||||||
client = anthropic.Anthropic()
|
client = anthropic.Anthropic()
|
||||||
message = client.messages.create(
|
message = client.messages.create(
|
||||||
model = CLAUDE_MODEL,
|
model = CLAUDE_MODEL,
|
||||||
max_tokens = 1024,
|
max_tokens = 3072,
|
||||||
system = SYSTEM_PROMPT,
|
system = SYSTEM_PROMPT,
|
||||||
messages = [{"role": "user", "content": prompt}],
|
messages = [{"role": "user", "content": prompt}],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -127,7 +127,11 @@ def _read_csv(path: Path) -> tuple[np.ndarray, np.ndarray]:
|
|||||||
volts.append(float(row[1]))
|
volts.append(float(row[1]))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass # skip any header row
|
pass # skip any header row
|
||||||
return np.array(times, dtype=np.float64), np.array(volts, dtype=np.float64)
|
t = np.array(times, dtype=np.float64)
|
||||||
|
v = np.array(volts, dtype=np.float64)
|
||||||
|
if len(t) < 2:
|
||||||
|
raise ValueError(f"Insufficient samples in {path.name} ({len(t)} rows parsed)")
|
||||||
|
return t, v
|
||||||
|
|
||||||
|
|
||||||
def _zero_crossings(times: np.ndarray, volts: np.ndarray) -> np.ndarray:
|
def _zero_crossings(times: np.ndarray, volts: np.ndarray) -> np.ndarray:
|
||||||
|
|||||||
21
mipi_test.py
21
mipi_test.py
@@ -322,19 +322,18 @@ def dual_capture(iteration):
|
|||||||
else:
|
else:
|
||||||
print(" SKIPPING PASS 3 SAVE.")
|
print(" SKIPPING PASS 3 SAVE.")
|
||||||
|
|
||||||
# Collect Rigol 1.8 V waveform (Agilent save takes ~5 s, Rigol should be done)
|
# Collect Rigol 1.8 V waveform.
|
||||||
|
# The Agilent LP acquire + save takes ~35 s, so the Rigol will have
|
||||||
|
# long since auto-captured by now. read_waveform_csv() sends :STOP
|
||||||
|
# before reading to guarantee the acquisition is finalised.
|
||||||
if rigol_scope.is_connected():
|
if rigol_scope.is_connected():
|
||||||
print(" PASS 3: WAITING FOR RIGOL 1.8 V CAPTURE...")
|
DATA_DIR.mkdir(exist_ok=True)
|
||||||
if rigol_scope.wait_captured(timeout_s=10.0):
|
v18_path = DATA_DIR / f"{ts}_pwr_{iteration:04d}_1v8.csv"
|
||||||
DATA_DIR.mkdir(exist_ok=True)
|
n = rigol_scope.read_waveform_csv(v18_path)
|
||||||
v18_path = DATA_DIR / f"{ts}_pwr_{iteration:04d}_1v8.csv"
|
if n:
|
||||||
n = rigol_scope.read_waveform_csv(v18_path)
|
print(f" SAVED: {v18_path.name} ({n} samples)")
|
||||||
if n:
|
|
||||||
print(f" SAVED: {v18_path.name} ({n} samples)")
|
|
||||||
else:
|
|
||||||
print(" RIGOL: Waveform read returned 0 samples.")
|
|
||||||
else:
|
else:
|
||||||
print(" RIGOL: Timed out waiting for capture.")
|
print(" RIGOL: Waveform read failed — check connection and probe.")
|
||||||
|
|
||||||
_restore_hs_config()
|
_restore_hs_config()
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ def configure():
|
|||||||
rigol.write(":CHANnel1:DISPlay 1")
|
rigol.write(":CHANnel1:DISPlay 1")
|
||||||
rigol.write(":CHANnel2:DISPlay 0")
|
rigol.write(":CHANnel2:DISPlay 0")
|
||||||
rigol.write(":CHANnel1:COUPling DC")
|
rigol.write(":CHANnel1:COUPling DC")
|
||||||
rigol.write(":CHANnel1:PROBe 1")
|
rigol.write(":CHANnel1:PROBe 10")
|
||||||
rigol.write(f":CHANnel1:SCALe {V18_SCALE:.3f}")
|
rigol.write(f":CHANnel1:SCALe {V18_SCALE:.3f}")
|
||||||
rigol.write(f":CHANnel1:OFFSet {V18_OFFSET:.3f}")
|
rigol.write(f":CHANnel1:OFFSet {V18_OFFSET:.3f}")
|
||||||
rigol.write(f":TIMebase:MAIN:SCALe {V18_TIMEBASE:.2E}")
|
rigol.write(f":TIMebase:MAIN:SCALe {V18_TIMEBASE:.2E}")
|
||||||
@@ -82,9 +82,11 @@ def configure():
|
|||||||
rigol.write(f":TRIGger:EDGe:LEVel {V18_TRIG_LEVEL:.3f}")
|
rigol.write(f":TRIGger:EDGe:LEVel {V18_TRIG_LEVEL:.3f}")
|
||||||
rigol.write(":TRIGger:SWEep AUTO") # auto: captures even without a droop trigger
|
rigol.write(":TRIGger:SWEep AUTO") # auto: captures even without a droop trigger
|
||||||
time.sleep(0.3)
|
time.sleep(0.3)
|
||||||
|
rigol.write(":RUN") # start acquiring immediately after configure
|
||||||
|
time.sleep(0.2)
|
||||||
|
|
||||||
print(f"[RIGOL] Configured: 1.8 V rail, {int(V18_TIMEBASE*1e6)} µs/div, "
|
print(f"[RIGOL] Configured: 1.8 V rail, {int(V18_TIMEBASE*1e6)} µs/div, "
|
||||||
f"trigger <{V18_TRIG_LEVEL} V falling (AUTO sweep)")
|
f"trigger <{V18_TRIG_LEVEL} V falling (AUTO sweep, running)")
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -92,8 +94,9 @@ def configure():
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def arm():
|
def arm():
|
||||||
"""Arm for a single acquisition. Non-blocking — returns immediately."""
|
"""Ensure scope is running so it is actively acquiring when the LP event occurs.
|
||||||
rigol.write(":SINGle")
|
The waveform is frozen with :STOP inside read_waveform_csv() at collection time."""
|
||||||
|
rigol.write(":RUN")
|
||||||
|
|
||||||
|
|
||||||
def wait_captured(timeout_s: float = TRIG_TIMEOUT_S) -> bool:
|
def wait_captured(timeout_s: float = TRIG_TIMEOUT_S) -> bool:
|
||||||
@@ -117,32 +120,52 @@ def wait_captured(timeout_s: float = TRIG_TIMEOUT_S) -> bool:
|
|||||||
def read_waveform_csv(path: Path) -> int:
|
def read_waveform_csv(path: Path) -> int:
|
||||||
"""
|
"""
|
||||||
Read Ch1 waveform from Rigol over SCPI and write to CSV.
|
Read Ch1 waveform from Rigol over SCPI and write to CSV.
|
||||||
The Rigol returns ASCII voltage values; we reconstruct the time axis
|
Sends :STOP first to ensure acquisition is complete before reading —
|
||||||
from the waveform preamble.
|
this is reliable regardless of trigger/status state.
|
||||||
|
|
||||||
Returns the number of samples written, or 0 on error.
|
Returns the number of samples written, or 0 on error.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
rigol.write(":WAVeform:SOURce CHANnel1")
|
rigol.write(":STOP")
|
||||||
rigol.write(":WAVeform:FORMat ASCII")
|
time.sleep(0.3)
|
||||||
rigol.write(":WAVeform:MODE NORMal")
|
|
||||||
|
|
||||||
|
rigol.write(":WAVeform:SOURce CHANnel1")
|
||||||
|
rigol.write(":WAVeform:FORMat ASC") # Rigol DS1000Z uses ASC not ASCII
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[RIGOL] Waveform setup error: {e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
try:
|
||||||
preamble = rigol.ask(":WAVeform:PREamble?").strip().split(",")
|
preamble = rigol.ask(":WAVeform:PREamble?").strip().split(",")
|
||||||
# [0]=fmt [1]=type [2]=points [3]=count [4]=x_incr [5]=x_orig [6]=x_ref
|
# [0]=fmt [1]=type [2]=points [3]=count [4]=x_incr [5]=x_orig [6]=x_ref
|
||||||
# [7]=y_incr [8]=y_orig [9]=y_ref
|
# [7]=y_incr [8]=y_orig [9]=y_ref
|
||||||
x_incr = float(preamble[4])
|
x_incr = float(preamble[4])
|
||||||
x_orig = float(preamble[5])
|
x_orig = float(preamble[5])
|
||||||
x_ref = float(preamble[6])
|
x_ref = float(preamble[6])
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[RIGOL] Preamble error: {e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
try:
|
||||||
raw = rigol.ask(":WAVeform:DATA?").strip()
|
raw = rigol.ask(":WAVeform:DATA?").strip()
|
||||||
|
|
||||||
# Strip any TMC binary header (#<digit><length>) if present
|
# Strip TMC binary header (#<n_digits><byte_count>...) if present
|
||||||
if raw.startswith("#"):
|
if raw.startswith("#"):
|
||||||
n_digits = int(raw[1])
|
n_digits = int(raw[1])
|
||||||
raw = raw[2 + n_digits:]
|
raw = raw[2 + n_digits:]
|
||||||
|
|
||||||
vals = [float(v) for v in raw.split(",") if v.strip()]
|
vals = [float(v) for v in raw.split(",") if v.strip()]
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[RIGOL] Data read error: {e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if not vals:
|
||||||
|
print("[RIGOL] No samples parsed — check scope channel and format settings")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
try:
|
||||||
path.parent.mkdir(exist_ok=True)
|
path.parent.mkdir(exist_ok=True)
|
||||||
with open(path, "w", newline="") as f:
|
with open(path, "w", newline="") as f:
|
||||||
writer = csv.writer(f)
|
writer = csv.writer(f)
|
||||||
@@ -150,9 +173,7 @@ def read_waveform_csv(path: Path) -> int:
|
|||||||
for i, v in enumerate(vals):
|
for i, v in enumerate(vals):
|
||||||
t = x_orig + (i - x_ref) * x_incr
|
t = x_orig + (i - x_ref) * x_incr
|
||||||
writer.writerow([f"{t:.9f}", f"{v:.6f}"])
|
writer.writerow([f"{t:.9f}", f"{v:.6f}"])
|
||||||
|
|
||||||
return len(vals)
|
return len(vals)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[RIGOL] Waveform read error: {e}")
|
print(f"[RIGOL] CSV write error: {e}")
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
Reference in New Issue
Block a user