Ethernet Shield отправка данных на сервер

paz001
Offline
Зарегистрирован: 23.08.2015

Доброго дня.

Стоит задача отправки на сервер показаний датчика - сработал/несработал. Дальше на сервере  уже обработать разными способами.

Объясните на пальцах как организовать отправку на ПК данных.  

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Вариант 1:

Ардуино работает в роли сервера. Вы обращаетесь к этому серверу с ПК посредством http-запросов для получения данных. Ардуино, обрабатывает ваши запросы и отдает нужные данные.

 

Вариант 2:

Ардуино работает в роли клиента. Нужен сторонний сервер. Ардуино передает на этот сервер данные, посредством http-запросов. Вы обращаетесь к этому серверу с ПК посредством http-запросов для получения данных.

paz001
Offline
Зарегистрирован: 23.08.2015

про вариант№2

а если в качестве сервера будет какая нибудь програмка на winsock'е? возможно ли в ардуине подготовить данные для этого сервера?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

paz001 пишет:

про вариант№2

а если в качестве сервера будет какая нибудь програмка на winsock'е? возможно ли в ардуине подготовить данные для этого сервера?

Любой web-сервер это не что иное, как программа на winsock'е или его аналогах в других системах. Так что чего ж тут невозможного?

paz001
Offline
Зарегистрирован: 23.08.2015

ЕвгенийП пишет:

paz001 пишет:

про вариант№2

а если в качестве сервера будет какая нибудь програмка на winsock'е? возможно ли в ардуине подготовить данные для этого сервера?

Любой web-сервер это не что иное, как программа на winsock'е или его аналогах в других системах. Так что чего ж тут невозможного?

Меня немного смущают данные (т.е. мне совершенно не понятно как они устроены), которые я буду отправлять с клиента на сервер. Сервер не веб, а просто ПК с линухом.

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

paz001, вам следует сначала понять, чего вы хотите.

 

Веб-сервер для ваших нужд можно развернуть на любом компьютере, подключенном к сети (даже локальной, был бы доступ). Не обязательно ПК - можно даже на роутере, РасПи, другой Ардуино и т.п.

paz001
Offline
Зарегистрирован: 23.08.2015

Gippopotam пишет:

paz001, вам следует сначала понять, чего вы хотите.

100% Ваша правда)

Вообще идея следующая: есть инфракрасный датчик движений. Необходимо регистрировать движение рук в зоне мониторинга и отправлять единицу на удаленный пк. Дальше эту единицу т.е. к факт срабатывания, конкатенируем со временем этой удаленной машины и все это дела сохраняем в файл гденибудь. Далее аналитическое ПО само берет из файла данные и что то сними делает. 

Код клиента.

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


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
byte server[] = { 192, 168, 1, 62 }; 
int val = 1; // датчик сработал
EthernetClient client;


void setup() {

Ethernet.begin(mac, ip);
Serial.begin(9600);
 
delay(1000);
 
Serial.println("connecting...");
 
if (client.connect(server, 8080)) {
  Serial.println("connected");
  client.println("GET /search?q=arduino HTTP/1.0");
  client.println();
} else {
  Serial.println("connection failed");
}
}

void loop() {
char buf[80]; // на всякий случай, вдруг отправить нужно массив данных
client.println(val); // или client.print(buf) Отправляем запрос, который обработается сервером

while (client.available()) {
int  isdata=1;
  char c = client.read(); // Читаем, что нам ответил Web-сервер
  Serial.print(c);  
 }
if (!client.connected()) {
int  isdata=0;
  Serial.println();
  Serial.println("disconnecting.");
client.stop();
}
}

Если будут какие либо предложения по реализации, то с удовольствием ознакомлюсь. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

paz001 пишет:

Меня немного смущают данные (т.е. мне совершенно не понятно как они устроены), которые я буду отправлять 

Тогда у Вас действительно большие проблемы и "помощь зала" здесь бессильна.

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

paz001 пишет:

Если будут какие либо предложения по реализации, то с удовольствием ознакомлюсь. 

Это вы, типа конкурс объявляете?

paz001
Offline
Зарегистрирован: 23.08.2015

Gippopotam пишет:

Это вы, типа конкурс объявляете?

какой конкурс, помощь зала, не более

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

paz001 пишет:

Gippopotam пишет:

Это вы, типа конкурс объявляете?

какой конкурс, помощь зала, не более

Сделайте простой сервер на Ардуино. Возьмите скетч из примера - он вроде умеет температуру отдавать.

Любым клиентом с ПК забирайте данные с этого сервера.

maxi_10
Offline
Зарегистрирован: 05.01.2012

<p>[/quote]</p>
<p>Меня немного смущают данные (т.е. мне совершенно не понятно как они устроены), которые я буду отправлять с клиента на сервер. Сервер не веб, а просто ПК с линухом.</p>
<p>[/quote]</p>

На линуксе вообще сервер можно написать в блокноте.

Вечером домой приду найду и выложу исходники своего старого проекта "СКУД для дворового спрт-зала"

https://www.youtube.com/watch?v=nE_Lr29Wlxs

maxi_10
Offline
Зарегистрирован: 05.01.2012

Нашол более старую версию нежли в видео ролике выше.

Сервер.

#!/bin/bash

CLIENTIP="Localhost"
PortIN="27050"
PortOUT="27051"

declare -f LOAD

function LOAD()
{
EX="0"
#nc -l "$PortIN" | tr -d '\000' | tr -d '\\r' | while read line; do 
nc -l "$PortIN" | tr -d '\000' | while read line; do 
if [ -n "$line" ]; then
	if [[ "$line" > "0000" ]]; then
		echo "$(date) ===>>>	GET		$line" >> Log.txt
		nline="$(echo $line | sed 's/^[ \t]*//;s/[ \t]*$//')"
		
		N1="$(echo "$nline" | cut -d, -f1)"
		N2="$(echo "$nline" | cut -d, -f2)"
		N3="$(echo "$nline" | cut -d, -f3)"
		N4="$(echo "$nline" | cut -d, -f4)"
		N5="$(echo "$nline" | cut -d, -f5)"
		N6="$(echo "$nline" | cut -d, -f6)"
		N7="$(echo "$nline" | cut -d, -f7)"
		case $N1 in
		cls)
			clear
			echo "$(date) ===>>>	Получена команда очистки терминала {cls}" >> Log.txt
			echo "$(date) ==============================================" >> Log.txt
		;;
		end)
			echo "$(date) ===>>>	Получена команда Выхода {end}" >> Log.txt
			echo "Exit"
			echo "$(date) ==============================================" >> Log.txt
			tput sgr0
			break
			EX="1"
		;;		
		new)
			echo ""
			echo "=============================================="
			echo "        $(date)"
			echo "Запись добавленна в базу"
			echo "$N2,	$N3,		$N4,	$N5,$N6,	$N7" >> Base.bas
			echo "ID - $N2"
			echo "Login - $N3"
			echo "$(date) ===>>>	Получена команда добавление записи в базу {new}" >> Log.txt
			echo "$(date) ===>>>	$N2	$N3	$N4	$N5	$N6	$N7" >> Log.txt
			echo "=============================================="
			echo ""
			echo "$(date) ==============================================" >> Log.txt
		;;
		chg)
			echo ""
			echo "=============================================="
			echo "        $(date)"
			echo "Запись в базе изменена"
			sed -i 's/^'$N2'.*/'$N2','$N3','$N4','$N5','$N6','$N7'/' Base.bas
			echo "ID - $N2"
			echo "Login - $N3"
			echo "$(date) ===>>>	Получена команда изменения записи в базе {chg}" >> Log.txt
			echo "$(date) ===>>>	$N2	$N3	$N4	$N5	$N6	$N7" >> Log.txt
			echo "=============================================="
			echo ""
			echo "$(date) ==============================================" >> Log.txt
		;;
		wr)
			echo ""
			echo "=============================================="
			echo "        $(date)"
			echo "BeckUP базы данных создан"
			cp Base.bas Base.bas.bkp
			echo "$(date) ===>>>	Получена команда на создание BeckUP файла базы {wr}" >> Log.txt
			echo "=============================================="
			echo ""
			echo "$(date) ==============================================" >> Log.txt
		;;		
		*)
			METADATA="$(cat "Base.bas" | grep -e "^$nline,")" # Основная фуункция поиска в базе
			
			RFID="$(echo $METADATA | cut -d, -f1 | sed 's/^[ \t]*//;s/[ \t]*$//')"
			LOGIN="$(echo $METADATA | cut -d, -f2 | sed 's/^[ \t]*//;s/[ \t]*$//')"
			TYPE="$(echo $METADATA | cut -d, -f3 | sed 's/^[ \t]*//;s/[ \t]*$//')"
			DATAON="$(echo $METADATA | cut -d, -f4 | sed 's/^[ \t]*//;s/[ \t]*$//')"
			DATAOFF="$(echo $METADATA | cut -d, -f5 | sed 's/^[ \t]*//;s/[ \t]*$//')"
			COUTN="$(echo $METADATA | cut -d, -f6 | sed 's/^[ \t]*//;s/[ \t]*$//')"
			STATUS="NULL"
			DCM="1"
			todaydate=`date +%d.%m.%Y`

			AD="$(echo $DATAOFF | cut -d. -f1)"
			AM="$(echo $DATAOFF | cut -d. -f2)"
			AY="$(echo $DATAOFF | cut -d. -f3)"

			CD=`date +%d`
			CM=`date +%m`
			CY=`date +%Y`

				if [ -n "$RFID" ]; then
					echo "$(date) ===>>>	$RFID	$LOGIN	$TYPE	$DATAON	$DATAOFF	$COUTN" >> Log.txt
					echo ""
					echo "=============================================="
					echo "        $(date)"
					echo "ID - $RFID"
					echo "Login - $LOGIN"
					if [ "$TYPE" -eq "0" ]; then
						echo "Type - Безлимитный"
						echo -e '\E[32;40m'"Status OPEN"; tput sgr0
						echo "$TYPE,$LOGIN" | nc "$CLIENTIP" "$PortOUT"
						echo "$(date) ===>>>	Status OPEN" >> Log.txt
					fi
					#-----------------------------------------------
					if [ "$TYPE" -eq "1" ]; then
						if [ "$CY" -le "$AY" ]; then
							if [ "$CM" -le "$AM" ]; then
								if [ "$CD" -le "$AD" ]; then	
										echo "Type - Действует до $DATAOFF"
										echo -e '\E[32;40m'"       $DATAON - $DATAOFF"; tput sgr0
										echo -e '\E[32;40m'"Status OPEN"; tput sgr0
										echo "$(date) ===>>>	Status OPEN" >> Log.txt
								else
									echo "Обонемент просрочен на несколько дней"
									echo -e '\E[31;40m'"       $DATAON - $DATAOFF"; tput sgr0
									echo -e '\E[31;40m'"Status CLOSE"; tput sgr0
									echo "$(date) ===>>>	Status CLOSE - Обонемент просрочен на несколько дней" >> Log.txt
								fi
							else
								echo "Обонемент просрочен на несколько месяцев"
								echo -e '\E[31;40m'"       $DATAON - $DATAOFF"; tput sgr0
								echo -e '\E[31;40m'"Status CLOSE"; tput sgr0
								echo "$(date) ===>>>	Status CLOSE - Обонемент просрочен на несколько месяцев" >> Log.txt
							fi
						else
							echo "Обонемент просрочен на несколько лет"
							echo -e '\E[31;40m'"       $DATAON - $DATAOFF"; tput sgr0
							echo -e '\E[31;40m'"Status CLOSE"; tput sgr0
							echo "$(date) ===>>>	Status CLOSE - Обонемент просрочен на несколько лет" >> Log.txt
						fi
					fi
					#----------------------------------------------- 
					if [ "$TYPE" -eq "2" ]; then
						if [ "$COUTN" -eq "0" ]; then
							echo "На абонементе кончились занятия"
							echo -e '\E[31;40m'"Status CLOSE"; tput sgr0
							echo "$(date) ===>>>	Status CLOSE - На абонементе кончились занятия" >> Log.txt
						else
							MODCOUTN=$[$COUTN-$DCM]
							echo "Type - Осталось $MODCOUTN занятий"
								sed -i 's/^'$RFID'.*/'$RFID','$LOGIN','$TYPE','$DATAON','$DATAOFF','$MODCOUTN'/' Base.bas
								echo -e '\E[32;40m'"Status OPEN"; tput sgr0
								echo "$(date) ===>>>	Status OPEN" >> Log.txt
						fi
					fi
					echo "=============================================="
					echo ""
				else
					echo ""
					echo "=============================================="
					echo "        $(date)"
					echo "ID - $line"
					echo -e '\E[31;40m'"Не верный код карты, данные в базе не найденны"; tput sgr0
					echo "$(date) ===>>>	Не верный код карты, данные в базе не найденны" >> Log.txt
					echo "=============================================="
					echo ""
				fi
			RFID=""
			LOGIN=""
			TYPE=""
			DATAON=""
			DATAOFF=""
			COUTN=""
		;;
		esac
		echo "$(date) ==============================================" >> Log.txt
	fi
else
	echo ""
	echo "=============================================="
	echo "        $(date)"
	echo -e '\E[31;40m'"Нет данных"; tput sgr0
	echo "$(date) ===>>>	Нет данных" >> Log.tx
	echo "=============================================="
	echo ""
fi
done
if [ "$EX" -eq "0" ]; then
	LOAD
else
	exit 0
fi
}
LOAD

tput sgr0
exit 0

 

 

Клиент на Линуксе

#!/bin/bash

echo $1 | nc localhost 27050
#nc -l -v 27051 | tr -d '\000' | tr -d '\\r' | while read line; do; echo "$line"; done
exit 0

 

Клиент на Ардуино

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

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress ip(192,168,1,57);
char server[] = "192.168.1.58";



EthernetClient client;

void setup() {
  Serial.begin(9600);
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    Ethernet.begin(mac, ip);
  }
  delay(500);
  Serial.println("connecting...");

  if (client.connect(server, 27050)) {
    Serial.println("connected");
    client.print("798");
    client.print("\n");
    client.stop();
  } 
  else {
    Serial.println("connection failed");
  }
}

vvoid loop()
{

}


 

 

Образец базы данных для тестов


#RFID 	- Номер карточки который высвечивается при сканировании.
#Login 	- Имя и инициалы клиента спортивного зала.
#Type 	- Тип абонемента: 
#						0 - Безлимитный абонемент
#						1 - абонемент на месяц или более (до указанной даты).
#						2 - абонемент на количество занятий (количество указывается в последней цифре).
#						3 - абонемент на месяц или более с посещением до 16 часов (до указанной даты).
#						4 - абонемент на количество занятий с посещением до 16 часов (количество указывается в последней цифре).
#						
#DataON 	- Дата начала действия абонемента (необходимо указывать только вслучае если указан тип "1").
#DataOFF - Дата окончания действия абонемента (необходимо указывать только вслучае если указан тип "1").
#Count	- Количество занятий на абонементе (это поле будет автоматически уменьшатся пока не дойдет до нуля).
#
#Если необходимо заблокировать клиента, перед его RFID кодом необходимо поставить символ # (Пример: 
	#00155753,Захаров_МИ,0,0,0,0 - этот пользователь не сможет отмечатся картой.
#
#=================================================================================================================

=========================================

# Безлимитные абонементы
134-417,	Malysheva_AF,	0,0,0,0



=========================================

# Абонементы по колличеству посещений
00000348,	Poltavskih_DM,	2,0,0,9
00000798,Sotnikov_AO,4,0,0,9
00000123,	Kalinin_ES,		2,0,0,	0
88-6435,	Zakhaov_MI,		2,0,0,49

=========================================

# Месячные абонементы
00000679,	Vasilev_DV,		1,	22.07.2014,	22.08.2014,	0
00000258,	Коровкин_МА,	1,	23.07.2014,	23.08.2014,	0
00000412,	Antonov_DV,		3,	22.05.2014,	31.07.2014,	0
00000800,	Chekrygin_DV,	1,	22.05.2014,	21.07.2014,	0
00000250,	Коровкин_МА,	1,	23.07.2014,	23.08.2014,	0

 

maxi_10
Offline
Зарегистрирован: 05.01.2012

paz001 пишет:

Gippopotam пишет:

paz001, вам следует сначала понять, чего вы хотите.

100% Ваша правда)

Вообще идея следующая: есть инфракрасный датчик движений. Необходимо регистрировать движение рук в зоне мониторинга и отправлять единицу на удаленный пк. Дальше эту единицу т.е. к факт срабатывания, конкатенируем со временем этой удаленной машины и все это дела сохраняем в файл гденибудь. Далее аналитическое ПО само берет из файла данные и что то сними делает. 

Код клиента.

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


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
byte server[] = { 192, 168, 1, 62 }; 
int val = 1; // датчик сработал
EthernetClient client;


void setup() {

Ethernet.begin(mac, ip);
Serial.begin(9600);
 
delay(1000);
 
Serial.println("connecting...");
 
if (client.connect(server, 8080)) {
  Serial.println("connected");
  client.println("GET /search?q=arduino HTTP/1.0");
  client.println();
} else {
  Serial.println("connection failed");
}
}

void loop() {
char buf[80]; // на всякий случай, вдруг отправить нужно массив данных
client.println(val); // или client.print(buf) Отправляем запрос, который обработается сервером

while (client.available()) {
int  isdata=1;
  char c = client.read(); // Читаем, что нам ответил Web-сервер
  Serial.print(c);  
 }
if (!client.connected()) {
int  isdata=0;
  Serial.println();
  Serial.println("disconnecting.");
client.stop();
}
}

Если будут какие либо предложения по реализации, то с удовольствием ознакомлюсь. 

 

собственно вам на линухе необходимо запустить только эту строчку

nc -l "$PortIN"
$PortIN - указать порт который будет слушать сервер

соответственно ардуино данные должна слать на этот порт.

paz001
Offline
Зарегистрирован: 23.08.2015
 if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
 
а с чем может быть связано Failed to configure Ethernet using DHCP?
 
мак адрес есть, ip пингуется, а mac == 0?
 
----------
UPD: разобрался
maxi_10
Offline
Зарегистрирован: 05.01.2012

Написал для вас линукс сервер который слушает порт 27050 и всё что понему приходит записывает в лог файл.

#!/bin/bash

PortIN="27050"

declare -f LOAD

function LOAD(){

nc -l "$PortIN" | while read line; do
echo $line >> logFor.log
LOAD
done
}

LOAD

exit 0



на диске в папке создать файл:

$ vi Server.sh

на экране нажимаем "A" или "I"

Вставляем в файл мой код, нажимаем Esc, вводим :w или Shift + ZZ

далее выполняем команду:

$ sudo chmod 777 Serveer.sh

В водим пароль администратора.

Запускаем сервер:

$ ./Server.sh

Всё.

Теперь всё что придет на порт 27050 будет записано в лог файл который будет лежать в текущей папке.

Линукс это система где всё ограниченно лишь твоей фантазией.

 

boban_
Offline
Зарегистрирован: 09.10.2013

Поправлю:

$ sudo chmod 777 Server.sh

Спасибо за код.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

boban_ пишет:
Поправлю: $ sudo chmod 777 Server.sh

"Это - неправильные пчелы" (с) Зачем же делать файл world writable? :)

chmod +x Server.sh

 

maxi_10
Offline
Зарегистрирован: 05.01.2012

Спасибо, опечатался.

paz001
Offline
Зарегистрирован: 23.08.2015

maxi_10 пишет:

собственно вам на линухе необходимо запустить только эту строчку

nc -l "$PortIN"
$PortIN - указать порт который будет слушать сервер

соответственно ардуино данные должна слать на этот порт.

Максим, большое спасибо за сорцы и видео. 

Вобщем и целом мне удалось запуститься в тестовом режиме.

 

maxi_10
Offline
Зарегистрирован: 05.01.2012

А скрипт из сообщения 15 не получилось запустить?

paz001
Offline
Зарегистрирован: 23.08.2015

maxi_10 пишет:

А скрипт из сообщения 15 не получилось запустить?

Говоря "удалось запуститься" имел ввиду клиентское по на ардуинке.

Мне только сегодня-завтра предоставят пк для "стендовых испытаний" и настройки датчика.

maxi_10
Offline
Зарегистрирован: 05.01.2012

paz001 пишет:

maxi_10 пишет:

А скрипт из сообщения 15 не получилось запустить?

Говоря "удалось запуститься" имел ввиду клиентское по на ардуинке.

Мне только сегодня-завтра предоставят пк для "стендовых испытаний" и настройки датчика.

Я имею ввиду ты запустил тот скрипт который я написал в 15 сообщении, он работает в фоне и пишет в лог всё что ты кидаешь на TCP порт? Или ты только nc -l 27050 запустил проверил?