Arduino语言是建立在C/C++基础上的,其实也就是基础的C语言,Arduino语言只不过把AVR单片机(微控制器)相关的一些参数设置都函数化,不用我们去了解他的底层,让我们不了解AVR单片机(微控制器)的朋友也能轻松上手。
在与Arduino DIYER接触的这段时间里,发现有些朋友对Arduino语言还是比较难入手,那么这里我就简单的注释一下Arduino语言(本人也是半罐子水,有错的地方还请各位指正)。
基础C语言
关键字:
if...else
必须紧接着一个问题表示式(expression),若这个表示式为真,紧连着表示式后的代码就会被执行。若这个表示式为假,则执行紧接着else之后的代码. 只使用 if不搭配else是被允许的。
范例:
if (val == 1) {
digitalWrite(LED,HIGH);
}
for
用来明定一段区域代码重复指行的次数。
范例:
for (int i = 0; i < 10; i++) {
Serial.print("ciao");
}
switch case
if叙述是程序里的分叉路口,switch case 是更多选项的路口。Swith case 根据变量值让程序有更多的选择,比起一串冗长的if叙述,使用swith case可使程序代码看起来比较简洁。
范例 :
switch (sensorValue) {
case 23:
digitalWrite(13,HIGH);
break;
case 46:
digitalWrite(12,HIGH);
break;
default: // 以上条件都不符合时,预设执行的动作
digitalWrite(12,LOW);
digitalWrite(13,LOW);
}
while
当while之后的条件成立时,执行括号内的程序代码。
范例 :
// 当sensor值小于512,闪烁LED灯
sensorValue = analogRead(1);
while (sensorValue < 512) {
digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,HIGH);
delay(100);
sensorValue = analogRead(1);
}
do... while
和while 相似,不同的是while前的那段程序代码会先被执行一次,不管特定的条件式为真或为假。因此若有一段程序代码至少需要被执行一次,就可以使用do…while架构。
范例 :
do {
digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,HIGH);
delay(100);
sensorValue = analogRead(1);
} while (sensorValue < 512);
break
让程序代码跳离循环,并继续执行这个循环之后的程序代码。此外,在break也用于分隔switch case 不同的叙述。
范例 :
//当sensor值小于512,闪烁LED灯
do {
// 按下按钮离开循环
if (digitalRead(7) == HIGH)
break;
digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,HIGH);
delay(100);
sensorValue = analogRead(1);
} while (sensorValue < 512);
continue
用于循环之内,它可以强制跳离接下来的程序,并直接执行下一个循环。
范例 :
for (light = 0; light < 255; light++)
{
// 忽略数值介于 140 到 200之间
if ((x > 140) && (x < 200))
continue;
analogWrite(PWMpin, light);
delay(10);
}
return
函数的结尾可以透过return回传一个数值。
例如,有一个计算现在温度的函数叫 computeTemperature(),你想要回传现在的温度给temperature变量,你可以这样写:
int temperature = computeTemperature();
int computeTemperature() {
int temperature = 0;
temperature = (analogRead(0) + 45) / 100;
return temperature;
}
goto
语法符号:
; (分号)
Arduino 语言每一行程序都是以分号为结尾。这样的语法让你可以自由地安排代码,你可以将两个指令放置在同一行,只要中间用分号隔开。 (但这样做可能降低程式的可读性。)
范例:
delay(100);
{} (大括号)
大括号用来将程式代码分成一个又一个的区块,如以下范例所示,在loop()函数的前、后,必须用大括号括起来。
=
+ 相加
- 相减
* 相乘
/ 相除
% 余数除法
== 等于
!=不等于
< 小于
> 大于
<= 小于等于
>= 大于等于
&& 交集
|| 联集
! 反相
++ 累加
-- 递减
+=
-=
*=
/=
数据类型:
boolean 布林
布尔变数的值只能为真(true)或是假(false)
char 字符
单一字符例如 A,和一般的计算机做法一样Arduino 将字符储存成一个数字,即使你看到的明明就是一个文字。
用数字表示一个字符时,它的值有效范围为 -128 到127。
注意:有两种主流的计算机编码系统ASCII 和UNICODE。ASCII 表示了127个字符, 用来在序列终端机和分时计算器之间传输文字。
UNICODE可表示的字符量比较多,在现代计算机操作系统内它可以用来表示多国语言。
在位数需求较少的信息传输时,例如意大利文或英文这类由拉丁文,阿拉伯数字和一般常见符号构成的语言,ASCII仍是目前主要用来交换信息的编码法。
byte 字节类型
储存的数值范围为0到255。如同字符一样字节型态的变量只需要用一个字节(8位)的内存空间储存。
int 整数
整数数据型态用到2字节的内存空间,可表示的整数范围为 –32,768 到 32,767; 整数变量是Arduino内最常用到的数据型态。
unsigned int 无符号整数(绝对值)
无号整数同样利用2字节的内存空间,无号意谓着它不能储存负的数值,因此无号整数可表示的整数范围为0 到 65,535。
long 长整数
长整数利用到的内存大小是整数的两倍,因此它可表示的整数范围从 –2,147,483,648 到 2,147,483,647。
unsigned long 无符号长整数
无号长整数可表示的整数范围为0 到 4,294,967,295。
float 浮点数
浮点数就是用来表达有小数点的数值,每个浮点数会用掉四字节的RAM,注意芯片内存空间的限制,谨慎的使用浮点数
double 双字节浮点
也叫双精度浮点数,可表达最大值为 1.7976931348623157 x 10308。
string 字符串
字符串用来表达文字信息,它是由多个ASCII字符组成(你可以透过序串端口发送一个文字讯息或者将之显示在液晶显示器上)。字符串中的每一个字符都用一个组元组空间储存,并且在字符串的最尾端加上一个空字符以提示Ardunio处理器字符串的结束。下面两种宣告方式是相同的。
例如:
char string1[] = "Arduino";//7字符+1空字符
char string2[8] = "Arduino"; // 与上行相同
array 数组
一串变量可以透过索引去直接取得。假如你想要储存不同程度的LED亮度时,你可以宣告六个变量light01,light02,light03,light04,light05,light06,但其实你有更好的选择,例如宣告一个整数数组变量如下:
int light[6] = {0 , 20 , 50 , 75 , 100}
"array" 这个字为没有直接用在变量宣告,而是[]和{}宣告数组。
控制指令
数据类型转换:
char()
byte()
int()
long()
float()
HIGH | LOW
表示数字IO口的电平,HIGH 表示高电平(1),LOW 表示低电平(0)。 HIGH 和LOW 也用来表示你开启或是关闭了一个Arduino的脚位(pin)
INPUT | OUTPUT
表示数字IO口的方向,INPUT 表示输入(高阻态),OUTPUT 表示输出(AVR能提供5V电压 40mA电流)。
true | false
true 表示真(1),false表示假(0)。
变数:
变量用来指定Arduino 内存中的一个位置,变量可以用来储存数据,程序人员可以透过脚本代码去不限次数的操作变数的值。
因为Arduino 是一个非常简易的微处理器,但你要宣告一个变量时必须先定义他的数据型态,好让微处理器知道准备多大的空间以储存这个变量值。
以上为基础c语言的关键字和符号,有c语言基础的都应该了解其含义,这里也不作过多的解释。
Arduino 语言
结构
1、声明变量及接口名称(int val;int ledPin=13;)。
2、void setup()
在程序开始时使用,在这个函数范围内放置初始化Arduino 板子的程式,主要程式开始撰写前, 使Arduino 板子装置妥当的指令可以初始化变量、管脚接口模式、启用库等(例如:pinMode(ledPin,OUTPUT);)。
3、void loop()
在setup()函数之后,即初始化之后,loop() 让你的程序循环地被执行。使用它来运转Arduino。连续执行函数内的语句,这部份的程式会一直重复的被执行,直到Arduino 板子被关闭。
功能
数字 I/O
pinMode(pin, mode)
数字IO口输入输出模式定义函数,将接口定义为输入或输出接口,用在setup()函数里,pin表示为0~13接口名称, mode表示为INPUT或OUTPUT。即“ pinMode(接口名称,OUTPUT或INPUT)”。
范例 :
pinMode(7,INPUT); // 将脚位 7 设定为输入模式
digitalWrite(pin, value)
数字IO口输出电平定义函数,将数字接口值至高或低、开或关,pin表示为0~13,value表示为HIGH或LOW,即digitalWrite(接口名称, HIGH或LOW)。但脚位必须先透过pinMode明示为输入或输出模式digitalWrite才能生效。比如定义HIGH可以驱动LED。
范例 :
digitalWrite(8,HIGH); //将脚位 8设定输出高电位
int digitalRead(pin)
数字IO口读输入电平函数,读出数字接口的值,pin表示为0~13,value表示为HIGH或LOW,即digitalRead(接口名称)。比如可以读数字传感器。当感测到脚位处于高电位时时回传HIGH,否则回传LOW。
范例 :
val = digitalRead(7); // 读出脚位 7 的值并指定给 val
模拟 I/O
int analogRead(pin)
模拟IO口读函数,从指定的模拟接口读取值,Arduino对该模拟值进行10-bit的数字转换,这个方法将输入的0-5电压值转换为 0到1023间的整数值。pin表示为0~5(Arduino Diecimila为0~5,Arduino nano为0~7)。即“analogRead(接口名称)”,比如可以读模拟传感器(10位AD,0~5V表示为0~1023)。
范例 :
val = analogRead(0); //读出类比脚位 0 的值并指定给 val变数
analogWrite(pin, value)
数字IO口PWM输出函数,给一个接口写入模拟值(PWM波)。改变PWM脚位的输出电压值。对于 ATmega168芯片的Arduino(包括Mini或BT),该函数可以工作于 3, 5, 6, 9, 10和 11号接口,即“analogWrite(接口名称, 数值)”,pin表示3, 5, 6, 9, 10, 11,value表示为0~255。比如可用于电机PWM调速或音乐播放。
例如:输出电压2.5伏特(V),该值大约是128。
范例 :
analogWrite(9,128); // 输出电压约2.5伏特(V)
扩展 I/O
shiftOut(dataPin, clockPin, bitOrder, value)
SPI外部IO扩展函数,通常使用带SPI接口的74HC595做8个IO扩展,把资料传给用来延伸数位输出的暂存器,此函式通常使用在延伸数位的输出。函式使用一个脚位表示资料、一个脚位表示时脉。dataPin为数据口,clockPin为时钟口,bitOrder用来表示位元间移动的方式,为数据传输方向(MSBFIRST高位在前,LSBFIRST低位在前),value会以byte形式输出,表示所要传送的数据(0~255),另外还需要一个IO口做74HC595的使能控制。
范例 :
shiftOut(dataPin, clockPin, LSBFIRST, 255);
unsigned long pulseIn(pin, value)
脉冲长度记录函数,设定读取脚位状态的持续时间,返回时间参数(us),例如使用红外线、加速度感测器测得某一项数值时,在时间单位内不会改变状态。pin表示为0~13,value为HIGH或LOW。比如value为HIGH,那么当pin输入为高电平时,开始计时,当pin输入为低电平时,停止计时,然后返回该时间。
范例 :
time = pulsein(7,HIGH); // 设定脚位7的状态在时间单位内保持为HIGH
时间函数
unsigned long millis()
返回时间函数(单位ms), 回传晶片开始执行到目前的毫秒,该函数是指,当程序运行就开始计时并返回记录的参数,该参数溢出大概需要50天时间。
范例:
duration = millis()-lastTime; // 表示自"lastTime"至当下的时间
delay(ms) 延时函数(单位ms),延时一段时间,暂停晶片执行多少毫秒,
delay(1000)为一秒。
范例:
delay(500); //暂停半秒(500毫秒)
delayMicroseconds(us) 延时函数(单位us)暂停晶片执行多少微秒。
delayMicroseconds(1000); //暂停1豪秒
数学函数
min(x, y)
求最小值 ,回传两数之间较小者
范例:
val = min(10,20); // 回传10
max(x, y)
求最大值 ,回传两数之间较大者
范例:
val = max(10,20); // 回传20
abs(x)
计算绝对值 ,回传该数的绝对值,可以将负数转正数。
范例:
val = abs(-5); // 回传5
constrain(x, a, b) 约束函数,下限a,上限b,判断x变数位于a与b之间的状态。x若小于a回传a;介于a与b之间回传x本身;大于b回传b
范例:
val = constrain(analogRead(0), 0, 255); // 忽略大于255的数
map(value, fromLow, fromHigh, toLow, toHigh)
约束函数,value必须在fromLow与toLow之间和fromHigh与toHigh之间。将value变数依照fromLow与fromHigh范围,对等转换至toLow与toHigh范围。时常使用于读取类比讯号,转换至程式所需要的范围值。
例如:
val = map(analogRead(0),0,1023,100, 200); // 将analog0 所读取到的讯号对等转换至100,200之间的数值。
pow(base, exponent)
开方函数,base的exponent次方。回传一个数(base)的指数(exponent)值。
范例:
double x = pow(y, 32); // 设定x为y的32次方
sq(x) 平方
sqrt(x) 开根号
回传double型态的取平方根值。
范例:
double a = sqrt(1138); // 回传1138平方根的近似值 33.73425674438
三角函数
sin (rad)
回传角度(radians)的三角函数sine值。
范例:
double sine = sin(2); // 近似值 0.90929737091
cos(rad)
回传角度(radians)的三角函数cosine值。
范例:
double cosine = cos(2); //近似值-0.41614685058
tan(rad)
回传角度(radians)的三角函数tangent值。
范例:
double tangent = tan(2); //近似值-2.18503975868
随机数函数
randomSeed(seed)
随机数端口定义函数,seed表示读模拟口analogRead(pin)函数 。
事实上在Arduino里的乱数是可以被预知的。所以如果需要一个真正的乱数,可以呼叫此函式重新设定产生乱数种子。你可以使用乱数当作乱数的种子,以确保数字以随机的方式出现,通常会使用类比输入当作乱数种子,藉此可以产生与环境有关的乱数(例如:无线电波、宇宙雷射线、电话和萤光灯发出的电磁波等)。
范例:
randomSeed(analogRead(5)); // 使用类比输入当作乱数种子
long random(max)
随机数函数,返回数据大于等于0,小于max。
范例:
long randnum = random(11); // 回传 0 -10之间的数字
long random(min, max)
随机数函数,返回数据大于等于min,小于max。
范例:
long randnum = random(0, 100); // 回传0 – 99 之间的数字
外部中断函数
attachInterrupt(interrupt, , mode)
外部中断只能用到数字IO口2和3,interrupt表示中断口初始0或1,表示一个功能函数,mode:LOW低电平中断,CHANGE有变化就中断,RISING上升沿中断,FALLING 下降沿中断。
detachInterrupt(interrupt)
中断开关,interrupt=1 开,interrupt=0 关。
中断使能函数
interrupts() 使能中断
noInterrupts() 禁止中断
串口收发函数
Serial.begin(speed)
串口定义波特率函数,设置串行每秒传输数据的速率(波特率),可以指定Arduino从电脑交换讯息的速率,通常我们使用9600 bps。,speed表示波特率,如9600,19200等。在同计算机通讯时,使用下面这些值:300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600或 115200 bps(每秒位元组)。。你也可以在任何时候使用其它的值,比如,与0号或1号插口通信就要求特殊的波特率。用在setup()函数里
范例:
Serial.begin(9600)
int Serial.available()
判断缓冲器状态。回传有多少位元组(bytes)的资料尚未被read()函式读取,如果回传值是0代表所有序列埠上资料都已经被read()函式读取。
范例:
int count = Serial.available();
int Serial.read()
读串口并返回收到参数。Serial.read()——读取持续输入的数据。读取1byte的序列资料
范例:
int data = Serial.read();
Serial.flush()
清空缓冲器。 有时候因为资料速度太快,超过程式处理资料的速度,你可以使用此函式清除缓冲区内的资料。经过此函式可以确保缓冲区(buffer)内的资料都是最新的。
范例:
Serial.flush();
Serial.print(data)
从串行端口输出数据。Serial.print(数据)默认为十进制等于Serial.print(数据,DEC)。
Serial.print(data, encoding)
经序列埠传送资料,提供编码方式的选项。Serial.print(数据,数据的进制)如果没有指定,预设以一般文字传送。
范例:
Serial.print(75); // 列印出 "75"
Serial.print(75, DEC); //列印出 "75"
Serial.print(75, HEX); // "4B" (75 的十六进位)
Serial.print(75, OCT); // "113" (75 in的八进位)
Serial.print(75, BIN); // "1001011" (75的二进位)
Serial.print(75, BYTE); // "K" (以byte进行传送,显示以ASCII编码方式)
Serial.println(data)
从串行端口输出数据,跟随一个回车和一个换行符。这个函数所取得的值与 Serial.print()一样。
Serial.println(data, encoding)
与Serial.print()相同,但会在资料尾端加上换行字元( )。意思如同你在键盘上打了一些资料后按下Enter。
范例:
Serial.println(75); //列印出"75 "
Serial.println(75, DEC); //列印出"75 "
Serial.println(75, HEX); // "4B "
Serial.println(75, OCT); // "113 "
Serial.println(75, BIN); // "1001011 "
Serial.println(75, BYTE); // "K "
Serial.println(data,number)
number指串口监视器面板上显示的数字小数点之后的位数。
以上几个函数是常用基本函数,还有很多以后会慢慢学习
Arduino语言库文件
/****************************************/
Arduuino复合运算符
+= , -= , *= , /=
对一个变量和另一个参数或变量完成一个数学运算。+=(以及其他)可以缩短语法长度。
Syntax语法
x += y; // 等价于 x = x + y;
x -= y; // 等价于 x = x - y;
x *= y; // 等价于 x = x * y;
x /= y; // 等价于 x = x / y;
Parameters参数
x:任何变量类型
y:任何变量类型或常数
Examples范例
x = 2;
x += 4; // x现在为6
x -= 3; // x现在为3
x *= 10; // x现在为30
x /= 2; // x现在为15
Syntax语法
x++; // increment x by one and returns the old value of x
// 将x的值加1并返回原来的x的值。 ++x; // increment x by one and returns the new value of x // 将x的值加1并返回现在的x的值。
x-- ; // decrement x by one and returns the old value of x // 将x的值减1并返回原来的x的值。
--x ; // decrement x by one and returns the new value of x // 将x的值减1并返回现在的x的值。
Parameters参数
x: an integer or long (possibly unsigned)
x:一个整数或长整数(可以无符号)
Returns返回
The original or newly incremented / decremented value of the variable.
返回变量原始值或增加/消耗后的新值。
Examples范例
x = 2;
y = ++x; // x now contains 3, y contains 3 // x现在为3,y为3
y = x--; // x contains 2 again, y still contains 3 // x现在仍然为2,y将为3