Thứ Bảy, 20 tháng 8, 2022

Đọc cảm biến siêu âm Ultrasonic HC SR04 SR05 đo khoảng cách bằng MicroPython (ESP8266, ESP32, Raspberry Pi Pico)

 Đôi khi một số dự án viết bằng Micropython, bạn cần đo khoảng cách bằng module cảm biến HC-SR04 hoặc HC-SR05.

Bài viết này, hướng dẫn bạn cách làm điều đó (đã test thử trên ESP8266, ESP32 và Pico)


Kết nối các chân của HC-SR04: VCC -> 5V, GND ->GND. Còn chân trig và echo thì tùy vào loại board bạn chọn (xem trong code).

Bạn có thể copy code sau đây để test thử

Thứ Bảy, 13 tháng 8, 2022

Đọc module cảm biến nhiệt độ, áp suất BMP280 bằng Micropython với Raspberry Pi Pico

Module cảm biến BMP280 giá rẻ có thể dùng để đo nhiệt độ, áp suất khí quyển. Trong phần này chúng ta đi đọc các thông tin này bằng Raspberry Pi Pico với MicroPython.

Bước 1: Đầu tiên chúng ta nối sơ đồ như sau:

Sơ đồ kết nối



Module cảm biến BMP280


Bước 2: Tải thư viện này về và lưu vào bộ nhớ của Pico với tên là bmp280.py

Thứ Sáu, 22 tháng 7, 2022

[MicroPython] Điều khiển đèn LED qua mạng websever với ESP8266

 Trong Module NodeMCU con ESP8266 chíp nạp CP có xây dựng sẵn 2 đèn LED. Một con được kết nối với chân GPIO2 và con LED kia kết nối với chân GPIO16.

Đặc điểm là cực Anode(+) của con LED kết nối với cực dương của nguồn điện, cực còn lại Cathode kết nối với chân GPIO, nên khi chân bật mức HIGH thì LED tắt còn, mức LOW thì LED sáng.



Trong bài hướng dẫn này, chúng ta sẽ đi điều khiển con 2 con LED này qua mạng bằng cách sử dụng Websever bằng cách kết nối Wifi mạng nội bộ.

Thứ Hai, 18 tháng 7, 2022

Đo nhiệt độ bằng cảm biến tích hợp trên Raspberry Pi Pico

 Trong con vi điều khiển RP2040 của Raspberry Pico có tích hợp sẵn một cảm biến đo nhiệt độ. Cảm biến này được kết nối với chân ADC4 (Analog Digital Convert).

Độ phân giải của các chân ADC trên RP2040 là 12 bit (tức 2^12=4096), được đo từ 0 đến 4095. Nhưng trong MicroPython thì được quy về 16 bit (2^16=65536) được đếm từ 0 đến 65535.




Theo tài liệu chính hãng Raspberry công bố, thì ở nhiệt độ chuẩn 27 độ C, chân ADC4 cho ra mức ra 0.706V và độ thay đổi nhiệt độ so với chuẩn 27 độ là 0.001721V / độ.

Do đó, để đo nhiệt độ từ cảm biến này, đầu tiên ta phải đọc mức điện áp của chân ADC4 rồi chia 65535 sau đó nhân với 3.3V

import machine
import time

camBienNhietDo = machine.ADC(4)
heSoChuyenDoi = 3.3/65535

while True:
    docSoMiliVolt = camBienNhietDo.read_u16() * heSoChuyenDoi
    nhietDoHienTai = 27 + (0.706 - docSoMiliVolt)/0.001721
    print(nhietDoHienTai)
    time.sleep(1)


3 cách nháy một đèn Led có sẵn với Raspberry Pi Pico bằng MicroPython

 Bo mạch Raspberry Pi Pico có một đèn LED xây dựng sẵn, đèn LED này kết nối với chân GP25. Vì thế, khi mới làm quen với lập trình chúng ta có thể điều khiển nhấp náy đèn LED này để hiểu hơn về viết code.



Dưới đây chúng ta sẽ tìm hiểu 3 cách nháy một đèn LED với Raspberry Pi Pico

Chủ Nhật, 3 tháng 7, 2022

Tài liệu học lập trình C++ căn bản Song ngữ Anh - Việt

 Tài liệu học lập trình C++ căn bản Song ngữ Anh Việt

Được soạn tham khảo từ nguồn W3School.

Được chia thành các buổi cho dễ học. Mỗi buổi lý thuyết cần 1 đến 2 buổi để thực hành.


  
Tải file pdf về tại đây:
https://drive.google.com/file/d/1u8-DnB3vAx7BtJNbArVbfQG1dQoxtK7H/view?usp=sharing
 
 

Thứ Bảy, 29 tháng 1, 2022

Kết nối màn hình LCD 162 LCM1602A-14 DS-162-3V3-SPI2C V6 với ESP8266 ESP32 bằng I2C trên Micropython

 Màn hình LCM1602A-14 DS-162-3V3-SPI2C V6 có ưu điểm là có cả 2 giao thức I2C và SPI, đồng thời dùng điện áp 3.3V, phù hợp cho ESP8266 / ESP32 hoặc Pico.



Kết nối VSS -> GND, VDD ->3.3V 
ESP8266:sda=12(D6), scl=14(D5)hoặc sda=12(D6), scl=13(D7)
ESP32GPIO21(SDA), GPIO22(SCL)
 

Bài này, hướng dẫn kết nối màn hình với ESP8266 và ESP32

Bước 1: Tải thư viện về máy và lưu vào ESP8266 / ESP32 với tên LCD_I2C.py

# Use lib for ESP8266 and ESP32 with LCD both I2C and SPI model LCM1602A-14 DS-162-3V3-SPI2C V6

import machine

import utime



COLUMNS = 16

ROWS    = 2



#Instruction set

CLEARDISPLAY         = 0x01



ENTRYMODESET         = 0x04

ENTRYLEFT            = 0x02

ENTRYRIGHT           = 0x00

ENTRYSHIFTINCREMENT  = 0x01

ENTRYSHIFTDECREMENT  = 0x00



DISPLAYCONTROL       = 0x08

DISPLAYON            = 0x04

DISPLAYOFF           = 0x00

CURSORON             = 0x02

CURSOROFF            = 0x00

BLINKON              = 0x01

BLINKOFF             = 0x00



FUNCTIONSET          = 0x20

_5x10DOTS            = 0x04

_5x8DOTS             = 0x00

_1LINE               = 0x00

_2LINE               = 0x08

_8BITMODE            = 0x10

_4BITMODE            = 0x00



class LCD:

    def __init__(self, sda, scl):

       

        self.column = 0

        self.row = 0

       

        self.address = 62 #0x3e

       

        self.command = bytearray(2)



        _sda = machine.Pin(sda)

        _scl = machine.Pin(scl)

       

        if (sda==12 and scl==13) or (sda==12 and scl==14) :

            self.i2c=machine.I2C(sda=_sda, scl=_scl, freq=400000)

        else:

            self.i2c=machine.SoftI2C(sda=_sda, scl=_scl, freq=400000)

       

        utime.sleep_ms(50)

       

        for i in range(3):

            self._command(FUNCTIONSET | _2LINE )

            utime.sleep_ms(10)

       

        self.on()

        self.clear()

       

        self._command(ENTRYMODESET | ENTRYLEFT | ENTRYSHIFTDECREMENT)

       

        self.set_cursor(0, 0)

       

    def on(self, cursor=False, blink=False):

        if cursor == False and blink == False:

            self._command(DISPLAYCONTROL | DISPLAYON | CURSOROFF | BLINKOFF)

        elif cursor == False and blink == True:

            self._command(DISPLAYCONTROL | DISPLAYON | CURSOROFF | BLINKON)

        elif cursor == True and blink == False:

            self._command(DISPLAYCONTROL | DISPLAYON | CURSORON | BLINKOFF)

        elif cursor == True and blink == True:

            self._command(DISPLAYCONTROL | DISPLAYON | CURSORON | BLINKON)        

   

    def off(self):

        self._command(DISPLAYCONTROL | DISPLAYOFF | CURSOROFF | BLINKOFF)

       

    def clear(self):

        self._command(CLEARDISPLAY)

        self.set_cursor(0, 0)

   

   

    def set_cursor(self, column, row):

        column = column % COLUMNS

        row = row % ROWS

        if row == 0:

            command = column | 0x80

        else:

            command = column | 0xC0

        self.row = row

        self.column = column

        self._command(command)

   

    def write(self, s):

        for i in range(len(s)):

            utime.sleep_ms(10)

            self.i2c.writeto(self.address, b'\x40'+s[i])

            self.column = self.column + 1

            if self.column >= COLUMNS:

                self.set_cursor(0, self.row+1)

       

    def _command(self, value):

        self.command[0] = 0x80

        self.command[1] = value

        self.i2c.writeto(self.address, self.command)

        utime.sleep_ms(1)


Bước 2: Tải file Code này về và test thử

# /*******************************************************************************

#  * Sử dụng màn hình LCD loại LCM1602A-14 DS-162-3V3-SPI2C V6 (adress: 0x3e = 62)có cả giao thức I2C và SPI Trên ESP8266

#  ********************************************************************************

#  * Connect ESP8266:

#  * option1: sda=12(D6), scl=14(D5)

#  * option2: sda=12(D6), scl=13(D7)

#  *

#  * Connect ESP32

#  * The ESP32 has two I2C channels and any pin can be set as SDA or SCL. When using the ESP32 with the Arduino IDE, the default I2C pins are

#  * GPIO21(SDA), GPIO22(SCL)

#  *******************************************************************************/



from LCD_I2C import *    #import LCD_I2C library

from machine import Pin

from time import sleep

led2 = Pin(2, Pin.OUT);



#ESP8266

lcd = LCD(sda=12, scl=14)



#ESP32

#lcd = LCD(sda=21, scl=22)



lcd.set_cursor(0,0)          # Set the cursor at first column, first row

lcd.write("Hello World")     # Write string to the LCD  

sleep(1)               # Delay for 1 second



lcd.off()                    # Off the lcd display without clearing the data

sleep(1)



lcd.on()                     # On LCD display without cursor and blink - cursor=False, blink=False - by default

sleep(1)



lcd.clear()

lcd.on(cursor=False, blink=True) # On LCD display without cursor and with blink

lcd.write("Without cursor and with blink")

sleep(3)



lcd.clear()

lcd.on(cursor=True, blink=False) # On LCD display with cursor and without blink

lcd.write("With cursor and without blink")

sleep(3)



lcd.clear()

lcd.on(cursor=True, blink=True)  # On LCD display with cursor and with blink

lcd.write("With cursor and blink")

sleep(3)



lcd.on(cursor = False, blink = False)

lcd.clear()

lcd.set_cursor(0,0)

lcd.write("Temp:")

lcd.write("30")

lcd.set_cursor(0,1)

lcd.write("RH:")

lcd.write("89%")

sleep(3)



lcd.clear()                 # Clear the data in display

i = 0



while True:

    while (i < 20):

        lcd.set_cursor(6,0) #Colum 6 and rows first

        lcd.write(str(i*1000))

        utime.sleep(0.1)

        i = i + 1

        lcd.clear()

   

    if (led2.value()==0):

        led2.value(1)

        lcd.clear()

        lcd.write("Led is: OFF")

        print("Led is: OFF")

    else:

        led2.value(0)

        lcd.clear()

        lcd.write("Led is: ON ")

        print("Led is: ON")

    sleep(1)


Scan địa chỉ của các thiết bị i2c trên Raspberry Pi Pico bằng Micropython

Thỉnh thoảng khi gắn các thiết bị giao thức i2c vào Raspberry Pi Pico mà bạn không biết địa chỉ của nó. Bài viết này sẽ hướng dẫn bạn lấy địa chỉ đó.

Bài viết được thực hiện trên ngôn ngữ Micropython và RP Pico.

#Scan địa chỉ các thiết bị i2c kết nối với Raspberry Pi Pico

#Raspberry pico hỗ trợ tối đa 2 kênh i2c

#Mặc định thì thiết bị giao tiếp qua GPIO8(SDA) chân thứ 11 và GPIO9(SCL) chân thứ 12

#Có thể sử dụng nhanh i2c=I2C(0), khi đó mặc định hiểu là SCL=Pin(9), SDA=Pin(8), freq=400000

#  * Connect ESP8266:

#  * option1: sda=12(D6), scl=14(D5)

#  * option2: sda=12(D6), scl=13(D7)

#  * Connect ESP32

#  * The ESP32 has two I2C channels and any pin can be set as SDA or SCL. When using the ESP32 with the Arduino IDE, the default I2C pins are

#  * GPIO21(SDA), GPIO22(SCL)


from machine import Pin, I2C

from time import sleep



i2c = I2C(0, scl = Pin(1), sda = Pin(0), freq = 100_000) #freq tần số không bắt buộc



print("Đang scan i2c bus...");

devices = i2c.scan()

sleep(1)



if len(devices) == 0 :

    print("Không có thiết bị i2c được tìm thấy !")

else:

    print("Thiết bị i2c tìm được: ", len(devices))

   

    for element in devices:

        print("Địa chỉ theo số thập phân: ", element, " | Địa chỉ Hex (thập lục phân): ", hex(element))

Thứ Sáu, 28 tháng 1, 2022

Điều khiển đèn Led built_in của ESP8266 thông qua dòng lệnh nhập từ của sổ Serial Monitor.

  

 Điều khiển đèn Led built_in của ESP8266 thông qua dòng lệnh nhập từ của sổ Serial Monitor

void setup() {

  Serial.begin(115200);

  pinMode(2, OUTPUT);

  pinMode(16, OUTPUT);

}

char endChar = '\n';

char chrTemp;

String strTemp="";

bool endChar_ok = false;

String strLenhDaNhan ="";

bool ledState = 0;

unsigned long currentTime, previousTime=0;



void loop() {

  while(Serial.available()>0 && endChar_ok == false){

    chrTemp = Serial.read();

    if(chrTemp == endChar){

      endChar_ok = true;

    } else{

      strTemp = strTemp+String(chrTemp);

      endChar_ok = false;

    }

  }

  if(endChar_ok == true){

    strLenhDaNhan = strTemp;

    Serial.println("#"+strTemp+"@");

    strTemp="";

    endChar_ok = false;

  }

  if(strLenhDaNhan == "Mở đèn led 2") digitalWrite(2, LOW);

  if(strLenhDaNhan == "Tắt đèn led 2") digitalWrite(2, HIGH);

  if(strLenhDaNhan == "Mở đèn led 16") digitalWrite(16, LOW);

  if(strLenhDaNhan == "Tắt đèn led 16") digitalWrite(16, HIGH);

  if(strLenhDaNhan == "Mở cả hai đèn led"){

    digitalWrite(2, LOW);

    digitalWrite(16, LOW);

  }

  if(strLenhDaNhan == "Tắt cả hai đèn led"){

    digitalWrite(2, HIGH);

    digitalWrite(16, HIGH);

  }  

  if(strLenhDaNhan == "Nháy đa hài"){

    currentTime = millis();

    digitalWrite(2, ! ledState);

    digitalWrite(16, ledState);

    if((currentTime - previousTime) > 500){

      ledState = ! ledState;

      previousTime = currentTime;

    }

  }

}