Jade Dungeon

Arduino 开发环境

Processing语言

小程序(sketch)

Adduino官方把小程序称为sketch。由两部分组成:

  • setup:Arduino被reset时执行一次。
  • loop:setup以后不停地循环。
/**
 * run once after reset
 */
void setup() {
	/* ... */
}

/**
 * the loop routine runs over and over again forever
 */
void loop() {
	/* ... */
}

Arduino的芯片以每秒16,000,000次指令的速度运行,loop()方法的运行时受时间控制的。

常用API

时间

等待毫秒:delay()

delay(int mil_seconds)

例:

int led = 13;

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

void loop() {
	digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
	delay(5000);             // wait for a second
	digitalWrite(led, LOW);  // turn the LED off by making the voltage LOW
	delay(1000);             // wait for a second
}

等待微秒:delayMicroseconds()

delayMicroseconds(unsigned int us)

当前微秒数:micros()

unsigned long time = micros()

当前毫秒数:millis()

unsigned long time = millis()

数字I/O

设置接口:pinMode()

pinMode(int pin, int mode)
  • pin is between 0 to 14
  • mode is INPUT, OUTPUT, or INPUT_PULLUP

读取:digitalRead()

int val = digitalRead(int pin)
  • pin is between 0 to 14
  • return is HIGH or LOW

写入:digitalWrite()

digitalWrite(int pin, int val)
  • pin is between 0 to 14
  • val is HIGH or LOW

例子:

void setup() {
  pinMode(13, OUTPUT);    // sets the digital pin 13 as output
}

void loop() {
  digitalWrite(13, HIGH); // sets the digital pin 13 on
  delay(1000);            // waits for a second
  digitalWrite(13, LOW);  // sets the digital pin 13 off
  delay(1000);            // waits for a second
}

模拟I/O

读取:analogRead()

int value = analogRead(pin)
  • return 0-1023 for 10 bits or 0-4095 for 12 bits

写入:analogWrite()

analogWrite(int pin, int value)
  • pin
  • value 0(always off) ~ 255(always on)

analogReference()

串口I/O

Serial是串口的抽象。

打开串口:Serial.begin

Serial.begin(int speed)
Serial.begin(int speed, config)
  • speed:速度(波特率)
  • config:设置data, parity, stop bits。有效值:
    • SERIAL_5N1
    • SERIAL_6N1
    • SERIAL_7N1
    • SERIAL_8N1 (the default)
    • SERIAL_5N2
    • SERIAL_6N2
    • SERIAL_7N2
    • SERIAL_8N2
    • SERIAL_5E1: even parity
    • SERIAL_6E1
    • SERIAL_7E1
    • SERIAL_8E1
    • SERIAL_5E2
    • SERIAL_6E2
    • SERIAL_7E2
    • SERIAL_8E2
    • SERIAL_5O1: odd parity
    • SERIAL_6O1
    • SERIAL_7O1
    • SERIAL_8O1
    • SERIAL_5O2
    • SERIAL_6O2
    • SERIAL_7O2
    • SERIAL_8O2

打印输出:Serial.print()

Serial.print(Any val)
Serial.print(Any val, int format)

例:

Serial.print(78, BIN)        // gives "1001110"
Serial.print(78, OCT)        // gives "116"
Serial.print(78, DEC)        // gives "78"
Serial.print(78, HEX)        // gives "4E"
Serial.print(1.23456, 0)     // gives "1"
Serial.print(1.23456, 2)     // gives "1.23"
Serial.print(1.23456, 4)     // gives "1.2346"

打印输出:Serial.println()

Processing程序例子

传感器与驱动器

传感器(Sensor)从外界接收信息,驱动器(Actuatur)向外界作出响应。

数字IO

设置数字IO引脚模式

例子:

#define LED 13 
#define BTN 7

int isPr = 0;
int oldPr = 0;
int isOn = 0;


void setup() {
	pinMode(LED, OUTPUT);
	pinMode(BTN,  INPUT);
}

void loop() {
	isPr = digitalRead(BTN);

	// 保存之前的按下状态,防止芯片16M次循环与人手按开关的时间差
	if ((isPr == HIGH) && (oldPr == LOW)) {
		isOn = 1 - isOn;
		delay(10);  // 延时10秒,防止按下开关瞬间的杂波
	}
	oldPr = isPr;

	if (isOn == 1) {
		digitalWrite(LED, HIGH);
	} else {
		digitalWrite(LED,  LOW);
	}
}
}}}}


==== 输出数字信号 ====

例:

{{{class="brush:c"
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);           // 13号引脚输出高电平5V

把输出电器的「正极」连接到13号数字IO引脚,「负极」连接到地线「GND」。

example

读取数字信号

例:

pinMode(7, INPUT);
int isOn = 0;

isOn = digitalRead(7)                   // 读取17号引脚

example

Arduino数字引脚上需要并联一个10kW的电阻的原因是什么?难道是为了快点把电耗光么?

读取模拟信号

Arduino有6个标有「Analog In」的引脚0 ~ 6,把0V到5V的电压分为0 ~ 1023级。

analogRead(pin)

例如2.5V的电压到引脚0,读到的值就是512

例,按环境光越暗,闪的频率越快:

#define LED 13

int val = 0;

void setup() {
	pinMode(LED, OUTPUT);
	// 模拟接口不用设置,
	// 因为那6个模拟接口只能用来模拟输入
}

void loop() {
	val = analogRead(0);

	digitalWrite(LED, HIGH);

	delay(val);

	digitalWrite(LED,  LOW);
	delay(val);
}

example

光敏电阻要串联10K欧电阻。

另一个例子,按光越强,LED越亮:

#define LED 9

int val = 0;

void setup() {
	pinMode(LED, OUTPUT);
	// 模拟接口不用设置,
	// 因为那6个模拟接口只能用来模拟输入
}

void loop() {
	val = analogRead(0);

	// val至少要除以4,模拟信号最大1023,
	// 而输出信号最大只有255
	analogWrite(LED, (val / 16));

	delay(10);
}

参考脉冲宽度调制(PWM)的例子连接LED,再结合光敏电阻。

脉冲宽度调制(PWM)

LED只有开和关两种状态,但是如果闪烁得足够快,可以模拟不同的亮度。

example

analogWrite()函数可以用指定引脚以0 ~ 255的级别输出信号:

analogWrite(int pin, int value)

例:

#define LED 9

int i =0;

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

void loop() {

	for (i = 0; i < 255; i++) {
		analogWrite(LED, i);
		delay(10);
	}

	for (i = 255; i > 0; i--) {
		analogWrite(LED, i);
		delay(10);
	}

}

example

电阻用470欧或是1K欧的,1K欧的变化程度更加明显一些。

加上按钮来控制,按一下开关开灯,长按调节亮度从暗到亮再到暗循环:

#define BTN 7
#define LED 9

int isPress = 0;
int oldPress = 0;

int state = 0;

int valState = 0;
int brightness = 0;
unsigned long startTime = 0; // 开始按下按钮的时间

void setup() {
	pinMode(BTN,  INPUT);
	pinMode(LED, OUTPUT);
}

void loop() {

	isPress = digitalRead(BTN);

	if ((isPress == HIGH) && (oldPress == LOW)) { // 如果是从松开到按下
		state = 1 - state;
		startTime = millis();  // 记下当前时间亳秒数,就是按下的时间
		delay(10);
	}

	if ((isPress == HIGH) && (oldPress == HIGH)) { // 如果按下后没有松开
		if (state == 1 && (millis() - startTime) > 500) { // 而且按下时间超过半秒
			valState++;
			if (valState >-1 && valState < 256) {
				brightness = valState;
			} else if (valState >-1 && valState < 511) {
				brightness = 255 - (valState - 255);
  		} else {
				brightness = 0;
				valState = 0;
    	}
			delay(50);
		}
	}

	oldPress = isPress;  // update old value

	if (state == 1) {
		analogWrite(LED, brightness);
	} else {
		analogWrite(LED, 0);
	}

}

串口通信

USB连接线除了可以烧录程序,还可以用来与连接的电脑通信。

Arduino用USB发送数据给电脑

Serial.begin()以指定的波特率打开串口:

Serial.begin(int feq)

例,发送光敏电阻的值给电脑:

#define SENSOR 0    // 光敏电阻连接在0号模拟引脚

void setup () {
	// 以波特率9600为参数打开通信串口
	Serial.begin(9600); 
}

void loop() {
	Serial.println(analogRead(SENSOR));
	delay(500);
}

电脑上用Arduino右上角的放大镜按钮打开「Serial Monitor」打开监控窗口。 窗口中会显示收到的值。