supla-device
Loading...
Searching...
No Matches
MCP23017.h
1/*
2 Copyright (C) AC SOFTWARE SP. Z O.O.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*/
18
19#pragma once
20
21/*
22 Dependency: https://github.com/RobTillaart/MCP23017_RT
23 Use library manager to install it
24*/
25
26#include <MCP23017.h>
27
28#include <supla/io.h>
29#include <supla/mutex.h>
30#include <supla/element.h>
31#include <supla/log_wrapper.h>
32
33namespace Supla {
34namespace Io {
35
36class MCP23017 : public Supla::Io::Base, Supla::Element {
37 public:
38 explicit MCP23017(uint8_t address = 0x20,
39 Supla::Mutex *mutex = nullptr,
40 TwoWire *wire = &Wire,
41 bool pullUp = false)
42 : Supla::Io::Base(false), mcp_(address, wire), mutex_(mutex) {
43 if (!mcp_.begin(pullUp)) {
44 SUPLA_LOG_ERROR("Unable to find MCP23017 at address: 0x%x", address);
45 } else {
46 SUPLA_LOG_DEBUG("MCP23017 is connected at address: 0x%x", address);
47 }
48 }
49
50 void onInit() {
51 read16FromMCP();
52 outState_ = inState_;
53 lastOutState_ = inState_;
54 }
55
56 void customPinMode(int channelNumber, uint8_t pin, uint8_t mode) override {
57 if (mutex_) mutex_->lock();
58 if (mcp_.isConnected()) {
59 mcp_.pinMode1(pin, mode);
60 }
61 if (mutex_) mutex_->unlock();
62 }
63
64 void customDigitalWrite(int channelNumber, uint8_t pin,
65 uint8_t val) override {
66 if (pin >= 16) {
67 SUPLA_LOG_WARNING("[MCP23017] can't write, pin %d out of range", pin);
68 return;
69 }
70 if (val) {
71 outState_ |= (1 << pin);
72 } else {
73 outState_ &= ~(1 << pin);
74 }
75 }
76
77 int customDigitalRead(int channelNumber, uint8_t pin) override {
78 if (pin >= 16) {
79 SUPLA_LOG_WARNING("[MCP23017] can't read, pin %d out of range", pin);
80 return 0;
81 }
82 return (inState_ >> pin) & 0x01;
83 }
84
85 unsigned int customPulseIn(int channelNumber, uint8_t pin, uint8_t value,
86 uint64_t timeoutMicro) override {
87 return 0;
88 }
89
90 void customAnalogWrite(int channelNumber, uint8_t pin, int val) override {}
91
92 int customAnalogRead(int channelNumber, uint8_t pin) override {
93 return 0;
94 }
95
96 void onTimer() override {
97 read16FromMCP();
98 write16ToMCP();
99 }
100
101 void read16FromMCP() {
102 if (mutex_) mutex_->lock();
103 if (mcp_.isConnected()) {
104 uint16_t data = mcp_.read16();
105 inState_ = (data >> 8) | (data << 8);
106 }
107 if (mutex_) mutex_->unlock();
108 }
109
110 void write16ToMCP() {
111 if (mutex_) mutex_->lock();
112 if (mcp_.isConnected() && outState_ != lastOutState_) {
113 uint16_t data = (outState_ >> 8) | (outState_ << 8);
114 mcp_.write16(data);
115 lastOutState_ = outState_;
116 }
117 if (mutex_) mutex_->unlock();
118 }
119
120 protected:
121 ::MCP23017 mcp_;
122 uint16_t outState_ = 0;
123 uint16_t inState_ = 0;
124 uint16_t lastOutState_ = 0;
125 Supla::Mutex *mutex_ = nullptr;
126};
127
128}; // namespace Io
129}; // namespace Supla
Base class for all elements of SuplaDevice.
Definition element.h:37
Definition io.h:35
void onInit()
Third method called on element in SuplaDevice.begin()
Definition MCP23017.h:50
void onTimer() override
Method called on timer interupt.
Definition MCP23017.h:96
Definition mutex.h:22