I’m using the library in a project that receives data from
a weather station using a RFM01 receiver with SPI. This part works. Now I have added a BMP085 pressure module that uses I2C
communication. SDA is connected to pin 3 and SCL to pin 5 of my rev.1 board. This simple test program never makes it past the bcm2835_i2c_begin();
/*****************************************************************************
* File: bmp085test.c
* Compiled with: gcc -o bmp085test bmp085test.c -l bcm2835
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <bcm2835.h>
char eeprom[22] = { 0, 0, };
void main()
{
bcm2835_i2c_begin();
bcm2835_i2c_setSlaveAddress(0x78);
uint8_t ret = bcm2835_i2c_read(eeprom, 22);
printf("Read return code: %d\n", ret);
bcm2835_i2c_end();
}
BTW the pressure module works perfectly well with a different bcm2835 library. I just don’t want to use two bcm2835 libraries in the same project. Any suggestions?
Sorry, but this is WAY beyond me. I tried to read up on the I2C protocol, but this might as well have been Chinese. I have absolutely no experience in electrical engineering; I’m strictly a software guy. The BMP085 datasheet says the steps to find the temperature and pressure are:
Here is my fist problem: how do I read 22 bytes from the module with a slave address of 0x77 starting at the register address 0xAA? The original BMP085 API has a function like:
i2c_read(0x77, 0xaa, eeprom, 22);
The bcm2835 library doesn’t have such a function. Here is what I have done so far:
At this point I can find the 22 byte EEPROM data starting at eeprom[20]. OK, I don’t understand that, but good to have the data anyway.
Now comes the second step. I’m supposed to write the value 0x2E to register 0xF4. Here I’m stuck, completely … Again the original API uses a function like:
i2c_write(0x77, 0xf4, &cmd_ut, 1);
My next commands are:
...
char cmd_ut = 0x2e;
bcm2835_i2c_write(&writecmd, 1);
bcm2835_i2c_write(&cmd_ut, 1);
usleep(4500);
bcm2835_i2c_write(&readcmd, 1);
bcm2835_i2c_read(reg, 50);
Where do I specify the address 0xf4 to write to? Whatever I do, the write command does nothing. I found out that after the successful execution I should find the data in eeprom[7] to eeprom[9].
What am I doing wrong?? Is the bcm2835 library missing a function here? Can anybody post a working I2C program (but again, I might not be able to understand it)?
Cheers
KarlHi Mike:
Thank you for your fast answer. I really appreciate you taking time to help users like me. I’ve got 40+ years of programming experience in Assembler, Fortran, Cobol, PL/1 … you name it. But not in C or any of its OO derivates! I’m also just finding my way around Linux, so I’ve got a lot to learn, all at the same time. I hope you bear with me.
The good news is: the read part work. The bcm2835_i2c_write(…); however just doesn’t seem to do what I want it to. Here is my sequence of commands:
This should get me the temperature in the utemp buffer. However what I get is whatever was left by the previous program in the specified register locations. If the last successful call (by a different program) was for the pressure, that’s what I get, even though I’ve requested the temperature. The two successive write commands don’t seem work. Here is another of my stupid (or maybe not) questions: how does the BMP085 module distinguish if the first parameter of the write command is an address (to write to) or a data (to be written into some address)?
Anyway, here is an excerpt of the program that works. It’s by Kevin Sangelee and part of his weather station project. For brevity I have only copied the i2c_write and i2c_read functions
I tried to compare this code to your read/write functions, but I’m probably comparing apples and oranges.
Thanks again for your help and this library!
Cheers
Karl