NACK using PIC24F as MASTER and ARDUINO as SLAVE in I2C communication

I have exactly the same problem. I’m using a PIC24FJ128GA010 (with an Explorer 16 development board) and an Arduino UNO.

I want to set the PIC as I2C MASTER and the Arduino as SLAVE.

According to my logical analyzer, the PIC is writting everything as it’s supposed to: writes the slave address, receives an ACK and then starts writting a string. However, I’m using the Wire library example from the Arduino and it doesn’t seem to ACK when it gets information.

I’m attaching the code so you can see.



* File: main.c
* Author: SusanaEca
* Created on 26 de Março de 2015, 19:26
#include "p24fxxxx.h"
#include "i2c.h"
#include "leds.h"

//Calculate baud rate of I2C
* I2CxBRG = (FCY/FSCL - FCY/10,000,000) - 1
* Based on FCY = FOSC/2; Doze mode and PLL are disabled.
#define Fosc (8000000) // crystal
#define Fcy (Fosc*4/2) // w.PLL (Instruction Per Second)
#define Fsck 400000 // 400kHz I2C
#define I2C1_BRG ((Fcy/2/Fsck)-1)
int main(void)
//Variable declaration
char SlaveAddress = 0x4;
unsigned char *letras;
unsigned char tx_data[] = {'P', 'I', '\0'};
// char c='M';
//Get your pointer to a variable
letras = tx_data;
//Set-up LEDs
LED_Enable (LED_D6);
LED_Enable (LED_D3);
//Initialize I2C1
OpenI2C1(I2C_ON, I2C1_BRG);
//Start I2C1 condition
StartI2C1 (); //Send the Start Bit
IdleI2C1(); //Wait to complete
//Write-to-Slave Address
MasterWriteI2C1((SlaveAddress<<0)|0); //Send device advice adress byte to the slave with the write indication
IdleI2C1(); //Wait to complete
//If ACK is received...
if( I2C1STATbits.ACKSTAT == 0 )
LED_On (LED_D6); //Light up LED #6
MasterputsI2C1(letras); //Send your string :)
IdleI2C1(); //Wait to complete
//If NACK (merda)...
if( I2C1STATbits.ACKSTAT == 1 ) 
LED_On (LED_D3); //Light up LED #3


// Wire Slave Receiver
// by Nicholas Zambetti <>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

#include <Wire.h>

void setup()
  Wire.begin(4); // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600); // start serial for output

void loop()

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
  while(1 < Wire.available()) // loop through all but the last
    char c =; // receive byte as a character
    Serial.print(c); // print the character
  int x =; // receive byte as an integer
  Serial.println(x); // print the integer