Ltspice

From Attie's Wiki
(Difference between revisions)
Jump to: navigation, search
m (Convert the CSV file to a RAW 8-bit file)
m (Convert the CSV file to an 8-bit wav file)
 
(12 intermediate revisions by one user not shown)
Line 1: Line 1:
==Using a captured waveform as LTspice input==
+
=Using a captured waveform as LTspice input=
 
This outlines the steps necessary to use a CSV file as input for LTspice.
 
This outlines the steps necessary to use a CSV file as input for LTspice.
  
Line 21: Line 21:
 
</source>
 
</source>
  
==Convert the CSV file to a RAW 8-bit file==
+
==Convert the CSV file to an 8-bit wav file==
 
Use the script below.
 
Use the script below.
 
There are a few configuration options:
 
There are a few configuration options:
{|
+
{|class="wikitable"
 
! Option Name !! Description
 
! Option Name !! Description
 
|-
 
|-
Line 42: Line 42:
 
CSV_COLUMN=2
 
CSV_COLUMN=2
  
SAMPLE_RATE=500000
+
SAMPLE_RATE=5000000
  
ROOT_FILENAME=$(echo ${CSV_FILE} | rev | cut -d . -f 2- | rev)
+
ROOT_FILENAME=${CSV_FILE%.*}
  
 
# end of configuration
 
# end of configuration
Line 59: Line 59:
 
   | tee .${CSV_FILE}.normal \
 
   | tee .${CSV_FILE}.normal \
 
   | sort -n \
 
   | sort -n \
| uniq \
+
  | uniq \
 
   > .${CSV_FILE}.sorted
 
   > .${CSV_FILE}.sorted
 
   
 
   
Line 95: Line 95:
 
# arg2: value stored in the word
 
# arg2: value stored in the word
 
function wnab() {
 
function wnab() {
WORD_SIZE=$1; shift
+
  WORD_SIZE=$1; shift
WORD_VALUE=$1; shift
+
  WORD_VALUE=$1; shift
printf "%0$((WORD_SIZE * 2))x" ${WORD_VALUE} \
+
  printf "%0$((WORD_SIZE * 2))x" ${WORD_VALUE} \
| fold -w2 \
+
    | fold -w2 \
| sed '1!G;h;$!d' \
+
    | sed '1!G;h;$!d' \
  | awk '{printf "%c", strtonum($0)}'
+
    | awk '{printf "%c", strtonum("0x" $0)}'
 
}
 
}
 
truncate -s0 ${WAV}
 
  
 
# ChunkID
 
# ChunkID
echo "RIFF" >> ${WAV}
+
echo -n "RIFF" > ${WAV}
 
# ChunkSize
 
# ChunkSize
 
wnab 4 ${CHUNK_SIZE} >> ${WAV}
 
wnab 4 ${CHUNK_SIZE} >> ${WAV}
 
# Format & Subchunk1ID
 
# Format & Subchunk1ID
echo "WAVEfmt " >> ${WAV}
+
echo -n "WAVEfmt " >> ${WAV}
 
# Subchunk1Size
 
# Subchunk1Size
 
wnab 4 16 >> ${WAV}
 
wnab 4 16 >> ${WAV}
Line 126: Line 124:
 
wnab 2 8 >> ${WAV}
 
wnab 2 8 >> ${WAV}
 
# Subchunk2ID
 
# Subchunk2ID
echo "data" >> ${WAV}
+
echo -n "data" >> ${WAV}
 
# Subchunk2Size
 
# Subchunk2Size
 
wnab 4 ${DATA_SIZE} >> ${WAV}
 
wnab 4 ${DATA_SIZE} >> ${WAV}
Line 135: Line 133:
 
Useful resources:
 
Useful resources:
 
* https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
 
* https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
 +
 +
==Feed into LTspice==
 +
You'll need a voltage source (like always), but instead of providing a DC voltage, you should enter the following:
 +
<source lang="text">
 +
wavefile="loaded.wav" chan=0
 +
</source>
 +
 +
Here is a sample sallen-key & comparator circuit that I'm testing out for my quadcopter:<br>
 +
[[File:ltspice_sallen_lowpass.png]]
 +
 +
When you now run the simulation, you'll get a nice output like this (probing Vin):<br>
 +
[[File:ltspice_simulation_from_wav.png]]
 +
 +
==Setting the initial voltage of a net==
 +
This is useful, for example when you have a passive low-pass filter, you can set the initial state of the capacitor, and that can reduce the amount that you have to simulate.
 +
# Name the net, for example "V1" (press <kbd>F4</kbd>)
 +
# Add a spice directive ".ic V(V1)=0.333" to set the voltage to 333mV (press <kbd>s</kbd>)

Latest revision as of 10:33, 2 September 2014

Contents

[edit] Using a captured waveform as LTspice input

This outlines the steps necessary to use a CSV file as input for LTspice.

[edit] Capture your waveform

I have captured the following waveform using my scope, and saved it as a CSV file.
Bldc waveform.png

A sample of the CSV file is shown below:

x-axis,3,D0-D7
second,Volt,
-1.0000000E-03,-48.2407212E-03,0
-999.8000E-06,-48.2407212E-03,0
-999.6000E-06,-48.2407212E-03,0
-999.4000E-06,-48.2407212E-03,0
- - - - - - - - >8 - - - - - - - -
+8.9990000E-03,-168.8437350E-03,0
+8.9992000E-03,-176.8839359E-03,0
+8.9994000E-03,-48.2407212E-03,0
+8.9996000E-03,-48.2407212E-03,0

[edit] Convert the CSV file to an 8-bit wav file

Use the script below. There are a few configuration options:

Option Name Description
CSV_FILE The source CSV file
CSV_COLUMN The column of the CSV file that you'd like to extract
SAMPLE_RATE The rate that the samples were stored at, in Hz
ROOT_FILENAME (optional) If you want to store the output somewhere else, then change this
#!/bin/bash -e
 
CSV_FILE=loaded.csv
CSV_COLUMN=2
 
SAMPLE_RATE=5000000
 
ROOT_FILENAME=${CSV_FILE%.*}
 
# end of configuration
 
cat ${CSV_FILE} \
  | tail -n+3 \
  | cut -d , -f ${CSV_COLUMN} \
  | sed -r \
    -e 's/^\+//' \
    -e 's/^(-?[0-9]+\.[0-9]+)[eE]([+-])([0-9]+)$/\1*(10^\2\3)/' \
    -e 's/\*\(10\^\+00\)$//' \
  | bc -l \
  | sed -re 's/^(-?)\./\10./' \
  | tee .${CSV_FILE}.normal \
  | sort -n \
  | uniq \
  > .${CSV_FILE}.sorted
 
cat .${CSV_FILE}.sorted | sed -n "1p;$(wc -l .${CSV_FILE}.sorted | cut -d ' ' -f 1)p" > .${CSV_FILE}.extremes
 
LO=$(cat .${CSV_FILE}.extremes | head -n 1)
if [ $(echo "${LO} < 0" | bc) == "1" ]; then
  OP=-
else
  OP=+
fi
HI=$(echo "($(cat .${CSV_FILE}.extremes | tail -n 1))${OP}(${LO})" | bc -l)
ML=$(echo "255/${HI}" | bc -l)
 
cat .${CSV_FILE}.normal \
  | sed -r \
    -e 's/^/((/' \
    -e 's/$/)/' \
    -e "s/$/${OP}(${LO})/" \
    -e "s/$/)*${ML}/" \
  | bc -l \
  | sed -r \
    -e 's/^([0-9]*).([0-9]?[0-9]?[0-9]?).*$/\1.\2/' \
  | tee .${CSV_FILE}.adjusted \
  | awk '{printf "%c", strtonum($0)}' \
  > ${ROOT_FILENAME}.raw
 
DATA_SIZE=$(stat -c%s ${ROOT_FILENAME}.raw)
CHUNK_SIZE=$((DATA_SIZE + 36))
 
WAV=${ROOT_FILENAME}.wav
 
# writeNumAsBin
# arg1: bytes used to represent the word
# arg2: value stored in the word
function wnab() {
  WORD_SIZE=$1; shift
  WORD_VALUE=$1; shift
  printf "%0$((WORD_SIZE * 2))x" ${WORD_VALUE} \
    | fold -w2 \
    | sed '1!G;h;$!d' \
    | awk '{printf "%c", strtonum("0x" $0)}'
}
 
# ChunkID
echo -n "RIFF" > ${WAV}
# ChunkSize
wnab 4 ${CHUNK_SIZE} >> ${WAV}
# Format & Subchunk1ID
echo -n "WAVEfmt " >> ${WAV}
# Subchunk1Size
wnab 4 16 >> ${WAV}
# AudioFormat
wnab 2 1 >> ${WAV}
# NumChannels
wnab 2 1 >> ${WAV}
# SampleRate
wnab 4 ${SAMPLE_RATE} >> ${WAV}
# ByteRate
wnab 4 ${SAMPLE_RATE} >> ${WAV}
# BlockAlign
wnab 2 1 >> ${WAV}
# BitsPerSample
wnab 2 8 >> ${WAV}
# Subchunk2ID
echo -n "data" >> ${WAV}
# Subchunk2Size
wnab 4 ${DATA_SIZE} >> ${WAV}
# data!
cat ${ROOT_FILENAME}.raw >> ${WAV}

Useful resources:

[edit] Feed into LTspice

You'll need a voltage source (like always), but instead of providing a DC voltage, you should enter the following:

wavefile="loaded.wav" chan=0

Here is a sample sallen-key & comparator circuit that I'm testing out for my quadcopter:
Ltspice sallen lowpass.png

When you now run the simulation, you'll get a nice output like this (probing Vin):
Ltspice simulation from wav.png

[edit] Setting the initial voltage of a net

This is useful, for example when you have a passive low-pass filter, you can set the initial state of the capacitor, and that can reduce the amount that you have to simulate.

  1. Name the net, for example "V1" (press F4)
  2. Add a spice directive ".ic V(V1)=0.333" to set the voltage to 333mV (press s)
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox