아두이노 웹제어 참조

CNC 2016. 11. 9. 18:00

nodejs + socket.io + arduino 이용


웹상 실시간 센서값 읽고 시리얼통신에 참조 할 만한 소스입니다.


아두이노 <--> 디바이스 간 실시간 멀티 시리얼통신 


app.js

var app = require('http').createServer(handler),
  io = require('socket.io').listen(app),
  fs = require('fs'),
  url = require('url'),
  SerialPort = require('serialport').SerialPort,
  // initialize serialport using the /dev/cu.usbmodem1411 serial port
  // remember to change this string if your arduino is using a different serial port
  sp = new SerialPort('/dev/cu.usbmodem1411', {
    baudRate: 115200
  }),
  // this var will contain the message string dispatched by arduino
  arduinoMessage = '',
  /**
   * helper function to load any app file required by client.html
   * @param  { String } pathname: path of the file requested to the nodejs server
   * @param  { Object } res: http://nodejs.org/api/http.html#http_class_http_serverresponse
   */
  readFile = function(pathname, res) {
    // an empty path returns client.html
    if (pathname === '/')
      pathname = 'client.html';

    fs.readFile('client/' + pathname, function(err, data) {
      if (err) {
        console.log(err);
        res.writeHead(500);
        return res.end('Error loading client.html');
      }
      res.writeHead(200);
      res.end(data);
    });
  },
  /**
   *
   * This function is used as proxy to print the arduino messages into the nodejs console and on the page
   * @param  { Buffer } buffer: buffer data sent via serialport
   * @param  { Object } socket: it's the socket.io instance managing the connections with the client.html page
   *
   */
  sendMessage = function(buffer, socket) {
    // concatenating the string buffers sent via usb port
    arduinoMessage += buffer.toString();

    // detecting the end of the string
    if (arduinoMessage.indexOf('\r') >= 0) {
      // log the message into the terminal
      // console.log(arduinoMessage);
      // send the message to the client
      socket.volatile.emit('notification', arduinoMessage);
      // reset the output string to an empty value
      arduinoMessage = '';
    }
  };

// creating a new websocket
io.sockets.on('connection', function(socket) {
  // listen all the serial port messages sent from arduino and passing them to the proxy function sendMessage
  sp.on('data', function(data) {
    sendMessage(data, socket);
  });
  // listen all the websocket "lightStatus" messages coming from the client.html page
  socket.on('lightStatus', function(lightStatus) {
    sp.write(lightStatus + '\r', function() {
      // log the light status into the terminal
      console.log('the light should be: ' + lightStatus);
    });
  });
});

// just some debug listeners
sp.on('close', function(err) {
  console.log('Port closed!');
});

sp.on('error', function(err) {
  console.error('error', err);
});

sp.on('open', function() {
  console.log('Port opened!');
});

// L3T'S R0CK!!!
// creating the server ( localhost:8000 )
app.listen(8000);
// server handler
function handler(req, res) {
  readFile(url.parse(req.url).pathname, res);
}


client.html
<title>Arduino and Nodejs</title>
    <style>
    center {
        font-size: 100px;
        font-family:arial;
    }
    </style>


    <button>
        Turn the light
        <span>on</span>
    </button>
    <script src="socket.io/socket.io.js"></script>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>


arduino.ino


// pin of the button connected to the arduino board
const int buttonPin = 7;
// pin of the led light
// it's actually also the default arduino debug light
const int ledPin = 13;

// simple variables used to store the led and the button statuses
String buttonStatus = "off";
String ledStatus = "off";

// it will hold all the messages coming from the nodejs server
String inputString = "";

// whether the string received form nodejs is complete
// a string is considered complete by the carriage return '\r'
boolean stringComplete = false;

/**
 *
 * arduino board setup
 *
 */

void setup()
{
  // set the Baud Rate
  Serial.begin(115200);
  // set the input pin
  pinMode(buttonPin, INPUT);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
}

/**
 *
 * Default arduino loop function
 * it runs over and over again
 *
 */

void loop()
{
  // read the button state and send a message to the nodejs server
  listenButtonChanges(digitalRead(buttonPin));
  // update the status of the led light connected to the arduino board
  updateLedStatus();
}

/**
 *
 * check the button connected to the pin 7 of the arduino board and
 * send messages through the serial port whenever the button gets clicked
 * @param  { boolean } tmpButtonStatus: its the current status of the button
 *
 */

void listenButtonChanges (boolean tmpButtonStatus) {
  // if it has not been clicked yet and it's down we can send the message
  if (tmpButtonStatus && buttonStatus == "off") {
    buttonStatus = "on";
    Serial.println("Hello World");
    // wait 1 s before sending the next message
    delay(1000);
  }
  // if the button is not pressed anymore we reset the buttonStatus variable to off
  if (!tmpButtonStatus) {
    buttonStatus = "off";
  }
}

/**
 *
 * Update the status of the led light reading the messages dispatched by the nodejs server
 *
 */

void updateLedStatus() {
  // detect whether the string has been completely received
  if (stringComplete) {
    // set and store the current led status
    if (inputString == "on\r") {
      ledStatus = "on";
    }
    if (inputString == "off\r") {
      ledStatus = "off";
    }
    // send the light status to the nodejs server
    Serial.println(ledStatus);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
  // turn on or off the led according to the latest light status stored
  digitalWrite(ledPin, ledStatus == "on" ? HIGH : LOW);
}

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
 void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a "\n" we detect the end of the string
    if (inChar == '\r') {
      stringComplete = true;
    }
  }
}




Posted by ksys
,