Last active
June 10, 2023 19:26
-
-
Save lucky-rydar/62afd03bccaed945408d667fd605a791 to your computer and use it in GitHub Desktop.
KY-023 driver for ESP32
This file contains 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
#ifndef JOY_H | |
#define JOY_H | |
#include "driver/gpio.h" | |
#include "driver/adc.h" | |
#include "rom/gpio.h" | |
#include <map> | |
#include <string> | |
using namespace std; | |
enum class Direction { | |
None, | |
Center, | |
Left, | |
Right, | |
Up, | |
Down | |
}; | |
enum class Button { | |
Pressed, | |
Released | |
}; | |
class JoystickConfig { | |
adc1_channel_t m_xChannel; | |
adc1_channel_t m_yChannel; | |
adc1_channel_t m_btnChannel; | |
adc_bits_width_t m_width; | |
adc_atten_t m_attenuation; | |
public: | |
JoystickConfig() { | |
m_xChannel = ADC1_CHANNEL_4; | |
m_yChannel = ADC1_CHANNEL_7; | |
m_btnChannel = ADC1_CHANNEL_6; | |
m_width = ADC_WIDTH_BIT_12; | |
m_attenuation = ADC_ATTEN_DB_11; | |
} | |
void setXChannel(adc1_channel_t channel) { | |
m_xChannel = channel; | |
} | |
void setYChannel(adc1_channel_t channel) { | |
m_yChannel = channel; | |
} | |
void setButtonChannel(adc1_channel_t channel) { | |
m_btnChannel = channel; | |
} | |
void setWidth(adc_bits_width_t width) { | |
m_width = width; | |
} | |
void setAttenuation(adc_atten_t attenuation) { | |
m_attenuation = attenuation; | |
} | |
adc1_channel_t getXChannel() { | |
return m_xChannel; | |
} | |
adc1_channel_t getYChannel() { | |
return m_yChannel; | |
} | |
adc1_channel_t getButtonChannel() { | |
return m_btnChannel; | |
} | |
adc_bits_width_t getWidth() { | |
return m_width; | |
} | |
adc_atten_t getAttenuation() { | |
return m_attenuation; | |
} | |
}; | |
struct JoystickState { | |
Direction m_x; | |
Direction m_y; | |
Button m_button; | |
}; | |
class Joystick { | |
private: | |
JoystickConfig m_config; | |
const std::map<Direction, std::string> m_directionMap = { | |
{Direction::None, "None"}, | |
{Direction::Left, "Left"}, | |
{Direction::Right, "Right"}, | |
{Direction::Up, "Up"}, | |
{Direction::Down, "Down"}, | |
{Direction::Center, "Center"} | |
}; | |
int m_maxAnalogValue; | |
int m_topAverage; | |
int m_bottomAverage; | |
public: | |
Joystick() = delete; | |
Joystick(JoystickConfig config) : m_config(config) { | |
adc1_config_width(m_config.getWidth()); | |
adc1_config_channel_atten(m_config.getXChannel(), m_config.getAttenuation()); | |
adc1_config_channel_atten(m_config.getYChannel(), m_config.getAttenuation()); | |
adc1_config_channel_atten(m_config.getButtonChannel(), m_config.getAttenuation()); | |
m_maxAnalogValue = (1 << m_config.getWidth()) - 1; | |
m_topAverage = (m_maxAnalogValue / 2) + (m_maxAnalogValue / 4); | |
m_bottomAverage = (m_maxAnalogValue / 2) - (m_maxAnalogValue / 4); | |
} | |
JoystickState getState() { | |
JoystickState state; | |
state.m_x = getXDirection(); | |
state.m_y = getYDirection(); | |
state.m_button = getButton(); | |
return state; | |
} | |
Direction getXDirection() { | |
int x = getX(); | |
if (x > m_topAverage) { | |
return Direction::Right; | |
} else if (x < m_bottomAverage) { | |
return Direction::Left; | |
} else { | |
return Direction::Center; | |
} | |
} | |
Direction getYDirection() { | |
int y = getY(); | |
if (y > m_topAverage) { | |
return Direction::Down; // it is inverted on hardware | |
} else if (y < m_bottomAverage) { | |
return Direction::Up; // it is inverted on hardware | |
} else { | |
return Direction::Center; | |
} | |
} | |
int getX() { | |
return adc1_get_raw(m_config.getXChannel()); | |
} | |
int getY() { | |
return adc1_get_raw(m_config.getYChannel()); | |
} | |
int getButtonRaw() { | |
return adc1_get_raw(m_config.getButtonChannel()); | |
} | |
Button getButton() { | |
return adc1_get_raw(m_config.getButtonChannel()) == 0 ? Button::Pressed : Button::Released; | |
} | |
std::string getXDirectionString() { | |
return m_directionMap.at(getXDirection()); | |
} | |
std::string getYDirectionString() { | |
return m_directionMap.at(getYDirection()); | |
} | |
std::string getButtonString() { | |
return getButton() == Button::Pressed ? "Pressed" : "Released"; | |
} | |
}; | |
#endif |
This file contains 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 <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include "freertos/FreeRTOS.h" | |
#include "freertos/task.h" | |
#include "driver/gpio.h" | |
#include "driver/adc.h" | |
#include "rom/gpio.h" | |
#include "joystick.hpp" | |
void joystick_printer(void*) { | |
JoystickConfig config; | |
Joystick j(config); | |
while (true) { | |
//printf("X: %s, Y: %s, Button: %s\n", | |
// j.getXDirectionString().data(), | |
// j.getYDirectionString().data(), | |
// j.getButtonString().data()); | |
printf("X: %d, Y: %d, Button: %d\n", | |
j.getX(), | |
j.getY(), | |
j.getButtonRaw()); | |
vTaskDelay(100 / portTICK_PERIOD_MS); | |
} | |
} | |
extern "C" void app_main(void) { | |
xTaskCreate(joystick_printer, "joystick_printer", 4096, NULL, 1, NULL); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment