Skip to content

Commit

Permalink
Add driver for MCP9808 i2c temperature sensor (#676)
Browse files Browse the repository at this point in the history
mcp9808: add support for temperature sensor
  • Loading branch information
gmonarque committed May 12, 2024
1 parent 7dbca2a commit 2a621dc
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 0 deletions.
48 changes: 48 additions & 0 deletions examples/mcp9808/main.go
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
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module tinygo.org/x/drivers

go 1.18

replace tinygo.org/x/drivers/mcp9808 => /home/kasterby/Documents/drivers/mcp9808

require (
github.com/eclipse/paho.mqtt.golang v1.2.0
github.com/frankban/quicktest v1.10.2
Expand Down
98 changes: 98 additions & 0 deletions mcp9808/mcp9808.go
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)
}
53 changes: 53 additions & 0 deletions mcp9808/registers.go
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
)
1 change: 1 addition & 0 deletions smoketest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/n
tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu9150/main.go
tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/sh1106/macropad_spi
tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/encoders/quadrature-interrupt
tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mcp9808/main.go
# network examples (espat)
tinygo build -size short -o ./build/test.hex -target=challenger-rp2040 ./examples/net/ntpclient/
# network examples (wifinina)
Expand Down

0 comments on commit 2a621dc

Please sign in to comment.