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?