Last active
June 20, 2025 12:57
-
-
Save osantana/91dbe2661289f0f7f692eaf105cde711 to your computer and use it in GitHub Desktop.
RoboPet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SPI.h> | |
#include <Wire.h> | |
#include <Adafruit_GFX.h> | |
#include <Adafruit_SSD1306.h> | |
#include <HCSR04.h> | |
#include <ESP32MX1508.h> | |
#include <ESP32Servo.h> | |
#include <NewPing.h> | |
#include <WiFi.h> | |
#include <WebServer.h> | |
// ========= | |
// Movimento | |
// ========= | |
#define CH1 0 // 16 Channels (0-15) are availible | |
#define CH2 1 // Make sure each pin is a different channel and not in use by other PWM devices (servos, LED's, etc) | |
#define RES 8 // Resolution in bits: 8 (0-255), 12 (0-4095), or 16 (0-65535) | |
#define FREQ 2500 // PWM Frequency in Hz | |
#define MOTOR_ESQUERDO_OUT1 18 | |
#define MOTOR_ESQUERDO_OUT2 19 | |
#define MOTOR_DIREITO_OUT1 22 | |
#define MOTOR_DIREITO_OUT2 23 | |
#define SONAR_TRIGGER 13 | |
#define SONAR_ECHO 12 | |
#define SERVO_PIN 14 | |
MX1508 motorA(MOTOR_ESQUERDO_OUT1, MOTOR_ESQUERDO_OUT2, CH1, CH2, RES, FREQ); | |
MX1508 motorB(MOTOR_DIREITO_OUT1, MOTOR_DIREITO_OUT2, CH1, CH2, RES, FREQ); | |
NewPing sonar(SONAR_TRIGGER, SONAR_ECHO, 200); // 200cm = distância máxima | |
const int servoPin = 14; | |
const int pwmChannel = 0; | |
const int resolution = 16; | |
const int freq = 50; | |
unsigned long lastScan = 0; | |
const unsigned long scanInterval = 100; // milissegundos entre passos | |
int angle = 45; | |
int step = 3; | |
void setServoAngle(int angle) { | |
int minPulse = 500; // us | |
int maxPulse = 2400; // us | |
int pulse = map(angle, 0, 180, minPulse, maxPulse); | |
int duty = (pulse * 65535L) / 20000; | |
ledcWrite(pwmChannel, duty); | |
} | |
// ======= | |
// Display | |
// ======= | |
#define SCREEN_WIDTH 128 // Largura display, em pixels | |
#define SCREEN_HEIGHT 32 // Altura display, em pixels | |
#define OLED_RESET -1 // Será o mesmo reset da placa | |
#define MOUTH_WIDTH 128 | |
#define MOUTH_HEIGHT 32 | |
#define SDA_PIN 33 | |
#define SCL_PIN 32 | |
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); | |
// 'img1', 128x32px | |
const unsigned char mouth_img1[] PROGMEM = { | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xc0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xe0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x01, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x60, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x20, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x03, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x03, 0x71, 0xff, 0xf0, 0x00, 0x1f, 0xff, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x03, 0x70, 0x07, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xe0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x01, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x03, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xf3, 0xc0, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0xf9, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfd, 0xe7, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0xfd, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xfd, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xfd, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xfd, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfd, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfd, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7f, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x7f, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x7f, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3f, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8f, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
}; | |
// 'img2', 128x32px | |
const unsigned char mouth_img2[] PROGMEM = { | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x60, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x60, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x03, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xc0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x01, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x80, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xe0, 0x00, 0x00, 0x01, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x7c, 0x00, 0x00, 0x07, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x8f, 0x00, 0x00, 0x3e, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xe3, 0xf0, 0x01, 0xf8, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0x7f, 0xff, 0xc1, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf3, 0x07, 0xfe, 0x19, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf3, 0xe0, 0x00, 0x39, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xfb, 0xe7, 0xdf, 0x3b, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xfb, 0xe7, 0xdf, 0x7b, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfb, 0xe7, 0xdf, 0x7b, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7b, 0xc0, 0x00, 0x3b, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x79, 0xdd, 0xec, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xcf, 0x79, 0x9d, 0xee, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xcf, 0x79, 0x9d, 0xee, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xde, 0x00, 0x00, 0x4e, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xc0, 0x1f, 0xfe, 0x06, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x87, 0xff, 0xff, 0xf0, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3f, 0x80, 0x00, 0xfe, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf8, 0x00, 0x00, 0x0f, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xc0, 0x00, 0x00, 0x01, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x73, 0x80, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x80, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00 | |
}; | |
// 'img3', 128x32px | |
const unsigned char mouth_img3[] PROGMEM = { | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x1f, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x3f, 0xfc, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x86, 0x07, 0xf0, 0x7e, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x1e, 0x60, 0x07, 0x7e, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1e, 0x7e, 0x3f, 0x7e, 0xf3, 0x80, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xde, 0x7e, 0x7f, 0x3e, 0xf9, 0xc0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xde, 0x7e, 0x7f, 0x3e, 0xfc, 0xe0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xde, 0x7e, 0x7f, 0x3e, 0xfc, 0x70, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x01, 0xc1, 0xde, 0x7e, 0x7f, 0x3e, 0xfc, 0x38, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0xde, 0x7f, 0x7f, 0x3c, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0xde, 0x7f, 0x7f, 0x3c, 0xfc, 0x0c, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0xce, 0x7f, 0x7f, 0x3c, 0xf8, 0x0e, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0xce, 0x7f, 0x7f, 0x7c, 0xc0, 0x06, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x7f, 0x3f, 0x78, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x80, 0x0f, 0x3c, 0x00, 0x38, 0x07, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x98, 0x00, 0x00, 0x13, 0xb8, 0x06, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x99, 0xcf, 0x3c, 0xf3, 0xb8, 0x0e, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0xd9, 0xcf, 0x3e, 0xf3, 0xb8, 0x1c, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0xd9, 0xcf, 0x3e, 0xf3, 0xb8, 0x18, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0xef, 0xbe, 0xf3, 0x38, 0x70, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xc9, 0xe7, 0x90, 0xf7, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x4d, 0xe4, 0x00, 0x03, 0x21, 0xc0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0c, 0xe0, 0x7f, 0xc0, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x07, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xbf, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xfe, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
}; | |
// 'img4', 128x32px | |
const unsigned char mouth_img4[] PROGMEM = { | |
0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x06, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0xf3, 0x80, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x01, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x03, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x03, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x01, 0xfb, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x19, 0x87, 0xf8, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x0d, 0x9e, 0x18, 0x00, 0x00, 0x7c, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x0d, 0xf8, 0x8c, 0x07, 0x80, 0xff, 0xdc, 0xe0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x0c, 0xe3, 0x86, 0x1f, 0xc1, 0x83, 0xbe, 0x60, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x36, 0x78, 0xe3, 0x38, 0x77, 0xe0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x73, 0xe0, 0x3e, 0x7f, 0xe3, 0xc0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0xf9, 0xc9, 0x9e, 0xe7, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf8, 0x1b, 0xcc, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xf3, 0xf3, 0xe1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe7, 0xf6, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe7, 0xe6, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0xcf, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0xdf, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0xff, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0xfe, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xfc, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x71, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
}; | |
const int mouth_allArray_LEN = 4; | |
const unsigned char* mouth_allArray[4] = { | |
mouth_img1, | |
mouth_img2, | |
mouth_img3, | |
mouth_img4 | |
}; | |
void drawMouth(byte number) { | |
display.clearDisplay(); | |
display.drawBitmap( | |
(display.width() - MOUTH_WIDTH) / 2, | |
(display.height() - MOUTH_HEIGHT) / 2, | |
mouth_allArray[number], MOUTH_WIDTH, MOUTH_HEIGHT, 1); | |
display.display(); | |
} | |
// ============== | |
// Remote Control | |
// ============== | |
const char* ssid = "robopet"; | |
const char* password = "12345678"; | |
WebServer server(80); | |
IPAddress IP; | |
const char* htmlPage = R"rawliteral( | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Robot Controller</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<style> | |
body { | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
height: 100vh; | |
font-family: sans-serif; | |
} | |
.control-grid { | |
display: grid; | |
grid-template-areas: | |
". forward ." | |
"left stop right" | |
". backward ."; | |
grid-gap: 10px; | |
} | |
button { | |
padding: 20px; | |
font-size: 16px; | |
min-width: 80px; | |
min-height: 50px; | |
border: none; | |
border-radius: 8px; | |
background-color: #007BFF; | |
color: white; | |
cursor: pointer; | |
} | |
.forward { grid-area: forward; } | |
.backward { grid-area: backward; } | |
.left { grid-area: left; } | |
.right { grid-area: right; } | |
.stop { grid-area: stop; background-color: #dc3545; } | |
</style> | |
</head> | |
<body> | |
<div class="control-grid"> | |
<button class="forward" onclick="sendCommand('forward')">Forward</button> | |
<button class="left" onclick="sendCommand('left')">Left</button> | |
<button class="stop" onclick="sendCommand('stop')">Stop</button> | |
<button class="right" onclick="sendCommand('right')">Right</button> | |
<button class="backward" onclick="sendCommand('back')">Backward</button> | |
</div> | |
<script> | |
function sendCommand(dir) { | |
fetch(`/move?dir=${dir}`); | |
} | |
</script> | |
</body> | |
</html> | |
)rawliteral"; | |
void stopMotors() { | |
motorA.motorStop(); | |
motorB.motorStop(); | |
} | |
void move(String dir) { | |
const int speed = 255; // PWM 0-255 | |
if (dir == "forward") { | |
drawMouth(0); | |
motorA.motorGo(speed); | |
motorB.motorGo(speed); | |
} else if (dir == "back") { | |
drawMouth(1); | |
motorA.motorRev(speed); | |
motorB.motorRev(speed); | |
} else if (dir == "left") { | |
drawMouth(2); | |
motorA.motorRev(speed); | |
motorB.motorGo(speed); | |
} else if (dir == "right") { | |
drawMouth(2); | |
motorA.motorGo(speed); | |
motorB.motorRev(speed); | |
} else { | |
drawMouth(3); | |
stopMotors(); | |
} | |
} | |
void setup() { | |
Serial.begin(115200); | |
// Initialize remote control | |
Serial.print("Setting AP (Access Point)..."); | |
WiFi.softAP(ssid, password); | |
IP = WiFi.softAPIP(); | |
Serial.print("AP IP address: "); | |
Serial.println(IP); | |
server.on("/", []() { | |
server.send(200, "text/html", htmlPage); | |
}); | |
server.on("/move", []() { | |
String dir = server.arg("dir"); | |
move(dir); | |
server.send(200, "text/plain", "OK"); | |
}); | |
server.begin(); | |
Serial.print("Server started..."); | |
// init display | |
Wire.begin(SDA_PIN, SCL_PIN); | |
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { | |
for (;;) | |
; | |
} | |
display.clearDisplay(); | |
ledcSetup(pwmChannel, freq, resolution); | |
ledcAttachPin(servoPin, pwmChannel); | |
drawMouth(0); | |
Serial.println("Waiting..."); | |
} | |
void loop() { | |
unsigned long now = millis(); | |
if (now - lastScan >= scanInterval) { | |
angle += step; | |
if (angle >= 135 || angle <= 45) { | |
step = -step; | |
} | |
setServoAngle(angle); | |
int dist = sonar.ping_cm(); | |
Serial.printf("Angle: %d°, Distance: %d cm\n", angle, dist); | |
lastScan = now; | |
delay(50); | |
} | |
server.handleClient(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment