SPIN CODE EXAMPLES FOR THE BEGINNER (Public Version)
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
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
Comments
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
·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
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
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
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
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
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
Thanks for the support.
When you get the docs and stuff, I hope you will add to this thread.
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
··········································
·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
kenjj
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
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)
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.
··
Why in Example #4 "count" was not defined as a variable?
Good to see this type of code.
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
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
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
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
·
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.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
[noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·
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.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
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
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
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.
··
Your explanation and Example 6 answered my question...Thanks
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
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.
··