Веб-сервер с двумя указателями температуры


Данный проект демонстрирует показания двух температур, измеренных с помощью Arduino, а также двух датчиков MCP9700.

Arduino Uno и Ethernet шилд используются в качестве веб-сервера, на котором размещается веб страница. На этой веб странице отображаются две температуры на двух приборах. Данная веб страница хранится на SD-карте, которая вставлена в кардридер micro SD-карт на Ethernet шилде.

Веб браузер используется для отображения показаний двух приборов на любом компьютере, находящемся в той же сети, что и Arduino.

На видео, показанном ниже, демонстрируется работа данного проекта при использовании двух датчиков температуры MCP9700, подсоединенным к Arduino с помощью макетной платы.



Принципиальная схема
Два температурных датчика MCP9700 соединены с Arduino и Ethernet шилдом, как показано на принципиальной схеме ниже.

Два температурных датчика можно использовать для независимого измерения двух отдельных температур, например, температуры на входе и температуры на выходе.

Конденсаторы C2 и C4 являются опциональными развязывающими конденсаторами по питанию. Конденсаторы C1 и C3 также являются опциональными конденсаторами и служат в качестве фильтра выходного напряжения, поступающего от датчика MCP9700.

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

Arduino скетч
Скетч, показанный ниже, может быть загружен в Arduino. Он представляет собой модифицированную версию из учебного материала веб-сервера с двумя приборами на базе Arduino, который в свою очередь является модифицированной версией из учебного материала части 15 по созданию веб-сервера с помощью Ethernet шилда на базе Arduino.
/*--------------------------------------------------------------
  Program:      two_temperatures

  Description:  Arduino web server web page displays two
                temperature values on two gauges.
                The web page is stored on the SD card.
                Ajax is used to update the analog values on the
                web page.
  
  Hardware:     Arduino Uno and official Arduino Ethernet
                shield. Should work with other Arduinos and
                compatible Ethernet shields.
                2Gb micro SD card formatted FAT16.
                MCP9700 temperature sensors interfaced to
                A2 & A3 analog inputs.
                
  Software:     Developed using Arduino 1.0.5 software
                Should be compatible with Arduino 1.0 +
                SD card contains web page called index.htm
  
  References:   - WebServer example by David A. Mellis and 
                  modified by Tom Igoe
                - SD card examples by David A. Mellis and
                  Tom Igoe
                - Ethernet library documentation:
                  http://arduino.cc/en/Reference/Ethernet
                - SD Card library documentation:
                  http://arduino.cc/en/Reference/SD
                - Gauge from:
                  https://github.com/Mikhus/canv-gauge

  Date:         3 August 2014
 
  Author:       W.A. Smith, http://startingelectronics.com
--------------------------------------------------------------*/

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

// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ   50

// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 20); // IP address, may need to change depending on network
EthernetServer server(80);  // create a server at port 80
File webFile;               // the web page file on the SD card
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0;              // index into HTTP_req buffer

void setup()
{
    // disable Ethernet chip
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);

    Serial.begin(9600);       // for debugging
    
    // initialize SD card
    Serial.println("Initializing SD card...");
    if (!SD.begin(4)) {
        Serial.println("ERROR - SD card initialization failed!");
        return;    // init failed
    }
    Serial.println("SUCCESS - SD card initialized.");
    // check for index.htm file
    if (!SD.exists("index.htm")) {
        Serial.println("ERROR - Can't find index.htm file!");
        return;  // can't find index file
    }
    Serial.println("SUCCESS - Found index.htm file.");
    
    Ethernet.begin(mac, ip);  // initialize Ethernet device
    server.begin();           // start to listen for clients
}

void loop()
{
    EthernetClient client = server.available();  // try to get client

    if (client) {  // got client?
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {   // client data available to read
                char c = client.read(); // read 1 byte (character) from client
                // buffer first part of HTTP request in HTTP_req array (string)
                // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
                if (req_index < (REQ_BUF_SZ - 1)) {
                    HTTP_req[req_index] = c;          // save HTTP request character
                    req_index++;
                }
                // last line of client request is blank and ends with \n
                // respond to client only after last line received
                if (c == '\n' && currentLineIsBlank) {
                    // send a standard http response header
                    client.println("HTTP/1.1 200 OK");
                    // remainder of header follows below, depending on if
                    // web page or XML page is requested
                    // Ajax request - send XML file
                    if (StrContains(HTTP_req, "ajax_inputs")) {
                        // send rest of HTTP header
                        client.println("Content-Type: text/xml");
                        client.println("Connection: keep-alive");
                        client.println();
                        // send XML file containing input states
                        XML_response(client);
                    }
                    else {  // web page request
                        // send rest of HTTP header
                        client.println("Content-Type: text/html");
                        client.println("Connection: keep-alive");
                        client.println();
                        // send web page
                        webFile = SD.open("index.htm");        // open web page file
                        if (webFile) {
                            while(webFile.available()) {
                                client.write(webFile.read()); // send web page to client
                            }
                            webFile.close();
                        }
                    }
                    // display received HTTP request on serial port
                    Serial.print(HTTP_req);
                    // reset buffer index and all buffer elements to 0
                    req_index = 0;
                    StrClear(HTTP_req, REQ_BUF_SZ);
                    break;
                }
                // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                } 
                else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
            } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection
    } // end if (client)
}

// send the XML file containing analog value
void XML_response(EthernetClient cl)
{
    int analog_val_1 = 0;
    int analog_val_2 = 0;
    char sample;
    
    // get the sum of 10 samples from analog inputs 2 and 3
    for (sample = 0; sample < 10; sample++) {
        analog_val_1 += analogRead(2);
        delay(2);
        analog_val_2 += analogRead(3);
        delay(2);
    }
    // calculate the average of the 10 samples
    analog_val_1 /= 10;
    analog_val_2 /= 10;
    
    cl.print("<?xml version = \"1.0\" ?>");
    cl.print("<inputs>");
    // read analog pin A2
//    analog_val = analogRead(2);
    cl.print("<analog>");
    cl.print(analog_val_1);
    cl.print("</analog>");
//    analog_val = analogRead(3);
    cl.print("<analog>");
    cl.print(analog_val_2);
    cl.print("</analog>");
    cl.print("</inputs>");
}

// sets every element of str to 0 (clears array)
void StrClear(char *str, char length)
{
    for (int i = 0; i < length; i++) {
        str[i] = 0;
    }
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind)
{
    char found = 0;
    char index = 0;
    char len;

    len = strlen(str);
    
    if (strlen(sfind) > len) {
        return 0;
    }
    while (index < len) {
        if (str[index] == sfind[found]) {
            found++;
            if (strlen(sfind) == found) {
                return 1;
            }
        }
        else {
            found = 0;
        }
        index++;
    }

    return 0;
}

SD-карта размещает веб страницу
HTML страница ниже, содержащая код JavaScript, может быть скопирована в файл, который называется index.htm; после этого данный файл необходимо скопировать на SD-карту.

Micro SD-карту следует вставить в кардридер Ethernet шилда Arduino, который в свою очередь необходимо подключить к плате Arduino, такой как Arduino Uno. Далее в Arduino нужно загрузить вышеуказанный скетч.

Также как и скетч выше, HTML страница ниже является модифицированной версией веб страницы из учебного материала веб-сервера с двумя приборами на базе Arduino, который в свою очередь является модифицированной версией из учебного материала части 15 по созданию веб-сервера с помощью Ethernet шилда на базе Arduino.

Как работает проект
1. Введите в строку вашего веб браузера IP адрес веб-сервера Arduino (в вышеуказанном Arduino скетче задан адрес 192.168.0.20); после этого веб-сервер Arduino загрузит веб страницу с SD карты в Ethernet шилд Arduino.
2. Код JavaScript, встроенный в веб страницу, которая запущена в веб браузере, будет запрашивать XML файл у веб-сервера Arduino каждые 200мс.
3. Когда Arduino получает запрос на выдачу XML файла, он будет считывать аналоговые значения с двух аналоговых входов, к которым подсоединены два датчика MCP9700, затем вставит эти значения в XML файл, который будет загружен назад в браузер.
4. Arduino получит десять аналоговых образцовых значений от каждого из аналоговых входов и отправит среднее значение в браузер. Это обеспечит небольшую фильтрацию аналоговых значений, что поможет предотвратить стрелки приборов от подергиваний или вибрирований вперед и назад.
5. После того, как браузер получит XML файл, код JavaScript в веб странице сможет извлечь аналоговые значения из XML файла и отправит их в приборы для отображения.

Код JavaScript преобразует необработанные аналоговые значения в значения температур. Например, используйте следующий код для первого аналогового значения:
data_val  = ((data_val * 5.0 / 1024.0) - 0.5) / 0.01;

Измерительный прибор
Компонент «измерительный прибор» разработан Михаилом Стадником (Mykhailo Stadnyk) и может быть загружен из Mikhus на github. Также смотрите статью в блоге о измерительных приборах.

По материалам сайта

10 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.