Now I want to write this code on an Attiny85 , but I am getting an error. I looked online for solutions and seems that the TImerOne.h isn't compatible with the Attiny85. Does it make sense? This code works fine on my Arduino Uno.
and the code (I changed " int AC_pin = 1" .It is originally "int AC_pin = 11;") :
/*
AC Light Control
Updated by Robert Twomey <rtwomey@u.washington.edu>
Changed zero-crossing detection to look for RISING edge rather
than falling. (originally it was only chopping the negative half
of the AC wave form).
Also changed the dim_check() to turn on the Triac, leaving it on
until the zero_cross_detect() turn's it off.
Adapted from sketch by Ryan McLaughlin <ryanjmclaughlin@gmail.com>
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230333861/30
*/
#include <TimerOne.h> // Avaiable from http://www.arduino.cc/playground/Code/Timer1
volatile int i=0; // Variable to use as a counter
volatile boolean zero_cross=0; // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 1; // Output to Opto Triac
int dim = 0; // Dimming level (0-128) 0 = on, 128 = 0ff
int inc=1; // counting up or down, 1=up, -1=down
int freqStep = 65; // This is the delay-per-brightness step in microseconds.
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want.
//
// The only tricky part is that the chopper circuit chops the AC wave twice per
// cycle, once on the positive half and once at the negative half. This meeans
// the chopping happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply.
// To calculate freqStep you divide the length of one full half-wave of the power
// cycle (in microseconds) by the number of brightness steps.
//
// (1000000 uS / 120 Hz) / 128 brightness steps = 65 uS / brightness step
//
// 1000000 us / 120 Hz = 8333 uS, length of one half-wave.
void setup() { // Begin setup
pinMode(AC_pin, OUTPUT); // Set the Triac pin as output
attachInterrupt(0, zero_cross_detect, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
Timer1.initialize(freqStep); // Initialize TimerOne library for the freq we need
Timer1.attachInterrupt(dim_check, freqStep);
// Use the TimerOne Library to attach an interrupt
// to the function we use to check to see if it is
// the right time to fire the triac. This function
// will now run every freqStep in microseconds.
}
void zero_cross_detect() {
zero_cross = true; // set the boolean to true to tell our dimming function that a zero cross has occured
i=0;
digitalWrite(AC_pin, LOW); // turn off TRIAC (and AC)
}
// Turn on the TRIAC at the appropriate time
void dim_check() {
if(zero_cross == true) {
if(i>=dim) {
digitalWrite(AC_pin, HIGH); // turn on light
i=0; // reset time step counter
zero_cross = false; //reset zero cross detection
}
else {
i++; // increment time step counter
}
}
}
void loop() {
dim+=inc;
if((dim>=128) || (dim<=0))
inc*=-1;
delay(18);
}
error:
acdimmer_sleeping.ino: In function 'void setup()':
acdimmer_sleeping:16: error: expected unqualified-id before '.' token
acdimmer_sleeping:17: error: expected unqualified-id before '.' token
Ok now here the new error message I get: TimerOne doesn't seems to be accepted.
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp: In member function 'void TimerOne::initialize(long int)':
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:51: error: 'TCCR1A' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:52: error: 'TCCR1B' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:52: error: 'WGM13' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp: In member function 'void TimerOne::setPeriod(long int)':
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:70: error: 'ICR1' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:73: error: 'TCCR1B' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp: In member function 'void TimerOne::pwm(char, int, long int)':
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:96: error: 'TCCR1A' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:100: error: 'TCCR1A' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp: In member function 'void TimerOne::disablePwm(char)':
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:109: error: 'TCCR1A' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:110: error: 'TCCR1A' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp: In member function 'void TimerOne::attachInterrupt(void (*)(), long int)':
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:117: error: 'TIMSK1' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp: In member function 'void TimerOne::detachInterrupt()':
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:125: error: 'TIMSK1' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp: In member function 'void TimerOne::resume()':
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:130: error: 'TCCR1B' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp: In member function 'void TimerOne::start()':
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:142: error: 'TIMSK1' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:143: error: 'PSRSYNC' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp: In member function 'void TimerOne::stop()':
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:163: error: 'TCCR1B' was not declared in this scope
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp: In member function 'long unsigned int TimerOne::read()':
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:204: error: 'ICR1' was not declared in this scope
Using ATtinys doesn't make much practical sense when you factor in the time spent programming, getting libraries to work, etc. You can easily get Mega328 boards for $6 plus change. eg. http://www.ebay.com/itm/310562519074
If you use ATtinys it's because you enjoy using them.
fungus:
PS: I wish there were shops around here that you could just pop in and buy an ATtiny84.
One of the advantages of living where I do ... mouser.com is close enough that, no matter what I choose for shipping, the package arrives the next day.
C:\arduino-1.0.3-windows\arduino-1.0.3\libraries\Timer1\TimerOne.cpp:148: error: 'PSRSYNC' was not declared in this scope
Searching the ATmega328 datasheet we find that PSRSYNC is used when resetting the prescaler. There are only 36 Google hits of PSRSYNC on this forum. ("pig latin" has two hits.) And, it looks like most of the 36 hits are posts from users like you who want TimerOne to work on other processors. Clearly, resetting the prescaler is not done very often in the Arduino world.
The next quest is "why". Is it necessary to reset the prescaler for TimerOne to function correctly? The method of interest...
void TimerOne::start() // AR addition, renamed by Lex to reflect it's actual role
{
unsigned int tcnt1;
TIMSK1 &= ~_BV(TOIE1); // AR added
GTCCR |= _BV(PSRSYNC); // AR added - reset prescaler (NB: shared with all 16 bit timers);
oldSREG = SREG; // AR - save status register
cli(); // AR - Disable interrupts
TCNT1 = 0;
SREG = oldSREG; // AR - Restore status register
do { // Nothing -- wait until timer moved on from zero - otherwise get a phantom interrupt
oldSREG = SREG;
cli();
tcnt1 = TCNT1;
SREG = oldSREG;
} while (tcnt1==0);
// TIFR1 = 0xff; // AR - Clear interrupt flags
// TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit
}
I cannot find any documentation for the start method. In addition, this comment is at the top of the header file...
start() amended to enable interrupts
Clearly that is no longer true. We cannot rely on the comments being correct.
As far as I can tell, start is only called by restart which is never called from the library. There is no calling context for start. We're left with no answer as to why the author felt it was necessary to reset the prescaler (or even when or why we would call start or restart).