-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPCF8574_LH.cpp
209 lines (178 loc) · 6.99 KB
/
PCF8574_LH.cpp
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
PCF8574_LH.cpp
Version 1.0.0
Created 03.10.2024
Author: Linus81 aka Giuseppe Musciacchio (github.com/linus81)
Copyright (C) 2024 Linus81 aka Giuseppe Musciacchio
This file is part of the Arduino pcf8574.h library.
The pcf8574.h library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "PCF8574_LH.h"
bool PCF8574_LH::available() {
// Attempt to initiate a transmission to the PCF8574 address
wire->beginTransmission(address);
int result = wire->endTransmission(); // End the transmission
// If endTransmission returns 0, the device is available
return (result == 0);
}
// Utility function to verify the validity of the pin
bool PCF8574_LH::isValidPin(uint8_t pin) {
return (pin >= 0 && pin <= 7); // Validates that the pin number is between 0 and 7
}
// Write to the register (8 bits)
// Returns 0 for success, 1 for transmission error, 2 for address error
uint8_t PCF8574_LH::WriteAll(uint8_t value) {
wire->beginTransmission(address);
wire->write(value);
int result = wire->endTransmission();
if (result == 0) this->reg = value; // Update the stored register value if successful
return result;
}
// Read from the register (8 bits)
uint8_t PCF8574_LH::ReadAll() {
int result = wire->requestFrom(address, (uint8_t) 1);
// if (result == 0) return 0xFF; // Error, return 0xFF
if (result == 0 || wire->available() == 0) {
Serial.println("Error: No byte received from PCF8574.");
return 0xFF; // Error, return 0xFF
}
return wire->read(); // Return the read value
}
// Return the current value of the register
uint8_t PCF8574_LH::getReg() {
return reg; // Return the stored register value
}
// Invert all bits in the register
void PCF8574_LH::ToggleAll() {
reg = ~reg; // Bitwise NOT operation to invert all bits
WriteAll(reg); // Write the inverted value to the register
}
// Set the same mode (INPUT/OUTPUT) for all pins
void PCF8574_LH::SetAllPinMode(uint8_t mode) {
if (mode == OUTPUT) {
reg = 0x00; // Set all pins to OUTPUT
} else {
reg = 0xFF; // Set all pins to INPUT (default HIGH for pull-up)
}
WriteAll(reg); // Write the updated register value
}
// Reverse the bits of a single byte
uint8_t PCF8574_LH::ReverseByte(uint8_t byte) {
byte = ((byte & 0xF0) >> 4) | ((byte & 0x0F) << 4);
byte = ((byte & 0xCC) >> 2) | ((byte & 0x33) << 2);
byte = ((byte & 0xAA) >> 1) | ((byte & 0x55) << 1);
return byte; // Return the reversed byte
}
// Reverse all bits in the current register
void PCF8574_LH::ReverseAllBit() {
reg = ReverseByte(reg); // Reverse the current register value
WriteAll(reg); // Write the updated value to the register
}
// Shift the register right by 'positions' bits
// and return the new value of the register
uint8_t PCF8574_LH::ShiftRight(uint8_t positions) {
// Check if the number of positions to shift is valid
if (positions > 0 && positions < 8) {
reg >>= positions; // Perform right shift
} else if (positions >= 8) {
reg = 0; // If shifting 8 or more positions, set the register to 0
}
WriteAll(reg); // Write the updated value to the register
return reg; // Return the new register value
}
// Shift the register left by 'positions' bits
// and return the new value of the register
uint8_t PCF8574_LH::ShiftLeft(uint8_t positions) {
// Check if the number of positions to shift is valid
if (positions > 0 && positions < 8) {
reg <<= positions; // Perform left shift
} else if (positions >= 8) {
reg = 0; // If shifting 8 or more positions, set the register to 0
}
WriteAll(reg); // Write the updated value to the register
return reg; // Return the new register value
}
// Check if a specific pin is high
bool PCF8574_LH::IsPinHigh(uint8_t pin) {
if (pin < 8) {
return (reg & (1 << pin)) != 0; // Return true if the pin is high
}
return false; // Default value for invalid pin
}
// Check if a specific pin is low
bool PCF8574_LH::IsPinLow(uint8_t pin) {
if (pin < 8) {
return (reg & (1 << pin)) == 0; // Return true if the pin is low
}
return false; // Default value for invalid pin
}
// Set the mode of a specific pin
void pinMode(PCF8574_LH& pcf, uint8_t pin, uint8_t mode) {
// Check if the pin is valid
if (!pcf.isValidPin(pin)) {
Serial.println("Error: Invalid pin.");
return; // Handle the error
}
// Update the register using getReg() method
uint8_t reg = pcf.getReg();
uint8_t mask = (1 << pin);
if (mode == INPUT) {
reg |= mask; // Set the pin's bit to 1 for INPUT
} else {
reg &= ~mask; // Set the pin's bit to 0 for OUTPUT
}
// Write the updated register value
pcf.WriteAll(reg);
}
// Set the digital value of a specific pin
void digitalWrite(PCF8574_LH& pcf, uint8_t pin, bool value) {
// Check if the pin is valid
if (!pcf.isValidPin(pin)) {
Serial.println("Error: Invalid pin.");
return; // Handle the error
}
// Update the register using getReg() method
uint8_t reg = pcf.getReg();
uint8_t mask = (1 << pin);
if (value) {
reg &= ~mask; // Set the pin's bit to 0 for HIGH
} else {
reg |= mask; // Set the pin's bit to 1 for LOW
}
// Write the updated register value
pcf.WriteAll(reg);
}
// Read the digital value of a specific pin
bool digitalRead(PCF8574_LH& pcf, uint8_t pin) {
// Check if the pin is valid
if (!pcf.isValidPin(pin)) {
Serial.println("Error: Invalid pin.");
return false; // Handle the error
}
// Read the register and return the pin value
uint8_t currentState = pcf.ReadAll();
return !(currentState & (1 << pin)); // Return LOW if the bit is 0, HIGH if it is 1
}
// Toggle the digital value of a specific pin
void digitalToggle(PCF8574_LH& pcf, uint8_t pin) {
// Check if the pin is valid
if (!pcf.isValidPin(pin)) {
Serial.println("Error: Invalid pin.");
return; // Handle the error
}
// Toggle the pin's bit using getReg() method
uint8_t reg = pcf.getReg();
uint8_t mask = (1 << pin);
reg ^= mask; // Toggle the pin's bit
// Write the updated register value
pcf.WriteAll(reg);
}