I want to use an IR type remote control but under water.
Water attenuates red and IR (infra red) even more. To maintain reasonable range (I'm not very specific regarding what a reasonable range is - a few meters I think) I want to use blue LEDs.
So far I have been unable to find just the chip part of an IR remote control nor a circuit to filter and decode.
The IR receiver chips have both an IR photodiode and an amplifier with very narrow bandpass, typically 38 kHz. For blue light you would have to implement those parts yourself, using an ordinary photodiode with blue filter and a bandpass amplifier.
The latter is not trivial for a beginner to make as a discrete circuit, but you might be able to use a digital filter on the Arduino input. An autocorrelation filter would be fast, and if you are interested, I can post an example.
The problem is that seawater is blue, as are the insides of pools. This means you'll have a lot of noise in your input results unless you use a bandpass filter and modulate the input at that frequency, like is done in normal IR receiver/remote combos.
An alternative is to send red or orange light, and have it be decoded using your own protocol, but you already mentioned this wouldn't work due to the shifting of the light spectrum in deep water. Not just your eyes, but also the receiver, would see that red light as green.
For blue light you would have to implement those parts yourself, using an ordinary photodiode with blue filter and a bandpass amplifier... as well as AGC. The energy levels (i.e. received signal levels) cover a wide dynamic range.
It is the non-photodiode part of the circuitry that I was hoping to obtain as a device, or some simple reduce risk circuitry, so that I could add the blue sensitive photodiode as an alternative to the IR sensitive one included within all the receivers.
I believe could design that myself (I have some experience as a hardware designer, mainly analogue over the past ten years or so). It would be a fiddle and occupy time and effort that I want to put into other things.
I am unclear how autocorrelation would work for this. I would appreciate some further information; I would like to look at your example please.
My feeling at the moment could be to use a standard low-cost IR receiver and significantly increase the transmitted power. That introduces other problems, not least the amount of energy required in a battery.
Unfortunately most of those are embedded in a pretty effective IR filter housing. How much blue light gets through that?
how autocorrelation would work for this.
You could convert the photodiode output to digital using a comparator, then feed it into an autocorrelation filter like this (which is currently configured to detect audio tones, input on the Arduino Uno comparator.
// fast audio tone detector, 8 bit autocorrelation function.
// This program detects the presence of an audio tone of
// the specified frequency f0 (below)
// output: lights LED with tone present within detection bandwidth
//
// for Arduino ATmega variants
// uses analog comparator module
// pin D6 = capacitively coupled audio input, biased to Vcc/2
// pin D7 = reference voltage, Vcc/2
//samples input for two full successive periods of the target tone frequency and
// compares the two samples for match.
//in theory, exact match will occur only if the sample frequency is an integer multiple
// of the input frequency.
#define LED 13
float f0 = 1000.0; //target frequency in Hz
unsigned int p0 = 1.0E6 / (8.0 * f0); //sample delay in microseconds
union i2b {
unsigned int i;
unsigned char b[2];
} val;
void setup ()
{
Serial.begin (9600);
Serial.print("Sample delay us ");
Serial.println(p0);
delay(500);
pinMode(LED, OUTPUT); //on board LED
digitalWrite(LED, 0);
ADCSRB = 0; // (Disable) ACME: Analog Comparator Multiplexer Enable
DIDR1 = 3; //disable digital inputs on D6/D7 (comparator AIN0/AIN1)
ACSR = (1 << ACI); //clear Analog Comparator interrupt flag, just in case
} // end of setup
void loop () {
static unsigned char i, result, sum;
sum = 0;
val.i = 0;
for (i = 0; i < 16; i++) {
if (ACSR & (1 << ACO)) val.i |= 1; //if input is HIGH, set bit in sample
val.i <<= 1;
delayMicroseconds(p0);
} //loop i
if ( (val.b[0] == 0) || (val.b[0] == 0xFF)) return; //no signal
result = val.b[1] ^ val.b[0]; //XOR the two one-byte samples
if (result == 0 ) digitalWrite(LED, 1); //match
while (result) { //count set bits
if (result & 1) sum++;
result >>= 1;
}
if (sum < 2) digitalWrite(LED, 1); //allow 1 set bit (bandpass)
else digitalWrite(LED, 0);
} // end of loop
Here is a more conventional IIR bandpass tone detector that I found somewhere, and have never got around to trying:
/* Sketch implements single tone detection using a narrow bandpass filter
* Tone detection occurs when integrated power out of BPF is greater than
* one half the integrated power of the full ADC band
*/
// ***************************************************************************
/* Integrator class maintains running average of input using recursion formula
xAvg = x + xAvg - xAvg/(2**N) where N is a positive integer
Effective integration period is on the order of 2**N
*/
class Integrator {
public:
long int xAvg ; // Running average left shifted N bits
int shift ;
Integrator(int N) { // Constructor for class
xAvg = 0 ;
shift = N ;
}
// Update average with sample and return updated average
long int integrate(long int xIn) {
xAvg = xAvg + xIn - (xAvg >> shift) ;
return (xAvg >> shift) ;
}
} ;
// ***************************************************************************
/* Digital bandpass filter for sample rate 2500 Hz, passband 995-1005 Hz */
/* Using: https://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html */
/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher
Command line: /www/usr/fisher/helpers/mkfilter -Bu -Bp -o 1 -a 3.9800000000e-01 4.0200000000e-01 -l */
#define NZEROS 2
#define NPOLES 2
#define GAIN 8.057026980e+01
static float xv[NZEROS + 1], yv[NPOLES + 1];
static int filterloop(int xIn) {
xv[0] = xv[1]; xv[1] = xv[2] ;
xv[2] = xIn * (1 / GAIN) ;
yv[0] = yv[1]; yv[1] = yv[2] ;
yv[2] = (xv[2] - xv[0]) + ( -0.9751778762 * yv[0]) + ( -1.5980786463 * yv[1]);
return int(yv[2]) ;
}
// ***************************************************************************
// Parameter and object definitions
#define sampleIntervalMicros 400 // Sample interval in microseconds
long int nextInterval ; // Time of next ADC collection cycle
Integrator adcRunningMean(8) ; // Integrator object to track ADC offset
Integrator channelPower(6) ; // Integrator object to track full band channel power
Integrator tonePower(6) ; // Integrator object to track filter band power
void setup() {
digitalWrite(LED_BUILTIN, LOW) ;
pinMode(LED_BUILTIN, OUTPUT) ;
Serial.begin(115200) ;
nextInterval = micros() + sampleIntervalMicros ;
}
void loop() {
if (micros() >= nextInterval) {
int x = analogRead(A0) ;
long int adcMean = adcRunningMean.integrate(x) ;
long int y = filterloop(x) ;
long int chanPower = channelPower.integrate(sq((x - adcMean))) ;
long int sigPower = tonePower.integrate(sq(y)) ;
nextInterval += sampleIntervalMicros ;
if (2 * sigPower > chanPower) {
digitalWrite(LED_BUILTIN, HIGH) ;
} else {
digitalWrite(LED_BUILTIN, LOW) ;
}
}
}
Seawater appears blue as the red is attenuated or filtered out from sunlight, which includes ‘all’ frequencies or colours. There is no wavelength altering, or shifting of the light spectrum. The red just warms up the water a little as the water absorbs this frequency. Thanks to Wikipedia I’ve attached a graph.
Commercial IR remote controls modulate the IR as typically 38kHz, some are other frequencies 34KHz too is popular IIRC. This is to aid ignoring the background or ambient illumination. Sunlight or room illumination does not operate at 38 kHz and therefore the receiver’s bandpass filter removes this.
It would be the same for blue under water. The blue is not modulated, it could be considered as ‘noise’ at DC.
I was having a hard time confirming the science behind what I said, which turned out to be wrong.
I kind of suspected this because if there was shifting, IR light would be visible, appearing red.
Nevertheless, the result is the same. Red and IR light aren't really going to work, because the saltwater absorbs it. Building your own receiver with modulation and a bandpass filter is the best option, because it recreates what goes on in normal IR receivers, except blue.
Building your own receiver with modulation and a bandpass filter is the best option, because it recreates what goes on in normal IR receivers, except blue.
That was my conclusion, which is why I was asking this question. As I wrote to jremington "I believe could design that myself (I have some experience as a hardware designer, mainly analogue over the past ten years or so). It would be a fiddle and occupy time and effort that I want to put into other things."
I was hoping that I might identify a device that did the majority or ideally, all, of what I wanted. I think that is unlikely
I am feeling that I may have to build some waterproof kit as actually see what range I get with a TV type remote control under water. Again optimistically it may 'just about do', but I'm not hopeful as the Wikipedia graph shows attentuation of red is > 100 x blue.
Thank you for your time and input.
Add a simple photodiode+transimpedance amplifier, and you should be close.
The fast autocorrelation code merely samples a digital input 16 times, stuffing the bits into a 16 bit integer, with a carefully calculated delay. If the upper and lower 8 bits match, then the input frequency is a submultiple of the sample frequency.
Another consideration is the water turbulence. All the information in the thread, so far, is for still, quiet, water. Any turbulence will cause refraction and reflection of light, which will also be noise at any wavelength you choose.
Paul