Using SoftwareSerial, sleep and external interrupt on ATTiny85

Hi all,

I have spent some time searching for a code example that could fit my next project, but found nothing that I managed to adapt to my wishlist:

  • Preferably ATTiny85 based (small, cheap, low power).
  • Sleep mode to save power when no action is needed.
  • Wake up when any of two pins are changed :
  • Rx pin on SoftwareSerial input
  • A RCWL-0516 "radar" doppler sensor

I found some examples where a watchdog timer was used as interrupt (not what I need), plus this project that I successfully tested to do sleep / wake up procedures with two different input pins, but it seemed to be incompatible with SoftwareSerial. Error message :

    Arduino: 1.8.2 (Windows 10), Board: "ATtiny25/45/85, ATtiny85, Internal 1 MHz"
    libraries\SoftwareSerial\SoftwareSerial.cpp.o (symbol from plugin): In function `SoftwareSerial::read()':
    (.text+0x0): multiple definition of `__vector_2'

    sketch\test_attiny85_sleep.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
    collect2.exe: error: ld returned 1 exit status

    exit status 1
    Error compiling for board ATtiny25/45/85.

    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.

I would appreciate if anyone can advice on existing code examples, or how to modify a watchdog timer based code to monitor two input pins. Maybe this or this could be modified (if compatible with SoftwareSerial).

The project will be a few slave units as stated above, controlled by a master unit that also will accept alarms from the slaves. This is working just fine in my current setup, I just want to add sleep mode to save power in the slave units.

Thanks.

I think I am close now... I managed to wake up and receive data via SoftwareSerial :

#include <SoftwareSerial.h>
#include <avr/sleep.h>   
#include <avr/power.h>    

unsigned long rx_millis;
unsigned long led_millis;

// ATTINY85                                                           physical pin #
// RESET                                                              1
#define RCWL_pin 3              // InPin from doppler radar module    2
#define LED_pin 4               // led                                3
// GND                                                                4
#define BZR_pin 0               // audio buzzer (active)              5
SoftwareSerial mySerial(2, 1);  // HC-12 radio (RX, TX)               7,6
// VCC                                                                8

void setup() {
  mySerial.begin(2400);
  pinMode(RCWL_pin, INPUT);
  pinMode(LED_pin, OUTPUT);
  pinMode(BZR_pin, OUTPUT);
  rx_millis = millis();
  led_millis = millis();
  attachInterrupt (3, wakeup, CHANGE);  // attach interrupt handler
}

void wakeup() {    
  sleep_disable ();      
  power_all_enable ();   
  rx_millis = millis();
}

void loop() {
  if (millis() > led_millis + 500) {                    // blink = awake indicator
    digitalWrite(LED_pin, !digitalRead(LED_pin));
    led_millis = millis();
  }

/* By manually transmitting a series of 4 bytes of data from another Arduino, I can
 * prevent this ATTiny from sleeping. I can also hear the 4 beeps. 
 * If I let it goto sleep, it awakes when I make the next transmission - with 4 new beeps. 
 */
  while (mySerial.available()) {                        // first recieved byte => wake up works ok
    uint8_t j = mySerial.read();
    digitalWrite(BZR_pin, 1);                           // one beep for each byte recieved
    delay(5);
    digitalWrite(BZR_pin, 0);
    delay(200);
    rx_millis = millis();
  }

  if (millis() > rx_millis + 10000) {                   // turn off the light & sleep after 10 seconds inactivity
    digitalWrite(LED_pin, 0);
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    sleep_cpu();
  }
}

To start with, the led keeps blinking to indicate awake state.
I can keep things like that by feeding mySerial with data from another Arduno (using series of 4 bytes).
When doing that, I can hear one beep for each byte recieved.
If I stop feeding it, it falls asleep (led stops blinking).
When I continue sending data, I hear the 4 beeps and the led starts blinking.

I have no idea how this can work, because I have not specified pin 2 as interrupt source.
But I need pin 3 also to do the same wakeup, and tried to add it in the code above but pin 3 does not wakeup.

Any ideas ?