Arduino Polska Forum

Pełna wersja: Duży TicTac - stacja pomiarów parametrów środowiskowych
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Cześć. Jak by kogoś zainteresowało co można zrobić z opakowania po dużych tictac'ach to zapraszam do lektury:

Potrzeba:
Chciałem coś co poda mi temperaturę, wilgotność, ciśnienie atmosferyczne w sposób czytelny.
Żeby to było przenośne z własną baterią.
Dodatkowo czas niech podaje.

Podzespoły.
W czeluściach mojego pudełka z modułami elektronicznymi znalazłem
NodeMCU v3 na ESP8266
czujnik powyższych danych BME280
moduł ładowania TP4056
wyświetlacz 0,96" 
ogniwo li-pol 3,7V 200mAh (zakupiłem je specjalnie ze względu na idealny wymiar do tego projektu).

Wykorzystane gotowe biblioteki:

wifi menager
adafruit do wyświetlacza, do BME280
NTP

WiFi menager swoją szybkością połączenia zadziwia. Od momentu startu do wyświetlenia informacji (w tym aktualizacji czasu NTP i odczytu danych z BME280 mija około 3 sekundy).

Sekwencja wygląda tak:
Start (ekran powitalny) około 3s.
Wyświetlenie czasu (godziny i minuty), wyświetlenie zmierzonych parametrów około 10s
głębokie uśpienie
oczekiwanie na ręczny reset
i od poczatku

Do resetu używany jest przycisk wbudowany w płytkę. 
A jako opakowanie na to wszystko użyłem pustego opakowania po TicTac. W nie przezroczystej części na gorący klej przykleiłem moduł ładowania ogniwa tak by go naładować otwiera się klapkę jak w zwykłych TicTac'ach i podłącza microUSB ładowarkę.

Ogniwo ma 20mm szerokości i na wcisk wchodzi z boku co ułatwia ułożenie.
Wykorzystałem grubość elementów i miękkość materiału by nie trzeba było niczym płytki mocować. jest ona na wcisk i trzyma się dodatkowo zaparta płytką ładowarki. 

NodeMCU ma to do siebie, że ma fizyczny przycisku resetu dla mnie idealnie umiejscowiony z tyłu.  To wystarczy do restartu bez dodatkowych urządzeń.
Poniżej kod oprogramowania:
Kod:
#include <Adafruit_BME280.h>
#include <NtpClientLib.h>
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>         // https://github.com/tzapu/WiFiManager
#include <Adafruit_SSD1306.h>
//Definicje wyswietlacza
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//deklaracje bmw280
Adafruit_BME280 bme;
float temperature, humidity, pressure, altitude;
int8_t timeZone = 1;
int8_t minutesTimeZone = 0;
char tabelaczasu[20];
String czas;
// Set web server port number to 80
WiFiServer server(80);

void odczyt_BME280() {
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  pressure = bme.readPressure() / 100.0F;
}
NTPSyncEvent_t ntpEvent;
boolean syncEventTriggered = false;
void processSyncEvent (NTPSyncEvent_t ntpEvent) {
    if (ntpEvent) {
        Serial.print ("Time Sync error: ");
        if (ntpEvent == noResponse)
            Serial.println ("NTP server not reachable");
        else if (ntpEvent == invalidAddress)
            Serial.println ("Invalid NTP server address");
    } else {
        Serial.print ("Got NTP time: ");
        Serial.println (NTP.getTimeDateString (NTP.getLastNTPSync ()));
    }
}
void setup() {
  Serial.begin(115200);
  // adresacja czujnika bme280
  bme.begin(0x76);
  //uruchomienie wyswietlacza
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  Serial.println(F("SSD1306 allocation failed"));
  for(;;);
  }
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Czekaj...");
  display.setCursor(0, 16);
  display.print("  odczyt    BME280     NTP");
  display.display();
 
  // NTP
  NTP.onNTPSyncEvent ([](NTPSyncEvent_t event) {
       ntpEvent = event;
       syncEventTriggered = true;
    });

 
  // WiFiManager
  // Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
 
  // Aby usunac dane wifi odkomentuj ponizsza linijke
  //wifiManager.resetSettings();

  //W razie nie znalezienia sieci uruchomi sie AP o ponizszej nazwie. Sluzy to skonfigurowaniu polaczenia wifi. 
  wifiManager.autoConnect("AutoConnectAP");
  // if you get here you have connected to the WiFi
  Serial.println("Polaczono do WiFi");
 
  server.begin();
  //konfiguracja i pobieranie danych z serwera NTP
  NTP.begin ("pool.ntp.org", timeZone, true, minutesTimeZone);
  NTP.setInterval (3600);
  Serial.println (NTP.getTimeDateString ());
 
   

//Konwersja czasu do tabeli znakow
czas = (NTP.getTimeDateString ());
czas.toCharArray(tabelaczasu, 20);
tabelaczasu [20] = '\0';
   
}


void loop(){

  static int i = 0;
  static int last = 0;
  static int last2 = 0;
 
  WiFiClient client = server.available();   // Listen for incoming clients
  //petla wykonywana co 1 sekunde
  if ((millis () - last) > 1000) {
        last = millis ();
        //odczyt danych z czujnika
        odczyt_BME280();
        //wyswietlenie danych w konsoli
        Serial.println(NTP.getTimeDateString ());
        Serial.print("Temperatura: ");Serial.print(temperature,1);Serial.print(" "); Serial.println("*C");
        Serial.print("Wilgotnosc: ");Serial.print(humidity,0);Serial.print(" % ");
        Serial.print("Cisnienie: ");Serial.print(pressure,0);Serial.println(" hPa ");
        //wyswietlenie danych na wyswietlaczu
        display.clearDisplay();
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(0, 0);
        display.print(tabelaczasu [0]); display.print(tabelaczasu [1]);display.print(":");display.print(tabelaczasu [3]); display.print(tabelaczasu [4]);
        display.setCursor(0, 16);// Display static text
        display.print("T: "); display.print(temperature,1); display.println(" *C");
        display.print("Wi: "); display.print(humidity,0); display.println(" %");
        display.print("Ci:"); display.print(pressure,0); display.println(" hP");
        display.display();
            }
// uspienie po okolo 9-10 sekuundach wyswietlania           
  if ((millis () - last2) > 12000) {
        //Serial.println(millis() - last);
        last2 = millis ();
        Serial.println("Gleboki sen");
        display.clearDisplay();
        display.setTextSize(3);
        display.setTextColor(WHITE);
        display.setCursor(0, 16);
        display.print(" Pa..");
        display.display();
        delay(500);
        display.clearDisplay();
        display.display();
        ESP.deepSleep(0); //pozostawia uspiony modul do czasu restartu recznego
            }

}

W załącznikach zdjęcia.
Po kilku dniach dokonałem paru zmian.
200mAh - to nie dużo.
Jak wiadomo zasilanie płytki przechodzi przez stabilizator LDO. 3.3V o naprawdę małym spadku ale  istotnym około 0,2-0,25. I tak jeżeli napięcie spadnie do 3,5V na baterii to płytka nie działa stabilnie. A wiadomo że ten rodzaj akumulatora działa poprawnie od 4,2 do 3,0V. Co zrobiłem:
- Zastosowałem jedno ogniwo 18650 - jest moc
- dodałem opornik 200kR od A0 do VIN
- oprogramowałem wyświetlanie napięcia na wysokości zegarka
- oprogramowałem wyłączanie przy napięciu 3,55. 
- dla upartych oprogramowałem wyłączanie przy napięciu 3,51 by nie dało się korzystać poniżej. 
W sekcji loop dla jednosekundowego przebiegu dodałem:

4.88 - taki współczynnik jest zgody co do 0,01V z miernikiem dla VIN i należy go dobrać każdorazowo przy odpowiednim rezystorze do jego rzeczywistej oporności. Ja to zrobiłem doświadczalnie.
Kod:
int rawVoltage = analogRead(A0);
        float voltage = 4.88 * rawVoltage / 1024.0;
        if (voltage < 3.55){
          Serial.println("Napiecie ponizej 3,55 naladuj baterie");
          display.clearDisplay();
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(0, 8);// Display static text
        display.print("   NISKI");
        display.setCursor(0, 16);
        display.print("  POZIOM");
        display.setCursor(0, 24);
        display.print(" BATERII");
        display.display();
        delay(1000);
        display.clearDisplay();
        display.display();
        ESP.deepSleep(0);
        }
        if (voltage < 3.51){
          Serial.println("Napiecie ponizej 3,51 bateria skrajnie wyczerpana");
          display.clearDisplay();
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(0, 8);// Display static text
        display.print(" BATERIA");
        display.setCursor(0, 16);
        display.print("WYCZERPANA");
        display.display();
        delay(500);
        display.clearDisplay();
        display.display();
        ESP.deepSleep(0);
        }