Shop OBEX P1 Docs P2 Docs Learn Events
What am I missing here? (waitcnt stuff) — Parallax Forums

What am I missing here? (waitcnt stuff)

Hello all! I haven't been around in a while and it's been even longer since I touched any prop code, but I'm currently working on a project and need some instrumentation (tachometer). I was never particularly good at programming, but I pretty much forgot the little bit I did knew. I know this all should be simple but I'm at a loss. Anyway, here's my current situation:

I took the xTach code from the obex and am trying to modify it a little. Specifically, since I intend to use a 38khz ir demodulator I wanted to add some code to modulate an ir led at that frequency. The system clock is set for 80mhz (5mhz crystal, 16x pll), so I figured I could toggle a pin using a little waitcnt loop in its own cog (I'm not against using a counter, but I don't know how and I'm not sure it can go below 500khz). Here's the code for that:

PRI PinPulser(p)

dira[p]~~

repeat
!outa[p]
waitcnt(2105 + cnt)

Assuming my multimeter is correct, I'm getting an output of 12.02khz...? At the least, I'd expect it to be 19khz. What am I missing here? Lowering the 2105 constant to a point that would get me close to 38khz starts having issues with spin overhead. I'm okay with switching it to pasm, but I'd like to understand where I went wrong with my math (80,000,000/38,000).

Cheers,
Mark

Comments

  • Ok, I'm guessing it's the spin overhead that's causing the issue. I'll try doing it in a PASM loop instead.
  • AribaAriba Posts: 2,690
    You can easy compensate the Spin overhead by calculating the delay from the previous CNT value that you waited for:
    PRI PinPulser(p) : tm
    
     dira[p]~~
    
     tm := CNT
     repeat
       !outa[p]
       waitcnt(tm += 2105)
    
    I'm not sure if Spin is fast enough for this loop.

    But the use of a counter is really the best solution here. You only need to set it up once at begin and then the pin toggles with 38 kHz forever...
     CTRA := %00100<<26 + PIN   'NCO mode + Output Pin
     FRQA := 54 * 38000         'Freq in Hz
     DIRA[PIN] := 1
     ...
    

    Andy
  • Thanks a lot, Andy! I liked the idea of using a counter, but I wasn't sure if it was possible at that frequency. I never was able to wrap my head around them, though. Checking the output on my meters, I'm seeing a nice solid 38.224khz. Awesome! Thanks again!
  • AribaAriba Posts: 2,690
    edited 2016-08-01 22:33
    Your welcome!

    If you want exact 38.00 kHz then use the factor 53.6871 instead of 54 to calculate the FRQA value. I would do it in a calculator and transfer the result into the Spin code.
    (BTW: 53.6871 is 2^32 / 80 Million = the number of sysclock ticks for 1 Hz)

    Andy
  • markmark Posts: 252
    edited 2016-08-02 06:26
    I haven't yet tested it to see whether or not the ir receiver likes it the way it is. Currently I'm having an issue with the BST terminal locking up after connecting to the prop (running linux). It's doing this with the Propeller Serial Terminal demo code as well as xTach. I haven't found any references online to this issue. Any ideas?
  • ElectrodudeElectrodude Posts: 1,657
    edited 2016-08-02 14:16
    I gave up on the BST terminal long ago due to its lock-up problems. Just use the Parallax Serial Terminal or Minicom or something instead.
  • I got picocom "working" which had been suggested in another thread, though it doesn't look like any of the escape characters work in it. Might give Minicom a shot.
  • Try this one. Works great as a frequency counter. You can just divide or multiply the frequency variable to give your desired output.



    ' EXAMPLE 14
    '
    ' PROPELLER FREQUENCY COUNTER: External Frequency Source
    '**********************************************************************************
    'IMPORTANT: This example may require an understanding of Example: 13
    '**********************************************************************************
    'WHAT'S NEW IN THIS EXAMPLE:
    ' SPECIAL PURPOSE PROPELLER REGISTERS: CTRA, FRQA, AND PHSA. Using these
    ' registers, an incoming frequency source is sampled for one second. The
    ' result is then displayed on a Parallax LCD.
    '**********************************************************************************
    'DIFFICULTY LEVEL: Intermediate
    '**********************************************************************************
    'PURPOSE: The purpose of this example is to show how to create a frequency counter
    ' using the Propeller's special purpose registers and display a frequency
    ' count in Hz on an LCD.
    'Submitted by Dave Scanlan, April 25, 2006
    'File: Example14_FreqCtrLCD_ExternalSource.spin
    '**********************************************************************************
    'CORRECT OUTPUT: After sampling an incoming digital wave, the result will be
    ' displayed as below:
    ' 4x20 LCD Module
    ' │††††††††††††††††††††††††††│
    ' │ PROPELLER │
    ' │ FREQUENCY COUNTER │
    ' │ │
    ' │ FREQ:XXXXXXXXXXXHz │
    ' ││
    '**********************************************************************************
    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    LCD_Pin = 1 'The LCD is connected to pin A0.
    LCD_Baud = 19_200 'Baud
    LCD_Lines = 4 'The number of lines on this LCD
    In = %0
    On = 1
    Off = 0
    '
    VAR
    Long Frequency
    '
    OBJ
    LCD: "debug_lcd" 'Creates the object LCD from "debug_lcd"
    '
    PUB Start
    Repeat
    MeasureFrequency
    DisplayFrequency
    '
    PUB MeasureFrequency | Pin
    Pin := 5 'Pulses are sampled on this pin.
    DirA[Pin] := In
    CTRA := 0 'Clear CTRA settings
    CTRA := (%01010 << 26 ) | (%001 << 23) | (0 << 9) | (Pin) 'Trigger to count rising
    ' edge on Pin A5
    FRQA := 1000 'Count 1000 pulses on each trigger
    PHSA := 0 'Clear accumulated value
    WaitCNT( 80_000_000 + CNT ) 'Wait for 1 second
    Frequency := PHSA / 1000 'Calculate Freq based on the sampling
    ' duration, 1000 ms (1 second)
    PUB DisplayFrequency
    'If LCD.Start(0, 19_200, 4 )
    If LCD.init(LCD_Pin, LCD_Baud, LCD_Lines) 'Initialize the LCD object LCD.Cursor(Off) 'Set cursor off
    LCD.Backlight(True) 'Set backlight on
    LCD.Cls 'Clear the LCD screen
    LCD.Str(string(" PROPELLER ")) 'Display string on LCD
    ' LCD.Newline
    LCD.Str(string(" FREQUENCY COUNTER")) 'Display string on LCD
    LCD.Gotoxy(2,3) 'Gotoxy(Col,Row)
    LCD.Str(string("FREQ:")) 'Display string on LCD
    LCD.Gotoxy(7,3)
    LCD.DecF(Frequency, 8) 'Display Freq. as a decimal.
    LCD.Gotoxy(15,3)
    LCD.Str(string("Hz")) 'Display string on LCD
    '**********************************************************************************
    'ADDITIONAL INFORMATION:
    ' -- The code for sampling an incoming wave is an adaptation from
    ' Dr. Martin Hebel's original code in the object, BS2.Function.spin.
    ' -- The results of this counter agree closely with the readings from an HP 5314A
    ' frequency counter with deviations of 0 to 6 Hz at 2MHz.
    ' -- For this example, the amplitude was 3 volts. Until, the max input voltage,
    ' has been "firmly" established for the Propeller, I would proceed with
    ' caution. Remember, this processor is a 3.3VDC device.
    ' -- For analog signals, a pre-conditioning Schmitt trigger is suggested.
    ' Resource: http://en.wikipedia.org/wiki/Schmitt_trigger
    'FORMAT FOR: LCD.DecF(Frequency, 8)
    ' LCD.DecF(Value, Field_Width)
    ' Prints signed decimal value in fixed-width field
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2016-08-11 02:00
    DigitalBob,

    Please post your code between [ code ] [ /code ]tags (without the spaces).

    Thanks,
    -Phil

    When, oh when, will the forum mavens enable the [noparse] tag so these things can be explained properly. It's been a freaking YEAR!!!!
  • I'm sorry but I don't go on here enough to know for Phi Phi Phil is. Do you work for Parallax or do you just like commenting on punctuation. Please enlighten m
  • No, I don't work for Parallax. The [ code ] tags are just a way to display code here on the forum that preserves indentation, like this:
    PUB Start
    Repeat
      MeasureFrequency
      DisplayFrequency
    

    instead of this:

    PUB Start
    Repeat
    MeasureFrequency
    DisplayFrequency

    All the city folks use 'em! :)

    -Phil
  • TorTor Posts: 2,010
    Yep, it's not about punctuation, it's about displaying code in a readable way (extra important for Spin, where indentation matters).
  • Phil
    I don't know a darn thing about how to post code. I just cut and paste then attach a spin file. So is it the cut and paste that's look bad or are you talking about the spin attachment. And how do you guys get that yellow background.

    Bob
  • DigitalBob wrote: »
    Phil
    I don't know a darn thing about how to post code. I just cut and paste then attach a spin file. So is it the cut and paste that's look bad or are you talking about the spin attachment. And how do you guys get that yellow background.

    Bob
    Hi DigitalBob,
    press the C-Button in the input box and
    paste the code between the
    
    [ code ] [ /code ]tags.

Sign In or Register to comment.