quarta-feira, 24 de fevereiro de 2016

Arduino through PHP

This post presents a project that will use three programming languages in order to communicate with an Arduino board from the browser.

The objective is simple: a Web page will send and receive data from the Arduino connected to a web server.

In the Arduino there will be a simple communication protocol that's responsible for the interaction with the sensors.

The Web server is running Apache over Windows and the programming language selected is PHP.

A small programming will allow for the web page, built with PHP, to send and receive data through the USB port. It's a small console mode application created with C#. The PHP web page server side will run this command with different parameters and it will return the data read from the Arduino.

Although there are multiple PHP frameworks that claim to work with the USB port none of them worked for me.


In the Arduino a servo is connected in 9 pin, a led is in the 12 pin and a ldr in the analog zero. The analog pins are connected with a ADC (Analog Digital Converter) that convert the electric tension into a number from 0 to 1024. The maximum voltage is around 5 volts which should convert to 1024.
The digital pins work in binary, 0 or 1, but the 9 pin has a PWM (Pulse Width Modulation) function which simulate the analog function by turning on and off very fast, this is how the fading effects are made with the LEDs.

This are the protocol communication rules:
- If the value receive in the Arduino is between 0 and 180, it will rotate the servo using that value as the angle.
- If the value is 181 then the LED toggles on or off.
- If the value is 182 the Arduino will send the LDR value.

The code for the Arduino:

 #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);
    }
  }
}

The Web page is a simple form with three buttons for each of the elements present in Arduino (LED, LDR e o servo).
Each button will call the C# console mode program with the command and the serial port.

The PHP code:

<html>
<body>
    <form method="POST">
        <input type="text" name="angle">
        <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["angle"])){
                echo "The angle is missing<br>";
                return;
            }
            $angle=$_POST["angle"];
            $command="console_servo.exe COM18 ".$angle;
            $result=exec($command);
        }
        if(!empty($_POST["bt_luz"])){
            echo "POST led<br>";
            $result=exec("console_servo.exe COM18 181");
        }
        if(!empty($_POST["bt_ldr"])){
            echo "POST ldr<br>";
            $result=exec("console_servo.exe COM18 182 er");
            $result=(int)$result;
        }
        if($result<0) $result="";
        echo $result."<br>";
    }
?>

The C# program uses a class that handles the communication with the serial port.
The code checks the parameters and than sends and receives the data to the Arduino.

And here's the code:

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;
        }
    }
}

The project can be download here.

Thanks for reading.

Sem comentários:

Enviar um comentário