CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Complete the task of slave[SOLVED]
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
hamid9543



Joined: 31 Jan 2013
Posts: 63

View user's profile Send private message

Complete the task of slave[SOLVED]
PostPosted: Fri Jan 04, 2019 6:06 am     Reply with quote

So I have a device set as the I2C master, and the rest of the devices on the bus are set as slaves. The master sends a command to each slave, and the slave executes this task (running motors, PID stuff, important time-sensitive code). I would like to be able to know when the slave is finished executing its task. The only way I can see to do this is to constantly have the master poll the slave, but this creates an issue, because every time the master polls the slave, it triggers an i2c interrupt on the slave and quits running the motor code for a short amount of time.
Is there anyway to solve this?


Last edited by hamid9543 on Mon Feb 10, 2020 1:22 pm; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Jan 04, 2019 7:43 am     Reply with quote

Using just the I2c, no.

However you could have a single line back to the main chip, and either
have all the slaves 'wire ored' ro this, so that it is pulled high by a resistor,
with the slaves pulling it low when they are busy, or have the slaves
each pulse it low when they complete a task, so the master can then
poll for who this was.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jan 04, 2019 1:06 pm     Reply with quote

As Mr. T says, using I2C no...
Can you use RS-485 or some other form of PIC2PIC communications ? If you can use the HW UARTs within PICs then interrupts are easy to do!

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Jan 04, 2019 1:33 pm     Reply with quote

The UART has the advantage of being bi-directional, so messages can
be sent back.
However with the extra lines to control a trasceiver (which would be
needed for a multiple shared bus), again extra pins would be needed.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jan 04, 2019 2:53 pm     Reply with quote

Yeah, forgot about the RS-485 needing 'direction control' pin. I'm kinda 'stuck' on a true single wire system designed 3 decades ago that allows address,outgoing data, incoming data to be sent on a single wire (plus ground), bidirectionally over miles of copper. Sigh. That was 1/2 my lifetime ago, no wonder I can't keep up with 'new' stuff !

Course now that PICs are less than a buck, an extra I/O pin shouldn't cut into the profit margin

Jay Smile
hamid9543



Joined: 31 Jan 2013
Posts: 63

View user's profile Send private message

PostPosted: Sat Jan 05, 2019 9:18 am     Reply with quote

Ttelmah wrote:
Using just the I2c, no.

However you could have a single line back to the main chip, and either
have all the slaves 'wire ored' ro this, so that it is pulled high by a resistor,
with the slaves pulling it low when they are busy, or have the slaves
each pulse it low when they complete a task, so the master can then
poll for who this was.


what i understand is you mean when slave complete its task pin become low and when slave is doing task the pin has remained in high level.
and during this master checks slave pin status
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jan 05, 2019 9:38 am     Reply with quote

yes....
and IF that I/O line is an Interrupt input, the Master doesn't have to 'poll' or 'scan' l or look at it.

The 'slave' devices would trigger the interrupt and your ISR would then tell 'main', someone has finished their task. 'main' would have to decide who it was.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Jan 05, 2019 11:54 am     Reply with quote

Or as I said you could 'wire or', by only driving low, when the chips
are busy. Then when the line goes high all the devices have finished.

You could also go 'sneaky' with the pulse mode.
If you use a CCP to detect this, you could time the pulse width.
Then have the slaves each send different width pulses, and you would
know which one has signalled.
Obviously the slaves would have to test that the line was high before
transmitting.
hamid9543



Joined: 31 Jan 2013
Posts: 63

View user's profile Send private message

PostPosted: Fri Jan 18, 2019 7:59 am     Reply with quote

pin_A0 of 18f66k80 has been connected to pin_A0 16f1829 and this pin send the end of task to master

master code
Code:
#include <18f66k80.h>
#fuses INTRC_IO       //Internal RC Osc, no CLKOUT
#fuses NOPROTECT      //Code not protected from reading
#fuses NOWDT          //No Watch Dog Timer
#fuses NOPUT          //No Power Up Timer
#fuses NOMCLR         //Master Clear pin used for I/O
#fuses NOCPD          //No EE protection
#fuses BROWNOUT   
//#use delay(internal=16MHz)
#use delay(clock=64MHz,crystal=16MHz)
#use rs232(UART1, RECEIVE_BUFFER = 4, baud = 38400)
#use i2c(MASTER,i2c1,slow,FORCE_HW)

void main()
{
   int8 ldr;
   while(TRUE)
   {
    if(input(PIN_A0)==1) printf("No Ready\n\r");
    if(input(PIN_A0)==0){
     printf("started i2c\n\r");
     i2c_start();
     i2c_write(0x29);
     char lsb = i2c_read(0);
     i2c_stop();
     printf("stopped i2c\n\r");
         }
   }

}



and slave

Code:
#include <16f1829.h>
#fuses INTRC_IO       //Internal RC Osc, no CLKOUT
#fuses NOPROTECT      //Code not protected from reading
#fuses NOWDT          //No Watch Dog Timer
#fuses NOPUT          //No Power Up Timer
#fuses NOMCLR         //Master Clear pin used for I/O
#fuses NOCPD          //No EE protection
#fuses BROWNOUT   

#device ADC=8
#use delay(internal=32mhz)
#use i2c(SLAVE,sda=PIN_B4,scl=PIN_B6,address=0x28,slow,FORCE_HW)
#use rs232(RECEIVE_BUFFER = 4,baud = 9600,UART1)
#define LDR_NUM  6
#define R_PIN PIN_A5

int8  command=0;
int8  adc_channel[LDR_NUM]={4,5,6,9,8,7},ldrc[LDR_NUM];
#INT_SSP
void ssp_interrupt()
{
   int state = i2c_isr_state();   
   if(state < 0x80)     // Master is sending data
   {
     command=i2c_read();
   }

   if(state >= 0x80)    // Master is requesting data from slave
   {
      i2c_write(data[state-0x80]);
      printf("*\n");
   }
output_high(pin_a0);
}
   
void main()
{
   setup_adc_ports(sAN4|sAN5|sAN6|sAN7|sAN8|sAN9);
   setup_adc(ADC_CLOCK_DIV_8);
   enable_interrupts(global);
   enable_interrupts(INT_SSP);
   output_low(pin_a0);
   while(true)
   {     
         if(input(pin_a0)){
         for(int8 d=0;d<LDR_NUM;d++)
         {
            set_adc_channel(adc_channel[d]);
            delay_us(10);
            ldr[d]=read_adc(); 
            printf("1\n");
         }
          printf("\r");
         for(i=0;i<LDR_NUM;i++)
         {
            if(ldr[i] >100) data_ldr[i]=1;
            else             data_ldr[i]=0;
            printf("2\n");           
         } 
            printf("\r");
            output_low(pin_a0);
            printf("3\n\r");

   } 
   } }


master print "no ready"
slave print nothing
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Jan 18, 2019 10:50 am     Reply with quote

The slave I2C, will have hung.
You can't have things that cause delays in an I2C receive routine.
Your slave routine is driving A0 high, whenever any character is received
on the I2C, not at the end of the task.
SLOW is not correct syntax for the slave (no speed for a slave, the master
controls the timing).
You are both testing, and driving the pin in the slave. You can only do this if
you use an 'open collector' drive. Otherwise the reading of the input will
set the pin to float, and it'll no longer be driven.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jan 18, 2019 4:30 pm     Reply with quote

He really should have lines..like 'old school' RS-232 hand shaking was....
hmm..wonder if that's even taught in school today ?

Jay
hamid9543



Joined: 31 Jan 2013
Posts: 63

View user's profile Send private message

PostPosted: Sat Jan 19, 2019 8:15 am     Reply with quote

temtronic wrote:
He really should have lines..like 'old school' RS-232 hand shaking was....
hmm..wonder if that's even taught in school today ?

Jay

would you please give me your suggestion?
what can i use instead of RS-232?
is there better alternative?
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sun Jan 20, 2019 2:04 am     Reply with quote

For a multi slave system with proper bidirectional communication
(but half duplex so only one direction at a time), look at RS485.
Just three wires needed at each PIC.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Complete the task of slave
PostPosted: Sun Jan 20, 2019 6:25 am     Reply with quote

hamid9543 wrote:

I would like to be able to know when the slave is finished executing its task. The only way I can see to do this is to constantly have the master poll the slave, but this creates an issue, because every time the master polls the slave, it triggers an i2c interrupt on the slave and quits running the motor code for a short amount of time.
Is there anyway to solve this?

Suppose you have 3 i2c slave chips. Each slave could have an output
i/o pin that sends out a logic '1' when it's doing the task, and a logic '0'
when it's doing nothing (or has finished the task).

Then create a 4th i2c slave chip. Connect the status indicator pins from
the first 3 slaves to pins B0, B1, and B2 on the 4th slave. Then poll the
4th slave to read that port and send it back to you.

Also, Microchip sells i2c slave chips that are i/o expanders. This would do
it easily, though they require some setup commands to be sent initially.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jan 20, 2019 7:05 am     Reply with quote

Do you HAVE to use I2C ? As pointed out it's not the best for 'communications'. To get the feedback of 'task done', you need more pins, more interconnections.
RS-485 only needs 2,so actually saves I/O line in the 'comm bus'. It's been used for 'device 2 device communications for decades.T he alarm industry adopted it a long time go. CCS in their FAQ section shows how to use a single wire to have several PICS talk to each other. I've used a variation of that for 3 decades.
I2C is generally only good for very short distances (on same PCB).
Without knowing the details of the project, perhaps you can use one powerful PIC instead of several smaller ones ? Give us more details and we may have other options for you.

Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group