我正在使用电容传感器来检测物体。传感器需要 24V 才能运行,但 ESP32 的运行电压为 2.2 至 3.6V。传感器的输入也将是 24V。所以我不能直接将传感器连接到ESP32,这会损坏我的ESP32。为此,我使用了继电器,将传感器与继电器连接,并将继电器与 ESP32 连接。
传感器的输出线和传感器的负极线与继电器线圈连接。
我使用 ESP32 的 25pin 作为输出,34pin 作为输入。
25pin接继电器12口,常闭接4口,常开接8口,34pin接8口。
当传感器检测到某些东西时,传感器灯会亮起。 ESP32 的 LED 也亮起,并在串行监视器上打印“Detected”,并且传感器灯、LED 保持亮起并连续打印“Detected”,直到物体与传感器接触。
但是当有物体时,传感器的灯保持关闭状态。但有时即使没有物体,LED 也会亮起并且“检测到”开始在串行监视器上打印。 另外,如果我从继电器(8 端口)上移除输入引脚(34 引脚)。有时它会打印“已检测到”并且 LED 也会亮起。
首先我声明引脚为数字,现在我声明引脚为模拟。
但结果仍然相同,但现在我通过添加 10 个传感器的输入并将总和除以 10 来归档数据。这工作得很好,但有时仍然会出现相同的问题。我想我已经清除了 ESP32 的缓冲区来解决这个问题。我不知道如何清除缓冲区。或者使用 millis() ?
代码如下:
const int input=34;
const int output=25;
const int led=2;
void setup() {
pinMode(input,INPUT);
pinMode(output,OUTPUT);
pinMode(led,2);
Serial.begin(300);
digitalWrite(output,HIGH);
}
void loop() {
int detect=0;
for(int i=0;i<10;i++){
detect+=analogRead(input);
}
detect=detect/10;
if(detect>4000){
Serial.println("Detected");
digitalWrite(led,HIGH);
detect=0;
}
else{
Serial.println("Not Detected");
digitalWrite(led,LOW);
detect=0;
}
}
确定您的硬件是否正确不在本网站范围内,但继电器是高或低的数字状态开关;因此通过模拟输入读取它没有什么意义。
您之前未使用数字输入进行的尝试更令人感兴趣,但是您在这两种情况下遇到的问题几乎肯定是由于开关反弹造成的。既然您提到了继电器线圈,很明显您没有使用固态继电器,因此它将受到开关反弹的影响。
开关弹跳是机电触点的一个问题,当触点打开或关闭时,电压会在短时间内发生变化。开关弹跳状态更改的时间和轮询开关可能会导致读取不正确的状态 - 特别是在您实施状态更改检测时。
要解决此问题,您的软件必须实现“去抖动”算法。一种简单的方法是对任何状态变化添加时间戳,然后在足够的时间过去,任何开关反弹都已稳定时接受该状态(20-30 毫秒通常就足够了)。
例如:
void loop()
{
// Debounce time in milliseconds
static const int DEBOUNCE_MS = 30 ;
// Initial state
static int proximity_detect_state = digitalRead( input ) ;
// Force state change of first iteration
static int previous_proximity_detect_state = !proximity_detect_state ;
// Debounce timestamp and state
static unsigned long state_change_timestamp = 0;
static bool debouncing = false ;
// Get input state and time
int input_state = digitalRead( input ) ;
int now = millis() ;
// Debounce input...
if( input_state != proximity_detect_state )
{
// State changed, timestamp it.
state_change_timestamp = now ;
debouncing = true ;
}
else if( debouncing &&
now - state_change_timestamp > DEBOUNCE_MS )
{
// Steady state for debounce period, accept it as a new state
proximity_detect_state = input_state ;
}
// On change of debounced state...
if( proximity_detect_state != previous_proximity_detect_state )
{
previous_proximity_detect_state = proximity_detect_state ;
if( proximity_detect_state != 0 )
{
Serial.println( "Detected" ) ;
digitalWrite(led,HIGH);
}
else
{
Serial.println("Not Detected");
digitalWrite(led,LOW);
}
}
}
上面的
// On change of debounced state...
部分只是为了防止串口连续输出。反复旋转 LED 状态是良性的,因此如果没有串行输出,则不需要 previous_proximity_detect_state
,您可以简单地拥有:
digitalWrite( led, proximity_detect_state ? HIGH : LOW ) ;
代替整个街区。