Arduino Polska Forum

Pełna wersja: Temperatura + enkoder + oled
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
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
(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...
Próbowałem wrzucić to do if milis ale wtedy nie odczytuje temperatury. Jest na to jakiś "patent" albo chociaż zmniejszyć czas odczytu
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....
Dzięki za pomoc. Jest lepiej także temat do zamknięcia Smile
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.