Связь ESP 32 с Arduino Uno
Я сделал робота-паука, используя Arduino и esp. Я создал устройство вывода звука, связанное с программой Python, которая записывает определенные данные (когда мы произносим команду) на плату esp, и, соответственно, голос будет активирован. Теперь я хочу связать их вместе.
Если esp32 отправляет определенные данные, функция в arduino выполняется. Поэтому я хочу подключить esp32 к arduino uno через последовательный монитор и отправить данные из esp 32 в arduino. У меня свободны только аналоговые контакты, поскольку все цифровые контакты используются для сервоприводов. как мне этого добиться?
В основном файле Arduino есть еще два файла flexitimer и flexitimer2.cpp, но редактировать их нет необходимости, поэтому я даю код основного файла.
#include <Servo.h> //для определения и управления сервоприводами
#include "FlexiTimer2.h"//чтобы установить таймер для управления всеми сервоприводами
/* Servos --------------------------------------------------------------------*/
//определяем 12 сервоприводов для 4 ног
char data = 0;
Servo servo[4][3];
//определяем порты сервоприводов
const int servo_pin[4][3] = { {2, 3, 4}, {5, 6, 7}, {8, 9, 10}, {11, 12, 13} };
/* Size of the robot ---------------------------------------------------------*/
const float length_a = 55;
const float length_b = 77.5;
const float length_c = 27.5;
const float length_side = 71;
const float z_absolute = -28;
/* Constants for movement ----------------------------------------------------*/
const float z_default = -50, z_up = -30, z_boot = z_absolute;
const float x_default = 62, x_offset = 0;
const float y_start = 0, y_step = 40;
const float y_default = x_default;
/* variables for movement ----------------------------------------------------*/
volatile float site_now[4][3]; //координаты конца каждого участка в реальном времени
volatile float site_expect[4][3]; //ожидаемые координаты конца каждого участка
float temp_speed[4][3]; //скорость каждой оси необходимо пересчитывать перед каждым движением
float move_speed; //скорость движения
float speed_multiple = 1; //скорость движения кратная
const float spot_turn_speed = 4;
const float leg_move_speed = 8;
const float body_move_speed = 3;
const float stand_seat_speed = 1;
volatile int rest_counter; //+1/0.02с, для автоматического отдыха
//параметр функции
const float KEEP = 255;
//определяем PI для расчета
const float pi = 3.1415926;
/* Constants for turn --------------------------------------------------------*/
// временная длина
const float temp_a = sqrt(pow(2 * x_default + length_side, 2) + pow(y_step, 2));
const float temp_b = 2 * (y_start + y_step) + length_side;
const float temp_c = sqrt(pow(2 * x_default + length_side, 2) + pow(2 * y_start + y_step + length_side, 2));
const float temp_alpha = acos((pow(temp_a, 2) + pow(temp_b, 2) - pow(temp_c, 2)) / 2 / temp_a / temp_b);
//место для поворота
const float turn_x1 = (temp_a - length_side) / 2;
const float turn_y1 = y_start + y_step / 2;
const float turn_x0 = turn_x1 - temp_b * cos(temp_alpha);
const float turn_y0 = temp_b * sin(temp_alpha) - turn_y1 - length_side;
/* ---------------------------------------------------------------------------*/
- setup function
---------------------------------------------------------------------------*/
void setup()
{
//запускаем последовательный порт для отладки
Serial.begin(9600);
Serial.println("Robot starts initialization");
//инициализируем параметр по умолчанию
pinMode(14, OUTPUT);
set_site(0, x_default - x_offset, y_start + y_step, z_boot);
set_site(1, x_default - x_offset, y_start + y_step, z_boot);
set_site(2, x_default + x_offset, y_start, z_boot);
set_site(3, x_default + x_offset, y_start, z_boot);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
site_now[i][j] = site_expect[i][j];
}
}
//запускаем сервосервис
FlexiTimer2::set(20, servo_service);
FlexiTimer2::start();
Serial.println("Servo service started");
//инициализируем сервоприводы
servo_attach();
Serial.println("Servos initialized");
Serial.println("Robot initialization Complete");
// стоять();
// задержка(1000);
// рукопожатие(2);
// Serial.println("хихиихихи");
// задержка(1000);
// шаг вперед();
// шаг вперед();
// шаг вперед();
// шаг вперед();
// шаг вперед();
// шаг вперед();
// задержка(1000);
// шаг назад();
// шаг назад();
// шаг назад();
// шаг назад();
// шаг назад();
// шаг назад();
// задержка(1000);
// Поверните налево();
// Поверните налево();
// Поверните налево();
// Поверните налево();
// задержка(1000);
// Поверните направо();
// Поверните направо();
// Поверните направо();
// Поверните направо();
// задержка(1000);
//hand_wave(4);
// задержка(1000);
// рукопожатие(4);
// задержка(1000);
// сидеть();
// задержка(1000);
}
void servo_attach(void)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
servo[i][j].attach(servo_pin[i][j]);
delay(100);
}
}
}
void servo_detach(void)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
servo[i][j].detach();
delay(100);
}
}
}
/*
- loop function
---------------------------------------------------------------------------*/
void loop()
{
if(Serial.available() > 0)
{
data = Serial.read();
Serial.print(data);
Serial.print("\n");
if(data == 'F')
{
Serial.println("Step forward");
step_forward();
}
else if(data == 'B')
{
Serial.println("Step back");
step_back();
}
else if(data == 'L')
{
Serial.println("Turn left");
turn_left();
}
else if(data == 'R')
{
Serial.println("Turn right");
turn_right();
}
else if(data == 'X')
{
Serial.println("Stand");
stand();
}
else if(data == 'x')
{
Serial.println("Sit");
sit();
}
else if(data == 'S' ||data == 'D' )
{
}
else if(data == 'W')
{
digitalWrite(14, HIGH);
}
else if(data == 'w')
{
digitalWrite(14, LOW);
}
else if(data == 'V')
{
Serial.println("Hand wave");
hand_wave(3);
}
else if(data == 'v')
{
Serial.println("Hand wave");
hand_shake(3);
}
else if(data == 'U')
{
Serial.println("Body dance");
body_dance(10);
}
else if(data == 'u')
{
Serial.println("Body dance");
body_dance(10);
}
while(Serial.available()) {Serial.read();}
}
}
/*
- sit
- blocking function
---------------------------------------------------------------------------*/
/*
- spot turn to right
- blocking function
- parameter step steps wanted to turn
---------------------------------------------------------------------------*/
void turn_right()
{
move_speed = spot_turn_speed;
if (site_now[2][1] == y_start)
{
//этап 2&0 ход
set_site(2, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(0, turn_x0 - x_offset, turn_y0, z_default);
set_site(1, turn_x1 - x_offset, turn_y1, z_default);
set_site(2, turn_x0 + x_offset, turn_y0, z_up);
set_site(3, turn_x1 + x_offset, turn_y1, z_default);
wait_all_reach();
set_site(2, turn_x0 + x_offset, turn_y0, z_default);
wait_all_reach();
set_site(0, turn_x0 + x_offset, turn_y0, z_default);
set_site(1, turn_x1 + x_offset, turn_y1, z_default);
set_site(2, turn_x0 - x_offset, turn_y0, z_default);
set_site(3, turn_x1 - x_offset, turn_y1, z_default);
wait_all_reach();
set_site(0, turn_x0 + x_offset, turn_y0, z_up);
wait_all_reach();
set_site(0, x_default + x_offset, y_start, z_up);
set_site(1, x_default + x_offset, y_start, z_default);
set_site(2, x_default - x_offset, y_start + y_step, z_default);
set_site(3, x_default - x_offset, y_start + y_step, z_default);
wait_all_reach();
set_site(0, x_default + x_offset, y_start, z_default);
wait_all_reach();
}
else
{
//этап 1 и 3 ход
set_site(1, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(0, turn_x1 + x_offset, turn_y1, z_default);
set_site(1, turn_x0 + x_offset, turn_y0, z_up);
set_site(2, turn_x1 - x_offset, turn_y1, z_default);
set_site(3, turn_x0 - x_offset, turn_y0, z_default);
wait_all_reach();
set_site(1, turn_x0 + x_offset, turn_y0, z_default);
wait_all_reach();
set_site(0, turn_x1 - x_offset, turn_y1, z_default);
set_site(1, turn_x0 - x_offset, turn_y0, z_default);
set_site(2, turn_x1 + x_offset, turn_y1, z_default);
set_site(3, turn_x0 + x_offset, turn_y0, z_default);
wait_all_reach();
set_site(3, turn_x0 + x_offset, turn_y0, z_up);
wait_all_reach();
set_site(0, x_default - x_offset, y_start + y_step, z_default);
set_site(1, x_default - x_offset, y_start + y_step, z_default);
set_site(2, x_default + x_offset, y_start, z_default);
set_site(3, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(3, x_default + x_offset, y_start, z_default);
wait_all_reach();
}
}
/*
- go forward
- blocking function
- parameter step steps wanted to go
---------------------------------------------------------------------------*/
void step_forward()
{
move_speed = leg_move_speed;
if (site_now[2][1] == y_start)
{
//этап 2 и 1 ход
set_site(2, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(2, x_default + x_offset, y_start + 2 * y_step, z_up);
wait_all_reach();
set_site(2, x_default + x_offset, y_start + 2 * y_step, z_default);
wait_all_reach();
move_speed = body_move_speed;
set_site(0, x_default + x_offset, y_start, z_default);
set_site(1, x_default + x_offset, y_start + 2 * y_step, z_default);
set_site(2, x_default - x_offset, y_start + y_step, z_default);
set_site(3, x_default - x_offset, y_start + y_step, z_default);
wait_all_reach();
move_speed = leg_move_speed;
set_site(1, x_default + x_offset, y_start + 2 * y_step, z_up);
wait_all_reach();
set_site(1, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(1, x_default + x_offset, y_start, z_default);
wait_all_reach();
}
else
{
//этап 0 и 3 ход
set_site(0, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(0, x_default + x_offset, y_start + 2 * y_step, z_up);
wait_all_reach();
set_site(0, x_default + x_offset, y_start + 2 * y_step, z_default);
wait_all_reach();
move_speed = body_move_speed;
set_site(0, x_default - x_offset, y_start + y_step, z_default);
set_site(1, x_default - x_offset, y_start + y_step, z_default);
set_site(2, x_default + x_offset, y_start, z_default);
set_site(3, x_default + x_offset, y_start + 2 * y_step, z_default);
wait_all_reach();
move_speed = leg_move_speed;
set_site(3, x_default + x_offset, y_start + 2 * y_step, z_up);
wait_all_reach();
set_site(3, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(3, x_default + x_offset, y_start, z_default);
wait_all_reach();
}
}
/*
- go back
- blocking function
- parameter step steps wanted to go
---------------------------------------------------------------------------*/
void step_back()
{
move_speed = leg_move_speed;
if (site_now[3][1] == y_start)
{
//этап 3&0 ход
set_site(3, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(3, x_default + x_offset, y_start + 2 * y_step, z_up);
wait_all_reach();
set_site(3, x_default + x_offset, y_start + 2 * y_step, z_default);
wait_all_reach();
move_speed = body_move_speed;
set_site(0, x_default + x_offset, y_start + 2 * y_step, z_default);
set_site(1, x_default + x_offset, y_start, z_default);
set_site(2, x_default - x_offset, y_start + y_step, z_default);
set_site(3, x_default - x_offset, y_start + y_step, z_default);
wait_all_reach();
move_speed = leg_move_speed;
set_site(0, x_default + x_offset, y_start + 2 * y_step, z_up);
wait_all_reach();
set_site(0, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(0, x_default + x_offset, y_start, z_default);
wait_all_reach();
}
else
{
//этап 1 и 2 ход
set_site(1, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(1, x_default + x_offset, y_start + 2 * y_step, z_up);
wait_all_reach();
set_site(1, x_default + x_offset, y_start + 2 * y_step, z_default);
wait_all_reach();
move_speed = body_move_speed;
set_site(0, x_default - x_offset, y_start + y_step, z_default);
set_site(1, x_default - x_offset, y_start + y_step, z_default);
set_site(2, x_default + x_offset, y_start + 2 * y_step, z_default);
set_site(3, x_default + x_offset, y_start, z_default);
wait_all_reach();
move_speed = leg_move_speed;
set_site(2, x_default + x_offset, y_start + 2 * y_step, z_up);
wait_all_reach();
set_site(2, x_default + x_offset, y_start, z_up);
wait_all_reach();
set_site(2, x_default + x_offset, y_start, z_default);
wait_all_reach();
}
}
// добавлено RegisHsu
void body_left(int i)
{
set_site(0, site_now[0][0] + i, KEEP, KEEP);
set_site(1, site_now[1][0] + i, KEEP, KEEP);
set_site(2, site_now[2][0] - i, KEEP, KEEP);
set_site(3, site_now[3][0] - i, KEEP, KEEP);
wait_all_reach();
}
void body_right(int i)
{
set_site(0, site_now[0][0] - i, KEEP, KEEP);
set_site(1, site_now[1][0] - i, KEEP, KEEP);
set_site(2, site_now[2][0] + i, KEEP, KEEP);
set_site(3, site_now[3][0] + i, KEEP, KEEP);
wait_all_reach();
}
void hand_wave(int i)
{
float x_tmp;
float y_tmp;
float z_tmp;
move_speed = 1;
if (site_now[3][1] == y_start)
{
body_right(15);
x_tmp = site_now[2][0];
y_tmp = site_now[2][1];
z_tmp = site_now[2][2];
move_speed = body_move_speed;
for (int j = 0; j < i; j++)
{
set_site(2, turn_x1, turn_y1, 50);
wait_all_reach();
set_site(2, turn_x0, turn_y0, 50);
wait_all_reach();
}
set_site(2, x_tmp, y_tmp, z_tmp);
wait_all_reach();
move_speed = 1;
body_left(15);
}
else
{
body_left(15);
x_tmp = site_now[0][0];
y_tmp = site_now[0][1];
z_tmp = site_now[0][2];
move_speed = body_move_speed;
for (int j = 0; j < i; j++)
{
set_site(0, turn_x1, turn_y1, 50);
wait_all_reach();
set_site(0, turn_x0, turn_y0, 50);
wait_all_reach();
}
set_site(0, x_tmp, y_tmp, z_tmp);
wait_all_reach();
move_speed = 1;
body_right(15);
}
}
void hand_shake(int i)
{
float x_tmp;
float y_tmp;
float z_tmp;
move_speed = 1;
if (site_now[3][1] == y_start)
{
body_right(15);
x_tmp = site_now[2][0];
y_tmp = site_now[2][1];
z_tmp = site_now[2][2];
move_speed = body_move_speed;
for (int j = 0; j < i; j++)
{
set_site(2, x_default - 30, y_start + 2 * y_step, 55);
wait_all_reach();
set_site(2, x_default - 30, y_start + 2 * y_step, 10);
wait_all_reach();
}
set_site(2, x_tmp, y_tmp, z_tmp);
wait_all_reach();
move_speed = 1;
body_left(15);
}
else
{
body_left(15);
x_tmp = site_now[0][0];
y_tmp = site_now[0][1];
z_tmp = site_now[0][2];
move_speed = body_move_speed;
for (int j = 0; j < i; j++)
{
set_site(0, x_default - 30, y_start + 2 * y_step, 55);
wait_all_reach();
set_site(0, x_default - 30, y_start + 2 * y_step, 10);
wait_all_reach();
}
set_site(0, x_tmp, y_tmp, z_tmp);
wait_all_reach();
move_speed = 1;
body_right(15);
}
}
void head_up(int i)
{
set_site(0, KEEP, KEEP, site_now[0][2] - i);
set_site(1, KEEP, KEEP, site_now[1][2] + i);
set_site(2, KEEP, KEEP, site_now[2][2] - i);
set_site(3, KEEP, KEEP, site_now[3][2] + i);
wait_all_reach();
}
void head_down(int i)
{
set_site(0, KEEP, KEEP, site_now[0][2] + i);
set_site(1, KEEP, KEEP, site_now[1][2] - i);
set_site(2, KEEP, KEEP, site_now[2][2] + i);
set_site(3, KEEP, KEEP, site_now[3][2] - i);
wait_all_reach();
}
void body_dance(int i)
{
float x_tmp;
float y_tmp;
float z_tmp;
float body_dance_speed = 2;
sit();
move_speed = 1;
set_site(0, x_default, y_default, KEEP);
set_site(1, x_default, y_default, KEEP);
set_site(2, x_default, y_default, KEEP);
set_site(3, x_default, y_default, KEEP);
wait_all_reach();
//стоять();
set_site(0, x_default, y_default, z_default - 20);
set_site(1, x_default, y_default, z_default - 20);
set_site(2, x_default, y_default, z_default - 20);
set_site(3, x_default, y_default, z_default - 20);
wait_all_reach();
move_speed = body_dance_speed;
head_up(30);
for (int j = 0; j < i; j++)
{
if (j > i / 4)
move_speed = body_dance_speed * 2;
if (j > i / 2)
move_speed = body_dance_speed * 3;
set_site(0, KEEP, y_default - 20, KEEP);
set_site(1, KEEP, y_default + 20, KEEP);
set_site(2, KEEP, y_default - 20, KEEP);
set_site(3, KEEP, y_default + 20, KEEP);
wait_all_reach();
set_site(0, KEEP, y_default + 20, KEEP);
set_site(1, KEEP, y_default - 20, KEEP);
set_site(2, KEEP, y_default + 20, KEEP);
set_site(3, KEEP, y_default - 20, KEEP);
wait_all_reach();
}
move_speed = body_dance_speed;
head_down(30);
}
/*
- microservos service /timer interrupt function/50Hz
- when set site expected,this function move the end point to it in a straight line
- temp_speed[4][3] should be set before set expect site,it make sure the end point
move in a straight line,and decide move speed.
---------------------------------------------------------------------------*/
void servo_service(void)
{
sei();
static float alpha, beta, gamma;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
if (abs(site_now[i][j] - site_expect[i][j]) >= abs(temp_speed[i][j]))
site_now[i][j] += temp_speed[i][j];
else
site_now[i][j] = site_expect[i][j];
}
cartesian_to_polar(alpha, beta, gamma, site_now[i][0], site_now[i][1], site_now[i][2]);
polar_to_servo(i, alpha, beta, gamma);
}
rest_counter++;
}
/*
- set one of end points' expect site
- this founction will set temp_speed[4][3] at same time
- non - blocking function
---------------------------------------------------------------------------*/
void set_site(int leg, float x, float y, float z)
{
float length_x = 0, length_y = 0, length_z = 0;
if (x != KEEP)
length_x = x - site_now[leg][0];
if (y != KEEP)
length_y = y - site_now[leg][1];
if (z != KEEP)
length_z = z - site_now[leg][2];
float length = sqrt(pow(length_x, 2) + pow(length_y, 2) + pow(length_z, 2));
temp_speed[leg][0] = length_x / length * move_speed * speed_multiple;
temp_speed[leg][1] = length_y / length * move_speed * speed_multiple;
temp_speed[leg][2] = length_z / length * move_speed * speed_multiple;
if (x != KEEP)
site_expect[leg][0] = x;
if (y != KEEP)
site_expect[leg][1] = y;
if (z != KEEP)
site_expect[leg][2] = z;
}
/*
- wait one of end points move to expect site
- blocking function
---------------------------------------------------------------------------*/
void wait_reach(int leg)
{
while (1)
if (site_now[leg][0] == site_expect[leg][0])
if (site_now[leg][1] == site_expect[leg][1])
if (site_now[leg][2] == site_expect[leg][2])
break;
}
/*
- wait all of end points move to expect site
- blocking function
---------------------------------------------------------------------------*/
void wait_all_reach(void)
{
for (int i = 0; i < 4; i++)
wait_reach(i);
}
/*
- trans site from cartesian to polar
- mathematical model 2/2
---------------------------------------------------------------------------*/
void cartesian_to_polar(volatile float &alpha, volatile float &beta, volatile float &gamma, volatile float x, volatile float y, volatile float z)
{
//вычисляем степень wz
float v, w;
w = (x >= 0 ? 1 : -1) * (sqrt(pow(x, 2) + pow(y, 2)));
v = w - length_c;
alpha = atan2(z, v) + acos((pow(length_a, 2) - pow(length_b, 2) + pow(v, 2) + pow(z, 2)) / 2 / length_a / sqrt(pow(v, 2) + pow(z, 2)));
beta = acos((pow(length_a, 2) + pow(length_b, 2) - pow(v, 2) - pow(z, 2)) / 2 / length_a / length_b);
//вычисляем степень xyz
gamma = (w >= 0) ? atan2(y, x) : atan2(-y, -x);
//трансградус пи->180
alpha = alpha / pi * 180;
beta = beta / pi * 180;
gamma = gamma / pi * 180;
}
/*
- trans site from polar to microservos
- mathematical model map to fact
- the errors saved in eeprom will be add
---------------------------------------------------------------------------*/
void polar_to_servo(int leg, float alpha, float beta, float gamma)
{
if (leg == 0)
{
alpha = 90 - alpha;
beta = beta;
gamma += 90;
}
else if (leg == 1)
{
alpha += 90;
beta = 180 - beta;
gamma = 90 - gamma;
}
else if (leg == 2)
{
alpha += 90;
beta = 180 - beta;
gamma = 90 - gamma;
}
else if (leg == 3)
{
alpha = 90 - alpha;
beta = beta;
gamma += 90;
}
servo[leg][0].write(alpha);
servo[leg][1].write(beta);
servo[leg][2].write(gamma);
}
ПРИМЕЧАНИЕ. Я удаляю некоторые функции, такие как void sit(void)
, поскольку достигнут максимальный предел символов.
Это мой код esp32
#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"
#define I2S_DOUT 25
#define I2S_BCLK 27
#define I2S_LRC 26
Audio audio;
char data = 0;
void setup()
{
Serial.begin(115200);
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.begin( "Physics", "299792458");
while (WiFi.status() != WL_CONNECTED)
delay(1500);
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(100);
audio.connecttospeech("Hello From akshit singh,,welcome to tapovan international school's project day ,,i am a smart walking robot ,you can also call me astra bot ", "en");
}
void loop(){
if(Serial.available() > 0)
{
data = Serial.read();
Serial.print(data);
if(data == 'A')
{
audio.connecttospeech("hello everyone ,welcome to tapovan international school's project day ", "en");
Serial.println("done");
}
else if(data == 'B')
{
audio.connecttospeech("BYE Bye everyone", "hi");
Serial.println("done 2");
}
else if(data == 'C')
{
audio.connecttospeech("i am a smart walking robot ,you can also call me astra bot ", "hi");
Serial.println("done 2");
}
else if(data == 'F')
{
audio.connecttospeech("going forward ,sir", "hi");
Serial.println("done 2");
}
else if(data == 'b')
{
audio.connecttospeech("going backward ,sir", "hi");
Serial.println("done 2");
}
else if(data == 'L')
{
audio.connecttospeech("moving left, sir", "hi");
Serial.println("done 2");
}
else if(data == 'R')
{
audio.connecttospeech("moving right ,sir", "hi");
Serial.println("done 2");
}
}
{
audio.loop();
}
}
void audio_info(const char *info) {
Serial.print("audio_info: "); Serial.println(info);
}
@Akshit Singh, 👍2
1 ответ
Ну, во-первых, вам нужно знать, что UNO работает при напряжении 5 В, а ESP32 - при 3 В 3, поэтому вам понадобится переключатель уровня между UNO и ESP32, если вы не хотите повредить ESP32.
>Вы можете создать двунаправленный переключатель уровня с помощью N-канальный МОП-транзистор и 2 резистора, или купите коммутационную плату или используйте чип, например GTL2010. Просто обратите внимание, что не все двунаправленные переключатели уровня одинаковы, некоторые требуют изменения направления с помощью штифта (обычно DIR), GTL2010 не из таких.
Bitbanged UART
Можно сделать на любом контакте.
Подойдет как однонаправленный, так и двунаправленный переключатель уровня.
SPI
Поскольку ваши сервоприводы не управляются аппаратным обеспечением ШИМ/таймера, вы можете использовать аналоговые контакты для нескольких ваших сервоприводов и использовать периферийное устройство SPI, которое использует контакты 10, 11, 12 и 13.
Ваш ESP32 отправляет команды, поэтому вам нужно настроить ESP32 в качестве ведущего, а UNO в качестве ведомого.
Как и опция BBUART, будет работать как однонаправленный, так и двунаправленный переключатель уровня.
I2C
При этом используются контакты SDA и SCL рядом с VREF, которые на самом деле представляют собой просто A4 и A5. И опять же, вы должны установить ESP32 главным, а UNO — подчиненным.
Имейте в виду, что вам понадобится двунаправленный переключатель уровня, однонаправленный не подойдет.
Хотя я не рекомендую, есть шанс, что вам удастся обойтись без использования переключателя уровня, подключив подтягивающие резисторы к 3V3. Обратите внимание: для регистрации atmega328P высокий логический уровень, входное напряжение должно составлять 60% от VCC. Таким образом, если он работает при 5 В, для чтения высокого уровня потребуется 3 В, что имеет шанс на работу. Но если он работает на 5V5, для регистрации высокого уровня потребуется 3V3, и, вероятно, он вообще не будет работать должным образом.
Еще одна причина использовать преобразователь уровня заключается в том, что библиотека Arduino I2C использует внутренние подтягивающие резисторы, поэтому вам придется изменить библиотеку, чтобы отключить их, чтобы ваши контакты ESP32 не подтягивались к 5 В.
>BBUART, вероятно, является лучшим выбором, поскольку он использует наименьшее количество контактов и с ним проще всего работать в коде. Все, что вам нужно, это переключатель уровня, и все готово. Но если вы чувствуете себя достаточно уверенно в программировании, вы можете попробовать I2C без переключателя уровня, а если он не работает, то купить его.
- LM7805 сильно нагревается с четырьмя серводвигателями
- Чтение данных из Google Таблиц с помощью Nodemcu
- I2C связь между Arduino Uno и Nodemcu32-s (ESP32)
- Распознавание голоса Arduino
- PN532 не обнаруживает RFID-карту при подключении к ESP32 в режиме I2C, но отлично работает с Arduino Uno
- ESP32-Cam не отвечает и не может запрограммировать — истекло время ожидания заголовка пакета
- Связь Arduino Uno и ESP32 с использованием RS485
- Uno - ESP32 SoftwareSerial связь не работает