0

I'm using one of my attiny's pins as digital input. I use it with a pulldown resistor. As input I use simple square wave generated by a separate waveform generator. igh state for square wave is 5V, low is 0V.

However, when I look at the voltage on the digital input, voltage of high state is below 2V, while low state is 0V. My arduino doesnt detect high state as "1".

Here is the code:

/*
 * Sketch for testing sleep mode with wake up on WDT.
 * Donal Morrissey - 2011.
 * ATTINY85
 */

#include <TinyWireM.h>                  // I2C Master lib for ATTinys which use USI - comment this out to use with standard arduinos
#include <LiquidCrystal_attiny.h>          // for LCD w/ GPIO MODIFIED for the ATtiny85


#include <avr/sleep.h> 
#include <avr/power.h>
#include <avr/wdt.h>

//uwaga na numer pinu! nie używać tego z resetem
#define STATUS_PIN  1
#define IN_PIN     4
#define LOOP_TIME 5000
#define TIMEOUT 100

#define GPIO_ADDR     0x27
LiquidCrystal_I2C lcd(GPIO_ADDR, 16, 2); // set address & 16 chars / 2 lines

/* f_wdt is a flag used to monitor watchdog status */
volatile int f_wdt=1;


/***************************************************
 *  Name:        ISR(WDT_vect)
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Watchdog Interrupt Service. This
 *               is executed when watchdog timed out.
 *
 ***************************************************/
ISR( WDT_vect){
  if(f_wdt == 0){
    f_wdt=1;
  }
  else{
  }
}


/***************************************************
 *  Name:        enterSleep
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Enters the arduino into sleep mode.
 *
 ***************************************************/
void enterSleep(void)
{
  lcd.clear();
  lcd.print("Asleep...");

  /* Enable the WD interrupt (note no reset). */
  WDTCR |= (1<<WDIE); 

  set_sleep_mode( SLEEP_MODE_PWR_DOWN );   /* EDIT: could also use SLEEP_MODE_PWR_DOWN for lowest power consumption. */
  sleep_enable();
  // Status pin goes low
  digitalWrite( STATUS_PIN, LOW );
  /* Now enter sleep mode. */
  sleep_mode();

  /* The program will continue from here after the WDT timeout*/
  sleep_disable(); /* First thing to do is disable sleep. */

  // Status pin goes low
  digitalWrite( STATUS_PIN, HIGH );

  /* Re-enable the peripherals. */
  power_all_enable();

  /* Disable the WD interrupt */
  WDTCR &= ~_BV(WDIE);
}



/***************************************************
 *  Name:        setup
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Setup for the serial comms and the
 *                Watch dog timeout. 
 *
 ***************************************************/
void setup()
{
  /*  Setup the LCD */
  lcd.init();                           // initialize the lcd
  lcd.backlight();                      // Print a message to the LCD.
  lcd.clear();
  lcd.setCursor(0,0);

  /* Inform the user about initialization process */
  lcd.print("Initializing...");
  delay(1000);

  /* Config pins */
  pinMode( IN_PIN, OUTPUT );
  pinMode( STATUS_PIN, OUTPUT );

  /* Initialize pins */
  digitalWrite( STATUS_PIN, HIGH );

  /*** Setup the WDT ***/

  /* Clear the reset flag of watchdog interrupts, so that they are available again. */
  MCUSR &= ~(1<<WDRF);

  /* Enable configuration changes
   */
  WDTCR |= (1<<WDCE) | (1<<WDE);


/*
WDP3       WDP2    WDP1     WDP0         Number of WDT     Typical Time-out at
                                         Oscillator Cycles     VCC = 5.0V
  0         0      0        0             2K (2048) cycles       16 ms
  0         0      0        1             4K (4096) cycles       32 ms
  0         0      1        0             8K (8192) cycles       64 ms
  0         0      1        1            16K (16384) cycles    0.125 s
  0         1      0        0            32K (32768) cycles    0.25 s
  0         1      0        1            64K (65536) cycles    0.5 s
  0         1      1        0            128K (131072) cycles 1.0 s
  0         1      1        1            256K (262144) cycles 2.0 s
  1         0      0        0            512K (524288) cycles 4.0 s
  1         0      0        1            1024K (1048576) cycles 8.0 s
*/
  /* set new watchdog timeout prescaler value */
  WDTCR =  0<<WDP3 | 1<<WDP2 | 1<<WDP1 | 0<<WDP0 ;

  lcd.clear();
  lcd.print("Initialisation");
  lcd.setCursor(0,1);
  lcd.print("complete.");
  delay(500); 
}



/***************************************************
 *  Name:        enterSleep
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Main application loop.
 *
 ***************************************************/
void loop()
{
  if(f_wdt == 1)
  {
    lcd.clear();
    lcd.print("Awake!");
    int start = millis();
    int end = 0;
    bool movement = false;
    int read = 0;
    lcd.clear();
    lcd.print( "Executing loop" );
    do{
      if( read = digitalRead(IN_PIN) ){
        lcd.setCursor(0,1);
        lcd.print( "Read value: " );
        lcd.print( read );

        //Wait for falling edge
        while( digitalRead(IN_PIN) != 0 );
        //Start counting time
        int endMov = 0;
        int startMov = millis();
        do{
          if( digitalRead( IN_PIN ) ){
            movement = true;
          }
          endMov=millis();
        }while( endMov - startMov < TIMEOUT && !movement );
            if( endMov - startMov >=LOOP_TIME ){
              lcd.clear();
              lcd.print("Time is out");
            }

            else{
              lcd.clear();
              lcd.print("Movement detected");
              lcd.setCursor(0,1);
              lcd.print( "Time: " );
              lcd.print( end-start );
            }
      }
      end=millis();
    }
    while( (end-start<LOOP_TIME) && !movement );

    if( end-start>=LOOP_TIME ){
      lcd.clear();
      lcd.print("Time is out");
    }

    else{
      lcd.clear();
      lcd.print("Movement detected");
      lcd.setCursor(0,1);
      lcd.print( "Time: " );
      lcd.print( end-start );
    }
    delay(1000);
    /* Don't forget to clear the flag. */
    f_wdt = 0;
    /* Re-enter sleep mode. */
    enterSleep();
  }
  else
  {
    /* Do nothing. */
  }
}

Does anyone has any idea why is it so?

  • Ideas, yes, but since you don't tell name or model number of waveform generator, or the value of the pulldown resistor, or which ATtiny, or which pin, or if anything else is in the circuit, who can say? Please edit your question to include that information. – James Waldby - jwpat7 Apr 11 '17 at 14:17
  • 1
    What value pulldown resistor? What is the output impedance of your waveform generator? – Majenko Apr 11 '17 at 14:25
0

First thing in my mind would be to check/change the pull-down resistor value.

The pull-down resistor must have a larger resistance than the impedance of the logic circuit, or else it might be able to pull the voltage down by too much and the input voltage at the pin would remain at a constant logical low value

Read more here.

  • I changed the pull down resistor to 360 ohms and 100k ohms, but it did not change a thing, unfortunately. Voltage levels are still too low. – Em Ka Apr 11 '17 at 14:36
  • Typical pull-down resistors 4.7K and 10K. But, it is also depending on your device connected to the pin. Do you know the impedance of your waveform generator? And another thing is how you set-up the pin in your firmware? Can you show us your code? – Sener Apr 11 '17 at 14:40
  • Impedance of my waveform generator is close to 0 ohms. I edited the post, code is available now – Em Ka Apr 11 '17 at 14:45
  • 1
    Are you sure you use that Pin as INPUT; This line; pinMode( IN_PIN, OUTPUT ); should be pinMode( IN_PIN, INPUT ); – Sener Apr 11 '17 at 14:50
  • Oh my god, this is embarassing... Thanks:) Now it works – Em Ka Apr 11 '17 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.