Needm help converting a Basic Stamp program to the Propeller
jknightandkarr
Posts: 234
I need help converting a BS2 program to the Propeller. I have both the BS2 and Prop versions code below, I am at an impass on the BS2's */ command. BS2 editor states it multiples and returns the middle 16-bits of the variables and/or constants. The Propeller seams to have only * & ** Multiply and return lower or upper 32 bits. So far I have not gotten into stuff like this, so I am not able to figure out how to write the original 'GrafVal = (RawVal - LoScale) */ Scale' for use with the Propeller chip... The only idea I have is something like:
GrafVal := (RawVal-LowScale)
GrafVal := GrafVal * Scale
GravVal := GrafVal >> 8
But I am almost posative that won't do the same thing. Any suggestions? Thanks.
Original Code: Stamp Works V2.1.pdf, on pg41
Current Propeller version:
Joe
GrafVal := (RawVal-LowScale)
GrafVal := GrafVal * Scale
GravVal := GrafVal >> 8
But I am almost posative that won't do the same thing. Any suggestions? Thanks.
Original Code: Stamp Works V2.1.pdf, on pg41
' {$STAMP BS2}
' {$PBASIC 2.5}
'SW21-EX05-LED.BS2
LEDs VAR OUTL
LEDsDIRs VAR DIRL
Pot PIN 15
DotGraf CON 0
BarGraf CON 1
GraphMode CON BarGraf
IsOn CON 1
IsOff CON 0
LoScale CON 10
HiScale CON 695
Span CON HiScale - LoScale
Scale CON $FFFF / Span
rawVal VAR Word
GrafVal VAR Byte
HiBit VAR Byte
NewBar VAR Byte
Reset:
LEDsDirs = %11111111
Main:
DO
GOSUB Read_Pot
GrafVal = (RawVal - LoScale) */ Scale
GOSUB Show_Graph
PAUSE 50
LOOP
Read_Pot:
HIGH Pot
PAUSE 1
RCTIME Pot, 1, RawVal
RETURN
Show_Graph:
HiBit = DCD (GrafVal / 32)
IF (GraphMode = BarGraf) THEN
NewBar = 0
IF (GrafVal > 0) THEN
DO WHILE (HiBit > 0)
NewBar = NewBar << 1
NewBar.BIT0 = IsOn
HiBit = HiBit >> 1
LOOP
ENDIF
LEDs= NewBar
ELSE
LEDs = HiBit
ENDIF
RETURN
Current Propeller version:
{{BS2 Bargraph.spin
Author:Joe R.
Version: 1.1 (March 6th, 2016
Updates: Ver 1.0-Original Release
1.1-Added Values to adjust I/O Pins
Future Updates:-Add shift register support.
-Add support for multiple pattern outputs for multiple
bargraph displays.
-Add multiple inputs. 1 for each bargraph display.
Oridinal File: SW21-EX05-LED_Graph.BS2, Stamp Works Ver 2.1 Pg. 41
Discription: Creates a configurable dot or bar LED graph, such as one on a VU meter
or a digital non-numerical fuel or volt gauge display.
}}
CON
_CLKMODE = XTAL1 + PLL16X 'Standard clock mode * crystal frequency = 80 MHz
_XINFREQ = 5_000_000
DotGraf = 0
BarGraf = 1
GraphMode = BarGraf 'DotGraf or BarGraf
IsOn = 1
IsOff = 0
LowScale = 10 'Low cap reading
HighScale = 695 'High cap reading
Span = HighScale - LowScale '685 total cap range
Scale = $FFFF / Span '95=$FFFF/685
Pot = 12 'Input from RC network.
VAR
WORD RawVal 'Value from I/O Pins '
BYTE HiBit, NewBar, GrafVal ' '
WORD LEDs, LEDsDirs '
BYTE LowDigitPin, HighDigitPin 'The pins for specifying digits.
'Must be contiguous
'HighDigitPin can be from 0
'to 7 more than LowDigitPin
'
PUB Settings(dLow, digits, s0, enabled)
'' Start the display
'' Parameters:
'' dLow - the pin number of the least significant digit
'' digits - the number of digits to display (up to 8)
'' s0 - the pin number of segment 0
'' enabled - the initial enabled state
LowDigitPin := dLow
HighDigitPin := dLow + ((digits - 1) <# 16) 'Limit to 16 leds
DIRA[LowDigitPin..HighDigitPin]~~ 'Set digit pins to outputs
OUTA[LowDigitPin..HighDigitPin]~~ 'Turn off all digits
DIRA[Pot]:=%1
Start
PUB Start
REPEAT
ReadPot
grafVal := (rawVal - LowScale) */ Scale
ShowGraph
WAITCNT ((CLKFREQ/1000)*50+CNT)
PRI ReadPot
OUTA[Pot]:=1
WAITCNT (CLKFREQ/1000+CNT)
RCTIME Pot, 1, rawValue
RETURN
PRI ShowGraph
HiBit:=|<(GrafVal/32)
IF GrafVal=BarGraf
NewBar:=0
IF GrafVal>0
REPEAT WHILE HiBit>0
NewBar = NewBar << 1
NewBar:=%000000000000001
HiBit := HiBit >> 1
ELSE
Leds:=NewBar
ELES
Leds:=HiBit
RETURN
Joe

Comments
Value1 = 100
Value1 = Value1 */ $0180
Value =150
Doing conventionally on a programming calc won't work, so I did
DEC 100 * HEX 0180
Got 38400 and then hit >> on the calc 8 times and got 150
So, Will
GrafVal := (RawVal-LowScale)
GrafVal := GrafVal * Scale
GravVal := GrafVal >> 8
actually work??
Joe
Just do: or a bit slower but more readable:
Andy
Joe
IF GrafVal=BarGraf
be:
IF GrafVal==BarGraf
?
Joe
CON _CLKMODE = XTAL1 + PLL16X 'Standard clock mode * crystal frequency = 80 MHz _XINFREQ = 5_000_000 DotGraf = 0 BarGraf = 1 GraphMode = 1'BarGraf 'DotGraf or BarGraf IsOn = 1 IsOff = 0 LowScale = 10 'Low cap reading HighScale = 695 'High cap reading Span = HighScale - LowScale '685 total cap range Scale = $FFFF / Span '95=$FFFF/685 95.67153 Pot = 15 'Input from RC network. VAR LONG us WORD RawVal 'Value from I/O Pins ' BYTE HiBit, NewBar, GrafVal ' ' WORD LEDs, LEDsDirs ' BYTE LowDigitPin, HighDigitPin 'The pins for specifying digits. 'Must be contiguous 'HighDigitPin can be from 0 'to 7 more than LowDigitPin ' PUB Settings(dLow, digits, s0, enabled) '' Start the display '' Parameters: '' dLow - the pin number of the least significant digit '' digits - the number of digits to display (up to 8) '' s0 - the pin number of segment 0 '' enabled - the initial enabled state dLow:=0 digits:=8 us:= clkfreq / 1_000_000 ' Clock cycles for 1 us LowDigitPin := dLow HighDigitPin := dLow + ((digits - 1) <# 16) 'Limit to 16 leds DIRA[LowDigitPin..HighDigitPin]~~ 'Set digit pins to outputs OUTA[LowDigitPin..HighDigitPin]~~ 'Turn off all digits DIRA[Pot]:=%1 Start PUB Start 'GrafVal:=0 'RawVal:=350 REPEAT ReadPot RawVal:=ReadPot GrafVal := (RawVal-LowScale) * Scale >> 8 'GrafVal := (RawVal-LowScale) 'GrafVal := GrafVal * Scale 'GravVal := GrafVal >> 8 ShowGraph WAITCNT ((CLKFREQ/1000)*50+CNT) PRI ReadPot OUTA[Pot]:=1 WAITCNT (CLKFREQ/1000+CNT) RawVal:= RCTIME (Pot, 1) 'rawValue returned 'RawVal:=RCTIME() RETURN PRI ShowGraph HiBit:=|<(GrafVal/32) IF GrafVal==1 'BarGraf NewBar:=0 IF GrafVal>0 REPEAT WHILE HiBit>0 NewBar:= NewBar << 1 NewBar:=%000000000000001 HiBit := HiBit >> 1 ELSE Leds:=NewBar ELSE Leds:=HiBit RETURN PUB RCTIME (Pin,State) :Duration | ClkStart, ClkStop {{ Reads RCTime on Pin starting at State, returns discharge time, returns in 1uS units dira[5]~~ ' Set as output outa[5]:=1 ' Set high BS2.Pause(10) ' Allow to charge x := RCTime(5,1) ' Measure RCTime BS2.DEBUG_DEC(x) ' Display }} DIRA[Pin]~ ClkStart := cnt ' Save counter for start time waitpne(State << pin, |< Pin, 0) ' Wait for opposite state to end clkStop := cnt ' Save stop time Duration := (clkStop - ClkStart)/uS ' calculate in 1us resolutionGoing to see if I can spot any issues while waiting for assistance. I think I have the result from the ReadPot and RCTIME done correctly, but nothing I try changes anything...
Joe
NewBar:= NewBar << 1 NewBar:=%000000000000001look very suspicious. I think you meant to have "|=" on the second line (so as to OR in a low bit to NewBar, instead of replacing it).The Stamp version is displaying the result on a set of 8 LEDs. The logic is similar for 16 LEDs but you'd have to grab the top 4 bits. The Stamp version allows it to display either the single LED, or a bar of LEDs like %1, %11, %111 etc. %11111111
With the ** operator, you have 32 bits to play with.
CON
Scale = $FFFF_FFFF / Span * 256 ' if Span = 685 then scale = 1_605_126_400
then with the **
GrafVal = (RawVal - LoScale) ** Scale
rescales to a maximum value of 256. For example, if RawVal - LoScale = 400, then 400 ** 1605126400 = 149. Note that 400/685 = 149/256
By your current method 400 * 95 >> 8 = 148, just a little more roundoff error from using $FFFF instead of $FFFFFFFF.
For the display, if you want to get the full bar without a REPEAT loop, just calculate from the original hibit value,
newbar := hiBit * 2 - 1 ' e.g. %10000 becomes %11111
PRI ShowGraph HiBit:=|<(GrafVal/32) IF GrafVal==1 'BarGraf NewBar:=0 IF GrafVal>0 REPEAT WHILE HiBit>0 NewBar:= NewBar << 1 NewBar:=%000000000000001 HiBit := HiBit >> 1 ELSE Leds:=NewBar ' <<<<< This line should probably be indented ELSE Leds:=HiBit RETURNIt's possible that line is always executing, since it's outside the scope of the ELSE statement. I also think ErSmith is right when he says your := should be an |=
You could also make the code a little faster by using the <<= or >>= versions of shift which combine the shift and the assignment in a single operation, when you're not storing the result to a different variable.
This would be the updated version with all changes:
PRI ShowGraph HiBit := |<(GrafVal/32) IF GrafVal==1 'BarGraf NewBar := 0 IF GrafVal>0 REPEAT WHILE HiBit>0 NewBar <<= 1 NewBar |= 1 HiBit >>= 1 ELSE Leds := NewBar ELSE Leds := HiBit RETURNI first wrote the program the same way in the BS2 editor. Like This?
NewBar:= NewBar << 1 NewBar|=%000000000000001Tried it and no change all leds still on...I will try that n see if anything changes.
That I didn't catch. Thank you! I fixed it, and tried <<=, >>= & still nada on changes...
I am going to try the serial terminal and debug and try and see what thing is doing.
Joe