图床 arduino-img/
太极创客arduino w3c-arduino 官方示例
爱上Arduino(公众号)
arducam
General Tips
- // 单行注释 /* 多行 注释 */ 每行代码之后用分号; 变颜色的词-关键词
- Serial.begin(9600); //打开串口通讯,设置传输速率为9600字节每秒
- 注意变量的作用于,如果在大括号里面定义,那么作用于就限于这个大括号。大括号外面的变量是全局变量
- 一般红色的是正极黑色的是负极。就像交流电线是一样的。
串口通讯
arduino可以通过USB线进行串口通讯,引脚0(RX)中的RX表示receive,而引脚1(TX)的TX表示Transmit,这两个引脚是专门用于串口通讯的。Arduino IDE软件中的“串口监视器”按钮可以显示相关内容。
目前用到的函数:
(1) Serial.available() //检测串口缓冲区是否有数据
具体来讲:Serial.available() 返回串口缓冲区中当前剩余的字符个数。一般用这个函数来判断串口的缓冲区有无数据,当Serial.available()>0时,说明串口接收到了数据,可以读取。
- Serial.avaliable()的返回值是当前缓冲区中接收到的数据字节数。为了使它一次就捕获到所有缓冲区中的数据,我们通常需要加延时函数。下图例子,一次读取串口监视器的所有缓存数据,没有延时的话,连续输出1。
void loop() { while (Serial.available()>0 ) //检测串口缓冲区是否有数据 { delay(100); Serial.println(Serial.available()); int a =Serial.read(); } }
- 特别注意,Serial.available并没有读取数据,所以没有读取之前,所有的数据都还是在当前缓冲区中。
(2) Serial.read() //read() 函数可用于从设备接收到数据中读取一个字节(8 个bits)的数据, 本函数属于Stream类
具体来讲:Serial.read()指从串口的缓冲区取出并读取一个Byte的数据,比如有设备通过串口向Arduino发送数据了,我们就可以用Serial.read()来读取发送的数据。实例如下
while (Serial.available()>0)
{
data= Serial.read();
delay(2);
}
注释:当串口接收到数据时(上面Serial.available()>0这句),反复读取串口的数据并赋值给data (上面data= Serial.read()这句),直到数据读完(即Serial.available()=0的时候)。
演示每读取一次少一个字节:
void setup(){
Serial.begin(9600);
}
void loop(){
if(Serial.available()>0){
delay(2000);
Serial.println("yes");
char inchar= Serial.read();
if(Serial.available()>0){
Serial.println("yes2");
}
else{
Serial.println("no2");
}
}
}
- 选用换行符或者回车,会多增加一个字节。多read一次。
参考资料:
1. Arduino的串口结束符及串口缓冲区
2. 深入理解Arduino的串口结束符及串口缓冲区
3. 关于arduino清空串口缓存Arduino的编程中,串口输入与输出都是针对ASCII码值的,比如字母's'的ASCII码值为115。
输入方面,对于Serial.read(), monitor中输入's'或者115,程序得到的值都为's'. 而且Serial.read()每次只能接受一个byte的数据,如果想要输入字符串,则需要专门写一段程序来实现。
(3) Serial.print()和Serial.println(),以人类可读的ASCII码形式向串口发送数据,但是后者有换行。
Serial.print(78) 发送 “78”
Serial.print(1.23456) 发送 “1.23”
Serial.print(‘N’) 发送 “N”
Serial.print(“Hello world.”) 发送 “Hello world.”
串口监视器输入2,那么Serial.print(Serial.read()) 的输入结果为50,因为2对应的ASCII码是50
数字I/O
(1) 引脚为输出(OUTPUT)模式
当引脚设置为输出(OUTPUT)模式时,引脚为低阻抗状态。这意味着Arduino可以向其它电路元器件提供电流。也就是说,Arduino引脚在输出(OUTPUT)模式下可以点亮LED或者驱动电机。(如果被驱动的电机需要超过40mA的电流,Arduino将需要三极管或其它辅助元件来驱动他们)
设为OUTPUT之后,就可以用digitalWrite()来设置高电平(5 V)或者低电平(0 V /GND),示例如下
void setup() {
// put your setup code here, to run once:
pinMode(8,OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(8,HIGH);
delay(1000);
digitalWrite(8,LOW);
}
(2) 引脚为输入(INPUT)模式
此时,引脚为高阻抗状态(100兆欧)。此时该引脚可用于读取传感器信号或开关信号。注意:当Arduino引脚设置为输入(INPUT)模式或者输入上拉(INPUT_PULLUP)模式,请勿将该引脚与负压或者高于5V的电压相连,否则可能会损坏Arduino控制器。
(3) 设置引脚为输入上拉(INPUT_PULLUP)模式
Arduino 微控制器自带内部上拉电阻。如果你需要使用该内部上拉电阻,可以通过pinMode()将引脚设置为输入上拉(INPUT_PULLUP)模式。
电机
电机根据电源种类分为直流电机(DC)交流电机(AC)和交直流两用电机(Universal),arduino通常配合直流电机进行开发。
这里用步进电机28BYJ-48,5V DC
#include<Stepper.h>
// 这里设置步进电机旋转一圈是多少步(可以根据步进电机实际进行修改,28BYJ-48 八拍为64步,单四拍为32步)。
//根据您的步进电机参数修改。
#define STEPS 64
//设置步进电机的步数和引脚(就是注意点2里面说的驱动板上IN1~IN4连接的四个数字口)。
Stepper stepper(STEPS, 8, 10, 9, 11);
void setup()
{
// 以每分钟转速设置电机速度,此功能不会使电机转动,只是设置调用step()时的速度。
stepper.setSpeed(500);
// 初始化串口,用于调试输出信息
Serial.begin(9600);
}
void loop()
{
stepper.step(300); //4步模式下旋转一周用2048 步。8拍模式下旋转一周用4096步。
delay(500);
stepper.step(-300);
delay(500);
}
注意接上板子的5V 的电源。
参考:How to use Arduino as a 28BYJ-48 Stepper Motor Controller with a ULN2004 Driver Board
舵机
棕色 — 接GND
橙色 — 接Digital 10 (PWM 信号)
红色 — 接 5V
#include <Servo.h>
#define PIN_SERVO 10
Servo myservo;
void setup()
{
myservo.attach(PIN_SERVO);
}
void loop()
{
myservo.write(0);
delay(1000);
myservo.write(80);
delay(1000);
myservo.write(160);
delay(1000);
myservo.write(80);
delay(1000);
myservo.write(0);
delay(1000);
}
注:如果上述舵机是在0度和180度之间来回旋转,但是实际运行过程中旋转到160度就停了下来,这时要修改attach方法的默认值,改为servo.attach(pin, 500, 2500),原因参考Servo - attach()或者孙老师视频。
舵机(servo) = 电机 + 控制 +反馈
舵机的旋转不像普通电机那样只是转圈圈,它可以根据你的指令旋转到0至180度之间的任意角度然后精准的停下来,常用于机器人、遥控飞机、飞机航模等。高速旋转的电机,通过齿轮降低了输出的转速,但是增加了输出轴上的输出扭矩,其结构如下图。
电位器(Potentiometer)实际上就是可变电阻。电位器和电机均被连接到电路板上。控制电路通过电位计可监控舵机的当前角度。如果轴的位置与控制信号相符,那么电机就会关闭。如果控制电路发现这个角度不正确,它就会控制马达转动,直到它达到指定的角度。舵机角度根据制造商的不同而有所不同。比如,一个180度的舵机,它可以在0度至180度之间运动。由于限位装置被安装在主输出装置上,超出这个范围机械结构就不能再转动了。舵机的输出功率与它所需要转动的距离成正比。如果输出轴需要转动很长的距离,马达就会全速运转,如果它只需要短距离转动,马达就会以较慢的速度运行,这叫做速度比例控制。
舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围,总间隔为2ms。脉冲的宽度(PWM信号的空占比,使用Arduino数字前带~的pin)将决定马达转动的距离:0.5ms————-0度; 1.0ms————45度; 1.5ms————90度; 2.0ms———–135度; 2.5ms———–180度。
Arduino 的驱动能力有限,所以当需要控制1 个以上的舵机时需要外接电源。一个机器人经常需要很多个舵机同时工作,此时需要加一个舵机控制板(比如PCA9685),舵机控制板本身是一个单片机,它不但能接多个舵机,同时也简化了舵机操作命令。SG90小舵机可用arduino板上的5V供电,大的舵机有的需要外部供电才能驱动,外接电源时需要将降到舵机指定的电压,否则会烧坏舵机。
常见的舵机如下:
- SG90,便宜,能够应付绝大部分场景(基本能用)。缺点是市面上有大量的山寨品,品质无法得到保证,另外塑料减速齿轮也比较容易磨损,扭矩也比较小。
- MG90,是SG90的升级版,使用了金属齿轮,扭矩和寿命都得到改善,当然价格更贵。
- MG996,金属齿轮,最大特点是扭矩大,几乎是SG90的10倍左右,体积也更大。
360度舵机 = 普通舵机 - 电位器
360度舵机不具备角度定位功能,只能控制转动的方向。360度舵机一个PWM信号,舵机会以一个特定的速度转动,类似与电机。但与电机不同的是,360舵机是闭环控制,速度控制稳定。 PWM 信号与360舵机转速的关系: 0.5ms----------------正向最大转速; 1.5ms----------------速度为0; 2.5ms----------------反向最大转速。
参考资料:
(1) 【Arduino百问】舵机?你懂舵机吗?三分钟深入了解舵机 更精准的控制——孙老师
(2) 舵机控制简易入门教程
(3) 180度舵机与360度舵机
Arduino UV Index Meter – Measuring UV Light
Arduino 制作光谱仪
Arduino 制作闪烁体探测器
参考资料:
(1) Wolszczak W, Krämer K W, Dorenbos P. CsBa2I5: Eu2+, Sm2+—The First High‐Energy Resolution Black Scintillator for γ‐Ray Spectroscopy[J]. physica status solidi (RRL)–Rapid Research Letters, 2019, 13(9): 1900158.
(2) Scintillino - an Arduino-based Quick&dirty Scintillation Counter
(3) ArduSiPM a small, light and low power, All-In-One particle detector
经典实例
blink
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
注:对于UNO板子,板子上的LED is attached to digital pin 13