Go Down

Topic: serial receive on attiny84 (Read 4081 times) previous topic - next topic

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: [Select]

// 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

Coding Badly


Thank you for the follow-up and code.

ProfePaco

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

leo72

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

mikalhart


leo72

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

Code: [Select]

#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

pescadito

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!

Go Up