Skip to content

Commit

Permalink
add ATtiny84 support
Browse files Browse the repository at this point in the history
  • Loading branch information
jcw committed Oct 17, 2011
1 parent 52a1987 commit 5165eb5
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 63 deletions.
2 changes: 1 addition & 1 deletion Ports.cpp
Expand Up @@ -383,7 +383,7 @@ void UartPlug::flush () {
WRITE_RESULT UartPlug::write (byte data) {
regSet(THR, data);
dev.stop();
#if ARDUINO >= 100 && !defined(__AVR_ATtiny85__)
#if ARDUINO >= 100 && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny85__)
return 1;
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion Ports.h
Expand Up @@ -9,7 +9,7 @@
#include <avr/pgmspace.h>

// keep the ATtiny85 on the "old" conventions until arduino-tiny gets fixed
#if ARDUINO >= 100 && !defined(__AVR_ATtiny85__)
#if ARDUINO >= 100 && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny85__)
#define WRITE_RESULT size_t
#else
#define WRITE_RESULT void
Expand Down
2 changes: 1 addition & 1 deletion PortsLCD.cpp
Expand Up @@ -179,7 +179,7 @@ inline void LiquidCrystalBase::command(byte value) {

inline WRITE_RESULT LiquidCrystalBase::write(byte value) {
send(value, HIGH);
#if ARDUINO >= 100 && !defined(__AVR_ATtiny85__)
#if ARDUINO >= 100 && !defined(__AVR_ATtiny84__) && !defined(__AVR_ATtiny85__)
return 1;
#endif
}
Expand Down
8 changes: 4 additions & 4 deletions RF12.cpp
Expand Up @@ -36,10 +36,10 @@
#elif defined(__AVR_ATtiny84__)

#define RFM_IRQ 2
#define SS_DDR DDRA
#define SS_PORT PORTA
#define SS_BIT 7
#define SPI_SS 3 // PA7, pin 6
#define SS_DDR DDRB
#define SS_PORT PORTB
#define SS_BIT 1
#define SPI_SS 1 // PB1, pin 3
#define SPI_MISO 4 // PA6, pin 7
#define SPI_MOSI 5 // PA5, pin 8
#define SPI_SCK 6 // PA4, pin 9
Expand Down
166 changes: 110 additions & 56 deletions examples/Ports/tiny50hz/tiny50hz.ino
@@ -1,36 +1,48 @@
// ATtiny85 measurement of peak-to-peak current at 50 Hz, w/ moving average.
// 2011-10-06 <jcw@equi4.com> http://opensource.org/licenses/mit-license.php
//
// Note that this "sketch" is not for the ATmega328 but for the ATtiny85,
// Note that this "sketch" is not for the ATmega328 but for the ATtiny84/85,
// see http://jeelabs.org/2011/10/10/ac-current-detection-works/

#include <JeeLib.h>
#include <PortsLCD.h>
#include <avr/sleep.h>

// for an ATtiny85, this compiles to a test code with an LCD + LED attached
// else we assume ATtiny84 and compile the real thing, including RF12 driver

#ifdef __AVR_ATtiny85__
#define TEST_CODE 1
#endif

#if TEST_CODE
#include <PortsLCD.h>
#define LED 1
PortI2C myI2C (1);
LiquidCrystalI2C lcd (myI2C);
#endif

#define ORDER 31
int values[ORDER];
int vmin, vmax;
struct { word last, prev; } payload;
byte lastTime;

static void led (byte on) {
#define LED 1
bitSet(DDRB, LED);
bitWrite(PORTB, LED, on);
#ifdef LED
bitSet(DDRB, LED);
bitWrite(PORTB, LED, on);
#endif
}

static void setupAdc () {
// 2.56V int ref, C2/B4 + C3/B3 diff, 20x
//ADMUX = bit(REFS2) | bit(REFS1) | bit(MUX2) | bit(MUX1) | bit(MUX0);
// 1.1V int ref, C2/B4 + C3/B3 diff, 20x
ADMUX = bit(REFS1) | bit(MUX2) | bit(MUX1) | bit(MUX0);
// disable these pins for digital I/O
DIDR0 |= bit(ADC2D) | bit(ADC3D);
// bipolar
ADCSRB = bit(BIN);
// clock/64 i.e. 128 KHz
ADCSRA = bit(ADEN) | bit(ADPS2) | bit(ADPS1);
// 1.1V int ref, C2/B4 + C3/B3 diff, 20x
ADMUX = bit(REFS1) | bit(MUX2) | bit(MUX1) | bit(MUX0);
// disable these pins for digital I/O
DIDR0 |= bit(ADC2D) | bit(ADC3D);
// bipolar
ADCSRB = bit(BIN);
// clock/8 i.e. 128 KHz
ADCSRA = bit(ADEN) | bit(ADPS1) | bit(ADPS0);
}

static int readAdc () {
Expand All @@ -41,52 +53,94 @@ static int readAdc () {
}

static void measure () {
// initialize
readAdc(); // discard first reading
int accum = 0;
for (byte i = 0; i < ORDER; ++i) {
values[i] = readAdc();
accum += values[i];
}
// acquire and determine min/max
vmin = 32767;
vmax = -32768;
byte next = 0;
for (word i = 0; i < 500; ++i) {
int last = values[next];
values[next] = readAdc();
accum += values[next] - last;
if (++next >= ORDER)
next = 0;
if (accum < vmin) vmin = accum;
if (accum > vmax) vmax = accum;
}
bitClear(PRR, PRADC); // power up the ADC
ADCSRA |= bit(ADEN); // enable the ADC
// initialize
readAdc(); // discard first reading
int accum = 0;
for (byte i = 0; i < ORDER; ++i) {
values[i] = readAdc();
accum += values[i];
}
// acquire and determine min/max
vmin = 32767;
vmax = -32768;
byte next = 0;
for (word i = 0; i < 500; ++i) {
int last = values[next];
values[next] = readAdc();
accum += values[next] - last;
if (++next >= ORDER)
next = 0;
if (accum < vmin) vmin = accum;
if (accum > vmax) vmax = accum;
}
ADCSRA &= ~ bit(ADEN); // disable the ADC
bitSet(PRR, PRADC); // power down the ADC
}

static void setPrescaler (uint8_t mode) {
cli();
CLKPR = bit(CLKPCE);
CLKPR = mode;
sei();
}

void setup () {
led(0);
lcd.begin(16, 2);
lcd.print("Hello, world!");
setupAdc();
setPrescaler(3); // div 8, i.e. 1 MHz
#if TEST_CODE
lcd.begin(16, 2);
lcd.print("Hello, world!");
#else
rf12_initialize(17, RF12_868MHZ, 5);
rf12_sleep(RF12_SLEEP);
#endif
setupAdc();
led(0);
ADCSRA &= ~ bit(ADEN); // disable the ADC
PRR = bit(PRTIM1) | bit(PRUSI) | bit(PRADC); // only keep timer 0 going
}

void loop () {
led(1);
delay(100);
led(0);
delay(900);

byte t = millis();
measure();
t = (byte) millis() - t;
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_mode();
byte nextTime = millis() >> 14; // 16384 ms
if (nextTime == lastTime)
return;
lastTime = nextTime;

lcd.setCursor(0, 1);
lcd.print(vmax - vmin);
lcd.print(' ');
lcd.print(vmin);
lcd.print('-');
lcd.print(vmax);
lcd.print(' ');
lcd.print((int) t);
lcd.print('.');
#if TEST_CODE
led(1);
delay(100);
led(0);

byte t = millis();
measure();
t = (byte) millis() - t;

lcd.setCursor(0, 1);
lcd.print(vmax - vmin);
lcd.print(' ');
lcd.print(vmin);
lcd.print('-');
lcd.print(vmax);
lcd.print(' ');
lcd.print((int) t);
lcd.print('.');
#else
// if (millis() < 900000) return; // don't report in first 15m after power up
measure();
setPrescaler(0); // div 1, i.e. speed up to 8 MHz
payload.prev = payload.last;
payload.last = vmax - vmin;
bitClear(PRR, PRUSI); // enable USI h/w
rf12_sleep(RF12_WAKEUP);
while (!rf12_canSend())
rf12_recvDone();
rf12_sendStart(0, &payload, sizeof payload);
rf12_sendWait(1);
rf12_sleep(RF12_SLEEP);
bitSet(PRR, PRUSI); // disable USI h/w
setPrescaler(3); // div 8, i.e. 1 MHz
#endif
}

0 comments on commit 5165eb5

Please sign in to comment.