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 D9 → MOSFET 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
- Flash the sketch.
- Open Tools → Serial Plotter (baud 115200).
- Slowly turn the pot on A0 to change duty.
- 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).