1 |
// ATtiny412 / ARDUINO
|
2 |
// _____
|
3 |
// VDD 1|* |8 GND
|
4 |
// (DAC) (AIN6) PA6 0 2| |7 4~ PA3 (AIN3)(SCK)(EXTCLK)
|
5 |
// (AIN7) PA7 1 3| |6 5 PA0 (nRESET/UPDI)
|
6 |
// (MOSI)(TXD*)(SDA) (AIN1) PA1 2 4|_____|5 3 PA2 (AIN2)(MISO)(RXD*)(SCL)
|
7 |
|
8 |
// Programmieradapter linke Seite Laptop
|
9 |
// Ausgang Trigger auf Pin 2&3 schält Pin 5&7
|
10 |
// dazwischen schläft er, Stromverbrauch ~0,5µA
|
11 |
// clock 8MHz, bei 1MHz ist RF-timing zu ungenau
|
12 |
|
13 |
#include <avr/sleep.h> // Sleep Modes
|
14 |
|
15 |
const int buttonPin = 2; // pin 4 / PCINT1
|
16 |
const int reedPin = 1; // pin 3 / PCINT7
|
17 |
const int rfPin = 3; // pin 5
|
18 |
const int ledPin = 4; // pin 7
|
19 |
const int Unused1 = 0; // pin 2
|
20 |
const int Unused2 = 5; // pin 6 / UPDI
|
21 |
volatile bool eventButton = false;
|
22 |
volatile bool eventSensorOn = false;
|
23 |
volatile bool eventSensorOff = false;
|
24 |
const int txRepeat = 15; // Original 30
|
25 |
const int txPulselength = 350; // protocol 1
|
26 |
|
27 |
void rfSend(unsigned long code, byte length) {
|
28 |
for (int nRepeat = 0; nRepeat < txRepeat; nRepeat++) {
|
29 |
for (char i = length - 1; i >= 0; i--) {
|
30 |
if (code & (1L << i))
|
31 |
rfTransmit(3, 1); // protocol 1
|
32 |
else
|
33 |
rfTransmit(1, 3); // protocol 1
|
34 |
}
|
35 |
rfTransmit(1, 31); // protocol 1
|
36 |
}
|
37 |
digitalWrite(rfPin, LOW);
|
38 |
}
|
39 |
|
40 |
void delay_pulselengths(uint16_t us)
|
41 |
{
|
42 |
while (us > 0)
|
43 |
{
|
44 |
delayMicroseconds(txPulselength);
|
45 |
us--;
|
46 |
}
|
47 |
}
|
48 |
|
49 |
void rfTransmit(byte high, byte low) {
|
50 |
digitalWrite(rfPin, HIGH);
|
51 |
delay_pulselengths(high);
|
52 |
digitalWrite(rfPin, LOW);
|
53 |
delay_pulselengths(low);
|
54 |
}
|
55 |
|
56 |
void flashLed (int wait) {
|
57 |
digitalWrite(ledPin, LOW); // LED ist low aktiv
|
58 |
delay(wait);
|
59 |
digitalWrite(ledPin, HIGH);
|
60 |
delay(wait);
|
61 |
}
|
62 |
|
63 |
ISR(PORTA_PORT_vect) {
|
64 |
if(!digitalRead(buttonPin)){
|
65 |
eventButton = true; // Button triggert auf Masse
|
66 |
}
|
67 |
else if(digitalRead(reedPin)){
|
68 |
eventSensorOn = true; // Vorrang Button, sonst Annahme, dass Interrupt vom Sensor kam
|
69 |
}
|
70 |
else if(!digitalRead(reedPin)){
|
71 |
eventSensorOff = true; // Vorrang Button, sonst Annahme, dass Interrupt vom Sensor kam
|
72 |
}
|
73 |
PORTA.INTFLAGS = PORT_INT1_bm; // Clear PA6 interrupt flag
|
74 |
PORTA.INTFLAGS = PORT_INT7_bm; // Clear PA7 interrupt flag
|
75 |
}
|
76 |
|
77 |
void setup () {
|
78 |
pinMode(ledPin, OUTPUT); //
|
79 |
digitalWrite (ledPin, HIGH); // LED liegt an Plus, beim Start ausschalten
|
80 |
pinMode(rfPin, OUTPUT);
|
81 |
PORTA.PIN1CTRL = PORT_PULLUPEN_bm; // Same as pinMode(Button, INPUT_PULLUP);
|
82 |
PORTA.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc;
|
83 |
pinMode(Unused1, INPUT_PULLUP); // Don't leave unused pins floating
|
84 |
pinMode(Unused2, INPUT_PULLUP);
|
85 |
|
86 |
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
87 |
sleep_enable();
|
88 |
} // end of setup
|
89 |
|
90 |
void loop () {
|
91 |
|
92 |
if (eventButton == true) {
|
93 |
flashLed(125);
|
94 |
rfSend(3848390, 24); // toggle, 3848390₁₀ = 3AB8C6₁₆
|
95 |
eventButton = false;
|
96 |
}
|
97 |
if (eventSensorOn == true) {
|
98 |
flashLed(125);
|
99 |
flashLed(125);
|
100 |
rfSend(3848393, 24); // An, 3848393₁₀ = 3AB8C9₁₆
|
101 |
eventSensorOn = false;
|
102 |
}
|
103 |
if (eventSensorOff == true) {
|
104 |
flashLed(500);
|
105 |
rfSend(3848396, 24); // Aus, 3848396₁₀ = 3AB8CC₁₆
|
106 |
eventSensorOff = false;
|
107 |
}
|
108 |
|
109 |
delay(1000); // unklar, ob noch benötigt
|
110 |
PORTA.PIN1CTRL = PORT_PULLUPEN_bm | PORT_ISC_LEVEL_gc; // Pullup + Trigger Button on low level
|
111 |
PORTA.PIN7CTRL = PORT_ISC_BOTHEDGES_gc; // Trigger Sensor auf beide Flanken
|
112 |
|
113 |
sleep_mode();
|
114 |
|
115 |
// sleep_cpu();
|
116 |
// Continue after interrupt
|
117 |
PORTA.PIN1CTRL = PORT_PULLUPEN_bm; // Turn off pin sense interrupt
|
118 |
PORTA.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc;
|
119 |
} // end of loop
|