| View previous topic :: View next topic | 
	
	
		| Author | Message | 
	
		| hamid9543 
 
 
 Joined: 31 Jan 2013
 Posts: 63
 
 
 
			    
 
 | 
			
				| Complete the task of slave[SOLVED] |  
				|  Posted: Fri Jan 04, 2019 6:06 am |   |  
				| 
 |  
				| 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Jan 04, 2019 7:43 am |   |  
				| 
 |  
				| 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: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Jan 04, 2019 1:06 pm |   |  
				| 
 |  
				| 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Jan 04, 2019 1:33 pm |   |  
				| 
 |  
				| 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: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Jan 04, 2019 2:53 pm |   |  
				| 
 |  
				| 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
  |  | 
	
		|  | 
	
		| hamid9543 
 
 
 Joined: 31 Jan 2013
 Posts: 63
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Jan 05, 2019 9:18 am |   |  
				| 
 |  
				|  	  | 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: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Jan 05, 2019 9:38 am |   |  
				| 
 |  
				| 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Jan 05, 2019 11:54 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Jan 18, 2019 7:59 am |   |  
				| 
 |  
				| 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Jan 18, 2019 10:50 am |   |  
				| 
 |  
				| 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: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Jan 18, 2019 4:30 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Jan 19, 2019 8:15 am |   |  
				| 
 |  
				|  	  | 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Jan 20, 2019 2:04 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				| Re: Complete the task of slave |  
				|  Posted: Sun Jan 20, 2019 6:25 am |   |  
				| 
 |  
				|  	  | 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: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Jan 20, 2019 7:05 am |   |  
				| 
 |  
				| 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
 |  | 
	
		|  | 
	
		|  |