Đỉnh NGUYỄN

life's a journey not a destination

ZigBee – Thu thập dữ liệu từ các cảm biến và truyền về máy chủ thông qua web service – phần 4

Leave a comment


1. Bước 7: Nạp chương trình vào Arduino Yún

1.1 Kết nối board mạch Arduino Yún với máy tính thông qua USB cable.

clip_image002

1.2 Viết chương trình

Mở Arduino IDE và viết chương trình:

#define DEBUG true // NOTE: the serial monitor must be opened if debug is true

#define DEBUG_LOG false

#include <SoftwareSerial.h>

#include <Bridge.h>

#include <HttpClient.h>

#include <FileIO.h>

#include <YunServer.h>

#include <YunClient.h>

const String WEB_SERVER_URL = “http://hss.f99.vn/api/&#8221;;

const char* LOG_DIRECTORY = “/www”; //”mnt/sd/arduino/www/Bridge”;

const char* LOG_FILE_NAME = “/www/log.txt”; //”mnt/sd/arduino/www/Bridge/log.txt”;

String AHWaddr;

bool contractIsActived = true;

char incomingByte = 0; // for incoming serial data

int ledPin = 13;

int rxPin = 11, txPin = 10;

SoftwareSerial mySerial(rxPin, txPin);

// Listen on default port 5555, the webserver on the Yun

// will forward there all the HTTP requests for us.

YunServer server;

void setup() {

// Initialize pins

pinMode(ledPin, OUTPUT);

pinMode(rxPin, INPUT);

pinMode(txPin, OUTPUT);

// Initialize Serial and SoftwareSerial

mySerial.begin(9600); // opens software serial port, sets data rate to 9600 bps

if (DEBUG) {

//this requires a serial cable between arduino and computer.

Serial.begin(4800);

delay(25);

// Wait until serial is opened. Blink fast while doing so

digitalWrite(ledPin, LOW);

while (!Serial) {

digitalWrite(ledPin, 1 – digitalRead(ledPin));

delay(25);

}

digitalWrite(ledPin, LOW);

}

// Initialize Bridge and FileSystem

Bridge.begin();

if (DEBUG_LOG) {

FileSystem.begin();

// Wait till the FileSystem-service is started

while (!FileSystem.exists(LOG_DIRECTORY))

delay(200);

}

// blink twice at startup

digitalWrite(ledPin, LOW);

digitalWrite(ledPin, HIGH); // first blink

delay(25);

digitalWrite(ledPin, LOW);

delay(100);

digitalWrite(ledPin, HIGH); // second blink

delay(25);

digitalWrite(ledPin, LOW);

// Listen for incoming connection only from localhost

// (no one from the external network could connect)

// server.listenOnLocalhost();

server.noListenOnLocalhost();

server.begin();

// Get Arduino hardware address (MAC)

AHWaddr = getHWaddr();

//writeToLogFile(“Arduino setup complete.”);

}

void loop() {

// Listen on default port 5555, the webserver on the Yun

// will forward there all the HTTP requests for us.

// Get clients coming from server

acceptRequest(server);

if (!contractIsActived) {

printDebug(“Contract is deactived. Please, contact your service provider!.”);

//if(mySerial.overflow())

// clear buffer

clearBuffer();

delay(25);

return;

}

/*incomingByte = ‘1’;

String result = getData(AHWaddr, String(“abcdefghijk”), String(incomingByte));

printDebug(result);

delay(500);*/

printDebug(“Available1: ” + String(mySerial.available()));

if (mySerial.available() > 0) {

while (mySerial.available() > 0 && mySerial.available() >= 9)

{

printDebug(“Available2: ” + String(mySerial.available()));

// read the incoming byte:

char buf[8];

int len = 8;

mySerial.readBytes(buf, len);

if (buf[0] == ‘4’) { // DEC: 4

// readStringUntil(‘\n’);

String sensorAddr = String(buf).substring(0, 8);

incomingByte = mySerial.read(); // sensor value

String sensorValue = String(incomingByte);

/*if(sensorAddr == “40ABB829”) {

incomingByte = mySerial.read(); // sensor value

sensorValue = sensorValue + String(incomingByte);

}*/

printDebug(“Received: HWaddr: 0013A200:” + sensorAddr + ” – Value: ” + sensorValue/* + ” – TimeStamp: ” + getTimeStamp()*/);

if (incomingByte != ‘0’) // value: 1 (DEC: 1, ASCII: 49)

{

//printDebug(“before send data”);

String result = putData(AHWaddr, sensorAddr, String(incomingByte));

printDebug(“Result: ” + result);

//printDebug(“end send data”);

// turn LED on

digitalWrite(ledPin, HIGH);

delay(25);

// turn LED off

digitalWrite(ledPin, LOW);

}

else

{

// turn LED off

digitalWrite(ledPin, LOW);

}

//printDebug(“before clear buffer”);

// clear buffer

clearBuffer();

//printDebug(“end clear buffer”);

}

}

Serial.flush();

}

delay(200);

}

/*——————————————————–

——– Bridge Library (for the Arduino Yun) ———-

——————————————————–*/

/*

Post data from Arduino to remote web server.

value: sensor value

http://arduino.cc/en/Tutorial/HttpClient

*/

void getData2(String AHWaddr, String SHWaddr, String value) {

// Initialize the client library

HttpClient client;

// Make a HTTP request:

//String url = String(“http://yun.f99.vn/api/yun/id=1?value=a&#8221;);

String url = String(WEB_SERVER_URL + String(“values?_ObjectMacAddress=”) + String(AHWaddr) + String(“&_MacAddress=”) + String(“0013A200:”) + String(SHWaddr) + String(“&_Signal=”) + String(value) + String(“&_Description=”) + String(“arduino%20yun%20test%20web%20service”));

//String url = “http://hss.f99.vn/api/values?_ObjectMacAddress=90:a2:da:fd:01:24&_MacAddress=5248656853564868&_Signal=49&_Description=arduino%20yun%20test%20web%20service&#8221;;

printDebug(“GET: ” + url);

//client.getAsynchronously(url);

client.get(url);

/*

int t = 1;

while(!client.ready() && t <= 40) {

delay(500);

t++;

}

if(t <= 40)

printDebug(” – [DONE]”, true);

else

printDebug(” – [TIME OUT]”, true);

*/

}

/*

Post data from Arduino to remote web server.

value: sensor value

http://arduino.cc/en/Tutorial/HttpClient

http://www.tutorialspoint.com/unix_commands/curl.htm

*/

String putData(String AHWaddr, String SHWaddr, String value) {

// Launch “curl http://domain.com&#8221; command

// curl is a command line utility that get the content of a url

Process p; // Create a process and call it “p”

p.begin(“curl”); // Process that launch the “cat” command

//p.addParameter(String(“–connect-timeout”/*seconds*/));

//p.addParameter(String(“10”));

//p.addParameter(String(“–max-time 10″/*seconds*/));

String url = String(WEB_SERVER_URL) + String(“values?_ObjectMacAddress=”) + String(AHWaddr) + String(“&_MacAddress=”) + String(“0013A200:”) + String(SHWaddr) + String(“&_Signal=”) + String(value) + String(“&_Description=”) + String(“arduino%20yun%20test%20web%20service”);

printDebug(“PUT: ” + url);

p.addParameter(url); // Add the cpuifo file path as parameter to cut

p.run(); // Run the process and wait for its termination

String result;

// Print command output on the Serial.

// A process output can be read with the stream methods

while (p.available() > 0) {

char c = p.read();

result += String(c);

}

return result;

}

/*

Post data from Arduino to remote web server.

value: sensor value

http://arduino.cc/en/Tutorial/HttpClient

*/

String postData(String AHWaddr, String SHWaddr, String value) {

// Launch “curl http://domain.com&#8221; command

// curl is a command line utility that get the content of a url

Process p; // Create a process and call it “p”

p.begin(“curl”); // Process that launch the “cat” command

String url = String(String(” –data-urlencode “” “) + String(“key1=value1”) + String(“&key2=value2″) + ” ” + WEB_SERVER_URL);

p.addParameter(url); // Add the cpuifo file path as parameter to cut

p.run(); // Run the process and wait for its termination

printDebug(“GET: ” + url);

String result;

// Print command output on the Serial.

// A process output can be read with the stream methods

while (p.available() > 0) {

char c = p.read();

result += String(c);

}

// Ensure the last bit of data is sent.

return result;

}

/*

Get Mac address

http://stackoverflow.com/questions/245916/best-way-to-extract-mac-address-from-ifconfig-output

ifconfig eth0 | grep -o -E ‘([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}’

*/

String getHWaddr() {

// Launch “cat /sys/class/net/eth1/address” command (shows Mac address info)

// cat is a command line utility that shows the content of a file

Process p; // Create a process and call it “p”

p.begin(“cat”); // Process that launch the “cat” command

p.addParameter(“/sys/class/net/eth1/address”); // Add the cpuifo file path as parameter to cut

p.run(); // Run the process and wait for its termination

String result;

// Print command output on the Serial.

// A process output can be read with the stream methods

while (p.available() > 0) {

char c = p.read();

result += String(c);

}

// Ensure the last bit of data is sent.

return result.substring(0, 17); // remove \n

}

/*

Get a string with the time stamp from linux via Bridge library.

Date format: MM/DD/YY HH:MM:SS

http://arduino.cc/en/Tutorial/TimeCheck

*/

String getTimeStamp() {

String result;

Process time;

// date is a command line utility to get the date and the time

// in different formats depending on the additional parameter

time.begin(“date”);

time.addParameter(“+%D %T”); // parameters: D for the complete date mm/dd/yy

// T for the time hh:mm:ss

time.run(); // run the command

// read the output of the command

while (time.available() > 0)

{

char c = time.read();

if (c != ‘\n’)

result += c;

}

return result;

}

/*

Write data into log file.

http://arduino.cc/en/Tutorial/YunDatalogger

*/

void writeToLogFile(String message) {

String dateTime = getTimeStamp();

File file = FileSystem.open(LOG_FILE_NAME, FILE_APPEND);

if (file)

{

file.println(dateTime + “: ” + message);

file.close();

}

}

/*

Clear all data in log file.

*/

void clearLogFile() {

FileSystem.remove(LOG_FILE_NAME);

}

/*——————————————————–

——————– WiFi Library ———————-

——————————————————–*/

// Not working (well well well)

String getXBeeAddr() {

// put the radio in command mode:

printDebug(“+++”);

String result;

// wait for the radio to respond with “OK\r”

char thisByte = 0;

while (Serial.available() > 0) {

thisByte = Serial.read();

result += String(thisByte);

}

return result;

}

/*——————————————————–

————- Bridge Library: Web Server —————

——————————————————–*/

/*

Use the Bridge library to access the digital and analog pins

on the board through REST calls. It demonstrates how

you can create your own API when using REST style

calls through the browser.

Possible commands created in this shetch:

* “/arduino/digital/13” -> digitalRead(13)

* “/arduino/digital/13/1” -> digitalWrite(13, HIGH)

* “/arduino/analog/2/123” -> analogWrite(2, 123)

* “/arduino/analog/2” -> analogRead(2)

* “/arduino/mode/13/input” -> pinMode(13, INPUT)

* “/arduino/mode/13/output” -> pinMode(13, OUTPUT)

* “/arduino/contract/status/1 -> active contact

This example code is part of the public domain

http://arduino.cc/en/Tutorial/Bridge

*/

void acceptRequest(YunServer server) {

// Get clients coming from server

YunClient client = server.accept();

// There is a new client?

if (client) {

// Process request

printDebug(“Ok ok”);

process(client);

// Close connection and free resources.

client.stop();

}

}

void process(YunClient client) {

// read the command

String command = client.readStringUntil(‘/’);

// is “digital” command?

if (command == “digital”) {

digitalCommand(client);

}

// is “analog” command?

if (command == “analog”) {

analogCommand(client);

}

// is “mode” command?

if (command == “mode”) {

modeCommand(client);

}

// is “contract” command?

if (command == “contract”) {

contractCommand(client);

}

}

void digitalCommand(YunClient client) {

int pin, value;

// Read pin number

pin = client.parseInt();

// If the next character is a ‘/’ it means we have an URL

// with a value like: “/digital/13/1”

if (client.read() == ‘/’) {

value = client.parseInt();

digitalWrite(pin, value);

}

else {

value = digitalRead(pin);

}

// Send feedback to client

client.print(F(“Pin D”));

client.print(pin);

client.print(F(” set to “));

client.println(value);

// Update datastore key with the current pin value

String key = “D”;

key += pin;

Bridge.put(key, String(value));

}

void analogCommand(YunClient client) {

int pin, value;

// Read pin number

pin = client.parseInt();

// If the next character is a ‘/’ it means we have an URL

// with a value like: “/analog/5/120”

if (client.read() == ‘/’) {

// Read value and execute command

value = client.parseInt();

analogWrite(pin, value);

// Send feedback to client

client.print(F(“Pin D”));

client.print(pin);

client.print(F(” set to analog “));

client.println(value);

// Update datastore key with the current pin value

String key = “D”;

key += pin;

Bridge.put(key, String(value));

}

else {

// Read analog pin

value = analogRead(pin);

// Send feedback to client

client.print(F(“Pin A”));

client.print(pin);

client.print(F(” reads analog “));

client.println(value);

// Update datastore key with the current pin value

String key = “A”;

key += pin;

Bridge.put(key, String(value));

}

}

void modeCommand(YunClient client) {

int pin;

// Read pin number

pin = client.parseInt();

// If the next character is not a ‘/’ we have a malformed URL

if (client.read() != ‘/’) {

client.println(F(“error”));

return;

}

String mode = client.readStringUntil(‘\r’);

if (mode == “input”) {

pinMode(pin, INPUT);

// Send feedback to client

client.print(F(“Pin D”));

client.print(pin);

client.print(F(” configured as INPUT!”));

return;

}

if (mode == “output”) {

pinMode(pin, OUTPUT);

// Send feedback to client

client.print(F(“Pin D”));

client.print(pin);

client.print(F(” configured as OUTPUT!”));

return;

}

client.print(F(“error: invalid mode “));

client.print(mode);

}

void contractCommand(YunClient client) {

String action;

int value;

// Read pin number

action = client.readStringUntil(‘s’);

// If the next character is a ‘/’ it means we have an URL

// with a value like: “/contract/status/1”

if (client.read() == 116/*’/’*/) {

value = client.parseInt();

contractIsActived = (value == 1) ? true : false;

}

else {

value = 0; // current status

}

// Send feedback to client

client.print(F(“Contract “));

client.print(action);

client.print(F(” set to “));

client.println(value);

}

/*——————————————————–

———————– Serial ————————-

——————————————————–*/

// Print debug information to serial and break line.

void printDebug(String s) {

if (DEBUG) {

Serial.println(s);

}

}

// Print debug info to serial with break line option

void printDebug(String s, bool breakLine) {

if (DEBUG) {

if (breakLine)

Serial.println(s);

else

Serial.print(s);

}

}

/*——————————————————–

——————– Cryptography ———————-

——————————————————–*/

void clearBuffer() {

// Serial.flush() has changed in Arduino 1.0. You can use the following instead: while(Serial.available()>0) Serial.read();

while (Serial.available() > 0)

Serial.read();

}

1.3 Nạp chương trình vào board mạch Arduino Yún

1. Chọn loại mạch là Arduino Yún.

clip_image003

2. Chọn cổng giao tiếp Serial tương ứng

clip_image004

3. Biên dịch mã nguồn

clip_image005

4. Nạp chương trình vào board mạch

clip_image006

Advertisements

Author: dinhnn

Senior software developer, a technical leader. You can be reached at via email to dinhnguyenngoc@gmail.com, via my blog at dinhnguyenngoc.wordpress.com, and on Twitter @dinhnguyenngoc.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s