-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add driver for MCP9808 i2c temperature sensor (#676)
mcp9808: add support for temperature sensor
- Loading branch information
Showing
5 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"machine" | ||
"time" | ||
|
||
"tinygo.org/x/drivers/mcp9808" | ||
) | ||
|
||
func main() { | ||
|
||
//tinygo monitor | ||
time.Sleep(time.Millisecond * 5000) | ||
|
||
//Configure I2C (in this case, I2C0 on RPI Pico), and wire the module accordingly | ||
machine.I2C0.Configure(machine.I2CConfig{ | ||
SCL: machine.GP1, | ||
SDA: machine.GP0, | ||
}) | ||
|
||
//Create sensor | ||
sensor := mcp9808.New(machine.I2C0) | ||
if !sensor.Connected() { | ||
println("MCP9808 not found") | ||
return | ||
} else { | ||
println("MCP9808 found") | ||
} | ||
|
||
time.Sleep(time.Millisecond * 1000) | ||
|
||
//Set resolution | ||
sensor.SetResolution(mcp9808.Maximum) | ||
|
||
time.Sleep(time.Millisecond * 1000) | ||
|
||
//Read temp. | ||
temp, err := sensor.ReadTemperature() | ||
if err != nil { | ||
println("MCP9808 error reading temperature") | ||
println(err.Error()) | ||
return | ||
} else { | ||
fmt.Printf("Temperature: %.2f \n", temp) | ||
} | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Package mcp9808 implements a driver for the MCP9808 High Accuracy I2C Temperature Sensor | ||
// | ||
// Datasheet: https://cdn-shop.adafruit.com/datasheets/MCP9808.pdf | ||
// Module: https://www.adafruit.com/product/1782 | ||
// Only implemented: temperature reading, resolution read & set | ||
package mcp9808 | ||
|
||
import ( | ||
"encoding/binary" | ||
"errors" | ||
|
||
"tinygo.org/x/drivers" | ||
) | ||
|
||
type Device struct { | ||
bus drivers.I2C | ||
Address uint16 | ||
} | ||
|
||
func New(bus drivers.I2C) Device { | ||
return Device{bus, MCP9808_I2CADDR_DEFAULT} | ||
} | ||
|
||
func (d *Device) Connected() bool { | ||
data := make([]byte, 2) | ||
d.Read(MCP9808_REG_DEVICE_ID, &data) | ||
return binary.BigEndian.Uint16(data) == MCP9808_DEVICE_ID | ||
} | ||
|
||
func (d *Device) ReadTemperature() (float64, error) { | ||
data := make([]byte, 2) | ||
var temp float64 | ||
if err := d.Read(MCP9808_REG_AMBIENT_TEMP, &data); err != nil { | ||
return 0, err | ||
} | ||
|
||
data[0] = data[0] & 0x1F | ||
if data[0]&0x10 == 0x10 { | ||
data[0] = data[0] & 0x0F | ||
temp = float64(data[0])*16 + float64(data[1])/16.0 - 256 | ||
} | ||
temp = float64(data[0])*16 + float64(data[1])/16.0 | ||
return temp, nil | ||
} | ||
|
||
func (d *Device) ReadResolution() (resolution, error) { | ||
data := make([]byte, 2) | ||
err := d.Read(MCP9808_REG_RESOLUTION, &data) | ||
if err != nil { | ||
return 0, err | ||
} | ||
switch data[0] { | ||
case 0: | ||
return Low, nil | ||
case 1: | ||
return Medium, nil | ||
case 2: | ||
return High, nil | ||
case 3: | ||
return Maximum, nil | ||
|
||
default: | ||
return 0, errors.New("unknown resolution") | ||
} | ||
} | ||
|
||
func (d *Device) SetResolution(r resolution) error { | ||
switch r { | ||
case Low: | ||
if err := d.Write(MCP9808_REG_RESOLUTION, []byte{0x00}); err != nil { | ||
return err | ||
} | ||
case Medium: | ||
if err := d.Write(MCP9808_REG_RESOLUTION, []byte{0x01}); err != nil { | ||
return err | ||
} | ||
case High: | ||
if err := d.Write(MCP9808_REG_RESOLUTION, []byte{0x02}); err != nil { | ||
return err | ||
} | ||
case Maximum: | ||
if err := d.Write(MCP9808_REG_RESOLUTION, []byte{0x03}); err != nil { | ||
return err | ||
} | ||
default: | ||
return nil | ||
} | ||
return nil | ||
} | ||
|
||
func (d *Device) Write(register byte, data []byte) error { | ||
buf := append([]byte{register}, data...) | ||
return d.bus.Tx(d.Address, buf, nil) | ||
} | ||
|
||
func (d *Device) Read(register byte, data *[]byte) error { | ||
return d.bus.Tx(d.Address, []byte{register}, *data) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Package mcp9808 implements a driver for the MCP9808 High Accuracy I2C Temperature Sensor | ||
// | ||
// Datasheet: https://cdn-shop.adafruit.com/datasheets/MCP9808.pdf | ||
// Module: https://www.adafruit.com/product/1782 | ||
package mcp9808 | ||
|
||
// Constants/addresses used for I2C. | ||
const ( | ||
MCP9808_DEVICE_ID = 0x0400 | ||
MCP9808_MANUF_ID = 0x0054 | ||
|
||
MCP9808_I2CADDR_DEFAULT = 0x18 //default I2C address | ||
MCP9808_REG_CONFIG = 0x01 //MCP9808 config register | ||
|
||
MCP9808_REG_CONFIG_SHUTDOWN = 0x0100 //shutdown config | ||
MCP9808_REG_CONFIG_CRITLOCKED = 0x0080 //critical trip lock | ||
MCP9808_REG_CONFIG_WINLOCKED = 0x0040 //alarm window lock | ||
MCP9808_REG_CONFIG_INTCLR = 0x0020 //interrupt clear | ||
MCP9808_REG_CONFIG_ALERTSTAT = 0x0010 //alert output status | ||
MCP9808_REG_CONFIG_ALERTCTRL = 0x0008 //alert output control | ||
MCP9808_REG_CONFIG_ALERTSEL = 0x0004 //alert output select | ||
MCP9808_REG_CONFIG_ALERTPOL = 0x0002 //alert output polarity | ||
MCP9808_REG_CONFIG_ALERTMODE = 0x0001 //alert output mode | ||
|
||
MCP9808_REG_UPPER_TEMP = 0x02 //upper alert boundary | ||
MCP9808_REG_LOWER_TEMP = 0x03 //lower alert boundery | ||
MCP9808_REG_CRIT_TEMP = 0x04 //critical temperature | ||
MCP9808_REG_AMBIENT_TEMP = 0x05 //ambient temperature | ||
MCP9808_REG_MANUF_ID = 0x06 //manufacturer ID | ||
MCP9808_REG_DEVICE_ID = 0x07 //device ID | ||
MCP9808_REG_RESOLUTION = 0x08 //resolution | ||
) | ||
|
||
/* | ||
======= ============ ============== | ||
value resolution reading Time | ||
======= ============ ============== | ||
0 0.5°C 30 ms | ||
1 0.25°C 65 ms | ||
2 0.125°C 130 ms | ||
3 0.0625°C 250 ms | ||
======= ============ ============== | ||
*/ | ||
type resolution uint8 | ||
|
||
const ( | ||
Low resolution = iota | ||
Medium | ||
High | ||
Maximum | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters