Novinky: Pridal som novú sekciu na webe - Turistika
Sitepoint logo

OLED teplomer s DS18B20 ovládaný ATTINY85

S kolegami sa chodievame od neskorého leta do jari otužovať a chcel som vedieť aká je tá voda vlastne teplá, teda skôr aká je studená. Doma som použil už viac krát presné Maximácke 1-wire teplomery DS18B20, takže voľba snímača bola jasná. Medzi hračkami sa povaľoval aj lacný OLED displej z ebay-u (ešte lacnejší…),ktorý má I2C rozhranie a radič SSD1306. Celé je to tak jednoduché, že by bol hriech nevyužiť maličký 8-pinový ATTINY85 (8kB FLASH, 2kB SRAM), ktorý kúpite aj u nás za 2 eurá, žiaľ v SMD prevedení jedine cez net.

8kB na program nie je veľa, preto som použil len dve knižnice – TinyWireM a OneWire. Zapojenie je úplne jednoduché, dá sa použiť aj univerzálny plošný spoj, fantázii sa medze nekladú.tinyOLEDthermo tinyOLEDthermo-pcb

Tu je celý kód (na stiahnutie ZIP), vysvetlenie a návod pod ním + návod ako program nahrať do mikroprocesoru.

#include <TinyWireM.h>
#include <OneWire.h>
#include "font6x8.h"
#include "font8X16.h"

#define SSD1306_SA  0x3C   // adresa OLED displeja

OneWire ds(4);  // HW PIN 3
byte adrT1[8] = {0x28, 0x4B, 0x6F, 0x88, 0x04, 0x00, 0x00, 0xB6};  //unikatny identifikator/adresa snimaca

void setup(){
  TinyWireM.begin();
  ds.reset_search();
  ssd1306_init();
  ssd1306_fillscreen(0x00);
  ssd1306_char_f6x8(0, 0, "Aktualna teplota");
}

void loop() {
  byte data[12];
  char cc1[20];

  ds.reset();
  ds.select(adrT1);
  ds.write(0x44, 1);     // zacni meranie teploty
  delay(1000);           // aspon 750ms, radsej viac, neponahlame sa

  ds.reset();
  ds.select(adrT1);    
  ds.write(0xBE);        // precitaj scratchpad

  for (byte i = 0; i < 9; i++) data[i] = ds.read();
  float celsius = ((data[1] << 8) + data[0]) * 0.0625;
  dtostrf(celsius,5,2,cc1);         //skonvertuj double na char*

  ssd1306_char_f8x16(0, 2, cc1);    //vypis teplotu
  ssd1306_char_f8x16(45, 2, "`C");  //a symbol stupnov
  delay(500);
}

// ----------------------------------------------------------------------------

void ssd1306_init(void){
  byte cmds[] = {0xAE, 0xA8, 0x3F, 0xD3, 0x00, 0xB0, 0x00, 0x10, 0x20, 0x00, 0x40, 0x81, 0xCF,
  0xA1, 0xC8, 0xA6, 0xD5, 0x80, 0xD9, 0xF1, 0xDA, 0x12, 0xDB, 0x30, 0x2E, 0x8D, 0x14, 0xAF};
  for(byte i = 0; i < sizeof(cmds); i++) ssd1306_send_command(cmds[i]);
}

void ssd1306_send_command(uint8_t command){
  TinyWireM.beginTransmission(SSD1306_SA);
  TinyWireM.send(0x80);
  TinyWireM.send(command);
  TinyWireM.endTransmission();
}

void ssd1306_send_data(uint8_t data){
  TinyWireM.beginTransmission(SSD1306_SA);
  TinyWireM.send(0x40);
  TinyWireM.send(data);
  TinyWireM.endTransmission();
}

void ssd1306_setpos(uint8_t x, uint8_t y){
  TinyWireM.beginTransmission(SSD1306_SA);
  TinyWireM.send(0x00);
  TinyWireM.send(0xb0+y);
  TinyWireM.send(((x&0xf0)>>4)|0x10);
  TinyWireM.send((x&0x0f)|0x01);
  TinyWireM.endTransmission();
}

void ssd1306_fillscreen(uint8_t fill_Data){
  uint8_t m,n;
  for(m=0;m<8;m++){
    ssd1306_send_command(0xb0+m);    //page0-page1
    ssd1306_send_command(0x00);        //low column start address
    ssd1306_send_command(0x10);        //high column start address
    for(n=0;n<128;n++) ssd1306_send_data(fill_Data);
  }
}

void ssd1306_char_f6x8(uint8_t x, uint8_t y, const char ch[]){
  uint8_t c,i,j=0;
  while(ch[j] != '\0'){
    c = ch[j] - 32;
    if(x>126){
      x=0;
      y++;
    }
    ssd1306_setpos(x,y);
    for(i=0;i<6;i++) ssd1306_send_data(pgm_read_byte(&ssd1306xled_font6x8[c*6+i]));
    x += 6;
    j++;
  }
}

void ssd1306_char_f8x16(uint8_t x, uint8_t y,const char ch[]){
  uint8_t c=0,i=0,j=0;
  while (ch[j]!='\0'){
    c = ch[j] - 32;
    if (x>120){
      x=0;
      y++;
    }
    ssd1306_setpos(x,y);
    for(i=0;i<8;i++) ssd1306_send_data(pgm_read_byte(&ssd1306xled_font8X16[c*16+i]));
    ssd1306_setpos(x,y+1);
    for(i=0;i<8;i++) ssd1306_send_data(pgm_read_byte(&ssd1306xled_font8X16[c*16+i+8]));
    x+=8;
    j++;
  }
}

Fonty a grafické funkcie som trochu upravil (zdroj) pre moje potreby a samotný kód v hlavnej slučke loop je taký jednoduchý, že hádam stačia len komentáre v kóde. Skompilovaný kód má necelých 7kB, ale dal by sa ešte trochu osekať, hlavne ak by sa použil len jeden font, prípadne fonty uložiť do externej I2C EEPROM – ale nebolo treba. Na krabičku by sa zišla 3D tlačiareň – ale bude musieť stačiť krabička od Tic-Tac 🙂 No a napájane zabezpečí aj CR2032 3V batéria, odber cca 6mA.

oledtiny1 oledtiny2


Categories:


Comments

9 odpovedí na na “OLED teplomer s DS18B20 ovládaný ATTINY85”

  1. jarkko Avatar
    jarkko

    program nedokážem skompilovať prečo…_?

    This report would have more information with
    „Show verbose output during compilation“
    enabled in File > Preferences.
    Arduino: 1.0.6 (Windows 7), Board: „ATtiny85 (internal 8 MHz clock)“
    c:/program files/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr25/crttn85.o: In function `__vector_default‘:

    (.vectors+0xa): relocation truncated to fit: R_AVR_13_PCREL against symbol `__vector_5′ defined in .text.__vector_5 section in core.a(wiring.c.o)

    c:/program files/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr25/crttn85.o:(.init9+0x2): relocation truncated to fit: R_AVR_13_PCREL against symbol `exit‘ defined in .fini9 section in c:/program files/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/avr25\libgcc.a(_exit.o)

    core.a(main.cpp.o): In function `main‘:

    C:\Program Files\Arduino\hardware\arduino\cores\arduino/main.cpp:44: relocation truncated to fit: R_AVR_13_PCREL against undefined symbol `serialEventRun()‘

    1. tomXX Avatar

      Akú verizu Arduino IDE používaš? Ja relatívne starú 1.0.1 . Skús si stiahnuť takú a vyskúšaj v nej.

      1. jarkko Avatar
        jarkko

        vyskúšal som aj vo verzií 1.0.1.
        s rovnakým výsledkom dá sa povedať aj s rovnakým poruchovým hlásením
        prosím Ťa kde mám uložiť fonty…(#include „font6x8.h“
        #include „font8X16.h“)
        – napr. -sketch“ Tiny85 Temp“ skompilujem bez problemov aj v ATTIN-e mi to funguje! Tento tvoj projekt
        sa mi veľmi páči chcel by som to rozbehať no neviem…

        1. tomXX Avatar

          Fonty sú v adresári kde je INO súbor s programom. Všetko si urobil ako bolo v návode? http://blog.sitepoint.sk/2014/11/22/programujeme-attiny-pomocou-arduina/

          1. jarkko Avatar
            jarkko

            všetko možné aj nemožné som vyskúšal a rovnaký výsledok
            pravdepodobne je chyba v samotnom Arduino IDE…
            ako som už spomínal iné programy pre attiny bez problémou skompilujem aj v samotnej ATTIN-e85 fungujú!
            akurát tento pekný projekt mi robí problémy…
            nemôžeš priložiť hex- programu ?

  2. tomXX Avatar

    Neuveríš, ale zrazu to začalo aj mne hádzať tú istú chybu 😀 Ale našiel som opravu a funguje – https://github.com/TCWORLD/ATTinyCore/tree/master/PCREL%20Patch%20for%20GCC

    1. jarkko Avatar
      jarkko

      yes..yes..yes Všetko funguje!!!Mám to odskúšané na IDE 1.0.6. verzií arduina.
      Tak teraz to treba už len upraviť na vlastné potreby atď…Veľké ĎAKUJEM
      patrí autorovi článku, ktorý to dotiahol až do konca
      Teším sa na tvoje nové projekty

      1. tomXX Avatar

        No super, to som rád.

        Roboty veľa, na tieto veci nemám moc času, myslel som že to bude lepšie.

  3. nick Avatar

    very nice project

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *