Go Down

Topic: attiny85 and TimerOne.h (Read 6 times) previous topic - next topic

pyrforos

hi guys im working on a project with one led matrix and 2 shift registers.Since i use 3 ports on my arduino(latch, data, clock) i was thinking to trasfer my code to an ATTiny85 .
im using this code
Code: [Select]
// 8*8 led matrix 2 shifters
#include <TimerOne.h>

//Pin connected to Pin 12 of 74HC595 (Latch)
int latchPin = 8;
//Pin connected to Pin 11 of 74HC595 (Clock)
int clockPin = 12;
//Pin connected to Pin 14 of 74HC595 (Data)
int dataPin = 11;
uint8_t led[8];
long counter1 = 0;
long counter2 = 0;
void setup() {
//set pins to output
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
led[0] = B11111111;
led[1] = B10000001;
led[2] = B10111101;
led[3] = B10100101;
led[4] = B10100101;
led[5] = B10111101;
led[6] = B10000001;
led[7] = B11111111;
Timer1.initialize(10000);
Timer1.attachInterrupt(screenUpdate);
}
void loop() {
counter1++;
if (counter1 >=100000) {counter2++;}
if (counter2 >= 10000) {
counter1 = 0;
counter2 = 0;
for (int i=0; i<8; i++) {
led[i]= ~led[i];
}
}
}
void screenUpdate() {
uint8_t row = B00000001;
for (byte k = 0; k < 9; k++) {
// Open up the latch ready to receive data!
digitalWrite(latchPin, LOW);
shiftIt(~row );
shiftIt(led[k] ); // LED array
// Close the latch, sending the data in the registers out to the
//matrix
digitalWrite(latchPin, HIGH);
row = row << 1;
}
}
void shiftIt(byte dataOut) {
// Shift out 8 bits LSB first,
// on rising edge of clock
boolean pinState;
//clear shift register read for sending data
digitalWrite(dataPin, LOW);
// for each bit in dataOut send out a bit
for (int i=0; i<8; i++) {
//set clockPin to LOW prior to sending bit
digitalWrite(clockPin, LOW);
// if the value of DataOut and (logical AND) a bitmask
// are true, set pinState to 1 (HIGH)
if ( dataOut & (1<<i) ) {
pinState = HIGH;
}
else {pinState = LOW;
}
//sets dataPin to HIGH or LOW depending on pinState
digitalWrite(dataPin, pinState);
//send bit out on rising edge of clock
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, LOW);
}
//stop shifting
digitalWrite(clockPin, LOW);
}



If i compile it for my duemillanove , no problem, but for my attiny85 i get this error.
Code: [Select]
attiny85 timer one.ccp tccr1b not declared in this scope

What can i do ?Thanks for your time...

pyrforos

So, it seems that the TimerOne library is not suported by attiny85...
Is there any code for driving med matrix without the use of TimerOne library?
PLEASE respond...

Jack Christensen

You are using Timer1 to call the screenUpdate function every 10ms, correct? Are you using Arduino Tiny to program the 't85 or something else?
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

pyrforos

thank you for responding.
Yes this is corrrect.
No im using the arduino duemillanove as isp to program them.

Jack Christensen

Are you programming from the Arduino IDE? What are you selecting from the Tools > Board menu? The standard Arduino IDE will program an ATmega328 or ATmega168.  You'll need something like Arduino Tiny to program an ATtiny85.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

deejayspinz


Are you programming from the Arduino IDE? What are you selecting from the Tools > Board menu? The standard Arduino IDE will program an ATmega328 or ATmega168.  You'll need something like Arduino Tiny to program an ATtiny85.


I have been programming my ATTiny from an Ard Uno using this approach:  http://hlt.media.mit.edu/?p=1229

pyrforos


Jack Christensen

I believe the HLT core uses Counter/Timer0 for millis(). Not sure if they use Timer1.  If not, or if it's used for something you don't use or care about, you should be able to appropriate it.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

pyrforos

.... not sure how to do that.... Could you pleaaaase help me?


pyrforos

#9
Oct 18, 2011, 09:41 pm Last Edit: Oct 18, 2011, 10:07 pm by pyrforos Reason: 1
ok i've been strangling  with the code (im a complete newbie...)
Code: [Select]
//Pin connected to Pin 12 of 74HC595 (Latch)
int latchPin = 0;
//Pin connected to Pin 11 of 74HC595 (Clock)
int clockPin = 1;
//Pin connected to Pin 14 of 74HC595 (Data)
int dataPin = 2;
uint8_t led[8];
long counter1 = 0;
long counter2 = 0;
//unsigned long  time;
long previousMillis = 0;
long interval = 10000;

void setup() {
//set pins to output
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
led[0] = B11111111;
led[1] = B10000001;
led[2] = B10111101;
led[3] = B10100101;
led[4] = B10100101;
led[5] = B10111101;
led[6] = B10000001;
led[7] = B11111111;
//Timer1.initialize(10000);
//Timer1.attachInterrupt(screenUpdate);
}
void loop() {
   

   
counter1++;
if (counter1 >=100000) {counter2++;}
if (counter2 >= 10000) {
counter1 = 0;
counter2 = 0;
for (int i=0; i<8; i++) {
led[i]= ~led[i];
}

}
unsigned long currentMillis = micros();
 if(currentMillis - previousMillis > interval) {
   // save the last time you blinked the LED
   previousMillis = currentMillis;
   screenUpdate();
}
delay(500);
}
void screenUpdate() {


uint8_t row = B00000001;
for (byte k = 0; k < 9; k++) {
// Open up the latch ready to receive data!
digitalWrite(latchPin, LOW);
shiftIt(~row );
shiftIt(led[k] ); // LED array
// Close the latch, sending the data in the registers out to the
//matrix
digitalWrite(latchPin, HIGH);
row = row << 1;
}
}

void shiftIt(byte dataOut) {
// Shift out 8 bits LSB first,
// on rising edge of clock
boolean pinState;
//clear shift register read for sending data
digitalWrite(dataPin, LOW);
// for each bit in dataOut send out a bit
for (int i=0; i<8; i++) {
//set clockPin to LOW prior to sending bit
digitalWrite(clockPin, LOW);
// if the value of DataOut and (logical AND) a bitmask
// are true, set pinState to 1 (HIGH)
if ( dataOut & (1<<i) ) {
pinState = HIGH;
}
else {pinState = LOW;
}
//sets dataPin to HIGH or LOW depending on pinState
digitalWrite(dataPin, pinState);
//send bit out on rising edge of clock
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, LOW);
}
//stop shifting
digitalWrite(clockPin, LOW);

}

but what it does is a very quick flickering .... But i believe is a start... :smiley-red:



EDIT: So news...
If i upload the code to my arduino and use it works.
If i upload it to the ATtiny85 there goes the flickering again... So i suppose is has to do with the internal clock... Is there any way to fix this?

Jack Christensen


.... not sure how to do that.... Could you pleaaaase help me?


I'll give it a shot, what's your clock frequency?
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/


Jack Christensen

#12
Oct 19, 2011, 01:07 am Last Edit: Oct 19, 2011, 03:18 am by Jack Christensen Reason: 1
Well if you haven't changed the fuses from the factory setting, then it's using the internal 8MHz RC oscillator divided by eight, so the CPU clock is 1MHz.

I wrote this using WinAVR.  I don't currently have the HLT core installed, but I did test it with Arduino Tiny and it worked (although I imagine it stepped all over its millis() function in the process, ha!).  I think it should work with HLT, but I recommend you try it standalone first.  Just copy the entire code below into a new sketch, wire an LED to pin 3 (on the DIP package, I assume you're using a DIP?) and see if it blinks on for a second, then off for a second.

If that works, then you only need about the last 30 lines of code as indicated by the comments, try adding those into your sketch. In your setup() function, replace "Timer1.initialize(10000);" and "Timer1.attachInterrupt(screenUpdate);" with "setupTimer1(screenUpdate);".

This is pretty much quick-and-dirty code for a very specific purpose, based on how I understood the requirement. Let me know how (if) it works for you!

Code: [Select]
//Example for Arduino forum.
//Use ATtiny85 Timer/Counter1 to call a function every 10ms.
//In setup(), call setupTimer1() and pass it the name of your function which will
//run as part of the interrupt service routine (ISR) every 10ms. This function must take no
//arguments, return nothing, and should run as quickly as possible. The delay() and millis()
//functions will not work while the ISR is running and so should be avoided.
//Works with 1MHz or 8MHz system clock (others may be possible, but I got lazy).
//
//In this example, the myISR() function simply turns an LED on for a second, then off for a second.
//Connect the LED to DIP pin 3 (PB4).
//
//Jack Christensen 18Oct2011
//
//Scotchware License: If we meet some day, and you think this is worth it, you can buy me a scotch.

#include <avr/io.h>
#include <avr/interrupt.h>

//function prototypes
void setupTimer1(void (*isrPointer)(void));
void setup(void);
void loop(void);
void myISR(void);

#define LED PORTB4                  //connect LED to this pin

#ifndef ARDUINO                     //main() function not required in Arduino environment
int main(void) {
    setup();
    for(;;) {loop();}
    return 0;
}
#endif

void setup(void) {
    DDRB |= _BV(LED);               //set the LED pin as an output
    setupTimer1(myISR);             //set timer1 up to call myISR every 10ms
}

void loop(void) {
}

void myISR() {                      //this function will be called every 10ms
    static uint8_t myCounter;

    if (++myCounter == 100) {       //has a second elapsed?
        myCounter = 0;
        PINB |= _BV(LED);           //toggle the LED
    }
}

//Copy code from here down, AND uncomment the following line and move it near the top of your sketch BEFORE the setup() function.
//void setupTimer1(void (*isrPointer)(void));        //function prototype for setupTimer1()
void (*userISR)(void);              //pointer to the user's ISR

void setupTimer1(void (*isrPointer)(void)) {
    userISR = isrPointer;           //save the pointer to the user's ISR
    //set timer1 up to generate an interrupt every millisecond
    TCCR1 |= _BV(CTC1);             //clear timer1 when it matches the value in OCR1C
    TIMSK |= _BV(OCIE1A);           //enable interrupt when OCR1A matches the timer value
    sei();                          //enable global interrupts
    OCR1A = 124;                    //set the match value for interrupt
    OCR1C = 124;                    //and the same match value to clear the timer
#if F_CPU == 1000000                //1MHz system clock
    TCCR1 |= _BV(CS12);             //set prescaler to divide by 8 (this starts the timer)
#elif F_CPU == 8000000              //8MHz system clock
    TCCR1 |= _BV(CS12) | _BV(CS11) | _BV(CS10);    //set prescaler to divide by 64 (this starts the timer)
#else
    Clock must be 1MHz or 8MHz!     //Error, only 1MHz or 8MHz clock (F_CPU) supported.
#endif
}

ISR(TIMER1_COMPA_vect) {            //handles the Timer1 Compare Match A interrupt
    static uint8_t interruptCount;

    if (++interruptCount == 10) {   //have there been 10 interrupts? (i.e. 10ms)
        interruptCount = 0;         //yes, reset the counter
        userISR();                  //and call the user's ISR
    }
}
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

pyrforos

#13
Oct 19, 2011, 02:42 pm Last Edit: Oct 19, 2011, 03:27 pm by pyrforos Reason: 1
a veryy big thanks mate!(LOL Scotchware License XD XD)

Well it blinks but for about 9 or 10 sec ,but if i chanche the value of
Code: [Select]
  if (++myCounter == 100) {       //has a second elapsed?
to
Code: [Select]
  if (++myCounter == 10) {       //has a second elapsed? is seems to be working :) for the blinky

im sorry, doesn't work on the project... i tried to play with the values but with no success...

Jack Christensen

Is it maybe blinking every 8 seconds? Maybe it thinks the clock is 8MHz when it's actually 1MHz. Comment out the lines indicated below, this will hard-code it for a 1MHz clock.

Code: [Select]
//#if F_CPU == 1000000                //1MHz system clock
    TCCR1 |= _BV(CS12);             //set prescaler to divide by 8 (this starts the timer)
//#elif F_CPU == 8000000              //8MHz system clock
//    TCCR1 |= _BV(CS12) | _BV(CS11) | _BV(CS10);    //set prescaler to divide by 64 (this starts the timer)
//#else
//    Clock must be 1MHz or 8MHz!     //Error, only 1MHz or 8MHz clock (F_CPU) supported.
//#endif
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Go Up