Hallo zusammen,
ich versuche nochmal hier mein Glück
Ich möchte gerne einem HC-SR04 Ultraschallentfernungssensor an einen TinyTx Sensor anschliessen. (wie in den Threads von meigrafd oder ps915 habe ich dies mit verschiedenen anderen am Laufen).
Beim HC-SR04 will es einfach nicht. Aktuelle Sketch unten beigefügt.
- Vcc/GND vom Tiny (D10) (geschaltet) => ich bekomme immer falsche Werte
- Vcc (egal ob 5V oder 3,3V)/GND vom Pi => hier bekomme ich korrekte Werte (auch komplett am Pi angeschlossen funktioniert der Sensor korrekt)
- ich habe dem Sensor am Tiny nach den Einschalten von Vcc auch zum testen extra Zeit gegeben:
digitalWrite(VCC_PIN, HIGH);
delay(3000);
hilft aber nicht
Nun habe ich vorhin folgenden Thread gefunden, der - wenn ich den richtig verstanden habe - ein vergleichbares Verhalten beschreibt und dort wird erwähnt, den HC-SR04 per MOSFET aus- und einzuschalten, wenn er für die Messung gebraucht wird:
http://forum.arduino.cc/index.php?topic=216079.0
Wenn dem so ist, kann mir mal jemand skizzieren, wie ich den MOSFET in Verbindung mit dem Tiny und dem HC-SR04 einzusetzen habe?
Vielen Dank für Infos und Hinweise...
P.S. Ich habe unten auch noch einen zweiten Sketch beigefügt, der nicht so umfangreich ist, jedoch bzgl. der Vcc Versorgung identisches Verhalten aufweist.
Aktuelle Sketch, zusätzlich mit SoftwareSerial zum Debuggen:
//----------------------------------------------------------------------------------------------------------------------
// TinyTX_TMP36 - An ATtiny84 and RFM12B Wireless Temperature Sensor Node
// By Nathan Chantrell. For hardware design see http://nathan.chantrell.net/tinytx
//
// **IMPORTANT** Note that the TMP36 must be fitted in the REVERSE orientation compared to the DS18B20
// and do not fit a resistor
//
// Using the Analog Devices TMP36 temperature sensor
//
// 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 <SoftwareSerial.h>
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // interrupt handler for JeeLabs Sleepy power saving
#define myNodeID 13 // 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 1 // Maximum number of times to retry
#define ACK_TIME 10 // Number of milliseconds to wait for an ack
#define echoPin 3 // Echo Pin
#define trigPin 9 // Trigger Pin
#define LEDPin 8 // Onboard LED
#define VCC_PIN 10
// UART
#define rxPin 0 // mod D7, PA3
#define txPin 7 // mod D3, PA7
#define Ping_Interval 3000 // 33 Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo)
#define SERIAL_BAUD 9600
SoftwareSerial mySerial(rxPin, txPin);
int maximumRange = 400; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance
unsigned long pingTimer;
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;
}
//########################################################################################################################
//Data Structure to be sent
//########################################################################################################################
//typedef struct {
// int temp; // Temperature reading
// int supplyV; // Supply voltage
//} Payload;
//Payload tinytx;
char msg[26];
// 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
//--------------------------------------------------------------------------------------------------
// 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_sendStart(RF12_HDR_ACK, (uint8_t *)msg, strlen(msg));
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_sendStart(0, (uint8_t *)msg, strlen(msg));
rf12_sendWait(2); // Wait for RF to finish sending while in standby mode
rf12_sleep(0); // Put RF module to sleep
return;
#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;
}
//########################################################################################################################
void setup() {
rf12_initialize(myNodeID,freq,network); // Initialize RFM12 with settings defined above
rf12_sleep(0); // Put the RFM12 to sleep
//HRG 18082014
//analogReference(INTERNAL); // Set the aref to the internal 1.1V reference
mySerial.begin(SERIAL_BAUD);
pinMode(VCC_PIN, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
pingTimer = millis() + Ping_Interval; // ping starts at >=29 ms, gives time for the Arduino to chill before starting.
mySerial.println("Transmitting...\n");
delay(100);
}
/* 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);
delay(3000);
// 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(trigPin,LOW);
delayMicroseconds(2);
digitalWrite(trigPin,HIGH);
delayMicroseconds(10);
digitalWrite(trigPin,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(echoPin, HIGH);
// convert the time into a distance
distance = microsecondsToCentimeters(duration);
if (distance >= maximumRange || distance <= minimumRange){
// Turn LED ON to indicate "out of range"
distance = -1;
digitalWrite(LEDPin, HIGH);
} else {
// Turn LED OFF to indicate successful reading.
digitalWrite(LEDPin, LOW);
}
digitalWrite(VCC_PIN, LOW);
mySerial.print("distance: ");
mySerial.print(distance);
mySerial.println("cm");
return distance;
}
void loop() {
bitClear(PRR, PRADC); ADCSRA |= bit(ADEN); // Enable the ADC
int dist = ping();
ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
int supplyV = readVcc(); // Get supply voltage
strcpy(msg,"v=");
itoa(supplyV,&msg[strlen(msg)],10);
strcat(msg,"&r=");
itoa(dist,&msg[strlen(msg)],10);
mySerial.print("Sending: ");
mySerial.println(msg);
rfwrite(); // Send data via RF
for (byte i = 0; i < 5; i++)
{
Sleepy::loseSomeTime(60000); //JeeLabs power save function: enter low power mode for 60 seconds (valid range 16-65000 ms)
}
}
Alles anzeigen
Weiterer Sketch, der minimierter ist aber sich gleich verhält bzgl. Vcc:
/*
HC-SR04 Ping distance sensor:
VCC to arduino 5v
GND to arduino GND
Echo to Arduino pin 7
Trig to Arduino pin 8
*/
#include <SoftwareSerial.h>
#define echoPin 3 // Echo Pin
#define trigPin 9 // Trigger Pin
#define LEDPin 8 // Onboard LED
#define VCC_PIN 10
// UART
#define rxPin 0 // mod D7, PA3
#define txPin 7 // mod D3, PA7
#define Ping_Interval 3000 // 33 Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo)
#define SERIAL_BAUD 9600
SoftwareSerial mySerial(rxPin, txPin);
int maximumRange = 400; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance
unsigned long pingTimer;
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;
}
void setup() {
mySerial.begin(SERIAL_BAUD);
pinMode(VCC_PIN, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
pingTimer = millis() + Ping_Interval; // ping starts at >=29 ms, gives time for the Arduino to chill before starting.
mySerial.println("Transmitting...\n");
delay(100);
}
/* 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);
delay(3000);
// 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(trigPin,LOW);
delayMicroseconds(2);
digitalWrite(trigPin,HIGH);
delayMicroseconds(10);
digitalWrite(trigPin,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(echoPin, HIGH);
// convert the time into a distance
distance = microsecondsToCentimeters(duration);
if (distance >= maximumRange || distance <= minimumRange){
// Turn LED ON to indicate "out of range"
distance = -1;
digitalWrite(LEDPin, HIGH);
} else {
// Turn LED OFF to indicate successful reading.
digitalWrite(LEDPin, LOW);
}
digitalWrite(VCC_PIN, LOW);
mySerial.print("distance: ");
mySerial.print(distance);
mySerial.println("cm");
}
void loop() {
if (millis() >= pingTimer) { // Is it time to ping?
pingTimer += Ping_Interval; // Set next time this sensor will be pinged.
ping();
}
}
Alles anzeigen