Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Подключение исполнительных устройств, датчиков, контроллеров.

Модератор: immortal

Аватара пользователя
sergejey
Site Admin
Сообщения: 4286
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 76 раз
Поблагодарили: 1559 раз
Контактная информация:

Re: Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Сообщение sergejey » Чт окт 03, 2013 5:18 pm

handy76 писал(а):Нужно либо ethernet shield прикручивать (пример Сергея http://smartliving.ru/Main/Arduino), либо через прогу Сергея ArduinoGW http://smartliving.ru/Main/ArduinoDirect.
У меня к коллегам другой вопрос: а можно ли в одном GET запросе с Ардуины менять несколько свойств одновременно?
Сейчас у меня стоит датчик DHT22 (температура и влажность). И он передает например температуру:
sprintf(buf, "GET /objects/?object=Sensor%i&op=set&p=temp&v=%0d.%d HTTP/1.0", header.from_node, (int)Uno1.temperature_Sensor, abs(temp1));
sendHTTPRequest();
И аналогично второй запрос на влажность.
А можно ли их объединить в один запрос? Я пробовал у меня не сработало, но возможно я что то сделал не так....
В одном запросе несколько переменных обновить не получится без дополнительного программирования. Можно поступить следующим образом -- сделать какой-нибудь скрипт с названием, скажем, multiData и вызывать так:
/objects/?script=multiData&a=1&b=2&c=e и т.д. по аналогии.
а в сам код скрипта уже внести следующее:
setGlobal('myObject.myProperty1',$params['a']);
setGlobal('myObject.myProperty2',$params['b']);
setGlobal('myObject.myProperty3',$params['c']);

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

Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
handy76
Сообщения: 33
Зарегистрирован: Пт авг 23, 2013 12:15 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Сообщение handy76 » Пт окт 04, 2013 8:33 am

Спасибо. :) Буду пробовать.

А еще вопрос, я не очень в PHP/

Скрипт вызываю так:
sprintf(buf, "GET /objects/?script=ArduinoSensorMultiData&a=Sensor%i&t=%0d.%d&h=%0d.%d&p=%i HTTP/1.0", header.from_node, (int)Uno1.temperature_Sensor, abs(temp1), (int)Uno1.humidity, abs(humi1), Uno1.pirState);

a=Sensor%i - это название сенсора (Sensor1, Sensor2 и т.д.)
t=%0d.%d&h=%0d.%d&p=%i - температура, влажность, датчик движения.

Теперь в скрипте нужно писать
setGlobal('myObject.myProperty1',$params['a']);

Как подставить в поле 'myObject.myProperty1' значение params['a'] объединенное с текстом .temp? Т.е. должно получиться 'Sensor1.temp'?

Пробовал так:
$sensor_t=params['a'].".temp";
setGlobal($sensor_t,$params['t']);

Но система ругается.
Аватара пользователя
sergejey
Site Admin
Сообщения: 4286
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 76 раз
Поблагодарили: 1559 раз
Контактная информация:

Re: Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Сообщение sergejey » Пт окт 04, 2013 11:34 am

Код: Выделить всё

Пробовал так:
$sensor_t=params['a'].".temp";
setGlobal($sensor_t,$params['t']);
Да вроде правильно всё. А как ругается?

Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
handy76
Сообщения: 33
Зарегистрирован: Пт авг 23, 2013 12:15 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Сообщение handy76 » Пт окт 04, 2013 12:28 pm

Пишет красным сверху:

Пожалуйста, заполните необходимые поля!

А ниже красным выделяет
Вложения
MDMError.JPG
MDMError.JPG (32.63 КБ) 16069 просмотров
Аватара пользователя
sergejey
Site Admin
Сообщения: 4286
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 76 раз
Поблагодарили: 1559 раз
Контактная информация:

Re: Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Сообщение sergejey » Пт окт 04, 2013 2:43 pm

Сразу не заметил -- надо params['a'] заменить на $params['a']
т.е. ругается на синтаксическую ошибку

Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
handy76
Сообщения: 33
Зарегистрирован: Пт авг 23, 2013 12:15 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Сообщение handy76 » Пт окт 04, 2013 4:00 pm

Семен Семеныч !!! ("Брилиантовая рука")

Виноват. Не увидел. Все заработало. Спасибо. :)
Аватара пользователя
viris
Сообщения: 89
Зарегистрирован: Вс янв 20, 2013 5:24 pm
Откуда: РФ Горловка ДНР
Благодарил (а): 1 раз
Поблагодарили: 2 раза
Контактная информация:

Re: Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Сообщение viris » Пн окт 14, 2013 8:40 pm

Всем привет. Вот попытал счастье добавить барометр BMP085 а в итоге показывает только температуру.
При запросе http://192.168.1.120/pressure на страницу выводит вот такие данные при каждом запросе температура меняется если греть датчик.
Alt(m):0 Pressure(mm Hg):5Š Temp:27.30


/**
* Контроллер-исполнительное устройство (к проекту http://smartliving.ru/)
* Platform: Arduino UNO R3 + EthernetShield W5100
* IDE: Arduino 1.0.1
*
* исполнительные устройства (реле) подключены к Digital 8 - 13
*
* /
* обращение по http://192.168.1.120/ выдаст справочную информацию по этому устройству (нужно для того, чтобы когда обращаешься
* по IP к устройству понять что это за контроллер и пр.)
*
* /state - состояние всез портов
* /command - выполнение команды
* команды можно вызывать серией в 1 запросе. Например http://192.168.1.120/command?3=CLICK&4=CLICK&5=ON&6=OFF
* только длинна строки запроса не должна привышать maxLength
* /getdev - получить список всех устройст на 1-wire
* формат вывода:
* T<номер устройства на шине>:<HEX адрес устройства>:<текущая температура в градусах цельсия>;[...]
* (пример T0:1060CF59010800E3:24.06;T1:109ABE59010800FE:24.56;)
*
*
**/

#include <Ethernet.h>
#include <SPI.h>
#include <Arduino.h>
#include "WebServer.h"// Webduino (https://github.com/sirleech/Webduino)
#include <OneWire.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#include <BMP085.h>

BMP085 dps = BMP085();

long Temperature = 0, Pressure = 0, Altitude = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xE4, 0xDE, 0x35 }; // MAC-адрес нашего устройства
byte ip[] = { 192, 168, 1, 120 };
byte subnet[] = { 255, 255, 255, 0 };
byte gateway[] = { 192, 168, 1, 1 };
byte dns_server[] = { 192, 168, 1, 1 };
// ip-адрес удалённого сервера
byte rserver[] = { 192, 168, 1, 3};

// Настройки выходов
int startPort=3;
int endPort=9;

// Настойка аналоговых входов
int startAn=1;
int endAn=2;

// Настройка входов
//int startPin=1;
//int endPin=5;

int old_entry=0;
char buf[80];

#define MAX_PINS 4 //здесь указываем максимальное количество входов 4
const byte pin_array[MAX_PINS] = { 3, 4, 5, 6 }; //номера используемых пинов
byte val_array[MAX_PINS] ={ 0, 0, 0, 0 }; //предыдущие значения для каждого порта

// Pin controller for connection data pin DS18S20
#define ONE_WIRE_BUS 2 // Digital 2 pin Arduino (куда подключен выход с шины датчиков DS18X20
#define TEMPERATURE_PRECISION 9

#define VERSION_STRING "0.1"
#define COMPILE_DATE_STRING "2013-10-14"

P(Page_info) = "<html><head><title>Bessonova 42/368 controller " VERSION_STRING "</title></head><body>\n";
P(location_info) = "Bessonova 42/368";
P(pin_info) = "D2 - 1-wire (many DS18S20)<br>D3-light undergroung";
P(version_info) = VERSION_STRING ". Compile date: " COMPILE_DATE_STRING;

String url = String(60);
int maxLength=50; // Максимальная длинна строки запроса

#define delayClick 1000 // задержка при обычном CLICK
#define delayLClick 3000 // задержка при длинном LCLICK
#define MAX_COMMAND_LEN (10)
#define MAX_PARAMETER_LEN (10)
#define COMMAND_TABLE_SIZE (9)
#define PREFIX ""

WebServer webserver(PREFIX, 80);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// Для поиска
DeviceAddress Termometers;
float tempC;

#define NAMELEN 32
#define VALUELEN 32

char gCommandBuffer[MAX_COMMAND_LEN + 1];
char gParamBuffer[MAX_PARAMETER_LEN + 1];
long gParamValue;

typedef struct {
char const *name;
void (*function)(WebServer &server);
} command_t;

command_t const gCommandTable[COMMAND_TABLE_SIZE] = {
//{"LED", commandsLed, },
{"HELP", commandsHelp, }, // Выводит список комманд (вызов http://192.168.1.120/command?8=HELP )
{"ON", commandsOn, }, // Устанавливает "1" на заданном цифровом порту (вызов http://192.168.1.120/command?8=ON )
{"OFF", commandsOff, }, // Устанавливает "0" на заданном цифровом порту (вызов http://192.168.1.120/command?8=OFF )
{"STATUS", commandsStatus, }, // Получить состояние цифрового порта (1 или 0) (вызов http://192.168.1.120/command?8=STATUS ),
// если вместо номера порта передать ALL (вызов http://192.168.1.120/command?ALL=STATUS ), то получим состояние всех портов (Пример вывода P3=0;P4=0;P5=0;P6=0;P7=0;P8=1;P9=1;)
{"CLICK", commandsClick, }, // Кратковременная "1" на порту 1сек (время настраивается) (вызов http://192.168.1.120/command?8=CLICK )
{"LCLICK", commandsLClick, }, // Кратковременная "1" на порту 3сек (время настраивается) (вызов http://192.168.1.120/command?8=LCLICK )
{"AN", commandsAn, },
{NULL, NULL }
};

/**********************************************************************************************************************
*
* Function: cliProcessCommand
*
* Description: Look up the command in the command table. If the
* command is found, call the command's function. If the
* command is not found, output an error message.
*
* Notes:
*
* Returns: None.
*
**********************************************************************/
void cliProcessCommand(WebServer &server)
{
int bCommandFound = false;
int idx;

gParamValue = strtol(gParamBuffer, NULL, 0); // Convert the parameter to an integer value. If the parameter is empty, gParamValue becomes 0.
for (idx = 0; gCommandTable[idx].name != NULL; idx++) { // Search for the command in the command table until it is found or the end of the table is reached. If the command is found, break out of the loop.
if (strcmp(gCommandTable[idx].name, gCommandBuffer) == 0) {
bCommandFound = true;
break;
}
}

if (bCommandFound == true) { // Если команда найдена (в массиве команд), то выполняем ее. Если нет - игнорируем
(*gCommandTable[idx].function)(server);
}
else { // Command not found
server.print("ERROR: Command not found");
}
}


/**********************************************************************************************************************/
/* Обработчики команд */

void commandsAn(WebServer &server) {
int anValue;
if (gParamValue>=startAn && gParamValue<=endAn)
anValue = analogRead(gParamValue);
Serial.print("Analog");
Serial.print(gParamValue);
Serial.print("=");
Serial.println(anValue);

}

void commandsOn(WebServer &server) {
if (gParamValue>=startPort && gParamValue<=endPort) {
digitalWrite(gParamValue,HIGH);
EEPROM.write(gParamValue,HIGH);
//Serial.print("Port "); //для отладки
//Serial.print(gParamValue); //для отладки
//Serial.println(" = ON"); //для отладки
} else ErrorMessage(server);
}

void commandsOff(WebServer &server) {
if (gParamValue>=startPort && gParamValue<=endPort) {
digitalWrite(gParamValue,LOW);
EEPROM.write(gParamValue,LOW);
//Serial.print("Port "); //для отладки
//Serial.print(gParamValue); //для отладки
//Serial.println(" = OFF"); //для отладки
} else ErrorMessage(server);
}

void commandsClick(WebServer &server) {
if (gParamValue>=startPort && gParamValue<=endPort) {
digitalWrite(gParamValue,HIGH);
delay(delayClick);
digitalWrite(gParamValue,LOW);
} else ErrorMessage(server);
}

void commandsLClick(WebServer &server) {
if (gParamValue>=startPort && gParamValue<=endPort) {
digitalWrite(gParamValue,HIGH);
delay(delayLClick);
digitalWrite(gParamValue,LOW);
} else ErrorMessage(server);
}

void commandsStatus(WebServer &server) {
if (strcmp(gParamBuffer, "ALL") == 0) { // выдать состояние всех пинов
for(int i=startPort;i<=endPort;i++) {
int st=digitalRead(i);
char my_st[5];
itoa(st,my_st,10);
server.print("P");
server.print(i);
server.print("=");
server.print(my_st);
server.print(";");
}
} else { // выдать состояние только 1 пина
if (gParamValue>=startPort && gParamValue<=endPort) {
server.print("P");
server.print(gParamValue);
server.print("=");
server.print(digitalRead(gParamValue));

} else ErrorMessage(server);
}
}

void commandsHelp(WebServer &server) {
int idx;
for (idx = 0; gCommandTable[idx].name != NULL; idx++) {
server.print(gCommandTable[idx].name);
server.print("<br>");
}
}

/**********************************************************************************************************************/

void ErrorMessage(WebServer &server) {
server.print("ERROR: This Pin is not configured for I/O");
}

/**********************************************************************************************************************
* Разбор запроса
**/
void parsedRequest(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
URLPARAM_RESULT rc;
char name[NAMELEN];
int name_len;
char value[VALUELEN];
int value_len;

server.httpSuccess(); // this line sends the standard "we're all OK" headers back to the browser

/* if we're handling a GET or POST, we can output our data here.
For a HEAD request, we just stop after outputting headers. */
if (type == WebServer::HEAD)
return;

if (strlen(url_tail))
{
while (strlen(url_tail)) // Разбор URI на составные части (выборка параметров)
{
rc = server.nextURLparam(&url_tail, name, NAMELEN, value, VALUELEN);
if (rc == URLPARAM_EOS) {
// server.printP(Params_end);
}
else // Получили параметр (name) и его значение (value)
{
// Выполняем команды
strcpy (gCommandBuffer, value); // параметры (значение)
strcpy (gParamBuffer, name); // команда
cliProcessCommand(server);
}
}
}
/*
if (type == WebServer::POST)
{
server.printP(Post_params_begin);
while (server.readPOSTparam(name, NAMELEN, value, VALUELEN))
{
server.print(name);
server.printP(Parsed_item_separator);
server.print(value);
server.printP(Tail_end);
}
}
*/

}

void get1wireDevices(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
//TODO получить все устройства на шине и выдать на страницу
int numberOfDevices = sensors.getDeviceCount();
sensors.begin();
for(int i=0;i<numberOfDevices; i++) {
if(sensors.getAddress(Termometers, i))
{
server.print("T");
server.print(i);
server.print(":");
for (uint8_t i = 0; i < 8; i++) {
if (Termometers < 16) server.print("0");
server.print(Termometers, HEX);
}
float tempC = sensors.getTempC(Termometers);
server.print(":");
server.print(tempC);
server.print(";");
} else {
// not found
server.print("NOT FOUND");
}
}
}


void stateRequest(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
strcpy (gParamBuffer, "ALL");
commandsStatus(server);
}
/*********************************************************************************************************************
*Получение данных из BMP085
**/
void getBMP085Devices(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
//TODO получить данные из BMP085 и выдать на страницу
dps.getPressure(&Pressure);
dps.getAltitude(&Altitude);
dps.getTemperature(&Temperature);

server.print(" Alt(m):");
server.print(Altitude/100);
server.print(" Pressure(mm Hg):");
server.print(Pressure/133,3223684);
server.print(" Temp:");
server.println(Temperature*0.1);
delay(2000);
}

/**********************************************************************************************************************
* Генерация и вывод информации об устройстве
**/
void infoRequest(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
server.printP(Page_info);
server.print("IP:");
server.print(Ethernet.localIP());
server.print("<br>Location: ");
server.printP(location_info);
server.print("<hr>Pin info:<br>");
server.printP(pin_info);
server.print("<hr>Pin current state: ");
strcpy (gParamBuffer, "ALL");
commandsStatus(server);
server.print("<hr><a href='/getdev'>1-wire devices</a>");
server.print("<hr><a href='/pressure'>BMP085</a>");
server.print("<hr>Commands: <br>");
commandsHelp(server);
server.print("<hr><br>Version info: ");
server.printP(version_info);

}

/**********************************************************************************************************************
* Поиск устройств (датчиков температуры на шине 1-wire)
**/
void searchDevices() {
Serial.println("Start search on 1-wire");
int numberOfDevices = sensors.getDeviceCount();
sensors.begin();

for(int i=0;i<numberOfDevices; i++) {
if(sensors.getAddress(Termometers, i))
{
Serial.print("Found device ");
Serial.print(i, DEC);
Serial.print(" with address: ");
for (uint8_t i = 0; i < 8; i++) {
if (Termometers < 16) Serial.print("0");
Serial.print(Termometers, HEX);
}

Serial.print("Resolution actually set to: ");
Serial.print(sensors.getResolution(Termometers), DEC);
Serial.println();
float tempC = sensors.getTempC(Termometers);
Serial.print(tempC);
Serial.println("C");

} else {
// not found
}
}
}

/**********************************************************************************************************************/
void setup() {
// Для дебага будем выводить отладочные сообщения в консоль
// TODO Убрать вывод в консоль "за дабаг" (т.е. вывод только если скимпилированно с поддержкой дебага)
Serial.begin(9600);
Wire.begin();
delay(1000);
dps.init();
Serial.println("Start");

Ethernet.begin(mac, ip, dns_server, gateway, subnet); // Инициализируем Ethernet Shield

webserver.setDefaultCommand(&infoRequest); // дефолтная страница вывода (информация о контроллере)
webserver.addCommand("command", &parsedRequest); // команды
webserver.addCommand("state", &stateRequest); // выдать состояния всех устройств
webserver.addCommand("getdev", &get1wireDevices); // получить список устройств на 1-wire
webserver.addCommand("pressure", &getBMP085Devices); // получить данные из BMP085
webserver.begin();

Serial.print("server is at ");
Serial.println(Ethernet.localIP());

// Настройка портов на вывод
for (int thisPort = startPort; thisPort <=endPort; thisPort++) {
pinMode(thisPort, OUTPUT);
digitalWrite(thisPort, EEPROM.read(thisPort));
//Serial.print("EEPROM"); //для отладки
//Serial.print(thisPort); //для отладки
//Serial.print(" = "); //для отладки
//Serial.println(EEPROM.read(thisPort)); //для отладки
}

// Настройки 1-wire
sensors.begin(); // Инициализация шины 1-wire (для датчиков температуры)
sensors.requestTemperatures(); // Перед каждым получением температуры надо ее запросить

searchDevices();

}

/**********************************************************************************************************************/
void loop() {
char buff[64];
int len = 64;
webserver.processConnection(buff, &len); // process incoming connections one at a time forever
sensors.requestTemperatures(); // Перед каждым получением температуры надо ее запросить

for( int i = 0; i < MAX_PINS; i++) //цикл переберает значения MAX_PIN попорядку
{
val_array = EEPROM.read(i);
byte l_pin_state = digitalRead(pin_array); //считать данные и записать в l_pin_state
if( l_pin_state != val_array ) // сравнить l_pin_state и val_array
{
Serial.print("Pin");
Serial.print(pin_array);
Serial.print("=");
Serial.println(l_pin_state);
val_array = l_pin_state; // записать текущее значение в val_array
EEPROM.write(i, l_pin_state);

delay(20);
}
}
}
Аватара пользователя
viris
Сообщения: 89
Зарегистрирован: Вс янв 20, 2013 5:24 pm
Откуда: РФ Горловка ДНР
Благодарил (а): 1 раз
Поблагодарили: 2 раза
Контактная информация:

Re: Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Сообщение viris » Пн окт 14, 2013 10:26 pm

Сам нашол ошибку server.print(Pressure/133,3223684); Должно быть так server.print(Pressure/133.3223684);

Теперь вопрос как это давление вывести в MajorDomo??? ПОМОГИТЕ. Чет ладу не дам. Подключено к Arduino.
Konstantin
Сообщения: 2
Зарегистрирован: Вт окт 15, 2013 6:25 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Сообщение Konstantin » Вт окт 15, 2013 6:48 pm

Добрый день!
Возник вопрос такого плана - получаю с сервера (скетч из сообщения 175), веб-переменными строку с датчиками ds - такого типа T0:283CF96E010000F5:26.81;T1:28FCCA6E010000A0:26.81;T2:28B2BD6E010000FA:26.87;
Если создаю 3 веб-переменные 1-я с маской T0:(.+?);, 2-я с T1:(.+?); 3-я с T2:(.+?);
От первой получаю данные, от двух других - нет. В php - чайник. Подскажите, плз, как правильно сделать вывод. Желательно с разбивкой в массив с hex номером и температурой и присвоением переменным датчиков.
Аватара пользователя
viris
Сообщения: 89
Зарегистрирован: Вс янв 20, 2013 5:24 pm
Откуда: РФ Горловка ДНР
Благодарил (а): 1 раз
Поблагодарили: 2 раза
Контактная информация:

Re: Скетч Arduino + W5100 обсуждаем, пишем, тестируем

Сообщение viris » Вт окт 15, 2013 7:48 pm

Konstantin писал(а):Добрый день!
Возник вопрос такого плана - получаю с сервера (скетч из сообщения 175), веб-переменными строку с датчиками ds - такого типа T0:283CF96E010000F5:26.81;T1:28FCCA6E010000A0:26.81;T2:28B2BD6E010000FA:26.87;
Если создаю 3 веб-переменные 1-я с маской T0:(.+?);, 2-я с T1:(.+?); 3-я с T2:(.+?);
От первой получаю данные, от двух других - нет. В php - чайник. Подскажите, плз, как правильно сделать вывод. Желательно с разбивкой в массив с hex номером и температурой и присвоением переменным датчиков.
Та же проблема. Только получаю данные с BMP085 Altitude Pressure Temperature а в итоге можно только одно значение вывести.
Ответить