Two-Axis Button Joystick Module
The two-axis button game joystick module uses the metal button joystick potentiometer found on PS2 game controllers. The module is specially designed with two analog output interfaces and one digital output interface. The output values correspond to the (X, Y) two-axis offsets respectively, and their type is analog; the button indicates whether the user is pressing on the Z-axis, and its type is digital switch quantity. With it, you can easily control objects moving in two-dimensional space. Therefore, through controller programming and plugging into a sensor expansion board, you can complete creative remote-control interactive works.
Module Source
Purchase link: https://detail.tmall.com/item.htm?abbucket=0&id=609784733201&ns=1&spm=a21n57.1.0.0.7b97523cuNeQqX
Specifications
Drive voltage: 3.3V~5V Control method: ADC+GPIO
View Materials
Output signal: The module is specially designed with two analog outputs (VRX, VRY) and one digital output interface (SW). The two analog output values correspond to the (X, Y) two-axis offsets respectively, and their type is analog; the button indicates whether the user is pressing on the Z-axis, and its type is digital switch quantity.
The cross joystick is a bidirectional 10K resistor; as the joystick direction changes, the tap resistance changes accordingly. If this module is powered with 5V, in the original state, the X and Y readout voltage is about 2.5V. When pressed in the arrow direction, the readout voltage decreases, with a minimum of 0V.
Porting Process
Pin Selection
VRX and VRY use the ADC function.
Port to Project
Our goal is to port the example to the ESP32-S3 dev board. Complete driver code has been provided for you. Follow the steps below to complete the porting.
For detailed instructions on creating folders and new .c and .h files, refer to section 1.4.2 in the [DHT11 Temperature and Humidity Sensor] chapter; we will not repeat it here.
Just note that here we change the file names bsp_dht11.c and bsp_dht11.h to bsp_joystick.c and bsp_joystick.h, and the folder name to Joystick.
Write Code
In the file bsp_joystick.c, write the following code.
/*
* LCSC-Openkits (LCKFB) software and hardware materials and related expansion board software and hardware materials are all open source on the official website.
* Dev board official website: www.lckfb.com
* Technical support resides on the forum; any technical questions are welcome for exchange and learning at any time.
* LCKFB Forum: club.szlcsc.com
* Follow our Bilibili account: [LCSC-Openkits (LCKFB)] to keep up with our latest updates!
* We do not make money by selling boards; we take cultivating engineers as our mission.
* Change Logs:
* Date Author Notes
* 2024-01-15 LCKFB-lp first version
*/
#include "bsp_joystick.h"
esp_adc_cal_characteristics_t *adc_chars;
void delay_ms(unsigned int ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}
void delay_us(unsigned int us)
{
ets_delay_us(us);
}
void delay_1ms(unsigned int ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}
void delay_1us(unsigned int us)
{
ets_delay_us(us);
}
/******************************************************************
* Function Name: ADC_Init
* Function Description: Initialize ADC+DMA function
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void ADC_Init(void)
{
gpio_config_t lll_config = {
.pin_bit_mask = (1ULL<<SW_PIN), // Configure pin
.mode =GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE, // Enable pull-up
.pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down
.intr_type = GPIO_INTR_DISABLE // Disable pin interrupt
};
gpio_config(&lll_config);
adc1_config_width(width);// 12-bit resolution
//ADC_ATTEN_DB_0: reference voltage is 1.1V
//ADC_ATTEN_DB_2_5: reference voltage is 1.5V
//ADC_ATTEN_DB_6: reference voltage is 2.2V
//ADC_ATTEN_DB_11: reference voltage is 3.3V
//adc1_config_channel_atten( channel,atten);// Set channel 0 and 3.3V reference voltage
// Allocate memory
adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
// Initialize the ADC characteristics so that conversion results and compensation factors can be correctly calculated
esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars);
}
/******************************************************************
* Function Name: Get_Adc_Dma_Value
* Function Description: Calculate the average of the data saved by DMA and output it
* Function Parameters: CHx which scan data
* Function Return: The corresponding ADC value of the scan
* Author: LC
* Notes: None
******************************************************************/
unsigned int Get_Adc_Dma_Value(char CHx)
{
unsigned char i = 0;
unsigned int AdcValue = 0;
/* Since we collect SAMPLES times, loop SAMPLES times */
for(i=0; i< SAMPLES; i++)
{
/* Accumulate */
AdcValue += adc1_get_raw(CHx);
}
/* Calculate the average */
AdcValue = AdcValue / SAMPLES;
return AdcValue;
}
/******************************************************************
* Function Name: Get_MQ2_Percentage_value
* Function Description: Read the joystick value and return the percentage
* Function Parameters: 0 = read the joystick left/right value, 1 = read the joystick up/down value
* Function Return: Returns the percentage
* Author: LC
* Notes: None
******************************************************************/
unsigned int Get_Joystick_Percentage_value(char dir)
{
int adc_new = 0;
int Percentage_value = 0;
adc_new = Get_Adc_Dma_Value(dir);
Percentage_value = ((float)adc_new/4095.0) * 100;
return Percentage_value;
}
/******************************************************************
* Function Name: Get_SW_state
* Function Description: Read whether the joystick is pressed
* Function Parameters: None
* Function Return: 0 joystick is pressed 1 joystick is not pressed
* Author: LC
* Notes: None
******************************************************************/
char Get_SW_state(void)
{
// If pressed
if( gpio_get_level(SW_PIN) == 0 )
{
return 0;
}
else
{
return 1;
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
In the file bsp_joystick.h, write the following code.
#ifndef _BSP_JOYSTICK_H_
#define _BSP_JOYSTICK_H_
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "freertos/queue.h"
#include <inttypes.h>
#include "sdkconfig.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "rom/ets_sys.h"
#include "esp_system.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "driver/spi_common.h"
#include "hal/gpio_types.h"
#include "driver/ledc.h"
#include "driver/mcpwm.h"
#include "esp_adc/adc_cali_scheme.h"
#include "esp_adc/adc_cali.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#include "string.h"
#define VRX_PIN 1
#define VRY_PIN 2
#define SW_PIN 3
#define DEFAULT_VREF 1100 // Default reference voltage, unit mV
#define x_channel ADC_CHANNEL_0 // VRX-ADC measurement channel
#define y_channel ADC_CHANNEL_1 // VRy-ADC measurement channel
#define width ADC_WIDTH_BIT_12 // ADC resolution
#define atten ADC_ATTEN_DB_11 // ADC attenuation
#define unit ADC_UNIT_1 // ADC1
// Number of samples
#define SAMPLES 30
void ADC_Init(void);
unsigned int Get_Joystick_Percentage_value(char dir);
char Get_SW_state(void);
#endif2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Porting Verification
In the main function of your project, write the following code.
/*
* LCSC-Openkits (LCKFB) software and hardware materials and related expansion board software and hardware materials are all open source on the official website.
* Dev board official website: www.lckfb.com
* Technical support resides on the forum; any technical questions are welcome for exchange and learning at any time.
* LCKFB Forum: club.szlcsc.com
* Follow our Bilibili account: [LCSC-Openkits (LCKFB)] to keep up with our latest updates!
* We do not make money by selling boards; we take cultivating engineers as our mission.
* Change Logs:
* Date Author Notes
* 2024-01-15 LCKFB-lp first version
*/
#include <stdio.h>
#include "bsp_joystick.h"
#include "string.h"
#include "esp_private/esp_task_wdt.h"
#include "esp_private/esp_task_wdt_impl.h"
int app_main(void)
{
esp_task_wdt_deinit();
ADC_Init();
printf("Demo Start......\r\n");
while(1)
{
printf("SW = %s\r\n", ( (Get_SW_state() )?"up":"down") );
printf("X = %d%%\r\n", Get_Joystick_Percentage_value(0) );
printf("Y = %d%%\r\n", Get_Joystick_Percentage_value(1) );
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Power-on effect:
Driver code:
File Download
📌 Materials Download Center (Click to Jump)
📌 In the Materials Download Center -> Module Porting Materials Download, inside the compressed package of this chapter.