Notifications
Clear all

Emergency Stop System Logic - Motor Control Board  

Page 1 / 6
  RSS

DroneBot Workshop
(@dronebot-workshop)
Workshop Guru Admin
Joined: 1 year ago
Posts: 627
2020-04-23 6:25 pm  

I wanted to explain how the Emergency Stop system functions.

The Emergency Stop signals can originate from any of six different sources:

  • From the I/O Node boards, via the I/O Distribution board. There are four of these.
  • From the Arduino Mega 2560.
  • From a momentary-contact pushbutton switch on the Motor Controller board.

 

On the Motor controller board, there are actually seven inputs to the ATMega328's that are used for the Emergency Stop.  The connections to both microcontrollers are paralleled.

  • All six of the above signals are routed to individual inputs on the ATMega328's.
  • One signal is a "combined signal" and is routed to the INT1 input on each ATMega328.

 

The combined signal is created using a 74LS11 Triple 3-Input AND gate, as illustrated below:

EM Stop.001

 

The logic operates as follows:

  • All Emergency stop inputs are active-low, in other words, the signal needs to go LOW to activate the Emergency Stop.
  • The inputs are all pulled HIGH with 10k resistors. In the actual implementation, these are part of a SIP resistor array.
  • The output of the logic circuitry will remain HIGH unless any one of the inputs goes LOW.
  • The connections from the six Emergency Stop inputs to the ATMega328's are not illustrated here, so just keep in mind that they are there.

 

Note that on the actual 6-conductor cables that route the connections from the four I/O Node boards the signal is active-high. A 74LS14 Hex Inverter Schmitt Trigger on the I/O Distribution board inverts the signal and removes any noise on the line, to prevent false triggering.

Logically, the code on each motor controller ATMega328 does the following:

  • An Interrupt is generated if the INT1 input goes LOW.
  • This event calls an interrupt service routine.
  • The interrupt service routine (ISR) queries the six inputs that are tied to the individual Emergency Stop inputs, to determine which one caused the interrupt.
  • If none of the six inputs are low it will be assumed that this was a false alarm and the ISR will exit without stopping the motor.
  • If one of the six inputs is LOW then it is a valid signal, and the motor is stopped.
  • The results are made available to the Arduino Mega 2560 via the I2C connection (remember, the ATMega328's are both operating as I2C slaves).

 

It might be necessary to add some electrical debouncing circuitry to the pushbutton switch input, but I'm hoping that can just be accommodated in software. I am currently testing this, and once I've determined the answer I can finish the motor controller board schematics for you.

😎

Bill

 

 

"Never trust a computer you can’t throw out a window." — Steve Wozniak


mbogelund liked
Quote
starnovice
(@starnovice)
Estimable Member
Joined: 1 year ago
Posts: 169
2020-04-23 7:40 pm  

@dronebot-workshop One of the issues I have with the emergency stop is if it gets triggered while the controller is in the middle of accelerating up to a particular speed.  Then the interrupt will occur and set the PWM to zero but when the interrupt ends the acceleration routine will set the motor to the next PWM it is accelerating too.  I know your code has the motorStatus variable.  I guess it is critical for the interrupt to set that variable and for all routines that deal with changing the PWM check it just before issuing a PWM command.  If it is set (I think originally you suggested 8 or 9) then the routine should just exit and the controller return to main loop waiting for the next command.

Pat Wicker (Portland, OR, USA)


ReplyQuote
DroneBot Workshop
(@dronebot-workshop)
Workshop Guru Admin
Joined: 1 year ago
Posts: 627
2020-04-23 10:09 pm  

@starnovice

If an Emergency Stop is initiated the intention is for the controller to stop both motors and cancel the current command. It then waits for the Arduino Mega to send a command to clear the emergency stop condition. 

It will not resume where it left off before the stop was initiated, it will remain stopped until another set of commands are received.

Does that make sense?

"Never trust a computer you can’t throw out a window." — Steve Wozniak


ReplyQuote
starnovice
(@starnovice)
Estimable Member
Joined: 1 year ago
Posts: 169
2020-04-23 10:28 pm  

@dronebot-workshop Yes the intent makes sense but you are still in the middle of a function call executing the last command and some how that function has to detect the stop and abort.  There is no other provision for cancelling that function.

Pat Wicker (Portland, OR, USA)


ReplyQuote
byron
(@byron)
Reputable Member
Joined: 1 year ago
Posts: 353
2020-04-23 11:46 pm  

@starnovice

If I understand correctly you are indicating that an interrupt will, well, interrupt your flow of code briefly and then your code will commence right at the point where it was interrupted.  Indeed that is what I would understand.  One could think of some options, but I though I would google to see what others may have done and I came across a thread on the Arduino site that appears to discuss this very issue, with some suggested ways to proceed.

https://forum.arduino.cc/index.php?topic=399548.0

I hope this helps and do let us know how you intend to structure your code so that you don't go straight back to the point where your code was interrupted. 


ReplyQuote
starnovice
(@starnovice)
Estimable Member
Joined: 1 year ago
Posts: 169
2020-04-24 12:55 am  

@byron Your reference explains very well the problem.  In a non-real time operating system like Arduino IDE there is no way to not go back to way you left off. 

The particular case I have run into is if movePWM has an acceleration value then it issues several PWM changes to the motor as it accelerates.  If it is interrupted in the middle, even though the motor will have been set to zero PWM, it will reset it to a new PWM.  If you use an if statement to check for the motorStatus (which should be "E-Stop") there is still the chance the interrupt will occur between the if statement and the setPWM statement.

Some of the possible solutions I was thinking of are:

1. use FreeRTOS a real time library for Arduino IDE that defines functions as tasks.  Then the interrupt routine can check for an existing task and kill it.

2. Use the motorStatus variable frequently.  The interrupt would set it to "E-Stop" and the interrupted function would be responsible for checking it frequently. particularly before issuing any PWM changes.  This is not 100% reliable because there can always be edge cases that slip by but it may minimize the damage.

3. Maybe someone has written a library for mutexes that can be used?

 

Pat Wicker (Portland, OR, USA)


ReplyQuote
byron
(@byron)
Reputable Member
Joined: 1 year ago
Posts: 353
2020-04-24 1:11 am  

@starnovice

How about a brute force approach.  The interrupt is coded to reset the Arduino.  The Arduino program always starts with an error flag that will only allow the code to proceed (at step 1) when cleared.  Some sort of  button is pushed to signal the clearing of the flag.

Thats all my inspiration for today as its way passed my bedtime, but I'll probably now dream of wayward robots.  Goodnight and sweet dreams 🤨  


ReplyQuote
starnovice
(@starnovice)
Estimable Member
Joined: 1 year ago
Posts: 169
2020-04-24 3:02 am  

@byron Interesting approach, I don't know if you can reset the Arduino from within Arduino code.

Pat Wicker (Portland, OR, USA)


ReplyQuote
robotBuilder
(@robotbuilder)
Honorable Member
Joined: 1 year ago
Posts: 502

ReplyQuote
byron
(@byron)
Reputable Member
Joined: 1 year ago
Posts: 353
2020-04-24 6:37 am  

@starnovice

As @casey link shows a restart appears to be possible programatically.  As I was dropping off last night I did also wonder if, in an emergency situation, power should be cut off to the motors by tripping a circuit breaker which could trip as a result of a signal from the arduino.  I don't know about the electronic circuit to achieve this though.

 


ReplyQuote
starnovice
(@starnovice)
Estimable Member
Joined: 1 year ago
Posts: 169
2020-04-24 8:06 am  

@byron While I see how this is possible it is a little drastic.  We are only talking about a short term stop, like when an ultra sonic sensor detects we are about to collide with something.  We want to stop quickly until we can calculate a new direction to move to.

Pat Wicker (Portland, OR, USA)


ReplyQuote
byron
(@byron)
Reputable Member
Joined: 1 year ago
Posts: 353
2020-04-24 11:13 am  

@starnovice

Cutting the power is overdoing it for navigation changes.  I was thinking of my foxbot where I have got to the stage of pausing the motors on alert conditions, but, as I'm hoping a scaled up version will be let loose in my field, I was minded I had not yet got any emergency stop procedures sorted out yet.

For my test code on a mini bot I am using a polu motor shield for a arduino uno.  This is controlled by a polu supplied library and my code issues commands to move the motors at a speed, forward or reverse, by sending a range of +400 to -400 to indicate the speed and direction of the motors.   When the command is issued it is, in human terms, acted upon instantly.  So I can issue a command +400 for full speed ahead followed by 0 an instant later to halt the motors.  The supplied library ramps up the PMW to full and back to 0 meaning the robot may just twitch.   As I thought this would be a bit drastic especially if its given a command +400 followed in  short order to go -400 I programmed in a change delay.  All new speed and direction values are compared to the current value and the actual change to the new value is made in incremental steps with a small delay after each change. (actually the incremental steps jumps from just 1 to jump from +-50 to +-50 in one step as my motors are not responsive for these smaller values).  After each incremental step change a 'stop flag' check is made and if a stop condition is found then the motor library is sent a 0 to indicate stop.  This works instantly.   

So that was probably a bit of a long winded way to say your option 2 - check a variable frequently would imho be the way to go.  If your function to ramp up the PMW carried this check with the timeframe you devise, and brought the PMW to 0 if necessary I think that you will find your robot will stop immediately.

This post was modified 6 months ago by byron

ReplyQuote
byron
(@byron)
Reputable Member
Joined: 1 year ago
Posts: 353
2020-04-24 12:05 pm  

@starnovice

after a short reflection, I suggest your PMW function simply sets the value according to a scale, like the polu library does in the example I gave (+400 to -400).  Its the function that calls the PMW setting function in terms your value scale that is responsible for the incremental calling of this function and checking the stop flag.  I'm saying this as I'm minded of your comment:

Posted by: @starnovice

This is not 100% reliable because there can always be edge cases that slip by

So let the PMW function complete but if its called in small steps and then I don't see a case for it not being 100% reliable (but I am limited 😎), and I don't think the very small time delay difference will make any practical difference to stopping your bot.


ReplyQuote
DroneBot Workshop
(@dronebot-workshop)
Workshop Guru Admin
Joined: 1 year ago
Posts: 627
2020-04-24 1:03 pm  

Thank you all, some great points raised here, I appreciate the input.

Before I respond to some individual points, which I will do. a bit later this morning, I want to propose that we put theory to the test.

To that effect, I've drawn up a simple schematic that you can throw together with an Arduino.  Those who have the existing Arduino Nano arrangement can also play along, just change the PWM pin in code. The hookup I have illustrated here uses the same pins as the "Version 2" motor controller.

EM Stop Exp01 jpg.001

 

I'm showing it with the Cytron controller and the gearmotor that DB1 uses (as I'll be testing mine on DB1), but any H-Bridge and motor could work for the experiment. You could even use an L298N and one of those yellow 6-volt motors to test with.

  • The PWM output is pin 11 (on the Nano design it was pin 10)
  • The Direction output pin 12 (the Nano is identical)
  • INT 1 is pin 3
  • Digital I/O pins 8 & 9, and A0-A3 setup as digital inputs, are for the individual Emergency Stop inputs

 

I haven't shown the 74LS11, but you could use the earlier diagram to wire it in if you wish. For the initial tests, we can probably get by without it, although I plan on hooking it up on my test.

I also haven't shown the INT0 connection to the rotary encoder on the motor.

All the connections can be referenced to the Google Doc that I shared a few days ago.  Look at the chart at the end of the document.

I'll need to clear off the 2nd workbench and wire this up now, and I'll post once it's ready to test.

Also, I'm pretty sure that some of you have advanced the code beyond what I originally posted, so if you could post or link to any updates you've made that would be great. Otherwise, I'll use the original as a base, and I'll get whatever code we start experimenting with onto GitHub so we can all work on it.

😎

Bill

"Never trust a computer you can’t throw out a window." — Steve Wozniak


ReplyQuote
starnovice
(@starnovice)
Estimable Member
Joined: 1 year ago
Posts: 169
2020-04-24 2:58 pm  

@dronebot-workshop I'll try to get my code posted to github soon.  The problem is I have not used github in the past so there might be a bit of a learning curve.  For the mega my code has provisions for reading cmds from the serial terminal for testing, from an IR controller, and from a PS2.  These are just test cases, the final version wouldn't need all of this.

I pretty much took all of your code, by going through you video frame by frame, and then implemented the acceleration and deceleration for each of the commands you suggest.  I did add one command "Rotate" to make it easier for rotation.

Pat Wicker (Portland, OR, USA)


ReplyQuote
Page 1 / 6