本页为5至10章例程,1至4章例程见示例程序基础部分
5.1.2 print和write输出方式的差异
/* 串口的高级用法 Print和write的使用 Arduino.cn */ float FLOAT=1.23456; int INT=123; byte BYTE[6]={48,49,50,51,52,53}; void setup(){ Serial.begin(9600); //Print的各种输出形式 Serial.println("Serial Print:"); Serial.println(INT); Serial.println(INT, BIN); Serial.println(INT, OCT); Serial.println(INT, DEC); Serial.println(INT, HEX); Serial.println(FLOAT); Serial.println(FLOAT, 0); Serial.println(FLOAT, 2); Serial.println(FLOAT, 4); //Write的各种输出形式 Serial.println(); Serial.println("Serial Write:"); Serial.write(INT); Serial.println(); Serial.write("Serial"); Serial.println(); Serial.write(BYTE,6); } void loop(){ }
5.1.3 read和peek输入方式的差异
//read函数读取串口数据 char col; void setup() { Serial.begin(9600); } void loop() { while(Serial.available()>0){ col=Serial.read(); Serial.print("Read: "); Serial.println(col); delay(1000); } }
//peek函数读取串口数据 char col; void setup() { Serial.begin(9600); } void loop() { while(Serial.available()>0){ col=Serial.peek(); Serial.print("Read: "); Serial.println(col); delay(1000); } }
5.1.4 串口读取字符串
//Read String void setup() { Serial.begin(9600); } void loop() { String inString=""; while (Serial.available() > 0) { char inChar = Serial.read(); inString += (char)inChar; //延时函数用于等待输入字符完全进去接收缓冲区 delay(10); } // 检查是否接收到数据,如果接收到,便输出该数据 if(inString!=""){ Serial.print("Input String: "); Serial.println(inString); } }
5.1.5 串口事件
/* Serial Event example When new serial data arrives, this sketch adds it to a String. When a newline is received, the loop prints the string and clears it. This example code is in the public domain. http://www.arduino.cc/en/Tutorial/SerialEvent */ String inputString = ""; // 用于保存输入数据的字符串 boolean stringComplete = false; // 字符串是否已接收完全 void setup() { // 初始化串口 Serial.begin(9600); // 设置字符串存储量为200个字节 inputString.reserve(200); } void loop() { // 当收到新的一行字符串时,输出这个字符串 if (stringComplete) { Serial.println(inputString); // 清空字符串 inputString = ""; stringComplete = false; } } /* 当一个新的数据被串口接收到时会触发SerialEvent事件 SerialEvent函数中的程序会在两次loop()之间运行 因此,如果你loop中有延时程序,会延迟该事件的响应。 造成数个字节的数据都可以被接收。 */ void serialEvent() { while (Serial.available()) { // 读取新的字节 char inChar = (char)Serial.read(); // 将新读取到的字节添加到inputString字符串中 inputString += inChar; // 如果收到换行符,则设置一个标记 // 再在loop()中检查这个标记,用以执行相关操作 if (inChar == '\n') { stringComplete = true; } } }
5.1.6 实验:串口控制RGB LED调光
/* OpenJumper Example 串口RGB LED调光 奈何col 2013.2.20 www.openjumper.cn */ int i; //保存PWM需要输出的值 String inString = ""; // 输入的字符串 char LED = ' ';// 用于判断指定LED颜色对应的引脚 boolean stringComplete=false;// 用于判断数据是否读取完成 void setup() { //初始化串口 Serial.begin(9600); } void loop() { if (stringComplete) { if (LED=='A'){ analogWrite(9,i); } else if (LED=='B'){ analogWrite(10,i); } else if (LED=='C'){ analogWrite(11,i); } // 清空数据,为下一次读取做准备 stringComplete = false; inString = ""; LED = ' '; } } //使用串口事件 // 读取并分离字母和数字 void serialEvent() { while (Serial.available()) { // 读取新的字符 char inChar = Serial.read(); //根据输入数据分类 // 如果是数字,则存储到变量inString中 // 如果是英文字符,则存储到变量LED中 // 如果是结束符“\n”,则结束读取,并将inString转换为int if (isDigit(inChar)) { inString += inChar; } else if (inChar == '\n') { stringComplete = true; i=inString.toInt(); } else LED=inChar; } }
5.1.7 更好的串口监视器——串口调试助手
[vc_button title=”下载Arduino串口助手” target=”_self” color=”wpb_button” icon=”none” size=”wpb_regularsize” href=”http://x.openjumper.cn/serial/”]
5.2.4 实验:Arduino间的串口通信
/* Arduino Mega端程序 串口使用情况: Serial ------ computer Serial1 ------ UNO SoftwareSerial */ void setup() { // 初始化Serial,该串口用于与计算机连接通信 Serial.begin(9600); // 初始化Serial1,该串口用于与设备B进行连接通信 Serial1.begin(9600); } // 两个字符串分别用于存储AB两端传输来的数据 String device_A_String = ""; String device_B_String = ""; void loop() { // 读取从计算机传入的数据,并通过Serial1发送给设备B if(Serial.available() > 0) { if(Serial.peek() != '\n') { device_A_String += (char)Serial.read(); } else { Serial.read(); Serial.print("you said: "); Serial.println( device_A_String ); Serial1.println( device_A_String ); device_A_String = ""; } } //读取从设备B传入的数据,并在串口监视器中显示 if(Serial1.available() > 0) { if(Serial1.peek() != '\n') { device_B_String += (char)Serial1.read(); } else { Serial1.read(); Serial.print("device B said: "); Serial.println( device_B_String ); device_B_String = ""; } } }
/* Arduino UNO端程序 串口使用情况: Serial ------ computer softSerial ------ Mega Serial1 */ #include <SoftwareSerial.h> //新建一个softSerial对象,RX:10,TX:11 SoftwareSerial softSerial(10, 11); void setup() { //初始化串口通信 Serial.begin(9600); //初始化软串口通信 softSerial.begin(9600); // 监听软串口通信 softSerial.listen(); } // 两个字符串分别用于存储AB两端传输来的数据 String device_B_String = ""; String device_A_String = ""; void loop() { // 读取从计算机传入的数据,并通过softSerial发送给设备B if (Serial.available() > 0) { if(Serial.peek() != '\n') { device_B_String += (char)Serial.read(); } else { Serial.read(); Serial.print("you said: "); Serial.println( device_B_String ); softSerial.println( device_B_String ); device_B_String = ""; } } //读取从设备A传入的数据,并在串口监视器中显示 if (softSerial.available() > 0) { if(softSerial.peek() != '\n') { device_A_String += (char)softSerial.read(); } else { softSerial.read(); Serial.print("device A said: "); Serial.println( device_A_String ); device_A_String = ""; } } }
5.3.4 主机写数据,从机接收数据
// Wire Master Writer // by Nicholas Zambetti <http://www.zambetti.com> // Demonstrates use of the Wire library // Writes data to an I2C/TWI slave device // Refer to the "Wire Slave Receiver" example for use with this // Created 29 March 2006 // This example code is in the public domain. #include <Wire.h> void setup() { //作为主机加入到IIC总线 Wire.begin(); } byte x = 0; void loop() { Wire.beginTransmission(4); //向地址为4的从机传送数据 Wire.write("x is "); // 发送5个字节的字符串 Wire.write(x); // 发送1个字节的数据 Wire.endTransmission(); // 结束传送 x++; delay(500); }
// Wire Slave Receiver // by Nicholas Zambetti <http://www.zambetti.com> // Demonstrates use of the Wire library // Receives data as an I2C/TWI slave device // Refer to the "Wire Master Writer" example for use with this // Created 29 March 2006 // This example code is in the public domain. #include <Wire.h> void setup() { //作为从机加入IIC总线,从机地址为4 Wire.begin(4); //注册一个IIC事件 Wire.onReceive(receiveEvent); //初始化串口 Serial.begin(9600); } void loop() { delay(100); } // 当主机发送的数据被接收到时,将触发receiveEvent事件 void receiveEvent(int howMany) { // 循环读取接收到的数据,最后一个数据单独读取 while(1 < Wire.available()) { char c = Wire.read(); // 以字符形式接收数据 Serial.print(c); // 串口输出该字符 } int x = Wire.read(); // 以整型形式接收数据 Serial.println(x); //串口输出该整形变量 }
5.3.5 从机发送数据,主机读取数据
// Wire Master Reader // by Nicholas Zambetti <http://www.zambetti.com> // Demonstrates use of the Wire library // Reads data from an I2C/TWI slave device // Refer to the "Wire Slave Sender" example for use with this // Created 29 March 2006 // This example code is in the public domain. #include <Wire.h> void setup() { //作为主机加入IIC总线 Wire.begin(); Serial.begin(9600); // 初始化串口通信 } void loop() { Wire.requestFrom(2, 6); // 向2号从机请求6个字节的数据 while(Wire.available())// 等待从机发送完数据 { char c = Wire.read(); // 将数据作为字符接收 Serial.print(c); // 串口输出字符 } delay(500); }
// Wire Slave Sender // by Nicholas Zambetti <http://www.zambetti.com> // Demonstrates use of the Wire library // Sends data as an I2C/TWI slave device // Refer to the "Wire Master Reader" example for use with this // Created 29 March 2006 // This example code is in the public domain. #include <Wire.h> void setup() { // 作为从机加入IIC总线,并将地址设为2 Wire.begin(2); // 注册一个事件,用于相应主机的数据请求 Wire.onRequest(requestEvent); } void loop() { delay(100); } // 每当主机请求数据时,该函数便会执行 // 在setup()中,该函数被注册为一个事件 void requestEvent() { Wire.write("hello "); // 用6个字节的信息回应主机的请求,hello后带一个空格 }
5.3.10 实验:使用数字电位器AD5206
/* Digital Pot Control This example controls an Analog Devices AD5206 digital potentiometer. The AD5206 has 6 potentiometer channels. Each channel's pins are labeled */ // 引用SPI库 #include <SPI.h> // 设置10号引脚控制AD5206的SS脚 const int slaveSelectPin = 10; void setup() { // 设置SS为输出 pinMode (slaveSelectPin, OUTPUT); // 初始化SPI SPI.begin(); } void loop() { // 分别操作6个通道的数字电位器 for (int channel = 0; channel < 6; channel++) { // 逐渐增大每个通道的阻值 for (int level = 0; level < 255; level++) { digitalPotWrite(channel, level); delay(10); } // 延时一段时间 delay(100); // 逐渐减小每个通道的阻值 for (int level = 0; level < 255; level++) { digitalPotWrite(channel, 255 - level); delay(10); } } } int digitalPotWrite(int address, int value) { // 将SS输出低电平,选择能这个设备 digitalWrite(slaveSelectPin,LOW); // 向SPI传输地址和对应的配置值 SPI.transfer(address); SPI.transfer(value); //将SS输出高电平,取消选择这个设备 digitalWrite(slaveSelectPin,HIGH); }
5.3.12 实验:使用74HC595扩展I/O口
/* 使用74HC595扩展I/O (shiftOut串行输出的使用) */ // ST_CP连接8号引脚 int latchPin = 8; // SH_CP 连接12号引脚 int clockPin = 12; // DS连接11号引脚 int dataPin = 11; void setup() { //初始化模拟SPI引脚 pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { //count up routine for (int j = 0; j < 256; j++) { //当你传输数据时,STCP需要保持低电平 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, j); // 传输完数据后,将STCP拉高 // 此时74HC595会更新并行引脚输出状态 digitalWrite(latchPin, HIGH); delay(1000); } }
6.1.2 EEPROM写入操作
/* * EEPROM Write * Stores values read from analog input 0 into the EEPROM. * These values will stay in the EEPROM when the board is * turned off and may be retrieved later by another sketch. */ #include <EEPROM.h> // EEPROM 的当前地址,即你将要写入的地址,这里就是从0开始写 int addr = 0; void setup() { } void loop() { //模拟值读出后是一个0-1024的值,但每字节的大小为0-255 //所以这里将值除以4再存储到val int val = analogRead(0) / 4; // 写入数据到对应的EEPROM空间 // 即使Arduino断电,数据也会保存在EEPROM里 EEPROM.write(addr, val); // 逐字节写入数据 // 当EEPROM空间写满后,重新从0地址开始写 addr = addr + 1; if (addr == 512) addr = 0; delay(100); }
6.1.3 EEPROM读取操作
/* * EEPROM Read * Reads the value of each byte of the EEPROM and prints it * to the computer. * This example code is in the public domain. */ #include <EEPROM.h> // 从地址0处开始读取EEPROM的值 int address = 0; byte value; void setup() { //初始化串口,并等待计算机打开串口 Serial.begin(9600); while (!Serial) { ; //等待串口连接,该功能仅支持Arduino Leonardo } } void loop() { // 从当前EEPROM地址中读取一个字节数据 value = EEPROM.read(address); Serial.print(address); Serial.print("\t"); Serial.print(value, DEC); Serial.println(); // 前进到下一个EEPROM地址 address = address + 1; //当读到EEPROM尾部时,跳转到起始地址0处 if (address == 512) address = 0; delay(500); }
6.1.4 EEPROM清除操作
/* * EEPROM Clear * Sets all of the bytes of the EEPROM to 0. * This example code is in the public domain. */ #include <EEPROM.h> void setup() { // 让EEPROM的512字节内容全部清零 for (int i = 0; i < 512; i++) EEPROM.write(i, 0); // 清零工作完成后,将L灯点亮,提示EEPROM清零完成 digitalWrite(13, HIGH); } void loop(){ }
6.1.5 使用共用体存储各类型数据到EEPROM
/* OpenJumper Examples 写入float类型到EEPROM 奈何col 2013.2.2 www.openjumper.cn */ #include <EEPROM.h> union data { float a; byte b[4]; }; data c; int addr = 0; int led = 13; void setup() { c.a=987.65; for(int i=0;i<4;i++) EEPROM.write(i, c.b[i]); pinMode(led, OUTPUT); } void loop() { //LED闪烁,提示任务已完成 digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); delay(1000); }
/* OpenJumper Examples 从EEPROM读出float类型 奈何col 2013.2.2 www.openjumper.cn */ #include <EEPROM.h> union data { float a; byte b[4]; }; data c; int addr = 0; int led = 13; void setup(){ for(int i=0;i<4;i++) c.b[i]=EEPROM.read(i); Serial.begin(9600); } void loop(){ //输出 Serial.println(c.a); delay(1000); }
6.1.9 创建文件
/* OpenJumper SD Module 创建文件 www.openjumper.cn */ #include <SD.h> File myFile; void setup(){ //我们在2号引脚上连接一个按键模块,用以控制程序开始 pinMode(2,INPUT_PULLUP); while(digitalRead(2)){} // 初始化串口通信 Serial.begin(9600); Serial.print("Initializing SD card..."); // Arduino上的SS引脚(UNO的10号引脚, Mega的53号引脚) // 必须保持在输出模式,否则SD库无法工作 pinMode(10, OUTPUT); if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); if (SD.exists("arduino.txt")) { Serial.println("arduino.txt exists."); } else { Serial.println("arduino.txt doesn't exist."); } // 打开一个新文件,并立即关闭。 // 如果指定文件不存在,将用该名称创建一个文件 Serial.println("Creating arduino.txt..."); SD.open("arduino.txt",FILE_WRITE); myFile.close(); // 检查文件是否存在 if (SD.exists("arduino.txt")) { Serial.println("arduino.txt exists."); } else { Serial.println("arduino.txt doesn't exist."); } } void loop(){ // 该程序只运行一次,所以在loop中没有其他操作 }
6.1.10 删除文件
/* OpenJumper SD Module 删除文件 www.openjumper.cn */ #include <SD.h> File myFile; void setup(){ //我们在2号引脚上连接一个按键模块,用以控制程序开始 pinMode(2,INPUT_PULLUP); while(digitalRead(2)){} // 初始化串口通信 Serial.begin(9600); Serial.print("Initializing SD card..."); // Arduino上的SS引脚(UNO的10号引脚, Mega的53号引脚) // 必须保持在输出模式否则SD库无法工作 pinMode(10, OUTPUT); if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); if (SD.exists("arduino.txt")) { Serial.println("arduino.txt exists."); } else { Serial.println("arduino.txt doesn't exist."); } // 删除文件 Serial.println("Removing arduino.txt..."); SD.remove("arduino.txt"); // 检查文件是否存在 if (SD.exists("arduino.txt")) { Serial.println("arduino.txt exists."); } else { Serial.println("arduino.txt doesn't exist."); } } void loop(){ // 该程序只运行一次,所以在loop中没有其他操作 }
6.1.11 写文件
/* OpenJumper SD Module 写文件 www.openjumper.cn */ #include <SD.h> File myFile; void setup() { //我们在2号引脚上连接一个按键模块,用以控制程序开始 pinMode(2,INPUT_PULLUP); while(digitalRead(2)){} // 初始化串口通信 Serial.begin(9600); while (!Serial) { ; // 等待串口连接,该方法只适用于Leonardo } Serial.print("Initializing SD card..."); // Arduino上的SS引脚(UNO的10号引脚, Mega的53号引脚) // 必须保持在输出模式否则SD库无法工作 pinMode(10, OUTPUT); if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); // 打开文件,需要注意的是一次只能打开一个文件 // 如果你要打开另一个文件,必须先关闭之前打开的文件 myFile = SD.open("arduino.txt", FILE_WRITE); // 如果文件打开正常,那么开始写文件 if (myFile) { Serial.print("Writing to arduino.txt..."); myFile.println("Hello Arduino!"); // 关闭这个文件 myFile.close(); Serial.println("done."); } else { // 如果文件没有被正常打开,那么输出错误提示 Serial.println("error opening arduino.txt "); } } void loop() { //程序只运行一次,因此loop中没有其他操作 }
6.1.12 读文件
/* OpenJumper SD Module 读文件 www.openjumper.cn */ #include <SD.h> File myFile; void setup(){ //我们在2号引脚上连接一个按键模块,用以控制程序开始 pinMode(2,INPUT_PULLUP); while(digitalRead(2)){} // 初始化串口通信 Serial.begin(9600); while (!Serial) { ; // 等待串口连接,该方法只适用于Leonardo } Serial.print("Initializing SD card..."); // Arduino上的SS引脚(UNO的10号引脚, Mega的53号引脚) // 必须保持在输出模式否则SD库无法工作 pinMode(10, OUTPUT); if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); // 打开文件,需要注意的是,一次只能打开一个文件 // 如果你要打开另一个文件,必须先关闭之前打开的文件 myFile = SD.open("arduino.txt"); // 如果文件打开正常,那么开始读文件 if (myFile) { Serial.println("arduino.txt:"); // 读取文件数据,直到文件结束 while (myFile.available()) { Serial.write(myFile.read()); } // 关闭这个文件 myFile.close(); } else { //如果文件没有正常打开,那么输出错误提示 Serial.println("error opening arduino.txt "); } } void loop(){ //程序只运行一次,因此loop中没有其他操作 }
6.2.2 DHT11温湿度传感器
[vc_button title=”下载DHT11类库” target=”_blank” color=”wpb_button” icon=”none” size=”wpb_regularsize” href=”http://x.openjumper.cn/dht11/”]
/* OpenJumper Examples DHT11 Moudle www.openjumper.cn */ #include <dht11.h> dht11 DHT11; #define DHT11PIN 2 void setup() { Serial.begin(9600); } void loop() { Serial.println("\n"); // 读取传感器数据 int chk = DHT11.read(DHT11PIN); Serial.print("Read sensor: "); // 检测数据是否正常接收 switch (chk) { case DHTLIB_OK: Serial.println("OK"); break; case DHTLIB_ERROR_CHECKSUM: Serial.println("Checksum error"); break; case DHTLIB_ERROR_TIMEOUT: Serial.println("Time out error"); break; default: Serial.println("Unknown error"); break; } // 输出湿度与温度信息 Serial.print("Humidity (%): "); Serial.println(DHT11.humidity); Serial.print("Temperature (oC): "); Serial.println(DHT11.temperature); delay(1000); }
6.2.3 温湿度记录器
/* OpenJumper Example 环境记录器 奈何col 2013.3.14 www.openjumper.cn */ #include <SD.h> #include <dht11.h> dht11 DHT11; #define DHT11_PIN 2 // DHT11引脚 #define LIGHT_PIN A0// 光敏引脚 const int chipSelect = 4;// TF卡CS选择引脚 void setup() { // 初始化串口 Serial.begin(9600); //将SS引脚设置为输出状态,UNO为10号引脚 pinMode(10, OUTPUT); // 初始化SD卡 Serial.println("Initializing SD card"); if (!SD.begin(chipSelect)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); } void loop() { // 读取DHT11的数据 Serial.println("Read data from DHT11"); DHT11.read(DHT11_PIN); // 读取光敏模块数据 Serial.println("Read data from Light Sensor"); int light=analogRead(LIGHT_PIN); // 打开文件并将DHT11检测到的数据写入文件 Serial.println("Open file and write data"); File dataFile = SD.open("datalog.txt", FILE_WRITE); if (dataFile) { dataFile.print(DHT11.humidity); dataFile.print(","); dataFile.print(DHT11.temperature); dataFile.print(","); dataFile.println(light); dataFile.close(); } else { Serial.println("error opening datalog.txt"); } //延时一分钟 Serial.println("Wait for next loop"); delay(60000); }
7.2 红外接收
[vc_button title=”下载IRremote类库” target=”_blank” color=”wpb_button” icon=”none” size=”wpb_regularsize” href=”http://x.openjumper.cn/ir-kit/”]
/* * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv * An IR detector/demodulator must be connected to the input RECV_PIN. * Version 0.1 July, 2009 * Copyright 2009 Ken Shirriff * http://arcfn.com */ #include <IRremote.h> int RECV_PIN = 11;// 红外一体化接收头连接到Arduino 11号引脚 IRrecv irrecv(RECV_PIN); decode_results results;// 用于存储编码结果的对象 void setup() { Serial.begin(9600);// 初始化串口通信 irrecv.enableIRIn();// 初始化红外解码 } void loop() { if (irrecv.decode(&results)) { Serial.println(results.value, HEX); irrecv.resume(); // 接收下一个编码 } }
7.3 红外发射
/* * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend * An IR LED must be connected to Arduino PWM pin 3. * Version 0.1 July, 2009 * Copyright 2009 Ken Shirriff * http://arcfn.com */ #include <IRremote.h> IRsend irsend; void setup() { Serial.begin(9600); // 初始化串口通信 } void loop() { if (Serial.read() != -1) { for (int i = 0; i < 3; i++) { irsend.sendSony(0xa90, 12); // 发送索尼电视机电源开关对应的编码 delay(40); } } }
7.4 实验:遥控家电设备
/* 获取原始红外信号 OpenJumper38K红外一体化接收模块 2013.4.24奈何col */ #include <IRremote.h> int RECV_PIN = 11; //红外接收模块连接在11脚 IRrecv irrecv(RECV_PIN); decode_results results; void setup() { Serial.begin(9600); irrecv.enableIRIn(); } void loop() { if (irrecv.decode(&results)) { dump(&results); irrecv.resume(); } } void dump(decode_results *results) { int count = results->rawlen; Serial.print("Raw ("); Serial.print(count); Serial.print("): "); for (int i = 0; i < count; i++) { Serial.print(results->rawbuf[i]*USECPERTICK); Serial.print(","); } Serial.println(); }
#include <IRremote.h> IRsend irsend; unsigned int on_button[243]={ 8300,4150,550,600,500,1550,600,1600,500,600,500,1600,550,600,500,1550,600,500,550,1650,500,1600,550,1600,550,550,550,1550,550,1650,500,1650,500,550,550,550,550,550,500,550,550,550,550,550,500,600,500,600,500,550,500,1600,550,550,550,550,550,550,500,550,550,550,550,600,450,600,450,600,550,1600,550,550,500,600,500,550,550,1600,550,550,500,550,550,550,550,550,550,550,500,550,550,550,550,550,500,550,550,550,550,550,550,550,500,550,550,550,500,600,500,550,550,550,550,550,500,600,500,550,550,550,500,600,500,550,550,550,500,600,500,550,550,550,550,550,500,550,550,550,550,550,500,550,550,550,550,550,500,600,500,550,550,550,500,600,500,550,550,550,550,550,500,550,550,550,550,550,550,550,500,550,550,550,550,550,500,550,550,550,550,550,500,550,550,550,550,550,500,600,500,550,550,550,500,600,500,550,550,550,550,550,500,550,550,550,550,550,500,600,500,550,550,550,500,600,500,550,550,550,500,600,500,550,550,550,550,550,500,550,550,1600,550,1600,550,1600,550,1600,550,500,550,550,550,550,550}; void setup(){} void loop() { irsend.sendRaw(open_button,243,38); //发送原始编码数据, delay(5000); }
8.1.5 实验:HelloWorld
/* LiquidCrystal Library - Hello World Demonstrates the use a 16x2 LCD display. The LiquidCrystal library works with all LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch prints "Hello World!" to the LCDand shows the time. */ // 包含头文件 #include <LiquidCrystal.h> // 实例化一个名为lcd的LiquidCrysta类型对象,并初始化相关引脚 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { // 设置LCD有几列几行,1602LCD为16列2行 lcd.begin(16, 2); //打印一段信息到LCD上 lcd.print("hello, world!"); } void loop() { // 将光标设置在列 0, 行 1 // 注意:在1602 LCD上行列的标号都是从0开始 lcd.setCursor(0, 1); // 将系统运行时间打印到LCD上 lcd.print(millis()/1000); }
8.1.6 实验:将串口输入数据显示到1602 LCD上
/* LiquidCrystal Library - Serial Input Demonstrates the use a 16x2 LCD display. The LiquidCrystal library works with all LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch displays text sent over the serial port (e.g. from the Serial Monitor) on an attached LCD. */ // 包含头文件 #include <LiquidCrystal.h> //实例化一个名为lcd的LiquidCrysta类型对象,并初始化相关引脚 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup(){ //设置LCD有几列几行,1602LCD为16列2行 lcd.begin(16, 2); // 初始化串口通信功能 Serial.begin(9600); } void loop() { // 当串口接收到字符时… if (Serial.available()) { // 等待所有数据输入进缓冲区 delay(100); // 清屏 lcd.clear(); // 读取所有可用的字符 while (Serial.available() > 0) { // 将字符一个一个的输出到LCD上。 lcd.write(Serial.read()); } } }
8.1.7 实验:显示滚动效果
/* LiquidCrystal Library - scrollDisplayLeft() and scrollDisplayRight() Demonstrates the use a 16x2 LCD display. The LiquidCrystal library works with all LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch prints "Hello World!" to the LCD and uses the scrollDisplayLeft() and scrollDisplayRight() methods to scroll the text. */ //包含头文件 #include <LiquidCrystal.h> //实例化一个名为lcd的LiquidCrysta类型对象,并初始化相关引脚 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { //设置LCD有几列几行,1602LCD为16列2行 lcd.begin(16, 2); // 打印一段信息到LCD上 lcd.print("hello, world!"); delay(1000); } void loop() { // 向左滚动13格 // 移动到显示区域以外 for (int positionCounter = 0; positionCounter < 13; positionCounter++) { // 向左移动一格 lcd.scrollDisplayLeft(); // 等待一会儿 delay(150); } // 向右滚动29格 //移动到显示区域以外 for (int positionCounter = 0; positionCounter < 29; positionCounter++) { // 向右移动一格 lcd.scrollDisplayRight(); //等待一会儿 delay(150); } // 向左滚动16格 // 移回中间位置 for (int positionCounter = 0; positionCounter < 16; positionCounter++) { // 向左移动一格 lcd.scrollDisplayLeft(); //等待一会儿 delay(150); } // 每次循环结束后,等待一会儿,再开始下一次循环 delay(1000); }
8.1.8 实验:显示自定义字符
/* LiquidCrystal Library - Custom Characters Demonstrates how to add custom characters on an LCD display. The LiquidCrystal library works with all LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch prints "I <heart> Arduino!" and a little dancing man to the LCD. */ // 包含头文件 #include <LiquidCrystal.h> //实例化一个名为lcd的LiquidCrysta类型对象,并初始化相关引脚 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // 自定义字符: byte heart[8] = { 0b00000, 0b01010, 0b11111, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000 }; byte smiley[8] = { 0b00000, 0b00000, 0b01010, 0b00000, 0b00000, 0b10001, 0b01110, 0b00000 }; byte frownie[8] = { 0b00000, 0b00000, 0b01010, 0b00000, 0b00000, 0b00000, 0b01110, 0b10001 }; byte armsDown[8] = { 0b00100, 0b01010, 0b00100, 0b00100, 0b01110, 0b10101, 0b00100, 0b01010 }; byte armsUp[8] = { 0b00100, 0b01010, 0b00100, 0b10101, 0b01110, 0b00100, 0b00100, 0b01010 }; void setup() { // 创建一个新字符 lcd.createChar(8, heart); // 创建一个新字符 lcd.createChar(1, smiley); // 创建一个新字符 lcd.createChar(2, frownie); // 创建一个新字符 lcd.createChar(3, armsDown); // 创建一个新字符 lcd.createChar(4, armsUp); //设置LCD有几列几行,1602LCD为16列2行 lcd.begin(16, 2); // 输出信息到LCD上 lcd.print("I "); lcd.write(8); lcd.print(" Arduino! "); lcd.write(1); } void loop() { // 读A0引脚连接的电位器的值 int sensorReading = analogRead(A0); // 将数据范围转换到 200 - 1000: int delayTime = map(sensorReading, 0, 1023, 200, 1000); // 设置光标在第二行,第五列 lcd.setCursor(4, 1); // 小人手臂放下 lcd.write(3); delay(delayTime); lcd.setCursor(4, 1); // 小人手臂抬起 lcd.write(4); delay(delayTime); }
8.2.1.1 设置时间
[vc_button title=”下载Time、DS1307类库” target=”_blank” color=”wpb_button” icon=”none” size=”wpb_regularsize” href=”http://x.openjumper.cn/rtc1307/”]
/* 设置DS1307的时间 RTC模块的使用 */ //声明这个模块用到的三个类库 #include <DS1307RTC.h> #include <Time.h> #include <Wire.h> const char *monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; // tmElements_t为保存日期时间的结构体类型 tmElements_t tm; void setup() { bool parse=false; bool config=false; // 获取编译时的时间和日期 if (getDate(__DATE__) && getTime(__TIME__)) { parse = true; // 将时间数据写入RTC模块 if (RTC.write(tm)) { config = true; } } Serial.begin(9600); delay(200); if (parse && config) { Serial.print("DS1307 configured Time="); Serial.print(__TIME__); Serial.print(", Date="); Serial.println(__DATE__); } else if (parse) { Serial.println("DS1307 Communication Error :-{"); Serial.println("Please check your circuitry"); } else { Serial.print("Could not parse info from the compiler, Time=\""); Serial.print(__TIME__); Serial.print("\", Date=\""); Serial.print(__DATE__); Serial.println("\""); } } void loop() { } // 获取时间数据并存入tm bool getTime(const char *str) { int Hour, Min, Sec; if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false; tm.Hour = Hour; tm.Minute = Min; tm.Second = Sec; return true; } // 获取日期数据并存入tm bool getDate(const char *str) { char Month[12]; int Day, Year; uint8_t monthIndex; if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false; for (monthIndex = 0; monthIndex < 12; monthIndex++) { if (strcmp(Month, monthName[monthIndex]) == 0) break; } if (monthIndex >= 12) return false; tm.Day = Day; tm.Month = monthIndex + 1; tm.Year = CalendarYrToTm(Year); return true; }
8.2.1.2 读出时间
#include <DS1307RTC.h> #include <Time.h> #include <Wire.h> void setup() { Serial.begin(9600); delay(200); Serial.println("DS1307RTC Read Test"); Serial.println("-------------------"); } void loop() { tmElements_t tm; // 读出DS1307中的时间数据 if (RTC.read(tm)) { Serial.print("Ok, Time = "); print2digits(tm.Hour); Serial.write(':'); print2digits(tm.Minute); Serial.write(':'); print2digits(tm.Second); Serial.print(", Date (D/M/Y) = "); Serial.print(tm.Day); Serial.write('/'); Serial.print(tm.Month); Serial.write('/'); Serial.print(tmYearToCalendar(tm.Year)); Serial.println(); } else { if (RTC.chipPresent()) { Serial.println("The DS1307 is stopped. Please run the SetTime"); Serial.println("example to initialize the time and begin running."); Serial.println(); } else { Serial.println("DS1307 read error! Please check the circuitry."); Serial.println(); } delay(9000); } delay(1000); } void print2digits(int number) { if (number >= 0 && number < 10) { Serial.write('0'); } Serial.print(number); }
8.2.2 电子时钟
/* DS1307和1602 LCD制作电子时钟 */ // 引用会使用到的四个库文件 #include <DS1307RTC.h> #include <Time.h> #include <Wire.h> #include <LiquidCrystal.h> // 实例化一个名为lcd的LiquidCrysta类型对象,并初始化相关引脚 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { // 设置LCD有几列几行,1602LCD为16列2行 lcd.begin(16, 2); // 打印一段信息到LCD上 lcd.print("This is a Clock"); delay(3000); lcd.clear(); } void loop() { tmElements_t tm; // 读出DS1307中的时间数据,并存入tm中 if (RTC.read(tm)) { // 清除屏幕显示内容 lcd.clear(); //在LCD第一行输出日期信息 lcd.setCursor(0, 0); lcd.print(tmYearToCalendar(tm.Year)); lcd.print("-"); lcd.print(tm.Month); lcd.print("-"); lcd.print(tm.Day); //在LCD第二行输出时间信息 lcd.setCursor(8, 1); lcd.print(tm.Hour); lcd.print(":"); lcd.print(tm.Minute); lcd.print(":"); lcd.print(tm.Second); } // 如果读取数据失败,则输出错误提示 else { lcd.setCursor(0, 1); lcd.print("error"); } //每秒钟更新一次显示内容 delay(1000); }
8.3.4 纯文本显示
[vc_button title=”下载u8glib类库” target=”_blank” color=”wpb_button” icon=”none” size=”wpb_regularsize” href=”http://x.openjumper.cn/mini12864/”]
/* 使用u8glib显示字符串 图形显示器:OpenJumper MINI 12864 控制器:Arduino UNO */ // 包含头文件,并新建u8g对象 #include "U8glib.h" U8GLIB_MINI12864 u8g(10, 9, 8); // draw函数用于包含实现显示内容的语句 void draw() { // 设置字体 u8g.setFont(u8g_font_unifont); // 设置文字及其显示位置 u8g.drawStr( 0, 20, "Hello Arduino"); } void setup() { } void loop() { // u8glib图片循环结构: u8g.firstPage(); do { draw(); } while( u8g.nextPage() ); // 等待一定时间后重绘 delay(500); }
8.3.5 数据显示
/* 使用print函数输出数据到LCD 图形显示器:OpenJumper MINI 12864 控制器:Arduino UNO */ #include "U8glib.h" U8GLIB_MINI12864 u8g(10, 9, 8); String t1="OpenJumper"; String t2="MINI"; int t3=12864; // draw函数用于包含实现显示内容的语句 void draw(void) { // 设定字体->指定输出位置->输出数据 u8g.setFont(u8g_font_ncenB14); u8g.setPrintPos(0, 20); u8g.print(t1); u8g.setFont(u8g_font_unifont); u8g.setPrintPos(50, 40); u8g.print(t2); u8g.setPrintPos(45, 60); u8g.print(t3); } void setup(void) { } void loop(void){ // u8glib图片循环结构: u8g.firstPage(); do { draw(); } while( u8g.nextPage() ); // 等待一定时间后重绘 delay(500); }
8.3.7 实验:显示图片
/* 使用u8glib显示位图 图形显示器:OpenJumper MINI 12864 控制器:Arduino UNO */ #include "U8glib.h" U8GLIB_MINI12864 u8g(10, 9, 8); /*宽度x高度=96x64*/ #define width 96 #define height 64 static unsigned char bitmap[] U8G_PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x80,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0xF0,0x00,0x00,0xE0,0xFF,0xFF,0x1F, 0x00,0x78,0x00,0x00,0x00,0xF0,0x1F,0x00,0x7C,0x00,0x00,0xFC,0xC0,0x7F,0x00,0x00, //为节约篇幅,此处代码省略 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xE0, 0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; void draw(void) { // graphic commands to redraw the complete screen should be placed here u8g.drawXBMP( 0, 0, width, height, bitmap); } void setup(void) { } void loop(void) { u8g.firstPage(); do { draw(); } while( u8g.nextPage() ); // 延时一定时间,再重绘图片 delay(500); }
9.2 模拟键盘输入信息
/* Keyboard Button test 该程序仅适用于Leonardo、Micro. 当按下按键时,发送文本. created 24 Oct 2011 modified 27 Mar 2012 by Tom Igoe This example code is in the public domain. http://www.arduino.cc/en/Tutorial/KeyboardButton */ const int buttonPin = 2; // 按键连接引脚 int previousButtonState = HIGH; // 之前按键状态 int counter = 0; // 按键计数器 void setup() { // 初始化按键引脚,如果没有上拉电阻,需要使用INPUT_PULLUP pinMode(buttonPin, INPUT); // 初始化模拟键盘功能 Keyboard.begin(); } void loop() { // 读按键状态 int buttonState = digitalRead(buttonPin); // 如果按键状态改变,且当前按键状态为高电平 if ((buttonState != previousButtonState)&& (buttonState == HIGH)) { // 按键计数器加1 counter++; // 模拟键盘输入信息 Keyboard.print("You pressed the button "); Keyboard.print(counter); Keyboard.println(" times."); } // 保存当前按键状态,用于下一次比较 previousButtonState = buttonState; }
9.2.2 模拟键盘组合按键
/* Keyboard logout This sketch demonstrates the Keyboard library. When you connect pin 2 to ground, it performs a logout. It uses keyboard combinations to do this, as follows: On Windows, CTRL-ALT-DEL followed by ALT-l On Ubuntu, CTRL-ALT-DEL, and ENTER On OSX, CMD-SHIFT-q To wake: Spacebar. Circuit: * Arduino Leonardo or Micro * wire to connect D2 to ground. created 6 Mar 2012 modified 27 Mar 2012 by Tom Igoe This example is in the public domain http://www.arduino.cc/en/Tutorial/KeyboardLogout */ #define OSX 0 #define WINDOWS 1 #define UBUNTU 2 //设置你的操作系统 int platform = WINDOWS; void setup() { // 将2号引脚设置为输入状态 //并开启内部上拉电阻 pinMode(2, INPUT_PULLUP); Keyboard.begin(); } void loop() { while (digitalRead(2) == HIGH) { // 等待2号引脚变成低电平 delay(500); } delay(1000); switch (platform) { case OSX: Keyboard.press(KEY_LEFT_GUI); // Shift+Q组合按键 Keyboard.press(KEY_LEFT_SHIFT); Keyboard.press('Q'); delay(100); Keyboard.releaseAll(); //回车确认: Keyboard.write(KEY_RETURN); break; case WINDOWS: // CTRL+ALT+DEL组合按键 Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_DELETE); delay(100); Keyboard.releaseAll(); //ALT+L组合按键: delay(2000); Keyboard.press(KEY_LEFT_ALT); Keyboard.press('l'); Keyboard.releaseAll(); break; case UBUNTU: // CTRL+ALT+DEL组合按键 Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_DELETE); delay(1000); Keyboard.releaseAll(); // 回车键确认登出 Keyboard.write(KEY_RETURN); break; } // 进入死循环,相当于结束程序 while(true); }
9.2.3 实验:使用摇杆模块控制计算机鼠标
/* OpenJumper Leonardo Example 使用摇杆扩展板模拟USB鼠标 http://www.openjumper.cn/ http://x.openjumper.cn/joystick-shield/ */ //摇杆硬件定义 int enableButton = 7; // 摇杆按键,用作鼠标功能使能按键 int upButton = 6; // 上方按键,模拟滚轮向上 int downButton = 3; // 下方按键,模拟滚轮向下 int leftButton = 5; // 左按键,模拟鼠标左键 int rightButton = 4; // 右按键,模拟鼠标右键 int xAxis = A1; // 遥感X轴 int yAxis = A0; // 遥感Y轴 int mouseSensitivity = 12; //鼠标灵敏度 int wheelSensitivity = 1; //滚轮灵敏度 boolean enable = false; //模拟鼠标功能是否可用 boolean lastEnableButtonState = HIGH; // 上一次使能按键读值 void setup() { //初始化各个按键 pinMode(enableButton,INPUT); pinMode(upButton,INPUT); pinMode(downButton,INPUT); pinMode(leftButton,INPUT); pinMode(rightButton,INPUT); // 开始控制鼠标 Mouse.begin(); } void loop() { // 使能按键按一次使能,再按一次不使能 boolean EnableButtonState = digitalRead(enableButton); if( (EnableButtonState == LOW) && (EnableButtonState != lastEnableButtonState) ) { enable=!enable; } lastEnableButtonState=EnableButtonState; if (enable) { // 读取鼠标偏移值 int x = readAxis(xAxis); int y = readAxis(yAxis); // 读取鼠标滚轮值 int wheel=0; if(digitalRead(upButton)==LOW){ wheel=wheelSensitivity; } else if(digitalRead(downButton)==LOW){ wheel=-wheelSensitivity; } // 移动鼠标位置或滚轮 Mouse.move(x, y, wheel); //点击鼠标左右键 ifClickButton(leftButton,MOUSE_LEFT); ifClickButton(rightButton,MOUSE_RIGHT); // 延时一段时间,可以通过该值调整鼠标移动速度 delay(10); } } //读取摇杆数据 // 即摇杆电位器的偏移量 int readAxis(int thisAxis) { int reading = analogRead(thisAxis); // 将读出的模拟值,缩小到一定范围 reading = map(reading, 0, 1023, 0, mouseSensitivity); // 计算出一个鼠标偏移量 int distance = reading - (mouseSensitivity/2); int threshold = mouseSensitivity/4; //如果电位器偏移量较小则不移动鼠标 if (abs(distance) < threshold) { distance = 0; } // 返回鼠标偏移量 return distance; } //判断按键是否被按下 void ifClickButton(int Buttonpin,uint8_t Button) { if (digitalRead(Buttonpin) == LOW){ if (!Mouse.isPressed(Button)) { Mouse.press(Button); } } else if (Mouse.isPressed(Button)) { Mouse.release(Button); } }
9.2.4 项目:PPT播放遥控器
/* 按键对应关系: ON> FFA25D OFF>FFE21D UP> FF9867 DOWN> FFB04F */ #include <IRremote.h> int RECV_PIN = 11; IRrecv irrecv(RECV_PIN); decode_results results; void setup(){ Serial.begin(9600); // 开始接收红外信号 irrecv.enableIRIn(); } void loop() { // 接收红外编码 if (irrecv.decode(&results)) { Serial.println(results.value, HEX); // 准备接收下一次编码 irrecv.resume(); } switch (results.value) { // 遥控器ON键>键盘F5键>开始播放 case 0xFFA25D: Keyboard.press(KEY_F5); Keyboard.releaseAll(); break; // 遥控器OFF键>键盘Esc键>退出播放 case 0xFFE21D: Keyboard.press(KEY_ESC); Keyboard.releaseAll(); break; // 遥控器向上键>键盘Esc键>退出播放 case 0xFF9867: Keyboard.press(KEY_LEFT_ARROW); Keyboard.releaseAll(); break; // 遥控器向下键>键盘Esc键>退出播放 case 0xFFB04F: Keyboard.press(KEY_RIGHT_ARROW); Keyboard.releaseAll(); break; } // 清空编码数据,开始下一次接收 results.value = 0; }
10.3.1 自定义IP地址
#include <SPI.h> #include <Ethernet.h> // 设置一个MAC地址 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //设置一个IP地址 byte ip[] = { 192, 168, 1, 177 }; void setup(){ // 初始化Ethernet功能 Ethernet.begin(mac, ip); } void loop(){ }
10.3.2 DHCP获取IP地址
/* OpenJumper DHCP Example http://www.openjumper.cn/ http://x.openjumper.cn/ethernet/ */ #include <SPI.h> #include <Ethernet.h> // 设置MAC地址 byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; void setup() { // 初始化串口通信 Serial.begin(9600); // 开启Ethernet连接: if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); // 连接失败,便进入一个死循环(相当于结束程序运行) for(;;); } // 输出你的本地IP地址 Serial.print("My IP address: "); for (byte thisByte = 0; thisByte < 4; thisByte++) { // 将四个字节的IP地址逐字节输出 Serial.print(Ethernet.localIP()[thisByte], DEC); Serial.print("."); } Serial.println(); } void loop() { }
10.4.1 建立Arduino Telnet聊天服务器
/* OpenJumper ChatServer Example http://www.openjumper.cn/ http://x.openjumper.cn/ethernet/ */ #include <SPI.h> #include <Ethernet.h> // 输入MAC地址和IP地址,此后的设置将会用到 // IP地址需要根据你的本地网络设置 // 网关和子网掩码是可选项,可以不用 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192,168,1, 177); // telnet 默认端口为23 EthernetServer server(23); boolean alreadyConnected = false; // 记录是否之前有客户端被连接 String thisString = ""; void setup() { // 初始化网络设备 Ethernet.begin(mac, ip); // 开始监听客户端 server.begin(); // 初始化串口 Serial.begin(9600); // 串口输出提示信息 Serial.print("Chat server address:"); Serial.println(Ethernet.localIP()); } void loop() { // 等待一个新的客户端连接 EthernetClient client = server.available(); // 当服务器第一次发送数据时,发送一个hello回应 if (client) { if (!alreadyConnected) { // 清除输入缓冲区 client.flush(); Serial.println("We have a new client"); client.println("Hello, client!"); alreadyConnected = true; } if (client.available() > 0) { // 读取从客户端发来的数据 char thisChar = client.read(); thisString += thisChar; // 检测到结束符,便输出字符串 if(thisChar=='\n'){ server.println(thisString); Serial.println(thisString); thisString = ""; } } } }
10.5.3 网页客户端
/* OpenJumper WebClient Example 访问百度,搜索“OpenJumper Arduino” 并返回搜索结果。 http://www.openjumper.cn/ http://x.openjumper.cn/ethernet/ */ #include <SPI.h> #include <Ethernet.h> // 输入MAC地址,及要访问的域名 byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; IPAddress ip(192,168,1,177); char serverName[] = "www.baidu.com"; // 初始化客户端功能 EthernetClient client; void setup() { // 初始化串口通信 Serial.begin(9600); //开始Ethernet连接 if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); // 如果DHCP方式获取IP失败,则使用自定义IP Ethernet.begin(mac, ip); } // 等待1秒钟用于Ethernet扩展板或W5100芯片完成初始化 delay(1000); Serial.println("connecting..."); // 如果连接成功,通过串口输出返回数据 if (client.connect(serverName, 80)) { Serial.println("connected"); // 发送HTTP请求: client.println("GET /s?wd=openjumper+arduino HTTP/1.1"); client.println(); } else { // 如果连接失败则输出提示: Serial.println("connection failed"); } } void loop() { // 如果有可读的服务器返回数据,则读取并输出数据 if (client.available()) { char c = client.read(); Serial.print(c); } //如果服务器中断了连接,则中断客户端功能 if (!client.connected()) { Serial.println(); Serial.println("disconnecting."); client.stop(); // 进入一个死循环,相当于停止程序 while(true); } }
10.5.4 网页服务器
/* OpenJumper WebServer Example 建立一个显示传感器信息的Arduino服务器 http://www.openjumper.cn/ http://x.openjumper.cn/ethernet/ */ #include <SPI.h> #include <Ethernet.h> // 设定MAC地址、IP地址 // IP地址需要参考你的本地网络设置 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192,168,1,177); // 初始化Ethernet库 // HTTP默认端口为80 EthernetServer server(80); void setup() { // 初始化串口通信 Serial.begin(9600); // 开始ethernet连接,并作为服务器初始化 Ethernet.begin(mac, ip); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); } void loop() { // 监听客户端传来的数据 EthernetClient client = server.available(); if (client) { Serial.println("new client"); // 一个Http请求结尾必须带有回车换行 boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); // 如果收到空白行,说明http请求结束,并发送响应消息 if (c == '\n' && currentLineIsBlank) { // 发送标准的HTTP响应 client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); // 添加一个meta刷新标签, 浏览器会每5秒刷新一次 // 如果此处刷新频率设置过高,可能会出现网页的卡死的状况 client.println("<meta http-equiv=\"refresh\" content=\"5\">"); // 输出每个模拟口读到的值 for (int analogChannel = 0; analogChannel < 6; analogChannel++) { int sensorReading = analogRead(analogChannel); client.print("analog input "); client.print(analogChannel); client.print(" is "); client.print(sensorReading); client.println("<br />"); } client.println("</html>"); break; } if (c == '\n') { // 已经开始一个新行 currentLineIsBlank = true; } else if (c != '\r') { // 在当前行已经得到一个字符 currentLineIsBlank = false; } } } // 等待浏览器接收数据 delay(1); // 断开连接 client.stop(); Serial.println("client disonnected"); } }
10.6.2 使用UDP收发数据
/* UDPSendReceive.pde: This sketch receives UDP message strings, prints them to the serial port and sends an "acknowledge" string back to the sender A Processing sketch is included at the end of file that can be used to send and received messages for testing with a computer. created 21 Aug 2010 by Michael Margolis This code is in the public domain. */ #include <SPI.h> #include <Ethernet.h> #include <EthernetUdp.h> // 为你的Arduino设置MAC地址和IP地址 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 0, 177); unsigned int localPort = 8888; // 设置需要监听的端口 // 接收和发送数据的数组 char packetBuffer[UDP_TX_PACKET_MAX_SIZE];//保存收到的数据包的缓冲区 char ReplyBuffer[] = "acknowledged"; // 一个返回的字符串 // 程序中我们需要使用EthernetUDP类库发送接收数据包 EthernetUDP Udp; void setup() { // 初始化网络并开始UDP通信 Ethernet.begin(mac,ip); Udp.begin(localPort); Serial.begin(9600); } void loop() { // 如果有可读数据, 那么读取一个包 int packetSize = Udp.parsePacket(); if(packetSize) { Serial.print("Received packet of size "); Serial.println(packetSize); Serial.print("From "); // 输出IP地址,端口等UDP连接信息 IPAddress remote = Udp.remoteIP(); for (int i =0; i < 4; i++) { Serial.print(remote[i], DEC); if (i < 3) { Serial.print("."); } } Serial.print(", port "); Serial.println(Udp.remotePort()); // 将数据包读进数组 Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE); Serial.println("Contents:"); Serial.println(packetBuffer); // 发送应答,到刚才传输数据包来的设备 Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); Udp.write(ReplyBuffer); Udp.endPacket(); } delay(10); }
10.7 项目:网页控制Arduino
/* OpenJumper WebServer Example 显示室内照度+开关灯控制 通过手机、平板、计算机等设备访问 Arduino Server,就看到当前室内光线照度 在A0引脚连接光敏模块,用于采集室内光线;在2号引脚连接LED模块。 http://www.openjumper.cn/ http://x.openjumper.cn/ethernet/ */ #include <SPI.h> #include <Ethernet.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192,168,1,177); EthernetServer server(80); EthernetClient client; String readString; int Light=2; void setup() { // 初始化串口通信 Serial.begin(9600); // 初始化Ethernet通信 Ethernet.begin(mac, ip); server.begin(); pinMode(Light,OUTPUT); Serial.print("Server is at "); Serial.println(Ethernet.localIP()); } void loop() { // 监听连入的客户端 client = server.available(); if (client) { Serial.println("new client"); // 一次http请求结束都带有一个空行 boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); //将收到的信息都保存在readString函数中 readString += c; // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank) { Serial.print(readString); // 发送HTML文本 SendHTML(); break; } // 检测是否有换行符 if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } // 检测是否有回车符 else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // 等待浏览器接收数据 delay(1); //关闭连接 client.stop(); Serial.println("client disonnected"); // 检查收到的信息中是否有”/?on”,有则开灯 if(readString.indexOf("/?on") >0)//checks for on { digitalWrite(Light, HIGH); Serial.println("Led On"); } // 检查收到的信息中是否有”/?off”,有则关灯 if(readString.indexOf("/?off") >0)//checks for off { digitalWrite(Light, LOW); // set pin 4 low Serial.println("Led Off"); } readString=""; } } // 用于输出HTML文本的函数 void SendHTML() { // 发送标准的HTTP响应 client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head><title>OpenJumper!</title></head>"); // 每十秒刷新一次 client.println("<meta http-equiv=\"refresh\" content=\"10\">"); client.println("<body>"); client.println("<div align=\"center\" style=\"border-style: dotted; font-size: 36px;\">"); client.println("<div align=\"center\">"); client.println("<strong>OpenJumper!<br />"); client.println("Arduino Web Server<br /></strong>"); client.println("</div><br />"); client.println("<div style=\"font-size: 30px;\">"); //显示室内光照度 client.println("Light intensity: "); // 即将A0采集到的模拟值输出 client.println(analogRead(A0)); client.println("<br />"); // on按钮 client.println("<a href=\"/?on\" target=\"inlineframe\"><button>on</button></a>"); client.println(" "); // off按钮 client.println("<a href=\"/?off\" target=\"inlineframe\"><button>off</button></a>"); client.println("<IFRAME name=inlineframe style=\"display:none\" >"); client.println("</IFRAME>"); client.println("<br /> "); client.println("</div><br />"); client.println("<ahref=\"http://x.openjumper.cn/ethernet/\">"); client.println("<imgsrc=\"http://www.openjumper.cn/ad.jpg\"></a>"); client.println("</div><p>"); client.println("<a href=\"http://weibo.com/coloz/\">zhou</a>@"); client.println("<a href=\"http://www.openjumper.cn/\">OpenJumper</a></p>"); client.println("</body>"); client.println("</html>"); }
发表评论