Skip to content

Commit 8d6f56f

Browse files
committed
Merge branch 'gas_sensor_mq-135' of https://github.com/rahul31124/pslab-android into gas_sensor_mq-135
2 parents 1531932 + 680689c commit 8d6f56f

8 files changed

Lines changed: 1250 additions & 22 deletions

File tree

assets/icons/l.png

12 KB
Loading
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import 'package:pslab/communication/peripherals/i2c.dart';
2+
import 'package:pslab/communication/science_lab.dart';
3+
import 'package:pslab/others/logger_service.dart';
4+
5+
class SSD1306 {
6+
static const String tag = "SH1106_Hardware";
7+
static const int address = 0x3C;
8+
9+
static const int _commandMode = 0x00;
10+
static const int _dataMode = 0x40;
11+
12+
final I2C i2c;
13+
List<int> _lastBuffer = List.filled(1024, -1);
14+
15+
SSD1306._(this.i2c);
16+
17+
static Future<SSD1306> create(I2C i2c, ScienceLab scienceLab) async {
18+
final display = SSD1306._(i2c);
19+
await display._initialize(scienceLab);
20+
return display;
21+
}
22+
23+
Future<void> _initialize(ScienceLab scienceLab) async {
24+
if (!scienceLab.isConnected()) throw Exception("ScienceLab device absent");
25+
26+
try {
27+
final List<int> initSequence = [
28+
0xAE,
29+
0xD5,
30+
0x80,
31+
0xA8,
32+
0x3F,
33+
0xD3,
34+
0x00,
35+
0x40,
36+
0xAD,
37+
0x8B,
38+
0x33,
39+
0xA1,
40+
0xC8,
41+
0xDA,
42+
0x12,
43+
0x81,
44+
0xFF,
45+
0xD9,
46+
0x1F,
47+
0xDB,
48+
0x40,
49+
0xA4,
50+
0xA6,
51+
0xAF,
52+
];
53+
54+
for (int cmd in initSequence) {
55+
await i2c.write(address, [cmd], _commandMode);
56+
}
57+
await clearDisplay();
58+
} catch (e) {
59+
logger.e("[$tag] Fatal initialization error: $e");
60+
rethrow;
61+
}
62+
}
63+
64+
Future<void> _setPosition(int column, int page) async {
65+
int offsetColumn = column + 2;
66+
await i2c.write(address, [0xB0 + page], _commandMode);
67+
await i2c.write(address, [offsetColumn & 0x0F], _commandMode);
68+
await i2c.write(address, [0x10 | (offsetColumn >> 4)], _commandMode);
69+
}
70+
71+
Future<void> clearDisplay() async {
72+
try {
73+
for (int page = 0; page < 8; page++) {
74+
await i2c.write(address, [0xB0 + page], _commandMode);
75+
await i2c.write(address, [0x00], _commandMode);
76+
await i2c.write(address, [0x10], _commandMode);
77+
78+
for (int chunk = 0; chunk < 132; chunk += 16) {
79+
int size = (chunk + 16 > 132) ? 132 - chunk : 16;
80+
await i2c.write(address, List.filled(size, 0x00), _dataMode);
81+
}
82+
}
83+
_lastBuffer = List.filled(1024, 0);
84+
} catch (e) {
85+
logger.e("[$tag] Error during clearDisplay: $e");
86+
}
87+
}
88+
89+
Future<void> sendFrameBuffer(List<int> buffer) async {
90+
if (buffer.length != 1024) return;
91+
92+
try {
93+
for (int page = 0; page < 8; page++) {
94+
int startIdx = page * 128;
95+
int firstCol = -1;
96+
int lastCol = -1;
97+
98+
for (int i = 0; i < 128; i++) {
99+
if (buffer[startIdx + i] != _lastBuffer[startIdx + i]) {
100+
if (firstCol == -1) firstCol = i;
101+
lastCol = i;
102+
}
103+
}
104+
105+
if (firstCol != -1) {
106+
int length = lastCol - firstCol + 1;
107+
108+
try {
109+
await _setPosition(firstCol, page);
110+
111+
for (int chunk = 0; chunk < length; chunk += 16) {
112+
int chunkSize = (chunk + 16 > length) ? length - chunk : 16;
113+
List<int> bytes = buffer.sublist(startIdx + firstCol + chunk,
114+
startIdx + firstCol + chunk + chunkSize);
115+
await i2c.write(address, bytes, _dataMode);
116+
}
117+
} catch (e) {
118+
// --- THE LAG KILLER ---
119+
// If the Android USB throws a 500ms timeout, DO NOT KEEP LOOPING.
120+
// Abort this frame entirely so the Flutter UI thread unfreezes instantly!
121+
_lastBuffer =
122+
List.filled(1024, -1); // Reset cache to heal on next tick
123+
return;
124+
}
125+
126+
// Only update cache if the write was perfectly successful
127+
for (int i = firstCol; i <= lastCol; i++) {
128+
_lastBuffer[startIdx + i] = buffer[startIdx + i];
129+
}
130+
}
131+
}
132+
} catch (e) {
133+
_lastBuffer = List.filled(1024, -1);
134+
}
135+
}
136+
}

0 commit comments

Comments
 (0)