summaryrefslogtreecommitdiffstats
path: root/adxl.py
blob: c87781df77d79f8c283a391235c2846086b90e43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import machine

class ADXL():
    ADXL_ADDR = 0x53

    def __init__(self, SCL, SDA):
        self.SCL = SCL
        self.SDA = SDA
        self._i2c = machine.I2C(scl=self.SCL, sda=self.SDA, freq=100000)

        self._last_x = 0.0
        self._last_y = 0.0
        self._last_z = 0.0
        self._last_act_x = 0.0
        self._last_act_y = 0.0
        self._last_act_z = 0.0

        self._is_active = False

        self._timer = machine.Timer(-1)
        self._timer.init(period=100, mode=machine.Timer.PERIODIC, callback=self._timer_cb)

        self._timer_cb(None)

    def setup(self):
        r = self._i2c.readfrom_mem(self.ADXL_ADDR, 0x2D, 1)

        if (not bool(r[0] & (1 << 3))):
            print('setup')
            # OFFSET_{X,Y,Z}
            #self._i2c.writeto_mem(self.ADXL_ADDR, 0x1E, bytes([25, 76, 183]))
            self._i2c.writeto_mem(self.ADXL_ADDR, 0x1E, bytes([25, 75, 131]))

            # BW_RATE not LOW_POWER datarate 12.5Hz 0111
            self._i2c.writeto_mem(self.ADXL_ADDR, 0x2C, (7).to_bytes(1, 'little'))
            # DATA_FORMAT: FULL_RES 8, 8g 2
            self._i2c.writeto_mem(self.ADXL_ADDR, 0x31, (8 + 2).to_bytes(1, 'little'))

            # THRESH_ACT 4 * 62.5 mg = 0.25g
            # THRESH_INACT 2 * 62.5 mg = 0.125g
            # TIME_INACT 5s
            # ACT_INACT_CTL INACT ac-coupled, all axis enabled
            self._i2c.writeto_mem(self.ADXL_ADDR, 0x24, bytes([10, 2, 5, 255]))

            # INT_MAP Activity to INT everything else INT2
            self._i2c.writeto_mem(self.ADXL_ADDR, 0x2F, (239).to_bytes(1, 'little'))

            # INT_ENABLE Activity, Inactivity
            # self._i3c.writeto_mem(self.ADXL_ADDR, 0x2E, (16 + 8).to_bytes(1, 'little'))
            self.inactivity_intr(True)

            # FIFO_CTL bypass FIFO
            self._i2c.writeto_mem(self.ADXL_ADDR, 0x38, (0).to_bytes(1, 'little'))

        # PWR_CTL Link mode 32, auto_sleep 16, measure 8 enable
        self._i2c.writeto_mem(self.ADXL_ADDR, 0x2D, (32 + 16 + 8).to_bytes(1, 'little'))

    def __decode_data(self, data):
            # micropython doesn't implement signed param and assumes signed=False
            d = int.from_bytes(data[0:2], 'little')
            if (d > 32767):
                d = -(65535 - d + 1)

            return d / 250

    def read_data(self):
        axis = self._i2c.readfrom_mem(self.ADXL_ADDR, 0x2B, 1)

        d = self._i2c.readfrom_mem(self.ADXL_ADDR, 0x32, 6)
        x = self.__decode_data(d[0:2])
        y = self.__decode_data(d[2:4])
        z = self.__decode_data(d[4:6])

        return (x, y, z)

    def _timer_cb(self, t):
        int_src = self._i2c.readfrom_mem(self.ADXL_ADDR, 0x30, 1)

        if (bool(int_src[0] & (1 << 4))):
            print('activity detected')
            self._is_active = True
            (self._last_act_x, self._last_act_y, self._last_act_z) = self.read_data()

        if (bool(int_src[0] & (1 << 3))):
            print('inactivity detected')
            self._is_active = False

        if (bool(int_src[0] & (1 << 7))):
            (self._last_x, self._last_y, self._last_z) = self.read_data()
            if (self._is_active):
                pass

    def is_active(self):
        return self._is_active

    def last_x(self):
        return self._last_x

    def last_y(self):
        return self._last_y

    def last_z(self):
        return self._last_z

    def activity_intr(self, enabled):
        int_en = self._i2c.readfrom_mem(self.ADXL_ADDR, 0x2E, 1)

        if (enabled):
            int_en = int_en[0] | (1 << 4)
        else:
            int_en = int_en[0] & ~(1 << 4)

        self._i2c.writeto_mem(self.ADXL_ADDR, 0x2E, int_en.to_bytes(1, 'little'))

    def inactivity_intr(self, enabled):
        int_en = self._i2c.readfrom_mem(self.ADXL_ADDR, 0x2E, 1)

        if (enabled):
            int_en = int_en[0] | (1 << 3)
        else:
            int_en = int_en[0] & ~(1 << 3)

        self._i2c.writeto_mem(self.ADXL_ADDR, 0x2E, int_en.to_bytes(1, 'little'))