blikání led po překročení teploty

Odpovědět
vanyj
Příspěvky: 6
Registrován: 20 říj 2017, 15:03
Reputation: 0

blikání led po překročení teploty

Příspěvek od vanyj » 21 pro 2017, 19:19

Ahoj
Můj první pokus s arduinem.
Rozsvicuju ledky podle teploty. Modrou, když je zima. Zelenou, když je akorat. Červenou když je horko. To my ještě šlo, ale když chci rozblikat modrou nebo červenou jako pro velkou zimu, nebo velké teplo tak buď svítí, nebo nesvítí. Komunikace po lince funguje takže v PC vydím hodnoty.

Program zde.

Kód: Vybrat vše

//teplotni cidlo dallas DS18B20 a diody

//knihovny
#include <OneWire.h>
#include <DallasTemperature.h>
#define modra  5
#define zelena  6
#define cervena  7
//nastaveni pinu, promenych
int pinCidlaDS = 4;
int LED = 13;
float teplota = 0;
int spodniLimitBlik = 19;
int spodniLimit = 22;
int horniLimit = 24;
int horniLimitBlik = 27;

unsigned long Time1, dT1;

//instalace oneWireDS z knihovny OneWire
OneWire oneWireDS(pinCidlaDS);
//instalace senzoryDS z knihovny DallasTemperature
DallasTemperature senzoryDS(&oneWireDS);
//----------------------------------------------------------
//-----------------------------------------------------------
void setup() {
  //komunikace pres seriovou linku
  Serial.begin(9600);
  //zapnuti komunikace knihovny s teplotnim cidlem
  senzoryDS.begin();
   //nastaveni pinu
  pinMode(LED, OUTPUT);
  pinMode(modra, OUTPUT);
  pinMode(zelena, OUTPUT);
  pinMode(cervena, OUTPUT);
  //prvni vypis po seriove lince
  Serial.println("MERENI TEPLOTY S LED DIODAMA");
  //zhasnu L LED
  digitalWrite(LED, LOW);
  dT1 = 1000 / 2;
  Time1 = millis();
}
//---------------------------------------------------------
//---------------------------------------------------------
void loop() {
 //nacteni informaci ze vsech cidel pripojenych na danem pinu
  senzoryDS.requestTemperatures();
  //vypis teploty na seriovou linku, pri pripojeni vice cidel na jeden pin muzeme postupne nacist vsechny teploty pomoci zmeny cisla v zavorce (0) - poradi dle unikatni adresy cidel
  Serial.print("Teplota cidla DS18B20: ");
  Serial.print(senzoryDS.getTempCByIndex(0));
  Serial.println("°C");
  //nastaveni teplota = vystup cidla
  teplota = senzoryDS.getTempCByIndex(0);
  
//------------------PROBLEM ZDE------------------------------------------------

  if(teplota <= spodniLimitBlik){
    Serial.println(", velka zima");
  //zapne blikani
if(millis() >= Time1){
  digitalWrite(modra, !digitalRead(modra));
  Time1 += dT1;
 }  
digitalWrite(zelena, LOW);
digitalWrite(cervena, LOW);}

//--------------------PROBLEM ZDE---------------------------------------------  

  else if(teplota > spodniLimitBlik && teplota <= spodniLimit)
{Serial.println(", zima");
digitalWrite(modra, HIGH);
digitalWrite(zelena, LOW);
digitalWrite(cervena, LOW);
 } 
 else if(teplota > spodniLimit && teplota < horniLimit)
 {Serial.println(", akorat");
 digitalWrite(modra, LOW);
digitalWrite(zelena, HIGH);
digitalWrite(cervena, LOW);
 }
 else if(teplota >= horniLimit && teplota < horniLimitBlik)
{Serial.println(", horko");
digitalWrite(modra, LOW);
digitalWrite(zelena, LOW);
digitalWrite(cervena, HIGH);
 } 
 
 //----------------------------PROBLEM ZDE---------------------------------

 else if(teplota >= horniLimitBlik){ 
  Serial.println(", velke horko");
  //zapne blikani
if(millis() >= Time1){
  digitalWrite(cervena, !digitalRead(cervena));
  Time1 += dT1;
 }
digitalWrite(zelena, LOW);
digitalWrite(modra, LOW);
}

//--------------------------PROBLEM ZDE----------------------------------------

  //pauza
  delay(20000);


}

Zkoušel jsem různe styly programů na to blikání a ani s jedním mi to nešlo.
*********************************************************************************************************
1.

Kód: Vybrat vše

// interval blikani
int interval=1000;
// sledovani casu
unsigned long predchoziMillis=0;


void setup() {
  //nastavy pin jeko vystup
pinMode(5, OUTPUT);  
pinMode(6, OUTPUT);
digitalWrite(5,HIGH);
delay(5000);
}

void loop() {
  //zapne blikani
unsigned long aktualniMillis = millis();
if((unsigned long)(aktualniMillis - predchoziMillis) >= interval) {
  digitalWrite(5, !digitalRead(5));
  predchoziMillis=aktualniMillis;
}
digitalWrite(6,LOW);
}
******************************************************************************************
2.

Kód: Vybrat vše

//aktualni cas
unsigned long aktualniMillis; 
//cas posledni akce
unsigned long predchoziMillis;
//promenna pro stav LED
boolean ledSvetlo;
//port pro led
int led = 7;
//-------------------------
//-------------------------
void setup() {
pinMode (led, OUTPUT);
}
//---------------------
//--------------------
void loop() {
aktualniMillis = millis();//podivam se na hodinky
if(ledSvetlo){//potrebuji LED shasnout nebo rosvitit?
  if(aktualniMillis - predchoziMillis > 1000) {
    predchoziMillis = aktualniMillis;
    ledSvetlo=LOW;
  }
}else if(aktualniMillis - predchoziMillis > 1000) {
  predchoziMillis = aktualniMillis;
  ledSvetlo=HIGH;
}
digitalWrite(led, ledSvetlo); //aktualizace stavu LED


}
*************************************************************************************************
3.

Kód: Vybrat vše

#define cervena 7
#define modra 5

unsigned long Time1, dT1;

void setup() {
pinMode(cervena, OUTPUT);
pinMode(modra, OUTPUT);

dT1 = 1000 / 2;
Time1 = millis();
}

void loop() {
 if(millis() >= Time1){
  digitalWrite(modra, !digitalRead(modra));
  Time1 += dT1;
 }

}
******************************************************************************************

Samostatně fungují, ale nevím jak je naroubovat do programu. Poraďte prosím.

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: blikání led po překročení teploty

Příspěvek od petan » 21 pro 2017, 20:20

Když dáš do loop() příkaz delay(), tak se ti tam program zastaví a bude tam čekat. Takže ledka nebude blikat.
Já bych to udělal takhle:
Vytvořil bych si třeba dva podprogramy - jeden by měřil v určitém intervalu teplotu a druhý by zajišťoval blikání. V hlavní smyčce bych podle načtené teploty řešil logiku. Třeba takto (netestoval jsem):

Kód: Vybrat vše

long timeMereni; //proměnná pro měření
long timeBlikani; //proměnná pro blikání

bool flag;	//proměnná, který bude "blikat"
bool redLed, greenLed, blueLed;	//stavy jednotlivých diod
int temp = 0; //teplota

void setup() {
	pinMode(5, OUTPUT);	//modrá
	pinMode(6, OUTPUT);	//zelená
	pinMode(7, OUTPUT);	//červená

}

void loop() {
	//časovač 1
	if (millis() >= timeMereni + 20000) {
		//měření teploty proběhne jednou za 20 sekund
		timeMereni = millis(); //ulož čas provedení podprogramu 1 

		ZmerTeplotu(); //spusť funkci Podprogram1 
	}

	//časovač 2
	if (millis() >= timeBlikani + 500) {
		//přepnutí proměnné se provede jednou za 500 ms
		timeBlikani = millis(); //ulož čas provedení podprogramu 2 

		flag = !flag;	//negace
	}

	//tady už pak bude jenom ta logika rozsvěcení ledek
	if (temp < -5) {
		//teplota je nižší než -5. Blikej modrou ledkou
		blueLed = flag;	//blikání
		redLed = false;	//trvale zhasnuto
		greenLed = false;
	}

	if (temp >= -5 && temp < 5) {
		//teplota je vyšší než -5 a menší než 5. sviť modou ledkou
		blueLed = true;
		redLed = false;
		greenLed = false;
	}


	if (temp >= 35) {
		//teplota je vyšší než 35. blikej červenou ledkou
		blueLed = false;
		redLed = flag;
		greenLed = false;
	}

	//a tak dále...


	//rozsvěcení LEDek
	digitalWrite(5, blueLed);
	digitalWrite(6, greenLed);
	digitalWrite(7, redLed);
}

void ZmerTeplotu() {
	//zde bude probíhat měření teploty
	temp = 25;
}

AstroMiK
Příspěvky: 593
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: blikání led po překročení teploty

Příspěvek od AstroMiK » 22 pro 2017, 09:19

Pozor na to používání funkce millis().
Pro trvale zapnuté zařízení asi po 50 dnech dojde k přtečení počítadla a program přestane číst teplotu.

Buď je třeba testovat ještě navíc stav, jestli je poslední zaznamenaná hodnota millis() větší, než aktuální millis().
Pokud ano, tak tu zaznamenanou hodnotu vynulovat.

Druhou možností je použít na hlavní smyčku obyčejné delay() - například na 0,5s a vlastní proměnnou si ty jednotlivé cykly odpočítávat.
V tomto případě by se ta pauza dala využít i pro blikání.

Nějak takhle:

Kód: Vybrat vše

... // nejake ty deklarace promennych
...
void loop (void)
  {
    if (pocitadlo == 0)
      {
        ZmerTeplotu();
        pocitadlo = 40;   // pocet pruchodu smyckou po kterych se zmeri teplota 
      } 
      
    if (teplota > 30)      // kdyz teplota presahne 30°, bude se kazdych 0,5s menit stav cervene LED (bude blikat)
      {
        zmen_stav_cervene_LED();
      }


...   //tady obslouzit i ostatni teploty
...
...

     
      
    pocitadlo --;
    delay(500);     // jedna smycka trva 0,5sekundy
  }
  

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: blikání led po překročení teploty

Příspěvek od petan » 22 pro 2017, 14:39

Koukni sem: http://playground.arduino.cc/Code/TimingRollover

Pokud mají obě proměnné stejný typ, tak přetečou ve stejnou dobu. Takže když když do proměnné která je těsně před přetečením přičteš číslo, tak proměnná přeteče a začíná počítat od 0. Stejně je to u millis.

Pokud by to bylo 8b proměnné (byte; 0 - 255) tak by to vypadalo tahle:

Kód: Vybrat vše

byte a, b, c;

a=250;
b=10;
c=a+b; //do c by se uložila hodnota 250+10 = 260. Jenže proměnné u 255 přeteče a změní se opět na 0, takže v c bude hodnota 5
Asi by bylo lepší millis na jednom místě přehrnout do proměnné. Uznávám, kód není úplně čistej :D
Důležité je používat všude unsigned long.


Takto mám časování řešeno v sodobaru a funguje bez vypnutí určitě déle jak dva měsíce.

vanyj
Příspěvky: 6
Registrován: 20 říj 2017, 15:03
Reputation: 0

Re: blikání led po překročení teploty

Příspěvek od vanyj » 26 pro 2017, 13:50

díky za rady
předělal jsem to na toto

Kód: Vybrat vše

//teplotni cidlo dallas DS18B20 a diody

//knihovny
#include <OneWire.h>
#include <DallasTemperature.h>
long timeMereni; 
long timeBlikani;
bool flag;
bool redLed, greenLed, blueLed;
int pinCidlaDS = 4;
float teplota = 0;

//instalace oneWireDS z knihovny OneWire
OneWire oneWireDS(pinCidlaDS);
//instalace senzoryDS z knihovny DallasTemperature
DallasTemperature senzoryDS(&oneWireDS);
//----------------------------------------------------------
//-----------------------------------------------------------
void setup() {
  //komunikace pres seriovou linku
  Serial.begin(9600);
  //zapnuti komunikace knihovny s teplotnim cidlem
  senzoryDS.begin();
   //nastaveni pinu
  pinMode(13, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  //prvni vypis po seriove lince
  Serial.println("MERENI TEPLOTY S LED DIODAMA");
  //zhasnu L LED
  digitalWrite(13, LOW);

}
//---------------------------------------------------------
//---------------------------------------------------------
void loop() {
  if (millis() >= timeMereni + 20000) {
    timeMereni = millis();
    ZmerTeplotu();
  }
  if (millis() >= timeBlikani + 500) {
    timeBlikani = millis();
    flag = !flag;
  }

  if(teplota < 20) {
    blueLed = flag;
    redLed = false;
    greenLed = false;
    }
    if (teplota >=20 && teplota < 22) {
      blueLed = true;
      redLed = false;
      greenLed = false;
    }
    if (teplota >=22 && teplota <24) {
      blueLed = false;
      redLed = false;
      greenLed = true;
    }
    if (teplota >=24 && teplota <26) {
      blueLed = false;
      redLed = true;
      greenLed = false;
    }
    if (teplota >=26) {
      blueLed = false;
      redLed = flag;
      greenLed = false;  
    }
    digitalWrite(5, blueLed);
    digitalWrite(6, greenLed);
    digitalWrite(7, redLed);
}
void ZmerTeplotu() {
  //nacteni informaci ze vsech cidel pripojenych na danem pinu
  senzoryDS.requestTemperatures();
  //vypis teploty na seriovou linku, pri pripojeni vice cidel na jeden pin muzeme postupne nacist vsechny teploty pomoci zmeny cisla v zavorce (0) - poradi dle unikatni adresy cidel
  Serial.print("Teplota cidla DS18B20: ");
  Serial.print(senzoryDS.getTempCByIndex(0));
  Serial.println("°C");
   //nastaveni teploty na senzor
  teplota = senzoryDS.getTempCByIndex (0);
}
A FUNGUJE TO

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: blikání led po překročení teploty

Příspěvek od petan » 26 pro 2017, 18:35

Tak to je good :)

Pro příště, až budeš vkládat kód, tak ho hoď mezi tagy code. Je to tlačítko s takovejma těma špičatejma závorkama a lomítkem.

zbysek
Site Admin
Příspěvky: 125
Registrován: 22 úno 2017, 15:18
Reputation: 0

Re: blikání led po překročení teploty

Příspěvek od zbysek » 26 pro 2017, 19:36

Přidal jsem code tagy za @vanyj :)

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 37 hostů