Need help making a C4 prop for airsoft

I’ve been playing airsoft and wanted a C4 prop (think like in CounterStrike). Saw some using Arduino Nano and LCDs, but thought it would be cool if it would also blow up if you shake it while armed… so I decided to make it out of a Proffie. I went and actually designed and 3D printed the whole thing.




It uses a 3 button setup, a 20px WS2812 strip, and a 128x64 SSD1306 OLED. I’ve also put a TP4056 module straight to the battery so I don’t have to disassemble the device for charging it, but never showing the actual Proffie USB and SD. But I digress.

The way I want it to work is the following way:

  • Default state is turned off (a referee will physically power it up before each game).
  • The Power button (is a latching one) acts to turns it on.
    – Once it’s turned on, if you shake it, it might explode (this feature should stay in all modes save for Exploded Mode).
  • The red button is the Arm button. You have to keep it pressed for a certain time (default 20 seconds):
    – The pixel display should advance as a progress bar until fully armed.
    – The LCD should state “ARMING”, then “ARMED” and then start the timer.
  • This activate the Countdown mode:
    – The timer counts down until it reaches zero and goes into Explode mode.
    – The pixel should work as a percentage progress bar.
    – A “ticking” sound should play.
    – Once the countdown reaches 0, it goes into Exploded Mode.
  • Exploded Mode:
    – It plays the “explode” sound.
    – Mode stays in until power is recycled (to avoid tampering).
    – Display shows “EXPLODED”.
  • Green button is the Defuse action. You have to keep it pressed for a certain time (default 20 seconds).
    – The pixel display should advance as a progress bar until fully armed.
    – The timer should still keep the countdown and the ticking sound.
    – If the action takes longer than the countdown, it should still explode.
    – If you defuse before the countdown reaches 0, it should go into Defused Mode.
  • Defused Mode:
    – It plays the “defuse” sound.
    – Mode stays in until power is recycled (to avoid tampering).
    – Display shows “Defused”.
    – You still need to release the PowerButton to be able to move it (optional).

Sorry for the lengthy explanation, but this post also works as a design document. I know it will take a while for me to implement this prop, but I have a couple of questions.

  1. Is there a way to implement a global timer? Something that will keep ticking until reset? I’m not sure were to start, I guess I would create a timer object, use a sleep() function for ticks, add methods finish, pause and stop and reset? Then I should add something like an UpdateInterval to update the countdown display and the blade state?

  2. I know this a non-standard OLED size, but I guess I should define my own fonts? It should be pretty similar to the BulletCount code?

  3. If I want to change the “tick” pitch or tempo depending on the percentage of time left, I guess I should have tickNN.wav and change the pitch/length/volume progressively on a clash?

Thanks for any help.

Yes of course. However, it probably wouldn’t work as you describe.
In particular, sleep() is usually a function that doesn’t return until some time has passed, and if you do that in ProffieOS, everything halts, because ProffieOS is not threaded. In general, your timer will almost certainly just store a timestamp, and then you will poll and update the current state in Loop() to make things happen.

Updating the screen may be possible by just calling SaberBase::DoMessage(), if that’s not enough, then you would need to write a custom controller the screen which makes sure that the right thing is displayed.

It might be unusual, but ProffieOS already supports this size screen. You just get four rows of characters instead of two. If you want a larger font, you will need to use the fontconvert tool and add that to the code.

If you do it based on absolute times rather than percentages, there are easy ways to do it. Basically, you can have one LONG wav file (let’s say an hour) which has all the ticks in it. When it hits certain limits (5 minutes left, 1 minute, left, 10 seconds left) ticks increase in speed and intensity. Now all you have to do is to seek to “length of file in seconds - countdown time in seconds” and everything will work, right?

Alternatively, you would just control which sound is played directly from the prop, not sure why clash would be involved.

I’m happy to help answering questions and come up with bits of code that will help make this happen.

2 Likes