I work on a project which aim is to get data from two 4-20 mA flow meters.
For that, an Arduino Uno slave first makes measurement on analogic ports (A0, A1) and get a tension (0-1023) (sensorValue and sensorValue2).
The slave send data to the master (Arduino Uno) directly from the integer used to get the tension from 0 to 1023.
The master does not get the proper integer send by the slave (there are some variations but that's not the true ones). I verified the data send, it seems to be good (integer from 0 to 1023).
The problem is that if I defined manually the value of the sensors values like (sensorValue=247 and sensorValue2=153) then the master receives the proper values.
// Request data from slave.
Wire.beginTransmission(SlaveDeviceId);
int available = Wire.requestFrom(SlaveDeviceId, (uint8_t)4);
if (available == 4)
{
int receivedValue = Wire.read() << 8 | Wire.read();
Serial.println(receivedValue);
delay(10);
int receivedValue2 = Wire.read() << 8 | Wire.read();
Serial.println(receivedValue2);
}
else
{
Serial.print("Unexpected number of bytes received: ");
Serial.println(available);
}
int result = Wire.endTransmission();
if (result)
{
Serial.print("Unexpected endTransmission result: ");
Serial.println(result);
}
If I get 202 from the analogic A0, the master receives 250.
If I code : sensorValue=202, then the master receives 202.
I can't understand why. I verified that sensorValue get from A0 is a true integer (it is).
I also verify the values send in the array "buffer" and the value of sensorValue : all are good before going to the master.
The I2C bus is not a serial bus where you put data on one end and it comes out at the other end. It is not that kind of bus.
Is it possible to do your project with a single Arduino Uno ? That is easier (a lot easier, really a lot easier).
The next option is a Serial bus, preferably with a Arduino board that has a spare hardware Serial port.
If you want to continue with the I2C bus, then you have to do everything just right. Your project might fail because of the I2C bus between two Arduino boards, because some project like that fail and are never finished. Therefor your goal should be a project that you can finish.
I had some projects in the past with slave and master on I2C bus (rain gauge) and it was working properly.
When I send a defined integer (as I said like sensorValue=202) the master receives the proper value. When the 202 come from the analogic port, the value received by the master is not the good one.
I can't believe the problem comes from I2C because I can send good data if it is defined "manually".
Also, at the step of the project, I can't go back to one Arduino Uno and no Slave (all are mounted on a PCB).
Can you show two minimal working sketches for the Master and the Slave that has the problem ?
It is easier if you use an array of integers:
Master board
int available = Wire.requestFrom(SlaveDeviceId, 4);
if (available == 4)
{
int16_t value[2]; // two signed integers of 16 bit, total 4 bytes
Wire.readBytes(value, sizeof(value));
}
Slave board
The onRequest handler:
int16_t value[2]; // two signed integers of 16 bit, total 4 bytes
value[0] = analogRead(A1);
value[1] = analogRead(A2);
Wire.write( value, sizeof(value));
I think that should work.
How do you know that nothing is received ?
If the 4 bytes are not received by the Master, then your I2C bus is not working.
What else is connected to the I2C bus ? Do you have pullup resistors ?
Can you choose Slave address 0x20 or so ? A value of 3 is too low, and I read that even 8 could cause a problem.
The analogRead() may cause a timeout of the current transmission.
The master can not know how many bytes it received, that's a known problem of the I2C protocol. Only 0 bytes signals an general bus error with this slave.
There is a 250 Ohm resistance like in the schema below to get a signal from 0-24V to be 0-5V (0-1023 in the analogic A0/A1). The 4 and the 20 mA can be programmed with the flow we want (0-35 L/min).
With one arduino, everything is ok in terms of values. The only problem we have is getting 250 instead of 202 from slave to master.
There are 2 flow meters with scheme like the picture below, one distance ultrasonic sensor (analogic with a voltage diviser) and 7 moisture sensor (SDI-12) repeated in 6 areas.
The only problem we have is with the flow meters and that's why I isolate only 1 flow meter to test the circuitry and code.
I'd try this:
Transmit a dummy byte (command...) to the slave first. Insert a delay that allows the slave to collect the current analog values in/after its onReceive event for subsequent transmission in onRequest.
If you really used that Master and Slave sketch in your reply #13, and the Master shows 250, then the analogRead() has returned 250. You do not show the value of the Slave, so it is 250.
Sorry for being so strict, but we have to be precise and accurate because something weird is going on.
I don't care if that is not possible, that is what you get. As soon as you use the I2C bus, then it is 250.
Your circuit needs a protection resistor in the signal path to A0. For example 1k (1k to 10k). It is possible to damage the analog circuitry inside the chip, while the rest of the chip still runs. It could be possible that analogRead() no longer reads the analog input correctly.
Do you have a schematic or a layout of your PCB ?
Do you have another Arduino board ? Can you do more tests ? for example with a potentiometer to the analog input, or exchange the Master and the Slave board. Can you show a photo ? Maybe you use a breadboard (they have bad contacts). Maybe a GND is missing between the Arduino boards.
Hi Koepel, I will try all you have mentioned (the potentiometer is really a good idea) and send some pictures.
Note that when I said it returned 250 instead of the value measured by AO, when I just ask the slave to read with the same circuitry, I have the good value. That's why the problem of I2C communication can be one the problem source.
I am going to check if the value returned by the master is proportional to the true value and that's why potentiometer is nice !
When you talk about protection, do you mean just a resistance like in the picture below?