Input analogici usati come input digitali su arduino Mega

Ciao a tutti, come da oggetto avrei la necessità di utilizzare alcuni ingressi analogici dell'Arduino Mega come input digitali ma non rieco a trovare nella documentazione come li devo dichiarare.

DigitalRead(????)

Altra domanda: sapete se anche sugli ingressi analogici è presente una reristenza interna di pull'up ?

Basta dichiararli di input e poi accederci normalmente:

pinMode(num_pin, INPUT);
DigitalRead(num_pin);

Quoto dalla documentazione:
http://arduino.cc/en/Reference/DigitalRead

The analog input pins can be used as digital pins, referred to as A0, A1, etc.

PS:
hai specificato "Mega". Dovrebbe valere anche per il Mega.

confermo leo, e aggiungo che sì, i pin analogici hanno una pull-up interna (l'ho letto giusto ieri sul reference)

Ok, grazie delle risposte, quindi se non ho capito male per leggere l'ingresso analogico n° 2 devo scrivere digitalRead(A2) giusto ?

Se scrivessi solo digitalRead(2) infatti andrei a leggere l'ingresso digitale 2 non quello analogico.

esatto

C'è ancora qualcosa che non va ! Non mi legge gli ingressi, secondo voi può dipendere dal fatto che il numero di pin lo dichiaro come "int" ?!? In effetti A0 non è un intero ma come li devo dichiarare ?!?

const int Ingresso[24] = {
  22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, A0, A1, A2, A3, A4, A5, A6, A7};

In questo modo non funziona ! =(

difitalRead prende in input un int, quindi non è quello il problema. A0 si riferisce quindi a un valore intero. Posta il codice

E' un po' lunghino ! Spero che si capisca:

// Associazione delle variabili ai vari pin

const int Ingresso[24] = {
  22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, A0, A1, A2, A3, A4, A5, A6, A7};
const int UscitaRele[14] = {
  23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49};
const int UscitaReleDIM[2] = {
  51, 53};
const int UscitaPWM[10] = {
  4, 5, 6, 7, 8, 9, 10, 11, 12, 13};

boolean StatoUscitaRele[14]; // Valore ON/OFF che viene scritto sulle uscite dei relè semplici
boolean StatoUscitaReleDIM[2]; // Valore ON/OFF che viene scritto sulle uscite dei relè dimmerati
int StatoUscitaValoreDIM[2]; // Valore analogico che viene scritto sui dimmer dei relè dimmerati
boolean StatoUscitaPWM[10]; // Se LOW "StatoUscitaValoreDIM" assume il valore 0, se HIGH "StatoUscitaValoreDIM" assume il valore scelto
int StatoUscitaValorePWM[10] = {
  255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; // Valori variabili delle uscite PWM
boolean VariazionePWM[10]; // Se è a true "StatoUscitaValorePWM" oscilla tra 0 e 255, se a false non cambia il valore
int IncrementoPWM[10] = {
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; // Vale "1" durante l'aumento del PWM e vale "-1" durante la diminuzione
boolean UltimoStatoPulsante[24]; // Stato del pulsante nel ciclo precedente
boolean StatoPulsante[24]; // Stato del pulsante nel ciclo attuale
int NumeroClickIngressi[24]; // Numero di click effettuati sui vai pulsanti
unsigned long TimePrimoClick[24]; // Time di quando viene fatto il primo click

void setup()
{
  Serial.begin(9600);
  // Imposto i 16 pulsanti come ingressi
  for (int i=0; i <= 23; i++)
  {
    pinMode(Ingresso[i], INPUT);
    digitalWrite(Ingresso[i], HIGH); 
  }
  // Imposto i 14 relè semplici come uscite
  for (int i=0; i <= 13; i++)
  {
    pinMode(UscitaRele[i], OUTPUT);
    digitalWrite(UscitaRele[i], LOW);
  }
  // Imposto i 2 relè dimmerati come uscite
  for (int i=0; i <= 1; i++)
  {
    pinMode(UscitaReleDIM[i], OUTPUT);
    digitalWrite(UscitaReleDIM[i], LOW);
  }
  // Imposto i 10 Mosfet come uscite PWM
  for (int i=0; i <= 9; i++)
  {
    pinMode(UscitaPWM[i], OUTPUT);
    analogWrite(UscitaPWM[i], 0);
  }
}

void loop()
{
  delay(30);
  // Eseguo queste operazioni per ogni pulsante
  for (int i=0; i <= 23; i++) {
    // Rilevo i fronti di discesa degli impulsi
    UltimoStatoPulsante[i] = StatoPulsante[i];
    StatoPulsante[i] = digitalRead(Ingresso[i]);
    if (UltimoStatoPulsante[i] == HIGH && StatoPulsante[i] == LOW)
    {
      NumeroClickIngressi[i]++;
      TimePrimoClick[i] = millis();
    }
    // Dopo 300mS dal primo click azzero il contatore ed eseguo l'azione a seconda che ci sia stato un singolo click o un doppio click
    if (millis() - TimePrimoClick[i] >= 300){
      if (NumeroClickIngressi[i] == 1){
        AzioneSingoloClick(i);
      }
      if (NumeroClickIngressi[i] >= 2){
        AzioneDoppioClick(i);
      }
      NumeroClickIngressi[i]=0;
    }
  }
  EseguiVariazioniPWM(); // Esegue la funzione che se richiesto varia il PWM dei mosfet
  ResetUscitaTemporizzato(7,10000); // Resetta il relè della Ventola dopo xxxxx mS
  ResetUscitaTemporizzato(8,10000); // Resetta il relè della Thermologika dopo xxxxx mS
}

// Azioni che vengono eseguite ad ogni singolo click degli ingressi
void AzioneSingoloClick(int NIngresso){
  if (NIngresso == 0){
    // Nessuna azione, l'ingresso è danneggiato
  }
  if (NIngresso == 1){
    InvertiUscitaPWM(1);
  }
  if (NIngresso == 2){
    InvertiUscitaPWM(0);
    InvertiUscitaPWM(2);
  }
  if (NIngresso == 3){
    InvertiUscitaReleDIM(0);
  }
  if (NIngresso == 4){
    InvertiUscitaRele(0);  
  }
  if (NIngresso == 5){
    InvertiUscitaRele(1);
  }
  if (NIngresso == 6){
    InvertiUscitaRele(2);
  }
  if (NIngresso == 7){
    InvertiUscitaRele(3);
  }
  if (NIngresso == 8){
    InvertiUscitaRele(4); 
  }
  if (NIngresso == 9){
    InvertiUscitaRele(5);
  }
  if (NIngresso == 10){
    InvertiUscitaPWM(6);
  }
  if (NIngresso == 11){
    InvertiUscitaPWM(5);
  }
  if (NIngresso == 12){
    InvertiUscitaRele(6);
  }
  if (NIngresso == 13){
    InvertiUscitaReleDIM(1);
  }
  if (NIngresso == 14){
    InvertiUscitaPWM(3);
  }
  if (NIngresso == 15){
    InvertiUscitaRele(8);
  }
  if (NIngresso == 16){
    InvertiUscitaRele(7);
  }
  if (NIngresso == 17){
    InvertiUscitaPWM(4);
  }
  if (NIngresso == 18){
  }
  if (NIngresso == 19){
  }
  if (NIngresso == 20){
  }
  if (NIngresso == 21){
  }
  if (NIngresso == 22){
  }
  if (NIngresso == 23){
  }
}

// Azioni che vengono eseguite ad ogni doppio click degli ingressi
void AzioneDoppioClick(int NIngresso){
  if (NIngresso == 0){
  }
  if (NIngresso == 1){
    if (StatoUscitaPWM[1] == HIGH) {
      VariazionePWM[1] = ! VariazionePWM[1];
    }
  }
  if (NIngresso == 2){
    if (StatoUscitaPWM[0] == HIGH) {
      VariazionePWM[0] = ! VariazionePWM[0];
    }

    if (StatoUscitaPWM[2] == HIGH) {
      VariazionePWM[2] = ! VariazionePWM[2];
    }
  }
  if (NIngresso == 3){

  }
  if (NIngresso == 4){

  }
  if (NIngresso == 5){

  }
  if (NIngresso == 6){

  }
  if (NIngresso == 7){

  }
  if (NIngresso == 8){

  }
  if (NIngresso == 9){

  }
  if (NIngresso == 10){
    if (StatoUscitaPWM[6] == HIGH) {
      VariazionePWM[6] = ! VariazionePWM[6];
    }
  }
  if (NIngresso == 11){
    if (StatoUscitaPWM[5] == HIGH) {
      VariazionePWM[5] = ! VariazionePWM[5];
    }
  }
  if (NIngresso == 12){

  }
  if (NIngresso == 13){

  }
  if (NIngresso == 14){
    if (StatoUscitaPWM[3] == HIGH) {
      VariazionePWM[3] = ! VariazionePWM[3];
    }
  }
  if (NIngresso == 15){
    if (StatoUscitaPWM[4] == HIGH) {
      VariazionePWM[4] = ! VariazionePWM[4];
    }
  }
  if (NIngresso == 16){
  }
  if (NIngresso == 17){
  }
  if (NIngresso == 18){
  }
  if (NIngresso == 19){
  }
  if (NIngresso == 20){
  }
  if (NIngresso == 21){
  }
  if (NIngresso == 22){
  }
  if (NIngresso == 23){
  }
}
void EseguiVariazioniPWM(){
  for (int NPWM=0; NPWM <= 9; NPWM++) {
    if (VariazionePWM[NPWM]==true){
      StatoUscitaValorePWM[NPWM] = StatoUscitaValorePWM[NPWM] + IncrementoPWM[NPWM];
      if (StatoUscitaValorePWM[NPWM] == 255 || StatoUscitaValorePWM[NPWM] == 0){
        IncrementoPWM[NPWM] = - (IncrementoPWM[NPWM]);
      }
      analogWrite (UscitaPWM[NPWM], StatoUscitaValorePWM[NPWM]);
    }
  }
}
void ResetUscitaTemporizzato(int NUscita, unsigned long TempoImpostato){
  if ((millis()- TimePrimoClick[NUscita]) >= TempoImpostato){
    StatoUscitaRele[NUscita] = LOW;
    digitalWrite(UscitaRele[NUscita],StatoUscitaRele[NUscita]); 
  }
}
void InvertiUscitaRele(int NUscita){
  StatoUscitaRele[NUscita] = ! StatoUscitaRele[NUscita];
  digitalWrite(UscitaRele[NUscita],StatoUscitaRele[NUscita]);
}
void InvertiUscitaReleDIM(int NUscita){
  StatoUscitaReleDIM[NUscita] = ! StatoUscitaReleDIM[NUscita];
  digitalWrite(UscitaReleDIM[NUscita],StatoUscitaReleDIM[NUscita]);
}
void InvertiUscitaPWM(int NUscita){
  if (StatoUscitaPWM[NUscita] == LOW){
    analogWrite(UscitaPWM[NUscita],StatoUscitaValorePWM[NUscita]);
    StatoUscitaPWM[NUscita] = HIGH;
  }
  else{
    analogWrite(UscitaPWM[NUscita],0);
    StatoUscitaPWM[NUscita] = LOW;
    VariazionePWM[NUscita] = LOW; // Se il PWM sta variando fermo il valore
  }
}

per questioni di leggibilità in AzioneDoppioClick e AzioneSingoloClick usa uno switch

poi in loop(), fai attenzione, per come è scritto il codice, ogni volta che clicchi il tempo di ritardo per il doppio click viene resettato

sinceramente di errori lato codice non ne vedo, non è che è un errore di cablaggio? Prova ogni loop a scrivere a video lo stato delle digitalRead, per vedere dove e come variano.

Per quanto riguarda l'uso dello switch hai ragione, stasera lo correggo così snellisco il codice.

Per quanto riguarda i 300ms è fatto apposta così: in questo modo ad ogni click si azzera il timeout e ho a disposizione 300ms dall'ultimo click effettuato, in modo che se per esempio devo rilevare un quadruplo click (non è il mio caso però) non ho solo 300ms ma fino a 900ms.

Riguardo alla prova del Serial.print mi sembra che avevo già provato e rilevavo (con tutti i pulsanti a riposo) "1" su tutti gli ingressi digitali e "0" sugli analogici. Premendo i pulsanti gli "1" vanno a "0" ma gli ingressi analogici rimangono a "0".

Credo che il problema possa essere dovuto o al fatto che sul Mega gli input analogici non abbiano le resistenze di pull-up oppure che l'ingresso non si chiama A0, A1, A2 ...

Ho provato a guardare il datasheet dell'ATMega per verificare la presenza delle resistenze di pull-up ma mi sono perso nella miriade di informazioni che ci sono !!!

bhè se non hai un voltimetro per controollare se la pull-up funziona, allora collega il pin analogico con uno digitale... :grin:

Scusa lesto ma avevo scritto una cavolata ! Il problema non erano gli ingressi ma le uscite !!! La funzione per il reset temporizzato di alcune uscite non funzionava e me le teneva sempre resettate. Ora funziona e ho anche sistemato il codice con lo switch. Grazie !

Se a qualcuno interessa ecco il codice funzionante per la mia centralina luci. E' doveroso condividerlo con la comunità. XD

// Associazione delle variabili ai vari pin

const int Ingresso[24] = {
  22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, A0, A1, A2, A3, A4, A5, A6, A7};
const int UscitaRele[14] = {
  23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49};
const int UscitaReleDIM[2] = {
  51, 53};
const int UscitaPWM[10] = {
  4, 5, 6, 7, 8, 9, 10, 11, 12, 13};

boolean StatoUscitaRele[14]; // Valore ON/OFF che viene scritto sulle uscite dei relè semplici
boolean StatoUscitaReleDIM[2]; // Valore ON/OFF che viene scritto sulle uscite dei relè dimmerati
int StatoUscitaValoreDIM[2]; // Valore analogico che viene scritto sui dimmer dei relè dimmerati
boolean StatoUscitaPWM[10]; // Se LOW "StatoUscitaValoreDIM" assume il valore 0, se HIGH "StatoUscitaValoreDIM" assume il valore scelto
int StatoUscitaValorePWM[10] = {
  255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; // Valori variabili delle uscite PWM
boolean VariazionePWM[10]; // Se è a true "StatoUscitaValorePWM" oscilla tra 0 e 255, se a false non cambia il valore
int IncrementoPWM[10] = {
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; // Vale "1" durante l'aumento del PWM e vale "-1" durante la diminuzione
boolean UltimoStatoPulsante[24]; // Stato del pulsante nel ciclo precedente
boolean StatoPulsante[24]; // Stato del pulsante nel ciclo attuale
int NumeroClickIngressi[24]; // Numero di click effettuati sui vai pulsanti
unsigned long TimePrimoClick[24]; // Time di quando viene fatto il primo click
unsigned long TimeAccensioneRele[24]; // Time di quando viene attivata l'uscita (per lo spegnimento temporizzato)
void setup()
{
  Serial.begin(9600);
  // Imposto i 16 pulsanti come ingressi
  for (int i=0; i <= 23; i++)
  {
    pinMode(Ingresso[i], INPUT);
    digitalWrite(Ingresso[i], HIGH); 
  }
  // Imposto i 14 relè semplici come uscite
  for (int i=0; i <= 13; i++)
  {
    pinMode(UscitaRele[i], OUTPUT);
    digitalWrite(UscitaRele[i], LOW);
  }
  // Imposto i 2 relè dimmerati come uscite
  for (int i=0; i <= 1; i++)
  {
    pinMode(UscitaReleDIM[i], OUTPUT);
    digitalWrite(UscitaReleDIM[i], LOW);
  }
  // Imposto i 10 Mosfet come uscite PWM
  for (int i=0; i <= 9; i++)
  {
    pinMode(UscitaPWM[i], OUTPUT);
    analogWrite(UscitaPWM[i], 0);
  }
}

void loop()
{
  delay(30);
  // Eseguo queste operazioni per ogni pulsante
  for (int i=0; i <= 23; i++) {
    // Rilevo i fronti di discesa degli impulsi
    UltimoStatoPulsante[i] = StatoPulsante[i];
    StatoPulsante[i] = digitalRead(Ingresso[i]);
    if (UltimoStatoPulsante[i] == HIGH && StatoPulsante[i] == LOW)
    {
      NumeroClickIngressi[i]++;
      TimePrimoClick[i] = millis();
    }
    // Dopo 300mS dal primo click azzero il contatore ed eseguo l'azione a seconda che ci sia stato un singolo click o un doppio click
    if (millis() - TimePrimoClick[i] >= 300){
      if (NumeroClickIngressi[i] == 1){
        AzioneSingoloClick(i);
      }
      if (NumeroClickIngressi[i] >= 2){
        AzioneDoppioClick(i);
      }
      NumeroClickIngressi[i]=0;
    }
  }
  EseguiVariazioniPWM(); // Esegue la funzione che se richiesto varia il PWM dei mosfet
  ResetUscitaTemporizzato(7,10000); // Resetta il relè della Ventola dopo xxxxx mS
  ResetUscitaTemporizzato(8,10000); // Resetta il relè della Thermologika dopo xxxxx mS
}

// Azioni che vengono eseguite ad ogni singolo click degli ingressi
void AzioneSingoloClick(int NIngresso){
  switch (NIngresso) {
  case 0:
    // Nessuna azione, l'ingresso è danneggiato
    break;
  case 1:
    InvertiUscitaPWM(1);
    break;
  case 2:
    InvertiUscitaPWM(0);
    InvertiUscitaPWM(2);
    break;
  case 3:
    InvertiUscitaReleDIM(0);
    break;
  case 4:
    InvertiUscitaRele(0);  
    break;
  case 5:
    InvertiUscitaRele(1);
    break;
  case 6:
    InvertiUscitaRele(2);
    break;
  case 7:
    InvertiUscitaRele(3);
    break;
  case 8:
    InvertiUscitaRele(4); 
    break;
  case 9:
    InvertiUscitaRele(5);
    break;
  case 10:
    InvertiUscitaPWM(6);
    break;
  case 11:
    InvertiUscitaPWM(5);
    break;  
  case 12:
    InvertiUscitaRele(6);
    break;  
  case 13:
    InvertiUscitaReleDIM(1);
    break;  
  case 14:
    InvertiUscitaPWM(3);
    break;  
  case 15:
    InvertiUscitaRele(8);
    TimeAccensioneRele[8]=millis();
    break;  
  case 16:
    InvertiUscitaRele(7);
    TimeAccensioneRele[7]=millis();
    break;  
  case 17:
    InvertiUscitaPWM(4);
    break;  
  case 18:
    break;  
  case 19:
    break;  
  case 20:
    break;  
  case 21:
    break;  
  case 22:
    break;  
  case 23:
    break;    
  default:
    ;
  }
}

// Azioni che vengono eseguite ad ogni doppio click degli ingressi
void AzioneDoppioClick(int NIngresso){
  switch (NIngresso) {
  case 0:
    // Nessuna azione, l'ingresso è danneggiato
    break;
  case 1:
    if (StatoUscitaPWM[1] == HIGH) {
      VariazionePWM[1] = ! VariazionePWM[1];
    }
    break;
  case 2:
    if (StatoUscitaPWM[0] == HIGH) {
      VariazionePWM[0] = ! VariazionePWM[0];
    }
    if (StatoUscitaPWM[2] == HIGH) {
      VariazionePWM[2] = ! VariazionePWM[2];
    }
    break;
  case 3:
    break;
  case 4: 
    break;
  case 5:
    break;
  case 6:
    break;
  case 7:
    break;
  case 8:
    break;
  case 9:
    break;
  case 10:
    if (StatoUscitaPWM[6] == HIGH) {
      VariazionePWM[6] = ! VariazionePWM[6];
    }
    break;
  case 11:
    if (StatoUscitaPWM[5] == HIGH) {
      VariazionePWM[5] = ! VariazionePWM[5];
    }
    break;  
  case 12:
    break;  
  case 13:
    break;  
  case 14:
    if (StatoUscitaPWM[3] == HIGH) {
      VariazionePWM[3] = ! VariazionePWM[3];
    }
    break;  
  case 15:
    if (StatoUscitaPWM[4] == HIGH) {
      VariazionePWM[4] = ! VariazionePWM[4];
    }
    break;  
  case 16:
    break;  
  case 17:
    break;  
  case 18:
    break;  
  case 19:
    break;  
  case 20:
    break;  
  case 21:
    break;  
  case 22:
    break;  
  case 23:
    break;    
  default:
    ;
  }
}
void EseguiVariazioniPWM(){
  for (int NPWM=0; NPWM <= 9; NPWM++) {
    if (VariazionePWM[NPWM]==true){
      StatoUscitaValorePWM[NPWM] = StatoUscitaValorePWM[NPWM] + IncrementoPWM[NPWM];
      if (StatoUscitaValorePWM[NPWM] == 255 || StatoUscitaValorePWM[NPWM] == 0){
        IncrementoPWM[NPWM] = - (IncrementoPWM[NPWM]);
      }
      analogWrite (UscitaPWM[NPWM], StatoUscitaValorePWM[NPWM]);
    }
  }
}
void ResetUscitaTemporizzato(int NUscita, unsigned long TempoImpostato){
  if (((millis()- TimeAccensioneRele[NUscita]) >= TempoImpostato) && StatoUscitaRele[NUscita] == HIGH){
    StatoUscitaRele[NUscita] = LOW;
    digitalWrite(UscitaRele[NUscita],StatoUscitaRele[NUscita]); 
  }
}
void InvertiUscitaRele(int NUscita){
  StatoUscitaRele[NUscita] = ! StatoUscitaRele[NUscita];
  digitalWrite(UscitaRele[NUscita],StatoUscitaRele[NUscita]);
}
void InvertiUscitaReleDIM(int NUscita){
  StatoUscitaReleDIM[NUscita] = ! StatoUscitaReleDIM[NUscita];
  digitalWrite(UscitaReleDIM[NUscita],StatoUscitaReleDIM[NUscita]);
}
void InvertiUscitaPWM(int NUscita){
  if (StatoUscitaPWM[NUscita] == LOW){
    analogWrite(UscitaPWM[NUscita],StatoUscitaValorePWM[NUscita]);
    StatoUscitaPWM[NUscita] = HIGH;
  }
  else{
    analogWrite(UscitaPWM[NUscita],0);
    StatoUscitaPWM[NUscita] = LOW;
    VariazionePWM[NUscita] = LOW; // Se il PWM sta variando fermo il valore
  }
}