I spent the weekend trying to interface a DS1621 thermometer i2c chip to my RCW4400w.
I ran into quite a bit of trouble (and i’m familiar interfacing to this chip from other micro’s) – and there wasn’t any information on the web or this forum, so now that I’ve got it working I wanted to post some code samples to help others.
I used i2c.lib but not i2c_devices.lib, because the DS1621 needs slightly different parameters than are supported by the more high-level library.
For all of these, THERM_ADDRESS is defined to 0x90, which would be A0,A1,A2 on the DS1621 tied to ground.
After a basic i2c_init() I initialize the chip by sending it a 0x0 control code to put it in continuous mode, then a 0xEE to start temp conversion:
void init_temp()
{
i2c_start_tx();
i2c_write_char(THERM_ADDRESS);
i2c_write_char(0xAC);
i2c_write_char(0x0);
i2c_start_tx();
i2c_write_char(THERM_ADDRESS);
i2c_write_char(0xEE);
i2c_stop_tx();
wait(1000);
}
I wait 1 second at the end of that function because it takes 1 second for the first temperature conversion to be ready to read. That’s a wait function I made, use whatever you’d like.
Here’s how I get the actual temperature:
float get_temp()
{
char data[2];
float ret;
i2c_start_tx();
i2c_write_char(THERM_ADDRESS);
i2c_write_char(0xAA);
i2c_write_char(0xAA);
i2c_start_tx();
i2c_write_char(THERM_ADDRESS+1);
i2c_read_char(&data[0]);
i2c_send_ack();
i2c_read_char(&data[1]);
i2c_send_nak();
i2c_stop_tx();
ret = (float)(data[0]);
if(data[1]>0) ret+=0.5;
return ret;
}
That gets both bytes of the temperature, and adds the half-celsius-degree onto the end of the MSB to return a valid float celsius value. Convert this to F by multiplying by 1.8 and adding 32 if you’d like.
You can also stop the conversion to save energy as follows:
void stop_temp()
{
i2c_start_tx();
i2c_write_char(THERM_ADDRESS);
i2c_write_char(0x22);
i2c_stop_tx();
}
The biggest problem I had getting this working was actually in the size of the pullup resistors. I ended up having to use extremely small pullups to get the DS1621 to respond. about 1.5k on the clock, and 500ohm on the data. If you have trouble make sure you play with your resistor values, or hook to an oscope as I did to debug.
Also, all those i2c_write_char calls will return a 0 if an ack was received – however, if your pullups are the wrong size it may register an ack always even if nothing was sent.
Hope I save someone else some time on this! Good luck!