Shop OBEX P1 Docs P2 Docs Learn Events
433MHz module: Translate basic to spin — Parallax Forums

433MHz module: Translate basic to spin

CrosswindsCrosswinds Posts: 182
edited 2012-03-29 12:18 in Propeller 1
Hello Guys!

Trying to control some wall-outlet relays, wich is cordless and works on the 433MHz band. I am completely new to the wireless stuff with propeller, and have never used it on another platform either.

I have found a protocol for the recievers, and also code that works with PIC (Basic, PBASIC?)


The protocol can be found following this link: http://svn.telldus.com/svn/rf_ctrl/nexa_2_6_driver/trunk/NexaProtocol.txt

And here is the Pbasic code:
DEFINE OSC 4

' Timing as described in NexaProtocol.txt
T CON 350      ' T = 350uS
T3 CON 1050    ' 3T
T32 CON 11200  ' 32T (Stop/Synch)

' Note we're using 1 VS X as shown in text
A1_ON  CON %111000000000 ' 12-bit code for House/Unit A1 ON
A1_OFF CON %011000000000 ' 12-bit code for House/Unit A1 OFF 

'           ||||||||||||____ 4-bit House code
'           ||||||||________ 4-bit Unit code
'           ||||____________ 3-bit Unknown code
'           |_______________ 1-bit Activation code 1=ON 0=OFF 

D_PACKET VAR WORD ' Holds 12-bit data packet to send
INDEX VAR BYTE    ' Data packet bit index pointer
LOOPS VAR BYTE    ' Loop counter

TX VAR PORTB.0    ' Connects to RF transmitter data in

LOW TX            ' TX output idles low for RF carrier OFF

Main:
    D_PACKET = A1_ON
    GOSUB Send
    PAUSE 5000
    D_PACKET = A1_OFF
    GOSUB Send
    PAUSE 5000
    GOTO Main
    
Send:
    FOR LOOPS = 1 TO 4    ' send each packet 4 times
      FOR INDEX = 0 TO 11 ' sends 12 bits per pass LSB 1st
        
        HIGH TX           ' The 1st half of a 0 or X  bit period is the
        PAUSEUS T         ' same so no need to repeat this sequence inside
        LOW TX            ' the IF block
        PAUSEUS T3 
        
        IF D_PACKET.0[INDEX]=1 THEN
           HIGH TX        ' send a 1 bit (1=X here)
           PAUSEUS T3
           LOW TX
           PAUSEUS T
        ELSE
           HIGH TX        ' send a 0 bit
           PAUSEUS T
           LOW TX
           PAUSEUS T3
        ENDIF
      NEXT INDEX          ' loop until all 12-bits sent
      
      ' Start of Stop/Synch period after each 12-bit packet
      HIGH TX
      PAUSEUS T
      LOW TX
      PAUSEUS T32
      ' End of Stop/Synch period
      
    NEXT LOOPS        ' send 4 packets per pass
    RETURN
      
    END



It would be great if someone could help me translate this to spin, so that i have a test-code as a kickstart.

The code above does also use the parallax module, but way back when they came separated as sender and reciever.



Iam very excited to get started with this project, so any help will be greatly appreciated!


Thanks guys.


Daniel

Comments

  • Mark_TMark_T Posts: 1,981
    edited 2012-03-27 10:09
    If you edit the post and add the code in code tags, that might help - you've lost all the indentation.
  • CrosswindsCrosswinds Posts: 182
    edited 2012-03-27 10:51
    Oh! Sorry, didnt notice that, Done!
  • CrosswindsCrosswinds Posts: 182
    edited 2012-03-28 10:35
    Come on guys! :)

    Some assistance please? =)
  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-28 11:48
    Have a look at the BS2_Functions object in the Propeller Object Exchange. This has most of the operations you need like LOW / HIGH / PAUSE. Everything else is pretty straightforward Spin with the REPEAT statement taking the place of the FOR / NEXT. You'll have to learn Spin, but there are some good introductions now ... start with the Propeller Education Kit Labs.

    Alternatively, you could use PropBasic which has some similarities to your PICBasic and gets translated into Spin and Propeller Assembly Language.
  • CrosswindsCrosswinds Posts: 182
    edited 2012-03-28 14:21
    Hey Mike, as usual thank you for your reply :)

    Is there any direct equivalent for LOW / HIGH / PAUSE in spin? I think that i will manage the repeat loops, but i got stuck really at the basics on how the transmitter works. Often there are a object wich you can look at and with the help of that translate the code.

    I have a bit experience of spin, but there are some methodes used with the transmitter that im not familliar with.
  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-28 14:27
    LOW x

    OUTA[x]~
    DIRA[x]~~

    HIGH x

    OUTA[x]~~
    DIRA[x]~~

    PAUSE x

    WAITCNT((CLKFREQ/1000)*x + CNT)

    If you've already done the DIRA[x]~~ somewhere in your initialization code, you don't have to do it again. I put it here because, strictly speaking, the LOW and HIGH statements put the I/O pin into output mode.
  • CrosswindsCrosswinds Posts: 182
    edited 2012-03-28 16:29
    Mike Green wrote: »
    LOW x

    OUTA[x]~
    DIRA[x]~~

    HIGH x

    OUTA[x]~~
    DIRA[x]~~

    PAUSE x

    WAITCNT((CLKFREQ/1000)*x + CNT)

    If you've already done the DIRA[x]~~ somewhere in your initialization code, you don't have to do it again. I put it here because, strictly speaking, the LOW and HIGH statements put the I/O pin into output mode.

    That was just stupid of me to not think of the standard outa and dira.. Jesus, you shouldnt put down the coding project for more then a week :)




    CON
    
    A1_ON = %111000000000
    
    
    Var
    
    byte counter
    byte counter2
    
    word D_PACKET
    
    
    PUB Main
    
    D_PACKET := A1_ON
    
    Repeat counter from 1 to 4
    
      Repeat counter2 from 0 to 11
    
        OUTA[1]~~
        DIRA[1]~~
        WAITCNT((CLKFREQ/1000)*350 + CNT)
        OUTA[1]~
        DIRA[1]~~
    
        
        OUTA[1]~~
        DIRA[1]~~
        WAITCNT((CLKFREQ/1000)*1050 + CNT)
    
    
          IF D_PACKET[counter2] := 1
            OUTA[1]~~
            DIRA[1]~~
            WAITCNT((CLKFREQ/1000)*1050 + CNT)
            OUTA[1]~
            DIRA[1]~~
            WAITCNT((CLKFREQ/1000)*350 + CNT
    
          ELSE
            OUTA[1]~~
            DIRA[1]~~
            WAITCNT((CLKFREQ/1000)*350 + CNT)
            OUTA[1]~
            DIRA[1]~~
            WAITCNT((CLKFREQ/1000)*1050 + CNT)
    
      OUTA[1]~~
      DIRA[1]~~
      WAITCNT((CLKFREQ/1000)*350 + CNT)
      OUTA[1]~
      DIRA[1]~~
      WAITCNT((CLKFREQ/1000)*11200 + CNT)
            
          
          
        
    
        
        
        
      
        
     
                       
    
        
        
        
      
        
     
                   
    


    Is this somewere right or should i stop right now?








    /Daniel
  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-28 17:35
    "IF D_Packet[counter2] := 1" won't work for several reasons. One, ":=" is the assignment operator, not a comparison operator. "==" compares for equal. Two, D_PACKET is a word, not a bit array and bits are not addressable in Spin. You have to process them using the bit logical operators. There are lots of ways to do what you want. This is one possibility: "IF (D_PACKET & |< counter2) <> 0". By the way, don't use extra indenting unless it's needed for something. I think you want the "repeat counter2 from 0 to 11" statement just before the IF statement with the extra indentation. Also, you can leave them in, but you really only need one DIRA[1]~~ at the beginning of your program. It stays in effect until changed.
  • CrosswindsCrosswinds Posts: 182
    edited 2012-03-29 09:36
    Hello Mike!

    Thank you very much for your help. I did the changes you mentioned, but no luck. Dont get any response from the reciever.


    I also tried to move down the repeat 0-11 but that dont change the result. Are you sure that it should only include the if-statements? Because to me it looks like it includes everything in the basic code.

    Anyway, i tried it both ways no luck. Its hard to tell whats happening since its wireless :)

    Any ideas?

    Heres the code:
    CON
    
    A1_ON = %111000000000
    
    Pin = 24
    
    
    Var
    
    byte counter
    byte counter2
    
    word D_PACKET
    
    
    PUB Main
    
    
    
    OUTA[25]~~
    DIRA[25]~~
    
    D_PACKET := A1_ON
    
    
    
     Repeat counter from 1 to 4
    
       Repeat counter2 from 0 to 11
    
        OUTA[Pin]~~
        DIRA[Pin]~~
        WAITCNT((CLKFREQ/1000)*350 + CNT)
        OUTA[Pin]~
        DIRA[Pin]~~
    
        
        OUTA[Pin]~~
        DIRA[Pin]~~
        WAITCNT((CLKFREQ/1000)*1050 + CNT)
    
         
        IF (D_PACKET & |< counter2) <> 0
            OUTA[Pin]~~
            DIRA[Pin]~~
            WAITCNT((CLKFREQ/1000)*1050 + CNT)
            OUTA[Pin]~
            DIRA[Pin]~~
            WAITCNT((CLKFREQ/1000)*350 + CNT)
        ELSE
            OUTA[Pin]~~
            DIRA[Pin]~~
            WAITCNT((CLKFREQ/1000)*350 + CNT)
            OUTA[Pin]~
            DIRA[Pin]~~
            WAITCNT((CLKFREQ/1000)*1050 + CNT)
    
      OUTA[Pin]~~
      DIRA[Pin]~~
      WAITCNT((CLKFREQ/1000)*350 + CNT)
      OUTA[Pin]~
      DIRA[Pin]~~
      WAITCNT((CLKFREQ/1000)*11200 + CNT)
    
    
  • CrosswindsCrosswinds Posts: 182
    edited 2012-03-29 10:32
    I noticed that we didnt put a DIRA on the pin from beginning, corrected that, but still no luck..
  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-29 10:36
    You need to fix your indenting. It's crucial.
    REPEAT ...
       <indent one level>
       REPEAT ...
         <indent two levels>
       'There would be a NEXT here
       'Not a part of the inner repeat
    'There would be a next here
    'Not a part of the outer repeat
    <more code not in the repeats>
    
  • CrosswindsCrosswinds Posts: 182
    edited 2012-03-29 10:48
    Mike, please take a look at the attached spin-file.

    Having a hard time understanding what im doing wrong with the indention. I feel that every line after the IF block should be included in the loop for the total packets (4), and i think it is.

    Its hard to describe, but please have a look.
  • CrosswindsCrosswinds Posts: 182
    edited 2012-03-29 11:31
    Hold your horses mike, i may have solved it
  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-29 11:47
    I've cleaned up your code and showed how I would have used constants and subroutines. I still think the indenting is wrong in terms of the nested loops and that's why it doesn't work.
  • CrosswindsCrosswinds Posts: 182
    edited 2012-03-29 12:18
    Hello Mike, I have solved it now. There were nothing wrong with the indention, but with the timing, it should not be ms, its us. I hooked it up to the oscilloscope and noticed that it was way to slow.
    So it works great now. And thanks for your clean code, some good pointers there!

    Thank you very much for all your help.
Sign In or Register to comment.