Jump to content
PLC Forum


kemosabe

RETURN

Recommended Posts

kemosabe

Signori, buongiorno.

Come da vostro consiglio, sto cercando di imparare il C con il libro da voi consigliato, e nel frattempo cercando di fare esercizi con il c, che so che non è solo c, di Arduino.

Sto cercando di modificare un programma carino, che ho trovato in rete, per l'apertura di una porta con codice numerico e con RFID.

 

Per il momento, visto che le mie modifiche non funzionano, sto cercando di capire la parte vecchia del programma. Solo che anche studiando sul libro, non riesco a capire come si comporta il " return" nelle varie situazioni in cui viene messo dopo una funzione.

1: non capisco quando dopo una funzione esempio if cosa succede se c'è un return senza valori.

2: in alcuni casi trovo il return con con () parentesi tonde senza nessun valore

3: return (1) oppure return(0)

in pratica vorrei capire che cosa fa il return. Per esempio come si comporta all'interno di uno switch case messo prima del break.

 

Vi chiedo se avete voglia di chiarirmi un po questo return......grazie!

Share this post


Link to post
Share on other sites

Livio Orsini

L'istruzione return, ritorna uno o più valori, secondo quanto dichiarato nella funzione.

Se la funzione è dichiarata void non ritorna alcun valore.

 

1 ora fa, kemosabe ha scritto:

return (1) oppure return(0)

In questo caso avrai una variabile dichiarata boolean e la funzione ritorna vero (1) o falso(0).

 

Comunque metti i codici di funzioni correispondeti a 3 casi, così ragionaimo su qualche cosa di reale.

Share this post


Link to post
Share on other sites
kemosabe
 mfrc522.PCD_Init();
      if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() )
      {
           citireNFC();
      if(validareNFC()) 
      {
        stare=1;
           id_valido();        
        return; 
        }
        else
        {
          id_error();      // 399 
          return;
          break;
        }
     }
       char c=myKeypad.getKey();
      if(c != NO_KEY)
      {
              String codcurent=iaCOD(c);
                int A=comparareCOD(codcurent);
        if(A==0)
        {               
           id_error();      // 401  
         return;
        }
        if(A==1)
        {
           id_valido();     //   360
           stare = 1;
         return;
        }
        if(A==2);
        {
         stare = 2;
                lcd.clear();
                  lcd.setCursor(0,0);
                    lcd.print("Pairing...");
                Serial.println("Pairing...");
              delay(2000);
         return;
        }
     } break;
 }

Ciao,come in questi casi, per esempio, vorrei capire cosa e dove ritorna il return. Come  vedi in alcuni casi c'è solo il return in altri c'è il return e il break......

grazie

Share this post


Link to post
Share on other sites
del_user_97632
5 ore fa, kemosabe ha scritto:

1: non capisco quando dopo una funzione esempio if cosa succede se c'è un return senza valori.

2: in alcuni casi trovo il return con con () parentesi tonde senza nessun valore

3: return (1) oppure return(0)

in pratica vorrei capire che cosa fa il return. Per esempio come si comporta all'interno di uno switch case messo prima del break.

 

Livio ti ha gia dato alcune spiegaizoni, ma forse aggiungo due parole

 

1. 

return senza valori si usa per uscire da una funzione void funzione()  prima della fine dello scope.

 

2.

return non e' una funzione, quindi return() e' un errore.

 

main.c:5:10: error: expected expression before ‘)’ token
    5 |  return ();

 

3. le parentesi su return (1); etc non servono, e molti correttori di sintassi segnalano di rimuoverle, ma e' lecito lasciarle.

Poi, molte funzioni

 

int funzione() { ... }

 

ritornano tipicamente 0 se non ci sono errori o un valore diverso da zero in caso di errore. Si usa generalmente int, perche' in molti casi gli errori sono negativi, ma sono convenzioni.

 

 

 

Edited by _angelo_

Share this post


Link to post
Share on other sites
del_user_97632

del tuo codice sopra,

manca la dichiarazione delal funzuone, che sara' immagino     void funzione()

 

le funzioni hanno uno spazio di vita detto "scope", tra le due graffe. 

 

void funzione()

{

}

 

il return esce dallo scope, termina la funziojne, e ritorni li dove la funzione era stata chiamata

 

Nota: il tuo codice e' forse incasinato con tabulazioni e graffe, dunque devi aver perso il filo per quello. Riordinalo.

 

 

Edited by _angelo_

Share this post


Link to post
Share on other sites
kemosabe

il pezzo di codice che vi ho allegato prima, in effetti è inserito in uno switch case.

ancora non capisco per esempio, quando è scritto senza variabile, ritorna al chiamante uno 0 o un 1 in caso di errore.

prendiamo questo pezzo e vediamo di capirci qualcosa.

char c=myKeypad.getKey();
      if(c != NO_KEY)
      {
              String codcurent=iaCOD(c);
                int A=comparareCOD(codcurent);
        if(A==0)
        {               
           id_error();      // 401  
         return;

quale tipo di errore puo succedere in questo pezzo.

int comparareCOD(String a)
{ 
if(a.equals(codacces))
return 1;
else if(a.equals(codpairing)) return 2;
else return 0; 
}

vi allego anche questo come esempio. mi fate capire quale errore puo essere scatenato,  e i vari return 1, 2 , 0, cosa restituiscono, a chi, e per quale scopo

grazie

Share this post


Link to post
Share on other sites
Livio Orsini
int comparareCOD(String a)
{ 
int iret;
if(a.equals(codacces))
iret = 1;
else if(a.equals(codpairing)) iret = 2;
else iret = 0; 
 return (iret);
}

 


Per far ritornare un valore devi scriverla così

Share this post


Link to post
Share on other sites
del_user_97632

beh intanto il codice qui sopra sembra compilato C++, lo si deduce da oggetti-porcheria "String" di VisualC se non ricordo male, comunque per il resto e' codice C

 

2 ore fa, kemosabe ha scritto:

quale tipo di errore puo succedere in questo pezzo.

a naso: e' stato premuto un tasto, o meglio un codice di alcuni tasti, se poi il codice non coincide  compareCOD restituisce 0 (errore in questo caso).

Share this post


Link to post
Share on other sites
kemosabe

il problema è che quei pezzi di codice sono quelli del programma originale, e funzionano.

il fatto è che non capisco il funzionamento dei vari return, 

return 1 ...... a chi restituisce  1????

return 2 ....... idem

return da solo....... dove ritorna il ciclo?

 

scusate se insisto ma non capisco:

char c=myKeypad.getKey();
      if(c != NO_KEY)
      {
              String codcurent=iaCOD(c);
                int A=comparareCOD(codcurent);
        if(A==0)
        {               
           id_error();      // 401  
         return;
        }
        if(A==1)
        {
           id_valido();     //   360
           stare = 1;
         return;
        }
        if(A==2);
        {
         stare = 2;
                lcd.clear();
                  lcd.setCursor(0,0);
                    lcd.print("Pairing...");
                Serial.println("Pairing...");
              delay(2000);
         return;
        }
     } break;

quello che capisco di questo pezzo è che se inserisco un codice e se il codice non corrisponde a :   iaCOD(c), A diventa 0, quindi va alla funzione ...id_error(); poi ritorna, ma dove?

se io non mettessi il return, uscito dalla funzione id_error(), non ritornerebbe lo stesso a " char c=myKeypad.getKey();" ????

per capire come funziona il return devo avere dei riscontri reali, altrimenti non ci arrivo........

 

grazie

Share this post


Link to post
Share on other sites
del_user_97632

Continui a postare codice incompleto e tutto stabulato. Manca parte della funzione, e il nome. Prova a postare almeno l'intera funzione. id_error() cosa faccia lo sai solo tu, manca il codice

Nei programmi, e qui non c'entra il C, c'e' un chiamante e un chiamato. Il return ritorna dal chiamante.

 

Edited by _angelo_

Share this post


Link to post
Share on other sites
Livio Orsini
2 ore fa, kemosabe ha scritto:

String codcurent=iaCOD(c);

int A=comparareCOD(codcurent);

if(A==0)

 

Qui chiami la funzione comparareCOD(codcurent);

Da qualche parte èm dichiarato int A

Ritorna dove c'è la riga del 1° if e rende un valore intero in A

 

Nella funzione che ho messo io ho dichiarato come locale int iret; il valore di iret almomentodel ritorno viene asseganto ad A.

 

Lo studio di un linguaggio va fatto con metodo!

Se ti basi su di un testo come il Ritchie, ma anche con altri testi, devi partire a studuare dalla prima pagina, provare i vari esercizi che incontri e non proseguire sino a quando non hai capito bene quello che hai fatto sino a quel punto.

 

Questo vale per qualsiasi cosa si studi. Saltabeccare da un  punto all'altro o, peggio, saltare certe parti che i considerano noiose o insignificanti è deleterio.

Solo quando domini bene il linguaggio puoi usare il testo come un manuale e consultarlo per verificare o rinfrescare certi argomenti specifici.

Inoltre bisognerebbe, prima ancora di studiare un linguaggio, farsi una cultura generale sulle tecniche di programmazione.

 

Io ho iniziato a programmare oltre 55 anni fa con stile "pene di molosso", poi pochi anni dopo ho dovuto dare un'esame universitario di programamzione e fortunatamente ho dovuto acquisire le basi teoriche sulle "macchine calcolatrici". Questo è stato, per me, il punto di svolta; da quel momento in poi ho imparato come si studia la programmazione e conme si affronta l'analisi di un problema software.

Share this post


Link to post
Share on other sites
kemosabe

Livio, tu hai ragione, perchè tutto quello che hai studiato ( università......), lo hai fatto per poi applicarlo al tuo lavoro.

Io, lo faccio per pura passione e con tanta voglia, ma, mai e poi mai potrei nemmeno avvicinarmi a quello che sai tu.

Cerco in tutti i modi, senza basi logicamente, ad apprendere, e penso che tu capisca che non è facile.

 Da quando avevo 10 anni, la mia passione era quella dell'elettricità, che poi mi ha portato per 40 anni a fare l'elettricista, ma ti assicuro che la mia seconda passione sono i computer, e da un po di tempo sto cercando di addentrarmi in questo mondo, che in un certo senso lega le mie due passioni.

Ti  e  Vi chiedo scusa se in base alle mie domande vi sembra che sia stupido, ma se secondo voi con le poche basi che ho, mi dite che dovrei lasciar perdere, lo faccio e cercherò di dedicarmi ad altro.

grazie per la comprensione

 

Share this post


Link to post
Share on other sites
Livio Orsini
1 ora fa, kemosabe ha scritto:

Ti  e  Vi chiedo scusa se in base alle mie domande vi sembra che sia stupido, ma se secondo voi con le poche basi che ho, mi dite che dovrei lasciar perdere, lo faccio e cercherò di dedicarmi ad altro.

 

Ma no, il forum esiste proprio per questo.

Sto solo cercando di spiegarti come studiare.

Anche se studi per hobby è sempre necessario farlo con metodo. Altrimenti si rischia da avere tanta confusione in testa.

 

Io vado per i 76,quello che faccio ora lo faccio solo per hobby, ovvero son tornato alle origini quando l'elettronica per me era solo passione.

Però anche se lavoro per hobby, quando mi metto a studiare qualche cosa di nuovo lo faccio con metodo.

A volte mi lascio prendere dall'entusiasmo e vado a tentativi, ma quasi mai i risultati sono buoni; quasi sempre è solo una perdita di tempo. Quando mi accorgo che sto facendo confusione, faccio un bel reset e riparto con metodo dall'inizio.

 

Comunque spero tu abbia capito come lavora la funzione return().

Se hai dei dubbi chiedi; al massimo ti arriva qualche .... saluto.

Share this post


Link to post
Share on other sites
dott.cicala

Partire dal C puro per imparare a programmare Arduino è molto faticoso, specialmente se si parte da zero e con un testo così "pesante" e teorico.

 

Arduino è nato proprio per facilitare l'apprendimento per mezzo della pratica e sarebbe meglio fare riferimento a uno dei tanti testi ad esso dedicati come ad esempio questo oppure questo ma ce ne sono molti altri che affrontano anche la programmazione avanzata.

 

Acquisite le basi ti sarà più facile affrontare lo studio del C anche se non è necessario conoscerlo nella sua completezza per programmare Arduino.

 

Tieni presente che nel mondo dell'automazione industriale ci sono tantissimi programmatori professionisti che non conoscono nulla del C, del testo strutturato in genere e nemmeno linguaggi di tipo IL...eppure lavorano, se bene o male è tutt'altro di scorso, ma hanno il loro mercato e riescono a soddisfare le richieste dei loro clienti, quindi non ti devi sentire incapace.

 

Hai solo scelto la strada più difficile.

Edited by dott.cicala

Share this post


Link to post
Share on other sites
kemosabe

Sono andato a vermi i manuali da te suggeriti,Stefano, e a parte due righe dove dice che return da solo ritorna al chiamante interrompendo l'esecuzione, o che ritorna un valore ad una variabile, non c'è molto altro.

Il fatto è che non capisco in che modo mi possa essere utile all'interno di un programma.

Posso partire da un esempio semplice?

 switch (stare)
  {
    case 0:
      {
        mfrc522.PCD_Init();
        if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() )
        { 
          citireNFC();         // chiama funzione di richiamo da eeprom
          if (validareNFC())   // se il codice è presente ed è corretto
          {
             id_valido();        //chiama funzione 
            stare = 0;           // poi ricomincia
            return;
          }
          else
          {
            id_error();      // se codice errato chiama questa funzione
            return;
            break;
          }
        }

        // ecc. ecc 

//        _-_---_---_----_--__--_-__----_--_----_--_-_-----

 switch (stare)
  {
    case 0:
      {
        mfrc522.PCD_Init();
        if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() )
        { 
          citireNFC();         // chiama funzione di richiamo da eeprom
          if (validareNFC())   // se il codice è presente ed è corretto
          {
             id_valido();        //chiama funzione 
            stare = 0;           // poi ricomincia
            
          }
          else
          {
            id_error();      // se codice errato chiama questa funzione
            
            break;
          }
        }

        // ecc. ecc 

come vedete ho inserito lo stesso codice due volte uno con e uno senza i return

da quel poco che so io quello che succede nel primo codice, succederebbe anche nel secondo.

Se cosi non fosse allora vorrei capirne le differenze.

 

Scusate ma sono un praticone, e mi piace vedere per capire.

 

Grazie

Share this post


Link to post
Share on other sites
Livio Orsini
1 ora fa, kemosabe ha scritto:

e a parte due righe dove dice che return da solo ritorna al chiamante interrompendo l'esecuzione, o che ritorna un valore ad una variabile, non c'è molto altro.

 

Corretto perchè non c'è altro da dire.

Per capirne l'utilità devi arrivare a capire l'utilità di delegare funzioni ripetitive a pezzi di codice specializzati nellafunzione

 

Ho dato una letta veloce alle due versioni; a mio avviso, come prima impressione, il return non sevono, per interrompere chi sono già le istruzioni di break.

 

Nel linguaggio "C", ed in quelli assimilati, la funzione "return" serve quando si vuole ritornare un valore.

Ti faccio un esempio semplicissimo.

......
int A, B, C;
.....
A = 3;
B = 5;
C = mul(A, B);

.....

int c mul(int a, int b)
{
  c = a * b;
  return c;
}

In questo caso chiami la funzione mul che esegue la moltiplicazione di 2 interi e rende un intero.

E' una cosa banale che non meriterebbe una funzione dedicata, però immagina di dover effetture un'operazione più complessaper esempio una conversione da esadecimale a BCD di un numero doppio intero.

 

Torno a ripeterti che partire a costruire un edificio da l secondo piano si spreca tempo e materiale.

Partire dalle fondazioni e poi costruire con i tempi giusti non è spreco di tempo, ma è risparmio di tempo

Edited by Livio Orsini

Share this post


Link to post
Share on other sites
kemosabe

solo a titolo di divertimento, vi allego il file con le modifiche da me apportate, alcune delle quali ancora non funzionano, vedi funzione open_door()

grazie ancora.......continuo lo studio del libro

#include <EEPROM.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>


//FASTLED
#include <FastLED.h>
#define DATA_PIN     3
#define NUM_LEDS    6
#define CLOCK_PIN 13
CRGB leds[NUM_LEDS];

//KEYPAD
#include <Keypad.h>
#include <Keypad_I2C.h>
#define I2CADDR 0x20     //il pezzo di codice che vi 
char customKey = 0;

//BLINK
unsigned long previousMillis = 0;

//DOOR
int fc_door = 4;
bool bool_door = false;
int last_door_state = LOW;
int door_state = LOW;
int val_fc_door = LOW;
bool fc_state = false;
bool door_time;
bool time_door;

//BUZZER
int Buzz = A5;

int stare = 0;
byte COD[10];
byte AUX[10];
int k = 0;
String codacces = "1234#";
String codpairing = "987A#";

//nfc
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
#define NEW_UID {0xDE, 0xAD, 0xBE, 0xEF}
MFRC522::MIFARE_Key key;

//lcd
LiquidCrystal_I2C lcd(0x27, 16, 2);

//TASTIERA
const byte numRows = 4; //number of rows on the keypad
const byte numCols = 4; //number of columns on the keypad

//keymap defines the key pressed according to the row and columns just as appears on the keypad
char keymap[numRows][numCols] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

//Code that shows the the keypad connections to the arduino terminals
byte rowPins[numRows] = {0, 1, 2, 3}; //Rows 0 to 3
byte colPins[numCols] = {4, 5, 6, 7}; //Columns 0 to 3

//initializes an instance of the Keypad class
//Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
Keypad_I2C myKeypad( makeKeymap(keymap), rowPins, colPins, numRows, numCols, I2CADDR);


void setup() {
  myKeypad.begin( );
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(50);
  FastLED.clear ();
  FastLED.show();
  pinMode(fc_door, INPUT_PULLUP);
  pinMode(Buzz, OUTPUT);

  //nfc
  Serial.begin(9600); // Initialize serial communications with the PC
  //Serial.println("Come apro?:");
  while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  SPI.begin(); // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522 card

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }
  start();      // 347
}

void citireNFC() {
  for (byte i = 0; i < (mfrc522.uid.size); i++) {
    COD[i] = mfrc522.uid.uidByte[i];
   
  }
 
  /*Serial.println("");
    Serial.print("COD  :   ");
    Serial.print(COD[0]);
    Serial.print(COD[1]);
    Serial.print(COD[2]);
    Serial.print(COD[3]);*/
}

void pairNFC() {
  Serial.println("");
  Serial.print("COD in pair  :  ");

  Serial.print(COD[0]);
  Serial.print(COD[1]);
  Serial.print(COD[2]);
  Serial.print(COD[3]);
  long r = 0;
  int c = 0;
  for (int i = 1; i <= EEPROM.read(0); i++)  {
    switch (i % 4)  {
      case 1 : {
          AUX[0] = EEPROM.read(i);
          break;
        }
      case 2 : {
          AUX[1] = EEPROM.read(i);
          break;
        }
      case 3 : {
          AUX[2] = EEPROM.read(i);
          break;
        }
      case 0 : {
          AUX[3] = EEPROM.read(i);
          break;
        }
    }
    if ((i) % 4 == 0) {
      Serial.println(r);

      if ( AUX[0] == COD[0] && AUX[1] == COD[1] && AUX[2] == COD[2] && AUX[3] == COD[3] ) {
        //lcd.clear();
        //lcd.setCursor(0,0);
        //lcd.print("ID PRESENTE");
        Serial.println("ID PRESENTE");
        leds[2].setRGB(0, 0, 255); //blue on
        FastLED.show();
        delay(2000);
        //lcd.setCursor(0,1);
        //lcd.print("SYSTEM");
        Serial.println("SYSTEM");
        leds[2].setRGB(0, 0, 0); //blue  off
        FastLED.show();

        //digitalWrite(b_led,LOW);
        delay(2000);
        c = 1;
        break;
      }
    }
  }
  if (c == 0) {
    int ttt = EEPROM.read(0);
    //lcd.print("ID AGGIUNTO");
    Serial.println("ID AGGIUNTO");
    leds[4].setRGB(255, 255, 255); //white on
    leds[2].setRGB(0, 0, 255); //blue on
    FastLED.show();
    Serial.print(COD[0]);
    Serial.print(COD[1]);
    Serial.print(COD[2]);
    Serial.print(COD[3]);

    EEPROM.write(ttt + 1, COD[0]);
    EEPROM.write(ttt + 2, COD[1]);
    EEPROM.write(ttt + 3, COD[2]);
    EEPROM.write(ttt + 4, COD[3]);

    ttt = ttt + 4;
    //Serial.println("ttt");
    //Serial.println(ttt);
    EEPROM.write(0, 0);
    EEPROM.write(0, ttt);
    //lcd.clear();
    //lcd.setCursor(0,0);
    leds[4].setRGB(0, 0, 0); //white off
    leds[2].setRGB(0, 0, 0); //blue  off
    FastLED.show();
    delay(2000);
    start();
  }
}


boolean validareNFC() {
  boolean c = false;
  for (int i = 1; i <= EEPROM.read(0); i++) {
    switch (i % 4) {
      case 1 : {
          AUX[0] = EEPROM.read(i);
          break;
        }
      case 2 : {
          AUX[1] = EEPROM.read(i);
          break;
        }
      case 3 : {
          AUX[2] = EEPROM.read(i);
          break;
        }
      case 0 : {
          AUX[3] = EEPROM.read(i);
          break;
        }
    }
    if ((i) % 4 == 0)
    {
      if ( AUX[0] == COD[0] && AUX[1] == COD[1] && AUX[2] == COD[2] && AUX[3] == COD[3])
        c = true;
    }
  }
  return c;
}

int comparareCOD(String a)
{
  if (a.equals(codacces))
    return 1;
  else if (a.equals(codpairing)) return 2;
  else return 0;
}

String iaCOD(char x)
{ char vec[8];
  vec[0] = x;
  lcd.setCursor(0, 0);
  lcd.clear();
  lcd.print('X');
  Serial.println('X');
  for (int i = 1; i < 5; i++)
  { vec[i] = myKeypad.waitForKey();
    lcd.print('X');
    Serial.println('X');
  }
  vec[5] = NULL;
  String str(vec);
  return str;
}

void loop() {

  switch (stare)
  {
    case 0:
      {
        mfrc522.PCD_Init();
        if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() )
        { 
          citireNFC();
          if (validareNFC())
          {
             id_valido();
            stare = 0;
            return;
          }
          else
          {
            id_error();      // 399
            return;
            break;
          }
        }
        char c = myKeypad.getKey();
        if (c != NO_KEY)
        {
          String codcurent = iaCOD(c);
          int A = comparareCOD(codcurent);
          if (A == 0)
          {
            id_error();      // 401
            return;
          }
          if (A == 1)
          {
            id_valido();     //   360
            stare = 1;
            return;
          }
          if (A == 2);
          {
            stare = 2;
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print("Pairing...");
            Serial.println("Pairing...");
            delay(2000);
            return;
          }
        } break;
      }
    case 1:
      {
        stare = 0;
        return;
      }
    case 2:
      {
        mfrc522.PCD_Init();
        if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() )
        {
          citireNFC();
          pairNFC();
          stare = 0;
          delay(2000);
         // start();

        }
        break;
      }
  }
}


void blinkled() // 263

{
  unsigned long previousMillis = millis();
  while (millis() - previousMillis < 3000UL)
  {
    leds[4].setRGB(0, 0, 0); //white
    leds[3].setRGB(255, 64, 0); //orange
    FastLED.show();
    delay(50);
    leds[4].setRGB(255, 255, 255); //white
    leds[3].setRGB(0, 0, 0); //red
    FastLED.show();
    delay(50);
    leds[4].setRGB(0, 0, 0); //white
    FastLED.show();
  }
}

void start()       
{
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.clear();
  lcd.print("COME APRO?");
  lcd.print("PORTA CHIUSA");
  Serial.println("Come apro?:");
  Serial.println("PORTA CHIUSA");
 
  door_time = true;
}

void id_valido() 
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("ID VALIDO");
  Serial.println("ID VALIDO");
   delay(1000);

  open_door();
  start();
}

void id_error()     
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("ID NON VALIDO");
  Serial.println("ID NON VALIDO");
  blinkled();                           
  lcd.setCursor(0, 1);
  lcd.clear();
  lcd.print("CHIUSA");
  Serial.println("CHIUSA");
  delay(1000);
  start();
}

void open_door() 
{
    door_state= digitalRead(fc_door); 
  if ( door_state) 
  {  
     leds[0]=CRGB(0,0,0);    //led porta   rosso  off aperta
     leds[1]=CRGB(0,255,0);  //led porta   verde  on  aperta  
       FastLED.show();
        //door_state = HIGH; 
  }  else   {    
             
             leds[0]=CRGB(255,0,0);       // led porta   rosso on chiusa  
              leds[1]=CRGB(0,0,0);       // led porta   verde off chiusa  
               FastLED.show();
               // door_state = LOW; 
 }
 unsigned long currentMillis = millis();
      
  // if (door_state == LOW || door_time==true)
  // {      
    if (door_time  && (millis() - previousMillis )>= 10000UL )
    {    
    
         door_time=false;
         time_door==false;
         
     } 
     time_door==true;
previousMillis = millis();


     
// }

  if (door_state == LOW  && time_door == true)
    {   leds[5]=CRGB(255,255,0);               // serratura on 
          leds[3]=CRGB(7,150,44);              // buzzer medio
          FastLED.show();
      Serial.println ("door close    time   serratura on 2 sec  suono medio");
          Serial.println ("          ");
          
    } else if (door_state == LOW && time_door==false)
      {          leds[5]=CRGB(152,52,221);               // serratura off
                   leds[3]=CRGB(0,0,0);                  // buzzer stop
                   FastLED.show();
        Serial.println ("door close   no time    no serratura  suono stop");
                  Serial.println ("          ");
                  delay(100);
                  
      } else if (time_door==false  && door_state == HIGH)
        {            leds[5]=CRGB(152,52,221);             // serratura off
                         leds[3]=CRGB(11,49,3);            // buzzer alto
                         FastLED.show();
          Serial.println ("door open & time stop    stop serratura  suono alto");
                     Serial.println ("              ");

}                       
}

 

Share this post


Link to post
Share on other sites
Livio Orsini

Che libreria stai usando per <LiquidCrystal_I2C.h>? perchè alcune hanno problemi

Share this post


Link to post
Share on other sites
del_user_97632

Codice un po' mal organizzato. Si fa fatica a leggerlo in quanto mal tabulato e mal scritto.

 

E' per chi  legge che ti aiuta e anche per te, come principiante, perche piu' e' ben chiaro e leggibile,

piu capisci al volo il funzionamento del codice. Ti consiglio di seguire uno stile di scrittura preciso.

Se non sai quale usare leggiti

https://www.kernel.org/doc/html/v4.10/process/coding-style.html

 

Altro consiglio, ok un buon libro, poi, una buona palestra di C e' l'opensource, da li puoi imparare molto,

il codice e' li ovunque in progetti gitlab etc, in genere scritto da esperti, visibile a tutti.

Un esempio il kernel linux.

https://elixir.bootlin.com/linux/v5.6-rc1/source

 

Poi, infine, verifica in open_door()

 

 time_door==false;
         
     } 
     time_door==true;

 

Edited by _angelo_

Share this post


Link to post
Share on other sites
del_user_97632

Qui c'e' qualcosa che non va

 

void blinkled() // 263

{
  unsigned long previousMillis = millis();
  while (millis() - previousMillis < 3000UL)
  {

previousMillis e' anche globale, ma se la ridefinisci dentro una funzione, viene usata

la variabile locale. Credo che la condizione sopra sia sempre vera.

lo "shadowing" di variabili e' da evitare.    https://en.wikipedia.org/wiki/Variable_shadowing

 

Edited by _angelo_

Share this post


Link to post
Share on other sites
kemosabe

per quanto riguarda la libreria <LiquidCrystal_I2C.h> sto usando la master.

molto interessante l'articolo sulla formattazione. 

si ho notato l'errore di previus millis, mi sono dimenticato di eliminarlo,grazie.

a parte queste cose, resta di fatto che la funzione open_door, se la uso da sola in un programma a parte funzione, se la inserisco nel programma che vi ho allegato prima no.

è per questo che vi chiedo delucidazioni su quei return, perchè non vorrei che fossero quelli che fanno fare alla funzione open_door strane cose

 

grazie

 

Share this post


Link to post
Share on other sites
Livio Orsini
29 minuti fa, kemosabe ha scritto:

se la uso da sola in un programma a parte funzione, se la inserisco nel programma che vi ho allegato prima no.

 

Che difetto riscontri?

 

Visto che l'ambiente arduino non ha la possibilità di inserire blocchi, fare delle traccie di percorso e altro di quanto servedevi arrangiarti con il monitor della seriale.

Nel programma metti dei Serial.println (" xxxx") con cui visualizzi dei messaggi (esempio 1, 2, ... n) così puoi seguire il percorso del tuo software e vedere se passa da determinati punti e che valore assumono le variabili facendole stampare, ad esempio se fai uno switch puoi far stampare immediatamente prima il valore della variabile dello switch.

 

35 minuti fa, kemosabe ha scritto:

per quanto riguarda la libreria <LiquidCrystal_I2C.h> sto usando la master.

 

Io uso una libreria scaricata dal forum ufficiale di Arduino (Testato è il nome della libreria).

 

Share this post


Link to post
Share on other sites
kemosabe

si Livio ho gia fatto le varie prove inserendo i serial.print, lo faccio sempre in fase di test.

In pratica il Millis di pausa della funzione open_door  è in una funzione in un'altro sketch funziona, quando la funzione la metto nel programma completo no.

Questo è uno dei dilemmi che non capisco di arduino

Share this post


Link to post
Share on other sites
del_user_97632
19 minuti fa, kemosabe ha scritto:

n pratica il Millis di pausa della funzione open_door  è in una funzione in un'altro sketch funziona,

 

Ah, ho capito tardi che lavoravi su arduino, ok.  Cosa vuoi fare di preciso ?

 

questo codice in open_door non ha molto senso a mio avviso

  // if (door_state == LOW || door_time==true)
  // {      
    if (door_time  && (millis() - previousMillis )>= 10000UL )
    {    
    
         door_time=false;
         time_door==false;
         
     } 
     time_door==true;
previousMillis = millis();


     

Se vuoi richiudere la serratura dopo 10 sedondi, da qualche parte nel main loop, dovresti effettuare il controllo del tempo e chiuderla (se aperta). Perche open_door la chiami una volta sola su id_valido

 

Share this post


Link to post
Share on other sites
kemosabe

scusa ma non capisco perchè, se creo un un nuovo skech e faccio la chiamata alla funzione dal loop:

ovvero questo:

//FASTLED
#include <FastLED.h>
#define DATA_PIN     3
#define NUM_LEDS    6
#define CLOCK_PIN 13
CRGB leds[NUM_LEDS];

//CONSTANTS

const int fc_door = 4; // Button
//const int serr = 6;       // serratura giallo
//const int buzzer_low = 5;  // green  buzzer basso
//const int buzzer_high = 7;   // red buzzer alto


//VARIABLES

int buttonPushCounter = 0;   // counter for the number of button presses
bool bool_door = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
bool time_door = false;
bool door_time=false;
//MILLIS
unsigned long previousMillis = 0;
const unsigned long interval = 5000;
const unsigned long redLedInterval = 2000;


void setup(){
   FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(50);
  FastLED.clear ();
  FastLED.show();
  
  Serial.begin ( 9600 );
     pinMode ( fc_door, INPUT );
    // pinMode ( buzzer_low, OUTPUT );
    //  pinMode( buzzer_high, OUTPUT );
      // pinMode ( serr, OUTPUT );
}


void loop(){
open_door();

  
}
void open_door() {
// read the pushbutton input pin:
    bool_door = digitalRead(fc_door);
    unsigned long currentMillis = millis();
// if button is pressed, turn relay on (if it wasn't already on), and reset the timer
// no need to check for previous state, in this specific case
    if( !door_time ) {
            time_door = true;
         if (currentMillis - previousMillis >= 6000) { 
                       previousMillis = currentMillis;
                leds[5].setRGB ( 0, 0, 0 );             //  serratura   giallo
                leds[1].setRGB ( 0, 0, 0 );      // buzzer basso   verde
                leds[0].setRGB ( 0, 0, 0 );   //buzzer alto  rosso    
                FastLED.show (); 
             time_door = false ;
             door_time = true ;
        }
   }
   
    
    
    
    
    
// if relay is currently on...
     if( time_door==true  && bool_door==LOW )  {
                           leds[5].setRGB ( 255, 255, 0 );        //  serratura   giallo
                           leds[1].setRGB ( 0, 255, 0);    // buzzer   verde
                            FastLED.show ();
     } else if (  time_door==true  && bool_door==HIGH) { 
                               leds[1].setRGB ( 0, 0, 0 );    // buzzer   verde
                               leds[0].setRGB ( 255, 0, 0 );
                                FastLED.show ();
       } else if  (  time_door==false  && bool_door==HIGH) {  
                               leds[0].setRGB ( 255, 0, 0 );
                                 FastLED.show ();
        } else if (  time_door==false  && bool_door==LOW) {  
                                 leds[0].setRGB ( 0, 0, 0 );
                                FastLED.show ();
          } 
}     

tutto funziona, magari c'è un modo migliore per farlo???

se lo inserisco nel programma con tastiera e rfid no

è qui che non capisco, perchè da una parte va e dall'altra no

ho apportato delle modifiche nel frattempo.

 

grazie

Edited by kemosabe

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...