Attiny2313 longer Watch dog time

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everybody, as always I be not AVR expert and need some help with my project. Basicaly I be doing a remote temperature sensor and it takes one measure per minute. I need the most efficiency to spare battery, so I make it take a measure, sleep, and then wake up again. The watch dog makes it. The problem is: Watch dog wakes the CPU up longer for 8 seconds and I need 60 seconds. Is any way to do this? :cry:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wake up for a very short time. Count one and go back to sleep. When the count reaches 8 (64 seconds), measure, reset the counter, and go back to sleep.

Incidentally, the watchdog is a very low accuracy timer.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried this, but the normal operation is take a measure and send it through USART to a remote receiver, and when this happens with the wakeup sleep procedure, the USART send just zeros. I think it freezes. If you want I can send the code and more details. Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It just dont work, it seems like be on reseting mode. My code for Watchdog initialization is:

void WDT_init(void)
{
WDTCSR =(1<<WDCE)|(1<<WDIE)|(1<<WDP3)|(0<<WDP2)|(0<<WDP1)|(1<<WDP0); // Watchdog Change Enable and 8 seconds timer.
MCUSR &=~(1<<WDRF); // MCU reset disable
WDTCSR&=~(1<<WDE); // Watchdog System Reset Enable
}

ISR interruption:


ISR(WDT_OVERFLOW_vect)
{

WDT_init();

i++;

if(i>8) // 64 Minutes
	{
	sleep_disable();
	WDTCSR&=~(1<<WDIF);
	WDT_init();
	i=0;
	}
	
}

Any suggestion?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please post the whole program, select the source-code and press the "Code"-button.

/Martin.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I be working on this alot days and no can do nothing more than 8 seconds sleep and wakep. Please can anybody please help me on this problem?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I be sending the entire code, if anyone can help to implement the code I will apreciate.

#include 
#include 
#include 
#include 
#include 

#define set_bit(adress,bit) (adress|=(1<<bit))
#define clr_bit(adress,bit) (adress&=~(1<<bit))
#define tst_bit(adress,bit) (adress&(1<<bit))

#define DQ 					PA0 // DS18S20 Sensor Input
#define DDR					DDRA
#define PORT				PORTA
#define PIN					PINA

#define CONVERT_T			0x44
#define READ_SCRATCHPAD		0xBE
#define SKIP_ROM			0xCC

#define BAUD 1200UL
#define UBRRVAL ((F_CPU/(BAUD*16UL))-1)

#define ID		0x01
#define SYNC	0xAA
#define A		0x41
#define Z		0x5A

void USART_Init( unsigned int baud ); // USART Initialization
void TransmitByte( unsigned char data );
void TransmitString( const char *str );
unsigned char reset(); // reset devices on the bus
unsigned char le_bit(); // reads a bit of a bus wire
unsigned char le_byte(); // reads a byte from a bus wire
void escreve_bit(unsigned char bit_1w);// writes a bit on a bus wire
void escreve_byte(char dado); // writes one byte at a bus wire
void WDT_init(void); //Watchdog Initialization
ISR(WDT_OVERFLOW_vect);

volatile char i=0;

int main(void)
{
// Buffer length must be at least 12bytes long! ["+XXX.XXXX C"]
uint8_t temperature[3];

set_sleep_mode(SLEEP_MODE_PWR_DOWN);

USART_Init(UBRRVAL);

WDT_init;

DDRB|=(1<<PB0);

for(;;)
	{
	
	//Blinks a Led if the sensor Fails
	while(reset())
	{
	PORTB|=(1<<PB0);
	_delay_ms(50);
	PORTB^=(1<<PB0);
	_delay_ms(50);
	cli();
	}
	
	reset();
	escreve_byte(SKIP_ROM);
	escreve_byte(CONVERT_T);

	//Wait until conversion is complete
	while(!le_bit());

	reset();
	escreve_byte(SKIP_ROM);
	escreve_byte(READ_SCRATCHPAD);

	//Read Scratchpad (only 2 first bytes)
	temperature[0]=le_byte();
	temperature[1]=le_byte();
	
	// RF433Mhz Transmition
	TransmitByte(0x00);		 								// Garbage
	TransmitByte(SYNC);		 								// Sinc Byte
	TransmitByte(A);			 							// Alfa Packet
	TransmitByte(A);		     							// Alfa Packet
	TransmitByte(ID);			 							// Module Identification
	TransmitByte(temperature[1]); 							// First Temperature Byte
	TransmitByte(temperature[0]); 							// Second Temperature Byte
	TransmitByte(Z);										// Omega Packet
	
	reset();
	
	sei();

	_delay_ms(50);

	sleep_mode(); // Sleep until Watchdog WakesUp for about 64 minutes (8 seconds * 4)
	
	}
}

void USART_Init( unsigned int baud )
{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<USBS)|(3<<UCSZ0);
}

void TransmitByte( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) );
/* Put data into buffer, sends the data */
UDR = data;
}

void TransmitString( const char *str )
{
	while((*str)!='\0')
	{
		TransmitByte(*str);
		str++;
	}

	TransmitByte('\0');
}

unsigned char reset() //reseta os dispositivos no barramento
{
unsigned char presente;
DDR = (1<<DQ); //DQ como saída
clr_bit(PORT,DQ); //DQ em nivel zero por 480us
_delay_us(480);
DDR = (0<<DQ);//pino SDA como entrada, o resistor de pull-up mantém DQ em nivel alto
_delay_us(60);
presente = tst_bit(PIN,DQ); //lê DQ, 0 = dispositivo presente, 1 = nenhum dispositivo detectado
_delay_us(240); //o pulso de presença pode ter 240us
return(presente);
}

unsigned char le_bit() //lê um bit do barramento 1 wire
{
unsigned char bit_1w;
DDR = (1<<DQ); // dá um pulso na linha, inicia quadro de leitura
clr_bit(PORT,DQ); // coloca saida em zero
DDR = (0<<DQ); //pino SDA como entrada, o resistor de pull-up mantem DQ em nivel alto
_delay_us (15); // aguarda o dispositivo colocar o dado na saída
bit_1w = tst_bit(PIN,DQ); //lê DQ
return (bit_1w); //retorna o dado
}

void escreve_bit(unsigned char bit_1w)//escreve um bit no barramento 1 wire
{
DDR = (1<<DQ);
clr_bit(PORT,DQ); //linha DQ em zero
if (bit_1w==1) set_bit(PORT,DQ); //coloca dado 1 na saida
_delay_us(120);
set_bit(PORT,DQ);
DDR = (0<<DQ); //ativa pull-up
}

unsigned char le_byte() //lê um byte do barramento 1 wire
{
unsigned char i, dado = 0;
for (i=0;i<8;i++) //lê oito bits iniciando pelo bit menos significativo
{
if (le_bit()==1) dado|=0x01<<i;
_delay_us(90); //aguarda o fim do quadro de leitura do bit atual
}
return (dado);
}

void escreve_byte(char dado) //escreve um byte no barramento 1 wire
{
unsigned char i, temp;
for (i=0; i<8; i++) //envia o byte iniciando do bit menos significativo
{
temp = dado>>i; //desloca o dado 1 bit à direita
temp &= 0x01; //isola o bit 0 (LSB)
escreve_bit(temp); //escreve o bit no barramento
}
}

void WDT_init(void)
{
WDTCSR =(1<<WDCE)|(1<<WDIE)|(1<<WDP3)|(0<<WDP2)|(0<<WDP1)|(1<<WDP0); // Watchdog Change Enable and 8 seconds timer.
MCUSR &=~(1<<WDRF); // MCU reset disable
WDTCSR&=~(1<<WDE); // Watchdog System Reset Enable
}


ISR(WDT_OVERFLOW_vect)
{

i++;

if(i>4) // 4 times 8 seconds = 64 seconds to WakeUp
	{
	sleep_disabe();
	i=0;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How should this work at all?

I would suggest:

volatile char i=0; 

int main(void) 
{ 
  // beginning of you main comes here
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); 
  USART_Init(UBRRVAL); 
  WDT_init; 
  DDRB|=(1<<PB0); 
  for(;;) {
    if (i >= 8) { // **8** times 8 seconds = 64 seconds
      // place the rest of your main here
      i = 0;
    }
  }
}

ISR(WDT_OVERFLOW_vect) 
{ 
  i++; 
}

BTW:
- No need for a prototype of your ISR.
- Your comment about buffer length (12) does not match with your declaration of buffer[3].

/Martin.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your "void WDT_init(void)" causes system reset.
Try this

void WDT_Initialization_as_Wakeup_Source( void )
{    
    MCUSR   &= ~(1<<WDRF);              
    WDTCSR   =  (1<<WDCE)|1<<WDE);                     
    WDTCSR   =  (1<<WDIF)|(1<<WDIE)|(1<<WDCE)|(1<<WDP3)|(1<<WDP0); 
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow, that is really amazing, it works great, thanks Jim, Martin and Visovian. :)