Ovdje pročitajte kako se registrirati na forum.

Croduino Nova kao brojač postova

Tvoj projekt je upravo dovršen? Podijeli s nama što si napravio u ovom podforumu! Upute drugima kako napraviti isti projekt su uvijek dobrodošle!
Odgovorite
domagoj#9564
Hobist
Hobist
Postovi: 59
Pridružen/a: ned tra 15, 2018 2:59 pm
Lokacija: Zagreb

Croduino Nova kao brojač postova

Post Postao/la domagoj#9564 » uto pro 11, 2018 10:49 pm

Uvod
Ima više razloga zašto sam se odlučio za ovaj projekt, ali najviše se odnosi na edukaciju, odnosno da nađem odgovore na neka pitanja. Zadatak je ovako postavljen: napraviti uređaj s WiFi-em i LDC-om koji će svakih X minuta provjeravati broj postova na forum.eradionca.com. Uređaj ima jednu tipku kojom označim da sam vidio zadnje postove ili kojom mogu prije isteka vremena aktivirati novu provjeru. Ovim primjerom pratim broj postova ali primjena može biti svakakva, praćenje vrijednosti dionica, kladionca, brzinu vjetra na Marsu, zapravo bilo čega.
Da rezimiram glavne razloge:
  1. Lijenost - redovito pratim ovaj forum ali mi se ne da svaki čaš gledati ima li neki novi post. Ovako imam igračku koja to radi umjesto mene. :)
  2. Htio sam Novu povezati s I2C LCD-om ali nisam bio siguran hoće li to ići zajedno. Prva sumnja je radni napon. Nova radi na 3,3V a LCD na 5V pa bi iz tog razloga trebao koristiti logic converter. Međutim, razgovarao sam s Davidom i rekao mi je da LCD direktno spojim na 3,3V i da će raditi. To je još jednostavnije i radi, što znači da LCD-u to ne smeta. Još važnije je da znam da LDC radi i na 3,3V. Možda radi i na 3,0. Treba probati
    Druga sumnja se odnosila na I2C LCD biblioteku funkcija koja radi s Basic2, ali nisam bio siguran radi li i s Novom. Npr. s Dambom ne radi pa sam zato sumnjao. Ali ni tu nema problema, radi.
  3. Htio sam se malo detljanije pozabaviti spajanjem na WiFi mrežu i internet. U izvornom kodu ćete vidjeti da sam koristio primjere iz KKM-a, ali sam ih malo izmjenio i to na način da kad završim provjeru, da se odspojim. Naravno da se nisam morao odspojiti ali ovo je testna faza nakon koje mislim napisati spajanje na jednu iz liste WiFi mreža, pa ako ne uspije na prvu, proba na drugu, treću itd. U takvoj situaciji se mora moći odspojiti. Drugo što se može dogoditi da se izgubi signal WiFi mreže, pa se mora moći naknadno spojiti, naravno automatski. Ovaj projektić sam testirao i na tu mogućnost. Zato sam na početku napisao da ovaj projekt ima i edukatvni karakter.
Kratak opis
Tu se zapravo nema što posebno napisati. Spojimo 3,3V i GND Nove i I2C adaptera, povežemo SDA i SCL linije Nove i adaptera i na kraju spojimo pin 15 s tipkalom preko pull-down otpornika. To je sve što od hardwarea treba. Neću opisivati tipkalo i pull-down otpornik jer je to detaljno opisano u KKM-u (https://e-radionica.com/hr/blog/2015/08 ... -otpornik/). I to je to. Sve što bi moglo biti interesantno u vezi ovog projekta je u samom izvornom kodu. Mislim da sam ga dobro komentirao pa ne bi trebalo biti nejasnoća. Prebacite ga na Novu i poigrajte se. Ako zapnete, postavite pitanje na ovom forumu, a ja pošto imam novu igračku, znajte da ću to vidjeti.

Još jedan detalj vezan uz Novu, barem primjerak koji ja imam. Pinovi 4 i 5 su zamijenili mjesta. Onaj pin koji u programu označite kao 4, na pločici je 5 i obratno. Kao da su oznake na pločici zamijenjene. Iste takve su i na layoutu Nove. To se odnosi i na oznake SDA i SCL koje su baš na pinovima 4 i 5. Njih isto morate zamijeniti. Ako vam LCD neće raditi možda da prvo provjerite imate li ovakav problem.

Evo par slikica.
slika
slika
I program.

Kod: Označite sve

#include "ESP8266WiFi.h"
#include <FastIO.h>
#include <I2CIO.h>
#include <LCD.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal_SR.h>
#include <LiquidCrystal_SR2W.h>
#include <LiquidCrystal_SR3W.h>
#include <Wire.h> 

#define D15 15

// kreira LCD objekt. Ne mijenjati varijable jer su pinovi LCDa tako zalemljeni s adapterom na plocici. 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
 
const char* ssid     = "********";  //naziv WiFi mreže
const char* password = "********"; //lozinka za WiFi mrežu
 
const char* host = "forum.e-radionica.com"; // stranica koju želimo otvoriti
String url = "/hr/index.php"; // budući da smo sada samo povezani na server(stranicu), 
                              // trebamo još otvoriti nešto s nje (path)
                              // da želimo naslovnu, url bi bio samo /
                              // ovdje otvaramo forum.eradionica.com na hrvatskom
char znak='-';
String br_postova_stari="0";
String br_postova_novi="0";
String tmp="";
unsigned long sekunde=0; //trenutno vrijeme do nove provjere
#define max_sekunde 1200; //koliko max sekundi se ceka do nove provjere
int i=-1;
int j=-1;
String linija="";


void setup() {
  pinMode(D15,INPUT);
  Serial.begin(9600); // započinjemo serijsku komunikaciju
  lcd.begin(16,2);              // potrebno da bismo mogli koristiti LCD.
                                // 16,2 oznacava dimenziju LCDa 
  lcd.backlight();              // upali pozadinsko osvjetljenje
  lcd.clear();                  // obrisi sve napisano na LCDu
  lcd.home ();                  // idi na pocetak prve linije(0,0)
  lcd.print("e-radionica.com"); // ispisi tekst
  lcd.setCursor(0,1);           // pocetak drugog reda
  lcd.print("Forum Counter");  // ispisi tekst
  Serial.println("e-radionica.com Forum Counter");

  delay(5000); //ova pauza je radi pozdravne poruke prilikom paljenja uređaja
} //end setup
 
void loop()
{
  if(sekunde==0)
  {
    sekunde=max_sekunde;
    Serial.println("Spajam se na WiFi mrezu");
    lcd.clear();                   
    lcd.home ();                   
    lcd.print("Spajam se na"); 
    lcd.setCursor(0,1);           
    lcd.print("WiFi mrezu");  
    if(WiFi.status() != WL_CONNECTED)
      WiFi.begin(ssid, password); // za početak se povezujemo na WiFi mrežu
     
    while (WiFi.status() != WL_CONNECTED) { // sve dok se NOVA ne poveže na WiFi mrežu
      delay(500);                           // ispisujemo točkice u Serial monitoru
      Serial.print(".");                    // čisto zbog nas, da znamo što se događa
      lcd.setCursor(15,1);
      lcd.print(znak);                      //ispisujemo animaciju
      if(znak=='-') znak='|';
      else if(znak=='|') znak='+';
      else if(znak=='+') znak=219; //moj LCD ima Asian character set
      else if(znak==219) znak='-'; //pa mi je ovaj znak trebao za animaciju
    }
  
    lcd.clear(); lcd.home();
    lcd.print("# "+br_postova_stari+"/"+br_postova_novi);
    lcd.setCursor(0,1);
    lcd.print("Provjeravam...");
    
    Serial.println("Povezani smo na WiFi! IP adresa je: ");  
    Serial.println(WiFi.localIP()); // ispisuje lokalnu WiFi adresu NOVE
    Serial.print("Sada se povezujem na ");
    Serial.println(host); // URL stranice na koju se povezujemo
     
    WiFiClient client; // kreiramo objekt klase WiFiClient za TCP konekciju
    if (!client.connect(host, 80)) // 80 je port na kojega se povezujemo, te ćete gotovo uvijek koristiti 80
    {  
      Serial.println("Ne mogu se spojiti na stranicu.."); // ako je spajanje neuspješno
      return; // kreće izvodit loop() ispočetka
    }
     
    Serial.print("Povezani smo na stranicu. Sada cemo otvoriti URL: ");
    Serial.println(url);
     
    // Ovo salje zahtjev(request) stranici
    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" + 
                 "Connection: close\r\n\r\n");

    while(!client.available()){Serial.print("."); delay(10); } //čekaj dok podaci ne postanu dostupni
    // Čitamo odgovor servera na naš zahtjev te taj isti odgovor printamo u Serial monitor
    while(client.available()){
      linija = client.readStringUntil('\r\n'); // čita liniju po liniju do teksta bull;
      i=linija.indexOf("Ukupno postova:");
      delay(10); //bez ove pauze nekad ne uspije dohvatiti podatke
      if(i>=0)
      {
        Serial.println(linija);
        br_postova_novi=linija.substring(i);
        j=br_postova_novi.indexOf("</strong>");
        tmp=br_postova_novi.substring(0,j);
        i=tmp.indexOf(">");
        br_postova_novi=tmp.substring(i+1);
        Serial.print("Postova: "); Serial.println(br_postova_novi);
        if(br_postova_stari!=br_postova_novi)
        {
          lcd.home();
          lcd.print("# "+br_postova_stari+"/"+br_postova_novi+" Novo");
        }
      }
    }
    
    Serial.println("Odjavljujem se s WiFi mreze");
    WiFi.disconnect();
  }//end if sekunde==0

  //provjeri tipku
  if(digitalRead(D15)) //tipka je stisnuta
  {
    if(br_postova_stari!=br_postova_novi)
      br_postova_stari=br_postova_novi;
    else
      sekunde=1; //forsiraj ponovnu provjeru
    lcd.home();
    lcd.print("# "+br_postova_stari+"/"+br_postova_novi+"          ");
  }
  lcd.setCursor(0,1);
  lcd.print("Jos "+sekunde2str(sekunde)+"           ");
  delay(1000); 
  sekunde--;
}//end loop

String sekunde2str(unsigned long sekunde)
{
  unsigned long m,s;
  m=sekunde/60; //minute
  s=sekunde%60; //sekunde
  return String(m)+":"+String(s);
} //end sekunde2str
Lijep pozdrav,
Domagoj
Avatar
david.zovko#2998
e-radionica.com team
e-radionica.com team
Postovi: 193
Pridružen/a: ned tra 15, 2018 2:59 pm
Lokacija: Osijek, Croatia
Kontakt:

Re: Croduino Nova kao brojač postova

Post Postao/la david.zovko#2998 » sri pro 12, 2018 8:42 am

Baš sam se veselio vidjeti ovaj projekt otkada ga je Domagoj najavio na emailu. Sviđa mi se što si napravio to jednostavno, a bez problema si mogao zakomplicirati do nebesa :)

Možeš li nam, molim te, samo malo detaljnije objasniti kako točno dohvaćaš broj postova sa web stranice? Tražiš liniju "Ukupno postova:" u HTML-u kojega dohvatiš i što onda? Kako znaš koliko znamenki ima brojka kada ju vadiš sa substring? Inače kod je stvarno dobro komentiran i razumljiv!

Mislim da ćemo si i mi ovdje u radionici morati ugraditi jedan ovakav!

P.S.: NOVA koju koristiš ima zamjenjene pinove 4 i 5, točno. To je je verzija v1.0. ili v1.1. Kasnije smo to popravili i više nije problem, tako da imate v1.2 ili NOVA2, sve je točno. Iako, na pinoutu jesu zamjenjeni SDA i SCL, previše smo ih naprintali! :think:
Sve verzije ovdje: https://github.com/e-radionicacom/Crodu ... agle-Files

P.S.S.: Budući da ESP8266 nema hardware I2C, nego ga softwareski emulira, I2C pinove možete prebaciti na bilokoje druge pinove. Samo unutar Wire.begin() ubacite brojeve pinova za koje želite da Vam budu SDA i SCL linije, tim redoslijedom.

Kod: Označite sve

Wire.begin(14, 16); //sada je pin 14 SDA, a pin 16 SCL
domagoj#9564
Hobist
Hobist
Postovi: 59
Pridružen/a: ned tra 15, 2018 2:59 pm
Lokacija: Zagreb

Re: Croduino Nova kao brojač postova

Post Postao/la domagoj#9564 » sri pro 12, 2018 9:53 am

Ne bi vjerovao koliko mi je ova stvarčica postala zabavna. Svako malo škicnem na broj postova a ne moram otvarati browser. Blažena lijenost. :)
Budući da broj postova dalje ne obrađujem, pa mi ne treba kao broj, već samo kao prikaz, filtriranje sam napravio u tri koraka i sve tretiram kao String.
Učitavam liniju po liniju stranice a ono što tražim u HTML-u to izgleda ovako: 'Ukupno postova: <strong>274</strong> ...'
  1. Učitanu liniju pospremim u varijablu linija i unutar nje prvo tražim 'Ukupno postova:' i kad nađem, rezultat izgleda ovako: 'Ukupno postova: <strong>274</strong> ...' (što je iza ... ignoriram). Rezultat spremim u varijablu br_postova_novi
  2. Nakon toga unutar varijable br_postova_novi tražim '</strong>' je se to nalazi iza broja pa rezultat izgleda ovako: 'Ukupno postova: <strong>274' a rezultat spremim u varijablu tmp.
  3. I na kraju untar varijable tmp tražim '>' jer se to nalazi ispred broja pa je konačni rezultat 274 koji spremim u varijablu br_postova_novi
Svako traženje ide od početka stringa, dakle tražim prvu pojavu stringa. Kada bi ih bilo više, ostale bi bile ignorirane.
U programu 274 je String a ne broj i dalje uspoređujem stringove jer mi je samo bitno jesu li različiti a ne koja im je stvarna vrijednost, linija programa 119: if(br_postova_stari!=br_postova_novi)
Da sam planirao kasnije nešto napraviti s tim brojem pretvorio bi ga u unsigned long, ali u ovom slučaju to nije bilo potrebno.
Ako su vrijednosti varijabli br_postova_stari i br_postova_novi različiti, na LCD-u se ispisuje Novo. Kada bi u takvoj situaciji pritisnuo tipku izjednačio bi staru vrijednost s novom i poruka Novo bi nestala s ekrana. A ako u trenutku jednakih vrijednosti staro i novo pritisnem tipku, program trenutno ide u provjeru, tj. ne čeka da istekne vrijeme. Kod mene je to 20 min,, odnosno 1200 s. To sam napravio tako da vrijednost varijable sekunde koja broji koliko još sekundi ima do nove provjere, postavim na 1. U slijedećem trenutku će postati 0, a kad je 0 ide u provjeru. Nisam je postavio na 0 jer je unsigned long pa kada je umanjujem za 1 postala bi zapravo jako velika. Stvar je u tome što se umanjivanje za 1 kronološki događa poslije detekcije tipke, a prije provjere jesu li sekunde došle na 0. U toj situaciji da varijabla nije unsigned, otišla bi na -1, a ovako na maksimalnu vrijednost, što bi bio bug.
Misim da sa sam spomenuo ono najvažnije. Ako ne, tu sam.
Pozdrav, Domagoj
Avatar
david.zovko#2998
e-radionica.com team
e-radionica.com team
Postovi: 193
Pridružen/a: ned tra 15, 2018 2:59 pm
Lokacija: Osijek, Croatia
Kontakt:

Re: Croduino Nova kao brojač postova

Post Postao/la david.zovko#2998 » sri pro 19, 2018 3:58 pm

Puno jasnije! Sad kužim, zapravo vadiš string unutar drugog stringa i onda njega prikazuješ na ekranu.

Jel još uvijek provjeravaš postove na LCU? :D idući korak bi morao biti implementirati da pokazuje koja je zadnja tema u koju je netko pisao ili tko je pisao.. ima tu ideja, ali onda ovo parsiranje postaje dosta zeznutije!
domagoj#9564
Hobist
Hobist
Postovi: 59
Pridružen/a: ned tra 15, 2018 2:59 pm
Lokacija: Zagreb

Re: Croduino Nova kao brojač postova

Post Postao/la domagoj#9564 » sri pro 19, 2018 7:10 pm

Upravo sam se vratio s terena i naravno da mi je brojač javio da ima novih postova. :) Prvi upgrade koji mislim napraviti je to da ću dodati LED kao indikator novih poruka. Pored LCD-a se to čini beskorisno, ali to bi bila verzija za slučaj kad nemaš LCD. Ne znam, treba ti LCD za novi projekt, a i dalje želiš indikator novih postova.
Možda i ne bi bio takav problem u parsiranju jer dio te statistike već postoji na samoj stranici, ali ono što bi mogao biti potencijalni problem (možda ne konkretno u ovom slučaju) da bi se pristup stranici preko Nove i specijaliziranog programa mogao protumačiti kao napad robota na stranicu, pa sigurnosni mehanizmi zabrane pristup. Kad budeš imao vremena, pogledaj u logovima web servera kako se registrira Nova kad pregledava početnu stranu foruma. Sigurno nije kao web browser. Prepoznat ćeš je po tome što bi se taj log trebao pojaviti svakih 20min, osim noću, tada sve pogasim.
Pozdrav, Domagoj
Odgovorite