Shop OBEX P1 Docs P2 Docs Learn Events
Re-discovering Spin — Parallax Forums

Re-discovering Spin

RsadeikaRsadeika Posts: 3,837
edited 2014-12-30 05:32 in Propeller 1
Yesterday I got a package from Parallax, which contained, among other things, an HIB board for my QuickStart board. Since I have not used Spin in quite awhile, I thought I would offer up my rendition of a beginners program. I am using the PropellerIDE for this, because it is the latest and the greatest.

The objects that come with an installation of PropellerIDE pretty much covers all the components that are on an HIB, except for one, the uSD card. I did not see any object or DEMO program that would show how to use this. I am sure that this oversight will be corrected in a short time, I hope.

I am also wondering if a specific object should be made that would contain all the methods for using all the components on the HIB, that way you could just use a command format to implement the specific component, just a thought.

Ray
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' test1.spin

'' Setup QuickStart board with HIB
CON
  _clkmode = XTAL1 + PLL16X
  _clkfreq = 80_000_000
  
OBJ
''  misc  : "tools"   '' Commonly used methods object
  term  : "Parallax Serial Terminal"  '' Access the debug terminal

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
PUB Start
  term.Start(115000)  '' Initialise the debug terminal
  
  term.str(string($d,"The blinker program.",$d))  '' Header message
  main

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
PUB main
  repeat
    blink

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
PRI blink  
    high(16)     '' Turn on LED P16.
    waitms(500)  '' Pause for half a second.
    low(16)      '' Turn off LED P16.
    waitms(500)  '' Pause for half a second.

  
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' These methods would be kept in a seperate object
''
'' How to use - wait(1) 
'' Pauses for one second   
PUB wait(time)
  waitcnt((80_000_000 * time) + cnt)  '' This method has a roll over
                                      '' when set for greater than 53 seconds.
'''''''''''''''

'' How to use - waitms(1000)
'' Pauses for one second
PUB waitms(time)
  waitcnt(((80_000_000 / 1000) * time) + cnt)  '' This method has a roll over
                                               '' when set for greater than
                                               '' 53 seconds.
'''''''''''''''

'' How to use - high(0)
'' Set high P0
PUB high(pin)
  DIRA[pin] := %1
  OUTA[pin] := 1
'''''''''''''''

'' How to use - low(0)
'' Set low P0
PUB low(pin)
  DIRA[pin] := %1
  OUTA[pin] := 0
'''''''''''''''

Comments

  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-12-27 07:39
    Use FSRW for the uSD card.

    I am also wondering if a specific object should be made that would contain all the methods for using all the components on the HIB

    No. As an example... what protocol would you select for IR in and IR out? Sony? Panasonic?

    Creating an object for everything on the HIB just means bloated code; go with individual objects for the pieces that you're using on the HIB for a given project.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-12-27 08:21
    Continuing with my QuickStart HIB theme, everybody should be thinking - but, what about the COGs. So below is a program, my rendition, of a generalized use of COGs. The code below has a small mystery, some of the Spin gurus will figure it out in no time. I got caught with this, and it sort of highlights a problem that you have to be aware of, Spin can get complicated, if you are not careful.

    I am now using my tools object, so if anybody is playing along, you will have to make that happen in your Spin rendition.

    Ray
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '' coged_blink.spin
    ''
    '' Setup QuickStart board with HIB
    CON
      _clkmode = XTAL1 + PLL16X
      _clkfreq = 80_000_000
      
    OBJ
      misc  : "tools"   '' Commonly used methods object
      term  : "Parallax Serial Terminal"  '' Access the debug terminal
    
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '' Create a stack for the new COGs
    VAR
      long cog1stack[10]
      long cog2stack[10]
      long cog3stack[10]
      long cog4stack[10]
      long cog5stack[10]
      long cog6stack[10]
      long cog7stack[10]
      
      
    PUB Start
      term.Start(115000)  '' Initialise the debug terminal
    '' Header message  
      term.str(string($d,"The coged blink program.",$d))
    '' Start the COGs
      cognew(Cog1LED,@cog1stack)
      cognew(Cog2LED,@cog2stack)
      cognew(Cog3LED,@cog3stack)
      cognew(Cog4LED,@cog4stack)
      cognew(Cog5LED,@cog5stack)
      cognew(Cog6LED,@cog6stack)
      cognew(Cog7LED,@cog7stack)
      
      main
    
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    PUB main
      repeat
        misc.high(23)
        misc.waitms(300)
        misc.low(23)
        misc.waitms(300)
      
    PUB Cog1LED
      repeat
        misc.high(16)
        misc.waitms(700)
        misc.low(16)
        misc.waitms(700)
    
    PUB Cog2LED
      repeat
        misc.high(17)
        misc.waitms(600)
        misc.low(17)
        misc.waitms(600)
    
    PUB Cog3LED
      repeat
        misc.high(18)
        misc.waitms(500)
        misc.low(18)
        misc.waitms(500)
    
    PUB Cog4LED
      repeat
        misc.high(19)
        misc.waitms(400)
        misc.low(19)
        misc.waitms(400)    
    
    PUB Cog5LED
      repeat
        misc.high(20)
        misc.waitms(700)
        misc.low(20)
        misc.waitms(700)
    
    PUB Cog6LED
      repeat
        misc.high(21)
        misc.waitms(600)
        misc.low(21)
        misc.waitms(600)
    
    '' Anybody figure out why this LED is not 
    '' going on/off??   
    PUB Cog7LED
      repeat
        misc.high(22)
        misc.waitms(500)
        misc.low(22)
        misc.waitms(500)
    
    
  • PublisonPublison Posts: 12,366
    edited 2014-12-27 08:30
    I guess if you shared tools.spin, we could check it out. :)
  • kuronekokuroneko Posts: 3,623
    edited 2014-12-27 08:48
    Rsadeika wrote: »
    '' Anybody figure out why this LED is not 
    '' going on/off??   
    PUB Cog7LED
      repeat
        misc.high(22)
        misc.waitms(500)
        misc.low(22)
        misc.waitms(500)
    
    You're simply running out of cogs. Not counting primary cog and PST you have 6 left ...
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-12-27 09:14
    I guess if you shared tools.spin, we could check it out.
    For you old timers in Spin, this should not be a problem, for some new people, a good exercise.
    You're simply running out of cogs. Not counting primary cog and PST you have 6 left ...
    For the benefit of some new people, kuroneko, is a Master Guru, in Spin, PASM, and I can only guess at what other programming languages. JonnyMac is more Spin/PASM, plus their are others.

    Since I setup my QS_HIB to do some prototyping, the next thing I might try is adding an XBee module and do some IO with that, not sure though.

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2014-12-27 09:42
    Publison wrote: »
    I guess if you shared tools.spin, we could check it out. :)


    Obviously creating IDE archive/zip buttons is a waste of time.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-12-27 10:57
    To me, the mystery is why you didn't write a single, more flexible blink routine and launch it as required. ;)

    For example:
    pri cog_led(pin, mson, msoff) | t                                ' launch with cognew()
    
      dira[pin] := 1                                                 ' make pin output in this cog
    
      mson  *= clkfreq / 1000                                        ' convert on ms to ticks
      msoff *= clkfreq / 1000                                        ' convert off ms to ticks
    
      t := cnt                                                       ' sync blink timing
      repeat
        outa[pin] := 1                                               ' led on
        waitcnt(t += mson)                                           ' wait
        outa[pin] := 0                                               ' led off
        waitcnt(t += msoff)                                          ' wait
    


    BTW, I tend to use 16 as my minimum stack size for a simple cog -- crashing the stack is a real nasty bit of business.

    TIP: When I have methods in my main program that are going to launch into a cog (as above), I declare them as private to remind me not to call them as standard methods.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-12-27 11:08
    Instead of the XBee that I mentioned earlier, maybe something that uses the HIB IR components. Maybe something along the line of having the TV remote controller turn on/off a particular LED on the HIB. I think everybody should have a remote controller handy. I am not sure that I saw any example code for using the HIB IR components, will have to check some more.

    Ray
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-12-27 11:12
    I do a lot of work with IR (one of EFX-TEK's current clients is a large laser-tag company -- IR in and out is a big part of the project).

    From ObEx that may be helpful:
    -- http://obex.parallax.com/object/319
    -- http://obex.parallax.com/object/321
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-12-27 11:33
    I just noticed that the HIB has a demodulator and an IR LED, I also have another HIB and QS board, maybe a more interesting thing to try is to have the two QS_HIB boards talk to each other, turn on/off each others LEDs? That would mean everybody would have to buy another QS_HIB set. I was planning on soldering the second HIB to one of the protoboards, which I just received, and turn that into prototyping set.

    Ray
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-12-27 11:41
    A good first project is to control the LEDs via TV remote. Once you have your TV remote figured out, you can point your HIB at the TV and control it.

    I have a "Glow with the Show'" hat from Disneyland that uses serial over IR (2400 baud) and I've used my HIB to control the hat. Disneyland uses the Propeller in several small projects and this year I will help them revamp a display -- we'll probably throw GWTS hat control in as well.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-12-27 13:58
    Well I tried to modify the JonnyMac SIRCS demo program, but no joy. I made some modification to the attached program to work with the PropellerIDE, but I am not getting any SIRCS code showing up on the screen. I tried both P8 and P9, neither seems to be responding. I noticed on HIB it shows RX P8 and TX P9, but in the docs it says "The infrared demodulator, connected to Propeller I/O pin P9...". In this case neither one is working.

    Ray
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-12-27 15:06
    I moved my SIRCS demo code to my HID template and... no problem. Here it is.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-12-28 03:39
    As usual the JonnyMac SIRC Demo is excellent, works as expected. The only mod that I did was to have the screen show one result for a keypress, at the top of the screen. What was occurring for me, I would press a key on the remote, and I would have anywhere from 3 - 5 same results show up on the screen. Now I press a key, does not matter how long I have it pressed down, only one result shows up, for the keypress, instead of maybe a screen full of the same result. And I added a decimal plus a hex readout, I think I will use the dec values.

    I tried to use some of the screen control commands, I was not getting what I expected. For instance, I tried to use the GOTOXY, to place the next read out after the banner, for what ever reason it clears the screen and then nothing shows up after that. Something as simple as that, and I seem to have a problem figuring it out.

    I guess the next thing is to create a program that has a remote keypress and a designated HIB LED turn on/off. The key to this is to have an object that has all the decimal key values and a response to each key press.

    I was thinking of a project where I would have these different devices in a room, and I would control them with an XBee, now I am thinking if you have one master with an XBee and IR, then I could control the other devices with the IR. Line of site for the IR, I guess I could point the master device at the ceiling and that should alleviate that problem somewhat.

    Ray
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-12-28 08:27
    I didn't gate the keys so that one can see that each key does in fact send repeated codes. A simple gating method is to insert a 250ms delay before re-enabling. Remotes will repeat a keycode 3 to 5 times, and the SIRCS frame is 45ms, hence 250ms allows for redundant codes to be ignored.
    pub main | key, bc
    
      setup
    
      ' open PST, select com port, enable, press a key
    
      term.rxflush
      term.rx
    
    
      ' SIRCS demo
    
      term.tx(term#CLS)
      term.str(@Banner)
    
      irin.enable                                                    ' allow ir input
    
      repeat
        key := irin.rx                                               ' wait for sircs
        bc   := irin.bit_count                                       ' get bit count
    
        case bc
          12:
            term.str(string("12 :: "))                               ' show bit count
            term.bin(key >> 7, 5)                                    ' show device code
            term.tx("_")                                             ' separater
            term.bin(key, 7)                                         ' show key code
            
          15:
            term.str(string("15 :: "))
            term.bin(key >> 7, 8)
            term.tx("_")
            term.bin(key, 7)
            
          20:
            term.str(string("20 :: "))
            term.bin(key >> 12, 8)
            term.tx("_")
            term.bin(key, 12)
            
          other:
            if (bc < 10)
              term.tx("0")
            term.dec(bc)
            term.str(string(" :: "))
            term.bin(key, bc)
            term.tx(" ")
            term.hex(key, 8)
            
        term.tx(term#CR)
    
        time.pause(250)                                              ' ignore key repeats
        irin.enable                                                  ' re-enable for next key
    


    When I need to move the cursor to a specific position (I do a lot of formatted output) I tend to add a method like this:
    pub move_cursor(col, row)
    
      term.tx(term#GOTOXY)
      term.tx(col)
      term.tx(row)
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-12-29 03:55
    Yesterday was a busy day, I created my contraption which I call the QS_HIBprotoSet. This is made of a rigid piece of cardboard, on the top side it holds the QS_HIB, in the center, and I have two small breadboards on either side. On the backside, I have two li-ion 18650 battery holders wired in series with a barrel plug. So far it works as expected. I also had a chance to check out the new JonnyMack SIRCS (jm_sircs), the Tom Doyle SIRCS (td_sircs), and the kuroneko vga80x25 (knk_vga80x25) programs.

    The only mods that I made to the jm_sircs program was, adding a dec and a hex listing along with the binary that you got originally. Somewhere along the line I will probably add a column header that labels the information, so you know what you are looking at.

    The td_sircs program was changed to run with the PropellerIDE, and I found it easier to figure out how to assign some code for the TV remote controller keys. I tested all the keys out with the LED on/off commands. This program is different from the jm_sircs, it does not "sniff" out the controller key codes.

    The knk_vga80x25 program is a plug and play demo, it worked with the PropellerIDE and the QS_HIB without a hitch, did not have to change one bit of code to have the demo run. On my 19" widescreen TV set with a vga plug, the characters displayed were very nice, even when the whole screen is filled. Now I have to look into creating an object that has a command structure so I can make it work in place of the "Parallax Serial Terminal".

    Somewhere along the line I will probably add a keyboard, once I figure out how the implement the knk_vga80x25 diver to work with it. But first I will try having the td_sircs display a message with a keypress of the TV remote controller, to the TV monitor. So far the one thing that I am missing is some ADC sockets, not sure if I have enough resources left on the QS_HIB to implement that. Now if Parallax could do a cost reduction on the QS_HIB, I think this combo has a lot of potential.

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-12-29 08:01
    I started to build a small program that uses the kuroneko vga80x25 driver, so far the program below sets up the vga and prints a banner. I noticed that after it prints the banner it does not do a NL or CR, so I guess that code is in the PASM, or a method has to be created. Since I am thinking that this would be used in the same manner as "Parallax Serial Terminal", in terms of commands, maybe it should have some standard methods for doing CR and NL, and whatever else, not sure what kuroneko had in mind. Some input on this would be appreciated. And once I have a keyboard attached I guess it will need all kinds of cursor control.

    Ray
    '' myQS_HIBset.spin
    
    CON
      _clkmode = XTAL1 + PLL16X
      _clkfreq = 80_000_000
    
    '' VGA ''''''''''''
    CON
      columns  = driver#res_x / 9
      rows    = driver#res_y / font#height
      bcnt    = columns * rows
      
      rows_raw = (driver#res_y + font#height - 1) / font#height
      bcnt_raw = columns * rows_raw
    CON
      vgrp  = 2
      mode  = 1
      video = (vgrp << 9 | mode << 8 | %%333_0) << 21
    CON
      CURSOR_ON      = driver#CURSOR_ON
      CURSOR_OFF     = driver#CURSOR_OFF
      CURSOR_ULINE   = driver#CURSOR_ULINE
      CURSOR_BLOCK   = driver#CURSOR_BLOCK
      CURSOR_FLASH   = driver#CURSOR_FLASH
      CURSOR_SOLID   = driver#CURSOR_SOLID
      
      #0, CM, CX, CY
    '''''''''''''''''''  
      
    OBJ
      misc   :  "tools"
      driver :  "waitvid.80x25.driver.2048"
      font   :  "halfrange8x16-2font"
      
      
      
    VAR
    '' VGA '''''''''
      long scrn[bcnt_raw / 2]
      long link[driver#res_m]
      long cursor
    ''''''''''''''''
       
    PUB Start
      vga_banner
      main
    
    PUB main
      repeat
      
    PUB vga_banner
      link{0} := video | @scrn{0}
      link[1] := font#height << 24 | font.addr
      link[2] := @cursor * $00010001
      
      driver.init(-1, @link{0})
      
      misc.waitms(50)
      setCursor(CURSOR_ON|CURSOR_ULINE|CURSOR_FLASH)
    
    '' Print string text, non-flashing BG, use %1110_100_1 flash BG  
      printText(%1110_100_0, string("This is the QS_HIBset program"))
      misc.waitms(50)
      
    PRI setCursor(setup)
      cursor.byte{CM} := (cursor.byte{CM} & !(CURSOR_ON|CURSOR_ULINE|CURSOR_FLASH)) | setup
    
    PRI printText(attr, s)
      repeat strsize(s)
        printChar(attr, byte[s++])
        
    PRI printChar(attr, c) | x, y
      c &= 127
      
      x := cursor.byte[CX]
      y := cursor.byte[CY]
      
      attr.byte[1] := c
      scrn.word[bcnt_raw - y * columns - ++x] := attr
      ifnot x //= columns
        y := ++y // rows
        
      cursor.byte[CX] := x
      cursor.byte[CY] := y
    
  • kuronekokuroneko Posts: 3,623
    edited 2014-12-29 11:38
    Rsadeika wrote: »
    I noticed that after it prints the banner it does not do a NL or CR, so I guess that code is in the PASM, or a method has to be created. Since I am thinking that this would be used in the same manner as "Parallax Serial Terminal", in terms of commands, maybe it should have some standard methods for doing CR and NL, ...
    This driver doesn't have a - what I'd call usable - UI. It's simply a proof-of-concept (Hi [thread=157354]Sapphire[/thread]!). Methods listed in the demo program explain initialisation, access to the character/attribute array and cursor control. That's it. That being said, there is an outstanding issue to bring it in line with the remainder of the driver collection.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-12-29 12:07
    Thanks kuroneko for the explanation. Usable access to the vga component has now been moved to the back burner, I do not have the talent to implement a UI. Maybe another chip with a developed UI for vga should be incorporated? But what and how?

    Now I guess I can experiment with the uSD. The one thing that I noticed was, for PropGCC the driver size was about 9K, and for Spin the size is about 7K, I was under the impression that it would be way smaller for Spin.

    The other thing that I noticed, with the HIB installed, when you apply power via the barrel socket, and you have the USB plugged in, when I try to program the chip, PropellerIDE comes back with a "Cannot find a Propeller chip". As soon as I unplug the power from the barrel socket, then the PropellerIDE finds the Propeller chip, is that my board, or is that the way it supposed to work?

    Ray
  • kuronekokuroneko Posts: 3,623
    edited 2014-12-30 00:42
    Rsadeika wrote: »
    I do not have the talent to implement a UI. Maybe another chip with a developed UI for vga should be incorporated? But what and how?
    You're acting as if there are no other VGA drivers (with UI) available ...
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-12-30 05:32
    Thanks kuroneko, moving on to something less controversial ...

    Ray
Sign In or Register to comment.