Stránka 1 z 2

Ovládání arduina přes web

Napsal: 06 srp 2019, 23:59
od Bart_
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?

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

Napsal: 07 srp 2019, 00:31
od Bart_
Viděl bych to na chybu v PHP..

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

Napsal: 07 srp 2019, 08:17
od pavel1tu
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/

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

Napsal: 07 srp 2019, 10:50
od Bart_
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..

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

Napsal: 07 srp 2019, 13:05
od pavel1tu
Promiň, bylo to přes tablet a vloudil se mi tam blbý odkaz
skoro na konci

https://arduino.cz/programovani-webovyc ... o-arduino/

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

Napsal: 09 srp 2019, 13:17
od KamilV
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

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

Napsal: 09 srp 2019, 13:31
od Bart_
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:

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

Napsal: 09 srp 2019, 13:48
od KamilV
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?

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

Napsal: 09 srp 2019, 13:53
od KamilV
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í...

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

Napsal: 09 srp 2019, 16:51
od Bart_
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