WEB термометр на NANO+ENC28J60+ DS18B20
- Войдите на сайт для отправки комментариев
Ср, 24/07/2013 - 09:12
Добрый день уважаемые форумчане.
Все еще пытаюсь разобраться с работой ENC28J60. Нашел на просторах интернет сети пример работы WEB термометра. К сожалению, наиболее трудные места в скетче не объесненены. Пытался 3 дня сам хоть что то понять, читал на английском (а с ним плохо) PROGMEM и PSTR функции. Пришол к Вам за помощью.
Ниже выкладываю скетч, прошу дать коментарии к строкам и функциям, особенно что касается вывода страници в html. Работу DS18B20 нет нужды коментировать, вроде с ним проблем нет. Проблему понимания вызывает все, что ниже 69 строки.
Спасибо всем откликнувшимся.
#include <OneWire.h>
#include <EtherCard.h>
// настройки Ethernet
#define BUF_SIZE 512
byte mac[] = { 0x00, 0x04, 0xA3, 0x21, 0xCA, 0x38 }; // MAC-адрес
byte fixed = false; // =false: пробовать получить адрес по DHCP,
// в случае неудачи использовать статический;
// =true: сразу использовать статический
uint8_t ip[] = { 169, 254, 8, 200 }; // Статический IP-адрес
uint8_t subnet[] = { 255, 255, 0, 0 }; // Маска подсети
uint8_t gateway[] = { 192, 168, 1, 20 }; // Адрес шлюза
uint8_t dns[] = { 192, 168, 1, 20 }; // Адрес DNS-сервера (необязателен)
byte Ethernet::buffer[BUF_SIZE];
static BufferFiller bfill; // used as cursor while filling the buffer
// настройки OneWire
#define DS18B20PIN 9
OneWire ds(DS18B20PIN);
// команды DS18B20
void setConversionTime(byte conf) {
ds.reset();
ds.skip(); // skip ROM
ds.write(0x4E); // write scratchpad
ds.write(0); // Th
ds.write(0); // Tl
ds.write(conf); // configuration
}
void startConversionAll() {
ds.reset();
ds.skip(); // skip ROM
ds.write(0x44,0); // start conversion
delay(10);
}
void setup(void)
{
Serial.begin(57600);
delay(2000);
/* Проверяем, что контроллер Ethernet доступен для работы */
Serial.println("Initialising the Ethernet controller");
if (ether.begin(sizeof Ethernet::buffer, mac, 10) == 0) {
Serial.println( "Ethernet controller NOT initialised");
while (true);
}
// Пытаемся получить адрес динамически
Serial.println("Attempting to get an IP address using DHCP");
if (ether.dhcpSetup()) {
ether.printIp("Got an IP address using DHCP: ", ether.myip);
} else {
// Если DHCP не доступен, используем статический ip-адрес
ether.staticSetup(ip, gateway, dns);
ether.printIp("DHCP FAILED, using fixed address: ", ether.myip);
fixed = true;
}
}
char okHeader[] PROGMEM =
"HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n"
"Pragma: no-cache\r\n"
;
char authorLink[] PROGMEM =
"</pre><hr>Read about me <a href=\"<a href="">http://mk90.blogspot.com\</a>" target=\"_blank\">here</a>"
;
static void homePage (BufferFiller& buf) {
buf.emit_p(PSTR("$F\r\n"
"<title>Arduino web-thermometr</title>"
"<h2>DS18B20 Network:</h2>"
"<pre>"), okHeader);
byte counter = 0;
byte addr[8];
byte data[12];
setConversionTime(0x7F); // установить 9-битное разрешение
startConversionAll(); // запустить конвертацию температуры
delay(100); // на конвертацию 9-битного значения требуется 93,75 мс
// ищем устройства и выводим результаты
ds.reset_search();
delay(250);
while (ds.search(addr)) {
buf.emit_p(PSTR("$D: "),++counter);
if ( OneWire::crc8(addr, 7) != addr[7]) {
buf.emit_p(PSTR("- address CRC is not valid!\n"));
continue;
} else if (addr[0] != 0x28) {
buf.emit_p(PSTR("- is not a DS18B20 family device!\n"));
continue;
}
ds.reset();
ds.select(addr);
ds.write(0xBE); // читать scratchpad
for (byte k=0; k<9; k++) { // нам потребуется 9 байт
data[k] = ds.read();
}
if ( OneWire::crc8( data, 8) != data[8]) {
buf.emit_p(PSTR("- value CRC is not valid!\n"));
continue;
}
buf.emit_p(PSTR(" $D.$D °C\n"), *(int *)data/16, (int) (abs(*(int *)data % 16) * 0.625));
}
buf.emit_p(PSTR("\nTotal: $D devices."), counter);
buf.emit_p(authorLink);
}
void loop(void)
{
word len = ether.packetReceive();
word pos = ether.packetLoop(len);
if (pos) {
bfill = ether.tcpOffset();
char* data = (char *) Ethernet::buffer + pos;
Serial.println(data); // распечатываем запрос для отладки
if (strncmp("GET / ", data, 6) == 0)
homePage(bfill);
else
bfill.emit_p(PSTR(
"HTTP/1.0 401 Unauthorized\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<h1>401 Unauthorized</h1>"));
// отправить ответ клиенту
ether.httpServerReply(bfill.position());
}
}
Нашел отличный сайт, где Лука объясняет работу библиотек, попробую разобраться с его помощью.
http://www.lucadentella.it/en
Нашел отличный сайт, где Лука объясняет работу библиотек, попробую разобраться с его помощью.
http://www.lucadentella.it/en
Да, отлично все написано, весьма пользительное чтение.
Прошу помочь.
#include <EtherCard.h> #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 9 static byte mymac[] = {0x00, 0x04, 0xA3, 0x21, 0xCA, 0x38}; byte Ethernet::buffer[1024]; float t1, t2; OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); void setup () { Serial.begin(57600); Serial.println("Server T&H"); if (!ether.begin(sizeof Ethernet::buffer, mymac, 10)) Serial.println( "Failed to access Ethernet controller"); else Serial.println("Ethernet controller initialized"); if (!ether.dhcpSetup()) Serial.println("Failed to get configuration from DHCP"); else Serial.println("DHCP configuration done"); ether.printIp("IP Address:\t", ether.myip); ether.printIp("Netmask:\t", ether.mymask); ether.printIp("Gateway:\t", ether.gwip); Serial.println(); } void loop() { sensors.requestTemperatures(); t1 = sensors.getTempCByIndex(0); delay (100); Serial.print ("T1= "); Serial.println (t1); t2 = sensors.getTempCByIndex(1); delay (100); Serial.print ("T2= "); Serial.println (t2); word len = ether.packetReceive(); word pos = ether.packetLoop(len); if(pos) { Serial.println("---------------------------------------- NEW PACKET ----------------------------------------"); Serial.println((char *)Ethernet::buffer + pos); Serial.println("--------------------------------------------------------------------------------------------"); Serial.println(); BufferFiller bfill = ether.tcpOffset(); bfill.emit_p(PSTR("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'><head>" "<meta http-equiv= refresh content=60;>" "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />" "</head>" "<html><body><h1>Server T and H</h1><br> T1= $T <br> T2= $T</body></html>"), t1, t2); ether.httpServerReply(bfill.position()); } }конкретно в этой части
bfill.emit_p(PSTR("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'><head>" "<meta http-equiv= refresh content=60;>" "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />" "</head>" "<html><body><h1>Server T and H</h1><br> T1= $T <br> T2= $T</body></html>"), t1, t2);В html выводиться
Т.е. вместо показаний (цифр) температуры у меня выводиться буква "Т", причем не понять русская или латинская.
Куда копать?
Т.е. вместо показаний (цифр) температуры у меня выводится буква "Т", причем не понять русская или латинская. Куда копать?
У Вас там в примерах должно быть что-то типа:
while (temp_string[i]) {
buf[TCP_CHECKSUM_L_P+3+plen]=temp_string[i++];
plen++;
}
Насколько я понял, в PSTR можно хранить заранее известные вещи, а не переменные, меняющиеся во времени.
Хотя, если у Вас все делает библиотека - попробуйте заменить $T на $D, как это указано в примере...
Т.е. вместо показаний (цифр) температуры у меня выводится буква "Т", причем не понять русская или латинская. Куда копать?
У Вас там в примерах должно быть что-то типа:
while (temp_string[i]) {
buf[TCP_CHECKSUM_L_P+3+plen]=temp_string[i++];
plen++;
}
Насколько я понял, в PSTR можно хранить заранее известные вещи, а не переменные, меняющиеся во времени.
Хотя, если у Вас все делает библиотека - попробуйте заменить $T на $D, как это указано в примере...
Я не понял вообще что делается в этих строках, которые Вы привели.
Я не понял вообще что делается в этих строках, которые Вы привели.
У Вас работает другая библиотека, так что надо разбираться с ней.
Вышеприведенный пример в моей библиотеке "выводит в html" массив, в котором находятся цифры с датчика температуры.
Я не понял вообще что делается в этих строках, которые Вы привели.
У Вас работает другая библиотека, так что надо разбираться с ней.
Вышеприведенный пример в моей библиотеке "выводит в html" массив, в котором находятся цифры с датчика температуры.
Немного разобрался, для вывода числа, действительно $D надо. Но float выводит 5 цифр, но как их связать с температурой не знаю, перевожу флоат в char, целые числа выводятся, ну а если byte - целые числа.
Что еще можно попробовать?
Ниже код и то что в html
#include <EtherCard.h> #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 9 static byte mymac[] = {0x00, 0x04, 0xA3, 0x21, 0xCA, 0x38}; byte Ethernet::buffer[1024]; float t1, t2; String T1; String T2; OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); void setup () { Serial.begin(57600); Serial.println("Server T&H"); if (!ether.begin(sizeof Ethernet::buffer, mymac, 10)) Serial.println( "Failed to access Ethernet controller"); else Serial.println("Ethernet controller initialized"); if (!ether.dhcpSetup()) Serial.println("Failed to get configuration from DHCP"); else Serial.println("DHCP configuration done"); ether.printIp("IP Address:\t", ether.myip); ether.printIp("Netmask:\t", ether.mymask); ether.printIp("Gateway:\t", ether.gwip); Serial.println(); } void loop() { sensors.requestTemperatures(); t1 = sensors.getTempCByIndex(0); delay (100); Serial.print ("t1= "); Serial.println (t1); t2 = sensors.getTempCByIndex(1); delay (100); Serial.print ("t2= "); Serial.println (t2); //T1=String(t1); Serial.println (T1); //T2=String(t2); Serial.println (T2); word len = ether.packetReceive(); word pos = ether.packetLoop(len); if(pos) { Serial.println("---------------------------------------- NEW PACKET ----------------------------------------"); Serial.println((char *)Ethernet::buffer + pos); Serial.println("--------------------------------------------------------------------------------------------"); Serial.println(); BufferFiller bfill = ether.tcpOffset(); bfill.emit_p(PSTR("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'><head>" "<meta http-equiv= refresh content=60;>" "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />" "</head>" "<html><body><h1>Server T and H</h1><br> T1= $D <br> T2= $D</body></html>"), t1, t2); ether.httpServerReply(bfill.position()); } }Праздную еще одну победу разума на незнакомыми языками програмирования!
#include <EtherCard.h> #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 9 static byte mymac[] = {0x00, 0x04, 0xA3, 0x21, 0xCA, 0x38}; byte Ethernet::buffer[1024]; float t1, t2; char T1[6], T2[6]; OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); void setup () { Serial.begin(57600); Serial.println("Server T&H"); if (!ether.begin(sizeof Ethernet::buffer, mymac, 10)) Serial.println( "Failed to access Ethernet controller"); else Serial.println("Ethernet controller initialized"); if (!ether.dhcpSetup()) Serial.println("Failed to get configuration from DHCP"); else Serial.println("DHCP configuration done"); ether.printIp("IP Address:\t", ether.myip); ether.printIp("Netmask:\t", ether.mymask); ether.printIp("Gateway:\t", ether.gwip); Serial.println(); } void loop() { sensors.requestTemperatures(); t1 = sensors.getTempCByIndex(0); delay (100); Serial.print ("t1= "); Serial.println (t1); dtostrf(t1,5,2,T1); Serial.print ("T1= "); Serial.println (T1); t2 = sensors.getTempCByIndex(1); delay (100); Serial.print ("t2= "); Serial.println (t2); dtostrf(t2,5,2,T2); Serial.print ("T2= "); Serial.println (T2); word len = ether.packetReceive(); word pos = ether.packetLoop(len); if(pos) { Serial.println("---------------------------------------- NEW PACKET ----------------------------------------"); Serial.println((char *)Ethernet::buffer + pos); Serial.println("--------------------------------------------------------------------------------------------"); Serial.println(); BufferFiller bfill = ether.tcpOffset(); bfill.emit_p(PSTR("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'><head>" "<meta http-equiv= refresh content=60;>" "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />" "</head>" "<html><body><h1>Сервер температуры </h1><br> T1= $S <br> T2= $S</body></html>"), T1, T2); ether.httpServerReply(bfill.position()); } }Воспользовавшись функцией dtostrf(); перевел float в string. И распечатал через PSTR() воспользовавшись указателем $S для вставки значений string.
dtostrf()
sensors.requestTemperatures(); t1 = sensors.getTempCByIndex(0); delay (100); Serial.print ("t1= "); Serial.println (t1); dtostrf(t1,5,2,T1); Serial.print ("T1= "); Serial.println (T1); t2 = sensors.getTempCByIndex(1); delay (100); Serial.print ("t2= "); Serial.println (t2); dtostrf(t2,5,2,T2); Serial.print ("T2= "); Serial.println (T2);PSTR()
bfill.emit_p(PSTR("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'><head>" "<meta http-equiv= refresh content=60;>" "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />" "</head>" "<html><body><h1>Сервер температуры </h1><br> T1= $S <br> T2= $S</body></html>"), T1, T2);Следующий шаг это упростить и сократить программу.
Буду пробовать PROGMEM и использование масивов данных в паре с циклами, а так же производить опрос датчиков раз в минуту.
Доавил в код данные с DHT22 и опять какая то "петрушка".
//EEPROM (0-3) - temperature_up, temperature_down, signal_T_up, signal_T_down //EEPROM (4,5) - humdity, signal_H_up //DHT22 pin3 //DS18B20 pin9 //signal good pin4 //signal bad pin5 //relay pin6 //relay pin7 //ledpin 8 #include <EtherCard.h> #include <OneWire.h> #include <DallasTemperature.h> #include "DHT.h" #include <EEPROM.h> #define ONE_WIRE_BUS 9 //не забыть переправить #define DHTPIN 3 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); static byte mymac[] = {0x00, 0x04, 0xA3, 0x21, 0xCA, 0x38}; byte Ethernet::buffer[1024]; float t[3]; char T[6][3]; OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); char flag=10; int simbol, Sg=4, Sb=5, signal; int Relay[2]; int R[2]; //long previousMillis = 0; //long interval = 30000; byte u[5]; //u[0]-верхняя температра регулирования u[1]-нижняя темп.рег u[2]-верхн темп. сигнала, u[3]-нижняя температура сигнала, u[4]-нормальный максимум влажности, u[5]-аварийный максимум влажности char html[] PROGMEM = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'><head>" "<meta http-equiv= refresh content=60;>" "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />" "</head><html><body><h1>Сервер температуры </h1><br>"; void setup () { Serial.begin(57600); for (int i=0; i<6; i++){ u[i] = EEPROM.read(i); Serial.print ("u["); Serial.print (i); Serial.print ("]= "); Serial.println (u[i]);} sensors.begin(); dht.begin(); // Serial.println("Server T&H"); if (!ether.begin(sizeof Ethernet::buffer, mymac, 10)) Serial.println( "Failed to access Ethernet controller"); else Serial.println("Ethernet controller initialized"); if (!ether.dhcpSetup()) Serial.println("Failed to get configuration from DHCP"); else Serial.println("DHCP configuration done"); ether.printIp("IP Address:\t", ether.myip); ether.printIp("Netmask:\t", ether.mymask); ether.printIp("Gateway:\t", ether.gwip); Serial.println(); Relay[1]=6; Relay[2]=7; pinMode(Relay[1], OUTPUT); digitalWrite(Relay[1], LOW); pinMode(Relay[2], OUTPUT); digitalWrite(Relay[2], LOW); pinMode(Sg, OUTPUT); digitalWrite(Sg, LOW); pinMode(Sb, OUTPUT); digitalWrite(Sb, LOW); } void loop() { if(Serial.available()){ simbol=Serial.read (); if (simbol==116) { byte q[4] = {0, 0, 0, 0}; for(byte i = 0; i < 4; i++) { q[i] = Serial.parseInt(); EEPROM.write(i, q[i]); } for(byte i = 0; i < 4; i++) { q[i] = EEPROM.read(i); Serial.print(q[i]); if(i < 1) Serial.print(','); else Serial.println(); } } if (simbol==104) { byte h[2] = {0, 0}; for(byte i = 0; i < 2; i++) { h[i] = Serial.parseInt(); EEPROM.write(i+4, h[i]); } for(byte i = 0; i < 2; i++) { h[i] = EEPROM.read(i+4); Serial.print(h[i]); if(i < 1) Serial.print(','); else Serial.println(); } } } sensors.requestTemperatures(); for (int i=0; i<4; i++) { if (i<2){ t[i] = sensors.getTempCByIndex(i); delay (100); if (t[i]>u[0]) { R[i]=HIGH; digitalWrite (Relay[i], R[i]);} if (t[i]<u[1]) { R[i]=LOW; digitalWrite (Relay[i], R[i]);} } if (i==2) { t[i] = dht.readTemperature();} if (i==3) { t[i] = dht.readHumidity();} // Serial.print ("t["); // Serial.print (i); // Serial.print ("]= "); // Serial.println (t[i]); dtostrf(t[i],5,2,T[i]); // Serial.print ("T["); // Serial.print (i); // Serial.print ("]= "); // Serial.println (T[i]); } word len = ether.packetReceive(); word pos = ether.packetLoop(len); if(pos) { // Serial.println("---------------------------------------- NEW PACKET ----------------------------------------"); // Serial.println((char *)Ethernet::buffer + pos); // Serial.println("--------------------------------------------------------------------------------------------"); // Serial.println(); ether.hisport = 80; BufferFiller bfill = ether.tcpOffset(); bfill.emit_p(PSTR("$F DS18B20-1= $S <br> DS18B20-2= $S <br> DHT22-T= $S <br> DHT22-H= $S</body></html>"), html, T[0], T[1], T[2], T[3]); ether.httpServerReply(bfill.position()); } }В Serial, для отладки, все выводиться нормально, а вот в html
Что за новая шляпа? Почему данные идут в перемешку.
Хочу добавить
Такое ощущение что 1 строка сумма 4, вторая сумма 3-х, 2 сумма 2-х и 4 строка 1 значение.
Help me please!!!!
Люди добрые и умные помогите решить задачу!!! Зарание всем благодврен.
скеч комбинировал из разных источников
Простите, за подьем темы, но вопрос в тему.