diff --git a/python/unihiker/DFRobot_DF2301Q.py b/python/unihiker/DFRobot_DF2301Q.py
new file mode 100644
index 0000000..c0b7e1e
--- /dev/null
+++ b/python/unihiker/DFRobot_DF2301Q.py
@@ -0,0 +1,94 @@
+import time
+from pinpong.board import gboard, I2C
+
+# I2C constants
+DF2301Q_I2C_ADDR = 0x64
+DF2301Q_I2C_REG_CMDID = 0x02
+DF2301Q_I2C_REG_PLAY_CMDID = 0x03
+DF2301Q_I2C_REG_SET_MUTE = 0x04
+DF2301Q_I2C_REG_SET_VOLUME = 0x05
+DF2301Q_I2C_REG_WAKE_TIME = 0x06
+
+class DFRobot_DF2301Q:
+ '''!
+ @brief Define DFRobot_DF2301Q basic class
+ '''
+ def __init__(self):
+ '''!
+ @brief Module init
+ '''
+ pass
+
+class DFRobot_DF2301Q_I2C(DFRobot_DF2301Q):
+ '''!
+ @brief Define DFRobot_DF2301Q_I2C basic class
+ '''
+ def __init__(self):
+ board = gboard
+ self.i2c_addr = DF2301Q_I2C_ADDR
+ self._i2c = I2C(0)
+ super().__init__()
+
+ def _read_reg(self, reg, length=1):
+ '''!
+ @brief read the data from the register
+ @param reg - register address
+ @param length - number of bytes to read
+ @return read data
+ '''
+ result = self._i2c.readfrom_mem_restart_transmission(self.i2c_addr, reg, length)
+ return result
+
+ def _write_reg(self, reg, data):
+ '''!
+ @brief writes data to a register
+ @param reg - register address
+ @param data - written data
+ '''
+ self._i2c.writeto_mem(self.i2c_addr, reg, bytes(data))
+
+ def get_CMDID(self):
+ '''!
+ @brief Get the ID corresponding to the command word
+ @return Return the obtained command word ID, returning 0 means no valid ID is obtained
+ '''
+ time.sleep(0.05)
+ return self._read_reg(DF2301Q_I2C_REG_CMDID)[0]
+
+ def play_by_CMDID(self, CMDID):
+ '''!
+ @brief Play the corresponding reply audio according to the command word ID
+ @param CMDID - Command word ID
+ @note Can enter wake-up state through ID-1 in I2C mode
+ '''
+ self._write_reg(DF2301Q_I2C_REG_PLAY_CMDID, [CMDID])
+ time.sleep(1)
+
+ def get_wake_time(self):
+ '''!
+ @brief Get the wake-up duration
+ @return The current set wake-up period
+ '''
+ return self._read_reg(DF2301Q_I2C_REG_WAKE_TIME)[0]
+
+ def set_wake_time(self, wake_time):
+ '''!
+ @brief Set wake-up duration
+ @param wake_time - Wake-up duration(0-255)
+ '''
+ self._write_reg(DF2301Q_I2C_REG_WAKE_TIME, [wake_time & 0xFF])
+
+ def set_volume(self, vol):
+ '''!
+ @brief Set voice volume
+ @param vol - Volume value(1~7)
+ '''
+ self._write_reg(DF2301Q_I2C_REG_SET_VOLUME, [vol])
+
+ def set_mute_mode(self, mode):
+ '''!
+ @brief Set mute mode
+ @param mode - Mute mode; set value 1: mute, 0: unmute
+ '''
+ self._write_reg(DF2301Q_I2C_REG_SET_MUTE, [1 if mode else 0])
+
diff --git a/python/unihiker/DFRobot_DF2301Q_Commands.py b/python/unihiker/DFRobot_DF2301Q_Commands.py
new file mode 100644
index 0000000..c197aaa
--- /dev/null
+++ b/python/unihiker/DFRobot_DF2301Q_Commands.py
@@ -0,0 +1,150 @@
+class CommandWord:
+ Silence = 0
+ WakeUpWordsForLearning = 1
+ HelloRobot = 2
+ CustomCommand1 = 5
+ CustomCommand2 = 6
+ CustomCommand3 = 7
+ CustomCommand4 = 8
+ CustomCommand5 = 9
+ CustomCommand6 = 10
+ CustomCommand7 = 11
+ CustomCommand8 = 12
+ CustomCommand9 = 13
+ CustomCommand10 = 14
+ CustomCommand11 = 15
+ CustomCommand12 = 16
+ CustomCommand13 = 17
+ CustomCommand14 = 18
+ CustomCommand15 = 19
+ CustomCommand16 = 20
+ CustomCommand17 = 21
+ GoForward = 22
+ Retreat = 23
+ ParkACar = 24
+ TurnLeftNinetyDegrees = 25
+ TurnLeftFortyFiveDegrees = 26
+ TurnLeftThirtyDegrees = 27
+ TurnRightFortyFiveDegrees = 29
+ TurnRightThirtyDegrees = 30
+ ShiftDownAGear = 31
+ LineTrackingMode = 32
+ LightTrackingMode = 33
+ BluetoothMode = 34
+ ObstacleAvoidanceMode = 35
+ FaceRecognition = 36
+ ObjectTracking = 37
+ ObjectRecognition = 38
+ LineTracking = 39
+ ColorRecognition = 40
+ TagRecognition = 41
+ ObjectSorting = 42
+ QrCodeRecognition = 43
+ GeneralSettings = 44
+ ClearScreen = 45
+ LearnOnce = 46
+ Forget = 47
+ LoadModel = 48
+ SaveModel = 49
+ TakePhotosAndSaveThem = 50
+ SaveAndReturn = 51
+ DisplayNumberZero = 52
+ DisplayNumberOne = 53
+ DisplayNumberTwo = 54
+ DisplayNumberThree = 55
+ DisplayNumberFour = 56
+ DisplayNumberFive = 57
+ DisplayNumberSix = 58
+ DisplayNumberSeven = 59
+ DisplayNumberEight = 60
+ DisplayNumberNine = 61
+ DisplaySmileyFace = 62
+ DisplayCryingFace = 63
+ DisplayHeart = 64
+ TurnOffDotMatrix = 65
+ ReadCurrentPosture = 66
+ ReadAmbientLight = 67
+ ReadCompass = 68
+ ReadTemperature = 69
+ ReadAcceleration = 70
+ ReadingSoundIntensity = 71
+ CalibrateElectronicGyroscope = 72
+ TurnOnTheCamera = 73
+ TurnOffTheCamera = 74
+ TurnOnTheFan = 75
+ TurnOffTheFan = 76
+ TurnFanSpeedToGearOne = 77
+ TurnFanSpeedToGearTwo = 78
+ TurnFanSpeedToGearThree = 79
+ StartOscillating = 80
+ StopOscillating = 81
+ Reset = 82
+ SetServoToTenDegrees = 83
+ SetServoToThirtyDegrees = 84
+ SetServoToFortyFiveDegrees = 85
+ SetServoToSixtyDegrees = 86
+ SetServoToNinetyDegrees = 87
+ TurnOnTheBuzzer = 88
+ TurnOffTheBuzzer = 89
+ TurnOnTheSpeaker = 90
+ TurnOffTheSpeaker = 91
+ PlayMusic = 92
+ StopPlaying = 93
+ TheLastTrack = 94
+ TheNextTrack = 95
+ RepeatThisTrack = 96
+ VolumeUp = 97
+ VolumeDown = 98
+ ChangeVolumeToMaximum = 99
+ ChangeVolumeToMinimum = 100
+ ChangeVolumeToMedium = 101
+ PlayPoem = 102
+ TurnOnTheLight = 103
+ TurnOffTheLight = 104
+ BrightenTheLight = 105
+ DimTheLight = 106
+ AdjustBrightnessToMaximum = 107
+ AdjustBrightnessToMinimum = 108
+ IncreaseColorTemperature = 109
+ DecreaseColorTemperature = 110
+ AdjustColorTemperatureToMaximum = 111
+ AdjustColorTemperatureToMinimum = 112
+ DaylightMode = 113
+ MoonlightMode = 114
+ ColorMode = 115
+ SetToRed = 116
+ SetToOrange = 117
+ SetToYellow = 118
+ SetToGreen = 119
+ SetToCyan = 120
+ SetToBlue = 121
+ SetToPurple = 122
+ SetToWhite = 123
+ TurnOnAc = 124
+ TurnOffAc = 125
+ IncreaseTemperature = 126
+ DecreaseTemperature = 127
+ CoolMode = 128
+ HeatMode = 129
+ AutoMode = 130
+ DryMode = 131
+ FanMode = 132
+ EnableBlowingUpDown = 133
+ DisableBlowingUpDown = 134
+ EnableBlowingRightLeft = 135
+ DisableBlowingRightLeft = 136
+ OpenTheWindow = 137
+ CloseTheWindow = 138
+ OpenCurtain = 139
+ CloseCurtain = 140
+ OpenTheDoor = 141
+ CloseTheDoor = 142
+ LearningWakeWord = 200
+ LearningCommandWord = 201
+ ReLearn = 202
+ ExitLearning = 203
+ IWantToDelete = 204
+ DeleteWakeWord = 205
+ DeleteCommandWord = 206
+ ExitDeleting = 207
+ DeleteAll = 208
\ No newline at end of file
diff --git a/python/unihiker/README.md b/python/unihiker/README.md
new file mode 100644
index 0000000..daf016a
--- /dev/null
+++ b/python/unihiker/README.md
@@ -0,0 +1,111 @@
+# DFRobot_DF2301Q
+
+1. Arduino-compatible controllers: Arduino UNO, Arduino Leonardo, Arduino MEGA, FireBeetle series controllers, Raspberry Pi, and ESP32
+
+2. Standard Gravity interface, plug-and-play, and 3.3V & 5V devices compatible
+
+3. Command word self-learning function: learn command words by the voice control module, and any audio can be used as a command
+
+4. Built-in fixed 150 commonly-used command words
+
+5. The module comes with a speaker and the interface for connecting external speaker, which can give voice feedback of recognition results in real time
+
+6. Adopt I2C & UART (not implemented) communication methods, and Gravity interface.
+
+7. On-board power indicator (red) and recognition status indicator (blue)
+
+8. Dual microphone receiver for better anti-noise ability and farther recognition distance
+
+
+
+
+## Product Link (https://www.dfrobot.com/)
+ SKU: SEN0539
+
+
+## Table of Contents
+
+* [Summary](#summary)
+* [Installation](#installation)
+* [Methods](#methods)
+* [Compatibility](#compatibility)
+* [History](#history)
+* [Credits](#credits)
+
+
+## Summary
+
+ * This library can be used to get the recognized command ID, and play the corresponding reply audio according to the ID;
+ * This library can also be used to get and set the wake-up state duration, set mute mode, set volume, enter wake-up state, and reset the module
+
+
+## Installation
+
+1. Clone the repository
+
+```python
+sudo git clone https://github.com/DFRobot/DFRobot_DF2301Q
+```
+
+2. SSH into your Unihiker [via Visual Studio Code](https://www.unihiker.com/wiki/get-started#4.3.%20Programming%20on%20VSCode)
+
+3. Create a `lib` folder under `root`
+
+4. Place the two library files in the `lib` folder
+
+5. Copy the example `i2c.py` file to the `root` folder and rename it as desired
+
+6. Run the example file
+## Methods
+
+```python
+"""#################################################################
+ Subclass using I2C interface for communication
+#################################################################"""
+
+ '''!
+ @brief Get the ID corresponding to the command word
+ @return Return the obtained command word ID, returning 0 means no valid ID is obtained
+ '''
+ def get_CMDID(self):
+
+ '''!
+ @brief Play the corresponding reply audio according to the command word ID
+ @param CMDID - Command word ID
+ @note Can enter wake-up state through ID-1 in I2C mode
+ '''
+ def play_by_CMDID(self, CMDID):
+
+ '''!
+ @brief Get the wake-up duration
+ @return The current set wake-up period
+ '''
+ def get_wake_time(self):
+
+ '''!
+ @brief Set wake-up duration
+ @param wakeTime - Wake-up duration(0-255)
+ '''
+ def set_wake_time(self, wake_time):
+
+ '''!
+ @brief Set volume
+ @param vol - Volume range(1-7)
+ '''
+ def set_volume(self, vol):
+
+ '''!
+ @brief Set mute mode
+ @param mode - Mute mode; set value 1: mute, 0: unmute
+ '''
+ def set_mute_mode(self, mode):
+```
+
+## History
+
+- 2024/07/24 - Version 1.0.0 released.
+
+
+## Credits
+
+Original python code written by qsjhyy(yihuan.huang@dfrobot.com), 2022. (Welcome to our [website](https://www.dfrobot.com/))
\ No newline at end of file
diff --git a/python/unihiker/examples/i2c.py b/python/unihiker/examples/i2c.py
new file mode 100644
index 0000000..f2bccbb
--- /dev/null
+++ b/python/unihiker/examples/i2c.py
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*
+"""
+ @file i2c.py
+ @brief Control the voice recognition module via I2C
+ @n Get the recognized command ID and play the corresponding reply audio according to the ID;
+ @n Get and set the wake-up state duration, set mute mode, set volume, and enter the wake-up state
+ @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
+ @licence The MIT License (MIT)
+ @author [timo614](timo614@gmail.com), [qsjhyy](yihuan.huang@dfrobot.com)
+ @version V1.0
+ @date 2022-12-30
+ @url https://github.com/DFRobot/DFRobot_DF2301Q
+"""
+
+import sys
+import time
+from pinpong.board import Board, I2C
+
+# Add the library to the system path
+sys.path.append('./lib')
+
+from DFRobot_DF2301Q import DFRobot_DF2301Q_I2C, DF2301Q_I2C_ADDR
+from DFRobot_DF2301Q_Commands import CommandWord
+
+Board("UNIHIKER").begin()
+
+# Create instance of the I2C device
+DF2301Q = DFRobot_DF2301Q_I2C()
+
+def setup():
+ '''
+ @brief Set voice volume
+ @param vol - Volume
+ '''
+ DF2301Q.set_volume(15)
+
+ '''
+ @brief Set mute mode
+ @param mode - Mute mode; set value 1: mute, 0: unmute
+ '''
+ DF2301Q.set_mute_mode(0)
+
+ '''
+ @brief Set wake-up duration
+ @param wakeTime - Wake-up duration(0-255)
+ '''
+ DF2301Q.set_wake_time(20)
+
+ '''
+ @brief Get the wake-up duration
+ @return The current set wake-up period
+ '''
+ print("wake_time = %u\n" % (DF2301Q.get_wake_time()))
+
+ '''
+ @brief Play the corresponding reply audio according to the command word ID
+ @param CMDID - Command word ID
+ @note Can enter wake-up state through ID-1 in I2C mode
+ '''
+ DF2301Q.play_by_CMDID(CommandWord.HelloRobot) # Common word ID
+
+def loop():
+ CMDID = DF2301Q.get_CMDID()
+ if CMDID != 0:
+ print("CMDID = %u\n" % CMDID)
+ time.sleep(1)
+
+if __name__ == "__main__":
+ setup()
+ while True:
+ loop()