byte, long, int - im a bit confused
timatron
Posts: 16
hi guys.
i'm working on a piece of code to work through an array of numbers and display them on an analog gauge
using a pwm wave, this is my first time using a dat block and im getting a bit confused. in the past i had
used the fullduplexserial to grab a dec from my input at the terminal and display it using the duty function
which is part of the pwm_8x object (thanks Phil!) So now I would like to loop through an array of values
and display them on the analog gauge, but i'm having trouble.
should i store the data block at bytes or longs, ie what does the duty function expect? i guess i just get a little lost in the type definitions.
below is my code, and i'll include the definition of the duty function below as well.
thanks for any help!
cheers,
tim
Post Edited (timatron) : 10/15/2008 7:00:05 PM GMT
i'm working on a piece of code to work through an array of numbers and display them on an analog gauge
using a pwm wave, this is my first time using a dat block and im getting a bit confused. in the past i had
used the fullduplexserial to grab a dec from my input at the terminal and display it using the duty function
which is part of the pwm_8x object (thanks Phil!) So now I would like to loop through an array of values
and display them on the analog gauge, but i'm having trouble.
should i store the data block at bytes or longs, ie what does the duty function expect? i guess i just get a little lost in the type definitions.
below is my code, and i'll include the definition of the duty function below as well.
thanks for any help!
cheers,
tim
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 DIN = 24 ' DIN is actually a DOUT on the prop but a DIN on the 7219 CLK = 26 CS = 25 base_pin0 = 0 base_pin8 = 8 base_pin16 = 16 OBJ Debug: "FullDuplexSerialPlus" pwm0: "pwm_x8" pwm8: "pwm_x8" pwm16: "pwm_x8" pub init | i, gaugeVal pwm0.start(base_pin0, %1111_1111, 2000) 'Setup for PWM output on pins A16 - A23 at 23KHz. pwm8.start(base_pin8, %1111_1111, 2000) 'Setup for PWM output on pins A16 - A23 at 23KHz. pwm16.start(base_pin16, %1111_1111, 2000) 'Setup for PWM output on pins A16 - A23 at 23KHz. Debug.start(31, 30, 0, 57600) waitcnt(clkfreq*2 + cnt) Debug.tx(16) WAITCNT(CLKFREQ*4+CNT) dira[noparse][[/noparse]24..26]~~ ' make these pins outputs outa[noparse][[/noparse]CS]~~ ' chip select idles high outa[noparse][[/noparse]CLK]~ ' clock idles low load($0FFF) ' intialize test WAITCNT(CLKFREQ*2+CNT) ' wait a little while load($0F00) ' turn test off load($0CFF) ' put out of shutdown mode load($09FF) ' address 7219's register 9 which sets the decode mode to BCD on all digits (FF) load($0B03) ' limit scan (B) to 4 digits (03) load($0A00) ' intensity register (0A) set to max ($0F) repeat repeat i from 1850 to 2008 gaugeVal := warVals[noparse][[/noparse]1850 - i] Debug.Dec(gaugeVal) Debug.Str(String(13)) display(i) 'gaugeDisplay(5, gaugeVal) 'this is the line that is broken WAITCNT(CLKFREQ/2+CNT) pub load(data) ' load 16-bit of data into the 7219 data ><= 16 ' bit reverse the 16-bits of data (7219 requires most significant bit first) outa[noparse][[/noparse]CS]~ ' start shift cycle repeat 16 ' for 16-bits outa[noparse][[/noparse]DIN] := data & 1 ' set DOUT to next bit of data (always in the lsb) outa[noparse][[/noparse]CLK]~~ ' single clock low-high and back to low for each data bit outa[noparse][[/noparse]CLK]~ data >>= 1 ' shift next bit into the lsb ready for testing outa[noparse][[/noparse]CS]~~ ' done all bits, now release CS at which point the 7219 will use the data pub display(number) | i ' display the number as 4 digits on the 7219 repeat i from 1 to 4 load(((5-i)<<8) + number // 10) ' find next digit (units) and send to display position (i) encoding this as 16-bits number /= 10 ' shift number right by one decimal digit pub gaugeDisplay(pin,level) if pin => 16 pwm16.duty(pin, level) elseif pin => 8 pwm8.duty(pin, level) elseif pin => 0 pwm0.duty(pin, level) DAT warVals byte 0, 0, 1, 1, 0, 0, 0, 1, 0, 2, 22, 25, 19, 18, 16, 11, 10, 11, 5, 10, 11, 7, 5, 7, 7, 11, 12, 9, 8, 9, 7, 9, 9, 7, 10, 8, 9, 11, 10, 10, 11, 11, 13, 12, 15, 11, 12, 46, 30, 30, 21, 20, 16, 19, 13, 7, 10, 9, 9, 10, 12, 16, 13, 48, 67, 60, 72, 79, 61, 48, 49, 44, 47, 44, 47, 48, 47, 48, 47, 48, 51, 54, 49, 46, 51, 51, 55, 55, 76, 94, 98, 0, 0, 113, 113, 97, 90, 77, 75, 82, 75, 66, 63, 55, 51, 48, 44, 42, 40, 42, 43, 41, 35, 40, 42, 50, 53, 48, 42, 45, 40, 41, 43, 36, 36, 35, 34, 24, 31, 32, 29, 32, 31, 32, 32, 32, 33, 33, 32, 36, 44, 36, 32, 30, 33, 31, 29, 32, 37, 34, 42, 42, 55, 47, 37, 40, 37, 21
CON resolution = 2400 'The number of steps in the pulse widths. Must be an integer multiple of 4. nlongs = resolution / 4 VAR long fcb long pwmdata[noparse][[/noparse]nlongs] long pinmask long previndex[noparse][[/noparse]8] byte cogno, basepin PUB duty(pinno, value) | vindex, pindex, i, mask, unmask ' This method defines a pin's duty cycle. It's arguments are: ' ' pinno: The pin number of the PWM output to modify. ' ' value: The new duty cycle (0 = 0% to resolution = 100%) ' ' Returns true on success; false, if pinno or value is invalid. if (1 << pinno & pinmask == 0 or value < 0 or value > resolution) return false pinno -= basepin mask := $01010101 << pinno unmask := !mask vindex := value >> 2 pindex := previndex[noparse][[/noparse]pinno] if (vindex > pindex) repeat i from pindex to vindex - 1 pwmdata[i] |= mask elseif (vindex < pindex) repeat i from pindex to vindex + 1 pwmdata[i] &= unmask pwmdata[noparse][[/noparse]vindex] := pwmdata[noparse][[/noparse]vindex] & unmask | mask & ($ffffffff >> (31 - ((value & 3) << 3)) >> 1) previndex[noparse][[/noparse]pinno] := vindex return true [/i][/i]
Post Edited (timatron) : 10/15/2008 7:00:05 PM GMT
Comments
repeat i from 1850 to 2008
gaugeVal := warVals[noparse][[/noparse]1850 - i]
This makes for negative numbers inside the brackets! You probably want [noparse][[/noparse]i-1850]...
it works now, genius!
thx,
timhttp://forums.parallax.com/forums/emoticons/idea.gif
to analyze your problem I compiled your code.
First thing was an error that file "pwm_x8" was not found.
I knew that this file is from the obex so I could download it from there.
Next time you should attach your complete project to your posting that the forum-members don't have
to download additional files.
If your code works with special hardware make a version that could be easily tested WITHOUT special hardware
Then i tested your code with additional debug-informations like this
and then it was clear what is wrong
this is the Debugoutput
the calculation 1850 - i delivers negative values !
just change it to "i - 1850" and everything should work fine independend of byte word or longs in the DAT-section
This Debug-demo shows how you can analyze a lot of problems yourself
just send all kind of interesting variables with a string that explains what the value is to the terminal software
local variables of methods are always longs
and as long as you don't make things like giving a word or byte a too high value (byte-values < 256 word-values < 65536)
this should work
best regards
Stefan
i think i never really understood bytes vs words vs longs.
i've always just hacked my way through spin, im less of a developer and more of a i really want to make an art piece with this electronics, why isnt it working!!![noparse]:)[/noparse]
also, going to bed and looking at it in the morning is a good idea.
cheers,
tim
If you don't have code size issues, the simplest thing is to make everything longs.
Ray