Offline
Newbie
Karma: 0
Posts: 35
|
 |
« on: October 15, 2011, 04:59:31 pm » |
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 // 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. attiny85 timer one.ccp tccr1b not declared in this scope
What can i do ?Thanks for your time...
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #1 on: October 17, 2011, 03:47:09 pm » |
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...
|
|
|
|
|
Logged
|
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 43
Posts: 2518
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #2 on: October 17, 2011, 04:26:47 pm » |
You are using Timer1 to call the screenUpdate function every 10ms, correct? Are you using Arduino Tiny to program the 't85 or something else?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #3 on: October 17, 2011, 05:09:13 pm » |
thank you for responding. Yes this is corrrect. No im using the arduino duemillanove as isp to program them.
|
|
|
|
|
Logged
|
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 43
Posts: 2518
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #4 on: October 17, 2011, 08:24:12 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 53
|
 |
« Reply #5 on: October 17, 2011, 08:42:59 pm » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #6 on: October 18, 2011, 10:31:05 am » |
im using the same method
|
|
|
|
|
Logged
|
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 43
Posts: 2518
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #7 on: October 18, 2011, 11:41:20 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #8 on: October 18, 2011, 12:35:02 pm » |
.... not sure how to do that.... Could you pleaaaase help me?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #9 on: October 18, 2011, 02:41:21 pm » |
ok i've been strangling with the code (im a complete newbie...) //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...  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?
|
|
|
|
« Last Edit: October 18, 2011, 03:07:50 pm by pyrforos »
|
Logged
|
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 43
Posts: 2518
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #10 on: October 18, 2011, 03:27:41 pm » |
.... not sure how to do that.... Could you pleaaaase help me?
I'll give it a shot, what's your clock frequency?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #11 on: October 18, 2011, 04:41:21 pm » |
|
|
|
|
|
Logged
|
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 43
Posts: 2518
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #12 on: October 18, 2011, 06:07:41 pm » |
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! //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 } }
|
|
|
|
« Last Edit: October 18, 2011, 08:18:20 pm by Jack Christensen »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #13 on: October 19, 2011, 07:42:46 am » |
a veryy big thanks mate!(LOL Scotchware License  ) Well it blinks but for about 9 or 10 sec ,but if i chanche the value of if (++myCounter == 100) { //has a second elapsed? to 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...
|
|
|
|
« Last Edit: October 19, 2011, 08:27:43 am by pyrforos »
|
Logged
|
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 43
Posts: 2518
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #14 on: October 19, 2011, 08:35:21 am » |
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. //#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
|
|
|
|
|
Logged
|
|
|
|
|
|