Don't let go. How to approach?

Hey everyone.

I'm looking for a little advice.

I'm building a prop to be used in paintball and airsoft games that will act as a clingy hostage. Essentially a box with 3Leds, a power switch, a piezo, and 2 metal plates acting as touch switches.

When picked up and touched on both plates it arms
Once armed it cannot be placed down and beeps and flashes once every 5 sec to let u know its armed
If you let go it will flash and beep for 20sec
10sec of 1beep/sec
5sec of 2beep /sec
5sec of 4beep /sec

If you pick it up again it will return to its armed state
If it times out all the LEDs will flash and it will give a continuos sound from the piezo

I'm fairly confident I have figured out how to hook up my touch ICs, LEDs and piezo efficiently but I'm looking for some advice on how to approach the coding

I have a basic knowledge and can manage to rad and write to pins and store the requires variable but I'm not sure the best way to get the Arduino to count down and interrupt the count if the switches are closed again.

I have an Arduino UNO to prototype this project, if anyone could give me some advice it would be greatly appreciated.

Thanks

Will it have a Stockholm Syndrome mode?

I suppose if the players that had it where acting as the captors rather than the rescuers then it already does :slight_smile:

On another note, would I maybe be best using the switches with the interup function on pin 2 and 3 (I think).
Write each mode as a separate function and have haughty and low interupts switch between them?
Would that work?

Will it look like Patty Hearst?

Basically this thing seems to be either doing nothing, or beeping 1/s, 2/s, 4/s or continuously.
In your loop you could have a state variable to say which of the above modes it is in.
You could use interupts or you could just poll (read) your inputs in the loop.
millis() can be used as a timer.

No, I don’t think interrupts are necessary.

I'll have a go at coding something and see where I get.
I was contemplating putting the switch inputs through an AND gate in order to elimates the need to check what state both switches are in.
Leaving just a single input that would be high if both are closed and low in and other situation. Worth my while or deal with in code?

External soldering and components vs. a couple of lines of code?
No brainer

I'll have a go at coding something and see where I get.

Don't program everything at once, you get a load of code and have no idea why it does not work.
Build the code step at a time, with some prints in there so that you know it is doing what you think.

That way your program always works all of the time.
If it stops working it is the last thing that you did which is wrong or you are not understanding.

It is simpler if you don't use interrupts.

No need for interupts. Look at the ‘blink without delay’ example to see how to do it.

How about a red 7 segment display showing time remaining.
<I know. I’ve seen too many movies…> :smiley:

So how is it going?
I do think you should have a "Patty Hearst" function where the hostage co-operates.

Henry_Best:
<I know. I’ve seen too many movies…> :smiley:

It needs to beep, as well, so that we know it’s electronic.

PeterH:

Henry_Best:
<I know. I’ve seen too many movies…> :smiley:

It needs to beep, as well, so that we know it’s electronic.

And when the hero cuts the correct wire, the display will not go off but continue to show 00:01.

The "Hero" being the bomb squad?

Stick a GPS on it... if you go below 40mph kabooom (once activating over 40mph) lol

cjdelphi:
The "Hero" being the bomb squad?

Or any 'James Bond' type character.

Stick a GPS on it... if you go below 40mph kabooom (once activating over 40mph) lol

Why bother with GPS? Just connect it up to the speedo.

First of all, don't use interrupts. Nothing about this project requires interrupts, and they complicate debugging. Second, study the BlinkWithoutDelay example to learn how to time program events without using delay(), so that your code is non-blocking. Third, use state-tracking variables with case statements to handle necessary behaviors, such as:

const int stateNobodyAtTheDoor = 0;
const int stateSomebodyAtTheDoor = 1;
const int stateOpenedTheDoor = 2;
const int stateTheyCameIn = 3;

int state = stateNobodyAtTheDoor;

loop() {
  switch(state) {
  case stateNobodyAtTheDoor:
    boolean somebodyHasArrived = digitalRead(doorPresenceSensorPin) == LOW;

    if (somebodyHasArrived)
      state = stateSomebodyAtTheDoor;
    break;
  case stateSomebodyAtTheDoor:
    openTheDoor();
    state = stateOpenedTheDoor;
    break;
  case stateOpenedTheDoor:
    boolean somebodyCameIn = digitalRead(doorEntrySensorPin) == LOW;
    if (somebodyCameIn)
      state = stateTheyCameIn;
    break;
  case stateTheyCameIn:
    closeTheDoor();
    state = stateNobodyAtTheDoor;
  }
}

This example intentionally uses more states than are really necessary just to try to make the point. Also, this example is a purely linear track of states, whereas your example would have branches, such as, "If the warning was triggered and it has been ten seconds, start blinking faster, but if the hostage was picked back up, go back to the not-warning state."

Thanks for the advice guys.
Just actually got back around to working on this. Had quite a busy few weeks :confused:

Anyway. I ditched the touch switches for now and just stuck down a couple of momentary switches I had in a box for prototyping purposes and have opted jus to use the build in LED on pin 13 just now.

My progress so far is fairly limited as I'm still trying to learn.

Got everything hooked up,
figured out how to produce basic audio
Got the arduino to check the states of both buttons and light the led when both are pressed
Sent text to serial in order to monitor what it's doing.

Essentially basic hardware interfacing is sorted :slight_smile:

I've been trying to wrap my head around how I'm going to get it to do what I want though, and I seem to have got nowhere.
I've potter to star coding again from scratch in order to clear my though processes a little but I'm still a little stuck.

Can I write four separate procedures and call them up as required or is that essentially what the state tracking is?

UPDATE
i persevered and tried it this way. It’s not exactly elegant but seems to do what I need it to do

//set button inputs

const int button1Pin = 3; //set pin 3 as input 1
const int button2Pin = 2; //set pin 2 as input 2
const int ledPin =  13;   // the number of the LED pin
const int relayPin = 4;       //set pin for relay to fire pyro

//set Variables

int button1State = 0;
int button2State = 0;
int timer = 30;
int beeptime(1000);


void setup() {
  
  Serial.begin(9600);
  // put your setup code here, to run once:
pinMode (button1Pin, INPUT);
pinMode (button2Pin, INPUT);
pinMode (ledPin, OUTPUT);
pinMode (relayPin, OUTPUT);
}

void loop() {
 
  
  
  
 Standby: //standby label;
 
 digitalWrite(relayPin, HIGH);//reset relay
 
 
 // check if the pushbuttons are pressed.
  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
  
 //if both buttons are pushed move to calm state 
  if (button1State == HIGH && button2State ==HIGH) {
    goto calm;
  }
    
    else{goto Standby;
    }
    
    
    
    
    
 calm://calm state
 timer=30; //reset timer to 30s
 beeptime=1000; //reset beemtime to 1s
 digitalWrite(ledPin, HIGH); //flash led on     
 delay(500);
 digitalWrite(ledPin, LOW);  //flash ledoff 
 delay(500);
 
// check if the pushbuttons are pressed.
  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
 
 //if both buttons are pushed move to calm state 
  if (button1State == HIGH && button2State ==HIGH) {
    goto calm;
  }
    
    else{goto Panic;
    }
    
    
    
    
    
    
 Panic://panicked state
 
Serial.print(timer);// print current time to serial
Serial.print('\n');//new line

timer=timer--; //count down 1 sec

if (timer>10) {
  goto tone1;
}

if (timer<=10 && timer>5) {
  goto tone2;
}
if (timer<=5 && timer>0) {
  goto tone3;
}

if (timer<0) {
  goto detonation;
}

tone1://one beep per sec
tone(8,400,200);
delay(beeptime);
goto buttoncheck;

tone2://2beep per sec
beeptime=500;
tone(8,400,200);
delay(beeptime);
tone(8,400,200);
delay(beeptime);
goto buttoncheck;

tone3://4beep per sec
beeptime=250;
tone(8,400,200);
delay(beeptime);
tone(8,500,200);
delay(beeptime);
tone(8,400,200);
delay(beeptime);
tone(8,500,200);
delay(beeptime);
goto buttoncheck;

buttoncheck:
// check if the pushbuttons are pressed.
  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
 
 //if both buttons are pushed move to calm state 
  if (button1State == HIGH && button2State ==HIGH) {
    goto calm;
  }
    
    else{goto Panic;
    }


 
 
 
 
 detonation:
 digitalWrite(relayPin, HIGH);
 Serial.print("BANG! you're dead!");
 tone(8,600,3000);
 delay(2000);
 
 
 
}

MacGyverUK:
UPDATE
i persevered and tried it this way. It’s not exactly elegant but seems to do what I need it to do

Gotos (AKA spaghetti code) make your code hard to follow.
You have 4 states:

  1. standby
  2. calm
  3. panic
  4. detonation
    Define a variable (say state) and, in setup(), initialise it to 1.
    Now your loop() will be:
    switch(state){
    case 1: //do all your standby stuff here. If the correct sequence of switches is pressed
    state =2;
    break;
    case 2: //do all your calm stuff here. If the correct sequence of switches is pressed
    state =3;
    break;
    case 3: //etc., etc.

Thanks.
That makes a little more sense now.

First time I learned to code was BBC basic and GOTO was just the easiest way for me to go. :slight_smile:

it turns out of course, that "GOTO" is built into "if", "for", "while", "break" and so on. Nothing (practical) could ever function without it.

But that's the point - using those constructs orders the code.