that is what I would like to know. How am I suppose to know if the code is working right? The bmp's datasheet shows way different values for all of those that i get.
OK, MSB is first, so bitshift AA then OR AB. I have no idea what this module does. However, in that screenshot, I am not clear on whether you should be getting a signed value instead. Which would require something like AA bitshift left 24, the Shift Arithmetic Right 16. Then OR AB. Maybe someone else can give better advice on this.
You will need to study the manual further to find out what is the purpose of the calibration data. My guess is that each module is calibrated with some baseline info stored for future use. In that screen shot, some of the values are not signed, so you can do what you were already doing on AC4 5 6 but correct the MSB/LSB thing.
ac4 := i2c.readLocation(bmpSCL, bmpAddr, $B0) << 8
ac4 |= i2c.readLocation(bmpSCL, bmpAddr, $B1)
I had issues with a I2C device previously. Tried everything I knew and a few others. I thought maybe the device was faulty.
I finally in the end got out a magnifying glass and looked at the markings on the case, and then realised that it wasn't the I2C device I thought it was, so I was addressing the wrong device.
Somehow the distributor I was using sent me the wrong RTC, same manufacturer but different model, and of course different addresses, memory and functions.
I had to re-do the whole Spin object I wrote to get it to work since the memory and functions were different.
You live and learn.
OK, MSB is first, so bitshift AA then OR AB. I have no idea what this module does. However, in that screenshot, I am not clear on whether you should be getting a signed value instead. Which would require something like AA bitshift left 24, the Shift Arithmetic Right 16. Then OR AB. Maybe someone else can give better advice on this.
You will need to study the manual further to find out what is the purpose of the calibration data. My guess is that each module is calibrated with some baseline info stored for future use. In that screen shot, some of the values are not signed, so you can do what you were already doing on AC4 5 6 but correct the MSB/LSB thing.
ac4 := i2c.readLocation(bmpSCL, bmpAddr, $B0) << 8
ac4 |= i2c.readLocation(bmpSCL, bmpAddr, $B1)
ac1 becomes 7159 using your code above.
ac4 becomes 33810
as for the calibration data, it is used in the second part of the pressure & temp math to calculate the true temperature & true pressure, which is just simple math. i can follow that part fine.
its just a matter of getting the right values from the device. the datasheet says the Chip ID is 0x55 and that is how you check that your communications are working properly.
@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 Even the placement and designators of the connectors. Now if those with little pcb/hardware experience would post their proposed design to the forum beforehand then the design could be vetted and produced with some confidence.
Better to mention some of ghe major problems than be silent, especially when they could be the cause.
The eeprom is quite a forgiving chip, but analog chips are not so forgiving of poor designs including power.
It is quite possible the problems are not software.
Better to mention some of ghe major problems than be silent, especially when they could be the cause.
The eeprom is quite a forgiving chip, but analog chips are not so forgiving of poor designs including power.
It is quite possible the problems are not software.
Every Sensor I am using is Digital. I have an analog pressure sensor, but requires much higher voltages than my batteries supply (16 volts needed, only 7v available)
I am pretty confident that it is in the software. My MPU-6050 works with a PASM i2c Driver 100%, but it dont work with the spin i2c driver.
Every Sensor I am using is Digital. I have an analog pressure sensor, but requires much higher voltages than my batteries supply (16 volts needed, only 7v available)
I am pretty confident that it is in the software. My MPU-6050 works with a PASM i2c Driver 100%, but it dont work with the spin i2c driver.
The interface is digital, but internally all of these sensors are analog and need a steady power supply. You are correct though that these modules mostly all have a power supply filter capacitor on board, so there is less need for you to include one outside. Extra never hurts.
Power supply, a case in point. Last week I had to troubleshoot a system where the digital interface was working but the analog portion was not. Here is a 'scope shot of the i2c transaction. Lots of runt pulses. Even so, the i2c was reading and setting the internal registers. It turned out that there was a cold solder joint on the power pin to the chip (a tiny DFN), so the power to the chip was parasite power through the pullup resistors. A fine tip and solder corrected the problem.
Upper red trace SDA, lower yellow trace SCL.
A 'scope and a logic analyzer such as the #32314 Saleae that Parallax sells can be invaluable to see exactly what is going on.
I've done a bunch of projects with I2C, never having a lick of trouble.
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.
So I had success with your scanner in finding both the MPU & BMP on the same i2c bus, so I did a little code mod & added in the BMP_Read function. I believe the values are correct, (MB) is the same value as the datasheet & others are fairly close.
A problem I think that is happening is how I merged the 3 values (up = up1 + up2 + up3). I dont quite understand bitshifting & the <<, >>, ~>=, etc. functions and how they are used to get the full 16 or 32 bit value into one (myVal).
Also by using readlocation vs readlocation16 the ouptut values change completely.
Here is what I did to the code:
'' =================================================================================================
''
'' File....... jm_i2c_scan.spin
'' Purpose....
'' Author..... Jon "JonnyMac" McPhalen
'' Copyright (c) 2014 Jon McPhalen
'' -- see below for terms of use
'' E-mail..... jon@jonmcphalen.com
'' Started....
'' Updated.... 09 FEB 2014
''
'' =================================================================================================
con { timing }
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000 ' 5MHz crystal
CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq ' system freq as a constant
MS_001 = CLK_FREQ / 1_000 ' ticks in 1ms
US_001 = CLK_FREQ / 1_000_000 ' ticks in 1us
con { io pins }
RX1 = 31 ' programming / terminal
TX1 = 30
SDA = 29 ' eeprom / i2c
SCL = 28
MPUsda = 8 ' All I2C Sensors on SAME Bus
MPUscl = 9
BMPSCL = 12
BMPSDA = 13
I2C_SDA = 10
I2C_SCL = 11
con
#0, LSBFIRST, MSBFIRST
con { pst formatting }
#1, HOME, GOTOXY, #8, BKSP, TAB, LF, CLREOL, CLRDN, CR
#14, GOTOX, GOTOY, CLS
bmpAddr = $EE
mpuAddr = $D0
obj
term : "fullduplexserial"
i2c : "jm_i2c_Mod"
var
' MPU-9150 $D0 %1101_0000
' BMP-180 $EE %1110_1110
long ac1, ac2, ac3, ac4, ac5, ac6, b1, b2, mb, mc, md, id
long UT, UP, oss
pub main | addr, check
term.start(RX1, TX1, %0000, 115_200)
i2c.setupx(I2C_SCL, I2C_SDA)
' open PST, enable, then press a key
repeat
term.rxflush
term.rx
'term.tx(CLS)
term.str(string("I2C Scanner", CR, CR))
repeat addr from %0000_0010 to %1111_1110 step %10 ' ignore r/w bit
ihex2(addr)
repeat 3
term.tx(" ")
ibin8(addr)
repeat 3
term.tx(" ")
i2c.start
check := i2c.write(addr)
i2c.stop
if (check == i2c#ACK)
term.str(string("Yes", CR))
else
term.str(string("No", CR))
if addr == $EE ' BMP Found
Read_BMP
if addr == $D0 ' MPU Found
Read_MPU
pause(50)
Pri Read_BMP | v1, v2, v3, up1, up2, up3, ut1, ut2, read16
{
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)
read16 := 0
' // Read Calibration Coefficients
if read16 == 0
ac1 := i2c.readLocation(bmpAddr, $AA) << 8
ac1 |= i2c.readLocation(bmpAddr, $AB)
'ac1 := i2c.readLocation(bmpAddr, $AA) << 24
'ac1 ~>= 16 ' shift arith right
'ac1 |= i2c.readLocation(bmpAddr, $AB)
ac2 := i2c.readLocation(bmpAddr, $AC) << 8
ac2 |= i2c.readLocation(bmpAddr, $AD)
ac3 := i2c.readLocation(bmpAddr, $AE) << 8
ac3 |= i2c.readLocation(bmpAddr, $AF)
ac4 := i2c.readLocation(bmpAddr, $B0) << 8
ac4 |= i2c.readLocation(bmpAddr, $B1)
ac5 := i2c.readLocation(bmpAddr, $B2) << 8
ac5 |= i2c.readLocation(bmpAddr, $B3)
ac6 := i2c.readLocation(bmpAddr, $B4) << 8
ac6 |= i2c.readLocation(bmpAddr, $B5)
b1 := i2c.readLocation(bmpAddr, $B6) << 8
b1 |= i2c.readLocation(bmpAddr, $B7)
b2 := i2c.readLocation(bmpAddr, $B8) << 8
b2 |= i2c.readLocation(bmpAddr, $B9)
mb := i2c.readLocation(bmpAddr, $BA) << 8
mb |= i2c.readLocation(bmpAddr, $BB)
mc := i2c.readLocation(bmpAddr, $BC) << 8
mc |= i2c.readLocation(bmpAddr, $BD)
md := i2c.readLocation(bmpAddr, $BE) << 8
md |= i2c.readLocation(bmpAddr, $BF)
elseif read16 == 1
ac1 := i2c.readLocation16(bmpAddr, $AA) ' 1B
ac2 := i2c.readLocation16(bmpAddr, $AC) ' FB
ac3 := i2c.readLocation16(bmpAddr, $AE) ' C7
ac4 := i2c.readLocation16(bmpAddr, $B0) ' 84
ac5 := i2c.readLocation16(bmpAddr, $B2) ' 61
ac6 := i2c.readLocation16(bmpAddr, $B4) ' 49
b1 := i2c.readLocation16(bmpAddr, $B6) ' 19
b2 := i2c.readLocation16(bmpAddr, $B8) ' 00
mb := i2c.readLocation16(bmpAddr, $BA) ' 80
mc := i2c.readLocation16(bmpAddr, $BC) ' D1
md := i2c.readLocation16(bmpAddr, $BE) ' 0A
id := i2c.readLocation(bmpAddr, $D0) ' 55 *** Should = 0x55
waitcnt((clkfreq / 4) + cnt)
term.str(string("AC1: "))
term.hex(ac1, 2)
term.str(string(" "))
term.dec(ac1)
term.tx(13)
term.str(string("AC2: "))
term.hex(ac2, 2)
term.str(string(" "))
term.dec(ac2)
term.tx(13)
term.str(string("AC3: "))
term.hex(ac3, 2)
term.str(string(" "))
term.dec(ac3)
term.tx(13)
term.str(string("AC4: "))
term.hex(ac4, 2)
term.str(string(" "))
term.dec(ac4)
term.tx(13)
term.str(string("AC5: "))
term.hex(ac5, 2)
term.str(string(" "))
term.dec(ac5)
term.tx(13)
term.str(string("AC6: "))
term.hex(ac6, 2)
term.str(string(" "))
term.dec(ac6)
term.tx(13)
term.str(string("B1: "))
term.hex(b1, 2)
term.str(string(" "))
term.dec(b1)
term.tx(13)
term.str(string("B2: "))
term.hex(b2, 2)
term.str(string(" "))
term.dec(b2)
term.tx(13)
term.str(string("MB: "))
term.hex(mb, 2)
term.str(string(" "))
term.dec(mb)
term.tx(13)
term.str(string("MC: "))
term.hex(mc, 2)
term.str(string(" "))
term.dec(mc)
term.tx(13)
term.str(string("MD: "))
term.hex(md, 2)
term.str(string(" "))
term.dec(md)
term.tx(13)
term.str(string("ID: "))
term.hex(id, 2)
term.str(string(" "))
term.dec(id)
term.tx(13)
'term.str(string("bmpAddr: "))
'term.hex(bmpAddr | 1, 2) ' 0 = EE, 1 = EF
'term.tx(13)
' // Read Uncompressed Temperature Value
' Write 0x2E into reg 0xF4, wait 4.5ms
' Read reg 0xF6 (MSB), 0xF7 (LSB)
i2c.writeLocation(bmpAddr, $F4, $2E) ' Temperature 0x2E 4.5
waitcnt((clkfreq / 222) + cnt) ' 4.5ms
ut1 := i2c.readLocation16(bmpAddr, $F6)
ut2 := i2c.readLocation16(bmpAddr, $F7)
'UT := i2c.readLocation16(bmpAddr, i2c#OneAddr|$F6)
UT := i2c.readLocation16(bmpAddr, $F6)
term.str(string("UT: "))
term.dec(UT)
term.str(string(" "))
term.hex(ut1, 2)
term.str(string(" "))
term.hex(ut2, 2)
term.str(string(" "))
term.dec(ut1 + ut2)
term.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(bmpAddr, $F4, $34 + (oss<<6))
' i2c.readLocation(SCL,device_address, register)
' i2c.writeLocation(SCL,device_address, register, value)
if oss == 0
i2c.writeLocation(bmpAddr, $F4, $34) ' Pressure (oss = 0) 0x34 4.5
waitcnt((clkfreq / 222) + cnt) ' 4.5ms
elseif oss == 1
i2c.writeLocation(bmpAddr, $F4, $74) ' Pressure (oss = 1) 0x74 7.5
waitcnt((clkfreq / 133) + cnt) ' 7.5ms
elseif oss == 2
i2c.writeLocation(bmpAddr, $F4, $B4) ' Pressure (oss = 2) 0xB4 13.5
waitcnt((clkfreq / 74) + cnt) ' 13.5ms
elseif oss == 3
i2c.writeLocation(bmpAddr, $F4, $F4) ' Pressure (oss = 3) 0xF4 25.5
waitcnt((clkfreq / 39) + cnt) ' 25.5ms
up1 := i2c.readLocation16(bmpAddr, $F6)
up2 := i2c.readLocation16(bmpAddr, $F7)
up3 := i2c.readLocation16(bmpAddr, $F8)
term.str(string("UP: "))
term.hex(up1 + up2 + up3, 6)
term.str(string(" "))
term.dec(up1 + up2 + up3)
term.tx(13)
term.str(string("UP 123 Hex: "))
term.hex(up1, 2)
term.str(string(" "))
term.hex(up2, 2)
term.str(string(" "))
term.hex(up3, 2)
term.tx(13)
term.str(string("UP 123 Dec: "))
term.dec(up1)
term.str(string(" "))
term.dec(up2)
term.str(string(" "))
term.dec(up3)
term.tx(13)
' // Calculate True Temperature
' // Calculate True Pressure
waitcnt(clkfreq + cnt)
Pri Read_MPU
con
{ ------------- }
{ B A S I C S }
{ ------------- }
pub ihex2(value)
term.tx("$")
term.hex(value, 2)
pub ibin8(value)
term.tx("%")
term.bin(value >> 4, 4)
term.tx("_")
term.bin(value & $0F, 4)
con
{ ------------- }
{ B A S I C S }
{ ------------- }
pub pause(ms) | t
'' Delay program in milliseconds
if (ms < 1) ' delay must be > 0
return
else
t := cnt - 1776 ' sync with system counter
repeat ms ' run delay
waitcnt(t += MS_001)
pub high(pin)
'' Makes pin output and high
outa[pin] := 1
dira[pin] := 1
pub low(pin)
'' Makes pin output and low
outa[pin] := 0
dira[pin] := 1
pub toggle(pin)
'' Toggles pin state
!outa[pin]
dira[pin] := 1
pub input(pin)
'' Makes pin input and returns current state
dira[pin] := 0
return ina[pin]
dat { license }
{{
Terms of Use: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
}}
and
'' =================================================================================================
''
'' File....... jm_i2c.spin
'' Purpose.... Low-level I2C routines (requires pull-ups on SCL and SDA)
'' Author..... Jon "JonnyMac" McPhalen
'' Copyright (c) 2009-2013 Jon McPhalen
'' -- elements inspired by code from Mike Green
'' E-mail.....
'' Started.... 28 JUL 2009
'' Updated.... 07 APR 2013
''
'' =================================================================================================
con { fixed io pins }
RX1 = 31 ' programming / debug port
TX1 = 30
EE_SDA = 29 ' eeprom
EE_SCL = 28
con
#0, ACK, NAK
var
long scl ' buss pins
long sda
pub setup
'' Setup I2C using Propeller EEPROM pins
setupx(EE_SCL, EE_SDA)
pub setupx(sclpin, sdapin)
'' Define I2C SCL (clock) and SDA (data) pins
longmove(@scl, @sclpin, 2) ' copy pins
dira[scl] := 0 ' float to pull-up
outa[scl] := 0 ' write 0 to output reg
dira[sda] := 0
outa[sda] := 0
repeat 9 ' reset device
dira[scl] := 1
dira[scl] := 0
if (ina[sda])
quit
pub wait(id) | ackbit
'' Waits for I2C device to be ready for new command
repeat
start
ackbit := write(id)
until (ackbit == ACK)
pub start
'' Create I2C start sequence
'' -- will wait if I2C buss SDA pin is held low
dira[sda] := 0 ' float SDA (1)
dira[scl] := 0 ' float SCL (1)
repeat while (ina[scl] == 0) ' allow "clock stretching"
dira[sda] := 1 ' SDA low (0)
dira[scl] := 1 ' SCL low (0)
pub write(i2cbyte) | ackbit
'' Write byte to I2C buss
'' -- leaves SCL low
i2cbyte := (i2cbyte ^ $FF) << 24 ' move msb (bit7) to bit31
repeat 8 ' output eight bits
dira[sda] := i2cbyte <-= 1 ' send msb first
dira[scl] := 0 ' SCL high (float to p/u)
dira[scl] := 1 ' SCL low
dira[sda] := 0 ' relase SDA to read ack bit
dira[scl] := 0 ' SCL high (float to p/u)
ackbit := ina[sda] ' read ack bit
dira[scl] := 1 ' SCL low
return (ackbit & 1)
pub read(ackbit) | i2cbyte
'' Read byte from I2C buss
dira[sda] := 0 ' make sda input
repeat 8
dira[scl] := 0 ' SCL high (float to p/u)
i2cbyte := (i2cbyte << 1) | ina[sda] ' read the bit
dira[scl] := 1 ' SCL low
dira[sda] := !ackbit ' output ack bit
dira[scl] := 0 ' clock it
dira[scl] := 1
return (i2cbyte & $FF)
pub stop
'' Create I2C stop sequence
dira[sda] := 1 ' SDA low
dira[scl] := 0 ' float SCL
repeat
until (ina[scl] == 1) ' hold for clock stretch
dira[sda] := 0 ' float SDA
' // -------------------- Extras --------------------
PUB ReStart ' SDA goes HIGH to LOW with SCL HIGH
outa[SDA]~~ ' Initially drive SDA HIGH
dira[SDA]~~
outa[SCL]~~ ' Initially drive SCL HIGH
'waitcnt(clkfreq / I2CDelay + cnt)
outa[SDA]~ ' Now drive SDA LOW
'waitcnt(clkfreq / I2CDelay + cnt)
outa[SCL]~ ' Leave SCL LOW
PUB devicePresent(deviceAddress) : ackbit
' send the deviceAddress and listen for the ACK
Start
ackbit := Write(deviceAddress | 0)
Stop
if ackbit == ACK
return true
else
return false
PUB readLocation(device_address, register) : value
start ' 1. Send a start sequence
write(device_address | 0) ' 2. Send 0xC0 ( I2C address of the CMPS03 with the R/W bit low (even address)
write(register) ' 3. Send 0x01 (Internal address of the bearing register)
start ' 4. Send a start sequence again (repeated start)
write(device_address | 1) ' 5. Send 0xC1 ( I2C address of the CMPS03 with the R/W bit high (odd address)
value := read(NAK) ' 6. Read data byte from CMPS03
stop ' 7. Send the stop sequence.
return value ' ^- Copied From (http://www.robot-electronics.co.uk/acatalog/I2C_Tutorial.html)
PUB writeLocation(device_address, register, value)
start ' 1. Send a start sequence
write(device_address) ' 2. Send the I2C address of the slave with the R/W bit low (even address)
write(register) ' 3. Send the internal register number you want to write to
write(value) ' 4. Send the data byte 5. [Optionally, send any further data bytes]
stop ' 6. Send the stop sequence.
PUB readLocation16(device_address, register) : value
start
write(device_address | 0)
write(register)
restart
write(device_address | 1)
'value := read(SCL,ACK)
'value <<= 8
value := read(ACK)
value |= read(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(NAK) & $ff)
stop
return value
PUB readLocation24(device_address, register) : value
start
write(device_address | 0)
write(register)
restart
write(device_address | 1)
value := read(ACK)
value <<= 8
value |= (read(ACK) & $ff)
value <<= 8
value |= (read(NAK) & $ff)
stop
return value
dat
{{
Terms of Use: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
}}
and the results for the BMP test, which appear correct (assuming).
you can see it detected both sensors fine ($D0 & $EE):
I have a uni-t scope & 2 logic analyzers (that dont work (no software to support them)).
I know I am having power issues on that pcb. in fact, it just went on the fritz this morning and will program the eeprom fine, but the output is about 1 time every 3 seconds, and the data is all 0's. But when I scoped the power rail its a good clean 3.30v.
I have a second pcb that I have switched to for testing the i2c sensors.
Edit: Now that I have switched to new pcb, I am able to get values from the MPU-9150 using the mpu6050 driver! Thanks to JonnyMac for an extremely simple i2c driver & i2c Scanner... I just modified the scanner code to read the sensors when they were detected. The Power issue quite probibly was the culpret.
Good news. You may recall I noticed your board did not have power connected to one of the 4 prop power pins - the one next to the xtal. Have you fixed this? This is extremely important - you can kill the props PLL (and perhaps other problems) if all 4 power and ground pins of the prop are not connected properly, and decoupled properly.
Good news. You may recall I noticed your board did not have power connected to one of the 4 prop power pins - the one next to the xtal. Have you fixed this? This is extremely important - you can kill the props PLL (and perhaps other problems) if all 4 power and ground pins of the prop are not connected properly, and decoupled properly.
Yes, my other pcb the VCC next to xtal is connected, however, due to the fact that I am not ordering my pcb's but etching myself, I have found it difficult to pack everything on the pcb & still connect all 4 power connections. 3 has been typical, but with the xtal vcc connected. I have been assuming it is fine being that they are internally connected. I have updated my pcb in DipTrace now.
Yes, my other pcb the VCC next to xtal is connected, however, due to the fact that I am not ordering my pcb's but etching myself, I have found it difficult to pack everything on the pcb & still connect all 4 power connections. 3 has been typical, but with the xtal vcc connected. I have been assuming it is fine being that they are internally connected. I have updated my pcb in DipTrace now.
IT IS NOT FINE IF ALL 4 POWER PINS ARE NOT CONNECTED TOGETHER. SAME APPLIES TO THE 4 GROUND PINS. AND THEY MUST HAVE DECOUPLING CAPACITORS AS CLOSE TOTHE PINS AS POSSIBLE. This isn't an option,it's mandatory. Otherwise you willget unpredictable results.
You aregetting unpredictable results, so fixthis first before you damage the prop chip, providing you haven't already!
IT IS NOT FINE IF ALL 4 POWER PINS ARE NOT CONNECTED TOGETHER. SAME APPLIES TO THE 4 GROUND PINS. AND THEY MUST HAVE DECOUPLING CAPACITORS AS CLOSE TOTHE PINS AS POSSIBLE. This isn't an option,it's mandatory. Otherwise you willget unpredictable results.
Im a little confused as to why parallax dont follow this procedure too well they own selves then.
I do have an old prop demo board that has since died, and I have based my circuits on its circuit:
There is only one capacitor as close to the pins as possible and that is the 1uf across the vdd & gnd with boen & resn in between them, other than that, there is only 1 more cap connected to the prop chip and that is over on the power supply's output, far from the chip.
The only thing I have done different is leave one power pin unconnected.
While there are missing decoupling caps on the Demo Board, all of the the power pins are connected.
I'm sure you're frustrated at the moment -- best to let go of that and just follow the good guidance you're getting: decoupling caps on EVERY IC (don't count on what others have or have not done), and make sure all power connections are in fact connected.
Parallax promted the QuickStart board as a reference design; note that it has bypass caps on on power connections to the Propeller. There isn't one on the EEPROM, probably because it is so close to the cap on one side of the Propeller.
I'm sure you're frustrated at the moment -- best to let go of that and just follow the good guidance you're getting
As frustrating as it is, I am doing just that. I have updated my pcb design with caps & all power's connected. I have also added resistors inline to all of my servo io's.
I am going to update my pcb's to this basic layout, it looks like a winner.
As for my sensors, I spent many hours last night reading the datasheet and trying relentlessly to get the mpu-9150 to give me the magnetometer data. I can follow the mpu6050 pasm driver (tho i dont know pasm at all) well enough to add config settings that are not currently available, and how the read sensors method works. But I have no clue how to retrieve the data that is being passed around in the asm code. I would like to be able to connect a bmp085/bmp180 and/or HMC5883 to the aux cl/da lines & read it with the mpu (master mode), then read the data from ext_sens_00 threw ext_sens_11 registers, which are sequential from the accelerometer (gyro - temp - accel - mag - bmp).
As frustrating as it is, I am doing just that. I have updated my pcb design with caps & all power's connected. I have also added resistors inline to all of my servo io's.
I am going to update my pcb's to this basic layout, it looks like a winner.
As for my sensors, I spent many hours last night reading the datasheet and trying relentlessly to get the mpu-9150 to give me the magnetometer data. I can follow the mpu6050 pasm driver (tho i dont know pasm at all) well enough to add config settings that are not currently available, and how the read sensors method works. But I have no clue how to retrieve the data that is being passed around in the asm code. I would like to be able to connect a bmp085/bmp180 and/or HMC5883 to the aux cl/da lines & read it with the mpu (master mode), then read the data from ext_sens_00 threw ext_sens_11 registers, which are sequential from the accelerometer (gyro - temp - accel - mag - bmp).
That pcb layout looks too basic, for instance it has the big pad under the chip that is grounded yet none of the Prop's grounds connect directly to it? Of course it's not a real design, it doesn't have any I/O connected etc. The other issue I have with many designs is the insistence in using big gull wing HC49 crystals, this is the most sensitive part of any design and it's hung out like a mainsail. There are plenty of cheap cylindrical and proper SMD crystals that do not cause this problem. BTW, as I said previously, a little Forth would have solved your little problem in very little time...... however this course has proved far more entertaining.
That pcb layout looks too basic, for instance it has the big pad under the chip that is grounded yet none of the Prop's grounds connect directly to it?
Actually that square in the center is connected to the nearly full ground plane.
The top layer is RED and the bottom layer is GREEN.
A combination of the top and bottom layers form a nearly full ground plane.
The top is stitched to the bottom by a bunch of vias.
as I said previously, a little Forth would have solved your little problem in very little time...... however this course has proved far more entertaining.
I am self-taught hobbyist entrepreneur. I haven't had any formal classes on electronics either, tho I should have & had the chances. I am aware pretty much every design I have needs some updates, and I try to fix them as I become aware of them. So thanks for all the input on things that need fixed, it is greatly appreciated. I have learned more from my own errors than anything else.
It is entertaining for me as well, as not being schooled in electronics, this is an excellent learning experience. How could one learn anything without first trying?
Hi Peter;
Actually that square in the center is connected to the nearly full ground plane.
The top layer is RED and the bottom layer is GREEN.
A combination of the top and bottom layers form a nearly full ground plane.
The top is stitched to the bottom by a bunch of vias.
Duane J
The top layer fill inside/under the Prop is connected to ground on the bottom plane but the ground pins from the Prop should/could be connected to the fill directly.
Here's an example of a complete PCB to illustrate what I tend to do.
In this case this PCB is fairly compact and I have elected to have the center fill connected to VDD and the bottom plane to ground.
I am self-taught hobbyist entrepreneur. I haven't had any formal classes on electronics either, tho I should have & had the chances. I am aware pretty much every design I have needs some updates, and I try to fix them as I become aware of them. So thanks for all the input on things that need fixed, it is greatly appreciated. I have learned more from my own errors than anything else.
It is entertaining for me as well, as not being schooled in electronics, this is an excellent learning experience. How could one learn anything without first trying?
Exactly, so we have to be ready to try things that we don't know. I come across problems like this all the time and I just know that before I had a Forth for the Prop that many things would not work and it wasn't easy to find out exactly why not or what it "saw". Forth is not just a language, it's the whole interactive operating environment for and on the Prop, it's my eyes and ears, my tools, which makes very short work of any annoying problems such as you have been facing.
The "entertaining" thing is a little bit of a dig I admit at conventional means vs this unconventional means and how much it has dragged out. It's a bit like batch processing with punched cards, submitting them and getting the results back that don't work but still scratching your head as to why vs an interactive real-time terminal. Yes, we interact with the PC when we use a conventional compiler but the "punched cards" that it produces doesn't interact with us.
The sample layout you referenced does not have a ground connected next to the xtal. Since this is a general layout, that may be ok, but it's a mandatory connection for the prop.This is a major bug!!!
I place a ground plane/layer under the prop connecting to all 4 prop ground pins. I place a 3v3 plane on the underside of the pcb under the prop with 4 100nF caps for decoupling. The 3v3 is fed via a single point which has a 10uF bulk cap between it and the ground feed. I also have a ground plane under the xtal, connected to the ground pin beside the xtal. This ground plane is isolated from the rest of the ground plane. This circuit reliably overclocks to 104MHz and I have tested to ~112MHz.
Currently you have way too many unknowns. You have to ensure the basics are met first. Otherwise you will go round endless circles and ultimately give up, which would be a bad thing. Obviously you have to take suggestions and weed them out. Some of them will be misleading, and some plain wrong. You have to decide which order to test. And that is part of learning too.
Do you have a DIP Prop? If so, then it is easy to put one on a breadboard to start with. Put a 100nF (0.1uF) and a 10uF tantalum across each set of power pins. Connect BOE, and a xtal, and 3v3 and you have a reliable circuit to begin experimenting with. Now you can plug in your various I2C board and test them. Just download with a propplug (no need for an eeprom). If you don't have a propplug but have a USB to serial (TTL) dongle, you can add the additional resistors, cap and transistor to your breadboard.
The sample layout you referenced does not have a ground connected next to the xtal. Since this is a general layout, that may be ok, but it's a mandatory connection for the prop.This is a major bug!!!
I place a ground plane/layer under the prop connecting to all 4 prop ground pins. I place a 3v3 plane on the underside of the pcb under the prop with 4 100nF caps for decoupling. The 3v3 is fed via a single point which has a 10uF bulk cap between it and the ground feed. I also have a ground plane under the xtal, connected to the ground pin beside the xtal. This ground plane is isolated from the rest of the ground plane. This circuit reliably overclocks to 104MHz and I have tested to ~112MHz.
Currently you have way too many unknowns. You have to ensure the basics are met first. Otherwise you will go round endless circles and ultimately give up, which would be a bad thing. Obviously you have to take suggestions and weed them out. Some of them will be misleading, and some plain wrong. You have to decide which order to test. And that is part of learning too.
Do you have a DIP Prop? If so, then it is easy to put one on a breadboard to start with. Put a 100nF (0.1uF) and a 10uF tantalum across each set of power pins. Connect BOE, and a xtal, and 3v3 and you have a reliable circuit to begin experimenting with. Now you can plug in your various I2C board and test them. Just download with a propplug (no need for an eeprom). If you don't have a propplug but have a USB to serial (TTL) dongle, you can add the additional resistors, cap and transistor to your breadboard.
The missing power connection is the +3.3v next to the xtal (on that design & fixed in latest), also, there is a copper pour that is on the pcb that is not in the picture.
I do have a few dip prop's laying around, however, I would still have to etch a pcb to use it. It will be just as easy to etch a smd pcb that can be used as well as tested with, and will save a few $$$ in materials. The latest will use 2 prop chips that talk to eachother via 2-wire serial (100% working already).
As for testing, I am using a different pcb now that has been upgraded from this one. Resistors on io's & extra caps on power pins. One power pin is still not connected (Pin 18 VCC) (the whole side of the ic is not used) & will be fixed on all future pcb's. (the down-side to learning from experience)
That "reference" pcb seems to have been updated with the ground connection on pin 27 but seems to have missed the point of why bypass caps might be necessary. The tiny 0402 bypass cap C3 which is connected to pin 30 seems to have it's connection to pin 27 all up around the crystal rather than direct through the ground plane and the center pad has not been utilized either. In all reality you would only need one bypass cap if all Prop power and ground pins had an intimate connection but because in many designs they don't then that is why it is "recommended" to use one on each side. Far better that it had the grounds connected to that center pad then dot the I's and cross the T's and make no sense.
The top layer fill inside/under the Prop is connected to ground on the bottom plane but the ground pins from the Prop should/could be connected to the fill directly.
Yes, I agree totally.
While that wasn't a bad board it certainly could have benefited by the extra direct connection of the grounds to that center square fill.
Hi Peter;
Yes, I agree totally.
While that wasn't a bad board it certainly could have benefited by the extra direct connection of the grounds to that center square fill.
Duane J
This is how I have done it with my other pcb's. I just dont have an image of them right at the moment so I snatched one off the internet.
The top layer fill inside/under the Prop is connected to ground on the bottom plane but the ground pins from the Prop should/could be connected to the fill directly.
Why is that? Aren't they connected to ground anyway? Why do they need to be connected to the fill directly? This is a genuine question - I'm a software person and only have a superficial understanding of electronics. Isn't ground ground? Or is there a problem with long(ish) traces (or wires) to ground?
...
As for testing, I am using a different pcb now that has been upgraded from this one. Resistors on io's & extra caps on power pins. One power pin is still not connected (Pin 18 VCC) (the whole side of the ic is not used) & will be fixed on all future pcb's. (the down-side to learning from experience)
Am I wasting my time??? Don't you get it - you MUST HAVE ALL 4 POWER PINS CONNECTED TOGETHER, AND ALL 4 GROUND PINS CONNECTED !!! Run a wire link.
Comments
ok then,
results are identical to other method:
that is what I would like to know. How am I suppose to know if the code is working right? The bmp's datasheet shows way different values for all of those that i get.
You will need to study the manual further to find out what is the purpose of the calibration data. My guess is that each module is calibrated with some baseline info stored for future use. In that screen shot, some of the values are not signed, so you can do what you were already doing on AC4 5 6 but correct the MSB/LSB thing.
ac4 := i2c.readLocation(bmpSCL, bmpAddr, $B0) << 8
ac4 |= i2c.readLocation(bmpSCL, bmpAddr, $B1)
I finally in the end got out a magnifying glass and looked at the markings on the case, and then realised that it wasn't the I2C device I thought it was, so I was addressing the wrong device.
Somehow the distributor I was using sent me the wrong RTC, same manufacturer but different model, and of course different addresses, memory and functions.
I had to re-do the whole Spin object I wrote to get it to work since the memory and functions were different.
You live and learn.
ac1 becomes 7159 using your code above.
ac4 becomes 33810
as for the calibration data, it is used in the second part of the pressure & temp math to calculate the true temperature & true pressure, which is just simple math. i can follow that part fine.
its just a matter of getting the right values from the device. the datasheet says the Chip ID is 0x55 and that is how you check that your communications are working properly.
The eeprom is quite a forgiving chip, but analog chips are not so forgiving of poor designs including power.
It is quite possible the problems are not software.
Every Sensor I am using is Digital. I have an analog pressure sensor, but requires much higher voltages than my batteries supply (16 volts needed, only 7v available)
I am pretty confident that it is in the software. My MPU-6050 works with a PASM i2c Driver 100%, but it dont work with the spin i2c driver.
Most I2C devices will tolerate clock speeds lower than their stated max (400kHz in this case) -- perhaps this is an exception.
The interface is digital, but internally all of these sensors are analog and need a steady power supply. You are correct though that these modules mostly all have a power supply filter capacitor on board, so there is less need for you to include one outside. Extra never hurts.
Power supply, a case in point. Last week I had to troubleshoot a system where the digital interface was working but the analog portion was not. Here is a 'scope shot of the i2c transaction. Lots of runt pulses. Even so, the i2c was reading and setting the internal registers. It turned out that there was a cold solder joint on the power pin to the chip (a tiny DFN), so the power to the chip was parasite power through the pullup resistors. A fine tip and solder corrected the problem.
Upper red trace SDA, lower yellow trace SCL.
A 'scope and a logic analyzer such as the #32314 Saleae that Parallax sells can be invaluable to see exactly what is going on.
So I had success with your scanner in finding both the MPU & BMP on the same i2c bus, so I did a little code mod & added in the BMP_Read function. I believe the values are correct, (MB) is the same value as the datasheet & others are fairly close.
A problem I think that is happening is how I merged the 3 values (up = up1 + up2 + up3). I dont quite understand bitshifting & the <<, >>, ~>=, etc. functions and how they are used to get the full 16 or 32 bit value into one (myVal).
Also by using readlocation vs readlocation16 the ouptut values change completely.
Here is what I did to the code:
and
and the results for the BMP test, which appear correct (assuming).
you can see it detected both sensors fine ($D0 & $EE):
I know I am having power issues on that pcb. in fact, it just went on the fritz this morning and will program the eeprom fine, but the output is about 1 time every 3 seconds, and the data is all 0's. But when I scoped the power rail its a good clean 3.30v.
I have a second pcb that I have switched to for testing the i2c sensors.
Edit: Now that I have switched to new pcb, I am able to get values from the MPU-9150 using the mpu6050 driver! Thanks to JonnyMac for an extremely simple i2c driver & i2c Scanner... I just modified the scanner code to read the sensors when they were detected. The Power issue quite probibly was the culpret.
Yes, my other pcb the VCC next to xtal is connected, however, due to the fact that I am not ordering my pcb's but etching myself, I have found it difficult to pack everything on the pcb & still connect all 4 power connections. 3 has been typical, but with the xtal vcc connected. I have been assuming it is fine being that they are internally connected. I have updated my pcb in DipTrace now.
You aregetting unpredictable results, so fixthis first before you damage the prop chip, providing you haven't already!
Im a little confused as to why parallax dont follow this procedure too well they own selves then.
I do have an old prop demo board that has since died, and I have based my circuits on its circuit:
http://www.rayslogic.com/propeller/DemoSched.gif
There is only one capacitor as close to the pins as possible and that is the 1uf across the vdd & gnd with boen & resn in between them, other than that, there is only 1 more cap connected to the prop chip and that is over on the power supply's output, far from the chip.
http://www.rayslogic.com/propeller/DemoPhoto.jpg
The only thing I have done different is leave one power pin unconnected.
While there are missing decoupling caps on the Demo Board, all of the the power pins are connected.
I'm sure you're frustrated at the moment -- best to let go of that and just follow the good guidance you're getting: decoupling caps on EVERY IC (don't count on what others have or have not done), and make sure all power connections are in fact connected.
Parallax promted the QuickStart board as a reference design; note that it has bypass caps on on power connections to the Propeller. There isn't one on the EEPROM, probably because it is so close to the cap on one side of the Propeller.
As frustrating as it is, I am doing just that. I have updated my pcb design with caps & all power's connected. I have also added resistors inline to all of my servo io's.
I came across this today:
http://longhornengineer.com/github/Appnotes_Propeller_LQFP-QFN-44/Layout.png
I am going to update my pcb's to this basic layout, it looks like a winner.
As for my sensors, I spent many hours last night reading the datasheet and trying relentlessly to get the mpu-9150 to give me the magnetometer data. I can follow the mpu6050 pasm driver (tho i dont know pasm at all) well enough to add config settings that are not currently available, and how the read sensors method works. But I have no clue how to retrieve the data that is being passed around in the asm code. I would like to be able to connect a bmp085/bmp180 and/or HMC5883 to the aux cl/da lines & read it with the mpu (master mode), then read the data from ext_sens_00 threw ext_sens_11 registers, which are sequential from the accelerometer (gyro - temp - accel - mag - bmp).
That pcb layout looks too basic, for instance it has the big pad under the chip that is grounded yet none of the Prop's grounds connect directly to it? Of course it's not a real design, it doesn't have any I/O connected etc. The other issue I have with many designs is the insistence in using big gull wing HC49 crystals, this is the most sensitive part of any design and it's hung out like a mainsail. There are plenty of cheap cylindrical and proper SMD crystals that do not cause this problem. BTW, as I said previously, a little Forth would have solved your little problem in very little time...... however this course has proved far more entertaining.
The top layer is RED and the bottom layer is GREEN.
A combination of the top and bottom layers form a nearly full ground plane.
The top is stitched to the bottom by a bunch of vias.
Duane J
I am self-taught hobbyist entrepreneur. I haven't had any formal classes on electronics either, tho I should have & had the chances. I am aware pretty much every design I have needs some updates, and I try to fix them as I become aware of them. So thanks for all the input on things that need fixed, it is greatly appreciated. I have learned more from my own errors than anything else.
It is entertaining for me as well, as not being schooled in electronics, this is an excellent learning experience. How could one learn anything without first trying?
The top layer fill inside/under the Prop is connected to ground on the bottom plane but the ground pins from the Prop should/could be connected to the fill directly.
Here's an example of a complete PCB to illustrate what I tend to do.
In this case this PCB is fairly compact and I have elected to have the center fill connected to VDD and the bottom plane to ground.
The "entertaining" thing is a little bit of a dig I admit at conventional means vs this unconventional means and how much it has dragged out. It's a bit like batch processing with punched cards, submitting them and getting the results back that don't work but still scratching your head as to why vs an interactive real-time terminal. Yes, we interact with the PC when we use a conventional compiler but the "punched cards" that it produces doesn't interact with us.
I place a ground plane/layer under the prop connecting to all 4 prop ground pins. I place a 3v3 plane on the underside of the pcb under the prop with 4 100nF caps for decoupling. The 3v3 is fed via a single point which has a 10uF bulk cap between it and the ground feed. I also have a ground plane under the xtal, connected to the ground pin beside the xtal. This ground plane is isolated from the rest of the ground plane. This circuit reliably overclocks to 104MHz and I have tested to ~112MHz.
Currently you have way too many unknowns. You have to ensure the basics are met first. Otherwise you will go round endless circles and ultimately give up, which would be a bad thing. Obviously you have to take suggestions and weed them out. Some of them will be misleading, and some plain wrong. You have to decide which order to test. And that is part of learning too.
Do you have a DIP Prop? If so, then it is easy to put one on a breadboard to start with. Put a 100nF (0.1uF) and a 10uF tantalum across each set of power pins. Connect BOE, and a xtal, and 3v3 and you have a reliable circuit to begin experimenting with. Now you can plug in your various I2C board and test them. Just download with a propplug (no need for an eeprom). If you don't have a propplug but have a USB to serial (TTL) dongle, you can add the additional resistors, cap and transistor to your breadboard.
The missing power connection is the +3.3v next to the xtal (on that design & fixed in latest), also, there is a copper pour that is on the pcb that is not in the picture.
I do have a few dip prop's laying around, however, I would still have to etch a pcb to use it. It will be just as easy to etch a smd pcb that can be used as well as tested with, and will save a few $$$ in materials. The latest will use 2 prop chips that talk to eachother via 2-wire serial (100% working already).
As for testing, I am using a different pcb now that has been upgraded from this one. Resistors on io's & extra caps on power pins. One power pin is still not connected (Pin 18 VCC) (the whole side of the ic is not used) & will be fixed on all future pcb's. (the down-side to learning from experience)
While that wasn't a bad board it certainly could have benefited by the extra direct connection of the grounds to that center square fill.
Duane J
This is how I have done it with my other pcb's. I just dont have an image of them right at the moment so I snatched one off the internet.
Why is that? Aren't they connected to ground anyway? Why do they need to be connected to the fill directly? This is a genuine question - I'm a software person and only have a superficial understanding of electronics. Isn't ground ground? Or is there a problem with long(ish) traces (or wires) to ground?