2 Arduino I2C communication
-
- Posts: 113
- http://meble-kuchenne.info.pl
- Joined: Thu Dec 10, 2020 5:40 pm
- Been thanked: 10 times
Re: 2 Arduino I2C communication
now I have modified as you wrote but I find the master uart output populated by many numbers that do not correspond with those read by the I2C bus
- Attachments
-
- mst3.fcfx
- (14.32 KiB) Downloaded 208 times
-
- Screenshot 2024-06-15 155821.png (33.33 KiB) Viewed 8354 times
-
- Screenshot 2024-06-15 155758.png (38.81 KiB) Viewed 8354 times
Re: 2 Arduino I2C communication
in ascii it reads this
- Attachments
-
- Screenshot 2024-06-15 163006.png (87.87 KiB) Viewed 8353 times
-
- Screenshot 2024-06-15 162829.png (32.9 KiB) Viewed 8353 times
-
- Valued Contributor
- Posts: 1453
- Joined: Wed Dec 09, 2020 9:37 pm
- Has thanked: 135 times
- Been thanked: 707 times
Re: 2 Arduino I2C communication
The terminal program is either splitting the received data very oddly - or something odd is occurring?
This is my 'master' program - I changed it to Uno but it should work AOK if you change the target back to a Mega.
With the slave having a 10ms delay in the loop in main and a 1s delay in the master I get (snapshot - it's been running a while)
Martin
This is my 'master' program - I changed it to Uno but it should work AOK if you change the target back to a Mega.
With the slave having a 10ms delay in the loop in main and a 1s delay in the master I get (snapshot - it's been running a while)
1023720
1023821
1023921
1024022
1024123
1024223
Martin
Re: 2 Arduino I2C communication
ok I changed the terminal and I read as you read, and from what I see the code already does a conversion of these 2 bytes and probably by increasing the count the third and fourth will join (if I interpreted correctly), but I have to give you a another question, if I send for example 20 bytes to the master, how can I get only 2 or 4? for example the third and the fourth?, or is it better that in the slave they are already divided into registers and then ask for each individual register? (if it can be done)
- Attachments
-
- Screenshot 2024-06-15 193631.png (219.51 KiB) Viewed 8341 times
-
- Valued Contributor
- Posts: 1453
- Joined: Wed Dec 09, 2020 9:37 pm
- Has thanked: 135 times
- Been thanked: 707 times
Re: 2 Arduino I2C communication
Good...
You can do either - if you want, you could do "write reg_addr, read n_bytes" to read individual registers - or if everything is to be read at once then pass back 20 bytes.
One advantage of the write ... read ... approach is that the master won't interrupt the slave whilst it is in the middle of reading the sensor (see before about disabling interrupts)
If you read all 20 bytes - depending on the variables returned (are they all 4 bytes or some 2 or 1 etc) you could add a 'helper' macro :
.x = GetValue(byte[] data, int index, int length) that returns a 'length' bytes value from index.
If you read individual registers - have .x = GetValue(.reply, length)
(eg .value = GetValue(.reply, 4, 4) would return the 4 byte value from .reply[4..7])
One thing to watch - I passed the data as MSB (most significant byte) first - this reads well on the oscilloscope (0,0,0,1 = 1) but the reality might be that registers are passed LSB (least . .) first (1, 0, 0, 0) - GetValue could handle this (and this will be consistent over all values) The datasheet should reveal all.
Martin
You can do either - if you want, you could do "write reg_addr, read n_bytes" to read individual registers - or if everything is to be read at once then pass back 20 bytes.
One advantage of the write ... read ... approach is that the master won't interrupt the slave whilst it is in the middle of reading the sensor (see before about disabling interrupts)
If you read all 20 bytes - depending on the variables returned (are they all 4 bytes or some 2 or 1 etc) you could add a 'helper' macro :
.x = GetValue(byte[] data, int index, int length) that returns a 'length' bytes value from index.
If you read individual registers - have .x = GetValue(.reply, length)
(eg .value = GetValue(.reply, 4, 4) would return the 4 byte value from .reply[4..7])
One thing to watch - I passed the data as MSB (most significant byte) first - this reads well on the oscilloscope (0,0,0,1 = 1) but the reality might be that registers are passed LSB (least . .) first (1, 0, 0, 0) - GetValue could handle this (and this will be consistent over all values) The datasheet should reveal all.
Martin
Re: 2 Arduino I2C communication
ok but do the registers have to be created in the slave? and if so how is it done? you write the statement .value = GetValue(.reply, 4, 4) but does the getvalue function need to be defined? because it is not recognized
Sorry if I ask you questions that may seem silly to you
Sorry if I ask you questions that may seem silly to you
-
- Valued Contributor
- Posts: 1453
- Joined: Wed Dec 09, 2020 9:37 pm
- Has thanked: 135 times
- Been thanked: 707 times
Re: 2 Arduino I2C communication
Yes - assuming the slave is connected to the sensor. The slave reads the values of the sensor registers (addresses, or depending on the sensor this might be flow_rate, temperature etc returned by the FC component) The slave then 'supplies' these to the master on request.
GetValue - yes this would need to be created (and maybe renamed !) This would be a macro something along the lines of:
Then in main:
.x = GetValue(.reply, 0, 4) // Get a long from pos 0
.y = GetValue(.reply, 4, 2) // Get a word from pos 4
.z = GetValue(.reply, 6, 1) // Get a byte from pos 6
Alternatively if the sensor returns 5 long ints (20 bytes?)
loop 5 times on .i
.results[.i] = GetValue(.reply, .i * 4, 4)
end loop
Martin
GetValue - yes this would need to be created (and maybe renamed !) This would be a macro something along the lines of:
Code: Select all
GetValue(byte[] data, int pos, int length) return unsigned_long
local v = 0
loop .length times on .i
.v = (.v << 8) + .reply[.i + .pos]
end loop
return = .v
.x = GetValue(.reply, 0, 4) // Get a long from pos 0
.y = GetValue(.reply, 4, 2) // Get a word from pos 4
.z = GetValue(.reply, 6, 1) // Get a byte from pos 6
Alternatively if the sensor returns 5 long ints (20 bytes?)
loop 5 times on .i
.results[.i] = GetValue(.reply, .i * 4, 4)
end loop
Martin