Micropython với I2C SPI UART

Micropython, micropython, ôi làm xong serie này chắc ám ảnh micropython luôn quá anh em, bài cuối rồi nhé, hết bài này là không còn được nghiên cứu micropython nữa đâu.

Quay lại lúc bắt đầu, series này gồm 4 bài đã cho ra mắt và đây là bài chốt hạ, anh em nếu lỡ bỏ sót thì có thể quay lại để xem tại post Micropython cơ bản dưới đây

Học Micropython cơ bản | Học ARM
Hello anh em, lại là mình đây, sau khi hoàn thành serie micropython thì đây sẽ là bài tổng hợp của mình tóm gọn nhẹ nhàng tình cảm lại cho anh em có thể theo dõi. Micropython về cơ bản là dễ, dễ hiểu dễ đọc, dễ làm, nhanh gọn lẹ và có thể nói là giống mì ăn liền như Arduino. Tùy mỗi người một mục đ…

Giờ thì mình quay lại với sơ đồ huyền thoại thôi. Sau đó là đi giải quyết từng thành viên còn sót lại

UART

Với UART của micropython bạn có thể tham khảo class UART ở link sau

Trong phần này thì mình dùng Arduino board làm UART source, và NodeMCU sẽ read message từ UART

Kết nối

Bạn có thể kết nối Arduino board và NodeMCU ESP8266 theo sơ đồ bảng sau

Chân Arduino NodeMCU
Chân 10 (RX) D10 (TXD0)
Chân 11 (TX) D9 (D1)
Chân GND GND

Chương trình

Đầu tiên là chương trình Arduino, tôi sẽ viết chương trình dùng SoftwareSerial để gửi nhận thông qua chân 10 và 11. Chương trình này sẽ ngồi đợi tín hiệu data UART từ NodeMCU tới

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
void setup()
{
  Serial.begin(9600);
  mySerial.begin(9600);
}
void loop()
{
  if (mySerial.available() > 0) {
    Serial.write(mySerial.read());
  }
}

Giờ bạn có thể upload nó xuống arduino nhưng hãy đảm bảo trằng các chân sau (digital 0, 1, 10, và 11 pin) không có kết nối tới board nào khác

Tiếp theo là chương trình cho NodeMCU, tạo một file uart.py như sau

from machine import UART
import time

def run():
    print('test UART')
    uart = UART(0, baudrate=9600)
    counter = 50
    while 1:
        uart.write(str(counter) + '\r\n')
        time.sleep(2)
        counter += 1
        if counter > 70:
            counter = 50

Kết quả

Giờ thì bạn có thể chạy Micropython thông qua WebREPL.

>>> import uart  
>>> uart.run()
test UART

Sau khi xong bạn có thể thấy output trên Serial Monitor của Arduino IDE với baud 9600 sẽ có dạng như sau

51
52
53
54
55
56
57
58
59
60

SPI

Vậy là xong bài UART rồi, giờ chuyển sang SPI thử nghiệm thôi anh em, bạn có thể dùng tất cả các pin cho SPI, để có thể giao tiếp SPI thì ta phải dùng thư viện của nó, anh em có thể tham khảo class SPI của micropython tại đây.

Trong phần này mình sẽ tiếp tục sử dụng Arduino Uno để giao tiếp với NodeMCU ESP8266 qua Micropython

Kết nối

Chúng ta kết nối theo sơ đồ bảng sau

Chân Arduino NodeMCU
Chân 11 (MOSI) D2 (GPIO4)
Chân 12 (MISO) D3 (GPIO0)
Chân 13 (SCK) D1 (GPIO5)
GND GND

Chương trình

Chương trình cho arduino Uno

#include <SPI.h>
char buf;
volatile byte pos;
volatile boolean isAvailable;
void setup() {
  Serial.begin (9600); // for debugging
  // SPI slave mode
  SPCR |= bit (SPE);
  SPCR |= _BV(SPIE);
  isAvailable = false;
  pos = 0;
  pinMode(MISO, OUTPUT);
  SPI.attachInterrupt();
}
ISR(SPI_STC_vect)
{
  byte c = SPDR;
  if (c > 64 && c < 91) {
    buf = c;
    isAvailable = true;
  }
}
void loop() {
  if (isAvailable) {
    Serial.println (buf);
    isAvailable = false;
  }
}

Chương trình python

from machine import Pin, SPI
import time


def run():
    print('test spi')
    gpio_sck = Pin(5)
    gpio_mosi = Pin(4)
    gpio_miso = Pin(0)

    spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=gpio_sck, mosi=gpio_mosi, miso=gpio_miso)
    val = 65
    while 1:
        spi.write(chr(val))     # write 1 byte to spi
        print('write spi: ' + str(val))

        time.sleep(2)
        val += 1
        if val > 90:
            val = 65

Kết quả

Sau khi bạn chạy micropython thông qua WebREPL thì sẽ có kết quả như sau

>>> import spi
>>> spi.run()
test spi
write spi: 65
write spi: 66
write spi: 67
write spi: 68
write spi: 69
write spi: 70

bạn sẽ thấy dữ liệu được gửi lên từ SPI của Arduino Uno

I2C

Với giao tiếp I2C thông qua 2 chân  SDA (Serial Data Line) và SCL (Serial Clock Line). Trong phần này mình sẽ dùng module AD/DA PCF8591 để giao tiếp với NodeMCU
MicroPython hỗ trợ I2C software cho tất cả các chân và bạn có thể tham khảo sử dụng nó thông qua class I2C tại đây

Kết nối

Bạn có thể kết nối theo bảng sau

Chân PCF8591 NodeMCU
SDA D1
SCL D2
VCC VCC
GND GND

Chương trình

from machine import Pin, I2C
import time


def run():
    print('read sensor from i2c protocol')
    PCF8591 = 0x48          # I2C bus address
    PCF8591_ADC_CH0 = '\x00'  # thermistor
    PCF8591_ADC_CH1 = '\x01'  # photo-voltaic cell
    PCF8591_ADC_CH3 = '\x03'  # potentiometer

    # construct an I2C bus
    gpio_scl = Pin(5)
    gpio_sda = Pin(4)
    i2c = I2C(scl=gpio_scl, sda=gpio_sda, freq=100000)

    while 1:
        # read thermistor
        i2c.writeto(PCF8591, PCF8591_ADC_CH0)
        i2c.readfrom(PCF8591, 1)
        data = i2c.readfrom(PCF8591, 1)
        print('Thermistor: ' + str(ord(chr(data[0]))))

        # photo-voltaic cell
        i2c.writeto(PCF8591, PCF8591_ADC_CH1)
        i2c.readfrom(PCF8591, 1)
        data = i2c.readfrom(PCF8591, 1)
        print('photo-voltaic: ' + str(ord(chr(data[0]))))

        # potentiometer
        i2c.writeto(PCF8591, PCF8591_ADC_CH3)
        i2c.readfrom(PCF8591, 1)
        data = i2c.readfrom(PCF8591, 1)
        print('potentiometer: ' + str(ord(chr(data[0]))))

        time.sleep(2)

Kết quả

Giờ thì dùng WebREPL load script mới ở trên xuống board và xem kết quả thôi

>>> import i2c  
>>> i2c.run()
read sensor from i2c protocol
Thermistor: 108
photo-voltaic: 171
potentiometer: 78
Thermistor: 108
photo-voltaic: 171
potentiometer: 79
Thermistor: 108
photo-voltaic: 116
potentiometer: 79
Thermistor: 108
photo-voltaic: 118
potentiometer: 78

Kết

Thế là xong full bộ điều khiển giao tiếp với UART/SPI/I2C rồi, giờ anh em có thể dựa trên đó tự làm các ứng dụng mà mình ưa thích thôi.

Hết rồi nhé ae, kết thúc series, hẹn gặp lại ae ở 1 series mới.