- Web - server на Arduino mega, nano с использованием POST запроса

Web - server на Arduino mega, nano для управления через Интернет с использованием POST запроса

Практика для студентов. Мясищев А.А.

1.Arduino mega (1280)

Фото сервера на Arduino mega

Интерфейс управления сервером на Arduino mega

Программа web-сервера на Arduino mega с контроллеров ethernet enc28j60

#include <UIPEthernet.h>

#define bufferMax 128

#include <OneWire.h>

#include <stdio.h>

#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

// Enter a MAC address and IP address for your controller below.

// The IP address will be dependent on your local network:

byte mac[] = {

0xDE, 0xAD, 0xBE, 0xEF, 0x11, 0xED

};

IPAddress ip(192, 168, 1, 18);

int bufferSize;

char buffer[bufferMax];

char post;

char buf[30];

// Initialize the Ethernet server library

// with the IP address and port you want to use

// (port 80 is default for HTTP):

EthernetServer server(81);

void setup() {

sensors.begin();

// Open serial communications and wait for port to open:

Serial.begin(9600);

while (!Serial) {

; // wait for serial port to connect. Needed for native USB port only

}

pinMode(3, OUTPUT); // 3-й вывод определен как выход для светодиода

pinMode(5, OUTPUT); // 5-й вывод определен как выход

pinMode(7, OUTPUT); // 7-й вывод определен как выход

// start the Ethernet connection and the server:

Ethernet.begin(mac, ip);

server.begin();

Serial.print("server is at ");

Serial.println(Ethernet.localIP());

}

void loop() {

// listen for incoming clients

EthernetClient client = server.available();

if (client) {

bufferSize=0;

Serial.println("new client");

// an http request ends with a blank line

boolean currentLineIsBlank = true;

while (client.connected()) {

if (client.available()) {

char c = client.read();

Serial.write(c);

// if you've gotten to the end of the line (received a newline

// character) and the line is blank, the http request has ended,

// so you can send a reply

if (c == '\n' && currentLineIsBlank) {

while(client.available()) { //Обработка запроса POST

post = client.read();

if(bufferSize < bufferMax)

buffer[bufferSize++] = post; // сохраняем новый символ в буфере и создаем приращение bufferSize

// Serial.write(post);

}

char r=buffer[2]; // Выборка символа, соответствующего состоянию красного

// светодиода (1-включен, 0-выкл.).

char g=buffer[6]; // ... - зеленого светодиода

char b=buffer[10]; // ... - синего светодиода

if( r==0x31) digitalWrite(3,HIGH); // Если для красного светодиода символ r

// равен 1(0x31) - зажигаем светодиод.

if( r==0x30) digitalWrite(3,LOW); // Если r соответствует 0(0x30) - гасим светодиод.

if( g==0x31) digitalWrite(5,HIGH); // Аналогично для зеленого

if( g==0x30) digitalWrite(5,LOW);

if( b==0x31) digitalWrite(7,HIGH); // и синего светодиодов

if( b==0x30) digitalWrite(7,LOW);

// send a standard http response header

client.println("HTTP/1.1 200 OK");

client.println("Content-Type: text/html; charset=\"Windows-1251\"");

client.print("Connection: close\r\n\r\n"); // the connection will be closed after completion of the response

client.println("<!DOCTYPE HTML>");

client.println("<html lang=\"ru\">");

client.println("<head>");

client.println("<title>Arduino mega</title>");

client.println("</head>");

client.println("<body>");

client.println("<font size=5 color=blue> Web-server на Arduino MEGA 1280 <br>и контроллере enc28j60 <br>с методом запроса POST</font>");

client.println("<br>");

client.println("<hr>");

client.println("<FORM action=\"\" method=\"POST\">");

client.println("<FONT size=4 color=red>Красный светодиод:</FONT><BR>");

client.println("<INPUT type=\"radio\" name=\"r\" value=\"1\">ON<br>");

client.println("<INPUT type=\"radio\" name=\"r\" value=\"0\"CHECKED>OFF<br><br>");

client.println("<FONT size=4 color=green>Зеленый светодиод:</FONT><BR>");

client.println("<INPUT type=\"radio\" name=\"g\" value=\"1\">ON<br>");

client.println("<INPUT type=\"radio\" name=\"g\" value=\"0\"CHECKED>OFF<br><br>");

client.println("<FONT size=4 color=blue>Синий светодиод:</FONT><BR>");

client.println("<INPUT type=\"radio\" name=\"b\" value=\"1\">ON<br>");

client.println("<INPUT type=\"radio\" name=\"b\" value=\"0\"CHECKED>OFF<br>");

client.println("<INPUT type=\"submit\" value=\"Ввести\">");

client.println("</FORM>");

client.println("<br>");

sensors.requestTemperatures();

dtostrf(sensors.getTempCByIndex(0),7,2,buf);

client.print("<font size=4 color=broun>Температура ");

client.print(buf);

client.println(" градусов C</font><br><br>");

if (digitalRead(3)){ client.println("<font size=4 color=red>Красный светодиод ВКЛЮЧЕН</font><br>"); }

else{ client.println("<font size=4 color=red>Красный светодиод ВЫКЛЮЧЕН</font><br>"); }

if (digitalRead(5)){ client.println("<font size=4 color=green>Зеленый светодиод ВКЛЮЧЕН</font><br>");}

else{ client.println("<font size=4 color=green>Зеленый светодиод ВЫКЛЮЧЕН</font><br>"); }

if (digitalRead(7)){client.println("<font size=4 color=blue>Синий светодиод ВКЛЮЧЕН</font><br>"); }

else{ client.println("<font size=4 color=blue>Синий светодиод ВЫКЛЮЧЕН</font><br>"); }

Serial.println(buffer);

client.println("<hr>");

client.print("Свободно памяти: ");

client.println(freeRam());

client.println("</body>");

client.println("</html>");

break;

}

if (c == '\n') {

// you're starting a new line

currentLineIsBlank = true;

} else if (c != '\r') {

// you've gotten a character on the current line

currentLineIsBlank = false;

}

}

}

// give the web browser time to receive the data

delay(10);

// close the connection:

client.stop();

Serial.println("client disconnected");

}

}

int freeRam () {

extern int __heap_start, *__brkval; int v;

return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); }

Для работы в сети с контроллером enc28j60 используется библиотека UIPEthernet

2.Arduino nano (328p)

Здесь используется среда программирования Arduino IDE 1.0.3, 1.0.5-r2

С поздними версиями может не работать библиотека Flash

Для работы в сети с контроллером enc28j60 используется библиотека UIPEthernet v.1.09

Фото сервера на Arduino nano

Интерфейс управления сервером на Arduino nano

Программа web-сервера на Arduino nano с контроллеров ethernet enc28j60

#include <UIPEthernet.h>

#define bufferMax 128

#include <OneWire.h>

#include <stdio.h>

#include <DallasTemperature.h>

#include <Flash.h>

#define ONE_WIRE_BUS 2

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

// Enter a MAC address and IP address for your controller below.

// The IP address will be dependent on your local network:

byte mac[] = {

0xDE, 0xAD, 0xBE, 0xEF, 0x11, 0xED

};

IPAddress ip(192, 168, 1, 18);

int bufferSize;

char buffer[bufferMax];

char post;

char buf[30];

char buff[130];

FLASH_STRING(st,

"<FONT size=5 color=green>Web-server on <font color=red><br>Arduino Nano</FONT><br> and <font color=blue>ENC28J60</font></font><BR>");

FLASH_STRING(st1,"<FORM action='' method=POST>");

FLASH_STRING(st2,"<FONT size=4 color=red>Red LED:</FONT><BR>");

FLASH_STRING(st3,"<INPUT type='radio' name='r' value='1'>ON<br>");

FLASH_STRING(st4,"<INPUT type='radio' name='r' value='0'CHECKED>OFF<br><br>");

FLASH_STRING(st5,"<FONT size=4 color=green>Green LED:</FONT><BR>");

FLASH_STRING(st6,"<INPUT type='radio' name='g' value='1'>ON<br>");

FLASH_STRING(st7,"<INPUT type='radio' name='g' value='0'CHECKED>OFF<br><br>");

FLASH_STRING(st8,"<FONT size=4 color=blue>Blue LED:</FONT><BR>");

FLASH_STRING(st9,"<INPUT type='radio' name='b' value='1'>ON<br>");

FLASH_STRING(st10,"<INPUT type='radio' name='b' value='0'CHECKED>OFF<br>");

FLASH_STRING(st11,"<INPUT type='submit' value='Input'></FORM>");

FLASH_STRING(st17,"<FONT size=4 color=blue>Temperature: ");

FLASH_STRING(st18,"<font size=4 color=red>Red LED ON</font><br>");

FLASH_STRING(st19,"<font size=4 color=red>Red LED OFF</font><br>");

FLASH_STRING(st20,"<font size=4 color=green>Green LED ON</font><br>");

FLASH_STRING(st21,"<font size=4 color=green>Green LED OFF</font><br>");

FLASH_STRING(st22,"<font size=4 color=blue>Blue LED ON</font><br>");

FLASH_STRING(st23,"<font size=4 color=blue>Blue LED OFF</font><br>");

FLASH_STRING(sth,"HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=\"Windows-1251\"\r\n\r\n");

// Initialize the Ethernet server library

// with the IP address and port you want to use

// (port 80 is default for HTTP):

EthernetServer server(81);

void setup() {

sensors.begin();

pinMode(3, OUTPUT); // 3-й вывод определен как выход для светодиода

pinMode(5, OUTPUT); // 5-й вывод определен как выход

pinMode(7, OUTPUT); // 7-й вывод определен как выход

digitalWrite(3,LOW);

digitalWrite(5,LOW);

digitalWrite(7,LOW);

// start the Ethernet connection and the server:

Ethernet.begin(mac, ip);

server.begin();

}

void loop() {

// listen for incoming clients

EthernetClient client = server.available();

if (client) {

bufferSize=0;

// an http request ends with a blank line

boolean currentLineIsBlank = true;

while (client.connected()) {

if (client.available()) {

char c = client.read();

// if you've gotten to the end of the line (received a newline

// character) and the line is blank, the http request has ended,

// so you can send a reply

if (c == '\n' && currentLineIsBlank) {

while(client.available()) { //Обработка запроса POST

post = client.read();

if(bufferSize < bufferMax)

buffer[bufferSize++] = post; // сохраняем новый символ в буфере и создаем приращение bufferSize

}

char r=buffer[2]; // Выборка символа, соответствующего состоянию красного

// светодиода (1-включен, 0-выкл.).

char g=buffer[6]; // ... - зеленого светодиода

char b=buffer[10]; // ... - синего светодиода

if( r==0x31) digitalWrite(3,HIGH); // Если для красного светодиода символ r

// равен 1(0x31) - зажигаем светодиод.

if( r==0x30) digitalWrite(3,LOW); // Если r соответствует 0(0x30) - гасим светодиод.

if( g==0x31) digitalWrite(5,HIGH); // Аналогично для зеленого

if( g==0x30) digitalWrite(5,LOW);

if( b==0x31) digitalWrite(7,HIGH); // и синего светодиодов

if( b==0x30) digitalWrite(7,LOW);

// send a standard http response header

sth.copy(buff,80); client.print(buff);

st.copy(buff,131); client.println(buff);

client.println("<br>");

st1.copy(buff,80); client.print(buff);

st2.copy(buff,80); client.print(buff);

st3.copy(buff,80); client.print(buff);

st4.copy(buff,80); client.print(buff);

st5.copy(buff,80); client.print(buff);

st6.copy(buff,80); client.print(buff);

st7.copy(buff,80); client.print(buff);

st8.copy(buff,80); client.print(buff);

st9.copy(buff,80); client.print(buff);

st10.copy(buff,80); client.print(buff);

st11.copy(buff,80); client.print(buff);

client.println("<br>");

sensors.requestTemperatures();

dtostrf(sensors.getTempCByIndex(0),7,2,buf);

st17.copy(buff,80); client.print(buff);

client.print(buf); client.print("C:</FONT>");

client.print("<br>");

client.print("<br>");

if (digitalRead(3)){ st18.copy(buff,121); client.print(buff); }

else{ st19.copy(buff,121); client.print(buff); }

if (digitalRead(5)){ st20.copy(buff,121); client.print(buff);}

else{ st21.copy(buff,121); client.print(buff); }

if (digitalRead(7)){st22.copy(buff,121); client.print(buff); }

else{ st23.copy(buff,121); client.print(buff); }

client.println("<br>");

client.print("FreeSRAM ");

client.println(freeRam());

break;

}

if (c == '\n') {

// you're starting a new line

currentLineIsBlank = true;

} else if (c != '\r') {

// you've gotten a character on the current line

currentLineIsBlank = false;

}

}

}

// give the web browser time to receive the data

delay(10);

// close the connection:

client.stop();

// Serial.println("client disconnected");

}

}

int freeRam () {

extern int __heap_start, *__brkval; int v;

return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); }

Особенность программы в том, что из-за малой памяти SRAM микроконтроллера atmega 328p переменные записываются в память программ. Для этого используется библиотека Flash