Задача – создать недорогое решение для получения «настоящего» напряжения 0-5V, управляемого по вайфай сети GET запросом.
В качестве решения были выбраны WiFi NodeM ESP8266 и микросхема ЦАП MCP4921 ( для этой микросхемы была в сети найдена хорошая библиотека для IDE Arduino, модернизировав которую,удалось получить работоспособный код для ESP8266 в среде ардуино)
Как установить и настороить IDE Arduino хорошо рассказано в материалах 1 и 2 .
Для программирования платы в среде Arduino надо выбрать (для платы RobotDyn) NodeMCU 1.0
Соответствие контактов, используемых в среде Arduino и платы:
Т.е. digitalWrite(0, HIGH) обозначит 3.3V на пине D3.
Для использования ШИМа используется команда analogWrite(16, 1024) – на пинах, на которых есть ШИМ ( волнистая линия от контактов):
Для получения » настояшего» не шимового, сглаженного напряжения использована микросхема MCP 4921 серии 49xx (последняя цифра показывает число каналов, предпоследняя – качество ЦАП (2 – 12 разрядный преобразователь).
ссылка на документацию серии.
Для работы микросхемы с IDE Arduino есть библиотека. Но библиотека для Arduino, не для ESP8266.
Для того, чтобы она стала компилироваться, необходимо поставить в ремарки все «ускорения» предусмотренные Автором библиотеки ( где он напямую программирует порты Atmel микропроцессоров.
В файле DAC_MCP49xx.cpp необходимо поставить в ремарки выражения, содержащие следующие команды:
//if (this->port_write) // PORTB &= 0xfb; // Clear PORTB pin 2 = arduino pin 10 //else
Ссылка на загрузку отредактированной библиотеки (архив 7Z)
Для работы этой библиотеки требуется стандартная для Arduino библиотека SPI.h.
» Библиотека SPI поддерживает все API Arduino-библиотеки SPI, включая функции beginTransaction() и endTransaction(), а также настройку фазы тактового сигнала (CPHA). Настройка полярности тактового сигнала (CPOL) пока не поддерживается (не работают режимы SPI_MODE2 и SPI_MODE3).
По умолчанию контактами для SPI являются…
- GPIO13 (MOSI)
- GPIO12 (MISO)
- GPIO14 (SCLK)
Также есть расширенный режим, позволяющий перенести шину SPI на аппаратные контакты SPI0. Для этого сначала вызовите функцию SPI.begin(), а затем SPI.pins(6, 7, 8, 0). В результате контакты изменятся на…
- SD1 (MOSI)
- SD0 (MISO)
- CLK (SCLK)
- GPIO0 (HWCS)
Этот режим использует те же контакты, что и контроллер, который считывает из flash-памяти программный код и управляется аппаратным арбитром (у flash-памяти всегда более высокий приоритет). В этом режиме линия CS будет управляться не вами, а самим устройством. У вас нет возможности узнать, когда арбитр дает доступ к шине, поэтому вы не можете управлять линией CS при помощи GPIO-контакта, т.е. вы должны позволить ему управлять линией CS автоматически. »
Схема соединений:
/* * This sketch demonstrates how to set up a simple HTTP-like server. * The server will set a GPIO pin depending on the request * http://server_ip/gpio/0 will set the GPIO2 low, * http://server_ip/gpio/1 will set the GPIO2 high * server_ip is the IP address of the ESP8266 module, will be * printed to Serial when the module is connected. */ #include <SPI.h> // need for DAC_MCP49xx.h #include <DAC_MCP49xx.h> // for MCP4921 DAC which prepare analog current (0-5V) #include <ESP8266WiFi.h> // for wifi internet const char* ssid = "ваш ssid wifi"; // ssid const char* password = "ваш пароль на доступ к сети"; // password // Create an instance of the server // specify the port to listen on as an argument WiFiServer server(80); // creating DCA instance DAC_MCP49xx dac(DAC_MCP49xx::MCP4921, 16); // setup procedure void setup() { // beginning serial port for check status Serial.begin(115200); delay(10); // prepare GPIO2 (invert led on board) pinMode(2, OUTPUT); // prepare PWM pin (D3 pin) pinMode(0, OUTPUT); //first parameters for pins and DAC digitalWrite(2, 0); analogWrite(0, 0); dac.output(0); // Connect to WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); //setup wifi WiFi.begin(ssid, password); //waiting for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("*"); } Serial.println(); Serial.println("WiFi connected"); // Start the server server.begin(); Serial.println("Server started"); // Print the IP address Serial.print("IP address: "); Serial.println(WiFi.localIP()); } // loop procedure void loop() { // Check if a client has connected WiFiClient client = server.available(); if (!client) { return; } // Wait until the client sends some data Serial.println("new client connected"); while(!client.available()){ delay(1); } // Read the first line of the request String req = client.readStringUntil('\r'); Serial.println(req); client.flush(); // Match the request int led_val; int pwm_val; int val_dac; if (req.indexOf("/gpio/0") != -1){ led_val = 1; // led off pwm_val = 512; // half of full PWM val_dac = 0; // 0V } else if (req.indexOf("/gpio/1") != -1){ val = 0; // led on val1 = 1024; // full PWM val_dac = 4095;// 5V } else { Serial.println("invalid request"); client.stop(); return; } // Set GPIO2 according to the request digitalWrite(2, val); // Set GPIO0 (D3 of board) analogWrite(0, val1); // set current thru DAC dac.output(val_dac); client.flush(); // Prepare the response String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now "; s += (val)?"high":"low"; s += "</html>\n"; // Send the response to the client client.print(s); delay(1); Serial.println("Client disonnected"); // The client will actually be disconnected // when the function returns and 'client' object is destroyed }
Осциллограф показывает очень хорошее качество "нормального" напряжения:
управляется сервер через GET запрос по адресу ESP8266:
Исходниками материалов для статьи послужили отличные посты, доступные в предыдущей статье.