About
Chirps from ten species of crickets were analyzed in terms of rhythm and dominant frequency to determine characteristics of constituent wavelets from each species' chirp. This data was translated into assembly language instructions to make an algorithm that synthesizes chirps. Each cricket contains a microcontroller running at 4 MHz, programmed with a virtual 2-bit square wave oscillator that interprets data from each chirp. As the crickets chirp, calls of different species cycle with varying length, making a multi-species chorus as the calls overlap. The negligible differences between the microcontrollers' on-board clocks were exploited to cause relative phasing amongst the chirps.

To keep body size small the printed circuit board was made as narrow as possible with few components. The crickets are made of masonite, monokote, paint, and electronic components.

Crickets has been installed at the Weisman Art Gallery in Minneapolis, REDCAT in Los Angeles, and at California Institute of the Arts.

Photos
Spectrograms
Code
;=========================================;
;   Crickets - 2005 Cooper Baker          ;
;=========================================;

; INIT ============================================================
        device  sx28l,osc4mhz
        device  turbo,stackx,optionx
        IRC_CAL irc_slow    ;irc_4mhz
        reset   main
        freq    4000000    
       
; DATA =======================================================

        ;================================
        org $008            ; memory page
        ;================================

oscil_count ds  1
oscil_loops ds  1
cycle_count ds  1
cycle_loops ds  1
seconds     ds  2
wait        ds  3
rand        ds  1
address     ds  1
wavelets    ds  1
rubs        ds  1
chirps      ds  1

watch rand,8,udec
watch chirps,8,udec
watch seconds,8,udec

; constants --------------------------------------------------
leds        equ ra
pins        equ rb
oscpin      equ rb.0
loud        equ %11111110
medi        equ %11111100
soft        equ %11110000
rest        equ %11111111

        ;================================
        org $000            ; memory page
        ;================================
       
; SYNTHESIS ===================================================

counter ;----------------------------------------------------
        mov     oscil_count,oscil_loops ;     + 2
:loop   nop                             ; * 1
        nop                             ; * 1
        nop                             ; * 1
        nop                             ; * 1
        djnz    oscil_count,:loop       ; * 4 + 2 =  
        retp                            ; * 8 + 4 total

oscil ;-----------------------------------------------------------
        clrb    oscpin
        call    @counter
        setb    oscpin
        call    @counter
        retp

cycle ;-----------------------------------------------------------
        mov     cycle_count,cycle_loops
:loop   call    @oscil
        djnz    cycle_count,:loop
        retp


; TIMING =======================================================

waiter ;----------------------------------------------------------
:loop   mov     wait+2,#16      ;     + 2 | 4 = 34
:loop_c mov     wait+1,#249     ; * 2     | 249 = 1496  
:loop_b mov     wait,#249       ; * 2     | 249 = 998          
:loop_a djnz    wait,:loop_a    ; * 4 + 2 | wait_a * 4 + 2 = a = 998
        djnz    wait+1,:loop_b  ; * 4 + 2 | wait_b * 6 + 2 + (a * wait_b) = b = 249998
        djnz    wait+2,:loop_c  ; * 4 + 2 | wait_c * 8 + 2 + (b * wait_c) = c = 1000026
        djnz    seconds,:loop   ; countdown (unrelated to clocking)
        retp                    ;     + 3
                                ; c + 5 = | 4,000,098 total clocks (~1 second)

random_chirps ;----------------------------------------------------------
        mov     W,<<rand
        mov     W,<<rand
        snb     rand.4
        xor     W,#1
        snb     rand.5
        xor     W,#1
        snb     rand.3
        xor     W,#1
        mov     rand,W
        mov     chirps,W
        clc
        rr      chirps          ; rand scaling by shifting
        clc
        rr      chirps
        clc
        rr      chirps
        clc
        rr      chirps  
        add     chirps,#1
        ret

random_waits ;----------------------------------------------------------
        mov     W,<<rand
        mov     W,<<rand
        snb     rand.4
        xor     W,#1
        snb     rand.5
        xor     W,#1
        snb     rand.3
        xor     W,#1
        mov     rand,W
        mov     seconds,W
        clc
        rr      seconds         ; rand scaling by shifting
        clc
        rr      seconds
        clc
        rr      seconds
        clc
        rr      seconds
        add     seconds,#1
        ret

; MAIN ============================================================
main    mov     !leds,#0
        mov     rand,#$a0
loop
        call    random_chirps
        call    @badlands
        call    random_waits
        call    waiter
       
        call    random_chirps
        call    @banded_scaly
        call    random_waits
        call    waiter

        call    random_chirps
        call    @black_faced_bush
        call    random_waits
        call    waiter

        call    random_chirps
        call    @carolina_ground
        call    random_waits
        call    waiter

        call    random_chirps
        call    @common_short_tailed
        call    random_waits
        call    waiter

        call    random_chirps
        call    @confused_ground
        call    random_waits
        call    waiter
   
        call    random_chirps
        call    @damp_loving_field
        call    random_waits
        call    waiter

        call    random_chirps
        call    @fall_field
        call    random_waits
        call    waiter

        jmp      loop

; CHIRP SUBROUTINES ==============================================
       
        ;================================
        org $200            ; memory page
        ;================================  

; JUMPS ** ** **
confused_ground
        jmp     confused_ground_jump
; ** ** ** ** **


badlands ;- 400 ms ---------------------------------------------
        mov     oscil_loops,#56     ; 4.4 kHz
:chirp                      
        mov     wavelets,#5         ; 5 wavelets
:wavelet
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#4      ; 1 ms
        call    @cycle              ;

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#4      ; 1 ms
        call    @cycle              ;

        mov     !pins,#loud         ; loud
        mov     cycle_loops,#22     ; 5 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off          

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#26     ; 6 ms
        call    @cycle              ;

        mov     !pins,#soft         ; soft
        mov     cycle_loops,#22     ; 5 ms
        call    @cycle              ;

        djnz    wavelets,:wavelet   ; wavelet loop

        mov     wavelets,#10        ; 310 ms
        mov     !pins,#rest         ; rest
        mov     cycle_loops,#136    ; 31 ms
:pause  call    @cycle              ;
        djnz    wavelets,:pause     ; pause loop
        djnz    chirps,:chirp       ; chirp loop
        retp

banded_scaly ;- 100 ms + 2 sec pause --------------------------------
        mov     oscil_loops,#37     ; 6.6 kHz
:chirp                      
        mov     wavelets,#11        ; 11 wavelets
:wavelet
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#20     ; 3 ms
        call    @cycle              ;

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#13     ; 2 ms
        call    @cycle              ;

        mov     !pins,#loud         ; loud
        mov     cycle_loops,#99     ; 15 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off          

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#7      ; 1 ms
        call    @cycle              ;

        mov     !pins,#soft         ; soft
        mov     cycle_loops,#26     ; 4 ms
        call    @cycle              ;

        mov     !pins,#rest         ; rest
        mov     cycle_loops,#165    ; 25 ms
        call    @cycle              ;
        mov     cycle_loops,#165    ; 25 ms
        call    @cycle              ;
        mov     cycle_loops,#165    ; 25 ms
        call    @cycle              ;
       
        djnz    wavelets,:wavelet ; wavelet loop

        mov     wavelets,#193       ; 1930 ms
        mov     !pins,#rest         ; rest
        mov     cycle_loops,#66     ; 10 ms
:pause  call    @cycle              ;
        djnz    wavelets,:pause     ; pause loop
        djnz    chirps,:chirp       ; chirp loop
        retp

black_faced_bush ;- 100 ms + 1 sec pause --------------------------------
        mov     oscil_loops,#52     ; 4.8 kHz
:chirp                      
        mov     wavelets,#11        ; 11 wavelets
:wavelet
        mov     rubs,#2
:rub
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#14     ; 3 ms
        call    @cycle              ;

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#14     ; 3 ms
        call    @cycle              ;

        mov     !pins,#loud         ; loud
        mov     cycle_loops,#34     ; 7 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off          

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#29     ; 6 ms
        call    @cycle              ;

        mov     !pins,#soft         ; soft
        mov     cycle_loops,#29     ; 6 ms
        call    @cycle              ;

        djnz    rubs,:rub           ; rub loop

        mov     !pins,#rest         ; rest
        mov     cycle_loops,#239    ; 50 ms
        call    @cycle              ;
       
        djnz    wavelets,:wavelet   ; wavelet loop

        mov     wavelets,#19        ; 950 ms
        mov     !pins,#rest         ; rest
        mov     cycle_loops,#239    ; 50 ms
:pause  call    @cycle              ;
       
        djnz    wavelets,:pause     ; pause loop
        djnz    chirps,:chirp       ; chirp loop
        retp

carolina_ground ;- continuous (396 ms loop) ---------------------------------------------
        mov     oscil_loops,#40     ; 6.1 kHz
:chirp                      
        mov     wavelets,#6         ; 6 wavelets
:wavelet
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#43     ; 7 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off  

        mov     !pins,#rest         ; rest
        mov     cycle_loops,#24     ; 4 ms
        call    @cycle              ;

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#43     ; 7 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off  

        mov     !pins,#rest         ; rest
        mov     cycle_loops,#24     ; 4 ms
        call    @cycle              ;
       
        mov     rubs,#3    
:rub
        mov     !pins,#loud         ; loud
        mov     cycle_loops,#43     ; 7 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off  

        mov     !pins,#rest         ; rest
        mov     cycle_loops,#24     ; 4 ms
        call    @cycle              ;

        djnz    rubs,:rub           ; rub loop
        djnz    wavelets,:wavelet   ; wavelet loop

        mov     !pins,#rest         ; rest
        djnz    chirps,:chirp       ; chirp loop
        retp

common_short_tailed ;- continuous (494 ms loop) ---------------------------------------------
        mov     oscil_loops,#44     ; 5.6 kHz
:chirp                      
        mov     wavelets,#38        ; 38 wavelets
:wavelet
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#6      ; 1 ms
        call    @cycle              ;  

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#6      ; 1 ms
        call    @cycle              ;
       
        mov     !pins,#loud         ; loud
        mov     cycle_loops,#17     ; 3 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off  

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#6      ; 1 ms
        call    @cycle              ;
       
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#11     ; 2 ms
        call    @cycle  
       
        mov     !pins,#rest         ; rest
        mov     cycle_loops,#24     ; 4 ms
        call    @cycle              ;
   
        djnz    wavelets,:wavelet   ; wavelet loop

        mov     !pins,#rest         ; rest
        djnz    chirps,:chirp       ; chirp loop
        retp

confused_ground_jump ;- continuous (396 ms loop) ---------------------------------------------
        mov     oscil_loops,#36     ; 6.9 kHz

:chirp  mov     rubs,#6             ; 6 rubs

:rub_a  mov     !pins,#soft         ; soft
        mov     cycle_loops,#62     ; 9 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off  

        mov     !pins,#rest         ; rest
        mov     cycle_loops,#35     ; 5 ms
        call    @cycle              ;
        djnz    rubs,:rub_a         ; rub_a loop
       
        mov     rubs,#6             ; 6 rubs
:rub_b  mov     !pins,#soft         ; soft
        mov     cycle_loops,#14     ; 2 ms
    not leds                        ; leds on          
        call    @cycle              ;  

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#35     ; 5 ms
        call    @cycle              ;  
       
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#14     ; 2 ms
    not leds                        ; leds on          
        call    @cycle              ;
       
        mov     !pins,#rest         ; rest
        mov     cycle_loops,#35     ; 5 ms
        call    @cycle              ;
        djnz    rubs,:rub_b         ; rub_b loop    
       
        mov     rubs,#24            ; 24 rubs
:rub_c  mov     !pins,#soft         ; soft
        mov     cycle_loops,#7      ; 1 ms
    not leds                        ; leds on          
        call    @cycle              ;  

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#7      ; 1 ms
        call    @cycle              ;
       
        mov     !pins,#loud         ; loud
        mov     cycle_loops,#28     ; 4 ms
        call    @cycle              ;
       
        mov     !pins,#medi         ; medi
        mov     cycle_loops,#7      ; 1 ms
        call    @cycle              ;
       
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#14     ; 2 ms
        call    @cycle              ;
    not leds                        ; leds off  
       
        mov     !pins,#rest         ; rest
        mov     cycle_loops,#35     ; 5 ms
        call    @cycle              ;
        djnz    rubs,:rub_c         ; rub_c loop
   
        mov     wavelets,#2         ; 2 wavelets

:wavelet
        mov     rubs,#3             ; 3 rubs (100 ms)

:rub_d  mov     !pins,#rest         ; rest
        mov     cycle_loops,#228    ; 33 ms
        call    @cycle              ;
        djnz    rubs,:rub_d         ; rub_d loop
               
        mov     rubs,#5             ; 5 rubs
:rub_e  mov     !pins,#soft         ; soft
        mov     cycle_loops,#62     ; 9 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off  

        mov     !pins,#rest         ; rest
        mov     cycle_loops,#35     ; 5 ms
        call    @cycle              ;
        djnz    rubs,:rub_e         ; rub_e loop    
   
        djnz    wavelets,:wavelet   ; wavelet loop

        mov     rubs,#12            ; 12 rubs (400 ms)
:rub_f  mov     !pins,#rest         ; rest
        mov     cycle_loops,#228    ; 33 ms
        call    @cycle              ;
        djnz    rubs,:rub_f         ; rub_f loop

        mov     rubs,#5
:rub_g  mov     !pins,#soft         ; soft
        mov     cycle_loops,#62     ; 9 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off  
   
        mov     !pins,#rest         ; rest
        mov     cycle_loops,#35     ; 5 ms
        call    @cycle              ;
        djnz    rubs,:rub_g         ; rub_g loop

        mov     rubs,#3             ; 3 rubs (100 ms)
:rub_h  mov     !pins,#rest         ; rest
        mov     cycle_loops,#228    ; 33 ms
        call    @cycle              ;
        djnz    rubs,:rub_h         ; rub_h loop

        mov     !pins,#rest         ; rest
        djnz    chirps,:chirp       ; chirp loop
        retp

        ;================================
        org $400            ; memory page
        ;================================
       
damp_loving_field ;- 400 ms ---------------------------------------------
        mov     oscil_loops,#56     ; 4.4 kHz
:chirp                      
        mov     wavelets,#2         ; 2 wavelets
:wavelet
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#35     ; 8 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off

        mov     !pins,#rest         ; rest
        mov     cycle_loops,#35     ; 8 ms
        call    @cycle              ;

        mov     !pins,#soft         ; soft
        mov     cycle_loops,#9      ; 2 ms
        call    @cycle
       
        mov     !pins,#medi         ; medi
        mov     cycle_loops,#9      ; 2 ms
        call    @cycle
       
        mov     !pins,#loud         ; loud
        mov     cycle_loops,#35     ; 8 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off          

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#9      ; 2 ms
        call    @cycle              ;

        mov     !pins,#soft         ; soft
        mov     cycle_loops,#31     ; 7 ms
        call    @cycle              ;

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#9      ; 4 ms
        call    @cycle
       
        mov     !pins,#loud         ; loud
        mov     cycle_loops,#35     ; 3 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off          

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#9      ; 6 ms
        call    @cycle              ;

        mov     !pins,#soft         ; soft
        mov     cycle_loops,#132    ; 30 ms
        call    @cycle              ;

        mov     rubs,#11            ; 110 ms
        mov     !pins,#rest         ; rest
        mov     cycle_loops,#44     ; 10 ms

:pause  call    @cycle              ;
        djnz    rubs,:pause         ; pause loop
        djnz    wavelets,:wavelet   ; wavelet loop
        djnz    chirps,:chirp       ; chirp loop
        retp


fall_field ;- 800 ms ---------------------------------------------
        mov     oscil_loops,#53     ; 4.7 kHz
:chirp                      
        mov     wavelets,#2    
:head
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#71     ; 15 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off
       
        mov     !pins,#rest         ; rest
        mov     cycle_loops,#71     ; 15 ms
        call    @cycle
       
        djnz    wavelets,:head      ; head loop
       
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#47     ; 10 ms
        call    @cycle
       
        mov     !pins,#medi         ; medi
        mov     cycle_loops,#47     ; 10 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off
           
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#47     ; 10 ms
        call    @cycle

        mov     !pins,#rest         ; rest
        mov     cycle_loops,#71     ; 15 ms
        call    @cycle
       
        mov     wavelets,#2         ; 2 wavelets
:wavelet
        mov     !pins,#soft         ; soft
        mov     cycle_loops,#24     ; 5 ms
        call    @cycle              ;

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#24     ; 5 ms
        call    @cycle              ;

        mov     !pins,#loud         ; loud
        mov     cycle_loops,#47     ; 10 ms
    not leds                        ; leds on          
        call    @cycle              ;  
    not leds                        ; leds off          

        mov     !pins,#medi         ; medi
        mov     cycle_loops,#24     ; 5 ms
        call    @cycle              ;

        mov     !pins,#soft         ; soft
        mov     cycle_loops,#24     ; 5 ms
        call    @cycle              ;

        mov     !pins,#rest         ; rest
        mov     cycle_loops,#71     ; 15 ms
        call    @cycle

        djnz    wavelets,:wavelet   ; wavelet loop

        mov     wavelets,#12        ; 600 ms
        mov     !pins,#rest         ; rest
        mov     cycle_loops,#235    ; 50 ms
:pause  call    @cycle              ;
        djnz    wavelets,:pause     ; pause loop
        djnz    chirps,:chirp       ; chirp loop
        retp