You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python的Ultrasonic Sensor、DC Motor与SW420并行运行方案咨询

Parallel Execution for Ultrasonic Motor Control + SW420 Collision Detection

Hey there! Let's figure out how to get your two system modules running in parallel—this collision avoidance + incident detection setup is a cool project. Since you already have working code for each part, we just need to integrate them so they can run simultaneously. Here are the most practical approaches based on common microcontrollers:

1. Use Real-Time Operating System (RTOS) Tasks (Best for ESP32/STM32)

If you're using an MCU that supports FreeRTOS (like ESP32), splitting your code into two independent tasks is the cleanest way to handle parallel operations. Each task runs its own logic without blocking the other.

Example Code Structure:

// Include necessary headers
#include <Arduino.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

// Define pins and global variables
#define ULTRASONIC_TRIG 2
#define ULTRASONIC_ECHO 3
#define MOTOR_PIN 5
#define SW420_PIN 4

bool collisionDetected = false;

// Task for ultrasonic distance checking and motor speed adjustment
void ultrasonicMotorTask(void *parameter) {
  while(1) {
    // Your existing ultrasonic distance detection code here
    digitalWrite(ULTRASONIC_TRIG, LOW);
    delayMicroseconds(2);
    digitalWrite(ULTRASONIC_TRIG, HIGH);
    delayMicroseconds(10);
    digitalWrite(ULTRASONIC_TRIG, LOW);
    long duration = pulseIn(ULTRASONIC_ECHO, HIGH);
    int distance = duration * 0.034 / 2;

    // Your existing motor speed adjustment logic here
    if(distance < 30) {
      analogWrite(MOTOR_PIN, 100); // Slow down motor
    } else {
      analogWrite(MOTOR_PIN, 255); // Full speed
    }

    vTaskDelay(pdMS_TO_TICKS(50)); // Small delay to avoid spamming
  }
}

// Task for SW420 collision detection
void collisionTask(void *parameter) {
  while(1) {
    // Your existing SW420 detection code here
    int sw420State = digitalRead(SW420_PIN);
    if(sw420State == HIGH && !collisionDetected) {
      collisionDetected = true;
      // Your display logic for accident result here
      Serial.println("Accident detected!");
      // Optional: Stop motor or take other emergency actions
      analogWrite(MOTOR_PIN, 0);
    }

    vTaskDelay(pdMS_TO_TICKS(10)); // Check frequently for collisions
  }
}

void setup() {
  Serial.begin(115200);
  // Initialize pins
  pinMode(ULTRASONIC_TRIG, OUTPUT);
  pinMode(ULTRASONIC_ECHO, INPUT);
  pinMode(MOTOR_PIN, OUTPUT);
  pinMode(SW420_PIN, INPUT);

  // Create tasks
  xTaskCreate(ultrasonicMotorTask, "Ultrasonic-Motor", 2048, NULL, 1, NULL);
  xTaskCreate(collisionTask, "Collision", 2048, NULL, 2, NULL); // Higher priority for collision
}

void loop() {
  // Main loop can be empty since tasks handle everything
  vTaskDelay(pdMS_TO_TICKS(1000));
}
  • The collision task has a higher priority so it responds immediately when an impact happens, even if the ultrasonic task is running.
  • Adjust the task stack size and delay times based on your hardware needs.

2. Hardware Interrupts + Non-Blocking Main Loop (Good for Arduino Uno/Nano)

If you're using an 8-bit MCU like ATmega328P (Arduino Uno), RTOS might be overkill. Instead, use a hardware interrupt for the SW420 sensor (since collisions are sudden events) and keep your ultrasonic/motor logic non-blocking in the main loop.

Example Code Structure:

#define ULTRASONIC_TRIG 2
#define ULTRASONIC_ECHO 3
#define MOTOR_PIN 5
#define SW420_PIN 4

bool collisionDetected = false;
unsigned long lastUltrasonicCheck = 0;
const long ultrasonicInterval = 50; // Check every 50ms

// Interrupt service routine (ISR) for SW420
void collisionISR() {
  collisionDetected = true;
}

void setup() {
  Serial.begin(9600);
  pinMode(ULTRASONIC_TRIG, OUTPUT);
  pinMode(ULTRASONIC_ECHO, INPUT);
  pinMode(MOTOR_PIN, OUTPUT);
  pinMode(SW420_PIN, INPUT_PULLUP); // Use internal pull-up if needed

  // Attach interrupt to SW420 pin (trigger on HIGH or LOW depending on your sensor)
  attachInterrupt(digitalPinToInterrupt(SW420_PIN), collisionISR, RISING);
}

void loop() {
  // Handle collision detection first if triggered
  if(collisionDetected) {
    Serial.println("Accident detected!");
    analogWrite(MOTOR_PIN, 0); // Stop motor
    // Add your display logic here
    collisionDetected = false; // Reset after handling, or leave true if you want to keep displaying
    delay(2000); // Optional: Wait before resuming (adjust as needed)
  }

  // Non-blocking ultrasonic and motor control
  unsigned long currentMillis = millis();
  if(currentMillis - lastUltrasonicCheck >= ultrasonicInterval) {
    lastUltrasonicCheck = currentMillis;

    // Your ultrasonic distance code
    digitalWrite(ULTRASONIC_TRIG, LOW);
    delayMicroseconds(2);
    digitalWrite(ULTRASONIC_TRIG, HIGH);
    delayMicroseconds(10);
    digitalWrite(ULTRASONIC_TRIG, LOW);
    long duration = pulseIn(ULTRASONIC_ECHO, HIGH);
    int distance = duration * 0.034 / 2;

    // Your motor speed adjustment
    if(distance < 30 && !collisionDetected) {
      analogWrite(MOTOR_PIN, 100);
    } else if(!collisionDetected) {
      analogWrite(MOTOR_PIN, 255);
    }
  }
}
  • The ISR triggers instantly when the SW420 detects a collision, so your system responds without delay.
  • We use millis() instead of delay() in the main loop to keep the ultrasonic/motor logic non-blocking.

3. Non-Blocking Polling (Simplest for Small MCUs)

If interrupts aren't an option, you can run both modules in the main loop using non-blocking code. This works as long as neither function uses delay() (replace with millis() timing).

Example Logic:

// Define variables for timing
unsigned long lastUltrasonicTime = 0;
unsigned long lastCollisionCheck = 0;
const int ultrasonicDelay = 50;
const int collisionDelay = 10;

void loop() {
  unsigned long now = millis();

  // Check ultrasonic and adjust motor if enough time has passed
  if(now - lastUltrasonicTime >= ultrasonicDelay) {
    lastUltrasonicTime = now;
    runUltrasonicMotorLogic(); // Your existing code wrapped in a function
  }

  // Check SW420 for collision
  if(now - lastCollisionCheck >= collisionDelay) {
    lastCollisionCheck = now;
    checkCollision(); // Your existing collision detection code wrapped in a function
  }
}
  • This approach makes the main loop cycle quickly, so both modules get frequent attention.
  • Make sure runUltrasonicMotorLogic() and checkCollision() don't include any blocking delays.

Scenario Example:

When your vehicle is running normally, the ultrasonic/motor task runs continuously, adjusting speed based on distance. If a side collision hits, either the high-priority RTOS task, the hardware interrupt, or the frequent collision check will immediately detect it, trigger the accident display, and can stop the motor if needed—all without interrupting the ultrasonic logic (though in practice, you'll likely want to halt motor control after a collision).

内容的提问来源于stack exchange,提问作者Rishabh Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:34:28