component mux16 "Select from one of sixteen input values"; pin in bit use_graycode"""\ This signifies the input will use Gray code instead of binary. Gray code is a good choice when using physical switches because for each increment only one select input changes at a time. """; pin in bit suppress_no_input"""\ This suppresses changing the output if all select lines are false. This stops unwanted jumps in output between transitions of input. but make in00 unavailable. """; pin in float debounce_time"""\ sets debounce time in seconds. eg. .10 = a tenth of a second input must be stable this long before outputs changes. This helps to ignore 'noisy' switches. """; pin in bit sel#[4] """\ Together, these determine which \\fBin\\fIN\\fR value is copied to \\fBout\\fR. """; pin out float out_f; pin out s32 out_s """\ Follows the value of one of the \\fBin\\fIN\\fR values according to the four \\fBsel\\fR values and whether use-graycode is active. The s32 value will be trunuated and limited to the max and min values of signed values. .RS .TP \\fBsel3=FALSE\\fR, \\fBsel2=FALSE\\fR, \\fBsel1=FALSE\\fR, \\fBsel0=FALSE\\fR \\fBout\\fR follows \\fBin0\\fR .TP \\fBsel3=FALSE\\fR, \\fBsel2=FALSE\\fR, \\fBsel1=FALSE\\fR, \\fBsel0=TRUE\\fR \\fBout\\fR follows \\fBin1\\fR .TP etc. .RE """; param r float elapsed "Current value of the internal debounce timer\n for debugging."; param r s32 selected "Current value of the internal selection variable after conversion\n for debugging"; pin in float in##[16] "array of selectable outputs"; variable double delaytime; variable int lastnum; variable int running; function _; license "GPL"; author "Chris S Morley"; see_also "mux2(9), mux4(9), mux8(9), mux_generic(9)."; ;; FUNCTION(_) { int i,num = 0; int internal[4]; if(suppress_no_input) { if (sel(0) + sel(1) + sel(2) + sel(3) == 0) { return; } } if (use_graycode) { internal[0] = sel(3); internal[1] = sel(2); internal[2] = sel(1); internal[3] = sel(0); for(i = 1; i < 4; i++){ internal[i] = internal[i] ^ internal[i - 1]; } selected = num = internal[3]+(internal[2]*2) + (internal[1]*4) + (internal[0]*8); }else{ selected = num = (sel(0))+(sel(1)*2) + (sel(2)*4) + (sel(3)*8); } if(debounce_time) { if (num != lastnum) { if (!running) { running = 1; delaytime = 0; } if (delaytime < debounce_time) { delaytime += fperiod; elapsed = delaytime; return; }else{ running = 0; lastnum = num; out_s = out_f = in(num); return; } } } /* select the output */ out_s = out_f = in(num); }