Skip to content

Instantly share code, notes, and snippets.

@lucky-rydar
Last active June 10, 2023 19:26
Show Gist options
  • Save lucky-rydar/62afd03bccaed945408d667fd605a791 to your computer and use it in GitHub Desktop.
Save lucky-rydar/62afd03bccaed945408d667fd605a791 to your computer and use it in GitHub Desktop.
KY-023 driver for ESP32
#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
#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