# Συζήτηση Κυκλωμάτων > Ψηφιακά Κυκλώματα > Μικροελεγκτές >  >  Ερωτήσεις σχετικά με το ARDUINO

## aris285

Καλησπέρα σε όλους. Άρχισα να κάνω τα πρώτα βήματα στο Arduino τον τελευταίο καιρό και θα σας ζαλίσω με ερωτήσεις σε αυτο το θέμα. υπομονη και μην βαρατε τον νεο...

απορία πρωτη. στον παρακατω κωδικα αναβοσβήνει ενα led 10 φορες οταν πατηθει το button και γινει η ''i=10'' .
πως θα κανω να ανανεωνετε η ''i'' πατωντας το button ενω τρεχει η while?




```
const int led = 5;
const int button = 6;
int buttonstate;
int i = 0;


void setup() {
    
    pinMode (led, OUTPUT);
    pinMode (button, INPUT_PULLUP); // internal pull up. Or "digitalWrite (button, HIGH);"
    digitalWrite (led, LOW);
    
    
}


void loop() {
    
    buttonstate = digitalRead(button);
    if (buttonstate == LOW) {
        i = 10;
    }
    
    while (i > 0) {
        digitalWrite(led, HIGH);
        delay (1000);
        digitalWrite(led, LOW);
        delay (1000);
        i = i - 1;
    }
    
}
```

----------


## Fire Doger

1. Όταν πατάς το κουμπί το i γίνετε 10 και στην while κάθε φορά το μειώνει κατά 1 μέχρι να γίνει 0.
2.



```

void loop() {
    buttonstate = digitalRead(button);
    if (buttonstate == LOW) {
        i = 10;
    }

    
    while (i > 0) {
        buttonstate = digitalRead(button);
        if (buttonstate == LOW) {
            i = 10;
        }

        digitalWrite(led, HIGH);
        delay (1000);
        digitalWrite(led, LOW);
        delay (1000);
        i = i - 1;
    }
    
}
```


Όπως θα παρατηρήσεις το κουμπί θα πρέπει να το κρατάς πολύ ώρα για να πιάσει, αυτό συμβαίνει γιατί έχεις την delay και 'κολλάει' σε εκείνο το σημείο ο κώδικας. Κανονικά θα έπρεπε να έχεις την millis αλλά θα τα μάθεις αυτά στην πορεία.

----------


## SProg

Εαν πατηθει το Button ενω εισαι 'μεσα' στη Delay, τοτε το προγραμμα που εκανες δεν θα το αντιληφθει.


Οποτε ή σπας τα Delay() σε πολυ μικροτερα χρονικα διαστηματα και χρησιμοποιεις μετρητες ή το κανεις με διακοπες.




```
const int led = 5;
const int button = 6;
volatile int i = 0;




void setup() 
{
    
    pinMode (led, OUTPUT);
    pinMode (button, INPUT_PULLUP); // internal pull up. Or "digitalWrite (button, HIGH);"
    digitalWrite (led, LOW);
    attachInterrupt(digitalPinToInterrupt(button), refresh, LOW);
}




void loop() 
{
    if (i > 0) 
    {
        digitalWrite(led, HIGH);
        delay (1000);
        digitalWrite(led, LOW);
        delay (1000);
        i = i - 1;
    }
}


void refresh() 
{
  i=10;
}
```


Απλα θα πρεπει να μπει το Button σε Pin που υποστηριζει εξωτερικη διακοπη.


EDIT: ή το κανεις με την millis() που αναφερει ο Στεφανος. Τωρα τη θυμηθηκα  :Very Happy:

----------


## Fire Doger

Του Σάββα είναι πιο σωστό (και καθαρό) αλλά επικίνδυνο για αρχάριο γιατί το debug είναι δύσκολο.

----------


## aris285

> 1. Όταν πατάς το κουμπί το i γίνετε 10 και στην while κάθε φορά το μειώνει κατά 1 μέχρι να γίνει 0.
> 2.
> 
> 
> 
> ```
> 
> void loop() {
>     buttonstate = digitalRead(button);
> ...



googlαροντας μαθαινεις. millis λιπον.

----------


## eleCtroAsxetos

καλή η millis αλλα δεν ξερω τι ακριβως προβλημα (hardware μαλλον ασυννενοησια...) ειχε το αρντουίνο μου όταν τη χρησιμοποίησα τελευταία φορα δεν καταφερα να την κανω να δουλέψει σωστά. Στην περιπτωση μου ειχα το αρντουινο να ελεγχει με pwm σημα ενα μοσφετ που με τη σειρα του θέρμαινε μια αντίσταση. Ειχα βαλει τη millis για να αναβοσβηνει ανα δευτερολεπτο ενα λεντακι οταν η θερμοκρασία ανεβαινε πάνω απο ενα οριο και να σβηνει κατω απο αυτο. Το λεντακι αναβοσβηνε κανονικα οσο θυμαμαι αλλα μετα δεν έσβηνε μετά παρα το οτι υπηρχαν οι αντιστοιχες εντολες στον κώδικα κατι κολλουσε το ποδαρακι στο HIGH. Ακρη μετα απο απειρο ψαξιμο δεν μπορεσα να βρω παρα το οτι ολοι μου ελεγαν οτι ο κωδικας ηταν σωστος και το παρατησα. Λεω δε μας παρατας για λεντακι! :Tongue2:

----------


## SProg

Ανεβασε το κωδικα ή κανε Link το ποστ.Μαρεσουν αυτα

----------


## Fire Doger

Όταν δουλεύει για λίγο και μετά χαλάει ή έχεις μπέρδεμα στα interrupt ή έκανε overflow o stack pointer ή βγήκες εκτός ορίων σε κάποια μεταβλητή και εκτελούσε κουτουρού εντολές.

----------


## eleCtroAsxetos

> Ανεβασε το κωδικα ή κανε Link το ποστ.Μαρεσουν αυτα



δυστυχως δεν υπάρχουν ποια αυτοι οι κωδικες ηταν περσινη υποθεση οταν σεταρα το ρυθμιζομενο κολλητηρι μου και προσπαθούσα  να βαλω αυτο το λεντακι σαν ενδειξη οτι το κολλητηρι επιασε τη σωστη θερμοκρασια οποτε ειναι ετοιμο προς χρηση. Τελικα κρατησα μονο τον απλο κωδικα και τελικα μπηκε ενα λεντακι που επαιρνε μονο αναλογικη εναυση απο την πύλη του μοσφετ.
Και θα ηθελα πραγματικα να το συζητησουμε. Το ειχα κουβεντιάσει κυρίως με τον δημιουργο του αρχικου προτζεκτ-κωδικα αλλα τελικα το παρατησαμε.

----------


## aris285

Από τι διάβασα η millis είναι ένας "counter"που τρέχει ασταμάτητα. Και σε τι τιμή κάνει overflow φήμες λένε σε 50 μέρες λειτουργεί ας μιλάμε για τεράστια τιμή έτσι?

----------


## tsimpidas

> Εαν πατηθει το Button ενω εισαι 'μεσα' στη Delay, τοτε το προγραμμα που εκανες δεν θα το αντιληφθει.
> 
> 
> Οποτε ή σπας τα Delay() σε πολυ μικροτερα χρονικα διαστηματα και χρησιμοποιεις μετρητες ή το κανεις με διακοπες.



το παραπάνω δεν ισχύει.
Οταν δεν έχεις πατήσει το κουμπί στον συγκεκριμένο κωδικά και είναι ας πούμε στην ''αναμονή''προσπερνά τα delay.

αν θέλετε να το δοκιμάσετε αυτό άπλα βάλτε ενα πολυ μεγάλο delay και μετά προσπαθήστε να ''πέσετε μέσα''

Αν δεν ειχε το '' if '' τότε θα ηταν σωστό αυτό που λες.


όταν επιλέγουμε την εντολή '' if '' τότε επιλέγουμε ανάγνωση του κωδικά κατά το τι θέλουμε,, δηλ, 
δυο διαφορετικοί κώδικες [ή και περισσότεροι] μέσα στο ίδιο loop εναλλάσσονται από το '' if ''.

----------


## elektronio

> το παραπάνω δεν ισχύει.
> Οταν δεν έχεις πατήσει το κουμπί στον συγκεκριμένο κωδικά και είναι ας πούμε στην ''αναμονή''προσπερνά τα delay.
> 
> αν θέλετε να το δοκιμάσετε αυτό άπλα βάλτε ενα πολυ μεγάλο delay και μετά προσπαθήστε να ''πέσετε μέσα''
> 
> Αν δεν ειχε το '' if '' τότε θα ηταν σωστό αυτό που λες.
> 
> 
> όταν επιλέγουμε την εντολή '' if '' τότε επιλέγουμε ανάγνωση του κωδικά κατά το τι θέλουμε,, δηλ, 
> δυο διαφορετικοί κώδικες [ή και περισσότεροι] μέσα στο ίδιο loop εναλλάσσονται από το '' if ''.







> απορία πρωτη. στον παρακατω κωδικα αναβοσβήνει ενα led 10 φορες οταν πατηθει το button και γινει η ''i=10'' .
> *πως θα κανω να ανανεωνετε η ''i'' πατωντας το button ενω τρεχει η while?*



Προφανώς δεν πρόσεξες καλά την ερώτηση στην οποία απευθύνεται η απάντηση. 

Την πρώτη φορά λειτουργεί σωστά. Μετά όταν βρίσκεται μέσα στο loop της while δεν ελέγχεται το button καθώς επίσης το πρόγραμμα παγώνει όταν μπαίνει στο delay, οπότε και δεν μπορεί να ανανεώσει το χρόνο. Αν μπει ο έλεγχος του button και μέσα στην while τότε αντί να περιμένεις να εκτελεστεί όλη η συνθήκη της while, για την περίπτωση 20 sec, θα μπορέσει να ανανεωθεί στα 2 sec εφόνον κρατιέται πατημένο το πλήκτρο. Αν πατήσεις και αφήσεις το πλήκτρο κατά την διάρκεια του delay το πρόγραμμα δεν θα καταλάβει ότι πατήθηκε το πλήκτρο.

----------


## tsimpidas

Έχεις δικιο, δεν πρόσεξα καλά την ερώτηση.

όταν μένει πατημένο το κουμπί συνεχίζει και το αναβοσβημα.
ο λόγος ανανέωσης της εντολής θα ηταν χρήσιμος για το καλύτερο στήσιμο του κωδικά.

----------


## SProg

> Από τι διάβασα η millis είναι ένας "counter"που τρέχει ασταμάτητα. Και σε τι τιμή κάνει overflow φήμες λένε σε 50 μέρες λειτουργεί ας μιλάμε για τεράστια τιμή έτσι?



Ασταματητα υπο προυποθεσεις.

----------


## aris285

εκανα νεο πρόγραμμα χρησιμοποιωντας την ''millis'' διχνει να δουλευει.
Δυστιχως πλακετα aeduino δεν εχω ακομα για να κανω real test.




```



const int led = 5;
const int button = 6;


int i = 0;
int buttonstate;
int ledstate = LOW;


unsigned long previousTime = 0; // long = int > 32767


void setup() {




  pinMode(led, OUTPUT);
  pinMode(button, INPUT_PULLUP);




}


void loop() {
  buttonstate = digitalRead(button);
  if (buttonstate == LOW) {
    i = 10;
  }
  if (i > 0) {
    unsigned long curentTime = millis();
    if (curentTime - previousTime >= 1000) {
      previousTime = curentTime;
      if (ledstate == LOW) {
        ledstate = HIGH;
      }
      else {
        ledstate = LOW;
        i = i - 1;
      }
    }
  }




}
```


Μια ερώτηση. Η ''unsigned'' που χρησιμεύει και τι κανει?

----------


## Fire Doger

Σημαίνει πως είναι απροσήμαστος αριθμός.
Για παράδειγμα ένας προσημασμένος 8bit αριθμός πάει από -128 μέχρι 127, ένας απροσήμαστος πάει από 0 μέχρι 255.
Αν πχ έχεις τον αριθμό 0xFF σε προσημασμένο είναι το -1 σε απροσήμαστο είναι το 255, βάζοντας το "unsigned" ο compiler του συμπεριφέρεται ως απροσήμαστο.

----------

aris285 (25-02-18)

----------


## SProg

Δηλωνει οτι η μεταβλητη αφορα μη προσημασμενο αριθμο, δεν παιρνει αρνητικες τιμες. 

Και γιατι δεν τις βαζουμε ολες signed (να παιρνει και αρνητικες και θετικες τιμες); Γιατι για προσημασμενους αριθμους δεσμευεται το MSB (το πιο σημαντικο bit) και το ευρος τιμων  (πχ στο θετικο μερος) της μεταβλητης γινεται /2 .


Δες:

chart-variable-types.png

----------

aris285 (25-02-18)

----------


## aris285

αρα ετσι δηλώνουμε οτι ο αριθμος ειναι παντα θετικος πχ και γλυτωνουμε το bit του + η - για οικονομία στο προγραμμα.

σωστα το καταλαβα?

----------


## Fire Doger

> αρα ετσι δηλώνουμε οτι ο αριθμος ειναι παντα θετικος πχ και γλυτωνουμε το bit του + η - για οικονομία στο προγραμμα.
> 
> σωστα το καταλαβα?



Τίποτα δεν γλιτώνεις, το πλήθος των πιθανών συνδυασμών παραμένει ίδιο, απλώς οι μισοί μεταφράζονται σε αρνητικούς αριθμούς.
Το αν γλιτώσεις κάτι εξαρτάτε απ' το τι θέλεις να κάνεις, αν για παράδειγμα θέλεις να μετράς απ' το 0 μέχρι το 200 τότε ένας προσημασμένος αριθμός χρειάζεται 2byte (16bit) για να τον εκφράσει ενώ ένας απροσήμαστος 1byte(8bit). Αν θέλεις να μετράς απ' το 0 μέχρι το 10 τότε είναι το ίδιο.

*Edit: 2 φορές απροσήμαστος έγραψα πριν

----------

aris285 (25-02-18)

----------


## aris285

μια διορθωση στον κωδικα γιατι ετσι οπως ηταν δεν προκειται να αναψει ποτε το led.




```



const int led = 5;
const int button = 6;


int i = 0;
int buttonstate;
int ledstate = LOW;


unsigned long previousTime = 0; // long = int > 32767


void setup() {




  pinMode(led, OUTPUT);
  pinMode(button, INPUT_PULLUP);




}


void loop() {
  buttonstate = digitalRead(button);
  if (buttonstate == LOW) {
    i = 10;
  }
  if (i > 0) {
    unsigned long curentTime = millis();
    if (curentTime - previousTime >= 1000) {
      previousTime = curentTime;
      if (ledstate == LOW) {
        ledstate = HIGH;
      }
      else {
        ledstate = LOW;
        i = i - 1;
      }
    }
    digitalWrite(led, ledstate);
  }
}
```

----------


## tsimpidas

μια ερώτηση έχω παρεμφερή με του Αρη.

σε γραμμή παράγωγης με 2 μοτέρ έχω έναν curent Sensor που σταμάτα την γραμμή αν 
αισθανθεί μεγάλο φορτιο,

την εγκατάσταση την έχω κάνει αυτή την στιγμή με δυο arduino ένα στα μοτέρ και ένα στο curent Sensor,, 
όμως 
θα ηθελα να το κάνω με ένα arduino και ανέπτυξα τον παρακάτω κωδικά=

int sensorValue;
int analogState = analogRead(4);


void setup()
{
  pinMode(6, OUTPUT);
}


void loop()
{
  sensorValue = analogRead(4); 

analogWrite(6, sensorValue / 4); 
//analogWrite(37, 1023 - sensorValue);
  // The delay can be change to get the desired reaction speed
  delay(10);  

analogState = analogRead(4);
   if (analogRead(4) == 175 ) //curent Sensor danger
{

delay(12000);

} else {

}

sensorValue = analogRead(3); 
analogWrite(5, sensorValue / 4); 
//analogWrite(37, 1023 - sensorValue);
  // The delay can be change to get the desired dimming 
  delay(10);  
sensorValue = analogRead(5); 
analogWrite(3, sensorValue / 4); 
//analogWrite(37, 1023 - sensorValue);
  // The delay can be change to get the desired dimming 
  delay(10);  
  }


πως θα μπορούσα να προσθέσω μεγαλύτερο εύρος τιμών στο σημειο=
   analogState = analogRead(4);
   if (analogRead(4) == 175 ) //curent Sensor danger

πχ να αισθάνεται ενα εύρος μεταξύ του 100 εως το 180 ?

γίνεται χωρίς να έχουμε ένα τεράστιο σεντόνι κώδικα ?

----------


## Fire Doger

Αλλάζεις την if με:
if(analogState>=110 && analogState<=180)

Αλλά δεν βλέπω τον λόγο να υπάρχει το άνω όριο, δηλαδή αν διαβάσει για τον χ-ψ λογο 200 να μην κάνει τίποτα?
Αν θέλεις πχ οτιδήποτε μεγαλυτερο ή ίσο του 110 γίνεται:
if(analogState>=110)

----------

tsimpidas (26-02-18)

----------


## tsimpidas

έχω ήδη ''στήσει'' τον σενσορα σε αυτές τις τιμές, ευχαριστω για την άμεση απάντηση, θα 
το δοκιμάσω άμεσα.

----------


## tsimpidas

> έχω ήδη ''στήσει'' τον σενσορα σε αυτές τις τιμές, ευχαριστω για την άμεση απάντηση, θα 
> το δοκιμάσω άμεσα.



διπλό thanks !!! δουλεύει άψογα  :Smile:

----------


## aris285

χαιρετώ και παλι το θεμα. Μια βοηθεια γιατι δεν βρησκω απαντηση στο ιντερνετ.

θελω να βαλω 3 μπουτον σε μια αναλογικη εισοδο και να διαβαζω την τιμη του καθε μουτον. 
Ξερω λιπον την τιμη που μου δινει το καθε μουτον και την οριζω πχ  int  buttonUp = 376;
το θεμα μου ειναι οτι το μπουτον δεν θα δινει παντα τιμη 376 διοτι οταν φθαρει η επαφη του θα αλαξει και η τιμη, οποτε πως ορισω στην int ευρος τιμης? 
δοκιμασα πχ int buttonUp = (365, 385);  αλλα δεν επιασε.

----------


## manolena

Μπορείς με μια if συνάρτηση και θέτοντας μια minimum και maximum τιμή να του λες να βλέπει μέσα σε αυτά τα όρια, δηλαδή να κάνεις μια AND στην ουσία για κάθε εύρος τιμών που θέλεις να ελέγχεις. Έτσι θα είσαι .σίγουρος πως η αναλογική είσοδος θα διαβάζει πάντα μια συγκεκριμένη ταση αλλά με κάποιες ανοχές, π.χ.:

int value;

value = analogRead (A0);
if ((value >=300) & (value <400)) //εδώ γράψε τι θα γινεται

...και ου το καθεξής.

----------


## SProg

Πινακα θελεις.


Σαν παραδειγμα.




```
                                   
int Button[x][3] = {{1, 837, 838}, // button 1
                    {2, 737, 738}, // button 2
                    {3, 610, 611}, // button 3

                                            .
                                            .
                                            .             };
```


Πρεπει να βαλεις και τους συνδιασμους οταν παταει >1 Button μαζι.

----------


## aris285

> Μπορείς με μια if συνάρτηση και θέτοντας μια minimum και maximum τιμή να του λες να βλέπει μέσα σε αυτά τα όρια, δηλαδή να κάνεις μια AND στην ουσία για κάθε εύρος τιμών που θέλεις να ελέγχεις. Έτσι θα είσαι .σίγουρος πως η αναλογική είσοδος θα διαβάζει πάντα μια συγκεκριμένη ταση αλλά με κάποιες ανοχές, π.χ.:
> 
> int value;
> 
> value = analogRead (A0);
> if ((value >=300) & (value <400)) //εδώ γράψε τι θα γινεται
> 
> ...και ου το καθεξής.



αυτο ειναι που θελω να αποφυγω για να γλυτοσω να γραφω σεντονια.





> Πινακα θελεις.
> 
> 
> Σαν παραδειγμα.
> 
> 
> 
> 
> ```
> ...



το δοκιμασα αλλα μου βγαζει το εξής σφαλμα.  'x' was not decleared in this scope

----------


## SProg

Οπου x βαζεις τον αριθμο των συνδιασμων....

----------


## aris285

> Οπου x βαζεις τον αριθμο των συνδιασμων....



δεν το καταφερνω μαλον κατι δεν καταλαβενω σωστα.
Ας πουμε οτι εχω μονο ενα μπουτον σε ολο το συστημα που μου δινει τιμη π.χ 500 και εγω θελω να βαλω ευρος απο 400-600 και τισ τιμες 400-600 θελω να τις ονομασω πχ val1 ετσι ωστε

button = analogRead (A0);
if (button == val1) {
mpla mpla mpla
}

----------


## aris285

Το καταφερα με αλον τροπο. Αμα κοβει το μαγκουφι  :Lol: 

π.χ



```

int buttonsval;

boolean but = false;

void setup () {

pinMode (A0, INPUT);

}


void loop () {

button();

if (but = true) {
BLA  BLA BLA
 }

}

void button () {

buttonsval = analogRead (A0);
if ((buttonsval >= 500) && (buttonsval <= 600)) {
but = true;

else {
but = false;
}
```

----------


## aris285

χαιρετω και παλι στο θεμα. Εχω μια ερωτηση σχετικα με AREF του atmega328p.
επιδη φτιαχνω μια κατασκευη σε custom πλακετα βλεπω οτι στο σχεδιο του UNO το AREF εχει μονο εναν 100nF στο GND. Δεν θα επρεπε να ειναι στο +?

----------


## aris285

κανεις...?

----------


## SProg

Σωστα το εχει.

----------


## aris285

οκ thanks

----------

