6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

M5StickVとM5StackをつなげてWiFi通信する - I2C編

Posted at

はじめに

M5StickVとM5StackをつなげてWiFi通信する で、M5StickVとM5Stackを接続してシリアル通信でWiFi通信してみました。シリアル通信は汎用性が高いものの、通信速度が上げられない、M5StickVに1つしかないGroveポートを占有してしまう、などの問題がありました。そこでI2Cで通信できないか試してみました。

image.png

image.png

準備

M5StackにはI2Cで通信するためのファームウェアを書き込みます。ソースは こちら

Sipeed社から提供されているMaixduinoのSPI用のファームウェア Maixduino_esp32_fimware を参考にさせて頂きました。また、M5StackをI2CのSlaveで通信させるところは、こちらの ESP32_I2C_Slave を参考にさせて頂きました。ありがとうございます。

M5StickV側

WiFi通信用のライブラリーはこちらの Maixduino_WiFiEspI2C

PubSubClientと組み合わせて、AWS IoTに接続するサンプルはこんな感じになります。

ESP32でAWS IoTに繋いでThing Shadowを弄る を参考にさせて頂きました。ありがとうございます。

main.cpp
/*--------------------------------------------------------------------
Copyright 2021 fukuen

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This software is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with The Arduino WiFiEsp library.  If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------*/

# include <Arduino.h>
# include <TFT_eSPI.h>
# include <Wire.h>
# include <WiFiEspI2C.h>
# include <PubSubClient.h>
# include "esp32_i2c.h"

TFT_eSPI lcd;

# define AXP192_ADDR 0x34
# ifdef M5STICKV
# define PIN_SDA 29
# define PIN_SCL 28
# define WIDTH 280
# define HEIGHT 240
# define XOFFSET 40
# define YOFFSET 60
# define I2C_SDA_PIN 34
# define I2C_SCL_PIN 35
# define I2C_SLAVE_ADDR 0x04
# endif

# define AXP173_ADDR 0x34
# ifdef MAIXAMIGO
# define PIN_SDA 27
# define PIN_SCL 24
# define WIDTH 480
# define HEIGHT 320
# define XOFFSET 0
# define YOFFSET 0
# define I2C_SDA_PIN 7 //27
# define I2C_SCL_PIN 9 //24
# define I2C_SLAVE_ADDR 0x04
# endif


char SSID[] = "<your ssid>";      // your network SSID (name)
char PASS[] = "<your pass>";      // your network password
int status = WL_IDLE_STATUS;

const char *endpoint = "<AWS_IOT_ENDPOINT>";
// Example: xxxxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com
const int port = 8883;
char *pubTopic = "/sample123";
char *subTopic = "/sample123";

const char* rootCA = "-----BEGIN CERTIFICATE-----\n" \
"......\n" \
"-----END CERTIFICATE-----\n";

const char* certificate = "-----BEGIN CERTIFICATE-----\n" \
"......\n" \
"-----END CERTIFICATE-----\n";


const char* privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" \
"......\n" \
"-----END RSA PRIVATE KEY-----\n";

// Initialize the Ethernet client object
WiFiEspSSLClient httpsClient;
PubSubClient mqttClient(httpsClient);

long messageSentAt = 0;
int dummyValue = 0;
char pubMessage[128];

void mqttCallback(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();
}

char buf[1024];

bool axp192_init() {
  Serial.printf("AXP192 init.\n");
  sysctl_set_power_mode(SYSCTL_POWER_BANK3,SYSCTL_POWER_V33);

  Wire.begin((uint8_t) PIN_SDA, (uint8_t) PIN_SCL, 400000);
  Wire.beginTransmission(AXP192_ADDR);
  int err = Wire.endTransmission();
  if (err) {
    Serial.printf("Power management ic not found.\n");
    return false;
  }
  Serial.printf("AXP192 found.\n");

  // Clear the interrupts
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x46);
  Wire.write(0xFF);
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x23);
  Wire.write(0x08); //K210_VCore(DCDC2) set to 0.9V
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x33);
  Wire.write(0xC1); //190mA Charging Current
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x36);
  Wire.write(0x6C); //4s shutdown
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x91);
  Wire.write(0xF0); //LCD Backlight: GPIO0 3.3V
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x90);
  Wire.write(0x02); //GPIO LDO mode
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x28);
  Wire.write(0xF0); //VDD2.8V net: LDO2 3.3V,  VDD 1.5V net: LDO3 1.8V
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x27);
  Wire.write(0x2C); //VDD1.8V net:  DC-DC3 1.8V
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x12);
  Wire.write(0xFF); //open all power and EXTEN
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x23);
  Wire.write(0x08); //VDD 0.9v net: DC-DC2 0.9V
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x31);
  Wire.write(0x03); //Cutoff voltage 3.2V
  Wire.endTransmission();
  Wire.beginTransmission(AXP192_ADDR);
  Wire.write(0x39);
  Wire.write(0xFC); //Turnoff Temp Protect (Sensor not exist!)
  Wire.endTransmission();

  fpioa_set_function(23, (fpioa_function_t)(FUNC_GPIOHS0 + 26));
  gpiohs_set_drive_mode(26, GPIO_DM_OUTPUT);
  gpiohs_set_pin(26, GPIO_PV_HIGH); //Disable VBUS As Input, BAT->5V Boost->VBUS->Charing Cycle

  msleep(20);
  return true;
}

void axp173_init() {
    Wire.begin((uint8_t) PIN_SDA, (uint8_t) PIN_SCL, 400000);
    Wire.beginTransmission(AXP173_ADDR);
    int err = Wire.endTransmission();
    if (err) {
        Serial.printf("Power management ic not found.\n");
        return;
    }
    Serial.printf("AXP173 found.\n");
# ifdef MAIXAMIGO
    //LDO4 - 0.8V (default 0x48 1.8V)
    Wire.beginTransmission(AXP173_ADDR);
    Wire.write(0x27);
    Wire.write(0x20);
    Wire.endTransmission();
    //LDO2/3 - LDO2 1.8V / LDO3 3.0V
    Wire.beginTransmission(AXP173_ADDR);
    Wire.write(0x28);
    Wire.write(0x0C);
    Wire.endTransmission();
# else
    // Clear the interrupts
    Wire.beginTransmission(AXP173_ADDR);
    Wire.write(0x46);
    Wire.write(0xFF);
    Wire.endTransmission();
    // set target voltage and current of battery(axp173 datasheet PG.)
    // charge current (default)780mA -> 190mA
    Wire.beginTransmission(AXP173_ADDR);
    Wire.write(0x33);
    Wire.write(0xC1);
    Wire.endTransmission();
    // REG 10H: EXTEN & DC-DC2 control
    Wire.beginTransmission(AXP173_ADDR);
    Wire.write(0x10);
    Wire.endTransmission();
    Wire.requestFrom(AXP173_ADDR, 1, 1);
    int reg = Wire.read();
    Wire.beginTransmission(AXP173_ADDR);
    Wire.write(0x10);
    Wire.write(reg & 0xFC);
    Wire.endTransmission();
# endif
}

void printWifiStatus() {
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

void connectAWSIoT() {
  while (!mqttClient.connected()) {
    if (mqttClient.connect("maixamigo")) {
      Serial.println("Connected.");
      int qos = 0;
      mqttClient.subscribe(subTopic, qos);
      Serial.println("Subscribed.");
    } else {
      Serial.print("Failed. Error state=");
      Serial.print(mqttClient.state());
      // Wait 5 seconds before retrying
      delay(5000);
      httpsClient.setCertificate(certificate);
      httpsClient.setPrivateKey(privateKey);
    }
  }
}

void setup() {
  Serial.begin(115200);
# ifdef M5STICKV
  axp192_init();
# else
  axp173_init();
# endif

  /* LCD init */
  lcd.begin();
  lcd.setRotation(1);

  lcd.fillRect(0, 0, WIDTH, HEIGHT, TFT_BLACK);
  lcd.setTextFont(0);
  lcd.setTextColor(TFT_WHITE);
  lcd.setCursor(0 + XOFFSET, 0 + YOFFSET);
  lcd.printf("running.");

  Wire1.begin((uint8_t)I2C_SDA_PIN, (uint8_t)I2C_SCL_PIN, (uint32_t)400000);
  WiFi.init(Wire1, I2C_SLAVE_ADDR);    // initialize ESP WiFi module

  Serial.println("## status");
  // check for the presence of the shield
//  if (WiFi.status() == WL_NO_SHIELD) {
  if (WiFi.status() == -2) {
      Serial.println("WiFi shield not present");
      // don't continue
      while (true);
  }

  // attempt to connect to WiFi network
  status = WiFi.begin(SSID, PASS);
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(SSID);
    // Connect to WPA/WPA2 network
    sleep(1);
    status = WiFi.status();
  }

  printWifiStatus();

  // Configure MQTT Client
//  httpsClient.setCACertificate(rootCA);
  httpsClient.setCertificate(certificate);
  httpsClient.setPrivateKey(privateKey);
  mqttClient.setServer(endpoint, port);
  mqttClient.setCallback(mqttCallback);

  Serial.println("connectAWSIoT");

  connectAWSIoT();
}

void loop() {
  // put your main code here, to run repeatedly:
  if (!mqttClient.connected()) {
    connectAWSIoT();
  }
  mqttClient.loop();

  long now = millis();
  if (now - messageSentAt > 5000) {
    messageSentAt = now;
    sprintf(pubMessage, "{\"message\": \"%d\"}", dummyValue++);
    Serial.print("Publishing message to topic ");
    Serial.println(pubTopic);
    Serial.println(pubMessage);
    mqttClient.publish(pubTopic, pubMessage);
    Serial.println("Published.");
  }
}

さいごに

これでGroveポートに複数のI2Cデバイスをつなげられるようになるといいと思っています。

まだまだ実験中で、I2C通信周りなどまだ改善が必要だと思っています。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?