• 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
U8glib i termometr ds18b20
#1
Witam serdecznie,
zamarzył mi się termometr na płytce nano.
Chciałbym to wszystko upakować w małą obudowę, wyświetlić na OLED 0,96 SD1306 (mono) i zasilić baterią 9V.
..niestety mam problem z kodem... i chyba z zasileniem, a raczej wytrzymałością baterii - ale o tym na końcu.

Zależy mi na fajnej czcionce i ramce wokół wyświetlacza lecz poniższy kod mi nie działa - nie umiem zmusić programu do współpracy biblioteki u8glib z ds18b20. Jeśli to możliwe, swoją drogą, chciałbym aby była rozdzielczość 12 bit ale wyświetlenie w formacie np: 33.3).

Znajdzie się jakaś pomocna dłoń i poprawi poniższy kod ? (nie zdziwię się jak trzeba by od nowa napisać :/ )  

Kod:
#include <SPI.h>
#include <Wire.h>
#include <OneWire.h>
#include <DS18B20.h>
#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);

const byte ONEWIRE_PIN = 2;
byte sensorAddress[8] = {0x28, 0x1E, 0x17, 0xEA, 0x5, 0x0, 0x0, 0x1C};

OneWire onewire(ONEWIRE_PIN);
DS18B20 sensors(&onewire);

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

void draw(void) {

u8g.setFont(u8g_font_fur35n);
u8g.drawStr( 4, 40, "36.6");
u8g.setFont(u8g_font_fur11);
u8g.drawStr( 10, 59, "Stopni Celsjusa");
u8g.drawFrame(0,0,128,64);


void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0X3C);
sensors.begin();

}

void loop() {
delay(50);
sensors.request(sensorAddress);
while(!sensors.available());
float temperature = sensors.readTemperature(sensorAddress);

}

Co do zasilania testowałem już prosty program i niestety świeża bateria Duracel 9V padła po 22 godzinach Sad Czy to normalne ?
edit:
Próbowałem jeszcze takich wypocin (jakimś cudem się kompiluje ale nie działa):
Kod:
#include <SPI.h>
#include <Wire.h>
#include <OneWire.h>
#include <Adafruit_SSD1306.h>
#include <DS18B20.h>
#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);

const byte ONEWIRE_PIN = 2;
byte sensorAddress[8] = {0x28, 0x1E, 0x17, 0xEA, 0x5, 0x0, 0x0, 0x1C};

OneWire onewire(ONEWIRE_PIN);
DS18B20 sensors(&onewire);

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);


void draw(void) {


 u8g.setFont(u8g_font_fur11);
 u8g.drawStr( 10, 59, "Stopni Celsjusa");
 u8g.drawFrame(0, 0, 128, 64);
}

void setup(void) {
 display.begin(SSD1306_SWITCHCAPVCC, 0X3C);
 sensors.begin();
 u8g.begin();

}

void loop(void) {
 delay(50);
 sensors.request(sensorAddress);
 while (!sensors.available());
 float temperature = sensors.readTemperature(sensorAddress);
 u8g.setFont(u8g_font_fur35n);
 display.setCursor(4, 40);
 u8g.print(temperature);
}


Z góry dziękuję za pomoc !
Pzdr.
 
Odpowiedź
#2
Wyświetlacz potrzebuje do 20mA, w nano to procek 15mA + 20mA CH340 (USB)+coś ledy. Jak typowa bateria 9V ma 600mAh to wystarczy zsumować zużycie, podzielić i wychodzi z 11h pracy, może Twoja bateria jest lepsza, może ekran nie zjada tylko bo to zależy ile jest aktywnych pixeli średnio w czasie, a 20mA jest pewnie max dla całego białego.
Z Arduino do zasilania z baterii najlepszy jest PRO MINI, nie ma konwertera UART, a sam procek można usypiać. Za to kłopotliwy przy programowaniu. Do tego zasilanie z 3 aku AA 2000mA i odpada również strata dopasowania napięcia (z 9V baterii tracisz prawie połowę pojemności na stabilizatorze liniowym). 8MHz Pro mini można bujać z 3V, tak samo ekran OLED i DS. Ewentualnie zamiast 3xAA to można wziąć 1 ogniowo laptopowe 4.2V. Bez usypiania czas pracy takiego ProMini około 100h na AA lub LiPo. Można też usypiać, naciskasz przycisk, budzi się, 1s na pomiar, 3s na wyświetlenie i spanie. Wtedy może działać latami (trzeba tylko usunąć LED SMD z płytki, bo jego 1mA to największe zużycie podczas uśpienia) - jak często ktoś będzie wybudzał, tak szybko padnie aku. Przy automatycznym wyświetlaniu co np. 10min. przez 5s mamy działania ponad rok.
Na początek proponuję  koszyk na 3-4 AA, ładowarkę chyba ma każdy, bo zajeździsz kosztowo ten projekt.
Co Ci działa, a co nie działa w kodzie? Na monitor portu umiesz wyslac temperaturę?
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#3
Dzięki za odpowiedź - faktycznie muszę pomyśleć nad innym źródłem zasilenia.
Co do kodu to nie wiem co nie działa - "słyszę że gdzieś dzwoni tylko nie wiem gdzie Sad "

Na monitor umiem wysłać, tak samo i na lcd np: 16x2 lub nawet na ten oled (kod poniżej)
Kod:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DS18B20.h>


const byte ONEWIRE_PIN = 2;
byte sensorAddress[8] = {0x28, 0x1E, 0x17, 0xEA, 0x5, 0x0, 0x0, 0x1C};

OneWire onewire(ONEWIRE_PIN);
DS18B20 sensors(&onewire);

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);


void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0X3C);
sensors.begin();

}

void loop() {
delay(50);
sensors.request(sensorAddress);
while(!sensors.available());
float temperature = sensors.readTemperature(sensorAddress);

display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(17,55);
display.println("Stopni Celsjusza");
display.setTextSize(3);
display.setCursor(22,10);
display.println(temperature);

display.display();

}
Jak widzisz powyżej tutaj wykorzystuje biblioteke adafruit.

Mi zależy aby wykorzystać do wyświetlenia temp (pobrania jakby danych z czujnika) biblioteke u8glib w takim ustawieniu (czcionka i ramka wokół wyświetlacza) jak poniżej w rozdzielczości 12 bit ale z jednym miejscem po przecinku.


Kod:
void draw(void) {

u8g.setFont(u8g_font_fur35n);
u8g.drawStr( 4, 40, "36.6"); // tutaj przyklad jak ma wyświetlać się na oled
u8g.setFont(u8g_font_fur11);
u8g.drawStr( 10, 59, "Stopni Celsjusa");
u8g.drawFrame(0,0,128,64);
}

Reasumując czuję się jak głąb bo potykam się o chyba bardzo prosty kod Sad
 
Odpowiedź
#4
Ciężko mi dojść o co Ci chodzi, czy tylko o to 1 miejsce, czy nie wyświetla nic na ekranie, czy przykład "36.6" wyświetla się prawidłowo? Nie mam tych bibliotek i nie sprawdzę u siebie jak to działa.
Jeżeli jedynym problemem jest obcięcie liczby z setek to po prostu chodzi o to, że typowo funkcje typu print/draw czy jak tam nazwane wysyłają string/tablice znaków. Niektóre w locie konwertują zmienne liczbowe na stringi/znaki.  W przypadku typu float/double jest to domyślnie z dwoma miejscami po przecinku. Można zrobić tak: Serial.println(zmienna), albo Serial.println(zmienna,x). To co wstawisz w x będzie liczbą miejsc po przecinku przy konwersji na napis.  Można też (a czasami trzeba) samemu sobie przygotować stringa do wysłania, ta funkcja u8g.drawStr wygląda jak dedykowana tylko do napisu (Str), może nie ma  takiej konwersji z liczb "w locie".  
Kod:
String napis="";
napis= String(zmiennatemp,1); //i tak po każdym odczycie temperatury przed wysłaniem na ekran,
// można dodać spacje by czyściło znaki wiodące przy spadku temperatury poniżej 10
// lub przy wzroście temperatury powyżej 0
//trzeba sprawdzić czy dobrze zaokrągla, czy np. tylko ucina 45,19->45,1 to lipa raczej
u8g.drawStr( 4, 40, napis);
Jak funkcja nie obsługuje zmiennych String, a tylko tablice char to trzeba skorzystać z funkcji typu itoa(int) lub ftoa(float) zamieniających zmienne liczbowe do tablicy char.
Jeśli funkcja obsługuje float to zwykle po zmiennej dodaje się przecinek i podaje liczbę miejsc po przecinku. Może też być osobna funkcja wypisująca string i osobne do różnych zmiennych liczbowych - trzeba zobaczyć co biblioteka oferuje.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości