ATtiny 85 to trigger Canon camera using IR LEDs and laser tripwire

Hey everyone,

I'm using Arduino and ATtiny to trigger my camera using IR LEDs. I'm using the great library found here:

http://sebastian.setz.name/arduino/my-libraries/multi-camera-ir-control/

I managed to set up my Arduino fine as a trigger - whenever I trip the laser the camera triggers almost instantly (I think there's probably about a 1-5ms delay) and I even hooked up a mode switch (trip forever or trip once).

Here's the basic circuit (sorry for the basic schematic - just whipped up on a whiteboard):

However, when I try the code on the ATtiny, suddenly the camera no longer fires. I've tried plugging a normal LED where the IR LED is and I can see that it's firing - it's just not triggering the camera for some reason.

I've tried using 3.3V input and 5V input for the ATTiny and the IR LED but no dice.

Here's the device wired up:

My guess is the timing on the ATTiny isn't precise enough to trigger properly - but I have no way of testing this.

Does anyone have any suggestions?

I'd also appreciate any feedback - this is about the third circuit I've ever built (blink!) so any general advice would be great :slight_smile: I'd really like to get this is a standalone item.

The good part is, it works fine with the Arduino!

Your schematic shows a transistor grounding the cathode of a diode connected directly to Vcc. Is that the yellow LED? Shouldn't there be a current limiting resistor somewhere in there?

If I recall the IR protocol, it flashes the IR light for precise periods. It might be the library you are using is tuned towards 16Mhz, and perhaps you are running the ATtiny85 at a different speed like 8Mhz or 20Mhz.

MichaelMeissner:
If I recall the IR protocol, it flashes the IR light for precise periods. It might be the library you are using is tuned towards 16Mhz, and perhaps you are running the ATtiny85 at a different speed like 8Mhz or 20Mhz.

Ah yes of course, I am running the ATtiny at 8Mhz! The code for the library shows this to fire the Canon camera:

void Canon::shutterNow()
{
 for(int i=0; i<16; i++) { 
    digitalWrite(_pin, HIGH);
    delayMicroseconds(11);
    digitalWrite(_pin, LOW);
    delayMicroseconds(11);
  } 
  delayMicroseconds(7330); 
  for(int i=0; i<16; i++) { 
    digitalWrite(_pin, HIGH);
    delayMicroseconds(11);
    digitalWrite(_pin, LOW);
    delayMicroseconds(11);
  }
}

Does the delayMicroseconds() function depend on the speed that chip is running at then I assume? Would I be safe enough in just halving all the times to get the same effect without having to use a crystal do you reckon?

johnwasser:
Your schematic shows a transistor grounding the cathode of a diode connected directly to Vcc. Is that the yellow LED? Shouldn't there be a current limiting resistor somewhere in there?

It is a yellow LED that I just used to visually test if the rest of the circuit was working, but you're right I should have had a resistor in there really! My bad.

Thanks for your help!

Maybe it is a timing issue due to the attiny using internal oscillator. The Arduino use a crystal .

You can tune the internal oscillator (I just don't know how, but Coding Badly has a TinyTuner)

Erni:
Maybe it is a timing issue due to the attiny using internal oscillator. The Arduino use a crystal .

You can tune the internal oscillator (I just don't know how, but Coding Badly has a TinyTuner)

Thanks, I'll give it a look :slight_smile:

Erni:
You can tune the internal oscillator (I just don't know how, but Coding Badly has a TinyTuner)

I now have two of them. :smiley: (disregarding all the test, experimental, and prototype ones)

You should put a pull-up resistor on the RESET pin.

Thanks, that's a good point, I completely forgot about the reset pin! I've just been looking at your Tiny Tuner stuff here:

http://arduino.cc/forum/index.php/topic,8553.0.html

and I just want to get a few things straight before I potentially damage a chip...

I upload the sketch 'Interactive_to_Serial' to the ATTiny.

I connect PB3 (which is transmitting) to the serial receiver and PB4 (which is receiving) to the serial transmitter.

The Receive/Transmitter presumably can just be the TX/RX pins on an Arduino Uno for example?

Then, set up the Uno to transmit 'x' at baud rate 9600 over TX and reset the ATTiny85.

Forgive me if anything here seems wrong, I'm new to this whole thing :cold_sweat:

Okay some updates:

I Found a good post on a blog from a guy who made his own camera remote:

and I managed to get his code up and running on the ATtiny85 AND it triggers the camera! SO I now know it's possible...

I was able to create a small loop that just fired the camera every second:

#define F_CPU 7900000 // clock frequency, set according to clock used!

#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define HPERIOD 0.01524  //delay between pulses
#define RATIO 0.4       // --?
#define NPULSES 16 //number of pulses

#define LEDOFF 0b00000001
#define LEDON  0b00000010


int main(void)
{
  uint8_t i;
  DDRB  = 0b00000010; // pin PB0 is input, pins PB1-PB4 are output
  PORTB = 0b00000001; // pull-up for input pin PB0
  while(1){
    for(i=0;i<NPULSES;i++)
    {
      PORTB = LEDON;
      _delay_ms(HPERIOD);
      PORTB = LEDOFF;
      _delay_ms(HPERIOD);
    }

    _delay_ms(7.33); // instant

    for(i=0;i<NPULSES;i++)
    {
      PORTB = LEDON;
      _delay_ms(HPERIOD);
      PORTB = LEDOFF;
      _delay_ms(HPERIOD);
    }
    _delay_ms(1000);
  }
}

The same person goes into detail about the timing and tolerances here:

However, when I replace the PORTB = LEDON/LEDOFF; parts of the code above with standard arduino code (digitalWrite(pin,HIGH)) it ceases to work properly...

I'm tearing my hair out over here!

Manticorp:
However, when I replace the PORTB = LEDON/LEDOFF; parts of the code above with standard arduino code (digitalWrite(pin,HIGH)) it ceases to work properly...

I'm tearing my hair out over here!

Note that writing a value to PORTB will change ALL pins associated with PORTB. It looks like LEDON and LEDOFF are changing two different pins. One of those pins is an input so writing to it is turning the pull-up resistor ON (1) and OFF (0).

johnwasser:
Note that writing a value to PORTB will change ALL pins associated with PORTB. It looks like LEDON and LEDOFF are changing two different pins. One of those pins is an input so writing to it is turning the pull-up resistor ON (1) and OFF (0).

Ah thanks, I'm still getting the hang of all this programming microchips stuff (obviously!). I'm so used to web programming and whatnot, all this 'hardware' stuff is really confusing ('what the hell is a register!?').

I'm beginning to think that instead of relying on programming for all of this (the mode switching, LDR calibration, etc) I should be taking a more hardware approach and designing the circuit a bit better and just using the little ATtiny85 to send the pulses that trigger the camera, that way I can keep the ATtiny in sleep mode most of the time and only turn it on when I need a pulse sent. Hmm.

Manticorp:
and I just want to get a few things straight before I potentially damage a chip...

Just include 220 ? (or higher) resistors in series: Arduino ? resistor ? ATtiny85. You can never go wrong with a series resistor. :wink:

I connect PB3 (which is transmitting) to the serial receiver and PB4 (which is receiving) to the serial transmitter.

I believe that is correct.

The Receive/Transmitter presumably can just be the TX/RX pins on an Arduino Uno for example?

Yes but you will have to remove the 328 processor from the circuit. You can either force it into reset by connecting a jumper from RESET to GND or you can remove the 328 processor from the board (with the power off).

AHA! Thank you good sir! I could NOT work out why it wasn't working, fantastic! Thank you so much!

OK
Now i think I have got it too ?

I get this result (Attiny85 @8mHz)

AA    BigSteps   This         -1  41150  -11273  57  13807  -31442     42  33749  -782  185  62765  31835     45  1522  110  155  64399  -3397
  2     AB    BigSteps   This         42  1496   20  57  13807  -31442     43  33749  -782  185  62765  31835     45  1522  110  155  64399  -3397
  3     AA    Confirm    This         41  1496   20  0      0  -31442     42  1496   20  1   1496  31835     43  1508   40  1   1508  -3397
  4     AA    Confirm    This         41  1496   20  0      0  -31442     42  1498   20  2   2994  31835     43  1508   40  1   1508  -3397
  5     A9    Confirm    Left         41  1496   20  0      0  -31442     42  1497   20  3   4491  31835     43  1508   40  1   1508  -3397
  6     A9    Confirm    Left         41  1490   20  1   1490  -31442     42  1497   20  3   4491  31835     43  1508   40  1   1508  -3397
  7     A9    Confirm    Left         41  1488   20  2   2978  -31442     42  1497   20  3   4491  31835     43  1508   40  1   1508  -3397
  8     A9    Confirm    Left         41  1491   20  0      0  -31442     42  1497   20  3   4491  31835     43  1508   40  1   1508  -3397
  9     A9    Confirm    Left         41  1491   20  1   1491  -31442     42  1497   20  3   4491  31835     43  1508   40  1   1508  -3397
 10     A9    Confirm    Left         41  1491   20  2   2982  -31442     42  1497   20  3   4491  31835     43  1508   40  1   1508  -3397
 11     AB    Confirm    Right        41  1489   20  3   4471  -31442     42  1497   20  3   4491  31835     43  1508   40  1   1508  -3397
 12     AB    Confirm    Right        41  1489   20  3   4471  -31442     42  1497   20  3   4491  31835     43  1508   40  2   3016  -3397
 13     AA    Finished   This         41  1489   48  3   4471   7452     42  1497   15  3   4491   7485     43  1508   40  3   4524   7540

Copy-and-paste the following line of code at the top of setup...

  OSCCAL = 0xAA;

--------------------------------------------------
                                     Left                               This                               Right
                                     -------------------------------    -------------------------------    -------------------------------
Step  OSCCAL  State      Position    Cal   9bt  Err  #   C9bt   CClk    Cal   9bt  Err  #   C9bt   CClk    Cal   9bt  Err  #   C9bt   CClk
----  ------  ---------  --------    ---  ----  ---  -  -----  -----    ---  ----  ---  -  -----  -----    ---  ----  ---  -  -----  -----
  1

That means that

  1. in my sketch i will do like this
void setup() {                
 OSCCAL = 0xAA;
}
  1. or I could store the value in EEPROM , and read it from there in setup()

...the error at that tuning is approximately (1497 - 1500) / 1500 = -0.20%

I just tried another attiny85 and got these result:

That should give the same error (in opposit direction) at (1503-1500)/1500 = +0,2 %

 13     B1    Finished   This         48  1493   35  3   4479   7465     49  1503   10  3   4506   7510     50  1510   48  3   4529   7548

Copy-and-paste the following line of code at the top of setup...

  OSCCAL = 0xB1;

--------------------------------------------------
                                     Left                               This                               Right
                                     -------------------------------    -------------------------------    -------------------------------
Step  OSCCAL  State      Position    Cal   9bt  Err  #   C9bt   CClk    Cal   9bt  Err  #   C9bt   CClk    Cal   9bt  Err  #   C9bt   CClk
----  ------  ---------  --------    ---  ----  ---  -  -----  -----    ---  ----  ---  -  -----  -----    ---  ----  ---  -  -----  -----

Excellent!

Because there are only 128 steps in the OSCCAL value 1, in the worst case, you call not be able to get better than 1/128*100 = 0.78% 2. The goal is ±1%. Anything better than that is just good luck.

1 Tiny Tuner 2 uses the full range; 256 values.
2 The actual value is a bit lower because the relationship between OSCCAL and the frequency is not linear.

Thankyou for the explanation Coding Badly.

BTW as an experiment I tried using 3V in room temperature - and 3V and low temperature (I put the Attiny85 in the freezer), but that didn't change much
3V ->1501
3V low temp. -> 1499

That has been my experience as well.

I built a three-minute timer for my wife that runs directly from two AA batteries using the internal oscillator (ATtiny13). Over the entire voltage range (3.2 V to 1.6V) there is less than a two second difference (2/(3*60)*100 = 1.1%).

This should give you a rough idea of what Atmel guarantees...