Sonda ds18b20 collegata a servo

Salve a tutti, sono nuovo del gruppo, quini spero di non infrangere nessuna regola anche se ho letto il regolamento. Mi trovo da giorni bloccato su un codice, e quindi oggi mi sono deciso di chiedere consiglio a chi ne sa più di me. Lo sketch, attraverso la dallas 18b20 rivela la temperature esterna, il mio intento sarebbe quello di far girare un servo (servo a rotazione continua) per un determinato tempo di un determinato angolo, il problema è che questa rotazione deve essere fatta solo una volta se si verifica la condizione, invece adesso la rotazione viene ripetuta continuamente a intervalli di un secondo, determinati dal delay(1000). Premetto che ho conoscenza base del mondo della programmazione quindi spero che qualcuno sia capace di darmi una dritta.
Allego il codice qui sotto:

#include <OneWire.h>
OneWire  ds(10);
#include <Servo.h>
Servo myservo;


void setup(void) {
  Serial.begin(9600);
  myservo.attach(6);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;

  if ( !ds.search(addr)) {

    ds.reset_search();
    delay(250);
    return;
  }

  switch (addr[0]) {
    case 0x10:

      type_s = 1;
      break;
    case 0x28:

      type_s = 0;
      break;
    case 0x22:

      type_s = 0;
      break;
    default:

      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);

  delay(1000);
  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);

  for ( i = 0; i < 12; i++) {
    data[i] = ds.read();
  }

  Serial.println();


  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3;
    if (data[7] == 0x10) {

      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);

    if (cfg == 0x00) raw = raw & ~7;
    else if (cfg == 0x20) raw = raw & ~3;
    else if (cfg == 0x40) raw = raw & ~1;

  }
  celsius = (float)raw / 16.0;

  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius ");

  if (celsius < 31) {

    for ( int i = 1550; i < 1630; i += 20 ) {

      myservo.writeMicroseconds( i );

      delay(10);
    }
  }

  if (celsius > 33 ) {
    myservo.attach(6);

    for ( int i = 1450; i > 1350; i -= 10 ) {

      myservo.writeMicroseconds( i );
      delay(100);


    }

  }
}

Buongiorno,
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 su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: ... mi sa che il regolamento non lo hai letto con attenzione :wink:
PP.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

okok, presentazione appena effettuata...mi accingo a leggere il regolamento con più attenzione :wink:

In pratica, se ho ben capito, se la tua temperatura è inferiore a 31° tu vuoi fare un’azione e se superiore a 33° ne vuoi fare un’altra, ma, entrambe, una sola volta all’avverarsi della condizione.

La cosa più semplice è che usi delle flag che ti dicono se hai già effettuato l’azione, così non la ripeti …
… parti con entrambe le flag messe a ‘true’ dopo di che:

...
byte flagMin = true;
byte flagMax = true;
...
...
if ( flagMin && (celsius < 31) ) {
   flagMin = false;
   flagMax = true;
   ...
   ...
}
...
if ( flagMax && (celsius > 33 ) ) {
   flagMin = true;
   flagMax = false;
   ...
   ...
}
...

… in questo modo, quando scendi sotto i 31° abiliti la possibilità di fare qualche cosa per sopra i 33° ma la disabiliti per sotto i 31° e, quando superi i 33°, riabiliti la possibilità per sotto i 31°, ma la disabiliti per sopra i 33° :wink:

Guglielmo

Grazie mille Guglielmo, non ci sarei mai arrivato senza il tuo aiuto... :wink: :wink:
Adesso provo e faccio sapere

Problema risolto, oltre alla flag ho inserito altri 2 cicli for nelle due if, che applicano un incremento di velocità pari a zero e così mi fermano i motori, poi al posto del delay ho messo il break, che fa “saltare” l’esecuzione del codice perchè con questo incremento si farebbe un loop infinito e non applicherebbe il codice che segue…Posto il codice casomai servisse a qualcuno.

#include <OneWire.h>
OneWire  ds(10);
#include <Servo.h>
Servo myservo;
volatile bool minFlag = true;
volatile bool maxFlag = true;



void setup(void) {
  Serial.begin(9600);
  myservo.attach(6);



}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;



  if ( !ds.search(addr)) {

    ds.reset_search();
    delay(250);
    return;
  }

  switch (addr[0]) {
    case 0x10:

      type_s = 1;
      break;
    case 0x28:

      type_s = 0;
      break;
    case 0x22:

      type_s = 0;
      break;
    default:

      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);

  delay(1000);
  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);

  for ( i = 0; i < 12; i++) {
    data[i] = ds.read();
  }

  Serial.println();


  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3;
    if (data[7] == 0x10) {

      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);

    if (cfg == 0x00) raw = raw & ~7;
    else if (cfg == 0x20) raw = raw & ~3;
    else if (cfg == 0x40) raw = raw & ~1;

  }
  celsius = (float)raw / 16.0;

  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius ");

  if (minFlag && (celsius < 31) ) {

    for ( int i = 1550; i < 1800; i += 10 ) {
      myservo.writeMicroseconds( i );
      delay(100);
    }

    for ( int i = 1550; i < 2000; i += 0 ) {
      myservo.writeMicroseconds( i );
      break;
    }
    minFlag = false;
    maxFlag = true;
  }

  if (maxFlag && (celsius > 31 ) ) {

    for ( int i = 1450; i > 1150; i -= 10 ) {
      myservo.writeMicroseconds( i );
      delay(100);
    }

    for ( int i = 1450; i > 1000; i -= 0 ) {
      myservo.writeMicroseconds( i );
      break;
    }
    minFlag = true;
    maxFlag = false;
  }
}

Angelo