Actions

KAmodESP32 POW RS485 (PL): Difference between revisions

From Kamamilabs.com - Wiki

 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
__jzpdf__
__jzpdf__
===== Opis =====
====== Opis ======
Płytka ewaluacyjna z modułem Wi-Fi typu ESP32-WROOM, interfejsem RS485 oraz wydajnym układem zasilania. <br> <br>
[https://kamami.pl/esp32/1191671-kamod-esp32-powrs485-plytka-ewaluacyjna-z-modulem-wi-fi-typu-esp32-wroom-i-interfejsem-rs485-5906623488070.html KAmodESP32 POW RS485] - Płytka ewaluacyjna z modułem Wi-Fi typu ESP32-WROOM, interfejsem RS485 oraz wydajnym układem zasilania. <br> <br>
Na płytce KAmod ESP32 POW+RS485 znajduje się moduł ESP32-WROOM umożliwiający komunikację w sieci bezprzewodowej Wi-Fi 2,4 GHz. Do programowania ESP32 zastosowano konwerter USB-UART ze złączem USB-C. Moduł jest połączony z interfejsem RS485 - popularnym rozwiązaniem w automatyce domowej i przemysłowej, umożliwiającym komunikację poprzez 2-żyłową skrętkę np. w standardzie MODBUS. Płytkę uzupełnia wydajny układ zasilania, który pracuje przy napięciu wejściowym z zakresu od 8 do 32 V, a dostarcza stabilizowanych napięć 5 V oraz 3,3 V o znacznej wydajności prądowej. Konstrukcja płytki odpowiada SBC rodziny Raspberry Pi - ma wymiary 81x56 mm, a na charakterystycznym, 40-stykowym złączu zostały wyprowadzone wszystkie istotne porty I/O oraz napięcia zasilające.
Na płytce KAmod ESP32 POW+RS485 znajduje się moduł ESP32-WROOM umożliwiający komunikację w sieci bezprzewodowej Wi-Fi 2,4 GHz. Do programowania ESP32 zastosowano konwerter USB-UART ze złączem USB-C. Moduł jest połączony z interfejsem RS485 - popularnym rozwiązaniem w automatyce domowej i przemysłowej, umożliwiającym komunikację poprzez 2-żyłową skrętkę np. w standardzie MODBUS. Płytkę uzupełnia wydajny układ zasilania, który pracuje przy napięciu wejściowym z zakresu od 8 do 32 V, a dostarcza stabilizowanych napięć 5 V oraz 3,3 V o znacznej wydajności prądowej. Konstrukcja płytki odpowiada SBC rodziny Raspberry Pi - ma wymiary 81x56 mm, a na charakterystycznym, 40-stykowym złączu zostały wyprowadzone wszystkie istotne porty I/O oraz napięcia zasilające.
<center>
<center>
Line 271: Line 271:
=====Program testowy=====
=====Program testowy=====
Kod programu testowego znajduje się poniżej, można go skompilować w środowisku Arduino.<br><br>
Kod programu testowego znajduje się poniżej, można go skompilować w środowisku Arduino.<br><br>
<syntaxhighlight lang="arduino" line>
#include <WiFi.h>
#include <NetworkClient.h>
#include <WiFiAP.h>
#include <HardwareSerial.h>


<code>
//LED
<span style="color: purple">#include</span> <span style="color: teal"><WiFi.h></span><br>
#define LED_PIN 2  
<span style="color: purple">#include</span> <span style="color: teal"> <NetworkClient.h></span><br>
<span style="color: purple">#include</span> <span style="color: teal"><WiFiAP.h></span><br>
<span style="color: purple">#include</span> <span style="color: teal"><HardwareSerial.h></span><br>
<br>
<span style="color: purple">#define </span> <span style="color: orange">LED_PIN</span> <span style="color: teal">2 </span><br>
<br>
//Server<br>
<span style="color: teal"><b>const char</b></span><span style="color: grey"> *ssid = </span><span style="color: teal">"KAmodESP32"</span><span style="color: grey">;</span><br>


<span style="color: teal"><b>const char</b></span><span style="color: grey"> *password = </span><span style="color: teal">"12345678"</span><span style="color: grey">;</span><br>
//Server
<span style="color: grey">NetworkServer </span><span style="color: orange">server</span><span style="color: grey">(</span><span style="color: teal">80</span><span style="color: grey">)</span><span style="color: grey">;</span><br><br>
const char *ssid = "KAmodESP32";
const char *password = "12345678";
NetworkServer server(80);


<span style="color: grey">IPAddress</span> <span style="color: orange">AP_LOCAL_IP</span> <span style="color: grey">(</span><span style="color: teal">192, 168, 1, 1</span><span style="color: grey">)</span><span style="color: grey">;</span><br>
IPAddress AP_LOCAL_IP(192, 168, 1, 1);
<span style="color: grey">IPAddress</span> <span style="color: orange">AP_GATEWAY_IP</span> <span style="color: grey">(</span><span style="color: teal">192, 168, 1, 254</span><span style="color: grey">)</span><span style="color: grey">;</span><br>
IPAddress AP_GATEWAY_IP(192, 168, 1, 254);
<span style="color: grey">IPAddress</span> <span style="color: orange">AP_NETWORK_MASK</span> <span style="color: grey">(</span><span style="color: teal">255, 255, 255, 0</span><span style="color: grey">)</span><span style="color: grey">;</span><br><br>
IPAddress AP_NETWORK_MASK(255, 255, 255, 0);


//RS485<br>
//RS485
<span style="color: purple">#define</span> <span style="color: orange">RS485_RXD</span> <span style="color: teal">27</span> <span style="color: grey">//RO PIN</span><br>
#define RS485_RXD 27 //RO PIN
<span style="color: purple">#define</span> <span style="color: orange">RS485_TXD</span> <span style="color: teal">25</span> <span style="color: grey">//DI PIN</span><br>
#define RS485_TXD 25 //DI PIN
<span style="color: purple">#define</span> <span style="color: orange">RS485_RE_DE</span> <span style="color: teal">26</span> <span style="color: grey">//RE & DE PIN</span><br>
#define RS485_RE_DE 26 //RE & DE PIN
<span style="color: purple">#define</span> <span style="color: orange">RX_BUFF_SIZE</span> <span style="color: teal">64</span><br>
#define RX_BUFF_SIZE 64
<span style="color: grey">HardwareSerial</span> <span style="color: orange">RS485Port</span><span style="color: grey">(</span><span style="color: teal">2</span><span style="color: grey">)</span><span style="color: grey">;</span><br><br>
HardwareSerial RS485Port(2);


<span style="color: teal">void</span> <span style="color: orange">setup</span><span style="color: grey">() {</span><br>
void setup() {
   //Serial
   //Serial
   <span style="color: orange">Serial.begin </span><span style="color: grey">(</span><span style="color: teal">115200</span><span style="color: grey">);</span>
   Serial.begin(115200);
   <span style="color: orange">Serial.println </span><span style="color: grey">(</span><span style="color: teal">"Hello. Configuring access point..."</span><span style="color: grey">);</span><br>
   Serial.println("Hello. Configuring access point...");


   //Server
   //Server
   <span style="color: orange">WiFi.softAPConfig</span><span style="color: grey">(AP_LOCAL_IP, AP_GATEWAY_IP, AP_NETWORK_MASK);</span>
   WiFi.softAPConfig(AP_LOCAL_IP, AP_GATEWAY_IP, AP_NETWORK_MASK);
   <span style="color: purple">if</span> <span style="color: grey">(!</span><span style="color: orange">WiFi.softAP</span><span style="color: grey">(ssid, password)) {</span>
   if (!WiFi.softAP(ssid, password)) {
     <span style="color: orange">log_e</span><span style="color: grey">(</span><span style="color: teal">"Soft AP creation failed."</span><span style="color: grey">);</span>
     log_e("Soft AP creation failed.");
     <span style="color: purple">while </span><span style="color: grey">(</span><span style="color: teal">1</span><span style="color: grey">)</span>;
     while (1);
   <span style="color: grey">}
   }
   IPAddress myIP = </span><span style="color: orange">WiFi.softAPIP</span><span style="color: grey">();</span>
   IPAddress myIP = WiFi.softAPIP();
   <span style="color: orange">Serial.print</span><span style="color: grey">(</span><span style="color: teal">"AP IP address: "</span><span style="color: grey">);</span>
   Serial.print("AP IP address: ");
   <span style="color: orange">Serial.println</span><span style="color: grey">(myIP);</span>
   Serial.println(myIP);
   <span style="color: orange">Serial.print</span><span style="color: grey">(</span><span style="color: teal">"AP MAC address: "</span><span style="color: grey">);</span>
   Serial.print("AP Mac Address: ");
   <span style="color: orange">Serial.println</span><span style="color: grey">(</span><span style="color: orange">WiFi.softAPmacAddress</span><span style="color: grey">());</span>
   Serial.println(WiFi.softAPmacAddress());
   <span style="color: orange">server.begin</span><span style="color: grey">();</span><br>
   server.begin();


   //RS485
   //RS485
   //pinMode(RS485_RE_DE, OUTPUT);
   //pinMode(RS485_RE_DE, OUTPUT);
   //digitalWrite(RS485_RE_DE, LOW);
   //digitalWrite(RS485_RE_DE, LOW);
   <span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">setPins</span><span style="color: grey">(RS485_RXD, RS485_TXD, RS485_RE_DE);</span>
   RS485Port.setPins(RS485_RXD, RS485_TXD, RS485_RE_DE);
   <span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">setHwFlowCtrlMode</span><span style="color: grey">(UART_HW_FLOWCTRL_CTS);</span>
   RS485Port.setHwFlowCtrlMode(UART_HW_FLOWCTRL_CTS);
   <span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">setMode</span><span style="color: grey">(UART_MODE_RS485_HALF_DUPLEX);</span>
   RS485Port.setMode(UART_MODE_RS485_HALF_DUPLEX);
   <span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">begin</span><span style="color: grey">(</span><span style="color: teal">115200</span><span style="color: grey">, SERIAL_8N1, RS485_RXD, RS485_TXD);</span>
   RS485Port.begin(115200, SERIAL_8N1, RS485_RXD, RS485_TXD);
   <span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"RS485 Hello"</span><span style="color: grey">);</span><br>
   RS485Port.println("RS485 Hello");


   //LED
   //LED
   <span style="color: orange">pinMode</span><span style="color: grey">(LED_PIN, OUTPUT);</span>
   pinMode(LED_PIN, OUTPUT);
   <span style="color: purple">for</span><span style="color: grey">(</span><span style="color: teal">int</span> <span style="color: grey">i=</span><span style="color: teal">0</span><span style="color: grey">; i<</span><span style="color: teal">10</span><span style="color: grey">; i++){</span>
   for(int i=0; i<10; i++){
     <span style="color: orange">digitalWrite</span><span style="color: grey">(LED_PIN, HIGH);</span>
     digitalWrite(LED_PIN, HIGH);
     <span style="color: orange">delay</span><span style="color: grey">(</span><span style="color: teal">200</span><span style="color: grey">);</span>
     delay(200);
     <span style="color: orange">digitalWrite</span><span style="color: grey">(LED_PIN, LOW);</span>
     digitalWrite(LED_PIN, LOW);
     <span style="color: orange">delay</span><span style="color: grey">(</span><span style="color: teal">200</span><span style="color: grey">);</span>
     delay(200);
  <span style="color: grey">}</span>
  }
<span style="color: grey">}</span><br>
}
<span style="color: teal">void</span> <span style="color: orange">loop</span><span style="color: grey">() {</span>
 
<span style="color: grey">Networkclient client =</span> <span style="color: orange">server</span><span style="color: grey">.</span><span style="color: orange">accept</span><span style="color: grey">();</span><br>
void loop() {
  NetworkClient client = server.accept();
 
  if (client) {
    Serial.println("********New Client********");
 
    String currentLine = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n') {
 
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
            client.print("<H1>Click <a href=\"/H\">here</a> to turn ON the LED.<br><br>");
            client.print("Click <a href=\"/L\">here</a> to turn OFF the LED.<br><br>");
            client.print("Click <a href=\"/RS485\">here</a> to write to RS485.<br><br></H1>");
            client.println();
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }


<span style="color: purple">if</span> <span style="color: grey">(client</span><span style="color: grey">)</span> {
        //if (currentLine.endsWith("GET /H")) {
  <span style="color: orange">Serial</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"********New client********"</span><span style="color: grey">);</span><br>
        if (currentLine.indexOf("GET /H") >= 0) {
          digitalWrite(LED_PIN, HIGH);
        }
        //if (currentLine.endsWith("GET /L")) {
        if (currentLine.indexOf("GET /L") >= 0) {
          digitalWrite(LED_PIN, LOW);
        }
        if (currentLine.endsWith("GET /RS485")) {
          RS485Port.println("You send message via RS485");
        }
      }
    }
    client.stop();
    Serial.println("********Client Disconnected********");
  } else {
    RS485Port.println("Tick...");
    delay(1000);
  }
}


  <span style="color: grey">String currentLine =</span> <span style="color: teal">""</span><span style="color: grey">;</span>
</syntaxhighlight>
  <span style="color: purple">while</span> <span style="color: grey">(</span><span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">connected</span><span style="color: grey">(</span><span style="color: grey">)</span><span style="color: grey">) {</span>
  <span style="color: purple">if</span> <span style="color: grey">(</span><span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">available</span><span style="color: grey">()) {</span>
    <span style="color: teal">char</span> <span style="color: grey">c =</span> <span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">read</span><span style="color: grey">();</span>
    <span style="color: orange">Serial</span><span style="color: grey">.</span><span style="color: orange">write</span><span style="color: grey">(c);</span>
    <span style="color: purple">if</span> <span style="color: grey">(c == '</span><span style="color: teal">\n</span><span style="color: grey">') {</span><br>
    <span style="color: purple">if</span> <span style="color: grey">(</span><span style="color: orange">currentLine</span><span style="color: grey">.</span><span style="color: orange">length</span><span style="color: grey">(</span><span style="color: grey">) == </span><span style="color: teal">0</span><span style="color: grey">) {</span>
      <span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"HTTP/1.1 200 OK"</span><span style="color: grey">);</span>
      <span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"Content-type:text/html"</span><span style="color: grey">);</span>
      <span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: grey">);</span>
      <span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"Click <a href=\"/H\">here</a> to turn ON the LED.<nowiki><br></nowiki>"</span><span style="color: grey">);</span>
      <span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"Click <a href=\"/L\">here</a> to turn OFF the LED.<nowiki><br></nowiki>"</span><span style="color: grey">);</span>
      <span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"Click <a href=\"/RS485\">here</a> to write to RS485.<nowiki><br></nowiki>"</span><span style="color: grey">);</span>
      <span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: grey">);</span>
      <span style="color: purple">break</span><span style="color: grey">;</span>
    <span style="color: grey">}</span> <span style="color: purple">else</span> <span style="color: grey">{</span>
      <span style="color: grey">currentLine =</span> <span style="color: teal">""</span><span style="color: grey">;</span>
    <span style="color: grey">}</span>
    <span style="color: grey">}</span> <span style="color: purple">else if</span> <span style="color: grey">(c != </span><span style="color: teal">'\r'</span><span style="color: grey">) {</span>
    <span style="color: grey">currentLine += c;</span>
    <span style="color: grey">}</span>
    //if (currentLine.endsWith("GET /H")) {
    <span style="color: purple">if</span> <span style="color: grey">(</span><span style="color: orange">currentLine</span><span style="color: grey">.</span><span style="color: orange">indexOf</span><span style="color: grey">(</span><span style="color: teal">"GET /H"</span><span style="color: grey">) >=</span> <span style="color: teal">0</span><span style="color: grey">) {</span>
    <span style="color: orange">digitalWrite</span><span style="color: grey">(LED_PIN, HIGH);</span>
    <span style="color: grey">}</span>
    //if (currentLine.endsWith("GET /L")) {
    <span style="color: purple">if</span> <span style="color: grey">(</span><span style="color: orange">currentLine</span><span style="color: grey">.</span><span style="color: orange">indexOf</span><span style="color: grey">(</span><span style="color: teal">"GET /L"</span><span style="color: grey">) >=</span> <span style="color: teal">0</span><span style="color: grey">) {</span>
    <span style="color: orange">digitalWrite</span><span style="color: grey">(LED_PIN, LOW);</span>
    <span style="color: grey">}</span>
    <span style="color: purple">if</span> <span style="color: grey">(</span><span style="color: orange">currentLine</span><span style="color: grey">.</span><span style="color: orange">endsWith</span><span style="color: grey">(</span><span style="color: teal">"GET /RS485"</span><span style="color: grey">)) {</span>
    <span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"You send message via RS485"</span><span style="color: grey">);</span>
    <span style="color: grey">}</span>
  <span style="color: grey">}</span>
  <span style="color: grey">}</span>
  <span style="color: orange">client</span><span style="color: grey">.</span><span style="color: orange">stop</span><span style="color: grey">();</span>
  <span style="color: orange">Serial</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"********Client Disconnected********"</span><span style="color: grey">);</span>
<span style="color: grey">}</span> <span style="color: purple">else</span> <span style="color: grey">{</span>
  <span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"Tick..."</span><span style="color: grey">);</span>
  <span style="color: orange">delay</span><span style="color: grey">(</span><span style="color: teal">1000</span><span style="color: grey">);</span>
<span style="color: grey">}</span>
<span style="color: grey">}</span><br>


<br>
</code>


Program testowy konfiguruje sprzętowy interfejs UART 2 do pracy jako interfejs RS485 ze sprzętowym sterowaniem kierunkiem transmisji:
Program testowy konfiguruje sprzętowy interfejs UART 2 do pracy jako interfejs RS485 ze sprzętowym sterowaniem kierunkiem transmisji:
<br><br>
<br><br>
<syntaxhighlight lang="arduino" line>
#define RS485_RXD 27 //RO PIN
#define RS485_TXD 25 //DI PIN
#define RS485_RE_DE 26 //RE & DE PIN
#define RX_BUFF_SIZE 64
HardwareSerial RS485Port(2);
...
RS485Port.setPins(RS485_RXD, RS485_TXD, RS485_RE_DE);
RS485Port.setHwFlowCtrlMode(UART_HW_FLOWCTRL_CTS);
RS485Port.setMode(UART_MODE_RS485_HALF_DUPLEX);
RS485Port.begin(115200, SERIAL_8N1, RS485_RXD, RS485_TXD);
RS485Port.println("RS485 Hello");
</syntaxhighlight>


<code>
<span style="color: purple">#define</span> <span style="color: orange">RS485_RXD</span> <span style="color: teal">27</span> //RO PIN <br>
<span style="color: purple">#define</span> <span style="color: orange">RS485_TXD</span> <span style="color: teal">25</span> //DI PIN<br>
<span style="color: purple">#define</span> <span style="color: orange">RS485_RE_DE</span> <span style="color: teal">26</span> //RE & DE PIN<br>
<span style="color: purple">#define</span> <span style="color: orange">RX_BUFF_SIZE</span> <span style="color: teal">64</span> <br>


<span style="color: gray">HardwareSerial</span> <span style="color: orange">RS485Port</span><span style="color: gray">(</span><span style="color: teal">2</span><span style="color: gray">);</span> <br>
...<br>
<span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">setPins</span><span style="color: grey">(RS485_RXD, RS485_TXD, RS485_RE_DE);</span><br>
<span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">setHwFlowCtrlMode</span><span style="color: grey">(UART_HW_FLOWCTRL_CTS);</span><br>
<span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">setMode</span><span style="color: grey">(UART_MODE_RS485_HALF_DUPLEX);</span><br>
<span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">begin</span><span style="color: grey">(</span><span style="color: teal">115200</span><span style="color: grey">, SERIAL_8N1, RS485_RXD, RS485_TXD);</span><br>
<span style="color: orange">RS485Port</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: teal">"RS485 Hello"</span><span style="color: grey">);</span><br>


</code>
<br>
<br>
Ponadto program testowy uruchamia moduł ESP32 w trybie access pointa oraz w roli serwera www:
Ponadto program testowy uruchamia moduł ESP32 w trybie access pointa oraz w roli serwera www:
<br>
<br>
<syntaxhighlight lang="arduino" line>
const char *ssid = "KAmodESP32";
const char *password = "12345678";
NetworkServer server(80);
IPAddress AP_LOCAL_IP(192, 168, 1, 1);
IPAddress AP_GATEWAY_IP(192, 168, 1, 254);
IPAddress AP_NETWORK_MASK(255, 255, 255, 0);
WiFi.softAPConfig(AP_LOCAL_IP, AP_GATEWAY_IP, AP_NETWORK_MASK);
if (!WiFi.softAP(ssid, password)) {
log_e("Soft AP creation failed.");
while (1);
}
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
Serial.print("AP Mac Address: ");
Serial.println(WiFi.softAPmacAddress());
server.begin();
</syntaxhighlight>


<code>
<br><span style="color: teal"><b>const char</b></span> <span style="color: grey">*ssid =</span> <span style="color: teal">"KAmodESP32"</span><span style="color: grey">;</span><br>
<span style="color: teal"><b>const char</b></span> <span style="color: grey">*password =</span> <span style="color: teal">"12345678"</span><span style="color: grey">;</span><br>
<span style="color: grey">NetworkServer</span> <span style="color: orange">server</span><span style="color: grey">(</span><span style="color: teal">80</span><span style="color: grey">);</span><br>
<span style="color: grey">IPAddress</span> <span style="color: orange">AP_LOCAL_IP</span><span style="color: grey">(</span><span style="color: teal">192</span><span style="color: grey">,</span> <span style="color: teal">168</span><span style="color: grey">,</span> <span style="color: teal">1</span><span style="color: grey">,</span> <span style="color: teal">1</span><span style="color: grey">);</span><br>
<span style="color: grey">IPAddress</span> <span style="color: orange">AP_GATEWAY_IP</span><span style="color: grey">(</span><span style="color: teal">192</span><span style="color: grey">,</span> <span style="color: teal">168</span><span style="color: grey">,</span> <span style="color: teal">1</span><span style="color: grey">,</span> <span style="color: teal">254</span><span style="color: grey">);</span><br>
<span style="color: grey">IPAddress</span> <span style="color: orange">AP_NETWORK_MASK</span><span style="color: grey">(</span><span style="color: teal">255</span><span style="color: grey">,</span> <span style="color: teal">255</span><span style="color: grey">,</span> <span style="color: teal">255</span><span style="color: grey">,</span> <span style="color: teal">0</span><span style="color: grey">);</span><br><br>
<span style="color: orange">WiFi</span><span style="color: grey">.</span><span style="color: orange">softAPConfig</span><span style="color: grey">(AP_LOCAL_IP, AP_GATEWAY_IP, AP_NETWORK_MASK);</span><br>
<span style="color: purple">if</span> <span style="color: grey">(!</span><span style="color: orange">WiFi</span><span style="color: grey">.</span><span style="color: orange">softAP</span><span style="color: grey">(ssid, password)) {</span><br>
<span style="color: orange">log_e</span><span style="color: grey">(</span><span style="color: teal">"Soft AP creation failed."</span><span style="color: grey">);</span><br>
<span style="color: purple">while</span> <span style="color: grey">(</span><span style="color: teal">1</span><span style="color: grey">);</span><br>
<span style="color: grey">}</span><br>
<span style="color: grey">IPAddress myIP =</span> <span style="color: orange">WiFi</span><span style="color: grey">.</span><span style="color: orange">softAPIP</span><span style="color: grey">();</span><br>
<span style="color: orange">Serial</span><span style="color: grey">.</span><span style="color: orange">print</span><span style="color: grey">(</span><span style="color: teal">"AP IP address: "</span><span style="color: grey">);</span><br>
<span style="color: orange">Serial</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(myIP);</span><br>
<span style="color: orange">Serial</span><span style="color: grey">.</span><span style="color: orange">print</span><span style="color: grey">(</span><span style="color: teal">"AP Mac Address: "</span><span style="color: grey">);</span><br>
<span style="color: orange">Serial</span><span style="color: grey">.</span><span style="color: orange">println</span><span style="color: grey">(</span><span style="color: orange">WiFi</span><span style="color: grey">.</span><span style="color: orange">softAPmacAddress</span><span style="color: grey">());</span><br>
<span style="color: orange">server</span><span style="color: grey">.</span><span style="color: orange">begin</span><span style="color: grey">();</span><br>
</code>
<br>
<br>
Po uruchomieniu programu testowego powstanie sieć Wi-Fi o nazwie (SSID): ''KAmodESP32'' z hasłem: 12345678. Za pomocą smartfona należy dołączyć się do tej sieci, a następnie w przeglądarce internetowej wpisać adres IP strony: 192, 168, 1, 1. Wyświetli się bardzo prosta strona www, która pozwoli sterować diodą LED D6 lub wysłać prosty komunikat poprzez interfejs RS485:
Po uruchomieniu programu testowego powstanie sieć Wi-Fi o nazwie (SSID): ''KAmodESP32'' z hasłem: 12345678. Za pomocą smartfona należy dołączyć się do tej sieci, a następnie w przeglądarce internetowej wpisać adres IP strony: 192, 168, 1, 1. Wyświetli się bardzo prosta strona www, która pozwoli sterować diodą LED D6 lub wysłać prosty komunikat poprzez interfejs RS485:

Latest revision as of 19:30, 1 November 2024

Opis

KAmodESP32 POW RS485 - Płytka ewaluacyjna z modułem Wi-Fi typu ESP32-WROOM, interfejsem RS485 oraz wydajnym układem zasilania.

Na płytce KAmod ESP32 POW+RS485 znajduje się moduł ESP32-WROOM umożliwiający komunikację w sieci bezprzewodowej Wi-Fi 2,4 GHz. Do programowania ESP32 zastosowano konwerter USB-UART ze złączem USB-C. Moduł jest połączony z interfejsem RS485 - popularnym rozwiązaniem w automatyce domowej i przemysłowej, umożliwiającym komunikację poprzez 2-żyłową skrętkę np. w standardzie MODBUS. Płytkę uzupełnia wydajny układ zasilania, który pracuje przy napięciu wejściowym z zakresu od 8 do 32 V, a dostarcza stabilizowanych napięć 5 V oraz 3,3 V o znacznej wydajności prądowej. Konstrukcja płytki odpowiada SBC rodziny Raspberry Pi - ma wymiary 81x56 mm, a na charakterystycznym, 40-stykowym złączu zostały wyprowadzone wszystkie istotne porty I/O oraz napięcia zasilające.

Podstawowe parametry
  • Moduł ESP32-WROOM umożliwiający komunikację w sieci Wi-Fi w paśmie 2,4 GHz
  • Zintegrowany konwerter UART-USB ze złączem USB-C umożliwiający programowanie układu ESP32
  • Interfejs RS485 do komunikacji Half-duplex z maksymalną szybkością 1 Mbps
  • Maksymalna liczba urządzeń dołączonych do magistrali RS485: 64
  • Dostosowany do napięcia zasilającego z zakresu 8...32 V
  • Dostarcza stabilizowanego napięcia 5,1 V o prądzie ciągłym do 3 A i krótkotrwałym do wartości 5 A
  • Dostarcza stabilizowanego napięcia 3,3 V o prądzie ciągłym do 1 A i krótkotrwałym do wartości 2 A
  • Zabezpieczenie przepięciowe, przeciążeniowe oraz termiczne
  • Na 40-stykowe złącze w standardzie Raspberry Pi zostały wyprowadzone wszystkie istotne porty I/O oraz napięcia zasilające
  • Wymiary płytki: 81x56 mm, wysokość ok. 20 mm
Wyposażenie standardowe
Kod Opis
KAmod ESP32 POW+RS485 Zmontowany i uruchomiony moduł
Schemat elektryczny

Moduł ESP32

Elementy odpowiedzialne za funkcje resetu i programowania

Złącze GPIO

Interfejs RS485

Diody sygnalizacyjne

Interfejs USB-UART

Blok zasilania o napięciu 5 V

Blok zasilania o napięciu 3 V

Złącze zasilania
Złącze Funkcja
POW&485

Phoenix MC3,81 mm

  • Doprowadza zasilanie do modułu
  • Złącze interfejsu RS485

Złącze POW&485 (J3) pozwala na dołączenie napięcia stałego (DC) z zakresu 8...32 V, z którego jest wytwarzane napięcie 5,1 V do zasilania wszystkich komponentów płytki. Dołączając napięcie do złącza POW&485 należy zwrócić uwagę na jego prawidłową polaryzację. Oznaczenie na spodzie płytki: POWER --|+ wskazuje prawidłową biegunowość zasilania:

  • -- - styk nr 1 to masa, ujemny biegun zasilania (GND),
  • + - styk nr 2 jest wejściem dodatniego bieguna zasilania.

Dołączenie zasilania o parametrach wystarczających do uzyskania napięcia 3,3 V będzie sygnalizowane świeceniem diody LED D3. Nie należy dołączać napięcia o wartości powyżej 34 V. Moduł zawiera zabezpieczenie przeciw-przepięciowe, które odłączy zasilanie przy napięciu wyższym od ok. 34 V. Dołączone źródło zasilania powinno mieć odpowiednią moc. Aby moduł mógł działać z zachowaniem wszystkich parametrów (5,1 V/ 5 A), moc źródła zasilania nie powinna być mniejsza niż 30 W. Dołączenie zasilania o niższej mocy będzie skutkowało niższą wartością maksymalnego prądu w obwodzie napięcia 5 V oraz 3,3 V.

Interfejs RS485
Złącze Funkcja
POW&485

Phoenix MC 3,81 mm

  • Doprowadza zasilanie do modułu
  • Złącze interfejsu RS485

Na płytce KAmod ESP32 POW RS485 został zaimplementowany kompletny obwód interfejsu RS485 wraz z elementami zabezpieczającymi przed przepięciami. W roli sterownika zastosowano układ ST485, który umożliwia dołączenie maksymalnie 64 urządzeń, pracuje w trybie half-duplex, realizuje komunikację z maksymalną prędkością 1 Mbps. Wysyłanie danych na magistralę jest sygnalizowane miganiem diody LED D4.

Połączenie interfejsu RS485 z modułem ESP32 jest następujące:

Sygnał RS485 Wyprowadzenie modułu ESP32
  • RO (odczyt z magistrali RS485)
  • DI (wysyłanie na magistralę RS485)
  • DE/RE (sterowanie kierunkiem komuniakcji;H – nadawanie/L - odczyt)
  • GPIO27
  • GPIO25
  • GPIO26

Medium transmisyjnym jest 2-żyłowa skrętka, którą należy dołączyć do złącza POW&485 (J3):

  • B-, styk nr 3, ujemny biegun magistrali RS485,
  • A+, styk nr 4, dodatni biegun magistrali RS485.

Należy także zapewnić połączenie wszystkich urządzeń w magistrali do wspólnej masy/uziemienia. Specyfikacja magistrali RS485 wymaga, aby wszystkie połączenia tworzyły linię bez rozgałęzień i pętli, a na jej końcach należy dołączyć rezystory 120 Ω, które pełnią rolę tzw. terminatorów magistrali. Na płytce KAmod ESP32 POW RS485 znajduje się odpowiedni rezystor, który można dołączyć do magistrali zakładając zworkę na szpilki oznaczone 120R.

Interfejs USB
Złącze Funkcja
P1

USB-C

  • Realizuje funkcję konwertera USB-UART
  • Umożliwia programowanie modułu ESP32
  • Jest alternatywnym wejściem zasilania

Złącze P1 typu USB-C jest połączone z kontrolerem typu CH340, który realizuje funkcje konwertera USB-UART. Interfejs UART może być używany w docelowej aplikacji, ale służy także do programowania modułu ESP32. Proces programowania może przebiegać całkowicie automatycznie, ponieważ kontroler CH340 steruje kluczowymi wyprowadzeniami modułu ESP32 (GPIO0Boot Select oraz EN - Chip Power-up).

Połączenia sygnałów pomiędzy CH340 i ESP32 są następujące:

Sygnał kontrolera CH340 Wyprowadzenie modułu ESP32
  • TXD (wyjście danych)
  • RXD (wejście danych)
  • DTR (wyście kontroli transmisji)
  • RTS (wyjście kontroli transmisji)
  • GPIO03 (UART0 RXD)
  • GPIO01 (UART0 TXD)
  • EN (Chip Power-up)
  • GPIO0 (Boot Select)

Do linii TXD jest dołączona dioda LED (D3), która sygnalizuje odbieranie danych z interfejsu USB. W przypadku użycia w docelowej aplikacji konwertera USB-UART należy zadbać o to, aby linie DTR oraz RTS pozostały nieobsługiwane (Handshaking: None).

Złącze USB-C może służyć jako alternatywne wejście zasilania dla płytki KAmod ESP32 POW RS485, jednak wtedy parametry obwodów zasilania nie będą spełnione. Napięcie na linii 5 V, będzie niższe i będzie wynosiło ok. 4,5 V; napięcie na linii 3,3 V nie powinno się zmienić; wydajność prądowa napięć 5 V oraz 3,3 V będzie dużo niższa i będzie zależała od zastosowanego zasilania na złączu USB-C.

Przyciski resetowania i programowania
Komponent Funkcja
  • Przycisk SW1 – PROG
  • Przycisk SW2 – RESET
  • Uruchamia tryb programowania poprzez UART (tylko w momencie restartu modułu ESP32)
  • Powoduje restart modułu ESP32

Przycisk RESET umożliwia wykonanie restartu modułu ESP32. Jest połączony z linią EN (Chip Power-up). modułu ESP32.

Przycisk PROG pozwala wprowadzić moduł ESP32 w tryb programowania. Należy wtedy nacisnąć przycisk RESET, następnie, trzymając wciśnięty RESET, przytrzymać przycisk PROG i wtedy zwolnić RESET, jednocześnie trzymając jeszcze przez chwilę wciśnięty PROG. Funkcjonalność ta może być przydatna, gdy z jakiegoś powodu tryb programowania nie będzie uruchamiany automatycznie poprzez konwerter USB-UART.

Kontrolki sygnalizacyjne
Komponent Funkcja
  • D3- USB TXD
  • D4- LED 485
  • D5- LED 3.3V
  • D6- LED IO-2
  • Miganie diody D3 oznacza przesyłanie danych z USB do modułu ESP32
  • Miganie diody D4 oznacza wysyłanie danych na magistralę RS485
  • Świecenie diody D5 oznacza działanie obwodu zasilania i obecność napięcia 3,3 V
  • Dioda D6 jest dołączona do wyprowadzenia GPIO2 modułu ESP32 i jej świecenie może być wyzwalane programowo

Na płytce KAmod ESP32 POW RS485 znajdują się 4 diody LED, które sygnalizują działanie różnych komponentów – zgodnie z powyższą tabelą.

Dioda D6 (LED IO-2) jest dołączona do wyprowadzenia GPIO2 modułu ESP32. Jej zaświecenie wymaga programowego ustawienia stanu wysokiego na wyprowadzeniu GPIO2

Złącze GPIO w standardzie RPi

Złącze GPIO (J1) w standardzie Raspberry Pi zawiera 40 szpilek, do których doprowadzone są linie zasilania 5 V, 3,3 V, GND oraz wyprowadzenia GPIO modułu ESP32. Wyprowadzenia interfejsów UART (TXD, RXD), I2C (SDA, SCL) oraz SPI (MOSI, MISO, SCLK, CS0) zostały rozmieszczone tak, jak ma to miejsce w płytkach rodziny Raspberry Pi.

Dokładny opis wyprowadzeń oraz ich funkcje pokazuje rysunek i tabela poniżej:

Opis wyprowadzeń został również naniesiony na spodzie płytki KAmod ESP32 POW RS485:

Uwagi dotyczące sygnałów wyprowadzonych na złącze GPIO

  • Porty GPIO 34, 35, 36 i 39 modułu ESP32 mogą pracować wyłącznie jako wejścia cyfrowe lub analogowe – zostały one oznaczone symbolem IN.
  • Porty GPIO 34 i 35 zostały wyposażone w rezystory podciągające pull-up 10k.
  • Porty GPIO 36 i 39 zostały wyposażone w dzielniki napięcia (100k/10k), dzięki czemu można do nich dołączyć napięcie o maksymalnej wartosci 35 V.
  • Porty GPIO 32 i 32 zostały dostosowane do funkcjonalności magistrali I2C i zawierają rezystory podciągające pull-up 2,2k.
  • Porty GPIO1 oraz GPIO3 pełnią funkcję interfejsu UART i zostały połączone do modułu konwertera USB-UART oraz równolegle do złącza GPIO J2. Interfejs UART wysyła/odczytuje dane do/z złącza GPIO J2 oraz konwertera USB-UART jednocześnie.
Wymiary

Wymiary płytki KAmod ESP32 POW RS485 to 81x56 mm. Wysokość maksymalna wynosi ok. 20 mm. Na płytce znajdują się 4 otwory montażowe o średnicy 3 mm rozmieszczone podobnie jak na płytkach z rodziny Raspberry Pi.

Program testowy

Kod programu testowego znajduje się poniżej, można go skompilować w środowisku Arduino.

#include <WiFi.h>
#include <NetworkClient.h>
#include <WiFiAP.h>
#include <HardwareSerial.h>

//LED
#define LED_PIN 2 

//Server
const char *ssid = "KAmodESP32";
const char *password = "12345678";
NetworkServer server(80);

IPAddress AP_LOCAL_IP(192, 168, 1, 1);
IPAddress AP_GATEWAY_IP(192, 168, 1, 254);
IPAddress AP_NETWORK_MASK(255, 255, 255, 0);

//RS485
#define RS485_RXD 27 //RO PIN
#define RS485_TXD 25 //DI PIN
#define RS485_RE_DE 26 //RE & DE PIN
#define RX_BUFF_SIZE 64
HardwareSerial RS485Port(2);

void setup() {
  //Serial
  Serial.begin(115200);
  Serial.println("Hello. Configuring access point...");

  //Server
  WiFi.softAPConfig(AP_LOCAL_IP, AP_GATEWAY_IP, AP_NETWORK_MASK);
  if (!WiFi.softAP(ssid, password)) {
    log_e("Soft AP creation failed.");
    while (1);
  }
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  Serial.print("AP Mac Address: ");
  Serial.println(WiFi.softAPmacAddress());
  server.begin();

  //RS485
  //pinMode(RS485_RE_DE, OUTPUT);
  //digitalWrite(RS485_RE_DE, LOW);
  RS485Port.setPins(RS485_RXD, RS485_TXD, RS485_RE_DE);
  RS485Port.setHwFlowCtrlMode(UART_HW_FLOWCTRL_CTS);
  RS485Port.setMode(UART_MODE_RS485_HALF_DUPLEX);
  RS485Port.begin(115200, SERIAL_8N1, RS485_RXD, RS485_TXD);
  RS485Port.println("RS485 Hello");

  //LED
  pinMode(LED_PIN, OUTPUT);
  for(int i=0; i<10; i++){
    digitalWrite(LED_PIN, HIGH);
    delay(200);
    digitalWrite(LED_PIN, LOW);
    delay(200);
  }
}

void loop() {
  NetworkClient client = server.accept();

  if (client) {
    Serial.println("********New Client********");

    String currentLine = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n') {

          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
            client.print("<H1>Click <a href=\"/H\">here</a> to turn ON the LED.<br><br>");
            client.print("Click <a href=\"/L\">here</a> to turn OFF the LED.<br><br>");
            client.print("Click <a href=\"/RS485\">here</a> to write to RS485.<br><br></H1>");
            client.println();
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }

        //if (currentLine.endsWith("GET /H")) {
        if (currentLine.indexOf("GET /H") >= 0) {
          digitalWrite(LED_PIN, HIGH);
        }
        //if (currentLine.endsWith("GET /L")) {
        if (currentLine.indexOf("GET /L") >= 0) {
          digitalWrite(LED_PIN, LOW);
        }
        if (currentLine.endsWith("GET /RS485")) {
          RS485Port.println("You send message via RS485");
        }
      }
    }
    client.stop();
    Serial.println("********Client Disconnected********");
  } else {
    RS485Port.println("Tick...");
    delay(1000);
  }
}


Program testowy konfiguruje sprzętowy interfejs UART 2 do pracy jako interfejs RS485 ze sprzętowym sterowaniem kierunkiem transmisji:

#define RS485_RXD 27 //RO PIN
#define RS485_TXD 25 //DI PIN
#define RS485_RE_DE 26 //RE & DE PIN
#define RX_BUFF_SIZE 64
HardwareSerial RS485Port(2);
...
RS485Port.setPins(RS485_RXD, RS485_TXD, RS485_RE_DE);
RS485Port.setHwFlowCtrlMode(UART_HW_FLOWCTRL_CTS);
RS485Port.setMode(UART_MODE_RS485_HALF_DUPLEX);
RS485Port.begin(115200, SERIAL_8N1, RS485_RXD, RS485_TXD);
RS485Port.println("RS485 Hello");



Ponadto program testowy uruchamia moduł ESP32 w trybie access pointa oraz w roli serwera www:

const char *ssid = "KAmodESP32";
const char *password = "12345678";
NetworkServer server(80);
IPAddress AP_LOCAL_IP(192, 168, 1, 1);
IPAddress AP_GATEWAY_IP(192, 168, 1, 254);
IPAddress AP_NETWORK_MASK(255, 255, 255, 0);
WiFi.softAPConfig(AP_LOCAL_IP, AP_GATEWAY_IP, AP_NETWORK_MASK);
if (!WiFi.softAP(ssid, password)) {
log_e("Soft AP creation failed.");
while (1);
}
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
Serial.print("AP Mac Address: ");
Serial.println(WiFi.softAPmacAddress());
server.begin();


Po uruchomieniu programu testowego powstanie sieć Wi-Fi o nazwie (SSID): KAmodESP32 z hasłem: 12345678. Za pomocą smartfona należy dołączyć się do tej sieci, a następnie w przeglądarce internetowej wpisać adres IP strony: 192, 168, 1, 1. Wyświetli się bardzo prosta strona www, która pozwoli sterować diodą LED D6 lub wysłać prosty komunikat poprzez interfejs RS485:

Linki