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 16F1827 Master & Arduino nano Slave

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



Joined: 25 Feb 2019
Posts: 3

View user's profile Send private message

I2C 16F1827 Master & Arduino nano Slave
PostPosted: Mon Feb 25, 2019 5:28 am     Reply with quote

Hi everyone,

I'm trying to get i2c communication between a PIC 16F1827 and an Arduino nano to transfer some data (an int).
I have been able to get Arduino to Arduino i2c to work but not between the PIC and the Arduino.

The code I'm currently using:

Master (PIC 16F1827)
Code:

#include <16F1827.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,MCLR,NOBROWNOUT
#use delay(clock=32000000)
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1, STREAM=PC)
#use i2c(Master, sda=PIN_B1, scl=PIN_B4)

#define SLAVE1_write 0x08
#define SLAVE1_read 0x09

void main(){
    int myBPM = 0;
    fprintf(PC, "\r\nmyBPM= %d", myBPM);
    while(1){
        i2c_start();
        i2c_write(SLAVE1_write);
        myBPM = i2c_read(0);
        i2c_stop();
        fprintf(PC, "\r\nmyBPM= %d", myBPM);
        delay_ms(1000);
    }
}


Slave (Arduino Nano) - Arduino gets signal from a pulse sensor, converts it to BPM and then transmits it to the PIC
Code:


#define USE_ARDUINO_INTERRUPTS true
#include <PulseSensorPlayground.h>
#include <Wire.h>

//  Variables
const int PulseWire = 0;
int Threshold = 600;   

int myBPM = 0;

PulseSensorPlayground pulseSensor;


void setup() {

  Serial.begin(9600);
 
  pulseSensor.analogInput(PulseWire);
  pulseSensor.setThreshold(Threshold);

  Wire.begin(8);
  Wire.onRequest(requestEvent);

  if (pulseSensor.begin()) {
    Serial.println("We created a pulseSensor Object !");
  }
}



void loop() {

  myBPM = pulseSensor.getBeatsPerMinute();

  if (pulseSensor.sawStartOfBeat()) {
    Serial.write(myBPM);
    Serial.println("♥  A HeartBeat Happened !");
    Serial.print("BPM: ");                       
    Serial.println(myBPM);
  }
 
  delay(20);                 

}

void requestEvent(){
  Wire.write(myBPM);
}


When I run the system I get the following:
    1. Some really strange sets of figures displayed (+x A5, etc...)
    2. The first fprintf doesn't print
    3. I keep getting the result "myBPM= -1" printed every second (so the while loop with delay is working)

I'm not sure what the issue is but I hope someone has tried i2c PIC master and Arduino slave before and can help me!

Extra notes:
    PIC and Arduino share a ground
    2x 10K Ohm Pullup resistors are used
    I need to use the 16F1827 at 32Mhz to drive Neopixel LEDs
    I'm using an Arduino as getting the BPM is much more streamlined then on PIC
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Mon Feb 25, 2019 6:16 am     Reply with quote

On the PIC, you are selecting to write to the slave.....
Not surprising you don't read the right value back.
You can only read data from the slave read address.
temtronic



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

View user's profile Send private message

PostPosted: Mon Feb 25, 2019 7:28 am     Reply with quote

I'd start with basic hardware first. What's the actual Vdds.? Are both micros 5 volt devices? Is the PIC 5 and the nano 3 volt ? Virtually everytime you try '5 and 3' , you'll run into problems...
OlivierV



Joined: 25 Feb 2019
Posts: 3

View user's profile Send private message

PostPosted: Mon Feb 25, 2019 8:55 am     Reply with quote

Ttelmah wrote:
On the PIC, you are selecting to write to the slave.....
Not surprising you don't read the right value back.
You can only read data from the slave read address.


So since I don't need to write anything to the Arduino should I take the i2c_write(SLAVE1_write) out?
And how do you specify to read from the Slave read address?
Just myBPM = i2c_read(SLAVE1_read)?


temtronic wrote:
I'd start with basic hardware first. What's the actual Vdds.? Are both micros 5 volt devices? Is the PIC 5 and the nano 3 volt ? Virtually everytime you try '5 and 3' , you'll run into problems...


Both are 5 Volt devices as far as I'm aware (the pulse sensor is also 5 volts and i power that straight from the Arduino).

Also I took the code from another example post on the forum and altered it slightly(http://www.ccsinfo.com/forum/viewtopic.php?t=39242&start=6). The example was for between 2 PICs though.

Sorry if these are some dumb questions but I'm just starting out with PICs
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Mon Feb 25, 2019 9:09 am     Reply with quote

Basic I2C.

The first byte transmitted (note _transmitted_), after an I2C start, is
the device address, as a 7 bit value, with an eighth bit (as the Lsb), which
specifies the bus direction for the rest of the transfer. It is this bit that
distinguishes the read address from the write address.

So to write to I2C, the sequence is:
Code:

Start
Send 'write' address
Then (optionally) send a register address.
Then send the data
Stop

To read from I2C, with a specified register address, the sequence is:
Code:

Start
send 'write' address
send register address
Restart
Send 'read' address *****
Read the data (with inverted ACK on last byte read)
Stop

To read without a register address, the sequence is:
Code:

Start
send 'read' address *****
Read data (with inverted ACK on last byte)
Stop

The direction control bit actually signals which way the transceivers
are to work. Remember it is the same wire that is both sending and
receiving data. The direction _must_ be set to 'read' before trying to
read from the bus.

The points marked ***** are where the bus reversal is triggered.

So to read from a device without using register addresses, the sequence
would be:
Code:

        i2c_start();
        i2c_write(SLAVE1_read);
        myBPM = i2c_read(0);
        i2c_stop();
temtronic



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

View user's profile Send private message

PostPosted: Mon Feb 25, 2019 9:37 am     Reply with quote

OK both are 5 volts, so that eliminates HW problems due to +5 vs +3...

Now, Ardunio code typically uses 7 bit I2C addresses vs PICs which use 8 bit addresses,so you'l need to confirm you're actually talking to the slave at the
correct addresses.
PCM P has an 'I2C scanner' program in the 'code library'. I'd copy/compile and run it. Actually I do that for every project that uses I2C. It'll confirm the I2C device is there AND what address it's at.

Also, be sure to have the correct I2C bus pullup resistors based on VDD ( 5 in your case), speed and distance. Typically 3k3, 4k7 will work.

I didn't really look at your code, prefer a one step,confirm hardware first approach.
Jay
OlivierV



Joined: 25 Feb 2019
Posts: 3

View user's profile Send private message

PostPosted: Tue Feb 26, 2019 8:45 am     Reply with quote

Thanks Ttelmah! I was looking for a simple explanation like yours but I couldn't find one anywhere. I'll try to implement the code tomorrow and get back to you.

Ok temtronic, I'll try find the PCM P I2C scanner program and test it out to see if I have the right addresses. The current Arduino addresses I got by specifying them in the code (that it is how I got Arduino to Arduino I2C to work. See below) but that might the wrong way of doing it with a PIC.

Code:
 Wire.begin(8);

How do I found out the right resistors to use? Is there an online calculator?

Also I got communication between the 2 to work with TTL RS232. Is there any benefits to get it to work using I2C instead of RS232? If there is no real benefit I might just stick with what I have.
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Tue Feb 26, 2019 9:48 am     Reply with quote

The PIC address will be twice the Arduino value.

The 'address' in I2C, is the upper 7 bits of the byte sent after the start.
On the PIC you work with the whole 'byte' as an entity. On the Arduino, just
with the upper seven bits.

The I2C documentation contains the calculations for the resistors.
Basically the smaller the resistor the more capacitance the bus can support.
However go too low, and standard drivers won't be able to pull the bus low.
Minimum for a 5V bus with 3mA drivers is about 1.7K. The maximum
value depends on the bus capacitance. At 5v, with a 2K pull up, you can
drive just on 400pF at standard rates. With 10K the maximum bus
capacitance is just 80pF. At 400KHz, this goes down to just 20pF....
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