Go Down

Topic: Aiuto con millis (Read 2360 times) previous topic - next topic

ziopippo

ciao...secondo me il problema sta proprio nella funzione silenzia().


Con certezza penso che il problema sia in questa funzione perchè se al posto di millis utilizzo delay funziona tutto a meraviglia.
Il problema è che ho fatto diverse prove ma non riesco a fargli fare ciò che voglio.

Puso

Scusa se dico la mia domanda...ma lo hai capito come funziona il mills()???

Puso

in pratica è il tempo da cui avvii i programma,ora ti serve un unsinged long per fare da cronometro......
se il cronometro raggiunge il tempo impostato ....cambia una variabile e fai ciò che desideri.
...cronometri ne puoi avere tanti...

ziopippo

in pratica è il tempo da cui avvii i programma,ora ti serve un unsinged long per fare da cronometro......
se il cronometro raggiunge il tempo impostato ....cambia una variabile e fai ciò che desideri.
...cronometri ne puoi avere tanti...

Si in effetti millis mi serve come creonometro per non usare delay()

Puso

si il millis() ...in pratica è da quando parte lo schetch....poi usi un unsigned long come STOP per (tipo il ceronometro)......poi usi una variablile pe fare ciò che vuoi.....e di cronometri ne puoi avere tanti...solo millis() fa partire il tempo...tutti i cronometri ti servono per fermarlo e leggerlo...poi fare ciò che vuoi.

ziopippo

Hai mica qualche link di esempio?

Puso

Scusa se la spiegazione non è delle migliori.

Puso

no...io sono a livello Hobbistico,ma se ti studi un po Millis()...maledetto Millis()....a pag 2 o3 ti fai una cultura..io ho imparato lì il millis()

ORSO2001

ciao ziopippo,

allora...per farla breve ti posto un mio esempio di alarm/snooze.
in pratica all'apparire di un allarme dato da random all'inizio hai che il LED sul pin 13 si accende, anche scritta su monitor seriale...se non fai nulla l'allarme si mette in pausa da solo...e si riattiva dopo un po'...se premi il pulsante snooze (attento che nell'esempio deve essere collegato a GND) l'allarme si tacita per un po' ma se ancora presente ritorna...a monitor seriale scrivo tutti gli stadi dell'alarm/snooze...vedi se ti può essere utile per quello che ti serve...manca il reset di tutto quando l'allarme rientra...
Code: [Select]
#define SNOOZEBUTTON 2

unsigned long alarmTime;
unsigned long snoozeTime;
boolean alarm;
boolean alarmNotPresent;
boolean snooze;


void setup() {
  Serial.begin(9600);
  pinMode(SNOOZEBUTTON , INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  alarmTime = millis();
  alarmNotPresent = true;
  alarm = false;
  snooze = false;
}

void loop() {
  int aCaso = random(0, 10000);
  if (aCaso == 500 && alarmNotPresent) {
    alarmNotPresent = false;
    Serial.println("allarme");
  }
  if (!alarmNotPresent) {
    if (!alarm) {
      digitalWrite(LED_BUILTIN, HIGH);
      alarm = true;
      alarmTime = millis();
    }
  }

  if (alarm) {
    if (!digitalRead(SNOOZEBUTTON) && !snooze) {
      Serial.println("snooze pressed");
      snooze = true;
      snoozeTime = millis();
      digitalWrite(LED_BUILTIN, LOW);
    }
    else if (snooze && millis() - snoozeTime >= 10000) {
      Serial.println("snooze time expired");
      digitalWrite(LED_BUILTIN, HIGH);
      alarmTime = millis();
      snooze = false;
    }
    if (!snooze) {
      if (digitalRead(LED_BUILTIN) && millis() - alarmTime >= 15000) {
        Serial.println("alarm horn pause");
        digitalWrite(LED_BUILTIN, LOW);
        alarmTime = millis();
      }
      if (!digitalRead(LED_BUILTIN) && millis() - alarmTime >= 5000) {
        Serial.println("alarm horn enable again");
        digitalWrite(LED_BUILTIN, HIGH);
        alarmTime = millis();
      }
    }
  }
}

ziopippo

Dunque, sono riuscito ad ottenere ciò che volevo ma ho ancora un'altro problema.
Nel momento in cui faccio il reset della board il buzzer non suona se non prima di arrivare al valore di snoozeDuration. E' chiaro che non ho intenzione di definirlo a 10 secondi ma a circa 5 minuti percui, significherebbe dover attendere questo tempo prima che il buzzer inizi a suonare al primo avvio e ciò non è normale.
Come potrei risolvere?


Code: [Select]
#include <OneWire.h>
#include <DallasTemperature.h>
#define Temp_Max_Stored 24.70
#define led_red D5
#define led_green D6
#define ONE_WIRE_BUS D4 // Data wire is plugged to arduino pin
#define buzzer D7 // buzzer to arduino pin D7
#define snoozeDuration 10000 // attesa 5 minuti (1000 millisecondi equivalgono ad un secondo)
#define pauseBetweenNotes 1000
#define noteDuration 1000
#define relay_pin D0

float tempDALLAS;
unsigned long  currentMillisAlarm = 0;
unsigned long  currentMillisSilenzia = 0;
unsigned long previousMillisAlarm = 0;
unsigned long previousMillisSilenzia = 0;
boolean outputTone = false;                // Records current state
bool snoozed = false;
bool silenzia = false;
OneWire oneWire1(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire1);
unsigned long t = 0;

void setup()
{
  Serial.begin(115200);
  // set up LEDs
  pinMode (led_red, OUTPUT);    digitalWrite(led_red, LOW);
  pinMode (led_green, OUTPUT); digitalWrite(led_green, LOW);
  pinMode (relay_pin, OUTPUT);  digitalWrite(relay_pin, HIGH);
  Serial.println("");  Serial.println("ArduAcquario MALAWI ");
}

void temperature()
{
  if (millis() - t > 5000) // Una volta ogni 5 secondi:
  {
    t = millis();
    sensors.requestTemperatures();
    tempDALLAS = sensors.getTempCByIndex(0);   // Read temperature of Dallas sensor
  }
}

void loop()
{
  temperature();
  while (tempDALLAS > Temp_Max_Stored)
  {
    Serial.println("================= ALARM TIME! ================");
    Serial.print ("Temp_Max_Stored = "); Serial.println (Temp_Max_Stored);
    temperature();
    digitalWrite (led_green, LOW); //set the LED off
    digitalWrite (led_red, HIGH); //set the LED on
    Serial.println();  Serial.print ("Temperatura acqua troppo ALTA! ");
    Serial.println(tempDALLAS); Serial.println();

    currentMillisSilenzia = millis();
    int Value = analogRead(0);
    int Btn = 0;

    if (Value > 5    &&  Value < 20)   Btn = 1; //enter
    if (Value > 240 &&  Value < 300) Btn = 2; //up
    if (Value > 400 &&  Value < 450) Btn = 3; //down
    if (Value > 500 &&  Value < 600) Btn = 4; //back

    if (Btn >= 1 && Btn <= 3)
    {
      previousMillisSilenzia = currentMillisSilenzia;
      silenzia = false;
      noTone(buzzer);
    }
    else silenzia = true;
    allarme();

    digitalWrite(relay_pin, LOW);
    delay(500);
    Serial.println(); Serial.println();
    Serial.println(currentMillisSilenzia - previousMillisSilenzia);
    Serial.println(snoozeDuration);
  }

  digitalWrite (led_green, HIGH ); //set the LED off
  digitalWrite (led_red, LOW); //set the LED on
  Serial.println("==============================================");
  Serial.print("Temperatura acqua coretta ");
  Serial.println(tempDALLAS);
  digitalWrite(relay_pin, HIGH);
  noTone(buzzer);
}

void allarme()
{
  if (currentMillisSilenzia - previousMillisSilenzia >= snoozeDuration)
  {
    silenzia = false;
   
  }
  else
  {
    silenzia = true;

  }
  if (!silenzia) {
    currentMillisAlarm = millis();
    if (outputTone)
    {
      if (currentMillisAlarm - previousMillisAlarm >= noteDuration)
      {
        previousMillisAlarm = currentMillisAlarm;
        noTone(buzzer);
        outputTone = false;
      }
    } // END if (outputTone)
    else
    {
      // We are currently in a pause
      // Check if it's been long enough and turn on if so
      if (currentMillisAlarm - previousMillisAlarm >= pauseBetweenNotes)
      {
        previousMillisAlarm = currentMillisAlarm;
        tone(buzzer, 1, 1000);
        outputTone = true;
      }
    } // END else
   
  } // END if silenzia
 
} // END allarme()

Io_me

Quindi vuoi che il buzzer cominci a suonare subito all'avvio, ma tenere la possibilità di silenziarlo per un certo tempo.
Io lo risolverei con l'uso di una boolean "prima volta" nata vera e resa falsa al primo utilizzo. Il suo utilizzo é di bypassare il primo timer che viene richiamato. Come? Assegnando il valore "corretto" alla previous presente o con un break. Come controllarla? Nel timer aggiungere un if (prima volta) nel quale agire
Non ho manco sbirciato il codice, che guardo domani se necessario

Go Up