• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Pomoc i poprawienie prostego kodu
#11
Jeszcze raz ja proszę o pomoc. Może ktoś przeanalizuje mój kod i pomoże wychwycić błędy. Kod się wgrywa i działa ale nie wiem czy gdzieś nie namieszałem z logiką. Układ zrobiłem na LGT8F328. Czy to jest dobry układ do takich zastosowań czy lepiej na innym? Pozdrawiam
Kod:
#include <avr/wdt.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS D7 // Pin OneWire
#define TEMPERATURE_PRECISION 9

byte znak0[8] = { 0b01100, 0b10010, 0b10010, 0b01100, 0b00000, 0b00000, 0b00000, 0b00000 }; // znak Ę i °C
byte znak1[8] = { 0b11111, 0b10000, 0b10000, 0b11111, 0b10000, 0b10000, 0b11111, 0b00010 };

int przekaznikGaz = D9;
int przekaznikPG = D10;
int przekaznikPW = D11;
int buzer = D4;

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress DS_NR1 = { 0x28, 0x32, 0xFD, 0x48, 0xF6, 0xA8, 0x3C, 0xF2 }; // Tu wpisać adresy czujników
DeviceAddress DS_NR2 = { 0x28, 0x6F, 0x82, 0x95, 0xF0, 0x01, 0x3C, 0x85 };

LiquidCrystal_I2C lcd(0x27,16,2); 
float tempW = 0;
float tempG = 0;
float hist = 1.5;
float tG = 31.5;
float tW = 31.5;
float histGaz = 15;
float tPG = 55;
void setup()
{
wdt_enable(WDTO_4S);

//  lcd.noBacklight();  //wyłącza podświetlenie
   
  sensors.begin();
  lcd.init();                   
  lcd.backlight();
  lcd.clear();
 
//przekaznikGaz jako wyjście
pinMode(przekaznikGaz, OUTPUT);      //przekaznikGaz jako wyjście
pinMode(przekaznikPG, OUTPUT); 
pinMode(przekaznikPW, OUTPUT); 
pinMode(buzer, OUTPUT);

digitalWrite(przekaznikGaz, HIGH);    //Włączenie pieca GAZ
digitalWrite(przekaznikPG, LOW);      // Włączenie cyrkulacji GAZ
digitalWrite(przekaznikPW, LOW);      // Włączenie cyrkulacj Węgiel
digitalWrite(buzer, LOW);            // ALARM!

  sensors.setResolution(DS_NR1, TEMPERATURE_PRECISION);
  sensors.setResolution(DS_NR2, TEMPERATURE_PRECISION);

}

void loop()
{
  sensors.requestTemperatures();
  tempW = sensors.getTempC(DS_NR1);  // pobierz temperaturę po kolei z termometrów
  tempG = sensors.getTempC(DS_NR2);
// ===============================================================================



if(tempW> (tW+hist)) // temperatura większa od 
{
  digitalWrite(przekaznikPW, HIGH);
// digitalWrite(przekaznikGaz, LOW);
}
  else if (tempW< (tW-hist))  // mniejsza od
  {
  digitalWrite(przekaznikPW, LOW);
// digitalWrite(przekaznikGaz, HIGH);
}

//====================================================

if((tempG>(tPG+histGaz)) || (tempW> 35))
{
  digitalWrite(przekaznikGaz, LOW);
}
else if (tempG<(tPG-histGaz))
{
digitalWrite(przekaznikGaz, HIGH);
}
//================================================
if(tempG> (tG+hist))
{
  digitalWrite(przekaznikPG, HIGH);
}
else if (tempG< (tG-hist))
{
  digitalWrite(przekaznikPG, LOW);
}

if((tempG>80) || (tempW>85))
{
  digitalWrite(buzer, HIGH);
  digitalWrite(przekaznikPG, HIGH);
  digitalWrite(przekaznikPW, HIGH);
  digitalWrite(przekaznikGaz, LOW);
}
else if((tempG<50) || (tempW<60))
{
  digitalWrite(buzer, LOW);
}

//=======================================

lcd.createChar(0, znak0);
lcd.createChar(1, znak1);
lcd.setCursor(0,0);
lcd.print("PIEC GAZ: ");
lcd.setCursor(10,0);
lcd.print(tempG,1);
lcd.print((char)0);
lcd.print("C");

//======================================

lcd.setCursor(0,1);
lcd.print("PIEC W");
lcd.print((char)1);
lcd.print("G: ");
lcd.setCursor(10,1);
lcd.print(tempW,1);
lcd.print((char)0);
lcd.print("C");

//=====================================
delay (3000);

wdt_reset();
}
//=================================


Z kodem sprawdzającym błąd czujników sobie nie poradziłem :(
 
Odpowiedź
#12
LGT8F328 to tylko podobny układ do atmega328, na pewno zweryfikuj czasy, u mnie w jednym z core ściągniętym z Internetu (bo musi być inny core, to nie jest AVR) millis rozjeżdżały się o ponad 10%, z tego samego powodu wdt.h może nie działać. 10% to może nie dużo, ale jeśli biblioteka DS korzysta z tego to może działać na granicy tego, co będzie interpretowane jako zera i jedynki, a przy delikatnym zakłóceniu, bez znaczenia dla AVR tu już klęknie.
Choć widzę, że u mnie w core jest ten plik i ma nawet do 32s zdefiniowane makra.
Wszystko musisz przetestować, np. wdt specjalnie blokując program w wybranym czasie, np. odlicz 10 cykli loop i zrób while(1), sprawdź czy restartuje i ponownie się uruchamia. Niektóre NANO nie podnosiły się po resecie WDT, trzeba im wgrać nowszy bootloader. Nie testowałem WDT w LGT w ogóle.
Generalnie bezpieczniej byłoby się uczyć na sprawdzonym AVR, ale podobno ceny poszły w górę jak za Bitcoin'a.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#13
(04-04-2022, 14:22)kaczakat napisał(a): LGT8F328 to tylko podobny układ do atmega328, na pewno zweryfikuj czasy, u mnie w jednym z core ściągniętym z Internetu (bo musi być inny core, to nie jest AVR) millis rozjeżdżały się o ponad 10%, z tego samego powodu wdt.h może nie działać. 10% to może nie dużo, ale jeśli biblioteka DS korzysta z tego to może działać na granicy tego, co będzie interpretowane jako zera i jedynki, a przy delikatnym zakłóceniu, bez znaczenia dla AVR tu już klęknie.
Choć widzę, że u mnie w core jest ten plik i ma nawet do 32s zdefiniowane makra.
Wszystko musisz przetestować, np. wdt specjalnie blokując program w wybranym czasie, np. odlicz 10 cykli loop i zrób while(1), sprawdź czy restartuje i ponownie się uruchamia. Niektóre NANO nie podnosiły się po resecie WDT, trzeba im wgrać nowszy bootloader. Nie testowałem WDT w LGT w ogóle.
Generalnie bezpieczniej byłoby się uczyć na sprawdzonym AVR, ale podobno ceny poszły w górę jak za Bitcoin'a.
Jestem noga i nie wiem jak to zrobić aby sprawdzić czy restartuje. Co i gdzie mam wpisać ? Możesz pomóc? Pozdrawiam
 
Odpowiedź
#14
WDT wymaga najnowszego bootoadera bo na starszym się kasztania i właśnie nie podnoszą.

Opisz każdą linijkę po co i dlaczego i co włącza/wyłącza a jak będzie opisane to mogę sprawdzić a nawet poprawić program i napisać od nowa.
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#15
Dodaj wydruk na serial zmiennej z inkrementacją, powinny rosnąć numery aż do momentu gdy program uruchomi się od nowa, przez reset WDT i znowu będą rosły od wartości początkowej.
...
void loop()
{
Serial.println(zmienna++);
if(zmienna>=10) while (1); //jak zrobi 10 cykli to ma się tu zablokowac, a WDT powinien zresetowac
delay(1000);
wdt_reset();
}
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#16
(04-04-2022, 17:22)Jarewa0606 napisał(a): WDT wymaga najnowszego bootoadera bo na starszym się kasztania i właśnie nie podnoszą.

Opisz każdą linijkę po co i dlaczego i co włącza/wyłącza a jak będzie opisane to mogę sprawdzić a nawet poprawić program i napisać od nowa.
Kod:
#include <avr/wdt.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS D7 // Pin OneWire
#define TEMPERATURE_PRECISION 9

byte znak0[8] = { 0b01100, 0b10010, 0b10010, 0b01100, 0b00000, 0b00000, 0b00000, 0b00000 }; // znak Ę i °C
byte znak1[8] = { 0b11111, 0b10000, 0b10000, 0b11111, 0b10000, 0b10000, 0b11111, 0b00010 };

int przekaznikGaz = D9; // Włącza piec gazowy
int przekaznikPG = D10; // Załącza pompę obiegową pieca gazowego
int przekaznikPW = D11; // żałącza pompę pieca węglowego
int buzer = D4;        // włącza alarm gdy temperatury przekraczają niebezpieczne lub coś jest nie tak

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress DS_NR1 = { 0x28, 0x32, 0xFD, 0x48, 0xF6, 0xA8, 0x3C, 0xF2 }; // Tu wpisać adresy czujników
DeviceAddress DS_NR2 = { 0x28, 0x6F, 0x82, 0x95, 0xF0, 0x01, 0x3C, 0x85 };

LiquidCrystal_I2C lcd(0x27,16,2); 
float tempW = 0;        // temperatura na piecu węglowym
float tempG = 0;        // temperatura na piecu gazowym
float hist = 1.5;        // aby przekaznik nie klikał
float tG = 31.5;
float tW = 31.5;
float histGaz = 15;
float tPG = 55;
void setup()
{
wdt_enable(WDTO_4S);

//  lcd.noBacklight();  //wyłącza podświetlenie
   
  sensors.begin();
  lcd.init();                   
  lcd.backlight();
  lcd.clear();
 
//przekaznikGaz jako wyjście
pinMode(przekaznikGaz, OUTPUT);      //przekaznik załączający piec gazowy
pinMode(przekaznikPG, OUTPUT);        // załączający pompe pieca gazowego
pinMode(przekaznikPW, OUTPUT);        // załączający pompe pieca węglowego
pinMode(buzer, OUTPUT);

digitalWrite(przekaznikGaz, HIGH);    //Włączenie pieca GAZ
digitalWrite(przekaznikPG, LOW);      // Włączenie cyrkulacji GAZ
digitalWrite(przekaznikPW, LOW);      // Włączenie cyrkulacj Węgiel
digitalWrite(buzer, LOW);            // ALARM!

  sensors.setResolution(DS_NR1, TEMPERATURE_PRECISION);
  sensors.setResolution(DS_NR2, TEMPERATURE_PRECISION);

}

void loop()
{
  sensors.requestTemperatures();
  tempW = sensors.getTempC(DS_NR1);  // pobierz temperaturę po kolei z termometrów
  tempG = sensors.getTempC(DS_NR2);
// ===============================================================================

if(tempW> (tW+hist)) // temperatura większa od  xx włącz pompe pieca węglowego
{
  digitalWrite(przekaznikPW, HIGH);
// digitalWrite(przekaznikGaz, LOW);
}
  else if (tempW< (tW-hist))  // mniejsza od xx wyłącz pompe weglowego
  {
  digitalWrite(przekaznikPW, LOW);
// digitalWrite(przekaznikGaz, HIGH);
}

//====================================================

if((tempG>(tPG+histGaz)) || (tempW> 35))      // jeżeli temperatura pieca gazowego jest większa od np. 70 C to go wyłącz
{
  digitalWrite(przekaznikGaz, LOW);            // lub gdy piec weglowy grzeje wyłącz gazowy
}
else if (tempG<(tPG-histGaz))
{
digitalWrite(przekaznikGaz, HIGH);
}

//================================================

if(tempG> (tG+hist))                            // jeżeli temperatura pieca gazowego większa od np 30 włącz pompe pieca gazowego
{
  digitalWrite(przekaznikPG, HIGH);
}
else if (tempG< (tG-hist))
{
  digitalWrite(przekaznikPG, LOW);
}
//====================================================

if((tempG>80) || (tempW>85))                  // jeżeli temperatury przekroczą niebezpieczne włącz alarm i obie pompy i wyłącz piec gazowy
{
  digitalWrite(buzer, HIGH);
  digitalWrite(przekaznikPG, HIGH);
  digitalWrite(przekaznikPW, HIGH);
  digitalWrite(przekaznikGaz, LOW);
}
else if((tempG<50) || (tempW<60))
{
  digitalWrite(buzer, LOW);
}

//=======================================

lcd.createChar(0, znak0);
lcd.createChar(1, znak1);
lcd.setCursor(0,0);
lcd.print("PIEC GAZ: ");
lcd.setCursor(10,0);
lcd.print(tempG,1);
lcd.print((char)0);
lcd.print("C");

//======================================

lcd.setCursor(0,1);
lcd.print("PIEC W");
lcd.print((char)1);
lcd.print("G: ");
lcd.setCursor(10,1);
lcd.print(tempW,1);
lcd.print((char)0);
lcd.print("C");

//=====================================

    // tutaj miało być że jak coś jest nie tak to włącz alarm!

//=====================================
delay (3000);

wdt_reset();            // sprawdzone działa jak zapętle
}
//=================================
 
Odpowiedź
#17
Dołącz mi swoje biblioteki LiquidCrystal_I2C.h i DallasTemperature.h i druga sprawa która wersja to nano? będzie to nowszy bootloader czy ten starszy? masz w zamiarze jakieś przyciski?
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#18
Używam płytek LGTBF328F - LQFP32 MiniEVB (Nano3 Compatible) BTE8-04
Przycisk nie potrzebny. Zmieniłem tylko wyświetlacz na 4x20 i teraz tak to wygląda.

Kod:
#include <avr/wdt.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 7 // Pin OneWire
#define TEMPERATURE_PRECISION 9

byte znak0[8] = { 0b01100, 0b10010, 0b10010, 0b01100, 0b00000, 0b00000, 0b00000, 0b00000 }; // znak Ę i °C
byte znak1[8] = { 0b11111, 0b10000, 0b10000, 0b11111, 0b10000, 0b10000, 0b11111, 0b00010 };

int przekaznikGaz = 9; // Włącza piec gazowy
int przekaznikPG = 10; // Załącza pompę obiegową pieca gazowego
int przekaznikPW = 11; // żałącza pompę pieca węglowego
int buzer = 12;        // włącza alarm gdy temperatury przekraczają niebezpieczne lub coś jest nie tak
int valG = 0;
int valW = 0;
//unsigned long aktualnyCzas = 0;
//unsigned long zapamietanyCzas = 0;

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress DS_NR1 = { 0x28, 0x32, 0xFD, 0x48, 0xF6, 0xA8, 0x3C, 0xF2 }; // Tu wpisać adresy czujników
DeviceAddress DS_NR2 = { 0x28, 0x6F, 0x82, 0x95, 0xF0, 0x01, 0x3C, 0x85 };

LiquidCrystal_I2C lcd(0x27,20,4); 
float tempW = 0;        // temperatura na piecu węglowym
float tempG = 0;        // temperatura na piecu gazowym
float hist = 1.5;        // aby przekaznik nie klikał
float tG = 31.5;
float tW = 31.5;
float histGaz = 15;
float tPG = 55;
void setup()
{
wdt_enable(WDTO_4S);

//  lcd.noBacklight();  //wyłącza podświetlenie
   
  sensors.begin();
  lcd.init();                   
  lcd.backlight();
  lcd.clear();
 
//przekaznikGaz jako wyjście
pinMode(przekaznikGaz, OUTPUT);      //przekaznik załączający piec gazowy
pinMode(przekaznikPG, OUTPUT);        // załączający pompe pieca gazowego
pinMode(przekaznikPW, OUTPUT);        // załączający pompe pieca węglowego
pinMode(buzer, OUTPUT);

digitalWrite(przekaznikGaz, HIGH);    //Włączenie pieca GAZ
digitalWrite(przekaznikPG, LOW);      // Włączenie cyrkulacji GAZ
digitalWrite(przekaznikPW, LOW);      // Włączenie cyrkulacj Węgiel
digitalWrite(buzer, LOW);            // ALARM!

  sensors.setResolution(DS_NR1, TEMPERATURE_PRECISION);
  sensors.setResolution(DS_NR2, TEMPERATURE_PRECISION);

}

void loop()
{
  //    lcd.clear();
// aktualnyCzas = millis();
  sensors.requestTemperatures();
  tempW = sensors.getTempC(DS_NR1);  // pobierz temperaturę po kolei z termometrów
  tempG = sensors.getTempC(DS_NR2);
// ===============================================================================

if(tempW> (tW+hist)) // temperatura większa od  xx włącz pompe pieca węglowego
{
  digitalWrite(przekaznikPW, HIGH);
// digitalWrite(przekaznikGaz, LOW);
}
  else if (tempW< (tW-hist))  // mniejsza od xx wyłącz pompe weglowego
  {
  digitalWrite(przekaznikPW, LOW);
// digitalWrite(przekaznikGaz, HIGH);
}

//====================================================

if((tempG>(tPG+histGaz)) || (tempW> 35))      // jeżeli temperatura pieca gazowego jest większa od np. 70 C to go wyłącz
{
  digitalWrite(przekaznikGaz, LOW);            // lub gdy piec weglowy grzeje wyłącz gazowy
}
else if (tempG<(tPG-histGaz))
{
digitalWrite(przekaznikGaz, HIGH);
}

//================================================

if(tempG> (tG+hist))                            // jeżeli temperatura pieca gazowego większa od np 30 włącz pompe pieca gazowego
{
  digitalWrite(przekaznikPG, HIGH);
}
else if (tempG< (tG-hist))
{
  digitalWrite(przekaznikPG, LOW);
}
//====================================================

if((tempG>80) || (tempW>85))                  // jeżeli temperatury przekroczą niebezpieczne włącz alarm i obie pompy i wyłącz piec gazowy
{
  digitalWrite(buzer, HIGH);
  digitalWrite(przekaznikPG, HIGH);
  digitalWrite(przekaznikPW, HIGH);
  digitalWrite(przekaznikGaz, LOW);
}
else if((tempG<50) || (tempW<60))
{
  digitalWrite(buzer, LOW);
}

//=======================================
// if (aktualnyCzas - zapamietanyCzas <= 5000UL) {
lcd.createChar(0, znak0);
lcd.createChar(1, znak1);
lcd.setCursor(0,0);
lcd.print("PIEC GAZOWY:  ");
//lcd.setCursor(10,0);
lcd.print(tempG,1);
lcd.print((char)0);
lcd.print("C");

// }
//======================================
// if (aktualnyCzas - zapamietanyCzas >= 10000UL) {
lcd.setCursor(0,1);
lcd.print("PIEC W");
lcd.print((char)1);
lcd.print("GLOWY: ");
//lcd.setCursor(10,1);
lcd.print(tempW,1);
lcd.print((char)0);
lcd.print("C");

//  zapamietanyCzas = aktualnyCzas;

// }
//=====================================
valG = digitalRead(przekaznikPG);
lcd.setCursor(0,2);
lcd.print("POMPA GAZOWY:  ");
if (valG > 0)
{
lcd.print("ON ");
}
else
{
lcd.print("OFF");
}

valW = digitalRead(przekaznikPW);
lcd.setCursor(0,3);
lcd.print("POMPA W");
lcd.print((char)1);
lcd.print("GLOWY: ");
if (valW > 0)
{
lcd.print("ON ");
}
else
{
lcd.print("OFF");
}
//=====================================
delay (3000);

wdt_reset();            // sprawdzone działa jak zapętle
}
//=================================


Załączone pliki
.zip   Nowy folder (2).zip (Rozmiar: 50.44 KB / Pobrań: 1)
 
Odpowiedź
#19
Jeszcze jakieś będą zmiany? bo na święta za to się wezmę i przerobie po swojemu jak umiem. A nie chciał bym poprawiać z powodu dużych zmian.
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#20
(12-04-2022, 18:22)Jarewa0606 napisał(a): Jeszcze jakieś będą zmiany? bo na święta za to się wezmę i przerobie po swojemu jak umiem. A nie chciał bym poprawiać z powodu dużych zmian.
Dziękuje za zainteresowanie. Zmian już nie będzie. Tylko zmieniłem LCD bo łatwiej mi było niż montować jakieś lampki kontrolne. Reszta została bez zmian.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości