I bought a special I2C pressure sensor and tried to run it on an arduino - but without any success.
With the I2C scanner sketch I found the device with address 0x6D.
The datasheet information:
Address: 0x6D (Write: 0xDA, read: 0xDB)
Data register: a 24bit signed integer, stored in 3 registers of address 0x06, 0x07, 0x08.
The example sketch on the datasheet is following:
iic_start(); //I2C start
iic_write(0xDA); //Device address, write operation
iic_write(0x06); //Write data start address
iic_start(); //Restart
iic_write(0xDA+1); //Device address (0xDB), read operation
dat=iic_readbyte(1); //Read first byte(0x06),ACK
dat <<= 8; //Shift
dat += iic_readbyte(1); //Read second byte(0x07),ACK
dat <<= 8; //Shift
dat += iic_readbyte(0); //Read third byte(0x08),NACK
iic_stop(); //Stop
I tried to translate it into arduino as following:
I tried many different options but still get the same value (4294967295) with connected sensor with different pressures and also when the sensor is disconnected. May anybody help me?
I think you may be confused about the function of the SENSOR_READ and _WRITE bits. These are the low bit of the device address and are handled automatically by the Wire library.
endTransmission() has a return code that will tell you if the transmission was successful or not. It might be good to see if you are successfully talking to your sensor.
According to the data sheet, register 6 is the high byte of the pressure value. Your code treats it as the low byte.
But that won't make a difference if the result is 0xFFFFFFF, as you report.
I tend to avoid the Wire library, and use the basic I2C routines, which are similar to those used in the data sheet. I've attached a copy, if you want to try that approach.
Thank you. I tried your I2C_lib.c, but there is an error message while compiling.
This is the sketch:
#include "I2C_lib.c"
float fadc;
float ADC;
int dat;
void setup()
{
Serial.begin(9600);
delay(100);
I2C_Init();
delay(100);
}
void loop()
{
I2C_Start();
I2C_Write(0xDA);
I2C_Write(0x06);
I2C_Start();
I2C_Write(0xDB);
dat=I2C_ReadACK(1); //Read first byte(0x06),ACK
dat <<= 8; //Shift
dat += I2C_ReadACK(1); //Read second byte(0x07),ACK
dat <<= 8; //Shift
dat += I2C_ReadNACK(0); //Read third byte(0x08),NACK
I2C_Stop(); //Stop
if(dat & 0x800000)
{
fadc= dat - 16777216.0;
}
else
{
fadc = dat;
}
ADC = 3.3* fadc /8388608.0;
P = 500 * (ADC-0.5)/2.0;
}
And this is the error message:
Arduino: 1.8.8 (Windows Store 1.8.19.0) (Windows 10), Board: "Arduino Leonardo"
sketch\I2C_lib.c: In function 'I2C_Init':
sketch\I2C_lib.c:23:5: error: 'TWSR' undeclared (first use in this function)
TWSR = 0; // prescalar to zero
^
sketch\I2C_lib.c:23:5: note: each undeclared identifier is reported only once for each function it appears in
sketch\I2C_lib.c:24:5: error: 'TWBR' undeclared (first use in this function)
TWBR = ((F_CPU/F_SCL)-16)/2; // set SCL frequency in TWI bit register
^
sketch\I2C_lib.c: In function 'I2C_Stop':
sketch\I2C_lib.c:29:2: error: 'TWCR' undeclared (first use in this function)
TWCR=TW_STOP;
^
sketch\I2C_lib.c:32:20: error: 'TWSTO' undeclared (first use in this function)
while(TWCR & _BV(TWSTO));
^
sketch\I2C_lib.c: In function 'I2C_Detect':
sketch\I2C_lib.c:38:5: error: 'TWCR' undeclared (first use in this function)
TWCR = TW_START; // send start condition
^
sketch\I2C_lib.c:40:2: error: 'TWDR' undeclared (first use in this function)
TWDR = addr; // load device's bus address
^
sketch\I2C_lib.c:15:20: error: 'TWSR' undeclared (first use in this function)
#define TW_STATUS (TWSR & 0xF8) // returns value of status register
^
sketch\I2C_lib.c:43:13: note: in expansion of macro 'TW_STATUS'
return (TW_STATUS==0x18); // return 1 if found; 0 otherwise
^
sketch\I2C_lib.c: In function 'I2C_Write':
sketch\I2C_lib.c:66:5: error: 'TWDR' undeclared (first use in this function)
TWDR = data; // load data to be sent
^
sketch\I2C_lib.c:67:5: error: 'TWCR' undeclared (first use in this function)
TWCR = TW_SEND; // and send it
^
sketch\I2C_lib.c:15:20: error: 'TWSR' undeclared (first use in this function)
#define TW_STATUS (TWSR & 0xF8) // returns value of status register
^
sketch\I2C_lib.c:69:13: note: in expansion of macro 'TW_STATUS'
return (TW_STATUS!=0x28); //0 if successful, 1 if not
^
sketch\I2C_lib.c: In function 'I2C_ReadACK':
sketch\I2C_lib.c:76:5: error: 'TWCR' undeclared (first use in this function)
TWCR = TW_ACK; // ack = will read more data
^
sketch\I2C_lib.c:78:12: error: 'TWDR' undeclared (first use in this function)
return TWDR;
^
sketch\I2C_lib.c: In function 'I2C_ReadNACK':
sketch\I2C_lib.c:86:5: error: 'TWCR' undeclared (first use in this function)
TWCR = TW_NACK; // nack = not reading more data
^
sketch\I2C_lib.c:88:12: error: 'TWDR' undeclared (first use in this function)
return TWDR;
^
exit status 1
Fehler beim Kompilieren für das Board Arduino Leonardo.
I'm a beginner and I don't know, what I done wrong.
That I2C library is intended for the Arduino Uno or similar with an ATmega328 processor. Evidently it will not work on the Leonardo, with the 32U4 processor.
From the schematic diagram I examined, it does not appear that the Leonardo has the required pullup resistors on the I2C lines (SDA and SCL). So, if they are not present on the sensor, I2C won't work. You may need to add them -- try 4.7K to 5V on each line.
What Arduino did you use to run the I2C address scanner?
As a beginner, you have started a difficult project.
I used the NodeMCU v3.2 to run the scanner. This should be the final device for the sensor.
I thought, it would not be difficult. I did read and test some examples with libraries and with the code on the datasheet it looked not very difficult.
I bought a special I2C pressure sensor and tried to run it on an arduino - but without any success.
With the I2C scanner sketch I found the device with address 0x6D.
The datasheet information:
Address: 0x6D (Write: 0xDA, read: 0xDB)
Data register: a 24bit signed integer, stored in 3 registers of address 0x06, 0x07, 0x08.
....
the I2C scanner returns an address so I guess it's safe to assume that your wiring is OK.
from what I can see, you have 0x6D as your device address and 0x06,0x07 and 0x08 are the internal register sub-addresses you want to access to read the pressure.
so using the standard Wire.h library, maybe try using this wire function which include the internal registers (untested):
#include <Wire.h>
#define SENSOR_ADDRESS 0x6D
#define PRESSURE_BYTES 3
const uint32_t PRESSURE_REG=0x00060708; //pressure registers 0x06 (MSB), 0x07, 0x08(LSB)
void setup()
{
Serial.begin(9600);
delay(5000);
Wire.begin();
delay(100);
}
void loop()
{
union {
uint8_t bytes[4];
uint32_t pressure;
} in;
//this is the function I was referring to...
Wire.requestFrom(SENSOR_ADDRESS, PRESSURE_BYTES, PRESSURE_REG, PRESSURE_BYTES, true);
if (Wire.available()) {
for (uint8_t i = PRESSURE_BYTES; i > 0; --i) {
in.bytes[i-1] = Wire.read();
}
}
Serial.print("HEX: 0x");
Serial.println(in.pressure,HEX);
delay(1000); //polls approx every second
}
sorry, not sure if I got the byte order right but I hope that helps!
No, it doesn't. From the datasheet you can see, that the pressure is stored as a 24-bit signed integer. Blackfin's code will not account for that, thus returning false data. For example, a measurement value of -500, using the provided code, will be stored as 16776716.
The datasheet provides you with the correct conversion from a 24-bit signed integer to a 32-bit signed integer (or float).
In addition to the above correction, the code that I and Blackfin posted, the byte order is handled incorrectly.
According to the data sheet, the byte in register 6 is the most significant byte of the pressure.
Also, you shouldn't need the Wire.available() call. Wire.requestFrom() is a complete transaction that either works, or it doesn't, and the program does nothing useful in the latter case.
I'm not shure, if I understand you. I saw, "low", "med" and "high" were in a wrong order. I also didn't insert the calculation in my posted sketch, because I wanted to keep the sketch as easy as possible.
Here is my code, that works and shows the preassure in "bar":