![]() |
Forum Index : Microcontroller and PC projects : Indoor RC tag combat and score board
Author | Message | ||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 5091 |
For our model airplane club I developed a tag combat system. In the summer, we fly larger model airplanes outside, but in winter time wind rain and temperature drive us indoor. We rent a sport hall, and fly with small light electric propelled airplanes. After having sufficient contact with walls, ceiling and floor, the planes look battered, and the pilots tired. To bring new energy in the indoor activity I decided to revive up a 10 year old (and never completed) project for indoor combat between airplanes. The game: pilots equip their plane with a small and light tag. The tag contains a IR sensor and IR emitter (the gun). A spare channel on the remote control receiver can be used to fire the IR gun. The IR receiver receives transmitted codes from competing IR guns (other planes). Some game parameters make the game exciting. When you are out of bullets, there is waiting time before you have new ammo. When you are deadly hurt, you cannot fire anymore. The tag remembers who shot you, and after combat you can list this. To practice shooting and aiming, a target is developed, based on a CMM1. It decodes IR pulses from the airplane tags, and creates a highscore list. These electronics have to be very light, the planes are below 200 gram. That is why was chosen for a 8 pin picaxe microcontroller. Example of the electronics on a plane ![]() The picaxe has embedded receiving and transmitting of SONY 12bit IR codes. Accidentally the CMM1 also supports these SONY codes. That eases the implementation of the system. Schematics of the tag (hand drawn sketch) ![]() The tag software (current version v0.5p) '------------------------------------------IR COMBAT --------------------------------------- 'it is a progam for IR combat with RC planes (indoor). Needed is a free channel on the receiver, 'that can be controlled from a FIRE button on the transmitter (i.e. the GEAR switch) 'Each plane has a IR tag, that fires IR pulses under command of the FIRE button, and an IR receiver, 'that senses competitors gun fire. Each plane has XX bullets to fire and can handle YY hits before 'it is destroyed. Each plane has a unique ID. 'Refil of ammunition can happen in 2 ways. '1/ landing, and keeping throttle at minimum for 5 successive seconds. The tag must be connected 'with the throttle channel. '2/ continue flying for 30 seconds, and then ammo is refilled. This is the case when throttle is 'not connected to the tag. 'Lethal damage to the plane is visible through a LED that is lit constantly, and firing is 'inhibitted. The only way to repair is to power down the complete plane, and power UP again. 'Hardware PICAXE 08M2 ' pin IO ' 8 GND ' 7 0=IR output LED (high = on) ' 6 1=throttle channel from receiver, res to gnd if not used ' 5 2=status LED (high=ON, shared with programming TX pin) ' 4 3=FIRE chanel from receiver ' 3 4=IR input sensor ' 2 5=gnd (programming RX pin) ' 1 +5V 'Versions ------------------------------------------------------------------------------------------ ' 0.1 Throttle connected everything works. ' Known problem: you cannot be hit while ammo is empty. Need to add gameplay when ' no throttle signal (time out on pulsin). ' 0.2 implement "no throttle", needs pull down at throttle pin to prevent noise ' 0.3 added comments for better understanding. ' 0.4 changes from playing with it and score board -2020- version ' 0.4p pinout change for breadboard soldering, LED inverted ' 0.5p hit list dump implemented 'Game Play ----------------------------------------------------------------------------------------- symbol AMMO = 100 'guns bullets symbol SHLD = 10 'lethal damage level symbol ME = 3 'unque tag number 0...127 symbol GROUNDED = 25 '25 x 200msec loops to refil ammo symbol REPLENISH = 30 '30 seconds brute force wait for new ammo 'IO pins ------------------------------------------------------------------------------------------- symbol LED = 2 '0 old symbol FIRE = 3 '2 old symbol THR = 1 symbol IRI = 4 '3 old symbol IRO = 0 '4 old 'memory variables ---------------------------------------------------------------------------------- symbol TMP = w0 'b0/b1 for measuring PWM pulse width symbol THR_IDLE = w1 'b2/b3 PWM pulse width when trhottle = idle symbol CNTR = b4 'counts 200msec loops for ammo refil symbol BULLETS = b5 'number of bullets left symbol HEALTH = b6 'life counter, 0 = dead symbol OPPONENT = b7 'unique ID of TAG of opponent that hit you '----------------------------------------- INIT the TAG -------------------------------------------- start: 'wait 1 Sec for the 2.4GHz receiver to lock, and stabilize low LED 'high LED pause 1000 high LED 'low LED 'life at maximum, no way to restore except repower HEALTH = SHLD calibrate: 'first check if there is a throttle pulse at all. 'this has a double function. It checks if the tag has THR attached. And if it has, it 'uses that value THR_IDLE as a reference for motor_off. pulsin THR,1,THR_IDLE 'if no pulse, time out after 1 second, value 0 returned if THR_IDLE = 0 then main2 'else value in 10uSec ticks (120 = 1200uSec = 1.2mSec) 'real value: this value is used later to determine that the airplane is on the ground. 'throttle values between 1.0msec and 1.2msec are assumed valid. if THR_IDLE > 120 then start if THR_IDLE < 100 then start 'add a small offset to cope with jitter THR_IDLE = THR_IDLE + 3 goto main2 'force 30sec immunity during takeoff '------------------------------------------ COMBAT PHASE --------------------------------------------- 'here we check if we must fire and do the firing (total time around 100ms), if not we listen to the 'IR sensor (100ms) to see if we are hit. This loops forever. In each loop there is a test for 'ammo and health. Both cases we escape the loop. main1: 'measure FIRE input pulse width in 10uSec ticks and store in w0 'this value jitters +/-1. For this application jitter is unimportant. pulsin FIRE,1,TMP 'check is pulse shows FIRE is active (<1.5mSec) if TMP < 150 then 'less than 1.5msec if BULLETS > 0 then 'fire the (IR) gun, this takes some 20-30msec irout IRO,1,ME 'lower ammo BULLETS = BULLETS - 1 'flash led to see that we have fired low LED 'high LED pause 40 toggle LED pause 30 end if else 'check if we are hit during 100msec irin [100,nohit] , IRI, OPPONENT 'if hit then register hit HEALTH = HEALTH - 1 ' we do nothing with OPPONENT yet ' here we could store hits in eeprom and read later into computer for ' ratings. write HEALTH,OPPONENT nohit: 'not hit endif ' debug - costs 150 msec *********************** 'debug ' debug end ************ *********************** 'check for ammo and refil routine if so if BULLETS = 0 then main2 'check for health, and stop forever all if we are dead. only repower can revive us. if HEALTH = 0 then low LED'high LED stop '-or- infinitely wait for dump command, then dump hit list 'this section needs testing first readout: 'check for the pulses from the dump remote control irin [100,readout] , IRI, OPPONENT if OPPONENT = 127 then 'dump EEPROM content for all hits for CNTR=0 to SHLD read CNTR,TMP irout IRO,1,TMP pause 200 next CNTR end if goto readout end if 'we are in good shape, go for next loop goto main1 '------------------------------------------ REFIL AMMO ----------------------------------------- ' refilling ammo either through waiting, or checking if the plane has been grounded for 5 seconds. main2: 'check if there is throttle channel connected, is there a pulse at all if THR_IDLE = 0 then wait30 'measure the throttle input pulse for 5 seconds, and make sure we stay on the ground 'if we repeat this test every 200mSec, we need 25 iterations for 5 seconds 'until condition met, toggle the led 5x per second (fast) for CNTR = 0 to GROUNDED pulsin THR,1,TMP if TMP > THR_IDLE then CNTR=0 end if toggle LED pause 10 toggle LED pause 180 next CNTR 'we have been grounded for 5 seconds, restore ammo, damage remains BULLETS = AMMO 'HEALTH = SHLD goto main1 wait30: 'throttle not connected, do a brute force wait 30 seconds 'LED blinks short short wait for CNTR = 0 to REPLENISH '30x1000msec = 30 sec low LED 'high LED pause 10 toggle LED pause 180 toggle LED pause 10 toggle LED pause 800 next CNTR BULLETS = AMMO goto main1 The target runs on a CMM1. An IR sensor is connected (see CMM manual) to pin 12 of the CMM1. Currently the target is connected via a cable (RJ11 telephone cable), but in the future there will be a wireless target. CMM1 26pin - RJ11 adapter board ![]() The target (front and rear) ![]() ![]() Screenshot of the highscore list ![]() The software that runs on the CMM1 '+---------------------------------------------+ '| | '| RC AIR COMBAT SCORE BOARD | '| | '| Indoor model airplane combat | '| | '| 2020-10-24 Volhout@thebackshed.com | '+---------------------------------------------+ 'get SONY IR in (pin12) and display hit scores ' 'Version: ' 1.0 get data from serial port from picaxe ' 2.0 use Maximite IR decoder ' 3.0 use names, not player numbers '--------------------- INIT -------------------- 'init and open IR port IR dev,key,IrInt Led=11 SetPin Led,dout 'led Pin(Led)=0 'off 'draw start screen Mode 2,3 '4 color mode with red and white Cls Font 2,3 'font 2 has full ascii set Color White Print " Who Hits" Line (202,0)-(478,60),White,B Line (0,0)-(200,60),White,B Font 2,5 'font 2 slightly bigger 'highscore list players=4 'number of players in one match Dim score(players,1) 'fill arrays For i=1 To players score(i,0)=0 score(i,1)=0 Next i Dim ame$(7) length 3 'until now 5 people have names ame$(0)="0 " 'no-one ame$(1)="BC " ame$(2)="WB " 'Wakjoe ame$(3)="HdL" 'me ame$(4)="RE " 'Remco ame$(5)="JH " 'Johan ame$(6)="6 " 'no-one ame$(7)="7 " 'no-one '--------------------- MAIN ------------------- 'main loop Do 'wait for new input If newinput=1 Then Pin(Led)=1 update show newinput=0 Pause 100:Pin(Led)=0 EndIf Loop End '----------------- INTERRUPT ----------------- 'interrupt loop. everything happens here IrInt: newinput=1 bkey=key IReturn '---------------- SUBROUTINES ---------------- 'add to the highscore list Sub update Local i,upd,added i=1:upd=0:added=0 Do If score(i,0)=bkey Then score(i,1)=score(i,1)+1 upd=1:added=0 EndIf If score(i,0)=0 Then score(i,0)=bkey score(i,1)=1 upd=0:added=1 EndIf i=i+1 If i>players Then upd=1 Loop Until upd+added>=1 sortit End Sub 'show the highscore list Sub show Color Red Print @(0,80) ame$(score(1,0) And 3);" ";Left$(Str$(score(1,1)),3) Color White If score(2,1) Then Print ame$(score(2,0) And 7);" ";Left$(Str$(score(2,1)),3) If score(3,1) Then Print ame$(score(3,0) And 7);" ";Left$(Str$(score(3,1)),3); End Sub 'sort the scores (max 1 place change per hit) Sub sortit Local i,j,g For i=1 To players-1 For j=i To players If score(i,1) < score(j,1) Then g=score(i,1):score(i,1)=score(j,1):score(j,1)=g g=score(i,0):score(i,0)=score(j,0):score(j,0)=g EndIf Next j Next i End Sub This code is still under development, we are just starting to use it in actual combat. Parameters will be tuned for optimum joy, features may be added (rockets ?). I already have prototyped a air defense "flak", a IR gun that rotates and elevates towards the attacking plane and fires back. The idea was to post it here, so it may transpire into idea's for others. The tag can be used in a very elementary "laser combat" suit for kids to play (just replace the pulse measurement of the fire channel with a fire button on the same GPIO pin). Volhout PicomiteVGA PETSCII ROBOTS |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2170 |
would look amazing with wing mounted lasers and a smoke machine in the hall ![]() https://www.youtube.com/watch?v=valQZEMJBEg Edited 2020-11-05 19:59 by CaptainBoing |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |