Problema Modellino Ascensore [Maturità]

Ciao a tutti!
Io ed altri miei amici stiamo preparando per la maturità un modellino di ascensore funzionante con due Arduino.
Il primo è un Arduino UNO e fa girare il codice che permette il corretto funzionamento dell'Ascensore, mentre il secondo è un Arduino UNO Ethernet nel quale gira un webserver che permette di comandare il modellino tramite computer e smartphone piuttosto che con il semplice ausilio dei tasti.
Proprio in questo punto si presenta il problema, utilizzando i tasti funziona tutto ok per esempio, se la mia cabina si trova al piano 1 e schiaccio il tasto 2, il motore funzionerà fina quando il finecorsa schiacciato sia quello corrispondente al tasto premuto.
Mentre, utilizzando il server qualcosa va storto se premo piano 4 si ferma al terzo, se rischiaccio il 4 val al 1 e così via, il concetto è il medesimo dato che i pin in uscita sono stati collegati in parallelo ai tasti dei piani dell'Arduino principale, pure le masse dei due Arduino sono state collegate insieme...

Non capisco proprio cosa ci sia che non possa andare...
Consigli? Ringrazio in anticipo...

Questo è il codice che gira nell'Arduino UNO (quello principale)

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

//motore cabina
int avm = 13; // Motore marcia avanti
int inm = 12; // Motore marcia indietro

//motore porta cabina
int po = 11; // Apertura porte
int pc = 10; // Chiusura porte

//finecorsa
int fp4 = 9; // Finecorsa piano 4
int fp3 = 8; // Finecorsa piano 3
int fp2 = 7; // Finecorsa piano 2
int fp1 = 6; // Finecorsa piano 1

//tasti piano
int tp4 = 5; //Tasto piano 4
int tp3 = 4; //Tasto piano 3
int tp2 = 3; //Tasto piano 2
int tp1 = 2; //Tasto piano 1

//dichiaro variabili
int P = 0;
int PT = 0;
int c = 0;
int d = 1;
int e = 0;
int val1 = 0;
int val2 = 0;
int val3 = 0;
int val4 = 0;
int val5 = 0;
int val6 = 0;
int val7 = 0;
int val8 = 0;

String readString; //string
boolean LEDON = false; //LED status flag

void setup()
{
//configuarazione pin
pinMode(avm, OUTPUT);
pinMode(inm, OUTPUT);
pinMode(po, OUTPUT);
pinMode(pc, OUTPUT);
pinMode(fp4, INPUT);
pinMode(fp3, INPUT);
pinMode(fp2, INPUT);
pinMode(fp1, INPUT);
pinMode(tp4, INPUT);
pinMode(tp3, INPUT);
pinMode(tp2, INPUT);
pinMode(tp1, INPUT);
Serial.begin(9600);
}

void loop( )
{

//inizio programma

finecorsa:
val1 = digitalRead(fp1);
val2 = digitalRead(fp2);
val3 = digitalRead(fp3);
val4 = digitalRead(fp4);
if (val1 == HIGH) { //controllo finecorsa piano 1
PT = 1 ;
goto pulsante; //si PIANO=1
}else if (val2 == HIGH) { //controllo finecorsa PIANO=2
PT = 2 ;
goto pulsante;
}else if (val3 == HIGH) {
PT = 3 ;
goto pulsante;
}else if (val4 == HIGH) {
PT = 4 ;
goto pulsante;
}else
goto finecorsa;

//fine controllo piani

pulsante:
if (c == 0 && PT>0){
P = PT;
c = 1;
}else
val5 = digitalRead(tp1);
val6 = digitalRead(tp2);
val7 = digitalRead(tp3);
val8 = digitalRead(tp4);
if (val5 == HIGH) { //controllo tasto piano 1
P = 1 ;
e = 1;
goto motore; //si PIANO=1
}else if (val6 == HIGH) { //no controllo tasto PIANO=2
P = 2 ;
e = 1;
goto motore;
}else if (val7 == HIGH) {
P = 3 ;
e = 1;
goto motore;
}else if (val8 == HIGH) {
P = 4 ;
e = 1;
goto motore;
//fine controllo tasti piani
}

motore: //avvio motore

if (P < PT) { //ascensore sotto alla destinazione
digitalWrite(avm, LOW);
digitalWrite(inm, HIGH);
d = 1; //cabina sale
goto porte;
}else if (P > PT) { //ascensore sopra alla destinzione
digitalWrite(inm, LOW);
digitalWrite(avm, HIGH); //cabina scende
d = 1;
goto porte;
}else if (P == PT) { //ascensore a destination
digitalWrite(avm, LOW); //motore spento
digitalWrite(inm, LOW);
d = d+1;
goto porte;
} //fine avvio motore

porte: //apertura porte
if (d == 2 && e == 1) {
digitalWrite(po, HIGH);
delay(500);
digitalWrite(po, LOW);
delay(3000);
digitalWrite(pc, HIGH);
delay(500);
digitalWrite(pc, LOW);
delay(500);
e=0;
}else goto finecorsa;

}

Mentre questo è il codice che gira nell'Arduino UNO Ethernet:

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {
192,168,0,30 };
File htmlFile;
Server server(80);

int i = 0;
int t1 = 6; // LED pin
int t2 = 7; // LED pin
int t3 = 8; // LED pin
int t4 = 9; // LED pin
String readString; //string
boolean LEDON = false; //LED status flag

void setup()
{
Ethernet.begin(mac, ip);
server.begin();
if (!SD.begin(4)) {
return;
}
pinMode(t1, OUTPUT);
pinMode(t2, OUTPUT);
pinMode(t3, OUTPUT);
pinMode(t4, OUTPUT);
Serial.begin(9600);
}

void loop()
{
Client client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
readString.concat(c); //store characters to string
if (c == '\n' && currentLineIsBlank) {
Serial.print(readString);
if(readString.indexOf("L=1") > 0) {//lets check if LED should be lighted
digitalWrite(t1, HIGH);
delay(1000);
digitalWrite(t1, LOW);
}
if(readString.indexOf("L=2") > 0) {//lets check if LED should be lighted
digitalWrite(t2, HIGH);
delay(500);
digitalWrite(t2, LOW);
}
if(readString.indexOf("L=3") > 0) {//lets check if LED should be lighted
digitalWrite(t3, HIGH);
delay(500);
digitalWrite(t3, LOW);
}

if(readString.indexOf("L=4") > 0) {//lets check if LED should be lighted
digitalWrite(t4,HIGH);
delay(500);
digitalWrite(t4, LOW);
}

client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println();
// inizializzo pagina (da togliere se uso ajax)
client.print("");
client.println("");
client.println("");
client.print("");
client.println("");
client.println("Comando Eseguito!");
// chiudo pagina da togliere se uso ajax
client.println("");
break;
}
if (c == '\n') {
currentLineIsBlank = true;
}
}
}
client.stop();
}
}

CIao

se ho ben capito stai usando l'arduino ethernet per "schiacciare" virtualmente i pulsanti, collegando le sue uscite "in parallelo" con i pulsanti reali? Potresti disegnare questo collegamento?

In generale se posso suggerire un altro approccio, potreste pensare di far "parlare" i due Arduino o addirittura ve ne basta uno solo che gestisce sia i pulsanti sia i comandi ricevuti via ethernet...

Esattamente, gli schemi me li farò inviare subito domani dato che li ha realizzati un mio amico.
Inizialmente avevo provato ad utilizzare un Arduino sia per il server che per l'ascensore, ma poi si bloccava perchè il software rimane in loop quando controlla i piani...
Grazie per la risposta!

pulsante:
if (c == 0 && PT>0){
  P = PT;
  c = 1;
  }else
val5 = digitalRead(tp1);  
val6 = digitalRead(tp2);  
val7 = digitalRead(tp3);  
val8 = digitalRead(tp4);

Mancano le parentesi graffe oppure c'è un else in più.
Così l'else è riferito solo a val5 = digitalRead(tp1); che non viene eseguito se l'if è vero.

Comunque, giudizio personale, il codice con quei goto è veramente... pittoresco.

Grazie mille per il consiglio, corggo subito!
Comunque lo so che il codice non è proprio dei migliori, sono alle prime armi con Arduino e la via dei goto mi è sembrata la più semplice e funzionale...
I problemi sono nati da quando abbiamo collegato il webserver, appena possibile provo il tutto con la correzione, grazie ancora...

Ciao

(so che ormai la maturità è vicina quindi non avrete molto tempo da dedicare al progetto :wink: ) il tuo sw si blocca perché la funzione finecorsa continua ad essere eseguita occupando tutte le risorse disponibili... vedo che sono stati usati molti "salti" (goto), mentre la "buona" programmazione, anche in Arduino, suggerisce di sfruttare il loop() principale utilizzando delle variabili di stato, qualcosa tipo:

  • premo il pulsante piano 1, imposto una variabile di stato che dice "sto andando al piano 1"
  • all'interno del loop principale verifico: sono nello stato "sto andando al piano 1"? allora controllo se ci sono arrivato

spero di essermi spiegato...

Grazie per i consigli utili, in futuro farò sicuramente attenzione a realizzare un programma più lineare, ma ora come ora ci hanno dato la scadenza di una settimana per finirlo alla meglio peggio.
Con i tasti funziona perfettamente, è quella la cosa strana...

Ecco gli schemi

ARDUINO01 Model (1).pdf (39.9 KB)

CIRCUITO DI POT01 Model (1).pdf (24.5 KB)

ciao

non mi è molto chiaro dallo schema come collegate il secondo arduino? :fearful:

Noi abbiamo fatto dei ponti tra i fili che si connettono dagli interruttore ai pin INPUT dell'Arduino UNO.

lucadentella:
non mi è molto chiaro dallo schema come collegate il secondo arduino? :fearful:

Che poi le uscite collegate con i pulsanti andrebbero disaccopiate con un diodo altrimenti premendo il pulsante si manda tensione ad una uscita che si presume sia LOW
Anche se questo non e' sicuramente il problema

ciao

per capirci meglio, il collegamento "classico" per leggere lo stato di un pulsante da Arduino è:


http://arduino.cc/it/Tutorial/Button

voi dove avete collegato il PIN out dell'arduino ethernet?

Il pin out dell'arduino ethernet è collegato al nodo Arduino_in, senza nessuna resistenza. Noi abbiamo 4 piani, quindi 4 cavi da un arduino all'altro; con tutti e 4 i cavi collegati il programma non funziona correttamente, se invece attacchiamo solo un cavo per volta (ovviamente il cavo corrispondente al piano al quale vogliamo indirizzare l'ascensore) tutto va liscio.

Daniborro:
con tutti e 4 i cavi collegati il programma non funziona correttamente

Non per essere precisetti ... anche se nel primo post e' stato specificato
I cavi sono 5 ; 4 comandi + il GND
La vostra configurazione come da schema e' di tipo PNP
Avete delle resistenze di Pull Down con pulsanti collegati al +5
Quindi , evitando di premere pulsanti con il II° Arduino collegato senza diodi di disaccoppiamento !!!
Le uscite del II° arduino dovranno essere poste a LOW e messe ad HIGH per inviare il comando
Dovranno essere HIGH per un breve tempo simulando il pulsante

NON PUO' non funzionare

Edit :
Vedo che i pulsanti sono alimentati con una 10 K ( mi sfugge il motivo !! ) ; questo mi fa' pensare che col II° Arduino collegato che avra' per logica le uscite LOW i pulsanti non funzioneranno proprio
Ma il prof. di elettrotecnica .. cosa dice ??

brunol949:
Ma il prof. di elettrotecnica .. cosa dice ??

Chissà quello di informatica? Penserà che sia un programma in Visual Basic. :grin:

Comunque, tralasciando le battute e le critiche già espresse nei post precedenti... in bocca al lupo per l'esame. :stuck_out_tongue: :stuck_out_tongue:

brunol949:

Daniborro:
con tutti e 4 i cavi collegati il programma non funziona correttamente

Non per essere precisetti ... anche se nel primo post e' stato specificato
I cavi sono 5 ; 4 comandi + il GND
La vostra configurazione come da schema e' di tipo PNP
Avete delle resistenze di Pull Down con pulsanti collegati al +5
Quindi , evitando di premere pulsanti con il II° Arduino collegato senza diodi di disaccoppiamento !!!
Le uscite del II° arduino dovranno essere poste a LOW e messe ad HIGH per inviare il comando
Dovranno essere HIGH per un breve tempo simulando il pulsante

NON PUO' non funzionare

Edit :
Vedo che i pulsanti sono alimentati con una 10 K ( mi sfugge il motivo !! ) ; questo mi fa' pensare che col II° Arduino collegato che avra' per logica gli ingressi LOW i pulsanti non funzioneranno proprio
Ma il prof. di elettrotecnica .. cosa dice ??

Certo che le uscite dell'arduino eth. sono poste LOW e messe HIGH per inviare il comando (e anche la temporizzazione è ok). La 10k è lì perchè il circuito inizialmente era diverso. Non ho nessun prof. di informatica e ripeto che siamo alle prime armi. COSA SUCCEDE: col collegamento attuale (5 cavi, mi ero dimenticato di menzionare la GND) l'ascensore funziona correttamente solo per due o tre volte, dopodichè inizia a mandare la cabina dove vuole lui. Se invece attacchiamo un filo per volta, ovviamente lasciando la GND collegata (2 cavi solamente), il tutto funziona correttamente. Grazie mille per l'aiuto fornitoci finora :slight_smile:

Principalmente dovreste identificare in quale dei 2 arduino è il problema.
Avete provato a mettere 4 pulsanti isolando arduino ethernet (forse è quello che intendi quando dici un filo alla volta)
L'ascensore si comporta in modo casuale dopo 2-3 comandi provenienti dall'ethernet? dopo quale evento accade? dopo aver premuto un pulsante? o va da solo anche senza premere nulla? non si ferma più? va su giù da solo?

Se con i pulsanti senza ethernet va bene come, ovvio il problema va cercato in arduinoethernet isolando l'altro arduino, in tal caso mettete 4 led sulle uscite che simulano i pulsanti e osservate al 2° 3° comando cosa accade, aggiungere qualche serial.print per fare dei debug nei punti critici del programma.
L'alimentatore ce la fa a sostenere il motore i leds e i 2 arduini quando tutto è acceso?

Io butto li qualche domanda, anche perchè certe cose non sono chiare, non descritte, c'e' un motorino o è simulato?
quelle sfilze di led in colonna cosa rappresentano, perchè ci sono 2 colonne di led? come rappresentate l'apertura e chiusura delle porte? Usate dei finecorsa quindi esiste realmente una cabina che sale e scende.....

commenta queste variabili .... cosa sono? tu che l'hai fatto lo sai sicuramente, rendi la vita più facile senza farci saltare su è giu dalle righe

//dichiaro variabili
int P = 0;
int PT = 0;
int c = 0;
int d = 1;
int e = 0;
int val1 = 0;
int val2 = 0;
int val3 = 0;
int val4 = 0;
int val5 = 0;
int val6 = 0;
int val7 = 0;
int val8 = 0;
ciao

Ok
ho copiato lo sketch sul mio arduino ethernet

condizione iniziale
RESET
scrivo http://192.168.2.177/?L=1 si accende il led 1 per 500 mill
scrivo http://192.168.2.177/?L=2 si accende il led 1 per 500 mill si spegne e si accende il led 2 per 500 mill
scrivo http://192.168.2.177/?L=4 si accende il led 1 per 500 mill si spegne, si accende il led 2 per 500 mill e poi il 4

rivedete quella parte

ciao

RISOLTO ora dovrebbe funzionare

prima del client.stop dovete svuotare la stringa riempita dal readString.concat(c); altrimenti rimangono nella stessa i comandi precedenti e appesi i nuovi comandi, ovviamente readString.indexOf vede tutti i comandi precedenti nella stringa eseguendoli tutti, inoltre quando la variabile supera la sua capacità si inchioda tutto

readString="";
client.flush();
client.stop();

consiglio: state usando la 0022-0023 le librerie di quelle versioni hanno dei bug il chip W5100 dopo un po' si inchioda e ha problemi al reset, sono stati corretti nelle vers. 1.0 e 1.0.1

bye