управление ардуиной из интернета-помогите

Gagarin74
Offline
Зарегистрирован: 24.08.2013

ещё вопрос на засыпку.

Вырисовывается алгоритм следующий.

1 Ардуина методом GET отсылает данные по температуре в базу SQL - с этим разобрались и работает.

2 PHP сервер рисует красивые графики итд итп -то же не проблема и к ардуине отношение не имеет.

а теперь вопрос!!!!

Как с этого сервера послать команду на ардуино что бы она вкл (выкл) реле. Вернее больше интересует сам код ардуинки.

Я как понимаю из описания ардуина должна перейти из режима клиента в режим сервера? Или я опять путаюсь в терминологии ?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Если трафик не важен можно и клиентом раз в секунд 10 на сервер стучаться и получать от него состояние реле, но это очень не очень :)

Сделайте из ардуино сервер. Пусть пхп-скрипт обращается к ардуинки когда надо что-то сделать, температуру получить или реле щелкнуть и всё.

А вообще если прям так хотите базы данных и т.д. может лучше в сторону распбери посмотреть? Там на линуксе поднимете и БД и сервер и все датчики подключите сразу и по HTTPS протоколу сможете цепляться без танцев с бубном ну и т.д. :)

Gagarin74
Offline
Зарегистрирован: 24.08.2013

не ,ну это не интересно :)

ардуинка на php отправляет только те параметры которые изменились. Во вторых скрипт php не достучиться до ардуинки -она имеет серый ip

И если не трудно опишите Ваш первый абздец поподробней.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну, например, Вы на сервере нажимаете кнопку "Реле Вкл." это состояние пишется ну пусть в туже базу данных. Ардуина в режиме клиента раз в 10 секунд (например) обращается к серверу с тем же запросом GET и просит RelayState.php (например) Сервер выполняет php и отсылает клиенту в ответ. Ардуинка получит что-то типа relay1=on обработает это и включит реле. Как-то так :)

Gagarin74
Offline
Зарегистрирован: 24.08.2013

мне вот это не понятно " Ардуина в режиме клиента раз в 10 секунд (например) обращается к серверу с тем же запросом GET и просит RelayState.php (например) Сервер выполняет php и отсылает клиенту в ответ. Ардуинка получит что-то типа relay1=on обработает это и включит реле. Как-то так :)"

ещё раз повторюсь -я ардуинку не очень хорошо знаю. Если не трудно,не спешите а дайте кусок хотябы кода где она будучи в режиме клиента и посылала данные с термометра (это уже реализованно) и ещё раз в 10 сек итд итп как у Вас в описании. Ардуинка получит что-то типа relay1=on обработает это и включит реле. Как-то так :)"

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Всё уже есть в примерах... Файл - Образцы - Ethernet - WebClientRepeating раз в 10 секунд запрашивает с сервера файлик latest.txt методом GET. Меняете GET запрос, например на тот что у Вас температуру отсылает и раз в 10 секунд будете получать на сервере "свежую" температуру.

Так же и с реле только вместо запроса температуры запрашиваете файлик как в стандартном примере, а этот файлик средствами php на сервере делаете, т.е. берёте с базы состояние реле и пишите relay1=on. Сервер этот подготовленный файлик передаст клиенту, клиент (ардуинка) распарсит его и в зависимости от того on или off включит или выключит реле.

Gagarin74
Offline
Зарегистрирован: 24.08.2013

бррррррррррррр  или все так просто или всё так тумманно.

я с температурой получаю и состояние реле (допустим ВКЛ).

На PHP странице сервера (компьютера) есть допустим две кнопки ВКЛ и ВЫКЛ. Так как текущее состояние ардуина нам передала ,за нами выбор или оставить или нажать (выкл). Вот тут и возникает вопрос.

Код посылки на ардуино и код приёма ардуино. Генерить посторонний файл не планируется.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

1) при нажатии на сервере кнопки ВКЛ или ВЫКЛ записываем куда-нибудь (например в БД) что мы щелкнули, например, в поле с именем relay1state

2) ничего не надо генерить, его один раз ручками написать надо (страничку с php скриптом) назвать, например, megasmarthome.php

3) ардуина раз в 10 секунд (например) шлет GET запрос на сервер вида GET /megasmarthome.php&temp1=25&relay1=getstate

4) сервер приняв запрос запустит на выполнение скрипты megasmarthome.php с параметрами temp1=25 и relay1=getstate

5) Скрипт берёт параметр temp1 и записывает его значение в БД. Далее берет параметр relay1 смотрит значение, а там getstate значит надо взять с базы состояние реле (поле relay1state) и передать его ардуине в виде да пусть хоть <H1>ON</H1>. Передать ардуине это значит что скрипт сформирует страничку (ну php обычный, так сказать динамическая страничка) вида <html><body><h1>ON</h1></body></html>

6) Ардуина на свой запрос GET получит ту самую сформированную страничку (не файлик) а просто код во входном буфере. Остаётся только посмотреть ON или OFF пришло с сервера и включить или выклчить реле.

com
Offline
Зарегистрирован: 06.09.2013

отвечать можно без тегов

valeraba
Offline
Зарегистрирован: 08.09.2014

Gagarin74 пишет:

бррррррррррррр  или все так просто или всё так тумманно.

 

Скорее первое.
Отправляя GET или POST запрос на сервер, всегда приходит ответ от сервера. Это спецификация HTTP протокола. Ответ будет содержать заголовки, которые сформирует для вас сервер, и само тело ответа, которое формируете вы. Вот в этом теле в совершенно произвольном виде вы и передадите команду для реле. Добавьте какие-нибудь ключевые слова, чтобы было легче выдрать вашу инфомацию из всего ответа, ведь заголовки вас интересовать не будут.
Формат HTTP очень простой, уж не знаю, давно бы изучили.

Gagarin74
Offline
Зарегистрирован: 24.08.2013

Добрался до ардуинки . поменял как и предлогали строчки. Не фурычит.

вот исходник . без исправлений. Отправляет нужные мне данные.Но только один раз.

/*
  Web client
 
 This sketch connects to a website (http://www.google.com)
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe, based on work by Adrian McEwen
 
 */

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
//char server[] = "www.google.com";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(172,16,2,126);
IPAddress server(80,252,153,121);
// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
  String filename = "/pr/pr.php";
  String A ="10";
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    
    String requestString="GET "+filename+"?q="+A+" HTTP/1.0";
    
    	client.println(requestString);
   // client.println("GET /search?q=arduino HTTP/1.1");
    //client.println("Host: www.google.com");
   //p://80.252.153.121/pr/pr.php
    client.println("Connection: close");
    client.println();
  } 
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop()

{
  // if there are incoming bytes available 
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
}

Запихните если не сложно это в цикл!!!!

 

com
Offline
Зарегистрирован: 06.09.2013

.. и побыстрее!

Gagarin74
Offline
Зарегистрирован: 24.08.2013

com пишет:

.. и побыстрее!

Палку не надо перегибать.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Вы смотрели стандарный пример про который я писал? WebClientRepeating. Откройте его и сразу всё поймете. Вам надо в методе httpRequest заменить 4ре строчки с запросом на свой код и всё. Поменять айпишники и если надо интервал. Понедельник день тяжелый :) Никто не хочет копипастить стандартные примеры.

com
Offline
Зарегистрирован: 06.09.2013

да, не надо. циклы хоть для приличия выучите

 

Gagarin74
Offline
Зарегистрирован: 24.08.2013

что то не фурычит

/*
  Repeating Web client
 
 This sketch connects to a a web server and makes a request
 using a Wiznet Ethernet shield. You can use the Arduino Ethernet shield, or
 the Adafruit Ethernet shield, either one will work, as long as it's got
 a Wiznet Ethernet module on board.
 
 This example uses DNS, by assigning the Ethernet client with a MAC address,
 IP address, and DNS address.
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 19 Apr 2012
 by Tom Igoe
 
 http://arduino.cc/en/Tutorial/WebClientRepeating
 This code is in the public domain.
 
 */

#include <SPI.h>
#include <Ethernet.h>

// assign a MAC address for the ethernet controller.
// fill in your address here:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// fill in an available IP address on your network here,
// for manual configuration:
IPAddress ip(172,16,2,126);
IPAddress server(80,252,153,121);
// fill in your Domain Name Server address here:
//IPAddress myDns(1,1,1,1);
String filename = "/pr/pr.php";
  String A ="10";
// initialize the library instance:
EthernetClient client;

//char server[] = "www.arduino.cc";

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 6*1000;  // delay between updates, in milliseconds
String requestString="GET "+filename+"?q="+A+" HTTP/1.0";
void setup() {
  // start serial port:
  Serial.begin(9600);
  // give the ethernet module time to boot up:
  delay(1000);
  // start the Ethernet connection using a fixed IP address and DNS server:
   Ethernet.begin(mac, ip);
  // print the Ethernet board/shield's IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
  String requestString="GET "+filename+"?q="+A+" HTTP/1.0";
}

void loop() {
  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  // if you're not connected, and ten seconds have passed since
  // your last connection, then connect again and send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    httpRequest();
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}

// this method makes a HTTP connection to the server:
void httpRequest() {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    // send the HTTP PUT request:
     String requestString="GET "+filename+"?q="+A+" HTTP/1.0";
    Serial.println(requestString);
    	client.println(requestString);
    client.println("Connection: close");
    client.println();

    // note the time that the connection was made:
    lastConnectionTime = millis();
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println("disconnecting.");
    Serial.println(requestString);
    client.stop();
  }
}

монитор порта выдает

"My IP address: 172.16.2.126
connection failed
disconnecting.
GET /pr/pr.php?q=10 HTTP/1.0
connection failed
disconnecting.
GET /pr/pr.php?q=10 HTTP/1.0
connection failed
disconnecting.
GET /pr/pr.php?q=10 HTTP/1.0
connection failed
disconnecting.
GET /pr/pr.php?q=10 HTTP/1.0
connection failed

"

не пойму в чем траблы

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

У меня Ваш код нормально работает, только что проверил поменяв только айпишники на свои. Ищите причину в своей сети.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Я неправильно выразился, код работает, выполняет то что в него заложено, но надо дорабатывать иначе начальное значение времени равно 0 и как только пройдет первых 6ть секунд метод будет вызываться в каждом цикле лооп и забивать всю сеть. Надо время последнего соединения менять не только когда успешное соединение, но и когда не смогли соединиться. тогда попытки соединения будут каждые 6ть секунд. 45 и 56 строка смысла не имеет можно удалить. Ну это так , то что на первый взгляд бросается в глаза. Смысл lastConnected тоже не понятен, в ардуино 1.5.8 этот пример не содержит lastConnected и всё отлично работает.

Gagarin74
Offline
Зарегистрирован: 24.08.2013

Дружище,выручай. Я уже на этот код смотрю пару часов и всё хуже и хуже.Я так же понимая что у Вас он может работать.У меня могут быть реальные проблемы с сеткой.

Если не трудно скиньте грамотно ПОТПРАВЛЕННЫЙ код. Очень тяжело разбираться в том что не знаешь и нет уверенности что на работе вообще это будет работать из за сетки. Хотя другие примеры худо бедно работают.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Сегдня времени нет. Ваш код из 66 поста рабочий. Надо проверять айпишники, нет ли в сети еще одного устройства с таким айпи, маршрутизатор проверять, чтобы по маку не банил, а может сервак ваш айпишник уже забанил из-за кучи запросов с интервалом в 6ть секунд

Gagarin74
Offline
Зарегистрирован: 24.08.2013

в том то и радость то что код из 66 поста у меня не работает. А вот этот код с тем же ip раотает превосходно.

Но не могу его в цикл вставить. Путуюсь в 3 березах

/*
  Web client
 
 This sketch connects to a website (http://www.google.com)
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe, based on work by Adrian McEwen
 
 */

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
//char server[] = "www.google.com";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(172,16,2,126);
IPAddress server(80,252,153,121);
// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
  String filename = "/pr/pr.php";
  String A ="10";
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    
    String requestString="GET "+filename+"?q="+A+" HTTP/1.0";
    
    	client.println(requestString);
   // client.println("GET /search?q=arduino HTTP/1.1");
    //client.println("Host: www.google.com");
   //p://80.252.153.121/pr/pr.php
    client.println("Connection: close");
    client.println();
  } 
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop()

{
  // if there are incoming bytes available 
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
}

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Разницу вижу только в одной строке Ethernet.begin(mac)

Попробуйте в скетче с 66 поста закомментировать 52 строку, а вместо неё написать Ethernet.begin(mac)

UPD

Должно заработать, если просто по мак то айпишник автоматом присвоится (DHCP) у Вас там просто свои заморочки с роутером.

Gagarin74
Offline
Зарегистрирован: 24.08.2013

вот за эту подсказку спасибо!!!!!!!!!!!!!!!!!!!!!!!!  все заработало!!!!!!

Gagarin74
Offline
Зарегистрирован: 24.08.2013

И ещё один вопрос для "Дурочка". Ардуина питается двумя спосабами (не одновременно) По USB и по питалову 12 вольт.

Когда по USB -интернет шильд да и сама ардуина работает (я имею ввиду что по сети идут данные в удаленную базу,мониторинг порта живет хорошо итд итп)

Как подключаю 12 вольт -всё глухо. Но светодиодики моргают как всегда и горелым не пахнет :)

В чем прикол?

valeraba
Offline
Зарегистрирован: 08.09.2014

Я с таким сталкивался на китайском клоне. Залечил тем, что при включении делал аппаратный ресет на W5100_RESET.
Что у вас не знаю, но симптом один в один.

Gagarin74
Offline
Зарегистрирован: 24.08.2013

а кодик рестарта не скините ?

valeraba
Offline
Зарегистрирован: 08.09.2014
bool PortableSocket::open(const __int8* aHost, __uint16 aPort) {
	//---reset the w5100 (Iteaduino IBoard Pro)----
	pinMode(47,OUTPUT);
	digitalWrite(47,LOW);
	delay(500);
	digitalWrite(47,HIGH);
	delay(50);
	pinMode(47,INPUT);
	//--------end reset-----------------------------
	socket.stop();
	if (Ethernet.begin(mac) == 0) {
		Serial.println("Failed to configure Ethernet using DHCP");
		Ethernet.begin(mac, ip);
	}
	delay(1000);
  
	if (socket.connect(aHost, aPort))
		return true;
	return false;
}

Но обязательно проверьте номер ножки, у вас может быть подругому.

Gagarin74
Offline
Зарегистрирован: 24.08.2013

ээээээээээээээээ , так у меня UNO

pinMode(47,OUTPUT); -  а у меня то какая ?