1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

12F675 with RF315 module

Discussion in 'Oshonsoft' started by mastero, May 7, 2016.

  1. mastero

    mastero Member

    Joined:
    Nov 27, 2011
    Messages:
    69
    Likes:
    1
    Hello all,


    I am trying to use RF module with PIC12f675.

    My code till now.

    TX CODE:
    ********************************************************************
    Dim i As Byte

    CMCON = 7

    TRISIO = %00001111

    Symbol led = GPIO.5
    loop:
    led = 0
    If GPIO.3 = 0 Then
    Serout GPIO.4, 9600, "1", CrLf
    Toggle led
    Endif

    If GPIO.0 = 0 Then
    Serout GPIO.4, 9600, "2", CrLf
    Toggle led
    Endif

    If GPIO.1 = 0 Then
    Serout GPIO.4, 9600, "3", CrLf
    Toggle led
    Endif
    If GPIO.2 = 0 Then
    Serout GPIO.4, 9600, "4", CrLf
    Toggle led
    Endif
    Goto loop
    *********************************************************
    RX CODE:
    *********************************************************
    Dim i As Byte
    Symbol led = GPIO.0

    CMCON = 7
    TRISIO = %00100000
    GPIO.1 = 0
    GPIO.2 = 0

    loop:
    led = 0
    Serin GPIO.5, 9600, i
    If i > 0 Then
    Gosub check
    Else
    Gosub loop
    Endif

    check:
    If i = "1" Then
    GPIO.1 = 1
    Toggle led
    Else

    If i = "2" Then
    GPIO.1 = 0
    Toggle led
    Else

    If i = "3" Then
    GPIO.2 = 1
    Toggle led
    Else

    If i = "4" Then
    GPIO.2 = 0
    Toggle led
    Endif
    Endif
    Endif
    Endif
    Gosub loop
    End
    ************************************************************************

    This code works perfect....

    Instead of one digit i want to send say ten digit at the press of a button.

    how to ?? any idea shall be good

    Thanx in advance.

    Mastero
     
  2. mastero

    mastero Member

    Joined:
    Nov 27, 2011
    Messages:
    69
    Likes:
    1
    Like seriously .... no one ?
     
  3. sagor1

    sagor1 Member

    Joined:
    Dec 11, 2014
    Messages:
    52
    Likes:
    2
    Not sure what you are going to do with 10 digits if all you can decode on the RX is 4 states. Regardless, if you want to send more than one digit, simply make the string longer, or concatenate the data like:
    Serout GPIO.4, 9600, "1","2","3", CrLf

    On the receive side, you would have to read all characters and re-assemble them into the format you want, and look for the "Cr" or Lf" as a read terminator. You would have to loop on a single character read until you hit that Cr character, read the LF and dump it, then build your read string.

    Another option would be to encode a byte as a hex value, anywhere from 0 to 255 (0x255), and process that as a result on a single character read.

    Also, look into using the read interrupt bit for the software uart, as to not get hung on a read that does not come. You can also use an un-used GPIO input pin as a read interrupt signal.
    Finally, use the "AllDigital" at the start of the code, easier than setting CMCON and ANSEL ( you are missing ANSEL = 0 in your code) if your code is all digital states.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. mastero

    mastero Member

    Joined:
    Nov 27, 2011
    Messages:
    69
    Likes:
    1

    Still no luck

    What am i doing wrong?

    TX-CODE

    Code (C):



    Define CONF_WORD = 0x3194
    Define CLOCK_FREQUENCY = 4
    'Define SIMULATION_WAITMS_VALUE = 1

    AllDigital
    TRISIO = %00000000

    Dim i As Byte
    Dim datatimer As Byte
    Dim delaycount As Byte

    Symbol led = GPIO.2
    Symbol vdd = GPIO.1

    i = 0
    led = 1
    vdd = 0
    datatimer = 200
    delaycount = 200

    '
    ****************************************************
    WaitMs 1000
    led = 0

    ASM:        bsf STATUS,RP0 ;bank 1
    ASM:        call 3ffh ;get the cal value
    ASM:        movwf OSCCAL ;calibrate
    ASM:        bcf STATUS,RP0 ;bank 0
    ASM:

    main:

    Gosub decrement_counters
    Gosub senddata

    Goto main
    End                                              

    '****************************************************

    decrement_counters:
        If delaycount = 0 Then


            If datatimer > 0 Then
                datatimer = datatimer - 1
            Endif

            delaycount = 200
        Else
            delaycount = delaycount - 1
        Endif
    Return                                            

    '
    ****************************************************
    senddata:

    If datatimer = 0 Then
        vdd = 1
        led = 1
        Serout GPIO.0, 9600, "+", "A", "B", "C", "D", "E", "#", CrLf
        vdd = 0
        WaitMs 50
        led = 0

        datatimer = 200
    Endif

    Return                                            



     
    RX-CODE:

    Code (C):


    Define CONF_WORD = 0x3194
    Define CLOCK_FREQUENCY = 4

    'Define SIMULATION_WAITMS_VALUE = 1

    AllDigital
    TRISIO = %00000001

    Dim i As Long
    Dim k As Byte
    Dim j As Byte
    Dim data(20) As Byte
    Dim serdata As Byte
    Dim allok As Bit
    Dim startmark As Bit
    Dim temp As Byte

    Symbol led = GPIO.2
    Symbol relay = GPIO.1

    j = 0
    i = 0
    k = 0
    led = 1
    relay = 1
    allok = False
    startmark = False

    WaitMs 1000

    relay = 0
    led = 0

    For k = 0 To 20 Step 1  '
    clear buffer
            data(k) = 0x00
    Next k

    ASM:        bsf STATUS,RP0 ;bank 1
    ASM:        call 3ffh ;get the cal value
    ASM:        movwf OSCCAL ;calibrate
    ASM:        bcf STATUS,RP0 ;bank 0

    main:

        Gosub loop
        Gosub dodata

    Goto main
        End

    loop:
    j = 0
    i = 0
    k = 0
    startmark = False
    allok = False

    loop_nr:
                Serin GPIO.0, 9600, serdata
                    If serdata > 0 Then

                        If serdata = "+" Then
                            startmark = True
                        Endif

                        If serdata = "#" And startmark = True Then
                            startmark = False
                            allok = True
                        Endif

                        If startmark = True Then
                            data(j) = serdata  'store data in buffer
                            If j = 20 Then
                                j = 0
                            Else
                                j = j + 1
                            Endif
                            Goto loop_nr
                        Endif

            Endif
        Return

    dodata:

    If allok = True Then
    If data(1) = "A" Then
    If data(2) = "B" Then
    If data(3) = "C" Then
    If data(4) = "D" Then
    If data(5) = "E" Then


    relay = 1
    WaitMs 10000
    relay = 0
    allok = False

    For k = 0 To 20 Step 1  '
    clear buffer
            data(k) = 0x00
    Next k


    Endif
    Endif
    Endif
    Endif
    Endif
    Endif
        Return


     

    Help me please someone :(
     
    Last edited: May 16, 2016
  6. sagor1

    sagor1 Member

    Joined:
    Dec 11, 2014
    Messages:
    52
    Likes:
    2
    First, do the ASM code after the start of the program (after i=0, led=1). It needs to be only done before the main "loop". Second, a RX program will not see those " marks, those denote Ascii characters to send in the sending routine. The RX routine should just be looking for the + sign first, then the A, then the B, and so on.
    Your "Lookup" function seems pointless, just check if serdata = "+" (or start trigger), then trigger the loop to read the rest.
    Waiting 100Ms between characters will miss the next character after the "startmark" is set...

    Back up a bit here. Simply do a RX read loop looking for the start, store the characters received until the CR or LF is received (accounting for overflow - then error). Only then, start to process the entire buffer in a separate loop to parse if the buffer is correct. You could even double the buffer size to account for out-of-sync messages, just look for the first + (or start) character as start of message.

    PS: I have not looked at the continuity of the code itself, but running this in the simulator should show any logic bugs.
     
    Last edited: May 15, 2016
  7. mastero

    mastero Member

    Joined:
    Nov 27, 2011
    Messages:
    69
    Likes:
    1
    Did the change still no luck........ above code has been edited
     
  8. sagor1

    sagor1 Member

    Joined:
    Dec 11, 2014
    Messages:
    52
    Likes:
    2
    I tested the RX code in the simulator, works as it should, but:
    1) You should clear the buffer/received array after toggling the LED pin
    2) You code is missing the config definitions. I used (internal OSC, everything else cleared):
    Define CONFIG = 0x3194
    3) You do not need the CMCON if you use "AllDigital", it sets it.

    I send the string "+ABCDE# in the software terminal emulator (define GPIO.0 as input), one byte at a time. You code seems to work (does not save the last "#", but not relevant).
    Code for RX: (I have to comment out the ASM code in suimulator as simulator reads invalid data). Un-comment the ASM code for real compile.

    Will look at TX code when I have time...




    Define CONFIG = 0x3194

    AllDigital
    TRISIO = %00000001

    'Define SIMULATION_WAITMS_VALUE = 1

    Dim i As Long
    Dim k As Byte
    Dim j As Byte
    Dim data(20) As Byte
    Dim serdata As Byte
    Dim allok As Bit
    Dim startmark As Bit
    Dim temp As Byte

    Symbol led = GPIO.2
    Symbol relay = GPIO.1

    j = 0
    i = 0
    k = 0
    led = 1
    relay = 1
    allok = False
    startmark = False

    WaitMs 1000

    relay = 0
    led = 0

    'ASM: bsf STATUS,RP0 ;bank 1
    'ASM: call 3ffh ;get the cal value
    'ASM: movwf OSCCAL ;calibrate
    'ASM: bcf STATUS,RP0 ;bank 0

    main:

    Gosub loop
    Gosub dodata

    Goto main
    End

    loop:
    j = 0
    i = 0
    k = 0
    startmark = False
    allok = False

    loop_nr:
    Serin GPIO.0, 9600, serdata

    If serdata > 0 Then

    If serdata = "+" Then
    startmark = True
    Endif

    If serdata = "#" And startmark = True Then
    startmark = False
    allok = True
    Endif

    If startmark = True Then
    data(j) = serdata 'store data in buffer
    If j = 20 Then
    j = 0
    Else
    j = j + 1
    Endif
    Goto loop_nr
    Endif

    Endif
    Return

    dodata:
    If allok = True Then
    If data(1) = "A" Then
    If data(2) = "B" Then
    If data(3) = "C" Then
    If data(4) = "D" Then
    If data(5) = "E" Then

    relay = 1
    WaitMs 10000
    relay = 0
    allok = False

    Endif
    Endif
    Endif
    Endif
    Endif
    Endif
    Return
     
  9. sagor1

    sagor1 Member

    Joined:
    Dec 11, 2014
    Messages:
    52
    Likes:
    2
    Checked the TX code, it does what it is supposed to. No need for the CrLf at the end, as that just adds more garbage characters that are not needed by the RX code anyway. Again, make sure you define the config flags, define the Mhz as well (I missed that in the RX code as well - make sure you define the frequency so the compiler knows how to do the serial timings!)
    Your datatimer and delaycount add up to almost 1 second total (I make it about 0.8 to 0.88 seconds)
    Enable the ASM: code as well...

    Code:
    Define CONFIG = 0x3194

    'Define SIMULATION_WAITMS_VALUE = 1
    Define CLOCK_FREQUENCY = 4.0


    AllDigital
    TRISIO = %00000000
    Dim i As Byte
    Dim datatimer As Byte
    Dim delaycount As Byte
    Symbol led = GPIO.2
    Symbol vdd = GPIO.1

    i = 0
    led = 1
    vdd = 0
    datatimer = 200
    delaycount = 200

    '****************************************************
    WaitMs 1000
    led = 0

    'ASM: bsf STATUS,RP0 ;bank 1
    'ASM: call 3ffh ;get the cal value
    'ASM: movwf OSCCAL ;calibrate
    'ASM: bcf STATUS,RP0 ;bank 0
    'ASM:
    main:

    Gosub decrement_counters
    Gosub senddata

    Goto main
    End

    '****************************************************

    decrement_counters:
    If delaycount = 0 Then


    If datatimer > 0 Then
    datatimer = datatimer - 1
    Endif

    delaycount = 200
    Else
    delaycount = delaycount - 1
    Endif
    Return

    '****************************************************
    senddata:

    If datatimer = 0 Then
    vdd = 1
    led = 1

    Serout GPIO.0, 9600, "+", "A", "B", "C", "D", "E", "#", CrLf
    vdd = 0
    WaitMs 50
    led = 0

    datatimer = 200
    Endif

    Return
     
  10. mastero

    mastero Member

    Joined:
    Nov 27, 2011
    Messages:
    69
    Likes:
    1
    sagor did the change still no luck ..... look at the code above
     
  11. sagor1

    sagor1 Member

    Joined:
    Dec 11, 2014
    Messages:
    52
    Likes:
    2
    Like I said, the code works in the simulator as I posted it. I notice there are longer delays in the RX code (delay 10S) vs the TX code which sends about every second or so. The RX code will not get characters until it has finished its timings, and goes back to read again.
    Also, have you checked the calibration factor in the 12F675 chips? A full erasure will remove the proper values, and clock speeds will vary a lot, enough to cause errors in serial data rates. Also, if fully erased, including the OSCCAL value, the code may crash and simply repeat from start. One must ensure the OSCCAL value is there. For example, one of my 675 chips has an OSCCAL of 3420 hex. OSCCAL is located at address 0x3FF (last byte of program ram). A PicKit2 (or 3) has a tool that can automatically regenerate the proper OSCCAL value and write it to that location.

    Another debugging method is to put in a few more LED flashes though the code (in non-critical areas). So, one flash is start of code, two flashes is start of uart send, etc. I would put in an error indicator in RX if J hits 20, you should really exit at that point as the data is too scrambled. Do a several LED flash in that case and exit.

    Now, how are the TX and RX connected to each other? If using a wire to test, that is the best option to make sure the communications is correct. Make sure you have a pull-up resistor on that TX/RX line (about 10k will do), and same ground between the PICs. Only once the comm is working can you look at other means to connect the two PICs for communications.

    You have an error in zeroing the data array. An array of 20 starts at 0, ends at 19, not 20. Your zero loops should read 0 to 19. That also means you cannot check for 20 in the read loop, since you cannot store a value in data(20), it does not exist

    Otherwise I see no reason why the code should not work. You can try lowering the speeds to 1200baud or something like that to reduce the amount of error if it is timing related.
     
  12. mastero

    mastero Member

    Joined:
    Nov 27, 2011
    Messages:
    69
    Likes:
    1
    The connection is via 315mhz Rf modules.

    One character works fine but when I send multiple character there is an issue and it does not read well.

    Very frustrating
     
  13. sagor1

    sagor1 Member

    Joined:
    Dec 11, 2014
    Messages:
    52
    Likes:
    2
    Radio links often require lots of delay. Try setting the character delay for SEROUT with the command:
    SEROUT_DELAYUS
    Default is 1000uS (1mS). Maybe increase that by 10 or 20. All that setting does is provide a delay between each sent character when sending a string of them.
    Or, send one character at a time, and put in a "Waitms 5000" or bigger between each character (use a send array that is coded with all characters, and do a "FOR" loop for sending one character and add delay after each)

    As for the RF module, does it have any "status" bits/signals, to indicate "ready" or link is "connected and good" ?

    Many of those RF link modules pick up lots of noise, invalid characters. There is no checksums or character validation with those. Some have a maximum data rate of 2400 or 4800, not 9600. Getting zeros is an indication of no signal, or no data. Maybe loop in loop_nr reading zeros and dumping them until you see a "+" and only then start grabbing data. I suspect your RX code has to process all characters, even zeroes, and determine what to do and when (needs a bit more logic)
    Typical RF link unit:
    http://www.sparkfun.com/datasheets/RF/KLP_Walkthrough.pdf

    PS: Also try inverting the signals for serial on both ends. Use SEROUTINV and SERININV as suggested by this article (different basic compiler)
    http://digitaldiy.io/articles/mcu-p...n-basic-example/90-proton-tutorial-rf-modules
     
    Last edited: May 16, 2016
  14. mastero

    mastero Member

    Joined:
    Nov 27, 2011
    Messages:
    69
    Likes:
    1
    Thanx sagor will look into it ...
     

Share This Page