Problems controlling multiple pics


+ Reply to Thread
Results 1 to 12 of 12
  1. #1
    Join Date
    May 2007
    Posts
    26

    Question Problems controlling multiple pics

    I am currently in the process of designing a servo controller. I have already been able to make a pic that can take a message from a pc serial port and command 11 servos position, and speed.

    Now I am having a very hard time taking the messages from a computer, and distributing them to multiple controllers.

    For now I am attempting to just control one servo controller, with one master pic interfaced to the pc.

    master pic
    Code:
            define OSC 8
            OSCCON = %1111110 ' sets internal osc to run at 8MHZ
    
    '----------turn analog on porta off, and use as digital input/output '----------this is used to allow serial input on the A bus.
            CMCON = 7 'Comparators OFF
            ANSEL = 0 'A/D OFF -- Port pins all digital
    '----------
    
    '---**Pins
    rsoutpin var porta.0
    rsinpin var porta.1
    
    picinpin var portb.4
    picoutpin var portb.5
    
    '---vars
        '-------- transfer vars
       message var byte
        '--------
    
    
    
    
    
    '---main program
    main:
    
    gosub pcin
    gosub picout
    
    goto main
    
    '----- retrieve next set of commands from pc.
    pcin:
    
    '----send serial request, and get user input, timeout 70 ms
            serout2 rsoutpin, 16468, ["ready set go!"] 'call for data
            '----
            serin2 rsinpin, 16468, 70, main, [message]
    '-----end serial request
    return
    
    '---- picout procedure waits for high on picinpin and then transmits data
    
    picout:
    input picinpin
    
    '--- wait until pic is ready to recieve
    while picinpin = 0 
    pause 1
    wend
    
    '-transmit message to pic.
    serout2 picoutpin, 16468, [donecommanding]
    return


    slave pic
    Code:
            define OSC 8
            OSCCON = %1111110 ' sets internal osc to run at 8MHZ
    
    '----------turn analog on porta off, and use as digital input/output '----------this is used to allow serial input on the A bus.
            CMCON = 7 'Comparators OFF
            ANSEL = 0 'A/D OFF -- Port pins all digital
    '----------
    
    '---**Pins
    picinpin var porta.1
    picoutpin var porta.0
    
    ledpin var portb.4
    
    
    
    '---**Variables
    
    
    '---processing vars
    ledstat var byte
    
    '------**main program
    
    
    
    main:
    
    gosub recieve
    gosub driveled
    
    goto main   'loop forever
    
    
    
    recieve:
    
    '----send ready signal and wait for message with timeout 150.
            high picoutpin  ' ready to recieve
            '----
            serin2 picinpin, 16468, 150, driveled,[ledstat]
            low picoutpin 'not ready to recieve data.
    '-----end serial request
    
    
    
    return 'return to main routine
    
    driveled:
    low picoutpin 'not ready to recieve data.
    
    if ledstat =  "O" then
    
    high  ledpin 'turn on led
    
    else
    
    low ledpin 'turn off led
    
    endif
    
    return
    
    
    end

    Now this code actually works when I send "O" the light turns on, when I send something else it turns off.

    My problem is I have to be able to transfer data that looks like this "03|005|225|y".

    DEC2 servonumber "|" DEC3 rate "|" DEC3 position "|" finalcommand (single byte "y"/"n")

    I have been unable to transmit this kind of data, and in addition to that I will need to have the master look at the servonumber and send the message to the appropriate slave with the correct servonumber (as all the slaves will be numbered the same internally)

    Please let me know if you have any suggestions, or insight into how to achieve this. I have made multiple attempts, but apparently my brain is not working.

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898

    Default

    Different method to do that, i'll suggest to have a look at the following link

    How to make your own PIC network
    http://www.picbasic.co.uk/forum/showthread.php?t=1192

    This could give you some pointers.

    HTH

    PS: most here, including myself, don't recommend to use the internal OSC for serial communication for reliability reasons. If your PIC have a USART, you should use it. HSERIN/HSEROUT. I'll also suggest you to read the available Modifier list. WAIT will be handy in your case.
    Last edited by mister_e; - 26th May 2007 at 19:13.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  3. #3
    Join Date
    May 2007
    Posts
    26

    Default hserin/hserout

    I am using 16f88 which does have an internal AUSART. But what is the difference between serin2 and hserin. I am a little confused about it.

  4. #4
    Join Date
    Aug 2005
    Location
    NC
    Posts
    8

    Default Serin2 & HSERIN

    Serin2 & HSerin share modifiers you can use, but to use HSerin you must set the config bits in the PIC to specify you are using a hardware communication option instead of "bit banging" the serial comms using Serin2 (or Serin, for that matter).

    Sorry, but you'll have to spend some more time in both the manual and the datasheet for your PIC to get it set up properly. Do a search in the Archives here in the forum, and with Google if you need more help. I've just about finished getting my comms working as I need, using these same procedures.

    Good luck!
    Brad

  5. #5
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898

    Default

    Quote Originally Posted by gandora View Post
    I am using 16f88 which does have an internal AUSART. But what is the difference between serin2 and hserin. I am a little confused about it.
    HSEROUT or HSERIN use the PIC Hardware USART, while SERIN/SERIN2/DEBUGIN use a software Serial communication solution.

    The only restriction when you're using HSERIN/HSEROUT is the I/O and the amount of serial port. With HSERIN/HSEROUT, you MUST use the PIC dedicated i/o (RX/TX) while any other software solution (SERIN.. ) allow you to choose any i/o.

    Using the PIC USART give you for free at very least, a 2 Bytes receiver buffer, and interrupt trigger sources.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  6. #6
    Join Date
    May 2007
    Posts
    26

    Post I got it working

    Now thankyou all for your feedback, I still don't know exactly how to use hserin yet, but I will most certainly use it later. However I was able to come up with a way of getting my method to work.

    Now the biggest problem is that using the internal clocks on both the master and the slave makes errors pop up, but I came up with a way to check for errors and continue to retransmit, or request data until it is error free. And I came up with the solution to the original problem which was that I just needed to use STR message\12. What I was doing in the original code was converting multiple bytes into single bytes, and then attempting to transfer them in that form, which changed the data format causing it to be unreadable by the driver.

    the simplest method to solve that problem is:

    message VAR byte[12]

    serin2 pcinpin, 16468, [STR message\12]

    and then

    serout2 picoutpin, 16468, [STR message\12]

    the problem with the above code is the fact that during the process of recieving and transmitting twice its almost guarenteed you will get bad data at some point.

    my solution :master code:
    Code:
            define OSC 8
            OSCCON = %1111110 ' sets internal osc to run at 8MHZ
    
    '----------turn analog on porta off, and use as digital input/output
    '----------this is used to allow serial input on the A bus.
            CMCON = 7 'Comparators OFF
            ANSEL = 0 'A/D OFF -- Port pins all digital
    '----------
    
    '---**Pins
    rsoutpin var porta.0
    rsinpin var porta.1
    
    picinpin var portb.4
    picoutpin var portb.5
    
    porta=0
    portb=0
    
    '---vars
        '-------- transfer vars
        'servonum var byte: rate var word:position var word:donecommanding var byte
        '--------
    
     message  var byte[12]
     message2  var byte[12]
    
    
    '---main program
    goto pcin
    '----- retrieve next set of commands from pc.
    pcin:
    
    '----send serial request      
            serout2 rsoutpin, 16468, ["waiting!"] 'call for data           
            '----
            serin2 rsinpin, 16468, [str message\12,str message2\12]
    
    'compare both arrays
        if message[0]=message2[0] and message[1]=message2[1] and _
        message[2]=message2[2] and message[3]=message2[3] and _
        message[4]=message2[4] and message[5]=message2[5] and _
        message[6]=message2[6] and message[7]=message2[7] and _
        message[8]=message2[8] and message[9]=message2[9] and _
        message[10]=message2[10] and message[11]=message2[11] then
            'arrays equal eachother then
            serout2 rsoutpin, 16468, [str message\12]
            goto picout
        endif
    
    
            
    
    serout2 rsoutpin, 16468, ["bad data!"]    
    goto pcin
    
    '---- picout procedure waits for high on picinpin and then transmits data
    
    picout:
        input picinpin
    
            while picinpin = 0
            pause 1
            wend
        serout2 picoutpin, 16468, [str message\12,str message\12]
        pause 6
    
            if picinpin = 1 then      'checks if data was recieved
            goto picout  're-send until recieved
            endif
    serout2 rsoutpin, 16468, ["|transmission succesful|"] 'tell computer
    goto pcin
    
    end

    Here is the code for the slaves recieve portion:

    Code:
    recieve:
    
    '----send high pic request, and get user input for motor drive    
             
             high picoutpin
                    
            '----
            '--by using skip 1 rather then wait ("|") losing data is 
            '--prevented when wait is used if the data goes through 
            '--wrong the command is lost altogether.
    
            serin2 picinpin, 16468,15,drivemotor, [dec2 servonum,skip 1,_
            dec3 rate,skip 1,dec3 position,skip 1,donecommanding,_
            dec2 servonum2,skip 1,dec3 rate2,skip 1,dec3 position2,skip 1,_
            donecommanding2]
            
            '---verify that the data matches
            if servonum!=servonum2 or rate!=rate2 or position!=position2 or _
            donecommanding!=donecommanding2 then
            'data is bad recieve again      
            goto recieve 'try again
            endif
            
            low picoutpin
    '-----end serial request
    
    gosub setupservo 
    
    goto drivemotor 'return to main routine



    I have one question, would using a lower baud rate decrease the frequency of errors? If you have any suggestions to improve this code, please feel free to through in your two cents. Thanks again!

  7. #7
    skimask's Avatar
    skimask Guest

    Default

    Quote Originally Posted by gandora View Post
    Now the biggest problem is that using the internal clocks on both the master and the slave makes errors pop up.........
    I have one question, would using a lower baud rate decrease the frequency of errors? If you have any suggestions to improve this code, please feel free to through in your two cents. Thanks again!
    You aren't going to be able to get away from serial transmission/reception errors when using the internal oscillator. If you were using the hardware UART, you might be able to tweak the baud by using the overrun and framing error bits in the UART itself (overrun generally too slow baud, framing generally too fast baud rate). But overall, if you're not tweaking OSCTUN for each 'F88, it's a crapshoot as to whether or not you oscillator is running near it's spec'd frequency or not, thereby, your SERIAL commands are off by the same amount.
    And a lower baud rate might help, but it's certainly not a fix.

    Code:
    'compare both arrays  -- easier to read method I think....
    for temp = 0 to 11 : if message[temp] <> message2[temp] then goto baddataout
    next temp
    serout2 rsoutpin, 16468, [str message\12]        'arrays equal each other
    goto picout
            
    baddataout:
    serout2 rsoutpin, 16468, ["bad data!"]    
    goto pcin

  8. #8
    Join Date
    May 2007
    Posts
    26

    Lightbulb Thankyou so much!

    Awesome coding suggestions. I was able to get rid of 4 pages of code using similar thinking after you showed me that. (guess my brain just finally started working) ^^

    also, I tried something just as a blind guess at a way to fix the problem, or help a little, and it worked really well. I put a 470 ohm resistor to the ground from the picin pin on the slave. seems to have gotten rid of noise that was causing it to think it was recieving data when it wasn't, and it lowered the number of errors in general pretty significantly.

    Maybe thats standard practice? Or was it really insanity to genius. Anyways hopefully that fixed it. ^^
    Last edited by gandora; - 29th May 2007 at 00:16.

  9. #9
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,817

    Default

    Quote Originally Posted by gandora View Post
    Awesome coding suggestions. I was able to get rid of 4 pages of code using similar thinking after you showed me that. (guess my brain just finally started working) ^^

    also, I tried something just as a blind guess at a way to fix the problem, or help a little, and it worked really well. I put a 470 ohm resistor to the ground from the picin pin on the slave. seems to have gotten rid of noise that was causing it to think it was recieving data when it wasn't, and it lowered the number of errors in general pretty significantly.

    Maybe thats standard practice? Or was it really insanity to genius. Anyways hopefully that fixed it. ^^
    Hmmmm, What it does is short out the hi impeadence noise, since the noise doesn't have the amperage to carry through, but the signal does.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  10. #10
    Join Date
    May 2007
    Posts
    26

    Thumbs up

    Quote Originally Posted by Joe S. View Post
    Hmmmm, What it does is short out the hi impeadence noise, since the noise doesn't have the amperage to carry through, but the signal does.
    Thats what I thought it was doing, I did the same thing with the line in from the pc and I haven't had any errors since, but I still have the double buffer system that will make sure i know when i get one.

    Now I can move on to the next challenge. Which is, having multiple commands qued to be executed at once.

    I will get to work on that task and post my results when I get somewhere with it.

  11. #11
    Join Date
    May 2007
    Posts
    26

    Post New capabilities.

    I have now given the master an 8 command buffer. And finnally life is good ^^.

    I think I am going to up the buffer to 16, but that will require that I use 2 buffer arrays. For now, heres the master code, feel free to make any suggestions, and just let me know if you use it in any projects.

    :MSmaster:
    Code:
    '****************************************************************
    '*  Name    : MSERVMASTER.BAS                                      *
    '*  Author  : Joseph Dattilo                                    *
    '*  Notice  : Copyright (c) 2007 Joseph Dattilo                 *
    '*          : All Rights Reserved                               *
    '*  Date    : 5/25/2007                                         *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
    
            define OSC 8
            OSCCON = %1111110 ' sets internal osc to run at 8MHZ
    
    '----------turn analog on porta off, and use as digital input/output
    '----------this is used to allow serial input on the A bus.
            CMCON = 7 'Comparators OFF
            ANSEL = 0 'A/D OFF -- Port pins all digital
    '----------
    
    '---**Pins
    rsoutpin var porta.0
    rsinpin var porta.1
    
    picinpin var portb.4
    picoutpin var portb.5
    
    porta=0
    portb=0
    
    '---vars
    
    temp var byte
    qued var byte
    outqued var byte
    
    message  var byte[24]
    
    '-up to 8 commands can be buffered in que array.
    que var byte[96]
    '---------------
    
    
    qued = 0 'set number in que to 0
    goto pcin
    
    '############################## pc recieve ################################
    'que up messages from pc
    '##########################################################################
    
    pcin:
    
            '---- let pc know we are ready to recieve message.      
            serout2 rsoutpin, 16468, ["waiting!"] 'call for data           
            '---- ready to recieve message
            serin2 rsinpin, 16468, [str message\24]
            
        '------------------------------------------------------------------------
        'compare both arrays checking for bad data if data bad request it again.
        for temp = 0 to 11 : if message[temp] <> message[temp+12] then goto baddata
        next temp
        '------------------------------------------------------------------------
    
        
        serout2 rsoutpin, 16468, [str message\12] 'send confirmation of reciept.
        
        '------------------inque-----------------
         for temp = 0 to 11:que[(12*qued)+temp]=message[temp]:next temp
         serout2 rsoutpin, 16468, ["Qued:",str que\(12*qued+12)] 'display all in que
         
        
        '----------------------------------------
        
        if message[11] = "n" then
        serout2 rsoutpin, 16468, ["still more commands!?"] 'debug statement
        
        qued=qued+1 'go to next position in que
        
        goto pcin   'request the data for the next item.
        
        else
        
        outqued = 0 'set picout que start position to 0 (first item in que first)
        
        goto picout 'we are ready to command the servo controller.
        
        endif
        
        
            
            '-------------------------
            'where bad data takes you.
            baddata:
            serout2 rsoutpin, 16468, ["bad data!"]    
            goto pcin
            '-------------------------
    
    
    
    '############################## pic transmit #############################
    '---- picout procedure waits for high on picinpin and then transmits data
    '#########################################################################
    
    picout:
    
    '---------------------unque next item into message array        
    for temp = 0 to 11:message[temp]=que[(12*outqued)+temp]
    message[temp+12]=que[(12*outqued)+temp]:next temp
    '------------------------------------------------------- 
    
        input picinpin
    
            while picinpin = 0
            pause 1
            wend       
    
    
        serout2 picoutpin, 16468, [str message\24]
        pause 7
    
            if picinpin = 1 then      'checks if data was recieved
            goto picout  're-send until recieved
            endif
            
    serout2 rsoutpin, 16468, ["SUCCESS|",str message\12,"|"] 'tell computer
    
    if outqued < qued then
    
    outqued = outqued +1 'move to next qued item
    goto picout          'proceed to transmit it.
    else
    serout2 rsoutpin, 16468, ["|ALL",DEC (qued+1),"items transmitted succesfully|"]
    qued=0
    goto pcin
    endif
    
    
    end

    It is important that you attribute for the pause 7 in the master in the slaves procedure to prevent the master from constantly retransmitting the first message in the que.

    This is the modified recieve part of the function which allows the mserv slave to recieve any number of messages in a row.
    :MSslave:
    Code:
    '############################SLAVE RECIEVE################################
           
    '######################################################################
    
    recieve:
    
            '----send serial request, and get user input for motor drive timeout 70 ms       
             
             high picoutpin
                    
            '----
            
            serin2 picinpin, 16468,20,drivemotor, [dec2 servonum[0],skip 1,_
            dec3 rate[0],skip 1,dec3 position[0],skip 1,donecommanding[0],_
            dec2 servonum[1],skip 1,dec3 rate[1],skip 1,dec3 position[1],skip 1,_
            donecommanding[1]]
            
            if servonum[0]!=servonum[1] or rate[0]!=rate[1] or _ 
            position[0]!=position[1] or donecommanding[0]!=donecommanding[1] then
            'data is bad recieve again      
            goto recieve 'try again
            endif
            
            low picoutpin
            '-----
    
                'setup the servo chosen
                goalarray[servonum-1]=position[0]  'set servo goal
                ratearray[servonum-1]=rate[0]      'set servo rate
                '
            'allow for multiple commands.
            if donecommanding[0] = "n" then
            pause 7 'pause long enough to make sure master does not attempt retrans.
            goto recieve
            endif
            
            
            
    goto drivemotor
    Last edited by gandora; - 29th May 2007 at 08:31.

  12. #12
    Join Date
    May 2007
    Posts
    26

    Cool

    Okay so that wasn't too hard.

    The master transmitter now uses pretty much all of the ram available on the 16F88 as a buffer. Allowing 16 commands to be stored and transmitted from 2 seperate buffers.

    I am pretty sure I will not be needing more then that for this project and so here it is.

    :MSmaster:
    Code:
    '****************************************************************
    '*  Name    : MSERVMASTER.BAS                                      *
    '*  Author  : Joseph Dattilo                                    *
    '*  Notice  : Copyright (c) 2007 Joseph Dattilo                 *
    '*          : All Rights Reserved                               *
    '*  Date    : 5/25/2007                                         *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
    
            define OSC 8
            OSCCON = %1111110 ' sets internal osc to run at 8MHZ
    
    '----------turn analog on porta off, and use as digital input/output
    '----------this is used to allow serial input on the A bus.
            CMCON = 7 'Comparators OFF
            ANSEL = 0 'A/D OFF -- Port pins all digital
    '----------
    
    '---**Pins
    rsoutpin var porta.0
    rsinpin var porta.1
    
    picinpin var portb.4
    picoutpin var portb.5
    
    porta=0
    portb=0
    
    '---vars
    
    temp var byte
    qued var byte
    outqued var byte
    
    message  var byte[24]
    
    '-up to 8 commands can be buffered in each que array adding up to 16 altogether.
    que var byte[96]
    que2 var byte[96]
    '---------------
    
    
    qued = 0 'set number in que to 0
    goto pcin
    
    '############################## pc recieve ################################
    'que up messages from pc
    '##########################################################################
    
    pcin:
    
            '---- let pc know we are ready to recieve message.      
            serout2 rsoutpin, 16468, ["waiting!"] 'call for data           
            '---- ready to recieve message
            serin2 rsinpin, 16468, [str message\24]
            
        '------------------------------------------------------------------------
        'compare both arrays checking for bad data if data bad request it again.
        for temp = 0 to 11 : if message[temp] <> message[temp+12] then goto baddata
        next temp
        '------------------------------------------------------------------------
    
        
        serout2 rsoutpin, 16468, [str message\12] 'send confirmation of reciept.
        
        '------------------inque-----------------
         
         for temp = 0 to 11
             if qued<8 then  'add to first que
             que[(12*qued)+temp]=message[temp]
             else             'add to second que
             que2[(12*(qued-8))+temp]=message[temp]
             endif
         next temp
         
             if qued>7 then
             serout2 rsoutpin, 16468, ["Que 1:",str que\96, _ 
             "Que 2:",str que2\(12*(qued-8)+12)]
             
             else
             
        serout2 rsoutpin, 16468, ["Que 1:",str que\(12*qued+12)] 'display all in que
        
             endif
        '----------------------------------------
        
        if message[11] = "n" and qued<15 then
        
        serout2 rsoutpin, 16468, ["still more commands!?"] 'debug statement
        
        qued=qued+1 'go to next position in que
        
        goto pcin   'request the data for the next item.
        
        else
        
        outqued = 0 'set picout que start position to 0 (first item in que first)
        
        goto picout 'we are ready to command the servo controller.
        
        endif
        
        
            
            '-------------------------
            'where bad data takes you.
            baddata:
            serout2 rsoutpin, 16468, ["bad data!"]    
            goto pcin
            '-------------------------
    
    
    
    '############################## pic transmit #############################
    '---- picout procedure waits for high on picinpin and then transmits data
    '#########################################################################
    
    picout:
    
    '---------------------unque next item into message array        
    for temp = 0 to 11
    
    
    
    if outqued<8 then  'add to first que
             message[temp]=que[(12*outqued)+temp]
             message[temp+12]=que[(12*outqued)+temp]
             else             'add to second que
             message[temp]=que2[(12*(outqued-8))+temp]
             message[temp+12]=que2[(12*(outqued-8))+temp]
             endif
    
    next temp
    '------------------------------------------------------- 
    
        input picinpin
    
            while picinpin = 0
            pause 1
            wend       
    
    
        serout2 picoutpin, 16468, [str message\24]
        pause 7
    
            if picinpin = 1 then      'checks if data was recieved
            goto picout  're-send until recieved
            endif
            
    serout2 rsoutpin, 16468, ["SUCCESS|",str message\12,"|"] 'tell computer
    
    if outqued < qued then
    
    outqued = outqued +1 'move to next qued item
    goto picout          'proceed to transmit it.
    else
    serout2 rsoutpin, 16468, ["|ALL",DEC (qued+1),"items transmitted succesfully|"]
    qued=0
    goto pcin
    endif
    
    
    end

    As a note no changes need be made to the slave from last version for cross compatability.

Similar Threads

  1. Multiple PICS from Same Crystal?
    By WOZZY-2010 in forum General
    Replies: 2
    Last Post: - 6th February 2010, 15:18
  2. Multiple Pics accessing single EEPROM
    By Atom058 in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 3rd February 2008, 17:22
  3. Retrieving infos from multiple PICs on a bus/chain
    By flotulopex in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 15th October 2007, 04:42
  4. Multiple PIC's with 1 crystal
    By puma in forum Schematics
    Replies: 11
    Last Post: - 20th March 2007, 17:02
  5. Multiple Pics to One serial port
    By Rleonard in forum Serial
    Replies: 1
    Last Post: - 18th January 2007, 18:30

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts