November 22, 2024, 09:45:12 AM

News:

You can now use Vixen to program your Prop-1 and Prop-2 controllers!  Get started quickly and easily, without having to learn PBASIC.  Details in the Library forum.


RC4 problem with the Propeller test code

Started by bsnut, July 08, 2011, 09:53:18 AM

Previous topic - Next topic

bsnut

July 08, 2011, 09:53:18 AM Last Edit: July 08, 2011, 09:55:18 AM by bsnut
Jon,

As you know, I have been working on my monitoring project for the ship "Zuni/Tamaroa" which is the Perfect Storm ship to monitor the 9 bilge sensors, fire alarm panel and shore power connection.  

The problem that I am having, is when I select a relay output on the RC4 with this code it blinks the relay that I selected when I keep the input on.

CON

 _clkmode = xtal1 + pll16x
 _xinfreq = 5_000_000                                          ' use 5MHz crystal

 CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
 MS_001   = CLK_FREQ / 1_000
 US_001   = CLK_FREQ / 1_000_000


 Bilge1          = 5
 Bilge2          = 6
 Silencepb       = 19
 Alarmlt         = 20

con

 RX1     = 31                                                  ' programming/debug
 TX1     = 30
 SIO     = 27                                                  ' TTL serial IO  
var
 long timer1, timer2


obj

 term : "fullduplexserial"                                     ' buffered serial io
 com1 : "fullduplexserial"                                     ' EFX device serial


pub main

 dira[20] := 1
 term.start(RX1, TX1, %0000, 115_200)                          ' start terminal
 com1.start(SIO, SIO, %1100, 38_400)                           ' start EFX serial

 repeat
   if timer1 == 30
     if (ina[Silencepb] == 1)
       outa[Alarmlt] := 0
       set_rc4(%00, %0000)
       
   if timer1 < 30
     if (ina[Bilge1] == 1)  
       pause(100)
       timer1 := timer1 + 1 '<# 30
       if timer1 == 30
         outa[Alarmlt] := 1
         set_rc4(%00, %0001)
         
   if (ina[Bilge1] == 0)
     outa[Alarmlt] := 0
     timer1 := 0
     set_rc4(%00, %0000)


   if timer2 == 30
     if (ina[Silencepb] == 1)
       outa[Alarmlt] := 0
       set_rc4(%00, %0000)
 
   if timer2 < 30
     if (ina[Bilge2] == 1)  
       pause(100)
       timer2 := timer2 + 1 '<# 30
       if timer2 == 30
         outa[Alarmlt] := 1
         set_rc4(%00, %0001)
     
   if (ina[Bilge2] == 0)
     outa[Alarmlt] := 0
     timer2 := 0
     set_rc4(%00, %0000)
   
pub pause(ms) | t

'' Delay program ms milliseconds

 t := cnt - 1088                                               ' sync with system counter
 repeat (ms #> 0)                                              ' delay must be > 0
   waitcnt(t += MS_001)

pub low(pin)

'' Makes pin output and low

 outa[pin] := 0
 dira[pin] := 1
 
pub set_rc4(addr, relays)

'' Update RC-4 at 'addr' with bits in 'relays'
'' -- replaces: SEROUT Sio, Baud, ("!RC4", addr, "S", relays)

 com1.str(string("!RC4"))                                      ' header
 com1.tx(addr)                                                 ' address
 com1.tx("S")                                                  ' set command
 com1.tx(relays & $F)  


When I comment out this code, the relay operates as I want it to when I keep the input on.

   if timer2 == 30
     if (ina[Silencepb] == 1)
       outa[Alarmlt] := 0
       set_rc4(%00, %0000)
 
   if timer2 < 30
     if (ina[Bilge2] == 1)  
       pause(100)
       timer2 := timer2 + 1 '<# 30
       if timer2 == 30
         outa[Alarmlt] := 1
         set_rc4(%00, %0001)
     
   if (ina[Bilge2] == 0)
     outa[Alarmlt] := 0
     timer2 := 0
     set_rc4(%00, %0000)

Is this problem being cause by no timing or is the way I code it? The goal is to be able to turn off the outside alarm when the silence button is pushed.

 
William Stefan
The Basic Stamp Nut

JonnyMac

July 09, 2011, 10:45:59 AM #1 Last Edit: July 09, 2011, 10:58:14 AM by JonnyMac
William,

Two things: 1) Your segmented logic is a little tough to follow (because it's not one structure) and, 2) there's a cool trick with Spin for running timers without having to resort to a another cog.  We'll cover #2 first.

Many of my programs have a main loop structure that looks like this:

 t := cnt                                                      ' sync with system counter
 repeat
 
   ' code here -- must consume < loop timing
 
   waitcnt(t += constant(MS_001 * 100))                        ' run loop every 100ms


One of my favorite features of the Propeller is the WAITCNT instruction.  This is different than PAUSE, and you must use it correctly else you can have problems.  Used correctly, though, it's incredibly powerful.  Remember that the Propeller has a system counter (called CNT) that increments every clock cycle.  All cogs have access to this counter.  The WAITCNT instruction will put the cog into low power mode and wait until the value in CNT hits a specific target.  That last part is critical: it doesn't wait a specific number of ticks (like PAUSE does), it waits for CNT to hit a specific value.

How do we use this, then?  We can create a synchronized delay (this is in the Propeller manual) by grabbing the value of CNT before dropping into our main code loop.  In the above code I use the variable 't' for this.  At the end of the loop we will use a WAITCNT that adds the amount of time we want for the loop.  The expression in the WAITCNT line will be evaluated before WAITCNT is executed, so we don't need two lines for this.  The only condition is that our code must run less than the intended delay (else we miss the WAITCNT target and have to wait for CNT to rollover which can take about 57 seconds at 80MHz).  The beauty of the synchronized loop is that we can change the code as we want and no matter what path(s) the code takes -- so long as it's less than the loop timing -- the loop timing will be EXACTLY as we specify.  This makes the technique fantastic for timing without headaches.  Of course, we could launch a background timer cog but this is not usually required for simple programs.

To you logic... if I read it right you could say this: If the Bilge input is clear then turn off any alarms and reset the input timer; if the Bilge input is on, increment a timer and when it hits 30 turn on an alarm -- if the silence input is not active.  Am I correct?  If yes, this is how I would structure the program (for one input only, I'll let you put the second back in).

Note, too, that I'm crazy anal-retentive when it comes to formatting Propeller code because the compiler demands neatness.  With that, I've modified some of your listing to my own style.

con

 _clkmode = xtal1 + pll16x
 _xinfreq = 5_000_000                                          ' use 5MHz crystal

 CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
 MS_001   = CLK_FREQ / 1_000
 US_001   = CLK_FREQ / 1_000_000
 

con

 RX1       = 31                                                ' programming/debug
 TX1       = 30
 SIO       = 27                                                ' TTL serial IO

 Bilge1    =  5
 Bilge2    =  6
 SilencePB = 19
 AlarmLt   = 20


var

 long  timer1
 long  timer2
 

obj

 term : "fullduplexserial"                                     ' buffered serial io
 com1 : "fullduplexserial"                                     ' EFX device serial


pub main | t

 low(AlarmLt)                                                  ' output and off

 term.start(RX1, TX1, %0000, 115_200)                          ' start terminal
 com1.start(SIO, SIO, %1100, 38_400)                           ' start EFX serial
 pause(1)

 t := cnt                                                      ' sync with system counter
 repeat
 
   if (ina[Bilge1] == 0)
     outa[AlarmLt] := 0                                        ' alarm off
     timer1 := 0                                               ' reset timer
     set_rc4(%00, %0000)
   else                                                        ' bilge input is on
     ++timer1                                                  ' increment timer
     if (timer1 => 30)                                         ' hit threshold?
       if (ina[SilencePB] == 0)                                ' okay to sound alarm?
         outa[Alarmlt] := 1                                    ' alarm light on
         set_rc4(%00, %0001)                                   ' activate RC-4
       else
         outa[Alarmlt] := 0                                    ' clear if silence selected
         set_rc4(%00, %0000)    
 
   waitcnt(t += constant(MS_001 * 100))                        ' run loop every 100ms
 

   
pub pause(ms) | t

'' Delay program ms milliseconds

 t := cnt - 1088                                               ' sync with system counter
 repeat (ms #> 0)                                              ' delay must be > 0
   waitcnt(t += MS_001)

   
pub low(pin)

'' Makes pin output and low

 outa[pin] := 0
 dira[pin] := 1
 
 
pub set_rc4(addr, relays)

'' Update RC-4 at 'addr' with bits in 'relays'
'' -- replaces: SEROUT Sio, Baud, ("!RC4", addr, "S", relays)

 com1.str(string("!RC4"))                                      ' header
 com1.tx(addr)                                                 ' address
 com1.tx("S")                                                  ' set command
 com1.tx(relays & $F)  


Finally, there still may be a flaw in the logic.  You have two bilge inputs but only one alarm output and one RC-4 output that is used.  The problem, I believe, is that Bilge1 could activate the alarm output and RC-4 and then the Bilge2 input could immediately clear it.  Something to think about.

Jon McPhalen
EFX-TEK Hollywood Office

bsnut

I see what you are talking about and I will try your code later on.

QuoteTo you logic... if I read it right you could say this: If the Bilge input is clear then turn off any alarms and reset the input timer; if the Bilge input is on, increment a timer and when it hits 30 turn on an alarm -- if the silence input is not active.  Am I correct?
Yes you are correct in what you are reading. One of the things I don't see in your code and I had in my code, was limiting the timer to 30 (max) like the code below.

    if timer1 < 30                            'Look at Bilge1 input when timer1 is not 30
      if (ina[Bilge1] == 1) 
        pause(100)
        timer1 := timer1 + 1 '<# 30  'timer1 stops at 30
        if timer1 == 30
          outa[Alarmlt] := 1                'turn on Alarmlt
          set_rc4(%00, %0001)         'turn on RC4 ch1
          alarmvar := 1                      'spinneret alarm variable runs once when timer1 == 30
          'my spinneret coms here

The reason why I was doing this, is because I didn't want this variable (alarmvar := 1) to be sent twice to the spinneret. Each bilge input has it's own number in this variable (alarmvar := 1 'bilge1 input, alarmvar := 2 'bilge2 input)
How would I prevent sending my "alarmvar" after the timer1 has reached 30 in your code structure?

Does the repeat code structure need to look like this
  t := cnt                                                      ' sync with system counter
  repeat
   
    if (ina[Bilge1] == 0)
      outa[AlarmLt] := 0                                        ' alarm off
      timer1 := 0                                               ' reset timer
      set_rc4(%00, %0000)
    else                                                        ' bilge input is on
      ++timer1                                                  ' increment timer
      if (timer1 => 30)                                         ' hit threshold?
        if (ina[SilencePB] == 0)                                ' okay to sound alarm?
          outa[Alarmlt] := 1                                    ' alarm light on
          set_rc4(%00, %0001)                                   ' activate RC-4
          alarmvar := 1                                           'spinneret alarm variable for bilge1 input
          'my spinneret coms here
        else
          outa[Alarmlt] := 0                                    ' clear if silence selected
          set_rc4(%00, %0000)   

    if (ina[Bilge2] == 0)
      outa[AlarmLt] := 0                                        ' alarm off
      timer1 := 0                                               ' reset timer
      set_rc4(%00, %0000)
    else                                                        ' bilge input is on
      ++timer2                                                  ' increment timer
      if (timer2 => 30)                                         ' hit threshold?
        if (ina[SilencePB] == 0)                                ' okay to sound alarm?
          outa[Alarmlt] := 1                                    ' alarm light on
          set_rc4(%00, %0001)                                   ' activate RC-4
          alarmvar := 1                                           'spinneret alarm variable for Bilge2 input
          'my spinneret coms here
        else
          outa[Alarmlt] := 0                                    ' clear if silence selected
          set_rc4(%00, %0000)
 
    waitcnt(t += constant(MS_001 * 100))                        ' run loop every 100ms


William Stefan
The Basic Stamp Nut

JonnyMac

July 10, 2011, 09:06:12 AM #3 Last Edit: July 10, 2011, 12:39:09 PM by JonnyMac
I'm more confused now.  You have two bilge alarms, but only one local output.  Do both timers have to be at or above 30 to trigger the alarm, or if either is above 30 should the alarm be on.

The way the code above works one bilge can trigger the alarm and the other can immediately reset it.  Thinking about it, I believe this is what you want.  It will track each timer and when -- and only when -- either hits 30 the Spinneret alarm is sent.  If either is above the threshold and local alarms are enabled it will activate the alarm, otherwise they're cleared.

pub main | t, lastrc4

  ' setup objects and IOs here

  lastrc4 := -1                                                 ' no match for either state

  t := cnt
  repeat
    waitcnt(t += constant(MS_001 * 100))

    timer1 := ++timer1 * ina[Bilge1]                            ' update timer1
    if (timer1 == 30)
      ' send Bilge 1 alarm to Spinneret

    timer2 := ++timer2 * ina[Bilge2]                            ' update timer2
    if (timer2 == 30)
      ' send Bilge 2 alarm to Spinneret

    if (((timer1 => 30) or (timer2 => 30)) and (ina[SilencePB] == 0))
      outa[AlarmLt] := 1
      if (lastrc4 <> %0001)
        set_rc4(%00, %0001)
        lastrc4 := %0001
    else
      outa[AlarmLt] := 0
      if (lastrc4 <> %0000)
        set_rc4(%00, %0000)
        lastrc4 := %0000


I've updated the code so that it only sends a message to th RC-4 when there is a change of state.
Jon McPhalen
EFX-TEK Hollywood Office

bsnut

July 10, 2011, 04:46:35 PM #4 Last Edit: July 16, 2011, 12:20:34 AM by bsnut
I am sorry if I am confusing you. This part of your code will work for me that you posted.

pub main | t, lastrc4

  ' setup objects and IOs here

  lastrc4 := -1                                                 ' no match for either state

  t := cnt
  repeat
    waitcnt(t += constant(MS_001 * 100))

    timer1 := ++timer1 * ina[Bilge1]                            ' update timer1
    if (timer1 == 30)
      ' send Bilge 1 alarm to Spinneret

    timer2 := ++timer2 * ina[Bilge2]                            ' update timer2
    if (timer2 == 30)
      ' send Bilge 2 alarm to Spinneret



This is the way the system is to work

1) If any of the Bilge inputs (9 of them) are trigger for 3 seconds (30 x 100 ms) they turn on the alarm light and turn on RC4 channel 1. Also each input has its own timer to keep track how long a input was triggered, if less then 30 don't turn on alarm light or set the RC4 channel 1. 

2. Each Bilge input has it's own value for "alarmvar" (alarmvar := 1 'Bilge input 1 , alarmvar := 2 'Bilge input 2). This variable is for the Spinneret communications to tell the Spinneret which Bilge input was triggered and only needs to be sent until silenced by the Silence pushbutton. For exmaple when the Bilge input 1 is reset and is retriggered 3 seconds then resend an 1 for the variable "alarmvar" to the Spinneret

3) If the Bilge inputs are all off or the Silence pushbutton is pushed and released can turn off the alarm light, turn off RC4 channel 1 and stop sending Bilge input value for "alarmvar" to the Spinneret.

This part works for turning off Alarmlt and turning off RC4.

    if (((timer1 => 30) or (timer2 => 30)) and (ina[SilencePB] == 0))
      outa[AlarmLt] := 1
      if (lastrc4 <> %0001)
        set_rc4(%00, %0001)
        lastrc4 := %0001
    else
      outa[AlarmLt] := 0
      if (lastrc4 <> %0000)
        set_rc4(%00, %0000)
        lastrc4 := %0000

Where will I place the code to prevent from sending the values for "alarmval" when the Silence pusboutton is pushed?
William Stefan
The Basic Stamp Nut

JonnyMac

Easy -- just change the condition to:

  if ((timer1 == 30) and (SilencePB == 0))
    ' send alarm to Spinneret
Jon McPhalen
EFX-TEK Hollywood Office

bsnut

July 10, 2011, 08:48:07 PM #6 Last Edit: July 11, 2011, 08:14:09 PM by bsnut
I will try out your code in the morning and I see that you pulled this from your PBasic play book.
    timer1 := ++timer1 * ina[Bilge1]                            ' update timer1


I should've though of this one ;D
William Stefan
The Basic Stamp Nut

bsnut

July 15, 2011, 11:37:54 PM #7 Last Edit: July 16, 2011, 02:31:12 AM by bsnut
Jon,

I tried your code and it worked with no problems, but the only thing is I had to hold the Silence pushbutton in order to keep the Alarm light off. So, I went bark to the drawing board(the  computer) and started reading my code that I posted and noticed why I was having problems before I started this topic. Thanks to you, I started to look at my code again and noticed, when I turned on Bilge1 input and Bilge2 was off the Alarm light would blink. This was because, I was trying turn on the output Alarmlt when the code that wrote was telling it to turn off. 

So, I changed the code that matches my needs and let's me turn off the Alarm light without holding the Silence pushbutton and of course I used some of the coding tricks that you shown me. But, I am still having a minor problem with the code. The problem is after I added Bilge5 input(code in red), it for some reason it's not turning on the RC4 ch1 and pin22. But, rest of my code (in blue) works the way I want to. What do you think is causing my problem?
CON

  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000                                          ' use 5MHz crystal

  CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
  MS_001   = CLK_FREQ / 1_000
  US_001   = CLK_FREQ / 1_000_000

  Acbilgeloss     = 4
  Bilge1          = 5
  Bilge2          = 6
  Bilge3          = 7
  Bilge4          = 8
  Bilge5          = 9
  Silencepb       = 19
  Alarmlt         = 22

con

  RX1     = 31                                                  ' programming/debug
  TX1     = 30
  SIO     = 27                                                  ' TTL serial IO 
var
  byte timer1
  byte timer2
  byte timer3
  byte timer4
  byte timer5
  long alarmval
  long inastates

obj

  com1 : "fullduplexserial"                                     ' EFX device serial


pub main | t, lastrc4

  dira[22] := 1
 
  com1.start(SIO, SIO, %1100, 38_400)                           ' start EFX serial


  t := cnt
  repeat

    waitcnt(t += constant(MS_001 * 100))
   
    if timer1 == 30   'Enables silence code when "timer1" = 30
      if (ina[Silencepb] == 1) 'Turns off Alarmlt when Silencepb is pushed
        outa[Alarmlt] := 0       'Turns off Alarm Light
        set_rc4(%00, %0000)
         
    if timer1 < 30                    'Disables code when "timer1" = 30
      timer1 := ++timer1 * ina[Bilge1]     ' update timer1
      if timer1 == 30                               'Looks for "timer1" = 30
        outa[Alarmlt] := 1                        'Turns the Alarm Light on
        set_rc4(%00, %0001)



    if timer2 == 30
      if (ina[Silencepb] == 1)
        outa[Alarmlt] := 0
        set_rc4(%00, %0000)
 
   
    if timer2 < 30
      timer2 := ++timer2 * ina[Bilge2]
      if timer2 == 30
        outa[Alarmlt] := 1
        set_rc4(%00, %0001)
         


    if timer3 == 30
      if (ina[Silencepb] == 1)
        outa[Alarmlt] := 0
        set_rc4(%00, %0000)
 
   
    if timer3 < 30
      timer3 := ++timer3 * ina[Bilge3]
      if timer3 == 30
        outa[Alarmlt] := 1
        set_rc4(%00, %0001)

     

    if timer4 == 30
      if (ina[Silencepb] == 1)
        outa[Alarmlt] := 0
        set_rc4(%00, %0000)
 
   
    if timer4 < 30
      timer4 := ++timer4 * ina[Bilge4]
      if timer4 == 30
        outa[Alarmlt] := 1
        set_rc4(%00, %0001)

     

    if timer5 == 30
      if (ina[Silencepb] == 1)
        outa[Alarmlt] := 0
        set_rc4(%00, %0000)
 
   
    if timer5 < 30
      timer5 := ++timer5 * ina[Bilge5]
      if timer4 == 30
        outa[Alarmlt] := 1
        set_rc4(%00, %0001)





    inastates := ina[Bilge5..Bilge1]  'Store the states of INA in "inastates"
    if inastates == %00000            'Wait for all inputs to be off and turn off Alarmlt
      outa[Alarmlt] := 0
      set_rc4(%00, %0000)
      timer1 := 0                     'Clear all timers to 0
      timer2 := 0
      timer3 := 0
      timer4 := 0
      timer5 := 0
       

pub set_rc4(addr, relays)

'' Update RC-4 at 'addr' with bits in 'relays'
'' -- replaces: SEROUT Sio, Baud, ("!RC4", addr, "S", relays)

  com1.str(string("!RC4"))                                      ' header
  com1.tx(addr)                                                 ' address
  com1.tx("S")                                                  ' set command
  com1.tx(relays & $F)

         
 

William Stefan
The Basic Stamp Nut

bsnut

Jon,
Here is my final code and it works without any problems. One thing I can say, I talk myself and take a break away from the computer I'm able to think things out ;D . I also have to come back to the computer type it out and test the code that's in my brain.

I am wondering if my previous posted code was a timing issue ???. I would love to know why.     

CON

  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000                                          ' use 5MHz crystal

  CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
  MS_001   = CLK_FREQ / 1_000
  US_001   = CLK_FREQ / 1_000_000

  Acbilgeloss     = 4
  Bilge1          = 5
  Bilge2          = 6
  Bilge3          = 7
  Bilge4          = 8
  Bilge5          = 9
  Bilge6          = 10
  Bilge7          = 11
  Silencepb       = 19
  Alarmlt         = 22

con

  RX1     = 31                                                  ' programming/debug
  TX1     = 30
  SIO     = 27                                                  ' TTL serial IO 
var
  byte timer1
  byte timer2
  byte timer3
  byte timer4
  byte timer5
  byte timer6
  byte timer7
  long alarmval
  long silencevar
  long inastates

obj

 
  com1 : "fullduplexserial"                                     ' EFX device serial

pub main | t

  dira[22] := 1
 
  com1.start(SIO, SIO, %1100, 38_400)                           ' start EFX serial


  t := cnt

  repeat

    waitcnt(t += constant(MS_001 * 100))
   
    if (ina[Silencepb] == 1)
      outa[Alarmlt] := 1
      set_rc4(%00, %0000)

    if timer1 < 30   'Disables the call when "timer" = 30
      Bilgeinput1
    if timer2 < 30
      Bilgeinput2
    if timer3 < 30 
      Bilgeinput3
    if timer4 < 30 
      Bilgeinput4
    if timer5 < 30 
      Bilgeinput5
    if timer6 < 30
      Bilgeinput6
    if timer7 < 30
      Bilgeinput7

    inastates := ina[Bilge7..Bilge1]  'Store the states of INA in "inastates"
    if inastates == %0000000            'Wait for all inputs to be off and turn off Alarmlt
      outa[Alarmlt] := 0
      set_rc4(%00, %0000)
      timer1 := 0                     'Clear all timers to 0
      timer2 := 0
      timer3 := 0
      timer4 := 0
      timer5 := 0
      timer6 := 0
      timer7 := 0
      alarmval := 0

pub Bilgeinput1

                           
    timer1 := ++timer1 * ina[Bilge1]   ' update timer1
    if timer1 == 30                    'Looks for "timer1" = 30
      outa[Alarmlt] := 1               'Turns the Alarm Light on
      set_rc4(%00, %0001)
      alarmval := 1

pub Bilgeinput2

                           'Disables code when "timer1" = 30
    timer2 := ++timer2 * ina[Bilge2]   ' update timer1
    if timer2 == 30                    'Looks for "timer1" = 30
      outa[Alarmlt] := 1               'Turns the Alarm Light on
      set_rc4(%00, %0001)
      alarmval := 2

pub Bilgeinput3

                           'Disables code when "timer1" = 30
    timer3 := ++timer3 * ina[Bilge3]   ' update timer1
    if timer3 == 30                    'Looks for "timer1" = 30
      outa[Alarmlt] := 1               'Turns the Alarm Light on
      set_rc4(%00, %0001)
      alarmval := 3

pub Bilgeinput4

                           'Disables code when "timer1" = 30
    timer4 := ++timer4 * ina[Bilge4]   ' update timer1
    if timer4 == 30                    'Looks for "timer1" = 30
      outa[Alarmlt] := 1               'Turns the Alarm Light on
      set_rc4(%00, %0001)
      alarmval := 4

pub Bilgeinput5

                           'Disables code when "timer1" = 30
    timer5 := ++timer5 * ina[Bilge5]   ' update timer1
    if timer5 == 30                    'Looks for "timer1" = 30
      outa[Alarmlt] := 1               'Turns the Alarm Light on
      set_rc4(%00, %0001)
      alarmval := 5

pub Bilgeinput6

                           'Disables code when "timer1" = 30
    timer6 := ++timer6 * ina[Bilge6]   ' update timer1
    if timer6 == 30                    'Looks for "timer1" = 30
      outa[Alarmlt] := 1               'Turns the Alarm Light on
      set_rc4(%00, %0001)
      alarmval := 6

pub Bilgeinput7

                           'Disables code when "timer1" = 30
    timer7 := ++timer7 * ina[Bilge7]   ' update timer1
    if timer7 == 30                    'Looks for "timer1" = 30
      outa[Alarmlt] := 1               'Turns the Alarm Light on
      set_rc4(%00, %0001)
      alarmval := 7
     
pub set_rc4(addr, relays)

'' Update RC-4 at 'addr' with bits in 'relays'
'' -- replaces: SEROUT Sio, Baud, ("!RC4", addr, "S", relays)

  com1.str(string("!RC4"))                                      ' header
  com1.tx(addr)                                                 ' address
  com1.tx("S")                                                  ' set command
  com1.tx(relays & $F)                                       
William Stefan
The Basic Stamp Nut

JonnyMac

July 16, 2011, 08:05:09 AM #9 Last Edit: July 16, 2011, 08:09:58 AM by JonnyMac
Remember you can do things in loops to remove redundant code.  I would do something like this to simplify the program(which uses a new variable called alarmbits and moves the timers into an array)

  t := cnt
  repeat
    waitcnt(t += constant(MS_001 * 100))

    alarmbits := %000_0000                                      ' clear arm bits for scan
    repeat idx from 0 to 6                                      ' loop through inputs
      timer[idx] := (++timer[idx] * ina[Bilge1+idx]) <# 30      ' update timer
     
      if (timer[idx] == 30)                                     ' if alarm
        alarmbits |= 1 << idx                                   '  set channel bit
     
    if ((SilencePB == 0) and (alarmbits <> %000_0000))
      outa[AlarmLt] := 1
      set_rc4(%00, %0001)

      ' send alarmbits via Spinneret for external processing

    else
      outa[AlarmLt] := 0
      set_rc4(%00, %0000)


See how easy that is?  And we're not sending more than one command to the RC-4 every 100ms.  Another thing: You're not helping yourself by defining the timers as bytes.  The native variable type for the Propeller is the long so unless there is a really compelling reason to use a different type (e.g., we have to use bytes for serial buffers), you should just stick to longs to prevent Spin from having to do behind-the-scenes processing of the non-native type.

Jon McPhalen
EFX-TEK Hollywood Office

bsnut

July 16, 2011, 11:21:55 AM #10 Last Edit: July 16, 2011, 04:03:01 PM by bsnut
Thank-you Jon and I see what your talking about. I was thinking about this way that you are showing. But, I didn't how to index the variables.

When I do spin programs for now on, will just stick to naming my variables as longs and not as bytes. I can see now, how spin is different from PBasic with it's memory.

I will try out what you are talking about later on.
William Stefan
The Basic Stamp Nut