' {$STAMP BS2} ' {$PBASIC 2.5} ' -----[ Program Description ]--------------------------------------------- ' Frequency and duty cycle meter using BS2. The results are displayed on an ' parallel LCD. ' Tronicgr 2006 for Greekbotics.knows.it (01/6/2006) ' ' Basic Stamp2 and LCD connections: ' BS2 ' ------\_/------ ' -| |- ' LCD 6 (E) -| P5 |- ' LCD 4 (RS) -| P4 |- ' LCD 11 (D4) -| P0 |- ' LCD 12 (D5) -| P1 |- ' LCD 13 (D6) -| P2 |- ' LCD 14 (D7) -| P3 |- ' -| |- ' --------------- ' Some LCD conections not shown above: ' LCD 1 - GND ' LCD 2 - VDD +5V ' LCD 3 - GND ' LCD 5 - GND ' LCD 15 - GND K (backlight) ' LCD 16 - Vdd A (backlight) ' -----[ I/O Definitions ]------------------------------------------------- E PIN 5 ' LCD Enable RW PIN 10 ' Read/Write\ RS PIN 4 ' Reg Select (1 = char) LcdDirs VAR DIRA ' dirs for I/O redirection LcdBus VAR OUTA FreqPin1 PIN 11 ' frequency input pin (on bs2) FreqPin2 PIN 12 ' frequency input pin (on bs2) FreqPin3 PIN 13 ' frequency input pin (on bs2) Speaker PIN 15 ledred PIN 7 ledgreen PIN 6 key1 PIN 8 key2 PIN 9 key3 PIN 10 ' -----[ Constants ]------------------------------------------------------- mSec CON 100 ' Measurement time in msec - BS2 sec CON 1000 ' Measurement time in msec - BS2 #DEFINE Lcd = 1 ' set to 0 for VFD οθονη #DEFINE BarGraph = 1 ' set to 0 for no graph LcdCls CON $01 ' clear the LCD LcdHome CON $02 ' move cursor home LcdCrsrL CON $10 ' move cursor left LcdCrsrR CON $14 ' move cursor right LcdDispL CON $18 ' shift chars left LcdDispR CON $1C ' shift chars right LcdDDRam CON $80 ' Display Data RAM control LcdCGRam CON $40 ' Character Generator RAM LcdLine1 CON $80 ' DDRAM address of line 1 LcdLine2 CON $C0 ' DDRAM address of line 2 ' -----[ Variables ]------------------------------------------------------- temp VAR Byte ' temp var used on LCD lcd_E VAR temp.BIT2 ' LCD Enable pin lcd_RS VAR temp.BIT3 FreqPin VAR Nib ' Input channel selection freq VAR Word ' frequency t1 VAR Word pulselen VAR Word r VAR Word ' Remainder i VAR Nib ' Iterations point VAR Bit Keyindex VAR Nib btnWrk VAR Byte accuracy VAR Bit result VAR Word ' calculated float-point output char VAR Byte ' for LCD addr VAR Word ' ee pointer (for DATA) percent VAR Word ' % of max data value VAR Word ' value to print width VAR Nib ' width of print field pad VAR Nib ' spaces for rj printing idx VAR Byte ' loop counter cols VAR Byte ' total graph colums blox VAR Byte ' whole blocks for graph ' -----[ EEPROM Data ]----------------------------------------------------- Banner1 DATA " TronicGR 2006 ", 0 Banner2 DATA "Frequency meter", 0 Banner3 DATA "www.Greekbotics", 0 Banner4 DATA ".Knows.it ", 0 DefaultL1 DATA " Hz 0 %", 0 #IF Lcd #THEN CC0 DATA $10, $10, $10, $10, $10, $10, $10, $00 CC1 DATA $18, $18, $18, $18, $18, $18, $18, $00 CC2 DATA $1C, $1C, $1C, $1C, $1C, $1C, $1C, $00 CC3 DATA $1E, $1E, $1E, $1E, $1E, $1E, $1E, $00 CC4 DATA $1F, $1F, $1F, $1F, $1F, $1F, $1F, $00 #ENDIF ' -----[ Initialization ]-------------------------------------------------- Reset: DIRL = %01111111 DIRH = %11000000 LOW RW LCD_Init: LOW ledred LOW ledgreen FREQOUT Speaker, 200, 2000, 2600 FREQOUT Speaker, 250, 3500, 2200 PAUSE 50 LcdBus = %0011 PULSOUT E, 1 : PAUSE 5 PULSOUT E, 1 : PAUSE 0 PULSOUT E, 1 : PAUSE 0 LcdBus = %0010 PULSOUT E, 1 char = %00101000 GOSUB LCD_Command char = %00001100 GOSUB LCD_Command char = %00000110 GOSUB LCD_Command INPUT ledred INPUT ledgreen DL_Characters: #IF Lcd #THEN char = LcdCGRam ' point to CG RAM GOSUB LCD_Command ' prepare to write CG data FOR idx = CC0 TO (CC4 + 7) ' build 5 custom chars READ idx, char ' get byte from EEPROM GOSUB LCD_Write ' put into LCD CG RAM NEXT #ENDIF LOW ledred LOW ledgreen Banner: char = LcdCls GOSUB LCD_Command addr = Banner1 GOSUB LCD_Put_String char = LcdLine2 GOSUB LCD_Command addr = Banner2 GOSUB LCD_Put_String PAUSE 500 char = LcdCls GOSUB LCD_Command addr = Banner3 GOSUB LCD_Put_String char = LcdLine2 GOSUB LCD_Command addr = Banner4 GOSUB LCD_Put_String PAUSE 500 char = LcdCls GOSUB LCD_Command addr = DefaultL1 GOSUB LCD_Put_String INPUT ledgreen INPUT ledred LOW ledgreen accuracy = 1 '------------------------------------------ 'Demo graph FOR freq = 0110 TO 9990 STEP 352 FREQOUT Speaker, 5, freq percent = freq result = freq GOSUB Show_data GOSUB Show_Percent NEXT FOR freq = 9990 TO 0110 STEP 550 FREQOUT Speaker, 5, freq percent = freq result = freq GOSUB Show_data GOSUB Show_Percent NEXT '------------------------------------------ FreqPin = 11 Keyindex = 0 btnWrk = 0 accuracy = 0 point = 1 percent = 0 result = 0 ' -----[ Program Code ]---------------------------------------------------- Main: GOSUB Keycheck 'check for keypresses GOSUB freq_measure 'do the frequency measurement GOSUB Duty_cycle_measure 'do the duty cycle measurement GOSUB Show_data 'shows frequency GOSUB Show_Percent 'shows duty cycle + bargraph GOTO Main ' -----[ Subroutines ]----------------------------------------------------- Keycheck: BUTTON key3, 0, 200, 20, btnWrk, 0, No_Press3 LOOKDOWN Keyindex, [11, 12, 13], FreqPin FOR i = 1 TO Keyindex FREQOUT Speaker, 150, 3500 PAUSE 50 NEXT Keyindex = Keyindex + 1 IF Keyindex > 3 THEN Keyindex = 0 PAUSE 1000 No_Press3: BUTTON key2, 0, 200, 20, btnWrk, 0, No_Press2 LOW ledred FREQOUT Speaker, 1000, freq INPUT ledred No_Press2: BUTTON key1, 0, 200, 20, btnWrk, 0, No_Press1 TOGGLE ledgreen FREQOUT Speaker, 150, 3500 IF ledgreen THEN accuracy = 1 ELSE accuracy = 0 ENDIF PAUSE 1000 No_Press1: RETURN Duty_cycle_measure: PULSIN FreqPin,1,T1 'READ T1 PULSIN FreqPin,0,pulselen 'READ T2 pulselen = pulselen + t1 r = t1 // pulselen ' Remainder percent = 0 ' Clear fractional quotient FOR i = 1 TO 4 ' Four digits to right of decimal r = r * 10 ' Multiply remainder by 10 percent = (10 * percent) + (r / pulselen) ' Multiply quotient by 10 and add r = r // pulselen ' Calculate next remainder NEXT RETURN freq_measure: IF accuracy = 1 THEN COUNT FreqPin, Sec, freq ' collect pulses for 1 second result= freq ELSEIF accuracy = 0 THEN COUNT FreqPin, mSec, freq ' collect pulses for 100 msec result = freq ENDIF RETURN Show_data: char = LcdLine1 GOSUB LCD_Command width = 5 point = 0 value = result GOSUB LCD_Put_RJ_Value RETURN Show_Percent: char = LcdLine1 + 10 GOSUB LCD_Command width = 4 point = 1 value = percent GOSUB LCD_Put_RJ_Value #IF BarGraph #THEN char = LcdLine2 ' position cursor GOSUB LCD_Command cols = (percent/100) */ 205 ' x 0.8 (100% = 80 pixels) blox = cols / 5 ' calculate whole blocks IF (blox > 0) THEN char = 4 FOR idx = 1 TO blox GOSUB LCD_Write NEXT ENDIF LOOKUP (cols // 5), [" ", 0, 1, 2, 3], char ' partial block GOSUB LCD_Write char = " " FOR idx = 0 TO (16 - blox) ' clear end of graph display GOSUB LCD_Write NEXT #ENDIF RETURN LCD_Put_String: DO READ addr, char addr = addr + 1 IF (char = 0) THEN EXIT GOSUB LCD_Write LOOP RETURN LCD_Put_RJ_Value: LOOKDOWN value, >=[10000, 1000, 100, 10, 0], pad pad = pad - (5 - width) IF (pad > 0) THEN char = " " FOR idx = 1 TO pad GOSUB LCD_Write NEXT ENDIF IF point = 1 THEN FOR idx = (width - pad - 1) TO 0 char = value DIG idx + "0" GOSUB LCD_Write IF idx = 2 THEN IF point THEN char = "." GOSUB LCD_Write ENDIF ENDIF NEXT ELSEIF point = 0 THEN IF accuracy = 0 THEN FOR idx = (width - pad -1) TO 0 char = value DIG idx + "0" GOSUB LCD_Write NEXT IF pad = 0 THEN char = " " GOSUB LCD_Write ELSE char = "0" GOSUB LCD_Write ENDIF ELSEIF accuracy = 1 THEN FOR idx = (width - pad -1) TO 0 char = value DIG idx + "0" GOSUB LCD_Write NEXT char = " " GOSUB LCD_Write ENDIF ENDIF RETURN ' -----[ LCD Subroutines ]----------------------------------------------------- ' ' LCD_Command: LOW RS LCD_Write: LcdBus = char.HIGHNIB PULSOUT E, 3 LcdBus = char.LOWNIB PULSOUT E, 3 HIGH RS RETURN