2020/6/28:
初版
PlatformIO Wio Lite RISC-V WiFi4 MQTT
概要
Wio_Lite_RISC-VボードでWiFiを動かす(その4:MQTT)。
これは「Wio_Lite_RISC-VボードでWiFiを動かす(その3:OSC)」の続きになる。ここでは、MQTTのデモプログラムについて記載する
開発ツール(PlatformIOなど)のインストールについては「開発ツールPlatformIOをcliで使う(Wio_Lite_RISC-V版)」を参照のこと、ここでは、WiFiを動かすためのプログラムについて記載する。
(ホストPCとしてはubuntuを想定している)
プログラムにある以下の関数に関しては、
https://github.com/nopnop2002/MQTT_via_ESP01/blob/master/MQTT_Subscribe_ESP01/MQTT_Subscribe_ESP01.inoにあるものを、そのまま流用した:
・int buildConnect(char *buf, int keep_alive, char *client_id, char *will_topic, char *will_msg)
・int buildSubscribe(char *buf, char *topic)
・int buildPublish(char *buf, char *topic, char *msg)
接続
wio-lite-rvボードのPA9(TX). PA10(RX)、GNDをUSBシリアルに接続する。
ちなみに、XIAOをUSBシリアルとして使用する場合は以下のように接続する:
wio-lite-rv |
XIAO |
PA10(RX) |
D6(TX) |
PA9(TX) |
D7(RX) |
GND |
GND |
MQTT_pub_test
MQTT送信プログラム:
src/MQTT_pub_test.cpp
#include <Arduino.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#define MY_SSID "your_ssid"
#define MY_PASSWD "your_passwd"
#define TARGET_IP "test.mosquitto.org"
#define OUT_PORT 1883
#define IN_PORT 1883
char ipAddress [20];
#define CLIENT_ID "fedx"
#define MQTT_KEEP_ALIVE 60
#define MQTT_WILL_TOPIC "ESP8266AT-MQTT/"
#define MQTT_WILL_MSG "I am leaving..."
char con[20];
char sub[100];
char pub[100];
int msize, plen, slen;
int buildConnect(char *buf, int keep_alive, char *client_id, char *will_topic, char *will_msg) {
int rlen = 12;
int pos = 14;
int client_id_len = strlen(client_id);
buf[pos++] = 0x00;
buf[pos++] = client_id_len;
for(int i=0;i<client_id_len;i++) {
buf[pos++] = client_id[i];
}
rlen = rlen + 2 + client_id_len;
int will_topic_len = strlen(will_topic);
int will_msg_len = strlen(will_msg);
if (will_topic_len > 0 && will_msg_len > 0) {
buf[pos++] = 0x00;
buf[pos++] = will_topic_len;
for(int i=0;i<will_topic_len;i++) {
buf[pos++] = will_topic[i];
}
buf[pos++] = 0x00;
buf[pos++] = will_msg_len;
for(int i=0;i<will_msg_len;i++) {
buf[pos++] = will_msg[i];
}
rlen = rlen + 2 + will_topic_len + 2 + will_msg_len;
}
buf[0] = 0x10;
buf[1] = rlen;
buf[2] = 0x00;
buf[3] = 0x06;
buf[4] = 'M';
buf[5] = 'Q';
buf[6] = 'I';
buf[7] = 's';
buf[8] = 'd';
buf[9] = 'p';
buf[10] = 0x03;
buf[11] = 0x02;
if (will_topic_len > 0 && will_msg_len > 0) buf[11] = 0x06;
buf[12] = 0x00;
buf[13] = keep_alive;
return buf[1] + 2;
}
int buildSubscribe(char *buf, char *topic) {
int tlen = strlen(topic);
for(int i=0;i<tlen;i++) {
buf[6+i] = topic[i];
}
buf[0] = 0x82;
buf[1] = tlen + 5;
buf[2] = 0x00;
buf[3] = 0x01;
buf[4] = 0x00;
buf[5] = tlen;
buf[tlen+6] = 0x00;
return buf[1] + 2;
}
int buildPublish(char *buf, char *topic, char *msg) {
int tlen = strlen(topic);
for(int i=0;i<tlen;i++) {
buf[4+i] = topic[i];
}
int mlen = strlen(msg);
for(int i=0;i<mlen;i++) {
buf[4+tlen+i] = msg[i];
}
buf[0] = 0x30;
buf[1] = tlen + mlen + 2;
buf[2] = 0x00;
buf[3] = tlen;
return buf[1] + 2;
}
static void wio_serial_init(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_USART0);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_USART1);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
usart_deinit(USART0);
usart_baudrate_set(USART0, 115200U);
usart_word_length_set(USART0, USART_WL_8BIT);
usart_stop_bit_set(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);
usart_deinit(USART1);
usart_baudrate_set(USART1, 115200U);
usart_word_length_set(USART1, USART_WL_8BIT);
usart_stop_bit_set(USART1, USART_STB_1BIT);
usart_parity_config(USART1, USART_PM_NONE);
usart_hardware_flow_rts_config(USART1, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(USART1, USART_CTS_DISABLE);
usart_receive_config(USART1, USART_RECEIVE_ENABLE);
usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
usart_enable(USART1);
}
int _get0_char(void) {
while ( usart_flag_get(USART0, USART_FLAG_RBNE)== RESET){
}
return (uint8_t)usart_data_receive(USART0);
}
int _get1_char(void) {
while ( usart_flag_get(USART1, USART_FLAG_RBNE)== RESET){
}
return (uint8_t)usart_data_receive(USART1);
}
int _put0_char(int ch)
{
usart_data_transmit(USART0, (uint8_t) ch );
while ( usart_flag_get(USART0, USART_FLAG_TBE)== RESET){
}
return ch;
}
int _put1_char(int ch)
{
usart_data_transmit(USART1, (uint8_t) ch );
while ( usart_flag_get(USART1, USART_FLAG_TBE)== RESET){
}
return ch;
}
void usart0_printf(const char *fmt, ...) {
char buf[100];
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
char *p = buf;
while( *p != '\0' ) {
_put0_char(*p);
p++;
}
}
void usart0_print(const char *s) {
while( *s != '\0' ) {
_put0_char(*s);
s++;
}
}
void usart0_println(const char *s) {
while( *s != '\0' ) {
_put0_char(*s);
s++;
}
_put0_char('\r');
_put0_char('\n');
}
void usart1_printf(const char *fmt, ...) {
char buf[100];
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
char *p = buf;
while( *p != '\0' ) {
_put1_char(*p);
p++;
}
}
void usart1_print(const char *s) {
while( *s != '\0' ) {
_put1_char(*s);
s++;
}
}
void usart1_println(const char *s) {
while( *s != '\0' ) {
_put1_char(*s);
s++;
}
_put1_char('\r');
_put1_char('\n');
}
int usart1_available(void) {
return ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET);
}
char res[500];
void get_res(void) {
int cpos = 0;
for(int cc=0; cc<24000000; cc++) {
while ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET) {
res[cpos] = (char) usart_data_receive(USART1); cpos++;
};
};
res[cpos] = 0;
}
void get_res2(void) {
int cpos = 0;
for(int cc=0; cc<500000; cc++) {
while ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET) {
res[cpos] = (char) usart_data_receive(USART1); cpos++;
};
};
res[cpos] = 0;
}
void setup()
{
wio_serial_init();
pinMode(LED_BUILTIN, OUTPUT);
delay(3000);
usart0_print("\r\n\r\n\r\n\r\n\r\n");
usart0_println("SEND:");
usart0_print("AT+RST\r\n");
usart1_print("AT+RST\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+GMR\r\n");
usart1_print("AT+GMR\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+CWQAP\r\n");
usart1_print("AT+CWQAP\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+CWMODE=1\r\n");
usart1_print("AT+CWMODE=1\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+CWJAP=\"");
usart0_print(MY_SSID);
usart0_print("\",\"");
usart0_print(MY_PASSWD);
usart0_print("\"\r\n");
usart1_print("AT+CWJAP=\"");
usart1_print(MY_SSID);
usart1_print("\",\"");
usart1_print(MY_PASSWD);
usart1_print("\"\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+CIFSR\r\n");
usart1_print("AT+CIFSR\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
int len = strlen( res );
bool done=false;
bool error = false;
int pos = 0;
while (!done)
{
if ( res[pos] == '\"') { done = true;}
pos++;
if (pos > len) { done = true; error = true;}
}
if (!error)
{
int buffpos = 0;
done = false;
while (!done)
{
if ( res[pos] == '\"' ) { done = true; }
else { ipAddress[buffpos] = res[pos]; buffpos++; pos++;}
}
ipAddress[buffpos] = 0;
}
else { strcpy(ipAddress,"ERROR"); }
usart0_println("SEND:");
usart0_print("AT+CIPMUX=1\r\n");
usart1_print("AT+CIPMUX=1\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+CIPSERVER=1,80\r\n"); ;
usart1_print("AT+CIPSERVER=1,80\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_printf("\r\nipAddress: %s\r\n\r\n",ipAddress);
usart0_printf("AT+CIPSTART=1,\"TCP\",\"%s\",%d\r\n",TARGET_IP,OUT_PORT);
usart1_printf("AT+CIPSTART=1,\"TCP\",\"%s\",%d\r\n",TARGET_IP,OUT_PORT);
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
msize = buildConnect(con,MQTT_KEEP_ALIVE,CLIENT_ID,MQTT_WILL_TOPIC,MQTT_WILL_MSG);
usart0_printf("AT+CIPSEND=1,%d\r\n",msize);
usart1_printf("AT+CIPSEND=1,%d\r\n",msize);
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
for (int i=0;i<msize;i++) _put1_char(con[i]);
for (int i=0;i<msize;i++) _put0_char(con[i]);
_put0_char('\r'); _put0_char('\n');
get_res();
}
void dispatch(void)
{
char *h[20]; for(int i=0; i<20; i++) h[i]=NULL;
h[0] = &res[0];
int pi = 1;
int cp;
int len = (int)strlen(res);
for (int i=0; i<len; i++) {
if ((res[i]=='+') && (res[i+1]=='I') && (res[i+2]=='P') && (res[i+3]=='D') ) {
for (cp = i+4; cp<len; cp++) {
if (res[cp]==':') break;
}
res[i] = 0;
h[pi] = &res[cp+1]; pi++;
}
};
for(int i=0; i<20; i++) {
if (h[i] != NULL) usart0_print(h[i]);
}
}
void loop()
{
digitalWrite(LED_BUILTIN, HIGH);
while(true) {
get_res2();
if ((int)strlen(res) != 0) {
dispatch();
} else {
plen = buildPublish(pub, "topic0", "msg-hello00");
usart0_printf("AT+CIPSEND=1,%d\r\n",plen);
usart1_printf("AT+CIPSEND=1,%d\r\n",plen);
get_res();
for (int i=0;i<plen;i++) _put1_char(pub[i]);
get_res();
usart0_println("pub-res:");
usart0_println(res);
usart0_println("-----------");
plen = buildPublish(pub, "topic0", "msg-hello01");
usart0_printf("AT+CIPSEND=1,%d\r\n",plen);
usart1_printf("AT+CIPSEND=1,%d\r\n",plen);
get_res();
for (int i=0;i<plen;i++) _put1_char(pub[i]);
get_res();
usart0_println("pub-res:");
usart0_println(res);
usart0_println("-----------");
plen = buildPublish(pub, "topic0", "msg-hello02");
usart0_printf("AT+CIPSEND=1,%d\r\n",plen);
usart1_printf("AT+CIPSEND=1,%d\r\n",plen);
get_res();
for (int i=0;i<plen;i++) _put1_char(pub[i]);
get_res();
usart0_println("pub-res:");
usart0_println(res);
usart0_println("-----------");
}
}
}
以下については、自分の環境に合わせて変更すること:
#define MY_SSID "your_ssid"
#define MY_PASSWD "your_passwd"
以下は利用するMQTTサーバー(broker)に合わせる:
#define TARGET_IP "test.mosquitto.org"
#define OUT_PORT 1883
#define IN_PORT 1883
書き込み後に「picocom /dev/ttyACM0 -b115200」で通信ソフトを起動すると以下のような出力が表示される:
$ picocom /dev/ttyACM0 -b115200
SEND:
AT+RST
RES:
AT+RST
OK
I (2989) wifi: state: 5 -> 0 (0)
WIFI DISCONNECT
sl
-----------
SEND:
AT+GMR
RES:
AT+GMR
AT version:2.1.0.0-dev(d25f6d2 - Oct 15 2019 12:03:04)
SDK version:v3.2-192-g81655f39
compile time(525fbfe):Oct 17 2019 05:39:13
Bin version:2.0.0(WROOM-02)
OK
...
<省略>
...
-----------
ipAddress: 192.168.0.18
AT+CIPSTART=1,"TCP","test.mosquitto.org",1883
RES:
AT+CIPSTART=1,"TCP","test.mosquitto.org",1883
1,CONNECT
OK
...
<省略>
対向する送受信プログラム
以下をブラウザ(chromeのみ)で動かす:
MQTT_AT_webTest.html
<html>
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<body>
<script>
document.body.innerHTML = '';
var consout = 'MQTT over WebSockets Test'+'<br>'
document.body.innerHTML = consout;
var client = mqtt.connect('ws://test.mosquitto.org:8081')
client.subscribe('topic0');
client.on('message', function(topic, payload) {
console.log([topic, payload].join(': '));
consout += [topic, payload].join(': ')+'<br>'
document.body.innerHTML = consout
});
client.publish('topic0', 'hello world of MQTT! #1');
client.publish('topic0', 'hello world of MQTT! #2');
client.publish('topic0', 'hello world of MQTT! #3');
client.publish('topic0', 'hello world of MQTT! #4');
client.publish('topic0', 'hello world of MQTT! #5');
</script>
</body>
</html>
上をプラウザーで起動した後、
wio-liteの送信プログラムを動作させる。
以下のweb画面が表示される(例):
MQTT over WebSockets Test
topic0: Bienvenue sur mosquitto.org
topic0: hello world of MQTT! #1 # webアプリで送信(publish)したものを受信している
topic0: hello world of MQTT! #2 # webアプリで送信(publish)したものを受信している
topic0: hello world of MQTT! #3 # webアプリで送信(publish)したものを受信している
topic0: hello world of MQTT! #4 # webアプリで送信(publish)したものを受信している
topic0: hello world of MQTT! #5 # webアプリで送信(publish)したものを受信している
topic0: msg-hello00 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello01 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello02 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello00 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello01 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello02 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello00 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello01 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello02 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello00 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello01 # wio-liteで送信(publish)したものを受信している
topic0: msg-hello02 # wio-liteで送信(publish)したものを受信している
...
MQTT_sub_test
MQTT受信プログラム:
src/MQTT_sub_test.cpp
#include <Arduino.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#define MY_SSID "your_ssid"
#define MY_PASSWD "your_passswd"
#define TARGET_IP "test.mosquitto.org"
#define OUT_PORT 1883
#define IN_PORT 1883
char ipAddress [20];
#define CLIENT_ID "fedx"
#define MQTT_KEEP_ALIVE 3600
#define MQTT_WILL_TOPIC "ESP8266AT-MQTT/"
#define MQTT_WILL_MSG "I am leaving..."
char con[20];
char sub[100];
char pub[100];
int msize, plen, slen;
int buildConnect(char *buf, int keep_alive, char *client_id, char *will_topic, char *will_msg) {
int rlen = 12;
int pos = 14;
int client_id_len = strlen(client_id);
buf[pos++] = 0x00;
buf[pos++] = client_id_len;
for(int i=0;i<client_id_len;i++) {
buf[pos++] = client_id[i];
}
rlen = rlen + 2 + client_id_len;
int will_topic_len = strlen(will_topic);
int will_msg_len = strlen(will_msg);
if (will_topic_len > 0 && will_msg_len > 0) {
buf[pos++] = 0x00;
buf[pos++] = will_topic_len;
for(int i=0;i<will_topic_len;i++) {
buf[pos++] = will_topic[i];
}
buf[pos++] = 0x00;
buf[pos++] = will_msg_len;
for(int i=0;i<will_msg_len;i++) {
buf[pos++] = will_msg[i];
}
rlen = rlen + 2 + will_topic_len + 2 + will_msg_len;
}
buf[0] = 0x10;
buf[1] = rlen;
buf[2] = 0x00;
buf[3] = 0x06;
buf[4] = 'M';
buf[5] = 'Q';
buf[6] = 'I';
buf[7] = 's';
buf[8] = 'd';
buf[9] = 'p';
buf[10] = 0x03;
buf[11] = 0x02;
if (will_topic_len > 0 && will_msg_len > 0) buf[11] = 0x06;
buf[12] = 0xff & (keep_alive >> 8);
buf[13] = 0xff & keep_alive;
return buf[1] + 2;
}
int buildSubscribe(char *buf, char *topic) {
int tlen = strlen(topic);
for(int i=0;i<tlen;i++) {
buf[6+i] = topic[i];
}
buf[0] = 0x82;
buf[1] = tlen + 5;
buf[2] = 0x00;
buf[3] = 0x01;
buf[4] = 0x00;
buf[5] = tlen;
buf[tlen+6] = 0x00;
return buf[1] + 2;
}
int buildPublish(char *buf, char *topic, char *msg) {
int tlen = strlen(topic);
for(int i=0;i<tlen;i++) {
buf[4+i] = topic[i];
}
int mlen = strlen(msg);
for(int i=0;i<mlen;i++) {
buf[4+tlen+i] = msg[i];
}
buf[0] = 0x30;
buf[1] = tlen + mlen + 2;
buf[2] = 0x00;
buf[3] = tlen;
return buf[1] + 2;
}
static void wio_serial_init(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_USART0);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_USART1);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
usart_deinit(USART0);
usart_baudrate_set(USART0, 115200U);
usart_word_length_set(USART0, USART_WL_8BIT);
usart_stop_bit_set(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);
usart_deinit(USART1);
usart_baudrate_set(USART1, 115200U);
usart_word_length_set(USART1, USART_WL_8BIT);
usart_stop_bit_set(USART1, USART_STB_1BIT);
usart_parity_config(USART1, USART_PM_NONE);
usart_hardware_flow_rts_config(USART1, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(USART1, USART_CTS_DISABLE);
usart_receive_config(USART1, USART_RECEIVE_ENABLE);
usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
usart_enable(USART1);
}
int _get0_char(void) {
while ( usart_flag_get(USART0, USART_FLAG_RBNE)== RESET){
}
return (uint8_t)usart_data_receive(USART0);
}
int _get1_char(void) {
while ( usart_flag_get(USART1, USART_FLAG_RBNE)== RESET){
}
return (uint8_t)usart_data_receive(USART1);
}
int _put0_char(int ch)
{
usart_data_transmit(USART0, (uint8_t) ch );
while ( usart_flag_get(USART0, USART_FLAG_TBE)== RESET){
}
return ch;
}
int _put1_char(int ch)
{
usart_data_transmit(USART1, (uint8_t) ch );
while ( usart_flag_get(USART1, USART_FLAG_TBE)== RESET){
}
return ch;
}
void usart0_printf(const char *fmt, ...) {
char buf[100];
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
char *p = buf;
while( *p != '\0' ) {
_put0_char(*p);
p++;
}
}
void usart0_print(const char *s) {
while( *s != '\0' ) {
_put0_char(*s);
s++;
}
}
void usart0_println(const char *s) {
while( *s != '\0' ) {
_put0_char(*s);
s++;
}
_put0_char('\r');
_put0_char('\n');
}
void usart1_printf(const char *fmt, ...) {
char buf[100];
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
char *p = buf;
while( *p != '\0' ) {
_put1_char(*p);
p++;
}
}
void usart1_print(const char *s) {
while( *s != '\0' ) {
_put1_char(*s);
s++;
}
}
void usart1_println(const char *s) {
while( *s != '\0' ) {
_put1_char(*s);
s++;
}
_put1_char('\r');
_put1_char('\n');
}
int usart1_available(void) {
return ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET);
}
char res[500];
int reslen;
void get_res(void) {
int cpos = 0;
for(int cc=0; cc<24000000; cc++) {
while ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET) {
res[cpos] = (char) usart_data_receive(USART1); cpos++;
};
};
res[cpos] = 0;
reslen = cpos;
}
void get_res2(void) {
int cpos = 0;
for(int cc=0; cc<500000; cc++) {
while ( usart_flag_get(USART1, USART_FLAG_RBNE)== SET) {
res[cpos] = (char) usart_data_receive(USART1); cpos++;
};
};
res[cpos] = 0;
reslen = cpos;
}
void setup()
{
wio_serial_init();
pinMode(LED_BUILTIN, OUTPUT);
delay(3000);
usart0_print("\r\n\r\n\r\n\r\n\r\n");
usart0_println("SEND:");
usart0_print("AT+RST\r\n");
usart1_print("AT+RST\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+GMR\r\n");
usart1_print("AT+GMR\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+CWQAP\r\n");
usart1_print("AT+CWQAP\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+CWMODE=1\r\n");
usart1_print("AT+CWMODE=1\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+CWJAP=\"");
usart0_print(MY_SSID);
usart0_print("\",\"");
usart0_print(MY_PASSWD);
usart0_print("\"\r\n");
usart1_print("AT+CWJAP=\"");
usart1_print(MY_SSID);
usart1_print("\",\"");
usart1_print(MY_PASSWD);
usart1_print("\"\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+CIFSR\r\n");
usart1_print("AT+CIFSR\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
int len = strlen( res );
bool done=false;
bool error = false;
int pos = 0;
while (!done)
{
if ( res[pos] == '\"') { done = true;}
pos++;
if (pos > len) { done = true; error = true;}
}
if (!error)
{
int buffpos = 0;
done = false;
while (!done)
{
if ( res[pos] == '\"' ) { done = true; }
else { ipAddress[buffpos] = res[pos]; buffpos++; pos++;}
}
ipAddress[buffpos] = 0;
}
else { strcpy(ipAddress,"ERROR"); }
usart0_println("SEND:");
usart0_print("AT+CIPMUX=1\r\n");
usart1_print("AT+CIPMUX=1\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_println("SEND:");
usart0_print("AT+CIPSERVER=1,80\r\n"); ;
usart1_print("AT+CIPSERVER=1,80\r\n");
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
usart0_printf("\r\nipAddress: %s\r\n\r\n",ipAddress);
usart0_printf("AT+CIPSTART=1,\"TCP\",\"%s\",%d\r\n",TARGET_IP,OUT_PORT);
usart1_printf("AT+CIPSTART=1,\"TCP\",\"%s\",%d\r\n",TARGET_IP,OUT_PORT);
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
msize = buildConnect(con,MQTT_KEEP_ALIVE,CLIENT_ID,MQTT_WILL_TOPIC,MQTT_WILL_MSG);
usart0_printf("AT+CIPSEND=1,%d\r\n",msize);
usart1_printf("AT+CIPSEND=1,%d\r\n",msize);
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
for (int i=0;i<msize;i++) _put1_char(con[i]);
for (int i=0;i<msize;i++) _put0_char(con[i]);
_put0_char('\r'); _put0_char('\n');
get_res();
slen = buildSubscribe(sub, "topic0");
usart0_printf("AT+CIPSEND=1,%d\r\n",slen);
usart1_printf("AT+CIPSEND=1,%d\r\n",slen);
get_res();
usart0_println("RES:");
usart0_println(res);
usart0_println("-----------");
for (int i=0;i<slen;i++) _put1_char(sub[i]);
get_res();
}
void dispatch(void)
{
char ph0,ph1,ph2,ph3;
char rtopic[20],rmsg[50];
int pd, ps;
int cp;
int len = reslen;
for (int i=0; i<len; i++) {
if ((res[i]=='+') && (res[i+1]=='I') && (res[i+2]=='P') && (res[i+3]=='D') ) {
for (cp = i+4; cp<len; cp++) {
if (res[cp]==':') break;
}
ph0 = res[cp+1];
ph1 = res[cp+2];
ph2 = res[cp+3];
ph3 = res[cp+4];
ps = cp+5;
for(pd=0; pd<ph3; pd++) {rtopic[pd]=res[ps]; ps++; };
rtopic[pd] = 0;
for(pd=0; pd<(ph1-ph3-2); pd++) {rmsg[pd]=res[ps]; ps++; };
rmsg[pd] = 0;
usart0_printf("received %s: %s\r\n",rtopic,rmsg);
}
};
}
void loop()
{
digitalWrite(LED_BUILTIN, HIGH);
while(true) {
get_res2();
if (reslen != 0) {
dispatch();
} else {
}
}
}
「MQTT_AT_webTest.html」をプラウザで起動した後、
wio-liteの受信プログラムを動作させる。
書き込み後に「picocom /dev/ttyACM0 -b115200」で通信ソフトを起動すると以下のような出力が表示される:
$ picocom /dev/ttyACM0 -b115200
SEND:
AT+RST
RES:
AT+RST
OK
I (2989) wifi: state: 5 -> 0 (0)
WIFI DISCONNECT
sl
-----------
SEND:
AT+GMR
RES:
AT+GMR
AT version:2.1.0.0-dev(d25f6d2 - Oct 15 2019 12:03:04)
SDK version:v3.2-192-g81655f39
compile time(525fbfe):Oct 17 2019 05:39:13
Bin version:2.0.0(WROOM-02)
OK
...
<省略>
OK
#以下、ブラウザーをリフレッシュ(リロード)するたびにpublishされ
#受信したものが以下のように表示される:
>
-----------
received topic0: hello world of MQTT! #1
received topic0: hello world of MQTT! #2
received topic0: hello world of MQTT! #3
received topic0: hello world of MQTT! #4
received topic0: hello world of MQTT! #5
received topic0: hello world of MQTT! #1
received topic0: hello world of MQTT! #2
received topic0: hello world of MQTT! #3
received topic0: hello world of MQTT! #4
received topic0: hello world of MQTT! #5
received topic0: hello world of MQTT! #1
received topic0: hello world of MQTT! #2
received topic0: hello world of MQTT! #3
received topic0: hello world of MQTT! #4
received topic0: hello world of MQTT! #5
received topic0: hello world of MQTT! #1
received topic0: hello world of MQTT! #2
received topic0: hello world of MQTT! #3
received topic0: hello world of MQTT! #4
received topic0: hello world of MQTT! #5
received topic0: hello world of MQTT! #1
received topic0: hello world of MQTT! #2
received topic0: hello world of MQTT! #3
received topic0: hello world of MQTT! #4
received topic0: hello world of MQTT! #5
...
...
参考情報
MQTT test server @mosquitto.org
https://test.mosquitto.org/
The server listens on the following ports:
1883 : MQTT, unencrypted
8883 : MQTT, encrypted
8884 : MQTT, encrypted, client certificate required
8080 : MQTT over WebSockets, unencrypted
8081 : MQTT over WebSockets, encrypted
websocketで使用するurlは以下になる:
'ws://test.mosquitto.org:8081'
MQTT test server @eclipse.org
http://mqtt.eclipse.org/
This is a public test MQTT broker service.
It currently listens on the following ports:
1883 : MQTT over unencrypted TCP
8883 : MQTT over encrypted TCP
80 : MQTT over unencrypted WebSockets (note: URL must be /mqtt )
443 : MQTT over encrypted WebSockets (note: URL must be /mqtt )
websocketで使用するurlは以下になる:
'ws://mqtt.eclipse.org/mqtt:443'
10 Free Public & Private MQTT Brokers(For Testing & Production)
Wio Lite RISC-V(GD32VF103)
Wio Lite RISC V GD32VF103 with ESP8266
Blink with a Wio Lite RISC-V with ESP8266
PlatformIO Core (CLI)
ESP8266をTCPサーバとTCPクライアントにするATコマンド実例 (1/4)
esp8266_at_command_examples_en.pdf
ESP8266をWifiモデムとして使う - ATコマンドによるMQTT通信
MQTT_via_ESP01
Arduino WiFi library for ESP8266 modules
espressif/ESP8266_AT - examples
Espressif Documentation
以上