I continue with my camera trap project. (Infra red beam triggers the camera to start filming.)
This time it's the Transmit end of the IR beam thats causing grief.
I use the tone command to generate the signal for the IR led. This works great, but then I wanted to add some bells and whistles
On switch on I wanted the voltage of the battery to be read and a standard led flashed to display the voltage.
After this I wanted the standard type led to be lit for a set time (perhaps 10 minutes) just to indicate that the IR transmitter is working, just while setting the system up. Then I want this led to go off so that there are no more visible lights, only the IR. I have already removed the power led on the Arduino mini.
It all works except that the standard led does not go off after the duration (I have it set on 10 seconds for convenience while testing). I eventually found that if I remove the tone command it all works great (except of course that no IR is being transmitted)
Can anyone tell me what I have done wrong? Many thanks in anticipation.
long startTime; // variable to store the start time
const long duration = 10000;//How long the display LED stays on
int intLed = 13;
int IR_LED_PIN = 12;
long value = 0;
int count = 0;
float voltage;//in mV
void setup() {
//delay(2000);
pinMode(intLed, OUTPUT);
pinMode(IR_LED_PIN, OUTPUT);
Serial.begin(9600);
value = analogRead(A3);
Serial.print("Value =");
Serial.println(value);
voltage = value * 4.1152;
Serial.print("Voltage in mV =");
Serial.println(voltage);
//Divides the voltage range into 4 parts and flashes an
// led accordingly. 4 flashes for full charge etc.
if (voltage >= 3870) {
count = 4;
}
if ((voltage < 3870) && (voltage >= 3720)) {
count = 3;
}
if ((voltage < 3720) && (voltage >= 3590)) {
count = 2;
}
if ((voltage < 3590) && (voltage >= 3470)) {
count = 1;
}
if (count == 4 or count == 3 or count == 2 or count == 1)
{
for (int i = 0; i < count; i++)
{
digitalWrite(intLed, HIGH);
delay(50);
digitalWrite(intLed, LOW);
delay(250);
}
}
//If voltage is even lower, flash the led very fast to indicate a warning
if ((voltage < 3470) && (voltage >= 2000)) {
count = 10;
}
if (count == 10)
{
for (int i = 0; i < count; i++)
{
digitalWrite(intLed, HIGH);
delay(40);
digitalWrite(intLed, LOW);
delay(40);
}
}
Serial.println(count);
delay(2000);
// generate 38kHz signal for the Infra Red Led
tone(IR_LED_PIN, 38000);
digitalWrite (intLed, HIGH);//Just a lit led to show the box is alive
startTime = millis(); // record the start time of te lit led
}
void loop() {
if (millis() - startTime >= duration) // check if duration has been reached
{
digitalWrite (intLed, LOW);//turn off the led so that no more lights are on
}
}
It's a mystery to me. I ran your code unmodified and it functions as it appears you meant it to do.
I used an original Nano, I do not expect the board type to be important, but what board did you say you are using here?
Are you sure you posted the code that does not work?
There is a bit of simplification to your code wothout changing its functions, but that shouldn't matter.
Add
Serial.println("off to the loop!");
}
at the bottom of you setup() function, like I did. Here, when i moves on to the loop, after the time period you set (I reduced it to 5 seconds, life too short!), the LED extinguishes. The tone plays on.
Seems like you got something weird, I agree with your next steps.
Meanwhile, I open my device under the umbrella and see this I did not finish or post. A functioning memory… I think I miss it.
I cannot test this, in transit working through a tiny window.
Here's the code you posted with just a few tweaks, none of which should change the behaviour of the sketch:
long startTime; // variable to store the start time
const long duration = 10000;//How long the display LED stays on
int intLed = 13;
int IR_LED_PIN = 12;
long value = 0;
int count = 0;
float voltage;//in mV
void setup() {
//delay(2000);
pinMode(intLed, OUTPUT);
pinMode(IR_LED_PIN, OUTPUT);
Serial.begin(9600);
value = analogRead(A3);
Serial.print("Value =");
Serial.println(value);
voltage = value * 4.1152;
Serial.print("Voltage in mV =");
Serial.println(voltage);
//Divides the voltage range into 4 parts and flashes an
// led accordingly. 4 flashes for full charge etc.
count = 0;
if (voltage >= 3870) {
count = 4;
}
else if (voltage >= 3720) {
count = 3;
}
else if (voltage >= 3590)) {
count = 2;
}
else if (voltage >= 3470) {
count = 1;
}
for (int i = 0; i < count; i++)
{
digitalWrite(intLed, HIGH);
delay(50);
digitalWrite(intLed, LOW);
delay(250);
}
//If voltage is even lower, flash the led very fast to indicate a warning
if ((voltage < 3470) && (voltage >= 2000)) {
count = 10;
for (int i = 0; i < count; i++)
{
digitalWrite(intLed, HIGH);
delay(40);
digitalWrite(intLed, LOW);
delay(40);
}
}
Serial.println(count);
delay(2000);
// generate 38kHz signal for the Infra Red Led
tone(IR_LED_PIN, 38000);
digitalWrite (intLed, HIGH);//Just a lit led to show the box is alive
startTime = millis(); // record the start time of te lit led
}
void loop() {
if (millis() - startTime >= duration) // check if duration has been reached
{
digitalWrite (intLed, LOW);//turn off the led so that no more lights are on
}
}
Hey @Bnorm , it looks like we are working on similar projects. It makes sense to test the Uno with everything connected to see if it has the same issues. The nano moves to the loop if you take out the tone() function, though, right?
You could alternatively use a timer to set up a 38kHz signal and see if that behaves any better. That's how I ended setting up my IR signal. I did mine on an attiny85, but the process should be about the same on the uno or nano, just making the adjustments for what your system clock frequency is and moving from an 8 bit timer to a 16 bit timer (I think that's what's on the atmega328p).
This next part isn't related to your current issue, so feel free to ignore it for the time being. There were a couple of issues I had to deal with that come to mind looking at your project.
Are you getting enough power in your IR LED supplying it with voltage from a pin? I ended up sending a signal to a transistor and powering the IR LED from the battery.
Are you modulating your 38kHz signal at all or leaving it at a steady 38kHz? Most of the 38kHz IR receivers I found will filter out a steady signal after a bit, assuming that it's background noise. I turn my signal on for half a millisecond and then off for 20 milliseconds. Doing something like that saves battery life, too.
const byte LED = 11; // Timer 2 "A" output: OC2A
void setup() {
pinMode (LED, OUTPUT);
// set up Timer 2
TCCR2A = _BV (COM2A0) | _BV(WGM21); // CTC, toggle OC2A on Compare Match
TCCR2B = _BV (CS20); // No prescaler
OCR2A = 209; // compare A register value (210 * clock speed)
// = 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095
} // end of setup
void loop() { }
It produced a nice 19khz signal. (my mini runs at 8mhz, I suspect this is why). These few lines of code mean nothing to me but I tried experimenting with that number "209" and eventually found that if changed to 104, it gives me what I want. I looked at it on a scope and it looks the right shape and everything!
Now all my code runs properly and I have loaded it onto my Green box prototype.
All is well.
How quickly I become happy when things start working again.
Big thanks to you guys for your help. (and Nick Gammon)
**********************************************8
I did run my IR led through a transistor back along, but I did some tests changing its inline resistor, I think over a range of 15 to 115ohms and found no real advantage anywhere so I opted to use a 100 ohm resistor which means that the led only draws 20mA. I thought this should be well within the pins capabilities so I decided to remove the transistor. I have run it for 5 days continuously since then and it seems to work ok.
It also seems fine without extra modulation of the signal.
Next I am going to try and fit my system with some NRF24L01 units. Watch this space .
Great, glad you have it working. That's close to the same method I used for mine, just a different timer mode.
If you want to turn the signal on and off in your loop (and you may still want to consider it for the power savings), you can use the following:
//Turn off 38kHz pulse
TCCR2A &= ~(_BV (COM2A0));
//Turn on 38kHz pulse
TCCR2A |= _BV (COM2A0);
If you're getting the range you want out of it, then great. I may end up decreasing the current going through mine, but I still need to do some more testing. How far away can your receiver detect a break (and beam break)?
Just curious, what IR receiver are you using? Always interesting to see another solution.
Ooh, you are going for bells and whistles. Look forward to seeing it.
I get about 7m out of it which is enough for my needs. I think I got more like 10m when I still had it running with the transistor, dont know why that was. I am using the TSSP4038.
Yeah, 7m should be good for most situations. Sounds like you had a slightly higher current and a brighter IR beam with the transistor.
One of the reasons I went with the TSOP IR remote style receiver is that it's supposed to be better at filtering out noise from sunlight and such. What I've read is that the ones that can receive the constant signal are more vulnerable to ambient noise. Have you had any trouble with that?
So..... 6 months later. A family related thing came up which has severly interfered with most of my nerdy pastimes. However, I have been plodding on and at least I have just managed to write this and stop this thread being closed due to inactivity.
Now, where did I get to. Ah yes, the thought of setting up a comms link between IR sensor and another unit which triggers the camera. I tried bluetooth standard, bluetooth LE, 433Mhz modules, NRF24L modules and maybe others. Most could do 30m range, which is all I need but only line of sight. A small wall or a car in the way will stop them dead. This would be no good for me.
I then considered some sort of wired link, but this is where I went off on another major excursion. I want my gadgets for outside use to be totally rain proof, in fact, more like waterproof. I am from an oceanographic engineering background so O rings dont phase me at all. Getting wires into waterproof enclosures however is more of a problem. I know it can be done with proper "pass throughs" but these are very expensive, and beyond my budget for this sort of project.
I then had a fanciful idea that I could have a 30m length of 2 core wire, at each end of which is a coil. Each of these coils can slide nicely over the exterior of my 2 units. At the transmit end another coil within the enclosere could induce a signal on to the coil outside. At the other end of the 30m wire the signal is induced back into the other enclosure for further proccessing.
I thought I was getting somewhere with this method on one or two occassions but it was all just too flakey. I have a box full of home made coils here in front of me just to remind me of all the hours I have wasted.
I have only recently become aware of these LoRa modules. They show some promise and I am thinking of going back down the radio link road. The RYLR998 looks good. There are loads of you tubes saying that they have a range of 15km or even more but one that impressed me was a guy that managed to get 750m range in a built up city environment. That would be ample for me. Any one played with these? They look like they may be exactly what I am looking for.
I have used individual component radio sets as well as a commercially available 4-in-1 module, all in the context of the r/c hobby.
CC2500, NRF24L01, A7105 and CYRF6936 RF are the designations, all are reliable 50 meters, maybe not 50 meters of dense damp foliage.
FWIW these four radios cover most of the r/c work I do. A cheap toy here and there might use something different, or employ a proprietary protocol, otherwise I can use one transmitter by switching models.
Key is having good power and antennae. Some toys, for example, use just a wire 30mm in length. Just orientating that to be perpendicular to the ground and parallel to the transmitting antenna can make a huge difference.
What library did you use in your experiments? I appreciate you may be so done with fiddling, but this shouldn't be impossible.
All but the 433Mhz units that I tried had built in pcb type antenas. perhaps this is why I got poor results. One problem is that I am trying to fit everything into nice smallish cylindrical enclosures. Space is at a premium. I think I might still try the RYLR998.
What did you think about my coils and wire idea? Did it defy some basic rules of physics and never stood a chance?
Sry, file under don't say anything if you have nothing to say. It looks plausible, but it's been a minute.
But if you are willing to run a wire or two to span the distance, you could put your creative energy instead into figuring out how to get the wires to go inside the enclosures without compromising the protection they are providing.
Then you could use a standard way of talking at that distance over a pair of wires.