Использование Raspberry Pi в роли Ethernet-шилда для Arduino


Alexandre Alapetite захотел собрать свой веб-регистратор температуры на базе Arduino, но не захотел разбираться с привередливостью своего Ethernet-шилда и решил заменить его своим Raspberry Pi.

Каждые пять минут, ​​Arduino отправляет данные с термопары через последовательный порт (USB), на Raspberry Pi в виде JSON-пакета. На Raspberry Pi используется node.js, который передаёт данные в интернет.

Node.js — серверная реализация языка JavaScript основанная на движке V8 от Google (используется в Chrome). Предназначена для создания масштабируемых распределенных сетевых приложений, таких как веб-сервер.


скетч Arduino
#include <math.h>

unsigned long UpdateDelay = 1000UL * 60 * 5;	//Update frequency
const byte Temperature1Pin = 0;	//Thermistor 1 (Outdoor)
const byte Temperature2Pin = 1;	//Thermistor 2 (Indoor)
const int Resistance1 = 9900;	//Ohms (measured from R10K of voltage divider 1)
const int Resistance2 = 9980;	//Ohms (measured from R10K of voltage divider 2)
const byte NbSamples = 8;	//Averaging

void setup()
{
	delay(1000);
	Serial.begin(9600);	//Start serial port
	pinMode(Temperature1Pin, INPUT);
	pinMode(Temperature2Pin, INPUT);
	digitalWrite(Temperature1Pin, LOW);
	digitalWrite(Temperature2Pin, LOW);
	analogRead(Temperature1Pin);
	analogRead(Temperature2Pin);
}

void loop()
{
	float rawADC1 = 0.0;
	float rawADC2 = 0.0;
	for (byte i = NbSamples; i > 0; i--)
	{//Averaging over several readings
		rawADC1 += analogRead(Temperature1Pin);
		rawADC2 += analogRead(Temperature2Pin);
		delay(100);
	}
	rawADC1 /= NbSamples;
	rawADC2 /= NbSamples;

	//Sending a JSON string over Serial/USB like: {"ab":"123","bc":"234","cde":"3546"}
	Serial.println("{\"adc\":\"" + String((long)round(100.0 * rawADC1)) +
			"\", \"celsius\":\"" + String((long)round(100.0 * thermistor(rawADC1, Resistance1))) +
			"\", \"adc2\":\"" + String((long)round(100.0 * rawADC2)) +
			"\", \"celsius2\":\"" + String((long)round(100.0 * thermistor(rawADC2, Resistance2))) +
			"\"}");

	delay(UpdateDelay);
}

float thermistor(float rawADC, float rSeries)
{//http://arduino.cc/playground/ComponentLib/Thermistor2
	//This method is not very advanced
	long resistance = (1024 * rSeries / rawADC) - rSeries;
	float temp = log(resistance);
	temp = 1 / (0.001129148 + (0.000234125 * temp) + (0.0000000876741 * temp * temp * temp));
	return temp - 273.15;	//Kelvin to Celsius
}


arduinoTemperature.js — скрипт, используемый чтобы обрабатывать JSON-сообщения отправленные Arduino (он также передает новую информацию на специальный веб-сервер с помощью POST-запроса).
"use strict";

var arduinoSerialPort = '/dev/ttyACM0';	//Serial port over USB connection between the Raspberry Pi and the Arduino

var os = require('os');
var serverSignature = 'Node.js / Debian ' + os.type() + ' ' + os.release() + ' ' + os.arch() + ' / Raspberry Pi B + Arduino Uno R3';

var postOptions =
{
	host: 'posttestserver.com',	//Change to your own server
	path: '/post.php',
	method: 'POST',
	headers:
	{
		'Content-Type': 'application/x-www-form-urlencoded',
		'Connection': 'close',
		'User-Agent': serverSignature
	}
};

var http = require('http');
function postData(s)
{//Standard HTTP POST request
	var myOptions = postOptions;
	postOptions.headers['Content-Length'] = s.length;

	var requestPost = http.request(myOptions, function(res)
	{
		res.setEncoding('utf8');
		res.on('data', function (chunk)
		{
			console.log(chunk);
		});
	});

	requestPost.on('error', function(e)
	{
		console.warn(e);
	});

	requestPost.write(s);
	requestPost.end();
}

var serialport = require('serialport');
var serialPort = new serialport.SerialPort(arduinoSerialPort,
{//Listening on the serial port for data coming from Arduino over USB
	parser: serialport.parsers.readline('\n')
});

var lastTemperatureIndoor = NaN;
var lastTemperatureOutoor = NaN;
var dateLastInfo = new Date(0);

var querystring = require('querystring');
serialPort.on('data', function (data)
{//When a new line of text is received from Arduino over USB
	try
	{
		var j = JSON.parse(data);
		lastTemperatureOutoor = j.celsius / 100.0;
		lastTemperatureIndoor = j.celsius2 / 100.0;
		dateLastInfo = new Date();
		//Forward the Arduino information to another Web server
		postData(querystring.stringify(j));
	}
	catch (ex)
	{
		console.warn(ex);
	}
});


function colourScale(t)
{//Generate an HTML colour in function of the temperature
	if (t <= -25.5) return '0,0,255';
	if (t <= 0) return Math.round(255 + (t * 10)) + ',' + Math.round(255 + (t * 10)) + ',255';
	if (t <= 12.75) return Math.round(255 - (t * 20)) + ',255,' + Math.round(255 - (t * 20));
	if (t <= 25.5) return Math.round((t - 12.75) * 20) + ',255,0';
	if (t <= 38.25) return '255,' + Math.round(255 - (t - 25.5) * 20) + ',0';
	return '255,0,0';
}

function htmlTemperature()
{
	return '<!DOCTYPE html>\n\
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB">\n\
<head>\n\
<meta charset="UTF-8" />\n\
<meta http-equiv="refresh" content="300" />\n\
<title>Temperature - Arduino - Raspberry Pi</title>\n\
<meta name="keywords" content="Temperature, Arduino, Raspberry Pi" />\n\
<meta name="viewport" content="initial-scale=1.0,width=device-width" />\n\
<meta name="robots" content="noindex" />\n\
<style type="text/css">\n\
html, body {background:black; color:white; font-family:sans-serif; text-align:center}\n\
.out {font-size:48pt}\n\
.in {font-size:36pt}\n\
.r, .sb {bottom:0; color:#AAA; position:absolute}\n\
.r {left:0.5em; margin-right:5em; text-align:left}\n\
.sb {right:0.5em}\n\
a {color:#AAA; text-decoration:none}\n\
a:hover {border-bottom:1px dashed}\n\
</style>\n\
</head>\n\
<body>\n\
<h1>Temperature somewhere</h1>\n\
<p>Outdoor<br /><strong class="out" style="color:rgb(' + colourScale(lastTemperatureOutoor) + ')">' +
	(Math.round(lastTemperatureOutoor * 10) / 10.0) + '°C</strong></p>\n\
<p>Indoor<br /><strong class="in" style="color:rgb(' + colourScale(lastTemperatureIndoor) + ')">' +
	(Math.round(lastTemperatureIndoor * 10) / 10.0) + '°C</strong></p>\n\
<p>' + dateLastInfo.toISOString() + '</p>\n\
<p class="r"><a href="http://alexandre.alapetite.fr/doc-alex/raspberrypi-nodejs-arduino/" title="Based on">Arduino + Raspberry Pi</a></p>\n\
</body>\n\
</html>\n\
';
}

module.exports.htmlTemperature = htmlTemperature;


Ссылки:
Raspberry Pi with Node.js and Arduino
nodejs.org

По теме:
Использование Raspberry Pi в стиле Arduino
Raspberry Pi — начало работы
Raspberry Pi увидел свет!
Превращаем ADSL-модем в Ethernet-шилд для Arduino/CraftDuino
  • +1
  • 25 июня 2012, 07:28
  • admin

Комментарии (3)

RSS свернуть / развернуть
+
+2
ну елки палки блин!
гвозди микроскопом! Юзать ардуину тупо как АЦП.
Уж лучяше бы взял цифровые датчики и подключил к GPIO
avatar

Radiolok

  • 25 июня 2012, 14:22
+
0
Совершенно бестолковое решение. Использовать связку Расберри + Ардуино только для регистрации температуры — расточительное безобразие. Здесь определенно половина железа — лишняя. Попахивает большим либо дилетантством, либо избытком денег.
avatar

Ozze

  • 25 июня 2012, 14:43
+
0
Да, странно, что он использовал arduino+PI вместо просто PI. Наверное простота программирования PI еще не достигла Ардуины, не смотря на наличие аналогичных тулзов.

P.S. Для сетевых датчиков оптимальное (по цене и возможностям) — ARM Cortex-M3 с встроенным Ethernet'ом. Arduino+Ethernet в любом раскладе заметно дороже (здесь обсуждали уже), не говоря уж о возможностях MCU.
avatar

snop

  • 10 июля 2012, 17:53

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.