Upgrade with SCPI Communication: PWM & One-Shot Signal Characterisation

This exercise combines Arduino PWM with Red Pitaya SCPI to capture a single waveform of your PWM output and stream it to the Arduino Serial Plotter—perfect for quick, repeatable measurements while you sweep duty cycle with a potentiometer.
What you’ll do
  • Set PWM on D9; duty controlled by a potentiometer on A0
  • Trigger a one-shot acquisition on Red Pitaya CH1 (HV gain) over Wi-Fi (TCP SCPI)
  • Print one value per line for the Arduino Serial Plotter

1) Prerequisites

  • Red Pitaya with the SCPI server running (via web UI → Development → SCPI → RUN or via SSH: systemctl start redpitaya_scpi)
  • Arduino IDE 2.x
  • This library in your Arduino libraries folder (contains wifiSCPI.h)
  • Wi-Fi: Red Pitaya and your Arduino board must be on the same network

2) Hardware Setup (Typical)

  • PWM path (Arduino → load):
    • Arduino D9MOSFET gate/driver → load → supply (per your power stage)
    • Important: Size your MOSFET/driver and supply safely for the load.
  • Duty control:
    • Potentiometer wiper → A0; ends to 3.3/5 V and GND (match your Arduino)
  • Measurement to Red Pitaya:
    • Probe the PWM node of interest into Red Pitaya CH1
    • CH1 gain = HV in the sketch (for higher swing); ensure you’re within input limits
  • Common ground:
    • GND between Arduino, Red Pitaya, and the power stage must be common
If your power stage is noisy or high-voltage, measure at a properly attenuated/isolated point and keep leads short.

3) Wi-Fi One-Shot PWM Characterization

Create arduino_secrets.h in your sketch folder with your Wi-Fi and RP endpoint:
#define SECRET_SSID "YourSSID" #define SECRET_PASS "YourPassword" #define SECRET_RP_IP "192.168.1.42" // or "rp-xxxxxx.local" #define SECRET_RP_PORT 5025 // try 5025; use 5000 on older images
Sketch (paste as-is):
/* One-shot PWM characterization → Serial Plotter (HV gain set) - Potentiometer on A0 sets PWM duty on D9 (external MOSFET/load) - Red Pitaya captures CH1 ONCE and returns it over Wi-Fi - Prints ONE VALUE PER LINE for Arduino Serial Plotter - Uses rp.scpi() (void) and rp.scpiBlock() (String) only */ #include "wifiSCPI.h" #include "arduino_secrets.h" // SECRET_SSID, SECRET_PASS, SECRET_RP_IP, SECRET_RP_PORT WifiSCPI rp; const int pwmPin = 9; const int potPin = A0; // === Tunables === const int DECIMATION = 256; // RP decimation const int READY_WAIT_MS = 2; // retry interval while waiting for data const int DATA_TIMEOUT_MS = 800; // safety timeout so we never hang const bool PRINT_HEADER = false; // optional label line for Serial Plotter bool acquired_once = false; bool connectToRP(uint8_t max_attempts = 5); bool oneShotAcquireAndPlot(); void streamWaveformToPlotter(String &samples); void setup() { Serial.begin(115200); pinMode(pwmPin, OUTPUT); delay(200); int adc = analogRead(potPin); // 0..1023 int duty = map(adc, 0, 1023, 0, 255); // 0..255 analogWrite(pwmPin, duty); if (!connectToRP()) { Serial.println("ERROR: Could not establish SCPI socket. (PWM will still run.)"); return; } if (PRINT_HEADER) Serial.println("ch1_volts:"); acquired_once = oneShotAcquireAndPlot(); if (!acquired_once) { Serial.println("ERROR: Acquisition failed (timeout or empty data)."); } else { Serial.println("# DONE: one-shot capture printed. (No further acquisitions will run.)"); } } void loop() { int adc = analogRead(potPin); int duty = map(adc, 0, 1023, 0, 255); analogWrite(pwmPin, duty); delay(5); } // --- Helpers --- bool connectToRP(uint8_t max_attempts) { for (uint8_t i = 0; i < max_attempts; i++) { rp.begin(SECRET_SSID, SECRET_PASS, SECRET_RP_IP, SECRET_RP_PORT); delay(300); return true; // We'll verify later by trying to read data } return false; } bool oneShotAcquireAndPlot() { // Full clean setup, then one capture rp.scpi("ACQ:RST"); rp.scpi(String("ACQ:DEC ") + DECIMATION); // >>> Set input gain to HV <<< rp.scpi("ACQ:SOUR1:GAIN HV"); // CH1 gain = HV rp.scpi("ACQ:SOUR2:GAIN HV"); // (optional) CH2 gain = HV rp.scpi("ACQ:DATA:FORMAT ASCII"); rp.scpi("ACQ:DATA:UNITS VOLTS"); rp.scpi("ACQ:TRIG:DLY 0"); // Start and trigger rp.scpi("ACQ:START"); rp.scpi("ACQ:TRIG NOW"); // Try to fetch data until non-empty or timeout unsigned long t0 = millis(); String samples; do { delay(READY_WAIT_MS); samples = rp.scpiBlock("ACQ:SOUR1:DATA?"); if (samples.length() > 0) break; } while ((millis() - t0) <= (unsigned long)DATA_TIMEOUT_MS); // Stop acquisition to leave RP idle (avoid future lockups) rp.scpi("ACQ:STOP"); if (samples.length() == 0) return false; streamWaveformToPlotter(samples); return true; } // Parse "{v1,v2,...}" → Serial Plotter friendly (one value per line) void streamWaveformToPlotter(String &samples) { samples.replace("{", ""); samples.replace("}", ""); int start = 0; while (true) { int commaIndex = samples.indexOf(',', start); String val = (commaIndex == -1) ? samples.substring(start) : samples.substring(start, commaIndex); val.trim(); if (val.length() > 0) { Serial.println(val); } if (commaIndex == -1) break; start = commaIndex + 1; } }

4) How to Run & Plot

  1. Flash the sketch.
  1. Open Tools → Serial Plotter (baud 115200).
  1. Slowly turn the pot on A0 to change duty.
  1. On boot, the sketch performs one capture and prints CH1 samples:
Need more captures? Convert oneShotAcquireAndPlot() into a function you call on a button or timer, or change the logic to re-arm after each plot.

5) Tuning Notes

  • DECIMATION
    • Effective sample rate scales with decimation (typical base is 125 MS/s):
      Use lower decimation for higher time resolution (short windows); increase decimation to view longer windows.
  • Gain (HV/LV)
    • Set to HV in the sketch. Use LV if your signal is small. Always stay within input limits.
  • Triggering
    • ACQ:TRIG NOW is simple for a one-shot. For edges, switch to e.g. ACQ:TRIG:LEV and ACQ:TRIG:EXT/ACQ:TRIG:EDGE as your firmware supports.
  • Units & Format
    • ACQ:DATA:UNITS VOLTS + ACQ:DATA:FORMAT ASCII → quick visualization. For speed, switch to binary reads once you’re done prototyping.

6) Safety & Signal Integrity

  • Use proper gate drivers, snubbers, and grounding for MOSFET loads.
  • Keep probe leads short. Reference grounds close to the switching node.
  • If measuring high voltage/current, ensure safe attenuation/isolation before CH1.

7) Troubleshooting

  • No data / timeout
    • Ensure SCPI server is running on RP.
    • Try port 5025, and if it fails, try 5000.
    • Increase DATA_TIMEOUT_MS if your system is slow to respond.
  • Flat or clipped waveform
    • Check HV/LV gain and expected amplitude.
    • Verify probe and ground connections; avoid saturating inputs.
  • Wi-Fi connect issues
    • Double-check SECRET_* values.
    • Make sure Arduino and RP are on the same subnet.
  • Plot looks “sparse”
    • Lower DECIMATION for higher sample density (shorter window).
    • If you need more points, switch to binary fetch and parse accordingly.
  • PWM looks noisy
    • Add proper gate resistors, snubbers, and decoupling.
    • Probe at the right node (e.g., after the driver vs raw switching node).