00 一些概念

  • CH340 驱动 。用于USB转串口的CH340芯片支持的平台驱动齐全,支持 Windows/Linux/Android/MacOS/WinCE 等操作系统。(通常副厂的Auduino UNO使用CH340芯片,电脑里可能没有这个驱动)

01 说明

02 点灯

  • setup(): 这个函数是开始的时候运行一次
  • loop():这个函数是执行函数,会不断循环工作
  • pinMode(pin,mode): 将数字10口指定为输入或输出
  • digitalwrite(pin,value): 将数字10口输出高电平或低电平
  • delay(ms):暂停执行多少毫秒
  • 在英文输入状态时,; 分号是作为结束符用
  • 在英文输入状态时,//是用作单行注释

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// C++ code
//
void setup()
{
pinMode(2, OUTPUT); //将2号引脚设置为输出模式
}

void loop()
{
digitalWrite(2, HIGH);//2号引脚输出高电位
delay(1000); // 等待一秒。在循环中,防止运行卡死,可delay(1);
digitalWrite(2, LOW);//2号引脚输出低电位
delay(1000);
}

03 HelloWorld

  • Serial:串口通信,即两个设备之间通过串口连接,通过串口发送数据,实现数据传输。
  • 波特率:单片机或计算机在串口通信时的速率,即每秒发送或接收的字节数。一定要保持通信设备的波特率一直,不然无法通信
  • Serial.begin(baudrate);:设置波特率baudrate,9600为默认值,115200为最大值。
  • Serial.read():读取串口数据并返回。
    • Serial.read() == ‘a’ 判断串口输入是否为a
  • Serial.println();从串行端口输出字符串,并换行
  • if(表达式){语句} if 表达式为真,执行语句

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// C++ code
//
void setup()
{
pinMode(11 , OUTPUT);//将11号引脚设置为输出模式
Serial.begin(9600);//将波特率设置为9600
}

void loop()
{
if(Serial.read() == 'c'){ //如果串行监视器读取到a
digitalWrite(11, HIGH);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(11, LOW);
delay(1000); // Wait for 1000 millisecond(s)
Serial.println("HelloWorld"); //在串行监视器输出HelloWorld
}
delay(1);
}

04 数字I/O口的外部电路(输入与输出)

  • 0 ~ 13口是arduino数字I/O的输入和输出
  • 0、1 一般作为串口通信使用,不接其他设备
  • digitalRead() 读取引脚电平,返回高低 HIGH、LOW
  • 输入端接法:利用电阻两端的电位差作为输入信号
  • 输出端:单片机的负载能力有限,利用好限流电阻和隔离

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// C++ code
//
void setup()
{
Serial.begin(9600);//将波特率设置为9600
pinMode(7, OUTPUT);//7号引脚设置为输出
pinMode(2, INPUT);//2号引脚设置为输入
}

void loop()
{
if(digitalRead(2) == HIGH){ //读取2号引脚电位并判断是否为高电位
digitalWrite(7 , HIGH); //7号引脚上的LED点亮
Serial.println("2号引脚高电位");
}
else{
digitalWrite(7,LOW);
}
delay(1);
}

05 变量与按钮防抖

  • 全局变量:整个程序都有效的变量
  • 局部变量:会在其所属的函数或者循环结束后消亡
  • if() 函数里面可以嵌套多层函数
  • = 号,代表赋值
  • == 号,代表比较

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int x=0
int pin1=0;
int pin2=0;
void setup(){
pinMode(2, INTPUT);
pinMode(7, OUTPUT);
}

void loop(){
pin1 = digitalRead(2);
if(pin1==1 and pin2==0){
delay(1); //起到防抖作用
x==0?x=1:x=0;
}
pin2 = pin1;
delay(1);//起到防抖作用
if(x==1){
digitalWrite(7, HIGH);
}else{
digitalWrite(7, LOW);
}
}

06 模拟输入与输出

  • A0 ~ A5 是arduino模拟输入的引脚
  • 3、5、6、9、10、11是arduino模拟输出的引脚
  • arduino模拟输入时感应电位器的电压在05V之间,模拟输出时输出的电压在05V之间
  • analogRead(pin):读取模拟输入引脚pin的电位,返回0-1023
  • analogWrite(pin,value):将模拟值(PWM波)输出到引脚,PWM的信号频率约为490赫兹。value范围0-255,对应的电压0-5V
  • map函数(看注释)

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// C++ code
//
// 读取、写入都是芯片在进行的操作。
// 即“芯片读取引脚的数值、芯片向引脚设置(写入)数值。
int moni=0; //设置全局变量,记录模拟信号
int light=0;
void setup()
{
Serial.begin(9600);//设置波特率
pinMode(3, OUTPUT);
}

void loop()
{
moni=analogRead(0);//读取模拟信号 A0脚的值
Serial.println(moni);
delay(30);
light=map(moni,0,1023,0,255);
/**
模拟输入返回的是0到1023的值,即moni的范围
模拟输出的函数analogWrite(pin,value)的参数value范围(0,255)
因此使用map()函数来对等转换。
map(value,fromeLow,fromHigh,toLow,toHigh)

*/
analogWrite(3,light);
delay(1);
}

07 呼吸灯

  • for(初始表达式;条件表达式;递增表达式){ 循环体; }

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// C++ code
//
int y = 0;
int x = 0;
void setup() {
pinMode(3, OUTPUT);
Serial.begin(9600);
}

void loop() {
y = analogRead(0);
x = map(y, 0, 1023, 1, 20);
for (int i = 0; i <= 255; i++) {
analogWrite(3, i);
Serial.println(x);
delay(x);
}
for (int i = 255; i >= 0; i--) {
analogWrite(3, i);
delay(x);
}
}

08 子函数(自定义函数)

  • void method(参数){函数体}
  • void 代表函数不返回任何值
  • method表示函数名
  • 参数:函数的输入参数,可以有多个,用逗号隔开

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// C++ code
//
int y = 0;
int x = 0;
void huxideng(int m, int n) {
analogWrite(3, m);
delay(n);
}
void setup() {
pinMode(3, OUTPUT);
}
void loop() {
y = analogRead(0);
x = map(y, 0, 1023, 0, 9);

for (int i = 0; i < 255; i++) {
huxideng(i, x);
}
for (int i = 255; i > 0; i--) {
huxideng(i, x);
}
}

09 自定义PWM信号

  • PWM:Pulse Width Modulation,脉冲宽度调制。即占空比控制,即控制输出的信号的宽度。
  • Arduino UNO板数字信号侧有 ~符号,表示这些引脚可以输出PWM信号。即3、5、6、9、10、11脚
  • 此例使用2号引脚“模拟”PWM。
  • delayMicroseconds(),暂停微妙,,即百万分之一秒
  • unsigned long 代表无符号长整型,即无符号的64位整数
  • millis(),返回晶片从开始运行到目前所经过的毫秒数 ms。该参数溢出大概需要50天

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//
/*
void setup() {
pinMode(2, OUTPUT);
Serial.begin(9600);
}

void loop() {
unsigned long t1 = 0;
unsigned long t2 = 0;
t1 = millis();
// 先遍历一个较大的数A,得到遍历所使用的时间t2,最后A/t2 得到该芯片的近似频率
// 27117Hz
// delayMicroseconds 控制高低电平持续时间
for (unsigned long i = 0; i < 27117; i++) {
digitalWrite(2, HIGH);
delayMicroseconds(1);
digitalWrite(2, LOW);
delayMicroseconds(1);
}
t2 = millis() - t1;
Serial.println(t2);
while (1) {
delay(1);
}
}
*-------------------------------------------------**/

void PWM(int m) {
digitalWrite(2, HIGH);
delayMicroseconds(m);
digitalWrite(2, LOW);
delayMicroseconds(1023 - m);
}

void setup() {
pinMode(2, OUTPUT);
}

void loop() {
PWM(analogRead(0));
}

10 光控灯

  • 模拟量与数字量。光敏电阻反馈的是模拟量,按钮开关反馈的是数字量

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int y = 0;
void setup() {
pinMode(12, OUTPUT);
Serial.begin(9600);
}
void loop() {
y = analogRead(0);
Serial.println(y);
if (y > 100) {
digitalWrite(12, 1);
} else {
digitalWrite(12, 0);
}
delay(1);
}

11 舵机(调用库文件)

  • 舵机是可以控制的电机,即伺服电机“青春版”。通电时不可手动转动。
  • 在上传代码时,需先断开舵机连接
  • attach(pin):将引脚连接到舵机,pin为舵机引脚(仅9、10口)
  • detach():断开舵机引脚连接。该接口可继续被用作PWM接口
  • attached():判断舵机引脚是否连接
  • write(angle):将舵机转到指定角度,角度为0-180,0为舵机中线,正负为舵机正负转
  • read():读取舵机当前的角度,返回值为0-180,0为舵机中线,正负为舵机正负转
  • 循环中需考虑舵机转动时间

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <Servo.h>

Servo duoji;
void setup() {
duoji.attach(9);
}
void loop() {
for (int i = 0; i <= 180; i++) {
duoji.write(i);
delay(10);
}
delay(1000);

for (int i = 180; i >= 0; i--) {
duoji.write(i);
delay(10);
}
delay(1000);
}

12 舵机自定义输出引脚

  • 使用PWM方式控制舵机,实现类似调用库的效果

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int pin = 2;
int jiaodu;
int PWM;
int dwp;
void duoji(int pin, int jiaodu) {
PWM = (jiaodu * 11) + 500; //将角度转换为500-2480的脉宽值
digitalWrite(pin, HIGH);
delayMicroseconds(PWM);
digitalWrite(pin, LOW);
delayMicroseconds(20000 - PWM);
}

void setup() {
pinMode(pin, OUTPUT);
}
void loop() {
dwp = map(analogRead(A0), 0, 1023, 0, 180); //电位器控制舵机角度
duoji(pin, dwp);
delay(10);
}

13 步进电机的接线与驱动

(Tinkercad无类似步进电机进行模拟)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
int a1 = 2;
int b1 = 3;
int c1 = 4;
int d1 = 5;
int sudu = 5;

void setup() {
pinMode(a1, OUTPUT);
pinMode(b1, OUTPUT);
pinMode(c1, OUTPUT);
pinMode(d1, OUTPUT);
}
void loop() {
pin_a1();
delay(sudu);
pin_b1();
delay(sudu);
pin_c1();
delay(sudu);
pin_d1();
delay(sudu);
}
void pin_a1() {
digitalWrite(a1, HIGH);
digitalWrite(b1, LOW);
digitalWrite(c1, LOW);
digitalWrite(d1, LOW);
}
void pin_b1() {
digitalWrite(a1, LOW);
digitalWrite(b1, HIGH);
digitalWrite(c1, LOW);
digitalWrite(d1, LOW);
}
void pin_c1() {
digitalWrite(a1, LOW);
digitalWrite(b1, LOW);
digitalWrite(c1, HIGH);
digitalWrite(d1, LOW);
}
void pin_d1() {
digitalWrite(a1, LOW);
digitalWrite(b1, LOW);
digitalWrite(c1, LOW);
digitalWrite(d1, HIGH);
}

14 红外遥控

  • 需先安装库文件。在IDE中搜索:IRremote。暂用2.0.1版本,最新4.4.1

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <IRremote.h>

int hwx = 8;
int deng = 2;
IRrecv hongwai(hwx);

decode_results results;

void setup() {
Serial.begin(9600);
hongwai.enableIRIn();
}
void loop() {
if (hongwai.decode(&results)) {
Serial.println(results.value, HEX);
if(results.value == 0x625EFF1){
digitalWrite(deng , HIGH);
}
else if(results.value == 0xF10BBB13){
digitalWrite(deng , LOW);
}

hongwai.resume();
}
delay(100);
}