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

I2c communication arduino master pic slave

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
luqman82303



Joined: 17 Feb 2020
Posts: 7

View user's profile Send private message

I2c communication arduino master pic slave
PostPosted: Mon Feb 17, 2020 9:37 am     Reply with quote

I am working on I2c communication between Arduino master and slave pic18f4520. The code I use works well on Proteus but when I implement on hardware it doesn't work. I don't get what the problem behind that can be. Anyone please help... Crying or Very sad

In the master there is simple LCD code is merged so sorry for that.

Slave PIC:
Code:

#include <18F4520.h>
#fuses HS, NOWDT,PUT,BROWNOUT,NOLVP
#fuses HS, PR, NOWDT
#use delay(clock=16000000)

#include <lcd.c>
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0x30, force_hw)

#INT_SSP
void ssp_interrupt()
{
//Clear Display

int8 incoming, state;

state = i2c_isr_state();
 
if(state < 0x80)     // Master is sending data
  {
  for(int i=0; i<=3 ; i++)
  {
   incoming = i2c_read();

   output_high(PIN_B1);
   
    printf(lcd_putc,"recev = %d",incoming);
   delay_ms(1000);
   //lcd_putc("Hello World");
   
    output_low(PIN_B1);
  }
 }

if(state >= 0x80)   // Master is requesting data from slave
  {
   output_high(PIN_A1);
 
  lcd_putc("master WANT READ");
   i2c_write(1);
   delay_ms (1000);
   
   output_low(PIN_A1);
  }
}

//======================================
void main ()
{
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);


}

Master:
Code:

// Include Arduino Wire library for I2C
#include <Wire.h>
#include <LiquidCrystal.h>
//#include <twi.h>
 
// Define Slave I2C Address
//#define SLAVE_ADDR
#define SLAVE_ADDR 0x30
//#define TWI_FREQ 16000000
 
// Define Slave answer size
#define ANSWERSIZE 1
 // Define LED Pin
int LED = 13;
 int b ;
 const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup()
{
  Wire.begin();
  Wire.setClock(200000);
  //Serial.begin(9600);
  Serial.begin(115200);

  //lcd
  lcd.begin(16, 2); // set up the LCD's number of columns and rows:
  // Print a message to the LCD.
  // lcd.print("hello, world!");

 //master
  pinMode(LED, OUTPUT);
  //Wire.setClock(400);  // Initialize I2C communications as Master
}
 
void loop()
{
 lcd.noDisplay();
 delay(50);
 lcd.display();////////display on
   
 
 
 ////////////////////////////////////////////////////////////////
 // Write a character to the Slave
//  Wire.beginTransmission(SLAVE_ADDR);         
 Wire.beginTransmission((SLAVE_ADDR<<1)|0x00);
 //lcd.print("master write");
 //delay(500);
 for(int i =0;i <=3 ;i++)
  {
  Serial.println("Write data to slave");
  lcd.print("master write");
  Wire.write(i);
  delay(500);
  lcd.clear();
  }
   delay(500);
  lcd.clear();
  Wire.endTransmission();
////////////////////////////////////////////////////////////////////////////////////// Serial.println("ENG");
 Wire.requestFrom(SLAVE_ADDR,ANSWERSIZE);   //  // Read response from Slave
 String response = ""; //  // Add characters to string
   
 while (Wire.available())
  {
    Serial.println("READ data FROM slave");
   //lcd.print("read from slave");// print the character
    //delay(500);
    // slave may send less than requested
    int c = Wire.read(); // receive a byte as character
    lcd.print("read from slave");// print the character
    delay(500);
    digitalWrite(LED, HIGH);
    lcd.clear();
   
      if(c == 1)
    {
     lcd.print("read done");
     delay (500);
   }
    //  response++;
     lcd.clear();    // Turn off the display
    digitalWrite(LED, LOW);
  }
  delay(500);
}
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Mon Feb 17, 2020 9:43 am     Reply with quote

Forget proteus/ISIS, unlikely anyone here can help.

Use real hardware instead.


Mike
temtronic



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

View user's profile Send private message

PostPosted: Mon Feb 17, 2020 9:47 am     Reply with quote

What Mike says...
Please read sticky above, PIC101, http://www.ccsinfo.com/forum/viewtopic.php?t=47549

It's well known that Proteus is defective, busted, corrupt, damaged, doesn't work reliably. NO Proteus schematic EVER presented here will work in the Real World.......NONE !

OK, with real hardware, what's the VDD of the system ?
These 2 lines of code inside the ISR:
Quote:

printf(lcd_putc,"recev = %d",incoming);
delay_ms(1000);

are a HUGE problem.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Mon Feb 17, 2020 10:38 am     Reply with quote

On state==80, you must read, then write.
If you don't, it causes an issue in the I2C hardware that Proteus doesn't
know about.....
It''s the only state where this has to happen.

The INT_SSP means _one_ transaction is occurring. Not 3. You need to
read/write just one byte.

Don't print in the ISR. The ISR needs to be handled and exited quickly.
Same comment about the delays.

Use the 'code' buttons when posting.
Code:

int8 bytes[2]; //small buffer for received
int1 have_data=FALSE;

#INT_SSP
void ssp_interrupt()
{
   int8 incoming, state;

   state = i2c_isr_state();

   if(state <= 0x80) // Master is sending data
   { //Note the = here
       incoming = i2c_read();
       if (state>0 && state<3)
           bytes[state-1]=incoming; //store data
       if (state==2)
           have_data=TRUE; //flag pair of bytes received
   }
   if(state >= 0x80) // Master is requesting data from slave
   {
       i2c_write(1);
   }
}


Then in your main, test for have_data==TRUE, then set it false and
print the bytes from 'bytes'.
luqman82303



Joined: 17 Feb 2020
Posts: 7

View user's profile Send private message

PostPosted: Mon Feb 17, 2020 11:58 am     Reply with quote

temtronic wrote:
What Mike says...
Please read sticky above, PIC101, http://www.ccsinfo.com/forum/viewtopic.php?t=47549

It's well known that Proteus is defective, busted, corrupt, damaged, doesn't work reliably. NO Proteus schematic EVER presented here will work in the Real World.......NONE !

OK, with real hardware, what's the VDD of the system ?
These 2 lines of code inside the ISR:
Quote:

printf(lcd_putc,"recev = %d",incoming);
delay_ms(1000);

are a HUGE problem.

Thanks for reply!!

I just remove these line but there is a problem about ISR(). They never called even if i just put a simple blink led in interrupt function they not even go there !!
What is reason behind that why ?
Code:
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
there interrupt never enable

i am new in pic so anything false i mention sorry for that.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 17, 2020 12:13 pm     Reply with quote

When the program falls off the end of main(), the PIC will go into Sleep
mode. CCS puts a SLEEP instruction at the end. (They don't tell you this).
To keep the PIC running, put a while(TRUE) statement at the end of the
program, as shown below in bold:
Quote:

void main ()
{
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);

while(TRUE);
}
temtronic



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

View user's profile Send private message

PostPosted: Mon Feb 17, 2020 12:51 pm     Reply with quote

re: sleep....
from the disassembled listing of my current program...
Code:

182:               } //end of main
  1096    0003     SLEEP

Yes, it's probably not in the manual, I've never checked. I've also never looked for a list of 'keywords' that should never be used as variables. I assume there is, I know MS BASIC had a list !
CCS does tell you, well, kind of, it is there, in the listing. Problem is, I bet not
too many programmers actually look at the listing.
luqman82303



Joined: 17 Feb 2020
Posts: 7

View user's profile Send private message

PostPosted: Mon Feb 17, 2020 4:47 pm     Reply with quote

Ttelmah wrote:
On state==80, you must read, then write.
If you don't, it causes an issue in the I2C hardware that Proteus doesn't
know about.....
It''s the only state where this has to happen.

The INT_SSP means _one_ transaction is occurring. Not 3. You need to
read/write just one byte.

Don't print in the ISR. The ISR needs to be handled and exited quickly.
Same comment about the delays.

Use the 'code' buttons when posting.
Code:

int8 bytes[2]; //small buffer for received
int1 have_data=FALSE;

#INT_SSP
void ssp_interrupt()
{
   int8 incoming, state;

   state = i2c_isr_state();

   if(state <= 0x80) // Master is sending data
   { //Note the = here
       incoming = i2c_read();
       if (state>0 && state<3)
           bytes[state-1]=incoming; //store data
       if (state==2)
           have_data=TRUE; //flag pair of bytes received
   }
   if(state >= 0x80) // Master is requesting data from slave
   {
       i2c_write(1);
   }
}


Then in your main, test for have_data==TRUE, then set it false and
print the bytes from 'bytes'.

Thanks for reply!!
I check those lines in my compiler but nothing is happening in i2c() interrupt!
I don't get the point, why the code is not going into isr function !!
Is there any hardware problem or the oscillator i use is not matched with Arduino crystal?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 17, 2020 6:33 pm     Reply with quote

luqman82303 wrote:

I don't get the point, why the code is not going into isr function !!

Did you read my post and do what I said ?

Do you have pull-up resistors on the SDA and SCL lines ? (4.7K ohms)
luqman82303



Joined: 17 Feb 2020
Posts: 7

View user's profile Send private message

PostPosted: Mon Feb 17, 2020 9:03 pm     Reply with quote

PCM programmer wrote:
luqman82303 wrote:

I don't get the point, why the code is not going into isr function !!

Did you read my post and do what I said ?

Do you have pull-up resistors on the SDA and SCL lines ? (4.7K ohms)



Yes I have 4.7k ohm resistor on scl and sda
emaxxenon



Joined: 21 Jan 2020
Posts: 42

View user's profile Send private message

PostPosted: Mon Feb 17, 2020 11:41 pm     Reply with quote

Would you share the connection scheme?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Feb 18, 2020 3:49 am     Reply with quote

You didn't answer the question again !

Did you add the line shown in bold below ?
Quote:
void main ()
{
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);

while(TRUE); // *** ADD THIS LINE ***
}
luqman82303



Joined: 17 Feb 2020
Posts: 7

View user's profile Send private message

PostPosted: Tue Feb 18, 2020 1:01 pm     Reply with quote

Thanks everyone .. so my I2c hardware finally in working !!

Slave
Code:

#include <18F452.H>
#fuses HS, NOWDT,PUT,BROWNOUT,NOLVP

#use delay(crystal=16000000)
//#use delay (clock=8000000)

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0x18, force_hw)

int8 bytes[2]; //small buffer for received
int1 have_data=FALSE;


#INT_SSP
void ssp_interrupt()
{
   int8 incoming, state;

   state = i2c_isr_state();

   if(state <= 0x80) // Master is sending data
   { //Note the = here
        output_high(PIN_A1);
       incoming = i2c_read();
       if (state>0 && state<3)
           bytes[state-1]=incoming; //store data
       if (state==2)
           have_data=TRUE; //flag pair of bytes received
   }
   if(state >= 0x80) // Master is requesting data from slave
   {
       i2c_write(1);
   }
}
   

void main ()
{
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);


while(TRUE);
 
}


Code:

//////////////////////////////////master//////////////

/*
  i2c-master-demo.ino
  Demonstrate use of I2C bus
  Master sends character and gets reply from Slave
  DroneBot Workshop 2019
  https://dronebotworkshop.com
*/
 
// Include Arduino Wire library for I2C
#include <Wire.h>
#include <stream.h>
#include <LiquidCrystal.h>
//#include <twi.h>
 
// Define Slave I2C Address
//#define SLAVE_ADDR
#define SLAVE_ADDR 0x0c
//#define TWI_FREQ 16000000
 
// Define Slave answer size
#define ANSWERSIZE 1
 // Define LED Pin
int LED = 13;
 int b ;
 const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


void setup()
{
  Wire.begin();
  Wire.setClock(100000);
  Serial.begin(9600);
//Serial.begin(115200);
//////////////////////////lcd
  lcd.begin(16, 2); // set up the LCD's number of columns and rows:
  // Print a message to the LCD.
 // lcd.print("hello, world!");

  /////////////////////////////////////////////////master
  pinMode(LED, OUTPUT);
  //Wire.setClock(400);  // Initialize I2C communications as Master
 
}
 
void loop()
{

//////////////////////////
lcd.noDisplay();
 delay(50);
 lcd.display();////////display on
 
 
 ////////////////////////////////////////////////////////////////
 // Write a character to the Slave
  Wire.beginTransmission(SLAVE_ADDR);         
 //Wire.beginTransmission((SLAVE_ADDR<<1)|0x00);
 //lcd.print("master write");
 //delay(500);
// for(int i =0;i <=3 ;i++)
//  {
  Serial.println("Write data to slave");
  lcd.print("master write");
  Wire.write(1);
  //Wire.write(2);
  //delay(500);
  //lcd.clear();
 // }
   delay(500);
  lcd.clear();
  Wire.endTransmission();
////////////////////////////////////////////////////////////////////////////////////////////////

 Wire.requestFrom(SLAVE_ADDR,ANSWERSIZE);   //  // Read response from Slave
 String response = ""; //  // Add characters to string
   
 while (Wire.available())
  {
    Serial.println("READ data FROM slave");
   //lcd.print("read from slave");// print the character
    //delay(500);
    // slave may send less than requested
    int c = Wire.read(); // receive a byte as character
    lcd.print("read from slave");// print the character
    delay(500);
    digitalWrite(LED, HIGH);
    lcd.clear();
   
    if(c == 1)
    {
      Serial.println("read done");
     lcd.print("read done");
     delay (500);
   }
    //  response++;
     lcd.clear();                   // Turn off the display:
    digitalWrite(LED, LOW);
  }
  delay(500);
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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