alexh-name / bsec_bme680_linux

Read the BME680 sensor with the BSEC library on Linux (e.g. Raspberry Pi)
Other
87 stars 48 forks source link

SPI comms for multiple sensors? #10

Closed Jedimaster711 closed 5 years ago

Jedimaster711 commented 6 years ago

Hi Alex, I'm looking to try and convert this to use the SPI interface with an end goal of using multiple sensors together and was wondering if you could provide any insight.

I am pretty new to programming(intro to C++ class), so any insight at all would be helpful.

I am currently looking to use the spidev library, unless there's any you'd recommend?

I am thinking i just need to swap out i2cOpen, i2cClose and i2cSetAddress, and their corresponding calls. I believe I am currently hung up on i2cSetAddress, specifically with if (ioctl(g_i2cFid, I2C_SLAVE, address) < 0) not fully sure what the SPI equivalent of this would be, so any help would be appreciated. I'm mostly just replacing every instance of "i2c" with "spi" and hoping for the best though. (also, I set spi_address = 0.0, no clue if that's right or not)

I understand if you aren't able to help me, and I thank you for creating this program regardless!

bsec_bme680.txt (made it a .txt just to upload it)

alexh-name commented 6 years ago

Hi Jedimaster711,

I'll try to come back to you at the end of the week.

Please know beforehand that unfortunately I don't have any experience with SPI, so I wouldn't expect much from my insights.

Best, Alex

Jedimaster711 commented 6 years ago

I think that this library appears to be the simplest http://www.raspberry-projects.com/pi/programming-in-c/spi/using-the-spi-interface it looks like the initialization is pretty straightforwards as well as the closing. Just have to figure out how to use the read and write correctly, prehaps I can figure that out tomorrow -edit: also, if my understanding is correct, SPI reads by writing data to the slave, and the slave can only send data back while it is being written to. Essentially the data buffers are swapped.

Jedimaster711 commented 6 years ago

update: I think i'm pretty close, I installed the bcm2835 library and I think I've got it talking over the SPI pins and using the SPI commands, but I believe it's still trying to talk using the I2C protocol. I believe that there's SPI and I2C protocols already in the BSEC library, so my question to you is; did you select the I2C portion somewhere in the code that I've not found yet, or does it just default to I2C unless SPI is specified?

I think i'm going to try to implement the SPI structures shown in the README.md file of the API folder and see if that's the last puzzle piece, fingers crossed!

alexh-name commented 6 years ago

Good luck!

I basically just filled in the blanks in ./example/bsec_iot_example.c in the BSEC distribution, where it states that SPI should be just as viable. The functions i2cOpen, i2cClose and i2cSetAddress are the only spots where my code is doing anything i2c related.

However you might want to take a look at ./example/bsec_integration.c of the BSEC distribution where it has a small part commented as /* Fixed I2C configuration */:

bme680_g.dev_id = BME680_I2C_ADDR_PRIMARY;
bme680_g.intf = BME680_I2C_INTF;
Jedimaster711 commented 6 years ago

After lots of head banging, I have gotten the BME680 running with SPI communications!!

do you have any insight as to how to use multiple sensors together?

alexh-name commented 6 years ago

Would you mind sharing your changes to use SPI?

I have no experience with SPI, but using multiple sensors should at least be possible by connecting to different pins and then running multiple instances of bsec_bme680_linux which had different addresses specified in compile time.

Given some spare time I could move specifying the address into the make.config.

Jedimaster711 commented 6 years ago

yeah I used the BCM2835 library here which has to be installed http://www.raspberry-projects.com/pi/programming-in-c/spi/using-the-spi-interface also change bme680_g.intf = BME680_I2C_INTF; to bme680_g.intf = BME680_SPI_INTF; in ./example/bsec_integration.c

I replaced i2cOpen and i2cClose with SPI versions, and scrapped i2cSetAddress I also had to make some changes to bus_read and bus_write

I also made some changes to main and output_ready to make it prompt a filename and save the output to a .csv file

bsec_bme680_SPI.txt

Jedimaster711 commented 6 years ago

Hey Alex, after a while, I have gone through several things trying to get 6 sensors running.

  1. I tried "hacking" the integration.c bsec_iot_loop function to alternate through different addresses, this worked alright for 2 sensors, but did them at 6 seconds instead of 3, also, once a third sensor was connected, it went back to only pinging the first sensor.

  2. I tried running the program 6 times(once for each sensor) for each address, this worked, but crashed after a short while. This is because SPI works all off shared data lines, and then I was bit-banging the ports, and I believe eventually the programs both tried writing to SPI ports at the same time and corrupted each other. I believe they crashed after about 1 hour or so

3.CURRENT: Now I am trying to use pthread to run the main() function as a thread for each sensor, with a global flag and delay for if the SPI port is in use to prevent them from simultaneously writing/reading and corrupting each other. Unfortunately, it looks like when my second thread initializes, it overwrites the dev_id of the first thread. I believe this is the bme680_g structure in the bsec_integration.c file, and I am going to try making a separate structure for each thread

alexh-name commented 5 years ago

Hi, I appreciate all your feedback and effort, thanks!

However, as I'm not going to use SPI myself I won't have any means to test and incorporate your code. It would be awesome if you could fork this project and then commit your changes for SPI there. Feel free to summon me for any more questions.