Hallo Leute,
ich habe mehrer Attiny84 im Betrieb. Genauer gesagt habe ich die TinyTX3 Sensoren von Nathan nachgebaut:
nathan.chantrell.net/tinytx-wireless-sensor/
Ich habe mehrere Türen und Fenster mit mit diesen Sensoren (Reed-Switch/Magnetkontakt) ausgestattet.
Diese Sensoren senden auch fleißig. Als Empfänger dient ein Raspberry Pi mit einem RFM12Pi (http://wiki.openenergymonitor.org/index.php?title=Raspberry_Pi)
Nun habe ich das "Problem", dass ich gerne die aktuelle Spannung der Sensoren empfangen möchte.
Zum auslesen wird die Funktion "readVcc();" benutzt (Siehe Sketch TinyTX_ReedSwitch.ino - Zeile 127)
Diese Funktion leifert die Spannung in mV.
Leider erhalte ich aber keine Spannungswerte am Empfänger.
Die Ausgabe über die serielle Schnitstelle am Pi ist folgende:
pi@raspberrypi ~ $ minicom -b 9600 -o -D /dev/ttyAMA0
2 0 0 85 18
2 1 0 85 18
4 0 0 13 17
4 1 0 13 17
1 0 0 91 16
1 1 0 106 16
Beispiel: 2 1 0 85 18
2 = Sender ID
1 = Status des Reedswitch
0 = ?
85 = ?
18 = ?
Soweit ich den Code verstanden habe wird hier die Struktur zum senden festgelegt:
//########################################################################################################################
//Data Structure to be sent
//########################################################################################################################
typedef struct {
int switchState; // Switch state
int supplyV; // Supply voltage
} Payload;
Payload tinytx;
//########################################################################################################################
Nun zu meiner Frage: Was muss geändert werden, damit ich am Empfänger die Spannung in mV empfangen kann?
Dies sind meine ersten Versuche mit Arduino, Attiny und co. Deswegen würde ich mich freuen, wenn jemand mit Programmiererfahrung für Mikrokontroller mir unter dir Arme greifen könnte!
Vielen Dank!
Sender Sketch:
//----------------------------------------------------------------------------------------------------------------------
// TinyTX - An ATtiny84 and RFM12B Wireless Sensor Node
// By Nathan Chantrell. For hardware design see http://nathan.chantrell.net/tinytx
//
// Detect a normally closed reed switch opening and closing with pin change interrupt to wake from sleep.
//
// Licenced under the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) licence:
// http://creativecommons.org/licenses/by-sa/3.0/
//
// Requires Arduino IDE with arduino-tiny core: http://code.google.com/p/arduino-tiny/
//----------------------------------------------------------------------------------------------------------------------
#include <JeeLib.h> // https://github.com/jcw/jeelib
#include <PinChangeInterrupt.h> // http://code.google.com/p/arduino-tiny/downloads/list
#include <avr/sleep.h>
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // interrupt handler for JeeLabs Sleepy power saving
#define myNodeID 1 // 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
#define SW_PIN 10 // Reed switch connected from ground to this pin (D10/ATtiny pin 13)
//########################################################################################################################
//Data Structure to be sent
//########################################################################################################################
typedef struct {
int switchState; // Switch state
int supplyV; // Supply voltage
} Payload;
Payload tinytx;
//########################################################################################################################
void setup() {
rf12_initialize(myNodeID,freq,network); // Initialize RFM12 with settings defined above
rf12_sleep(0); // Put the RFM12 to sleep
pinMode(SW_PIN, INPUT); //set the pin to input
digitalWrite(SW_PIN, HIGH); //use the internal pullup resistor
attachPcInterrupt(SW_PIN,wakeUp,FALLING); // attach a PinChange Interrupt on the falling edge
PRR = bit(PRTIM1); // only keep timer 0 going
ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
sleep_mode(); // Sleep now
}
void wakeUp(){}
void loop() {
int switchState = digitalRead(SW_PIN); // Read the state of the reed switch
if (switchState == LOW) { // Door/window is open
tinytx.switchState = 1; // 1 indicates open
}
else { // Door/window is closed
tinytx.switchState = 0; // 0 indicates closed
}
tinytx.supplyV = readVcc(); // Get supply voltage
rfwrite(); // Send data via RF
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
sleep_mode(); // Sleep now
}
//--------------------------------------------------------------------------------------------------
// 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
while (!rf12_canSend())
rf12_recvDone();
rf12_sendStart(0, &tinytx, sizeof tinytx);
rf12_sendWait(2); // Wait for RF to finish sending while in standby mode
rf12_sleep(0); // Put RF module to sleep
return;
#endif
}
// 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
//--------------------------------------------------------------------------------------------------
// 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;
}
Empgänger Sketch: