i2c Nothing Works!!!
Why cant sensors just use something simple like serial UART? I have only ONE i2c device that "works", and that device being the MPU-6050 and that is using the PASM MPU-6050 Driver from Obex.
Now I have also the MPU-9150 (wont work), the bmp180 (x3) (wont work), the bmp085 (x3) (wont work), the hmc5883 (x3) (wont work) and (x7) IR Thermopiles (wont work) and All Modules. I know im not getting shipped multiple broken parts from multiple sources and Everything revolves around i2c.
I have tried every SPIN driver available on obex, and now the PASM drivers as well. Still to this day, I only have ONE working device. All of my other sensors work fine. SPI ok, serial uart, ok. analog to adc ok.
Ive even tried running the BMP threw the MPU's xDA port. I can get the Chip ID, but that is all I can get, everything else appears to be wrong. Ive tried the mpu-9150 obex driver (dont work). ive tried EVERY bmp obex driver (dont work).
I have had made multiple attempts at i2c, even here on the forums. Is there any way to get this stupid protocol to work???!?!??!?!
Now I have also the MPU-9150 (wont work), the bmp180 (x3) (wont work), the bmp085 (x3) (wont work), the hmc5883 (x3) (wont work) and (x7) IR Thermopiles (wont work) and All Modules. I know im not getting shipped multiple broken parts from multiple sources and Everything revolves around i2c.
I have tried every SPIN driver available on obex, and now the PASM drivers as well. Still to this day, I only have ONE working device. All of my other sensors work fine. SPI ok, serial uart, ok. analog to adc ok.
Ive even tried running the BMP threw the MPU's xDA port. I can get the Chip ID, but that is all I can get, everything else appears to be wrong. Ive tried the mpu-9150 obex driver (dont work). ive tried EVERY bmp obex driver (dont work).
I have had made multiple attempts at i2c, even here on the forums. Is there any way to get this stupid protocol to work???!?!??!?!
Comments
I can only tell you that if I had the sensors sitting on my Tachyon Forth system that I would be having them debugged and operating while you watch. Because it's interactive you can scan the bus, delve a little deeper into a device, type in a one-line test and see if it works, etc.
This is a quick scan of my I2C bus through the serial terminal.
.I2CBUS
Fast Device at 0040 BC BC BC BC BC BC BC BC
Fast Device at 00A0 00 00 00 00 00 00 00 00
Fast Device at 00AE FF FF FF FF FF FF FF FF
Fast Device at 00DE FF FF FF FF FF FF FF FF ok
Hardware connections, and if you require pullups on the devices. Then, you have to consider the device address, an if the device address is configurable, is it set correctly at it's input pins. Next, consider your code. I remember going through the i2c learning curve with various devices, and you must tackle the process of tracking down these problems. It gets easier every time. Post your code and maybe someone can spot something. Without code, you will get very little help in this particular case. I use the basic i2c driver for most things that don't require high speed. Once you find a driver that works you just stick with it since a lot of your code will be similar so you can copy and paste blocks into other device needs with small changes. A schematic would be helpful, or even a photo of the setup if it is breadboarded, some info may be obvious just by looking at the setup.
Most parallax boards already have this on P28&P29. But, if you are using different pins, you will need to add those resistors yourself.
Drivers in general do not support clock stretching as it is very rare to find a chip that needs this as it was designed for decades old slow processors acting as slaves mostly. From perusing the sensor datasheets I see no mention of this. Since this is the case the clock line is normally driven high as well as low so no resistor is needed.....wait . However, since you have quite a number of devices on the bus and no telling the length or capacitance of the bus it would be advisable to use a much lower pull-up value on the SDA line, even if there are pull-ups already. Use a value of 2K2 as I2C buses have no problem handling that easily and it will pull-up the line faster. Since you are trying to get these devices to work I would also use a 2K2 on the clock line as well just in case your driver does not drive the line high.
I have tried on both my i2c & gps io (same layout as i2c, on pins 12 & 13). I mentioned before that the Modules come with pullup resistors, so I tried a port with no resistors as well.
I have 2 BMP-180's for testing both ways, one on the i2c bus via the MPU-6050, and one on the GPS Bus (no resistors) (uses module resistors).
They are connected according to the mpu-6050 datasheet (replace Magnetometer with BMP-180 Module).
I mentioned that I have many modules that dont work. Please dont assume they are all hooked up at once. When I test something I prefer to do it one thing at a time. With the exception of now; I am trying to use the MPU-6050 as an inline master to control the bmp since I have been able to get the mpu to work, but only with a PASM driver from obex (i dont know assembly) and cannot get it to work on my own as seen in this code. Which leaves me stuck.
i2c Test Code: i2c Testing.zip
my MPU-6050 Driver that works: MPU-6050.spin (Updated from OBEX Version)
You have:
bmpAddrR = %1110_1110
bmpAddrW = %1110_1111
Yet the reverse should be true. The LSB of the device address distinguishes
between read (1) and write (0) operation, corresponding to address 0xEF (read) and 0xEE (write).
At this stage in your debugging, I'd suggest that you learn everything you can about I2C and one particular device. Then, look at the drivers and see what's happening. I also suggest getting a logic analyzer so that you can see the actual bits being sent. I like the Logic16.
The link provided is another case of someone who could not get anything to work. Don't think you are alone with having trouble with i2c device sanity. In the end it usually comes down to a simple mix of enabling factors, and you are left wondering, what the hey!
I agree with Peter that you may want stiffer pull-ups on your I2C buss with the devices being off-board.
As you may not know Tachyon like Peter does, I wrote a little I2C scanner in Spin (that uses my driver). Running on the PAB the only device address that responds is the boot EEPROM ($A0). You don't have to use the EEPROM buss with my driver; you may specify any two pins.
it started as just bmpAddr = %1110_1110 and was the address found by i2cScanner.
i added separate R & W so i could test them at the same time.
[FONT=courier new][SIZE=1] i2c.writeLocation(mpuSCL, [COLOR=#FF0000]bmpAddrW[/COLOR], $F4, $2E) ' Temperature 0x2E 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms ut1 := i2c.readLocation(mpuSCL, bmpAddr, $F6)[/SIZE][/FONT]
That doesn't work with the driver, because you had defined bmpAddrW asbmpAddrW = % 1110_1111
That is reverse of what it should be, that final bit sets the i2c for Read rather than for write.
An aside, That particular driver, BASIC_I2C driver does not knock that bit down when it does a write. Although it should, as it defines the xmit=0, but then in the writepage method does this...
ackbit := Write(SCL, devSel | Xmit)
but I think that should be, XMIT = $FE, and...
ackbit := Write(SCL, devSel & XMIT)
You are better off with bmpAddr as you have it with readLocation. The driver takes care of setting the bit high for a Read, and it leaves it low for a Write.
yes, that is how i was able to read the Chip ID (0x55) & coefficents (only part of them), i think i was reading the temp & pressure, but only 3 of the 5 digits. when i held the unit i would see the temp climb, then fall when i let go of it... but pressure, nothing changed that value, and it just bounced around.
You do not have 3v3 next to the Xtal connected (definite no-no)
You don't have bypass caps next to all the prop power pins, or you bring them to one close central point, with one cap. (search the forum for many suggestions/rules - search overclocking)
You don't appear to have bypass caps on the input or output pins of VREG1 (see the datasheets) - they need to be at the pins
In fact, your whole pcb is missing bypass caps at most ICs.
The I2C chips you are using specifically require special considerations, both in layout, and in bypass caps (see their datasheets)
This could explain your problems.
I hope this helps. There are some good app notes put out by some of the chip suppliers (not necessarily from those manufactures you are using).
@Cluso99: Don't start something you can't finish, there are too many things to point out that you may as well design a new pcb in the process
Con _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 CLK_FREQ = ((_clkmode-xtal1)>>6)*_xinfreq MS_001 = CLK_FREQ / 1_000 ' // Propeller Pinout Misc1 = 0 Misc2 = 1 Misc3 = 2 Misc4 = 3 MCPCLK = 4 MCPDOut = 5 MCPDIn = 5 MCPCS = 6 NC1 = 7 MPUsda = 8 ' All I2C Sensors on SAME Bus MPUscl = 9 RPitx = 10 RPirx = 11 GPSrx = 12 ' SCL GPStx = 13 ' SDA BMPSCL = 12 BMPSDA = 13 WiFitx = 14 ' White WiFirx = 15 ' Green Misc5 = 16 Misc6 = 17 Misc7 = 18 LED = 19 Piezo = 20 Servo6 = 21 ' Left Side Airlerons Servo5 = 22 ' Gyro Select Servo4 = 23 ' Gyro / Rudder NC2 = 24 Servo3 = 25 ' Motor Speed / Power Servo2 = 26 ' Elevator Servo1 = 27 ' Right Side Airlerons EEPROMscl = 28 EEPROMsda = 29 DEBUGSERtx = 30 DEBUGSERrx = 31 SCL = 12 ' // BMP-180 Settings bmpAddr = 10_1110 bmpAddrR = 10_1110 bmpAddrW = 10_1111 mpuAddr = 01_0000 OSS1 = 0 ' Ultra Low Power OSS2 = 1 ' Standard OSS3 = 2 ' High Resolution OSS4 = 3 ' Ultra High Resolution ' EEPROM data base address - i.e 32K (assumes a 64kb eeprom installed!!) EEPROM_Base = $8000 EEPROMAddr = 10_0000 i2cSCL = 28 ' i2cSDA = 29 OBJ i2c : "pasm_i2c_driver_Ext" ' Finds Both Devices, All Data = FF 'i2c : "basic_i2c_driver_1.3_Mod" ' Finds MPU Only, Data = 255 Ser : "FullDuplexSerial" Var long ac1, ac2, ac3, ac4, ac5, ac6, b1, b2, mb, mc, md, id long UT, UP long T, P long i2cAddress, i2cSlaveCounter long oss Pub Start ser.start(31,30,0,115200) i2c.Initialize(bmpSCL) ' // PASM i2c Driver 'i2c.Initialize(mpuSCL, mpuSDA) ' // basic_i2c_driver1.3_Mod oss := OSS2 repeat ' // All I2C Sensors on SAME Bus ' // MPU-6050 if i2c.devicePresent(mpuSCL, mpuAddr) == True ser.str(string("MPU - Device Located!")) ser.tx(13) waitcnt(clkfreq + cnt) GetMPU else ser.str(string("MPU - Device Not Found")) ser.tx(13) waitcnt(clkfreq + cnt) ' // BMP-180 if i2c.devicePresent(bmpSCL, bmpAddr) == True ser.str(string("BMP - Device Located!")) ser.tx(13) waitcnt(clkfreq + cnt) GetBMP_bmp else ser.str(string("BMP - Device Not Found")) ser.tx(13) waitcnt(clkfreq + cnt) Pub GetMPU | X, Y, Z, A, B, C 'repeat ' // Setup: power mgmt, dlp, smplrtdiv, gyro & accel i2c.writeLocation(mpuSCL, mpuAddr, 107, 000001) ' X Gyro as Clock Source i2c.writeLocation(mpuSCL, mpuAddr, 26, 000011) ' 40 Hz DLP i2c.writeLocation(mpuSCL, mpuAddr, 25, 000001) ' Sample Rate = 500 Hz i2c.writeLocation(mpuSCL, mpuAddr, 27, 011000) ' Gyro = FS3 i2c.writeLocation(mpuSCL, mpuAddr, 28, 010000) ' Accel = AFS2 ' // Read Values X := i2c.readLocation(mpuSCL, mpuAddr, 59) ' = 255 ser.str(string("MPU Out: ")) ser.dec(X) ser.tx(13) Pub GetBMP_BMP | v1, v2, v3, up1, up2, up3, ut1, ut2 'repeat { Table 5: Calibration Coefficients BMP180 reg adr Parameter MSB LSB AC1 0xAA 0xAB AC2 0xAC 0xAD AC3 0xAE 0xAF AC4 0xB0 0xB1 AC5 0xB2 0xB3 AC6 0xB4 0xB5 B1 0xB6 0xB7 B2 0xB8 0xB9 MB 0xBA 0xBB MC 0xBC 0xBD MD 0xBE 0xBF } ' i2c.readLocation(SCL,device_address, register) ' // Read Calibration Coefficients ac1 := i2c.readLocation(bmpSCL, bmpAddr, $AA) ' 1B ac2 := i2c.readLocation(bmpSCL, bmpAddr, $AC) ' FB ac3 := i2c.readLocation(bmpSCL, bmpAddr, $AE) ' C7 ac4 := i2c.readLocation(bmpSCL, bmpAddr, $B0) ' 84 ac5 := i2c.readLocation(bmpSCL, bmpAddr, $B2) ' 61 ac6 := i2c.readLocation(bmpSCL, bmpAddr, $B4) ' 49 b1 := i2c.readLocation(bmpSCL, bmpAddr, $B6) ' 19 b2 := i2c.readLocation(bmpSCL, bmpAddr, $B8) ' 00 mb := i2c.readLocation(bmpSCL, bmpAddr, $BA) ' 80 mc := i2c.readLocation(bmpSCL, bmpAddr, $BC) ' D1 md := i2c.readLocation(bmpSCL, bmpAddr, $BE) ' 0A id := i2c.readLocation(bmpSCL, bmpAddr, $D0) ' 55 *** Should = 0x55 waitcnt((clkfreq / 4) + cnt) ser.str(string("AC1: ")) ser.hex(ac1, 2) ser.str(string(" ")) ser.dec(ac1) ser.tx(13) ser.str(string("AC2: ")) ser.hex(ac2, 2) ser.str(string(" ")) ser.dec(ac2) ser.tx(13) ser.str(string("AC3: ")) ser.hex(ac3, 2) ser.str(string(" ")) ser.dec(ac3) ser.tx(13) ser.str(string("AC4: ")) ser.hex(ac4, 2) ser.str(string(" ")) ser.dec(ac4) ser.tx(13) ser.str(string("AC5: ")) ser.hex(ac5, 2) ser.str(string(" ")) ser.dec(ac5) ser.tx(13) ser.str(string("AC6: ")) ser.hex(ac6, 2) ser.str(string(" ")) ser.dec(ac6) ser.tx(13) ser.str(string("B1: ")) ser.hex(b1, 2) ser.str(string(" ")) ser.dec(b1) ser.tx(13) ser.str(string("B2: ")) ser.hex(b2, 2) ser.str(string(" ")) ser.dec(b2) ser.tx(13) ser.str(string("MB: ")) ser.hex(mb, 2) ser.str(string(" ")) ser.dec(mb) ser.tx(13) ser.str(string("MC: ")) ser.hex(mc, 2) ser.str(string(" ")) ser.dec(mc) ser.tx(13) ser.str(string("MD: ")) ser.hex(md, 2) ser.str(string(" ")) ser.dec(md) ser.tx(13) ser.str(string("ID: ")) ser.hex(id, 2) ser.str(string(" ")) ser.dec(id) ser.tx(13) 'ser.str(string("bmpAddr: ")) 'ser.hex(bmpAddr | 1, 2) ' 0 = EE, 1 = EF 'ser.tx(13) ' // Read Uncompressed Temperature Value ' Write 0x2E into reg 0xF4, wait 4.5ms ' Read reg 0xF6 (MSB), 0xF7 (LSB) i2c.writeLocation(bmpSCL, bmpAddrW, $F4, $2E) ' Temperature 0x2E 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms ut1 := i2c.readLocation(bmpSCL, bmpAddr, $F6) ut2 := i2c.readLocation(bmpSCL, bmpAddr, $F7) 'UT := i2c.readLocation16(bmpSCL, bmpAddr, i2c#OneAddr|$F6) ser.str(string("UT: ")) ser.hex(ut1, 2) ser.str(string(" ")) ser.hex(ut2, 2) ser.str(string(" ")) ser.dec(ut1 + ut2) ser.tx(13) ' // Read Uncompressed Pressure Value ' Write 0x34+(oss<<6) into reg 0xF4, wait #.#ms ' Read reg 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB) 'i2c.writeLocation(bmpSCL, bmpAddr, $F4, $34 + (oss<<6)) ' i2c.readLocation(SCL,device_address, register) ' i2c.writeLocation(SCL,device_address, register, value) if oss == 0 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $34) ' Pressure (oss = 0) 0x34 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms elseif oss == 1 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $74) ' Pressure (oss = 1) 0x74 7.5 waitcnt((clkfreq / 133) + cnt) ' 7.5ms elseif oss == 2 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $B4) ' Pressure (oss = 2) 0xB4 13.5 waitcnt((clkfreq / 74) + cnt) ' 13.5ms elseif oss == 3 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $F4) ' Pressure (oss = 3) 0xF4 25.5 waitcnt((clkfreq / 39) + cnt) ' 25.5ms up1 := i2c.readLocation(bmpSCL, bmpAddr, $F6) up2 := i2c.readLocation(bmpSCL, bmpAddr, $F7) up3 := i2c.readLocation(bmpSCL, bmpAddr, $F8) ser.str(string("UP: ")) ser.hex(up1 + up2 + up3, 6) ser.str(string(" ")) ser.dec(up1 + up2 + up3) ser.tx(13) ser.str(string("UP 123 Hex: ")) ser.hex(up1, 2) ser.str(string(" ")) ser.hex(up2, 2) ser.str(string(" ")) ser.hex(up3, 2) ser.tx(13) ser.str(string("UP 123 Dec: ")) ser.dec(up1) ser.str(string(" ")) ser.dec(up2) ser.str(string(" ")) ser.dec(up3) ser.tx(13) ' // Calculate True Temperature ' // Calculate True Pressure waitcnt(clkfreq + cnt) Pub GetBMP_MPU | v1, v2, v3, up1, up2, up3, ut1, ut2 'repeat { Table 5: Calibration Coefficients BMP180 reg adr Parameter MSB LSB AC1 0xAA 0xAB AC2 0xAC 0xAD AC3 0xAE 0xAF AC4 0xB0 0xB1 AC5 0xB2 0xB3 AC6 0xB4 0xB5 B1 0xB6 0xB7 B2 0xB8 0xB9 MB 0xBA 0xBB MC 0xBC 0xBD MD 0xBE 0xBF } ' i2c.readLocation(SCL,device_address, register) ' // Read Calibration Coefficients ac1 := i2c.readLocation(mpuSCL, bmpAddr, $AA) ' 1B ac2 := i2c.readLocation(mpuSCL, bmpAddr, $AC) ' FB ac3 := i2c.readLocation(mpuSCL, bmpAddr, $AE) ' C7 ac4 := i2c.readLocation(mpuSCL, bmpAddr, $B0) ' 84 ac5 := i2c.readLocation(mpuSCL, bmpAddr, $B2) ' 61 ac6 := i2c.readLocation(mpuSCL, bmpAddr, $B4) ' 49 b1 := i2c.readLocation(mpuSCL, bmpAddr, $B6) ' 19 b2 := i2c.readLocation(mpuSCL, bmpAddr, $B8) ' 00 mb := i2c.readLocation(mpuSCL, bmpAddr, $BA) ' 80 mc := i2c.readLocation(mpuSCL, bmpAddr, $BC) ' D1 md := i2c.readLocation(mpuSCL, bmpAddr, $BE) ' 0A id := i2c.readLocation(mpuSCL, bmpAddr, $D0) ' 55 *** Should = 0x55 waitcnt((clkfreq / 4) + cnt) ser.str(string("AC1: ")) ser.hex(ac1, 2) ser.str(string(" ")) ser.dec(ac1) ser.tx(13) ser.str(string("AC2: ")) ser.hex(ac2, 2) ser.str(string(" ")) ser.dec(ac2) ser.tx(13) ser.str(string("AC3: ")) ser.hex(ac3, 2) ser.str(string(" ")) ser.dec(ac3) ser.tx(13) ser.str(string("AC4: ")) ser.hex(ac4, 2) ser.str(string(" ")) ser.dec(ac4) ser.tx(13) ser.str(string("AC5: ")) ser.hex(ac5, 2) ser.str(string(" ")) ser.dec(ac5) ser.tx(13) ser.str(string("AC6: ")) ser.hex(ac6, 2) ser.str(string(" ")) ser.dec(ac6) ser.tx(13) ser.str(string("B1: ")) ser.hex(b1, 2) ser.str(string(" ")) ser.dec(b1) ser.tx(13) ser.str(string("B2: ")) ser.hex(b2, 2) ser.str(string(" ")) ser.dec(b2) ser.tx(13) ser.str(string("MB: ")) ser.hex(mb, 2) ser.str(string(" ")) ser.dec(mb) ser.tx(13) ser.str(string("MC: ")) ser.hex(mc, 2) ser.str(string(" ")) ser.dec(mc) ser.tx(13) ser.str(string("MD: ")) ser.hex(md, 2) ser.str(string(" ")) ser.dec(md) ser.tx(13) ser.str(string("ID: ")) ser.hex(id, 2) ser.str(string(" ")) ser.dec(id) ser.tx(13) 'ser.str(string("bmpAddr: ")) 'ser.hex(bmpAddr | 1, 2) ' 0 = EE, 1 = EF 'ser.tx(13) ' // Read Uncompressed Temperature Value ' Write 0x2E into reg 0xF4, wait 4.5ms ' Read reg 0xF6 (MSB), 0xF7 (LSB) i2c.writeLocation(mpuSCL, bmpAddrW, $F4, $2E) ' Temperature 0x2E 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms ut1 := i2c.readLocation(mpuSCL, bmpAddr, $F6) ut2 := i2c.readLocation(mpuSCL, bmpAddr, $F7) 'UT := i2c.readLocation16(mpuSCL, bmpAddr, i2c#OneAddr|$F6) ser.str(string("UT: ")) ser.hex(ut1, 2) ser.str(string(" ")) ser.hex(ut2, 2) ser.str(string(" ")) ser.dec(ut1 + ut2) ser.tx(13) ' // Read Uncompressed Pressure Value ' Write 0x34+(oss<<6) into reg 0xF4, wait #.#ms ' Read reg 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB) 'i2c.writeLocation(mpuSCL, bmpAddr, $F4, $34 + (oss<<6)) ' i2c.readLocation(SCL,device_address, register) ' i2c.writeLocation(SCL,device_address, register, value) if oss == 0 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $34) ' Pressure (oss = 0) 0x34 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms elseif oss == 1 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $74) ' Pressure (oss = 1) 0x74 7.5 waitcnt((clkfreq / 133) + cnt) ' 7.5ms elseif oss == 2 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $B4) ' Pressure (oss = 2) 0xB4 13.5 waitcnt((clkfreq / 74) + cnt) ' 13.5ms elseif oss == 3 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $F4) ' Pressure (oss = 3) 0xF4 25.5 waitcnt((clkfreq / 39) + cnt) ' 25.5ms up1 := i2c.readLocation(mpuSCL, bmpAddr, $F6) up2 := i2c.readLocation(mpuSCL, bmpAddr, $F7) up3 := i2c.readLocation(mpuSCL, bmpAddr, $F8) ser.str(string("UP: ")) ser.hex(up1 + up2 + up3, 6) ser.str(string(" ")) ser.dec(up1 + up2 + up3) ser.tx(13) ser.str(string("UP 123 Hex: ")) ser.hex(up1, 2) ser.str(string(" ")) ser.hex(up2, 2) ser.str(string(" ")) ser.hex(up3, 2) ser.tx(13) ser.str(string("UP 123 Dec: ")) ser.dec(up1) ser.str(string(" ")) ser.dec(up2) ser.str(string(" ")) ser.dec(up3) ser.tx(13) ' // Calculate True Temperature ' // Calculate True Pressure waitcnt(clkfreq + cnt)
My mpu-6050 is the ONLY i2c device i have that "works' and does so quite nicely.
SPI devices work 100% (MCP-3208 & RFM23BP (different pcb))
Already on it.. i have 2 newer designs. This one just happens to be on a working ccpm uav prototype that is near completion. Its got a power short as well, my 3.3v reg runs hot (not on new designs). and one of my tracks or joints came loose. it will be replaced very soon, however, this is no reason to not go ahead and finish it, extra parts dangling. Then I will have a crude working model. Still needing altitude / airspeed sensor (2x bmp's) and I would like to get my mpu-9150 working.
Pub GetMPU | X, Y, Z, A, B, C 'repeat ' // Setup: power mgmt, dlp, smplrtdiv, gyro & accel i2c.writeLocation(mpuSCL, mpuAddr, 107, 000001) ' X Gyro as Clock Source i2c.writeLocation(mpuSCL, mpuAddr, 26, 000011) ' 40 Hz DLP i2c.writeLocation(mpuSCL, mpuAddr, 25, 000001) ' Sample Rate = 500 Hz i2c.writeLocation(mpuSCL, mpuAddr, 27, 011000) ' Gyro = FS3 i2c.writeLocation(mpuSCL, mpuAddr, 28, 010000) ' Accel = AFS2
Are you intending to send binary values here? If so, why is there no %?
My suggestion would be to start from scratch with one module, re-read the manual and attempt to read just one register only successfully. If you are getting an ack and ID, then you must be addressing the registers incorrectly, that is assuming the device is functioning properly. Bite size chunks.
test %1000_0000
the reason for the MPU stuff was just a simple test to see if i could get the mpu6050 working on my own (which i cant).
' // Setup: power mgmt, dlp, smplrtdiv, gyro & accel i2c.writeLocation(mpuSCL, mpuAddr, 107, %00000001) ' X Gyro as Clock Source i2c.writeLocation(mpuSCL, mpuAddr, 26, %00000011) ' 40 Hz DLP i2c.writeLocation(mpuSCL, mpuAddr, 25, %00000001) ' Sample Rate = 500 Hz i2c.writeLocation(mpuSCL, mpuAddr, 27, %00011000) ' Gyro = FS3 i2c.writeLocation(mpuSCL, mpuAddr, 28, %00010000) ' Accel = AFS2
I see i missed a few:
Con _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 CLK_FREQ = ((_clkmode-xtal1)>>6)*_xinfreq MS_001 = CLK_FREQ / 1_000 ' // Propeller Pinout Misc1 = 0 Misc2 = 1 Misc3 = 2 Misc4 = 3 MCPCLK = 4 MCPDOut = 5 MCPDIn = 5 MCPCS = 6 NC1 = 7 MPUsda = 8 ' All I2C Sensors on SAME Bus MPUscl = 9 RPitx = 10 RPirx = 11 GPSrx = 12 ' SCL GPStx = 13 ' SDA BMPSCL = 12 BMPSDA = 13 WiFitx = 14 ' White WiFirx = 15 ' Green Misc5 = 16 Misc6 = 17 Misc7 = 18 LED = 19 Piezo = 20 Servo6 = 21 ' Left Side Airlerons Servo5 = 22 ' Gyro Select Servo4 = 23 ' Gyro / Rudder NC2 = 24 Servo3 = 25 ' Motor Speed / Power Servo2 = 26 ' Elevator Servo1 = 27 ' Right Side Airlerons EEPROMscl = 28 EEPROMsda = 29 DEBUGSERtx = 30 DEBUGSERrx = 31 SCL = 12 ' // BMP-180 Settings bmpAddr = 10_1110 bmpAddrR = 10_1110 bmpAddrW = 10_1111 mpuAddr = 01_0000 OSS1 = 0 ' Ultra Low Power OSS2 = 1 ' Standard OSS3 = 2 ' High Resolution OSS4 = 3 ' Ultra High Resolution ' EEPROM data base address - i.e 32K (assumes a 64kb eeprom installed!!) EEPROM_Base = $8000 EEPROMAddr = 10_0000 i2cSCL = 28 ' i2cSDA = 29 OBJ i2c : "pasm_i2c_driver_Ext" ' Finds Both Devices, All Data = FF 'i2c : "basic_i2c_driver_1.3_Mod" ' Finds MPU Only, Data = 255 Ser : "FullDuplexSerial" Var long ac1, ac2, ac3, ac4, ac5, ac6, b1, b2, mb, mc, md, id long UT, UP long T, P long i2cAddress, i2cSlaveCounter long oss Pub Start ser.start(31,30,0,115200) i2c.Initialize(bmpSCL) ' // PASM i2c Driver 'i2c.Initialize(mpuSCL, mpuSDA) ' // basic_i2c_driver1.3_Mod oss := OSS2 repeat ' // All I2C Sensors on SAME Bus ' // MPU-6050 if i2c.devicePresent(mpuSCL, mpuAddr) == True ser.str(string("MPU - Device Located!")) ser.tx(13) waitcnt(clkfreq + cnt) GetMPU else ser.str(string("MPU - Device Not Found")) ser.tx(13) waitcnt(clkfreq + cnt) ' // BMP-180 if i2c.devicePresent(bmpSCL, bmpAddr) == True ser.str(string("BMP - Device Located!")) ser.tx(13) waitcnt(clkfreq + cnt) GetBMP_bmp else ser.str(string("BMP - Device Not Found")) ser.tx(13) waitcnt(clkfreq + cnt) Pub GetMPU | X, Y, Z, A, B, C 'repeat ' // Setup: power mgmt, dlp, smplrtdiv, gyro & accel i2c.writeLocation(mpuSCL, mpuAddr, 107, 000001) ' X Gyro as Clock Source i2c.writeLocation(mpuSCL, mpuAddr, 26, 000011) ' 40 Hz DLP i2c.writeLocation(mpuSCL, mpuAddr, 25, 000001) ' Sample Rate = 500 Hz i2c.writeLocation(mpuSCL, mpuAddr, 27, 011000) ' Gyro = FS3 i2c.writeLocation(mpuSCL, mpuAddr, 28, 010000) ' Accel = AFS2 ' // Read Values X := i2c.readLocation(mpuSCL, mpuAddr, 59) ' = 255 ser.str(string("MPU Out: ")) ser.dec(X) ser.tx(13) Pub GetBMP_BMP | v1, v2, v3, up1, up2, up3, ut1, ut2 'repeat { Table 5: Calibration Coefficients BMP180 reg adr Parameter MSB LSB AC1 0xAA 0xAB AC2 0xAC 0xAD AC3 0xAE 0xAF AC4 0xB0 0xB1 AC5 0xB2 0xB3 AC6 0xB4 0xB5 B1 0xB6 0xB7 B2 0xB8 0xB9 MB 0xBA 0xBB MC 0xBC 0xBD MD 0xBE 0xBF } ' i2c.readLocation(SCL,device_address, register) ' // Read Calibration Coefficients ac1 := i2c.readLocation(bmpSCL, bmpAddr, $AA) ' 1B ac2 := i2c.readLocation(bmpSCL, bmpAddr, $AC) ' FB ac3 := i2c.readLocation(bmpSCL, bmpAddr, $AE) ' C7 ac4 := i2c.readLocation(bmpSCL, bmpAddr, $B0) ' 84 ac5 := i2c.readLocation(bmpSCL, bmpAddr, $B2) ' 61 ac6 := i2c.readLocation(bmpSCL, bmpAddr, $B4) ' 49 b1 := i2c.readLocation(bmpSCL, bmpAddr, $B6) ' 19 b2 := i2c.readLocation(bmpSCL, bmpAddr, $B8) ' 00 mb := i2c.readLocation(bmpSCL, bmpAddr, $BA) ' 80 mc := i2c.readLocation(bmpSCL, bmpAddr, $BC) ' D1 md := i2c.readLocation(bmpSCL, bmpAddr, $BE) ' 0A id := i2c.readLocation(bmpSCL, bmpAddr, $D0) ' 55 *** Should = 0x55 waitcnt((clkfreq / 4) + cnt) ser.str(string("AC1: ")) ser.hex(ac1, 2) ser.str(string(" ")) ser.dec(ac1) ser.tx(13) ser.str(string("AC2: ")) ser.hex(ac2, 2) ser.str(string(" ")) ser.dec(ac2) ser.tx(13) ser.str(string("AC3: ")) ser.hex(ac3, 2) ser.str(string(" ")) ser.dec(ac3) ser.tx(13) ser.str(string("AC4: ")) ser.hex(ac4, 2) ser.str(string(" ")) ser.dec(ac4) ser.tx(13) ser.str(string("AC5: ")) ser.hex(ac5, 2) ser.str(string(" ")) ser.dec(ac5) ser.tx(13) ser.str(string("AC6: ")) ser.hex(ac6, 2) ser.str(string(" ")) ser.dec(ac6) ser.tx(13) ser.str(string("B1: ")) ser.hex(b1, 2) ser.str(string(" ")) ser.dec(b1) ser.tx(13) ser.str(string("B2: ")) ser.hex(b2, 2) ser.str(string(" ")) ser.dec(b2) ser.tx(13) ser.str(string("MB: ")) ser.hex(mb, 2) ser.str(string(" ")) ser.dec(mb) ser.tx(13) ser.str(string("MC: ")) ser.hex(mc, 2) ser.str(string(" ")) ser.dec(mc) ser.tx(13) ser.str(string("MD: ")) ser.hex(md, 2) ser.str(string(" ")) ser.dec(md) ser.tx(13) ser.str(string("ID: ")) ser.hex(id, 2) ser.str(string(" ")) ser.dec(id) ser.tx(13) 'ser.str(string("bmpAddr: ")) 'ser.hex(bmpAddr | 1, 2) ' 0 = EE, 1 = EF 'ser.tx(13) ' // Read Uncompressed Temperature Value ' Write 0x2E into reg 0xF4, wait 4.5ms ' Read reg 0xF6 (MSB), 0xF7 (LSB) i2c.writeLocation(bmpSCL, bmpAddr, $F4, $2E) ' Temperature 0x2E 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms ut1 := i2c.readLocation(bmpSCL, bmpAddr, $F6) ut2 := i2c.readLocation(bmpSCL, bmpAddr, $F7) 'UT := i2c.readLocation16(bmpSCL, bmpAddr, i2c#OneAddr|$F6) ser.str(string("UT: ")) ser.hex(ut1, 2) ser.str(string(" ")) ser.hex(ut2, 2) ser.str(string(" ")) ser.dec(ut1 + ut2) ser.tx(13) ' // Read Uncompressed Pressure Value ' Write 0x34+(oss<<6) into reg 0xF4, wait #.#ms ' Read reg 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB) 'i2c.writeLocation(bmpSCL, bmpAddr, $F4, $34 + (oss<<6)) ' i2c.readLocation(SCL,device_address, register) ' i2c.writeLocation(SCL,device_address, register, value) if oss == 0 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $34) ' Pressure (oss = 0) 0x34 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms elseif oss == 1 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $74) ' Pressure (oss = 1) 0x74 7.5 waitcnt((clkfreq / 133) + cnt) ' 7.5ms elseif oss == 2 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $B4) ' Pressure (oss = 2) 0xB4 13.5 waitcnt((clkfreq / 74) + cnt) ' 13.5ms elseif oss == 3 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $F4) ' Pressure (oss = 3) 0xF4 25.5 waitcnt((clkfreq / 39) + cnt) ' 25.5ms up1 := i2c.readLocation(bmpSCL, bmpAddr, $F6) up2 := i2c.readLocation(bmpSCL, bmpAddr, $F7) up3 := i2c.readLocation(bmpSCL, bmpAddr, $F8) ser.str(string("UP: ")) ser.hex(up1 + up2 + up3, 6) ser.str(string(" ")) ser.dec(up1 + up2 + up3) ser.tx(13) ser.str(string("UP 123 Hex: ")) ser.hex(up1, 2) ser.str(string(" ")) ser.hex(up2, 2) ser.str(string(" ")) ser.hex(up3, 2) ser.tx(13) ser.str(string("UP 123 Dec: ")) ser.dec(up1) ser.str(string(" ")) ser.dec(up2) ser.str(string(" ")) ser.dec(up3) ser.tx(13) ' // Calculate True Temperature ' // Calculate True Pressure waitcnt(clkfreq + cnt) Pub GetBMP_MPU | v1, v2, v3, up1, up2, up3, ut1, ut2 'repeat { Table 5: Calibration Coefficients BMP180 reg adr Parameter MSB LSB AC1 0xAA 0xAB AC2 0xAC 0xAD AC3 0xAE 0xAF AC4 0xB0 0xB1 AC5 0xB2 0xB3 AC6 0xB4 0xB5 B1 0xB6 0xB7 B2 0xB8 0xB9 MB 0xBA 0xBB MC 0xBC 0xBD MD 0xBE 0xBF } ' i2c.readLocation(SCL,device_address, register) ' // Read Calibration Coefficients ac1 := i2c.readLocation(mpuSCL, bmpAddr, $AA) ' 1B ac2 := i2c.readLocation(mpuSCL, bmpAddr, $AC) ' FB ac3 := i2c.readLocation(mpuSCL, bmpAddr, $AE) ' C7 ac4 := i2c.readLocation(mpuSCL, bmpAddr, $B0) ' 84 ac5 := i2c.readLocation(mpuSCL, bmpAddr, $B2) ' 61 ac6 := i2c.readLocation(mpuSCL, bmpAddr, $B4) ' 49 b1 := i2c.readLocation(mpuSCL, bmpAddr, $B6) ' 19 b2 := i2c.readLocation(mpuSCL, bmpAddr, $B8) ' 00 mb := i2c.readLocation(mpuSCL, bmpAddr, $BA) ' 80 mc := i2c.readLocation(mpuSCL, bmpAddr, $BC) ' D1 md := i2c.readLocation(mpuSCL, bmpAddr, $BE) ' 0A id := i2c.readLocation(mpuSCL, bmpAddr, $D0) ' 55 *** Should = 0x55 waitcnt((clkfreq / 4) + cnt) ser.str(string("AC1: ")) ser.hex(ac1, 2) ser.str(string(" ")) ser.dec(ac1) ser.tx(13) ser.str(string("AC2: ")) ser.hex(ac2, 2) ser.str(string(" ")) ser.dec(ac2) ser.tx(13) ser.str(string("AC3: ")) ser.hex(ac3, 2) ser.str(string(" ")) ser.dec(ac3) ser.tx(13) ser.str(string("AC4: ")) ser.hex(ac4, 2) ser.str(string(" ")) ser.dec(ac4) ser.tx(13) ser.str(string("AC5: ")) ser.hex(ac5, 2) ser.str(string(" ")) ser.dec(ac5) ser.tx(13) ser.str(string("AC6: ")) ser.hex(ac6, 2) ser.str(string(" ")) ser.dec(ac6) ser.tx(13) ser.str(string("B1: ")) ser.hex(b1, 2) ser.str(string(" ")) ser.dec(b1) ser.tx(13) ser.str(string("B2: ")) ser.hex(b2, 2) ser.str(string(" ")) ser.dec(b2) ser.tx(13) ser.str(string("MB: ")) ser.hex(mb, 2) ser.str(string(" ")) ser.dec(mb) ser.tx(13) ser.str(string("MC: ")) ser.hex(mc, 2) ser.str(string(" ")) ser.dec(mc) ser.tx(13) ser.str(string("MD: ")) ser.hex(md, 2) ser.str(string(" ")) ser.dec(md) ser.tx(13) ser.str(string("ID: ")) ser.hex(id, 2) ser.str(string(" ")) ser.dec(id) ser.tx(13) 'ser.str(string("bmpAddr: ")) 'ser.hex(bmpAddr | 1, 2) ' 0 = EE, 1 = EF 'ser.tx(13) ' // Read Uncompressed Temperature Value ' Write 0x2E into reg 0xF4, wait 4.5ms ' Read reg 0xF6 (MSB), 0xF7 (LSB) i2c.writeLocation(mpuSCL, bmpAddr, $F4, $2E) ' Temperature 0x2E 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms ut1 := i2c.readLocation(mpuSCL, bmpAddr, $F6) ut2 := i2c.readLocation(mpuSCL, bmpAddr, $F7) 'UT := i2c.readLocation16(mpuSCL, bmpAddr, i2c#OneAddr|$F6) ser.str(string("UT: ")) ser.hex(ut1, 2) ser.str(string(" ")) ser.hex(ut2, 2) ser.str(string(" ")) ser.dec(ut1 + ut2) ser.tx(13) ' // Read Uncompressed Pressure Value ' Write 0x34+(oss<<6) into reg 0xF4, wait #.#ms ' Read reg 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB) 'i2c.writeLocation(mpuSCL, bmpAddr, $F4, $34 + (oss<<6)) ' i2c.readLocation(SCL,device_address, register) ' i2c.writeLocation(SCL,device_address, register, value) if oss == 0 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $34) ' Pressure (oss = 0) 0x34 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms elseif oss == 1 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $74) ' Pressure (oss = 1) 0x74 7.5 waitcnt((clkfreq / 133) + cnt) ' 7.5ms elseif oss == 2 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $B4) ' Pressure (oss = 2) 0xB4 13.5 waitcnt((clkfreq / 74) + cnt) ' 13.5ms elseif oss == 3 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $F4) ' Pressure (oss = 3) 0xF4 25.5 waitcnt((clkfreq / 39) + cnt) ' 25.5ms up1 := i2c.readLocation(mpuSCL, bmpAddr, $F6) up2 := i2c.readLocation(mpuSCL, bmpAddr, $F7) up3 := i2c.readLocation(mpuSCL, bmpAddr, $F8) ser.str(string("UP: ")) ser.hex(up1 + up2 + up3, 6) ser.str(string(" ")) ser.dec(up1 + up2 + up3) ser.tx(13) ser.str(string("UP 123 Hex: ")) ser.hex(up1, 2) ser.str(string(" ")) ser.hex(up2, 2) ser.str(string(" ")) ser.hex(up3, 2) ser.tx(13) ser.str(string("UP 123 Dec: ")) ser.dec(up1) ser.str(string(" ")) ser.dec(up2) ser.str(string(" ")) ser.dec(up3) ser.tx(13) ' // Calculate True Temperature ' // Calculate True Pressure waitcnt(clkfreq + cnt)
and the results of this code... appears correct-ish. still only getting a maximum of 3 digits on 5 digit values (decimal).
Here is an example
readkeyvar := i2c2.i2cRead(i2cSCL2, 0) 'read first bit field 0 - 7 readkeyvar |= i2c2.i2cRead(i2cSCL2, 0) << 8 'read second bit field 8 - 15
ac1 := i2c.readLocation(bmpSCL, bmpAddr, $AA) ' 1B ac1 |= i2c.readLocation(bmpSCL, bmpAddr, $AB) << 8 ' 1B or: ac1 := i2c.readLocation(bmpSCL, bmpAddr, $AB) ' 1B ac1 |= i2c.readLocation(bmpSCL, bmpAddr, $AA) << 8 ' 1B
Depends on what gets returned first, lsb or msb. But you get the idea.
I have also tried one straight to the i2c bus (replacing the mpu6050).
As of right now, the one connected to the GPS bus is giving the data back, but it is missing half of all of the values. And I think the problem lies in the read method. it is only doing an 8 bit read when it should be doing a 16 bit read (according to datasheet). but when i use i2c.readregister16, devices are located, but all data is = 0. Now if i switch to "basic_i2c_driver_1.3_Mod" then it will return data.
' // Read Calibration Coefficients ac1 := i2c.readLocation16(bmpSCL, bmpAddr, $AA) ' 1B ac2 := i2c.readLocation16(bmpSCL, bmpAddr, $AC) ' FB ac3 := i2c.readLocation16(bmpSCL, bmpAddr, $AE) ' C7 ac4 := i2c.readLocation16(bmpSCL, bmpAddr, $B0) ' 84 ac5 := i2c.readLocation16(bmpSCL, bmpAddr, $B2) ' 61 ac6 := i2c.readLocation16(bmpSCL, bmpAddr, $B4) ' 49 b1 := i2c.readLocation16(bmpSCL, bmpAddr, $B6) ' 19 b2 := i2c.readLocation16(bmpSCL, bmpAddr, $B8) ' 00 mb := i2c.readLocation16(bmpSCL, bmpAddr, $BA) ' 80 mc := i2c.readLocation16(bmpSCL, bmpAddr, $BC) ' D1 md := i2c.readLocation16(bmpSCL, bmpAddr, $BE) ' 0A id := i2c.readLocation(bmpSCL, bmpAddr, $D0) ' 55 *** Should = 0x55
now i didnt change how the chip id is read because it is only one register location ($D0) so it appears to be still correct.
i also notice there is no " - " sign that was expected in the results. could this be similar to what your saying about the msb / lsb? I was thinking this was were the problem was comming from, but the results are constantly different (with different applications of code) I am not sure which one is correct.
PUB readLocation16(SCL,device_address, register) : value start(SCL) write(SCL,device_address | 0) write(SCL,register) restart(SCL) write(SCL,device_address | 1) 'value := read(SCL,ACK) 'value <<= 8 value := read(SCL,ACK) value |= read(SCL,ACK) << 8 'readkeyvar := i2c2.i2cRead(i2cSCL2, 0) 'read first bit field 0 - 7 'readkeyvar |= i2c2.i2cRead(i2cSCL2, 0) << 8 'read second bit field 8 - 15 value |= (read(SCL,NAK) & $ff) stop(SCL) return value
and the main code to this:
Con _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 CLK_FREQ = ((_clkmode-xtal1)>>6)*_xinfreq MS_001 = CLK_FREQ / 1_000 ' // Propeller Pinout Misc1 = 0 Misc2 = 1 Misc3 = 2 Misc4 = 3 MCPCLK = 4 MCPDOut = 5 MCPDIn = 5 MCPCS = 6 NC1 = 7 MPUsda = 8 ' All I2C Sensors on SAME Bus MPUscl = 9 RPitx = 10 RPirx = 11 GPSrx = 12 ' SCL GPStx = 13 ' SDA BMPSCL = 12 BMPSDA = 13 WiFitx = 14 ' White WiFirx = 15 ' Green Misc5 = 16 Misc6 = 17 Misc7 = 18 LED = 19 Piezo = 20 Servo6 = 21 ' Left Side Airlerons Servo5 = 22 ' Gyro Select Servo4 = 23 ' Gyro / Rudder NC2 = 24 Servo3 = 25 ' Motor Speed / Power Servo2 = 26 ' Elevator Servo1 = 27 ' Right Side Airlerons EEPROMscl = 28 EEPROMsda = 29 DEBUGSERtx = 30 DEBUGSERrx = 31 bmpAddr = 10_1110 mpuAddr = 01_0000 OSS1 = 0 ' Ultra Low Power OSS2 = 1 ' Standard OSS3 = 2 ' High Resolution OSS4 = 3 ' Ultra High Resolution ' EEPROM data base address - i.e 32K (assumes a 64kb eeprom installed!!) EEPROM_Base = $8000 EEPROMAddr = 10_0000 i2cSCL = 28 ' i2cSDA = 29 OBJ 'i2c : "pasm_i2c_driver_Ext" ' Finds Both Devices, All Data = FF i2c : "basic_i2c_driver_1.3_Mod" ' Finds MPU Only, Data = 255 Ser : "FullDuplexSerial" Var long ac1, ac2, ac3, ac4, ac5, ac6, b1, b2, mb, mc, md, id long UT, UP long T, P long i2cAddress, i2cSlaveCounter long oss Pub Start ser.start(31,30,0,115200) 'i2c.Initialize(bmpSCL) ' // PASM i2c Driver i2c.Initialize(bmpSCL, bmpSDA) ' // basic_i2c_driver1.3_Mod oss := OSS2 repeat ' // All I2C Sensors on SAME Bus ' // MPU-6050 if i2c.devicePresent(mpuSCL, mpuAddr) == True ser.str(string("MPU - Device Located!")) ser.tx(13) waitcnt(clkfreq + cnt) GetMPU else ser.str(string("MPU - Device Not Found")) ser.tx(13) waitcnt(clkfreq + cnt) ' // BMP-180 if i2c.devicePresent(bmpSCL, bmpAddr) == True ser.str(string("BMP - Device Located!")) ser.tx(13) waitcnt(clkfreq + cnt) GetBMP_bmp else ser.str(string("BMP - Device Not Found")) ser.tx(13) waitcnt(clkfreq + cnt) Pub GetMPU | X, Y, Z, A, B, C 'repeat ' // Setup: power mgmt, dlp, smplrtdiv, gyro & accel i2c.writeLocation(mpuSCL, mpuAddr, 107, 000001) ' X Gyro as Clock Source i2c.writeLocation(mpuSCL, mpuAddr, 26, 000011) ' 40 Hz DLP i2c.writeLocation(mpuSCL, mpuAddr, 25, 000001) ' Sample Rate = 500 Hz i2c.writeLocation(mpuSCL, mpuAddr, 27, 011000) ' Gyro = FS3 i2c.writeLocation(mpuSCL, mpuAddr, 28, 010000) ' Accel = AFS2 ' // Read Values X := i2c.readLocation(mpuSCL, mpuAddr, 59) ' = 255 ser.str(string("MPU Out: ")) ser.dec(X) ser.tx(13) Pub GetBMP_BMP | v1, v2, v3, up1, up2, up3, ut1, ut2 'repeat { Table 5: Calibration Coefficients BMP180 reg adr Parameter MSB LSB AC1 0xAA 0xAB AC2 0xAC 0xAD AC3 0xAE 0xAF AC4 0xB0 0xB1 AC5 0xB2 0xB3 AC6 0xB4 0xB5 B1 0xB6 0xB7 B2 0xB8 0xB9 MB 0xBA 0xBB MC 0xBC 0xBD MD 0xBE 0xBF } ' i2c.readLocation(SCL,device_address, register) ' // Read Calibration Coefficients ac1 := i2c.readLocation16(bmpSCL, bmpAddr, $AA) ' 1B ac2 := i2c.readLocation16(bmpSCL, bmpAddr, $AC) ' FB ac3 := i2c.readLocation16(bmpSCL, bmpAddr, $AE) ' C7 ac4 := i2c.readLocation16(bmpSCL, bmpAddr, $B0) ' 84 ac5 := i2c.readLocation16(bmpSCL, bmpAddr, $B2) ' 61 ac6 := i2c.readLocation16(bmpSCL, bmpAddr, $B4) ' 49 b1 := i2c.readLocation16(bmpSCL, bmpAddr, $B6) ' 19 b2 := i2c.readLocation16(bmpSCL, bmpAddr, $B8) ' 00 mb := i2c.readLocation16(bmpSCL, bmpAddr, $BA) ' 80 mc := i2c.readLocation16(bmpSCL, bmpAddr, $BC) ' D1 md := i2c.readLocation16(bmpSCL, bmpAddr, $BE) ' 0A id := i2c.readLocation(bmpSCL, bmpAddr, $D0) ' 55 *** Should = 0x55 waitcnt((clkfreq / 4) + cnt) ser.str(string("AC1: ")) ser.hex(ac1, 2) ser.str(string(" ")) ser.dec(ac1) ser.tx(13) ser.str(string("AC2: ")) ser.hex(ac2, 2) ser.str(string(" ")) ser.dec(ac2) ser.tx(13) ser.str(string("AC3: ")) ser.hex(ac3, 2) ser.str(string(" ")) ser.dec(ac3) ser.tx(13) ser.str(string("AC4: ")) ser.hex(ac4, 2) ser.str(string(" ")) ser.dec(ac4) ser.tx(13) ser.str(string("AC5: ")) ser.hex(ac5, 2) ser.str(string(" ")) ser.dec(ac5) ser.tx(13) ser.str(string("AC6: ")) ser.hex(ac6, 2) ser.str(string(" ")) ser.dec(ac6) ser.tx(13) ser.str(string("B1: ")) ser.hex(b1, 2) ser.str(string(" ")) ser.dec(b1) ser.tx(13) ser.str(string("B2: ")) ser.hex(b2, 2) ser.str(string(" ")) ser.dec(b2) ser.tx(13) ser.str(string("MB: ")) ser.hex(mb, 2) ser.str(string(" ")) ser.dec(mb) ser.tx(13) ser.str(string("MC: ")) ser.hex(mc, 2) ser.str(string(" ")) ser.dec(mc) ser.tx(13) ser.str(string("MD: ")) ser.hex(md, 2) ser.str(string(" ")) ser.dec(md) ser.tx(13) ser.str(string("ID: ")) ser.hex(id, 2) ser.str(string(" ")) ser.dec(id) ser.tx(13) 'ser.str(string("bmpAddr: ")) 'ser.hex(bmpAddr | 1, 2) ' 0 = EE, 1 = EF 'ser.tx(13) ' // Read Uncompressed Temperature Value ' Write 0x2E into reg 0xF4, wait 4.5ms ' Read reg 0xF6 (MSB), 0xF7 (LSB) i2c.writeLocation(bmpSCL, bmpAddr, $F4, $2E) ' Temperature 0x2E 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms ut1 := i2c.readLocation16(bmpSCL, bmpAddr, $F6) ut2 := i2c.readLocation16(bmpSCL, bmpAddr, $F7) 'UT := i2c.readLocation16(bmpSCL, bmpAddr, i2c#OneAddr|$F6) UT := i2c.readLocation16(bmpSCL, bmpAddr, $F6) ser.str(string("UT: ")) ser.dec(UT) ser.str(string(" ")) ser.hex(ut1, 2) ser.str(string(" ")) ser.hex(ut2, 2) ser.str(string(" ")) ser.dec(ut1 + ut2) ser.tx(13) ' // Read Uncompressed Pressure Value ' Write 0x34+(oss<<6) into reg 0xF4, wait #.#ms ' Read reg 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB) 'i2c.writeLocation(bmpSCL, bmpAddr, $F4, $34 + (oss<<6)) ' i2c.readLocation(SCL,device_address, register) ' i2c.writeLocation(SCL,device_address, register, value) if oss == 0 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $34) ' Pressure (oss = 0) 0x34 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms elseif oss == 1 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $74) ' Pressure (oss = 1) 0x74 7.5 waitcnt((clkfreq / 133) + cnt) ' 7.5ms elseif oss == 2 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $B4) ' Pressure (oss = 2) 0xB4 13.5 waitcnt((clkfreq / 74) + cnt) ' 13.5ms elseif oss == 3 i2c.writeLocation(bmpSCL, bmpAddr, $F4, $F4) ' Pressure (oss = 3) 0xF4 25.5 waitcnt((clkfreq / 39) + cnt) ' 25.5ms up1 := i2c.readLocation16(bmpSCL, bmpAddr, $F6) up2 := i2c.readLocation16(bmpSCL, bmpAddr, $F7) up3 := i2c.readLocation16(bmpSCL, bmpAddr, $F8) ser.str(string("UP: ")) ser.hex(up1 + up2 + up3, 6) ser.str(string(" ")) ser.dec(up1 + up2 + up3) ser.tx(13) ser.str(string("UP 123 Hex: ")) ser.hex(up1, 2) ser.str(string(" ")) ser.hex(up2, 2) ser.str(string(" ")) ser.hex(up3, 2) ser.tx(13) ser.str(string("UP 123 Dec: ")) ser.dec(up1) ser.str(string(" ")) ser.dec(up2) ser.str(string(" ")) ser.dec(up3) ser.tx(13) ' // Calculate True Temperature ' // Calculate True Pressure waitcnt(clkfreq + cnt) Pub GetBMP_MPU | v1, v2, v3, up1, up2, up3, ut1, ut2 'repeat { Table 5: Calibration Coefficients BMP180 reg adr Parameter MSB LSB AC1 0xAA 0xAB AC2 0xAC 0xAD AC3 0xAE 0xAF AC4 0xB0 0xB1 AC5 0xB2 0xB3 AC6 0xB4 0xB5 B1 0xB6 0xB7 B2 0xB8 0xB9 MB 0xBA 0xBB MC 0xBC 0xBD MD 0xBE 0xBF } ' i2c.readLocation(SCL,device_address, register) ' // Read Calibration Coefficients ac1 := i2c.readLocation(mpuSCL, bmpAddr, $AA) ' 1B ac2 := i2c.readLocation(mpuSCL, bmpAddr, $AC) ' FB ac3 := i2c.readLocation(mpuSCL, bmpAddr, $AE) ' C7 ac4 := i2c.readLocation(mpuSCL, bmpAddr, $B0) ' 84 ac5 := i2c.readLocation(mpuSCL, bmpAddr, $B2) ' 61 ac6 := i2c.readLocation(mpuSCL, bmpAddr, $B4) ' 49 b1 := i2c.readLocation(mpuSCL, bmpAddr, $B6) ' 19 b2 := i2c.readLocation(mpuSCL, bmpAddr, $B8) ' 00 mb := i2c.readLocation(mpuSCL, bmpAddr, $BA) ' 80 mc := i2c.readLocation(mpuSCL, bmpAddr, $BC) ' D1 md := i2c.readLocation(mpuSCL, bmpAddr, $BE) ' 0A id := i2c.readLocation(mpuSCL, bmpAddr, $D0) ' 55 *** Should = 0x55 waitcnt((clkfreq / 4) + cnt) ser.str(string("AC1: ")) ser.hex(ac1, 2) ser.str(string(" ")) ser.dec(ac1) ser.tx(13) ser.str(string("AC2: ")) ser.hex(ac2, 2) ser.str(string(" ")) ser.dec(ac2) ser.tx(13) ser.str(string("AC3: ")) ser.hex(ac3, 2) ser.str(string(" ")) ser.dec(ac3) ser.tx(13) ser.str(string("AC4: ")) ser.hex(ac4, 2) ser.str(string(" ")) ser.dec(ac4) ser.tx(13) ser.str(string("AC5: ")) ser.hex(ac5, 2) ser.str(string(" ")) ser.dec(ac5) ser.tx(13) ser.str(string("AC6: ")) ser.hex(ac6, 2) ser.str(string(" ")) ser.dec(ac6) ser.tx(13) ser.str(string("B1: ")) ser.hex(b1, 2) ser.str(string(" ")) ser.dec(b1) ser.tx(13) ser.str(string("B2: ")) ser.hex(b2, 2) ser.str(string(" ")) ser.dec(b2) ser.tx(13) ser.str(string("MB: ")) ser.hex(mb, 2) ser.str(string(" ")) ser.dec(mb) ser.tx(13) ser.str(string("MC: ")) ser.hex(mc, 2) ser.str(string(" ")) ser.dec(mc) ser.tx(13) ser.str(string("MD: ")) ser.hex(md, 2) ser.str(string(" ")) ser.dec(md) ser.tx(13) ser.str(string("ID: ")) ser.hex(id, 2) ser.str(string(" ")) ser.dec(id) ser.tx(13) 'ser.str(string("bmpAddr: ")) 'ser.hex(bmpAddr | 1, 2) ' 0 = EE, 1 = EF 'ser.tx(13) ' // Read Uncompressed Temperature Value ' Write 0x2E into reg 0xF4, wait 4.5ms ' Read reg 0xF6 (MSB), 0xF7 (LSB) i2c.writeLocation(mpuSCL, bmpAddr, $F4, $2E) ' Temperature 0x2E 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms ut1 := i2c.readLocation(mpuSCL, bmpAddr, $F6) ut2 := i2c.readLocation(mpuSCL, bmpAddr, $F7) 'UT := i2c.readLocation16(mpuSCL, bmpAddr, i2c#OneAddr|$F6) ser.str(string("UT: ")) ser.hex(ut1, 2) ser.str(string(" ")) ser.hex(ut2, 2) ser.str(string(" ")) ser.dec(ut1 + ut2) ser.tx(13) ' // Read Uncompressed Pressure Value ' Write 0x34+(oss<<6) into reg 0xF4, wait #.#ms ' Read reg 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB) 'i2c.writeLocation(mpuSCL, bmpAddr, $F4, $34 + (oss<<6)) ' i2c.readLocation(SCL,device_address, register) ' i2c.writeLocation(SCL,device_address, register, value) if oss == 0 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $34) ' Pressure (oss = 0) 0x34 4.5 waitcnt((clkfreq / 222) + cnt) ' 4.5ms elseif oss == 1 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $74) ' Pressure (oss = 1) 0x74 7.5 waitcnt((clkfreq / 133) + cnt) ' 7.5ms elseif oss == 2 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $B4) ' Pressure (oss = 2) 0xB4 13.5 waitcnt((clkfreq / 74) + cnt) ' 13.5ms elseif oss == 3 i2c.writeLocation(mpuSCL, bmpAddr, $F4, $F4) ' Pressure (oss = 3) 0xF4 25.5 waitcnt((clkfreq / 39) + cnt) ' 25.5ms up1 := i2c.readLocation(mpuSCL, bmpAddr, $F6) up2 := i2c.readLocation(mpuSCL, bmpAddr, $F7) up3 := i2c.readLocation(mpuSCL, bmpAddr, $F8) ser.str(string("UP: ")) ser.hex(up1 + up2 + up3, 6) ser.str(string(" ")) ser.dec(up1 + up2 + up3) ser.tx(13) ser.str(string("UP 123 Hex: ")) ser.hex(up1, 2) ser.str(string(" ")) ser.hex(up2, 2) ser.str(string(" ")) ser.hex(up3, 2) ser.tx(13) ser.str(string("UP 123 Dec: ")) ser.dec(up1) ser.str(string(" ")) ser.dec(up2) ser.str(string(" ")) ser.dec(up3) ser.tx(13) ' // Calculate True Temperature ' // Calculate True Pressure waitcnt(clkfreq + cnt)
and the results of this are as shown:
ok, so I went ahead and tried this:
ac1 := i2c.readLocation(bmpSCL, bmpAddr, $AA) ' 1B ac2 := i2c.readLocation(bmpSCL, bmpAddr, $AC) ' FB ac3 := i2c.readLocation(bmpSCL, bmpAddr, $AE) ' C7 ac4 := i2c.readLocation(bmpSCL, bmpAddr, $B0) ' 84 ac5 := i2c.readLocation(bmpSCL, bmpAddr, $B2) ' 61 ac6 := i2c.readLocation(bmpSCL, bmpAddr, $B4) ' 49 b1 := i2c.readLocation(bmpSCL, bmpAddr, $B6) ' 19 b2 := i2c.readLocation(bmpSCL, bmpAddr, $B8) ' 00 mb := i2c.readLocation(bmpSCL, bmpAddr, $BA) ' 80 mc := i2c.readLocation(bmpSCL, bmpAddr, $BC) ' D1 md := i2c.readLocation(bmpSCL, bmpAddr, $BE) ' 0A ac1 |= i2c.readLocation(bmpSCL, bmpAddr, $AB) << 8 ' 1B ac2 |= i2c.readLocation(bmpSCL, bmpAddr, $AD) << 8 ' FB ac3 |= i2c.readLocation(bmpSCL, bmpAddr, $AF) << 8 ' C7 ac4 |= i2c.readLocation(bmpSCL, bmpAddr, $B1) << 8 ' 84 ac5 |= i2c.readLocation(bmpSCL, bmpAddr, $B3) << 8 ' 61 ac6 |= i2c.readLocation(bmpSCL, bmpAddr, $B5) << 8 ' 49 b1 |= i2c.readLocation(bmpSCL, bmpAddr, $B7) << 8 ' 19 b2 |= i2c.readLocation(bmpSCL, bmpAddr, $B9) << 8 ' 00 mb |= i2c.readLocation(bmpSCL, bmpAddr, $BB) << 8 ' 80 mc |= i2c.readLocation(bmpSCL, bmpAddr, $BD) << 8 ' D1 md |= i2c.readLocation(bmpSCL, bmpAddr, $BF) << 8 ' 0A
which is very close to readLocation16's results, but they are all off a bit.
Above Code:
AA AB
AC AD
AE AF