Skip to content

Instantly share code, notes, and snippets.

@KobayashiRui
Last active July 3, 2024 10:05
Show Gist options
  • Save KobayashiRui/094ac01d9d3cd2445faa2a1ef103646f to your computer and use it in GitHub Desktop.
Save KobayashiRui/094ac01d9d3cd2445faa2a1ef103646f to your computer and use it in GitHub Desktop.
esp32の使い方についてまとめる

esp32にとは

arduino互換のマイコンでwifiとbluetoothを内蔵で1400円の開発キットが買える 今開発をするなら最もオススメできる

動作電源

  • 1.5Vの乾電池2本直列を3.3Vinに接続で動作確認済み
  • 充電池での動作確認を予定

Arduinoとの違い

  • analogreadが3.3Vでarduinoと違い5Vでないので注意する

ArduinoIDEで開発するまでの手順

  1. arduinoIDEをダウンロードしたディレクトリ内のhardwareディレクトリに移動する
  2. espressifというディレクトリを作成
  3. esp32というディレクトリを作成
  4. **https://github.com/espressif/arduino-esp32**からコードをダウンロードする
  5. 解凍時の中身のみをesp32の中に移動する 注意上記の作業の結果hardware/espressif/esp32内にcoresやpackageなど様々なファイルが入っている状態にする。git cloneなどをしてespressif内にarduino-esp32をそのまま入れないこと

上記の作業を終了するとArduinoIDEのツール内にあるボードからESP32 Dev Moduleが選択できる

Wifiサーバー接続テスト

#include <WiFi.h>

const char SSID[] = "********";
const char PASSWORD[] = "*****";

WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  while (!Serial);

  WiFi.begin(SSID, PASSWORD);
  Serial.print("WiFi connecting");

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }

  Serial.println(" connected");

  server.begin();

  Serial.print("HTTP Server: http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");
}

void loop() {
  WiFiClient client = server.available();
  if (client) {
    client.println("Hello World!");
    client.stop();
  }
}

上記のプログラムを実行するとwifiに接続されブラウザで表示されたipに接続すると Hello World!と表示される

I2C通信

I2C通信を利用したサーボ制御

I2Cを利用Adafruit 16-Channel 12-bit PWM/Servo Driverを使用する これを使用することで複数のサーボを動かすことが可能になる

Adafruit 16-Channel 12-bit PWM/Servo Driverの使用までにすること

**https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library**をarduinoIDEのディレクトリ内の```libraries```内にgit cloneする(zipからダウンロードして解凍でも問題ない)

サンプルコード

参考 https://media.dmm-make.com/item/2495/

#include<Wire.h>
#include<Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm= Adafruit_PWMServoDriver();

#define SERVOMIN 150
#define SERVOMAX 600

void setup() {
  pwm.begin();
  pwm.setPWMFreq(50);
  servo_write(0,90);
  delay(3000);
}

void loop() {
  servo_write(0,90);
  servo_write(2,90);
  servo_write(4,90);
  delay(1000);
}

void servo_write(int n, int ang){
  ang = map(ang, 0, 180, SERVOMIN, SERVOMAX);
  pwm.setPWM(n, 0, ang);
}

上記のプログラムの注意

  1. SERVOMINとSERVOMAXの値はそのサーボの最小最大のPWM周波数なので使用するサーボによって設定を変更する
  2. pwm.setPWMFreqはサーボのPWM周期なので使用サーボによって設定を変更する

esp32とPCのROSを接続する

  • rosのノードとしてesp32を使用しpubsubの通信などができる
  • 有線、無線のどちらも使用可能
  • 準備はrosserialをインストールするだけ

rosserialを使用するまで

  1. PC側の準備 : 下記のパッケージをダウンロード
sudo apt-get install ros-kinetic-rosserial-arduino
sudo apt-get install ros-kinetic-rosserial

kineticの部分は自分のPCに入っていいるrosのパッケージに合わせる

  1. ArduinoIDEをインストールしたディレクトリ内の libraries ディレクトリに移動する
  2. rosrun rosserial_arduino make_libraries.py . を実行する
    注意 上記のコマンド実行前にlibrariesにros_libディレクトリがあった場合削除する
  3. 上記の作業を終了後、ArduinoIDEのサンプルスケッチの中にros_libが入っていた場合作業終了となりrosserialが利用できる

rosserialのサンプルコード

  1. hello_world!を配信する
#include <ros.h>
#include <std_msgs/String.h>

ros::NodeHandle  nh;

std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);

char hello[13] = "hello world!";

void setup()
{
  nh.initNode();
  nh.advertise(chatter);
}

void loop()
{
  str_msg.data = hello;
  chatter.publish( &str_msg );
  nh.spinOnce();
  delay(1000);
}
  1. sensor_msgsのJointStateを購読して配信する
#include <ros.h>
#include <sensor_msgs/JointState.h>
#include <std_msgs/Float64.h>

ros::NodeHandle nh;

std_msgs::Float64 angle_msg;
ros::Publisher chatter("chatter",&angle_msg);

void messageCb( const sensor_msgs::JointState& msg){
  angle_msg.data = msg.position[0]*180/3.14;
}

ros::Subscriber<sensor_msgs::JointState> sub("joint_states", messageCb );

void setup()
{ 
  nh.initNode();
  nh.advertise(chatter);
  nh.subscribe(sub);
}

void loop()
{  
  chatter.publish(&angle_msg);
  nh.spinOnce();
  delay(100);
}
  1. wifiを利用してhello_world!を配信する
#include <ros.h>
#include <std_msgs/String.h>
#include <WiFi.h>

const char SSID[] = "******";
const char PASSWORD[] = "*******";
IPAddress server(192,168,0,1);
const uint16_t serverPort = 11411;

WiFiClient client;

class WiFiHardware {

  public:
  WiFiHardware() {};

  void init() {
    // do your initialization here. this probably includes TCP server/client setup
    client.connect(server, serverPort);
  }

  // read a byte from the serial port. -1 = failure
  int read() {
    // implement this method so that it reads a byte from the TCP connection and returns it
    //  you may return -1 is there is an error; for example if the TCP connection is not open
    return client.read();         //will return -1 when it will works
  }

  // write data to the connection to ROS
  void write(uint8_t* data, int length) {
    // implement this so that it takes the arguments and writes or prints them to the TCP connection
    for(int i=0; i<length; i++)
      client.write(data[i]);
  }

  // returns milliseconds since start of program
  unsigned long time() {
     return millis(); // easy; did this one for you
  }
};


ros::NodeHandle_<WiFiHardware> nh;

std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);

char hello[13] = "hello world!";

void setup()
{
  Serial.begin(115200);
  WiFi.begin(SSID,PASSWORD);
    Serial.print("WiFi connecting");

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }

  Serial.println(" connected");
  nh.initNode();
  nh.advertise(chatter);
  delay(10);
}

void loop()
{
  str_msg.data = hello;
  chatter.publish( &str_msg );
  nh.spinOnce();
  delay(1000);
}

注意
IPAddress serverの部分はホストとなるPCのIPアドレスをifconfigなどで調べて入力する
serverportはデフォルトでは11411になっているので基本的に変更の必要はない

esp32(arduino)と通信をするノードの起動

esp32と通信をするには有線でもwifiでもその通信のためのノードを起動する必要がある
そのため、esp32にコードを書き込んだら、PC側で通信用のノードを起動するのを忘れないこと

  • 有線の場合
rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0

**_port:=**の後ろは自分の使用しているesp32が挿入されているポートであるため自分の状態によって変更する
ArduinoIDEで選択したところと同じで問題ない
注意
上記の作業で接続の許可がないと言われたら chmod 777 /dev/ttyUSB0というように権限を与える
有線でArduino側のシリアルモニタを起動するとエラーになるので注意

  • 無線の場合
rosrun rosserial_python serial_node.py tcp

注意
無線の場合は逆にSerial.beginを指定しないと接続できなかったため注意する

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment