• 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
Temperatura + enkoder + oled
#1
Witam.

Mam problem z programem jeżeli chodzi o czasy odświeżania temperatury i odczyty enkodera. 
Problem polega na tym, że jeżeli odczytuje temperature i wyświetlam ja na oled to enkoder działa z opóźnieniem odczytu temperatury. 
I kolejna kwestia jak zaokrąglić odczyt temp. do liczb całkowitych, narazie robię to na zmiennej ale wolał bym użyć innego rozwiązania.
Podzespoły:
-Arduino Nano
-Oled 1306
-czujnik temp. DS18B20
-enkoder KY-040 z rezystorami podciagajacymi
Kod:
#define PinA 2 ///pin A enkodera
#define PinB 3 ///pin B enkodera
#define przycisk 4 /// przycisk enkodera
#define OLED_ADDR   0x3C // adres wyswietlacza
#define ILOSC_KROKOW 32 //ilosc krokow silnika
#define predkosc 100///Predkosc silnika krokowego
#define ilosc_krokow 200 ///ilosc krokow jednego kieliszka
#define ONE_WIRE_BUS 5 ///pin sondy
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Stepper.h> //biblioteka silnikow krokowych
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
Adafruit_SSD1306 display(128, 64); //rozdzielczosc  wyswietlacza
Stepper krokowiec(ILOSC_KROKOW, 8, 9, 10, 11); //piny do sterowania krokowcem


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




unsigned long time = 0;
long ilosc_impulsow = 1;
int licznik = 0;
int val;
int valA;

byte menuCount = 1;
byte dir = 0;
bool runState = false;
unsigned long czas = 0; //czas arduino
unsigned long temp = 0;


void setup()
{
czas = millis();
sensors.begin();
pinMode (4, INPUT_PULLUP);
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
Serial.begin(9600);
pinMode(PinA,INPUT); //pin A enkodera wejscie
pinMode(PinB,INPUT); //pin b enkodera wejscie
pinMode(przycisk,INPUT_PULLUP); //wejscie przycisku z podciagnieciem

attachInterrupt(0, blinkA, LOW);
attachInterrupt(1, blinkB, LOW);
time = millis();
display.clearDisplay();
display.display();
}


void loop()
{
  int temperatura = (sensors.getTempCByIndex(0));
  sensors.requestTemperatures(); //pobranie temp
  Serial.println(sensors.getTempCByIndex(0));
  Serial.println(temperatura);

  while (licznik != ilosc_impulsow)
{
licznik = ilosc_impulsow;
Serial.println(licznik);
}
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);

  display.setCursor(15, 0);
  display.println("PIJEMY ?");
  //---------------------------------
  display.setTextSize(5);
  display.setCursor(50, 30);
  display.println(licznik);
  display.display();
  /////////////temperatura
     display.setTextColor(WHITE);
     display.setTextSize(2);
     display.setCursor(5,50);
     display.print (temperatura);
     display.setTextSize(1);
     display.print("*");
     display.setTextSize(2);
     display.print("C");
     display.display();


///odczyt licznika i polanie
if (digitalRead (przycisk)== LOW){
  for (val = 0; val < licznik; val++) { //odczyt zmiennej licznika i powtorzenie x razy
     display.clearDisplay();
     display.setTextSize(2);
     display.setCursor(10, 25);
     display.println("POLEWANIE");
     //display.display();
     krokowiec.setSpeed(predkosc);
     krokowiec.step(ilosc_krokow);
     }
  }
  }
void blinkA()
{
if ((millis() - time) > 10)
ilosc_impulsow--;
    if (ilosc_impulsow<1)ilosc_impulsow=1;
time = millis();

}

void blinkB()
{
if ((millis() - time) > 10)
ilosc_impulsow++ ;
     if (ilosc_impulsow>12)ilosc_impulsow=12;
time = millis();
}

Pozdrawiam Smile
 
Odpowiedź
#2
(21-05-2020, 20:22)mateuszfcg napisał(a): Problem polega na tym, że jeżeli odczytuje temperature i wyświetlam ja na oled to enkoder działa z opóźnieniem 

Bo czujniki Wire odczyt jest blokujący... Wiec na czas odczytu wszystko staje a to trochę trwa...
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#3
Próbowałem wrzucić to do if milis ale wtedy nie odczytuje temperatury. Jest na to jakiś "patent" albo chociaż zmniejszyć czas odczytu
 
Odpowiedź
#4
Zmniejsz rozdzielczość odczytu .. Powinno przyspieszyć, tym bardziej ze raczej nie potrzebujesz takich dokładnych wyników..

Standardowo jest chyba 12bitów dokładność 0.06stC- 750ms a minimum 9bitów dokładność 0.5stC-94ms to spora różnica...

Jesli bedzie za wolno to trzeba pomyśleć o zmianie czujnika....
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#5
Dzięki za pomoc. Jest lepiej także temat do zamknięcia Smile
 
Odpowiedź
#6
Nie trzeba rezygnować z rozdzielczości by zejść z blokowaniem loop do 20ms, po prostu trzeba wyłączyć czekanie na zakończenie pomiaru, a odczyt pomiaru wykonać nie wcześniej niż po 750ms od zlecenia. W zaokrągleniu można to zrobić co 1 w odwrotnej kolejności, odczyt i zlecenie następnego pomiaru, powtórzyć za 1s, lub odczytać w parzystych a pytać w nieparzystych:
Kod:
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);


uint32_t czasTeraz,czasPoprzedni,tik=10, czas1,czas2,czas3,czas4,roznica,maximum,srednia;
uint8_t n10,fn10,sekundy,minuty,godziny,dni,nic;

bool fsekundy,fminuty,fgodziny,fdni;
void setup() {
//  sysClock(INT_OSC32);
  // put your setup code here, to run once:
Serial.begin(115200);
  sensors.begin();
sensors.setWaitForConversion(0);
}

void loop() {
  czas();
  // put your main code here, to run repeatedly:
if(fsekundy)
{
  if(sekundy%2==0)
  {
     sensors.requestTemperatures(); // Send the command to get temperatures
     delay(10);
     float odczyt=sensors.getTempCByIndex(0);
     Serial.print("Odczyt temperatury zaraz po zleceniu konwersji: ");
     Serial.println(odczyt);
  }
  else
  {
     float odczyt=sensors.getTempCByIndex(0);
     Serial.print("Odczyt temperatury w innej sekundzie: ");
     Serial.println(odczyt);
  }
}


}


void czas()
{
  czasTeraz=millis();
fn10=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik)
{
  czasPoprzedni=czasTeraz;
  fn10=1;
  n10++;
  if(n10>=100)
  {
    n10=0;
    sekundy++;
    fsekundy=1;
     if (sekundy>=60)
    {
      sekundy=0;
      minuty++;
      fminuty=1;
      if (minuty>=60)
      {
        minuty=0;
        godziny++;
        fgodziny=1;
        if (godziny>=24)
        {
          godziny=0;
          fdni=1;
          dni++;
   
        }
      }
    }
  }
}
}
No ale trzeba jakoś liczyć upływający czas.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości