I’m new to Electric Imp and I2C so this is probably a stupid question. I’m trying to build a temperature logger with a TMP102 module from SparkFun and based on some Arduino examples I guessed it might be as simple as:
`
hardware.configure(I2C_12);
hardware.i2c12.configure(CLOCK_SPEED_100_KHZ);
local i2c = hardware.i2c12;
imp.configure(“Temperature sensor”, [], []);
function readTemp()
{
local result = i2c.read(0x48, “”, 2);
server.show(result);
imp.wakeup(2, readTemp);
}
readTemp();
`
Apparently it’s not as the code outputs null. Any help would be greatly appreciated.
Unfortunately it’s still returning null. In some examples I noticed that people first write “” to the device first to “wake” it up (I tried it as well). Is this necessary? Is the i2c.read equal to Arduino function Wire.requestFrom? Also in some examples the read/write bit seems to be included in the address.
I’ve tried adresses 0x48, 0x48<<1 and 0x90 as well as all the addresses between 0x00 and 0xff. The pull-up resistors for the SCL and SDA are included in the SparkFun TMP102 breakout.
Jane uses a TMP112 which appears to be similar to the TMP102; the jane example code writes the pointer register when reading the temperature like this:
Thanks for all the answers. The pointer register points to the temperature register (00) by default so writing shouldn’t be necessary nor has it helped. The SparkFun part number is SEN-09418. I’m sorry I forgot to mention that the ADDR0 is already tied to ground. I’ve also checked that SCL is connected to pin 1 and SDA to pin 2 and the solder joints seem good, but maybe I should check them once more. I noticed the Jane example and tried reading “\x00” as well, but it didn’t help either. The ATmega328 example on the SparkFun product page uses 0x92 for writing and 0x93 for reading (ADDR0 tied to VCC), but in my case reading 0x91 didn’t help.
I just got it working with the following code and pin1=SCL and pin2=SDA. In the arduino world, the Vcc is 5V, here I use 3.3V (from the arduino)
Code:
`// LM75 (CN75) Temperature Monitor using I2C
hardware.configure(I2C_12);
local i2c = hardware.i2c12;
local out_temp = OutputPort(“Temperature”);
imp.configure(“Temperature LM75”, [],[out_temp]);
// Wait at least 36ms
imp.sleep(0.05);
local a = 0.0;
local temperature = 0.0;
a = i2c.read(0x90, "\\x00", 2);
if (a==null){
temperature=999;
} else {
if (a[0]>127){
temperature = (a[0]-127)*-1.0; // values above 127 are negative degrees
if (a[1]==128) temperature -= 0.5;
} else {
temperature = a[0];
if (a[1]==128) temperature += 0.5;
}
}
// log and print
server.log(format("temperature %.2f C ",temperature));
server.show(format("%.2f C", temperature));
//Send data to server
out_temp.set(temperature);
Although the code below is in Processing, it may give you an idea for help in debugging your I2C wiring etc.
`// --------------------------------------
//
//
// This sketch tests the standard 7-bit addresses from 0 to 127.
// Devices with higher bit address might not be seen properly.
//
// Ric Batty
// September 2012
// version 121014-2307
//
// Using Arduino IDE 1.0.1
//
#include <Wire.h>
byte return_code;
byte I2C_address;
int count_Devices;
int count_Scans;
int scan_Index;
int total_Scans = 1; // You can bump this up or just hit reset for another scan
#define settle_time 10 // Time delay bewteen the Wire.beginTransmission and Wire.endTransmission #define scan_period 1000 // Scan period, nominally 1 scan per second
//
//
//------------------------------------------------------------
//
void setup()
{
Serial.begin(9600);
Serial.println(“
I2C Address Scanner v121014-2307
”);
count_Devices = 0;
count_Scans = 0;
scan_Index = 1;
Wire.begin();
}
count_Devices = 0;
for(I2C_address = 0; I2C_address <= 127; I2C_address++ ) {
Wire.beginTransmission(I2C_address);
delay(settle_time);
return_code = Wire.endTransmission();
/*
Returns
byte, which indicates the status of the transmission:
0:success
1:data too long to fit in transmit buffer
2:received NACK on transmit of address
3:received NACK on transmit of data
4:other error
*/
if (return_code == 0) {
// Return code of 0 means the Wire begin and end were recognized
Serial.print(" I2C device found at address ");
Serial.print(format2Hex(I2C_address));
Serial.println(" !");
count_Devices++;
}
else if (return_code==4) {
Serial.print(" Unknown error at I2C_address ");
Serial.print(format2Hex(I2C_address));
Serial.println(" ***");
}
else {
// Do nothing
}
}
if (count_Devices == 0) {
Serial.println(" **** No I2C devices found **** ");
}
else {
Serial.print(format2Dec(count_Devices));
Serial.println(" I2C device(s) found");
}
Serial.println("-Scan end\
");
delay(scan_period); // wait for next scan
scan_Index++;
}
}
String format2Hex(byte I2C_Address) {
String tempS;
tempS = String(I2C_Address,HEX);
tempS.toUpperCase();
if (I2C_Address < 0x10) {
tempS = “0” + tempS;
}
tempS = “0x” + tempS;
return tempS;
}
String format2Dec(int input) {
String tempS;
tempS = String(input,DEC);
if (input < 10) {
tempS = " " + tempS;
}
return tempS;
}
`
This is my take on it, a class that wraps TMP102. Works great and gives fractional values. Also note what documentations says about i2c:
The I2C bit rate is currently fixed at 100kHz, however a future firmware revision is expected to allow for configuration of this. Note also that external pull-ups are required, it is not possible to enable the internal pull-ups when pins are used for I2C.
I’m not using any pull-ups though and it works just fine.
/Per
//
// TMP102 Temperature Reader
// Uses i2c on pins 8, 9
//
class TemperatureReader {
i2c = null;
// Constructor
constructor() {
hardware.i2c89.configure(CLOCK_SPEED_100_KHZ);
i2c = hardware.i2c89;
}
function readData() {
// Start conversion
i2c.write(0x90, "");
i2c.write(0x90, "0");
// Wait for conversion to finish
imp.sleep(0.05);
// Read msb and lsb
local a = i2c.read(0x90, "\\x00", 2);
if (a == null){
return 999; // Dang...
}
// Calculate no of steps. Each step is 0.0625 degrees centigrades.
local temp = ((((a[0] & 0x7f) << 8) + a[1]) >> 4) * 0.0625;
// Is negative value?
if (a[0] & 0x80) {
temp *= -1;
}
return temp;
}
}
Thanks for pointing that incorrect note in the docs out! I2C clock has been configurable for a while now (50/100/400kHz). You still need pullups as the internal ones aren’t strong enough even for 50kHz.
Ah, now I get why my setup is so stable. The breakout board I have for the TMP102 has 1k pull-ups on it. They are just so tiny that I didn’t notice until now.
Hope somebody can help me out because I’m really stuck…
Trying to read one of these click with my Imp @ i2c12, but not getting anything other than ‘null’ when doing the i2c read command.
Everything is wired OK (double-checked with multi-meter, 3V3 is there @ Vcc, both SDA & SCL are held High by breakout resistors) and I’ve tried all of the classes listed in this thread to no avail (they’re pretty much identical, but I tried them all just to be sure…)
Any ideas what could be causing this?
I recall that someone mentioned the first two pins on the Sparkfun Imp breakout misbehaving - could this be it? Should I try with i2c89?