I have a number of ATTiny84 boards from back with Nathan Chantrell, Jean-Claude Wippler, the folks at Open Energy Monitor, and others were using this MCU and RFM12B radios (and later the RFM69CW in compatible mode) to send sensor data to a Raspberry Pi gateway.
Back then the Arduino IDE core I was using was different than the modern one that Spence Konde (@DrAzzy) created.
The original Nathan Chantrell TinyTx sketches suggested in the comments:
// Requires Arduino IDE with arduino-tiny core: http://code.google.com/p/arduino-tiny/
I still worked with ATTiny84 a bit here and there, but found it more and more difficult to maintain a working version of that older core.
Today I tried out the Spence Konde ATTinyCore ( 1.5.2) for the first time. It is awesome.
I got out the old TinyTx sketch (below) and found that it compiled on the first try.
I uploaded it to a breadboard version of the early RFM2Pi from Open Energy Monitor.
The RFM69CW sends one packet successfully, then hangs.
I added some code to turn on an LED during setup, then turn it off after the code reaches a certain point. I found that the MCU hangs at "sendWait(2)" in the rfwrite function.
If I replace this with "delay(5)" the sketch works as expected, transmitting a counter every 10 seconds.
This could be hardware. Breadboards are notorious, especially with these radios. I tested wiring it a few different ways. I tested more than one RFM69CW radio. Still, could be hardware.
My question for this forum is: could it be something incompatible in the JeeLib sendWait method and the ATTinyCore?
//----------------------------------------------------------------------------------------------------------------------
// TinyTX Send test, sends an incrementing counter and battery voltage every 10 seconds
// By Nathan Chantrell. For hardware design see http://nathan.chantrell.net/tinytx
//
// Licenced under the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) licence:
// http://creativecommons.org/licenses/by-sa/3.0/
//----------------------------------------------------------------------------------------------------------------------
#define RF69_COMPAT 1
#include <JeeLib.h> // https://github.com/jcw/jeelib
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // interrupt handler for JeeLabs Sleepy power saving
#define myNodeID 28 // RF12 node ID in the range 1-30
#define network 210 // RF12 Network group.
#define freq RF12_433MHZ // Frequency of RFM12B module
//#define USE_ACK // Enable ACKs, comment out to disable
#define RETRY_PERIOD 5 // How soon to retry (in seconds) if ACK didn't come in
#define RETRY_LIMIT 5 // Maximum number of times to retry
#define ACK_TIME 10 // Number of milliseconds to wait for an ack
int counter;
//########################################################################################################################
//Data Structure to be sent
//########################################################################################################################
typedef struct {
int counter; // counter
int supplyV; // Supply voltage
} Payload;
Payload tinytx;
// Wait a few milliseconds for proper ACK
#ifdef USE_ACK
static byte waitForAck() {
MilliTimer ackTimer;
while (!ackTimer.poll(ACK_TIME)) {
if (rf12_recvDone() && rf12_crc == 0 &&
rf12_hdr == (RF12_HDR_DST | RF12_HDR_CTL | myNodeID))
return 1;
}
return 0;
}
#endif
//--------------------------------------------------------------------------------------------------
// Send payload data via RF
//-------------------------------------------------------------------------------------------------
static void rfwrite(){
#ifdef USE_ACK
for (byte i = 0; i <= RETRY_LIMIT; ++i) { // tx and wait for ack up to RETRY_LIMIT times
rf12_sleep(-1); // Wake up RF module
while (!rf12_canSend())
rf12_recvDone();
rf12_sendStart(RF12_HDR_ACK, &tinytx, sizeof tinytx);
rf12_sendWait(2); // Wait for RF to finish sending while in standby mode
byte acked = waitForAck(); // Wait for ACK
rf12_sleep(0); // Put RF module to sleep
if (acked) { return; } // Return if ACK received
Sleepy::loseSomeTime(RETRY_PERIOD * 1000); // If no ack received wait and try again
}
#else
rf12_sleep(-1); // Wake up RF module
rf12_sendNow(0, &tinytx, sizeof tinytx);
rf12_sendWait(2); // Wait for RF to finish sending while in standby mode. BB: The sketch currently hangs here.
//delay(5); //BB: Delay(5) will work in place of rf12_sendWait(2). The sketch will then dutifully send messages each time interval.
digitalWrite(8, LOW); //BB: The sketch doesn't currently get past rf12_sendWait(2) and the LED stays on. Sketch stops.
rf12_sleep(0); // Put RF module to sleep
return;
#endif
}
//--------------------------------------------------------------------------------------------------
// Read current supply voltage
//--------------------------------------------------------------------------------------------------
long readVcc() {
bitClear(PRR, PRADC); ADCSRA |= bit(ADEN); // Enable the ADC
long result;
// Read 1.1V reference against Vcc
#if defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega328
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate Vcc in mV
ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
return result;
}
//########################################################################################################################
void setup() {
pinMode(8, OUTPUT);
digitalWrite(8, HIGH); // turn the LED off by making the voltage LOW
rf12_initialize(myNodeID,freq,network); // Initialize RFM12 with settings defined above
rf12_sleep(0); // Put the RFM12 to sleep
PRR = bit(PRTIM1); // only keep timer 0 going
ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
}
void loop() {
counter++;
tinytx.counter = (counter); // Get temperature reading and convert to integer, reversed at receiving end
tinytx.supplyV = readVcc(); // Get supply voltage
rfwrite(); // Send data via RF
Sleepy::loseSomeTime(10000); //JeeLabs power save function: enter low power mode for 10 seconds (valid range 16-65000 ms)
}



