Shop OBEX P1 Docs P2 Docs Learn Events
Prop to Prop communication — Parallax Forums

Prop to Prop communication

PodionPodion Posts: 90
edited 2012-10-03 16:20 in Propeller 1
Hello

I have 2 prop, they work in series using the this http://forums.parallax.com/showthread.php?134641-DEMO-High-Speed-Multi-Prop-to-Prop-Communication

My problem is that i have 4 button to control 1 light. I have 2 ON and 2 OFF. Wen i click ON the light turn on but wen I click OFF on the client prop the light stay ON.

I what to know if it's possible to use 4 button to turn on and off a single light?

Client code
{{***************************************
*  HighSpeed Client        DEMO v1.0a *
*  Author: Beau Schwabe               *
*  Copyright (c) 2011 Parallax, Inc.  *               
*  See end of file for terms of use.  *               
***************************************


Revision History:
  Version 1.0   - (09/20/2011) initial release
  Version 1.0a  - (09/26/2011) minor change to detect When the USB plug is connected
                               to the PC.  This prevents unwanted resets.


}}
CON
  ' Set up the processor clock in the standard way for 80MHz on DemoBoard
  _CLKMODE      = xtal1 + pll16x
  _XINFREQ      = 5_000_000 + 0000


    RX_Pin       = 26
    TX_Pin       = 27
    Command      = 00  '' Feature not used in this demo
    Offset       = 0      '' Feature not used in this demo


    USB_Rx       = 31
    USB_Tx       = 30


    RANGE        = 23       'Range is 0 to RANGE.
    SAMPLES      = 2        'Number of samples to pick: 1 to RANGE + 1 
    temps        = 1
    _irrpin         = 0     'ir receiver module on this pin
        _device         = 0     'accept any device code
        _dlyrpt         = 6     'delay before acception code as repeat
{{  


Round Robin configuration using 2 Propellers:


   ┌────────────────────────────//────────────────────────────┐
   │ ┌─────────────────┐               ┌─────────────────┐    │
   │ │   Propeller 1   │               │   Propeller 2   │    │
   ┣─┤RX             TX├──┳───//───┳─┤RX             TX├──┫
    │     Client      │             │     Server      │    
    └─────────────────┘             └─────────────────┘    
  Vss                      Vss      Vss                      Vss
       


Round Robin configuration using 3 or more Propellers:


   ┌────────────────────────────/.../────────────────────────────────/.../────────────────────────────┐
   │ ┌─────────────────┐                  ┌─────────────────┐                  ┌─────────────────┐    │
   │ │   Propeller 2   │                  │   Propeller N   │                  │   Propeller 1   │    │
   ┣─┤RX             TX├──┳───/.../───┳─┤RX             TX├──┳───/.../───┳─┤RX             TX├──┫
    │     Client      │                │     Client      │                │     Server      │    
    └─────────────────┘                └─────────────────┘                └─────────────────┘    
  Vss                      Vss         Vss                      Vss         Vss                      Vss






Note: All resistors tied to Vss are 330 Ohm and are there to establish a transmission line
Note: All resistors between TX and RX are 100 Ohm and are there to current limit the I/O's in the chance
      of a collision.




With round robin, the idea is that you have one buffer that propagated around and around inside the
round robin loop.  To avoid any data collisions, all Propellers are capable of reading any location
within the buffer, however each Propeller has a specific (assigned by the programmer) location that
it can write to.


So in the Demo, there is a 1K long buffer (4K bytes).  As an example Propeller 1 may only write to
locations 0 to 255.  While Propeller 2 can write to locations 256 to 511.  Propellers 3 & 4 depicted
as N because of the expandable nature of round robin would write to the remaining 512 to 1023 locations.
 


}}
VAR


long   Buffer[10]
long   Buffer1[10]


byte   Pin[10]
long Stack[400],Stack1[400]


byte    numbers[RANGE + 1]
long    seed
long    keycode                                
OBJ
  hsRX   : "HSp2pRX"                       'High Speed Receive driver
  hsTX   : "HSp2pTX"                       'High Speed Transmit driver
  PST    : "Parallax Serial Terminal"      'RS232 Serial Driver
  rcvir : "ir_reader_sony"
   SN   : "Simple_Numbers"            
PUB Main   
 Start
PUB Main_IR
rcvir.init(_irrpin,_device,_dlyrpt,true)   'startup
Start_IR1   
PUB Start|debugLED
'-------------------------------------------------------------------------------------------
     if ina[USB_Rx] == 0        '' Check to see if USB port is powered
        outa[USB_Tx] := 0       '' Force Propeller Tx line LOW if USB not connected
     else
        cognew(SerialDisplay,@Stack)    '' Initialize serial communication to the PC


'-------------------------------------------------------------------------------------------                                                        
    dira[16..23]~~                                      '<- I/O direction for debug LEDs  
'-------------------------------------------------------------------------------------------     
    repeat 
      hsRX.RX(RX_Pin,@Buffer)                           '<- Receive Data from External Propeller
      hsTX.TX(TX_Pin,10,@Buffer,Command,Offset)       '<- Transmit Data to External Propeller
      
      
      hsTX.TX(TX_Pin,10,@Buffer1,Command,Offset)       '<- Transmit Data to External Propeller
      hsRX.RX(RX_Pin,@Buffer1)


      
     Menu_Principal  
     
'-------------------------------------------------------------------------------------------
     
'-------------------------------------------------------------------------------------------
PUB Start_IR1
                       
  repeat
    
    keycode := rcvir.fifo_get   'try a get from fifo
    if keycode == -1            'empty try again
      keycode := keycode + 1
      next
    else
    keycode := keycode + 1  
    
    Menu_Principal_IR
    
    
PUB Menu_Principal_IR
                                                                ' ~~=on ~=off
  dira[16..21]~~


                                                   
     
  [COLOR=#ff0000]case keycode
  
                
           1  : bytemove(@Buffer1,@IR_ON,strsize(@IR_ON))
               outa[16]~~
          129 : bytemove(@Buffer1,@IR_OFF,strsize(@IR_OFF))
                outa[16]~[/COLOR]
     
          
            
     2  : !outa[17]        
     3  : !outa[18]
     4  : !outa[19]
     5  : !outa[20]
     6  : !outa[21]
     7  :  outa[16..21]~~
     8  : LED
     9  : RANDOM
     22 :  outa[16..21]~            
PUB SerialDisplay               'DEBUG ONLY
    PST.Start(19200)
    repeat
      PST.HOME
      PST.dec(Buffer1[9] )                                  '<- Display Data
     
PUB Menu_Principal

  [COLOR=#ff0000]case Buffer[0]
   1: outa[16]~~
   0: outa[16]~ [/COLOR]


 
         
  outa[17] := Buffer[1]
  
  outa[18] := Buffer[2]
  
  outa[19] := Buffer[3]
  
  outa[20] := Buffer[4]
  
  outa[21] := Buffer[5]


PUB RANDOM | i, j, sample1, sample2
repeat 10 
   
     
  repeat i from 10 to RANGE                              'Fill numbers array in order.
     numbers[i] := i
     
     
  repeat i from 10 to (SAMPLES - 1)      
    j := ||?seed // (RANGE - i + 1) + i                 'Pick a number at random from the remaining choices.
    sample1 := numbers[j]
    bytemove(@numbers[i + 1], @numbers[i], j - i)       'Shift the values to make room.
    numbers[i] := sample1
     if sample1 < sample2
        sample2 := sample1
        waitcnt( _xinfreq / temps +cnt)
        outa[16..23]~
        waitcnt( _xinfreq / temps +cnt) 
        !outa[sample2]
                   
        next
        
     if sample1 > sample2
        sample2 := sample1
        waitcnt( _xinfreq / temps +cnt)
        outa[16..23]~
        waitcnt( _xinfreq / temps +cnt) 
        !outa[sample2]
                   
        next
     
     if sample1 == sample2
        j := ||?seed // (RANGE - i + 1) + i                 'Pick a number at random from the remaining choices.
        sample1 := numbers[j]
        bytemove(@numbers[i + 1], @numbers[i], j - i)       'Shift the values to make room.
        numbers[i] := sample1                
        next
                                    'Put the selected number in the newly vacated spot.
                    
  bytemove(@Buffer1,@NB1,strsize(@NB1))
   
 
PUB LED
  dira[16..23]~~
  outa[16..23]~ 
repeat 10 
   
   outa[16]~
  !outa[23]
  waitcnt ( _xinfreq  + cnt)
  !outa[23]
  !outa[22]
  waitcnt ( _xinfreq  + cnt)
  !outa[22]
  !outa[21]
  waitcnt ( _xinfreq  + cnt)
  !outa[21]
  !outa[20]
  waitcnt ( _xinfreq  + cnt)
  !outa[20]
  !outa[19]
  waitcnt ( _xinfreq  + cnt)
  !outa[19]
  !outa[18]
  waitcnt ( _xinfreq  + cnt)
  !outa[18]
  !outa[17]
  waitcnt ( _xinfreq  + cnt)
  !outa[17]
  !outa[16]
  waitcnt ( _xinfreq  + cnt)


outa[16]~


bytemove(@Buffer1,@NB2,strsize(@NB2))


DAT
NB1  BYTE 1,0
NB2  BYTE 2,0
PIN0 BYTE 0,0
PIN1 BYTE 1,0


IR_ON BYTE 1,0
IR_OFF BYTE 129,0 

Server code
{{
&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; 
Copyright (c) 2011 AgaveRobotics LLC.
See end of file for terms of use.


File....... HTTPServer.spin 
Author..... Mike Gebhard
Company.... Agave Robotics LLC
Email...... mailto:mike.gebhard@agaverobotics.com
Started.... 11/01/2010
Updated.... 07/16/2011        
&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; 
}}


{
About:
  HTTPServer is the designed for use with the Spinneret Web server manufactured by Parallax Inc.


Usage:
  HTTPServer is the top level object.
  Required objects:
        • Parallax Serial Terminal.spin
        • W5100_Indirect_Driver.spin
        • S35390A_SD-MMC_FATEngineWrapper.spin
        • Request.spin
        • Response.spin
        • StringMethods.spin
        • S35390A_RTCEngine.spin 


Change Log:
 
}




CON
  _clkmode = xtal1 + pll16x     
  _xinfreq = 5_000_000


  MAX_PACKET_SIZE = $5C0 '1472   '$800 = 2048
  RxTx_BUFFER     = $800         '$600 = 1536
  TEMP_BUFFER     = $600         '$5B4 = 1460 
  TCP_PROTOCOL    = 01        '$300 = 768 
  UDP_PROTOCOL    = 10        '$200 = 512 
  TCP_CONNECT     = $04          '$100 = 256                 
  DELAY           = $10
  MAX_TRIES       = $25                


  #0, DONE, PUT, CD
                                           
  RX_Pin       = 27
  TX_Pin       = 26
  Command      = 00  '' Feature not used in this demo
  Offsett       = 0      '' Feature not used in this demo
DAT
  mac                   byte    $00, $08, $DC, $16, $F2, $73
  subnet                byte    255, 255 ,255, 0
  gateway               byte    108,171,79,7  'WAN Default Gateway : 24.230.203.1
  ip                    byte    192,168,0,105  'LAN
  port                  word    5555
  remoteIp              byte    24,230,203,105 'http://www.whatismyip.com
  remotePort            word    80
  uport                 word    5050 
  emailIp               byte    0, 0, 0, 0
  emailPort             word    25
  status                byte    $00, $00, $00, $00   
  rxdata                byte    $0[RxTx_BUFFER]
  txdata                byte    $0[RxTx_BUFFER]
  udpdata               byte    $0[TEMP_BUFFER]
  fileErrorHandle       long    $0
  debug                 byte    $0
  lastFile              byte    $0[12], 0
  closedState           byte    00
  openState             byte    00
  listenState           byte    00
  establishedState      byte    00
  closingState          byte    00
  closeWaitState        byte    00 
  lastEstblState        byte    00
  lastEstblStateDebug   byte    00
  udpListen             byte    00
  tcpMask               byte    11
  udpMask               byte    00   
  fifoSocketDepth       byte    $0
  fifoSocket            long    $00_00_00_00
  debugSemId            byte    $00
  debugCounter          long    $00
  stringMethods         long    $00
  closingTimeout        long    $00, $00, $00, $00
  udpLen                long    $00
  time                  byte    "00/00/0000 00:00:00", 0
  httpDate              byte    "Wed, 01 Feb 2000 01:00:00 GMT", 0
  globalCache           byte    $1
                 


NB0   BYTE 999,0
NB1   BYTE 1,0
NB2   BYTE 2,0
NB3   BYTE 3,0
NB4   BYTE 4,0
NB5   BYTE 5,0
NB6   BYTE 6,0
NB7   BYTE 7,0
NB8   BYTE 8,0
NB9   BYTE 9,0
NB22    BYTE 22,0              
VAR
  long StackSpace[20]
  long stack[50]
  long    Buffer[10]
  long    Buffer1[10]
  byte    Pin[10]
OBJ
  pst           : "Parallax Serial Terminal"
  Socket        : "W5100_Indirect_Driver"
  SDCard        : "S35390A_SD-MMC_FATEngineWrapper"
  Request       : "Request"
  Response      : "Response"
  str           : "StringMethods"
  rtc           : "S35390A_RTCEngine"


  hsRX          : "HSp2pRX"                       'High Speed Receive driver
  hsTX          : "HSp2pTX"                       'High Speed Transmit driver
PUB Initialize | id, size, st , x


  debug := 1    
  SDCard.Start
  stringMethods := str.Start
  Request.Constructor(stringMethods)
  Response.Constructor(stringMethods, @txdata)


  pst.Start(115_200)
  pause(200) 


  'Mount the SD card
  pst.str(string("Mount SD Card - ")) 
  SDCard.mount(fileErrorHandle)
  pst.str(string("OK",13))
  
  pst.str(string("Start RTC: "))
  rtc.RTCEngineStart(29, 28, -1)
  
  pause(200)
  pst.str(FillTime)
    
  'Start the W5100 driver
  if(Socket.Start)
    pst.str(string(13, "W5100 Driver Started", 13))
    pst.str(string(13, "Status Memory Lock ID    : "))
    pst.dec(Socket.GetLockId)
    pst.char(13) 




  if(debugSemId := locknew) == -1
    pst.str(string("Error, no HTTP server locks available", 13))
  else
    pst.str(string("HTTP Server Lock ID      : "))
    pst.dec(debugSemId)
    pst.char(13)
    


  'Set the Socket addresses  
  SetMac(@mac)
  SetGateway(@gateway)
  SetSubnet(@subnet)
  SetIP(@ip)


  ' Initailize TCP sockets (defalut setting; TCP, Port, remote ip and remote port)
  repeat id from 0 to 3
    InitializeSocket(id)
    Request.Release(id)
    pause(50)


  ' Set all TCP sockets to listen
  pst.char(13) 
  repeat id from 0 to 3 
    Socket.Listen(id)
    pst.str(string("TCP Socket Listener ID   : "))
    pst.dec(id)
    pst.char(13)
    pause(50)


  pst.Str(string(13,"Started Socket Monitoring Service", 13))
   x := 6
  cognew(StatusMonitor, @StackSpace)
  pause(250)
 
  
  




  pst.Str(string(13, "Initial Socket States",13))
  StackDump


  pst.Str(string(13, "Initial Socket Queue",13))
  QueueDump


  pst.str(string(13,"//////////////////////////////////////////////////////////////",13))


  Main


   
PUB Main | packetSize, id, i, reset, j, temp
  ''HTTP Service
  repeat
    comm
    repeat until fifoSocket == 0
    
      bytefill(@rxdata, 0, RxTx_BUFFER)


      if(debug)
        pst.str(string(13, "----- Start of Request----------------------------",13))
        pause(DELAY)
      else
        pause(DELAY)
        
      ' Pop the next socket handle 
      id := DequeueSocket
      if(id < 0)
        next
      
      if(debug)
        pst.str(string(13,"ID: "))
        pst.dec(id)
        pst.str(string(13, "Request Count     : "))
        pst.dec(debugCounter)
        pst.char(13)


      packetSize := Socket.rxTCP(id, @rxdata)


      reset := false
      if ((packetSize < 12) AND (strsize(@rxdata) < 12))
        repeat i from 0 to MAX_TRIES
           pst.str(string(13,"* Retry *"))
          'Wait for a few moments and try again
          waitcnt((clkfreq/300 ) + cnt)
          packetSize := Socket.rxTCP(id, @rxdata)
          if(packetSize > 12)
            quit
          if(i == MAX_TRIES)
            'Clean up resource request   
            Request.Release(id)
            Socket.Disconnect(id)
            reset := true
            if(debug)
              StackDump
              pst.char(13)
              QueueDump
              pst.str(string(13,"* Timeout *",13))
            
      if(reset)
        next


      Request.InitializeRequest(id, @rxdata)
      
      if(debug)
        pst.char(13)
        HeaderLine1(id)
      else
        pause(DELAY)


      ' Process router
      Dispatcher(id)


      'Clean up request resource
      Request.Release(id)


      ' This starts the close process -> 0x00
      ' use close to force a close
      Socket.Disconnect(id)


      bytefill(@txdata, 0, RxTx_BUFFER)
      
      debugCounter++


  GotoMain
PUB comm


     dira[23]~~ 
 
  repeat 1
      
   
      hsTX.TX(TX_Pin,10,@Buffer,Command,Offsett)       '<- Transmit Data to External Propeller
      hsRX.RX(RX_Pin,@Buffer)                          '<- Receive Data from External Propeller 
                                     
      hsRX.RX(RX_Pin,@Buffer1)                         '<- Receive Data from External Propeller
      hsTX.TX(TX_Pin,10,@Buffer1,Command,Offsett)      '<- Transmit Data to External Propeller


          
    
  case Buffer1[0]
          1: outa[23]~~
          129: outa[23]~


  return
PRI SendLedResposne(id) | headerLen, qstr,qstr1
  '' Get the query string value
    comm
  qstr :=  Request.Get(id, string("led"))
    qstr1 := Buffer1[0]
  
  '' Exit if there is no querystring
    if(qstr == 0)
      return false
   
  '' Turn the LED on if the led= value is "on"  
  if  (strcomp(string("on"), qstr ))  or qstr1 == 1
    LedStatus(1)
     Buffer[0] := 1
     qstr1 := 1
     
   
   comm  
  if (strcomp(string("off"), qstr ))  or qstr1 == 129
    LedStatus(0)
     Buffer[0] := 0
     qstr1 := 129
     
  
   comm  
  if (strcomp(string("what"), qstr ))
    if(pin[0]) == 1 and qstr1 == 1
      qstr := string("on")
      qstr1 := 1
    else
      qstr := string("off") 
      qstr1 := 0    
   comm     
  '' Build and send the header
  '' Send the value of led= on or off
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  Socket.txTCP(id, qstr, strsize(qstr))
   comm 
  return true
PRI SendLedResposneA(id) | headerLen, qstr
  '' Get the query string value
  qstr :=  Request.Get(id, string("led"))
   
  '' Exit if there is no querystring
  if(qstr == 0)
    return false
   
  '' Turn the LED on if the led= value is "on"  
  if (strcomp(string("on"), qstr )) 
    LedStatus1(1)
    Buffer[1] := 1
  if (strcomp(string("off"), qstr )) 
    LedStatus1(0)
     Buffer[1] := 0
  if (strcomp(string("what"), qstr ))
    if(pin[1])== 1
      qstr := string("on")
    else
      qstr := string("off") 
          
        
  '' Build and send the header
  '' Send the value of led= on or off
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  Socket.txTCP(id, qstr, strsize(qstr))
   comm
  return true
PRI SendLedResposneB(id) | headerLen, qstr
  '' Get the query string value
  qstr :=  Request.Get(id, string("led"))
   
  '' Exit if there is no querystring
  if(qstr == 0)
    return false
   
  '' Turn the LED on if the led= value is "on"  
  if (strcomp(string("on"), qstr ))
    LedStatus2(1)
    Buffer[2] := 1
  if (strcomp(string("off"), qstr )) 
    LedStatus2(0)
     Buffer[2] := 0
  if (strcomp(string("what"), qstr ))
    if(pin[2])==1
      qstr := string("on")
    else
      qstr := string("off") 
          
        
  '' Build and send the header
  '' Send the value of led= on or off
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  Socket.txTCP(id, qstr, strsize(qstr))
   comm
  return true


PRI SendLedResposneC(id) | headerLen, qstr
  '' Get the query string value
  qstr :=  Request.Get(id, string("led"))
   
  '' Exit if there is no querystring
  if(qstr == 0)
    return false
   
  '' Turn the LED on if the led= value is "on"  
  if (strcomp(string("on"), qstr ))
    LedStatus3(1)
    Buffer[3] := 1
  if (strcomp(string("off"), qstr )) 
    LedStatus3(0)
     Buffer[3] := 0
  if (strcomp(string("what"), qstr ))
    if(pin[3])==1
      qstr := string("on")
    else
      qstr := string("off") 
          
        
  '' Build and send the header
  '' Send the value of led= on or off
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  Socket.txTCP(id, qstr, strsize(qstr))
   comm
  return true
PRI SendLedResposneD(id) | headerLen, qstr
  '' Get the query string value
  qstr :=  Request.Get(id, string("led"))
   
  '' Exit if there is no querystring
  if(qstr == 0)
    return false
   
  '' Turn the LED on if the led= value is "on"  
  if (strcomp(string("on"), qstr ))
    LedStatus4(1)
    Buffer[4] := 1
  if (strcomp(string("off"), qstr )) 
    LedStatus4(0)
     Buffer[4] := 0
  if (strcomp(string("what"), qstr ))
    if(pin[4])==1
      qstr := string("on")
    else
      qstr := string("off") 
          
        
  '' Build and send the header
  '' Send the value of led= on or off
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  Socket.txTCP(id, qstr, strsize(qstr))
   comm
  return true
PRI SendLedResposneE(id) | headerLen, qstr
  '' Get the query string value
  qstr :=  Request.Get(id, string("led"))
   
  '' Exit if there is no querystring
  if(qstr == 0)
    return false
   
  '' Turn the LED on if the led= value is "on"  
  if (strcomp(string("on"), qstr ))
    LedStatus5(1)
    Buffer[5] := 1
  if (strcomp(string("off"), qstr )) 
    LedStatus5(0)
     Buffer[5] := 0
  if (strcomp(string("what"), qstr ))
    if(pin[5])==1
      qstr := string("on")
    else
      qstr := string("off") 
          
        
  '' Build and send the header
  '' Send the value of led= on or off
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  Socket.txTCP(id, qstr, strsize(qstr))
   comm
  return true
PRI SendLedResposneF(id) | headerLen, qstr
  '' Get the query string value
  qstr :=  Request.Get(id, string("led"))
   
  '' Exit if there is no querystring
  if(qstr == 0)
    return false
   
  '' Turn the LED on if the led= value is "on"  
  if (strcomp(string("on"), qstr ))
    LedStatus6(1)
    Buffer[6] := 1
  if (strcomp(string("off"), qstr )) 
    LedStatus6(0)
     Buffer[6] := 0
  if (strcomp(string("what"), qstr ))
    if(pin[6])==1
      qstr := string("on")
    else
      qstr := string("off") 
          
        
  '' Build and send the header
  '' Send the value of led= on or off
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  Socket.txTCP(id, qstr, strsize(qstr))
   comm
  return true
PRI SendLedResposneG(id) | headerLen, qstr
  '' Get the query string value
  qstr :=  Request.Get(id, string("led"))
   
  '' Exit if there is no querystring
  if(qstr == 0)
    return false
   
  '' Turn the LED on if the led= value is "on"  
  if (strcomp(string("on"), qstr ))
    LedStatus7(1)
    Buffer[7] := 1
  if (strcomp(string("off"), qstr )) 
    LedStatus7(0)
     Buffer[7] := 0
  if (strcomp(string("what"), qstr ))
    if(pin[7])==1
      qstr := string("on")
    else
      qstr := string("off") 
          
        
  '' Build and send the header
  '' Send the value of led= on or off
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  Socket.txTCP(id, qstr, strsize(qstr))
   comm
  return true
PRI SendLedResposneH(id) | headerLen, qstr
  '' Get the query string value
  qstr :=  Request.Get(id, string("led"))
   
  '' Exit if there is no querystring
  if(qstr == 0)
    return false
   
  '' Turn the LED on if the led= value is "on"  
  if (strcomp(string("on"), qstr ))
    LedStatus8(1)
    Buffer[8] := 1
  if (strcomp(string("off"), qstr )) 
    LedStatus8(0)
     Buffer[8] := 0
  if (strcomp(string("what"), qstr ))
    if(pin[8])==1
      qstr := string("on")
    else
      qstr := string("off") 
          
        
  '' Build and send the header
  '' Send the value of led= on or off
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  Socket.txTCP(id, qstr, strsize(qstr))
   comm
  return true
PRI SendLedResposneI(id) | headerLen, qstr
  '' Get the query string value
  qstr :=  Request.Get(id, string("led"))
   
  '' Exit if there is no querystring
  if(qstr == 0)
    return false
   
  '' Turn the LED on if the led= value is "on"  
  if (strcomp(string("on"), qstr ))
    LedStatus9(1)
    Buffer[9] := 1
  if (strcomp(string("off"), qstr )) 
    LedStatus9(0)
     Buffer[9] := 0
  if (strcomp(string("what"), qstr ))
    if(pin[9])==1
      qstr := string("on")
    else
      qstr := string("off") 
          
        
  '' Build and send the header
  '' Send the value of led= on or off
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  Socket.txTCP(id, qstr, strsize(qstr))
   comm
  return true
PRI Dispatcher(id)
  ''Do some processing before sending the response
  comm
  Request.Get(id, string("led")) 
  comm      
  if(strcomp(Request.GetFileName(id), string("aled.htm"))  AND Request.GetDepth(id) == 1)     
    if(SendLedResposne(id))
       comm
      return
   comm   
  Request.Get(id, string("led"))    
  if(strcomp(Request.GetFileName(id), string("aleda.htm")) AND Request.GetDepth(id) == 1)     
    if(SendLedResposneA(id))
      return
  Request.Get(id, string("led"))    
  if(strcomp(Request.GetFileName(id), string("aledb.htm")) AND Request.GetDepth(id) == 1)     
    if(SendLedResposneB(id))
      return
  Request.Get(id, string("led"))    
  if(strcomp(Request.GetFileName(id), string("aledc.htm")) AND Request.GetDepth(id) == 1)     
    if(SendLedResposneC(id))
      return
  Request.Get(id, string("led"))    
  if(strcomp(Request.GetFileName(id), string("aledd.htm")) AND Request.GetDepth(id) == 1)     
    if(SendLedResposneD(id))
      return
  Request.Get(id, string("led"))    
  if(strcomp(Request.GetFileName(id), string("alede.htm")) AND Request.GetDepth(id) == 1)     
    if(SendLedResposneE(id))
      return
  Request.Get(id, string("led"))    
  if(strcomp(Request.GetFileName(id), string("aledf.htm")) AND Request.GetDepth(id) == 1)     
    if(SendLedResposneF(id))
      return
  Request.Get(id, string("led"))    
  if(strcomp(Request.GetFileName(id), string("aledg.htm")) AND Request.GetDepth(id) == 1)     
    if(SendLedResposneG(id))
      return
  Request.Get(id, string("led"))    
  if(strcomp(Request.GetFileName(id), string("aledh.htm")) AND Request.GetDepth(id) == 1)     
    if(SendLedResposneH(id))
      return
  Request.Get(id, string("led"))    
  if(strcomp(Request.GetFileName(id), string("aledi.htm")) AND Request.GetDepth(id) == 1)     
    if(SendLedResposneI(id))
      return      
  StaticFileHandler(id)
  comm
  return


  


PRI LedStatus(state) 
  pin[0] := state
  return
  
PRI LedStatus1(stateA)
  
  pin[1] := stateA
  return
  
PRI LedStatus2(stateB)
  
  pin[2] := stateB
  return
PRI LedStatus3(stateC)
  
  pin[3] := stateC
  return
PRI LedStatus4(stateD)
  
  pin[4] := stateD
  return
PRI LedStatus5(stateE)
  
  pin[5] := stateE
  return
PRI LedStatus6(stateF)
  
  pin[6] := stateF
  return
PRI LedStatus7(stateG)
  
  pin[7] := stateG
  return
PRI LedStatus8(stateH)
  
  pin[8] := stateH
  return
PRI LedStatus9(stateI)
  
  pin[9] := stateI
  return
PRI GotoMain
  Main
PRI StaticFileHandler(id) | fileSize, i, headerLen, temp, j
  ''Serve up static files from the SDCard
  
  'pst.str(string(13,"Static File Handler",13)) 
  SDCard.changeDirectory(@approot)
  pst.char(13)
  
  'Make sure the directory exists
  ifnot(ChangeDirectory(id))
    'send 404 error
    WriteError(id)
    SDCard.changeDirectory(@approot)
    return
    
  ' Make sure the file exists
  ifnot(FileExists(Request.GetFileName(id)))
    'send 404 error
    WriteError(id)
    SDCard.changeDirectory(@approot)
    return


  ' Open the file for reading
  SDCard.openFile(Request.GetFileName(id), "r")
  fileSize := SDCard.getFileSize


  'WriteResponseHeader(id)
  'BuildHeader(extension, statusCode, expirer)
  headerLen := Response.BuildHeader(Request.GetExtension(id), 200, globalCache)
  Socket.txTCP(id, @txdata, headerLen)
  
  if fileSize < MAX_PACKET_SIZE
    ' send the file in one packet
    SDCard.readFromFile(@txdata, fileSize)
    Socket.txTCP(id, @txdata, fileSize)
  else
    ' send the file in a bunch of packets 
    repeat
      SDCard.readFromFile(@txdata, MAX_PACKET_SIZE)  
      Socket.txTCP(id, @txdata, MAX_PACKET_SIZE)
      fileSize -= MAX_PACKET_SIZE
      ' once the remaining fileSize is less then the max packet size, just send that remaining bit and quit the loop
      if fileSize < MAX_PACKET_SIZE and fileSize > 0
        SDCard.readFromFile(@txdata, fileSize)
        Socket.txTCP(id, @txdata, fileSize)
        quit
   
      ' Bailout
      if(i++ > 1_000_000)
        WriteError(id)
        quit
     
  SDCard.closeFile
  SDCard.changeDirectory(@approot)
  return




  
PRI WriteError(id) | headerOffset
  '' Simple 404 error
  pst.str(string(13, "Write 404 Error",13 ))
  headerOffset := Response.BuildHeader(Request.GetExtension(id), 404, false)
  Socket.txTCP(id, @txdata, headerOffset)
  return




''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' directory and file handlers
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
PRI ChangeDirectory(id) | i, found
  'Handle directory structure for this Request
  if(Request.GetDepth(id) > 1)
    repeat i from 0 to Request.GetDepth(id)-2
      'Return if the directory is not found 
      ifnot(FileExists(Request.GetPathNode(id, i)))
        return false
      found := SDCard.changeDirectory(Request.GetPathNode(id, i))
  return true     




  
PRI FileExists(fileToCompare) | filenamePtr
'Start file find at the top of the list
  SDCard.startFindFile 
  'Verify that the file exists
  repeat while filenamePtr <> 0
    filenamePtr := SDCard.nextFile 
    if(str.MatchPattern(filenamePtr, fileToCompare, 0, false ) == 0 )
      return true


  return false


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Time Methods and Formats
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
PRI GetTime(id) | ptr, headerOffset
  ptr := @udpdata
  FillHttpDate
  
  bytemove(ptr, string("<p>"),3)
  ptr += 3


  bytemove(ptr, @httpDate, strsize(@httpDate))
  ptr += strsize(@httpDate)
  
  bytemove(ptr, string("</p>"),4)
  ptr += 3  


  headerOffset := Response.BuildHeader(Request.GetExtension(id), 200, false)
  Socket.txTCP(id, @txdata, headerOffset)
  StringSend(id, @udpdata)
  bytefill(@udpdata, 0, TEMP_BUFFER)
  
  return
 
 
PRI FillTime | ptr, num
 'ToString(integerToConvert, destinationPointer)
 '00/00/0000 00:00:00
  ptr := @time
  rtc.readTime
  


  FillTimeHelper(rtc.clockMonth, ptr)
  ptr += 3


  FillTimeHelper(rtc.clockDate, ptr)
  ptr += 3


  FillTimeHelper(rtc.clockYear, ptr)
  ptr += 5


  FillTimeHelper(rtc.clockHour , ptr)
  ptr += 3


  FillTimeHelper(rtc.clockMinute , ptr)
  ptr += 3


  FillTimeHelper(rtc.clockSecond, ptr) 
 
  return @time




PRI FillHttpDate | ptr, num, temp
 'ToString(integerToConvert, destinationPointer)
 'Wed, 01 Feb 2000 01:00:00 GMT
  ptr := @httpDate
  rtc.readTime




  temp := rtc.getDayString
  bytemove(ptr, temp, strsize(temp))
  ptr += strsize(temp) + 2


  FillTimeHelper(rtc.clockDate, ptr)
  ptr += 3


  temp := rtc.getMonthString
  bytemove(ptr, temp, strsize(temp))
  ptr += strsize(temp) + 1


  FillTimeHelper(rtc.clockYear, ptr)
  ptr += 5


  FillTimeHelper(rtc.clockHour , ptr)
  ptr += 3


  FillTimeHelper(rtc.clockMinute , ptr)
  ptr += 3


  FillTimeHelper(rtc.clockSecond, ptr)
  
  return @httpDate
 


PRI FillTimeHelper(number, ptr) | offset
  offset := 0
  if(number < 10)
    offset := 1
     
  str.ToString(@number, @tempNum)
  bytemove(ptr+offset, @tempNum, strsize(@tempNum))
  


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' SDCard Logger
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
PRI AppendLog(logToAppend)
  '' logToAppend:  Pointer to a string of test we'd like to log
  SDCard.changeDirectory(@approot) 


  if(FileExists(@logfile))
    SDCard.openFile(@logfile, "A")
  else
    SDCard.newFile(@logfile)


  SDCard.writeData(string(13,10,"----- Start "),14)
  SDCard.writeData(FillTime, 19)
  SDCard.writeData(string(" -----"),6)
  SDCard.writeData(@crlf_crlf, 2)


  SDCard.writeData(logToAppend, strsize(logToAppend))
  SDCard.writeData(@crlf_crlf, 2)
  
  SDCard.writeData(string("----- End "),10)
  SDCard.writeData(FillTime, 19)
  SDCard.writeData(string(" -----"),6)
  SDCard.writeData(@crlf_crlf, 2)


  SDCard.closeFile


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Memory Management
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
PRI Set(DestAddress, SrcAddress, Count)
  bytemove(DestAddress, SrcAddress, Count)
  bytefill(DestAddress+Count, $0, 1)
  


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Socekt helpers
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


PRI GetTcpSocketMask(id)
  return id & tcpMask


  
PRI DecodeId(value) | tmp
    if(01 & value)
      return 0
    if(10 & value)
      return 1
    if(00 & value)
      return 2 
    if(00 & value)
      return 3
  return -1




PRI QueueSocket(id) | tmp
  if(fifoSocketDepth > 4)
    return false


  tmp := |< id
  
  'Unique check
  ifnot(IsUnique(tmp))
    return false
    
  tmp <<= (fifoSocketDepth++) * 8
  
  fifoSocket |= tmp


  return true




PRI IsUnique(encodedId) | tmp
  tmp := encodedId & $0F
  repeat 4
    if(encodedId & fifoSocket)
      return false
    encodedId <<= 8
  return true 
    


PRI DequeueSocket | tmp
  if(fifoSocketDepth == 0)
    return -2
  repeat until not lockset(debugSemId) 
  tmp := fifoSocket & $0F
  fifoSocket >>= 8  
  fifoSocketDepth--
  lockclr(debugSemId)
  return DecodeId(tmp)


  
PRI ResetSocket(id)
  Socket.Disconnect(id)                                                                                                                                 
  Socket.Close(id)
  
PRI IsolateTcpSocketById(id) | tmp
  tmp := |< id
  tcpMask &= tmp




PRI SetTcpSocketMaskById(id, state) | tmp
'' The tcpMask contains the socket the the StatusMonitor monitors
  tmp := |< id
  
  if(state == 1)
    tcpMask |= tmp
  else
    tmp := !tmp
    tcpMask &= tmp 
    
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' W5100 Helper methods
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
PRI GetCommandRegisterAddress(id)
  return Socket#_S0_CR + (id * $0100)


PRI GetStatusRegisterAddress(id)
  return Socket#_S0_SR + (id * $0100)


    
PRI SetMac(_firstOctet)
  Socket.WriteMACaddress(true, _firstOctet)
  return 




PRI SetGateway(_firstOctet)
  Socket.WriteGatewayAddress(true, _firstOctet)
  return 




PRI SetSubnet(_firstOctet)
  Socket.WriteSubnetMask(true, _firstOctet)
  return 




PRI SetIP(_firstOctet)
  Socket.WriteIPAddress(true, _firstOctet)
  return 






PRI StringSend(id, _dataPtr)
  Socket.txTCP(id, _dataPtr, strsize(_dataPtr))
  return 




PRI SendChar(id, _dataPtr)
  Socket.txTCP(id, _dataPtr, 1)
  return 


 
PRI SendChars(id, _dataPtr, _length)
  Socket.txTCP(id, _dataPtr, _length)
  return 
         


PRI InitializeSocket(id)
  Socket.Initialize(id, TCP_PROTOCOL, port, remotePort, @remoteIp)
  return


PRI InitializeSocketForEmail(id)
  Socket.Initialize(id, TCP_PROTOCOL, port, emailPort, @emailIp)
  return
  
PRI InitializeUPDSocket(id)
  Socket.Initialize(id, UDP_PROTOCOL, uport, remotePort, @remoteIp)
  return




''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Debug/Display Methods
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
PRI QueueDump
  '' Display socket IDs in the queue
  '' ie 00000401 -> socket Zero is next to pop off
  pst.str(string("FIFO["))
  pst.dec(fifoSocketDepth)
  pst.str(string("] "))
  pst.hex(fifoSocket, 8)


    
PRI StackDump | clsd, open, lstn, estb, clwt, clng, id, ulst
  '' This method is purely for debugging
  '' It displays the status of all socket registers
  repeat until not lockset(debugSemId)
  clsd := closedState
  open := openState
  lstn := listenState
  estb := establishedState
  clwt := closeWaitState
  clng := closingState
  ulst := udpListen
  lockclr(debugSemId)


  pst.char(13) 
  repeat id from 3 to 0
    pst.dec(id)
    pst.str(string("-"))
    pst.hex(status[id], 2)
    pst.str(string(" "))
    pause(1)


  pst.str(string(13,"clsd open lstn estb clwt clng udps", 13))
  pst.bin(clsd, 4)
  pst.str(string("-"))
  pst.bin(open, 4)
  pst.str(string("-"))
  pst.bin(lstn, 4)
  pst.str(string("-"))  
  pst.bin(estb, 4)
  pst.str(string("-"))  
  pst.bin(clwt, 4)
  pst.str(string("-"))  
  pst.bin(clng, 4)
  pst.str(string("-"))  
  pst.bin(ulst, 4)
  pst.char(13)
   
PRI HeaderLine1(id) | i
  pst.str(Request.GetMethod(id))
  pst.char($20)


  i := 0
  repeat Request.GetDepth(id)
    pst.char($2F)
    pst.str(Request.GetPathNode(id, i++))
    
   
PRI Pause(Duration)  
  waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt)
  return




PRI StatusMonitor | id, tmp, value
'' StatusMonitor is the heartbeat of the project
'' Here we monitor the state of the Wiznet 5100's 4 sockets
  repeat


    Socket.GetStatus32(@status[0])


    ' Encode status register states
    repeat until not lockset(debugSemId)


    closedState := openState := listenState := establishedState := {
     } closeWaitState := closingState := 0
     
    repeat id from 0 to 3
      case(status[id])
        $00: closedState               |= |< id
             closedState               &= tcpMask  
        $13: openState                 |= |< id
             openState                 &= tcpMask                   
        $14: listenState               |= |< id
             listenState               &= tcpMask
        $17: establishedState          |= |< id
             establishedState          &= tcpMask
        $18,$1A,$1B: closingState      |= |< id
                     closingState      &= tcpMask
        $1C: closeWaitState            |= |< id
             closeWaitState            &= tcpMask
        $1D: closingState              |= |< id
             closingState              &= tcpMask
        $22: udpListen                 |= |< id
             udpListen                 &= udpMask 


    if(lastEstblState <> establishedState)
      value := establishedState
      repeat while value > 0
        tmp := DecodeId(value)
        if(tmp > -1)
          QueueSocket(tmp)
          tmp := |< tmp
          tmp := !tmp
          value &= tmp
      lastEstblState := establishedState


    lockclr(debugSemId)
    
    ' Initialize a closed socket 
    if(closedState > 0)
      id := DecodeId(closedState)
      if(id > -1)
        InitializeSocket(id & tcpMask)
    
    'Start a listener on an initialized/open socket   
    if(openState > 0)
      id := DecodeId(openState)
      if(id > -1)
        Socket.Listen(id & tcpMask)


    ' Close the socket if the status is close/wait
    ' response processor should close the socket with disconnect
    ' there could be a timeout so we have a forced close.
    ' TODO: CCheck for a port that gets stuck in a closing state
    'if(closeWaitState > 0)
      'id := DecodeId(closeWaitState)
      'if(id > -1)
        'Socket.Close(id & tcpMask)






    'pause(100)
return
    
DAT
  approot               byte    "\", 0 
  defaultpage           byte    "index.htm", 0
  logfile               byte    "log.txt", 0
  'binFile               byte    "filename.bin", 0
  FS                    byte    "/", 0
  fn                    byte    "filename=", 0
  doublequote           byte    $22, 0
  crlf                  byte    13, 10, 0
  crlf_crlf             byte    13, 10, 13, 10, 0
  uploadfile            byte    $0[12], 0
  uploadfolder          byte    "uploads", 0
  tempNum               byte    "0000",0
  multipart             byte    "Content-Type: multipart/form-data; boundary=",0
  boundary              byte    $2D, $2D
  boundary1             byte    $0[64]
  'loadme                file    "TogglePin0.binary"                 


Comments

  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-09-29 18:49
    not sure if this will help or not, but I would think that changing this :
               1  : bytemove(@Buffer1,@IR_ON,strsize(@IR_ON))
                   outa[16]~~
              129 : bytemove(@Buffer1,@IR_OFF,strsize(@IR_OFF))
                    outa[16]~
    

    To :
               1  : bytemove(@Buffer1,@IR_ON,strsize(@IR_ON))
                   outa[16]~~
              129 : bytemove(@Buffer1,@IR_OFF,strsize(@IR_OFF))
                    DIRA[16]~~
    

    will fix your problem
  • PodionPodion Posts: 90
    edited 2012-09-29 19:05
    not sure if this will help or not, but I would think that changing this :
               1  : bytemove(@Buffer1,@IR_ON,strsize(@IR_ON))
                   outa[16]~~
              129 : bytemove(@Buffer1,@IR_OFF,strsize(@IR_OFF))
                    outa[16]~
    

    To :
               1  : bytemove(@Buffer1,@IR_ON,strsize(@IR_ON))
                   outa[16]~~
              129 : bytemove(@Buffer1,@IR_OFF,strsize(@IR_OFF))
                    DIRA[16]~~
    

    will fix your problem

    Ok I will give it a try ! Thank you. :-)
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-09-29 19:06
    Podion wrote: »
    I what to know if it's possible to use 4 button to turn on and off a single light?

    Short answer: Yes, it is possible.

    I don't know it it's possible with the code you're using.

    It looks like one of your Props uses Beau's Prop to Prop code while the other uses Mike G's Spinnerete code.

    I wouldn't think the two would communicate with each other.

    I don't see Beau's objects used in the second Prop's code anywhere (there's a lot going on in the server code so I may have missed it).


    Edit: I did miss seeing Beau's code. Sorry. That's a lot a code to wade through. It might help to write some simple Prop to Prop test code without all the internet stuff.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2012-09-29 20:30
    I also use :
    DIRA[16]~~
    
    OUTA[16] := 1 ' On
    ' or
    OUTA[16] := 0 ' Off
    
  • idbruceidbruce Posts: 6,197
    edited 2012-09-30 05:48
    Podion

    Yes, it is not only possible, but they do it in residential electrical construction all the time. I don't have the switching combinations down as in poles and throws, but here is how it is done with very common three-way and four way switches, with 120V single phase wiring. The same principle can be adapted by using switches with the appropriate poles and throws.

    Bruce

    EDIT: What is your current wiring schematic for the light and pushbuttons?
    EDIT: In fact, with this type of configuration, the number of switching locations is pratically endless. Just keep adding four-way switches in between the two three-way switches.
    718 x 432 - 29K
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-09-30 07:33
    idbruce wrote: »
    here is how it is done with very common three-way and four way switches, with 120V single phase wiring. The same principle can be adapted by using switches with the appropriate poles and throws.

    Bruce,

    I suppose we can let Podion correct us, but my interpretation of the problem was to have push buttons connected to two different Props. Each Prop would have an "on" and a "off" button. My guess is, these "on" and "off" buttons should control a LED on only one of the Props.

    By using microcontrollers, the wiring can be kept very simple since the uC can take care of the logic.
  • idbruceidbruce Posts: 6,197
    edited 2012-09-30 07:41
    @Duane
    I suppose we can let Podion correct us, but my interpretation of the problem was to have push buttons connected to two different Props. Each Prop would have an "on" and a "off" button. My guess is, these "on" and "off" buttons should control a LED on only one of the Props.

    Whatever the case, I believe the logic would be equal to the switch states of the circuitry shown. And I believe that if it was controlled logically, as in 1s and 0s, I believe it could be done with four single pole pushbuttons.
  • idbruceidbruce Posts: 6,197
    edited 2012-09-30 07:48
    In fact, I think that might be a cool object for the OBEX. Using single pole pushbuttons as three-way and four-way switches to control a lighting circuit.

    Something such as the functions: AddThreeWayPB(PIN), AddFourWay(PIN)

    If the logic was correct, a person could control a light circuit from numerous locations.

    EDIT: More like this
    AddThreeWayPBs(3W_START_PIN, 3W_END_PIN, LIGHT_PIN), AddFourWayPB(PIN, LIGHT_PIN)
    EDIT: With the addition of more functions such as GetThreeWayState(PIN), SetThreeWayState(PIN), GetFourWayState(PIN), SetFourWayState(PIN)

    EDIT: However, if spare pins are available, the same circuitry could be replicated with the spare pins

    EDIT: Or simply tie the light to a pin, monitor the state as on or off, and if one of the pushbuttons is pressed, simply change the state of the light pin.
  • PodionPodion Posts: 90
    edited 2012-09-30 18:43
    @Duane Degn your are rite.

    There is a code that I simplify. The principle is the same, 2 prop work in serial to control 1 light via 2 ON button and 2 OFF. Each prop have is own ON/OFF button. In reality those button are a IR remote. remote code 1 = On 2=Off / 3=On 4=Off.

    The 3 way don't work for this. the logic of the tree way : Off+Off=Off, On+Off=On, On+On=Off, Off+On=On and this is not what i want.

    {{***************************************
    *  HighSpeed Server         DEMO v1.0 *
    *  Author: Beau Schwabe               *
    *  Copyright (c) 2011 Parallax, Inc.  *               
    *  See end of file for terms of use.  *               
    ***************************************
    
    
    Revision History:
      Version 1.0   - (09/20/2011) initial release
    
    
    
    
    }}
    CON
      ' Set up the processor clock in the standard way for 80MHz on DemoBoard
      _CLKMODE      = xtal1 + pll16x
      _XINFREQ      = 5_000_000 + 0000
    
    
        RX_Pin       = 27
        TX_Pin       = 26
        Command      = 00  '' Feature not used in this demo
        Offset       = 0      '' Feature not used in this demo
        '--------------------------------------------------------
        _irrpin      = 24     'ir receiver module on this pin
        _device      = 0      'accept any device code
        _dlyrpt      = 6      'delay before acception code as repeat
    
    
    {{
    
    
    Round Robin configuration using 2 Propellers:
    
    
       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;//&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
       &#9474; &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;               &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;    &#9474;
       &#9474; &#9474;   Propeller 1   &#9474;               &#9474;   Propeller 2   &#9474;    &#9474;
       &#9507;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9523;&#9472;&#9472;&#9472;//&#9472;&#9472;&#9472;&#9523;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9515;
       &#61628; &#9474;     Client      &#9474;    &#61628;        &#61628; &#9474;     Server      &#9474;    &#61628;
       &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;        &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;
      Vss                      Vss      Vss                      Vss
           
    
    
    Round Robin configuration using 3 or more Propellers:
    
    
       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
       &#9474; &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;                  &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;                  &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;    &#9474;
       &#9474; &#9474;   Propeller 2   &#9474;                  &#9474;   Propeller N   &#9474;                  &#9474;   Propeller 1   &#9474;    &#9474;
       &#9507;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9523;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9523;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9523;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9523;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9515;
       &#61628; &#9474;     Client      &#9474;    &#61628;           &#61628; &#9474;     Client      &#9474;    &#61628;           &#61628; &#9474;     Server      &#9474;    &#61628;
       &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;           &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;           &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;
      Vss                      Vss         Vss                      Vss         Vss                      Vss
    
    
    
    
    
    
    Note: All resistors tied to Vss are 330 Ohm and are there to establish a transmission line
    Note: All resistors between TX and RX are 100 Ohm and are there to current limit the I/O's in the chance
          of a collision.
    
    
    
    
    With round robin, the idea is that you have one buffer that propagated around and around inside the
    round robin loop.  To avoid any data collisions, all Propellers are capable of reading any location
    within the buffer, however each Propeller has a specific (assigned by the programmer) location that
    it can write to.
    
    
    So in the Demo, there is a 1K long buffer (4K bytes).  As an example Propeller 1 may only write to
    locations 0 to 255.  While Propeller 2 can write to locations 256 to 511.  Propellers 3 & 4 depicted
    as N because of the expandable nature of round robin would write to the remaining 512 to 1023 locations.
     
    
    
    }}
    VAR
    
    
    long   Buffer[10]
    long    Buffer1[10]
    long    keycode
    long    cogStack[500]
    long    stack[20]
    
    
    OBJ
      hsRX   : "HSp2pRX"                       'High Speed Receive driver
      hsTX   : "HSp2pTX"                       'High Speed Transmit driver
      rcvir  : "ir_reader_sony"
       SN    : "Simple_Numbers"
      
    PUB Main
     
     Start_IR
    PUB Start_IR
       rcvir.init(_irrpin,_device,_dlyrpt,true)   'startup  
        Start_IR1
    
    
    PUB Start_IR1
                           'start the tv terminal
      
      dira[23]~~
      
      repeat
        start
        start1 
        keycode := rcvir.fifo_get   'try a get from fifo
        if keycode == -1            'empty try again
          next
        else
        keycode := keycode + 1
                
           
        
    
    
    
    
    PUB start
    
    
          case keycode
           1 :  bytemove(@Buffer,@NB1,strsize(@NB1))' <- Moves TestMessage into Buffer 
           2 :  bytemove(@Buffer,@NB2,strsize(@NB2))
           3 :  bytemove(@Buffer,@NB3,strsize(@NB3))
           4 :  bytemove(@Buffer,@NB4,strsize(@NB4))
           5 :  bytemove(@Buffer,@NB5,strsize(@NB5))
           6 :  bytemove(@Buffer,@NB6,strsize(@NB6))
           7 :  bytemove(@Buffer,@NB7,strsize(@NB7))
           8 :  bytemove(@Buffer,@NB8,strsize(@NB8))
           9 :  bytemove(@Buffer,@NB9,strsize(@NB9))
           22 : bytemove(@Buffer,@NB22,strsize(@NB22))
           other : bytemove(@Buffer,@NB0,strsize(@NB0))
           
          
    pub start1
          
          comm      
    PUB comm      
        repeat 1
      
         
          hsTX.TX(TX_Pin,10,@Buffer,Command,Offset)       '<- Transmit Data to External Propeller
          hsRX.RX(RX_Pin,@Buffer)
                                    '<- Receive Data from External Propeller     
          hsRX.RX(RX_Pin,@Buffer1)
          hsTX.TX(TX_Pin,10,@Buffer1,Command,Offset)       '<- Transmit Data to External Propeller
          
        return
                
    Dat
    NB0   BYTE 999,0
    NB1   BYTE 1,0
    NB2   BYTE 2,0
    NB3   BYTE 3,0
    NB4   BYTE 4,0
    NB5   BYTE 5,0
    NB6   BYTE 6,0
    NB7   BYTE 7,0
    NB8   BYTE 8,0
    NB9   BYTE 9,0
    NB22    BYTE 22,0
    CON
    





    {{
    ***************************************
    *  HighSpeed Client        DEMO v1.0a *
    *  Author: Beau Schwabe               *
    *  Copyright (c) 2011 Parallax, Inc.  *               
    *  See end of file for terms of use.  *               
    ***************************************
    
    
    Revision History:
      Version 1.0   - (09/20/2011) initial release
      Version 1.0a  - (09/26/2011) minor change to detect When the USB plug is connected
                                   to the PC.  This prevents unwanted resets.
    
    
    }}
    CON
      ' Set up the processor clock in the standard way for 80MHz on DemoBoard
      _CLKMODE      = xtal1 + pll16x
      _XINFREQ      = 5_000_000 + 0000
    
    
        RX_Pin       = 27
        TX_Pin       = 26
        Command      = 00  '' Feature not used in this demo
        Offset       = 0      '' Feature not used in this demo
    
    
        USB_Rx       = 31
        USB_Tx       = 30
    
    
        RANGE        = 23       'Range is 0 to RANGE.
        SAMPLES      = 2        'Number of samples to pick: 1 to RANGE + 1 
        temps        = 1
    
    
         _irrpin     = 0     'ir receiver module on this pin
        _device      = 0      'accept any device code
        _dlyrpt      = 6      'delay before acception code as repea
    {{  
    
    
    Round Robin configuration using 2 Propellers:
    
    
       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;//&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
       &#9474; &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;               &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;    &#9474;
       &#9474; &#9474;   Propeller 1   &#9474;               &#9474;   Propeller 2   &#9474;    &#9474;
       &#9507;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9523;&#9472;&#9472;&#9472;//&#9472;&#9472;&#9472;&#9523;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9515;
       &#61628; &#9474;     Client      &#9474;    &#61628;        &#61628; &#9474;     Server      &#9474;    &#61628;
       &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;        &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;
      Vss                      Vss      Vss                      Vss
           
    
    
    Round Robin configuration using 3 or more Propellers:
    
    
       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
       &#9474; &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;                  &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;                  &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;    &#9474;
       &#9474; &#9474;   Propeller 2   &#9474;                  &#9474;   Propeller N   &#9474;                  &#9474;   Propeller 1   &#9474;    &#9474;
       &#9507;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9523;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9523;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9523;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9523;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9515;
       &#61628; &#9474;     Client      &#9474;    &#61628;           &#61628; &#9474;     Client      &#9474;    &#61628;           &#61628; &#9474;     Server      &#9474;    &#61628;
       &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;           &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;           &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;
      Vss                      Vss         Vss                      Vss         Vss                      Vss
    
    
    
    
    
    
    Note: All resistors tied to Vss are 330 Ohm and are there to establish a transmission line
    Note: All resistors between TX and RX are 100 Ohm and are there to current limit the I/O's in the chance
          of a collision.
    
    
    
    
    With round robin, the idea is that you have one buffer that propagated around and around inside the
    round robin loop.  To avoid any data collisions, all Propellers are capable of reading any location
    within the buffer, however each Propeller has a specific (assigned by the programmer) location that
    it can write to.
    
    
    So in the Demo, there is a 1K long buffer (4K bytes).  As an example Propeller 1 may only write to
    locations 0 to 255.  While Propeller 2 can write to locations 256 to 511.  Propellers 3 & 4 depicted
    as N because of the expandable nature of round robin would write to the remaining 512 to 1023 locations.
     
    
    
    }}
    VAR
    
    
    long    Buffer[10]
    long    Buffer1[10]
    long Stack[400]
    long Stack1[400]
    
    
    byte    numbers[RANGE + 1]
    long    seed
    long    keycode                                
    OBJ
      hsRX   : "HSp2pRX"                       'High Speed Receive driver
      hsTX   : "HSp2pTX"                       'High Speed Transmit driver
      PST    : "Parallax Serial Terminal"      'RS232 Serial Driver
       rcvir : "ir_reader_sony"
       SN   : "Simple_Numbers"         
    PUB Main
     rcvir.init(_irrpin,_device,_dlyrpt,true)   'startup
     Start_IR1     
    PUB start|debugLED
    '-------------------------------------------------------------------------------------------                                                      
                                             '<- I/O direction for debug LEDs  
    '-------------------------------------------------------------------------------------------     
        repeat 
          hsRX.RX(RX_Pin,@Buffer)                           '<- Receive Data from External Propeller
          hsTX.TX(TX_Pin,10,@Buffer,Command,Offset)       '<- Transmit Data to External Propeller
          
          
          hsTX.TX(TX_Pin,10,@Buffer1,Command,Offset)       '<- Transmit Data to External Propeller
          hsRX.RX(RX_Pin,@Buffer1)
          
          
          Menu_Principal
    '-------------------------------------------------------------------------------------------
         
    '-------------------------------------------------------------------------------------------
    PUB Start_IR1
      dira [16]~~
     
      repeat
        
        keycode := rcvir.fifo_get   'try a get from fifo
        if keycode == -1            'empty try again
          next
        else
        keycode := keycode + 1  
        
       case keycode
        3: outa[16] := 1 
        4: outa[16] := 0
      return  
    PUB Menu_Principal
      dira [16]~~
      case Buffer
       1: outa[16] := 1
       2: outa[16] := 0
         
    Dat
    
    
    NB2   BYTE 1,0  
    


    Client_DEMO.spinHSp2pRX.spinHSp2pTX.spinir_reader_sony.spinMain.spinServer_DEMO.spinSimple_Numbers.spin
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2012-10-01 00:48
    I'll look at your code tomorrow (ahem later today) ... I suspect though you could have each propeller with a switch act like a one shot to a specific memory address that you are passing to all of the other propellers. This way if anybody gives an ON signal the memory address gets set, otherwise, if anybody sends an OFF signal the memory address gets cleared. Doing that would allow for 2-propellers, 3-propellers, ... N-propellers, whatever to control the same lighting
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2012-10-01 07:07
    Podion,

    One thing I see in the Client portion of your code is that you are never calling the PUB start|debugLED routine.... where you have the High speed RX and TX routines. Also, you should be able to do this using only one buffer instead of two. That would eliminate some redundancy with transmitting and receiving.

    When attaching files, can you use the File-->Archive-->Project and then attach the resulting file? This makes sure that we have all of the pieces when trying to look at code.

    Thanks.

    I'll try to setup a demo using some of my original code to show how a 3-way or even a 4-Way switch might work as I explained in an earlier post.
  • PodionPodion Posts: 90
    edited 2012-10-01 10:46
    The PUB start|debugLED is manage by the Main.spin

    Main.spin


    CON  
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      
    
    
    VAR
    
    
      long  cogStack[400]
      long  routine1_cog, routine2_cog, routine3_cog
     
    OBJ
     
      IR    :       "Client_DEMO"
      
    PUB Go  
    
    
     waitcnt(cnt + (clkfreq * 2))
      
     cognew(Parallel_Routine_1, @cogStack[0])
     cognew(Parallel_Routine_2, @cogStack[200])
    
    
    PUB Parallel_Routine_1
       IR.start
    PUB Parallel_Routine_2
      IR.Main 
    
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2015-09-27 00:45
    Podion,

    I just went from your latest example... in that, the PUB start|debugLED routine was not referenced. None the less, here is a bit of revised DEMO code from my original code that shows how to implement a switch function across multiple Propellers to control lights, etc.

    On each Propeller the 'switch' acts like a one-shot, where it's only acted upon if there is a change in its state. If there is a change in state, that state gets passed along to the other Propellers in the loop. Both Clients and Server have control of a memory address (pre defined in your code) that determines if the lights are on or off. Note: the DEMO uses the 8 leds built into the Propeller Demo board and/or the Propeller QuickStart as well as the Def-Con badges.

    Because the switches are setup in one-shot mode, there is a possibility that you may want to turn the lights OFF but the switch at your location is already OFF. In this case you will need to turn the switch ON, and then OFF to take control of the lighting. The opposite is true if you want to turn the lights ON and the switch position at your location is already ON. You must first turn your switch OFF and then back ON. If however your switch matches the current state of the lighting situation, then all you need to do is move your switch to the desired position.
  • PodionPodion Posts: 90
    edited 2012-10-03 15:20
    I replace the PUB start|debugLED by PUB comm on the server side.
  • PodionPodion Posts: 90
    edited 2012-10-03 16:20
    I tried to adapt your code in mine and I'm not successful. I do not know if it's because I use an IR code and I have no real switch, in my code the IR keycode is the switch. The light i want to control is only plug to the client propeller.
    {{***************************************
    *  HighSpeed Client        DEMO v1.0a *
    *  Author: Beau Schwabe               *
    *  Copyright (c) 2011 Parallax, Inc.  *               
    *  See end of file for terms of use.  *               
    ***************************************
    
    
    Revision History:
      Version 1.0   - (09/20/2011) initial release
      Version 1.0a  - (09/26/2011) minor change to detect When the USB plug is connected
                                   to the PC.  This prevents unwanted resets.
    
    
    }}
    CON
      ' Set up the processor clock in the standard way for 80MHz on DemoBoard
      _CLKMODE      = xtal1 + pll16x
      _XINFREQ      = 5_000_000 + 0000
    
    
        RX_Pin       = 27
        TX_Pin       = 26
        Command      = %0000  '' Feature not used in this demo
        Offset       = 0      '' Feature not used in this demo
    
    
        USB_Rx       = 31
        USB_Tx       = 30
    
    
        RANGE        = 23       'Range is 0 to RANGE.
        SAMPLES      = 2        'Number of samples to pick: 1 to RANGE + 1 
        temps        = 1
    
    
         _irrpin     = 0     'ir receiver module on this pin
        _device      = 0      'accept any device code
        _dlyrpt      = 6      'delay before acception code as repea 
    {{   
    
    
    Round Robin configuration using 2 Propellers:
    
    
       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;//&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
       &#9474; &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;               &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;    &#9474;
       &#9474; &#9474;   Propeller 1   &#9474;               &#9474;   Propeller 2   &#9474;    &#9474;
       &#9507;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9523;&#9472;&#9472;&#9472;//&#9472;&#9472;&#9472;&#9523;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9515;
       &#61628; &#9474;     Client      &#9474;    &#61628;        &#61628; &#9474;     Server      &#9474;    &#61628;
       &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;        &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;
      Vss                      Vss      Vss                      Vss
           
    
    
    Round Robin configuration using 3 or more Propellers:
    
    
       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
       &#9474; &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;                  &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;                  &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;    &#9474;
       &#9474; &#9474;   Propeller 2   &#9474;                  &#9474;   Propeller N   &#9474;                  &#9474;   Propeller 1   &#9474;    &#9474;
       &#9507;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9523;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9523;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9523;&#9472;&#9472;&#9472;/.../&#9472;&#9472;&#9472;&#9523;&#9472;&#9508;RX             TX&#9500;&#9472;&#61629;&#61630;&#9472;&#9515;
       &#61628; &#9474;     Client      &#9474;    &#61628;           &#61628; &#9474;     Client      &#9474;    &#61628;           &#61628; &#9474;     Server      &#9474;    &#61628;
       &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;           &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;           &#61464; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#61464;
      Vss                      Vss         Vss                      Vss         Vss                      Vss
    
    
    
    
    
    
    Note: All resistors tied to Vss are 330 Ohm and are there to establish a transmission line
    Note: All resistors between TX and RX are 100 Ohm and are there to current limit the I/O's in the chance
          of a collision.
    
    
    
    
    With round robin, the idea is that you have one buffer that propagated around and around inside the
    round robin loop.  To avoid any data collisions, all Propellers are capable of reading any location
    within the buffer, however each Propeller has a specific (assigned by the programmer) location that
    it can write to.
    
    
    So in the Demo, there is a 1K long buffer (4K bytes).  As an example Propeller 1 may only write to
    locations 0 to 255.  While Propeller 2 can write to locations 256 to 511.  Propellers 3 & 4 depicted
    as N because of the expandable nature of round robin would write to the remaining 512 to 1023 locations.
     
    
    
    }}
    VAR
    
    
    long    Buffer[10]
    long    Buffer1[10]
    long Stack[400]
    long Stack1[400]
    
    
    byte    numbers[RANGE + 1]
    long    seed
    long    keycode                                
    OBJ
      hsRX   : "HSp2pRX"                       'High Speed Receive driver
      hsTX   : "HSp2pTX"                       'High Speed Transmit driver
      PST    : "Parallax Serial Terminal"      'RS232 Serial Driver
       rcvir : "ir_reader_sony"
       SN   : "Simple_Numbers"         
    PUB Main
     rcvir.init(_irrpin,_device,_dlyrpt,true)   'startup
     Start_IR1     
    PUB start|debugLED
      
        repeat
         
          hsRX.RX(RX_Pin,@Buffer)                           '<- Receive Data from External Propeller 
          hsTX.TX(TX_Pin,10,@Buffer,Command,Offset)       '<- Transmit Data to External Propeller
    
    
          hsTX.TX(TX_Pin,10,@Buffer1,Command,Offset)       '<- Transmit Data to External Propeller
          hsRX.RX(RX_Pin,@Buffer1)
    
    
          Menu_Principal  
    
    
    PUB Start_IR1
    
    
      dira [16]~~
      
      repeat
        
        keycode := rcvir.fifo_get   'try a get from fifo
        if keycode == -1            'empty try again
          next
        else
        keycode := keycode + 1  
        
    [COLOR=#ff0000]    case keycode[/COLOR]
    [COLOR=#ff0000]      3: outa[16] := 1          'LED ON  Control by client  [/COLOR]
    [COLOR=#ff0000]      4: outa[16] := 0          'LED OFF Control by client    [/COLOR]
      return       
    PUB Menu_Principal
    
    
      dira [16]~~
      
      case Buffer
    [COLOR=#ff0000]    1: outa[16] := 1           'LED ON  Control by server[/COLOR]
    [COLOR=#ff0000]    2: outa[16] := 0           'LED OFF  Control by server
    
    [/COLOR]
Sign In or Register to comment.