uno+5100 нужна помощь

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

Модератор: immortal

Ответить
artemon25
Сообщения: 112
Зарегистрирован: Чт авг 25, 2016 10:33 pm
Благодарил (а): 15 раз
Поблагодарили: 6 раз

uno+5100 нужна помощь

Сообщение artemon25 » Чт ноя 24, 2016 8:57 pm

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

**/


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


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, 4 };

// Настройки выходов
int startPin=4;
int endPin=9;


// 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 "2012-09-18"

// Pin controller for data DTH11
#define DHTPIN 3 // Digital 3 pin Arduino (куда подключен выход с шины датчиков DTH11)
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);

const int pinPhoto = A0;
int raw = 0;

P(Page_info) = "<html><head><title>smartliving.ru controller " VERSION_STRING "</title></head><body>\n";
P(location_info) = "underground server room";
P(pin_info) = "D2 - 1-wire (many DS18S20) <br>D3 - DTH11 sensor <br>D4-light undergroung";
P(version_info) = VERSION_STRING ". Compile date: " COMPILE_DATE_STRING;

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

#define delayClick 1000 // задержка при обычном CLICK
#define delayLClick 3000 // задержка при длинном LCLICK
#define MAX_COMMAND_LEN (10)
#define MAX_PARAMETER_LEN (10)
#define COMMAND_TABLE_SIZE (8)
#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://xx.xx.xx.xx/command?8=HELP )
{"ON", commandsOn, }, // Устанавливает "1" на заданном цифровом порту (вызов http://xx.xx.xx.xx/command?8=ON )
{"OFF", commandsOff, }, // Устанавливает "0" на заданном цифровом порту (вызов http://xx.xx.xx.xx/command?8=OFF )
{"STATUS", commandsStatus, }, // Получить состояние цифрового порта (1 или 0) (вызов http://xx.xx.xx.xx/command?8=STATUS ),
// если вместо номера порта передать ALL (вызов http://xx.xx.xx.xx/command?ALL=STATUS ), то получим состояние всех портов (Пример вывода P3=0;P4=0;P5=0;P6=0;P7=0;P8=1;P9=1;)
{"CLICK", commandsClick, }, // Кратковременная "1" на порту 1сек (время настраивается) (вызов http://xx.xx.xx.xx/command?8=CLICK )
{"LCLICK", commandsLClick, }, // Кратковременная "1" на порту 3сек (время настраивается) (вызов http://xx.xx.xx.xx/command?8=LCLICK )
{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 commandsOn(WebServer &server) {
if (gParamValue>=startPin && gParamValue<=endPin) {
digitalWrite(gParamValue,HIGH);
} else ErrorMessage(server);
}

void commandsOff(WebServer &server) {
if (gParamValue>=startPin && gParamValue<=endPin) {
digitalWrite(gParamValue,LOW);
} else ErrorMessage(server);
}

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

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

void commandsStatus(WebServer &server) {
if (strcmp(gParamBuffer, "ALL") == 0) { // выдать состояние всех пинов
for(int i=startPin;i<=endPin;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>=startPin && gParamValue<=endPin) {
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");
}
}
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
float t = dht.readTemperature();

// check if returns are valid, if they are NaN (not a number) then something went wrong!
if (isnan(t) || isnan(h)) {
server.print("DHT NOT FOUND");
} else {
server.print("Humidity: ");
server.print(h);
server.print(" %\t");
server.print("Temperature: ");
server.print(t);
server.println(" *C");
}
}


void stateRequest(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
strcpy (gParamBuffer, "ALL");
commandsStatus(server);
}

/**********************************************************************************************************************
* Генерация и вывод информации об устройстве
**/
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>Commands:<br>");
commandsHelp(server);
server.print("<hr><br>Version info: ");
server.printP(version_info);

}

/**********************************************************************************************************************
* Поиск устройств (датчиков температуры на шине 1-wire)
**/
void searchDevices() {
Serial.print("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
}
}
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(t) || isnan(h)) {
Serial.print("DHT NOT FOUND");
} else {
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C");
}
}


/**********************************************************************************************************************/
void setup() {
// Для дебага будем выводить отладочные сообщения в консоль
//TODO Убрать вывод в консоль "за дабаг" (т.е. вывод только если скимпилированно с поддержкой дебага)
Serial.begin(9600);
pinMode( pinPhoto, INPUT );
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.begin();

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

// Настройка портов на вывод
for (int thisPin = startPin; thisPin <=endPin; thisPin++) {
pinMode(thisPin, OUTPUT);
}
// Настройки 1-wire
sensors.begin(); // Инициализация шины 1-wire (для датчиков температуры)
sensors.requestTemperatures(); // Перед каждым получением температуры надо ее запросить

searchDevices();
// Инициализация DTH11
dht.begin();

}

/**********************************************************************************************************************/
void loop() {
char buff[64];
int len = 64;
webserver.processConnection(buff, &len); // process incoming connections one at a time forever
raw = analogRead( pinPhoto );
Serial.println( raw );
delay(5000);
}


в принципе всё скомпилировалось и залилось на UNO и в мониторе порта есть данные с ds1820, dht22, и через каждые 5 секунд обновляется данные с фоторезистора а теперь вопрос на странице в броузере 192.168.1.120 есть данные с ds1820 и dht22 а с фоторезистора нигде нет может както надо вызвать эти данные. А так же нужна помощь как добавить эту иформацию в majordomo
нужна помощь и подсказки что делать дальше
заранее всем огромное спасибо
artemon25
Сообщения: 112
Зарегистрирован: Чт авг 25, 2016 10:33 pm
Благодарил (а): 15 раз
Поблагодарили: 6 раз

Re: uno+5100 нужна помощь

Сообщение artemon25 » Чт ноя 24, 2016 10:36 pm

при запросе http://192.168.1.120/getdev выдаёт значение такого типа T0:28FFC830A11503B0:21.50;Humidity: 75.50 % Temperature: 19.60 *C . с помощью веб переменных вытянул значения с ds1820 в шаблоне поиска писал запрос T0:28FFC830A11503B0:(.+?); пробовал по такому же принципу вытянуть значение с dht22 шаблоном Temperature:(.+?*C); и соответствено Humidity:(.+?); но ничего не появилось наверное как то по другому шаблон поиска писать надо отсюда вопрос к знатокам как???
yden
Сообщения: 141
Зарегистрирован: Пн авг 22, 2016 10:03 am
Благодарил (а): 28 раз
Поблагодарили: 5 раз

Re: uno+5100 нужна помощь

Сообщение yden » Вт ноя 29, 2016 4:30 am

ТС, можно я влезу, обо вопрос по связке uno + 5100 + majordomo, чтоб новые темы не плодить?
В моем проекте uno будет собирать данные с других контроллеров по rs485 и nrf24l01 и выступать в роли посредника между ними. Для отображения собираемой информации планирую использовать Raspberry Pi + majordomo.
Вопрос: для обмена информацией между uno и Raspberry Pi для majordomo можно использовать w5100?

спасибо
sly28
Сообщения: 5
Зарегистрирован: Пт мар 11, 2016 1:48 pm
Благодарил (а): 1 раз
Поблагодарили: 0

Re: uno+5100 нужна помощь

Сообщение sly28 » Чт дек 08, 2016 9:16 pm

Ну чтобы темы не плодить, и я сюда влезу. Хоть у меня не уно, но смысл, думаю, тот же..
Есть система: комп с majordomo, соедеиненный по сети с мегой(китай)+W5100(китай).
Мега управляет несколькими реле. Сигналы на переключение реле как правило посылает majordomo. Так же при определенных условиях мега отправляет данные в сторону majordomo..
Вроде бы все работает, НО! иногда случается, что команды, отправляемые от majordomo в сторону меги (для переключения реле) как-то подвисают, то есть веб интерфейс отработал, переключил статус объекта, а мега - молчит, если при этом попытаться переключить другое реле, то система уже не реагирует (и веб интерфейсе статус объекта тоже не меняется), и такое подвисание держится от 5 до 15 секунд, после чего, все команды "выстреливают" из меги.
Библиотеку EThernet использую из проекта AMS, файлы не передаю, SD-карта отсутствует.
Что самое интересное, если в момент такого подвисания мега начинает слать пакеты в сторону majordomo, то они прекрасно доходят и majordomo прекрасно реагирует на них... и как правило, после этого, через секунду команды (подвисшие) начинают исполняться..
Во время подвисания ардуина работает, на сериал выводит информацию (раз в цикл), в majordomo тоже циклы все работают... и не могу понять в чем затык? на кого грешить?
Прошу Вашей помощи, а то мои идеи уже закончились.. :(
Ответить