12 KiB
12 KiB
MCU簡易教學
MCU種類
MCU(Microcontroller Unit),中文名為「微控制器單元」、「單晶片微電腦」。MCU 將中央處理器(CPU)、記憶體(RAM)、輸入 / 輸出介面(I/O)等等一大堆東西,全部整合在「一塊 IC」 上面。可以負責做少量、簡單的資料運算與處理。
實驗室常用的MCU有:
Arduino
ESP32
Raspberry Pi Pico
ESP32
Raspberry Pi Pico
編譯器-Arduino IDE
Arduino與ESP32都可以透過Arduino IDE進行編譯
強烈推薦使用Arduino IDE 版本1.8的
有人使用2.X的版本,過一星期就回歸1.8….
若是要書寫ESP32(https://hackmd.io/@Robert/Hk1rGMsU3)
編譯器-Thonny IDE
ESP32與Pi Pico都可以透過Thonny IDE進行編譯
但編譯前須先燒錄相關韌體
ESP32燒錄
[參考網址](https://chtseng.wordpress.com/2023/01/14/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8thonnymicropython%E6%92%B0%E5%AF%ABesp32-cam%E7%A8%8B%E5%BC%8F/)
目前ESP32執行效率比 Pi Pico高,之後以ESP32為教學
選擇
若以一般實驗室內部進行專案開發,根據需求選擇:
若無網路需求,則以Arduino為主
IOT的需求則建議使用ESP32
控制馬達、接收資料、量測數據,這些基本的擇一使用即可
!!!極度重要!!!
在一般工廠使用,若訊號干擾很強的那種,一律走有線連接
接下來會以控制馬達作為教學
MCU控制
馬達接線圖
MCU控制(WEB)
ESP32寫micropython
import network
import ure
import usocket as socket
import gc
import machine
import time
import utime
from machine import Pin
import uasyncio as asyncio
import urequests
import ujson
led=Pin(2,Pin.OUT)
out_1 = Pin(26,Pin.OUT)
out_2 = Pin(27,Pin.OUT)
wlan = network.WLAN(network.STA_IF)
# 連接WIFI
def connect_to_wifi(ssid, password):
# 固定 IP
ip = '192.168.1.185'
subnet = '255.255.255.0'
gateway = '192.168.1.1'
dns = '8.8.8.8'
wlan.active(True)
wlan.active(False)
wlan.active(True)
wlan.ifconfig((ip, subnet, gateway, dns)) # 設定參數
wlan.connect(ssid, password)
print('Starting to connect to WiFi')
for i in range(20):
print('Trying to connect to WiFi in {}s'.format(i))
utime.sleep(1)
if wlan.isconnected():
break
if wlan.isconnected():
led.value(1)
time.sleep(0.5)
led.value(0)
time.sleep(0.5)
led.value(1)
time.sleep(0.5)
led.value(0)
print('Connected to WiFi:', ssid)
print('WiFi connection successful!')
print('Network configuration:', wlan.ifconfig())
# 馬達一圈
def motor_run(request):
for i in range(0,200):
out_2.value(1)
time.sleep(0.01)
out_2.value(0)
time.sleep(0.01)
return "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n"+"motor run end"
# 馬達1/10圈
def motor_36_run(request):
for i in range(0,20):
out_2.value(1)
time.sleep(0.01)
out_2.value(0)
time.sleep(0.01)
return "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n"+"motor run end"
# 錯誤請求
def handleNotFound(request):
return "HTTP/1.0 404 Not Found\r\nContent-Type: text/plain\r\n\r\n"+"Page not found"
# 主函数
def main():
wifi_ssid ="leo"
wifi_password="00000000"
# 連接WIFI
connect_to_wifi(wifi_ssid, wifi_password)
# 創建網頁API
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 8080))
server_socket.listen(1)
print("Server is listening on port 80...")
out_1.value(0)
while True:
# 斷線重連
if not wlan.isconnected():
print('again')
connect_to_wifi(wifi_ssid, wifi_password)
client_socket, client_addr = server_socket.accept()
print("Received connection from:", client_addr)
request_data = client_socket.recv(1024).decode('utf-8')
if request_data:
if "GET /motor_run" in request_data:
response_data = motor_run(request_data)
elif "GET /motor_36_run" in request_data:
response_data = motor_36_run(request_data)
else:
response_data = handleNotFound(request_data)
client_socket.send(response_data.encode('utf-8'))
client_socket.close()
# 運行主程式
main()
ESP32寫Arduino(WEB)
#include <Wire.h>
#include <WiFi.h>
#include <WebServer.h>
#include <WiFiClient.h>
#include <HTTPClient.h>
int out_1_pin = 26;
int out_2_pin = 27;
const char *ssid = "leo"; // Put your SSID here
const char *password = "00000000";
unsigned long previousMillis =0;
unsigned long interval = 30000;
WebServer server(80);
//WiFi連線
void WifiConnecte() {
//Set your Static IP address
IPAddress local_IP(192, 168,1 , 185);
// Set your Gateway IP address
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("STA Failed to configure");
}
//開始WiFi連線
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi連線成功");
Serial.print("IP Address:");
Serial.println(WiFi.localIP());
}
void handleNotFound() {
//digitalWrite(LED,LOW);//LED
String message = "Server is running!\n\n";
//server.send(200, "text/plain", message);
}
//Web_chaek
void web_check(void){
WiFiClient client = server.client();
String response = "HTTP/1.1 200 OK\r\n";
response += "Content-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n";
server.sendContent(response);
}
void motor_run(){
digitalWrite(out_1_pin, LOW); // 方向
for (int i = 0; i < 200; i++) {
digitalWrite(out_2_pin, HIGH); // 将引脚设置为高电平
delay(10); // 等待10毫秒
digitalWrite(out_2_pin, LOW); // 将引脚设置为低电平
delay(10); // 等待10毫秒
}
WiFiClient client = server.client();
server.send(200, "text/plain","run end");
}
void motor_36_run(){
digitalWrite(out_1_pin, LOW); // 方向
for (int i = 0; i < 20; i++) {
digitalWrite(out_2_pin, HIGH); // 将引脚设置为高电平
delay(10); // 等待10毫秒
digitalWrite(out_2_pin, LOW); // 将引脚设置为低电平
delay(10); // 等待10毫秒
}
WiFiClient client = server.client();
server.send(200, "text/plain","run end");
}
void setup() {
// put your setup code here, to run once:
pinMode(out_1_pin, OUTPUT);
pinMode(out_2_pin, OUTPUT);
Serial.begin(115200);
Serial.println("Hello!");
WifiConnecte();
server.on("/motor_run",HTTP_GET,motor_run);
server.on("/motor_36_run",HTTP_GET,motor_36_run);
server.on("/web_check",HTTP_GET,web_check);
server.onNotFound(handleNotFound);
server.begin();
}
void loop() {
// put your main code here, to run repeatedly:
unsigned long currentMills = millis();
if ((WiFi.status() != WL_CONNECTED)&& (currentMills - previousMillis >= interval)) {
Serial.print(millis());
Serial.print("wifi正在連線中... ");
WiFi.disconnect();//断开连接
WiFi.reconnect();
WifiConnecte();
}
server.handleClient();
}
ESP32(COM)
int out_1_pin = 26;
int out_2_pin = 27;
bool LEDState = HIGH;
void setup() {
// initialize digital pin LED_BUILTIN as an output.
Serial.begin(115200);
pinMode(out_1_pin, OUTPUT);
pinMode(out_2_pin, OUTPUT);
}
void motor_run(){
digitalWrite(out_1_pin, LOW); // 方向
for (int i = 0; i < 200; i++) {
digitalWrite(out_2_pin, HIGH); // 将引脚设置为高电平
delay(10); // 等待10毫秒
digitalWrite(out_2_pin, LOW); // 将引脚设置为低电平
delay(10); // 等待10毫秒
}
}
void motor_36_run(){
digitalWrite(out_1_pin, LOW); // 方向
for (int i = 0; i < 20; i++) {
digitalWrite(out_2_pin, HIGH); // 将引脚设置为高电平
delay(10); // 等待10毫秒
digitalWrite(out_2_pin, LOW); // 将引脚设置为低电平
delay(10); // 等待10毫秒
}
}
// the loop function runs over and over again forever
void loop() {
if (Serial.available() > 0) { // 检查是否有可用的串行数据
char receivedData[64]; // 用于存储接收到的数据
int dataSize = Serial.readBytesUntil('\n', receivedData, sizeof(receivedData)); // 读取串行数据直到遇到换行符为止
receivedData[dataSize] = '\0'; // 添加字符串结束符
Serial.print("Received: "); // 打印接收到的消息
Serial.println(receivedData); // 打印接收到的数据
if(strcmp(receivedData, "move_all") == 0) {
motor_run();
Serial.println("run_all"); // 打印接收到的数据
}
if(strcmp(receivedData, "move_36") == 0) {
motor_36_run();
Serial.println("run_36"); // 打印接收到的数据
}
}
delay(10);
}
Arduino(COM)
bool LEDState = HIGH;
void setup() {
// initialize digital pin LED_BUILTIN as an output.
Serial.begin(115200);
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
digitalWrite(12, HIGH);
}
void motor_run(){
digitalWrite(12, LOW); // 方向
for (int i = 0; i < 200; i++) {
digitalWrite(13, HIGH); // 将引脚设置为高电平
delay(10); // 等待10毫秒
digitalWrite(13, LOW); // 将引脚设置为低电平
delay(10); // 等待10毫秒
}
}
void motor_36_run(){
digitalWrite(12, LOW); // 方向
for (int i = 0; i < 20; i++) {
digitalWrite(13, HIGH); // 将引脚设置为高电平
delay(10); // 等待10毫秒
digitalWrite(13, LOW); // 将引脚设置为低电平
delay(10); // 等待10毫秒
}
}
// the loop function runs over and over again forever
void loop() {
if (Serial.available() > 0) { // 检查是否有可用的串行数据
char receivedData[64]; // 用于存储接收到的数据
int dataSize = Serial.readBytesUntil('\n', receivedData, sizeof(receivedData)); // 读取串行数据直到遇到换行符为止
receivedData[dataSize] = '\0'; // 添加字符串结束符
Serial.print("Received: "); // 打印接收到的消息
Serial.println(receivedData); // 打印接收到的数据
if(strcmp(receivedData, "move_all") == 0) {
motor_run();
Serial.println("run_all"); // 打印接收到的数据
}
if(strcmp(receivedData, "move_36") == 0) {
motor_36_run();
Serial.println("run_36"); // 打印接收到的数据
}
}
delay(10);
}
影片如下
http://140.125.21.65:8418/Education/MCU/raw/branch/master/PPT/%E5%AA%92%E9%AB%942.mp4