Arduino IDE开发STM32 Nucleo-L073RZ水泵无法运行问题求助
STM32 Nucleo-L073RZ水泵不工作问题排查与修复
一、核心问题分析
引脚重复定义冲突
你将trigPin和buton1都定义为PA9,同一个引脚既做超声波触发输出,又做按钮输入,导致引脚功能混乱,按钮状态读取完全不可靠,这是水泵不响应的首要原因。距离变量未更新
distance变量没有任何赋值逻辑,始终保持初始值0,即便进入distance <=5分支,按钮读取失效也无法触发水泵动作。GPIO直接驱动水泵的硬件局限
STM32 GPIO引脚输出电流仅为mA级,水泵属于大电流感性负载,直接连接会烧毁引脚,且无法驱动水泵运转。
二、修复步骤
1. 修复引脚冲突
将按钮引脚替换为空闲GPIO(示例用PA0,可根据布线调整):
#define buton1 PA0 // 替换原PA9,避免与trigPin冲突
2. 补充超声波测距逻辑
在mainFunction开头添加测距代码,实时更新distance:
void mainFunction() { // 新增超声波测距逻辑 digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = duration * 0.034 / 2; // 转换为厘米 // 原有代码... }
3. 优化按钮输入稳定性
启用GPIO内部上拉电阻,避免浮空误判:
void setup() { // ...原有代码... pinMode(buton1, INPUT_PULLUP); // 替换原INPUT // ...原有代码... }
同时修改按钮判断逻辑(上拉模式下,按下按钮引脚为低电平):
if(digitalRead(buton1) == LOW) // 替换原==1 { // ...原有分支代码... }
4. 搭建水泵驱动电路
必须通过外部驱动电路连接水泵,推荐两种方案:
- 继电器模块:PC4接继电器控制引脚,继电器触点端连接水泵和匹配电压的电源。
- N沟道MOS管驱动:PC4通过1kΩ电阻接MOS管栅极,MOS管漏极接水泵一端,源极接地,水泵另一端接电源,同时并联1N4007续流二极管保护元件。
三、修复后完整代码
#include <LiquidCrystal.h> #define LCD_RS PB8 #define LCD_EN PB9 #define LCD_D4 PA8 #define LCD_D5 PB10 #define LCD_D6 PB4 #define LCD_D7 PA10 #define trigPin PA9 #define echoPin PA7 #define buton1 PA0 #define motor PC4 LiquidCrystal lcd( LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7 ); long duration, distance; void setup() { lcd.begin( 16, 2 ); lcd.print( "SENSORED WATER" ); lcd.setCursor( 3, 1 ); lcd.print( "DISPENSER" ); delay( 2000 ); lcd.clear(); pinMode( buton1, INPUT_PULLUP ); pinMode( motor, OUTPUT ); Serial.begin( 9600 ); pinMode( trigPin, OUTPUT ); pinMode( echoPin, INPUT ); } void mainFunction() { // 超声波测距逻辑 digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = duration * 0.034 / 2; Serial.print( "Button State: " ); Serial.println( digitalRead( buton1 ) ); lcd.print( "CHOOSE AMOUNT" ); lcd.setCursor( 0, 1 ); lcd.print( "TALL VENTI GRANDE" ); if( digitalRead( buton1 ) == LOW ) { if( distance <= 5 ) { lcd.clear(); lcd.print( "Filling started" ); digitalWrite( motor, HIGH ); delay( 5000 ); digitalWrite( motor, LOW ); lcd.clear(); } else { lcd.clear(); lcd.print( "BARDAK KOY LA!" ); delay( 2000 ); lcd.clear(); } } } void loop() { mainFunction(); }
内容的提问来源于stack exchange,提问作者Alp
相关产品推荐
相关产品推荐

