However, Arduino is telling me it cannot even detect the M3021 I have after it is all wired in, and I'm not sure why. I wonder if I am not putting in the correct 0x address, but I'm not sure how to determine what address I should be using. I have also tried to scan for I2C addresses when it is all wired up and nothing is detected.
Any help is greatly appreciated (including tutorials I could read).
I think that you have a sensor with a analog output.
Do you have a multimeter to measure the analog output ? Is the white wire internally connected to the black wire ? Then you can measure the voltage of the green wire.
Bi-directional bus lines are implemented by the devices (master and slave) using open-drain output stages and a pull-up resistor connected to the positive supply voltage. The recommended pull-up resistor value depends on the system setup (capacitance of the circuit or cable and bus clock frequency). In most cases, 4.7kΩ is a reasonable choice. The capacitive loads on SDA and SCL line have to be the same. It is important to avoid asymmetric capacitive loads.
I assume you have the 4.7 KOhm resistors in place?
Address consists of a 7-digit binary value. The factory setting for the I2C slave address is 0x28, 0x36 or 0x46 depending on the interface type selected from the ordering information. The address is always followed by a write bit (0) or read bit (1). The default hexadecimal I2C header for read access to the sensor is therefore 0x51, 0x6D, 0x8D respectively, based on the ordering information.
You either have the sensor with an analog output (as Kopel covers) or you are not correctly using the right address. The four wire sensors can be analog out or I2C. Exactly what you have should reflect in the exact part number. That or as suggested measure the green wire to common with pressure applied.
So when I have the pressure transducer supplied with power (red and black wires into my Arduino's 5V and GND pins, respectively) and I measure voltage across green and white wires with multimeter I get 0.3 mV, which seems correct. (0-5000 PSI sensor, 0-100 mV output, 0.3 x 5000/100 = 15 psi [~room pressure]). And when I applied a pressure to the sensor the voltage went up as expected. Check!
What I don't understand is how to wire the white and green wires into my Arduino. Right now I've got the green wire going into A0 and the white wire going to GND, but the incoming serial data from A0 doesn't seem to change when I apply higher pressure to the sensor.
Any idea if I have the wiring wrong, or something else?
If you can measure the voltage with a multimeter, than you can measure it with a Arduino analog input. Unless the sketch is wrong, or a breadboard has a bad contacts, or a jumper wire is broken, or the Arduino board is broken, or one of the many other reasons.
Can you check everything, and if you can't find it, please show us a photo and the sketch.
What do measure with a multimeter at A0 when everything is connected as you have now ?
Which Arduino board do you have ?
The signal is 0...100mV, so if the analog reference is set to 1.1V (if you have an Arduino Uno), and take the average of a few samples, then the result is reasonable accurate, less than 5% inaccurate should be no problem, maybe 2% is possible when the Arduino is always at room temperature and the sketch is tuned for the actual voltage of the internal reference.
If you have the 0 to 100 mV analog out changing the applied pressure should change Vout proportionally. Green is Vout Pos and White is Vout Neg.
Your sensor appears to be part of what TE references as their MSP300 Series which offer a variety of outputs so we assume you have the 0-100 mV analog out. If you are not seeing a voltage change on the output with 5.0 volts applied something is wrong. Then too consider 0 to 5000 units = 0 to 100 mV is 20 uV per unit of measure. Good luck on the resolution. Even using the Arduino 1. Vref and averaging.
You may also want to measure between the White and Black for continuity. Using the 5.0 volts from your Arduino is fine as long as placing your analog Arduino Ground with your Vout negative (White) is not a problem.
Thanks for your help! I got it to work. My issue ended up being that I didn't realize that there would be 1.8V going through the analog output circuit when all wired up.
Is the white wire internally connected to the black wire ? If you disconnect the sensor from your project, can you verify that those are connected inside the sensor ?
You probably only need the green wire to A0, but you can try if connecting the white wire to GND changes something.
Oops I just edited my previous message to you to say:
"
Thanks for your help! I got it to work. My issue ended up being that I didn't realize that there would be 1.8V going through the analog output circuit when all wired up.
"
My next issue is that the system (as is) is rather insensitive to voltage change on the 0-100 mV range.
Between 0-3500 PSI my output data only changes from 364.00 to 374.00 (always 00 in the decimal place, not sure why), so it appears that I can only register changes of 350 PSI. Any idea how to make my output data have greater precision?
Between 0-3500 PSI my output data only changes from 364.00 to 374.00 (always 00 in the decimal place, not sure why), so it appears that I can only register interval changes of 350 PSI. Any idea how I should approach making my output data have better resolution/precision?
OK while I don't know why you are seeing 1.8 volts can we assume you have the 0 to 100 mV output sensor? Now in your very first post you mention using code for a similar sensor. Your link is for a sensor using I2C communication. That code looks like this:
#include <Wire.h>
int M3200address = 0x28; // 0x28, 0x36 or 0x46, depending on the sensor.
float maxPressure =100; // pressure in PSI for this sensor, 100, 250, 500, ... 10k.
byte status;
unsigned long pressureMillis = 0;
const int pressureTiming = 500; // 500ms every data acquisition
void setup (){
Serial.begin(9600);
Serial.println("M3200 initializing");
Wire.begin();
}
void loop(){
if (millis()-pressureMillis >= pressureTiming){
pressureMillis = millis();
Wire.requestFrom(M3200address,4); // request 4 bytes
int n = Wire.available();
if( n == 4){
status = 0;
uint16_t rawP; // pressure data from sensor
uint16_t rawT; // temperature data from sensor
rawP = (uint16_t) Wire.read(); // upper 8 bits
rawP <<= 8;
rawP |= (uint16_t) Wire.read(); // lower 8 bits
rawT = (uint16_t) Wire.read(); // upper 8 bits
rawT <<= 8;
rawT |= (uint16_t) Wire.read(); // lower 8 bits
status = rawP >> 14; // The status is 0, 1, 2 or 3
rawP &= 0x3FFF; // keep 14 bits, remove status bits
rawT >>= 5; // the lowest 5 bits are not used
// The math could be done with integers, but I choose float for now
float pressure = ((rawP - 1000.0) / (15000.0 - 1000.0)) * maxPressure;
float temperature = ((rawT - 512.0) / (1075.0 - 512.0)) * 55.0;
Serial.print("Status = ");
Serial.println(status);
Serial.print( "Pressure = ");
Serial.println( pressure);
Serial.print( "Temperature = ");
Serial.println( temperature);
Serial.println("-------------------------------------");
}else{
Serial.println( "M3200 Pressure Transducer not Detected");
}
}
}
That code is not going to work for a sensor with a 0 to 100 mV signal out to A0 on your Arduino. So what Arduino do you have and can you post your code?
The answer(s) are in there somewhere. There are ways to go about this and we will get there.
Ron
If you have the 0-100mV sensor, then you have the cheapest version of the sensor, with only the wheatstone bridge. So sensor element only, and no added electronics.
To use that sensor, you must add your own electronis (differential amp, A/D, etc.)
The easiest way is with a HX711 breakout board.
Leo..
I wonder if it's because the OP damaged it by treating the analog output like I2C SCL, which would short the output to ground every time the clock signal went low.
Well, that's consistent with 1.8 volts at no pressure:
1023 x (1.8 v / 5 v ) = 368...in the ballpark of 364.
and 3500 psi would add 1023 x (3500 / 5000) x (0.1 v / 5 v) = 14 counts, in the ballpark of your (374 - 364 = 10 counts).
That would be INTEGER, not interval. And it looks like you're reporting analogRead values, not PSI.
If it really is just a Wheatstone bridge as @Wawa says (which makes sense but hadn't occurred to me ), then the reason it is showing 1.8 volts could be because it is being excited with 3.6 volts[*], and 1.8 volts is the common mode voltage (the no-load voltage with respect to ground measured at either the white wire or the green wire).
[*] edit to add... never mind...that doesn't make sense, because the OP is powering ("exciting") it with 5v.....so how can it be 3.6v? Maybe there's a huge offset...
I have to agree with Wawa in that the output is that of a bridge. So the sensor out common and the Arduino Ground are not the same. I also figure a differential input from sensor to measurement plane is needed. Just as Wawa points out.
So I have a question. While far from a guru of the ADS1115 I have played with the module. I like the P-Gain feature and the Differential Input features. Would an ADS1115 work using differential input and setting the P-Gain for sixteen (+/- 256 mV 1 bit = 0.0078125mV ). Additionally you get the I2C.
Getting late and dogs want out but does anyone see adding an ADS1115 module as a viable solution? Use the diff input mode and in the code map the 0 to 100 mV to 0 to 5000 PSI or whatever the units are.