Comunicazione seriale con arduino [aiuto]

Il cosa inviare è importante perchè in questa maniera stabilisci un "protocollo" di comunicazione e non mandi dati a "casaccio" ma stabilisci delle regole ben precise, visto che poi da lato Arduino i comandi non sono molto sofisticati.

sisi quello che intendevo dire è che il protocollo ancora non l'ho stabilito e che vorrei stabilirlo in modo da rendere il compito ad arduino il più semplice possibile.
Ma non so quale sia questo modo

Mi potresti aiutare a trovare il modo giusto per la gestione in arduino? ti ripeto la stringa la posso inviare come vuoi, quindi se tu magari sai come fare questa cosa, dimmi di quale stringa hai bisogno in input per farlo

Io mi baserei sulla readBytesUntil()

Spedisci 4 cifre più un fine msg ad esempio #
tra le variabili globali:

char buf[10];
if(Serial.available()>0)
{ byte nletti,funz=0,tempo=0; 
  nletti=Serial.readBytesUntil('#', buf, sizeof(buf));
  if(nletti>0)    // può non leggere nulla, se attende oltre timeout
  {  funz=buf[0]-'0';           // primo char convertito in cifra    es. '3' => 51   51-'0'  => 51-48 => 3 come valore
     tempo=(buf[1]-'0')*10+(buf[2]-'0');     
  }
  
}

Non ho arduino collegato, non posso provarlo e stò per andare a dormire :sleeping:

Wow grazie mille :slight_smile:
L'unica cosa che non ho capito bene è perchè dichiari funzione e tempo come byte?

funz=buf[0]-'0';           // primo char convertito in cifra    es. '3' => 51   51-'0'  => 51-48 => 3 come valore
     tempo=(buf[1]-'0')*10+(buf[2]-'0');

Questi due calcoli neanche ho capito :\

Però magari mi rispondi domani xD
Buona notte e grazie mille :smiley:

vedi, i dati puoi inviarli grezzi, come byte, facilmente leggibili dai PC, o in forma di lettere, facilmente leggibili dagli umani.

Arduino ua l'ascii come tabella per trasformare i caratteri in numeri. Ogni carattere (e i numeri sono caratteri) è trasformato nell'equivalente numero della tabella e poi inviato.
Svataggio: ogni carattere è un byte, quindi mooolta byte/s sono sprecati, oltre che la conversione da lettera a valore utilizzabile (esempio: gli int sono sempre 2 byte grezzi, in lettere dipende da quante cifre ha il numero...)
Vantaggio: se apri il serial monito leggi il numero e non un serie di simboli "a caso"

Byte perchè tu invii due valori, la prima è una sola cifra perciò 0-9 e un byte basta e lo metto in variabile funz (potevo chiamarla pippo)
la seconda 00-99 e perciò un byte basta (messo in variabile tempo, secondo le tue indicazioni iniziali)

Poi ho visto oggi che la seconda è a tre cifre perciò tempo deve essere int.

quando spedisci 1230# allora dopo la lettura avrai nel buffer di nome buf[]

buf
[0] = '1'       carattere '1' che nella tabella ascii è il numero 49
[1] = '2'       carattere '2' in ascii 50 
[2] = '3'       carattere '3' in ascii 51
[3] = '0'       carattere '0' in ascii 48
[4] = boh da qui in poi non si sa, ci può essere 0 (valore) o un valore a caso

Per il computer '0' è il valore 48 che stampato a video è il simbolo '0'

Perciò
funz = buf[0] - '0'; ovvero 49-48
tempo= (buf[1]-'0')*100 + (buf[2]-'0')*10 + (buf[3]-'0') * 1; ovvero (50-48)*100 + (51-48)10 + 48-481

E' obbligatorio che vengano inviati sempre 4 cifre e a finire il #
altrimenti quel calcolo sballa. Perciò "010" o "003" e non "10" o "3"
Se il secondo valore non ha dimensione fissa (3 char) allora bisogna usare altra tecnica.

isdigit() è una funzione che ti dice se il carattere è una cifra cioè tra '0' e '9' (tra 48 e 57)
if( isdigit(buf[0]) ) // se la cella 0 di buf contiene una cifra

atoi() converte da stringa a intero (stringa=array o vettori di caratteri con alla fine '\0' o null, NON oggetto String)
val = atoi(buf); // ma buf deve terminare con carattere '\0'

ok ora funzione se lo comando tramite monitor seriale
ma non tramite php
quindi il problema sta nel php :
comunque il codice è questo

void loop ()
{
  if(Serial.available()>0)
{ byte nletti,funz=0,tempo=0; 
  nletti=Serial.readBytesUntil('#', buf, sizeof(buf));
  if(nletti>0)    // può non leggere nulla, se attende oltre timeout
  {  funz=buf[0]-'0';           // primo char convertito in cifra    es. '3' => 51   51-'0'  => 51-48 => 3 come valore
     tempo=(buf[1]-'0')*100+(buf[2]-'0')*10+(buf[3]-'0'); 
     pausa= int(tempo);
     funzione= int(funz);
  }
}
switch (funzione)
     {
        case 0:;break;
        case 1: uno_alla_volta(pausa);azzera();break;
        case 2: livelli(pausa);azzera();break;
        case 3: colonne(pausa);azzera();break;
        case 4: verticale(pausa);azzera();break;
     }
}

Però se gli invio una nuova serie, aspetta prima la fine della funzione e poi fa partire l'altra, perchè? :\ non c'è un modo per arrestare l'esecuzione e far partire la nuova?
Inoltre ogni volta che finisce la funzione, aspetta un po' prima di farla ripartire, non si coporta come si dovrebbe comportare semplicemente in loop (accade con tutte le funzioni)

Qual'è il problema di questo pezzo di codice? O.o

echo ' 
		<form action="arduino.php" method="post" target="_self"> 
				<label><b>Scegli la funzione </b>
				<select name="funzione" size="1">
				<option value="1">Uno alla volta</option>
				<option value="2">Livelli</option>
				<option value="3">Colonne</option>
				<option value="4">Verticale</option>		
				</select></label>

				<label>Tempo intermittenza in millisecondi (3 cifre) <input type="text" name="pausa" size="4"/></label>
				<input type="text" name="nascosto" value="inviato" hidden/>
				<input type="submit" value="Invia" />				
			</form>
';
			if (!isset($_POST['nascosto']))
			{}
			else
			{
				if($_POST['pausa']!='' )
				{
					if (strlen($_POST['pausa'])==3)
					{	
						$messaggio=''.$_POST['funzione'].$_POST['pausa'].'#';
						$serial->sendMessage($messaggio,1);
						echo $messaggio;
					}
					else
					{
						echo'<font color="red">La pausa deve essere formata da 3 cifre</font> 
';
					}
				}
				else
				{
					echo'<font color="red">Inserisci la pausa prima di inviare!</font>
';
				}
			}

Cioè inviando la stessa stringa ad arduino tramite monitor seriale, arduino funziona.
Però inviandola tramite php, non va :expressionless:
Eppure me la stampa la stringa, quindi vuol dire che il messaggio dovrebbe inviarlo.
Inoltre se arduino è in funzione, quando chiudo il monitor seriale e carico la pagina di arduino, questo smette di funzionare :\

Sto utilizzando la php_serial_class

@toti94:

  1. se hai URGENZA, rivolgiti ad un programmatore professionista, gli paghi la parcella e ti fai fare il programma che ti serve. Ho tolto "URGENTE" dal titolo perché il forum non è un centro assistenza
  2. perché aprire 2 thread per lo stesso problema? stai avendo problemi nella comunicazione seriale/php tra arduino e computer, perché non continuare qui?

Scusa per l'urgente
Ho aperto un altro post perchè qui si parlava dello sketch arduino, mentre nell'altro del codice php :expressionless:
Scusa comunque :\

il pezzo di codice PHP che mostri SEMBRA corretto... c'è da vedere se lo è anche la parte prima, in particolare dcove inizilaizzi laslasse $serial

<?php session_start();?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<script type="text/javascript" src="jquery-1.9.1.js"></script>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script src="elementi/slideshow.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Sito d'esame-Arduino</title>
</head>

<body>
<div id="accentramento">
	<div id="barra_utente">
	<?php include'elementi/barra_utente.php'; ?>
	</div>
	<div id="cont_slide">
	<?php include'elementi/slideshow.html'; ?>
	</div>
	<div id="menu">
	<?php include "elementi/menu.html"; ?>
	</div>
	 <div id="contenitore">
	<div id="parte_centrale">
	<?php if (!isset($_SESSION["accesso"]))
	{
		echo '<h1>Accesso Negato</h1>
Devi effettuare prima il login per accedere a questa pagina!!';
	}
	else
	{
	  echo'<h1>Seleziona la funzione che vuoi visualizzare sul cubo</h1><hr />
';
		include 'elementi/php_serial.class.php';
		$serial = new phpSerial;

		$serial->deviceSet("COM3");
		$serial->confBaudRate(9600);
		$serial->confParity("none");
		$serial->confCharacterLength(8);
		$serial->confStopBits(1);
		$serial->confFlowControl("none");

		$serial->deviceOpen();		
		
		echo ' 
		<form action="arduino.php" method="post" target="_self"> 
				<label><b>Scegli la funzione </b>
				<select name="funzione" size="1">
				<option value="1">Uno alla volta</option>
				<option value="2">Livelli</option>
				<option value="3">Colonne</option>
				<option value="4">Verticale</option>		
				</select></label>

				<label>Tempo intermittenza in millisecondi (3 cifre) <input type="text" name="pausa" size="4"/></label>
				<input type="text" name="nascosto" value="inviato" hidden/>
				<input type="submit" value="Invia" />				
			</form>
';
			if (!isset($_POST['nascosto']))
			{}
			else
			{
				if($_POST['pausa']!='' )
				{
					if (strlen($_POST['pausa'])==3)
					{	
						$messaggio=''.$_POST['funzione'].$_POST['pausa'].'#';
						$serial->sendMessage($messaggio,1);
						echo $messaggio;
					}
					else
					{
						echo'<font color="red">La pausa deve essere formata da 3 cifre</font> 
';
					}
				}
				else
				{
					echo'<font color="red">Inserisci la pausa prima di inviare!</font>
';
				}
			}
		}	
		$serial->deviceClose();	
?>
</div>
  </div>
  
  <div id="footer">
	<?php include'elementi/footer.php'; ?>
  </div>
</div>

</body>
</html>
$serial->deviceSet("COM3");
$serial->confBaudRate(9600);

sicuro di questi 2 parametri?

sisi, l'ide mi porta la com 3 e in setup ho scritto Serial.begin(9600)

ma ti da qualche errore? non è che lasci aperto il serialMonitor di arduino?

no il serial monitor non è aperto.
In php non ho nessun errore, mentre in arduino non so se arriva o meno dato che non posso controllare sul monitor :S

Ho risolto ...
A quanto pare il "#" finale dava problemi :\ così l'ho tolto e funziona tutto

Prima ha funzionato e ora non va più :expressionless: cos'è sta robba D:

EDIT: mi sono accorto che PHP funziona solo con la 3a funzione, ovvero "colonne", poi se ne invio un altra si blocca con l'ultima colonna illuminata :\