2

I have an arduino uno as the master I2C device talking to an ATtiny85 as the slave. What I want to do is have the Attiny85 receive a message from the UNO to tell it to power off which will then trigger a mosfet to turn all the power off to the UNO and then sleep for a period of time. This all seems to be working fine but every now and then I seem to get a lock up where the UNO just stays on. Is what I am doing below ok. I am worried about TinyWireS_stop_check() call and if that is going to be messed up by the fact I have delays in the loop and also the fact it goes to sleep.

Thanks

// Code for the ATtiny85
#include <powernap.h>
#include <TinyWireSlave.h>

#define I2C_SLAVE_ADDRESS 0x4 // Address of the slave
#define POWER A3
// The default buffer size, Can't recall the scope of defines right now
#ifndef TWI_RX_BUFFER_SIZE
#define TWI_RX_BUFFER_SIZE ( 16 )
#endif

uint8_t sleepInterval = 1;
bool cycleComplete = false;
bool sleepNow = false;

Napper napper;

enum InterComms
{
    IDLE = 0,
    PWR_OFF = 1,
    CALIBRATION_MODE = 2,
    SLEEP_INTERVAL = 3,
    KEEPALIVE = 4
};

char rxChrData; //Receives the data.
char rxString[12];  //Varbiable for holding one string of data.
int rxIndex = 0; //Used to index rxString.
int i = 99;
bool calibrationMode = true; //Always true when power is turned on


void requestEvent()
{
    TinyWireS.send(calibrationMode);
}

void receiveEvent(uint8_t howMany)
{
    if (TinyWireS.available()) {
        if (howMany < 1)
        {   // Sanity-check
            return;
        }
        if (howMany > TWI_RX_BUFFER_SIZE)
        {   // Also insane number
            return;
        }

        howMany--;
        uint8_t byte = TinyWireS.receive();
        switch (byte)
        {
        case PWR_OFF:
            i = 100;
            sleepNow = true;
            break;
        case CALIBRATION_MODE:
            calibrationMode = true;
            i = 110;
            break;
        case SLEEP_INTERVAL:
            i = 120;
            howMany--;
            sleepInterval = TinyWireS.receive();
            break;
        case KEEPALIVE:
            i = 130;
            measureTimer = millis();
            break;
        default:
            i = IDLE;
            break;
        }
        //Make sure buffer is emppty
        while(howMany--)
            TinyWireS.receive();
    }
}

void setup()
{
    pinMode(POWER, OUTPUT);
    analogWrite(POWER, 255);

    TinyWireS.begin(I2C_SLAVE_ADDRESS); // join i2c network

    TinyWireS.onReceive(receiveEvent); // not using this
    TinyWireS.onRequest(requestEvent);

    napper.setup();

    measureTimer = millis();
    return;
}

void loop()
{
    unsigned long currentMillis = millis();

    TinyWireS_stop_check();

    if (sleepNow)
    {
        sleepNow = false;
        tws_delay(2000);
        cycleComplete = true;
        calibrationMode = false;
        analogWrite(POWER, 0);
        tws_delay(200);
        napper.napminutes(sleepInterval);
        analogWrite(POWER, 255);
        cycleComplete = false;
        //Reset timer
        measureTimer = millis();
    }

    if ((unsigned long)(currentMillis - measureTimer) > (300000) /*&& !cycleComplete*/)
    {
        analogWrite(POWER, 0);
        tws_delay(1000);
        analogWrite(POWER, 255);
        measureTimer = millis();
    }
}
  • If you are trying to save power, have you considered getting rid of the ATTINY85 and transistor completely? Power the UNO directly (not using the on board regulator) and have it put itself into deep sleep (where it uses almost no power) on receipt of your message. You could also wake on receipt of of another message. All it would take is a couple free pins on the UNO, and would be a much lower power (and simpler) solution. – bigjosh Sep 25 '17 at 13:24
  • Thanks for the reply. The attiny powers down other modules along with the UNO so unfortunately just putting the uno to sleep wouldnt be enough. The uno will be replaced by a standalone atmega328p. – SpeedOfSpin Sep 25 '17 at 14:46
  • Could you have the UNO be the master controller and have it control the power to the other devices? Likely all it would take is one pin on the UNO (or bare 382) connected to a transistor. – bigjosh Sep 25 '17 at 15:25
  • 1
    Can you post the schematic of your circuit? Moreover if you turn off the UNO but then put power to its pins because the I2C is still on, you'll power it again... – frarugi87 Sep 25 '17 at 15:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.