Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
I2C echo example
30-11-2013, 04:54 AM,
#1
I2C echo example
Hello everyone. I built two pinguinos: 18f4550 and 18f2550. Both running with a 20Mhz crystal.
Here is the thing. The Master.pde and Slave.pde examples in Communications/i2c work just fine. I removed most of it to leave an echo Slave device, but the Master hangs before ending the transmission. Here is the code:
MASTER:
Code:
#define SLAVE_ADDRESS 0x2C

void setup(){
CDC.println("starting setup\n");
toggle(USERLED);
  Wire.begin(I2C_MASTER_MODE,I2C_100KHZ);
  //Serial.begin(9600);
  CDC.println("setup done\n");
}

void loop(){
char c;
  c = CDC.getKey();  
  CDC.println("begin transmision: ");
  delay(100);
  Wire.beginTransmission(SLAVE_ADDRESS);
  Wire.write(c);                           // Sends DATA
  Wire.endTransmission(1);
  CDC.println("End transmission\nRequest data");
  delay(100);
  Wire.requestFrom(SLAVE_ADDRESS,2); //request 2 bytes
  delay(100);
      while(Wire.available())    // slave may send less than requested
    {
      c = Wire.read(); // receive a byte as character
      Serial.printf("Received: %2X",c);         // print the character
    }
  CDC.println("End transmission\n");
  delay(1000);
}

SLAVE:
Code:
#define SLAVE_ADDRESS 0x2C
#define I2C_BUFFER_SIZE 32

void receiveEvent(u8);
void requestEvent(void);

u8 rxbuffer[32];
u8 cdcount=0;

void setup()
{
u8 i;
  Wire.begin(SLAVE_ADDRESS,0); // join i2c bus with address #xx
                               // the second parameter (0) is not used in the present slave mode
  for(i=0;i<6;i++)  // to show the slave is started waiting interrupts and commands
    {toggle(USERLED); delay(500);}
  Wire.onReceive(receiveEvent); // register event
// In this example the following call is required because in the requestEvent procedure
// the slave send data to the master as requested by it thru a requestFrom call :
  Wire.onRequest(requestEvent); // register event
  CDC.println("End of setup");
}

void loop()
{
// slave working on interrupts
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
    CDC.println("RequestEvent\n");
    Wire.writeS(rxbuffer,cdcount); //echo data
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(u8 count)
{
u8 i;
CDC.println("ReceiveEvent\n");
  i=0;
  cdcount = count;
  while(Wire.available())
    rxbuffer[i++] = Wire.read();
  
  rxbuffer[cdcount]=0x0;
  CDC.printf("received: %s",rxbuffer);
  
}


Master prints:
setup done
begin transmision:

while Slave prints the following lines after manually restarting the Master a few times:
RequestEvent
ReceiveEvent (exactly the opposite order than the Master code :S)


It never reaches:
"End transmission\nRequest data" line in the Master code. Nor the "received: %s" line in the slave.

Ideas? Suggestions?


2) question. How can I test if a Slave has been disconnected without notification? (power failures, etc).
Thanks in advance
Reply
30-11-2013, 06:41 PM, (This post was last modified: 30-11-2013, 07:07 PM by gtcbreizh.)
#2
RE: I2C echo example
As I am I2cmaster.c and I2cslave.c's author I am going to take care of your problem with great interest. Yet be patient because now I am running behind a lot of things.
André

I already see line 26 :
Serial.printf("Received: %2X",c); // print the character
Probably it is CDC.printf( ...

I am going to test with this change. Try it on your side, probably you will be quicker than me ;-)

(30-11-2013, 06:41 PM)gtcbreizh Wrote: As I am I2cmaster.c and I2cslave.c's author I am going to take care of your problem with great interest. Yet be patient because now I am running behind a lot of things.
André
Reply
02-12-2013, 05:38 AM,
#3
RE: I2C echo example
(30-11-2013, 06:41 PM)gtcbreizh Wrote: As I am I2cmaster.c and I2cslave.c's author I am going to take care of your problem with great interest. Yet be patient because now I am running behind a lot of things.
André

I already see line 26 :
Serial.printf("Received: %2X",c); // print the character
Probably it is CDC.printf( ...

I am going to test with this change. Try it on your side, probably you will be quicker than me ;-)

(30-11-2013, 06:41 PM)gtcbreizh Wrote: As I am I2cmaster.c and I2cslave.c's author I am going to take care of your problem with great interest. Yet be patient because now I am running behind a lot of things.
André


Thanks!!! that worked hahahaha I can't believe I skipped that while I was replacing the serial bus with the USB.


So... my other question is still open:

1) how do I handle a disconnection in one slave? I'm going to use a p82b715 i2c extender to communicate over 20mts with 3 slaves. Some of them may, or may not disconnect unexectedly. How should I handle this?

2) new question. Why did you use so many delays in your code? is it some kind of limitation in the pic hardware?


THANKS!!!!
2)
Reply
02-12-2013, 08:25 AM,
#4
RE: I2C echo example
(02-12-2013, 05:38 AM)dc_740 Wrote:
(30-11-2013, 06:41 PM)gtcbreizh Wrote: As I am I2cmaster.c and I2cslave.c's author I am going to take care of your problem with great interest. Yet be patient because now I am running behind a lot of things.
André

I already see line 26 :
Serial.printf("Received: %2X",c); // print the character
Probably it is CDC.printf( ...

I am going to test with this change. Try it on your side, probably you will be quicker than me ;-)

(30-11-2013, 06:41 PM)gtcbreizh Wrote: As I am I2cmaster.c and I2cslave.c's author I am going to take care of your problem with great interest. Yet be patient because now I am running behind a lot of things.
André


Thanks!!! that worked hahahaha I can't believe I skipped that while I was replacing the serial bus with the USB.


So... my other question is still open:

1) how do I handle a disconnection in one slave? I'm going to use a p82b715 i2c extender to communicate over 20mts with 3 slaves. Some of them may, or may not disconnect unexectedly. How should I handle this?

-> you can test each slave before really starting each dialog by sending it a specific code (for instance 0x80 to ask "are you connected ?"). If the slave doesn't precisely reply you know it is disconnected. Then you regularly recall it to know whether its status has changed in order to recover a good dialog.

2) new question. Why did you use so many delays in your code? is it some kind of limitation in the pic hardware?

->would you precise where you exactly find "so many delays" ?


THANKS!!!!
Reply
02-12-2013, 02:16 PM, (This post was last modified: 02-12-2013, 03:15 PM by dc_740.)
#5
RE: I2C echo example
(02-12-2013, 08:25 AM)gtcbreizh Wrote:
(02-12-2013, 05:38 AM)dc_740 Wrote:
(30-11-2013, 06:41 PM)gtcbreizh Wrote: As I am I2cmaster.c and I2cslave.c's author I am going to take care of your problem with great interest. Yet be patient because now I am running behind a lot of things.
André

I already see line 26 :
Serial.printf("Received: %2X",c); // print the character
Probably it is CDC.printf( ...

I am going to test with this change. Try it on your side, probably you will be quicker than me ;-)

(30-11-2013, 06:41 PM)gtcbreizh Wrote: As I am I2cmaster.c and I2cslave.c's author I am going to take care of your problem with great interest. Yet be patient because now I am running behind a lot of things.
André


Thanks!!! that worked hahahaha I can't believe I skipped that while I was replacing the serial bus with the USB.


So... my other question is still open:

1) how do I handle a disconnection in one slave? I'm going to use a p82b715 i2c extender to communicate over 20mts with 3 slaves. Some of them may, or may not disconnect unexectedly. How should I handle this?

-> you can test each slave before really starting each dialog by sending it a specific code (for instance 0x80 to ask "are you connected ?"). If the slave doesn't precisely reply you know it is disconnected. Then you regularly recall it to know whether its status has changed in order to recover a good dialog.

2) new question. Why did you use so many delays in your code? is it some kind of limitation in the pic hardware?

->would you precise where you exactly find "so many delays" ?


THANKS!!!!


1) Thanks! I'll try that
2) There are at least 9 delays. Before the "requestFrom", and "available" calls.



For future references. Working code:
MASTER:
Code:
#define SLAVE_ADDRESS 0x2C

void setup(){
CDC.println("starting setup\n");
toggle(USERLED);
  Wire.begin(I2C_MASTER_MODE,I2C_100KHZ);
  CDC.println("setup done\n");
}

void loop(){
char c;
  c = CDC.getKey();  
  CDC.println("begin transmision: ");
  delay(100);
  Wire.beginTransmission(SLAVE_ADDRESS);
  Wire.write(c);                           // Sends DATA
  Wire.endTransmission(1);
  CDC.println("End transmission\nRequest data");
  delay(100);
  Wire.requestFrom(SLAVE_ADDRESS,2); //request 2 bytes
  delay(100);
      while(Wire.available())    // slave may send less than requested
    {
      c = Wire.read(); // receive a byte as character
      CDC.printf("Received: %2X",c);         // print the character
    }
  CDC.println("End transmission\n");
  delay(1000);
}

SLAVE:
Code:
#define SLAVE_ADDRESS 0x2C
#define I2C_BUFFER_SIZE 32

void receiveEvent(u8);
void requestEvent(void);

u8 rxbuffer[32];
u8 cdcount=0;

void setup()
{
u8 i;
  Wire.begin(SLAVE_ADDRESS,0); // join i2c bus with address #xx
                               // the second parameter (0) is not used in the present slave mode
  for(i=0;i<6;i++)  // to show the slave is started waiting interrupts and commands
    {toggle(USERLED); delay(500);}
  Wire.onReceive(receiveEvent); // register event
// In this example the following call is required because in the requestEvent procedure
// the slave send data to the master as requested by it thru a requestFrom call :
  Wire.onRequest(requestEvent); // register event
  CDC.println("End of setup");
}

void loop()
{
// slave working on interrupts
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
    CDC.println("RequestEvent\n");
    Wire.writeS(rxbuffer,cdcount); //echo data
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(u8 count)
{
u8 i;
CDC.println("ReceiveEvent\n");
  i=0;
  cdcount = count;
  while(Wire.available())
    rxbuffer[i++] = Wire.read();
  
  rxbuffer[cdcount]=0x0;
  CDC.printf("received: %s",rxbuffer);
  
}
Reply
02-12-2013, 05:45 PM, (This post was last modified: 02-12-2013, 05:47 PM by gtcbreizh.)
#6
RE: I2C echo example
Some delays are put between a master question and a slave reply to be sure that the slave has a sufficient time to prepare its response.
A main delay 1000msec is found at the end of void loop() because in my demo example I want to read what is listed on the terminal screen.
In your application if you need a lot time for true processing you can try and omit these delays. Let us keep a practical mind !

Some delays are put between a master question and a slave reply to be sure that the slave has a sufficient time to prepare its response.
A main delay 1000msec is found at the end of void loop() because in my demo example I want to read what is listed on the terminal screen.
In your application if you need a lot of time for true processing you can try and omit these delays. Let us keep a practical mind !
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)