Da hast du was falsch verstanden.
Der HC-SR04 benötigt mindestens 4.5V auf VCC, typischerweise 5V und maximal 5.5V.
Der TRIGGER pin funktioniert auch mit 3V3.
Das LOW Signal aus dem ECHO pin ist < 1.0V. Das HIGH Signal entspricht dem des VCC's also typischerweise 5V aber mindestens 4.5V.
Das steht auch so ähnlich in deiner Anleitung.
Da es in deiner Beschreibung/Anleitung um den Anschluss an den PI geht - du aber den ATtiny84A hast, kannst du diese Spannungs Geschichte ignorieren. Der ATtiny84A verträgt maximal 5,5V aber der PI verträgt maximal 3V3.
Quellen:
http://www.mikrocontroller.net/attachment/218…chreibung_3.pdf
https://docs.google.com/document/d/1Y-…vP8saG73rE/edit
Die folgenden Pins des ATTiny84A sind PWM fähig:
pin#5 , D2
pin#6 , D3
pin#7 , D4
pin#8 , D5
.
+-\/-+
VCC 1| |14 GND
(D0) PB0 2| |13 AREF (D10)
(D1) PB1 3| |12 PA1 (D9)
(PB3) RESET 4| |11 PA2 (D8)
INT0 PWM (D2) PB2 5| |10 PA3 (D7)
PWM (D3) PA7 6| |9 PA4 (D6) SCK
SDA PWM (D4) PA6 7| |8 PA5 (D5) PWM
+----+
Hierbei muss man beachten das bei sowohl TinyTX3 als auch TinyTX4 nur der D3 oben zugänglich ist. Also muss dieser pin zwangsläufig dafür genutzt werden.
Den VCC pin macht man auch schaltbar über z.B. D10.
Den Trigger pin brauch nur ein digital output sein, dafür bietet sich D9 an.
Was auch noch zu beachten wäre ist dass der HC-SR04 eine maximale Distance von 400cm hat, also sollte man in dem Sketch dies auch kontrollieren und dann zB " -1 " ausgeben um "out of range" zu signalisieren. Ebenso wie mindestens 2cm, näher ran kann er ebenfalls nicht erkennen.
Versuch es mal mit folgendem Sketch:
(untested)
"Send_HCSR04_Watchdog.ino"
// RFM12B Sender for ReedSwitch Sensor with Watchdog (saves much more Power!)
// HC-SR04 Ping distance sensor
//
// Basiert zum Teil auf der Arbeit von Nathan Chantrell
//
// modified by meigrafd @ 17.01.2015
//------------------------------------------------------------------------------
#include <RFM12B.h>
// Power-Save-Stuff.
// http://www.surprisingedge.com/low-power-atmegatiny-with-watchdog-timer/
// https://www.sparkfun.com/tutorials/309
// http://jeelabs.org/tag/lowpower/
#include <avr/sleep.h>
volatile int watchdog_counter;
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) { watchdog_counter++; }
// 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms
// 6=1sec, 7=2sec, 8=4sec, 9=8sec
// From: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
int watchdog_wakeup = 9; // Wake up after 8 sec
//------------------------------------------------------------------------------
// You will need to initialize the radio by telling it what ID it has and what network it's on
// The NodeID takes values from 1-127, 0 is reserved for sending broadcast messages (send to all nodes)
// The Network ID takes values from 0-255
// By default the SPI-SS line used is D10 on Atmega328. You can change it by calling .SetCS(pin) where pin can be {8,9,10}
#define NODEID 1 // network ID used for this unit
#define NETWORKID 210 // the network ID we are on
#define GATEWAYID 22 // the node ID we're sending to
#define FREQ RF12_433MHZ // Frequency of RFM12B module
#define ACK_TIME 2000 // # of ms to wait for an ack
#define requestACK false // request ACK? (true/false)
#define SENDDELAY 300000 // wait this many ms between sending packets. 300000ms / 1000 / 8 = 37,5 * 8sec = 5Min.
//------------------------------------------------------------------------------
// PIN-Konfiguration
//------------------------------------------------------------------------------
// SENSOR pins
#define VCC_PIN 10 // HC-SR04 connected from ground to this pin (D10/ATtiny pin 13)
#define ECHO_PIN 3 // PWM pin#6 , D3
#define TRIG_PIN 9 // digital output , pin#12 , D9
// LED pin
#define LEDpin 8 // D8, PA2 (ATtiny pin 11) - set to 0 to disable LED
//------------------------------------------------------------------------------
/*
+-\/-+
VCC 1| |14 GND
(D0) PB0 2| |13 AREF (D10)
(D1) PB1 3| |12 PA1 (D9)
(PB3) RESET 4| |11 PA2 (D8)
INT0 PWM (D2) PB2 5| |10 PA3 (D7)
PWM (D3) PA7 6| |9 PA4 (D6) SCK
SDA PWM (D4) PA6 7| |8 PA5 (D5) PWM
+----+
*/
//encryption is OPTIONAL
//to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start encrypting
// - to stop encrypting call .Encrypt(NULL)
#define KEY "a4gBM69UZ03lQyK4"
// Need an instance of the Radio Module
RFM12B radio;
// Reed switchState
int switchState;
// String zum Versand per 433 Mhz
char msg[26];
// 7,5 * 8sec = 1 Min. 37,5 * 8sec = 5Min.
int watchdog_limit = SENDDELAY / 1000 / 8;
int maximumRange = 400; // Maximum range needed
int minimumRange = 2; // Minimum range needed
long duration, distance; // Duration used to calculate distance
//##############################################################################
static void activityLed (byte state, byte time = 0) {
if (LEDpin) {
pinMode(LEDpin, OUTPUT);
if (time == 0) {
digitalWrite(LEDpin, state);
} else {
digitalWrite(LEDpin, state);
delay(time);
digitalWrite(LEDpin, !state);
}
}
}
// blink led
static void blink (byte pin, byte n = 3) {
if (LEDpin) {
pinMode(pin, OUTPUT);
for (byte i = 0; i < 2 * n; ++i) {
delay(100);
digitalWrite(pin, !digitalRead(pin));
}
}
}
//--------------------------------------------------------------------------------------------------
// Read current supply voltage (in mV)
//--------------------------------------------------------------------------------------------------
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
//result = 1125300L / result; // Back-Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
result = 1126400L / result; // Back-calculate Vcc in mV
return result;
}
//--------------------------------------------------------------------------------------------------
// Power Save Functions
//--------------------------------------------------------------------------------------------------
// Enable / Disable ADC, saves ~230uA
void enableADC(bool b) {
if (b == true){
bitClear(PRR, PRADC); // power up the ADC
ADCSRA |= bit(ADEN); // enable the ADC
delay(10);
} else {
//ADCSRA &= ~(1<<ADEN); // Disable ADC
ADCSRA &= ~ bit(ADEN); // disable the ADC
bitSet(PRR, PRADC); // power down the ADC
}
}
void goToSleep() {
// SLEEP_MODE_IDLE -the least power savings
// SLEEP_MODE_ADC
// SLEEP_MODE_PWR_SAVE
// SLEEP_MODE_STANDBY
// SLEEP_MODE_PWR_DOWN -the most power savings
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode.
sleep_enable(); // Enable sleep mode.
sleep_mode(); // Enter sleep mode.
// After waking from watchdog interrupt the code continues to execute from this point.
sleep_disable(); // Disable sleep mode after waking.
// Re-enable the peripherals.
//power_all_enable();
}
// 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms
// 6=1sec, 7=2sec, 8=4sec, 9=8sec
// From: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void setup_watchdog(int timerPrescaler) {
if (timerPrescaler > 9 ) timerPrescaler = 9; //Correct incoming amount if need be
byte bb = timerPrescaler & 7;
if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary
//This order of commands is important and cannot be combined
MCUSR &= ~(1<<WDRF); //Clear the watchdog reset
WDTCSR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable
WDTCSR = bb; //Set new watchdog timeout value
WDTCSR |= _BV(WDIE); //Set the interrupt enable, this will keep unit from resetting after each int
}
//--------------------------------------------------------------------------------------------------
/* The following trigPin/echoPin cycle is used to determine the distance of the nearest object by bouncing soundwaves off of it. */
long ping() {
digitalWrite(VCC_PIN, HIGH);
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// The ECHO pin is used to read the signal from the PING))): a HIGH
// pulse whose duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
duration = pulseIn(ECHO_PIN, HIGH);
// convert the time into a distance
distance = microsecondsToCentimeters(duration);
if (distance >= maximumRange || distance <= minimumRange){
// indicate "out of range"
distance = -1;
}
digitalWrite(VCC_PIN, LOW);
return distance;
}
long microsecondsToCentimeters(long microseconds) {
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
//--------------------------------------------------------------------------------------------------
// init Setup
void setup() {
// configure RFM12B
radio.Initialize(NODEID, FREQ, NETWORKID);
#ifdef KEY
radio.Encrypt((byte*)KEY); //comment this out to disable encryption
#endif
radio.Control(0xC040); // Adjust low battery voltage to 2.2V
radio.Sleep(); // sleep right away to save power
pinMode(VCC_PIN, OUTPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
analogReference(INTERNAL); // Set the aref to the internal 1.1V reference
watchdog_counter = 500; // set to have an initial transmition when starting the sender.
setup_watchdog(watchdog_wakeup);
enableADC(false); // power down/disable the ADC
//ACSR = (1<<ACD); // Disable the analog comparator
//DIDR0 = 0x3F; // Disable digital input buffers on all ADC0-ADC5 pins.
//ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
PRR = bit(PRTIM1); // only keep timer 0 going
if (LEDpin) {
activityLed(1, 1000); // LED on
}
}
// Loop
void loop() {
goToSleep(); // goes to sleep for about 8 seconds and continues to execute code when it wakes up
// 15 * 4 sec = 1 Min , 75 * 4 sec = 5 Min , 225 * 4 sec = 15 min
// 7,5 * 8sec = 1 Min. 37,5 * 8sec = 5Min.
if (watchdog_counter >= watchdog_limit) {
watchdog_counter = 1;
enableADC(true); // power up/enable the ADC
int supplyV = readVcc(); // Get supply voltage
int Distance = ping();
// msg-Variable mit Daten zum Versand fuellen, die spaeter an das WebScript uebergeben werden
strcpy(msg,"v=");
itoa(supplyV,&msg[strlen(msg)],10);
strcat(msg,"&d=");
itoa(Distance,&msg[strlen(msg)],10);
// Send data via RF
radio.Wakeup();
radio.Send(GATEWAYID, (uint8_t *)msg, strlen(msg), requestACK);
//radio.Send(GATEWAYID, &msg, sizeof(msg), requestACK);
radio.SendWait(2); //wait for RF to finish sending (2=standby mode, 3=power down)
radio.Sleep();
if (LEDpin) {
blink(LEDpin, 2); // blink LED
}
enableADC(false); // power down/disable the ADC
}
}
Alles anzeigen
Binäre Sketchgröße: 5.872 Bytes (von einem Maximum von 8.192 Bytes)