Infrared reception
So, while waiting on a new main board, I decided to work on the software a bit. I wanted to get IR reception/transmission working reliably and also modify the code to support the new motor controllers (PWM on all motors + control signals supported with a shift register).
I began with the IR reception. Most importantly, this will record the hit from the other tank's shot. Secondarily, it will be used to receive commands from an IR remote. I sourced some cheap IR remotes from Sparkfun. I think that these will be useful for debugging (in debug mode, you will be able to control basic tank functions with the remote). Also, they can be used to give a start signal for the tanks to begin fighting.
I had messed with the IR stuff a little, before, using the IRemote library. The library makes it stupid-simple but when I tried using it with the rest of my tank code, I began having problems. The main issue seemed to be that, even though I had my IR receiver diode on a hardware interrupt pin, the library did not seem to be leveraging that. In my use case, I wanted an IR signal to trigger an interrupt, for the code to process the signal, and then return to whatever else it was doing. The IRemote library appears to allow for processing of the signal in small increments, while allowing for other activities in between. The other issue is that IRemote uses digitalRead() to access the receiver, whereas a direct call to the pin port register is much faster (but results in less portable code).
I had trouble including a modified version of IRemote in my code, maybe just for dumb reasons, I'm not sure.
Anyway, all this is to say that I got in deep and ended up rolling my own IR code. I did this by copying and modifying code from this stellar IR tutorial from Adafruit. This took me the better part of my Sunday, I'm afraid. I had lots of stupid problems and made stupid mistakes. But now I have a standalone chunk of code that attaches a hardware interrupt, receives IR pulses and returns a 32-bit value.
Earlier, I had wanted to preserve the IR signal that the toy tank sends, out of the box. This would allow robots to fight human-controlled tanks, in theory. But, in the end, I will probably use a signal code from the IR remote, so that the tank can be "shot" by the remote. I suppose I could support both codes.
So, while I'm still waiting on the PCBs, here are remaining software items to work on:
- IR transmission [I will probably use the IRemote library for this and I think it will work fine, since I do not have to worry about interrupts. If program space becomes an issue, I could consider "rolling my own" and ditching the IRemote library entirely. Rolling my own would probably just mean a clumsy port of the IRemote transmisssion code.]
- Motor control via shift-register [This should be straight-forward. I've already done some exploratory code and I think I have a solid handle on it.]
- Unit tests [In my professional life, I write tests every time I develop software. I would really like to see unit tests for my Laser Tag Robot Tank code. I've done a little exploration here but need to do more. The hard thing, of course, is mocking the Arduino.]
In more speculative stuff, I've been thinking about optical wheel encoders. I had earlier thought them totally unnecessary for this application but lately I've been thinking they could be really useful. A wheel encoder on each track-driving wheel would mean that I could:
- back away from obstacles and turn in a defined pattern
- have the tank drive a given number of feet when a button on the remote is pressed
- implement a "steady turret" feature, where the turret stays at a fixed point, no matter if the tank is turning or driving (maybe not realistic, given that the turret rotation can not keep pace with the tank's turning)
All the above can be implemented more crudely with guesses as to timing. But I would expect results to vary widely as the tank experiences changes in battery voltage.
Downsides to the wheel encoders are:
- increased cost and complexity
- there is possibly not enough room for even a super-basic optical encoder, at the tank wheels?
- would require two pins [I would probably have to give up two LEDs]
- two more rapidly-firing software interrupts [though, honestly, probably not near rapid enough to cause issue]
The case for wheel encoders seemed to be compelling enough that I wanted to at least buy some and test them out. I'm still looking for cheap, reflective, off-the-shelf ones, though, and I haven't found much. I found this page with lots of useful information about creating your own.
I began with the IR reception. Most importantly, this will record the hit from the other tank's shot. Secondarily, it will be used to receive commands from an IR remote. I sourced some cheap IR remotes from Sparkfun. I think that these will be useful for debugging (in debug mode, you will be able to control basic tank functions with the remote). Also, they can be used to give a start signal for the tanks to begin fighting.
I had messed with the IR stuff a little, before, using the IRemote library. The library makes it stupid-simple but when I tried using it with the rest of my tank code, I began having problems. The main issue seemed to be that, even though I had my IR receiver diode on a hardware interrupt pin, the library did not seem to be leveraging that. In my use case, I wanted an IR signal to trigger an interrupt, for the code to process the signal, and then return to whatever else it was doing. The IRemote library appears to allow for processing of the signal in small increments, while allowing for other activities in between. The other issue is that IRemote uses digitalRead() to access the receiver, whereas a direct call to the pin port register is much faster (but results in less portable code).
I had trouble including a modified version of IRemote in my code, maybe just for dumb reasons, I'm not sure.
Anyway, all this is to say that I got in deep and ended up rolling my own IR code. I did this by copying and modifying code from this stellar IR tutorial from Adafruit. This took me the better part of my Sunday, I'm afraid. I had lots of stupid problems and made stupid mistakes. But now I have a standalone chunk of code that attaches a hardware interrupt, receives IR pulses and returns a 32-bit value.
Earlier, I had wanted to preserve the IR signal that the toy tank sends, out of the box. This would allow robots to fight human-controlled tanks, in theory. But, in the end, I will probably use a signal code from the IR remote, so that the tank can be "shot" by the remote. I suppose I could support both codes.
So, while I'm still waiting on the PCBs, here are remaining software items to work on:
- IR transmission [I will probably use the IRemote library for this and I think it will work fine, since I do not have to worry about interrupts. If program space becomes an issue, I could consider "rolling my own" and ditching the IRemote library entirely. Rolling my own would probably just mean a clumsy port of the IRemote transmisssion code.]
- Motor control via shift-register [This should be straight-forward. I've already done some exploratory code and I think I have a solid handle on it.]
- Unit tests [In my professional life, I write tests every time I develop software. I would really like to see unit tests for my Laser Tag Robot Tank code. I've done a little exploration here but need to do more. The hard thing, of course, is mocking the Arduino.]
In more speculative stuff, I've been thinking about optical wheel encoders. I had earlier thought them totally unnecessary for this application but lately I've been thinking they could be really useful. A wheel encoder on each track-driving wheel would mean that I could:
- back away from obstacles and turn in a defined pattern
- have the tank drive a given number of feet when a button on the remote is pressed
- implement a "steady turret" feature, where the turret stays at a fixed point, no matter if the tank is turning or driving (maybe not realistic, given that the turret rotation can not keep pace with the tank's turning)
All the above can be implemented more crudely with guesses as to timing. But I would expect results to vary widely as the tank experiences changes in battery voltage.
Downsides to the wheel encoders are:
- increased cost and complexity
- there is possibly not enough room for even a super-basic optical encoder, at the tank wheels?
- would require two pins [I would probably have to give up two LEDs]
- two more rapidly-firing software interrupts [though, honestly, probably not near rapid enough to cause issue]
The case for wheel encoders seemed to be compelling enough that I wanted to at least buy some and test them out. I'm still looking for cheap, reflective, off-the-shelf ones, though, and I haven't found much. I found this page with lots of useful information about creating your own.
Comments
Post a Comment