BS2 counter divider
in BASIC Stamp
New to forum.
Using BS2, because I have them, from many years ago.
Need to refresh my skills to use pics.
Looking for ideas on using BS2 to divide by 4 and divide by "N" up to 500 simultaneously.
I input and two outputs.
Needs to work from 10 to 1,000hz input from hall tach sensor on motor.
I have a program working with about 15 lines of code.
2 "pulsout,1"
Works to 1khz with either divider output, but only to a few 100hz with both outputs.
Misses counts.
Is there a better (faster) way than pulsout?
Intention is to migrate to pic when it's debugged.
Will a faster pic take care of problem?
Using BS2, because I have them, from many years ago.
Need to refresh my skills to use pics.
Looking for ideas on using BS2 to divide by 4 and divide by "N" up to 500 simultaneously.
I input and two outputs.
Needs to work from 10 to 1,000hz input from hall tach sensor on motor.
I have a program working with about 15 lines of code.
2 "pulsout,1"
Works to 1khz with either divider output, but only to a few 100hz with both outputs.
Misses counts.
Is there a better (faster) way than pulsout?
Intention is to migrate to pic when it's debugged.
Will a faster pic take care of problem?
Comments
2. BS-2x or p or whatever would be faster by up to a factor of maybe four or so.
3. This sounds to me like a job for PROPELLORMAN. You could get an Activity board for $50 direct from the factory.
Main: PULSOUT 2,1 GOTO Main
Take 468 microseconds, 218 of that for the PULSOUT and 250 for the GOTO. Code to detect input edges and to execute something like x // N will stretch it out to around 2ms for the loop with no hope of catching edges at 0.5ms for 1kHz input. If you can use a divide by 4 logic chip as a prescaler ahead of the BS2, that just might give it enough time with edges at manageable 2ms intervals instead of .5ms.Are you using a vanilla BS2, or do you already have a BS2p? I agree with Tom, the Propeller can do this task easily. Also a Pic, if that is the way you want to go, as it is easily done in assembly language. The BASIC Stamp is relatively slow, because its PIC processor is executing an interpreter.
Yes, I'm using plain BS2 from many years ago.
Have other issues now getting my old epic pic equipment working.
Also can't get my old win98 computer to find BS2 activity board.
"no hrdw found"
Everything works on dos computer, but hard to see. Even in monochrome.
Serial port works with other dos programs.
Have the hardware coming (from parallax) to start using my win7 desktop. A belkin usb to serial didn't work.
All the same sw and hrdw from 15 years ago. Only my brain is different.
Changes are difficult in hrdw.
Hope to migrate to a pic only, with sw changes as needed.
Don't know asm.
Epic will compile from BS2 if I figure it out again.
Paste text???
Did not have it commented, so I'll add a couple.
Total var word
wfp: 'waiting for pulse
if in10 = 0 then plsout
if in10 = 1 then wfp
plsout:
total = total + 1
'debug dec total,cr 'slows program
if total // 10 = 0 then plsout9 'divide by 10
'if total // 4 = 0 then plsout8 'remark
wfnp: 'waiting for next pulse
if in10 = 1 then wfp
goto wfnp
plsout9:
pulsout 9,1
total = 0 ' zero total after divide by "N"
goto wfnp
plsout8:
pulsout 8,1
goto wfnp
I put together a non-modal snippet as follows.
' {$STAMP BS2} ' {$PBASIC 2.5} N VAR WORD X VAR WORD y VAR BIT z VAR BIT DIR1=1 DIR2=1 DO y = IN0 X = y ^ z + x ' detect edges and add to X z = y OUT1 = x.BIT1 ' square wave output at 1/4 the input frequency OUT2 = x // N MAX 1 ' low pulses at 1/N the input frequency LOOP
This uses XOR logic to detect the edges, also logic that doesn't use pulsout to generate the outputs. Avoids a mix of GOTOs. It may work at 200Hz too, but certainly not at 1kHz.Are you using the most recent PBASIC 2.5 editor from Parallax?
My usb won't work.
That was just my first attempt. I have no idea about speed and such.
First I've attempted in 15 years.
Not coming back easily.
All my pic stuff is outdated. Can't get it to run on anything so far.
Found an XP with a parallel port.
Better I start over with something windows if I have to re-learn anyway.
All it does is send pulses to a tachometer and speedometer from electric vehicle.
Motor hall effect gives 4PPR hence the divide by 4.
Speedometer changes with gear ratio and tire size. Divide by "N".
There are a few other things I may want it to do.
CON _clkmode = xtal1 + pll16x 'Standard clock mode _xinfreq = 5_000_000 '* crystal frequency = 80 MHz PulsIn = 1 'input signal Out4 = 2 'divide by four OutN = 3 'divide by n DivideN = 23 'divisor VAR word Count4, CountN PUB main dira[Out4]~~ dira[OutN]~~ repeat waitpeq(|<PulsIn, |<PulsIn, 0) 'input signal rises if (++Count4 == 4) 'count to four outa[Out4]~~ 'output goes high if needful Count4 := 0 'and counter is reset if (++CountN == DivideN) 'counts to n outa[OutN]~~ CountN := 0 waitpeq(0, |<PulsIn, 0) 'input signal falls outa[Out4..OutN]~ 'assumes they are adjacent
This would leave room for lots of "few other things I may want to do". -_-
Couldn't get the xor to work BS2.
Nor do I understand it.
This divides by 4 and 10 when tested slow input.
n var word
x var word
y var bit
z var bit
dir8=1
dir9 =1
loop:
y = in10
x = y ^ z + x
z = y
out8 = x // 8 max 1
out9 = x // 20 max 1
goto loop
Thank you.
I'm looking for something that I can move to a pic.
I've done that from stamp.
How about if I get "into" propellor?
Or should I jump right into pic?
Either way, I'll have to learn a new language.
If your PIC stuff is so old it no longer works, but you want a small MCU, (ie smaller than a Prop), I'd suggest moving to a more capable family like the SiLabs EFM8 series.
Cheapest starting hardware there, is either TOOLSTICK850-B-SK (sub$10 for Debug+Device) or SLSTK2020A (sub $30, with LCD)
and because this is a good teaching example, I took your specs, and here is the EFM8 code....
Note the coded steps are very similar to the Spin above, but somewhat faster again as this is Assembler.
At default /8 clock Sim says this can cope with 58.892kHz Tacho in, and with /1 it can do 471.142kHz
(These parts have a 24.5MHz 2% on chip calibrated oscillator)
; EFM8BB1_Spartan_PollDiv.asm - Smallest working file for Pin Poll and Divide EFM8BB1 TSim51 Example. ; ; Web Example: Someone wanted Tacho divider, of /4 and /N=500, Fin of 1kHz (500us edges) ; The venerable Basic Stamp manages just ~200Hz so too slow to be usable. ; ; With just 3+4 ASM lines of INIT, and 5+9 ASM lines of 3 Loop code, this tiny example works in 42 bytes. ; TSim51 Scope and Breadboard are used, Generator drives TachoIN, and Scope shows DivA.DivB results. ; $DATE $TITLE ( EFM8BB1_Spartan_PollDiv ) $NOPAGING $NOMOD51 $INCLUDE (SI_EFM8BB1_Defs.inc) ; Eval: SLSTK2020A Smallest & cheapest device 31c/1k (!) for 2k model ; or ;$INCLUDE (SI_C8051F850_Defs.INC) ; Eval: TOOLSTICK850-B-SK ; ~~~~~~~~~~~~~~ SLSTK2020A Eval Board mapping LED and Buttons ~~~~~~~~~~~~~~~~~ UIF_LED2_Red_P16 BIT P1.6 ; L=On UIF_LED1_Blue_P15 BIT P1.5 ; L=On UIF_LED0_Green_P14 BIT P1.4 ; L=On UIF_PB1 BIT P0.3 ; L=On UIF_PB0 BIT P0.2 ; L=On EFM_DISP_ENABLE bit P2.3 ; L=EFM8 off, BC on DSEG at 20H BitAdrB0: ds 1 UserBit6 BIT BitAdrB0.6 DSEG at 30H PrevP0: ds 1 ;CLK_24p5MHz EQU 1 ;comment out for /8 SysCLK 3.0625MHz PinMask EQU 0000_0100b ; Choose a pin to poll P0.2 Connect to 1kHz Gen in Breadboard. DivA_Val EQU 04 DivB_Val EQU 500 DivA_OutPin_P16 BIT UIF_LED2_Red_P16 DivB_OutPin_P15 BIT UIF_LED1_Blue_P15 ; ~~~~~~~~~~~~~~~~~~ CODE START ~~~~~~~~~~~~~~~~~~~~~~~~~~ CSEG at 0000h ;Reset vector ; AJMP Init ; No interrupts in this Spartan101 example ; ORG 7BH ; may not be needed Init: MOV WDTCN,#0DEh ; Disable WDT !IMPORTANT! as defaults ON in this variant. MOV WDTCN,#0ADh ; If remove this, WDTO occurs @ (1/80k)*4^(0x7+3) = 13.1072s ~ 2 scope sweeps. Try it and see. ; ; MOV XBR0,#00000000b ; XBR0: Port I/O Crossbar [SYSCKE CP1AE CP1E CP0AE CP0E SMB0E SPI0E URT0E] SFR Page = 0x0, 0x20; SFR Address: 0xE1 ; No peripherals used IFDEF CLK_24p5MHz MOV CLKSEL,#0 ;CLKSEL: Clock Select [DIVRDY CLKDIV2..0 - CLKSL2..0] Reset 10110000 SFR Page = ALL; SFR Address: 0xA9 ENDIF ; Keep Default 24.5MHz /8 SysCLK , uncomment to speed x8 MOV XBR2,#01000000b ; XBR2: Port I/O Crossbar [WEAKPUD XBARE - - - URT1CTSE URT1RTSE URT1E] SFR Page = 0x0, 0x20; SFR Address: 0xE3 ;XBARE = Enable Port Connection, other bits low, No peripherals used, Weak Pullups enabled InitVARs: TestPath EQU 01 IF TestPath MOV A,#01 ; first path is all counters overflow, use for timing test, longest path. MOV R7,A MOV R6,A MOV R5,A Else MOV R7,#DivA_Val ; Same as overflow init. MOV R6,#LOW(DivB_Val) MOV R5,#HIGH(DivB_Val)+1 ENDIF PinPollLoop: MOV A,P0 ; <<break here = Time Start Poll loop (eg 14 SysCLK) XCH A,PrevP0 ; Save this sample, get last copy XRL A,PrevP0 ; Hi on any BITs <> ANL A,#PinMask ; get just the wanted bit JZ PinPollLoop ; Test for Change ? Inner loop 11 SysCLKs ; Have a Pin Change ; Check Divider A eg /4 DJNZ R7,ChkDivB ; Divider A ; MOV R7,#DivA_Val CPL DivA_OutPin_P16 ; Toggles at /DivA_Val of IP toggle rate ChkDivB: ; Check Divider B eg /500 DJNZ R6,ChkDivC DJNZ R5,ChkDivC ; 16b counter ; MOV R6,#LOW(DivB_Val) MOV R5,#HIGH(DivB_Val)+1 CPL DivB_OutPin_P15 ; Toggles at /DivB_Val of IP toggle rate ChkDivC: ;No more Div checks ? then reloop AJMP PinPollLoop ; << Break here end both Counters, eg 26 Clks 8.49us @ 3.0625MHz default low speed. Size_EFM8BB1_Spartan_PollDiv EQU $-Init ; 0x2a = 42 bytes ; Tests fine at 1kHz, can push to 0.5/8.49u = 58892.81508 at default slow /8 clk ) ; Test at 58.892kHz ? OK ; 471.142kHz count tracking capable at 24.5MHz full speed. END
If you plan to end up with pic, any detour (say, into propellorLand) seems unneedful.
I used the propellor itself as a pulse generator; had been using a 555 but it (the 555) wouldn't run much above 100 kHz.
This exercise got me to understand just how cool waitpeq actually is. Without it, syncing up to an edge would take at least two instructions (three if you had to mask something off). With it, you just start executing instructions again at exactly the right time and with very little uncertainty.
CON _clkmode = xtal1 + pll16x 'Standard clock mode _xinfreq = 5_000_000 '* crystal frequency = 80 MHz PulsIn = 1 'input signal Out4 = 2 'divide by four OutN = 3 'divide by n DivideN = 23 'divisor OBJ Freq : "Synth" VAR long MyPar[4] 'used to pass parameters byte cog 'in case we need to stop the ccog PUB main Freq.Synth("A",5, 1_000_000) 'start up a sythesizer in this cog ' FrequencySynth v1.1 'page 4 of signals in OBEX MyPar[0] := DivideN 'divisor MyPar[1] := 1 << PulsIn 'mask corresponding to input MyPar[2] := 1 << Out4 MyPar[3] := 1 << OutN cog := cognew(@Mach, @MyPar) 'start the PASM cog repeat 'forever waitcnt(clkfreq+cnt) dat 'this is the machine cog org 0 'begin at the beginning Mach mov AdPar, Par 'get the parameter address rdlong divis, AdPar 'get the divisor add AdPar, #4 'to next parameter rdlong PulsInMsk, AdPar 'mask corresponding to input add AdPar, #4 rdlong Out4Msk, AdPar add AdPar, #4 rdlong OutNMsk, AdPar mov OutBMsk, OutNMsk or outbMsk, Out4Msk 'and a mask for both outputs or dira, OutBMsk 'make them outputs mov Count4, #4 'initialize the counters mov CountN, divis Loop waitpeq PulsInMsk, PulsInMsk 'wait for positive edge sub Count4, #1 wz 'decrement and saee if done if_z or outa, Out4Msk 'generate the pulse if_z mov Count4, #4 'and re-initialize the counter sub CountN, #1 wz 'now the same for count by N if_z or outa, OutNMsk 'generate that pulse if_z mov CountN, divis waitpeq Zero, PulsInMsk 'wait for negative edge andn outa, OutBMsk 'terminate either or both jmp #Loop 'forever Zero long 0 AdPar res 1 'address of parameter divis res 1 'divisor for outN PulsInMsk res 1 'mask for input pin Out4Msk res 1 'mask for output OutNMsk res 1 OutBMsk res 1 'mask for both outputs Count4 res 1 'counts to four CountN res 1 'counts to N
Think I'll get some new equipment and give it a try.
Thanks for all the suggestions.
Learned a lot studying this.
I think I understand the XOR now. Detects both edges as I understand it?
Also googled -do, still haven't found it in my BS2 book???
I'll try again using a different bit "OUT1 = x.BIT1" for divide by 4.
Slowly coming back to me.
Got the new stamp hrdw, so I can run in windows now.
Look for DO...LOOP in the most recent manual:
https://www.parallax.com/downloads/basic-stamp-manual
Would have never thought of using logic and word bits, even though I've done a lot with ttl logic gates.