Controllo rele e temperatura da pagina web su router OpenWrt

Tutto sull'Arduino e la sua grande famiglia... Atmel AVR, Microchip PIC, ecc...

Moderatori: ragno, tapino, alez, zulu, davidea

cybor
Messaggi: 85
Iscritto il: 04 apr 2009, 11:50

Controllo rele e temperatura da pagina web su router OpenWrt

Messaggio da cybor »

Ciao,

inspirato da un progetto visto in rete che si propone di controllare un relè usb commerciale tramite un aga con firmware modificato sto provando a realizzare una cosa simile con Vodafone Station (OpenWRT) ed Arduino, ovviamente :-)

Ho realizzato uno sketch che tramite terminale seriale (CuteCom) invia dei comandi per controllare 2 rele e leggere la temperatura dal classico Dallas DS18B20.

In pratica scrivo 'rele07=1' per accendere ed ovviamente 'rele07=0' per spengere se invece scrivo 'term', per adesso ho collegato un solo Dallas e non gestisco gli indirizzi, ottengo la temperatura.

Ho collegato Arduino alla VS, si crea il ttyACM0 ma se mando 'echo -e "rele08=1" >/dev/ttyACM0' (sul pin 8 ovviamente ho l'altro relè) non succede nulla, stesso dicasi da shell del PC, se però prima di dare l'echo do 'tail -f /dev/ttyACM0 &' e dopo rido il comando, le funzioni relè vanno finchè non killo la tail.

Ho provato a cercare su Google il perchè di questo, probabilmente la tail sincronizza la seriale, senza i comandi arrivano ad Arduino, i led lampeggiano, ma evidentemente la seriae non è impostata a 9600 8N1, come richiede il mio sketch, ma non ho trovato nulla.

Qualche idea ?

Ciao, Carlo.

Edit 08 Aprile 2013 23:20 - Riscritto completamente index.php adottando Ajax e spostando i comandi php per la seriale su file esterni.

Il progetto non è completamente funzionante, ma lo riporto nel caso servisse come spunto a qualcuno.
La parte relè funziona perfettamente e semplicemente modificando i limiti del ciclo for-next si possono aumentare i relè controllati, ovviamente adattando anche lo sketch.

ATTENZIONE - La parte temperatura non funziona, in realtà, il comando arriva ad Arduino, provato dal led collegato al pin 6, però per qualche motivo non viene letto dallo script php. Anche la parte che ritorna il valore e l'aggiorna nel <div> è da mettere a punto.

Purtroppo non sono l'unico ad avere problemi del genere con la seriale, come da bibliografia varia sul web.

I comandi sono 'rele0x=y' con x = 7 e 8 e y = 0 ed 1, c'è anche 'temp' che restituisce la temperatura dell'unico Dallas collegato.
I pin dei relè sono ovviamene 7 ed 8 mentre il Dallas è collegato al pin 3, i relè sono in logica negata.

Questo è lo sketch per Arduino:

Codice: Seleziona tutto

*---------------------------------*/
/*  Controllo relè tramite seriale */
/*---------------------------------*/

/* Indirizzi Dallas:
   Su RTC = 28ADAC4A0400007F
*/

#include <OneWire.h>
#include <DallasTemperature.h>

// Costanti
const int  		pinRele1 = 7;
const int  		pinRele2 = 8;
#define ONE_WIRE_BUS 3		// Pin Dallas DS18B20 

// Variabili
String strIngresso  = "";        // Contiene la stringa ricevuta
String strCmd       = String(5);
String strTmp  = "";
boolean strCompleta = false;    // Stato stringa ricevuta

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);


// Settaggi iniziali
void setup()
{
	// Settaggio Pin Rele' in Output ed impostazione a riposo per i rele in logica negata
    pinMode(pinRele1, OUTPUT);
	pinMode(pinRele2, OUTPUT);
	pinMode(6, OUTPUT);
	digitalWrite(pinRele1, HIGH);
	digitalWrite(pinRele2, HIGH);
    // Impostazioni seriale
	Serial.begin(9600);
	sensors.begin();
	delay(1000);
}

// Definizioni funzioni richiamate nel programma. 
String estrCmd(String, int, int);
// int estrVal(String, int, int);

// Funzione Principale
void loop()
{
	// Quando la stringa è completa la stampa ed inizia le operazioni:
	if (strCompleta) {
		// Elaborazione dei dati ricevuti dalla seriale 
	    // Estrazione del comando (rele/temp)	
		strCmd = estrCmd(strIngresso, 0, 3); 

		// Scrittura pin digitali
		if (strCmd == "rele") {
		    // Estrazione dei campi Valore e Piedino e conversione in itero
			String strTmp = estrCmd(strIngresso, 4, 5);
		    int piedino = strTmp.toInt();
			// Verifica che il pin del Rele sia nel range consentito
			if (piedino >= 7 || piedino <= 8){
				strTmp = estrCmd(strIngresso, 7, 7); 
				int valore = strTmp.toInt();
				Serial.print(" Pin = ") ;   	Serial.print(piedino);
				Serial.print(" valore = ") ;	Serial.println(valore);
				if (valore == 1){
					digitalWrite(piedino, LOW);
				}
				if (valore == 0){
					digitalWrite(piedino, HIGH);
				}
			}
		}
		
		// Lettura temperatura da dallas 
		if (strCmd == "temp") {
			sensors.requestTemperatures();
			float temperatura = sensors.getTempCByIndex(0);
			//Serial.print(" Temperatura = ") ;
			Serial.println(temperatura);
			digitalWrite(6, HIGH);
			delay(3000);
			digitalWrite(6, LOW);
		}	
			
		// Azzeramento variabili stringa ingresso:
//		Serial.print(" !! strIngresso = ") ;	Serial.println(strIngresso);
		strIngresso = "";
		strCmd = "";
		strCompleta = false;
	}
}

// Estrazione dati dalla stringa di input
String estrCmd(String stringa, int iniz, int fine)
{
    String comando = "";
	int k;
	fine++;
	for (k=iniz; k<fine; k++){
		char thisChar = stringa[k];
		comando.concat(thisChar);
	}	
    return comando;
}

/*
  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() {
	// Acquisizione di una carattere dalla seriale quando disponibile
	while (Serial.available()) {
		char carIngr = (char)Serial.read(); 
		//  Serial.print(" carIngr = ") ; Serial.println(carIngr) ;

		// Accodamento del carattere nella stringa
		strIngresso += carIngr;
		// All'arrivo del carattere di fine linea commuto lo switch ( strCompleta )
		if (carIngr == '\n') {
			strCompleta = true;
		}
	}
}
Ho installato lighthttpd per php su openwrt (Sembra uno scioglilingua :-) ) come da guida qui:http://wiki.openwrt.org/doc/howto/http. ... d.and.php5

E per finire ho creato la pagina iniziale /www/index.php

Codice: Seleziona tutto

<script>
// 
var myRequest = null;
function CreateXmlHttpReq(handler) {
  var xmlhttp = null;
  try {
    xmlhttp = new XMLHttpRequest();
  } catch(e) {
    try {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
  xmlhttp.onreadystatechange = handler;
  return xmlhttp;
}
function myHandler() {
    if (myRequest.readyState == 4 && myRequest.status == 200) {
       	alert(myRequest.responseText);  // Restituisce i dati da 'myRequest'
    }
}
/* Funzione per leggere la temperatura ed aggiornare il <div> */
function leggeTemp(sensore) {
    	var r = Math.random();
	myRequest = CreateXmlHttpReq(myHandler);
	myRequest.open("GET","temp.php?sensore="+escape(sensore)+"&rand="+escape(r));
// alert("temp.php?sensore="+escape(sensore)+"&rand="+escape(r));	
	myRequest.send(null);
	
	// Lettura dell'ID del div e relativo aggiornamento
	var divTemp = document.getElementById("divTemp1");
//	alert("divTemp = " +escape(divTemp));
    	divTemp.innerHTML = (myRequest.responseText);
}

/* Funzione per comandare i rele su seriale */
function rele(stato, pin) {
    	var r = Math.random();
   	myRequest = CreateXmlHttpReq(myHandler);
    	myRequest.open("GET","rele.php?pin="+escape(pin)+"&stato="+escape(stato)+"&rand="+escape(r));
//    alert("rele.php?pin="+escape(pin)+"&stato="+escape(stato)+"&rand="+escape(r));
    	myRequest.send(null);
}
</script>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//IT"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Rele Arduino</title>
</head>
<body>

<TABLE BORDER="1" ALIGN=CENTER> 
<TR><TD COLSPAN=4><H1>Rele Arduino</H1></TD></TR>

<?php
// Creazione Tabella Temperature
for ($temp = 1 ; $temp <= 1 ; $temp++)
	{
	echo "<TR><TD COLSPAN=1>Temperatura ".$temp; echo "</TD>\n";
	echo "<TD ALIGN=CENTER><input type='button' value='O' onClick='leggeTemp(".$temp.")'/>";
	echo "</TD>\n";
	echo '<TD></script><div id="divTemp'.$temp.'">N/D</div>' ;echo "</TD>\n";
	
	echo "</TD>\n";echo "</TR>";
	}

// Creazione Tabella Comandi Rele
for ($rele = 7 ; $rele <= 8 ; $rele++)
	{
	echo "<TR><TD>Rele ".$rele; echo "</TD>\n";
	echo "<TD ALIGN=CENTER><input type='button' value='On' onClick='rele(\"on\", ".$rele.")'/>";
	echo "</TD>\n";
	echo "<TD ALIGN=CENTER><input type='button' value='Off' onClick='rele(\"off\", ".$rele.")'/>";
	echo "</TD>\n";echo "</TR>";
	}
?>

</TABLE>
</body>
</html>
Di seguito il codice php per attivare il relè e per leggere la temperatura.

rele.php

Codice: Seleziona tutto

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
ini_set('display_startup_errors',1);

define("PORT","/dev/ttyUSB0");
require "php_serial.class.php";
$serial = new phpSerial;
$serial->deviceSet(PORT);
$serial->confBaudRate(9600);
$serial->confParity("none");
$serial->confCharacterLength(1);
$serial->confStopBits(1);
$serial->confFlowControl("none");
$serial->deviceOpen();
//    sleep(1);

if (isset($_GET['stato'])) {
	if ($_GET['pin'] > 9){
		$rele="rele";
	} else {
		$rele="rele0";
	}
	
    if ($_GET['stato'] == "on") {
    	$serial->sendMessage($rele.$_GET['pin']."=1\n");
    } else if ($_GET['stato'] == "off") {
    	$serial->sendMessage($rele.$_GET['pin']."=0\n");
    }   
}

$read = $serial->readPort();
echo $read;
$serial->deviceClose();
?>
temp.php

Codice: Seleziona tutto

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
ini_set('display_startup_errors',1);

define("PORT","/dev/ttyUSB0");
require "php_serial.class.php";
$serial = new phpSerial;
$serial->deviceSet(PORT);
$serial->confBaudRate(9600);
$serial->confParity("none");
$serial->confCharacterLength(1);
$serial->confStopBits(1);
$serial->confFlowControl("none");
$serial->deviceOpen();
//sleep(1);

if (isset($_GET['sensore'])) {   
	echo "sensore=".$_GET['sensore']; 
    $serial->sendMessage("temp\n");
    }
    
$read = $serial->readPort();
echo $read;
$serial->deviceClose();
?>
Ho copiato la php_serial.class.php presa dal sito dello sviluppatore http://www.phpclasses.org/browse/file/17926.html nella directory /www

A questo punto avviare il server con il comando '# /etc/init.d/lighttpd start' e puntare il browser all'indirizzo del router ed alla porta scelta nel config di lighttpd.
Ultima modifica di cybor il 08 apr 2013, 23:34, modificato 3 volte in totale.
Avatar utente
alez
Messaggi: 3074
Iscritto il: 09 mag 2007, 17:11

Re: Comandi su seriale da shell

Messaggio da alez »

Lo sketch Arduino l'hai prima testato con la console seriale della IDE di arduino?

Se funziona controlla che sulla VS la seriale sia settata alla velocità e agli altri parametri corretti per comunicare con Arduino.
Ciao alez
Avatar utente
ragno
Messaggi: 3017
Iscritto il: 20 gen 2007, 09:43
Località: Marte e dintorni
Contatta:

Re: Comandi su seriale da shell

Messaggio da ragno »

Il consiglio di testare prima tutto dal serial monitor dell'IDE, mi pare la prima cosa da fare. ;)
Aggiungo che collegando un classico adattatore usb2ttl ai pin 0 e 1 dell'arduino (aggiungendo un gnd da qualche parte) e collegando l'arduino alla VS come da circuito, si puo' loggare tutto il traffico dei comandi inviati dalla VS all'Arduino.

Controllare il flow control, meglio impostarlo su NONE.

(Rimane anche un'altra possibilita' tutto funziona, ma il parser comandi lato arduino non funziona perche' la sequenza di terminazione della stringhe non deve essere solo LF ma CR-LF).

:ciao:
vdr: 1.4.7+extpatch54 (pensionata), 1.7.27 (yavdr 0.4)
Percorri la via che porta al sole,
e non camminare sui sentieri oscuri.

E quando penso che sia finita,
è proprio allora che comincia la salita.
cybor
Messaggi: 85
Iscritto il: 04 apr 2009, 11:50

Re: Comandi su seriale da shell

Messaggio da cybor »

Con il monitor seriale dell'IDE ufficiale funziona avendo l'accortezza di settare 'NL' come terminatore e mi sembra normale visto che il parser usa proprio '\n' per rilevare la fine della stringa.

Il problema sembra tutto sulla seriale lato host (PC o VS), penso che inviando i comandi direttamente da shell il device ttyACM0 non sia correttamente inizializzato ed aperto, cosa che avviene correttamente usando CuteCom o il monitor seriale dell'IDE Arduino.

Sto provando con setserial e stty ma non sto ottenendo nessun risultato, proverò a breve anche a monitorare con l'adattatore USB/seriale.

Ho provato anche con Putty. Settando LF implicito dopo ogni CR funziona correttamente.

Rimango dell'idea che inviando da shell i comandi sul device seriale ttyACM0 la velocità sia fluttuante e quindi non leggibili da Arduino.
Avatar utente
ragno
Messaggi: 3017
Iscritto il: 20 gen 2007, 09:43
Località: Marte e dintorni
Contatta:

Re: Comandi su seriale da shell

Messaggio da ragno »

@cybor: devi trovare una maniera di capire (settare) a che velocita' e' impostata la com virtuale sotto VS. La velocita' comunque non puo' essere flottante.

In ogni caso la velocita' lato arduino puo' essere variata in fase di inizializzazione con Serial.begin() impostando una delle velocita' canoniche' (da 9600 a 115200) quindi non sei vincolato ai 9600.

:ciao:
vdr: 1.4.7+extpatch54 (pensionata), 1.7.27 (yavdr 0.4)
Percorri la via che porta al sole,
e non camminare sui sentieri oscuri.

E quando penso che sia finita,
è proprio allora che comincia la salita.
Avatar utente
ragno
Messaggi: 3017
Iscritto il: 20 gen 2007, 09:43
Località: Marte e dintorni
Contatta:

Re: Comandi su seriale da shell

Messaggio da ragno »

per stty prova:

Codice: Seleziona tutto

stty -F /dev/tty<tua usb arduino> cs8 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts -clocal
:ciao:

p.s. riferimento http://web.archive.org/web/201208120801 ... index.html
vdr: 1.4.7+extpatch54 (pensionata), 1.7.27 (yavdr 0.4)
Percorri la via che porta al sole,
e non camminare sui sentieri oscuri.

E quando penso che sia finita,
è proprio allora che comincia la salita.
cybor
Messaggi: 85
Iscritto il: 04 apr 2009, 11:50

Re: Comandi su seriale da shell

Messaggio da cybor »

@ ragno

Grazie per i consigli, ho provato con la stringa stty, ma come altre trovate su internet, compreso sul sito di Arduino, non funzionano.

L'unico risultato raggiunto è stato dalla shell del PC con un adattatore USB/seriale da 1 € con PL2303 che collegato ai pin 1 e 2 funziona perfettamente sia a 9600 che 38400, ho anche provato a sostituire il terminatore da '\n' a '#' e continua a funzionare solo questo adattatore e purtroppo solo su PC mentre su VS non va nulla, oltretutto il comando stty su VS va solo sul device USB0 mentre fallisce su ACM0 e comunque dopo non va nulla in ogni modo.

@ alez

dicevi di controllare la velocità della seriale sulla VS, ma è proprio quello che non riesco a fare, qualche idea ?

Penso che, salvo qualche idea illuminante, la mollerò li, ci sono troppi problemi ed oltretutto dovrei anche affrontare il problema della ricezione dei dati da passare all'interfaccia web dove vorrei fa comparire le temperature, farò giusto un ultimo tentativo per vedere se si riesce a fare qualcosa in python.
Avatar utente
ragno
Messaggi: 3017
Iscritto il: 20 gen 2007, 09:43
Località: Marte e dintorni
Contatta:

Re: Comandi su seriale da shell

Messaggio da ragno »

@cybor, ma il tuo dongle usb2ttl come viene riconosciuto dalla VS? Sempre come ACMx oppure USBx?
Al limite se andasse come USB potresti utilizzare una board senza convertitore (ad esempio lo xino, ma potresti pure fare qualcosa con una semplice breadboard, avendo l'arduino come base per programmare il chip , collegare i pin 1, 2 e gnd) ed andare con quello.

ciao
vdr: 1.4.7+extpatch54 (pensionata), 1.7.27 (yavdr 0.4)
Percorri la via che porta al sole,
e non camminare sui sentieri oscuri.

E quando penso che sia finita,
è proprio allora che comincia la salita.
Avatar utente
alez
Messaggi: 3074
Iscritto il: 09 mag 2007, 17:11

Re: Comandi su seriale da shell

Messaggio da alez »

Per settare la velocità, guarda se su VS c'è il comando setserial.

Come dice Ragno, il dongle deve essere visto come /dev/ttyUSB0 e non come ACM0






p.s. x Ragno: l'ultimo clone di duemilanove che mi è arrivato ha un PL2003 invece del classico FTDI, si tratta del roboduino

http://www.dipmicro.com/img/1/BTE-RCBDUE-1.jpg
Ciao alez
Avatar utente
ragno
Messaggi: 3017
Iscritto il: 20 gen 2007, 09:43
Località: Marte e dintorni
Contatta:

Re: Comandi su seriale da shell

Messaggio da ragno »

alez ha scritto:
p.s. x Ragno: l'ultimo clone di duemilanove che mi è arrivato ha un PL2003 invece del classico FTDI, si tratta del roboduino

http://www.dipmicro.com/img/1/BTE-RCBDUE-1.jpg
Ah, ecco come stanno risparmiando su qualcosa, l'FTDI e' piu' performante del cinese PL2023, pero' in verita' nel collegamento seriale non ho mai notato differenze (almeno fino a 115200).
Peccato perche il 2009 con ftdi, puoi pure utilizzarlo come programmatore.

:ciao:
vdr: 1.4.7+extpatch54 (pensionata), 1.7.27 (yavdr 0.4)
Percorri la via che porta al sole,
e non camminare sui sentieri oscuri.

E quando penso che sia finita,
è proprio allora che comincia la salita.
Avatar utente
alez
Messaggi: 3074
Iscritto il: 09 mag 2007, 17:11

Re: Comandi su seriale da shell

Messaggio da alez »

Beh per quello ho il duemilanove originale con modifica FTDI :D
Ciao alez
cybor
Messaggi: 85
Iscritto il: 04 apr 2009, 11:50

Re: Comandi su seriale da shell

Messaggio da cybor »

In effetti sono stato poco chiaro nel messaggio precedente, quando usavo la seriale di arduino ho sempre usato il device ttyACM0 mentre ogni volta che ho fatto delle prove con il PL2303 ho usato il device ttyUSB0.

Ho fatto ulteriori prove e sono riuscito a far passare qualche comando dando una
# cat /dev/ttyUSB0

e poi settando la seriale in un altro terminale con
# stty -F /dev/ttyUSB0 speed 38400 raw

Comunque non tutti i comandi arrivano, in realtà la cosa non è del tutto campata in aria ma c'è qualcosa che mi sfugge, al seguente link c'è un cosa del tutto simile alla mia:

http://ediy.com.my/index.php/blog/item/ ... -using-lua

Domani farò qualche altra prova.

Si, sono a conoscenza di moduli Arduino senza USB, giusto questa mattina mi sono arrivati 2 Arduino Pro Mini che avevo ordinato qualche tempo fa.
Avatar utente
ragno
Messaggi: 3017
Iscritto il: 20 gen 2007, 09:43
Località: Marte e dintorni
Contatta:

Re: Comandi su seriale da shell

Messaggio da ragno »

@cybor: non mi pare molto "smart" gestire la seriale da 2 terminali.

Io fare cosi:

1) test per vedere se la seriale esiste: echo "1" > /dev/ttyUSB0
2) impostare la seriale a livello hardware (bps, flow control,parita', etc) con setserial
3) impostare l'i/o per il terminale tramite stty.

A mio avviso tutto cio' ha valenza solo nel caso tu voglia utilizzare i comandi di rendirizzamento direttamente da console, ma se utilizzi un programma come miniterm o altro, nessuno di questi passi e' necessario perche imposti tutto dal programma stesso.

:ciao:

p.s. strano che il FTDI sia riconosciuto diversamente dal PLC2023...
vdr: 1.4.7+extpatch54 (pensionata), 1.7.27 (yavdr 0.4)
Percorri la via che porta al sole,
e non camminare sui sentieri oscuri.

E quando penso che sia finita,
è proprio allora che comincia la salita.
cybor
Messaggi: 85
Iscritto il: 04 apr 2009, 11:50

Re: Comandi su seriale da shell

Messaggio da cybor »

Alla fine ho rinunciato all'uso della port Ftdi di Arduino, stranamente uno scrauso adattatore USB<>Seriale a poco più di un euro su OpenWRT funziona meglio, io ho provato con la backfire, magari con la trunk va meglio, sicuramente in futuro proverò.
La /dev/ttyACM0 non accetta neanche le cat e le tail, esce subito senza messaggi.

Comunque visto che vi ho tediato alquanto e che molto cortesemente mi avete risposto, vi beccate tutto il codice... anche se incompleto :-P

I comandi sono 'rele0x=y' con x = 7 e 8 e y = 0 ed 1, c'è anche 'temp' che restituisce la temperatura dell'unico Dallas collegato.
I pin dei relè sono ovviamene 7 ed 8 mentre il Dallas è collegato al pin 3, i relè sono in logica negata.

Questo è lo sketch per Arduino:

Codice: Seleziona tutto

/*---------------------------------*/
/*  Controllo relè tramite seriale */
/*---------------------------------*/

/* Indirizzi Dallas:
   Su RTC = 28ADAC4A0400007F
*/

#include <OneWire.h>
#include <DallasTemperature.h>

// Costanti
const int  		pinRele1 = 7;
const int  		pinRele2 = 8;
#define ONE_WIRE_BUS 3		// Pin Dallas DS18B20 

// Variabili
String strIngresso  = "";        // Contiene la stringa ricevuta
String strCmd       = String(5);
String strTmp  = "";
boolean strCompleta = false;    // Stato stringa ricevuta

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);


// Settaggi iniziali
void setup()
{
	// Settaggio Pin Rele' in Output ed impostazione a riposo per i rele in logica negata
    pinMode(pinRele1, OUTPUT);
	pinMode(pinRele2, OUTPUT);
	digitalWrite(pinRele1, HIGH);
	digitalWrite(pinRele2, HIGH);
    // Impostazioni seriale
	Serial.begin(9600);
	sensors.begin();
	delay(1000);
}

// Definizioni funzioni richiamate nel programma. 
String estrCmd(String, int, int);
// int estrVal(String, int, int);

// Funzione Principale
void loop()
{
	// Quando la stringa è completa la stampa ed inizia le operazioni:
	if (strCompleta) {
		// Elaborazione dei dati ricevuti dalla seriale 
	    // Estrazione del comando (rele/temp)	
		strCmd = estrCmd(strIngresso, 0, 3); 

		// Scrittura pin digitali
		if (strCmd == "rele") {
		    // Estrazione dei campi Valore e Piedino e conversione in itero
			String strTmp = estrCmd(strIngresso, 4, 5);
		    int piedino = strTmp.toInt();
			// Verifica che il pin del Rele sia nel range consentito
			if (piedino >= 7 || piedino <= 8){
				strTmp = estrCmd(strIngresso, 7, 7); 
				int valore = strTmp.toInt();
				Serial.print(" Pin = ") ;   	Serial.print(piedino);
				Serial.print(" valore = ") ;	Serial.println(valore);
				if (valore == 1){
					digitalWrite(piedino, LOW);
				}
				if (valore == 0){
					digitalWrite(piedino, HIGH);
				}
			}
		}
		
		// Lettura temperatura da dallas 
		if (strCmd == "temp") {
			sensors.requestTemperatures();
			float temperatura = sensors.getTempCByIndex(0);
			Serial.print(" Temperatura = ") ;	Serial.println(temperatura);
		}	
			
		// Azzeramento variabili stringa ingresso:
		strIngresso = "";
		strCompleta = false;
	}
}

// Estrazione dati dalla stringa di input
String estrCmd(String stringa, int iniz, int fine)
{
    String comando = "";
	int k;
	fine++;
	for (k=iniz; k<fine; k++){
		char thisChar = stringa[k];
		comando.concat(thisChar);
	}	
    return comando;
}

/*
  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() {
	// Acquisizione di una carattere dalla seriale quando disponibile
	while (Serial.available()) {
		char carIngr = (char)Serial.read(); 
		//  Serial.print(" carIngr = ") ; Serial.println(carIngr) ;

		// Accodamento del carattere nella stringa
		strIngresso += carIngr;
		// All'arrivo del carattere di fine linea commuto lo switch ( strCompleta )
		if (carIngr == '\n') {
			strCompleta = true;
		}
	}
}
Ho installato lighthttpd per php su openwrt (Sembra uno scioglilingua :-) come da guida qui:http://wiki.openwrt.org/doc/howto/http. ... d.and.php5

E per finire ho creato la pagina iniziale /www/index.php

Codice: Seleziona tutto

<?php

error_reporting(E_ALL);
ini_set("display_errors", 1);
ini_set('display_startup_errors',1);

define("PORT","/dev/ttyUSB0");
 
if (isset($_GET['action'])) {
    require "php_serial.class.php";
    $serial = new phpSerial;
    $serial->deviceSet(PORT);
    $serial->confBaudRate(9600);
    $serial->confParity("none");
    $serial->confCharacterLength(1);
    $serial->confStopBits(1);
    $serial->confFlowControl("none");
    $serial->deviceOpen();
    sleep(2);
    if ($_GET['action'] == "on") {
        $serial->sendMessage("rele07=1\n");
        } else if ($_GET['action'] == "off") {
        $serial->sendMessage("rele07=0\n");
    }
    $read = $serial->readPort();
    echo $read;
    $serial->deviceClose();
}
?>
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Rele Arduino</title>
</head>
<body>
<br>
<h1>Rele Arduino</h1>
 
<a href="<?php echo $_SERVER['PHP_SELF'] . "?action=on" ?>">
   <button style="width:100px""><h1>ON</h1></button></a>

<a href="<?php echo $_SERVER['PHP_SELF'] . "?action=off" ?>">
   <button style="width:100px""><h1>OFF</h1></button></a>

</body>
</html>
Ho copiato la php_serial.class.php presa dal sito dello sviluppatore http://www.phpclasses.org/browse/file/17926.html nella directory /www

A questo punto avviare il server con il comando '# /etc/init.d/lighttpd start' e puntare il browser all'indirizzo del router ed alla porta scelta nel config di lighttpd.

Sicuramente aggiungerò altre funzioni, per esempio il secondo relè che adesso non è selezionabile da pagina web ed la lettura del Dallas o meglio ancora di più Dallas.
Avatar utente
ragno
Messaggi: 3017
Iscritto il: 20 gen 2007, 09:43
Località: Marte e dintorni
Contatta:

Re: Comandi su seriale da shell

Messaggio da ragno »

@cybor: grazie per la condivisione!
Il tuo sketch si dovrebbe adattare molto facilmerente ai moduli NRF2401...

:ciao:
vdr: 1.4.7+extpatch54 (pensionata), 1.7.27 (yavdr 0.4)
Percorri la via che porta al sole,
e non camminare sui sentieri oscuri.

E quando penso che sia finita,
è proprio allora che comincia la salita.
Rispondi