Initial
This commit is contained in:
commit
e0a693b3c4
5
ReMixer/.gitignore
vendored
Normal file
5
ReMixer/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
10
ReMixer/.vscode/extensions.json
vendored
Normal file
10
ReMixer/.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
39
ReMixer/include/README
Normal file
39
ReMixer/include/README
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
46
ReMixer/lib/README
Normal file
46
ReMixer/lib/README
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
19
ReMixer/platformio.ini
Normal file
19
ReMixer/platformio.ini
Normal file
@ -0,0 +1,19 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:nanoatmega328]
|
||||
platform = atmelavr
|
||||
board = nanoatmega328
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
arduino-libraries/Servo
|
||||
https://github.com/GreyGnome/EnableInterrupt
|
||||
https://github.com/JohnCHarrington/PWMRead
|
||||
|
93
ReMixer/src/main.cpp
Normal file
93
ReMixer/src/main.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include <Arduino.h>
|
||||
#include <Servo.h>
|
||||
#include "PWMRead.h"
|
||||
#include "radio.h"
|
||||
#include "mixer.h"
|
||||
|
||||
// int leftMotorPin = LED_BUILTIN;
|
||||
int leftMotorPin = PD3;
|
||||
int rightMotorPin = PD5;
|
||||
|
||||
// int steeringPin = PD6;
|
||||
// int throttlePin = PD7;
|
||||
Radio radio{};
|
||||
|
||||
Servo leftMotor;
|
||||
Servo rightMotor;
|
||||
|
||||
Mixer mixer{
|
||||
radio,
|
||||
Mixer::Motor{leftMotor, true},
|
||||
Mixer::Motor{rightMotor, false}
|
||||
};
|
||||
|
||||
// PWMRead throttle(PD6, 1000, 1500, 2000);
|
||||
|
||||
// PWMRead throttle(PB3);
|
||||
|
||||
int angle = 0;
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
// int result = myFunction(2, 3);
|
||||
|
||||
|
||||
Serial.begin(9600);
|
||||
// pinMode(PB3, OUTPUT);
|
||||
|
||||
leftMotor.attach(leftMotorPin);
|
||||
rightMotor.attach(rightMotorPin);
|
||||
|
||||
pinMode(PD6, INPUT);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// scan from 0 to 180 degrees
|
||||
// for(angle = 0; angle < 180; angle++)
|
||||
// {
|
||||
// leftMotor.write(angle);
|
||||
// rightMotor.write(180-angle);
|
||||
// delay(15);
|
||||
// }
|
||||
// // now scan back from 180 to 0 degrees
|
||||
// for(angle = 180; angle > 0; angle--)
|
||||
// {
|
||||
// leftMotor.write(angle);
|
||||
// rightMotor.write(180-angle);
|
||||
// delay(15);
|
||||
// }
|
||||
|
||||
// int pwm = pulseIn(PB1, HIGH, 25000);
|
||||
// // Serial.write(throttle.readPercentage());*
|
||||
// Serial.println(pwm, DEC);
|
||||
|
||||
// unsigned long highTime = pulseIn(throttlePin, HIGH);
|
||||
// unsigned long lowTime = pulseIn(throttlePin, LOW);
|
||||
|
||||
// // Calculate the period and frequency
|
||||
// unsigned long period = highTime + lowTime;
|
||||
// float frequency = 1000000.0 / period; // Convert to Hz
|
||||
|
||||
// // Calculate the duty cycle
|
||||
// float dutyCycle = (highTime / (float)period) * 100;
|
||||
|
||||
// // Output the values
|
||||
// Serial.print("Hightime: ");
|
||||
// Serial.print(highTime);
|
||||
// Serial.print(" Frequency: ");
|
||||
// Serial.print(frequency);
|
||||
// Serial.print(" Hz, Duty Cycle: ");
|
||||
// Serial.print(dutyCycle);
|
||||
// Serial.println(" %");
|
||||
|
||||
// Serial.print("Throttle: ");
|
||||
// Serial.print(radio.getThrottle());
|
||||
// Serial.print(" Steering: ");
|
||||
// Serial.println(radio.getSteering());
|
||||
|
||||
// delay(500); // Wait for a bit before measuring again
|
||||
mixer.updateOutputs();
|
||||
}
|
46
ReMixer/src/mixer.cpp
Normal file
46
ReMixer/src/mixer.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "mixer.h"
|
||||
|
||||
Mixer::Mixer(Radio radio, Motor left, Motor right)
|
||||
: m_radio{radio}
|
||||
, m_leftMotor{left}
|
||||
, m_rightMotor{right}
|
||||
{
|
||||
}
|
||||
|
||||
void Mixer::updateOutputs()
|
||||
{
|
||||
auto steering = m_radio.getSteering() / 2;
|
||||
auto throttle = m_radio.getThrottle() * 2;
|
||||
Serial.print("Throttle: ");
|
||||
Serial.print(throttle);
|
||||
Serial.print(" Steering: ");
|
||||
Serial.print(steering);
|
||||
|
||||
auto mixLeft = steering + throttle;
|
||||
auto mixRight = -steering + throttle;
|
||||
|
||||
auto mixAbs = max(abs(mixLeft), abs(mixRight));
|
||||
if (mixAbs > 100)
|
||||
{
|
||||
float scaleDown = 100.0f / (float)mixAbs;
|
||||
mixLeft = (int)((float)mixLeft * scaleDown);
|
||||
mixRight = (int)((float)mixRight * scaleDown);
|
||||
// mixLeft *= scaleDown;
|
||||
// mixRight *= scaleDown;
|
||||
}
|
||||
|
||||
// Map to "servo" output [0, 180]
|
||||
auto mappedLeft = map(mixLeft* (m_leftMotor.inverted ? -1 : 1), -100, 100, 0, 180);
|
||||
auto mappedRight = map(mixRight* (m_rightMotor.inverted ? -1 : 1), -100, 100, 0, 180);
|
||||
|
||||
|
||||
Serial.print(" Left: ");
|
||||
Serial.print(mappedLeft);
|
||||
Serial.print(" Right: ");
|
||||
Serial.println(mappedRight);
|
||||
|
||||
// return to avoid actuating
|
||||
// return;
|
||||
m_leftMotor.servo.write(mappedLeft);
|
||||
m_rightMotor.servo.write(mappedRight);
|
||||
}
|
31
ReMixer/src/mixer.h
Normal file
31
ReMixer/src/mixer.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
// #include <Arduino.h>
|
||||
#include <Servo.h>
|
||||
#include "radio.h"
|
||||
|
||||
class Mixer
|
||||
{
|
||||
public:
|
||||
struct Motor
|
||||
{
|
||||
Motor(Servo servo, bool inverted)
|
||||
: servo{servo}
|
||||
, inverted{inverted}
|
||||
{}
|
||||
|
||||
Servo servo;
|
||||
bool inverted;
|
||||
};
|
||||
|
||||
|
||||
Mixer(Radio radio, Motor left, Motor right);
|
||||
|
||||
// Read the radio and apply mix to motors
|
||||
void updateOutputs();
|
||||
|
||||
private:
|
||||
Radio m_radio;
|
||||
Motor m_leftMotor;
|
||||
Motor m_rightMotor;
|
||||
};
|
27
ReMixer/src/radio.cpp
Normal file
27
ReMixer/src/radio.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "radio.h"
|
||||
|
||||
Radio::Radio(int throttlePin, int steeringPin)
|
||||
: throttleData{}
|
||||
, steeringData{}
|
||||
{
|
||||
throttleData.pin = throttlePin;
|
||||
steeringData.pin = steeringPin;
|
||||
}
|
||||
|
||||
int Radio::getThrottle() { return getSignalData(throttleData); }
|
||||
|
||||
int Radio::getSteering() { return getSignalData(steeringData); }
|
||||
|
||||
int Radio::getSignalData(ChannelData data)
|
||||
{
|
||||
auto highTime = pulseIn(data.pin, HIGH);
|
||||
|
||||
if (highTime > data.signalMid - data.deadzone && highTime < data.signalMid + data.deadzone)
|
||||
{
|
||||
highTime = data.signalMid;
|
||||
}
|
||||
|
||||
auto normalized = map(highTime, data.signalLow, data.signalHigh, -100, 100);
|
||||
|
||||
return normalized * (data.inverted ? -1 : 1);
|
||||
}
|
33
ReMixer/src/radio.h
Normal file
33
ReMixer/src/radio.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class Radio
|
||||
{
|
||||
public:
|
||||
|
||||
struct ChannelData
|
||||
{
|
||||
int pin;
|
||||
int signalLow = 1150;
|
||||
int signalHigh = 1850;
|
||||
int signalMid = 1500;
|
||||
bool inverted = false;
|
||||
int deadzone = 30;
|
||||
};
|
||||
|
||||
ChannelData throttleData;
|
||||
ChannelData steeringData;
|
||||
|
||||
Radio(int throttlePin = PD7, int steeringPin = PD6);
|
||||
|
||||
int getThrottle();
|
||||
|
||||
int getSteering();
|
||||
|
||||
private:
|
||||
int m_throttlePin;
|
||||
int m_steeringPin;
|
||||
|
||||
int getSignalData(ChannelData data);
|
||||
};
|
11
ReMixer/test/README
Normal file
11
ReMixer/test/README
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
5
ps4Controller/.gitignore
vendored
Normal file
5
ps4Controller/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
10
ps4Controller/.vscode/extensions.json
vendored
Normal file
10
ps4Controller/.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
3
ps4Controller/CMakeLists.txt
Normal file
3
ps4Controller/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(ps4Controller)
|
39
ps4Controller/include/README
Normal file
39
ps4Controller/include/README
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
46
ps4Controller/lib/README
Normal file
46
ps4Controller/lib/README
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
63
ps4Controller/platformio.ini
Normal file
63
ps4Controller/platformio.ini
Normal file
@ -0,0 +1,63 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
; THIS CHIP DOES NOT SUPPORT CONVENTINAL BLUETOOTH
|
||||
[env:esp32-c3-devkitm-1]
|
||||
|
||||
platform = espressif32
|
||||
board = esp32-c3-devkitm-1
|
||||
framework = arduino
|
||||
|
||||
lib_deps =
|
||||
madhephaestus/ESP32Servo
|
||||
https://github.com/philsson/PS4-esp32
|
||||
|
||||
monitor_speed = 115200
|
||||
board_build.partitions = min_spiffs.csv
|
||||
|
||||
|
||||
; upload_protocol = espota
|
||||
; upload_port = esp32-3DD870.lan
|
||||
|
||||
|
||||
[env:espressif32]
|
||||
platform = espressif32
|
||||
; board = esp32-c3-devkitm-1
|
||||
; board = wemos_d1_mini32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
; framework = espidf
|
||||
lib_deps =
|
||||
madhephaestus/ESP32Servo
|
||||
; arduino-libraries/PS4-esp32
|
||||
; https://github.com/aed3/PS4-esp32.git
|
||||
; https://github.com/philsson/PS4-esp32
|
||||
|
||||
; espidf implementation
|
||||
https://github.com/saippua/PS4-esp-idf
|
||||
|
||||
; Enable Classic Bluetooth (SPP)
|
||||
; To avoid "undefined reference to `esp_spp_init'" error"
|
||||
build_flags =
|
||||
-Os ; Optimize for size
|
||||
; -D CONFIG_BT_ENABLED=1
|
||||
; -D CONFIG_BT_CLASSIC_ENABLED=1
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
|
||||
; board_build.partitions = huge_app.csv
|
||||
board_build.partitions = min_spiffs.csv
|
||||
; to save size
|
||||
build_type = release
|
||||
|
||||
upload_protocol = espota
|
||||
; upload_port = esp32c3-8783B4.lan
|
||||
upload_port = esp32-3DD870.lan
|
2008
ps4Controller/sdkconfig.espressif32
Normal file
2008
ps4Controller/sdkconfig.espressif32
Normal file
File diff suppressed because it is too large
Load Diff
6
ps4Controller/src/CMakeLists.txt
Normal file
6
ps4Controller/src/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
# This file was automatically generated for projects
|
||||
# without default 'CMakeLists.txt' file.
|
||||
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources})
|
211
ps4Controller/src/main.cpp
Normal file
211
ps4Controller/src/main.cpp
Normal file
@ -0,0 +1,211 @@
|
||||
#include <Arduino.h>
|
||||
#include <ESP32Servo.h>
|
||||
#include <WiFi.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include <PS4Controller.h> // Include the PS4-esp32 library
|
||||
// #include <esp_bt.h>
|
||||
// #include <esp_bt_main.h>
|
||||
// #include <esp_bt_device.h>
|
||||
|
||||
// Wi-Fi credentials
|
||||
const char* ssid = "FaRgO2G4";
|
||||
const char* password = "Johansson85";
|
||||
|
||||
// Telnet server
|
||||
WiFiServer telnetServer(23);
|
||||
WiFiClient telnetClient;
|
||||
|
||||
Servo leftMotor;
|
||||
Servo rightMotor;
|
||||
|
||||
// Callback function to handle PS4 controller events
|
||||
void onPS4Event() {
|
||||
// Print joystick values
|
||||
Serial.printf("Left Stick: (%d, %d)\n", PS4.LStickX(), PS4.LStickY());
|
||||
Serial.printf("Right Stick: (%d, %d)\n", PS4.RStickX(), PS4.RStickY());
|
||||
|
||||
// Print button presses
|
||||
if (PS4.isConnected()) {
|
||||
if (PS4.Circle()) Serial.println("Circle button pressed");
|
||||
if (PS4.Cross()) Serial.println("Cross button pressed");
|
||||
if (PS4.Triangle()) Serial.println("Triangle button pressed");
|
||||
if (PS4.Square()) Serial.println("Square button pressed");
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// Start Serial for debugging
|
||||
Serial.begin(115200);
|
||||
|
||||
// Connect to Wi-Fi
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("\nWi-Fi connected");
|
||||
Serial.print("IP Address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
// Start Telnet server
|
||||
telnetServer.begin();
|
||||
telnetServer.setNoDelay(true);
|
||||
|
||||
// Initialize OTA
|
||||
ArduinoOTA.onStart([]() {
|
||||
String type = (ArduinoOTA.getCommand() == U_FLASH) ? "sketch" : "filesystem";
|
||||
Serial.println("Start updating " + type);
|
||||
});
|
||||
ArduinoOTA.onEnd([]() {
|
||||
Serial.println("\nEnd");
|
||||
});
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
|
||||
});
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
Serial.printf("Error[%u]: ", error);
|
||||
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
|
||||
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
|
||||
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
|
||||
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
|
||||
else if (error == OTA_END_ERROR) Serial.println("End Failed");
|
||||
});
|
||||
ArduinoOTA.begin();
|
||||
|
||||
// Attach servos
|
||||
leftMotor.attach(15);
|
||||
rightMotor.attach(16);
|
||||
|
||||
|
||||
// Initialize PS4 controller
|
||||
// PS4.begin("7C:9E:BD:3D:D8:72"); // Replace with your ESP32's Bluetooth MAC address
|
||||
// PS4.begin("DC:A2:66:DD:72:C0");
|
||||
PS4.begin("dc:a2:66:dd:72:c0");
|
||||
// PS4.attach(onPS4Event); // Attach the event handler
|
||||
Serial.println("Waiting for PS4 controller...");
|
||||
}
|
||||
|
||||
// void printBluetoothMAC() {
|
||||
// const uint8_t* mac = esp_bt_dev_get_address();
|
||||
// if (mac) {
|
||||
// if (telnetClient && telnetClient.connected()) {
|
||||
// telnetClient.printf("ESP32 Bluetooth MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
// mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
// }
|
||||
// Serial.printf("ESP32 Bluetooth MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
// mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
// } else {
|
||||
// if (telnetClient && telnetClient.connected()) {
|
||||
// telnetClient.println("Failed to get Bluetooth MAC Address");
|
||||
// }
|
||||
// Serial.println("Failed to get Bluetooth MAC Address");
|
||||
// }
|
||||
// }
|
||||
|
||||
void loop() {
|
||||
// Handle OTA updates
|
||||
ArduinoOTA.handle();
|
||||
|
||||
// printBluetoothMAC();
|
||||
|
||||
// Handle Telnet client
|
||||
if (telnetServer.hasClient()) {
|
||||
if (telnetClient) telnetClient.stop();
|
||||
telnetClient = telnetServer.available();
|
||||
Serial.println("Telnet client connected");
|
||||
}
|
||||
if (telnetClient && telnetClient.connected()) {
|
||||
while (telnetClient.available()) {
|
||||
Serial.write(telnetClient.read());
|
||||
}
|
||||
}
|
||||
|
||||
// Send serial output to Telnet client
|
||||
if (telnetClient && telnetClient.connected()) {
|
||||
telnetClient.println("Servo positions updated");
|
||||
}
|
||||
|
||||
// // Sweep the servo from 0 to 180 degrees
|
||||
// for (int pos = 0; pos <= 180; pos++) {
|
||||
// leftMotor.write(pos);
|
||||
// rightMotor.write(pos);
|
||||
// delay(15);
|
||||
// }
|
||||
|
||||
// // Sweep the servo from 180 to 0 degrees
|
||||
// for (int pos = 180; pos >= 0; pos--) {
|
||||
// leftMotor.write(pos);
|
||||
// rightMotor.write(pos);
|
||||
// delay(15);
|
||||
// }
|
||||
|
||||
// // Handle PS4 controller input
|
||||
// if (PS4.isConnected()) {
|
||||
// // Example: Control servos with left joystick
|
||||
// int leftStickY = PS4.LStickY(); // Get Y-axis value of the left stick
|
||||
// int servoPosition = map(leftStickY, -128, 127, 0, 180); // Map to servo range
|
||||
// leftMotor.write(servoPosition);
|
||||
// rightMotor.write(servoPosition);
|
||||
// }
|
||||
if (PS4.isConnected()) {
|
||||
if (PS4.Right()) Serial.println("Right Button");
|
||||
if (PS4.Down()) Serial.println("Down Button");
|
||||
if (PS4.Up()) Serial.println("Up Button");
|
||||
if (PS4.Left()) Serial.println("Left Button");
|
||||
|
||||
if (PS4.Square()) Serial.println("Square Button");
|
||||
if (PS4.Cross()) Serial.println("Cross Button");
|
||||
if (PS4.Circle()) Serial.println("Circle Button");
|
||||
if (PS4.Triangle()) Serial.println("Triangle Button");
|
||||
|
||||
if (PS4.UpRight()) Serial.println("Up Right");
|
||||
if (PS4.DownRight()) Serial.println("Down Right");
|
||||
if (PS4.UpLeft()) Serial.println("Up Left");
|
||||
if (PS4.DownLeft()) Serial.println("Down Left");
|
||||
|
||||
if (PS4.L1()) Serial.println("L1 Button");
|
||||
if (PS4.R1()) Serial.println("R1 Button");
|
||||
|
||||
if (PS4.Share()) Serial.println("Share Button");
|
||||
if (PS4.Options()) Serial.println("Options Button");
|
||||
if (PS4.L3()) Serial.println("L3 Button");
|
||||
if (PS4.R3()) Serial.println("R3 Button");
|
||||
|
||||
if (PS4.PSButton()) Serial.println("PS Button");
|
||||
if (PS4.Touchpad()) Serial.println("Touch Pad Button");
|
||||
|
||||
if (PS4.L2()) {
|
||||
Serial.printf("L2 button at %d\n", PS4.L2Value()); // [0, 255]
|
||||
}
|
||||
if (PS4.R2()) {
|
||||
Serial.printf("R2 button at %d\n", PS4.R2Value());
|
||||
}
|
||||
|
||||
if (PS4.LStickX()) {
|
||||
Serial.printf("Left Stick x at %d\n", PS4.LStickX()); // [-128, 127]
|
||||
}
|
||||
if (PS4.LStickY()) {
|
||||
Serial.printf("Left Stick y at %d\n", PS4.LStickY());
|
||||
}
|
||||
if (PS4.RStickX()) {
|
||||
Serial.printf("Right Stick x at %d\n", PS4.RStickX());
|
||||
}
|
||||
if (PS4.RStickY()) {
|
||||
Serial.printf("Right Stick y at %d\n", PS4.RStickY());
|
||||
auto value = PS4.RStickY();
|
||||
auto remapped = map(value, -128, 127, 0, 180);
|
||||
leftMotor.write(remapped);
|
||||
}
|
||||
|
||||
if (PS4.Charging()) Serial.println("The controller is charging");
|
||||
if (PS4.Audio()) Serial.println("The controller has headphones attached");
|
||||
if (PS4.Mic()) Serial.println("The controller has a mic attached");
|
||||
|
||||
Serial.printf("Battery Level : %d\n", PS4.Battery());
|
||||
|
||||
Serial.println();
|
||||
// This delay is to make the output more human readable
|
||||
// Remove it when you're not trying to see the output
|
||||
// delay(1000);
|
||||
}
|
||||
}
|
11
ps4Controller/test/README
Normal file
11
ps4Controller/test/README
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
Loading…
x
Reference in New Issue
Block a user