In [1]:
(version)
Out[1]:
"8.3"
In [2]:
(require racket
         racket/list
         racket/format
         (prefix-in pict: pict))
In [3]:
(require bhdl)
#<procedure:parameter-procedure>
In [5]:
;; FIXME use global?
(define global
  (make-circuit
   (pin GND 3V3 5V VCC USB5V)))

simple RC circuit

In [6]:
(define (RC-fixed)
         (make-circuit
              (pin In Out GND)
               (part [R1 (R '1k)]
                      [C1 (C '1p)])
          (wire (list (*- self.In R1.1)
                          (*- R1.2 C1.1 self.Out)
                          (*- C1.2 self.GND)))
          (layout (inset (vc-append R1 C1) 20))))
In [7]:
(show-layout (RC-fixed))
"DEBUG: /var/folders/jd/pqbc6_7j0y5gc2kjxjntw8c40000gn/T/PKGS-src-ROOT-BHDL-syst----iVc-fpio-main.rkt-63-15_16388428281638842828919"
"DEBUG: /var/folders/jd/pqbc6_7j0y5gc2kjxjntw8c40000gn/T/PKGS-src-ROOT-BHDL-syst----iVc-fpio-main.rkt-63-15_16388428281638842828934"
Out[7]:
In [8]:
(circuit-plot (RC-fixed))
DEBUG:  (Number of conflicts: 0)
generating pdf ..
link: /tmp/out.pdf
Out[8]:

A delayed push trigger

In [9]:
;; some component libraries
(define/IC (MOSFET)
           #:FP ((lcsc->fp "C727149") 1 2 3))
In [10]:
(define/IC (SW_Push)
           #:FP ((kicad->fp "Button_Switch_THT.pretty/"
                                 "SW_PUSH_6mm.kicad_mod")
                 2 1 2 1)
           #:LEFT 1
           #:RIGHT 2
           #:PREFIX "BT")
In [12]:
(define (delay-push-fixed)
  (make-circuit
      (pin VCC GND Ctrl)
      (part (RC1 (RC-fixed))
              [D1 (Diode '1N4148)]
              [R4 (R '1k)]
              [SW1 (SW_Push)]
              [Q1 (MOSFET '2N7002)]
              [R2 (R '10k)]
              [D2 (LED)])
      (wire (list (*- RC1.Out D1.anode Q1.1)
                      (*- RC1.GND Q1.2)
                      (*- Q1.3 self.Ctrl))
        (list (*- self.VCC SW1 D1.cathode RC1.In self.GND)
                   (*- self.VCC D2 self.Ctrl)))
   ;; TODO implement a default layout
;;    #:layout (pict:rectangle 200 200)
;;    #:layout (inset SW1 50)
   ;; UPDATE I'm using only the btn for the layout, so that layter module can direclty use this to layout the buttons
   (layout SW1)
   ))
In [13]:
(placer-url "http://localhost:8082")
In [15]:
;; FIXME this does not seem to be deterministic
;; TODO implement copy-on-assign semantic, like pict?
;; (parameterize ([current-directory "./out/onebutton/delay-push-fixed"]
;;                [padding-general 2])
;;     (circuit-export (delay-push-fixed)
;;                     #:auto-place #t
;;                     #:formats '(kicad pdf png)))

connect ESP-01 module

In [16]:
(define/IC (ESP01)
           #:FP ((lcsc->fp "C503581") 
                 GND GPIO2 GPIO0 URXD
                 UTXD CH_PD RST VCC))
requesting https://easyeda.com/api/products/C503581/svgs ..
requesting https://easyeda.com/api/components/23261b76862b485688b2cbb27543de76 ..
DEBUG:  (Saved to /Users/hebi/Library/Application Support/bhdl/bhdl-footprints/easyeda/23261b76862b485688b2cbb27543de76.json)
In [17]:
(define/IC (OneBattery)
           ;; FIXME using pinheader for battery holder?
           #:FP ((kicad->fp "kicad-footprints" 
                           "Connector_PinHeader_2.54mm.pretty"
                           "PinHeader_1x02_P2.54mm_Horizontal.kicad_mod")
                 pos neg))
In [18]:
(atom->fp-pict (OneBattery))
"DEBUG: /var/folders/jd/pqbc6_7j0y5gc2kjxjntw8c40000gn/T/PKGS-src-ROOT-BHDL-syst----iVc-fpio-main.rkt-63-15_16388429181638842918308"
Out[18]:
In [19]:
(define one-button
  (make-circuit 
    (part [delay_sw1 (delay-push-fixed)]
           [BT1 (OneBattery '3V)]
           [U1 (ESP01)])
   (wire (list
              ;; TODO use thr-hole footprint for resistors
              (*- BT1.pos (R '10k) U1.RST)
              (*- BT1.pos (R '10k) U1.CH_PD)
              (*- BT1.pos U1.VCC delay_sw1.VCC)
                   (*- BT1.neg U1.GND delay_sw1.GND)
                   (*- U1.RST delay_sw1.Ctrl)))
   (layout (inset (hc-append 200 delay_sw1 U1)
                   0 20 0 20))))
"DEBUG: /var/folders/jd/pqbc6_7j0y5gc2kjxjntw8c40000gn/T/PKGS-src-ROOT-BHDL-syst----iVc-fpio-main.rkt-63-15_16388429361638842936268"
In [20]:
(show-layout one-button)
Out[20]:
In [21]:
;; FIXME this does not seem to be deterministic
;; TODO implement copy-on-assign semantic, like pict?
(parameterize ([current-directory "./out/onebutton/one"]
               [padding-general 1])
    (circuit-export one-button
                    #:auto-place #t
                    #:formats '(kicad pdf png)))
DEBUG:  (sending for placement ..)
DEBUG:  (saving ..)
generating KiCAD PCB ..
"DEBUG: /var/folders/jd/pqbc6_7j0y5gc2kjxjntw8c40000gn/T/PKGS-src-ROOT-BHDL-syst----iVc-fpio-main.rkt-95-15_16388429431638842943669"
"DEBUG: /var/folders/jd/pqbc6_7j0y5gc2kjxjntw8c40000gn/T/PKGS-src-ROOT-BHDL-syst----iVc-fpio-main.rkt-95-15_16388429431638842943673"
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/one/out.kicad_pcb
DEBUG:  (Number of conflicts: 0)
generating pdf ..
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/one/out.pdf
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/one/out.png
Out[21]:

Layout Examples in paper

In [23]:
(define layout-example 
  (make-circuit 
      (part [btn1 (SW_Push)]
             [btn2 (SW_Push)]
             [btn3 (SW_Push)]
             [mcu (ESP01)])
     (wire (list (*- btn1 mcu.GPIO0)
                     (*- btn2 mcu.GPIO2)
                     (*- btn3 mcu.RST)))
     (layout (hc-append (vc-append btn1 btn2 btn3) 
;;                          (rotate mcu (/ pi 4))
                         mcu))))
In [24]:
(show-layout layout-example)
Out[24]:
In [25]:
(parameterize ([current-directory "./out/onebutton/layout-example"]
               [padding-general 1])
    (circuit-export layout-example
                    #:auto-place #t
                    #:formats '(kicad pdf png)))
DEBUG:  (sending for placement ..)
DEBUG:  (saving ..)
generating KiCAD PCB ..
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/layout-example/out.kicad_pcb
DEBUG:  (Number of conflicts: 0)
generating pdf ..
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/layout-example/out.pdf
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/layout-example/out.png
Out[25]:

BHDL circuit with 3 push buttons

In [27]:
(define three-button
  (make-circuit 
    (part [buttons (for/list ([i (in-range 3)])
                                 (delay-push-fixed))]
           [BT1 (OneBattery '3V)]
           [U1 (ESP01)])
   (wire (list 
              (*- BT1.pos (R '10k) U1.RST)
              (*- BT1.pos (R '10k) U1.CH_PD)
              (*- BT1.pos U1.VCC)
              (for/list ([btn buttons])
                        (*- BT1.pos btn.VCC))
              ;; neg to GNDs
               (for/list ([btn buttons])
                         (*- BT1.neg U1.GND btn.GND))
              ;; connect GPIOs
              (for/list ([btn buttons]
                         [ctrl (list (pin-ref U1 'RST)
                                     (pin-ref U1 'GPIO0)
                                     (pin-ref U1 'GPIO2))])
                        (*- ctrl btn.Ctrl))
               ))
   (layout (inset (hc-append 300 (apply vc-append buttons) U1)
                   0))))
In [28]:
(pict:frame (show-layout three-button))
Out[28]:
In [29]:
(parameterize ([current-directory "./out/onebutton/three"]
               [padding-general 1])
    (circuit-export three-button
                    #:auto-place #t
                    #:formats '(kicad pdf png)))
DEBUG:  (sending for placement ..)
DEBUG:  (saving ..)
generating KiCAD PCB ..
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
WARNING:  (smd must have either layer top or bottom, but got multi)
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/three/out.kicad_pcb
DEBUG:  (Number of conflicts: 2)
generating pdf ..
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/three/out.pdf
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/three/out.png
Out[29]:

Calculating RC values

In [30]:
(define (get-C tau R)
  (/ tau R))
In [32]:
(define (RC-flexible tau)
  (make-circuit
     (pin In Out GND)
    (part [R1 (R 1000)]
           [C1 (C (get-C tau 1000))])
    (wire (list (*- self.In R1.1)
                   (*- R1.2 C1.1 self.Out)
                   (*- C1.2 self.Out)))
   (layout (inset (vc-append R1 C1) 20))))
In [33]:
(RC-flexible 1)
Out[33]:
#<Composite-44388>
In [34]:
;; FIXME this does not seem to be deterministic
;; TODO implement copy-on-assign semantic, like pict?
(parameterize ([current-directory "./out/onebutton/flex"]
               [padding-general 2])
    (circuit-export (RC-flexible 1)
                    #:auto-place #f
                    #:formats '(kicad pdf png bom)))
generating KiCAD PCB ..
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/flex/out.kicad_pcb
Generating BOM ..
DEBUG:  (Number of conflicts: 0)
generating pdf ..
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/flex/out.pdf
link: /Users/hebi/git/bhdl.org/notebooks/out/onebutton/flex/out.png
Out[34]:
In [35]:
;; read the CSV file
(call-with-input-file "out/onebutton/flex/BOM.csv"
                      (lambda (in)
                        (displayln (port->string in))))
Annotation, Name, Footprint, Values
R1,Resistor/R,0603,(1000)
C2,Capacitor/C,#f,(1/1000)
In [ ]: