Arduino I2C sends unexpected NACK

Asked

Viewed 512 times

32

I’m wearing a Development board of microchip (explorer 16) with the pic24f128ga010 as Master and the Arduino as Slave. The PIC is sending everything right, but for some reason NACK for all the date, just send ACK at the beginning when the Address.

PIC Code (Master):

/* 
* File: main.c
* Author: SusanaEca
*
* Created on 26 de Março de 2015, 19:26
*/
//Libraries
#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);

    while(1)
    {
        //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 (erro)...
            if (I2C1STATbits.ACKSTAT == 1) 
            {
                LED_On(LED_D3); //Light up LED #3
            }
        }
    }
}

Arduino code (Slave):

// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// 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()
{
    delay(100);
}

// 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 = Wire.read(); // receive byte as a character
        Serial.print(c); // print the character
    }
    int x = Wire.read(); // receive byte as an integer
    Serial.println(x); // print the integer
}

logic Software

  • 3

    (SlaveAddress<<0)|0 - Because the <<0 and the |0? Wouldn’t it be easier just to use SlaveAddress?

  • 1

    This bit indicates whether the master will write or read. If it is 0 write if it is 1 read.

  • 1

    The master has to send the address and as the least meaningful bit for 0 or 1.

  • 1

    Your question would have much more visibility on board Arduino or Electrical Engineering.

  • 1

    Well, it’s been 1 year and 8 months since this was posted and I commented above. But Cindy, if you’re still around and you see this someday and you’re still interested in this subject, when you answer comments, put a @nome-do-usuário to notify the user in question (in my case, @VictorStafusa). As I was not notified, I did not see that you answered to me and I ended up knowing it only by chance, almost two years later.

  • 1

    To have only the least significant bit, use (SlaveAddress & 1).

Show 1 more comment

1 answer

2

Browser other questions tagged

You are not signed in. Login or sign up in order to post.