Ciao a tutti dopo essermi consigliato sull'acquisto di un nano.. mi vorrei avventurare verso un primo sketch, ho letto e ho visto degli esempi. Accetto consigli e soprattutto aiuto.. vorrei pilotare un motore passo passo che comanda una serratura.
Quindi partendo dal passo 0 che corrisponde a serratura aperta, vorrei che con un comando di un pulsante il "nano" facesse partire con la rampa il motore per X passi (diciamo 100 come esempio) e arrivare a serratura chiusa. Al successivo comando, trovandosi in stato "serratura chiusa" (e quindi al passo 100) dovrebbe partire nel senso inverso fino al passo 0 "serratura aperta" per poi predisporsi di nuovo nel senso opposto.
Che ne dite ??
Grazie per quello che fate !
Si, tutto chiaro, si può fare certamente.
Quindi hai il nostro permesso per iniziare a scrivere il codice. Se hai problemi, postalo e vediamo.
... solo un consiglio, avenedo personalmente avuto una porta motorizzata in questo modo, prevedi comunque il sistema di apertura manuale, sia dall'interno che all'esterno
Guglielmo
GPP01...
uhm .. proprio uguale ? allora uno sketch ci sarebbe.... certo lo vorrei capire..
DOCDOC
certo se Guglielmo lo ha.. preferirei partire da una base, anche se intendo aggiungere qualche variante.. tipo lo farei alimentato da una batteria al piombo montata sulla porta e quindi con monitor di tensione con un paio di led si segnalazione, in modo da caricarla al bisogno, magari una volta al mese.. e evitare i black out e evitare i fili che si rompono sulla cerniera della porta..
Mi serve una striscia led che si accenda in apertura temporizzata,... qualche chicca
16.1:
Ehi! Sto imparando a memoria i punti del regolamento!
... certo, scritto in "LabWindows CVI™" su piattaforma Windows Server per un complesso sistema di sicurezza ... non credo che su Arduino si possa compilare
Guglielmo
non volevo che nessuno me lo scrivesse.. partivo da una base.. lo so che per voi è una cappellata.. .per me povero principiante.. è difficile ma mi ci metto e mi correggerete
Bisogna cominciare dalle basi: accendere un LED, farlo lampeggiare e andare avanti. Anche nei progetti complessi, dove non si è sicuri bisogna fare un passo per volta. Facendo un passo per volta, impari e memorizzi.
Però... Perché vuoi usare un passo-passo? Non sarebbe meglio un motore comune e un microswitch di fine corsa?
No.. non è pratico avevo provato, con i fine corsa magnetici su un ingranaggio moltiplicato, ma è troppo critico.. anche perchè la chiave fa 2 giri e mezzo, l'ingranaggio con i due fine corsa deve stare sulla parte mobile della porta, e quindi appunto moltiplicando l'asse finale servono quindi 3 ingranaggi, c'è poco spazio e invece con un passo passo di potenza opportuna penso di poterlo montare diretto sulla chiave. Con i passi giusti non ci sono problemi di fine corsa.
Certo che farò passo passo.. anche il progetto...
Quindi inizia con il saper gestire un LED (es. fallo lampeggiare ad intervalli di 1 secondo) poi modificalo per fare in modo che quando premi un pulsante si accende il LED e se lo premi nuovamente lo spegni. Per questo prototipo hai due cose essenzialmente da imparare:
- il concetto di "pull up" o "pull down" ossia il pulsante se lo colleghia +5V significa che quando lo premi il pin di Arduino va HIGH ma quando non lo premi deve restare a LOW, e questo si fa aggiungendo una resistenza (valore alto, es. 10k) tra il pin e GND per mantenerlo "basso" (il "pull down"); se invece il pulsante lo colleghi tra pin e GND allora devi avere una resistenza che tiene il pin "alto" (il "pull up"), cosa che puoi fare senza aggiungere nulla perché Arduino ha una sua resistenza interna di pull up, che attivi definendo il pin non come INPUT ma INPUT_PULLUP
- il "debounce": i contatti metallici del pulsante non vanno direttamente da chiuso ad aperto, ma per un breve intervallo "rimbalzano" ("bounce") un poco per cui tu avresti varie letture LOW e HIGH fino a che si stabilizza sul valore corretto. Per evitare questo puoi in prima battuta e per semplicità semplicemente fare in modo che quando rilevi che il pulsante (ossia il suo pin) cambia stato, attendi un certo tempo con la funzione delay() (bastano pochi millisecondi, metti 100 e stai per ora tranquillo così).
Questa cosa penso che con un minimo di studio dovresti farcela. Quando ti funziona, metti da parte questo codice.
Fatto questo secondo passo, e ti funziona correttamente, devi imparare a gestire gli stepper, e per fare questo ti conviene partire da uno degli esempi della libreria Stepper senza per ora toccare il codice del punto precedente.
Una volta che hai capito come muovere in un verso o nell'altro uno stepper, allora integrerai queste cose dentro al codice del pulsante (il LED a questo punto lo usi come "monitor" dello stato della serratura, facendolo accendere ad esempio quando la serratura è aperta (es. posizione/step 100 o quello che definirai come "aperto") e spegnere quando è chiuso (es. posizione 0).
Per questa integrazione ovviamente se dovessi trovare difficoltà posta qui il tuo codice (e magari anche uno schemino di come hai collegato il tutto) e ti aiuteremo!
Grazie Doc .. un pò di esperienza "elettronica" ce l'ho.. faccio riparazione e autocostruizione da una 40 ina di anni... è la programmazione che non ho mai fatto.. poco e niente, ho fatto qualcosa con i picaxe.. ma elementare..
Sto aspettando il NANO che ho ordinato.. e parto..
Sto ancora attendendo l'hardware, ma vedo che ci sono varie scuole di pensiero, chi mette le costanti prima del void setup chi usa il comando define, chi usa const int e chi invece non mette costanti ma parte subito dentro il void setup con il pinMode.. c'è una regola da seguire o .. si va a gusto personale ??
Le regole ci sarebbero ma sono per lo più sconosciute alla maggior parte degli utenti, poi c'è ci sono gli esempi anche ufficiali ed altri attendibile (per nomea) che di fatto fanno quello che gli viene spontaneo.
Così ti ritrovi con:
int pinLed = 9;
Ma se un in byte (tipo byte, uint8_t) ci puoi salvare numeri da 0÷255, perché usare int che occupa 2 byte in ram?
inoltre se il valore di pinLed non lo modifichi e non vuoi che
accidentalmente possa essere modificato durante run-time, allora il qualificatore const fa proprio al caso tuo.
PS: in breve, siamo nel farwest e ognuno fa quello che gli
pare e senza alcuna buona ragione.
Ciao.
ahahaha vero
Ad ogni modo, visto che @spippolone deve ancora acquisire un "modus operandi", io mi sentirei di consigliare di usare sempre l'approccio con le variabili.
Usando una variabile const al posto del #define si da modo al compilatore di eseguire il type checking e di stanare eventuali errori di assegnazione.
const uint8_t pinNumber = 5;
// o in alternativa
const byte pinNumer = 5;
Io in generale preferisco uint8_t (e uint16_t, int16_t, uint32_t etc etc) perché ho sempre in evidenza in modo conciso che si tratta di un unsigned int da 8 bit.
Ci sono cose che devono stare al di fuori di qualsiasi funzione, come le variabili globali: normalmente si mettono all'inizio, ma potresti anche metterle altrove. Qualche volta ho visto variabili globali dichiarate poco prima della funzione che le usa principalmente. Per il compilatore è la stessa cosa; se le metti all'inizio, però, stanno tutte insieme e si ritrovano facilmente.
Per quanto riguarda le dimensioni delle variabili, nota che nell'ambiente di Arduino una variabile bool occupa comunque un byte intero, perché i singoli bit non vengono gestiti indipendentemente. Se ti serve una logica a tre stati, come nella funzione che ho inventato e che uso sempre per leggere un encoder rotativo, nello stesso spazio in RAM una variabile int8_t ti permette di avere +1, 0 e -1.
Concordo con tutto. Ma in ogni caso, per restare nelle convezioni globalmente utilizzate (e totalmente trasparenti per il compilatore), per le costanti ed eventuali simboli costanti da #define è opportuno indicarle con nomi totalmente in maiuscolo, per poterli distinguere ad occhio dalle variabili. Quindi non "pinNumber" ad esempio ma "PIN_NUMBER".
Io poi preferisco dare anche un prefisso per indicare l'uso, generalmente almeno "P_" per i pin seguito dal nome logico o dall'uso, ad esempio "const byte P_LED_ROSSO = 10;", e tutte le costanti che rappresentano dei parametri di configurazione li metto solitamente in cima al listato per poter essere facilmente identificate e modificate all'occorrenza.
PS: Diciamo che è vero che non ci sono regole fisse, come dice Maurotec, perché nessuno ha mai creato uno "standard" imposto in qualche modo, ma è viceversa vero che sono quasi tutte solo delle "convenzioni" largamente utilizzate. Per cui se uno scrive del codice che guarderà solo lui potrà fare ovviamente quello che gli pare, se deve condividerlo o, peggio, lavorarci in più persone, allora meglio avere uno stile più coerente e conosciuto possibile, evitando il "far west"
@spippolone : ti suggersico di scaricari (il pdf è gratuito) e studiarti il seguente TESTO. Ti chiarirà parecchie cose.
Guglielmo
?
non mi è per nulla chiara, come idea
io non userei mai una variabile "const" per una "impostazione" del tipo numero di piedino o dimensione di un array
abbiamo già discusso che usando una #define si lascia al compilatore la libertà di usare il tipo preferito, inoltre trattandosi di costanti conosciute a compile-time sono possibili ottimizzazioni letteralmente "impossibili a run-time",
il (forse non tanto) buon Astrobeed anni fa ha sviscerato per bene la cosa, e usare #define velocizza "definitivamente" il programma,
con buona pace dei programmatori C++, che continuano a dire il contrario
io continuo a non vedere nessun caso ove il modificatore const sia necessario, raramente utile
C'è la "libertà tecnica" di fare un po' di tutto, ma procedendo in alcuni modi le cose sono più chiare, meno soggette a errori o confusione, più facili da modificare e/o correggere. Per il principiante sono quasi sottigliezze filosofiche, inizialmente difficili da "inquadrare", ma col tempo, e magari qualche "guida di stile"come quella indicata da Guglielmo, si trova il compromesso tra chiarezza, ordine e concisione.
Ad esempio una riga come:
digitalWrite(12, 0); // scrive 0 sul pin 12
è qualcosa di totalmente incomprensibile e anche il commento è inutile al fine di capire cosa si sta facendo in quel punto. Non si sa neppure se quello zero vuol dire "acceso" o "spento", perché questo dipende da cosa c'è collegato al pin 12.
Già meglio un commento sensato:
digitalWrite(12, 0); // accende luce
Si comprende che stiamo accendendo, cosa, e che il livello di accensione in questo caso è zero.
Ma usando delle costanti, o dei nomi di comodo definiti con #define, anche il commento e i vari numeri dei pin e valori dei livelli diventano inutili in quanto il codice è "autoesplicativo":
digitalWrite(PIN_LUCE, LIVELLO_ACCESO);
O ancora in quel punto si può richiamare una funzione dal nome ancora più esplicativo, che si incaricherà poi del vero e proprio "lavoro sporco", in modo da scrivere la logica nel modo più chiaro e leggibile:
accendi_luce();
Quindi non è un obbligo usare queste cose, ma una scelta che porta a scrivere programmi più comprensibili e meno soggetti ad errori.
Per quanto riguarda il motore invece, occhio che i passo passo possono perdere colpi, per cui normalmente si mettono sempre dei finecorsa per settare "lo zero". Considera anche il caso di corrente che va via a metà percorso, o accensione senza sapere lo stato esatto della meccanica.
Io uso indistintamente l'uno o l'altro a seconda dei casi (o più spesso del caso ), non ne faccio una questione di parrocchia C contro la parrocchia C++
Ci sono pro e contro in qualsiasi scelta e anche questa non fa eccezione. Chiaramente se si tratta solo di impostare un pin la differenza tra i due metodi è prossima all'inesistente, ma in altri casi il tipo giusto di variabile potrebbe risparmiarti ore di debug.