Neste post vamos criar um projeto que vai implicar utilizar três linguagens de programação diferentes e tudo para permitir comunicar com um Arduino através do browser.
O objetivo é criar uma página Web que permitirá enviar e receber dados de um Arduino ligado a um servidor Web.
No Arduino implementamos um protocolo muito simples de comunicação que faz a interação com os sensores e comunica com o servidor Web.
O servidor Web é um computador com Windows a correr o Apache e a linguagem de programação utilizada para a criação das páginas será o PHP.
Para permitir a comunicação do PHP com a porta USB do Arduino será desenvolvimento um pequeno programa em C#, modo Consola, que será chamado a partir do PHP com alguns parâmetros e que posteriormente fará a ligação ao Arduino.
Apesar de existirem livrarias de funções em PHP para utilizar a porta série não consegui fazer com que funcionassem em Windows.
No Arduino vamos ter um servo ligado ao pino 9, um LED ligado ao pino 12 e um LDR no pino A0. O pino 9 e o pino 12 são digitais, o pino A0 é um pino analógico. Os pinos analógicos estão ligados a um ADC (Analog Digital Convert) que faz a conversão entre a tensão elétrica recebida e um valor entre 0 e 1024. O valor máximo, por defeito, é de 5 volts que corresponde a 1024.
O pino 9 é um pino com função PWM (Pulse Width Modulation) que permite simular o envio de valores entre 0 (LOW) e 1 (HIGH), é esta função que permite fazer efeito de fade com LEDs.
Neste caso vamos ter um protocolo muito simples que respeita as seguintes regras:
- Se o valor recebido pelo Arduino estiver entre 0 e 180, inclusive, este corresponderá ao ângulo de posicionamento do servo.
- Se o valor recebido é 181 então o LED liga ou desliga, de acordo com o estado anterior.
- Se o valor recebido é 182 então o Arduino envia o valor do LDR.
Assim o código do Arduino fica:
#include <Servo.h>
Servo myservo;
int pos = 0;
int led=0;
int ledPort=12;
int ldrPin=A0;
byte nivelLuz=0;
void setup()
{
myservo.attach(9);
Serial.begin(9600);
pinMode(ledPort,OUTPUT);
}
void loop()
{
byte valor;
if(Serial.available()){
valor=Serial.read();
if(valor>=0 && valor<=180) myservo.write(valor);
if(valor==181){
if(led==0){
digitalWrite(ledPort,HIGH);
led=1;
}else{
digitalWrite(ledPort,LOW);
led=0;
}
}
if(valor==182){
delay(150);
nivelLuz=analogRead(ldrPin);
Serial.println(nivelLuz);
}
}
}
A página Web vai conter um formulário simples com três botões para controlar cada um dos dispositivos presentes no Arduino (LED, LDR e o servo).
Cada botão invoca o programa desenvolvido em C# com o comando e a porta séria a utilizar.
O código PHP fica:
<html>
<body>
<form method="POST">
<input type="text" name="angulo">
<input type="submit" name="bt" value="Servo">
<input type="submit" name="bt_luz" value="Led">
<input type="submit" name="bt_ldr" value="Luz">
</form>
</body>
</html>
<?php
ini_set("display_errors",1);
if(!empty($_POST)){
if(!empty($_POST["bt"])){
echo "POST servo<br>";
if(empty($_POST["angulo"])){
echo "Preencha o angulo<br>";
return;
}
$angulo=$_POST["angulo"];
$comando="console_servo.exe COM18 ".$angulo;
$resultado=exec($comando);
}
if(!empty($_POST["bt_luz"])){
echo "POST led<br>";
$resultado=exec("console_servo.exe COM18 181");
}
if(!empty($_POST["bt_ldr"])){
echo "POST ldr<br>";
$resultado=exec("console_servo.exe COM18 182 er");
$resultado=(int)$resultado;
}
if($resultado<0) $resultado="";
echo $resultado."<br>";
}
?>
O programa em C# inclui uma classe que implementa a comunicação com a porta série.
O código do programa começa por verificar os parâmetros que são passados e em função deles utilizar um objeto criado com base na classe de comunicação para enviar e receber os dados do Arduino.
namespace console_servo
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 1)
{
string strler = args[0];
Comunica portaler = new Comunica(strler);
int valorlido=portaler.lerLinha();
Console.Write(valorlido.ToString());
return;
}
if (args.Length == 3)
{
string strenvia = args[0];
byte valorenviar;
if (byte.TryParse(args[1], out valorenviar) == false)
{
Console.Write("Usage: servo porta valor er");
return;
}
Comunica portalerenviar = new Comunica(strenvia);
portalerenviar.envia(valorenviar);
Thread.Sleep(150);
int valordevolver = portalerenviar.lerLinha();
Console.Write(valordevolver);
return;
}
if (args.Length != 2)
{
Console.Write("Usage: servo porta valor");
return;
}
byte valor = 0;
if (byte.TryParse(args[1], out valor)==false)
{
Console.Write("Usage: servo porta valor");
return;
}
string str=args[0];
Comunica porta = new Comunica(str);
porta.envia(valor);
Console.Write("ok");
}
}
class Comunica
{
string porta;
SerialPort sp;
string buffer;
public Comunica(string porta)
{
this.porta = porta;
sp = new SerialPort(porta);
sp.Open();
}
~Comunica()
{
if (sp.IsOpen) sp.Close();
sp.Dispose();
}
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
buffer = sp.ReadExisting();
}
public void envia(byte x)
{
byte[] valores = new byte[2];
valores[0] = x;
sp.Write(valores, 0, 1);
}
public byte ler()
{
byte[] valores=new byte[2];
sp.Read(valores, 0, 1);
return valores[0];
}
public int lerLinha()
{
string linha =sp.ReadLine();
int valor = 0;
if(int.TryParse(linha, out valor)==false)
return -1;
else
return valor;
}
}
}
O projeto completo pode ser descarregado aqui.
Sem comentários:
Enviar um comentário