Grove interface
Grove is a standard embedded development kit connection interface definition.
What is Grove system
Grove is a modular standard connector prototype system. Grove uses building block assembly electronic technology. Compared with systems based on jumpers or soldering, it is easier to connect, test and build, and simplifies the learning system. The Grove system allows you to build a real system. Therefore, it requires some learning and professional knowledge to connect objects correctly.
The Grove system consists of a basic processing unit (trunk) and various modules (tree branches) with standardized connectors. The base unit (usually a microprocessor) allows easy connection of any input or output from the Grove module. Each Grove module can usually handle a single function, such as a simple button or a more complex heart rate sensor.
If the processing unit you are using does not have a Grove interface. You can use the Grove to Pin Header adapter cable to connect the pins of the Raspberry Pi or Arduino to the Grove module.
Of course, ODYSSEY-STM32MP157C provides two Grove interfaces, one is a digital Grove interface and the other is an I2C Grove interface. Users can quickly build project prototypes through these two Grove interfaces. I have compiled some Grove module information, and friends in need can click to buy.
factory | model | interface | link |
---|---|---|---|
Seeed | All-in-one Grove sensor kit | - | Click to buy |
Seeed | 1.12 inch OLED display module | I2C | Click to buy |
Seeed | 0.96 inch 12864 OLED display module | I2C | Click to buy |
Seeed | Green LED Grove Module | GPIO | Click to buy |
Seeed | White LED Grove Module | GPIO | Click to buy |
Seeed | Variable color LED Grove module | GPIO | Click to buy |
Seeed | Programmable RGB full color LED module | GPIO | Click to buy |
Quickly test Grove modules
It is very easy to test the Grove module on the ODYSSEY-STM32MP157C development board, because Seeed Studio has provided us with a Python-based Grove library ( https://github.com/Seeed-Studio/grove.py ). There are many test programs, including buttons, LEDs, display screens, motors and other modules.
But before using these libraries, we still need to do some work! If you have completed the environment setup in the previous section " [ODYSSEY-STM32MP157C] Environment Setup and System Operation ", then we can directly test the GPIO.
First, install Grove.py
sudo pip3 install Seeed-grove.py
Then, download the grove.py library source code
git clone https://github.com/Seeed-Studio/grove.py
Enter the grove directory and run the example
cd grove.py/grove
sudo python3 grove_gpio.py 5
At this point, if you plug in the Grove Kit expansion board and connect an IO module (such as LED lights, relays) to Grove port 5, you will see the LED lights flashing or the relay opening and closing actions.
Use Libgpiod library
In the spirit of diligence and frugality, I did not start with the Grove module, but used the ODYSSEY-STM32MP157C development board + the existing LED module to complete the experiment. Those who don’t have one, get in the car quickly~
How to operate GPIO without Grove library? The answer is-libgpiod library!
Starting from Linux 4.8, it is no longer recommended to use the sysfs interface (/sys/class/gpio) to operate GPIO. Instead, it is recommended to use character devices to operate in the user space. libgpiod is a library for operating GPIO character devices, and provides some Tools to facilitate developers to debug.
gpiodetect
—— List all gpiochips present on the system, as well as their names, labels and GPIO lines.gpioinfo
—— List all lines of the specified gpiochip, as well as their names, users, directions, activity status and other signs.gpioget
—— Read the value of the specified GPIO line.gpioset
—— Set the value of the specified GPIO line.gpiofind
—— Find the corresponding gpiochip and inline offset by name.gpiomon
—— Wait for the event on the specified GPIO line, or specify the event to be monitored.
E.g:
# gpiodetect
gpiochip0 [GPIOA] (16 lines)
gpiochip1 [GPIOB] (16 lines)
gpiochip2 [GPIOC] (16 lines)
gpiochip3 [GPIOD] (16 lines)
gpiochip4 [GPIOE] (16 lines)
gpiochip5 [GPIOF] (16 lines)
gpiochip6 [GPIOG] (16 lines)
gpiochip7 [GPIOH] (16 lines)
gpiochip8 [GPIOI] (16 lines)
gpiochip9 [GPIOZ] (16 lines)
Control LED blinking
I connected an LED module to GPIO_A14 (pin 7) of the 40-pin expansion interface , and GPIO_A14 corresponds to line 14 of gpiochip0. Therefore, the LED can be turned on and off by the following commands.
gpioset gpiochip0 14=1 # 高电平
gpioset gpiochip0 14=0 # 低电平
Therefore, we can write a shell script in this way to achieve the effect of LED flashing.
#!/bin/bash
while :
do
gpioset gpiochip0 14=0
sleep 0.5
gpioset gpiochip0 14=1
sleep 0.5
done
Run the shell script, the effect is as follows:
Realize the effect of breathing light
To achieve the effect of breathing light, DAC digital-to-analog conversion and PWM control are usually used . Of course, software PWM can also be implemented, but it is not a very good method in terms of operating efficiency. At the same time, since the STM32MP157C contains a Cortex-M4 core, we can implement the breathing light on the M4 side by completely using the STM32 MCU programming method.
It's the same LED module . This time I choose GPIO_A3 (pin 29). Because PA3 has a timer function, it can be set to PWM control output mode.
-
Open STM32CubeIDE, create a new project, select STM32MP157C chip.
-
Assign the PA3 pin to the Cortex-M4 core, configure PA3 to TIM2_CH4 mode, configure Timer2, and enable Channel 4, as shown in the figure below.
-
Then configure the TIM2 parameters. Since the frequency of the Timer is 64 MHz, the prescaler coefficient is set to 64-1, and the auto reload value is set to 1000-1. So the PWM frequency is 64,000,000 / 64/1000 = 1000 Hz.
-
Then, we can adjust the duty cycle (dutyCycle) of PWM in one cycle (for example, 1ms) to realize the breathing light effect. The main function code is as follows.
int main(void) { /* USER CODE BEGIN 1 */ uint16_t dutyCycle = 0; /* USER CODE END 1 */ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); if(IS_ENGINEERING_BOOT_MODE()) { /* Configure the system clock */ SystemClock_Config(); } /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM2_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4); /* USER CODE END 2 */ /* USER CODE BEGIN WHILE */ while (1) { while (dutyCycle < 1000) { dutyCycle++; __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, dutyCycle); HAL_Delay(1); } HAL_Delay(200); while (dutyCycle > 10) /* 为了效果好一点,我故意不让LED全灭 */ { dutyCycle--; __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, dutyCycle); HAL_Delay(1); } HAL_Delay(400); } }
-
Click the "hammer" in the toolbar of STM32CubeIDE to compile the project, and an elf file (such as led_CM4.elf) will be generated in the /CM4/Debug/ directory.
-
The newly generated file into ODYSSEY-STM32MP157C led_CM4.elf the
/lib/firmware
directory, and execute the following operation.echo led_CM4.elf > /sys/class/remoteproc/remoteproc0/firmware echo start > /sys/class/remoteproc/remoteproc0/state
At this point, the firmware on the Cortex-M4 side is already running! The effect of the breathing light is as follows: