Hi, I'm building a few battery powered sensors based on the ATtiny85V (the V chip is somewhat slower and works at lower voltages than the regular ATtiny85) and the nRF24L01. I need one GPIO pin for a reed switch, the rest can be used for the SPI protocol to drive the nRF24L01. Because it's battery powered I need it to be as low power as possible. I stumbled across the 3-pin solution where two pins are free for other purposes, but because the CE pin is tied high it uses a lot more power. I then found the 4-pin solution below:
My problem is that neither the 3-pin nor the 4-pin solution works. When I connect all 5 pins as in the RF24 example everything works but no pins are free for the reed switch. An LED connected to ATtiny pin 3 (CE) blinks in a rhythm and the data packets get sent as they should. When I try to wire up the CSN pin as above, using the capacitor, diode, and resistor, the LED on pin 3 stays on constantly and no packets get sent.
Two possible alternatives would be to use the ATtiny84V which has more GPIO pins anyway, or to use the RST pin as GPIO, but neither of these are optimal in my opinion.
As stopgap solution you could connect a 1K pullup resistor to the reset pin and connect your reed switch via a 3K resistor to it. Your reed switch will then pull RST from VCC to a VCC / 4 * 3 level, which you can easily detect with analogread(). without resetting the Attiny.
Here is a little demonstration sketch that prints the VCC voltage and the RST pin voltage. If you connect a potmeter to GND<>RST<>VCC and turn it slowly you will also notice at what RST pin voltage level your Attiny85 goes into reset state.
To be used with Attinycore, as that supports "Serial".
void setup() {
Serial.begin(9600);// prints on PB0 as TX
}
void loop() {
uint16_t VCC = analogReadVCC(); // VCC in milliVolt
Serial.print("VCC = ");
Serial.print(VCC);// Prints VCC in milliVolt
Serial.print(F(" mV \t Reset pin voltage = "));
Serial.print(analogRead(A0)*(uint32_t) VCC / 1023);
Serial.println(" mV");
delay(500);
}
uint16_t analogReadVCC() {
ADMUX = _BV(MUX3) | _BV(MUX2); // select 1.1V Vref
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC)); // measuring
return 1126400L / ADC;
}
While it won't hurt I don't think you need the "V" version at 3 Volt. It will run happily until 2.7 Volt.
[edit] This example also could give you an easy way to send a low battery alarm as it is measuring VCC.
As stopgap solution you could connect a 1K pullup resistor to the reset pin and connect your reed switch via a 3K resistor to it.
I appreciate the input. I don't consider this a totally elegant solution though, I'd rather use an actual GPIO pin for the reed switch. If that's not possible at all with the ATtiny85, I would use an ATtiny84 before I start repurposing pins.
The thing is I already have the ATtiny85 microcontrollers but if necessary I'll order the bigger chips. They're not prohibitively expensive.
While it won't hurt I don't think you need the "V" version at 3 Volt. It will run happily until 2.7 Volt.
I chose the V version because I want it to run even at lower voltages than 3V. The nRF24L01 apparently runs at as little as 1.9V and I wanted a microcontroller that can do the same.
I made a quick schematic that accomodates the ATtiny84: