Ovládání arduina přes web

Bart_
Příspěvky: 18
Registrován: 06 srp 2019, 23:24
Reputation: 0

Ovládání arduina přes web

Příspěvek od Bart_ » 06 srp 2019, 23:59

Ahoj, celkem neúspěšně se snažím rozchodit ovládání arduina přes internet. Mám napsanou PHP aplikaci, která mi loguje data do MySQL databáze. Pak mám napsanou stránku, která tyto data sosá a jen je vypíše. Tato stránka by měla sloužit pro arduino,aby se na ní arduino připojilo a vzalo si údaje. Tyto údaje dále přiřadit správným proměnným. Případně je možné se připojit do MySQL přímo z arduina? Vybírám všechna políčka, protože se všemi pracuji, před každým zápisem do tabulek se mi předchozí zápis smaže, takže mám v tabulce vždy jeden řádek.
PHP pro ovládání arduina:

Kód: Vybrat vše

<?php
header('Content-Type: text/plain');
        // put your code here
        require_once('Db.php');
                Db::connect('127.0.0.1:3306', 'arduino', 'admin', 'Bartolomej');
                
                $water = Db::queryAll('
                                SELECT * FROM `water`;
                                ');
                foreach ($water as $u)
{
        $xD = ($u['xD']);
        $yD = ($u['yD']);            
        $xN = ($u['xN']);            
        $yN = ($u['yN']);     
        $prodlevaD= ($u['prodlevaD']);
        $prodlevaN = ($u['prodlevaN']);
        $nepProvoz = ($u['nepProvoz']);
                  
}

$profil = Db::queryAll('
                                SELECT * FROM `profil`;
                                ');
                foreach ($profil as $v)
{
        $DTnas = ($v['DTnas']);
        $DHnas = ($v['DHnas']);            
        $DCnas = ($v['DCnas']);            
        $NTnas = ($v['NTnas']);     
        $NHnas = ($v['NHnas']);
        $NCnas = ($v['NCnas']);
        $Thystereze = ($v['Thystereze']);
        $Hhystereze = ($v['Hhystereze']);
        $Chystereze = ($v['Chystereze']);
        $trvaniDneHod = ($v['trvaniDneHod']);
        $trvaniDneMin = ($v['trvaniDneMin']);
        $SzapHod = ($v['SzapHod']);
        $SzapMin = ($v['SzapMin']);
                    
}

$settings = Db::queryAll('
                                SELECT * FROM `settings`;
                                ');
                foreach ($settings as $w)
{
        $IP_arduino = ($w['IP_arduino']);
                 
}

/*$bool = Db::queryAll('
                                SELECT * FROM `bool`;
                                ');
                foreach ($bool as $x)
{
        $atmosOn = htmlspecialchars($x['atmosOn']);
        $vetrakOn = htmlspecialchars($x['vetrakOn']);            
        $vetrakSvetla = htmlspecialchars($x['vetrakSvetla']);            
}*/
echo("$xD;");
echo("$yD;");
echo("$xN;");
echo("$yN;");
echo("$prodlevaD;");
echo("$prodlevaN;");
echo("$DTnas;");
echo("$DHnas;");
echo("$DCnas;");
echo("$NTnas;");
echo("$NHnas;");
echo("$NCnas;");

echo("$Thystereze;");
echo("$Hhystereze;");
echo("$Chystereze;");
echo("$trvaniDneHod;");
echo("$trvaniDneMin;");
echo("$SzapHod;");
echo("$SzapMin");


/*
echo("IP_arduino $IP_arduino ");

/*echo("atmosOn $atmosOn");
echo("vetrakOn $vetrakOn");
echo("vetrakSvetla $vetrakSvetla")*/

        ?>
Arduino se připojí na server, dostane se pomocí GET na správnou stránku, ale String, který by si mělo vzít je nějaký "pošmodrchaný". Arduino se mi po cca 4 minutách běhu zasekne. Kód Arduina:

Kód: Vybrat vše

#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xAA, 0xBB, 0xCC, 0x81, 0x7B, 0x4A }; //fyzicka adresa MAC
IPAddress serverName (10,0,0,139); // webserver
IPAddress ip(10, 0, 0, 150);
EthernetClient client;
void setup(){
 if (Ethernet.begin(mac) == 0) {
    Serial.println("DHCP nepridelilo adresu, skusam so statickou...");
    Ethernet.begin(mac, ip);
  }
  Serial.begin(115200);
  Serial.println("setup");
}
 
void loop(){
  Serial.println("loop");
if (client.connect(serverName, 80)) {  //starts client connection, checks for connection
    Serial.println("Pripojene");
    client.println("GET /ovladani.php"); //download text
    client.println("Host: 10.0.0.139");
    client.println("Connection: close");
    client.println();
    /*while (client.connected()) {
      String hlavicka = client.readStringUntil('\n');
      Serial.println(hlavicka);
      if (hlavicka == "\r") {
        break;
      }*/
    
   String premenna = client.readStringUntil('\n');
   delay(5000);
   Serial.println("Premenna je:");
   Serial.println(premenna);
  
   /*char ovladani [50];
   premenna.toCharArray(ovladani ,50);
   Serial.println(ovladani);

   */
   
} 
  else {
    Serial.println("Pripojenie neuspesne"); //chyba ak nie som pripojeny
    Serial.println();
  }

  client.stop(); //ukonc spojenie
  delay(5000); //pockaj 5s a vykonaj novu slucku loop
}
Výstup na Serial monitor:
23:31:55.889 -> setup
23:31:55.889 -> loop
23:31:55.889 -> Pripojene
23:31:55.889 -> Premenna je:
23:31:55.921 -> 2 ,!,!,!,!, , 5 4 , 0 , 7 4 , 0 ,1,1,50,1,1,1,0
Přičemž vypsaný String by měl vypadat takto:
20,1,3,1,1,0,25,40,400,27,40,400,1,1,50,1,1,1,0
Zkoušel jsem i kód s funkcí client.find ale to mělo prachbídnou úspěšnost. Za 30 min běhu kódu to našlo hledaný výraz jen 2x :-(
Taky jsem zkoušel knihovnu MySQL connector https://github.com/ChuckBell/MySQL_Connector_Arduino ale v tomto případě se mi nepodařilo ani připojit do databáze. Chybí mi tam někde zadávání do jaké databáze by se mělo arduino připojit.
Pak mě ještě napadlo další řešení a to,že by PHP vytvořilo soubor s proměnými a ten by si arduino potom stáhlo a zněj vytáhlo informace. Ale to není tak elegantní.
Nejdivnější je, že mi to dneska v jednu chvíli vypisovalo správně. Pak jsem se tam ale pokusil použít funkci strtok() a arduino mi přestalo kompilovat, musel sem aktualizovat balíček AVR desek. Ani po vrácení se na předchozí verzi to nefunguje.
Poradíte mi někdo prosím jak správně ovládat arduino přes webovou stránku? Jak ho ovládáte vy?

Bart_
Příspěvky: 18
Registrován: 06 srp 2019, 23:24
Reputation: 0

Re: Ovládání arduina přes web

Příspěvek od Bart_ » 07 srp 2019, 00:31

Viděl bych to na chybu v PHP..

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Ovládání arduina přes web

Příspěvek od pavel1tu » 07 srp 2019, 08:17

Jak dostat z mySQL data do Arduina je pěkný český článek.
Vyzkoušej to podle něj a pak si to uprav pro své potřeby.

https://navody.arduino-shop.cz/
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Bart_
Příspěvky: 18
Registrován: 06 srp 2019, 23:24
Reputation: 0

Re: Ovládání arduina přes web

Příspěvek od Bart_ » 07 srp 2019, 10:50

Ahoj, díky za tip. Máš odkaz přímo na článek? Prošel jsem všech 29 stran návodů, ale ani na jedné nebyla na první pohled zmíňka o MySQL..

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Ovládání arduina přes web

Příspěvek od pavel1tu » 07 srp 2019, 13:05

Promiň, bylo to přes tablet a vloudil se mi tam blbý odkaz
skoro na konci

https://arduino.cz/programovani-webovyc ... o-arduino/
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: Ovládání arduina přes web

Příspěvek od KamilV » 09 srp 2019, 13:17

Kolik záznamů vrátí dotaz: SELECT * FROM `water`; ?
Ty napřed vytáhneš pomocí queryAll všechny záznamy, projdeš je postupně pomocí foreach cyklu, ale přepisuješ stále ty stejné proměnné.
Takže ve výsledku dostaneš jen poslední záznam z toho dotazu. To už rovnou můžeš udělat SELECT * FROM water ORDER BY id DESC LIMIT 1

Bart_
Příspěvky: 18
Registrován: 06 srp 2019, 23:24
Reputation: 0

Re: Ovládání arduina přes web

Příspěvek od Bart_ » 09 srp 2019, 13:31

V tabulce water je vždy jeden řádek a 7 sloupců (při uložení nových hodnot pro ovládání zálivky (do tabulky water) je předchozí záznam smazán). PHP kód jsem pochopil tak, že Db::queryAll pošle MySQL dotaz (vyber všechny záznamy z tabulky) a foreach je přiřadí proměnným v PHP. No a tyto přoměnné bych rád dostal do arduina. Názvy proměnných v MySQL, v PHP a v arduinu jsou totožné. S PHP a MySQL se teprve učím..a když se to tak vezme tak i s arduinem :lol:

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: Ovládání arduina přes web

Příspěvek od KamilV » 09 srp 2019, 13:48

Pokud se vždy operuje právě s jedním záznamem, tak si zavolej nějakou query metodu (nevím, co to je za DB knihovnu), nemusíš volat queryAll.
Pak tě odpadne potřeba cyklu foreach (protože procházet cyklem všechny záznamy, když je právě jeden, je zbytečné).

Co dostaneš na výstup, když si tu url otevřeš v prohlížeči? Není tam problém s kódováním? Nechceš si v PHP poslat i hlavičku o UTF-8?

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: Ovládání arduina přes web

Příspěvek od KamilV » 09 srp 2019, 13:53

A ukazuješ nám správné verze skriptů? V PHP odděluješ jednotlivé hodnoty středníkem, ale v serial logu jsou oddělené čárkami, to se jen tak samo nezmění...

Bart_
Příspěvky: 18
Registrován: 06 srp 2019, 23:24
Reputation: 0

Re: Ovládání arduina přes web

Příspěvek od Bart_ » 09 srp 2019, 16:51

Máš pravdu, kódy kvůli nepozornosti nebyly aktuální..
Arduino:

Kód: Vybrat vše

#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xAA, 0xBB, 0xCC, 0x81, 0x7B, 0x4A }; //fyzicka adresa MAC
IPAddress serverName (10, 0, 0, 140); // webserver
IPAddress ip(10, 0, 0, 150);
EthernetClient client;
void setup() {
  if (Ethernet.begin(mac) == 0) {
    Serial.println("DHCP nepridelilo adresu, skusam so statickou...");
    Ethernet.begin(mac, ip);
  }
  Serial.begin(115200);
}

void loop() {
  if (client.connect(serverName, 80)) {  //starts client connection, checks for connection
    Serial.println("Pripojene");
    client.println("GET /ovladani.php"); //download text
    client.println("Host: 10.0.0.140");
    client.println("Connection: close");
    client.println();
   /* while (client.connected()) {
      String hlavicka = client.readStringUntil('\n');
      Serial.println(hlavicka);
      if (hlavicka == "\r") {
        break;
      }
    }*/

    String premenna = client.readStringUntil('\n');
    delay(5000);
    Serial.println("Premenna je:");
    Serial.println(premenna);

    /* char ovladani [500];
      premenna.toCharArray(ovladani ,500);
      Serial.println(ovladani);*/

  }
  else {
    Serial.println("Pripojenie neuspesne"); //chyba ak nie som pripojeny
    Serial.println();
  }
  client.stop(); //ukonc spojenie
  delay(5000); //pockaj 5s a vykonaj novu slucku loop
}
PHP:

Kód: Vybrat vše

<?php
header('Content-Type: text/plain; charset=utf-8');
        // put your code here
        require_once('Db.php');
                Db::connect('127.0.0.1:3306', 'arduino', 'admin', 'Bartolomej');
                
                $water = Db::queryAll('
                                SELECT * FROM `water`;
                                ');
                foreach ($water as $u)
{
        $xD = ($u['xD']);
        $yD = ($u['yD']);            
        $xN = ($u['xN']);            
        $yN = ($u['yN']);     
        $prodlevaD= ($u['prodlevaD']);
        $prodlevaN = ($u['prodlevaN']);
        $nepProvoz = ($u['nepProvoz']);
                  
}

$profil = Db::queryAll('
                                SELECT * FROM `profil`;
                                ');
                foreach ($profil as $v)
{
        $DTnas = ($v['DTnas']);
        $DHnas = ($v['DHnas']);            
        $DCnas = ($v['DCnas']);            
        $NTnas = ($v['NTnas']);     
        $NHnas = ($v['NHnas']);
        $NCnas = ($v['NCnas']);
        $Thystereze = ($v['Thystereze']);
        $Hhystereze = ($v['Hhystereze']);
        $Chystereze = ($v['Chystereze']);
        $trvaniDneHod = ($v['trvaniDneHod']);
        $trvaniDneMin = ($v['trvaniDneMin']);
        $SzapHod = ($v['SzapHod']);
        $SzapMin = ($v['SzapMin']);
                    
}

$settings = Db::queryAll('
                                SELECT * FROM `settings`;
                                ');
                foreach ($settings as $w)
{
        $IP_arduino = ($w['IP_arduino']);
                 
}

/*$bool = Db::queryAll('
                                SELECT * FROM `bool`;
                                ');
                foreach ($bool as $x)
{
        $atmosOn = htmlspecialchars($x['atmosOn']);
        $vetrakOn = htmlspecialchars($x['vetrakOn']);            
        $vetrakSvetla = htmlspecialchars($x['vetrakSvetla']);            
}*/
echo("$xD;");
echo("$yD;");
echo("$xN;");
echo("$yN;");
echo("$prodlevaD;");
echo("$prodlevaN;");
echo("$nepProvoz;");
echo("$DTnas;");
echo("$DHnas;");
echo("$DCnas;");
echo("$NTnas;");
echo("$NHnas;");
echo("$NCnas;");

echo("$Thystereze;");
echo("$Hhystereze;");
echo("$Chystereze;");
echo("$trvaniDneHod;");
echo("$trvaniDneMin;");
echo("$SzapHod;");
echo("$SzapMin");


/*
echo("IP_arduino $IP_arduino ");

/*echo("atmosOn $atmosOn");
echo("vetrakOn $vetrakOn");
echo("vetrakSvetla $vetrakSvetla")*/

        ?>
výstup na serial monitor:
16:36:50.331 -> Pripojene
16:36:55.335 -> Premenna je:
16:36:55.335 -> 20;5;30;5;1;1!0!2!;!5!1 5 ; 3!4 ; 0 ;!;!;!0!1 ; ;!6!2
Přísahám, že mi to ještě před chvilkou psalo správný výstup. Čím to je, že se mi po několika upravach kódu arduina začne psát tato matlanina (pouze přidávám další řádky)? Přijde mi jako kdyby to správný výstup psalo, jen když tomu dám několik hodin "voraz"..

stránka vypíše toto, source code vypadá stejně
20;5;30;5;1;1;0;25;75;1250;23;40;400;1;1;50;18;0;16;20

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 6 hostů