Question about timers ATtiny85 code and question -Arduino

Thread Starter

fredric58

Joined Nov 28, 2014
252
Hello, the question is in regards to line 42,43 and 112. unfortunately the line number do not appear here and the lines are not highlight. (at least while I compose this.) It works in PREVIEW !!!!! This is my 1st attempt to upload code properly. I have built the project, successfully programmed the ATtiny85 with my Arduino as the ISP and it works like it should.


Line 112 comment: // if it's dark, flash the LED for 2 mS (where is that command coming from?)
I believe it is related to lines 42 and 43 but I am not sure.
Line 42 comment: // set a2d prescale factor to 128
Line 43 comment: // 8 MHz / 128 = 62.5 KHz, inside the desired 50-200 KHz range.

What I would like to learn today is how to change (flash the LED for 2 mS) to MORE mS or even go as far as SECONDS and to MINUTES if thats possible. Note, the accuracy is not so important as to need a RTC.



Arduino Code:
// ATtiny85 torch detector
// Author: Nick Gammon
// Date: 25 February 2015

// ATMEL ATTINY 25/45/85 / ARDUINO
// Pin 1 is /RESET
//
//                  +-\/-+
// Ain0 (D 5) PB5  1|    |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2) Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//            GND  4|    |5  PB0 (D 0) pwm0
//                  +----+

/*

  Pin 2 (PB3) <-- LDR (GL5539) --> Pin 7 (PB2) <----> 56 k <----> Gnd

  Pin 5 (PB0) <---- LED ---> 100 R <-----> Gnd
 
*/


#include <avr/sleep.h>    // Sleep Modes
#include <avr/power.h>    // Power management
#include <avr/wdt.h>      // Watchdog timer

const byte LED = 0;          // pin 5
const byte LDR_ENABLE = 3;   // pin 2
const byte LDR_READ = 1;     // Ain1 (PB2) pin 7
const int LIGHT_THRESHOLD = 200;  // Flash LED when darker than this

 // when ADC completed, take an interrupt
EMPTY_INTERRUPT (ADC_vect);
 
// Take an ADC reading in sleep mode (ADC)
float getReading (byte port)
  {
  power_adc_enable() ;
  ADCSRA = bit (ADEN) | bit (ADIF);  // enable ADC, turn off any pending interrupt
 
  // set a2d prescale factor to 128
  // 8 MHz / 128 = 62.5 KHz, inside the desired 50-200 KHz range.

  ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2);
 
  if (port >= A0)
    port -= A0;
    
#if defined(__AVR_ATtiny85__)
  ADMUX = (port & 0x07);  // AVcc   
#else   
  ADMUX = bit (REFS0) | (port & 0x07);  // AVcc   
#endif

  noInterrupts ();
  set_sleep_mode (SLEEP_MODE_ADC);    // sleep during sample
  sleep_enable();
 
  // start the conversion
  ADCSRA |= bit (ADSC) | bit (ADIE);
  interrupts ();
  sleep_cpu ();     
  sleep_disable ();

  // reading should be done, but better make sure
  // maybe the timer interrupt fired

  // ADSC is cleared when the conversion finishes
  while (bit_is_set (ADCSRA, ADSC))
    { }

  byte low  = ADCL;
  byte high = ADCH;

  ADCSRA = 0;  // disable ADC
  power_adc_disable();
 
  return (high << 8) | low;
 
  }  // end of getReading
 
// watchdog interrupt
ISR (WDT_vect)
{
   wdt_disable();  // disable watchdog
}  // end of WDT_vect

#if defined(__AVR_ATtiny85__)
  #define watchdogRegister WDTCR
#else
  #define watchdogRegister WDTCSR
#endif
 
void setup ()
  {
  wdt_reset();
  pinMode (LED, OUTPUT);
  pinMode (LDR_ENABLE, OUTPUT);
  ADCSRA = 0;            // turn off ADC
  power_all_disable ();  // power off ADC, Timer 0 and 1, serial interface
  }  // end of setup

void loop ()
  {
  // power up the LDR, take a reading
  digitalWrite (LDR_ENABLE, HIGH);
  int value = getReading (LDR_READ);
  // power off the LDR
  digitalWrite (LDR_ENABLE, LOW);
 
  // if it's dark, flash the LED for 2 mS
  if (value < LIGHT_THRESHOLD)
    {
    power_timer0_enable ();
    delay (1);  // let timer reach a known point
    digitalWrite (LED, HIGH);
    delay (2);
    digitalWrite (LED, LOW);
    power_timer0_disable ();
    }
 
  goToSleep ();
  }  // end of loop
 
void goToSleep ()
  {
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  noInterrupts ();       // timed sequence coming up

  // pat the dog
  wdt_reset();
 
  // clear various "reset" flags
  MCUSR = 0;     
  // allow changes, disable reset, clear existing interrupt
  watchdogRegister = bit (WDCE) | bit (WDE) | bit (WDIF);
  // set interrupt mode and an interval (WDE must be changed from 1 to 0 here)
  watchdogRegister = bit (WDIE) | bit (WDP2) | bit (WDP1) | bit (WDP0);    // set WDIE, and 2 seconds delay
 
  sleep_enable ();       // ready to sleep
  interrupts ();         // interrupts are required now
  sleep_cpu ();          // sleep               
  sleep_disable ();      // precaution
  }  // end of goToSleep
 

Thread Starter

fredric58

Joined Nov 28, 2014
252
I see that, and the highlight feature is pretty cool too. At a glance it looks like my first code upload is a success. Now what I need is to be pointed in the direction of where the command came from.
 

KeithWalker

Joined Jul 10, 2017
2,930
The length of time the LED is on for is the "delay" statement in line 118. It is in mS so if you change the "2" to "500", the LED should stay on for half a second.
 

Thread Starter

fredric58

Joined Nov 28, 2014
252
Hello Keith, Thank you. another question, the only way I can explain is as a drummer. it's called a triplet 123. 3 equal beats. right now, it doesn't go, 1-2-1-2-1-2. (on-off-on-off) the light actually goes, on-2-3-on-2-3 (on-off-off-on_off-off) if you were to count it as a time signature. it could be that the LED doesn't respond quick enough, 2mS is a short amount of time. I'll try your suggestion at 1 second and see what happens. my eventual goal is to have it go "ON" for a second, then OFF maybe 5sec. I'm just getting into timers and WOW, there is a lot to it. Thanks for the reply and have a great weekend. Fred
 

Thread Starter

fredric58

Joined Nov 28, 2014
252
Hello Keith, I am thinking I can add this to accomplish what I need, your thoughts ?
Arduino torchlight:
    digitalWrite (LED, HIGH);
    delay (500); // 1/2 second
    digitalWrite (LED, LOW); //then add
    delay (5000)  //5 seconds? all my projects are designed to work in the dark.
 

Thread Starter

fredric58

Joined Nov 28, 2014
252
Thanks Keith, programming it now to see what happens. I am unfortunately dealing with something call "chemo brain fog" after a year of treatments. That stuff is terrible. But I survived, I got released from treatment last week. You can't imagine unless you've had it what it is like having poison pumped into your body for 52 hours every other week. It makes me look stupid cause I just don't remember stuff. Thanks for your patience, hope your having a great weekend. Fred

Stage 4 pancreatic cancer. Odds of living 6 months, 1%, I am 10 months past my expiration date. PTL.
 

Thread Starter

fredric58

Joined Nov 28, 2014
252
Hey Keith, I changed the program, but FORGOT to load the ISP program to the arduino. So it would upload to the ATtiny 85. Once I figured that out it works REALLY WELL. The (2) MS just wasn't enough time to get the LED to it's full brightness. Now it's about 40X brighter, I can see it from about 3/10 of a mile, which is perfect. Thanks for helping out. If you'll PM me, if that's possible. perhaps I can figure out some way to send you $20 for a cold beer or 2? OR, for a 1/2 pint of whiskey and a nice cigar to enjoy one evening. Thanks again.
 

KeithWalker

Joined Jul 10, 2017
2,930
Hey Keith, I changed the program, but FORGOT to load the ISP program to the arduino. So it would upload to the ATtiny 85. Once I figured that out it works REALLY WELL. The (2) MS just wasn't enough time to get the LED to it's full brightness. Now it's about 40X brighter, I can see it from about 3/10 of a mile, which is perfect. Thanks for helping out. If you'll PM me, if that's possible. perhaps I can figure out some way to send you $20 for a cold beer or 2? OR, for a 1/2 pint of whiskey and a nice cigar to enjoy one evening. Thanks again.
The ATtiny 85 is a fantastic little beast. It opens up all kinds of possibilities. I hope you have lots of fun being creative with it,
Knowing that I was able to help someone is more than sufficient thanks for me, but I appreciate the offer. Thank you.
:)
 

Thread Starter

fredric58

Joined Nov 28, 2014
252
Thank you then. very much. I have 1 more operation tomorrow and then I'm done with hospitals. yes it is a cool little chip. I plan on using this project because it works at night and is low power to activate a larger project running on a separate power supply. As I understand it the ATtiny 85 WDT only has a window of approx 8 seconds. Do you know if it would be possible to loop that 8 seconds where it would count 8 + 8 + 8 to give me an approx 24 second window? What would it be called so I can research it? I'm gonna go searching now, I am pretty sure someones done it? never hurts to ask.
Thanks, Fred
 

KeithWalker

Joined Jul 10, 2017
2,930
You can repeat the delay function as many times as you wish. Just put it in a for -next loop with an incrementing counter that will end the loop at the correct count.
for (int i=1; i<24; i++)
{ delay(1000); }
 

Thread Starter

fredric58

Joined Nov 28, 2014
252
Thanks, I'll have to wrap my head around that. but it looks like, if i =1 and if i is less than 24, add 1000 till i =24. I remember studying the i++ but I will have to revisit it. I've been away from this for a couple years. But it is slowly coming back! Thanks
Fred
 

djsfantasi

Joined Apr 11, 2010
9,131
Why don’t you just
delay(24000); ?​
The parameter to the delay() function is an unsigned long int. On an Arduino, this is over 2 billion milliseconds (2 million seconds). Easily handle 24 seconds.

The delay() function is not related to the watchdog timer in practice.
 

Thread Starter

fredric58

Joined Nov 28, 2014
252
Hello dj, that's interesting, and simple. I'm new to the ATtiny 85. This particular code is something I find fascinating because of the LDR function and the sleep function and I simply didn't know it might be possible to do it that way. If it will work that is a simple solution. Thank you. I do find Keiths suggestion more along the lines of learning something a bit more complex. I will try both. To add to this, I would like to ask if I can use pin 6 to add another LED? Blink (2) lights at different intervals.
 

KeithWalker

Joined Jul 10, 2017
2,930
During the delay function, the program does not run any code, so using it to blink two LEDs at different intervals would only work if one rate is a multiple of the other. It could probably be done using two of the different internal timers but it will involve a bit of complex low level register programming. I will let you do the research on that one.
 

djsfantasi

Joined Apr 11, 2010
9,131
Hello dj, that's interesting, and simple. I'm new to the ATtiny 85. This particular code is something I find fascinating because of the LDR function and the sleep function and I simply didn't know it might be possible to do it that way. If it will work that is a simple solution. Thank you. I do find Keiths suggestion more along the lines of learning something a bit more complex. I will try both. To add to this, I would like to ask if I can use pin 6 to add another LED? Blink (2) lights at different intervals.
Another solution is to use the millis() function instead of the delay() function to perform your timings. This doesn’t block execution of your code and allows you to schedule many different events, each with their own timings.

You can search for “using millis() instead of delay() to learn this technique. Here is one article that illustrates this technique. It’s a great technique to become familiar with!
 

Thread Starter

fredric58

Joined Nov 28, 2014
252
Hey guys, both are interesting and appreciated comments. As for "using it to blink two LEDs at different intervals would only work if one rate is a multiple of the other." I do not understand the statement. As for "millis" I am a little familiar with it and will study the provided article. Thank you.

Here is a "theoretical question" My goal is to modify this ATtiny 85 and code to trigger a basic latching switch. 1 led blink = high and it latches on. the other LED blink (high) would unlatch to off. My concern is that what if? the device I am turning on is in an "on state." but the READ LDR says it's time to go to sleep before the second LED (high signal) turns the device OFF. it is only a 20 second interval, however it would be possible for the 85 to be put to sleep during that 20 seconds. Which I am pretty sure at this point the battery operated device would continue to run unnecessarily all day until it "woke up again" and resumed it's "on" "off" program. Just thinking ahead and I would believe a "condition" would need to be added to facilitate turning off the powered device before sleep mode occurs. I'm getting ahead of myself but I analyze the crap out of everything. Being a battery powered device I absolutely can not afford for it to run all day unnecessarily. Thank you, Fred
 
Top