element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
    About the element14 Community
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      •  Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
EZ-EV Challenge
  • Challenges & Projects
  • Design Challenges
  • EZ-EV Challenge
  • More
  • Cancel
EZ-EV Challenge
Forum SmartAssist EV - Strict Priority Hierarchy with Tactile Mechanical Bumpers - Part 6
  • News
  • Projects
  • Forum
  • DC
  • Leaderboard
  • Files
  • Members
  • More
  • Cancel
  • New
Join EZ-EV Challenge to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • Replies 0 replies
  • Subscribers 60 subscribers
  • Views 24 views
  • Users 0 members are here
Related

SmartAssist EV - Strict Priority Hierarchy with Tactile Mechanical Bumpers - Part 6

jelektro
jelektro 6 hours ago
Ultrasonic sensors can miss low-profile objects, clear glass, or acoustic-absorbing fabrics. To handle these blind spots, we add physical Tactile Bumper Switches (CollisionPin_L, CollisionPin_R) as a final layer of defense.To manage all these inputs, the code uses a Strict Priority Hierarchy inside the core runtime evaluation loop:Priority 1 (Highest): Tactile Impact Check. If a physical collision is registered, the robot stops everything, backs up, and executes a wide turning maneuver.Priority 2 (Medium): Ultrasonic Proactive Clearance. If an object is detected within 30cm, the robot performs a quick corrective turn to avoid an accident.Priority 3 (Lowest): Standard Path Following. If both safety systems report a clear path, the robot continues tracking the line.
The full software build adds tactical mechanical bumper microswitches routed to pins A4 (18) and A5 (19). This program runs a rigorous hierarchy matrix: physical bumper triggers grab immediate absolute priority (initiating multi-second reversing maneuvers), sonar triggers handle medium-priority non-contact adjustments, while line following proceeds only when both safety nets report a clear path. 
Here is the final, production-ready source architecture merging all four functional modules:


#include <Arduino.h> #include <IRremote.hpp> // --- COMPREHENSIVE HARDWARE PIN CONFIGURATION --- const int motorPinA_1A = 5; const int motorPinA_1B = 6; const int motorPinB_1A = 9; const int motorPinB_1B = 10; const int IR_RECEIVE_PIN = 2; const int trigPin = 4; const int echoPin = 3; // Physical Tactile Bumpers (Mapped to available analog pins working as digital inputs) const int CollisionPin_L = 18; // Pin A4 const int CollisionPin_R = 19; // Pin A5 // Line Tracking Photo-interrupters const int TrackingPin_L = A2; const int TrackingPin_R = A3; enum RobotMode { MODE_MANUAL, MODE_AUTONOMOUS }; RobotMode currentMode = MODE_MANUAL; const int motorSpeed = 200; int spd = 195; // Specific heavy escape/evasive speed vector int trackSpeed = 200; unsigned long lastCommandTime = 0; const unsigned long commandTimeout = 250; void motor(int A1, int A2, int B1, int B2) { analogWrite(motorPinA_1A, A1); analogWrite(motorPinA_1B, A2); analogWrite(motorPinB_1A, B1); analogWrite(motorPinB_1B, B2); } float getDistance() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); long duration = pulseIn(echoPin, HIGH, 30000); float d = duration * 0.0343 / 2; if (d == 0) return 999.0; return d; } void exec_cmd(byte key_val) { switch (key_val) { case 0x1C: if (currentMode == MODE_MANUAL) { currentMode = MODE_AUTONOMOUS; Serial.println("System Notification: AUTONOMY MODE ENGAGED."); } else { currentMode = MODE_MANUAL; motor(0, 0, 0, 0); Serial.println("System Notification: MANUAL OVERRIDE ENGAGED."); } break; case 0x18: if (currentMode == MODE_MANUAL) motor(0, motorSpeed, 0, motorSpeed); break; case 0x08: if (currentMode == MODE_MANUAL) motor(motorSpeed, 0, 0, motorSpeed); break; case 0x5A: if (currentMode == MODE_MANUAL) motor(0, motorSpeed, motorSpeed, 0); break; case 0x52: if (currentMode == MODE_MANUAL) motor(motorSpeed, 0, motorSpeed, 0); break; default: if (currentMode == MODE_MANUAL) motor(0, 0, 0, 0); break; } } void setup() { Serial.begin(9600); // pinMode(motorPinA_1A, OUTPUT); // pinMode(motorPinA_1B, OUTPUT); // pinMode(motorPinB_1A, OUTPUT); // pinMode(motorPinB_1B, OUTPUT); IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); // Initialize switches using internal pullups (Switches must connect directly to GND) pinMode(CollisionPin_L, INPUT_PULLUP); pinMode(CollisionPin_R, INPUT_PULLUP); pinMode(TrackingPin_L, INPUT_PULLUP); pinMode(TrackingPin_R, INPUT_PULLUP); Serial.println("System Core Ready."); } void loop() { if (IrReceiver.decode()) { byte command = IrReceiver.decodedIRData.command; exec_cmd(command); if (currentMode == MODE_MANUAL) lastCommandTime = millis(); IrReceiver.resume(); } if (currentMode == MODE_MANUAL) { if (millis() - lastCommandTime > commandTimeout) { motor(0, 0, 0, 0); } } else if (currentMode == MODE_AUTONOMOUS) { float distance = getDistance(); // Evaluate binary conditions of active bumper connections int sumVal = (digitalRead(CollisionPin_L) == LOW ? 1 : 0) * 2 + (digitalRead(CollisionPin_R) == LOW ? 1 : 0); // --- HIERARCHY LEVEL 1: Absolute Physical Impact Interception (Bumpers) --- if (sumVal > 0) { Serial.print("TACTILE COLLISION TRIGGERED. Code: "); Serial.println(sumVal); if (sumVal == 1) { // Right-side crash -> Back up, then pivot left motor(spd, 0, spd, 0); delay(2000); motor(spd, 0, 0, spd); delay(2000); } else if (sumVal == 2) { // Left-side crash -> Back up, then pivot right motor(spd, 0, spd, 0); delay(2000); motor(0, spd, spd, 0); delay(2000); } else if (sumVal == 3) { // Frontal center crash -> Back up, then pivot left motor(spd, 0, spd, 0); delay(2000); motor(spd, 0, 0, spd); delay(2000); } } // --- HIERARCHY LEVEL 2: Medium Proactive Clearance Monitoring (Sonar) --- else if (distance < 30) { motor(motorSpeed, 0, 0, motorSpeed); // Fast defensive evasion left delay(300); } // --- HIERARCHY LEVEL 3: Standard Path Routine (Line Following) --- else { int trackL = digitalRead(TrackingPin_L); int trackR = digitalRead(TrackingPin_R); int Track = trackL * 2 + trackR; if (Track == 0) motor(0, 0, 0, 0); else if (Track == 1) motor(0, trackSpeed, trackSpeed, 0); else if (Track == 2) motor(trackSpeed, 0, 0, trackSpeed); else if (Track == 3) motor(0, trackSpeed, 0, trackSpeed); delay(10); } } }
  • Sign in to reply
  • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube