Salve a tutti, sono un nuovo iscritto che da qualche mese ha approcciato al mondo di Arduino. Chiedo scusa in anticipo se farò qualche domanda stupida ma sono ancora nella fase di orientamento.
Sono alle prese con progettino che utilizza quattro dei pin digitali per pilotare una scheda relè a quattro canali. Pur avendo inizializzato nel codice lo stato dei pin come Low, gli stessi sono sempre in stato high con il risultato che sui relè i contatti n.o. sono sempre collegati . I pin vanno in low ed i relè passano allo stato n.c. solo quando si attiva la routine di comando che cambia lo stato del PIN. Di per sé non sarebbe un problema perché mi è bastato invertire i contatti ed ottenere il risultato voluto, solo che uno dei relè comanda una periferica alimentata a parte quindi quando Arduino uno non è alimentato la periferica parte perché lo stato del relè passa su n.c. e poi anche perché sono curioso di capire il motivo di questa cosa e soprattutto di capire come risolverla visto che tutti i tentativi che ho effettuato non hanno dato esito. Vi ringrazio tutti in anticipo.
Buonasera,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il succitato REGOLAMENTO ... Grazie.
Guglielmo
P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nel rispetto del suddetto regolamento nessuno ti risponderà (eventuali risposte verrebbero cancellate), quindi ti consiglio di farla al più presto.
Chiedo scusa...provvedo subito a presentarmi nella sezione opportuna. Geazie
Pur avendo inizializzato nel codice lo stato dei pin come Low, gli stessi sono sempre in stato high
Lo dici perché hai misurato con un tester la tensione sui pin, oppure lo deduci perché vedi i relé attivarsi? Se è il secondo caso allora è normale, le comuni schede relé per Arduino si attivano con LOW e disattivano con HIGH (non è obbligatorio che HIGH significhi acceso).
Bisognerebbe vedere il programma che hai scritto. Comunque sospetto che tu abbia scritto solamente
digitalWrite (pin, HIGH);
senza dichiarare il modo di funzionamento del pin:
pinMode (pin, OUTPUT);
che è indispensabile per le uscite (tranne quelle su cui usi analogWrite, in PWM, che ha il pinMode incorporato nella funzione stessa), altrimenti i pin sono impostati come ingressi e quando vai a fare un digitalWrite (pin, HIGH) anziché portare a livello alto l'uscita inserisci la resistenza di pull-up sull'ingresso!
Salve, si ho misurato con tester e sui pin sono presenti circa 5v.
Salve, nel codice ho associato i pin ad altrettante variabili poi ho indicato esattamente:
pinMode (nomepin, OUTPUT);
digitalWrite(nomepin, LOW);
Ho controllato il codice più volte e fatto vari tentativi compreso cambiare scheda ma sui pin digitali continuano ad esserci 5V, alla fine per disperazione ho invertito i collegamenti sui relè ma, ripeto, ero curioso di capire come mai succedeva questa cosa.
Non è che stai usando una scheda a relè con l'attivazione a livello basso, come dice Claudio_FF?
Le comuni schede relé per Arduino si attivano con LOW e disattivano con HIGH.
Comunque, il digitalWrite (pin, LOW); iniziale per impostare l'uscita a livello basso è inutile, perché è già all'interno del pinMode. Serve, invece, un digitalWrite (pin, HIGH); se i relè sulla tua scheda si attivano a livello basso per mantenerli diseccitati all'accensione. Abituati al fatto che non sempre HIGH significa attivo e LOW non attivo: a volte è necessario lavorare con logica inversa. Ci sono anche stratagemmi con #define e simili, ma se ti abitui mentalmente alla possibilità della logica inversa è molto meglio, perché ti può capitare di dover capire programmi scritti da altri in cui è necessario.
Che ne dici di pubblicare tutto il codice (mi raccomando, come da regolamento, il codice, una volta inserito va TUTTO selezionato e va premuta l'icona </> nella barra degli strumenti per contrassegnarlo, appunto come codice. Inoltre, affinché sia ben leggibile, esso deve essere correttamente "indentato" ... questo lo si fa premendo ctrlT su un PC o cmd T su un Mac all'intero del IDE) e farci vedere se magari ci sono dei problemi ...
Inoltre metti un link alla esatta scheda relè che hai acquistato.
Guglielmo
Innanzitutto grazie per le vostre risposte,
Non è che stai usando una scheda a relè con l'attivazione a livello basso, come dice Claudio_FF?
mi è sorto un dubbio e ho subito ri-verificato ma confermo gli identici risultati, percui almeno per logica :
- se fossero ad attivazione a livello basso sui pin digitali non dovrei avere 5v
- all'accensione con la sola alimentazione, cioè senza collegare il pin digitale, dovrebbero essere in stato alto ed invece sono al livello basso infatti collegano i morsetti corrispondenti alla posizione normalmente chiuso (così come dovrebbe essere).
Però ora provo a definire i pin a livello alto, poichè questa prova non l'ho ancora fatta.
Vi aggiorno tra qualche ora e grazie
Allora prove effettuate e niente da fare se predispongo i pin a livello HIGH, perchè tutto resta invariato, mentre se commento le righe pinmode output i rele tornano allo stato normale ma i comandi di stato con digitalwrite non hanno esito... ritengo perchè non siano soddisfatte le condizioni previste dagli if.
In sostanza, se ho ben capito, si potrebbe concludere che il comando pinmode output predispone i pin al livello logico HIGH e non LOW. Il motivo però mi resta oscuro.
È esattamente il contrario a meno che non fai un digitalWrite(pin, HIGH) prima di chiamare il pinMode().
In pratica così viene abilitata la resistenza di pull-up, e quando imposti il pin come uscita te lo ritrovi al livello HIGH invece di LOW come accade normalmente.
Il codice, però, è top secret...
... infatti ... vd. mio post #9
Guglielmo
E sarà l'ennesimo brevetto...
L'esatto opposto, disegnati uno schemino e avrai chiaro il perché
Sbagliato anche questo, disegnati lo schemino e avrai chiaro perché. In conclusione dimentica questa "logica" , è sbagliata. Pubblica codice, schema e modello della scheda relè e vedrai che si trova il tuo errore
Salve, nessun segreto ma è solo che ieri stavo provando i consigli che mi avevate dato e oggi sono riuscito solo adesso a trovare un attimo di tempo. Sapete meglio di me come funziona arduino è un hobby ma quando la famiglia chiama bisogna correre.
Siete un po cattivelli... scherzo naturalmente.
Il codice è semplicissimo, ed assemblato guardando un po qui e un po li.
Mi serviva di attivare una piccola pompa di irrigazione per quando non sono a casa.
L'hardware è composto da un display, un timer 1307, un sensore di umidità del terreno, una piccola pompa da 5v attivata da una scheda relè (avevo solo quella da 4 altrimenti avrei usato quella da uno) e 50 cm di tubo.
Il codice è questo:
#include <Wire.h>
#include "RTClib.h"
#include <Adafruit_SSD1306.h>
#define IRR 7
#define OLED_RESET 4
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
RTC_DS1307 rtc;
bool IRRIG = LOW;
int tIRRIG= 1000;
unsigned long ir, tir;
int sIRRIG = LOW;
int umi;
int qumi = 40;
int mm, hh;
int dd, ms, yy;
void setup() {
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
if (!rtc.begin()) {
Serial.println("Errore! Verifica il cablaggio RTC!");
return;
}
if (!rtc.isrunning()) {
Serial.println("Configuro l'ora");
//Uso l'ora di compilazione dello sketch
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// per farlo a mano...
// January 21, 2014 at 3am you would call
//rtc.adjust(DateTime(2022, 1, 05, 18, 22, 0));
//DateTime now = rtc.now();
}
display.setTextSize(1);
display.clearDisplay();
pinMode(IRR, OUTPUT);
digitalWrite(IRR, LOW);
}
void loop() {
if (IRRIG) {
tir = millis() - ir;
if (tir >= tIRRIG) {
ir = millis();
sIRRIG = !sIRRIG;
if (sIRRIG) {
digitalWrite(IRR, HIGH);
tIRRIG = 4000;
} else {
digitalWrite(IRR, LOW);
tIRRIG = 10000;
}
} else {
digitalWrite(IRR, LOW);
}
}
}
void umid() {
for (int i = 0; i < 100; i++) {
umi += analogRead(A3);
}
umi = umi / 100;
umi = map (umi, 0, 1024, 100, 0);
Serial.println(umi);
if (umi < qumi) {
sIRRIG = HIGH;
} else {
sIRRIG = LOW;
digitalWrite(IRR, LOW);
}
display.setCursor(0, 0);
display.print(dd);
display.print("/");
display.print(ms);
display.print("/");
display.print(yy);
display.print(" - ");
display.print(hh);
display.print(":");
display.print(mm);
display.setCursor(0, 10);
display.print("UMIDITA TERRENO:");
display.print(umi);
display.print("%");
}
Comunque se utilizzo il comando pinmode output sul pin 7 leggo 5v ed il digitalwrite successivo che lo setta a low non ha esito
Ti sei accorto che la tua loop() non funziona? La prima if non sarà mai vera...
... non solo, l'inizializzazione dei pin di I/O è la prima cosa da fare, proprio per evitare strane attivazione delle cose ad essi collegate.
Guglielmo
Però ci ho pensato. Non sono sicuro che la macro LOW sia definita, non la ho trovata con una veloce occhiata alla documentazione, se non definita potrebbe essere malinterpretata dal preprocessore e intesa come errore (diverso da zero) e quindi valere true? Questa si una macro definita come non zero?