Temperatura + enkoder + oled - mateuszfcg - 21-05-2020
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
RE: Temperatura + enkoder + oled - Jarewa0606 - 21-05-2020
(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...
RE: Temperatura + enkoder + oled - mateuszfcg - 21-05-2020
Próbowałem wrzucić to do if milis ale wtedy nie odczytuje temperatury. Jest na to jakiś "patent" albo chociaż zmniejszyć czas odczytu
RE: Temperatura + enkoder + oled - Jarewa0606 - 21-05-2020
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....
RE: Temperatura + enkoder + oled - mateuszfcg - 22-05-2020
Dzięki za pomoc. Jest lepiej także temat do zamknięcia
RE: Temperatura + enkoder + oled - kaczakat - 23-05-2020
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.
|