Go Down

Topic: Attiny84 und Ultraschall Sensor will nicht (Read 2670 times) previous topic - next topic

xpix

Hallo,

das ist mein zweiter Postz und ich hoffe alles richtig zu machen. Ich sitze nun schon 3 tage an diesem Problem und ich rufe nach Hilfe :)

Also, ich will mit einer Batterie, einem Attiny84 sowie einem Ultraschallsensor eine Einparkhilfe bauen. Da unsere Garafge keinen Strom hat soll das ganze autark in einem Gehäuse mindfestens ein Jahr durchlaufen. Folgenden Flkow habe ich mir ausgedacht und programmiert:

- attiny ist im Sleep Mode und wacht alle 4 Sekunden auf
- ließt den Lichteinfall an einem Fotowiderstand
- ist dieser über einen gewissen Wert (Rückfahrscheinwerfer des Autos) wird ...
- der Ultraschallsensor unter Strom gesetzt und 20ms gewartet
- dann Abstandsmessung ...
- über den Abstand werden 3 LED's (rot, gelb, grün) aktiviert die den Abstand anzeigen
- kein Licht ... zzzz

Soweit so gut :) Mein Problem ist folgendes:

Wenn ich den HC-SR04 direkt an die Battery schalte, geht er wunderbar und zeigt den Abstand an. Ich will aber Strom sparen und ihn nur anschalten wenn er auch gebraucht wird. Also schalte ich einen Pin 4 auf HIGH und versorge den Sensor dann mit Strom wenn auch Licht erkannt wurde, dann zeigt er aber nur 0cm an und ich bekomme das einfach nicht zum laufen.

Was habe ich alles geprüft:
- Beim Messen verbraucht der Sensor ca. 9mA ... die liegen am Pin4 an
- Versorgungspannung liegt bei 5V direkt und am Pin 4 bei 4,7V
- nach dem Anschalten des Pin 4 habe ich ihm bis zu 100ms Zeit gelassen bevor ich messe ... nix

Datasheet:
http://www.micropik.com/PDF/HCSR04.pdf


Also ich bin etwas verzweifelt. Hier noch der Code:

Code: [Select]

//****************************************************************
/*
* Xpark spotter
* XPIX Development /  Frank Herrmann
*
* sleepavr code from:
* KHM 2008 / Lab3/  Martin Nawrath nawrath@khm.de
* Kunsthochschule fuer Medien Koeln
* Academy of Media Arts Cologne
*/
//****************************************************************

#include <avr/sleep.h>
#include <avr/wdt.h>
#include "Ultrasonic.h"

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

#define ECHOPIN 2        // Pin to receive echo pulse
#define TRIGPIN 3        // Pin to send trigger pulse
#define MAX_DISTANCE 300 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
#define ULTRAPW 4        // Pin to power up Ultrasonic

#define PINSTATUSLED 10

#define PINRED 7        // LED RED
#define PINGREEN 6      // LED GREEN
#define PINYELLOW 5     // LED YELLOW

#define PHOTO 2

volatile boolean f_wdt=1;

/*
* setup function
* Initialize the serial line (D0 & D1) at 115200.
* Then set the pin defined to receive echo in INPUT
* and the pin to trigger to OUTPUT.
*/

void setup()
{
   Serial.begin(115200);
   Serial.println("XPark Version 0.1 (c) Frank Herrmann 2013");
   
   // Start Status LED
   pinMode(PINSTATUSLED,OUTPUT);    // set all ports into state after sleep
   pinMode(PINRED,OUTPUT);    // set all ports into state after sleep
   pinMode(PINGREEN,OUTPUT);    // set all ports into state after sleep
   pinMode(PINYELLOW,OUTPUT);    // set all ports into state after sleep
   pinMode(ULTRAPW,OUTPUT);    // set all ports into state after sleep

   digitalWrite(PINSTATUSLED, HIGH);
   digitalWrite(PINRED, HIGH);
   digitalWrite(PINGREEN, HIGH);
   digitalWrite(PINYELLOW, HIGH);

   digitalWrite(ULTRAPW, HIGH);

   // CPU Sleep Modes
   cbi( MCUCR,SE );      // sleep enable, power down mode
   cbi( MCUCR,SM0 );     // power down mode
   sbi( MCUCR,SM1 );     // power down mode
   
   setup_watchdog(8);

   delay(1000);
   
   off();
}

/*
* loop function.
*
*/
void loop()
{
   if (f_wdt==1) {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs
      f_wdt=0;       // reset flag

      pinMode(PINSTATUSLED,OUTPUT);    // set all ports into state after sleep
      digitalWrite(PINSTATUSLED, HIGH);

      int light = analogRead(PHOTO);  // reading photoresistor
      Serial.print("light: " );
      Serial.println(light );

      if(light > 285){
         // State on and wait some ms
         delay(50);
         f_wdt=1;       // reset flag

         // Light, wakeup and measure ...
         getDistance();
      } else {
        off();

        // Dark, go sleep ...
         pinMode(PINSTATUSLED,INPUT);     // set all used port to intput to save power
         pinMode(PINRED,INPUT);    // set all ports into state after sleep
         pinMode(PINGREEN,INPUT);    // set all ports into state after sleep
         pinMode(PINYELLOW,INPUT);    // set all ports into state after sleep
   
         system_sleep(); // Zzzzz ....
   
         pinMode(PINRED,OUTPUT);    // set all ports into state after sleep
         pinMode(PINGREEN,OUTPUT);    // set all ports into state after sleep
         pinMode(PINYELLOW,OUTPUT);    // set all ports into state after sleep
         pinMode(PINSTATUSLED,OUTPUT);    // set all ports into state after sleep
         delay(20);                 // wait until the last serial character is send
      }
   }
}

// Function to turn off all LEDs

void off(){
  digitalWrite(PINRED, LOW);
  digitalWrite(PINYELLOW, LOW);
  digitalWrite(PINGREEN, LOW);i
}

long getDistance(){
   delay(50);
   
   Ultrasonic ultrasonic(TRIGPIN,ECHOPIN); // Create and initialize the Ultrasonic object.
   int cm = ultrasonic.Ranging(CM); // Range is calculated in Centimeters. 

   Serial.print("distance: " );
   Serial.print(cm);
   Serial.println(" cm");
   
   // Switch LED's off
   off();

   if(cm >= 150){
      digitalWrite(PINGREEN, HIGH);
   }
   if(cm < 150 && cm >= 100){
      digitalWrite(PINYELLOW, HIGH);
   }
   if(cm && cm < 100){
      digitalWrite(PINRED, HIGH);
   }
   return cm;
}

//****************************************************************
// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {

   // Serial.print("Sleep ..." );
   delay(20);
   
   cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF

   set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
   sleep_enable();

   sleep_mode();                        // System sleeps here

   sleep_disable();                     // System continues execution here when watchdog timed out
   sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
}

//****************************************************************
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {

   byte bb;
   int ww;
   if (ii > 9 ) ii=9;
   bb=ii & 7;
   if (ii > 7) bb|= (1<<5);
      bb|= (1<<WDCE);
      ww=bb;
      Serial.println(ww);

      MCUSR &= ~(1<<WDRF);
      // start timed sequence
      WDTCSR |= (1<<WDCE) | (1<<WDE);
      // set new watchdog timeout value
      WDTCSR = bb;
      WDTCSR |= _BV(WDIE);
}

//****************************************************************
// Watchdog Interrupt Service / is executed when  watchdog timed out
ISR(WDT_vect) {
   f_wdt=1;  // set global flag
}

pylon

Nach Datenblatt verbraucht der Sensor 15mA, beim Aussenden des Tones evtl. kurzfristig noch mehr. Ich würde ihn nicht direkt mit dem GPIO speisen, sondern diesen über einen Transistor an die Versorgungsspannung hängen.

xpix


Nach Datenblatt verbraucht der Sensor 15mA, beim Aussenden des Tones evtl. kurzfristig noch mehr. Ich würde ihn nicht direkt mit dem GPIO speisen, sondern diesen über einen Transistor an die Versorgungsspannung hängen.


Hmm, auch das hatte ich schon probiert, ein Darlington dran gehängt und den PIN4 das Teil freischalten lassen. Aber gut ich probier das nochmal :) Wäre doch verrückt wenn das nicht geht?!

jurs


Wäre doch verrückt wenn das nicht geht?!


Brauchen diese Sensoren nicht überhaupt sehr viel länger als 100ms nach dem Anlegen der Betriebsspannung, bis sie betriebsbereit sind? Mehr so in der Gegend von 2 sec nachdem die Betriebsspannung anliegt?

xpix

#4
Mar 19, 2013, 12:20 pm Last Edit: Mar 19, 2013, 12:23 pm by xpix Reason: 1

Mehr so in der Gegend von 2 sec nachdem die Betriebsspannung anliegt?


Das wäre aber ziemlich crazy ... würde aber einiges erklären. Hmm, ich werde das mal erforschen, danke für den Tipp!

Wenn dem aber so wäre, warum wartet dieses Beispiel dann nicht 2 sec bevor es den Sensor anspricht?

https://code.google.com/p/arduino-new-ping/wiki/NewPing_Single_Pin_Sketch

pylon

Quote
Wenn dem aber so wäre, warum wartet dieses Beispiel dann nicht 2 sec bevor es den Sensor anspricht?


Weil das ein normaler Sketch ist und dieser erst nach dem Bootloader ausgeführt wird, somit ca. 2 sec nachdem das System mit Strom versorgt wurde.

xpix


Weil das ein normaler Sketch ist und dieser erst nach dem Bootloader ausgeführt wird, somit ca. 2 sec nachdem das System mit Strom versorgt wurde.


Super tipp, das werd ich heute gleich mal ausprobieren. Na wenn der so lange braucht, dann ist alles klar.

Go Up