STM32F103を使ってみる

MQTT通信



こちらでArduinoのMQTT 通信を紹介しています。
Publisher SubscriberともライブラリとTOPICだけを変えて書きこんでみましたがあっさりと動きました。
WIZ550ioにも対応したPublish側スケッチは以下のようになります。
/*

 MQTT Publish for STM32F103 with W5x000 Module
 
 W5x00 <--> STM32F103 Pinout
 SS    <--> PA4 BOARD_SPI1_NSS_PIN
 SCK   <--> PA5 BOARD_SPI1_SCK_PIN
 MISO  <--> PA6 BOARD_SPI1_MISO_PIN
 MOSI  <--> PA7 BOARD_SPI1_MOSI_PIN
 3.3V  <--> 3.3V
 GND   <--> GND
 3.3V  <--> 4.7KOhm <---> RST

*/

#include <SPI.h>
#include <Ethernet_STM.h>   // https://github.com/rogerclarkmelbourne/Arduino_STM32
#include <PubSubClient.h> // https://github.com/knolleary/pubsubclient

#define INTERVAL        30 // 30秒毎にPublish
//#define MQTT_SERVER     "broker.hivemq.com"
//#define MQTT_SERVER     "iot.eclipse.org"
#define MQTT_SERVER     "192.168.10.40"  // You need change
#define MQTT_PORT       1883
#define MQTT_TOPIC      "stm32f103/C8T6" // You can change
#define MQTT_WILL_MSG   "I am leaving..." // You can change
#define RUNNING_LED     PB0 // 0: Disable RUNNING_LED

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
#if defined(WIZ550io_WITH_MACADDRESS) // Use assigned MAC address of WIZ550io
;
#else
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
#endif 

EthernetClient ethClient;
PubSubClient pubsubClient(ethClient);

unsigned long lastTime = 0;

void errorDisplay(char* buff) {
  int stat = 0;
  Serial.print("Error:");
  Serial.println(buff);
  while(1) {
    if (RUNNING_LED) {
      digitalWrite(RUNNING_LED,stat);
      stat = !stat;
      delay(100);
    }
  }
}

void setup() {
  delay(1000);Serial.begin(9600);
  Serial.println("\n[MQTT Publish for EW5x00]");

  if (RUNNING_LED) {
    pinMode(RUNNING_LED,OUTPUT);
    digitalWrite(RUNNING_LED,LOW);
  }

  // start Ethernet and UDP
#if defined(WIZ550io_WITH_MACADDRESS)
  if (Ethernet.begin() == 0) {
#else
  if (Ethernet.begin(mac) == 0) {
#endif 
    errorDisplay("Failed to configure Ethernet using DHCP");
  }

  Serial.print("My IP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("Netmask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("GW IP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("DNS IP: ");
  Serial.println(Ethernet.dnsServerIP());

#if defined(WIZ550io_WITH_MACADDRESS)
  byte mac_address[6] ={0,};
  W5100.getMACAddress(mac_address);
  Serial.print("MAC: ");
  for(int i = 0; i < 6; i++) {
    Serial.print("0x");
    Serial.print(mac_address[i],HEX);
    Serial.print(" ");
  }
  Serial.println();
#endif

  pubsubClient.setServer(MQTT_SERVER, MQTT_PORT);

  char clientid[30];
  IPAddress ip = Ethernet.localIP();
  Serial.print(ip[0]);
  Serial.print(".");
  Serial.print(ip[1]);
  Serial.print(".");
  Serial.print(ip[2]);
  Serial.print(".");
  Serial.println(ip[3]);
  sprintf(clientid,"STM32-%03d-%03d-%03d-%03d",(int)ip[0],(int)ip[1],(int)ip[2],(int)ip[3]);
  Serial.print("clientid=");
  Serial.println(clientid);
  Serial.print("Attempting MQTT connection...");
  // Attempt to connect
  if (!pubsubClient.connect(clientid,MQTT_TOPIC,0,0,MQTT_WILL_MSG)) {
    errorDisplay("connect Fail");
  }
  Serial.println("connected");
  lastTime = millis();
 
}

void loop(){
  static int counter=0;
  static int value = 0;
  static int running_state = 1;
  char msg[50];

  if (Serial.available() > 0) {
    char inChar = Serial.read();
    Serial.println("KeyIn");
    pubsubClient.disconnect();
    Serial.println("Publish end");
    while(1) { }
  }

  if (!pubsubClient.connected()) {
    errorDisplay("not connect");
  }
  pubsubClient.loop();

  long now = millis();
  if (now - lastTime > 1000) {
    lastTime = now;
    counter++;
    if (RUNNING_LED) digitalWrite(RUNNING_LED,running_state);
    running_state = !running_state;
    if (counter > INTERVAL) {
      ++value;
      snprintf (msg, 75, "hello world!! I'm STM32F103 #%ld", value);
      Serial.print("Publish message: ");
      Serial.println(msg);
      if (!pubsubClient.publish(MQTT_TOPIC, msg)) {
        errorDisplay("publish fail");
      }
      counter=0;
    }
  } 
}



WIZ550ioにも対応したSubscribe側スケッチは以下のようになります。
/*

 MQTT Subscribe for STM32F103 with W5x000 Module
 
 W5x00 <--> STM32F103 Pinout
 SS    <--> PA4 BOARD_SPI1_NSS_PIN
 SCK   <--> PA5 BOARD_SPI1_SCK_PIN
 MISO  <--> PA6 BOARD_SPI1_MISO_PIN
 MOSI  <--> PA7 BOARD_SPI1_MOSI_PIN
 3.3V  <--> 3.3V
 GND   <--> GND
 3.3V  <--> 4.7KOhm <---> RST

*/

#include <SPI.h>
#include <Ethernet_STM.h>   // https://github.com/rogerclarkmelbourne/Arduino_STM32
#include <PubSubClient.h> // https://github.com/knolleary/pubsubclient

#define MQTT_SERVER     "192.168.10.40"  // You need change
#define MQTT_PORT       1883
#define MQTT_TOPIC      "stm32f103/#"
#define MQTT_WILL_MSG   "I am leaving..." // You can change
#define RUNNING_LED     PB1 // 0: Disable RUNNING_LED

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
#if defined(WIZ550io_WITH_MACADDRESS) // Use assigned MAC address of WIZ550io
;
#else
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
#endif 

EthernetClient ethClient;
PubSubClient pubsubClient(ethClient);

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] [");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println("]");
}

void errorDisplay(char* buff) {
  int stat = 0;
  Serial.print("Error:");
  Serial.println(buff);
  while(1) {
    digitalWrite(RUNNING_LED,stat);
    stat = !stat;
    delay(100);
  }
}

void setup() {
  delay(1000);Serial.begin(9600);
  Serial.println("\n[MQTT Subscribe for EW5x00]");

  if (RUNNING_LED) {
    pinMode(RUNNING_LED,OUTPUT);
    digitalWrite(RUNNING_LED,LOW);
  }

  // start Ethernet and UDP
#if defined(WIZ550io_WITH_MACADDRESS)
  if (Ethernet.begin() == 0) {
#else
  if (Ethernet.begin(mac) == 0) {
#endif 
    errorDisplay("Failed to configure Ethernet using DHCP");
  }

  Serial.print("My IP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("Netmask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("GW IP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("DNS IP: ");
  Serial.println(Ethernet.dnsServerIP());

#if defined(WIZ550io_WITH_MACADDRESS)
  byte mac_address[6] ={0,};
  W5100.getMACAddress(mac_address);
  Serial.print("MAC: ");
  for(int i = 0; i < 6; i++) {
    Serial.print("0x");
    Serial.print(mac_address[i],HEX);
    Serial.print(" ");
  }
  Serial.println();
#endif
 
  pubsubClient.setServer(MQTT_SERVER, MQTT_PORT);
  pubsubClient.setCallback(callback);

  char clientid[30];
  IPAddress ip = Ethernet.localIP();
  sprintf(clientid,"%03d-%03d-%03d-%03d",ip[0], ip[1], ip[2], ip[3]);
  Serial.print("clientid=");
  Serial.println(clientid);
  // Loop until we're reconnected
  while (!pubsubClient.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (pubsubClient.connect(clientid,MQTT_TOPIC,0,0,MQTT_WILL_MSG)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(pubsubClient.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }

  if (!pubsubClient.subscribe(MQTT_TOPIC)) {
    errorDisplay("subscribe Fail");
  }

}

void loop() {
  pubsubClient.loop();
}



ESP01をWifiモデムとして使ったMQTTをこちらで公開していま す。
こちらのボードを使うと直接ESP01をマウントできます。
ESP01とはUART2を使って通信します。


次回はWIZ550ioモジュールを紹介します。

続く...