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
Да, отлично все написано, весьма пользительное чтение.
Прошу помочь.
конкретно в этой части
В 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
Праздную еще одну победу разума на незнакомыми языками програмирования!
Воспользовавшись функцией dtostrf(); перевел float в string. И распечатал через PSTR() воспользовавшись указателем $S для вставки значений string.
dtostrf()
PSTR()
Следующий шаг это упростить и сократить программу.
Буду пробовать PROGMEM и использование масивов данных в паре с циклами, а так же производить опрос датчиков раз в минуту.
Доавил в код данные с DHT22 и опять какая то "петрушка".
В Serial, для отладки, все выводиться нормально, а вот в html
Что за новая шляпа? Почему данные идут в перемешку.
Хочу добавить
Такое ощущение что 1 строка сумма 4, вторая сумма 3-х, 2 сумма 2-х и 4 строка 1 значение.
Help me please!!!!
Люди добрые и умные помогите решить задачу!!! Зарание всем благодврен.
скеч комбинировал из разных источников
Простите, за подьем темы, но вопрос в тему.