FluxSand 1.0
FluxSand - Interactive Digital Hourglass
Loading...
Searching...
No Matches
ads1115.hpp
1#pragma once
2
3#include <atomic>
4#include <cstdint>
5#include <cstdio>
6#include <functional>
7#include <iostream>
8#include <stdexcept>
9#include <thread>
10
11#include "bsp_gpio.hpp"
12#include "bsp_i2c.hpp"
13
21template <int CHANNEL_NUM>
22class Ads1115 {
23 public:
24 static constexpr uint8_t DEFAULT_I2C_ADDR = 0x48;
25 static constexpr uint8_t POINTER_CONVERSION = 0x00;
26 static constexpr uint8_t POINTER_CONFIG = 0x01;
27
34 Ads1115(I2cDevice& i2c, Gpio& drdy, uint8_t address = DEFAULT_I2C_ADDR)
35 : i2c_(i2c), drdy_gpio_(drdy), i2c_addr_(address) {
37 StartScan();
38 }
39
43 void StartScan() {
44 scanning_ = true;
45 current_channel_ = 0;
46 ConfigureChannel(current_channel_);
47
49 [this]() { OnDataReady(); });
50 }
51
55 void Stop() { scanning_ = false; }
56
62 float GetVoltage(int channel) const {
63 if (channel < 0 || channel >= CHANNEL_NUM) {
64 return 0.0f;
65 }
66 return voltages_[channel];
67 }
68
73 // Set Lo_thresh = 0x0000 (MSB = 0)
74 uint8_t lo_thresh[3] = {0x02, 0x00, 0x00};
75 i2c_.WriteRaw(lo_thresh, 3);
76
77 // Set Hi_thresh = 0x8000 (MSB = 1)
78 uint8_t hi_thresh[3] = {0x03, 0x80, 0x00};
79 i2c_.WriteRaw(hi_thresh, 3);
80 }
81
85 void Display() const {
86 for (int i = 0; i < CHANNEL_NUM; ++i) {
87 std::cout << "Channel " << i << ": " << voltages_[i] << " V ";
88 }
89 std::cout << '\n';
90 }
91
97 void RegisterChannelCallback(int channel, std::function<void(float)> cb) {
98 if (channel >= 0 && channel < CHANNEL_NUM) {
99 callbacks_[channel] = cb;
100 }
101 }
102
103 private:
104 // NOLINTNEXTLINE
105 I2cDevice& i2c_;
106 // NOLINTNEXTLINE
107 Gpio& drdy_gpio_;
108 uint8_t i2c_addr_;
109 std::function<void(float)> callbacks_[CHANNEL_NUM];
110
111 std::atomic<bool> scanning_{false};
112 int current_channel_ = 0;
113 float voltages_[CHANNEL_NUM] = {0.0f};
114
120 void OnDataReady() {
121 if (!scanning_) {
122 return;
123 }
124
125 // Read and convert voltage
126 int16_t raw = ReadConversion();
127 voltages_[current_channel_] =
128 static_cast<float>(raw) * 0.000125f; // 125 µV/LSB
129
130 // Invoke user callback
131 if (callbacks_[current_channel_]) {
132 callbacks_[current_channel_](voltages_[current_channel_]);
133 }
134
135 // Switch to next channel
136 current_channel_ = (current_channel_ + 1) % CHANNEL_NUM;
137 ConfigureChannel(current_channel_);
138 }
139
144 void ConfigureChannel(int channel) {
145 if (channel < 0 || channel > 3) {
146 return;
147 }
148
149 uint16_t config = 0;
150 config |= (0x04 + channel) << 12; // MUX: AINx vs GND
151 config |= (1 << 9); // PGA ±4.096V
152 config |= (0 << 8); // Mode: Continuous
153 config |= (0b111 << 5); // Data Rate: 860 SPS
154
155 uint8_t data[3] = {
156 POINTER_CONFIG,
157 static_cast<uint8_t>((config >> 8) & 0xFF),
158 static_cast<uint8_t>(config & 0xFF),
159 };
160
161 i2c_.WriteRaw(data, 3);
162
163 // Wait for config to take effect; discard first reading
164 std::this_thread::sleep_for(std::chrono::milliseconds(1));
166 }
167
172 int16_t ReadConversion() {
173 uint8_t pointer = POINTER_CONVERSION;
174 i2c_.WriteRaw(&pointer, 1);
175
176 uint8_t buf[2] = {};
177 i2c_.ReadRegisters(POINTER_CONVERSION, buf, 2);
178
179 return static_cast<int16_t>((buf[0] << 8) | buf[1]);
180 }
181};
ADS1115 ADC driver with GPIO interrupt-based channel cycling.
Definition ads1115.hpp:22
float GetVoltage(int channel) const
Returns the latest voltage reading from a specific channel.
Definition ads1115.hpp:62
void Display() const
Prints voltage readings of all channels to console.
Definition ads1115.hpp:85
void ConfigureChannel(int channel)
Configures ADS1115 for a specific single-ended channel.
Definition ads1115.hpp:144
void StartScan()
Starts scanning the channels and enabling data-ready interrupt.
Definition ads1115.hpp:43
Ads1115(I2cDevice &i2c, Gpio &drdy, uint8_t address=DEFAULT_I2C_ADDR)
Constructor.
Definition ads1115.hpp:34
void Stop()
Stops the scan process.
Definition ads1115.hpp:55
int16_t ReadConversion()
Reads the 16-bit signed conversion result.
Definition ads1115.hpp:172
void EnableReadyInterruptMode()
Registers interrupt-based data-ready mode (comparator configuration)
Definition ads1115.hpp:72
void RegisterChannelCallback(int channel, std::function< void(float)> cb)
Registers a callback function for a specific channel.
Definition ads1115.hpp:97
void OnDataReady()
Called on rising edge of ALERT/RDY pin Reads current value, stores it, calls callback,...
Definition ads1115.hpp:120
void EnableInterruptRisingEdgeWithCallback(Callback cb)
Definition bsp_gpio.hpp:109
void WriteRaw(const uint8_t *data, size_t length)
Definition bsp_i2c.hpp:104
void ReadRegisters(uint8_t reg, uint8_t *buffer, size_t length)
Definition bsp_i2c.hpp:86