Skip to content

Commit 1340277

Browse files
monkeykingblacktuanpmt
authored andcommitted
I2C/OLED (#11)
* I2C/OLED * Thay doi noi dung I2C/OLED
1 parent 0a89fe4 commit 1340277

File tree

4 files changed

+390
-0
lines changed

4 files changed

+390
-0
lines changed
509 KB
Loading
42.2 KB
Loading

docs/arduino/i2c_oled.rst

Lines changed: 389 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,389 @@
1+
Giao tiếp ESP32 với OLED qua I2C
2+
--------------------------------
3+
4+
OLED là gì?
5+
===========
6+
7+
OLED là viết tắt của chữ **Organic Light Emitting Diode** dùng để chỉ cấu tạo của màn hình gồm các diode phát quang hữu cơ, vật liệu này có khả năng phát sáng khi có dòng điện chạy qua, người dùng có thể hiểu đơn giản công nghệ màn hình OLED sử dụng vô số các led phát quang để tạo nên một màn hình hiển thị lớn tùy theo kích thước chế tạo và công nghệ của nhà sản xuất. Công nghệ màn hình này có khả năng cho chất lượng ảnh tươi, độ tái tạo màu sắc tuyệt vời. Hơn nữa do được cấu tạo bằng các diode phát quang nên người ta có thể chế tạo được màn hình OLED mỏng hơn rất nhiều so với công nghệ màn hình LCD trước đây.
8+
9+
Một màn hình OLED bao gồm một lớp vật liệu hữu cơ với chủ yếu là cacbon nằm giữa hai điện cực anot và catot sẽ tự động phát sáng mỗi khi có dòng điện chạy qua.
10+
11+
.. image:: ../_static/oled-technology-seminar-ppt-8-638.jpg
12+
13+
OLED có rất nhiều **ưu điểm** vượt trội:
14+
15+
- Hình ảnh nịnh mắt, sắc nét.
16+
- Độ sáng và độ tương phản cao.
17+
- Màu đen hiển thị sâu.
18+
- Có khả năng tùy biến theo nhiều hình dạng khác nhau.
19+
- Tiết kiệm năng lượng.
20+
- Góc nhìn rộng hơn.
21+
22+
Bên cạnh đó OLED vẫn còn có một số **nhược điểm** sau:
23+
24+
- Chi phí sản xuất cao.
25+
- Tuổi thọ kém.
26+
27+
Trong bài viết này sẽ sử dụng đến màn hình `SSD1306 OLED 128x64 0.96"-I2C <https://iotmaker.vn/ssd1306-oled-096inch-128x64-i2c.html>`_.
28+
29+
.. image:: ../_static/oled-096-iotmakervn.png
30+
:width: 200px
31+
32+
Thông số kỹ thuật:
33+
34+
- Điện ấp sử dụng: ``3V3`` đến ``5V`` (DC)
35+
- Công suất tiêu thụ: ``0.04W``
36+
- Góc hiển thị: Lớn hơn ``16 độ``
37+
- Độ phân giải: ``128x64`` pixel (Điểm ảnh)
38+
- Độ rộng màn hình: ``0.96"``
39+
- Giao tiếp: ``I2C``
40+
- Màu: Trắng và Đen
41+
42+
I2C
43+
===
44+
45+
Ở trên chúng ta thấy rằng ``SSD1306_OLED`` sử dụng giao tiếp ``I2C``, vậy ``I2C`` là gì?
46+
47+
``I²C``, viết tắt của từ **Inter-Integrated Circuit**, là một loại bus nối tiếp được phát triển bởi hãng sản xuất linh kiện điện tử Philips. Ban đầu, loại bus này chỉ được dùng trong các linh kiện điện tử của Philips. Sau đó, do tính ưu việt và đơn giản của nó, I²C đã được chuẩn hóa và được dùng rộng rãi trong các mô đun truyền thông nối tiếp của vi mạch tích hợp ngày nay.
48+
49+
Cấu tạo và nguyên lý hoạt động của I2C
50+
++++++++++++++++++++++++++++++++++++++
51+
52+
Khi có nhiều thiết bị ``I2C`` trên bus, thì phải (và chỉ) có 1 **Master** để điều khiển Bus - Có thể có nhiều **Slave** bị động, được điều khiển bởi **Master**
53+
54+
``I2C`` sử dụng hai đường truyền tín hiệu:
55+
56+
- Một đường tạo xung dao động (SCL) chỉ do **Master** phát đi ( thông thường ở 100kHz và 400kHz, mức cao nhất là 1Mhz và 3.4MHz).
57+
- Một đường truyền dữ liệu (SDA) từ **Master** sang **Slave** hoặc ngược lại.
58+
59+
Về lý thuyết lẫn thực tế ``I2C`` sử dụng 7 bit (10 bit - chế độ mở rộng) để định địa chỉ, do đó trên một bus có thể có tới 2^7 địa chỉ tương ứng với 128 thiết bị có thể kết nối, nhưng chỉ có 112 , 16 địa chỉ còn lại được sử dụng vào mục đích riêng. Bit còn lại quy định việc đọc hay ghi dữ liệu (1 là write, 0 là read).
60+
61+
Điểm mạnh của ``I2C`` chính là sự đơn giản của nó: một khối điều khiển trung tâm có thể điều khiển cả một mạng thiết bị mà chỉ cần hai lối ra điều khiển.
62+
63+
Các chế độ hoạt động của I2C
64+
++++++++++++++++++++++++++++
65+
66+
Dựa vào tốc độ sẽ có 2 loại:
67+
68+
- Chế độ chuẩn (standard mode) hoạt động ở tốc độ 100Kbit/s.
69+
- Chế độ tốc độ thấp (low-speed mode) hoạt động ở tốc độ 10 Kbit/s.
70+
71+
Nếu chia theo quan hệ chủ tớ:
72+
73+
- Một Master một Slave.
74+
- Một Master nhiều Slave.
75+
76+
.. Note::
77+
78+
Mỗi thiết bị khi làm **Slave** sẽ có một địa chỉ khác nhau để thiết bị **Master** có thể nhận diện được và gữi lệnh xuống. Vì vậy sẽ không có chuyện nhầm lẫn giữa các thiết bị.
79+
80+
.. Note::
81+
82+
Hai chân truyền dữ liệu SCL và SDA luôn hoạt động ở chế độ mở, vì vậy cần phải có một điện trở kéo (tức là Vcc -> trở -> SCL/SDA). Giá trị của điện trở giao động từ 1kOhm đến 4.7kOhm tùy theo tốc độ truyền (thông thường sẽ sử dụng trở 2kOhm cho tốc độ 400kbps và 10kOhm cho tốc độ 100kbps)
83+
84+
Tài liệu tham khảo
85+
++++++++++++++++++
86+
87+
Để có thể hiểu rõ hơn về ``I2C`` bạn có thể vào `đây <http://maxembedded.com/2014/02/inter-integrated-circuits-i2c-basics/>`_ để tìm hiểu thêm.
88+
89+
Demo
90+
====
91+
92+
Linh kiện sử dụng:
93+
94+
+-------------------------------+----------------------------------------------------------+
95+
| Board ESP32-Wifi-Uno | https://iotmaker.vn/esp32-iot-uno.html |
96+
+-------------------------------+----------------------------------------------------------+
97+
| SSD1306 OLED 128x64 0.96 | https://iotmaker.vn/ssd1306-oled-096inch-128x64-i2c.html |
98+
+-------------------------------+----------------------------------------------------------+
99+
100+
Về phần mềm, để dễ dàng lập trình cho OLED trên android các bạn tải thư viện `SSD1306 <https://github.com/squix78/esp8266-oled-ssd1306/archive/master.zip>`_.
101+
102+
Để thêm thư viện vào arduino các bạn mở Arduino lên và chọn Menu ``Sketch\Inclue Library\Add .Zip Library`` sau đó bạn tìm tới thư mục chứa ``master.zip`` và nhấn ``OK``.
103+
104+
Dưới đây sẽ là một số lệnh cơ bản trong thư viện:
105+
106+
Điều khiển màn hình:
107+
++++++++++++++++++++
108+
109+
Khởi tạo:
110+
111+
.. c:function:: void init()
112+
113+
Giải phóng bộ nhớ đã được sử dụng:
114+
115+
.. c:function:: void (end)
116+
117+
Reset:
118+
119+
.. c:function:: void resetDisplay(void)
120+
121+
Kết nối lại:
122+
123+
.. c:function:: void reconnect(void)
124+
125+
Mở màn hình:
126+
127+
.. c:function:: void displayOn(void)
128+
129+
Tắt màn hình:
130+
131+
.. c:function:: void displayOff(void)
132+
133+
Xóa bộ nhớ đệm:
134+
135+
.. c:function:: void clear(void)
136+
137+
Hiển thị ra màn hình:
138+
139+
.. c:function:: void display(void)
140+
141+
Đặt độ tương phản:
142+
143+
.. c:function:: void setContrast(char contrast)
144+
145+
Đảo chiều màn hình:
146+
147+
.. c:function:: void flipScreenVertically()
148+
149+
Vẽ ảnh pixel:
150+
+++++++++++++
151+
152+
Thiết lập màu sắc (color có thể là ``WHITE`` ``BLACK`` hoặc là ``INVERSE``):
153+
154+
.. c:function:: void setColor(color)
155+
156+
Vẽ một điểm tại vị trí x,y:
157+
158+
.. c:function:: void setPixel(int16_t x, int16_t y)
159+
160+
Vẽ đường thẳng từ điểm 0 tới điểm 1:
161+
162+
.. c:function:: void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1)
163+
164+
Vẽ hình chữ nhật:
165+
166+
.. c:function:: void drawRect(int16_t x, int16_t y, int16_t width, int16_t height)
167+
168+
hoặc
169+
170+
.. c:function:: void fillRect(int16_t x, int16_t y, int16_t width, int16_t height)
171+
172+
Vẽ hình tròn:
173+
174+
.. c:function:: void fillCircle(int16_t x, int16_t y, int16_t radius)
175+
176+
hoặc
177+
178+
.. c:function:: void drawCircle(int16_t x, int16_t y, int16_t radius)
179+
180+
Vẽ đường thẳng theo chiều dọc:
181+
182+
.. c:function:: void drawHorizontalLine(int16_t x, int16_t y, int16_t length)
183+
184+
Vẽ đường thẳng theo chiều ngang:
185+
186+
.. c:function:: void drawVerticalLine(int16_t x, int16_t y, int16_t length)
187+
188+
Viết chữ:
189+
+++++++++
190+
191+
.. c:function:: void drawString(int16_t x, int16_t y, String text)
192+
193+
hoặc
194+
195+
.. c:function:: void drawStringMaxWidth(int16_t x, int16_t y, int16_t maxLineWidth, String text)
196+
197+
Lấy độ dài của một chuỗi:
198+
199+
.. c:function:: uint16_t getStringWidth(const char* text, uint16_t length);
200+
201+
hoặc
202+
203+
.. c:function:: uint16_t getStringWidth(String text)
204+
205+
Chỉnh vị trí của chuỗi (TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH)
206+
207+
.. c:function:: void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment)
208+
209+
Có thể xem thêm về thư viện tại https://github.com/squix78/esp8266-oled-ssd1306
210+
211+
Code Example
212+
++++++++++++
213+
214+
.. code:: cpp
215+
216+
#include <Wire.h>
217+
#include "SSD1306.h>
218+
219+
// Initialize the OLED display using Wire library
220+
SSD1306 display(0x3c, 21, 22);
221+
222+
// Adapted from Adafruit_SSD1306
223+
void drawLines() {
224+
for (int16_t i=0; i<DISPLAY_WIDTH; i+=4) {
225+
display.drawLine(0, 0, i, DISPLAY_HEIGHT-1);
226+
display.display();
227+
delay(10);
228+
}
229+
for (int16_t i=0; i<DISPLAY_HEIGHT; i+=4) {
230+
display.drawLine(0, 0, DISPLAY_WIDTH-1, i);
231+
display.display();
232+
delay(10);
233+
}
234+
delay(250);
235+
236+
display.clear();
237+
for (int16_t i=0; i<DISPLAY_WIDTH; i+=4) {
238+
display.drawLine(0, DISPLAY_HEIGHT-1, i, 0);
239+
display.display();
240+
delay(10);
241+
}
242+
for (int16_t i=DISPLAY_HEIGHT-1; i>=0; i-=4) {
243+
display.drawLine(0, DISPLAY_HEIGHT-1, DISPLAY_WIDTH-1, i);
244+
display.display();
245+
delay(10);
246+
}
247+
delay(250);
248+
249+
display.clear();
250+
for (int16_t i=DISPLAY_WIDTH-1; i>=0; i-=4) {
251+
display.drawLine(DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, i, 0);
252+
display.display();
253+
delay(10);
254+
}
255+
for (int16_t i=DISPLAY_HEIGHT-1; i>=0; i-=4) {
256+
display.drawLine(DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, 0, i);
257+
display.display();
258+
delay(10);
259+
}
260+
delay(250);
261+
display.clear();
262+
for (int16_t i=0; i<DISPLAY_HEIGHT; i+=4) {
263+
display.drawLine(DISPLAY_WIDTH-1, 0, 0, i);
264+
display.display();
265+
delay(10);
266+
}
267+
for (int16_t i=0; i<DISPLAY_WIDTH; i+=4) {
268+
display.drawLine(DISPLAY_WIDTH-1, 0, i, DISPLAY_HEIGHT-1);
269+
display.display();
270+
delay(10);
271+
}
272+
delay(250);
273+
}
274+
275+
// Adapted from Adafruit_SSD1306
276+
void drawRect(void) {
277+
for (int16_t i=0; i<DISPLAY_HEIGHT/2; i+=2) {
278+
display.drawRect(i, i, DISPLAY_WIDTH-2*i, DISPLAY_HEIGHT-2*i);
279+
display.display();
280+
delay(10);
281+
}
282+
}
283+
284+
// Adapted from Adafruit_SSD1306
285+
void fillRect(void) {
286+
uint8_t color = 1;
287+
for (int16_t i=0; i<DISPLAY_HEIGHT/2; i+=3) {
288+
display.setColor((color % 2 == 0) ? BLACK : WHITE); // alternate colors
289+
display.fillRect(i, i, DISPLAY_WIDTH - i*2, DISPLAY_HEIGHT - i*2);
290+
display.display();
291+
delay(10);
292+
color++;
293+
}
294+
// Reset back to WHITE
295+
display.setColor(WHITE);
296+
}
297+
298+
// Adapted from Adafruit_SSD1306
299+
void drawCircle(void) {
300+
for (int16_t i=0; i<DISPLAY_HEIGHT; i+=2) {
301+
display.drawCircle(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, i);
302+
display.display();
303+
delay(10);
304+
}
305+
delay(1000);
306+
display.clear();
307+
308+
// This will draw the part of the circel in quadrant 1
309+
// Quadrants are numberd like this:
310+
// 0010 | 0001
311+
// ------|-----
312+
// 0100 | 1000
313+
//
314+
display.drawCircleQuads(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, DISPLAY_HEIGHT/4, 0b00000001);
315+
display.display();
316+
delay(200);
317+
display.drawCircleQuads(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, DISPLAY_HEIGHT/4, 0b00000011);
318+
display.display();
319+
delay(200);
320+
display.drawCircleQuads(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, DISPLAY_HEIGHT/4, 0b00000111);
321+
display.display();
322+
delay(200);
323+
display.drawCircleQuads(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, DISPLAY_HEIGHT/4, 0b00001111);
324+
display.display();
325+
}
326+
327+
void printBuffer(void) {
328+
// Initialize the log buffer
329+
// allocate memory to store 8 lines of text and 30 chars per line.
330+
display.setLogBuffer(5, 30);
331+
332+
// Some test data
333+
const char* test[] = {
334+
"Hello",
335+
"World" ,
336+
"----",
337+
"Show off",
338+
"how",
339+
"the log buffer",
340+
"is",
341+
"working.",
342+
"Even",
343+
"scrolling is",
344+
"working"
345+
};
346+
347+
for (uint8_t i = 0; i < 11; i++) {
348+
display.clear();
349+
// Print to the screen
350+
display.println(test[i]);
351+
// Draw it to the internal screen buffer
352+
display.drawLogBuffer(0, 0);
353+
// Display it on the screen
354+
display.display();
355+
delay(500);
356+
}
357+
}
358+
359+
void setup() {
360+
display.init();
361+
362+
// display.flipScreenVertically();
363+
364+
display.setContrast(255);
365+
366+
drawLines();
367+
delay(1000);
368+
display.clear();
369+
370+
drawRect();
371+
delay(1000);
372+
display.clear();
373+
374+
fillRect();
375+
delay(1000);
376+
display.clear();
377+
378+
drawCircle();
379+
delay(1000);
380+
display.clear();
381+
382+
printBuffer();
383+
delay(1000);
384+
display.clear();
385+
}
386+
387+
void loop() { }
388+
389+
Các bạn có thể lấy thêm ví dụ trong thư mục ``Example`` trong file ``Zip`` các bạn download vừa rồi.

docs/arduino/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ Cài đặt
77
Cài đặt Arduino IDE<install>
88
Cài đặt thư viện <library>
99
Blink <blink>
10+
I2C/OLED <i2c_oled>

0 commit comments

Comments
 (0)