본문 바로가기

Raspberry Pi/Step Motor, Web 02

Stepping Motor Control with Raspberry, Arduino on th Web

라즈베리파이와 아두이노를 이용하여 웹에서 스테핑모터 제어하기


이 페이지는 앞의 내용에 연결되는 페이지이므로 반드시 처음 페이지부터 참조해야 자연스럽게 이해가 됩니다.

사용된 스테핑 모터와 제어용 보드에 대한 상세한 설명도 앞페이지에서 확인해 주세요

앞 페이지 참조


테스트 환경

라즈베리파이 B+, Node.js, 라즈베리파이에 아두이노 개발환경(Arduino IDE)을 설치함

아두이노 UNO

스테핑모터(), 스테핑모터 제어보드

아두이노의 USB 케이블을 라즈베리파이의 USB 포트에 연결하고 node-serialport 라이브러리를 이용하여 시리얼 통신



라즈베리파이에서 실행되는 웹서버 프로그램 및 html 파일

/home/pi/www/web_node_serial.js

var http = require('http'); var fs = require('fs'); var formidable = require('formidable'); var util = require('util'); var server = http.createServer( function(req, res) { if(req.method.toLowerCase()=='get') { displayForm(res); }else if(req.method.toLowerCase()=='post'){ processAllFieldsOfTheForm(req, res); } } ); function displayForm(res) { console.log('GET'); fs.readFile('step_motor_control.html', function(err, data){ res.writeHead(200, { 'Content-Type':'text/html', 'Content-Length':data.length }); res.write(data); }); } function processAllFieldsOfTheForm(req, res) { console.log('POST'); var form = new formidable.IncomingForm(); form.parse(req, function(err, fields, files) { res.writeHead(200, { 'Content-Type':'text/plain' }); var msg = fields.speed+" "+fields.revolution; serialSend(msg, res); console.log("Form Received:"+msg); res.write('Received from Webbrowser:'+msg+'\n\n'); }); } server.listen(8088); console.log('Server running at port 8088'); function serialSend(web_data, res) { var SerialPort = require("serialport").SerialPort; serialPort = new SerialPort("/dev/ttyUSB0", { baudrate: 9600, dataBits:8, parity:'none', stopBits: 1, flowControl: false }); serialPort.on("open", function() { console.log("open"); serialPort.on("data", function(data) { res.write('Received from Arduino:'+data+'\n\n'); res.end(); console.log('Received from Arduino:' + data+'\n'); }); serialPort.write(web_data, function(err, results){ console.log('err: ' + err); console.log('results : '+ results); }); /* serialPort.close(function(err){ console.log('port closed', err); }); */ serialPort.on("error", function(err) { console.log('error : '+ err); }); serialPort.on("close", function(){ console.log("closed"); }); }); }



/home/pi/www/step_motor_control.html

<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<title> Stepping Motor Control </title>
<style type="text/css">
	#svrMsg { border:1px solid gray;}
	input[type=range] { width:400px; }
</style>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"
	integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
	crossorigin="anonymous"></script>
<script>
$(function(){
	//alert('jquery ready!');
});

function ajaxRequest() {
	var param = {};
	param.speed = $('input[name=speed]').val();
	param.revolution = $('input[name=revolution]').val();
	$.ajax(
	{	url:'web_node_serial.js',
	 	type:'post',
		data:param,
		dataType:'text',
		success:function(res) {
			$('div#svrMsg').text(res);
		},
		error:function(xhr, status, err){
			$('div#svrMsg').text(err);
		}
	});
}
</script>
</head>

<body>
<p>
 Stepping Motor Control
<p>
Speed (+0.04 ~ +0.15) : <input type="range" name="speed" min="0.04" max="0.15" step="0.01"
 value="0.04" oninput="$('#spdOut').val(this.value);">
<output id="spdOut"><p>

Revolutions & Direction (-5 ~ +5) : <input type="range" name="revolution" min="-5" max="5" step="0.01"
 value="0.01" oninput="$('#amtOut').val(this.value);">
<output id="amtOut"><p>

<label for="svrMsg">Server Msg</label>
<div id='svrMsg'></div>

<button type="button" onclick='ajaxRequest();'> Apply </button>
</body>
</html>


아두이노에서 실행될 스텝모터 제어용 코드

라즈베리파이에 설치된 Arduino IDE에서 작성하여 아두이노에 업로드함

스테핑 모터의 회전방향 제어 : myStepper.setStep( 스텝수 ) -> 스텝수가 양수이면 정회전, 음수이면 역회전함

스테핑 모터의 회전수(량)은 위의 스텝수의 크기에 따라 결정됨

스테핑 모터의 회전속도 제어 : myStepper.setSpeed( n * 64 ) -> n 값이 0.04~0.15이면 적절함

#include <StepperAK.h> //use modified stepper library with 1000/0100/0010/0001 magnet firing sequence. Put library in your library folder. #define gearratio 64 //1:64 gear ratio const int stepsPerRevolution = 2048; //the Arduino Kit motor is geared down. By experiment I determined that 2048 steps turn the shaft one round. // instantiate a 4-wire stepper on pins 8 through 11: Stepper myStepper(stepsPerRevolution, 8,9,10,11); void setup() { Serial.begin(9600); } float speed = 0.0F; int amount = 0; int step = 0; void loop() { if(Serial.available()) { String msg = Serial.readString(); int idx = msg.indexOf(" "); if(idx < 0) return; String spd = msg.substring(0, idx); if(spd=="" || spd==NULL) spd = "0.15"; String amt = msg.substring(idx+1); if(amt=="" || amt==NULL) amt = "1.0"; char spdbuf[32]; spd.toCharArray(spdbuf, sizeof(spdbuf)); speed = atof(spdbuf); char amtbuf[32]; amt.toCharArray(amtbuf, sizeof(amtbuf)); float _amount = atof(amtbuf); amount = _amount * 2048.0F; myStepper.setSpeed( speed * 64 ); if( amount > 0) step = 1; else if( amount < 0 ) step = -1; else step = 0; char pChrBuffer[50]; String res = "Speed:"; res += dtostrf(speed, 5, 2, pChrBuffer ); res += " Steps:"; res += String(amount); Serial.println(res); } if(amount!=0) { if(amount>0) { if(--amount == 0) step = 0; }else if(amount<0){ if(++amount ==0) step = 0; } } myStepper.step(step); }