Hello guys,
I am trying to change the slave address of a NPA 201 pressure sensor by Amphenol Sensors. I want to connect up to 50 sensors with the Arduino UNO R3 and according to the data sheet, it is possible to change the address by modifying the sensor’s EEPROM. Right now I am working with the NPA 201 EV-Board which has the I2C pull-ups included. The procedure for the address change is explained in the application note attached below, however, I had some problems sending the commands via the Wire.h library. Somehow I managed to manipulate the wrong data bits in the EEPROM and already destroyed one sensor by trying to change its address I can’t find the sensor with the i2c_scanner anymore…
A possible issue could be that I could not send the commands in step 2 (see Application Note) properly. I checked some of the Wire.h-commands on an oscilloscope, and I can’t figure out how to realize a command like that one:
[7 bit address + Read bit (=1)] , [command byte ( = 0x20 )]
Whenever I use “Wire.requestFrom(sensor_address);” it doesn’t seem to accept any other command bytes. It is also possible that all the commands worked properly and that I just modified the wrong bits in the memory.
I also tried out the Soft.I2C library but couldn’t get it done yet.
Do you guys have any idea how to send commands like that with the Wire.h library or could you think of any other possibilities? I’d prefer not to use a multiplexer, because space is limited in my application.
I’ll attach my code below (the one that killed the sensor), maybe there are some other mistakes in it which I did not see…
I am grateful for any kind of help and suggestions, thanks for your time!
Cheers, Max
/* NPA 201
25.07.2017
*/
#include <Wire.h>
const int sensor_addr = 0x27; //default sensor address
const int read_delay = 21; //read delay suggested in datasheet
const int power_delay = 1000; //delay before powering on the sensor
int PowerPin = 13;
int rbuf[5], msb[17], lsb[17]; //msb und lsb for memory read, rbuf for pressure reading
float P, T, Pconv, Tconv ;
byte error;
void setup() {
pinMode(PowerPin, OUTPUT);
Wire.begin(); // join i2c bus
Serial.begin(9600); // start serial communication
}
void loop() {
// NPA201 barometric pressure sensor
//power on sensor (the sensor needs to be set in command mode right after start-up
delay(power_delay);
digitalWrite(PowerPin, HIGH);
delay(1); // necessary delay for sensor probably due to start-up time
// put sensor in command mode
Wire.beginTransmission(sensor_addr); // transmit to device
Wire.write(0xA9); // start command mode
error = Wire.endTransmission(); // stop transmitting
delay(read_delay);
if (error == 0) {
Serial.println("transmission 1 successful");
}
else {
Serial.println("error in transmission 1");
}
// Read data from sensor memory
for (int i = 20; i <= 36; i++) { //assuming decimal counting here, maybe that was a first issue
Serial.print("Location ");
Serial.println(i);
Wire.beginTransmission(sensor_addr); // transmit to device
Wire.write(i); // move to each register location. That was my workaround trying to read out the memory data
Wire.endTransmission(); // stop transmitting
delay(read_delay);
//read register data and output to serial console
Wire.requestFrom(sensor_addr, 3); // request 3 bytes from sensor
Serial.print("Statusbyte: ");
Serial.println(Wire.read(),BIN);
Serial.print("MSB: ");
msb[i] = Wire.read();
lsb[i] = Wire.read();
Serial.println(msb[i],BIN);
Serial.print("LSB: ");
Serial.println(lsb[i],BIN);
}
//MODIFY ADDRESS DETAILS
lsb[22] = 0x28; //Word02 (Location 22) should contain address details
Serial.println("new address: ");
Serial.print(lsb[22], BIN);
// increment sensor memory page counter
Wire.beginTransmission(sensor_addr);
Wire.write(0x5E); // increment memory page
error = Wire.endTransmission(); // stop transmitting
delay(read_delay);
if (error == 0) {
Serial.println("sensor incrementation successful");
}
else {
Serial.println("error in transmission (step 4)");
}
//Write new memory page to sensor
int k = 20; // k as counter to access previously saved register values
for (int j = 40; j<=56; j++) {
Wire.beginTransmission(sensor_addr); // transmit to device
Wire.write(j);Wire.write(msb[k]);Wire.write(lsb[k]); // send command bytes to memory
Wire.endTransmission(); // stop transmitting
delay(read_delay);
k = k+1;
} // end of writing loop
// create memory page checksum
Wire.beginTransmission(sensor_addr); // transmit to device
Wire.write(0xAA); // checksum command
error = Wire.endTransmission(); // stop transmitting
delay(read_delay);
if (error == 0) {
Serial.println("checksum successful");
}
else {
Serial.println("error in transmission (step 6)");
}
//exit programming mode
Wire.beginTransmission(sensor_addr); // transmit to device
Wire.write(0xA8); // end command mode
error = Wire.endTransmission(); // stop transmitting
delay(read_delay);
if (error == 0) {
Serial.println("Exit Programming mode successful");
}
else {
Serial.println("error in transmission (step 7)");
}
// check status
Wire.requestFrom(sensor_addr, 1);
Serial.print("Statusbyte: ");
Serial.println(Wire.read(),BIN);
//----------------------------------------------------------------------
digitalWrite(PowerPin, LOW);
Serial.println("Sensor off");
delay(60000); // delay in msec
}
NPA201-Datasheet.pdf (1.07 MB)
NPA201-ApplicationNote.pdf (282 KB)