Skip to content

Instantly share code, notes, and snippets.

@jscrane jscrane/.gitignore
Last active Feb 20, 2019

Embed
What would you like to do?
TinySensor sketch
.lib
*.cpp.o
tinysensor.ino.bin
tinysensor.ino.elf
tinysensor.eep
�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������

Using uC-Makefile and avrdude

$ make -I ~/src/uC-Makefile write-fuses write-flash
$ avrdude -v -p t84 -P /dev/ttyUSB0 -b 19200 -c avrisp -U eeprom:w:1.eep

Avrdude only

$ avrdude -v -p t84 -P /dev/ttyUSB0 -b 19200 -c avrisp -U flash:w:fw.bin -U eeprom:w:1.eep -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xfe:m

This sketch now requires the damellis core for attiny and my SPI library.

�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
BOARD=t84db
include arduino-tiny.mk
// Jeelib no longer compiles under Arduino (for me anyway) so
// this is a cut-down version.
// See https://github.com/jcw/jeelib/blob/master/Ports.cpp for (c)
#include <Arduino.h>
#include <avr/sleep.h>
#include <util/atomic.h>
#include "sleepy.h"
static volatile byte watchdogCounter;
static byte backupMode = 0;
void Sleepy::watchdogEvent(void) {
++watchdogCounter;
}
void Sleepy::watchdogInterrupts (char mode) {
#ifndef WDTCSR
#define WDTCSR WDTCR
#endif
// correct for the fact that WDP3 is *not* in bit position 3!
if (mode & bit(3))
mode ^= bit(3) | bit(WDP3);
// pre-calculate the WDTCSR value, can't do it inside the timed sequence
// we only generate interrupts, no reset
byte wdtcsr = mode >= 0 ? bit(WDIE) | mode : backupMode;
if(mode>=0) backupMode = WDTCSR;
MCUSR &= ~(1<<WDRF);
ATOMIC_BLOCK(ATOMIC_FORCEON) {
WDTCSR |= (1<<WDCE) | (1<<WDE); // timed sequence
WDTCSR = wdtcsr;
}
}
/// @see http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html
void Sleepy::powerDown (void) {
byte adcsraSave = ADCSRA;
ADCSRA &= ~ bit(ADEN); // disable the ADC
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
ATOMIC_BLOCK(ATOMIC_FORCEON) {
sleep_enable();
// sleep_bod_disable(); // can't use this - not in my avr-libc version!
#ifdef BODSE
MCUCR = MCUCR | bit(BODSE) | bit(BODS); // timed sequence
MCUCR = (MCUCR & ~ bit(BODSE)) | bit(BODS);
#endif
}
sleep_cpu();
sleep_disable();
// re-enable what we disabled
ADCSRA = adcsraSave;
}
void Sleepy::loseSomeTime(word msecs) {
word msleft = msecs;
// only slow down for periods longer than the watchdog granularity
while (msleft >= 16) {
char wdp = 0; // wdp 0..9 corresponds to roughly 16..8192 ms
// calc wdp as log2(msleft/16), i.e. loop & inc while next value is ok
for (word m = msleft; m >= 32; m >>= 1)
if (++wdp >= 9)
break;
watchdogCounter = 0;
watchdogInterrupts(wdp);
powerDown();
watchdogInterrupts(-1); // off
// when interrupted, our best guess is that half the time has passed
word halfms = 8 << wdp;
msleft -= halfms;
if (watchdogCounter == 0) {
break;
}
msleft -= halfms;
}
// adjust the milli ticks, since we will have missed several
extern volatile unsigned long timer0_millis;
timer0_millis += msecs - msleft;
}
#ifndef __SLEEPY_H__
#define __SLEEPY_H__
class Sleepy {
public:
static void watchdogEvent(void);
static void watchdogInterrupts(char mode);
static void powerDown(void);
static void loseSomeTime(word ms);
};
#endif
#ifndef TINYSENSOR_H
#define TINYSENSOR_H
const unsigned char sensor_type_id = 0;
struct sensor_payload_t
{
uint32_t ms;
uint8_t light, status;
int16_t humidity, temperature;
uint16_t battery;
};
#endif
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <EEPROM.h>
#include <DHT.h>
#include "tinysensor.h"
#include "sleepy.h"
const uint8_t CE_PIN = 8;
const uint8_t CS_PIN = 7;
const uint8_t DHT_PIN = 2;
RF24 radio(CE_PIN, CS_PIN);
RF24Network network(radio);
DHT dht;
const uint8_t channel = 90;
const uint16_t master_node = 0;
uint16_t this_node;
const uint8_t retry_count = 5; // 250+5*15*250 = 19mS
const uint8_t retry_delay = 15; // 15*250uS
const uint32_t interval = 60000;
const uint32_t min_interval = 15000;
void setup(void)
{
pinMode(A1, INPUT_PULLUP);
dht.setup(DHT_PIN);
SPI.begin();
radio.begin();
radio.enableDynamicPayloads();
radio.setRetries(retry_delay, retry_count);
this_node = EEPROM.read(0);
network.begin(channel, this_node);
}
ISR(WDT_vect) { Sleepy::watchdogEvent(); }
void loop(void)
{
radio.powerUp();
network.update();
uint8_t light = 255 - analogRead(A1) / 4;
uint16_t battery = analogRead(A0);
sensor_payload_t payload = { millis(), light, dht.getStatus(), dht.getHumidity(), dht.getTemperature(), battery };
RF24NetworkHeader header(master_node, sensor_type_id);
bool ok = network.write(header, &payload, sizeof(payload));
radio.powerDown();
uint32_t l = light;
uint32_t s = 1000 * (255 - l) / 3;
if (s < min_interval)
s = min_interval;
do {
uint32_t i = min(s, interval);
Sleepy::loseSomeTime(i);
s -= i;
} while (s > 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.