• 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
Problem z sekundnikiem.
#1
Witam. 
Postanowiłem zrobić sobie taki projekcik jak zegarek z termometrem.
 Użyłem do tego projektu Arduino Nano, DS1307, DS18B20 oraz wyświetlacz Oled.
Problemem jest wskazanie sekund. A mianowicie czasem pokazuje sekunda po sekundzie, ale zazwyczaj pokazuje co drugą sekundę a wskazania sekund są nie metryczne. Czas wyświetlenia między zmianami nieraz trwa więcej niż sekundę a czasem ułamek sekundy. 
  Proszę o sprawdzenie kodu i wskazanie błędu. 

Kod PHP:
#include <Wire.h>
#include <DS1307.h>
#include <SPI.h> 
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
DS1307 clock;
RTCDateTime dt;
 
#define ONE_WIRE_BUS 11
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup()
{
 
 clock.begin();
 
 display.begin(SSD1306_SWITCHCAPVCC0x3C);
 
 display.clearDisplay();
 
 display.setTextSize(1);
 
 display.setTextColor(WHITE);
 
 display.setCursor(25,0);
 
 display.println("inicjalizacja");
 
 display.setTextSize(2);
 
 display.setTextColor(WHITE);
 
 display.setCursor(25,15);
 
 display.println("DS 1307"); 
 
 display.display();
 
 sensors.begin();
 
 
  if 
(!clock.isReady())
 
 {
 
   
    clock
.setDateTime(__DATE____TIME__);
 
   
  
}
 
 delay(2000);
}
 
void loop()
{
 
 dt clock.getDateTime();
 
 sensors.requestTemperatures();
 
 display.clearDisplay();
 
 display.setTextSize(1);
 
 display.setTextColor(WHITE);
 
 display.setCursor(0,0);
 
 display.print("TEMPERATURA =");
 
 display.setTextSize(1);
 
 display.setTextColor(WHITE);
 
 display.setCursor(84,0);
 
 display.print(sensors.getTempCByIndex(0));
 
 display.setTextSize(1);
 
 display.setTextColor(WHITE);
 
 display.setCursor(30,25);
 
 display.print(dt.day);
 
 display.print(" - ");
 
 display.print(dt.month);
 
 display.print(" - ");
 
 display.print(dt.year);
 
 display.setTextSize(2);
 
 display.setTextColor(WHITE);
 
 display.setCursor(20,9);
 
 display.print(dt.hour);
 
 display.print(":");
 
 display.print(dt.minute);
 
 display.print(":");
 
 display.print(dt.second);
 
 display.display();
 
 delay(1000);

 
Odpowiedź
#2
Sprawa jest bardzo prosta -> usuń delay(1000) .
Pomagam za darmo więc szanuj mój czas.
Wklejaj tekst a nie jego zdjęcie.
Nie pisz następnego postu jak nie odpowiedziałeś na poprzedni.
Jak mądrze zadawać pytania
 
Odpowiedź
#3
Ok. Pomogło z tym że nie jest to płynne odliczanie. Sporadycznie się przycina. Zauważyłem że te przycięcia są w momencie kiedy zmienia się wyświetlenie temperatury.
 
Odpowiedź
#4
1. Wysyłanie wszystkich informacji na wyświetlacz w każdym cyklu jest nieefektywne. Wysyłaj wartości które się zmieniają i to w momencie gdy nastąpi zmiana wartości.
2. Konwersja temperatury w czujniku trochę trwa(w zależności od rozdzielczości nawet 750ms). Wyślij "requestTemperatures", odczekaj odpowiedni czas, a potem odczytaj wartość. Wszystko to z użyciem millis aby nie blokować.
3. Odczyt wartości też robisz nieefektywnie bo używasz metody getTempCByIndex zamiast getTempC. Przy małej ilości urządzeń tego tak nie widać ale przy większej tak.
4. Generalnie to cała biblioteka jest trochę bez sensu bo przelicza na float. Jest to wygodne ale zajmuje dużo miejsca w pamięci i czasu.
Pomagam za darmo więc szanuj mój czas.
Wklejaj tekst a nie jego zdjęcie.
Nie pisz następnego postu jak nie odpowiedziałeś na poprzedni.
Jak mądrze zadawać pytania
 
Odpowiedź
#5
Witam,
A nie możesz sprawdzać czy konwersja temperatury jest kompletna i dopiero wtedy zmieniać temperaturę do wyświetlania? Jeśli nie jest kompletna to wyświetlać jedynie czas.
Pozdrawiam.
 
Odpowiedź
#6
Dzięki panowie za podpowiedzi. Starałem się poradzić sobie z tym problemem ale więcej namieszałem niż polepszyłem.
Jestem początkującym ale mam duży apetyt na wiedzę i wszelakie podpowiedz. ma takie pytanie. Jak wy poradzilibyście sobie z tym projektem. Chodzi mi o to jak byście napisali taki programik. Jestem ciekaw jak wyglądały by program napisany przez takich doświadczonych programistów.
 
Odpowiedź
#7
Witam ponownie. Po kilku dniach kombinacji wypociłem takowy kod
Kod:
#include <Wire.h>
#include <DS1307.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DS18B20.h>
#define OLED_RESET 4
byte address[8] = {0x28, 0x16, 0x5A, 0x1E, 0x7, 0x0, 0x0, 0x88};
Adafruit_SSD1306 display(OLED_RESET);
DS1307 clock;
RTCDateTime dt;
#define ONE_WIRE_BUS 11
OneWire oneWire(ONE_WIRE_BUS);
DS18B20 sensors(&oneWire);
void setup()
{
 clock.begin();
 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 display.clearDisplay();
 display.setTextSize(1);
 display.setTextColor(WHITE);
 display.setCursor(25,0);
 display.println("inicjalizacja");
 display.setTextSize(2);
 display.setTextColor(WHITE);
 display.setCursor(25,15);
 display.println("DS 1307");
 display.display();
 sensors.begin(11);
 sensors.request(address);
 // Jeśli nie ustawiono daty, ustawiamy
 if (!clock.isReady())
 {
   // Data i czas z momentu kompilacji
   clock.setDateTime(__DATE__, __TIME__);
   
 }
 delay(2000);
}

void loop()
{
   if (sensors.available())
 {
   float temperature = sensors.readTemperature(address);
 sensors.request(address);
 }
 dt = clock.getDateTime();
 display.clearDisplay();
 display.setTextSize(1);
 display.setTextColor(WHITE);
 display.setCursor(0,0);
 display.print("TEMPERATURA =");
 display.setTextSize(1);
 display.setTextColor(WHITE);
 display.setCursor(84,0);
 display.print(sensors.readTemperature(address));
 display.setTextSize(1);
 display.setTextColor(WHITE);
 display.setCursor(25,25);
 display.print(dt.day);
 display.print(" - ");
 display.print(dt.month);
 display.print(" - ");
 display.print(dt.year);
 display.setTextSize(2);
 display.setTextColor(WHITE);
 display.setCursor(20,9);
 display.print(dt.hour);
 display.print(":");
 display.print(dt.minute);
 display.print(":");
 display.print(dt.second);
 display.display();
}


Raczej działa ale wolałbym żeby ktoś go sprawdził czy oby na pewno jest ok.
 
Odpowiedź
#8
Witam,
Trzy poprawki:
- zmienną temperature zadeklaruj jako globalną, tj. przed blokiem setup() float temperature; Nie zapomnij wyciąć float przed temperature wewnątrz loop()!

- zamiast: display.print(sensors.readTemperature(address));
ma być: display.print(temperature);

- usuń zbędne, powtarzające się: display.setTextSize(1);
display.setTextColor(WHITE);
bo po co powtarzasz te instrukcje skoro nie zmieniasz koloru i rozmiaru czcionki (oczywiście dla godzin, minut i sekund zostaw .....setTextSize(2); ).

Pozdrawiam.
 
Odpowiedź
#9
(20-03-2017, 15:04)Smaczek napisał(a): Witam,
Trzy poprawki:
- zmienną temperature zadeklaruj jako globalną, tj. przed blokiem setup()   float temperature;  Nie zapomnij wyciąć float przed temperature wewnątrz loop()!

- zamiast: display.print(sensors.readTemperature(address));
ma być: display.print(temperature);

- usuń zbędne, powtarzające się:    display.setTextSize(1);
                                                                     display.setTextColor(WHITE);
bo po co powtarzasz te instrukcje skoro nie zmieniasz koloru i rozmiaru czcionki (oczywiście dla godzin, minut i sekund zostaw .....setTextSize(2);  ).

Pozdrawiam.

Czy o to chodziło???
Kod:
#include <Wire.h>
#include <DS1307.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DS18B20.h>
#define OLED_RESET 4
#define ONE_WIRE_BUS 11
byte address[8] = {0x28, 0x16, 0x5A, 0x1E, 0x7, 0x0, 0x0, 0x88};
float temperature;
Adafruit_SSD1306 display(OLED_RESET);
DS1307 clock;
RTCDateTime dt;
OneWire oneWire(ONE_WIRE_BUS);
DS18B20 sensors(&oneWire);
void setup()
{
 clock.begin();
 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 display.clearDisplay();
 display.setTextSize(1);
 display.setTextColor(WHITE);
 display.setCursor(25,0);
 display.println("inicjalizacja");
 display.setTextSize(2);
 display.setTextColor(WHITE);
 display.setCursor(25,15);
 display.println("DS 1307");
 display.display();
 sensors.begin(12);
 sensors.request(address);
 if (!clock.isReady())
 {
   clock.setDateTime(__DATE__, __TIME__);
 }
 delay(3000);
}

void loop()
{
   if (sensors.available())
 {
 temperature = sensors.readTemperature(address);
 sensors.request(address);
 }
 dt = clock.getDateTime();
 display.clearDisplay();
 display.setTextSize(1);
 display.setTextColor(WHITE);
 display.setCursor(0,0);
 display.print("TEMPERATURA =");
 display.setCursor(84,0);
 display.print(temperature);
 display.setCursor(25,25);
 display.print(dt.day);
 display.print(" - ");
 display.print(dt.month);
 display.print(" - ");
 display.print(dt.year);
 display.setTextSize(2);
 display.setCursor(20,9);
 display.print(dt.hour);
 display.print(":");
 display.print(dt.minute);
 display.print(":");
 display.print(dt.second);
 display.display();
}
 
Odpowiedź
#10
Witam,
Tak, ale jeszcze display.setTextColor(WHITE); dubluje się Tobie w setup().
Pozdrawiam.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości