• 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
Uno + BME280 + ESP8266 + clock (NTP)
#1
Zobiłem stację pogody na BME280... Plus wyświetla też sekwencyjnie pewien tekst...
Chciałbym dołożyć do tego zegart "ściągający" czas po NTP; z zastosowaniem ESP8266...
Ale utknąłem...
O ile kod 'stacji pogody' znalazłem i wgrałem, o tyle nie za bardzo wiem jak do tego dołaczyć kod zegara NTP...

Na innym form znalazłem interesujący mnie kod, ale coś nie za bardzo wychdzi mi zgranie całości...


NTP / ESP8266 / zegar




Kod:
/////screen
#include <Wire.h>
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 11
#define DELTAY 21
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
/////////////////////////////BME280
#include "BlueDot_BME280.h"
BlueDot_BME280 bme280 = BlueDot_BME280();
//////////////////////////////
void setup() {
  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  display.display();
  Serial.println(F("Basic Weather Station"));
  bme280.parameter.communication = 0;
  bme280.parameter.I2CAddress = 0x76;
  bme280.parameter.sensorMode = 0b11;
  bme280.parameter.IIRfilter = 0b100;                    //Setup for IIR Filter
  bme280.parameter.humidOversampling = 0b101;            //Setup Humidity Oversampling
  bme280.parameter.tempOversampling = 0b101;             //Setup Temperature Ovesampling
  bme280.parameter.pressOversampling = 0b101;            //Setup Pressure Oversampling
  bme280.parameter.pressureSeaLevel = 1013.25;           //default value of 1013.25 hPa
  bme280.parameter.tempOutsideCelsius = 15;              //default value of 15°C
  if (bme280.init() != 0x60)
  {
    while (1);
  }
  else
  {
    Serial.println(F("BME280 detected!"));
  }
  Serial.println();
  Serial.println();


}
void loop()
{

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.print("T");
  display.setCursor(25, 0);
  display.print(bme280.readTempC());
  display.setCursor(115, 0);
  display.print("C");
  display.drawCircle(110, 2, 2, WHITE); // put degree symbol ( ° )
  display.setTextSize(2);
  display.setCursor(0, 17);
  display.print("H");
  display.setCursor(25, 17);
  display.print(bme280.readHumidity());
  display.setCursor(115, 17);
  display.print("%");
  display.setCursor(0, 36);
  display.print("P");
  display.setCursor(25, 36);
  display.print(bme280.readPressure());
  display.setCursor(110, 43);
  display.setTextSize(1);
  display.print("hPa");
  display.setCursor(25, 56);
  display.setTextSize(1);
  display.print("Alt. ");
  display.print(bme280.readAltitudeMeter());
  display.print(" m");
  display.display();
  delay(3000);
  display.clearDisplay();
  display.setCursor(15, 0);
  display.setTextSize(2);
  display.print(" Adres:");
  display.setCursor(15, 16);
  display.setTextSize(2);
  display.print("SomeCity");
  display.setCursor(15, 36);
  display.setTextSize(2);
  display.print("41-803");
  display.setCursor(5, 55);
  display.setTextSize(1);
  display.print("st. Green 32");
  display.display();
  delay(1000);

  display.clearDisplay();
  display.setCursor(15, 3);
  display.setTextSize(1);
  display.print("GPS Position:");
  display.setCursor(15, 26);
  display.setTextSize(1);
  display.print("N 48  14'"" 0.308\"");
  display.drawCircle(42, 28, 2, WHITE); // put degree symbol ( ° )
  display.setCursor(15, 54);
  display.setTextSize(1);
  display.print("E 21  13'"" 26.108\"");
  display.drawCircle(42, 56, 2, WHITE); // put degree symbol ( ° )
  display.display();
  delay(1000);

}
 
Odpowiedź
#2
Działający kod NTP masz w materiałach dodatkowych do "Mini stacji pogodowej" opublikowanej w tym roku w Elektronice dla wszystkich.
 
Odpowiedź
#3
Dobra rada.
Program rozdzielaj na podprogramy, dla każdej części osobny a w pętli tylko "odnośniki" do nich, wtedy program jest przejrzysty.
Np
void odczyt_czujnikow ()
{
tu kod programu
}
void wyswietlacz ()
{
tu kod programu
}
void zegar ()
{
tu kod programu
}
a w
loop ()
{
odczyt_czujnikow();
wyswietlacz();
zegar();
}
łatwo wtedy dołączać kolejne lub wyłączać przez zakomentowywanie znakiem //
Może napisałem oczywistą oczywistość, ale napisałem.

Pozdrawiam
 
Odpowiedź
#4
O.K. Cenna porada...
Ale na tym etapie mam za małą wiedzę, aby te 2 programy połączyć...

Myślałem, że ktoś robił coś zbliżonego na wyświetlaczu OLED 128x64 oraz ESP8266, Arduino i BME280...
Tzn. stacja pogody + dokładny czas z NTP...
 
Odpowiedź
#5
(14-11-2019, 19:40)darekpawel napisał(a): Myślałem, że ktoś robił coś zbliżonego na wyświetlaczu OLED 128x64 oraz ESP8266, Arduino i BME280...
Tzn. stacja pogody + dokładny czas z NTP...
Liczba możliwych do rozegrania partii szachowych jest większa niż szacowana liczba atomów we Wszechświecie. Liczba możliwych do zbudowania urządzeń jeszcze większa ale masz szczęście, projekt "Mini stacja pogodowa AVT-3249" http://es2.noip.pl/projekty_avt/2019-07_...udowa).gif ma przecież:
- OLED 128x64.
- Jest na ESP8266.
- Ma BME280.
- Obsługuje NTP.
- Napisane w Arduino IDE.
- Działa: http://es2.noip.pl:81
Czego jeszcze potrzebujesz?
Jak jeszcze projekt ma się zbliżyć?
 
Odpowiedź
#6
Tak, to jest jakiś przykład/możliwość.
Chodzi mi o coś podobnego, a konkretnie:
- czas jest synchronizowany (NTP) przez moduł ESP8266 wg tego projektu -> NTP - ESP8266 
- sygnał ma być podawany do Arduino
- i wyświetlony na OLED 128x64

Pytanie konkretne - jak oczytać w Arduino czas (z ESP8266) i wyświetlić na OLED?
Chodzi o część programową, oczywiście...


Kod:
/********************
- www.geekstips.com
- Arduino Time Sync from NTP Server using ESP8266 WiFi module
- Arduino code example
********************/

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

char ssid[] = "*************";  //  your network SSID (name)
char pass[] = "********";       // your network password


unsigned int localPort = 2390;      // local port to listen for UDP packets

/* Don't hardwire the IP address or we won't get the benefits of the pool.
*  Lookup the IP address for the host name instead */
//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
IPAddress timeServerIP; // time.nist.gov NTP server address
const char* ntpServerName = "time.nist.gov";

const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println();

  // We start by connecting to a WiFi network
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
 
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  Serial.println("Starting UDP");
  udp.begin(localPort);
  Serial.print("Local port: ");
  Serial.println(udp.localPort());
}

void loop()
{
  //get a random server from the pool
  WiFi.hostByName(ntpServerName, timeServerIP);

  sendNTPpacket(timeServerIP); // send an NTP packet to a time server
  // wait to see if a reply is available
  delay(1000);
 
  int cb = udp.parsePacket();
  if (!cb) {
    Serial.println("no packet yet");
  }
  else {
    Serial.print("packet received, length=");
    Serial.println(cb);
    // We've received a packet, read the data from it
    udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    Serial.print("Seconds since Jan 1 1900 = " );
    Serial.println(secsSince1900);

    // now convert NTP time into everyday time:
    Serial.print("Unix time = ");
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;
    // print Unix time:
    Serial.println(epoch);


    // print the hour, minute and second:
    Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
    Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
    Serial.print(':');
    if ( ((epoch % 3600) / 60) < 10 ) {
      // In the first 10 minutes of each hour, we'll want a leading '0'
      Serial.print('0');
    }
    Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
    Serial.print(':');
    if ( (epoch % 60) < 10 ) {
      // In the first 10 seconds of each minute, we'll want a leading '0'
      Serial.print('0');
    }
    Serial.println(epoch % 60); // print the second
  }
  // wait ten seconds before asking for the time again
  delay(10000);
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
  Serial.println("sending NTP packet...");
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  udp.beginPacket(address, 123); //NTP requests are to port 123
  udp.write(packetBuffer, NTP_PACKET_SIZE);
  udp.endPacket();
}



[Obrazek: 7687a9f2f03311acmed.png]
 
Odpowiedź
#7
Cytat:Pytanie konkretne - jak oczytać w Arduino czas (z ESP8266) i wyświetlić na OLED?
Chodzi o część programową, oczywiście...
Konkretne pytanie, po co ArduinoUNO?

Porównajmy:
- ArduinoUNO: CPU 8bit, 16MHz. Ram 2kB (śmiech). Flash 32kB. Brak DMA. Koszt klona ok 30zł. Ok 12MIPS przy 16MHz.
- ESP8266: 32-bit, 80/160MHz. 80kB RAM dla użytkownika. Flash min 512kB. DMA. Koszt ok 30zł  (np Wemos D1 w KAMAMI). 400MIPS ale to chyba przy 240MHz, 20% na Wi-Fi. teoretycznie wychodzi 130MIPS przy 80MHz (i tak przepaść w stosunku do AVR).

Chcesz więc aby potężny (w stosunku do kiepskiego AVR) realizował TYLKO NTP a resztę zadań wykonywał AVR, zadań, które z palcem w d... może zrobić ESP. Niepotrzebnie zwiększasz koszty, pobór prądu, zmniejszając jednocześnie niezawodność.
Gdzie sens? Gdzie logika?

Dostałeś link do projektu, do którego są dostępne kody źródłowe. jak widać na obrazkach z artykułu, wszystko realizuje ESP i nie potrzebny mu dodatkowy, marny AVR. Po co chcesz komplikować sobie życie dokładając AVR?
 
Odpowiedź
#8
Sens i logika są bardzo proste - czas poświęcony na zrealizowanie projektu, czy też po prostu na naukę ma pewną wartość. Jeśli użycie Arduino UNO sprawi, że ktoś kto dopiero zaczyna przygodę z programowaniem sobie poradzi i zrealizuje projekt, to będzie dla niego ogromnym plusem - prawdopodobnie znacznie większym niż kilka zł wydane na sprzęt.
Czy w projekcie będzie jeden procesor, dwa, albo może pięć oraz płytka Atnela - nie ma najmniejszego znaczenia. Jeśli to jedna sztuka, ale nie produkcja seryjna, a projekt ma przede wszystkim czegoś jego autora nauczyć - to ten właśnie cel zostanie osiągnięty. A koszty.... nauka po prostu kosztuje. Ale za to później można z tego co się nauczyło korzystać. I w godzinę zarobić na cały sprzęt o którym tyle niepotrzebnej dyskusji się toczy.
Natomiast używanie gotowych kitów z AVT, gdzie nie ma dostępu do kodów źródłowych (to akurat chyba lepiej) - niczego i nikogo nie nauczy. Więc to jest faktyczne wyrzucanie pieniędzy i zupełny bezsens. W tym rzeczywiście nie ma ani sensu, ani logiki.
 
Odpowiedź
#9
Ktoś kto pyta o gotowce, i korzysta z bibliotek niepotrzebnych, na pewno nie myśli o nauce... Nawet nie przepisał kodu po swojemu , tylko na zasadzie kopiuj/wklej z jakiś przykładów. To powiedz jak ma sie nauczyć??
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#10
Ja zaczynałem od przepisywania programów z gazet - dawno, bardzo dawno temu. Przepisywałem nic nie rozumiejąc, a później uczyłem się do czego był program. Więc jak dla mnie nawet używanie gotowej biblioteki, wzorowanie się na programie z internetu jest nauką. Oczywiście sklejenie programu z gotowców nie czyni z kogoś programisty doskonałego - ale to jest taki mały kroczek... Moim zdaniem wszystko zależy od etapu na którym jesteśmy. Jak ktoś dopiero zaczyna, to Arduino UNO i gotowe biblioteki są całkiem ciekawym rozwiązaniem.
Nie twierdzę, że tak należy pisać wysokiej jakości programy, ale to chyba nie jest forum dla profesjonalistów którzy szukają najlepszych praktyk do oprogramowania krytycznego dla bezpieczeństwa. No chyba że się mylę Smile
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości