Skip to content

Instantly share code, notes, and snippets.

@safiire
Last active September 4, 2015 02:51
Show Gist options
  • Select an option

  • Save safiire/2a6f793f55aa7b2826a6 to your computer and use it in GitHub Desktop.

Select an option

Save safiire/2a6f793f55aa7b2826a6 to your computer and use it in GitHub Desktop.
RC Filter Circuit simulation in Scheme
;;;; RC Filter Simulation
;; Calculates the frequency response of an RC filter
;; and displays it with ASCII art
;; This is just a program I always write to learn a new programming language
;; I tried out Scheme's lazy lists for this
;;
;; Frequency Response
;; ----------------------------------------------------------------
;; |****************************** |
;; | ***** |
;; | *** |
;; | *** |
;; | ** |
;; | ** |
;; | *** |
;; | *** |
;; | ***** |
;; | ********|
;; | |
;; ----------------------------------------------------------------
;;
;; 2015 Saf Allen
(use numbers)
(use mathh)
(use matchable)
(use lazy-lists)
;; Some definitions
(define pi 3.141592653589793)
(define tau (* 2 pi))
(define vertical 10)
(define horizontal 64)
;; Create a resistor
(define (make-resistor r)
(cons 'resistor r))
;; Create a capacitor
(define (make-capacitor c)
(cons 'capacitor c))
;; Get resistance
(define (resistance component)
(match component
[('resistor . r) r]
[('capacitor . _) 0] ))
;; Get capacitance
(define (capacitance component)
(match component
[('resistor . _) 0]
[('capacitor . c) c]))
;; Get impedance
(define (impedance component frequency)
(match component
[('resistor . r) r]
[('capacitor . c) (make-rectangular 0 (- (expt (* tau frequency c) -1)))]))
;; Make an RC filter
(define (make-rc-filter r c)
(cons r c))
;; What is the filter cutoff?
(define (filter-cutoff filter)
(let ((resistor (car filter))
(capacitor (cdr filter)))
(expt (* tau (resistance resistor) (capacitance capacitor)) -1)))
;; What is the total impedance of the circuit?
(define (total-impedance filter frequency)
(let ((resistor (car filter))
(capacitor (cdr filter)))
(+ (impedance resistor frequency) (impedance capacitor frequency))))
;; What is the total current of the circuit?
(define (total-current filter voltage frequency)
(/ voltage (total-impedance filter frequency)))
;; What is the voltage across the resistor?
(define (voltage-across-resistor filter voltage frequency)
(let ((resistor (car filter)))
(* (total-current filter voltage frequency) (impedance resistor frequency))))
;; What is the voltage across the capacitor?
(define (voltage-across-capacitor filter voltage frequency)
(let ((capacitor (cdr filter)))
(* (total-current filter voltage frequency) (impedance capacitor frequency))))
;; Convert MIDI note to frequency
(define (midi->frequency midi)
(* 440 (expt 2 (/ (- midi 69) 12))))
;; Do a frequency sweep over every second MIDI note
(define (frequency-sweep filter)
(Map (lambda (midi)
(let (
(frequency (midi->frequency midi))
(voltage 1))
(magnitude (voltage-across-capacitor filter voltage frequency)))) (Filter even? (Cardinals))))
;; Make a list containing x, n times
(define (repeat x n)
(if (zero? n)
'()
(cons x (repeat x (- n 1)))))
;; Maps floating point voltages from 0-1 into integers from 0-{vertical height of graph}
(define (voltage->integers sweep)
(map (lambda (voltage)
(round (* voltage vertical))) sweep))
;; Display an ascii filter sweep
(define (display-sweep sweep)
(let (
(line (list->string (repeat #\- horizontal)))
(vert '(10 9 8 7 6 5 4 3 2 1 0))
(responses (voltage->integers sweep)))
(print "Frequency Response")
(display " ")
(print line)
(for-each (lambda (vert)
(display "|")
(for-each (lambda (response)
(if (= vert response)
(display "*")
(display " "))) responses)
(print "|")) vert)
(print line)))
;; Main
(define (main args)
(let* (
(resistor (make-resistor 220))
(capacitor (make-capacitor 0.000001))
(filter (make-rc-filter resistor capacitor))
(infinite-sweep (frequency-sweep filter))
(midi-sweep (List->list (Take horizontal infinite-sweep))))
(display-sweep midi-sweep)
(print "Filter cutoff is at:")
(print (filter-cutoff filter))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment