Pages: [1]   Go Down
Author Topic: serial receive on attiny84  (Read 3695 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi All,
I've been using (and loving) the arduino-tiny core: http://code.google.com/p/arduino-tiny/
with an ATtiny84 and Arduino IDE v.22 (my project uses too many third-party libraries at the moment to make the switch to 1.0 right now).
I was struggling to get serial communication to work with it. There's a debug_serial library but I need bidirectional communication.
I came across this thread that said NewSoftSerial does the trick, http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1285218245/all
so I downloaded NewSoftSerial10c from http://arduiniana.org/libraries/newsoftserial/
Sure enough transmitting works fine, but reception not at all.
Digging into NewSoftSerial.cpp you can see that the necessary pin change interrupts are only defined for ATmega168 and 328.
I added references for ATtiny84, and it seems to be working fine so far. I've only tested it on pin D10 as receive, so it might not work on every pin. Of course, use at your own risk...
Nick

Code:
// Abstractions for maximum portability between processors
// These are macros to associate pins to pin change interrupts
#if !defined(digitalPinToPCICR) // Courtesy Paul Stoffregen
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)NULL))
#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)NULL))))
#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))
#elif defined(__AVR_ATtiny84__)
#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 10) ? (&GIMSK) : ((uint8_t *)NULL))
#define digitalPinToPCICRbit(p) (((p) <= 2) ? 5 : 4)
#define digitalPinToPCMSK(p)    (((p) <= 2) ? (&PCMSK1) : (((p) <= 10) ? (&PCMSK0) : ((uint8_t *)NULL)))
#define digitalPinToPCMSKbit(p) (((p) <= 2) ? (p) : (((p) - 10) * -1))
#else
#define digitalPinToPCICR(p)    ((uint8_t *)NULL)
#define digitalPinToPCICRbit(p) 0
#define digitalPinToPCMSK(p)    ((uint8_t *)NULL)
#define digitalPinToPCMSKbit(p) 0
#endif
#endif
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 197
Posts: 12741
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Thank you for the follow-up and code.
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 128
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Very interesting. I think I will use it on a ATtiny85...
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank your for your solution. That was a problem that I discovered a couple of months ago too.
Logged


Austin, TX USA
Offline Offline
God Member
*****
Karma: 4
Posts: 997
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cool indeed.  Thanks!

Mikal
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

For those is interested in, here is the code for Attinyx5 too:

Code:
#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || (__AVR_ATtiny85__)
#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 5) ? (&GIMSK) : ((uint8_t *)NULL))
#define digitalPinToPCICRbit(p) 5
#define digitalPinToPCMSK(p)    (((p) >= 0 && (p) <= 5) ? (&PCMSK) : ((uint8_t *)NULL))
#define digitalPinToPCMSKbit(p) (p)

Not completely tested but should work
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

NewSoftwareSerial replace SoftwareSerial for AtTiny85
Great!! it worket at 4800 and 9600 for attiny85!!

just download NewSoftSerial10c from http://arduiniana.org/libraries/newsoftserial/
add as before:

#elif defined(__AVR_ATtiny84__)                                                             //mymodif here
#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 10) ? (&GIMSK) : ((uint8_t *)NULL))   
#define digitalPinToPCICRbit(p) (((p) <= 2) ? 5 : 4)
#define digitalPinToPCMSK(p)    (((p) <= 2) ? (&PCMSK1) : (((p) <= 10) ? (&PCMSK0) : ((uint8_t *)NULL)))
#define digitalPinToPCMSKbit(p) (((p) <= 2) ? (p) : (((p) - 10) * -1))

#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || (__AVR_ATtiny85__)          //mymodif here
#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 5) ? (&GIMSK) : ((uint8_t *)NULL))
#define digitalPinToPCICRbit(p) 5
#define digitalPinToPCMSK(p)    (((p) >= 0 && (p) <= 5) ? (&PCMSK) : ((uint8_t *)NULL))
#define digitalPinToPCMSKbit(p) (p)

and add

void NewSoftSerial::enable_timer0(bool enable) 
{
  if (enable)
#if defined(__AVR_ATmega8__) || (__AVR_ATtiny85__) //mymodif here
    sbi(TIMSK, TOIE0);
#else
    sbi(TIMSK0, TOIE0);
#endif
  else
#if defined(__AVR_ATmega8__) || (__AVR_ATtiny85__) //mymodif here
    cbi(TIMSK, TOIE0);
#else
    cbi(TIMSK0, TOIE0);
#endif
}

best regards, pescadito!
Logged

Pages: [1]   Go Up
Jump to: