Go Down

Topic: (SOLVED) I2C communication problem- NXP I2C RFID EEPROM (Read 7942 times) previous topic - next topic

swoudlxy

Jul 30, 2014, 06:04 am Last Edit: Sep 16, 2014, 07:33 pm by robtillaart Reason: 1
Recently I am doing code development. I have four pressure sensors and their value are read by Arduino UNO. After that these value will be send to the EEPROM of a NXP I2C RFID tag via I2C. I monitored the data one the serial port, these data are recognized correct but could not send to NXP chip.

Below is my code. Would it be possible some professions could take a look? I really don't know where is the mistake:

Code: [Select]

#include <Wire.h>
#define NXP 0x51 //NXP chip address is 101 0001

const int numberOfSensors = 4;
int sensorPins [numberOfSensors] = {
 0, 1, 2, 3}; //Analog input pins 0-3
int pullupPins [numberOfSensors] = {
 14, 15, 16, 17}; //Digital names for analog input pins 0-3

void setup() {
for(int i = 0; i < numberOfSensors; i++) // set analog pins as inputs, although this is also the default
   pinMode(sensorPins[i], INPUT);
for(int i = 0; i < numberOfSensors; i++) // set internal pullup resistors for all analog pins in use
   digitalWrite(pullupPins[i], HIGH);
 Serial.begin(9600);
 Wire.begin();
}


void loop() {
unsigned int address = 0x6000; // The address access for I2C and RFID are different for the same bank. For user memory
// I2C address starts from 6000h
 for (int count = 0; count < numberOfSensors; count++) {
   int sensorReading = analogRead(sensorPins[count]); // read each sensor as deffined in sensorPins array
   if(sensorReading >1000)
   {Wire.write('N');}
   else{
     if(sensorReading <100)
     {Wire.write('N');}
     else
     {Wire.write((int)(address>>8));
     Wire.write((int)(address&0xFF));
     Wire.write(sensorReading);}
    // address+=2;}
   }
   Serial.print(sensorReading, DEC); // print its value out decimally
   if (count < numberOfSensors - 1) Serial.print(","); // if this isn't the last sensor to read then print a comma after it
 }

 Serial.println(); // after all the sensors have been read print a newline and carriage return
 delay(10); // delay by # milliseconds
}

moderator: added code tags =>  # button above smileys

swoudlxy

Recently I am doing code development. I have four pressure sensors and their value are read by Arduino UNO. After that these value will be send to the EEPROM of a NXP I2C RFID tag via I2C. I monitored the data one the serial port, these data are recognized correct but could not send to NXP chip.

Below is my code. Would it be possible some professions could take a look? I really don't know where is the mistake:
Code: [Select]
#include <Wire.h>
#define NXP 0x51

const int numberOfSensors = 4;
int sensorPins [numberOfSensors] = {
  0, 1, 2, 3}; //Analog input pins 0-3
int pullupPins [numberOfSensors] = {
  14, 15, 16, 17}; //Digital names for analog input pins 0-3

void setup() {
for(int i = 0; i < numberOfSensors; i++) // set analog pins as inputs, although this is also the default
    pinMode(sensorPins[i], INPUT);
for(int i = 0; i < numberOfSensors; i++) // set internal pullup resistors for all analog pins in use
    digitalWrite(pullupPins[i], HIGH);
  Serial.begin(9600);
  Wire.begin();
}


void loop() {
unsigned int address = 0;
  for (int count = 0; count < numberOfSensors; count++) {
    int sensorReading = analogRead(sensorPins[count]); // read each sensor as deffined in sensorPins array
    if(sensorReading >1000)
    {Wire.write('N');}
    else{
      if(sensorReading <100)
      {Wire.write('N');}
      else
      {Wire.write((int)(address>>8));
      Wire.write((int)(address&0xFF));
      Wire.write(sensorReading);}
     // address+=2;}
    }
    Serial.print(sensorReading, DEC); // print its value out decimally
    if (count < numberOfSensors - 1) Serial.print(","); // if this isn't the last sensor to read then print a comma after it
  }

  Serial.println(); // after all the sensors have been read print a newline and carriage return
  delay(10); // delay by # milliseconds
}

JimboZA

#2
Jul 30, 2014, 06:19 am Last Edit: Jul 30, 2014, 06:31 am by JimboZA Reason: 1
My I2C EEPROM usage is limited to lifting some code from the Playground, and adding one line as suggested by forum member cattledog.

I think the whole write thing needs to be wrapped in a begin/end transmission as below. I may be wrong, but that's the way the code in the playground works. The code below is a function but you could put the begin, end and delay into your in-line code.

Code: [Select]
// below is the write function, untouched from playground, except ***
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
 int rdata = data;
 Wire.beginTransmission(deviceaddress);
 Wire.write((int)(eeaddress >> 8)); // MSB
 Wire.write((int)(eeaddress & 0xFF)); // LSB
 Wire.write(rdata);
 Wire.endTransmission();
 delay(5);  //added at cattledog's suggestion ***
}
Johannesburg hams call me: ZS6JMB on Highveld rep 145.7875 (-600 & 88.5 tone)
Dr Perry Cox: "Help me to help you, help me to help you...."
Your answer may already be here: https://forum.arduino.cc/index.php?topic=384198.0

swoudlxy

Hooo, really. I forgot that! Thanks very much and I will have a try again.

JimboZA

Wondering why you posted twice....  if it was to put the code tags round the code, you could have chosen Modify and fixed this one.


I posted in the other thread
Johannesburg hams call me: ZS6JMB on Highveld rep 145.7875 (-600 & 88.5 tone)
Dr Perry Cox: "Help me to help you, help me to help you...."
Your answer may already be here: https://forum.arduino.cc/index.php?topic=384198.0

swoudlxy

Thanks very much. I have received. I modified the code but it still doesn't work :~ :~

I though it might be the memory address problem. Which address should I start for a RFID tag? EPC bank or TID bank or User memory bank?

Many thanks.

Code: [Select]
#include <Wire.h>
#define NXP 0x51

const int numberOfSensors = 4;
int sensorPins [numberOfSensors] = {
  0, 1, 2, 3}; //Analog input pins 0-3
int pullupPins [numberOfSensors] = {
  14, 15, 16, 17}; //Digital names for analog input pins 0-3

void setup() {
for(int i = 0; i < numberOfSensors; i++) // set analog pins as inputs, although this is also the default
    pinMode(sensorPins[i], INPUT);
for(int i = 0; i < numberOfSensors; i++) // set internal pullup resistors for all analog pins in use
    digitalWrite(pullupPins[i], HIGH);
  Serial.begin(9600);
  Wire.begin();
}

void loop() {
unsigned int address = 0x2004; // The EPC memory bank starts
  for (int count = 0; count < numberOfSensors; count++) {
    int sensorReading = analogRead(sensorPins[count]); // read each sensor as deffined in sensorPins array
    if(sensorReading >1000)
    {Wire.write('N');}
    else{
      if(sensorReading <100)
      {Wire.write('N');}
      else
      {
      Wire.beginTransmission(NXP);
      Wire.write((int)(address>>8));
      Wire.write((int)(address&0xFF));
      Wire.write(sensorReading);
      Wire.endTransmission();
      delay (5);}
     // address+=2;}
    }
    Serial.print(sensorReading, DEC); // print its value out decimally
    if (count < numberOfSensors - 1) Serial.print(","); // if this isn't the last sensor to read then print a comma after it
  }

  Serial.println(); // after all the sensors have been read print a newline and carriage return
  delay(10); // delay by # milliseconds
}

cattledog

#6
Jul 30, 2014, 06:45 pm Last Edit: Jul 30, 2014, 07:11 pm by cattledog Reason: 1
Quote
I though it might be the memory address problem. Which address should I start for a RFID tag? EPC bank or TID bank or User memory bank?


Can you provide a link to the data sheet for the NXP chip?

I see a different problem in that your analog sensor readings are integers, and the Wire.write routine is for bytes. You will need to break your integers into high and low bytes and then store in two address locations. When reading them you recombine to an integer.

There are many forum and google examples on how to do this. You can use  highByte() and lowByte() or the bitshift approach like you use in the address.

swoudlxy

Many thanks for your suggestion. Let me check that code again~
The link of NXP chip is as following:
http://www.nxp.com/documents/data_sheet/SL3S4011_4021.pdf

cattledog

You will need to read the data sheet carefully because this eeprom has some sort of wordwrite rather individual bytes. I think the address locations are two wide.

Quote
The byte address must be an even value due to the word wise organization of the
EEPROM.


I don't fully understand the data sheet at first glance, but you may be able to write highByte() and lowByte in the same wire.write section after sending an even address.. I don't think the wire.write(sensorReading) is the correct syntax. I may be incorrect in these statements so take them for quick guesses.

Quote
Each data byte in the memory has a 16-bit (two byte wide) address. The Most Significant
Byte (Table 15) is sent first, followed by the Least Significant Byte (Table 15). Bits b15 to
b0 form the address of the byte in memory.


It does seems clear that you want to write into user memory.

Unless someone can come up with an example for you, I think you are in experimentation mode. To debug your code, it will be best to write and read once in setup() rather than in loop(). If things go wrong, you can write a lot of times to the EEPROM in a hurry.

Good luck.


swoudlxy

Hi, Thanks very much for your suggestion~~ I know it has word write and no byte write. So is that mean I can send one word at the same time to the assigned address? Because this is my first time to touch I2C code and Arduino, many thanks for your instuctions.
Code: [Select]
byte sensorReading_H=highByte(sensorReading);
      byte sensorReading_L=lowByte(sensorReading);
      Wire.beginTransmission(NXP);
      Wire.write((int)(address>>8)); //MSB
      Wire.write((int)(address&0xFF)); //LSB     
      Wire.write(sensorReading_H);
      Wire.write(sensorReading_L);
      Wire.endTransmission();

cattledog

Quote
So is that mean I can send one word at the same time to the assigned address?


I don't know. Try it and see if it works.

Make sure you get the small delay() back in after wire.endTransmission.

swoudlxy

Yeah, I will try that first in setup() to see whether it works. Thanks very much for your kindness~~~

swoudlxy

Thanks all and the code has been run successfully in my project. 8) 8)

cattledog

To help others I would suggest you modify the subject matter to "(SOLVED) I2C communication problem-  NXP I2C RFID EEPROM" so it shows more specifically in search.

Also. more importantly, please post your successful code.

Congratulations for working your way through this.

swoudlxy

Thanks again. The code is modified as following:
Code: [Select]
byte sensorReading_H=highByte(sensorReading); //High 8-bit of sensorReading
      byte sensorReading_L=lowByte(sensorReading); //Low 8-bit of sensorReading
      Wire.beginTransmission(address);
      Wire.write((int)(address>>8)); //MSB
      Wire.write((int)(address&0xFF)); //LSB
      //Send two bytes of data
      Wire.write(sensorReading_H);
      Wire.write(sensorReading_L);
      Wire.endTransmission();

Go Up