Shop OBEX P1 Docs P2 Docs Learn Events
SPIN CODE EXAMPLES FOR THE BEGINNER (Public Version) — Parallax Forums

SPIN CODE EXAMPLES FOR THE BEGINNER (Public Version)

Dave ScanlanDave Scanlan Posts: 160
edited 2008-10-06 01:32 in Propeller 1
SPIN CODE EXAMPLES

IMPORTANT: The examples on this thread are for educational purposes only.·

PLEASE POST EXAMPLES OF SPIN CODE ON THIS THREAD THAT MEET THE FOLLOWING CRITERIA:
· 1. Can be used to learn Spin code
· 2. Have the necessary documentation
· 3.·Have been tested

THE DIFFICULTY LEVEL OF THESE EXAMPLES IS SET WITH THE FOLLOWING IN MIND:
(1) The user has no Propeller with which to execute the code
(2) The user has no documentation

·
DOCUMENTATION:
·· 1.·To view all examples, go into this thread.
·· 2. PDF File·of·many examples on this thread (See file attachment.)
······
(File compiled by Charlie Johnson, updated May 15, 2006)
DOWNLOAD CODE:
·· 1. ZIP FILE OF 16 EXAMPLES (See file attachment.)
······ (File compiled by Brain Riley)



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··

Post Edited (Dave Scanlan) : 6/2/2006 8:02:29 AM GMT
«1345678

Comments

  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-04 14:04
    EXAMPLE 01

    ONE LED BLINKS FIVE TIMES·
    '                                           EXAMPLE01
    '
    '                                      ONE LED BLINKS FIVE TIMES
    '*************************************************************************************************
    'IMPORTANT:  Please run this code and attempt to understand it before advancing to
    '            Example02, Example03, etc.  In the future, examples will be added and each will
    '            gradually increase in complexity and/or cover a different concept.
    '*************************************************************************************************
    '                                     
    'DIFFICULTY LEVEL: Very easy
    '
    'PURPOSE:
    '  -- The purpose of this example is to demonstrate an extremely simple program that almost anyone
    '     will be able to understand. This is a "Hello World" type of program.
    '  -- Future examples will become increasingly more complex.
    '  -- This program shows how to turn on and off a single LED at port A16 every second.  This
    '     on-off sequence will be repeated five times.
    '  -- Also, this program explains one way to use WaitCnt to pause program execution.
    '  -- Future examples will build on each other; therefore, less internal documentation will be
    '     needed.
    '  -- Only one of the eight processors is used in this example.
    '  -- IT IS ASSUMED THAT THE PROGRAMMER HAS OR IS READING THE PROPELLER'S EXTERNAL DOCUMENTATION
    '     AND HAS SOME PREVIOUS PROGRAMMING EXPERIENCE WITH MICROCONTROLLERS. IT IS FURTHER
    '     ASSUMED THAT ONE LED IS CORRECTLY CONNECTED TO PORT A16.  IF YOU HAVE THE DEVELOPMENT
    '     KIT, THE CONNECTION WILL NOT BE A PROBLEM.
    '  -- Every effort has been made to insure that the code in this and future examples
    '     runs correctly.
    'Submitted by Dave Scanlan, Feb 27, 2006
    'File: Example01_BlinkingOneLED.spin       
    '*************************************************************************************************
    'CORRECT OUTPUT: The LED at port A16 will blink every second, five times.
    '*************************************************************************************************
    '
    '
    CON
    'Set clock speed to 80 MHz
      _clkmode = xtal1 + pll16x        'Sets the clock speed to 80 MHz using a times 16 multiplier
      _xinfreq = 5_000_000             'Crystal speed: 5 MHz
    ' 
      High = 1                         'A CONstant used to set an output port to about 3 volts
      Low  = 0                         'A CONstant used to set an output port to about 0 volts
      Out = %1                         'A CONstant used to set a port's direction to Out
    ' 
    VAR
      Byte Pin                         'Declares Pin to be a global VARiable of a type Byte
    ' 
    PUB Start                          'A PUBlick procedure named Start                                                             
      BlinkingLED                      'Calls the PRIvate procedure BlinkingLED
    '                                                                                                                               
    PRI BlinkingLED                    'A PRIvate procedure named BlinkingLED
      Pin := 16                        'Assigns 16 to the variable Pin                                      
      DirA[noparse][[/noparse]Pin] := Out                 'Makes port A16 an output port
      Repeat 5                         'Repeats the code indented under it 5 times
        'TURN THE LED ON AND OFF
        ' -- The LED, at port A16, is on for 1/2 second and off for 1/2 second.
        ' -- The System Counter increments by one for every System Clock pulse. Thus, if the
        '    System Clock is running at 80MHz, the System Counter will increment 80 million times
        '    in one second; and every counter increment will take 12.5ns (1/80MHz).
        '    Each WaitCnt statement below is set to cause a 1/2 second wait:
        '    40_000_000 counter increments * 12.5ns = 500ms (1/2 second)
    ' 
             OutA[noparse][[/noparse]Pin] := High         'LED ON                                      
             WaitCnt(40_000_000 + Cnt) 'ONE-HALF SECOND WAIT
             OutA[noparse][[/noparse]Pin] := Low          'LED OFF
             WaitCnt(40_000_000 + Cnt) 'ONE-HALF SECOND WAIT
    '
    'INDENTION IS IMPORTANT IN SPIN: There are no ENDIFs, END REPEATs, END SUBs, NEXTs, etc.
    

    FEWER COMMENTS (EASIER TO READ)
    EXAMPLE 01
    '                               FEWER COMMENTS (EASIER TO READ)
    '                                         EXAMPLE01
    '
    '                                   ONE LED BLINKS FIVE TIMES
    '**************************************************************************************
    'IMPORTANT:  Please run this code and attempt to understand it before advancing to
    '            Example02, Example03, etc.  
    '**************************************************************************************
    'DIFFICULTY LEVEL: Very easy
    '
    'Submitted by Dave Scanlan, March 15, 2006
    'File: FewerComments.spin                  
    '**************************************************************************************
    'CORRECT OUTPUT: The LED at port A16 will blink every second, five times.
    '**************************************************************************************
    '
    CON
      _clkmode = xtal1 + pll16x      
      _xinfreq = 5_000_000             
      High = 1                         
      Low  = 0                         
      Out = %1                         
    ' 
    VAR
      Byte Pin                         
    ' 
    PUB Start                                                                                                                       
      BlinkingLED                      
    '                                                                                                                               
    PRI BlinkingLED                    
      Pin := 16                                                                                             
      DirA[noparse][[/noparse]Pin] := Out                 
      Repeat 5                         
        OutA[noparse][[/noparse]Pin] := High         'LED ON                                           
        WaitCnt(40_000_000 + Cnt) 'ONE-HALF SECOND WAIT
        OutA[noparse][[/noparse]Pin] := Low          'LED OFF
        WaitCnt(40_000_000 + Cnt) 'ONE-HALF SECOND WAIT
    '
    'INDENTION IS IMPORTANT IN SPIN: There are no ENDIFs, END REPEATs, END SUB, etc.
    


    Post Edited (Dave Scanlan) : 3/15/2006 2:23:03 PM GMT
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-04 14:18
    ·EXAMPLE 02

    ·HOW TO DECLARE A LOCAL VARIABLE AND CALL MORE THAN ONE PROCEDURE

    '                                        EXAMPLE02
    '
    '                HOW TO DECLARE A LOCAL VARIABLE AND CALL MORE THAN ONE PROCEDURE.
    '*************************************************************************************************
    'IMPORTANT: Please run or examine closely previous examples before running this code. If you do
    '           this, you are more likely to understand this example.
    '************************************************************************************************* 
    'WHAT'S NEW IN THIS EXAMPLE:
    '
    '   LOCAL VARIABLES: This example demonstrates how to declare a local variable. A local variable
    '                    is only known within the procedure in which it is declared.  Also, it is
    '                    is only active while the code in that procedure is being run. 
    '   TWO PROCEDURES:  This example demonstrates calling more than one procedure.
    '*************************************************************************************************
    '
    'DIFFICULTY LEVEL: Very easy
    '
    'PURPOSE:
    '  -- The purpose of this example is to demonstrates how to declare a local variable
    '     within a procedure, and to demonstrate how to call two procedures. One procedure, when
    '     called, will cause the LED at port A16 to blink five times. This will be followed by a call
    '     to a second procedure that will cause the LED at port A17 to blink five times.
    '
    '  -- Note that one sequence of five blinks is followed in time by another sequence of five blinks.
    '     This sequential behavior occurs because only one processor is executing the code. In the next
    '     example, EXAMPLE03, both sequences of blinks will occur at the SAME TIME because we will use
    '     two processors.  One processor will handle one sequence of five blinks and at the same
    '     time a second processor will handle a second sequence of five blinks.
    '
    'ADDITIONAL INFORMATION: 
    '  -- The comments in the code are typically used to explain new statements or new concepts not
    '     explained in previous examples.  In order to eliminate comment clutter, the code comments
    '     in previous examples have usually been eliminated.
    '  -- IT IS ASSUMED THAT THE PROGRAMMER HAS OR IS READING THE PROPELLER'S EXTERNAL DOCUMENTATION
    '     AND HAS SOME PREVIOUS PROGRAMMING EXPERIENCE WITH MICROCONTROLLERS. IT IS FURTHER
    '     ASSUMED THAT TWO LEDS ARE CONNECTED TO PORTS A16 AND A17.
    '  -- Every effort has been made to insure that the code in all examples runs correctly.
    '
    'Submitted by Dave Scanlan, March 4, 2006           
    'File: Example02_LocalVarAndCallingTwoProcedures.spin
    '*************************************************************************************************
    'CORRECT OUTPUT: The LED at port A16 will blink five times.  This sequence of blinks will be
    '                followed by the LED at port A17 blinking five times.
    '
    '                NOTE: The output from this example will be compared to the output in the next
    '                      example where two processors will be running.
    '*************************************************************************************************
    CON
      _clkmode  = xtal1 + pll16x
      _xinfreq  = 5_000_000
    ' 
      High = 1
      Low  = 0
      Out = %1
    '
    VAR
      'No global variables needed
    ' 
    PUB Start
      BlinkingLED_A16                   'This call is executed first.
      BlinkingLED_A17                   'This call is executed next but only after       
                                        '   BlinkingLED_A16 has finished executing.    
    '
    PRI BlinkingLED_A16 | Pin           '| Pin is declared as a local variable
                                        '  Pin is only known within BlinkingLED_A16                                          
      Pin := 16                         '  Reference to Pin stops when this procedure ends.                 
      DirA[noparse][[/noparse]Pin] := Out
    '                
      Repeat 5
       OutA[noparse][[/noparse]Pin] := High                'LED ON                               
       WaitCnt(40_000_000 + Cnt)        'ONE-HALF SECOND WAIT
       OutA[noparse][[/noparse]Pin] := Low                 'LED OFF
       WaitCnt(40_000_000 + Cnt)        'ONE-HALF SECOND WAIT
    '
    '
    PRI BlinkingLED_A17 | Pin           '| Pin is declared as a local variable
                                        '  Pin is only known within BlinkingLED_A17.                                          
      Pin := 17                         '  Reference to Pin stops when this procedure ends.                 
      DirA[noparse][[/noparse]Pin] := Out
    '                
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High               'LED ON                               
        WaitCnt(40_000_000 + Cnt)       'ONE-HALF SECOND WAIT
        OutA[noparse][[/noparse]Pin] := Low                'LED OFF
        WaitCnt(40_000_000 + Cnt)       'ONE-HALF SECOND WAIT
    '
    'INDENTION IS IMPORTANT IN SPIN.
    

    FEWER COMMENTS (EASIER TO READ)
    EXAMPLE 02
    '                            FEWER COMMENTS (EASIER TO READ)
    '
    '                                       EXAMPLE02
    '
    '           HOW TO DECLARE A LOCAL VARIABLE AND CALL MORE THAN ONE PROCEDURE.
    '*************************************************************************************
    'IMPORTANT: Please run or examine closely previous examples before running this code. 
    '           If you do this, you are more likely to understand this example.
    '*************************************************************************************             
    'DIFFICULTY LEVEL: Very easy
    '************************************************************************************* 
    'CORRECT OUTPUT: The LED at port A16 will blink five times.  This sequence of blinks 
    '                will be followed by the LED at port A17 blinking five times.
    '
    '                NOTE: The output from this example will be compared to the output 
    '                      in the next example where two processors will be running.
    'Submitted by Dave Scanlan, March 15, 2006         
    'File: Example02_FewerComments.spin
    '************************************************************************************* 
    CON
      _clkmode  = xtal1 + pll16x
      _xinfreq  = 5_000_000
      High = 1
      Low  = 0
      Out = %1
    '
    VAR
      'No global variables needed
    PUB Start
      BlinkingLED_A16                   
      BlinkingLED_A17                                                                    
    '
    PRI BlinkingLED_A16 | Pin           
      Pin := 16                                                                                             
      DirA[noparse][[/noparse]Pin] := Out
      Repeat 5
       OutA[noparse][[/noparse]Pin] := High                'LED ON                               
       WaitCnt(40_000_000 + Cnt)        'ONE-HALF SECOND WAIT
       OutA[noparse][[/noparse]Pin] := Low                 'LED OFF
       WaitCnt(40_000_000 + Cnt)        'ONE-HALF SECOND WAIT
    '
    '
    PRI BlinkingLED_A17 | Pin           
      Pin := 17                                                                                             
      DirA[noparse][[/noparse]Pin] := Out
       Repeat 5
        OutA[noparse][[/noparse]Pin] := High               'LED ON                               
        WaitCnt(40_000_000 + Cnt)       'ONE-HALF SECOND WAIT
        OutA[noparse][[/noparse]Pin] := Low                'LED OFF
        WaitCnt(40_000_000 + Cnt)       'ONE-HALF SECOND WAIT
    '
    'INDENTION IS IMPORTANT IN SPIN.
    



    Post Edited (Dave Scanlan) : 3/19/2006 3:18:51 AM GMT
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-03-04 14:22
    Dave,

    thanks a lot for sharing your code samples with the public. I think this and any following samples will help people interested in the Propeller and the Spin language to better understand this really powerful system.

    Please let me add one word of caution to users who want to down-load Spin code examples:

    Spin code is indentation-sensitive, i.e. instructions that shall belong to a block must be indented, like the four non-comment lines following the Repeat 5 in Dave's first example. When you highlight and copy Spin code from the screen, indentation might get lost, or messed up when you paste this text into the Propeller IDE, or any other text editor. Therefore, you better use the file attachment to download the source code into a local directory on your computer.

    This also means that all others publishing Spin sample code should always attach a copy of the original spin file to their posts.

    I'm pretty sure, this will help avoiding a lot of confusion. (See the other "Spin Code Formatting" thread that has grown pretty long in the meantime. Instead of "fooling around" with IE, Firefox, Opera, etc. simply make use of file attachments smile.gif ).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-04 14:24
    EXAMPLE 03

    USING TWO COGS (TWO PROCESSORS)

    '                                           EXAMPLE03
    '
    '                               USING TWO COGS (TWO PROCESSORS)                               
    '*************************************************************************************************
    'IMPORTANT: This example requires an understanding of examples 01 and 02.
    '*************************************************************************************************
    'WHAT'S NEW IN THIS EXAMPLE:
    '
    '   COG: This is the term used by the designers (Parallax, Inc.) of the Propeller. It refers 
    '        to a processor in the Propeller chip. This chip has eight Cogs, or processors.
    '*************************************************************************************************
    '
    'DIFFICULTY LEVEL: Easy
    '
    'PURPOSE:
    '  -- The purpose of this example is to demonstrate the use of two Cogs (two processors)
    '     running separate procedures in PARALLEL.
    '
    'ADDITIONAL INFORMATION: 
    '  -- The two procedures in this example have the same function as in Example 02; that is, the
    '     procedures turn on and off an LED every second. However, in this example the procedures
    '     run in PARALLEL because each is run by a different processor; consequently, the
    '     two LEDs will blink in sync. In Example 02, the two procedures were run sequentially
    '     using one processor.
    '
    'Submitted by Dave Scanlan, March 4, 2006          
    'File: Example03_UsingTwoCogs.spin
    '*************************************************************************************************
    'CORRECT OUTPUT: The LEDs at A16 and A17 should blink on and off every second. Both should
    '                blink on and off at the same time. 
    '*************************************************************************************************
    CON
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    ' 
      High = 1
      Low  = 0
    '
    VAR
      long  stack0[noparse][[/noparse]20]                   'Sets up a stack space for a Cog(processor)
      long  stack1[noparse][[/noparse]20]                   'Sets up a stack space for a second Cog(processor)
                                         'long stack0[noparse][[/noparse]20]: Allocates 20 longs for the stack.
                                         'long stack1[noparse][[/noparse]20]: Allocates 20 longs for the stack.     
    PUB Start
      cognew(BlinkingLED_A16, @stack0)   'Starts a Cog, calls BlinkingLED_A16, the Cog uses @stack0
      cognew(BlinkingLED_A17, @stack1)   'Starts a Cog, calls BlinkingLED_A17, the Cog uses @stack1
    '
    PRI BlinkingLED_A16 | Pin              
      Pin := 16
      DirA[noparse][[/noparse]Pin] := %1
    '                 
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(40_000_000 + Cnt)          
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(40_000_000 + Cnt)          
    '
    PRI BlinkingLED_A17 | Pin              
      Pin := 17
      DirA[noparse][[/noparse]Pin] := %1
    '                 
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(40_000_000 + Cnt)          
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(40_000_000 + Cnt)
    '
    'INDENTION IS IMPORTANT IN SPIN CODE
    


    FEWER COMMENTS (EASIER TO READ)
    EXAMPLE 03
    '                          FEWER COMMENTS (EASIER TO READ)
    '
    '                                    EXAMPLE03
    '
    '                          USING TWO COGS (TWO PROCESSORS)                                    
    '*****************************************************************************
    'IMPORTANT: This example requires an understanding of examples 01 and 02.
    '***************************************************************************** 
    'DIFFICULTY LEVEL: Easy
    '*****************************************************************************
    'CORRECT OUTPUT: The LEDs at A16 and A17 should blink on and off every second. 
    '                Both should blink on and off at the same time.
    'Submitted by Dave Scanlan, March 15, 2006         
    'File: Example03_FewerComments.spin
    '***************************************************************************** 
    CON
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
      High = 1
      Low  = 0
    '
    VAR
      long  stack0[noparse][[/noparse]20]                   
      long  stack1[noparse][[/noparse]20]                   
    '                                                                                             
    PUB Start
      cognew(BlinkingLED_A16, @stack0)   
      cognew(BlinkingLED_A17, @stack1)   
    '
    PRI BlinkingLED_A16 | Pin              
      Pin := 16
      DirA[noparse][[/noparse]Pin] := %1
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(40_000_000 + Cnt)          
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(40_000_000 + Cnt)          
    '
    PRI BlinkingLED_A17 | Pin              
      Pin := 17
      DirA[noparse][[/noparse]Pin] := %1
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(40_000_000 + Cnt)          
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(40_000_000 + Cnt)
    'INDENTION IS IMPORTANT IN SPIN CODE
    

    Post Edited (Dave Scanlan) : 3/19/2006 3:19:20 AM GMT
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-04 14:28
    Hi G
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-04 23:30
    EXAMPLE 04

    DISPLAYS TEXT ON A VIDEO MONITOR

    '                                           EXAMPLE04
    '
    '                               DISPLAYS TEXT ON A VIDEO MONITOR                              
    '*************************************************************************************************
    'IMPORTANT: This example requires an understanding of examples 01, 02, and 03.
    '*************************************************************************************************
    'WHAT'S NEW IN THIS EXAMPLE:
    '
    '   TV_Terminal: This is an object that generates the signals necessary to drive a video monitor.
    '
    '   VideoDisplay: An instance of the object TV_Terminal.
    '
    '   Repeat Count From 1 To 5: This is a loop that will increment the variable, Count, from 1 to 5.
    '                             The code under it is repeated five times.
    '*************************************************************************************************
    'DIFFICULTY LEVEL: Easy
    '
    'PURPOSE:
    '  -- Demonstrates how to send text to a video monitor, and how to set the foreground and
    '     background colors of a video monitor to white-on-blue.
    '
    'ADDITIONAL INFORMATION: 
    '  -- The video signal output is a composite signal.
    '  -- TV_Terminal is an object call TV_Terminal.spin found in the "Propeller Tool" subdirectory.
    '  -- Any name could have been used instead of "VideoDisplay"
    '  -- This examples requires an elementary knowledge of OOP.
    '  -- This example assumes you have the development kit or a schematic of it.  
    '     You will need one of these to generate a composite video out.
    ' 
    'Submitted by Dave Scanlan, March 3, 2006          
    'File: Example04_VideoOutput.spin
    '**************************************************************************************************
    'CORRECT OUTPUT: A text string and an incrementing decimal number will be displayed five times.
    '**************************************************************************************************
    '
    CON
      _clkmode = xtal1 + pll16x       
      _xinfreq = 5_000_000
      NewLine = 13
      ClearScreen = 0
     ' 
    OBJ
      VideoDisplay: "TV_Terminal"                   'Creates the object VideoDisplay
    '
    PUB Start
    '
      DisplayTextOnMonitor
    '
    PRI DisplayTextOnMonitor | Count
      VideoDisplay.start(12)                        'Initializes the VideoDisplay object
      SetScreenWhiteOnDarkBlue                      'Calls a procedure that sets the foreground
                                                    '  color to white and the background color
                                                    '  to dark blue.
    '
      Repeat Count From 1 To 5                      'For every loop, Count increments by one.
        WaitCnt(40_000_000 + Cnt) 
        VideoDisplay.str(string("THE COUNT IS: "))  'Sends a text string to the video monitor.
        VideoDisplay.dec(Count)                     'Sends a numeric value to a video monitor.
        VideoDisplay.out(NewLine)                   'Sends a NewLine to a video monitor.
        WaitCnt(40_000_000 + Cnt)
      VideoDisplay.out(ClearScreen)                 'Clear screen.
    ' 
    PRI SetScreenWhiteOnDarkBlue                    'Sets the foreground color to white and the
      VideoDisplay.out(3)                           '  background color to dark blue on the monitor.
      VideoDisplay.out(5)
    '
    'INDENTION IS IMPORTANT IN SPIN:  Spin does not use Ends in its blocks of code.   For
    '                                 example, there is no End Repeat after the Repeat loop and
    '                                 you must indent after CON, OBJ, PUB, PRI, and DAT.
    '
    'Be sure to use the latest version of Tv_Terminal
    

    EXAMPLE 04

    FEWER COMMENTS (EASIER TO READ)
    '                          FEWER COMMENTS (EASIER TO READ)
    '
    '                                    EXAMPLE04
    '
    '                          DISPLAYS TEXT ON A VIDEO MONITOR                                  
    '*****************************************************************************
    'IMPORTANT: This example requires an understanding of examples 01, 02, and 03.                     
    '***************************************************************************** 
    'DIFFICULTY LEVEL: Easy
    '*****************************************************************************  
    'CORRECT OUTPUT: A text string and an incrementing decimal number will
    '                be displayed five times.
    'Submitted by Dave Scanlan, March 15, 2006         
    'File: Example04_VideoOutput.spin
    '***************************************************************************** 
    '
    CON
      _clkmode = xtal1 + pll16x       
      _xinfreq = 5_000_000
      NewLine = 13
      ClearScreen = 0
     ' 
    OBJ
      VideoDisplay: "TV_Terminal"                   
    '
    PUB Start(12)
      DisplayTextOnMonitor
    '
    PRI DisplayTextOnMonitor | Count
      VideoDisplay.start                            
      SetScreenToWhiteOnDarkBlue
    '                   
      Repeat Count From 1 To 5                      
        WaitCnt(40_000_000 + Cnt) 
        VideoDisplay.str(string("THE COUNT IS: "))  
        VideoDisplay.dec(Count)                     
        VideoDisplay.out(NewLine)                   
        WaitCnt(40_000_000 + Cnt)
    '   
      VideoDisplay.out(ClearScreen)                 
    ' 
    PRI SetScreenToWhiteOnDarkBlue                  
      VideoDisplay.out(3)                           
      VideoDisplay.out(5)
    '
    'INDENTION IS IMPORTANT IN SPIN
    'Be sure to use the latest version of Tv_Terminal
    


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ··

    Post Edited (Dave Scanlan) : 6/19/2006 4:32:50 PM GMT
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2019-01-24 20:29
    The attached two programs use an green LED to make a light meter. The LED is hooked up on the prototyping area of the Propeller demo board, with the anode (long wire) to pin a1 and the cathode (short wire) through a 330 ohm resistor to pin a0. A 220 pf capacitor is in parallel with the LED. the diagram shows what the circuit should look like. The Propeller IDE comes with its own font (the Parallax font) that includes schematic symbols that you can include in the documentation of a program. You can't see the font on your screen until you have the font installed, but the diagram is a GIF created from a screen capture (printScreen key), cropped in Paint.

    Screen%20Shot%202019-01-23%20at%2012.48.27%20PM.png
    The LED is hooked up between two pins so that it can be both forward biased to make it light up, and then reverse biased so that it can be used as a photodiode to measure ambient light levels. In the second mode, the 220 pf capacitor is charged up to 5 volts reverse bias across the LED, and the program measures how long it takes for the capacitor to discharge down to 1.65 volts (like RCTIME on the Stamp). The Propeller runs on 3.3 volts, and its input switching threshold is 1/2 of that, close to 1.65 volts.

    The first program illustrates how to make Propeller pin an input, and the rate of flashing of the LED is proportional to the ambient light level. The program also shows a couple of different ways to sample the input: 1) using a program REPEAT loop, 2) using the WAITPEQ command (wait for pin equal...), and 3) using the WAITPNE command (wait for pin not equal ...).

    The second program builds on that to turn the 8 leds on the demo board into a display like a VU meter, to show the ratiometric light level. The Propeller language has some pretty amazing math operators built in. The following is the condensed version of the code. Please see the listing for the documentation dcomponent. The Propeller IDE gives you several different views of your program documentation easier.

    CON
       ledn = 0       ' LED cathode (negative, n-type semiconductor) attached to this pin
       ledp = 1       ' LED anode (positive, p-type semiconductor) attached to this pin
    
    'This program leaves the clock at the default ~12 mHz RC clock source.
    
    VAR
      long ticker, ticker0
      word ratio
      
    PUB light_meter              ' make a light meter from an LED
       blipLED                    
       readLED
       ticker0 := ticker         ' initial value, defines our maximum light level.
       repeat                    ' repeat the following indented statements forever.
          blipLED
          readLED
          logTicker               ' Display the bar graph
            
    
    PRI blipLED                   ' briefly flash the LED
      outa[noparse][[/noparse]ledp] := 1             ' see lightMeter1 for comments                         
      dira[noparse][[/noparse]ledp] := 1
      outa[noparse][[/noparse]ledn] := 0          
      dira[noparse][[/noparse]ledn] := 1
      waitcnt(240000 + cnt)    
       
    PRI readLED                  ' read the time it takes for photocurrent to charge capacitor
      outa[noparse][[/noparse]ledp] := 0            ' see lightMeter1 for comments
      dira[noparse][[/noparse]ledp] := 1            
      outa[noparse][[/noparse]ledn] := 1
      dira[noparse][[/noparse]ledn] := 1
      waitcnt(2400 + cnt)        
      ticker := 0                ' going to measure time ticks using this variable
      dira[noparse][[/noparse]ledn] := 0            
      repeat until ina[noparse][[/noparse]ledn] == 0       
        ++ticker                 ' every time around the loop, ticker increases by 1
                                 ' so it measures the time until ina[noparse][[/noparse]ledn] goes low
                                 ' ticker is a small number in bright light.
                                 
    
    PRI logTicker                  ' to display the result time as logarithmic (VU) bar graph
      dira := dira | $00ff0000     ' the yellow leds on demo booard are on a16-a23
      ratio := ticker0 * 8 / ticker   ' ratio = 8 when current light level = initial light level
                                   ' this ratio can range from 0 in dim light
                                   ' (when ticker is a large number, > ticker0 * 8)
                                   ' to a large number in bright light (ticker =1)
      outa := (|< >| ratio -1) << 16      ' makes the output VU bar graph on a16--a23
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com

    Post Edited (Tracy Allen) : 3/5/2006 2:16:00 AM GMT
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-03-05 03:54
    Ah so thats what you were working on at the seminar, I wondered why you kept slowly tapping that green LED. I saw your discussion on the forums, but I didn't piece the two together until now [noparse]:)[/noparse].

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·1+1=10
  • FORDFORD Posts: 221
    edited 2006-03-05 04:39
    This is the most informative thread so far on this forum,

    I can see that SPIN is going to be·great (and looks fairly simple)·to learn once we get the official documentation.

    thanks for the posts above, keeping it simple is good at this stage.

    Cheers,
    Chris - West Oz
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-05 05:06
    Chris,

    Thanks for the support.

    When you get the docs and stuff, I hope you will add to this thread.

    Dave

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔





    ··
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-05 06:16
    · Coded by Beau Schwabe (Parallax).
    ··········································
    ·Note: Posted with permission by Dave Scanlan
    ········· Follow his directions carefully.· Great demo.
    ''********************************************************************************
    ''** Fun example uses the LED's on the demo board to display a bitmap           **
    ''** pattern stored in a data table                                             **
    ''********************************************************************************
    '' Coded by Beau Schwabe (Parallax).                                            **
    ''********************************************************************************
    ''
    ''                    Directions:
    ''                    Load the program. LED's will appear to ALL be on.
    ''                    Rapidly move the demo board back-n-forth.
    ''                    (unplug USB2SER connector first-grin
    ''            
    ''
    '' Other options to this program would be to use an accelerometer
    '' to determine which direction/speed you are moving, and display
    '' an actual message forward or backward accordingly.
      _xinfreq      = 5_000_000          'Set crystal frequency to 5 MHz
      _clkmode      = xtal1 + pll16x     'wind it up to 80 MHz via a X16 PLL
     
    CON
      Rate = 50_000                      'Set motion rate.
     
    VAR
     
    PUB Message | scan
      dira[noparse][[/noparse]16..23] := %11111111          'Make I/O's 16 to 23 OUTPUTs
      
      repeat                             'Enter Endless Loop
        repeat scan from 0 to 26         'Create an offset index from 0 to 26
         outa[noparse][[/noparse]16..23] := Propeller[noparse][[/noparse]scan] 'Lookup byte value in data table at offset 'scan'
         waitcnt(Rate + cnt)             'pause so we can see something
     
    DAT
    Propeller     byte %00000000
                  byte %00010000
                  byte %00111000
                  byte %01111100
                  byte %11111110
                  byte %01111100
                  byte %00111000
                  byte %00010000
                  byte %00000000
     
                  byte %00000000
                  byte %11111111
                  byte %10000001
                  byte %10000001
                  byte %10000001
                  byte %11111111
                  byte %00000000
     
                  byte %00000000
                  byte %10000000
                  byte %01000000
                  byte %00110000
                  byte %00011000
                  byte %00000111
                  byte %00011000
                  byte %00110000
                  byte %01000000
                  byte %10000000
                  byte %00000000
    
  • kjennejohnkjennejohn Posts: 171
    edited 2006-03-05 07:02
    Can this thread be "pinned" for reference?

    kenjj
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-05 16:33
    EXAMPLE 05

    USING TWO COGS (PROCESSORS) WITH ARGUMENTS AND PARAMETERS

    '                                           EXAMPLE 05
    '
    '                       USING TWO COGS(PROCESSORS) WITH ARGUMENTS AND PARAMETERS              
    '*************************************************************************************************
    'IMPORTANT: This example may require an understanding of examples 01, 02, 03, AND 04
    '*************************************************************************************************
    'WHAT'S NEW IN THIS EXAMPLE:
    '
    '   ARGUMENTS/PARAMETERS:  Arguments pass values to their corresponding Parameters.
    '                          Note: Some programmers use the word "parameter" to refer
    '                                to both the argument and its corresponding parameter.
    '                                This programmer does not.  Having seperate names makes
    '                                it easier to refer to them in the documentation.
    '*************************************************************************************************
    '
    'DIFFICULTY LEVEL: Easy
    '
    'PURPOSE:
    '  -- The purpose of this example is to demonstrate the use of Arguments and Parameters when
    '     two Cogs(processors) are running in parallel.
    '
    'ADDITIONAL INFORMATION:
    '  -- Two procedures run in parallel as they did in EXAMPLE 03. This time, however,
    '     the WaitCnt time is set by passing two different values to the two procedures by using
    '     arguments and parameters.
    '
    '     The Argument (WaitPeriod_Arg) passes 8_000_000 to its corresponding parameter
    '     (WaitPeriod_Par) in one procedure, and 80_000_000 in the other procedure.
    '     The result of this is that one LED will blink on and off every 0.2 seconds and
    '     the other every 2.0 seconds.
    '
    'Submitted by Dave Scanlan, March 5, 2006          
    'File: Example05_TwoCogsArgParGlobalVar.spin
    '*************************************************************************************************
    'CORRECT OUTPUT: The LED at A16 will blink on and off every 0.2 seconds and the LED at A17 will
    '                blink on and off every 2.0 seconds.  The blinking will occur in parallel, but
    '                the LED at A16 will finish ten times faster. Both LEDs will blink five times.   
    '*************************************************************************************************
    CON
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    ' 
      High = 1
      Low  = 0
    '
    VAR
      Long Stack0[noparse][[/noparse]20]                           'Sets up a stack space for a Cog(processor)
      Long Stack1[noparse][[/noparse]20]                           'Sets up a stack space for a second Cog(processor)
                                                'long Stack0[noparse][[/noparse]20]: Allocates 20 longs for the stack.
                                                'long Stack1[noparse][[/noparse]20]: Allocates 20 longs for the stack.
    '                                    
      Long WaitPeriod_Arg                       'Arg in WaitPeriod_Arg stands for Argument.
                                                'Sets the rate at which the LED blinks.
    ' 
    '
    PUB Start
    '
      WaitPeriod_Arg := 8_000_000               '0.1 second wait period
    ' 
     'Starts a New Cog(Calls BlinkingLED_A16 (WaitPeriod Argument),This Cog uses @stack0)             
      CogNew(BlinkingLED_A16 (WaitPeriod_Arg), @Stack0)
      
      WaitPeriod_Arg := 80_000_000              '1.0 second wait period
      
     'Starts a New Cog(Calls BlinkingLED_A17 (WaitPeriod Argument), This Cog uses @stack1)
      CogNew(BlinkingLED_A17 (WaitPeriod_Arg), @Stack1)
    '
    '
    'LED Blinks Fast
    PRI BlinkingLED_A16 (WaitPeriod_Par) | Pin  'Par in WaitPeriod_Par stands for Parameter.
      Pin := 16
      DirA[noparse][[/noparse]Pin] := %1
    '
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(WaitPeriod_Par + Cnt)            '0.1 second wait period 
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(WaitPeriod_Par + Cnt)            '0.1 second wait period
    '
    '
    'LED Blinks Slowly
    PRI BlinkingLED_A17 (WaitPeriod_Par)| Pin    'Par in WaitPeriod_Par stands for Parameter.            
      Pin := 17
      DirA[noparse][[/noparse]Pin] := %1
    '                 
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(WaitPeriod_Par + Cnt)            '1.0 second wait period  
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(WaitPeriod_Par + Cnt)            '1.0 second wait period
     
       
    'INDENTION IS IMPORTANT IN SPIN CODE.
    'FOR THE ADVANCED LEARNER:
    '  -- Arguments and Parameters are used to help eliminate tightly coupled code. In other words,
    '     procedures of code can pass values to each other without using global variables.
    '     The use of global variables to pass values between procedures is call Common Coupling,
    '     and this we try to avoid. (Use Google Search Words: Common Coupling Structured Design)
    '     Because the Argument (WaitPeriod_Arg) was declared as a global variable, two
    '     different names were required for an argument and its corresponding parameter. More
    '     on this in EXAMPLE 06.)
    '  -- In order to keep this example simple, a global variable is used; but in EXAMPLE 06
    '     we will show you how to eliminate this global variable by  using local variables
    '     instead.
    '  -- In Spin, Arguments pass values to their corresponding Parameters "by value".
    


    EXAMPLE 05
    FEWER COMMENTS (EASIER TO READ)
    '                                 FEWER COMMENTS (EASIER TO READ)
    '
    '                                           EXAMPLE 05
    '
    '                       USING TWO COGS (PROCESSORS) WITH ARGUMENTS AND PARAMETERS             
    '*************************************************************************************************
    'CORRECT OUTPUT: The LED at A16 will blink on and off every 0.2 seconds and the LED at A17 will
    '                blink on and off every 2.0 seconds.  The blinking will occur in parallel, but
    '                the LED at A16 will finish ten times faster. Both LEDs will blink five times.
    'Submitted by Dave Scanlan, March 5, 2006          
    'File: Example05_FewerComments.spin
    '*************************************************************************************************
    '
    CON
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000' 
      High = 1
      Low  = 0
    '
    VAR
      Long Stack0[noparse][[/noparse]20]                           
      Long Stack1[noparse][[/noparse]20]                           
      Long WaitPeriod_Arg                       
    '
    PUB Start
      WaitPeriod_Arg := 8_000_000                                                                     
      CogNew(BlinkingLED_A16 (WaitPeriod_Arg), @Stack0)
    ' 
      WaitPeriod_Arg := 80_000_000              '
      CogNew(BlinkingLED_A17 (WaitPeriod_Arg), @Stack1)
    '
    'LED Blinks Fast
    PRI BlinkingLED_A16 (WaitPeriod_Par) | Pin  '
      Pin := 16
      DirA[noparse][[/noparse]Pin] := %1
    ' 
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(WaitPeriod_Par + Cnt)            
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(WaitPeriod_Par + Cnt)            
    '
    'LED Blinks Slowly
    PRI BlinkingLED_A17 (WaitPeriod_Par)| Pin                                                            
      Pin := 17
      DirA[noparse][[/noparse]Pin] := %1
    ' 
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(WaitPeriod_Par + Cnt)                                     
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(WaitPeriod_Par + Cnt)            
    

    Post Edited (Dave Scanlan) : 3/19/2006 3:20:23 AM GMT
  • pjvpjv Posts: 1,903
    edited 2006-03-05 16:50
    Hi Dave;

    Yes, I like the ability to see both. The detail is always nice, and as one gets onto things a bit more, then the condensed version is easier to read.

    Thanks for your efforts, and keep up the good work.

    Cheers,

    Peter (pjv)
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-05 16:56
    Hi Peter,

    Thanks for responding.

    Dave

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    PLEASE LET·ME KNOW IF YOU FIND THE VERSION WITH LESS DOCUMENTATION
    HELPFUL AND·I WILL CONTINUE TO POST TWO VERSIONS FOR EACH EXAMPLE.






    ··
  • CHIPKENCHIPKEN Posts: 45
    edited 2006-03-05 17:37
    Dave,

    Why in Example #4 "count" was not defined as a variable?

    Good to see this type of code.

    Chuck
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-05 17:50
    Hi Chuck,

    The variable "count" was defined as a local variable in Example 04.· See EXAMPLE 02 for defining variables as local.
    Thanks for responding and for your support.

    Dave
  • Kaos KiddKaos Kidd Posts: 614
    edited 2006-03-06 17:05
    Well.
    I can honestly say I'm getting a good 'preview' for the SPIN language.
    These examples are exciting to read. Both with and with out the examples.
    (I'm not sure if it's Dave's program (as the poster) or Beau's (his name is in the file credits)
    The example program is very interesting, and prompts the following questions:
    #1: How did you derive the 50,000 as the basis for timing the display?
    #2: The coding...

    PUB Message | scan 'What happened to PUB Start ?
    .....
    .....
    repeat '<- ok, a forever endless loop
    repeat scan from 0 to 26 '<- scan was declaired as a pram into this routine, but no value ???

    I take it the command 'repeat' can take a complex (or simple) form of a 'FOR NEXT' ?
    If no PUB Start is present, the the SPIN startup code runs the first PUB it finds?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Just tossing my two bits worth into the bit bucket


    KK
    ·
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-03-06 17:13
    There is no keyword for the beginning routine (like C's main). The top level object will always begin execution with the first function declared.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·1+1=10
  • Kaos KiddKaos Kidd Posts: 614
    edited 2006-03-06 17:51
    Ahhh, that makes sence then...
    SO the PUB Start could be PUB AnyName, and it can contain code for that one cog, launch other cogs etc...
    So very cool...

    Tracy, I did learn something here, today. I never knew that by revers biasing a LED you could read ambient light in a room. so very kewl...
    How accurate is it?

    And the whole "SHAKE A MESSAGE" thing is awesome. I was (and still am), puzzled as to how they get them to work. Now, I have an idea.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Just tossing my two bits worth into the bit bucket


    KK
    ·
  • Beau SchwabeBeau Schwabe Posts: 6,545
    edited 2006-03-06 18:10
    Kaos Kidd said...

    #1: How did you derive the 50,000 as the basis for timing the display?


    The number was really just hunt-and-peck trial and error. Other values will certainly work,
    I wanted to select a value that did not appear to "flicker" when the board was stationary.

    This example demonstrates:

    1) Using the I/O port to control LEDs
    2) Using indexed data tables
    3) Persistence of vision in combination with 1 and 2 to visually "see" by way of motion what is stored in the data table.


    #3 is what will get you if you don't read the directions carefully, as some will attest. smilewinkgrin.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Kaos KiddKaos Kidd Posts: 614
    edited 2006-03-06 18:24
    Well Beau, it's one "sharp" program...
    [noparse]:)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Just tossing my two bits worth into the bit bucket


    KK
    ·
  • Charlie JohnsonCharlie Johnson Posts: 147
    edited 2006-03-06 18:35
    Dave,

    In example 5,

    PUB Start
    WaitPeriod_Arg := 8_000_000
    CogNew(BlinkingLED_A16 (WaitPeriod_Arg), @Stack0)
    .
    .
    .
    .
    'LED Blinks Fast
    PRI BlinkingLED_A16 (WaitPeriod_Par) | Pin '

    Is the WaitPeriod_Par a local variable?
    If so could the WaitPeriod_Arg and WaitPeriod_Par both be called WaitPeriod? Or would this be a name conflict?

    I understand the naming as it is for ease of getting the idea of Arguments and parameters accros.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-03-06 19:00
    No those are arguments of the function, Pin is a local variable.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·1+1=10
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-06 19:33
    Dave,
    
    In example 5,
    
    PUB Start
    WaitPeriod_Arg := 8_000_000 
    CogNew(BlinkingLED_A16 (WaitPeriod_Arg), @Stack0)
    .
    .
    .
    .
    'LED Blinks Fast
    PRI BlinkingLED_A16 (WaitPeriod_Par) | Pin '
    
    Is the WaitPeriod_Par a local variable?
    If so could the WaitPeriod_Arg and WaitPeriod_Par both be called WaitPeriod? Or would this be a name conflict?
    
    I understand the naming as it is for ease of getting the idea of Arguments and parameters accros.
    

    Technically, there is a difference between a local variable and a parameter, but what they do share in common is that they both can be used in BlinkingLED_A16 like variables; that is, you can assign values to them, and you can access their values.
    Because Waitperiod_Par is a "pass-by-value" parameter, it has its own location in memory just like Pin, a local variable.·Their scope is limited to just BlinkingLED_A16.· The only way you can get to WaitPeriod_Par from outside of·BlinkingLED_A16 is to appropriately use an argument.·
    WaitPeriod_Par is not a local variable.
    Both WaitPeriod_Par and Pin "die" as soon as the procedure has finished.
    I suggest you try Google for more information.· I typically spend at least two hours explaining this stuff in lectures. Not so easy to understand.· Perhaps I should reference some of my powerpoint lecture slides.
    ·You could not use WaitPeriod for both the argument and the parameter in this example 05.· Yes, you are correct.· There would be a name conflict. I am about to post example 06 and in it you can use the same name for both the argument and its corresponding parameter.
    Dave
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-06 20:48
    EXAMPLE 06

    SAME AS EXAMPLE 05, BUT WITH A LOCAL VARIABLE AS THE ARGUMENT
    '                                           EXAMPLE 06
    '
    '                  SAME AS EXAMPLE 05, BUT WITH A LOCAL VARIABLE AS THE ARGUMENT              
    '*************************************************************************************************
    'IMPORTANT: This example WILL require an understanding of examples 01, 02, 03, 04, and 05
    '*************************************************************************************************
    'WHAT'S NEW IN THIS EXAMPLE:
    '   LOCAL VARIABLE AS AN ARGUMENT: In EXAMPLE 05, the argument was a global variable. In this
    '                                  example the argument is a local variable.
    '
    '                                  If a global variable is used as an argument, the exact same
    '                                  name cannot be used as the name for the argument's
    '                                  corresponding parameter.  This is why two different
    '                                  names were used in EXAMPLE 05. (See EXAMPLE 05)
    '                 
    '                                  In this example, we do not need to make the names different
    '                                  because the argument is declared as a local variable.
    '                                  Thus, WaitPeriod is used for the argument and the parameter.
    '                                  Having the same name makes tracing through the code with
    '                                  nested procedural calls, much easier to follow.
    '
    '   NOTE:  IN ANY COMPUTER LANGUAGE IT IS ALWAYS BEST TO USE A LOCAL VARIABLE WHEN POSSIBLE TO
    '          CONTROL COUPLING BETWEEN PROCEDURES.  THE PROGRAMMER SHOULD KEEP THE PROCEDURES IN 
    '          ANY PROGRAM LOOSELY COUPLED, NOT TIGHTLY COUPLED.  GLOBAL VARIABLES CAUSE TIGHTLY
    '          COUPLED PROCEDURES AND LEAD TO ERRORS THAT ARE DIFFICULT TO TRACE.
    '     
    '*************************************************************************************************
    '
    'DIFFICULTY LEVEL: INTERMEDIATE 
    '
    'PURPOSE:
    '  -- The purpose of this example is to show ONE of the benifits for using a local
    '     variable as an argument.
    '
    'ADDITIONAL INFORMATION:
    '  -- EXAMPLE 05 where a global variable was used for the argument
    '       ARGUMENT NAME                   PARAMETER NAME
    '         WaitPeriod_Arg                  WaitPeriod_Par
    '
    '  -- EXAMPLE 06 where a local variable was used for the argument
    '     ARGUMENT NAME                    PARAMETER NAME
    '       WaitPeriod                       WaitPeriod
    '
    'Submitted by Dave Scanlan, March 5, 2006          
    'File: Example05_TwoCogsArgParLocalVar.spin
    '*************************************************************************************************
    'CORRECT OUTPUT: The LED at A16 will blink on and off every 0.2 seconds and the LED at A17 will
    '                blink on and off every 2.0 seconds.  The blinking will occur in parallel, but
    '                the LED at A16 will finish ten times faster. Both LEDs will blink five times.   
    '*************************************************************************************************
    CON
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    ' 
      High = 1
      Low  = 0
    '
    VAR
      Long Stack0[noparse][[/noparse]20]                        'Sets up a stack space for a Cog(processor)
      Long Stack1[noparse][[/noparse]20]                        'Sets up a stack space for a second Cog(processor)
                                             'long Stack0[noparse][[/noparse]20]: Allocates 20 longs for the stack.
                                             'long Stack1[noparse][[/noparse]20]: Allocates 20 longs for the stack.                                        
      
    PUB Start  | WaitPeriod                  'WaitPeriod sets the rate at which the LED blinks.
    '
      WaitPeriod := 8_000_000                '0.1 second wait period
      
     'Starts a New Cog(Calls BlinkingLED_A16 (WaitPeriod argument), This Cog uses @stack0)            
      CogNew(BlinkingLED_A16 (WaitPeriod), @Stack0)
      
      WaitPeriod := 80_000_000               '1.0 second wait period
      
     'Starts a New Cog(Calls BlinkingLED_A17 (WaitPeriod argument), This Cog uses @stack1)
      CogNew(BlinkingLED_A17 (WaitPeriod), @Stack1)
    '
    '
    'LED Blinks Fast
    PRI BlinkingLED_A16 (WaitPeriod) | Pin    'Par in WaitPeriod_Par stands for Parameter.
      Pin := 16
      DirA[noparse][[/noparse]Pin] := %1
    '
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(WaitPeriod + Cnt)              '0.1 second wait period   
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(WaitPeriod + Cnt)              '0.1 second wait period
    '
    '
    'LED Blinks Slowly
    PRI BlinkingLED_A17 (WaitPeriod)| Pin      'Par in WaitPeriod_Par stands for Parameter.              
      Pin := 17
      DirA[noparse][[/noparse]Pin] := %1
    '                 
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(WaitPeriod + Cnt)               '1.0 second wait period   
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(WaitPeriod + Cnt)               '1.0 second wait period    
    'INDENTION IS IMPORTANT IN SPIN CODE.
    'FOR THE ADVANCED LEARNER:
    '  -- Arguments and Parameters are used to help eliminate tightly coupled code. 
    '     The use of global variables to pass values between procedures is call Common 
    '     Coupling, and this we try to avoid.
    '  -- Global variables have a strong potential to cause serious errors which are very
    '     difficult to locate.
    '  -- A FULL EXPLANATION OF GLOBAL VARIABLE EFFECTS WOULD REQUIRE A TWO-HOUR LECTURE...OR LONGER.
    '     I suggest a Google search using these words: Common Coupling Structured Design
    '  -- Arguments pass values to their corresponding parameters "by value" in Spin.   
    


    FEWER COMMENTS (EASIER TO READ)
    EXAMPLE 06

    ··············· SAME AS EXAMPLE 05, BUT WITH A "LOCAL VARIABLE" AS THE ARGUMENT
    ····
    '                                 FEWER COMMENTS (EASIER TO READ)
    '
    '                                           EXAMPLE 06
    '
    '                 SAME AS EXAMPLE 05, BUT WITH A "LOCAL VARIABLE" AS THE ARGUMENT     
    '*************************************************************************************************
    'CORRECT OUTPUT: The LED at A16 will blink on and off every 0.2 seconds and the LED at A17 will
    '                blink on and off every 2.0 seconds.  The blinking will occur in parallel, but
    '                the LED at A16 will finish ten times faster. Both LEDs will blink five times.
    'Submitted by Dave Scanlan, March 5, 2006         
    'File: Example05_TwoCogsArgParLocalVar.spin
    '*************************************************************************************************
    CON
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    ' 
      High = 1
      Low  = 0
    '
    VAR
      Long Stack0[noparse][[/noparse]20]                           
      Long Stack1[noparse][[/noparse]20]                           
    '
    PUB Start  | WaitPeriod
    '
      WaitPeriod := 8_000_000                                                                         
      CogNew(BlinkingLED_A16 (WaitPeriod), @Stack0)
    ' 
      WaitPeriod := 80_000_000    
      CogNew(BlinkingLED_A17 (WaitPeriod), @Stack1)
    '
    'LED Blinks Fast
    PRI BlinkingLED_A16 (WaitPeriod) | Pin      
      Pin := 16
      DirA[noparse][[/noparse]Pin] := %1
    '
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(WaitPeriod + Cnt)                
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(WaitPeriod + Cnt)                
    '
    'LED Blinks Slowly
    PRI BlinkingLED_A17 (WaitPeriod)| Pin                                                                
      Pin := 17
      DirA[noparse][[/noparse]Pin] := %1
    '                 
      Repeat 5
        OutA[noparse][[/noparse]Pin] := High                                                     
        WaitCnt(WaitPeriod + Cnt)                                         
        OutA[noparse][[/noparse]Pin] := Low                   
        WaitCnt(WaitPeriod + Cnt)                                          
    

    Post Edited (Dave Scanlan) : 3/19/2006 3:21:17 AM GMT
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-06 20:58
    In EXAMPLE 06 above the local variable "Pin" will not hold its place in the posting format. It looks ok in the preview. After two attempts I decided to just leave this note.
    There is a similar problem in the full version of EXAMPLE 06. Part of a comment does not hold its format. The word "stack" gets pushed over to the left margin. This too looks ok in the preview.

    Dave

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    PLEASE LET·ME KNOW IF YOU FIND THE VERSION WITH LESS DOCUMENTATION
    HELPFUL AND·I WILL CONTINUE TO POST TWO VERSIONS FOR EACH EXAMPLE.






    ··
  • Charlie JohnsonCharlie Johnson Posts: 147
    edited 2006-03-06 21:12
    Thanks Dave,

    Your explanation and Example 6 answered my question...Thanks
  • DigitalDjDigitalDj Posts: 207
    edited 2006-03-07 01:16
    Hello All,

    Yes i have to agree with above post, seeing code posted to help learn spin is great. I just recently purchased the SX Tool Kit and it would be nice if the·SX·forum would do the same.

    Regards,

    Kevin
  • Dave ScanlanDave Scanlan Posts: 160
    edited 2006-03-07 02:35
    DigitalDj,

    Your comment is appreciated by all who post their programs here.

    Dave

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    PLEASE LET·ME KNOW IF YOU FIND THE VERSION WITH LESS DOCUMENTATION
    HELPFUL AND·I WILL CONTINUE TO POST TWO VERSIONS FOR EACH EXAMPLE.






    ··
Sign In or Register to comment.