Shop OBEX P1 Docs P2 Docs Learn Events
A question about qsin — Parallax Forums

A question about qsin

I am studding Spin2 on a Prop2

Would anyone mind breaking this down into an explanation of what is going on or point me to a documentation of qsin

I get the Level, Y and X but not the 256, 128 or shift left.

Y := (qsin(level, x++, 256 ) + 128 ) << 8

Comments

  • JonnyMacJonnyMac Posts: 9,003

    Spin2 documentation is available here:
    -- https://docs.google.com/document/d/16qVkmA6Co5fUNKJHF6pBfGfDupuRwDtf-wyieh_fbqw/

    • The third parameter in QSIN is the number of elements in the circle
    • +128 might be to lift the result from -128...127 to 0..255
    • << 8 is the same as multiplying by 256 -- this would make the output 16-bits (with the low byte always $00)

    If you have a P2, why not create a simple test program to examine the output? Do things incrementally. I started here:

      repeat x from 0 to 255
        y := qsin(255, x, 256)
        term.fstr2(@"%3d  %4d \r", x, y)
        waitms(1)
    

    From 0 to 127 the output values were positive. 128 was zero. from 128 to 255 the output values were negative. This shows that QSIN returns a signed value. At position 63 (corresponding to ~90 degrees) the output was equal to the length (first parameter).

    Sadly, Parallax hasn't had the same staff or resources to create the excellent docs we had with the P1, so it's up to us to experiment. Do share results; I'm sure others will appreciate it.

  • LMSLMS Posts: 19

    Yes indeed I do have some P2 but what is this

    term.fstr2(@"%3d %4d \r", x, y)

  • AribaAriba Posts: 2,685
    edited 2024-01-16 16:03

    Maybe this code makes it more clear:

    CON
      _clkfreq = 200_000_000
    
    PUB TestSin() | angle, sine, radius
      radius := 1000                          'sine output -1000..+1000
      repeat angle from 0 to 360 step 15      'go thru one circle 0..360 degree
        sine := qsin(radius, angle, 360)      '360 = full circle (called TwoPi in Doc: 360 degree = 2*Pi in radian)
        debug(sdec(angle),sdec(sine))         'show values  (Debug must be enabled in Run-Menu)
    

    Andy

  • LMSLMS Posts: 19

    @Ariba said:
    Maybe this code makes it more clear:

    CON
      _clkfreq = 200_000_000
    
    PUB TestSin() | angle, sine, radius
      radius := 1000                          'sine output -1000..+1000
      repeat angle from 0 to 360 step 15      'go thru one circle 0..360 degree
        sine := qsin(radius, angle, 360)      '360 = full circle (called TwoPi in Doc: 360 degree = 2*Pi in radian)
        debug(sdec(angle),sdec(sine))         'show values  (Debug must be enabled in Run-Menu)
    

    Andy

    Actually Andy that helped a load because I was losing time trying to understand serial formatting using term.fstr2 suggested by Jon, your debug line made all the difference. I should look up more of this debug command because it appears more closer to the hardware.

  • JonnyMacJonnyMac Posts: 9,003

    Indeed, DEBUG is built into the compiler. For formatted output I use my jm_fullduplexerial.spin2 which is included in the library files if you downloaded and installed Propeller Tool.

  • LMSLMS Posts: 19
    edited 2024-01-16 19:34

    Appreciate your input Jon, however, I am really against using third party libs if possible; or one never learns how to do stuff. I am more of creating working and complete snippets of code then later sticking them together in my own messy style.

    Here's the code for 8-Bit version, trying to figure now how to do a true 16-Bit version but I do not think this is really possible given the DAC registers are just 8-Bit; I do have an idea:
    `

    CON
    _clkfreq = 300_000_000
    MAX_LEN = 64
    BUF_SIZE = 32

    VAR
    long i,Radius, Angle, S1,S2,loops

    PUB Main( )

    Pinlow(8)
    Pinlow(9)
    radius :=127

    repeat loops from 0 to 10000
    repeat angle from 0 to 359 'step 15
    S1 := qsin(radius, angle, 360)
    S2 := qcos(radius, angle, 360)
    S1:=S1+128
    S2:=S2+128
    wrpin(8, p_dac_124r_3v + (S1 & $FF) <<8)
    wrpin(9, p_dac_124r_3v + (S2 & $FF) <<8)
    'debug(sdec(S1),sdec(S2),sdec(angle))
    'waitus(10)

    `
    And the result:

  • @LMS said:
    Here's the code for 8-Bit version, trying to figure now how to do a true 16-Bit version but I do not think this is really possible given the DAC registers are just 8-Bit; I do have an idea:

    The DACs themselves are 8 bit, but there's a smart mode that does dithering to get almost-16bit precision (almost because it clips at $FF00): https://p2docs.github.io/pin.html#p-dac-dither-rnd

  • LMSLMS Posts: 19

    @Wuerfel_21 said:

    @LMS said:
    Here's the code for 8-Bit version, trying to figure now how to do a true 16-Bit version but I do not think this is really possible given the DAC registers are just 8-Bit; I do have an idea:

    The DACs themselves are 8 bit, but there's a smart mode that does dithering to get almost-16bit precision (almost because it clips at $FF00): https://p2docs.github.io/pin.html#p-dac-dither-rnd

    Meaning that it would be 65536 - 255 = 65281 ?

  • Yes.

  • LMSLMS Posts: 19
    edited 2024-01-17 01:45

    I found this, on a youtube video linked at the bottom

    Its supposed to be 16bit but it does not appear to be working as it should, of course I could have made a typo.
    The output pin somehow gets activated, goes from zero to 3.3V but without steps . For testing I use a real scope on the P2 pin.

    Any ideas chaps?

    `
    CON
    _clkfreq = 300_000_000
    _pin = 8

    PUB go( ) | i

    pinstart(_pin, p_dac_124r_3v | p_oe | p_dac_dither_pwm, 256, 0)
    repeat
    wypin(_pin, $7f00 + (i & $3ff))
    waitms(20)
    i++
    `

  • AribaAriba Posts: 2,685

    This code produces a 16bit sine wave at pin 8 with about 10ms periode

    CON
      _clkfreq = 200_000_000
      DAC = 8
    
    PUB TestSin16() | angle, sine, radius
      radius := $7FFF
      pinstart(DAC, P_DAC_990R_3V + P_OE + P_DAC_DITHER_RND, 1, 0)
      repeat
        repeat angle from 0 to 3600
          sine := qsin(radius, angle, 3600)
          wypin(DAC, $7FFF + sine)
    

    Andy

    BTW: use 3 backticks before and after code, not only one

  • LMSLMS Posts: 19

    @Ariba said:
    This code produces a 16bit sine wave at pin 8 with about 10ms periode

    CON
      _clkfreq = 200_000_000
      DAC = 8
    
    PUB TestSin16() | angle, sine, radius
      radius := $7FFF
      pinstart(DAC, P_DAC_990R_3V + P_OE + P_DAC_DITHER_RND, 1, 0)
      repeat
        repeat angle from 0 to 3600
          sine := qsin(radius, angle, 3600)
          wypin(DAC, $7FFF + sine)
    

    Andy

    BTW: use 3 backticks before and after code, not only one

    Lovely Cheers, that does prove that it works and it will get me progressing.

    Re: the Backticks, I always selected them from the dropdown, its a bug on the website ?.

  • AribaAriba Posts: 2,685

    If you do it with the dropdown, you need to select the whole code first.
    One Backtick is inserted if you select a part of a single line.

Sign In or Register to comment.